Use cloth lite and proguard
This commit is contained in:
parent
fdcdb6d9fa
commit
71dd92703e
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@
|
||||
*.iws
|
||||
|
||||
# IntelliJ
|
||||
out.map
|
||||
out/
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
57
build.gradle
57
build.gradle
@ -1,3 +1,20 @@
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.json.JsonSlurper
|
||||
import proguard.gradle.ProGuardTask
|
||||
import net.fabricmc.loom.task.RunClientTask
|
||||
import net.fabricmc.loom.task.RunServerTask
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
google()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.guardsquare:proguard-gradle:7.0.1'
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'fabric-loom' version '0.7-SNAPSHOT'
|
||||
id 'maven-publish'
|
||||
@ -12,6 +29,22 @@ group = project.maven_group
|
||||
|
||||
repositories {
|
||||
maven { url = 'https://maven.terraformersmc.com/'; name = "ModMenu" }
|
||||
maven { url "https://maven.shedaniel.me/" }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
testmod {
|
||||
compileClasspath += main.compileClasspath + main.output
|
||||
runtimeClasspath += main.runtimeClasspath + main.output
|
||||
}
|
||||
}
|
||||
|
||||
task runTestmodClient(type: RunClientTask) {
|
||||
classpath sourceSets.testmod.runtimeClasspath
|
||||
}
|
||||
|
||||
task runTestmodServer(type: RunServerTask) {
|
||||
classpath sourceSets.testmod.runtimeClasspath
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@ -24,6 +57,7 @@ dependencies {
|
||||
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
||||
// You may need to force-disable transitiveness on them.
|
||||
modImplementation "com.terraformersmc:modmenu:1.16.9"
|
||||
include modImplementation("me.shedaniel.cloth:cloth-config-lite-fabric:1.0.4")
|
||||
}
|
||||
|
||||
processResources {
|
||||
@ -37,6 +71,29 @@ processResources {
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude "fabric.mod.json"
|
||||
}
|
||||
|
||||
doLast {
|
||||
fileTree(dir: outputs.files.asPath, include: "**/*.json").each {
|
||||
File file -> file.text = JsonOutput.toJson(new JsonSlurper().parse(file))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def proguardJarOut = file(jar.archiveFile.get().getAsFile().absolutePath.replace(".jar", "-min.jar"))
|
||||
|
||||
task proguardJar(type: ProGuardTask, dependsOn: jar) {
|
||||
configuration './proguard.conf'
|
||||
verbose
|
||||
injars jar.archiveFile.get().getAsFile()
|
||||
outjars proguardJarOut
|
||||
libraryjars files(configurations.compileClasspath)
|
||||
printmapping 'out.map'
|
||||
}
|
||||
|
||||
tasks.remapJar {
|
||||
input.set proguardJarOut
|
||||
archiveClassifier.set null
|
||||
dependsOn proguardJar
|
||||
}
|
||||
|
||||
// ensure that the encoding is set to UTF-8, no matter what the system default is
|
||||
|
11
proguard.conf
Normal file
11
proguard.conf
Normal file
@ -0,0 +1,11 @@
|
||||
-libraryjars <java.home>/jmods/java.base.jmod(!**.jar;!module-info.class)
|
||||
-keep public class io.gitlab.jfronny.libjf.config.JfConfig {
|
||||
public protected *;
|
||||
}
|
||||
-keep public class io.gitlab.jfronny.libjf.Libjf
|
||||
-keep public class io.gitlab.jfronny.libjf.config.ModMenu
|
||||
-repackageclasses 'jf.lib'
|
||||
-allowaccessmodification
|
||||
-overloadaggressively
|
||||
-optimizationpasses 5
|
||||
-optimizations '*'
|
@ -1,36 +0,0 @@
|
||||
package io.gitlab.jfronny.libjf;
|
||||
|
||||
import io.gitlab.jfronny.libjf.config.Entry;
|
||||
import io.gitlab.jfronny.libjf.config.EntryInfo;
|
||||
import io.gitlab.jfronny.libjf.config.JfConfig;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/*from https://github.com/Minenash/TinyConfig*/
|
||||
public class ExampleConfig implements JfConfig {
|
||||
@Entry
|
||||
public static boolean boolTest = false;
|
||||
|
||||
@Entry(min = 5)
|
||||
public static int intTest = 20;
|
||||
|
||||
@Entry
|
||||
public static double decimalTest = 20;
|
||||
|
||||
@Entry(dynamicTooltip = "dieStrTooltip", max = 5)
|
||||
public static String dieStr = "lolz";
|
||||
|
||||
@Entry
|
||||
public static Test enumTest = Test.Test;
|
||||
|
||||
private static List<Text> dieStrTooltip(List<EntryInfo> infos) {
|
||||
return Collections.singletonList(new LiteralText("safbjkasf"));
|
||||
}
|
||||
|
||||
public enum Test {
|
||||
Test, ER
|
||||
}
|
||||
}
|
@ -27,7 +27,6 @@ public class Libjf implements PreLaunchEntrypoint {
|
||||
|
||||
@Override
|
||||
public void onPreLaunch() {
|
||||
registerConfig(MOD_ID, ExampleConfig.class);
|
||||
for (EntrypointContainer<JfConfig> entrypointContainer : FabricLoader.getInstance().getEntrypointContainers(MOD_ID + ":config", JfConfig.class)) {
|
||||
String id = entrypointContainer.getProvider().getMetadata().getId();
|
||||
Libjf.registerConfig(id, entrypointContainer.getEntrypoint().getClass());
|
||||
|
@ -2,30 +2,14 @@ package io.gitlab.jfronny.libjf.config;
|
||||
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.*;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/* Based on https://github.com/TeamMidnightDust/MidnightLib
|
||||
* see https://github.com/TeamMidnightDust/MidnightLib/blob/main/LICENSE
|
||||
*/
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class Config {
|
||||
private static final Pattern INTEGER_ONLY = Pattern.compile("(-?[0-9]*)");
|
||||
private static final Pattern DECIMAL_ONLY = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
|
||||
|
||||
public Class configClass;
|
||||
public Class<?> configClass;
|
||||
public String translationPrefix;
|
||||
public Path path;
|
||||
public final List<EntryInfo> entries = new ArrayList<>();
|
||||
@ -36,49 +20,13 @@ public class Config {
|
||||
configClass = config;
|
||||
|
||||
for (Field field : config.getFields()) {
|
||||
Class<?> type = field.getType();
|
||||
EntryInfo info = new EntryInfo();
|
||||
|
||||
Entry e;
|
||||
try { e = field.getAnnotation(Entry.class); }
|
||||
catch (Exception ignored) { continue; }
|
||||
|
||||
info.width = e.width();
|
||||
info.field = field;
|
||||
|
||||
if (type == int.class) textField(info, Integer::parseInt, INTEGER_ONLY, e.min(), e.max(), true);
|
||||
else if (type == double.class) textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(),false);
|
||||
else if (type == float.class) textField(info, Float::parseFloat, DECIMAL_ONLY, e.min(), e.max(),false);
|
||||
else if (type == String.class) textField(info, String::length, null, Math.min(e.min(),0), Math.max(e.max(),1),true);
|
||||
else if (type == boolean.class) {
|
||||
Function<Object,Text> func = value -> new LiteralText((Boolean) value ? "True" : "False").formatted((Boolean) value ? Formatting.GREEN : Formatting.RED);
|
||||
info.widget = new AbstractMap.SimpleEntry<ButtonWidget.PressAction, Function<Object, Text>>(button -> {
|
||||
info.value = !(Boolean) info.value;
|
||||
button.setMessage(func.apply(info.value));
|
||||
}, func);
|
||||
}
|
||||
else if (type.isEnum()) {
|
||||
List<?> values = Arrays.asList(field.getType().getEnumConstants());
|
||||
Function<Object,Text> func = value -> new TranslatableText(translationPrefix + "enum." + type.getSimpleName() + "." + info.value.toString());
|
||||
info.widget = new AbstractMap.SimpleEntry<ButtonWidget.PressAction, Function<Object,Text>>( button -> {
|
||||
int index = values.indexOf(info.value) + 1;
|
||||
info.value = values.get(index >= values.size()? 0 : index);
|
||||
button.setMessage(func.apply(info.value));
|
||||
}, func);
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
entries.add(info);
|
||||
|
||||
try { info.defaultValue = field.get(null); }
|
||||
catch (IllegalAccessException ignored) {}
|
||||
|
||||
try {
|
||||
info.dynamicTooltip = config.getMethod(e.dynamicTooltip());
|
||||
info.dynamicTooltip.setAccessible(true);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
}
|
||||
|
||||
try { Libjf.GSON.fromJson(Files.newBufferedReader(path), config); }
|
||||
@ -87,48 +35,15 @@ public class Config {
|
||||
for (EntryInfo info : entries) {
|
||||
try {
|
||||
info.value = info.field.get(null);
|
||||
info.tempValue = info.value.toString();
|
||||
}
|
||||
catch (IllegalAccessException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void textField(EntryInfo info, Function<String,Number> f, Pattern pattern, double min, double max, boolean cast) {
|
||||
boolean isNumber = pattern != null;
|
||||
info.widget = (BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) (t, b) -> s -> {
|
||||
s = s.trim();
|
||||
if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches()))
|
||||
return false;
|
||||
|
||||
Number value = 0;
|
||||
boolean inLimits = false;
|
||||
System.out.println(((isNumber ^ s.isEmpty())));
|
||||
System.out.println(!s.equals("-") && !s.equals("."));
|
||||
info.error = null;
|
||||
if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) {
|
||||
value = f.apply(s);
|
||||
inLimits = value.doubleValue() >= min && value.doubleValue() <= max;
|
||||
info.error = inLimits? null : new AbstractMap.SimpleEntry<>(t, new LiteralText(value.doubleValue() < min ?
|
||||
"§cMinimum " + (isNumber? "value" : "length") + (cast? " is " + (int)min : " is " + min) :
|
||||
"§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max)));
|
||||
}
|
||||
|
||||
info.tempValue = s;
|
||||
t.setEditableColor(inLimits? 0xFFFFFFFF : 0xFFFF7777);
|
||||
info.inLimits = inLimits;
|
||||
b.active = entries.stream().allMatch(e -> e.inLimits);
|
||||
|
||||
if (inLimits)
|
||||
info.value = isNumber? value : s;
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
public void write() {
|
||||
try {
|
||||
if (!Files.exists(path)) Files.createFile(path);
|
||||
Files.write(path, Libjf.GSON.toJson(configClass.newInstance()).getBytes());
|
||||
Files.write(path, Libjf.GSON.toJson(configClass.getDeclaredConstructor().newInstance()).getBytes());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -1,132 +0,0 @@
|
||||
package io.gitlab.jfronny.libjf.config;
|
||||
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.ScreenTexts;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.resource.language.I18n;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ConfigScreen extends Screen {
|
||||
public ConfigScreen(Screen parent, Config config) {
|
||||
super(new TranslatableText(config.translationPrefix + "title"));
|
||||
this.parent = parent;
|
||||
this.config = config;
|
||||
}
|
||||
private final Screen parent;
|
||||
private final Config config;
|
||||
|
||||
// Real Time config update //
|
||||
@Override
|
||||
public void tick() {
|
||||
for (EntryInfo info : config.entries)
|
||||
try { info.field.set(null, info.value); }
|
||||
catch (IllegalAccessException ignore) {}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
this.addButton(new ButtonWidget(this.width / 2 - 154, this.height - 28, 150, 20, ScreenTexts.CANCEL, button -> {
|
||||
try { Libjf.GSON.fromJson(Files.newBufferedReader(config.path), config.configClass); }
|
||||
catch (Exception e) { config.write(); }
|
||||
|
||||
for (EntryInfo info : config.entries) {
|
||||
try {
|
||||
info.value = info.field.get(null);
|
||||
info.tempValue = info.value.toString();
|
||||
}
|
||||
catch (IllegalAccessException ignored) {}
|
||||
}
|
||||
Objects.requireNonNull(client).openScreen(parent);
|
||||
}));
|
||||
|
||||
ButtonWidget done = this.addButton(new ButtonWidget(this.width / 2 + 4, this.height - 28, 150, 20, ScreenTexts.DONE, (button) -> {
|
||||
for (EntryInfo info : config.entries)
|
||||
try { info.field.set(null, info.value); }
|
||||
catch (IllegalAccessException ignore) {}
|
||||
config.write();
|
||||
Objects.requireNonNull(client).openScreen(parent);
|
||||
}));
|
||||
|
||||
int y = 45;
|
||||
for (EntryInfo info : config.entries) {
|
||||
addButton(new ButtonWidget(width - 155, y, 40,20, new LiteralText("Reset").formatted(Formatting.RED), (button -> {
|
||||
info.value = info.defaultValue;
|
||||
info.tempValue = info.value.toString();
|
||||
Objects.requireNonNull(client).openScreen(this);
|
||||
})));
|
||||
|
||||
if (info.widget instanceof Map.Entry) {
|
||||
Map.Entry<ButtonWidget.PressAction, Function<Object,Text>> widget = (Map.Entry<ButtonWidget.PressAction, Function<Object, Text>>) info.widget;
|
||||
addButton(new ButtonWidget(width-110,y,info.width,20, widget.getValue().apply(info.value), widget.getKey()));
|
||||
}
|
||||
else {
|
||||
TextFieldWidget widget = addButton(new TextFieldWidget(textRenderer, width-110, y, info.width, 20, null));
|
||||
widget.setText(info.tempValue);
|
||||
|
||||
Predicate<String> processor = ((BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) info.widget).apply(widget,done);
|
||||
widget.setTextPredicate(processor);
|
||||
|
||||
children.add(widget);
|
||||
}
|
||||
y += 25;
|
||||
}
|
||||
|
||||
}
|
||||
int aniX = this.width / 2;
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
this.renderBackground(matrices);
|
||||
|
||||
if (aniX < this.width / 2) {
|
||||
aniX = aniX +40;
|
||||
}
|
||||
|
||||
int stringWidth = (int) (title.getString().length() * 2.75f);
|
||||
this.fillGradient(matrices, this.width / 2 - stringWidth, 10, this.width /2 + stringWidth, 29, -1072689136, -804253680);
|
||||
this.fillGradient(matrices, this.width / 2 - aniX, 35, width/2 + aniX, this.height - 40, -1072689136, -804253680);
|
||||
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
drawCenteredText(matrices, textRenderer, title, width/2, 15, 0xFFFFFF);
|
||||
|
||||
int y = 40;
|
||||
for (EntryInfo info : config.entries) {
|
||||
drawTextWithShadow(matrices, textRenderer, new TranslatableText(config.translationPrefix + info.field.getName()), 12, y + 10, 0xFFFFFF);
|
||||
|
||||
if (info.error != null && info.error.getKey().isMouseOver(mouseX,mouseY))
|
||||
renderTooltip(matrices, info.error.getValue(), mouseX, mouseY);
|
||||
else if (mouseY >= y && mouseY < (y + 25)) {
|
||||
if (info.dynamicTooltip != null) {
|
||||
try {
|
||||
renderTooltip(matrices, (List<Text>) info.dynamicTooltip.invoke(null, config.entries), mouseX, mouseY);
|
||||
y += 25;
|
||||
continue;
|
||||
} catch (Exception e) { e.printStackTrace(); }
|
||||
}
|
||||
String key = config.translationPrefix + info.field.getName() + ".tooltip";
|
||||
if (I18n.hasTranslation(key)) {
|
||||
List<Text> list = new ArrayList<>();
|
||||
for (String str : I18n.translate(key).split("\n"))
|
||||
list.add(new LiteralText(str));
|
||||
renderTooltip(matrices, list, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
y += 25;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package io.gitlab.jfronny.libjf.config;
|
||||
|
||||
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 Entry {
|
||||
String dynamicTooltip() default "";
|
||||
int width() default 100;
|
||||
double min() default Double.MIN_NORMAL;
|
||||
double max() default Double.MAX_VALUE;
|
||||
}
|
@ -1,20 +1,9 @@
|
||||
package io.gitlab.jfronny.libjf.config;
|
||||
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class EntryInfo {
|
||||
Field field;
|
||||
Object widget;
|
||||
int width;
|
||||
Method dynamicTooltip;
|
||||
Map.Entry<TextFieldWidget, Text> error;
|
||||
Object defaultValue;
|
||||
Object value;
|
||||
String tempValue;
|
||||
boolean inLimits = true;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package io.gitlab.jfronny.libjf.config;
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
import io.gitlab.jfronny.libjf.Libjf;
|
||||
import me.shedaniel.clothconfiglite.api.ConfigScreen;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -13,18 +15,22 @@ public class ModMenu implements ModMenuApi {
|
||||
Map<String, ConfigScreenFactory<?>> factories = new HashMap<>();
|
||||
for (Map.Entry<String, Config> entry : Libjf.getConfigs().entrySet()) {
|
||||
if (!Libjf.MOD_ID.equals(entry.getKey()))
|
||||
factories.put(entry.getKey(), s -> new ConfigScreen(s, entry.getValue()));
|
||||
factories.put(entry.getKey(), buildFactory(entry.getValue()));
|
||||
}
|
||||
return factories;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
for (Map.Entry<String, Config> entry : Libjf.getConfigs().entrySet()) {
|
||||
if (Libjf.MOD_ID.equals(entry.getKey()))
|
||||
return s -> new ConfigScreen(s, entry.getValue());
|
||||
private static ConfigScreenFactory<?> buildFactory(Config config) {
|
||||
return s -> {
|
||||
ConfigScreen c = ConfigScreen.create(new TranslatableText(config.translationPrefix + "title"), s);
|
||||
for (EntryInfo entry : config.entries) {
|
||||
c.add(new TranslatableText(config.translationPrefix + entry.field.getName()),
|
||||
entry.value, () -> entry.defaultValue, v -> {
|
||||
entry.value = v;
|
||||
config.write();
|
||||
});
|
||||
}
|
||||
new Exception("Could not find own config screen, this is bad").printStackTrace();
|
||||
return null;
|
||||
return c.get();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
{
|
||||
"libjf.jfconfig.title": "JfConfig example",
|
||||
"libjf.jfconfig.boolTest": "Bool Test",
|
||||
"libjf.jfconfig.intTest": "Int Test",
|
||||
"libjf.jfconfig.decimalTest": "Decimal Test",
|
||||
"libjf.jfconfig.dieStr": "String Test",
|
||||
"libjf.jfconfig.enumTest": "Enum Test",
|
||||
"libjf.jfconfig.enum.Test.Test": "Test",
|
||||
"libjf.jfconfig.enum.Test.ER": "ER"
|
||||
}
|
@ -20,9 +20,6 @@
|
||||
],
|
||||
"modmenu": [
|
||||
"io.gitlab.jfronny.libjf.config.ModMenu"
|
||||
],
|
||||
"libjf:config": [
|
||||
"io.gitlab.jfronny.libjf.ExampleConfig"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
@ -31,5 +28,10 @@
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.3",
|
||||
"minecraft": "1.16.5"
|
||||
},
|
||||
"custom": {
|
||||
"modmenu": {
|
||||
"badges": ["library"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
15
src/testmod/java/io/gitlab/jfronny/libjf/test/TestMod.java
Normal file
15
src/testmod/java/io/gitlab/jfronny/libjf/test/TestMod.java
Normal file
@ -0,0 +1,15 @@
|
||||
package io.gitlab.jfronny.libjf.test;
|
||||
|
||||
import io.gitlab.jfronny.libjf.config.JfConfig;
|
||||
|
||||
public class TestMod implements JfConfig {
|
||||
public static boolean boolTest = false;
|
||||
public static int intTest = 20;
|
||||
public static double decimalTest = 20;
|
||||
public static String dieStr = "lolz";
|
||||
public static Test enumTest = Test.Test;
|
||||
|
||||
public enum Test {
|
||||
Test, ER
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
"libjf-testmod.jfconfig.title": "JfConfig example",
|
||||
"libjf-testmod.jfconfig.boolTest": "Bool Test",
|
||||
"libjf-testmod.jfconfig.intTest": "Int Test",
|
||||
"libjf-testmod.jfconfig.decimalTest": "Decimal Test",
|
||||
"libjf-testmod.jfconfig.dieStr": "String Test",
|
||||
"libjf-testmod.jfconfig.enumTest": "Enum Test"
|
||||
}
|
11
src/testmod/resources/fabric.mod.json
Normal file
11
src/testmod/resources/fabric.mod.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "libjf-testmod",
|
||||
"version": "${version}",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"libjf:config": [
|
||||
"io.gitlab.jfronny.libjf.test.TestMod"
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user