Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Johannes Frohnmeyer | 1e93e0f793 | |
Johannes Frohnmeyer | 763f3c6ed4 |
|
@ -1,8 +1,6 @@
|
|||
package io.gitlab.jfronny.libjf;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.fabricmc.loader.api.metadata.CustomValue;
|
||||
import io.gitlab.jfronny.gson.JsonElement;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -23,17 +21,14 @@ public class Flags {
|
|||
(source, value) -> new BooleanFlag(source, value.getAsBoolean()));
|
||||
}
|
||||
|
||||
private static <T> Set<T> getFlags(String name, BiFunction<String, String, T> makeFromProp, BiFunction<String, CustomValue, T> makeFromFmj) {
|
||||
private static <T> Set<T> getFlags(String name, BiFunction<String, String, T> makeFromProp, BiFunction<String, JsonElement, T> makeFromMod) {
|
||||
Set<T> flags = new LinkedHashSet<>();
|
||||
String propName = "libjf." + name;
|
||||
if (System.getProperty(propName) != null)
|
||||
flags.add(makeFromProp.apply("System Property", System.getProperty(propName)));
|
||||
for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
|
||||
if (!mod.getMetadata().containsCustomValue("libjf")) continue;
|
||||
CustomValue.CvObject co = mod.getMetadata().getCustomValue("libjf").getAsObject();
|
||||
if (!co.containsKey(name)) continue;
|
||||
flags.add(makeFromFmj.apply("Mod: " + mod.getMetadata().getId(), co.get(name)));
|
||||
}
|
||||
LoaderGlue.INSTANCE.obtainFlags(name, (id, data) -> {
|
||||
flags.add(makeFromMod.apply("Mod: " + id, data));
|
||||
});
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,9 @@ import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders;
|
|||
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
|
||||
import io.gitlab.jfronny.libjf.log.JULBridge;
|
||||
import io.gitlab.jfronny.libjf.log.SLF4JPlatformLogger;
|
||||
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class LibJf implements PreLaunchEntrypoint {
|
||||
public class LibJf {
|
||||
public static final String MOD_ID = "libjf";
|
||||
public static final SystemLoggerPlus LOGGER = SystemLoggerPlus.forName(MOD_ID);
|
||||
|
||||
|
@ -19,11 +18,6 @@ public class LibJf implements PreLaunchEntrypoint {
|
|||
GsonHolders.registerSerializer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreLaunch() {
|
||||
setup();
|
||||
}
|
||||
|
||||
private static boolean setup = false;
|
||||
private static boolean bootstrapped = false;
|
||||
public static void setup() {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package io.gitlab.jfronny.libjf;
|
||||
|
||||
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
|
||||
import io.gitlab.jfronny.commons.throwable.Try;
|
||||
import io.gitlab.jfronny.gson.JsonElement;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public interface LoaderGlue {
|
||||
LoaderGlue INSTANCE = Try.orThrow(() -> {
|
||||
boolean isFabric = false;
|
||||
try {
|
||||
Class.forName("net.fabricmc.loader.api.FabricLoader");
|
||||
isFabric = true;
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
if (isFabric) {
|
||||
return (LoaderGlue) Class.forName("io.gitlab.jfronny.libjf.fabric.FabricGlue").getConstructor().newInstance();
|
||||
} else {
|
||||
return (LoaderGlue) Class.forName("io.gitlab.jfronny.libjf.forge.ForgeGlue").getConstructor().newInstance();
|
||||
}
|
||||
});
|
||||
|
||||
void obtainFlags(String name, BiConsumer<String, JsonElement> out);
|
||||
SystemLoggerPlus getEarlyLogger(String name);
|
||||
boolean isClient();
|
||||
}
|
|
@ -1,32 +1,32 @@
|
|||
package io.gitlab.jfronny.libjf.coprocess;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class CoProcessManager implements ModInitializer {
|
||||
private final List<CoProcess> coProcesses = new ArrayList<>();
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
coProcesses.addAll(FabricLoader.getInstance().getEntrypoints(LibJf.MOD_ID + ":coprocess", CoProcess.class));
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
|
||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) ServerLifecycleEvents.SERVER_STOPPED.register(server -> this.stop());
|
||||
public class CoProcessManager {
|
||||
private static final List<CoProcess> coProcesses = new ArrayList<>();
|
||||
|
||||
public static void initialize() {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(CoProcessManager::stop));
|
||||
start();
|
||||
}
|
||||
|
||||
private void start() {
|
||||
public static void add(CoProcess coProcess) {
|
||||
coProcesses.add(coProcess);
|
||||
}
|
||||
|
||||
private static void start() {
|
||||
for (CoProcess coProcess : coProcesses) {
|
||||
coProcess.start();
|
||||
}
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
public static void stop() {
|
||||
for (Iterator<CoProcess> iter = coProcesses.iterator(); iter.hasNext(); ) {
|
||||
CoProcess coProcess = iter.next();
|
||||
coProcess.stop();
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package io.gitlab.jfronny.libjf.fabric;
|
||||
|
||||
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
|
||||
import io.gitlab.jfronny.gson.JsonElement;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.LoaderGlue;
|
||||
import io.gitlab.jfronny.libjf.coprocess.CoProcess;
|
||||
import io.gitlab.jfronny.libjf.coprocess.CoProcessManager;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
||||
import net.fabricmc.loader.api.metadata.CustomValue;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class FabricGlue implements LoaderGlue, PreLaunchEntrypoint, ModInitializer {
|
||||
@Override
|
||||
public void onPreLaunch() {
|
||||
LibJf.setup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
for (CoProcess entrypoint : FabricLoader.getInstance().getEntrypoints(LibJf.MOD_ID + ":coprocess", CoProcess.class)) {
|
||||
CoProcessManager.add(entrypoint);
|
||||
}
|
||||
if (!LoaderGlue.INSTANCE.isClient()) ServerLifecycleEvents.SERVER_STOPPED.register(server -> CoProcessManager.stop());
|
||||
CoProcessManager.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void obtainFlags(String name, BiConsumer<String, JsonElement> out) {
|
||||
for (ModContainer mod : FabricLoader.getInstance().getAllMods()) {
|
||||
if (!mod.getMetadata().containsCustomValue("libjf")) continue;
|
||||
CustomValue.CvObject co = mod.getMetadata().getCustomValue("libjf").getAsObject();
|
||||
if (!co.containsKey(name)) continue;
|
||||
out.accept(mod.getMetadata().getId(), FabricLoaderGsonGenerator.toGson(co.get(name)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SystemLoggerPlus getEarlyLogger(String name) {
|
||||
return new LoaderPlatformLogger(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClient() {
|
||||
return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.gson;
|
||||
package io.gitlab.jfronny.libjf.fabric;
|
||||
|
||||
import io.gitlab.jfronny.gson.*;
|
||||
import net.fabricmc.loader.api.metadata.CustomValue;
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.libjf.log;
|
||||
package io.gitlab.jfronny.libjf.fabric;
|
||||
|
||||
import io.gitlab.jfronny.commons.logger.CompactLogger;
|
||||
import net.fabricmc.loader.impl.util.log.Log;
|
|
@ -3,15 +3,15 @@ package io.gitlab.jfronny.libjf.gson;
|
|||
import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders;
|
||||
import io.gitlab.jfronny.gson.ExclusionStrategy;
|
||||
import io.gitlab.jfronny.gson.FieldAttributes;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.LoaderGlue;
|
||||
|
||||
public class HiddenAnnotationExclusionStrategy implements ExclusionStrategy {
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
|
||||
return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT
|
||||
return LoaderGlue.INSTANCE.isClient()
|
||||
? fieldAttributes.getAnnotation(ServerOnly.class) != null
|
||||
: fieldAttributes.getAnnotation(ClientOnly.class) != null;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.gitlab.jfronny.libjf.log;
|
|||
import io.gitlab.jfronny.commons.logger.HotswapLoggerFinder;
|
||||
import io.gitlab.jfronny.commons.logger.LeveledLoggerFinder;
|
||||
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
|
||||
import io.gitlab.jfronny.libjf.LoaderGlue;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EarlyLoggerSetup extends LeveledLoggerFinder {
|
||||
|
@ -10,7 +11,7 @@ public class EarlyLoggerSetup extends LeveledLoggerFinder {
|
|||
// When a logger is used before the game is initialized, SLF4J is not yet available.
|
||||
// To support that, this implementation which redirects to Fabric Loader's internal logging abstraction is used instead.
|
||||
// After the game is initialized, something calls LibJF.setup (usually preEntry), which replaces this factory with a SLF4J-based one.
|
||||
HotswapLoggerFinder.updateAllStrategies((name, module, level) -> new LoaderPlatformLogger(name));
|
||||
HotswapLoggerFinder.updateAllStrategies((name, module, level) -> LoaderGlue.INSTANCE.getEarlyLogger(name));
|
||||
}
|
||||
|
||||
private final LeveledLoggerFinder delegate = new HotswapLoggerFinder();
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
"fabric-lifecycle-events-v1": "*"
|
||||
},
|
||||
"entrypoints": {
|
||||
"main": ["io.gitlab.jfronny.libjf.coprocess.CoProcessManager"],
|
||||
"preLaunch": ["io.gitlab.jfronny.libjf.LibJf"]
|
||||
"main": ["io.gitlab.jfronny.libjf.fabric.FabricGlue"],
|
||||
"preLaunch": ["io.gitlab.jfronny.libjf.fabric.FabricGlue"]
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
package io.gitlab.jfronny.libjf.config.impl;
|
||||
|
||||
import io.gitlab.jfronny.commons.serialize.gson.api.v2.GsonHolders;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.LoaderGlue;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.Category;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.JfConfig;
|
||||
import io.gitlab.jfronny.libjf.config.api.v2.dsl.CategoryBuilder;
|
||||
import io.gitlab.jfronny.libjf.gson.FabricLoaderGsonGenerator;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.metadata.CustomValue;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.gitlab.jfronny.libjf.config.impl.ConfigCore.MODULE_ID;
|
||||
|
||||
public class AuxiliaryMetadata {
|
||||
public static AuxiliaryMetadata of(Category category) {
|
||||
AuxiliaryMetadata meta = new AuxiliaryMetadata();
|
||||
|
@ -35,15 +32,10 @@ public class AuxiliaryMetadata {
|
|||
var metaRef = new Object() {
|
||||
AuxiliaryMetadata meta = null;
|
||||
};
|
||||
FabricLoader.getInstance().getModContainer(modId).ifPresent(container -> {
|
||||
CustomValue cv = container.getMetadata().getCustomValue(MODULE_ID);
|
||||
if (cv == null) {
|
||||
cv = container.getMetadata().getCustomValue("libjf");
|
||||
if (cv != null) {
|
||||
cv = cv.getAsObject().get("config");
|
||||
}
|
||||
LoaderGlue.INSTANCE.obtainFlags("config", (id, data) -> {
|
||||
if (id.equals(modId)) {
|
||||
metaRef.meta = GsonHolders.API.getGson().fromJson(data, AuxiliaryMetadata.class);
|
||||
}
|
||||
if (cv != null) metaRef.meta = GsonHolders.API.getGson().fromJson(FabricLoaderGsonGenerator.toGson(cv), AuxiliaryMetadata.class);
|
||||
});
|
||||
return metaRef.meta;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
|
||||
import org.codehaus.plexus.util.IOUtil
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
plugins {
|
||||
id("jfmod.module")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://maven.neoforged.net/releases")
|
||||
}
|
||||
|
||||
base {
|
||||
archivesName = "libjf-forge"
|
||||
}
|
||||
|
||||
lom {
|
||||
loaderVersion = "20.4.210"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//TODO this dependency setup has only been tested in dev.
|
||||
// It may not work in a production environment.
|
||||
"loomDevelopmentDependencies"(project(":libjf-base")) {
|
||||
isTransitive = false
|
||||
}
|
||||
shadow(project(":libjf-base", "dev")) {
|
||||
isTransitive = false
|
||||
}
|
||||
include(modImplementation("net.fabricmc.fabric-api:fabric-lifecycle-events-v1")!!)
|
||||
shadow(libs.bundles.commons)
|
||||
}
|
||||
|
||||
// workaround to ensure our custom System.LoggerFinder is initialized early
|
||||
// ideally, we would use the configuration API, but that seems to cause a class loading issue with fabric loader
|
||||
//tasks.shadowJar {
|
||||
// val path = "META-INF/services/io.gitlab.jfronny.libjf.LoaderGlue"
|
||||
// val field = ServiceFileTransformer::class.java.getDeclaredField("serviceEntries").apply { isAccessible = true }
|
||||
// exclude(path)
|
||||
// transform(object: ServiceFileTransformer() {
|
||||
// private val serviceEntries get() = field.get(this) as MutableMap<String, Any>
|
||||
// override fun transform(context: TransformerContext?) {
|
||||
// super.transform(context)
|
||||
// (serviceEntries[path] as ByteArrayOutputStream).run {
|
||||
// reset()
|
||||
// file("src/main/resources/$path").inputStream().use { IOUtil.copy(it, this) }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
//}
|
|
@ -0,0 +1 @@
|
|||
loom.platform=neoforge
|
|
@ -0,0 +1,36 @@
|
|||
package io.gitlab.jfronny.libjf.forge;
|
||||
|
||||
import io.gitlab.jfronny.commons.logger.SystemLoggerPlus;
|
||||
import io.gitlab.jfronny.gson.JsonElement;
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import io.gitlab.jfronny.libjf.LoaderGlue;
|
||||
import io.gitlab.jfronny.libjf.log.SLF4JPlatformLogger;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.loading.FMLEnvironment;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public class ForgeGlue implements LoaderGlue {
|
||||
@Override
|
||||
public void obtainFlags(String name, BiConsumer<String, JsonElement> out) {
|
||||
ServiceLoader.load(ModFlagSource.class).stream().forEach(provider -> {
|
||||
JsonElement element = provider.get().obtain();
|
||||
if (element != null) {
|
||||
out.accept(provider.type().getName(), element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public SystemLoggerPlus getEarlyLogger(String name) {
|
||||
return new SLF4JPlatformLogger(LoggerFactory.getLogger(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClient() {
|
||||
return FMLEnvironment.dist == Dist.CLIENT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package io.gitlab.jfronny.libjf.forge;
|
||||
|
||||
import io.gitlab.jfronny.libjf.LibJf;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
|
||||
@Mod(LibJf.MOD_ID)
|
||||
public class LibJfForge {
|
||||
public LibJfForge() {
|
||||
LibJf.setup();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package io.gitlab.jfronny.libjf.forge;
|
||||
|
||||
import io.gitlab.jfronny.gson.JsonElement;
|
||||
|
||||
public interface ModFlagSource {
|
||||
JsonElement obtain();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
modLoader = "javafml"
|
||||
loaderVersion = "[2.0,)"
|
||||
issueTrackerURL = "https://git.frohnmeyer-wds.de/JfMods/LibJF/issues"
|
||||
license = "MIT"
|
||||
|
||||
[[mods]]
|
||||
modId = "libjf"
|
||||
version = "${version}"
|
||||
displayName = "LibJF for Forge"
|
||||
authors = "JFronny"
|
||||
description = '''
|
||||
Library mod by JFronny, ported to NeoForge
|
||||
'''
|
||||
|
||||
[[dependencies.libjf]]
|
||||
modId = "neoforge"
|
||||
type = "required"
|
||||
versionRange = "[${loader_version},)"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
||||
|
||||
[[dependencies.libjf]]
|
||||
modId = "minecraft"
|
||||
type = "required"
|
||||
versionRange = "${minecraft_version}"
|
||||
ordering = "NONE"
|
||||
side = "BOTH"
|
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"pack": {
|
||||
"description": "LibJF",
|
||||
"pack_format": 8
|
||||
}
|
||||
}
|
|
@ -36,3 +36,6 @@ include("libjf-web-v1")
|
|||
|
||||
include("libjf-bom")
|
||||
include("libjf-catalog")
|
||||
|
||||
|
||||
include("libjf-forge")
|
||||
|
|
Loading…
Reference in New Issue