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
|
*.iws
|
||||||
|
|
||||||
# IntelliJ
|
# IntelliJ
|
||||||
|
out.map
|
||||||
out/
|
out/
|
||||||
# mpeltonen/sbt-idea plugin
|
# mpeltonen/sbt-idea plugin
|
||||||
.idea_modules/
|
.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 {
|
plugins {
|
||||||
id 'fabric-loom' version '0.7-SNAPSHOT'
|
id 'fabric-loom' version '0.7-SNAPSHOT'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
|
@ -12,6 +29,22 @@ group = project.maven_group
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven { url = 'https://maven.terraformersmc.com/'; name = "ModMenu" }
|
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 {
|
dependencies {
|
||||||
|
@ -24,6 +57,7 @@ dependencies {
|
||||||
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
||||||
// You may need to force-disable transitiveness on them.
|
// You may need to force-disable transitiveness on them.
|
||||||
modImplementation "com.terraformersmc:modmenu:1.16.9"
|
modImplementation "com.terraformersmc:modmenu:1.16.9"
|
||||||
|
include modImplementation("me.shedaniel.cloth:cloth-config-lite-fabric:1.0.4")
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@ -37,6 +71,29 @@ processResources {
|
||||||
from(sourceSets.main.resources.srcDirs) {
|
from(sourceSets.main.resources.srcDirs) {
|
||||||
exclude "fabric.mod.json"
|
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
|
// 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
|
@Override
|
||||||
public void onPreLaunch() {
|
public void onPreLaunch() {
|
||||||
registerConfig(MOD_ID, ExampleConfig.class);
|
|
||||||
for (EntrypointContainer<JfConfig> entrypointContainer : FabricLoader.getInstance().getEntrypointContainers(MOD_ID + ":config", JfConfig.class)) {
|
for (EntrypointContainer<JfConfig> entrypointContainer : FabricLoader.getInstance().getEntrypointContainers(MOD_ID + ":config", JfConfig.class)) {
|
||||||
String id = entrypointContainer.getProvider().getMetadata().getId();
|
String id = entrypointContainer.getProvider().getMetadata().getId();
|
||||||
Libjf.registerConfig(id, entrypointContainer.getEntrypoint().getClass());
|
Libjf.registerConfig(id, entrypointContainer.getEntrypoint().getClass());
|
||||||
|
|
|
@ -2,30 +2,14 @@ package io.gitlab.jfronny.libjf.config;
|
||||||
|
|
||||||
import io.gitlab.jfronny.libjf.Libjf;
|
import io.gitlab.jfronny.libjf.Libjf;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
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.lang.reflect.Field;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.*;
|
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 {
|
public class Config {
|
||||||
private static final Pattern INTEGER_ONLY = Pattern.compile("(-?[0-9]*)");
|
public Class<?> configClass;
|
||||||
private static final Pattern DECIMAL_ONLY = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
|
|
||||||
|
|
||||||
public Class configClass;
|
|
||||||
public String translationPrefix;
|
public String translationPrefix;
|
||||||
public Path path;
|
public Path path;
|
||||||
public final List<EntryInfo> entries = new ArrayList<>();
|
public final List<EntryInfo> entries = new ArrayList<>();
|
||||||
|
@ -36,49 +20,13 @@ public class Config {
|
||||||
configClass = config;
|
configClass = config;
|
||||||
|
|
||||||
for (Field field : config.getFields()) {
|
for (Field field : config.getFields()) {
|
||||||
Class<?> type = field.getType();
|
|
||||||
EntryInfo info = new EntryInfo();
|
EntryInfo info = new EntryInfo();
|
||||||
|
|
||||||
Entry e;
|
|
||||||
try { e = field.getAnnotation(Entry.class); }
|
|
||||||
catch (Exception ignored) { continue; }
|
|
||||||
|
|
||||||
info.width = e.width();
|
|
||||||
info.field = field;
|
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);
|
entries.add(info);
|
||||||
|
|
||||||
try { info.defaultValue = field.get(null); }
|
try { info.defaultValue = field.get(null); }
|
||||||
catch (IllegalAccessException ignored) {}
|
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); }
|
try { Libjf.GSON.fromJson(Files.newBufferedReader(path), config); }
|
||||||
|
@ -87,48 +35,15 @@ public class Config {
|
||||||
for (EntryInfo info : entries) {
|
for (EntryInfo info : entries) {
|
||||||
try {
|
try {
|
||||||
info.value = info.field.get(null);
|
info.value = info.field.get(null);
|
||||||
info.tempValue = info.value.toString();
|
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException ignored) {}
|
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() {
|
public void write() {
|
||||||
try {
|
try {
|
||||||
if (!Files.exists(path)) Files.createFile(path);
|
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) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
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;
|
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.Field;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class EntryInfo {
|
public class EntryInfo {
|
||||||
Field field;
|
Field field;
|
||||||
Object widget;
|
|
||||||
int width;
|
|
||||||
Method dynamicTooltip;
|
|
||||||
Map.Entry<TextFieldWidget, Text> error;
|
|
||||||
Object defaultValue;
|
Object defaultValue;
|
||||||
Object value;
|
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.ConfigScreenFactory;
|
||||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||||
import io.gitlab.jfronny.libjf.Libjf;
|
import io.gitlab.jfronny.libjf.Libjf;
|
||||||
|
import me.shedaniel.clothconfiglite.api.ConfigScreen;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -13,18 +15,22 @@ public class ModMenu implements ModMenuApi {
|
||||||
Map<String, ConfigScreenFactory<?>> factories = new HashMap<>();
|
Map<String, ConfigScreenFactory<?>> factories = new HashMap<>();
|
||||||
for (Map.Entry<String, Config> entry : Libjf.getConfigs().entrySet()) {
|
for (Map.Entry<String, Config> entry : Libjf.getConfigs().entrySet()) {
|
||||||
if (!Libjf.MOD_ID.equals(entry.getKey()))
|
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;
|
return factories;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private static ConfigScreenFactory<?> buildFactory(Config config) {
|
||||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
return s -> {
|
||||||
for (Map.Entry<String, Config> entry : Libjf.getConfigs().entrySet()) {
|
ConfigScreen c = ConfigScreen.create(new TranslatableText(config.translationPrefix + "title"), s);
|
||||||
if (Libjf.MOD_ID.equals(entry.getKey()))
|
for (EntryInfo entry : config.entries) {
|
||||||
return s -> new ConfigScreen(s, entry.getValue());
|
c.add(new TranslatableText(config.translationPrefix + entry.field.getName()),
|
||||||
}
|
entry.value, () -> entry.defaultValue, v -> {
|
||||||
new Exception("Could not find own config screen, this is bad").printStackTrace();
|
entry.value = v;
|
||||||
return null;
|
config.write();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
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": [
|
"modmenu": [
|
||||||
"io.gitlab.jfronny.libjf.config.ModMenu"
|
"io.gitlab.jfronny.libjf.config.ModMenu"
|
||||||
],
|
|
||||||
"libjf:config": [
|
|
||||||
"io.gitlab.jfronny.libjf.ExampleConfig"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mixins": [
|
"mixins": [
|
||||||
|
@ -31,5 +28,10 @@
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=0.11.3",
|
"fabricloader": ">=0.11.3",
|
||||||
"minecraft": "1.16.5"
|
"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