Merge remote-tracking branch 'origin/1.20' into dev/1.20.2

This commit is contained in:
embeddedt 2023-09-05 11:21:20 -04:00
commit b56a65c192
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
31 changed files with 593 additions and 256 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1 @@
ko_fi: embeddedt

22
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,22 @@
ModernFix is a standard Minecraft-style Gradle project powered by Architectury Loom. To build the mod for all platforms,
run the `build` task (e.g. via `./gradlew build`). You can also use `./gradlew forge:build` or `./gradlew fabric:build`
to build for just one loader (e.g. when debugging and wanting to rebuild quickly).
You must use Java 17 to develop ModernFix as the toolchain requires it. Nonetheless, the 1.16 mod JARs will work on
a Minecraft instance with Java 8.
## Submitting pull requests
Code or documentation contributions are welcome. Please keep the following points in mind:
* This project supports many Minecraft versions. Ideally, contributions should be made to the oldest relevant MC version.
For instance, a PR optimizing new worldgen should be made to 1.18 (not 1.19 or 1.20) while a PR optimizing something
like recipes should be made to 1.16 (the oldest supported version).
This somewhat unconventional policy ensures that all supported versions are treated equal when it comes to development,
rather than the onus being on other modders and players to backport changes that are needed. Changes to older versions are
quickly ported up to the latest one as part of the regular development cycle. You are still welcome to open PRs against
a newer branch if desired - but the change will likely be applied manually and not merged as a regular PR.
* Please ensure your code is reasonably neat and sufficiently documented. Remember that self-documenting code is always
better.

View File

@ -1,6 +1,6 @@
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.2-SNAPSHOT" apply false
id "dev.architectury.loom" version "1.3-SNAPSHOT" apply false
id "maven-publish"
id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
id 'com.palantir.git-version' version '1.0.0'
@ -8,6 +8,7 @@ plugins {
id 'se.bjurr.gitchangelog.git-changelog-gradle-plugin' version '1.79.0'
id "com.modrinth.minotaur" version "2.+" apply false
id("com.diffplug.spotless") version "6.18.0" apply false
id 'modernfix.common-conventions' apply false
}
architectury {
@ -16,147 +17,7 @@ architectury {
ext.archives_base_name = 'modernfix'
allprojects {
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
apply plugin: "com.diffplug.spotless"
spotless {
java {
removeUnusedImports()
}
}
architectury {
compileOnly()
}
group = 'org.embeddedt'
// extract base version from tag, generate other metadata ourselves
def details = versionDetails()
def plusIndex = details.lastTag.indexOf("+")
if(plusIndex == -1) {
plusIndex = details.lastTag.length()
}
def baseVersion = details.lastTag.substring(0, plusIndex)
def dirtyMarker = grgit.status().clean ? "" : ".dirty"
def commitHashMarker = details.commitDistance > 0 ? ("." + details.gitHash.substring(0, Math.min(4, details.gitHash.length()))) : ""
def preMarker = (details.commitDistance > 0 || !details.isCleanTag) ? ("-beta." + details.commitDistance) : ""
if(preMarker.length() > 0) {
// bump to next patch release
def versionParts = baseVersion.tokenize(".")
baseVersion = "${versionParts[0]}.${versionParts[1]}.${versionParts[2].toInteger() + 1}"
}
def versionString = "${baseVersion}${preMarker}+mc${minecraft_version}${commitHashMarker}${dirtyMarker}"
version = versionString
archivesBaseName = rootProject.archives_base_name + '-' + project.name
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
repositories {
maven { url 'https://modmaven.dev/' }
maven {
url "https://cursemaven.com"
content {
includeGroup "curse.maven"
}
}
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
maven {
name = 'ParchmentMC'
url = 'https://maven.parchmentmc.org'
}
maven {
// Shedaniel's maven (Architectury API)
url = "https://maven.architectury.dev"
content {
includeGroup "me.shedaniel"
}
}
maven {
// saps.dev Maven (KubeJS and Rhino)
url = "https://maven.saps.dev/minecraft"
content {
includeGroup "dev.latvian.mods"
}
}
maven { // CTM
url "https://maven.tterrag.com/"
}
maven { url 'https://maven.blamejared.com' }
repositories {
maven {
name = "Fuzs Mod Resources"
url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/"
}
}
maven {
url 'https://maven.terraformersmc.com/releases'
}
maven { url = "https://jitpack.io" }
}
}
configure(subprojects.findAll {it.name == "common" || it.name == "forge" || it.name == "fabric"}) {
apply plugin: "dev.architectury.loom"
loom {
silentMojangMappingsLicense()
}
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings loom.layered() {
officialMojangMappings()
if(rootProject.hasProperty("parchment_version")) {
parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip")
}
}
}
processResources {
def mixinFileList = []
def mixinDirectory = file("src/main/java/org/embeddedt/modernfix/" + project.name + "/mixin")
fileTree(mixinDirectory).visit { FileVisitDetails details ->
if(details.file.isFile()) {
def fileName = mixinDirectory.relativePath(details.file).toString().replaceFirst(/\.java$/, "").replace('/', '.')
mixinFileList << fileName
}
}
def mixinClassesStringB = new StringBuilder()
for(int i = 0; i < mixinFileList.size(); i++) {
mixinClassesStringB.append(" \"")
mixinClassesStringB.append(mixinFileList.get(i))
mixinClassesStringB.append('"')
if(i < (mixinFileList.size() - 1))
mixinClassesStringB.append(',')
mixinClassesStringB.append('\n')
}
def replacements = [
mixin_classes: mixinClassesStringB.toString()
]
inputs.properties replacements
def filePattern = "modernfix-" + project.name + ".mixins.json"
filesMatching(filePattern) {
expand replacements
}
}
}
apply plugin: 'modernfix.common-conventions'
tasks.withType(JavaCompile).configureEach {
// ensure that the encoding is set to UTF-8, no matter what the system default is
@ -203,74 +64,4 @@ tasks.register('checkCleanTag') {
}
}
configure(subprojects.findAll {it.name == "forge" || it.name == "fabric"}) {
apply plugin: 'com.matthewprenger.cursegradle'
apply plugin: 'com.modrinth.minotaur'
loom {
mods {
main { // to match the default mod generated for Forge
sourceSet project.sourceSets.main
sourceSet project(':common').sourceSets.main
}
}
runs {
client {
vmArgs "-Xmx1G"
vmArgs "-Xms1G"
property("mixin.debug.export", "true")
}
}
}
def copyJarNameConsistent = tasks.register('copyJarNameConsistent', Copy) {
from remapJar // shortcut for createJar.outputs.files
into project.file("build/libs")
rename { name -> "modernfix-" + project.name + "-latest.jar" }
}
def copyJarToBin = tasks.register('copyJarToBin', Copy) {
from remapJar // shortcut for createJar.outputs.files
into rootProject.file("bin")
mustRunAfter "copyJarNameConsistent"
}
tasks.build.dependsOn(copyJarToBin, copyJarNameConsistent)
def isBeta = project.version.toString().contains("beta")
curseforge {
if (System.getenv("CURSEFORGE_TOKEN") != null) {
apiKey = System.getenv("CURSEFORGE_TOKEN")
project {
id = "790626"
changelog = file('../CHANGELOG.md')
changelogType = "markdown"
releaseType = isBeta ? "beta" : "release"
addGameVersion project.name.capitalize()
gameVersionStrings.addAll(supported_minecraft_versions.tokenize(","))
mainArtifact remapJar
}
}
}
modrinth {
token = System.getenv("MODRINTH_TOKEN")
projectId = "modernfix" // This can be the project ID or the slug. Either will work!
versionType = isBeta ? "beta" : "release" // This is the default -- can also be `beta` or `alpha`
uploadFile = remapJar
gameVersions = supported_minecraft_versions.tokenize(",")
loaders = project.name.equals("forge") ? ["forge", "neoforge"] : ["fabric"]
changelog.set(provider { file("CHANGELOG.md").getText('UTF-8') })
}
tasks.curseforge.dependsOn(rootProject.generateChangelog)
tasks.modrinth.dependsOn(rootProject.generateChangelog)
tasks.register('publishToModSites') {
publishToModSites.dependsOn(tasks.modrinth)
publishToModSites.dependsOn(tasks.curseforge)
}
}
println "ModernFix: " + version

3
buildSrc/build.gradle Normal file
View File

@ -0,0 +1,3 @@
plugins {
id 'groovy-gradle-plugin'
}

0
buildSrc/settings.gradle Normal file
View File

View File

@ -0,0 +1,81 @@
plugins {
id 'java'
id 'architectury-plugin'
id 'maven-publish'
id 'com.diffplug.spotless'
}
spotless {
java {
removeUnusedImports()
}
}
architectury {
compileOnly()
}
group = 'org.embeddedt'
// extract base version from tag, generate other metadata ourselves
def details = versionDetails()
def plusIndex = details.lastTag.indexOf("+")
if(plusIndex == -1) {
plusIndex = details.lastTag.length()
}
def baseVersion = details.lastTag.substring(0, plusIndex)
def dirtyMarker = grgit.status().clean ? "" : ".dirty"
def commitHashMarker = details.commitDistance > 0 ? ("." + details.gitHash.substring(0, Math.min(4, details.gitHash.length()))) : ""
def preMarker = (details.commitDistance > 0 || !details.isCleanTag) ? ("-beta." + details.commitDistance) : ""
if(preMarker.length() > 0) {
// bump to next patch release
def versionParts = baseVersion.tokenize(".")
baseVersion = "${versionParts[0]}.${versionParts[1]}.${versionParts[2].toInteger() + 1}"
}
def versionString = "${baseVersion}${preMarker}+mc${minecraft_version}${commitHashMarker}${dirtyMarker}"
version = versionString
archivesBaseName = rootProject.archives_base_name + '-' + project.name
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
repositories {
maven { url 'https://modmaven.dev/' }
maven {
url "https://cursemaven.com"
content {
includeGroup "curse.maven"
}
}
maven {
name = 'ParchmentMC'
url = 'https://maven.parchmentmc.org'
}
maven {
// Shedaniel's maven (Architectury API)
url = "https://maven.architectury.dev"
content {
includeGroup "me.shedaniel"
}
}
maven {
// saps.dev Maven (KubeJS and Rhino)
url = "https://maven.saps.dev/minecraft"
content {
includeGroup "dev.latvian.mods"
}
}
maven { // CTM
url "https://maven.tterrag.com/"
}
maven { url 'https://maven.blamejared.com' }
repositories {
maven {
name = "Fuzs Mod Resources"
url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/"
}
}
maven {
url 'https://maven.terraformersmc.com/releases'
}
maven { url = "https://jitpack.io" }
}

View File

@ -0,0 +1,52 @@
plugins {
id 'modernfix.common-conventions'
id 'dev.architectury.loom'
}
loom {
silentMojangMappingsLicense()
accessWidenerPath = file("${rootDir}/common/src/main/resources/modernfix.accesswidener")
}
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings loom.layered() {
officialMojangMappings()
if(rootProject.hasProperty("parchment_version")) {
parchment("org.parchmentmc.data:parchment-${minecraft_version}:${parchment_version}@zip")
}
}
}
tasks {
processResources {
def mixinFileList = []
def mixinDirectory = file("src/main/java/org/embeddedt/modernfix/" + project.name + "/mixin")
fileTree(mixinDirectory).visit { FileVisitDetails details ->
if(details.file.isFile()) {
def fileName = mixinDirectory.relativePath(details.file).toString().replaceFirst(/\.java$/, "").replace('/', '.')
mixinFileList << fileName
}
}
def mixinClassesStringB = new StringBuilder()
for(int i = 0; i < mixinFileList.size(); i++) {
mixinClassesStringB.append(" \"")
mixinClassesStringB.append(mixinFileList.get(i))
mixinClassesStringB.append('"')
if(i < (mixinFileList.size() - 1))
mixinClassesStringB.append(',')
mixinClassesStringB.append('\n')
}
def replacements = [
mixin_classes: mixinClassesStringB.toString()
]
inputs.properties replacements
def filePattern = "modernfix-" + project.name + ".mixins.json"
filesMatching(filePattern) {
expand replacements
}
}
}

View File

@ -0,0 +1,69 @@
plugins {
id 'com.matthewprenger.cursegradle'
id 'com.modrinth.minotaur'
}
loom {
mods {
main { // to match the default mod generated for Forge
sourceSet project.sourceSets.main
sourceSet project(':common').sourceSets.main
}
}
runs {
client {
vmArgs "-Xmx1G"
vmArgs "-Xms1G"
property("mixin.debug.export", "true")
}
}
}
def copyJarNameConsistent = tasks.register('copyJarNameConsistent', Copy) {
from remapJar // shortcut for createJar.outputs.files
into project.file("build/libs")
rename { name -> "modernfix-" + project.name + "-latest.jar" }
}
def copyJarToBin = tasks.register('copyJarToBin', Copy) {
from remapJar // shortcut for createJar.outputs.files
into rootProject.file("bin")
mustRunAfter "copyJarNameConsistent"
}
tasks.build.dependsOn(copyJarToBin, copyJarNameConsistent)
def isBeta = project.version.toString().contains("beta")
curseforge {
if (System.getenv("CURSEFORGE_TOKEN") != null) {
apiKey = System.getenv("CURSEFORGE_TOKEN")
project {
id = "790626"
changelog = file('../CHANGELOG.md')
changelogType = "markdown"
releaseType = isBeta ? "beta" : "release"
addGameVersion project.name.capitalize()
gameVersionStrings.addAll(supported_minecraft_versions.tokenize(","))
mainArtifact remapJar
}
}
}
modrinth {
token = System.getenv("MODRINTH_TOKEN")
projectId = "modernfix" // This can be the project ID or the slug. Either will work!
versionType = isBeta ? "beta" : "release" // This is the default -- can also be `beta` or `alpha`
uploadFile = remapJar
gameVersions = supported_minecraft_versions.tokenize(",")
loaders = [project.name]
changelog.set(provider { file("CHANGELOG.md").getText('UTF-8') })
}
tasks.curseforge.dependsOn(rootProject.generateChangelog)
tasks.modrinth.dependsOn(rootProject.generateChangelog)
tasks.register('publishToModSites') {
publishToModSites.dependsOn(tasks.modrinth)
publishToModSites.dependsOn(tasks.curseforge)
}

View File

@ -1,9 +1,9 @@
architectury {
common(rootProject.enabled_platforms.split(","))
plugins {
id "modernfix.mod-common-conventions"
}
loom {
accessWidenerPath = file("src/main/resources/modernfix.accesswidener")
architectury {
common(rootProject.enabled_platforms.split(","))
}
ext.jei_minecraft_version = "1.19.4" /* temporary, till 1.20 releases */

View File

@ -7,7 +7,6 @@ import net.minecraft.world.item.ItemStack;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
import org.embeddedt.modernfix.searchtree.DummySearchTree;
import org.embeddedt.modernfix.searchtree.SearchTreeProviderRegistry;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWErrorCallback;
@ -37,7 +36,7 @@ public abstract class MinecraftMixin {
SearchRegistry.TreeBuilderSupplier<ItemStack> tagSupplier = list -> provider.getSearchTree(true);
this.searchRegistry.register(SearchRegistry.CREATIVE_NAMES, nameSupplier);
this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, tagSupplier);
this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new DummySearchTree<>());
//this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, list -> new DummySearchTree<>());
ModernFixPlatformHooks.INSTANCE.registerCreativeSearchTrees(this.searchRegistry, nameSupplier, tagSupplier, this::populateSearchTree);
// grab components for all key mappings in order to prevent them from being loaded off-thread later
// this populates the LazyLoadedValues

View File

@ -16,7 +16,7 @@ import org.embeddedt.modernfix.render.SimpleItemModelView;
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.ModifyVariable;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = ItemRenderer.class, priority = 600)
@ -37,8 +37,8 @@ public abstract class ItemRendererMixin {
* we do not need to go through the process of rendering every quad. Just render the south ones (the ones facing the
* camera).
*/
@ModifyVariable(method = "renderModelLists", at = @At("HEAD"), index = 1, argsOnly = true)
private BakedModel useSimpleWrappedItemModel(BakedModel model, BakedModel arg, ItemStack stack, int combinedLight, int combinedOverlay, PoseStack matrixStack, VertexConsumer buffer) {
@ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderModelLists(Lnet/minecraft/client/resources/model/BakedModel;Lnet/minecraft/world/item/ItemStack;IILcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;)V"), index = 0)
private BakedModel useSimpleWrappedItemModel(BakedModel model, ItemStack stack, int combinedLight, int combinedOverlay, PoseStack matrixStack, VertexConsumer buffer) {
if(!RenderState.IS_RENDERING_LEVEL && !stack.isEmpty() && model.getClass() == SimpleBakedModel.class && transformType == ItemDisplayContext.GUI) {
FastItemRenderType type;
ItemTransform transform = model.getTransforms().gui;

View File

@ -166,11 +166,13 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin {
"getFluidState", "method_26227", "m_60819_", "func_204520_s"
);
Map<String, MethodNode> injectorMethodNames = new HashMap<>();
Map<String, MethodNode> allMethods = new HashMap<>();
Map<String, String> injectorMixinSource = new HashMap<>();
String descriptor = Type.getDescriptor(MixinMerged.class);
for(MethodNode m : targetClass.methods) {
if((m.access & Opcodes.ACC_STATIC) != 0)
continue;
allMethods.put(m.name, m);
Set<AnnotationNode> seenNodes = new HashSet<>();
if(m.invisibleAnnotations != null) {
for(AnnotationNode ann : m.invisibleAnnotations) {
@ -217,18 +219,43 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin {
}
}
Set<String> accessedFieldNames = new HashSet<>();
// We now know all methods that have been injected into initCache. See what fields they write to
injectorMethodNames.forEach((name, method) -> {
if(cacheCalledInjectors.contains(name)) {
for(AbstractInsnNode n : method.instructions) {
if(n instanceof FieldInsnNode) {
FieldInsnNode fieldAcc = (FieldInsnNode)n;
if(fieldAcc.getOpcode() == Opcodes.PUTFIELD && fieldAcc.owner.equals(targetClass.name)) {
accessedFieldNames.add(fieldAcc.name);
// Make a map of all injected methods called by initCache
Map<String, MethodNode> writingMethods = new HashMap<>(injectorMethodNames);
writingMethods.keySet().retainAll(cacheCalledInjectors);
// Recursively check the injected methods for any methods they may call
int previousSize = 0;
Set<String> checkedCalls = new HashSet<>();
while(writingMethods.size() > previousSize) {
previousSize = writingMethods.size();
List<String> keysToCheck = new ArrayList<>(writingMethods.keySet());
for(String name : keysToCheck) {
if(!checkedCalls.add(name))
continue;
for(AbstractInsnNode n : writingMethods.get(name).instructions) {
if(n instanceof MethodInsnNode) {
MethodInsnNode invokeNode = (MethodInsnNode)n;
if(invokeNode.owner.equals(targetClass.name)) {
MethodNode theMethod = allMethods.get(invokeNode.name);
if(theMethod != null)
writingMethods.put(invokeNode.name, theMethod);
}
}
}
}
}
// We now know all methods that have been injected into initCache, and their callers. See what fields they write to
writingMethods.forEach((name, method) -> {
for(AbstractInsnNode n : method.instructions) {
if(n instanceof FieldInsnNode) {
FieldInsnNode fieldAcc = (FieldInsnNode)n;
if(fieldAcc.getOpcode() == Opcodes.PUTFIELD && fieldAcc.owner.equals(targetClass.name)) {
accessedFieldNames.add(fieldAcc.name);
}
}
}
});
// Lastly, scan all injected methods and see if they retrieve from the field. If so, inject a generateCache
// call at the start.

View File

@ -207,10 +207,11 @@ public class ModernFixEarlyConfig {
disableIfModPresent("mixin.perf.thread_priorities", "smoothboot", "threadtweak");
disableIfModPresent("mixin.perf.boost_worker_count", "smoothboot", "threadtweak");
disableIfModPresent("mixin.perf.async_jei", "modernui");
disableIfModPresent("mixin.perf.compress_biome_container", "chocolate", "betterendforge" ,"skyblockbuilder");
disableIfModPresent("mixin.perf.compress_biome_container", "chocolate", "betterendforge" ,"skyblockbuilder", "modern_beta");
disableIfModPresent("mixin.bugfix.mc218112", "performant");
disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant");
disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me");
disableIfModPresent("mixin.bugfix.preserve_early_window_pos", "better_loading_screen");
disableIfModPresent("mixin.perf.cache_strongholds", "littletiles");
// content overlap
disableIfModPresent("mixin.perf.deduplicate_wall_shapes", "dashloader");

View File

@ -28,6 +28,32 @@ public class ModelBakeryHelpers {
*/
public static final int MAX_MODEL_LIFETIME_SECS = 300;
/**
* These folders will have all textures stitched onto the atlas when dynamic resources is enabled.
*/
public static String[] getExtraTextureFolders() {
return new String[] {
"attachment",
"bettergrass",
"block",
"blocks",
"cape",
"entity/bed",
"entity/chest",
"item",
"items",
"model",
"models",
"part",
"pipe",
"ropebridge",
"runes",
"solid_block",
"spell_effect",
"spell_projectile"
};
}
private static <T extends Comparable<T>, V extends T> BlockState setPropertyGeneric(BlockState state, Property<T> prop, Object o) {
return state.setValue(prop, (V)o);
}

View File

@ -5,13 +5,14 @@ import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.Util;
public class ModernFixConfigScreen extends Screen {
private OptionList optionList;
private Screen lastScreen;
public boolean madeChanges = false;
private Button doneButton;
private Button doneButton, wikiButton;
public ModernFixConfigScreen(Screen lastScreen) {
super(Component.translatable("modernfix.config"));
this.lastScreen = lastScreen;
@ -21,9 +22,13 @@ public class ModernFixConfigScreen extends Screen {
protected void init() {
this.optionList = new OptionList(this, this.minecraft);
this.addWidget(this.optionList);
this.wikiButton = new Button.Builder(Component.translatable("modernfix.config.wiki"), (arg) -> {
Util.getPlatform().openUri("https://github.com/embeddedt/ModernFix/wiki/Summary-of-Patches");
}).pos(this.width / 2 - 155, this.height - 29).size(150, 20).build();
this.doneButton = new Button.Builder(CommonComponents.GUI_DONE, (arg) -> {
this.onClose();
}).pos(this.width / 2 - 100, this.height - 29).size(200, 20).build();
}).pos(this.width / 2 - 155 + 160, this.height - 29).size(150, 20).build();
this.addRenderableWidget(this.wikiButton);
this.addRenderableWidget(this.doneButton);
}

View File

@ -0,0 +1,67 @@
package org.embeddedt.modernfix.util;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.*;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
/**
* All code here is derived from Guava's Stopwatch and Platform classes.
* Too bad it's not a public method call indeed...
*/
public class TimeFormatter {
static String formatCompact4Digits(double value) {
return String.format(Locale.ROOT, "%.4g", value);
}
public static String formatNanos(long nanos) {
TimeUnit unit = chooseUnit(nanos);
double value = (double) nanos / NANOSECONDS.convert(1, unit);
return formatCompact4Digits(value) + " " + abbreviate(unit);
}
private static TimeUnit chooseUnit(long nanos) {
if (DAYS.convert(nanos, NANOSECONDS) > 0) {
return DAYS;
}
if (HOURS.convert(nanos, NANOSECONDS) > 0) {
return HOURS;
}
if (MINUTES.convert(nanos, NANOSECONDS) > 0) {
return MINUTES;
}
if (SECONDS.convert(nanos, NANOSECONDS) > 0) {
return SECONDS;
}
if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) {
return MILLISECONDS;
}
if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) {
return MICROSECONDS;
}
return NANOSECONDS;
}
private static String abbreviate(TimeUnit unit) {
switch (unit) {
case NANOSECONDS:
return "ns";
case MICROSECONDS:
return "\u03bcs"; // μs
case MILLISECONDS:
return "ms";
case SECONDS:
return "s";
case MINUTES:
return "min";
case HOURS:
return "h";
case DAYS:
return "d";
default:
throw new AssertionError();
}
}
}

View File

@ -8,6 +8,7 @@
"modernfix.perf_mod_warning": "It is recommended to install the mods, but the warning(s) can be disabled in the ModernFix config.",
"modernfix.config": "ModernFix mixin config",
"modernfix.config.done_restart": "Done (restart required)",
"modernfix.config.wiki": "Open wiki",
"modernfix.message.reload_config": "A mod config file change was detected. To prevent loading files that aren't done saving, reloading must be triggered by running /mfrc.",
"modernfix.option.on": "on",
"modernfix.option.off": "off",

View File

@ -0,0 +1,117 @@
{
"key.modernfix": "ModernFix",
"key.modernfix.config": "Apri la schermata configurazione",
"modernfix.jei_load": "Caricamento JEI in corso, potrebbe richiedere un po' di tempo",
"modernfix.no_lazydfu": "LazyDFU non è installato. Se Minecraft deve aggiornare i dati di gioco da una versione precedente, potrebbe esserci un notevole lag.",
"modernfix.no_ferritecore": "FerriteCore non è installato. L'uso della memoria sarà molto elevato.",
"modernfix.connectedness_dynresoruces": "Connectedness e l'opzione risorse dinamiche di ModernFix non sono compatibili. Rimuovi Connectedness o disabilita le risorse dinamiche nella configurazione di ModernFix.",
"modernfix.perf_mod_warning": "Si consiglia di installare le mod, ma gli avvertimenti possono essere disabilitati nella configurazione di ModernFix.",
"modernfix.config": "Configurazione mixin ModernFix",
"modernfix.config.done_restart": "Fatto (riavvio richiesto)",
"modernfix.message.reload_config": "È stata rilevata una modifica al file di configurazione. Per evitare di caricare file che non sono ancora stati salvati, è necessario avviare nuovamente il caricamento eseguendo /mfrc.",
"modernfix.option.on": "attivo",
"modernfix.option.off": "disattivo",
"modernfix.option.disabled": "disabilitato",
"modernfix.option.enabled": "abilitato",
"modernfix.option.mod_override": " da mod [%s]",
"modernfix.config.not_default": " (modificato)",
"asynclocator.map.locating": "Mappa (Ricerca in corso...)",
"asynclocator.map.none": "Mappa (Nessuna caratteristica vicina trovata)",
"modernfix.option.category.performance": "Prestazioni",
"modernfix.option.category.performance.description": "Funzionalità che aiutano a migliorare le prestazioni di gioco/avvio",
"modernfix.option.category.bugfixes": "Risoluzione errori",
"modernfix.option.category.bugfixes.description": "Correzioni di bug di base per migliorare la stabilità del gioco",
"modernfix.option.category.troubleshooting": "Risoluzione di problemi/Strumenti",
"modernfix.option.category.troubleshooting.description": "Funzionalità pensate per assistere nella diagnosi dei problemi",
"modernfix.option.category.expert_only": "Solo per esperti",
"modernfix.option.category.expert_only.description": "Non modificare a meno che tu sappia cosa stai facendo",
"modernfix.option.name.mixin.perf.async_jei": "Caricamento JEI in background",
"modernfix.option.mixin.perf.async_jei": "Solo per la versione 1.16. **Un'ottimizzazione fondamentale.** Parcheggia JEI per eseguire il ricaricamento su un thread in background, eliminando completamente il lungo ritardo che aggiunge al caricamento del mondo.",
"modernfix.option.mixin.perf.async_locator": "Solo per la versione 1.16. Riporta le patch di Async Locator mod per eliminare i blocchi del server associati a `/locate`, generazione di tabelle del bottino, ecc.",
"modernfix.option.mixin.perf.biome_zoomer": "Solo per la versione 1.16. Ottimizzazione minore per migliorare le prestazioni del zoom sulla biome usando la logica dalla versione 1.18.",
"modernfix.option.mixin.perf.blast_search_trees": "Tutte le versioni. Se sono installate REI o JEI, la costruzione delle tabelle di ricerca vanilla per la ricerca creativa viene disabilitata e la ricerca viene invece effettuata utilizzando le implementazioni di ricerca di queste mod. Questo risparmia alcuni secondi durante il caricamento del mondo e probabilmente risparmia anche un po' di RAM (sebbene non sia stato misurato).",
"modernfix.option.mixin.perf.boost_worker_count": "Solo per la versione 1.16. Rimuove il limite codificato sul conteggio dei thread dei lavoratori, simile a quanto fatto da Mojang nella versione 1.18.",
"modernfix.option.mixin.perf.cache_blockstate_cache_arrays": "Tutte le versioni. Evita di creare copie nuove di array enumerativi ogni volta che viene inizializzata una cache di blockstate. Ottimizzazione minore, ma semplice da fare.",
"modernfix.option.mixin.perf.cache_model_materials": "Tutte le versioni. Memorizza la collezione `RenderMaterial` (texture) e la lista delle dipendenze che i modelli restituiscono invece di richiederne il calcolo ad ogni richiesta. Aiuta ad accelerare il processo di caricamento/modellazione dei modelli.",
"modernfix.option.mixin.perf.cache_strongholds": "Tutte le versioni. Salva l'elenco generato delle posizioni delle fortezze con il mondo, invece di rigenerarlo ad ogni caricamento del mondo. Risparmia un po' di tempo nella versione 1.16, e molto di più nelle versioni 1.18 e 1.19.",
"modernfix.option.mixin.perf.cache_upgraded_structures": "Tutte le versioni. Molti mod includono file di strutture obsoleti, il che richiede al gioco di aggiornarli utilizzando DFU ogni volta che vengono caricati. Questo può essere piuttosto lento. Questa patch aggiunge una logica per invece salvare la versione aggiornata della struttura e riutilizzarla al caricamento successivo. Per gestire il caso in cui il mod cambia un file di struttura ma non il nome, l'hash del file originale viene confrontato con la versione in cache e se non corrispondono la struttura verrà nuovamente aggiornata.",
"modernfix.option.mixin.perf.compress_biome_container": "Solo per la versione 1.16. Ottimizzazione minore presa in prestito da Hydrogen, che cerca di risparmiare spazio nel contenitore della biome quando possibile. Questo viene disabilitato automaticamente se sono installati mod in conflitto come BetterEnd o Chocolate.",
"modernfix.option.mixin.perf.datapack_reload_exceptions": "Tutte le versioni. Riduce lo spam nei log e potrebbe migliorare leggermente la velocità di caricamento evitando di stampare le tracce dello stack per alcune eccezioni comunemente generate durante il ricaricamento dei datapack (ad esempio, oggetti mancanti nelle tabelle di bottino/ricette). Il messaggio verrà comunque stampato.",
"modernfix.option.mixin.perf.dedicated_reload_executor": "Tutte le versioni. Sposta il ricaricamento dei resource pack e dei datapack in un pool di thread dedicato anziché utilizzare i thread predefiniti `Worker-Main`. Questo consente ai mod Smooth Boot di potenzialmente migliorare le prestazioni in modalità singleplayer durante l'esecuzione, senza rallentare l'avvio a causa di un conteggio limitato di thread.",
"modernfix.option.mixin.perf.deduplicate_location": "Tutte le versioni, ma disabilitato per impostazione predefinita a causa dell'impatto sui tempi di caricamento. Duplica i namespace e i percorsi delle risorse. Questo risparmia memoria, ma aumenta anche il costo di costruzione di una nuova `ResourceLocation` in modo significativo.",
"modernfix.option.mixin.perf.dynamic_dfu": "Tutte le versioni. Modifica l'inizializzazione di DFU in modo che avvenga la prima volta che è necessario eseguire un aggiornamento. Questo è simile a LazyDFU, ma si differenzia in quanto evita di caricare *qualsiasi* classe/struttura dati DFU, mentre LazyDFU disabilita solo l'ottimizzazione delle regole. Fondamentalmente, questa opzione è una versione più sicura di DataFixerSlayer, in quanto caricherà comunque DFU quando necessario.\n\nIn genere dovresti continuare a utilizzare LazyDFU anche con questa opzione abilitata, in quanto l'ottimizzazione delle regole DFU altrimenti causerà lag.",
"modernfix.option.mixin.perf.dynamic_resources": "Tutte le versioni. Vedi https://github.com/embeddedt/ModernFix/wiki/Dynamic-Resources-FAQ.",
"modernfix.option.mixin.perf.dynamic_structure_manager": "Tutte le versioni. Consente al gioco di scaricare i file delle strutture dopo la generazione, anziché mantenerli caricati per sempre.",
"modernfix.option.mixin.perf.fast_registry_validation": "Tutte le versioni. Forge cerca inutilmente un metodo tramite riflessione ogni volta che viene convalidato un registro. Questa patch semplicemente memorizza nella cache il valore restituito poiché sarà lo stesso ogni volta.",
"modernfix.option.mixin.perf.faster_font_loading": "Tutte le versioni. Ottimizza il renderer dei font per caricare i font più velocemente, velocizzando il ricaricamento delle risorse.",
"modernfix.option.mixin.perf.faster_item_rendering": "Tutte le versioni. Evita di renderizzare i lati degli oggetti nelle interfacce utente (GUI). (Sì, sembra che anche il gioco di base lo faccia.)\n\nQuesto può triplicare il frame rate (FPS) con un mod come REI/JEI installato su GPU meno potenti, se sono visibili abbastanza oggetti. Disabilitato per impostazione predefinita poiché è una funzionalità nuova e non testata molto, ma dovrebbe essere sicuro. Il problema più probabile è che gli oggetti siano completamente invisibili nelle interfacce utente (GUI) o che appaiano piatti nel mondo.",
"modernfix.option.mixin.perf.faster_texture_loading": "Tutte le versioni precedenti alla 1.19.4. Evita di leggere le texture due volte (la prima volta utilizzando un percorso di codice molto lento) e invece ne effettua un caricamento più veloce (simile a 1.19.3+).",
"modernfix.option.mixin.perf.faster_texture_stitching": "Tutte le versioni. Consente al gioco di utilizzare un sistema di cucitura delle texture più veloce, originariamente sviluppato da SuperCoder79 per lwjgl3ify su 1.7.10, che può risparmiare tempo durante il caricamento. Raramente si è riscontrato che causi artefatti strani su blocchi o interfacce utente (GUI), potrebbe essere un errore di Sodium.",
"modernfix.option.mixin.perf.jeresources_startup": "Solo 1.16. Ottimizza Just Enough Resources in modo da non ricreare inutilmente le entità dei villaggi molte volte per la stessa professione, risparmiando tempo durante l'avvio di JEI.",
"modernfix.option.mixin.perf.kubejs": "Solo 1.16. Ottimizzazioni per KubeJS per evitare copie inutili di `ItemStack`, ecc., riducendo il tempo richiesto per caricare i datapack.",
"modernfix.option.mixin.perf.model_optimizations": "Tutte le versioni. Implementa ottimizzazioni per velocizzare il processo di caricamento dei modelli.",
"modernfix.option.mixin.perf.nbt_memory_usage": "Tutte le versioni. Utilizza una mappa di supporto più efficiente per i tag NBT composti che deduplica i nomi chiave e utilizza anche una mappa di array per i composti molto piccoli. Ciò riduce l'onere di memorizzare molti tag composti in memoria.",
"modernfix.option.mixin.perf.nuke_empty_chunk_sections": "Solo 1.16, ispirato a Hydrogen. Evita di memorizzare in memoria le sezioni di chunk piene di aria, segnalandole invece come vuote.",
"modernfix.option.mixin.perf.remove_biome_temperature_cache": "Tutte le versioni. Rimuove la cache delle temperature dei biome come fa Lithium nelle versioni moderne.",
"modernfix.option.mixin.perf.resourcepacks": "Tutte le versioni. **Un'ottimizzazione fondamentale.** I lanci nelle versioni moderne sono fortemente rallentati dall'accesso al filesystem. Molte richieste vengono fatte frequentemente ai pacchetti di risorse per elencare le risorse o verificare se esiste una risorsa specifica, e ognuna di queste richieste produce una chiamata API al file molto lenta.\n\nModernFix elimina completamente la maggior parte del collo di bottiglia semplicemente memorizzando in cache un elenco di tutte le risorse presenti nei pacchetti di risorse forniti dai mod e in quelli vanilla. La cache viene ricostruita alla ricarica delle risorse (ad eccezione delle risorse vanilla, poiché non dovrebbero mai cambiare mentre il gioco è in esecuzione).\n\nNon ci sono problemi di compatibilità noti con questa patch, ad eccezione di OptiFine (le sue risorse CTM non vengono caricate correttamente). Tuttavia, non consiglio di utilizzare OptiFine in nessuno scenario, poiché aggiunge diversi minuti all'avvio da solo e non è testato con ModernFix.",
"modernfix.option.mixin.perf.reuse_datapacks": "Solo versione 1.16. Tenta di velocizzare il passaggio tra mondi in giocatore singolo saltando il riavvio dei datapack quando possibile. Potrebbe causare problemi di compatibilità con alcuni mod, ma è abilitato per impostazione predefinita.",
"modernfix.option.mixin.perf.rewrite_registry": "Tutte le versioni. **Attualmente semi-rotto.** Sostituisce aggressivamente alcune parti interne del sistema di registro di Forge con versioni più veloci, tuttavia attualmente causa blocchi durante il caricamento di alcuni modpack. Disabilitato per impostazione predefinita per ovvi motivi.",
"modernfix.option.mixin.perf.skip_first_datapack_reload": "Solo versioni 1.16 e 1.19. **Un'ottimizzazione fondamentale.**\n\nNel mezzo del ciclo di sviluppo 1.16, Forge ha patchato il gioco per ricaricare i datapack due volte quando si caricava un mondo esistente, al fine di risolvere un problema di spostamento dell'ID dei biome. Purtroppo, le ricariche dei datapack richiedono spesso più di 30 secondi e quindi questo influisce molto sui tempi di caricamento del mondo.\n\nModernFix apporta le modifiche necessarie per evitare questa ricarica, basandosi sulla pull request incompiuta di Forge #8163.\n\nQuesta modifica è stata rimossa da Forge nella versione 1.18, ma poi una patch simile è stata aggiunta *nuovamente* nella versione 1.19 per risolvere il problema dei datapack dei mod che non venivano caricati durante la creazione di nuovi mondi in giocatore singolo. Fortunatamente, il problema è limitato alla schermata di creazione del mondo nella versione 1.19, e i mondi esistenti richiedono solo una ricarica. Tuttavia, questo raddoppia comunque la durata della lag spike quando si fa clic su \"Crea nuovo mondo\" nella versione 1.19, quindi ModernFix apporta nuovamente modifiche per evitare una ricarica ridondante.",
"modernfix.option.mixin.perf.state_definition_construct": "Tutte le versioni. Abilitato solo se è installato FerriteCore. Sfrutta la gestione dei blockstate di FerriteCore per accelerarne la creazione. Questo può aiutare ad accelerare l'avvio con mod che aggiungono molti blockstate, come ad esempio le mod di mobili.",
"modernfix.option.mixin.perf.sync_executor_sleep": "Tutte le versioni. Evita che il thread principale giri inutilmente consumando un core della CPU mentre aspetta che i lavoratori di caricamento dei mod finiscano.",
"modernfix.option.mixin.perf.thread_priorities": "Tutte le versioni. Regola le priorità dei thread dei lavoratori e del server in modo che siano inferiori al thread del client. Questo aiuta a migliorare la stabilità degli FPS su macchine con pochi core della CPU, purché l'implementazione Java in uso rispetti le priorità.",
"modernfix.option.mixin.perf.use_integrated_resources": "Principalmente per la versione 1.16. Corregge JEResources affinché utilizzi i dati delle tabelle del bottino del server integrato se si gioca in giocatore singolo, anziché ricaricare inutilmente le tabelle del bottino. Risparmia alcuni secondi in più durante l'avvio di JEI.",
"modernfix.option.mixin.bugfix.concurrency": "Le patch in questo gruppo risolvono problemi legati alla concorrenza in Minecraft e/o Forge. La maggior parte di esse provoca crash rari e difficili da diagnosticare durante il caricamento.",
"modernfix.option.mixin.bugfix.edge_chunk_not_saved": "Questa opzione è un porting della mod Chunk Saving Fix di SuperCoder (perché non mi sono reso conto che era già disponibile per Forge all'epoca).",
"modernfix.option.mixin.bugfix.mc218112": "Questa opzione risolve un deadlock che può verificarsi se viene lanciata un'eccezione durante l'elaborazione dei dati dell'entità. Vanilla non sblocca correttamente il gestore dei dati quando dovrebbe farlo. Questo è tracciato come MC-218112 nel bug tracker ed è stato corretto da Mojang nella versione 1.17.",
"modernfix.option.mixin.bugfix.packet_leak": "**Sperimentale**, non abilitato per impostazione predefinita. Un tentativo di correzione per il problema di perdita di memoria che si verifica dopo aver giocato abbastanza a lungo nella versione 1.16.",
"modernfix.option.mixin.bugfix.paper_chunk_patches": "Versioni 1.18 e successive. **Un'ottimizzazione fondamentale.** Porta una patch da Paper che risolve i problemi nella versione 1.17 con il caricamento dei chunk che richiede enormi quantità di memoria e genera molte istanze di `CompletableFuture`. Le versioni 1.18+ ora possono caricare mondi con soli 400MB di memoria come poteva fare la 1.16.",
"modernfix.option.mixin.bugfix.tf_cme_on_load": "Modifica Twilight Forest per eseguire la configurazione client non thread-safe utilizzando il thread principale, come dovrebbe fare, anziché il thread worker FML.",
"modernfix.option.mixin.feature.branding": "Aggiunge ModernFix all'elenco del marchio nella schermata dei titoli e anche alla schermata F3.",
"modernfix.option.mixin.feature.direct_stack_trace": "Di solito disabilitato, può essere abilitato per forzare la traccia dello stack grezzo da registrare quando si verifica un crash. Occasionalmente, il sistema di report dei crash di Vanilla non funziona correttamente e fornisce una traccia/report dello stack completamente irrilevante.",
"modernfix.option.mixin.feature.measure_time": "Utilizza alcune iniezioni per misurare il tempo di caricamento del mondo, il tempo di ricarica dei datapack, il tempo di ricarica delle risorse, il tempo di avvio e aggiunge i ganci necessari per abilitare la logica del profiler inutilizzata di Vanilla per la ricarica delle risorse, se configurato.",
"modernfix.option.mixin.feature.spam_thread_dump": "**Da utilizzare solo per scopi di debug.** Fa sì che venga registrato un thread dump nel registro ogni 60 secondi. Questo può aiutare a diagnosticare i blocchi inspiegabili durante il caricamento/gioco.",
"modernfix.option.mixin.bugfix.chunk_deadlock": "Tenta di prevenire i blocchi del sistema di chunk o fornisce informazioni di debug aggiuntive nel registro quando si verificano. Questi blocchi di solito si manifestano come il server che si blocca indefinitamente (ad esempio, le entità non si muovono), mentre il client continua a funzionare normalmente.",
"modernfix.option.mixin.bugfix.chunk_deadlock.valhesia": "Modifica Valhesia Structures per risolvere un problema nel suo codice che causa blocchi frequenti del worldgen/caricamento dei chunk.",
"modernfix.option.mixin.bugfix.cofh_core_crash": "Corregge un problema di multithreading in CoFH Core che può causare crash rari durante l'avvio.",
"modernfix.option.mixin.bugfix.ctm_resourceutil_cme": "Corregge un problema di multithreading in ConnectedTexturesMod che può causare crash rari durante l'avvio.",
"modernfix.option.mixin.bugfix.ender_dragon_leak": "Corregge una perdita di memoria in Vanilla causata dal drago dell'End che mantiene un riferimento al mondo client precedente.",
"modernfix.option.mixin.bugfix.entity_load_deadlock": "Corregge molti problemi in cui EntityJoinWorldEvent/EntityJoinLevelEvent causano un blocco del worldgen, ritardando leggermente il caricamento dell'entità. Non dovrebbe, tuttavia, causare cambiamenti di comportamento visibili in gioco.",
"modernfix.option.mixin.bugfix.fix_config_crashes": "Corregge il problema di Forge delle configurazioni che occasionalmente diventano corrotte durante il lancio del gioco.",
"modernfix.option.mixin.bugfix.item_cache_flag": "Corregge MC-258939",
"modernfix.option.mixin.bugfix.preserve_early_window_pos": "Fa sì che la finestra di gioco mantenga le sue dimensioni esistenti quando il controllo passa dal caricamento anticipato di Forge al codice di Minecraft. Corregge il problema della finestra che torna al centro dello schermo dopo essere stata trascinata, ecc.",
"modernfix.option.mixin.bugfix.refinedstorage.te_bug": "Corregge i blocchi di archiviazione esterna di Refined Storage che occasionalmente non mostrano i contenuti dei cassetti, ecc. quando vengono caricati. Backport di Refined Storage PR #3435, che è stato applicato solo alla versione 1.18 e successive.",
"modernfix.option.mixin.bugfix.remove_block_chunkloading": "Corregge il fatto che i maiali zombie tengano perpetuamente caricato il chunk 0, 0 su Forge. Backport di Forge PR #8583.",
"modernfix.option.mixin.bugfix.starlight_emptiness": "Corregge un crash occasionale di Starlight dovuto all'inizializzazione non corretta delle mappe di vuoto. Backport della stessa correzione in Starlight per la versione 1.18.x.",
"modernfix.option.mixin.core": "Patch di base necessarie per far funzionare ModernFix",
"modernfix.option.mixin.perf.reduce_blockstate_cache_rebuilds": "Tutte le versioni. **Un'ottimizzazione fondamentale.** Le versioni più recenti di Minecraft (dopo la 1.12) hanno implementato un sistema di cache dei blockstate che memorizza le informazioni frequentemente utilizzate su un blockstate, come ad esempio se è solido, la sua forma di collisione, ecc. Ricostruire questa cache è abbastanza veloce nella versione standard (richiede solo uno o due secondi), ma è molto lento con molti mod installati, poiché sono presenti molti più blockstate nel gioco che devono tutti avere le loro cache ricostruite.\n\nQuesto problema viene esacerbato da Forge poiché la cache viene ricostruita in molti punti quando i dati sarebbero quasi certamente inutilizzati prima della successiva ricostruzione. Esempi includono subito prima di raggiungere il menu principale (durante la fase \"Freezing data\"), nonché più volte (!) quando viene caricato un mondo.\n\nModernFix risolve questo collo di bottiglia delle prestazioni rendendo invece le ricostruzioni della cache pigre. Ogni blockstate ricostruisce la sua cache la prima volta che i dati vengono acceduti. In qualsiasi momento in cui Vanilla o Forge tenterebbero di ricostruire le cache per tutti i blockstate, questo viene ridirezionato per invalidare semplicemente la cache su ciascun blockstate.\n\nQuesto non dovrebbe avere alcun impatto sul TPS dopo che l'avvio è concluso.",
"modernfix.option.mixin.devenv": "Patch utilizzate durante l'esecuzione in un ambiente di sviluppo, per miglioramenti di velocità e/o test",
"modernfix.option.mixin.safety": "Patch di concorrenza per prevenire crash durante il lancio",
"modernfix.option.mixin.feature.integrated_server_watchdog": "Aggiunge il watchdog vanilla anche ai mondi in giocatore singolo, ma stampa solo le tracce dello stack anziché terminare forzatamente il mondo. Questa versione include la funzionalità di Fullstack Watchdog, ma quest'ultimo è comunque necessario per il multiplayer.",
"modernfix.option.mixin.feature.snapshot_easter_egg": "Aggiunge funzionalità easter egg (non influisce su alcuna visualizzazione o comportamento vanilla) quando si esegue una versione snapshot.",
"modernfix.option.mixin.feature.spark_profile_launch": "Se abilitato e installata una versione compatibile di Spark, l'intera sequenza di avvio verrà profilata fino al menu principale.",
"modernfix.option.mixin.feature.warn_missing_perf_mods": "Mostra un avviso all'avvio se altri mod per le prestazioni considerati essenziali e altamente compatibili non sono presenti",
"modernfix.option.mixin.launch.class_search_cache": "Sostituisce il risolutore delle risorse di Forge (usato per trovare il codice del gioco e di un mod) con una versione significativamente più veloce, accelerando l'avvio",
"modernfix.option.mixin.perf.clear_fabric_mapping_tables": "Riduce l'utilizzo della memoria cancellando le strutture di dati di mappatura in Fabric Loader che sono ridondanti o raramente utilizzate dai mod. Disabilitato per impostazione predefinita per motivi di compatibilità.",
"modernfix.option.mixin.perf.clear_mixin_classinfo": "Carica forzatamente tutti i mixin quando il lancio termina e quindi cancella le strutture di dati di mixin per rimuovere gran parte della memoria di Mixin. Disabilitato per impostazione predefinita per motivi di compatibilità.",
"modernfix.option.mixin.perf.deduplicate_wall_shapes": "Rende la maggior parte dei blocchi murari condividere lo stesso oggetto forma anziché avere ognuno la propria copia. Può ridurre notevolmente l'utilizzo della memoria quando vengono aggiunti molti blocchi murari dai mod.",
"modernfix.option.mixin.perf.dynamic_resources.ae2": "Patch di compatibilità AE2 per le risorse dinamiche",
"modernfix.option.mixin.perf.dynamic_resources.ctm": "Patch di compatibilità CTM per le risorse dinamiche",
"modernfix.option.mixin.perf.dynamic_resources.rs": "Patch di compatibilità Refined Storage per le risorse dinamiche",
"modernfix.option.mixin.perf.dynamic_resources.supermartijncore": "Patch di compatibilità SuperMartijn642CoreLib per le risorse dinamiche",
"modernfix.option.mixin.perf.dynamic_resources.diagonalfences": "Patch di compatibilità Diagonal Fences per le risorse dinamiche",
"modernfix.option.mixin.perf.faster_advancements": "Riscrive la logica di controllo degli avanzamenti per renderla più veloce e per evitare StackOverflowError in pacchetti grandi. Porting di Advancements Debug da Fabric.",
"modernfix.option.mixin.perf.patchouli_deduplicate_books": "Risolve il problema dei libri di Patchouli che memorizzano molti oggetti vuoti con tag NBT, riducendo l'utilizzo della memoria.",
"modernfix.option.mixin.perf.remove_spawn_chunks": "Rimuove completamente i chunk di spawn dal gioco. Non vengono più caricati affatto, a differenza di 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": "Risolve la perdita di risorse vaniglia di ObjectModificationManager in Blueprint, riducendo l'utilizzo della memoria. Nonostante la correzione sia stata contribuita in PR #195, non è ancora stata rilasciata.",
"modernfix.option.mixin.bugfix.removed_dimensions": "Risolve il problema del gioco che non riesce a caricare i mondi se vengono rimossi i mod delle dimensioni. Backport di Forge PR #8959.",
"modernfix.option.mixin.perf.compact_bit_storage": "Corregge lo spreco di memoria causato da alcuni server legacy (ad esempio Hypixel) che inviano chunk vuoti come se contenessero blocchi. Riduce notevolmente l'utilizzo della memoria su questi server.",
"modernfix.option.mixin.perf.deduplicate_climate_parameters": "Deduplica gli oggetti parametro del clima utilizzati dal nuovo sistema di biome, può risparmiare ~2MB ma rallenta leggermente la ricarica dei datapack.",
"modernfix.option.mixin.perf.dynamic_entity_renderers": "Costruisce i modelli delle entità la prima volta che vengono visti anziché durante l'avvio. Alcuni mod non sono compatibili con questa opzione e causeranno crash di EntityRenderer.",
"modernfix.option.mixin.perf.twilightforest.structure_spawn_fix": "Risolve il lag causato dal worldgen di Twilight Forest che controlla le strutture in modo molto inefficiente",
"modernfix.option.mixin.perf.fast_forge_dummies": "Velocizza il congelamento del registro di Forge durante l'avvio utilizzando un percorso del codice più veloce",
"modernfix.option.mixin.perf.tag_id_caching": "Velocizza l'uso delle voci dei tag memorizzando nella cache l'oggetto di posizione anziché ricrearlo ogni volta",
"modernfix.option.mixin.feature.disable_unihex_font": "Rimuove il font Unicode, risparmiando 10MB ma causando la mancata visualizzazione dei caratteri speciali"
}

View File

@ -4,9 +4,12 @@
"modernfix.jei_load": "JEIを読み込み中... しばらく時間がかかる可能性があります。",
"modernfix.no_lazydfu": "LazyDFUがインストールされていません。Minecraftが古いバージョンのゲームデータを更新する必要がある場合、目立つラグが発生する可能性があります。",
"modernfix.no_ferritecore": "FerriteCoreがインストールされていません。メモリ使用量は非常に高くなります。",
"modernfix.connectedness_dynresoruces": "ConnectednessとModernFixのダイナミックリソースオプションは互換性がありません。ModernFixの設定でConnectednessを削除するか、ダイナミックリソースを無効にしてください。",
"modernfix.perf_mod_warning": "Modをインストールすることをお勧めしますが、警告はModernFixの設定で無効にできます。",
"modernfix.config": "ModernFixによるmixinの設定",
"modernfix.config.done_restart": "完了 (再起動が必要)",
"modernfix.config.wiki": "wikiを開く",
"modernfix.message.reload_config": "MODコンフィグファイルの変更が検出されました。保存が完了していないファイルのロードを防ぐため、/mfrc を実行してリロードをトリガーする必要があります。",
"modernfix.option.on": "オン",
"modernfix.option.off": "オフ",
"modernfix.option.disabled": "無効",

View File

@ -8,6 +8,7 @@
"modernfix.perf_mod_warning": "推荐安装这些模组,但你也可以在现代化修复的配置中禁用此警告。",
"modernfix.config": "现代化修复Mixin配置",
"modernfix.config.done_restart": "完成(生效需重启)",
"modernfix.config.wiki": "打开英文wiki",
"modernfix.message.reload_config": "检测到模组配置文件的更改。为了避免加载尚未保存完毕的文件重载过程必须通过使用§b/mfrc§r命令来触发。",
"modernfix.option.on": "开启",
"modernfix.option.off": "关闭",

View File

@ -1,6 +1,8 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.2"
id 'com.adarshr.test-logger' version '3.2.0'
id "modernfix.mod-common-conventions"
id "modernfix.platform-conventions"
}
architectury {
@ -8,10 +10,6 @@ architectury {
fabric()
}
loom {
accessWidenerPath = project(":common").loom.accessWidenerPath
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files.

View File

@ -87,7 +87,6 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
// we can handle recursion in getModel without issues
fabric_enableGetOrLoadModelGuard = false;
this.blockColors = val;
this.ignoreModelLoad = true;
this.loadedBakedModels = CacheBuilder.newBuilder()
.expireAfterAccess(ModelBakeryHelpers.MAX_MODEL_LIFETIME_SECS, TimeUnit.SECONDS)
.maximumSize(ModelBakeryHelpers.MAX_BAKED_MODEL_COUNT)
@ -119,6 +118,11 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
this.bakedTopLevelModels = new DynamicBakedModelProvider((ModelBakery)(Object)this, bakedCache);
}
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", ordinal = 0))
private void ignoreFutureModelLoads(CallbackInfo ci) {
this.ignoreModelLoad = true;
}
private <K, V> void onModelRemoved(RemovalNotification<K, V> notification) {
if(!debugDynamicModelLoading)
return;
@ -193,7 +197,10 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
@Redirect(method = "bakeModels", at = @At(value = "INVOKE", target = "Ljava/util/Map;keySet()Ljava/util/Set;"))
private Set<ResourceLocation> skipBake(Map<ResourceLocation, UnbakedModel> instance) {
return Collections.emptySet();
Set<ResourceLocation> modelSet = new HashSet<>(instance.keySet());
if(modelSet.size() > 0)
ModernFix.LOGGER.info("Early baking {} models", modelSet.size());
return modelSet;
}
/**

View File

@ -16,6 +16,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@ -43,8 +44,8 @@ public class ModelManagerMixin {
private BlockModel loadSingleBlockModel(ResourceManager manager, ResourceLocation location) {
return manager.getResource(location).map(resource -> {
try {
return BlockModel.fromStream(resource.openAsReader());
try (BufferedReader reader = resource.openAsReader()) {
return BlockModel.fromStream(reader);
} catch(IOException e) {
ModernFix.LOGGER.error("Couldn't load model", e);
return null;
@ -54,8 +55,8 @@ public class ModelManagerMixin {
private List<ModelBakery.LoadedJson> loadSingleBlockState(ResourceManager manager, ResourceLocation location) {
return manager.getResourceStack(location).stream().map(resource -> {
try {
return new ModelBakery.LoadedJson(resource.sourcePackId(), GsonHelper.parse(resource.openAsReader()));
try (BufferedReader reader = resource.openAsReader()) {
return new ModelBakery.LoadedJson(resource.sourcePackId(), GsonHelper.parse(reader));
} catch(IOException e) {
ModernFix.LOGGER.error("Couldn't load blockstate", e);
return null;

View File

@ -1,4 +1,6 @@
apply plugin: "dev.architectury.loom"
plugins {
id 'dev.architectury.loom'
}
loom {
accessWidenerPath = project(":common").loom.accessWidenerPath

View File

@ -1,5 +1,7 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.2"
id "modernfix.mod-common-conventions"
id "modernfix.platform-conventions"
}
architectury {
@ -8,8 +10,6 @@ architectury {
}
loom {
accessWidenerPath = project(":common").loom.accessWidenerPath
forge {
convertAccessWideners = true
extraAccessWideners.add loom.accessWidenerPath.get().asFile.name
@ -108,9 +108,8 @@ jar {
//"Specification-Vendor": "modernfix authors",
"Specification-Version" : "1", // We are version 1 of ourselves
"Implementation-Title" : project.name,
"Implementation-Version" : project.jar.archiveVersion,
"Implementation-Version" : project.jar.archiveVersion
//"Implementation-Vendor": "modernfix authors",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
])
}
}

View File

@ -79,7 +79,7 @@ public class NightConfigFixer {
private static boolean couldShowMessage = true;
private static void triggerConfigMessage() {
if(couldShowMessage && Minecraft.getInstance().level != null && ModernFixClient.recipesUpdated && ModernFixClient.tagsUpdated) {
if(false && couldShowMessage && Minecraft.getInstance().level != null && ModernFixClient.recipesUpdated && ModernFixClient.tagsUpdated) {
Minecraft.getInstance().execute(() -> {
if(Minecraft.getInstance().level != null) {
couldShowMessage = false;

View File

@ -0,0 +1,57 @@
package org.embeddedt.modernfix.forge.mixin.bugfix.chunk_deadlock;
import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
@Mixin(value = ServerChunkCache.class, priority = 1100)
public abstract class ServerChunkCache_CurrentLoadingMixin {
@Shadow @Nullable protected abstract ChunkHolder getVisibleChunkIfPresent(long l);
private static final MethodHandle CURRENTLY_LOADING;
static {
try {
Field currentlyLoadingField = ObfuscationReflectionHelper.findField(ChunkHolder.class, "currentlyLoading");
currentlyLoadingField.setAccessible(true);
CURRENTLY_LOADING = MethodHandles.lookup().unreflectGetter(currentlyLoadingField);
} catch(Exception e) {
throw new RuntimeException("Failed to get currentlyLoading field", e);
}
}
/**
* Check the currentlyLoading field before going to the future chain, as was done in 1.16. In 1.18 upstream seems
* to have only applied this to getChunkNow().
*/
@Inject(method = "getChunk", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;getChunkFutureMainThread(IILnet/minecraft/world/level/chunk/ChunkStatus;Z)Ljava/util/concurrent/CompletableFuture;"), cancellable = true, require = 0)
private void checkCurrentlyLoading(int chunkX, int chunkZ, ChunkStatus requiredStatus, boolean load, CallbackInfoReturnable<ChunkAccess> cir) {
long i = ChunkPos.asLong(chunkX, chunkZ);
ChunkHolder holder = this.getVisibleChunkIfPresent(i);
if(holder != null) {
LevelChunk c;
try {
c = (LevelChunk)CURRENTLY_LOADING.invokeExact(holder);
} catch(Throwable e) {
e.printStackTrace();
c = null;
}
if(c != null)
cir.setReturnValue(c);
}
}
}

View File

@ -4,6 +4,7 @@ import net.minecraft.server.Bootstrap;
import net.minecraftforge.network.NetworkConstants;
import org.slf4j.Logger;
import org.embeddedt.modernfix.forge.load.ModWorkManagerQueue;
import org.embeddedt.modernfix.util.TimeFormatter;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -11,6 +12,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.lang.management.ManagementFactory;
@Mixin(Bootstrap.class)
public class BootstrapMixin {
@Shadow private static boolean isBootstrapped;
@ -20,7 +23,7 @@ public class BootstrapMixin {
@Inject(method = "bootStrap", at = @At("HEAD"))
private static void doModernFixBootstrap(CallbackInfo ci) {
if(!isBootstrapped) {
LOGGER.info("ModernFix bootstrap");
LOGGER.info("ModernFix reached bootstrap stage ({} after launch)", TimeFormatter.formatNanos(ManagementFactory.getRuntimeMXBean().getUptime() * 1000L * 1000L));
ModWorkManagerQueue.replace();
}
}

View File

@ -16,8 +16,11 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
@ -41,8 +44,8 @@ public class ModelManagerMixin {
private BlockModel loadSingleBlockModel(ResourceManager manager, ResourceLocation location) {
return manager.getResource(location).map(resource -> {
try {
return BlockModel.fromStream(resource.openAsReader());
try (BufferedReader reader = resource.openAsReader()) {
return BlockModel.fromStream(reader);
} catch(IOException e) {
ModernFix.LOGGER.error("Couldn't load model", e);
return null;
@ -52,8 +55,8 @@ public class ModelManagerMixin {
private List<ModelBakery.LoadedJson> loadSingleBlockState(ResourceManager manager, ResourceLocation location) {
return manager.getResourceStack(location).stream().map(resource -> {
try {
return new ModelBakery.LoadedJson(resource.sourcePackId(), GsonHelper.parse(resource.openAsReader()));
try (BufferedReader reader = resource.openAsReader()) {
return new ModelBakery.LoadedJson(resource.sourcePackId(), GsonHelper.parse(reader));
} catch(IOException e) {
ModernFix.LOGGER.error("Couldn't load blockstate", e);
return null;

View File

@ -5,9 +5,9 @@ junit_version=5.10.0-M1
mixinextras_version=0.2.0-beta.9
mod_id=modernfix
minecraft_version=23w33a
minecraft_version=1.20.2-pre1
enabled_platforms=fabric
forge_version=1.20.1-47.0.14
forge_version=1.20.1-47.1.3
# parchment_version=2023.07.09
refined_storage_version=4392788
jei_version=13.1.0.2

View File

@ -1,6 +1,7 @@
plugins {
//id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'java'
id 'modernfix.common-conventions'
}
group 'org.embeddedt'