Skip to content

Commit

Permalink
Better fix for config corruption
Browse files Browse the repository at this point in the history
Defer posting of all config reload events to the main thread, and
don't process any until after the launch finishes. This should
hopefully fix some synchronization issues
  • Loading branch information
embeddedt committed Aug 3, 2023
1 parent 1989f12 commit dbff17a
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
Expand Up @@ -3,17 +3,21 @@
import com.electronwill.nightconfig.core.file.FileWatcher;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
import org.embeddedt.modernfix.util.CommonModUtil;

import java.lang.reflect.Field;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

public class NightConfigFixer {
public static final LinkedHashSet<Runnable> configsToReload = new LinkedHashSet<>();
private static int tickCounter = 0;
public static void monitorFileWatcher() {
if(!ModernFixMixinPlugin.instance.isOptionEnabled("bugfix.fix_config_crashes.NightConfigFixerMixin"))
return;
Expand All @@ -28,6 +32,30 @@ public static void monitorFileWatcher() {
}, "replacing Night Config watchedFiles map");
}

/**
* Called by the render thread on the client, and the server thread on the server. Processes all the accumulated
* file watch events.
*/
public static void runReloads() {
if((tickCounter++ % 20) != 0)
return;
List<Runnable> runnablesToRun;
synchronized (configsToReload) {
if(configsToReload.isEmpty())
return;
runnablesToRun = new ArrayList<>(configsToReload);
configsToReload.clear();
}
ModernFix.LOGGER.info("Processing {} config reloads", runnablesToRun.size());
for(Runnable r : runnablesToRun) {
try {
r.run();
} catch(RuntimeException e) {
e.printStackTrace();
}
}
}

private static final Class<?> WATCHED_FILE = LamdbaExceptionUtils.uncheck(() -> Class.forName("com.electronwill.nightconfig.core.file.FileWatcher$WatchedFile"));
private static final Field CHANGE_HANDLER = ObfuscationReflectionHelper.findField(WATCHED_FILE, "changeHandler");

Expand Down Expand Up @@ -59,17 +87,12 @@ static class MonitoringConfigTracker implements Runnable {
}

/**
* Add the config
* Add the config runnable to the list to be processed by the main thread.
*/
@Override
public void run() {
synchronized(configsToReload) {
int oldSize = configsToReload.size();
configsToReload.add(configTracker);
if(oldSize == 0) {
ModernFixMixinPlugin.instance.logger.info("Config file change detected on disk. The Forge feature to watch config files for changes is currently disabled due to random corruption issues.");
ModernFixMixinPlugin.instance.logger.info("This functionality will be restored in a future ModernFix update.");
}
}
}
}
Expand Down
Expand Up @@ -4,6 +4,7 @@
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RecipesUpdatedEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.gui.ForgeIngameGui;
Expand All @@ -20,7 +21,9 @@
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLEnvironment;
import org.embeddedt.modernfix.ModernFixClient;
import org.embeddedt.modernfix.forge.config.NightConfigFixer;
import org.embeddedt.modernfix.screen.ModernFixConfigScreen;

import java.util.ArrayList;
Expand Down Expand Up @@ -51,6 +54,9 @@ public void onConfigKey(TickEvent.ClientTickEvent event) {
if(event.phase == TickEvent.Phase.START && configKey.consumeClick()) {
Minecraft.getInstance().setScreen(new ModernFixConfigScreen(Minecraft.getInstance().screen));
}
if(FMLEnvironment.dist == Dist.CLIENT && event.phase == TickEvent.Phase.START && ModernFixForge.launchDone) {
NightConfigFixer.runReloads();
}
}

private static final List<String> brandingList = new ArrayList<>();
Expand Down
Expand Up @@ -6,6 +6,7 @@
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.OnDatapackSyncEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.*;
Expand All @@ -15,6 +16,7 @@
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.network.FMLNetworkConstants;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
Expand All @@ -27,6 +29,7 @@
import org.embeddedt.modernfix.forge.ModernFixConfig;
import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler;
import org.embeddedt.modernfix.forge.config.ConfigFixer;
import org.embeddedt.modernfix.forge.config.NightConfigFixer;
import org.embeddedt.modernfix.forge.packet.PacketHandler;
import org.embeddedt.modernfix.forge.registry.ObjectHolderClearer;
import org.embeddedt.modernfix.forge.util.KubeUtil;
Expand All @@ -36,6 +39,7 @@
@Mod(ModernFix.MODID)
public class ModernFixForge {
private static ModernFix commonMod;
public static boolean launchDone = false;

public ModernFixForge() {
commonMod = new ModernFix();
Expand All @@ -54,6 +58,13 @@ public ModernFixForge() {
ConfigFixer.replaceConfigHandlers();
}

@SubscribeEvent
public void onServerTick(TickEvent.ServerTickEvent event) {
if(FMLEnvironment.dist == Dist.DEDICATED_SERVER && event.phase == TickEvent.Phase.END && ModernFixForge.launchDone) {
NightConfigFixer.runReloads();
}
}

@SubscribeEvent
public void onDatapackSync(OnDatapackSyncEvent event) {
if(event.getPlayer() != null) {
Expand Down
Expand Up @@ -30,6 +30,7 @@
import org.embeddedt.modernfix.forge.classloading.FastAccessTransformerList;
import org.embeddedt.modernfix.forge.classloading.ModernFixResourceFinder;
import org.embeddedt.modernfix.forge.config.NightConfigFixer;
import org.embeddedt.modernfix.forge.init.ModernFixForge;
import org.embeddedt.modernfix.forge.packet.PacketHandler;
import org.embeddedt.modernfix.forge.spark.SparkLaunchProfiler;
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
Expand Down Expand Up @@ -270,6 +271,7 @@ public void onLaunchComplete() {
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.spark_profile_launch.OnForge")) {
CommonModUtil.runWithoutCrash(() -> SparkLaunchProfiler.stop("launch"), "Failed to stop profiler");
}
ModernFixForge.launchDone = true;
}

public String getPlatformName() {
Expand Down

0 comments on commit dbff17a

Please sign in to comment.