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

This commit is contained in:
embeddedt 2023-07-28 21:41:44 -04:00
commit 4a66802b37
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
7 changed files with 170 additions and 41 deletions

2
.gitignore vendored
View File

@ -2,6 +2,8 @@ eclipse
run
libs
media
__pycache__
*.pyc
classes/
.architectury-transformer/
fabric/fabricloader.log

View File

@ -128,21 +128,8 @@ public class ModernFixEarlyConfig {
mixinsMissingMods.put(mixinClassName, requiredModId);
else if(isClientOnly && !ModernFixPlatformHooks.INSTANCE.isClient())
mixinsMissingMods.put(mixinClassName, "[not client]");
List<String> mixinOptionNames = dotSplitter.splitToList(mixinClassName);
StringBuilder optionBuilder = new StringBuilder(mixinClassName.length());
optionBuilder.append("mixin");
// mixin.core, mixin.safety can be top-level, everything else must have a subcategory
boolean allowTopLevel;
if(mixinOptionNames.size() > 0)
allowTopLevel = mixinOptionNames.get(0).equals("core") || mixinOptionNames.get(0).equals("safety");
else
allowTopLevel = false;
for(int i = 0; i < mixinOptionNames.size() - 1; i++) {
optionBuilder.append('.');
optionBuilder.append(mixinOptionNames.get(i));
if(i > 0 || allowTopLevel)
mixinOptions.add(optionBuilder.toString());
}
String mixinCategoryName = "mixin." + mixinClassName.substring(0, mixinClassName.lastIndexOf('.'));
mixinOptions.add(mixinCategoryName);
}
} catch(IOException e) {
ModernFix.LOGGER.error("Error scanning file " + mixinPath, e);
@ -198,6 +185,17 @@ public class ModernFixEarlyConfig {
this.options.putIfAbsent(optionName, option);
this.optionsByCategory.put(OptionCategories.getCategoryForOption(optionName), option);
}
for(Map.Entry<String, Option> entry : this.options.entrySet()) {
int idx = entry.getKey().lastIndexOf('.');
if(idx <= 0)
continue;
String potentialParentKey = entry.getKey().substring(0, idx);
Option potentialParent = this.options.get(potentialParentKey);
if(potentialParent != null) {
System.out.println(potentialParentKey + " -> " + entry.getKey());
entry.getValue().setParent(potentialParent);
}
}
// Defines the default rules which can be configured by the user or other mods.
// You must manually add a rule for any new mixins not covered by an existing package rule.
this.addMixinRule("launch.class_search_cache", true);

View File

@ -11,6 +11,7 @@ public class Option {
private Set<String> modDefined = null;
private boolean enabled;
private boolean userDefined;
private Option parent = null;
public Option(String name, boolean enabled, boolean userDefined) {
this.name = name;
@ -37,10 +38,33 @@ public class Option {
this.modDefined.add(modId);
}
public void setParent(Option option) {
this.parent = option;
}
public Option getParent() {
return this.parent;
}
public int getDepth() {
if(this.parent == null)
return 0;
else
return this.parent.getDepth() + 1;
}
public boolean isEnabled() {
return this.enabled;
}
/**
* Checks if this option will effectively be disabled (regardless of its own status)
* by the parent rule being disabled.
*/
public boolean isEffectivelyDisabledByParent() {
return this.parent != null && (!this.parent.enabled || this.parent.isEffectivelyDisabledByParent());
}
public boolean isOverridden() {
return this.isUserDefined() || this.isModDefined();
}
@ -57,6 +81,13 @@ public class Option {
return this.name;
}
public String getSelfName() {
if(this.parent == null)
return this.name;
else
return this.name.substring(this.parent.getName().length() + 1);
}
public void clearModsDefiningValue() {
this.modDefined = null;
}

View File

@ -24,10 +24,11 @@ import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
private final int maxNameWidth;
private int maxNameWidth = 0;
private static final int DEPTH_OFFSET = 20;
private static final Component OPTION_ON = Component.translatable("modernfix.option.on").withStyle(style -> style.withColor(ChatFormatting.GREEN));
private static final Component OPTION_OFF = Component.translatable("modernfix.option.off").withStyle(style -> style.withColor(ChatFormatting.RED));
@ -36,22 +37,42 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
private ModernFixConfigScreen mainScreen;
private static MutableComponent getOptionComponent(String optionName) {
String friendlyKey = "modernfix.option.name." + optionName;
MutableComponent baseComponent = Component.literal(optionName);
private static MutableComponent getOptionComponent(Option option) {
String friendlyKey = "modernfix.option.name." + option.getName();
MutableComponent baseComponent = Component.literal(option.getSelfName());
if(I18n.exists(friendlyKey))
return Component.translatable(friendlyKey).withStyle(style -> style.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, baseComponent)));
else
return baseComponent;
}
public void updateOptionEntryStatuses() {
for(Entry e : this.children()) {
if(e instanceof OptionEntry) {
((OptionEntry)e).updateStatus();
}
}
}
private final Set<Option> addedOptions = new HashSet<>();
private void addOption(Option option) {
if(addedOptions.add(option)) {
int w = this.minecraft.font.width(getOptionComponent(option)) + DEPTH_OFFSET * option.getDepth();
this.maxNameWidth = Math.max(w, this.maxNameWidth);
this.addEntry(new OptionEntry(option.getName(), option));
ModernFixMixinPlugin.instance.config.getOptionMap().values().stream()
.filter(subOption -> subOption.getParent() == option)
.sorted(Comparator.comparing(Option::getName))
.forEach(this::addOption);
}
}
public OptionList(ModernFixConfigScreen arg, Minecraft arg2) {
super(arg2,arg.width + 45, arg.height, 43, arg.height - 32, 20);
this.mainScreen = arg;
int maxW = 0;
Multimap<String, Option> optionsByCategory = ModernFixMixinPlugin.instance.config.getOptionCategoryMap();
List<String> theCategories = OptionCategories.getCategoriesInOrder();
for(String category : theCategories) {
@ -59,21 +80,15 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
this.addEntry(new CategoryEntry(Component.translatable(categoryTranslationKey)
.withStyle(Style.EMPTY.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable(categoryTranslationKey + ".description"))))
));
List<Option> sortedKeys = optionsByCategory.get(category).stream().filter(key -> {
optionsByCategory.get(category).stream().filter(key -> {
int dotCount = 0;
for(char c : key.getName().toCharArray()) {
if(c == '.')
dotCount++;
}
return dotCount >= 2;
}).sorted(Comparator.comparing(Option::getName)).collect(Collectors.toList());
for(Option option : sortedKeys) {
int w = this.minecraft.font.width(getOptionComponent(option.getName()));
maxW = Math.max(w, maxW);
this.addEntry(new OptionEntry(option.getName(), option));
}
}).sorted(Comparator.comparing(Option::getName)).forEach(this::addOption);
}
this.maxNameWidth = maxW;
}
protected int getScrollbarPosition() {
@ -144,9 +159,9 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
this.option.setEnabled(!this.option.isEnabled(), !this.option.isUserDefined());
ModernFix.LOGGER.error("Unable to save config", e);
}
OptionList.this.updateOptionEntryStatuses();
}).tooltip(toggleTooltip).pos(0, 0).size(55, 20).build();
if(this.option.isModDefined())
this.toggleButton.active = false;
updateStatus();
this.helpButton = new Button.Builder(Component.literal("?"), (arg) -> {
Minecraft.getInstance().setScreen(new ModernFixOptionInfoScreen(mainScreen, optionName));
}).pos(75, 0).size(20, 20).build();
@ -157,12 +172,16 @@ public class OptionList extends ContainerObjectSelectionList<OptionList.Entry> {
}
}
void updateStatus() {
this.toggleButton.active = !(this.option.isModDefined() || this.option.isEffectivelyDisabledByParent());
}
@Override
public void render(PoseStack matrixStack, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean isMouseOver, float partialTicks) {
MutableComponent nameComponent = getOptionComponent(this.name);
MutableComponent nameComponent = getOptionComponent(option);
if(this.option.isUserDefined())
nameComponent = nameComponent.withStyle(style -> style.withItalic(true)).append(Component.translatable("modernfix.config.not_default"));
float textX = (float)(left + 160 - OptionList.this.maxNameWidth);
float textX = (float)(left + DEPTH_OFFSET * option.getDepth() + 160 - OptionList.this.maxNameWidth);
float textY = (float)(top + height / 2 - 4);
OptionList.this.minecraft.font.draw(matrixStack, nameComponent, textX, textY, 16777215);
this.toggleButton.setPosition(left + 175, top);

View File

@ -69,5 +69,37 @@
"modernfix.option.mixin.feature.branding": "Adds ModernFix to the branding list on the title screen, and also to the F3 screen.",
"modernfix.option.mixin.feature.direct_stack_trace": "Normally off, can be enabled to force the raw stack trace to be dumped to the log when a crash occurs. Occasionally vanilla's crash report system fails to work properly and gives an entirely irrelevant stack trace/report.",
"modernfix.option.mixin.feature.measure_time": "Uses a couple injections to measure world load time, datapack reload time, resource reload time, bootstrap time, and adds the necessary hooks to enable vanilla's unused profiler logic for resource reloading if so configured.",
"modernfix.option.mixin.feature.spam_thread_dump": "**To be used for debugging purposes only.** Causes a thread dump to be output to the log every 60 seconds. This can help to diagnose unexplained freezes during loading/gameplay."
"modernfix.option.mixin.feature.spam_thread_dump": "**To be used for debugging purposes only.** Causes a thread dump to be output to the log every 60 seconds. This can help to diagnose unexplained freezes during loading/gameplay.",
"modernfix.option.mixin.bugfix.chunk_deadlock": "Attempts to prevent chunk system deadlocks or provide additional debug information in the log when they occur. These deadlocks usually manifest as the server freezing indefinitely (e.g. entities not moving), while the client continues to work just fine.",
"modernfix.option.mixin.bugfix.chunk_deadlock.valhesia": "Patches Valhesia Structures to fix an issue in its code that causes frequent worldgen/chunkloading deadlocks.",
"modernfix.option.mixin.bugfix.cofh_core_crash": "Fixes a multithreading issue in CoFH Core that can cause rare crashes during launch.",
"modernfix.option.mixin.bugfix.ctm_resourceutil_cme": "Fixes a multithreading issue in ConnectedTexturesMod that can cause rare crashes during launch.",
"modernfix.option.mixin.bugfix.ender_dragon_leak": "Fixes a memory leak in vanilla caused by the ender dragon retaining a reference to the previous client world.",
"modernfix.option.mixin.bugfix.entity_load_deadlock": "Fixes many issues where EntityJoinWorldEvent/EntityJoinLevelEvent cause a worldgen deadlock, by slightly deferring entity loading. Should not, however, cause any noticeable behavior changes in-game.",
"modernfix.option.mixin.bugfix.fix_config_crashes": "Fixes Forge configs occasionally becoming corrupted when launching the game.",
"modernfix.option.mixin.bugfix.item_cache_flag": "Fixes MC-258939",
"modernfix.option.mixin.bugfix.preserve_early_window_pos": "Makes the game window retain its existing size when control is handed over from Forge's early loading to Minecraft code. Fixes the window teleporting back to the center of the screen after being dragged, etc.",
"modernfix.option.mixin.bugfix.refinedstorage.te_bug": "Fixes Refined Storage external storage blocks occasionally failing to show contents of drawers, etc. when loaded. Backport of Refined Storage PR #3435, which was only applied to 1.18 and later.",
"modernfix.option.mixin.bugfix.remove_block_chunkloading": "Fixes zombie pigmen keeping the 0, 0 chunk loaded perpetually on Forge. Backport of Forge PR #8583.",
"modernfix.option.mixin.bugfix.starlight_emptiness": "Fixes an occasional Starlight crash due to emptiness maps not being initialized. Backport of the same fix in Starlight for 1.18.x.",
"modernfix.option.mixin.core": "Core patches required for ModernFix to work",
"modernfix.option.mixin.devenv": "Patches used when running in a development environment, for speed improvement and/or testing",
"modernfix.option.mixin.safety": "Concurrency patches to prevent crashes during launch",
"modernfix.option.mixin.feature.integrated_server_watchdog": "Adds the vanilla watchdog to singleplayer worlds as well, but just prints out the stacktraces rather than forcefully terminating the world. This version includes the functionality of Fullstack Watchdog, but the latter is still needed for multiplayer.",
"modernfix.option.mixin.feature.snapshot_easter_egg": "Adds easter egg features (does not affect any vanilla visuals or behavior) when running on a snapshot version.",
"modernfix.option.mixin.feature.spark_profile_launch": "If enabled, and a compatible version of Spark is installed, the entire launch sequence will be profiled until the main menu.",
"modernfix.option.mixin.feature.warn_missing_perf_mods": "Shows a warning on startup if other performance mods considered essential and highly compatible are not present",
"modernfix.option.mixin.launch.class_search_cache": "Replaces Forge's resource finder (used to find game and a mod code) with a significantly faster version, speeding up launch",
"modernfix.option.mixin.perf.clear_fabric_mapping_tables": "Reduces memory usage by clearing mapping data structures in Fabric Loader that are either redundant or rarely used by mods. Off by default for compatibility reasons.",
"modernfix.option.mixin.perf.clear_mixin_classinfo": "Force-loads all mixins when launch finishes and then clears out mixin data structures to remove most of Mixin's memory footprint. Disabled by default for compatibility reasons.",
"modernfix.option.mixin.perf.deduplicate_wall_shapes": "Makes most wall blocks share the same shape object instead of each one having its own copy. Can reduce memory usage substantially when lots of wall blocks are added by mods.",
"modernfix.option.mixin.perf.dynamic_resources.ae2": "AE2 compatibility patch for dynamic resources",
"modernfix.option.mixin.perf.dynamic_resources.ctm": "CTM compatibility patch for dynamic resources",
"modernfix.option.mixin.perf.dynamic_resources.rs": "Refined Storage compatibility patch for dynamic resources",
"modernfix.option.mixin.perf.dynamic_resources.supermartijncore": "SuperMartijn642CoreLib compatibility patch for dynamic resources",
"modernfix.option.mixin.perf.faster_advancements": "Rewrites the advancement checking logic to be faster and not cause StackOverflowError in large packs. Port of Advancements Debug from Fabric.",
"modernfix.option.mixin.perf.patchouli_deduplicate_books": "Fix Patchouli books storing many empty items with NBT tags, reducing memory usage.",
"modernfix.option.mixin.perf.remove_spawn_chunks": "Completely removes spawn chunks from the game. They are no longer loaded at all, unlike Ksyxis.",
"modernfix.option.mixin.perf.use_integrated_resources.jepb": "",
"modernfix.option.mixin.perf.use_integrated_resources.jeresources": ""
}

View File

@ -1,22 +1,35 @@
#!/usr/bin/python3
import json
import subprocess
import argparse, json, os, subprocess, sys
# to import other scripts in same folder
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from contextlib import redirect_stdout
from modernfixlib import get_valid_mixin_options
parser = argparse.ArgumentParser(description='Generate ModernFix patch summary Markdown file.')
parser.add_argument('-p', '--langpath', default='common/src/main/resources/assets/modernfix/lang/en_us.json')
args = parser.parse_args()
branch_name = subprocess.check_output(['git', 'branch', '--show-current']).decode("utf-8").strip()
with open('doc/generated/' + branch_name + '-Summary-of-Patches.md', 'w') as output_file:
all_current_mixin_options = get_valid_mixin_options()
options_missing_descriptions = set()
with redirect_stdout(output_file):
with open('common/src/main/resources/assets/modernfix/lang/en_us.json') as lang_json:
with open(args.langpath) as lang_json:
lang_obj = json.loads(lang_json.read())
option_names = []
option_names = set()
for key, value in lang_obj.items():
if key.startswith("modernfix.option.mixin."):
option_names.append(key.replace("modernfix.option.", ""))
option_names.sort()
option_names.add(key.replace("modernfix.option.", ""))
option_names_sorted = list(option_names)
option_names_sorted.sort()
print()
for option in option_names:
for option in option_names_sorted:
if option not in all_current_mixin_options:
continue
option_description = lang_obj.get("modernfix.option." + option)
option_friendly_name = lang_obj.get("modernfix.option.name." + option)
print(f"### `{option}`")
@ -24,3 +37,15 @@ with open('doc/generated/' + branch_name + '-Summary-of-Patches.md', 'w') as out
if option_description is not None:
print(option_description)
print("")
else:
options_missing_descriptions.add(option)
options_missing_descriptions.update(all_current_mixin_options.difference(option_names))
# sort the list of missing descriptions and print them out if there are any
missing_descriptions_list = list(options_missing_descriptions)
missing_descriptions_list.sort()
num_missing = len(missing_descriptions_list)
if num_missing > 0:
print(f"Missing {num_missing} descriptions:")
for option in missing_descriptions_list:
print(f" - {option}")

22
scripts/modernfixlib.py Normal file
View File

@ -0,0 +1,22 @@
import os
import re
def get_valid_mixin_options():
all_mixin_options = set()
# gather all mixins in mixin folders
for platform in [ "common", "fabric", "forge" ]:
base_path = f"{platform}/src/main/java/org/embeddedt/modernfix/{platform}/mixin"
for root, dirs, files in os.walk(base_path):
for file in files:
if file.endswith(".java"):
mixin_name = root.replace(base_path, "").replace(os.path.sep, ".")
if mixin_name.startswith("."):
mixin_name = mixin_name[1:]
all_mixin_options.add("mixin." + mixin_name)
# gather any mixin strings referenced in ModernFixEarlyConfig
with open('common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java') as config_java:
config_str = config_java.read()
for option in re.findall(r"\"(mixin(?:\.[a-z_]+)+)\"", config_str):
all_mixin_options.add(option)
return all_mixin_options