Skip to content

Commit 36eb73b

Browse files
committed
Generify config patch to also work with Night Config Fixes mod
1 parent b499a05 commit 36eb73b

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

forge/src/main/java/org/embeddedt/modernfix/forge/config/NightConfigFixer.java

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import java.lang.reflect.Field;
1313
import java.nio.file.Path;
1414
import java.util.Collections;
15+
import java.util.HashMap;
16+
import java.util.Map;
1517
import java.util.Set;
1618
import java.util.concurrent.ConcurrentHashMap;
1719
import java.util.function.Function;
@@ -34,17 +36,32 @@ public static void monitorFileWatcher() {
3436
}
3537

3638
private static final Class<?> WATCHED_FILE = LamdbaExceptionUtils.uncheck(() -> Class.forName("com.electronwill.nightconfig.core.file.FileWatcher$WatchedFile"));
37-
private static final Class<?> CONFIG_WATCHER = LamdbaExceptionUtils.uncheck(() -> Class.forName("net.minecraftforge.fml.config.ConfigFileTypeHandler$ConfigWatcher"));
3839
private static final Field CHANGE_HANDLER = ObfuscationReflectionHelper.findField(WATCHED_FILE, "changeHandler");
3940

40-
private static final Field COMMENTED_FILE_CONFIG = ObfuscationReflectionHelper.findField(CONFIG_WATCHER, "commentedFileConfig");
41-
4241
private static final Class<?> WRITE_SYNC_CONFIG = LamdbaExceptionUtils.uncheck(() -> Class.forName("com.electronwill.nightconfig.core.file.WriteSyncFileConfig"));
4342
private static final Class<?> AUTOSAVE_CONFIG = LamdbaExceptionUtils.uncheck(() -> Class.forName("com.electronwill.nightconfig.core.file.AutosaveCommentedFileConfig"));
4443
private static final Field AUTOSAVE_FILECONFIG = ObfuscationReflectionHelper.findField(AUTOSAVE_CONFIG, "fileConfig");
4544

4645
private static final Field CURRENTLY_WRITING = ObfuscationReflectionHelper.findField(WRITE_SYNC_CONFIG, "currentlyWriting");
4746

47+
private static final Map<Class<?>, Field> CONFIG_WATCHER_TO_CONFIG_FIELD = Collections.synchronizedMap(new HashMap<>());
48+
49+
private static Field getCurrentlyWritingFieldOnWatcher(Object watcher) {
50+
return CONFIG_WATCHER_TO_CONFIG_FIELD.computeIfAbsent(watcher.getClass(), clz -> {
51+
while(clz != null && clz != Object.class) {
52+
for(Field f : clz.getDeclaredFields()) {
53+
if(CommentedFileConfig.class.isAssignableFrom(f.getType())) {
54+
f.setAccessible(true);
55+
ModernFixMixinPlugin.instance.logger.debug("Found CommentedFileConfig: field '{}' on {}", f.getName(), clz.getName());
56+
return f;
57+
}
58+
}
59+
clz = clz.getSuperclass();
60+
}
61+
return null;
62+
});
63+
}
64+
4865
static class MonitoringMap extends ConcurrentHashMap<Path, Object> {
4966
public MonitoringMap(ConcurrentHashMap<Path, ?> oldMap) {
5067
super(oldMap);
@@ -56,11 +73,7 @@ public Object computeIfAbsent(Path key, Function<? super Path, ?> mappingFunctio
5673
Object watchedFile = mappingFunction.apply(path);
5774
try {
5875
Runnable changeHandler = (Runnable)CHANGE_HANDLER.get(watchedFile);
59-
// replace Forge's config tracker with our own
60-
if(CONFIG_WATCHER.isAssignableFrom(changeHandler.getClass()))
61-
CHANGE_HANDLER.set(watchedFile, new MonitoringConfigTracker(changeHandler));
62-
else
63-
ModernFixMixinPlugin.instance.logger.warn("Unexpected Forge config tracker class: {}", changeHandler.getClass().getName());
76+
CHANGE_HANDLER.set(watchedFile, new MonitoringConfigTracker(changeHandler));
6477
} catch(ReflectiveOperationException e) {
6578
e.printStackTrace();
6679
}
@@ -99,15 +112,18 @@ private boolean isSaving(FileConfig config) throws ReflectiveOperationException
99112
@Override
100113
public void run() {
101114
try {
102-
CommentedFileConfig cfg = (CommentedFileConfig)COMMENTED_FILE_CONFIG.get(this.configTracker);
103-
while(isSaving(cfg)) {
104-
// block until the config is no longer marked as saving
105-
// Forge shouldn't save the config twice in a row under normal conditions so this should fix the
106-
// original bug
107-
try {
108-
Thread.sleep(500);
109-
} catch (InterruptedException e) {
110-
return;
115+
Field theField = getCurrentlyWritingFieldOnWatcher(this.configTracker);
116+
if(theField != null) {
117+
CommentedFileConfig cfg = (CommentedFileConfig)theField.get(this.configTracker);
118+
while(isSaving(cfg)) {
119+
// block until the config is no longer marked as saving
120+
// Forge shouldn't save the config twice in a row under normal conditions so this should fix the
121+
// original bug
122+
try {
123+
Thread.sleep(500);
124+
} catch (InterruptedException e) {
125+
return;
126+
}
111127
}
112128
}
113129
} catch(ReflectiveOperationException e) {

0 commit comments

Comments
 (0)