LibJF/libjf-base/src/main/java/io/gitlab/jfronny/libjf/LibJf.java

66 lines
3.4 KiB
Java

package io.gitlab.jfronny.libjf;
import com.sun.jdi.connect.Transport;
import io.gitlab.jfronny.commons.Serializer;
import io.gitlab.jfronny.commons.logger.DelegateLogger;
import io.gitlab.jfronny.commons.logger.HotswapLoggerFinder;
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
import io.gitlab.jfronny.commons.serialize.databind.DatabindSerializer;
import io.gitlab.jfronny.commons.serialize.databind.ObjectMapper;
import io.gitlab.jfronny.commons.serialize.json.JsonTransport;
import io.gitlab.jfronny.libjf.log.JULBridge;
import io.gitlab.jfronny.libjf.log.SLF4JPlatformLogger;
import io.gitlab.jfronny.libjf.serialize.LenientTransport;
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
import org.slf4j.LoggerFactory;
public class LibJf implements PreLaunchEntrypoint {
public static final String MOD_ID = "libjf";
public static final SystemLoggerPlus LOGGER = SystemLoggerPlus.forName(MOD_ID);
public static final ObjectMapper MAPPER = new ObjectMapper();
public static final JsonTransport JSON_TRANSPORT = new JsonTransport();
public static final JsonTransport LENIENT_TRANSPORT = new LenientTransport();
static {
Serializer.setInstance(new DatabindSerializer<>(JSON_TRANSPORT, MAPPER));
}
@Override
public void onPreLaunch() {
setup();
}
private static boolean setup = false;
private static boolean bootstrapped = false;
public static void setup() {
bootstrap();
if (!setup) {
setup = true;
// Sometimes a mod using LibJF may want to log before game libraries are initialized.
// For that case, an implementation of System.Logger that redirects to Fabric Loader's logger is used at startup.
// After the game is initialized though, that becomes unnecessary, and we can switch to using SLF4J directly.
// The setup method is called after the game is initialized, so this is the perfect place to do this.
HotswapLoggerFinder.updateAllStrategies((name, module, level) -> new SLF4JPlatformLogger(LoggerFactory.getLogger(name)));
}
}
public static void bootstrap() {
if (!bootstrapped) {
bootstrapped = true;
// I use System.Logger for logging.
// LibJF ships a service loaded in System.LoggerFinder, which delegates to Fabric Loader and (later on) SLF4J (after setup).
if (LOGGER instanceof DelegateLogger) {
// If the ServiceLoader was able to find this service, any Logger generated will be a DelegateLogger since that class is used by the HotswapLoggerFinder.
// This means that redirection to SLF4J is already set up and we don't need to do anything.
LOGGER.debug("HotswapLoggerFinder was loaded successfully. No need to install JULBridge.");
} else {
// If Fabric Loader is run in production, the ServiceLoader may not pick up this implementation quickly enough.
// In that case, the JUL backend is selected and this cannot be changed, so we need to redirect logs from JUL instead.
// The JULBridge does exactly that by redirecting JUL logs to loggers created by its own instance of EarlyLoggerSetup.
JULBridge.install();
LOGGER.debug("JULBridge was installed. If available in your launcher, please enable the ServiceLoader fix for better performance.");
}
}
}
}