[config] Expose tooltips/titles as comments in json
This commit is contained in:
parent
5dc4198077
commit
4a65a61b7e
|
@ -3,7 +3,7 @@ libjf-base is a dependency of all other modules and provides common functionalit
|
||||||
It has no dependencies.
|
It has no dependencies.
|
||||||
It includes:
|
It includes:
|
||||||
|
|
||||||
- a Gson strategy to ignore fields annotated with GsonHidden
|
- a Gson strategy to ignore fields annotated with GsonHidden, ClientOnly and ServerOnly
|
||||||
- LazySupplier, a supplier that caches the result of another supplier to which it delegates
|
- LazySupplier, a supplier that caches the result of another supplier to which it delegates
|
||||||
- ThrowingRunnable and ThrowingSupplier, counterparts of their default lambdas which allow exceptions
|
- ThrowingRunnable and ThrowingSupplier, counterparts of their default lambdas which allow exceptions
|
||||||
- a "flags" system to allow dynamically enabling LibJF features through system properties and fabric.mod.json
|
- a "flags" system to allow dynamically enabling LibJF features through system properties and fabric.mod.json
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class TestConfig implements JfConfig {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
You MUST annotate any field configurable through the UI as @Entry and the class MUST extend JfConfig.
|
You MUST annotate any field configurable through the UI as @Entry and the class MUST extend JfConfig.
|
||||||
You MAY annotate fields as @GsonHidden to not serialize them (-> [libjf-base](libjf-base.md)).
|
You MAY annotate fields as @GsonHidden, @ClientOnly or @ServerOnly to hide them from the file as well them (-> [libjf-base](libjf-base.md)).
|
||||||
Numeric values MAY have a min and max value specified in their @Entry.
|
Numeric values MAY have a min and max value specified in their @Entry.
|
||||||
|
|
||||||
To register a config, add a `libjf:config` entrypoint pointing to its class to your fabric.mod.json.
|
To register a config, add a `libjf:config` entrypoint pointing to its class to your fabric.mod.json.
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.gitlab.jfronny.libjf.gson;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface ClientOnly {
|
||||||
|
}
|
|
@ -2,12 +2,17 @@ package io.gitlab.jfronny.libjf.gson;
|
||||||
|
|
||||||
import io.gitlab.jfronny.gson.ExclusionStrategy;
|
import io.gitlab.jfronny.gson.ExclusionStrategy;
|
||||||
import io.gitlab.jfronny.gson.FieldAttributes;
|
import io.gitlab.jfronny.gson.FieldAttributes;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
public class HiddenAnnotationExclusionStrategy implements ExclusionStrategy {
|
public class HiddenAnnotationExclusionStrategy implements ExclusionStrategy {
|
||||||
public boolean shouldSkipClass(Class<?> clazz) {
|
public boolean shouldSkipClass(Class<?> clazz) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
|
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
|
||||||
return fieldAttributes.getAnnotation(GsonHidden.class) != null;
|
if (fieldAttributes.getAnnotation(GsonHidden.class) != null) return true;
|
||||||
|
return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT
|
||||||
|
? fieldAttributes.getAnnotation(ServerOnly.class) != null
|
||||||
|
: fieldAttributes.getAnnotation(ClientOnly.class) != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package io.gitlab.jfronny.libjf.gson;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface ServerOnly {
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
package io.gitlab.jfronny.libjf.config.api;
|
package io.gitlab.jfronny.libjf.config.api;
|
||||||
|
|
||||||
import io.gitlab.jfronny.gson.JsonObject;
|
import io.gitlab.jfronny.gson.JsonObject;
|
||||||
|
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
||||||
import io.gitlab.jfronny.libjf.config.impl.EntryInfo;
|
import io.gitlab.jfronny.libjf.config.impl.EntryInfo;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -15,15 +18,16 @@ public interface ConfigInstance {
|
||||||
}
|
}
|
||||||
void load();
|
void load();
|
||||||
void write();
|
void write();
|
||||||
void loadObject(JsonObject source);
|
|
||||||
JsonObject writeObject();
|
|
||||||
void syncToClass();
|
|
||||||
void syncFromClass();
|
|
||||||
String getModId();
|
String getModId();
|
||||||
boolean matchesConfigClass(Class<?> candidate);
|
|
||||||
List<EntryInfo> getEntries();
|
List<EntryInfo> getEntries();
|
||||||
Map<String, Runnable> getPresets();
|
Map<String, Runnable> getPresets();
|
||||||
List<String> getReferencedConfigs();
|
List<String> getReferencedConfigs();
|
||||||
Map<String, ConfigInstance> getCategories();
|
Map<String, ConfigInstance> getCategories();
|
||||||
String getCategoryPath();
|
|
||||||
|
@ApiStatus.Internal void syncToClass();
|
||||||
|
@ApiStatus.Internal void syncFromClass();
|
||||||
|
@ApiStatus.Internal boolean matchesConfigClass(Class<?> candidate);
|
||||||
|
@ApiStatus.Internal void loadFrom(JsonObject source);
|
||||||
|
@ApiStatus.Internal void writeTo(JsonWriter writer) throws IOException;
|
||||||
|
@ApiStatus.Internal String getCategoryPath();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package io.gitlab.jfronny.libjf.config.impl;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import io.gitlab.jfronny.gson.Gson;
|
import io.gitlab.jfronny.gson.Gson;
|
||||||
|
import io.gitlab.jfronny.gson.GsonBuilder;
|
||||||
import io.gitlab.jfronny.libjf.LibJf;
|
import io.gitlab.jfronny.libjf.LibJf;
|
||||||
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
||||||
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
import io.gitlab.jfronny.libjf.config.api.ConfigInstance;
|
||||||
|
import io.gitlab.jfronny.libjf.gson.HiddenAnnotationExclusionStrategy;
|
||||||
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
|
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.fabricmc.loader.api.ModContainer;
|
import net.fabricmc.loader.api.ModContainer;
|
||||||
|
@ -12,6 +14,7 @@ import net.fabricmc.loader.api.metadata.CustomValue;
|
||||||
import net.fabricmc.loader.impl.util.log.Log;
|
import net.fabricmc.loader.impl.util.log.Log;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -23,7 +26,12 @@ public class ConfigHolderImpl implements ConfigHolder {
|
||||||
private ConfigHolderImpl() {
|
private ConfigHolderImpl() {
|
||||||
}
|
}
|
||||||
public static final String MODULE_ID = LibJf.MOD_ID + ":config";
|
public static final String MODULE_ID = LibJf.MOD_ID + ":config";
|
||||||
public static final Gson GSON = new Gson();
|
public static Gson GSON = new GsonBuilder()
|
||||||
|
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
|
||||||
|
.excludeFieldsWithModifiers(Modifier.PRIVATE)
|
||||||
|
.addSerializationExclusionStrategy(new HiddenAnnotationExclusionStrategy())
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.create();
|
||||||
private final Map<String, ConfigInstance> configs = new HashMap<>();
|
private final Map<String, ConfigInstance> configs = new HashMap<>();
|
||||||
private final Map<Path, ConfigInstance> configsByPath = new HashMap<>();
|
private final Map<Path, ConfigInstance> configsByPath = new HashMap<>();
|
||||||
|
|
||||||
|
|
|
@ -2,23 +2,24 @@ package io.gitlab.jfronny.libjf.config.impl;
|
||||||
|
|
||||||
import io.gitlab.jfronny.gson.JsonElement;
|
import io.gitlab.jfronny.gson.JsonElement;
|
||||||
import io.gitlab.jfronny.gson.JsonObject;
|
import io.gitlab.jfronny.gson.JsonObject;
|
||||||
|
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
||||||
import io.gitlab.jfronny.libjf.config.api.*;
|
import io.gitlab.jfronny.libjf.config.api.*;
|
||||||
import io.gitlab.jfronny.libjf.generic.Try;
|
import io.gitlab.jfronny.libjf.config.impl.entrypoint.JfConfigSafe;
|
||||||
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
|
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
|
||||||
import net.fabricmc.loader.impl.util.log.Log;
|
import net.fabricmc.loader.impl.util.log.Log;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class ConfigInstanceAbstract implements ConfigInstance {
|
public abstract class ConfigInstanceAbstract implements ConfigInstance {
|
||||||
public static final String CONFIG_PRESET_DEFAULT = "libjf-config-v0.default";
|
public static final String CONFIG_PRESET_DEFAULT = "libjf-config-v0.default";
|
||||||
public final String modId;
|
public final String modId;
|
||||||
private final String categoryPath;
|
private final String categoryPath;
|
||||||
public final Class<?> configClass;
|
public final Class<?> configClass;
|
||||||
private final Constructor<?> configConstructor;
|
|
||||||
public final List<String> referencedConfigs;
|
public final List<String> referencedConfigs;
|
||||||
public final List<EntryInfo> entries = new ArrayList<>();
|
public final List<EntryInfo> entries = new ArrayList<>();
|
||||||
public final Map<String, Runnable> presets = new LinkedHashMap<>();
|
public final Map<String, Runnable> presets = new LinkedHashMap<>();
|
||||||
|
@ -28,10 +29,6 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
|
||||||
this.modId = modId;
|
this.modId = modId;
|
||||||
this.categoryPath = categoryPath;
|
this.categoryPath = categoryPath;
|
||||||
this.configClass = configClass;
|
this.configClass = configClass;
|
||||||
this.configConstructor = Try.orElse(configClass::getDeclaredConstructor, e -> {
|
|
||||||
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not get constructor for config class of " + modId + ", saving will be unavailable", e);
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
this.referencedConfigs = List.copyOf(meta.referencedConfigs);
|
this.referencedConfigs = List.copyOf(meta.referencedConfigs);
|
||||||
for (Field field : configClass.getFields()) {
|
for (Field field : configClass.getFields()) {
|
||||||
EntryInfo info = new EntryInfo();
|
EntryInfo info = new EntryInfo();
|
||||||
|
@ -120,32 +117,43 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadObject(JsonObject source) {
|
public void loadFrom(JsonObject source) {
|
||||||
ConfigHolderImpl.GSON.fromJson(source, configClass);
|
for (EntryInfo entry : entries) {
|
||||||
|
if (source.has(entry.field.getName())) {
|
||||||
|
JsonElement el = source.get(entry.field.getName());
|
||||||
|
entry.value = ConfigHolderImpl.GSON.fromJson(el, entry.field.getGenericType());
|
||||||
|
} else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Config does not contain entry for " + entry.field.getName());
|
||||||
|
}
|
||||||
for (Map.Entry<String, ConfigInstance> entry : subcategories.entrySet()) {
|
for (Map.Entry<String, ConfigInstance> entry : subcategories.entrySet()) {
|
||||||
if (source.has(entry.getKey())) {
|
if (source.has(entry.getKey())) {
|
||||||
JsonElement el = source.get(entry.getKey());
|
JsonElement el = source.get(entry.getKey());
|
||||||
if (el.isJsonObject()) entry.getValue().loadObject(el.getAsJsonObject());
|
if (el.isJsonObject()) entry.getValue().loadFrom(el.getAsJsonObject());
|
||||||
else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Config category is not a JSON object, skipping");
|
else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Config category is not a JSON object, skipping");
|
||||||
}
|
} else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Config does not contain entry for subcategory " + entry.getKey());
|
||||||
}
|
}
|
||||||
|
syncToClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonObject writeObject() {
|
public void writeTo(JsonWriter writer) throws IOException {
|
||||||
try {
|
syncFromClass();
|
||||||
if (configConstructor == null) {
|
writer.beginObject();
|
||||||
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not save config of " + modId + " due to a missing constructor");
|
String val;
|
||||||
return new JsonObject();
|
for (EntryInfo entry : entries) {
|
||||||
}
|
if ((val = JfConfigSafe.TRANSLATION_SUPPLIER.apply(modId + ".jfconfig." + categoryPath + entry.field.getName() + ".tooltip")) != null)
|
||||||
JsonObject jo = ConfigHolderImpl.GSON.toJsonTree(configConstructor.newInstance()).getAsJsonObject();
|
writer.comment(val);
|
||||||
for (Map.Entry<String, ConfigInstance> entry : subcategories.entrySet()) {
|
if (entry.field.getType().isEnum())
|
||||||
jo.add(entry.getKey(), entry.getValue().writeObject());
|
writer.comment("Valid: [" + Arrays.stream(entry.field.getType().getEnumConstants()).map(Objects::toString).collect(Collectors.joining(", ")) + "]");
|
||||||
}
|
writer.name(entry.field.getName());
|
||||||
return jo;
|
ConfigHolderImpl.GSON.toJson(entry.value, entry.field.getGenericType(), writer);
|
||||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
throw new RuntimeException("Could not access constructor needed to generate config JSON", e);
|
|
||||||
}
|
}
|
||||||
|
for (Map.Entry<String, ConfigInstance> entry : subcategories.entrySet()) {
|
||||||
|
if ((val = JfConfigSafe.TRANSLATION_SUPPLIER.apply(modId + ".jfconfig." + categoryPath + entry.getKey() + ".title")) != null)
|
||||||
|
writer.comment(val);
|
||||||
|
writer.name(entry.getKey());
|
||||||
|
entry.getValue().writeTo(writer);
|
||||||
|
}
|
||||||
|
writer.endObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,9 +166,6 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syncFromClass();
|
syncFromClass();
|
||||||
for (ConfigInstance instance : subcategories.values()) {
|
|
||||||
instance.syncToClass();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,9 +182,6 @@ public abstract class ConfigInstanceAbstract implements ConfigInstance {
|
||||||
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not read value", e);
|
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not read value", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ConfigInstance instance : subcategories.values()) {
|
|
||||||
instance.syncFromClass();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,6 +2,7 @@ package io.gitlab.jfronny.libjf.config.impl;
|
||||||
|
|
||||||
import io.gitlab.jfronny.gson.JsonElement;
|
import io.gitlab.jfronny.gson.JsonElement;
|
||||||
import io.gitlab.jfronny.gson.JsonParser;
|
import io.gitlab.jfronny.gson.JsonParser;
|
||||||
|
import io.gitlab.jfronny.gson.stream.JsonWriter;
|
||||||
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
|
import io.gitlab.jfronny.libjf.unsafe.JfLanguageAdapter;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.fabricmc.loader.impl.util.log.Log;
|
import net.fabricmc.loader.impl.util.log.Log;
|
||||||
|
@ -27,22 +28,22 @@ public class ConfigInstanceRoot extends ConfigInstanceAbstract {
|
||||||
if (Files.exists(path)) {
|
if (Files.exists(path)) {
|
||||||
try (BufferedReader br = Files.newBufferedReader(path)) {
|
try (BufferedReader br = Files.newBufferedReader(path)) {
|
||||||
JsonElement element = JsonParser.parseReader(br);
|
JsonElement element = JsonParser.parseReader(br);
|
||||||
if (element.isJsonObject()) loadObject(element.getAsJsonObject());
|
if (element.isJsonObject()) loadFrom(element.getAsJsonObject());
|
||||||
else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Invalid config: Not a JSON object for " + modId);
|
else Log.error(JfLanguageAdapter.LOG_CATEGORY, "Invalid config: Not a JSON object for " + modId);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not read config for " + modId, e);
|
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not read config for " + modId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
syncFromClass();
|
|
||||||
write();
|
write();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write() {
|
public void write() {
|
||||||
JfConfigWatchService.lock(path, () -> {
|
JfConfigWatchService.lock(path, () -> {
|
||||||
try (BufferedWriter bw = Files.newBufferedWriter(path)) {
|
try (BufferedWriter bw = Files.newBufferedWriter(path);
|
||||||
ConfigHolderImpl.GSON.toJson(writeObject(), bw);
|
JsonWriter jw = ConfigHolderImpl.GSON.newJsonWriter(bw)) {
|
||||||
|
writeTo(jw);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not write config", e);
|
Log.error(JfLanguageAdapter.LOG_CATEGORY, "Could not write config", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package io.gitlab.jfronny.libjf.config.impl.entrypoint;
|
package io.gitlab.jfronny.libjf.config.impl.entrypoint;
|
||||||
|
|
||||||
|
import io.gitlab.jfronny.libjf.LibJf;
|
||||||
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
import io.gitlab.jfronny.libjf.config.api.ConfigHolder;
|
||||||
import io.gitlab.jfronny.libjf.config.api.JfConfig;
|
import io.gitlab.jfronny.libjf.config.api.JfConfig;
|
||||||
import io.gitlab.jfronny.libjf.config.impl.ConfigHolderImpl;
|
import io.gitlab.jfronny.libjf.config.impl.ConfigHolderImpl;
|
||||||
|
@ -8,13 +9,22 @@ import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.fabricmc.loader.api.entrypoint.EntrypointContainer;
|
import net.fabricmc.loader.api.entrypoint.EntrypointContainer;
|
||||||
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
||||||
import net.fabricmc.loader.impl.util.log.Log;
|
import net.fabricmc.loader.impl.util.log.Log;
|
||||||
|
import net.minecraft.util.Language;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class JfConfigSafe implements PreLaunchEntrypoint {
|
public class JfConfigSafe implements PreLaunchEntrypoint {
|
||||||
|
public static Function<String, String> TRANSLATION_SUPPLIER = s -> null;
|
||||||
@Override
|
@Override
|
||||||
public void onPreLaunch() {
|
public void onPreLaunch() {
|
||||||
for (EntrypointContainer<JfConfig> config : FabricLoader.getInstance().getEntrypointContainers(ConfigHolderImpl.MODULE_ID, JfConfig.class)) {
|
for (EntrypointContainer<JfConfig> config : FabricLoader.getInstance().getEntrypointContainers(ConfigHolderImpl.MODULE_ID, JfConfig.class)) {
|
||||||
registerIfMissing(config.getProvider().getMetadata().getId(), config.getEntrypoint().getClass());
|
registerIfMissing(config.getProvider().getMetadata().getId(), config.getEntrypoint().getClass());
|
||||||
}
|
}
|
||||||
|
TRANSLATION_SUPPLIER = s -> {
|
||||||
|
String translated = Language.getInstance().get(s);
|
||||||
|
return translated.equals(s) ? null : translated;
|
||||||
|
};
|
||||||
|
ConfigHolderImpl.GSON = LibJf.GSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerIfMissing(String modId, Class<?> klazz) {
|
public static void registerIfMissing(String modId, Class<?> klazz) {
|
||||||
|
|
Loading…
Reference in New Issue