Enable use of FML's unused TracingPrintStream for tracking mod messages on System.out
We implement this ourselves because we need it on 1.20.1 anyway, it will eventually be implemented upstream in NeoForge, at which point this feature will be removed: https://github.com/neoforged/FancyModLoader/issues/277
This commit is contained in:
parent
aae944da9f
commit
11f18cd739
|
|
@ -181,6 +181,7 @@ public class ModernFixEarlyConfig {
|
|||
.put("mixin.feature.snapshot_easter_egg", true)
|
||||
.put("mixin.feature.warn_missing_perf_mods", true)
|
||||
.put("mixin.feature.spark_profile_launch", false)
|
||||
.put("mixin.feature.log_stdout_in_log_files", true)
|
||||
.put("mixin.devenv", isDevEnv)
|
||||
.putConditionally(() -> !isFabric, "mixin.bugfix.fix_config_crashes", true)
|
||||
.putConditionally(() -> !isFabric, "mixin.feature.registry_event_progress", false)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
package org.embeddedt.modernfix.platform.forge;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import net.minecraft.client.searchtree.SearchRegistry;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.CreativeModeTabSearchRegistry;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegisterCommandsEvent;
|
||||
import net.minecraftforge.fml.ModLoader;
|
||||
import net.minecraftforge.fml.loading.FMLLoader;
|
||||
import net.minecraftforge.fml.loading.FMLPaths;
|
||||
import net.minecraftforge.fml.loading.LoadingModList;
|
||||
import net.minecraftforge.fml.loading.TracingPrintStream;
|
||||
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
import net.minecraftforge.server.ServerLifecycleHooks;
|
||||
import org.embeddedt.modernfix.api.constants.IntegrationConstants;
|
||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||
import org.embeddedt.modernfix.forge.classloading.ATInjector;
|
||||
import org.embeddedt.modernfix.forge.classloading.FastAccessTransformerList;
|
||||
import org.embeddedt.modernfix.forge.config.NightConfigFixer;
|
||||
import org.embeddedt.modernfix.forge.config.NightConfigWatchThrottler;
|
||||
import org.embeddedt.modernfix.forge.init.ModernFixForge;
|
||||
import org.embeddedt.modernfix.forge.packet.PacketHandler;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.embeddedt.modernfix.spark.SparkLaunchProfiler;
|
||||
import org.embeddedt.modernfix.util.CommonModUtil;
|
||||
import org.embeddedt.modernfix.util.DummyList;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.injection.struct.InjectorGroupInfo;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ModernFixPlatformHooksImpl implements ModernFixPlatformHooks {
|
||||
public boolean isClient() {
|
||||
return FMLLoader.getDist() == Dist.CLIENT;
|
||||
}
|
||||
|
||||
public boolean isDedicatedServer() {
|
||||
return FMLLoader.getDist().isDedicatedServer();
|
||||
}
|
||||
|
||||
private static final String verString = Optional.ofNullable(
|
||||
ModernFixMixinPlugin.class.getPackage().getImplementationVersion())
|
||||
.orElse("[unknown]");
|
||||
|
||||
public String getVersionString() {
|
||||
return verString;
|
||||
}
|
||||
|
||||
public boolean modPresent(String modId) {
|
||||
return FMLLoader.getLoadingModList().getModFileById(modId) != null;
|
||||
}
|
||||
|
||||
public boolean isDevEnv() {
|
||||
return !FMLLoader.isProduction();
|
||||
}
|
||||
|
||||
public MinecraftServer getCurrentServer() {
|
||||
return ServerLifecycleHooks.getCurrentServer();
|
||||
}
|
||||
|
||||
public boolean isEarlyLoadingNormally() {
|
||||
return LoadingModList.get().getErrors().isEmpty();
|
||||
}
|
||||
|
||||
public boolean isLoadingNormally() {
|
||||
return isEarlyLoadingNormally() && ModLoader.isLoadingStateValid();
|
||||
}
|
||||
|
||||
public Path getGameDirectory() {
|
||||
return FMLPaths.GAMEDIR.get();
|
||||
}
|
||||
|
||||
public void sendPacket(ServerPlayer player, Object packet) {
|
||||
PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), packet);
|
||||
}
|
||||
|
||||
public void injectPlatformSpecificHacks() {
|
||||
if(!isEarlyLoadingNormally() && ModernFixMixinPlugin.instance.isOptionEnabled("bugfix.forge_at_inject_error.ATInjector")) {
|
||||
ATInjector.injectModATs();
|
||||
}
|
||||
FastAccessTransformerList.attemptReplace();
|
||||
|
||||
/* https://github.com/FabricMC/Mixin/pull/99 */
|
||||
try {
|
||||
Field groupMembersField = InjectorGroupInfo.class.getDeclaredField("members");
|
||||
groupMembersField.setAccessible(true);
|
||||
Field noGroupField = InjectorGroupInfo.Map.class.getDeclaredField("NO_GROUP");
|
||||
noGroupField.setAccessible(true);
|
||||
InjectorGroupInfo noGroup = (InjectorGroupInfo)noGroupField.get(null);
|
||||
groupMembersField.set(noGroup, new DummyList<>());
|
||||
} catch(NoSuchFieldException ignored) {
|
||||
// Connector will replace FML's mixin with one which already has the fix, don't bother logging
|
||||
} catch(RuntimeException | ReflectiveOperationException e) {
|
||||
ModernFixMixinPlugin.instance.logger.error("Failed to patch mixin memory leak", e);
|
||||
}
|
||||
|
||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.spark_profile_launch.OnForge")) {
|
||||
CommonModUtil.runWithoutCrash(() -> SparkLaunchProfiler.start("launch"), "Failed to start profiler");
|
||||
}
|
||||
|
||||
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.log_stdout_in_log_files.PrintStreamReplacement")) {
|
||||
System.setOut(new TracingPrintStream(LoggerFactory.getLogger("STDOUT"), System.out));
|
||||
System.setErr(new TracingPrintStream(LoggerFactory.getLogger("STDERR"), System.err));
|
||||
}
|
||||
|
||||
NightConfigFixer.monitorFileWatcher();
|
||||
NightConfigWatchThrottler.throttle();
|
||||
}
|
||||
|
||||
public void applyASMTransformers(String mixinClassName, ClassNode targetClass) {
|
||||
|
||||
}
|
||||
|
||||
public void onServerCommandRegister(Consumer<CommandDispatcher<CommandSourceStack>> handler) {
|
||||
MinecraftForge.EVENT_BUS.addListener((RegisterCommandsEvent event) -> {
|
||||
handler.accept(event.getDispatcher());
|
||||
});
|
||||
}
|
||||
|
||||
private static Multimap<String, String> modOptions;
|
||||
public Multimap<String, String> getCustomModOptions() {
|
||||
if(modOptions == null) {
|
||||
modOptions = ArrayListMultimap.create();
|
||||
for (ModInfo meta : LoadingModList.get().getMods()) {
|
||||
meta.getConfigElement(IntegrationConstants.INTEGRATIONS_KEY).ifPresent(optionsObj -> {
|
||||
if(optionsObj instanceof Map) {
|
||||
Map<Object, Object> options = (Map<Object, Object>)optionsObj;
|
||||
options.forEach((key, value) -> {
|
||||
if(key instanceof String && value instanceof String) {
|
||||
modOptions.put((String)key, (String)value);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return modOptions;
|
||||
}
|
||||
|
||||
public void registerCreativeSearchTrees(SearchRegistry registry, SearchRegistry.TreeBuilderSupplier<ItemStack> nameSupplier, SearchRegistry.TreeBuilderSupplier<ItemStack> tagSupplier, BiConsumer<SearchRegistry.Key<ItemStack>, List<ItemStack>> populator) {
|
||||
for (SearchRegistry.Key<ItemStack> nameKey : CreativeModeTabSearchRegistry.getNameSearchKeys().values()) {
|
||||
registry.register(nameKey, nameSupplier);
|
||||
}
|
||||
for (SearchRegistry.Key<ItemStack> tagKey : CreativeModeTabSearchRegistry.getTagSearchKeys().values()) {
|
||||
registry.register(tagKey, tagSupplier);
|
||||
}
|
||||
Map<CreativeModeTab, SearchRegistry.Key<ItemStack>> tagSearchKeys = CreativeModeTabSearchRegistry.getTagSearchKeys();
|
||||
CreativeModeTabSearchRegistry.getNameSearchKeys().forEach((tab, nameSearchKey) -> {
|
||||
SearchRegistry.Key<ItemStack> tagSearchKey = tagSearchKeys.get(tab);
|
||||
tab.setSearchTreeBuilder((contents) -> {
|
||||
populator.accept(nameSearchKey, contents);
|
||||
populator.accept(tagSearchKey, contents);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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() {
|
||||
return "Forge";
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user