Port to java 16 and MC 1.17

This commit is contained in:
ffrann
2021-05-26 20:27:14 -04:00
parent c2d7cacdab
commit f468546eea
21 changed files with 157 additions and 156 deletions
+12 -6
View File
@@ -4,13 +4,15 @@
*The last config library you will ever use.* *The last config library you will ever use.*
ΩConfig is a hyper-minimal config library based on [Auto Config](https://github.com/shedaniel/AutoConfig). It aims to achieve ΩConfig is a hyper-minimal config library based on [Auto Config](https://github.com/shedaniel/AutoConfig). It aims to
the following goals: achieve the following goals:
- Be lightweight (<10 KB) for JIJ usage - Be lightweight (<10 KB) for JIJ usage
- Exceedingly simple design & API for developers - Exceedingly simple design & API for developers
- Intuition and usability for players - Intuition and usability for players
The following is an example of a simple ΩConfig setup: The following is an example of a simple ΩConfig setup:
```java ```java
public class TestConfig implements Config { public class TestConfig implements Config {
@@ -24,6 +26,7 @@ public class TestConfig implements Config {
} }
``` ```
```java ```java
public class MyModInitializer { public class MyModInitializer {
@@ -35,7 +38,9 @@ public class MyModInitializer {
} }
} }
``` ```
--- ---
### Extra API Utilities ### Extra API Utilities
ΩConfig provides several utility methods for developers. ΩConfig provides several utility methods for developers.
@@ -43,11 +48,12 @@ public class MyModInitializer {
**save()** - *saves a modified configuration instance to disk* **save()** - *saves a modified configuration instance to disk*
```java ```java
MyModInitializer.CONFIG.value = false; MyModInitializer.CONFIG.value=false;
MyModInitializer.CONFIG.save(); // writes the new value to disk MyModInitializer.CONFIG.save(); // writes the new value to disk
``` ```
--- ---
### License ### License
ΩConfig is available under Public Domain.
You are encouraged to utilize the code in this repository in any way you wish. ΩConfig is available under Public Domain. You are encouraged to utilize the code in this repository in any way you wish.
+15 -12
View File
@@ -10,7 +10,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.guardsquare:proguard-gradle:7.0.1' classpath 'com.guardsquare:proguard-gradle:7.1.0-beta4'
} }
} }
@@ -105,7 +105,7 @@ subprojects {
tasks.publish.dependsOn build //stupid fix for maven/loom not publishing the main artifact tasks.publish.dependsOn build //stupid fix for maven/loom not publishing the main artifact
task ('proguard', type: proguard.gradle.ProGuardTask) { task('proguard', type: proguard.gradle.ProGuardTask) {
configuration './proguard.conf' configuration './proguard.conf'
verbose verbose
injars project.buildDir.toString() + '/libs/' + archivesBaseName + "-" + project.mod_version + ".jar" injars project.buildDir.toString() + '/libs/' + archivesBaseName + "-" + project.mod_version + ".jar"
@@ -137,7 +137,7 @@ subprojects {
allprojects { allprojects {
apply plugin: "fabric-loom" apply plugin: "fabric-loom"
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = targetCompatibility = JavaVersion.VERSION_16
version = System.getenv("TRAVIS_TAG") ?: project.mod_version version = System.getenv("TRAVIS_TAG") ?: project.mod_version
repositories { repositories {
@@ -146,7 +146,7 @@ allprojects {
url = "https://maven.fabricmc.net" url = "https://maven.fabricmc.net"
} }
maven { url = "https://maven.terraformersmc.com/releases/"} maven { url = "https://maven.terraformersmc.com/releases/" }
} }
dependencies { dependencies {
@@ -155,10 +155,19 @@ allprojects {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modRuntime "com.terraformersmc:modmenu:1.16.8" modRuntime "com.terraformersmc:modmenu:2.0.0-beta.4"
modCompileOnly "com.terraformersmc:modmenu:1.16.8" modCompileOnly "com.terraformersmc:modmenu:2.0.0-beta.4"
} }
}
jar {
from(rootProject.file("LICENSE.md")) {
rename { "LICENSE_${project.archivesBaseName.replace('-', '_')}" }
}
}
afterEvaluate {
processResources { processResources {
// this will ensure that this task is redone when there"s a change // this will ensure that this task is redone when there"s a change
inputs.property "version", mod_version inputs.property "version", mod_version
@@ -176,12 +185,6 @@ allprojects {
exclude "fabric.mod.json" exclude "fabric.mod.json"
} }
} }
jar {
from(rootProject.file("LICENSE.md")) {
rename { "LICENSE_${project.archivesBaseName.replace('-', '_')}"}
}
}
} }
sourceSets { sourceSets {
+4 -7
View File
@@ -1,17 +1,14 @@
# Done to increase the memory available to gradle. # Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G org.gradle.jvmargs=-Xmx1G
# Fabric Properties # Fabric Properties
# check these on https://modmuss50.me/fabric.html # check these on https://modmuss50.me/fabric.html
minecraft_version=1.16.5 minecraft_version=21w20a
yarn_mappings=1.16.5+build.5 yarn_mappings=21w20a+build.19
loader_version=0.11.2 loader_version=0.11.3
# Mod Properties # Mod Properties
mod_version=1.0.5 mod_version=1.0.5
maven_group=draylar maven_group=draylar
archives_base_name=omega-config archives_base_name=omega-config
# Dependencies # Dependencies
# check this on https://modmuss50.me/fabric.html # check this on https://modmuss50.me/fabric.html
fabric_version=0.32.0+1.16 fabric_version=0.34.6+1.17
@@ -10,8 +10,8 @@ import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.NbtList;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -28,36 +28,33 @@ import java.util.*;
public class OmegaConfig { public class OmegaConfig {
private static final Logger LOGGER = LogManager.getLogger();
private static final List<Config> REGISTERED_CONFIGURATIONS = new ArrayList<>();
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static final Identifier CONFIG_SYNC_PACKET = new Identifier("omegaconfig", "sync"); public static final Identifier CONFIG_SYNC_PACKET = new Identifier("omegaconfig", "sync");
public static final Gson SYNC_ONLY_GSON = new GsonBuilder().addSerializationExclusionStrategy(new SyncableExclusionStrategy()).setPrettyPrinting().create(); public static final Gson SYNC_ONLY_GSON = new GsonBuilder().addSerializationExclusionStrategy(new SyncableExclusionStrategy()).setPrettyPrinting().create();
private static final Logger LOGGER = LogManager.getLogger();
private static final List<Config> REGISTERED_CONFIGURATIONS = new ArrayList<>();
static { static {
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> server.execute(() -> {
server.execute(() -> {
PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer()); PacketByteBuf packet = new PacketByteBuf(Unpooled.buffer());
// list of configurations that are synced // list of configurations that are synced
CompoundTag root = new CompoundTag(); NbtCompound root = new NbtCompound();
ListTag configurations = new ListTag(); NbtList configurations = new NbtList();
// Iterate over each configuration. // Iterate over each configuration.
// Find values that should be synced and send the value over. // Find values that should be synced and send the value over.
OmegaConfig.getRegisteredConfigurations().forEach(config -> { OmegaConfig.getRegisteredConfigurations().forEach(config -> {
if(config.hasAnySyncable()) { if (config.hasAnySyncable()) {
configurations.add(config.writeSyncingTag()); configurations.add(config.writeSyncingTag());
} }
}); });
// save to packet and send to user // save to packet and send to user
root.put("Configurations", configurations); root.put("Configurations", configurations);
packet.writeCompoundTag(root); packet.writeNbt(root);
handler.sendPacket(ServerPlayNetworking.createS2CPacket(CONFIG_SYNC_PACKET, packet)); handler.sendPacket(ServerPlayNetworking.createS2CPacket(CONFIG_SYNC_PACKET, packet));
}); }));
});
} }
public static <T extends Config> T register(Class<T> configClass) { public static <T extends Config> T register(Class<T> configClass) {
@@ -69,7 +66,7 @@ public class OmegaConfig {
// We want to provide access to the config as soon as it is created, so we: // We want to provide access to the config as soon as it is created, so we:
// 1. serialize to disk if the config does not already exist // 1. serialize to disk if the config does not already exist
// 2. read from disk if it does exist // 2. read from disk if it does exist
if(!configExists(config)) { if (!configExists(config)) {
writeConfig(configClass, config); writeConfig(configClass, config);
REGISTERED_CONFIGURATIONS.add(config); REGISTERED_CONFIGURATIONS.add(config);
} else { } else {
@@ -109,14 +106,14 @@ public class OmegaConfig {
Map<String, String> keyToComments = new HashMap<>(); Map<String, String> keyToComments = new HashMap<>();
// populate key -> comments map // populate key -> comments map
for(Field field : configClass.getDeclaredFields()) { for (Field field : configClass.getDeclaredFields()) {
addFieldComments(field, keyToComments); addFieldComments(field, keyToComments);
} }
// get inner-class fields // get inner-class fields
// TODO: recursively get inner classes? // TODO: recursively get inner classes?
for(Class<?> innerClass : configClass.getDeclaredClasses()) { for (Class<?> innerClass : configClass.getDeclaredClasses()) {
for(Field field : innerClass.getDeclaredFields()) { for (Field field : innerClass.getDeclaredFields()) {
addFieldComments(field, keyToComments); addFieldComments(field, keyToComments);
} }
} }
@@ -154,7 +151,7 @@ public class OmegaConfig {
Files.write(configPath, res.toString().getBytes()); Files.write(configPath, res.toString().getBytes());
} catch (IOException ioException) { } catch (IOException ioException) {
LOGGER.error(ioException); LOGGER.error(ioException);
LOGGER.info(String.format("Write error, using default values for config %s.", configClass.toString())); LOGGER.info(String.format("Write error, using default values for config %s.", configClass));
} }
} }
@@ -164,7 +161,7 @@ public class OmegaConfig {
// Find comment // Find comment
for (Annotation annotation : annotations) { for (Annotation annotation : annotations) {
if(annotation instanceof Comment) { if (annotation instanceof Comment) {
keyToComments.put(fieldName, ((Comment) annotation).value()); keyToComments.put(fieldName, ((Comment) annotation).value());
break; break;
} }
@@ -186,16 +183,16 @@ public class OmegaConfig {
int index = -1; int index = -1;
char[] chars = input.toCharArray(); char[] chars = input.toCharArray();
for(int i = 0; i < chars.length; i++) { for (int i = 0; i < chars.length; i++) {
char at = chars[i]; char at = chars[i];
if(at != ' ') { if (at != ' ') {
index = i; index = i;
break; break;
} }
} }
if(index != -1) { if (index != -1) {
return input.substring(0, index); return input.substring(0, index);
} else { } else {
return ""; return "";
@@ -1,7 +1,7 @@
package draylar.omegaconfig.api; package draylar.omegaconfig.api;
import draylar.omegaconfig.OmegaConfig; import draylar.omegaconfig.OmegaConfig;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtCompound;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Arrays; import java.util.Arrays;
@@ -16,12 +16,12 @@ public interface Config {
OmegaConfig.writeConfig((Class<Config>) getClass(), this); OmegaConfig.writeConfig((Class<Config>) getClass(), this);
} }
default CompoundTag writeSyncingTag() { default NbtCompound writeSyncingTag() {
CompoundTag tag = new CompoundTag(); NbtCompound tag = new NbtCompound();
tag.putString("ConfigName", getName()); tag.putString("ConfigName", getName());
// all config vs. individual fields // all config vs. individual fields
if(Arrays.stream(getClass().getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) { if (Arrays.stream(getClass().getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
// write ALL fields to tag // write ALL fields to tag
String json = OmegaConfig.GSON.toJson(this); String json = OmegaConfig.GSON.toJson(this);
tag.putString("Serialized", json); tag.putString("Serialized", json);
@@ -67,7 +67,7 @@ public interface Config {
* modids for configuration screen instances in their menu. * modids for configuration screen instances in their menu.
* If you are intending for this config to have a ModMenu config * If you are intending for this config to have a ModMenu config
* screen, this method should return the modid specified in your fabric.mod.json. * screen, this method should return the modid specified in your fabric.mod.json.
* * <p>
* If this method is not overridden, null will be returned, which * If this method is not overridden, null will be returned, which
* means this config is not explicitly associated with any particular mod. * means this config is not explicitly associated with any particular mod.
* *
@@ -99,7 +99,7 @@ public interface Config {
* By default, a config such as 'my_config' will appear at /config/my_config.json. * By default, a config such as 'my_config' will appear at /config/my_config.json.
* If this method specifies a directory, such as 'configurations', * If this method specifies a directory, such as 'configurations',
* the config file will appear at /config/configurations/my_config.json. * the config file will appear at /config/configurations/my_config.json.
* * <p>
* Nested directories can be specified by using a string such as 'configurations/client'. * Nested directories can be specified by using a string such as 'configurations/client'.
* *
* @return the directory of this config * @return the directory of this config
@@ -3,13 +3,12 @@ package draylar.omegaconfig.mixin;
import draylar.omegaconfig.OmegaConfig; import draylar.omegaconfig.OmegaConfig;
import draylar.omegaconfig.api.Config; import draylar.omegaconfig.api.Config;
import draylar.omegaconfig.api.Syncing; import draylar.omegaconfig.api.Syncing;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.util.NbtType; import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.RunArgs; import net.minecraft.client.RunArgs;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.ListTag;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -31,15 +30,15 @@ public class ClientMixin {
method = "<init>", method = "<init>",
at = @At("RETURN")) at = @At("RETURN"))
private void onReturn(RunArgs args, CallbackInfo ci) { private void onReturn(RunArgs args, CallbackInfo ci) {
ClientSidePacketRegistry.INSTANCE.register(OmegaConfig.CONFIG_SYNC_PACKET, (context, buffer) -> { ClientPlayNetworking.registerGlobalReceiver(OmegaConfig.CONFIG_SYNC_PACKET, (client, handler, buf, responseSender) -> {
CompoundTag tag = buffer.readCompoundTag(); NbtCompound tag = buf.readNbt();
savedClientConfig.clear(); savedClientConfig.clear();
context.getTaskQueue().execute(() -> { client.execute(() -> {
if(tag != null && tag.contains("Configurations")) { if (tag != null && tag.contains("Configurations")) {
ListTag list = tag.getList("Configurations", NbtType.COMPOUND); NbtList list = tag.getList("Configurations", NbtType.COMPOUND);
list.forEach(compound -> { list.forEach(compound -> {
CompoundTag syncedConfiguration = (CompoundTag) compound; NbtCompound syncedConfiguration = (NbtCompound) compound;
String name = syncedConfiguration.getString("ConfigName"); String name = syncedConfiguration.getString("ConfigName");
String json = syncedConfiguration.getString("Serialized"); String json = syncedConfiguration.getString("Serialized");
boolean allSync = syncedConfiguration.getBoolean("AllSync"); boolean allSync = syncedConfiguration.getBoolean("AllSync");
@@ -56,7 +55,7 @@ public class ClientMixin {
// locate all fields that differ between the client and server, assign values from server to client (this will mutate the stored object) // locate all fields that differ between the client and server, assign values from server to client (this will mutate the stored object)
for (Field field : server.getClass().getDeclaredFields()) { for (Field field : server.getClass().getDeclaredFields()) {
if(allSync || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) { if (allSync || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
try { try {
field.setAccessible(true); field.setAccessible(true);
Object serverValue = field.get(server); Object serverValue = field.get(server);
@@ -79,15 +78,15 @@ public class ClientMixin {
@Inject( @Inject(
method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V", method = "disconnect(Lnet/minecraft/client/gui/screen/Screen;)V",
at = @At("RETURN")) at = @At("RETURN"))
private void restoreConfigurations(Screen screen, CallbackInfo ci) { private void restoreConfigurations(CallbackInfo ci) {
for(Config config : savedClientConfig) { for (Config config : savedClientConfig) {
for(Config potentiallySynced : OmegaConfig.getRegisteredConfigurations()) { for (Config potentiallySynced : OmegaConfig.getRegisteredConfigurations()) {
if(config.getName().equals(potentiallySynced.getName())) { if (config.getName().equals(potentiallySynced.getName())) {
boolean allConfigSyncs = Arrays.stream(config.getClass().getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing); boolean allConfigSyncs = Arrays.stream(config.getClass().getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing);
// mutate object in registered configurations // mutate object in registered configurations
for (Field field : config.getClass().getDeclaredFields()) { for (Field field : config.getClass().getDeclaredFields()) {
if(allConfigSyncs || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) { if (allConfigSyncs || Arrays.stream(field.getAnnotations()).anyMatch(annotation -> annotation instanceof Syncing)) {
try { try {
field.setAccessible(true); field.setAccessible(true);
Object preSyncValue = field.get(config); Object preSyncValue = field.get(config);
@@ -4,7 +4,6 @@
"package": "draylar.omegaconfig.mixin", "package": "draylar.omegaconfig.mixin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [ "mixins": [
], ],
"client": [ "client": [
"ClientMixin" "ClientMixin"
@@ -12,11 +12,12 @@ public class OmegaConfigGui {
/** /**
* Registers a ModMenu configuration screen for the given {@link Config} instance. * Registers a ModMenu configuration screen for the given {@link Config} instance.
*
* @param config registered config to create a ModMenu screen for * @param config registered config to create a ModMenu screen for
* @param <T> config type * @param <T> config type
*/ */
public static <T extends Config> void registerConfigScreen(T config) { public static <T extends Config> void registerConfigScreen(T config) {
if(FabricLoader.getInstance().isModLoaded("modmenu")) { if (FabricLoader.getInstance().isModLoaded("modmenu")) {
ModMenuHelper.injectScreen(config, parent -> new OmegaConfigScreen<>(config, parent)); ModMenuHelper.injectScreen(config, parent -> new OmegaConfigScreen<>(config, parent));
} }
} }
@@ -5,19 +5,16 @@ import draylar.omegaconfig.api.Config;
import draylar.omegaconfiggui.api.screen.widget.LabelWidget; import draylar.omegaconfiggui.api.screen.widget.LabelWidget;
import draylar.omegaconfiggui.api.screen.widget.TypeWidgets; import draylar.omegaconfiggui.api.screen.widget.TypeWidgets;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier; import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.Tessellator;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats; import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair; import net.minecraft.util.Pair;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -32,7 +29,7 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
private static final List<Class<?>> validClasses = Arrays.asList(Double.class, String.class, Boolean.class); private static final List<Class<?>> validClasses = Arrays.asList(Double.class, String.class, Boolean.class);
private final T config; private final T config;
private final Screen parent; private final Screen parent;
private final Map<Field, Pair<WidgetSupplier<Object, AbstractButtonWidget>, AbstractButtonWidget>> fieldWidgets = new HashMap<>(); private final Map<Field, Pair<WidgetSupplier<Object, ClickableWidget>, ClickableWidget>> fieldWidgets = new HashMap<>();
public OmegaConfigScreen(T config, Screen parent) { public OmegaConfigScreen(T config, Screen parent) {
super(new LiteralText("")); super(new LiteralText(""));
@@ -54,24 +51,24 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
Class<?> unbox = TypeWidgets.unbox(field.getType()); Class<?> unbox = TypeWidgets.unbox(field.getType());
// label // label
addChild(new LabelWidget(150, 15 + height / 6 + 20 * over, new LiteralText(field.getName()))); addDrawable(new LabelWidget(150, 15 + height / 6 + 20 * over, new LiteralText(field.getName())));
// get value // get value
field.setAccessible(true); field.setAccessible(true);
Object value = field.get(config); Object value = field.get(config);
// button / interact // button / interact
AbstractButtonWidget button; ClickableWidget button;
WidgetSupplier<Object, AbstractButtonWidget> widgetSupplier = (WidgetSupplier<Object, AbstractButtonWidget>) TypeWidgets.get(unbox); WidgetSupplier<Object, ClickableWidget> widgetSupplier = (WidgetSupplier<Object, ClickableWidget>) TypeWidgets.get(unbox);
if(widgetSupplier != null) { if (widgetSupplier != null) {
button = widgetSupplier.create(this,250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()), value); button = widgetSupplier.create(this, 250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()), value);
} else { } else {
button = new TextFieldWidget(client.textRenderer, 250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName())); button = new TextFieldWidget(client.textRenderer, 250, 5 + height / 6 + 25 * over, 100, 20, new LiteralText(field.getName()));
} }
fieldWidgets.put(field, new Pair<>(widgetSupplier, button)); fieldWidgets.put(field, new Pair<>(widgetSupplier, button));
addButton(button); addSelectableChild(button);
over++; over++;
} }
@@ -92,15 +89,17 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
config.save(); config.save();
}); });
addButton(save); addSelectableChild(save);
addButton(exit); addSelectableChild(exit);
} }
@Override @Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
renderBackground(matrices); renderBackground(matrices);
for (AbstractButtonWidget button : this.buttons) { //TODO make this work. for Drawables (children) it works in parent method
/*
for (ClickableWidget button : this.) {
button.render(matrices, mouseX, mouseY, delta); button.render(matrices, mouseX, mouseY, delta);
} }
@@ -109,6 +108,8 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
((Drawable) element).render(matrices, mouseX, mouseY, delta); ((Drawable) element).render(matrices, mouseX, mouseY, delta);
} }
} }
*/
} }
@Override @Override
@@ -129,13 +130,13 @@ public class OmegaConfigScreen<T extends Config> extends Screen {
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferBuilder = tessellator.getBuffer(); BufferBuilder bufferBuilder = tessellator.getBuffer();
this.client.getTextureManager().bindTexture(OPTIONS_BACKGROUND_TEXTURE); this.client.getTextureManager().bindTexture(OPTIONS_BACKGROUND_TEXTURE);
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
bufferBuilder.begin(7, VertexFormats.POSITION_TEXTURE_COLOR); bufferBuilder.begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR);
bufferBuilder.vertex(x, height + y, 0.0D).texture(0.0F, (float)height / 32.0F + (float)vOffset).color(r, g, b, 255).next(); bufferBuilder.vertex(x, height + y, 0.0D).texture(0.0F, (float) height / 32.0F + (float) vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, height + y, 0.0D).texture((float)width / 32.0F, (float)height / 32.0F + (float)vOffset).color(r, g, b, 255).next(); bufferBuilder.vertex(width + x, height + y, 0.0D).texture((float) width / 32.0F, (float) height / 32.0F + (float) vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(width + x, y, 0.0D).texture((float)width / 32.0F, (float)vOffset).color(r, g, b, 255).next(); bufferBuilder.vertex(width + x, y, 0.0D).texture((float) width / 32.0F, (float) vOffset).color(r, g, b, 255).next();
bufferBuilder.vertex(x, y, 0.0D).texture(0.0F, (float)vOffset).color(r, g, b, 255).next(); bufferBuilder.vertex(x, y, 0.0D).texture(0.0F, (float) vOffset).color(r, g, b, 255).next();
tessellator.draw(); tessellator.draw();
} }
} }
@@ -1,9 +1,9 @@
package draylar.omegaconfiggui.api.screen.widget; package draylar.omegaconfiggui.api.screen.widget;
import draylar.omegaconfiggui.mixin.AbstractButtonWidgetAccessor; import draylar.omegaconfiggui.mixin.ClickableWidgetInvoker;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget; import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@@ -20,8 +20,8 @@ public class BaseTextFieldWidget extends TextFieldWidget {
public void setTextFieldFocused(boolean focused) { public void setTextFieldFocused(boolean focused) {
// unfocus all others // unfocus all others
parent.children().forEach(element -> { parent.children().forEach(element -> {
if(element instanceof AbstractButtonWidget) { if (element instanceof ClickableWidget) {
((AbstractButtonWidgetAccessor) element).callSetFocused(false); ((ClickableWidgetInvoker) element).callSetFocused(false);
} }
}); });
@@ -13,14 +13,12 @@ public class DoubleFieldWidget extends BaseTextFieldWidget {
@Override @Override
public void write(String string) { public void write(String string) {
try { try {
if(string.equals(".") && !getText().contains(".")) { if (!string.equals(".") || getText().contains(".")) {
super.write(string);
} else {
Double.parseDouble(string); Double.parseDouble(string);
super.write(string);
} }
super.write(string);
} catch(NumberFormatException ignored) { } catch (NumberFormatException ignored) {
} }
} }
@@ -30,6 +30,10 @@ public class TypeWidgets {
PRIMITIVE_TO_BOXED.put(void.class, Void.class); PRIMITIVE_TO_BOXED.put(void.class, Void.class);
} }
private TypeWidgets() {
// NO-OP
}
@Nullable @Nullable
public static <T> WidgetSupplier<T, ?> get(Class<T> typeClass) { public static <T> WidgetSupplier<T, ?> get(Class<T> typeClass) {
return (WidgetSupplier<T, ?>) CLASS_WIDGETS.get(unbox(typeClass)); return (WidgetSupplier<T, ?>) CLASS_WIDGETS.get(unbox(typeClass));
@@ -38,8 +42,4 @@ public class TypeWidgets {
public static Class<?> unbox(Class<?> c) { public static Class<?> unbox(Class<?> c) {
return PRIMITIVE_TO_BOXED.getOrDefault(c, c); return PRIMITIVE_TO_BOXED.getOrDefault(c, c);
} }
private TypeWidgets() {
// NO-OP
}
} }
@@ -1,10 +1,11 @@
package draylar.omegaconfiggui.api.screen.widget; package draylar.omegaconfiggui.api.screen.widget;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget; import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
public interface WidgetSupplier<T, A extends AbstractButtonWidget> { public interface WidgetSupplier<T, A extends ClickableWidget> {
AbstractButtonWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, T value); ClickableWidget create(Screen parent, int x, int y, int width, int height, LiteralText prompt, T value);
T get(A widget); T get(A widget);
} }
@@ -21,12 +21,12 @@ public class DoubleWidgetSupplier implements WidgetSupplier<Double, DoubleFieldW
String message = widget.getText(); String message = widget.getText();
// if it is just a . or empty, return 0 // if it is just a . or empty, return 0
if(message.equals(".") || message.isEmpty()) { if (message.equals(".") || message.isEmpty()) {
return 0.0; return 0.0;
} }
// trim potential trailing . // trim potential trailing .
if(message.indexOf(".") == message.length()) { if (message.indexOf(".") == message.length()) {
message = message.substring(0, message.length() - 1); message = message.substring(0, message.length() - 1);
} }
@@ -4,7 +4,6 @@ import draylar.omegaconfiggui.api.screen.widget.BaseTextFieldWidget;
import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier; import draylar.omegaconfiggui.api.screen.widget.WidgetSupplier;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.AbstractButtonWidget;
import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.LiteralText; import net.minecraft.text.LiteralText;
@@ -1,11 +1,11 @@
package draylar.omegaconfiggui.mixin; package draylar.omegaconfiggui.mixin;
import net.minecraft.client.gui.widget.AbstractButtonWidget; import net.minecraft.client.gui.widget.ClickableWidget;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(AbstractButtonWidget.class) @Mixin(ClickableWidget.class)
public interface AbstractButtonWidgetAccessor { public interface ClickableWidgetInvoker {
@Invoker @Invoker
void callSetFocused(boolean focused); void callSetFocused(boolean focused);
} }
@@ -4,7 +4,7 @@
"package": "draylar.omegaconfiggui.mixin", "package": "draylar.omegaconfiggui.mixin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [ "mixins": [
"AbstractButtonWidgetAccessor", "ClickableWidgetInvoker",
"ModMenuAccessor" "ModMenuAccessor"
], ],
"client": [ "client": [
@@ -3,8 +3,8 @@ package draylar.omegatest;
import draylar.omegaconfig.OmegaConfig; import draylar.omegaconfig.OmegaConfig;
import draylar.omegatest.config.ClassConfigTest; import draylar.omegatest.config.ClassConfigTest;
import draylar.omegatest.config.NestedConfigTest; import draylar.omegatest.config.NestedConfigTest;
import draylar.omegatest.config.StructuresConfigTest;
import draylar.omegatest.config.SimpleConfigTest; import draylar.omegatest.config.SimpleConfigTest;
import draylar.omegatest.config.StructuresConfigTest;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
public class OmegaTestMain implements ModInitializer { public class OmegaTestMain implements ModInitializer {
@@ -19,12 +19,6 @@ public class SimpleConfigTest implements Config {
@Comment(value = "This is an inner static class.") @Comment(value = "This is an inner static class.")
public Test test = new Test(); public Test test = new Test();
public static class Test {
@Comment(value = "This is the value inside the class!")
public boolean innerTest = false;
}
@Override @Override
public String getName() { public String getName() {
return "test-config"; return "test-config";
@@ -34,4 +28,10 @@ public class SimpleConfigTest implements Config {
public @Nullable String getModid() { public @Nullable String getModid() {
return "omega-config-test"; return "omega-config-test";
} }
public static class Test {
@Comment(value = "This is the value inside the class!")
public boolean innerTest = false;
}
} }
@@ -21,6 +21,11 @@ public class StructuresConfigTest implements Config {
return "mostructures-config-v2"; return "mostructures-config-v2";
} }
@Override
public String getExtension() {
return "json5";
}
public static class Features { public static class Features {
@Comment("Airplanes & Air Balloons") @Comment("Airplanes & Air Balloons")
public boolean air_features = true; public boolean air_features = true;
@@ -123,9 +128,4 @@ public class StructuresConfigTest implements Config {
public int killer_bunny_castle_seperation = 25; public int killer_bunny_castle_seperation = 25;
public int killer_bunny_castle_spacing = 50; public int killer_bunny_castle_spacing = 50;
} }
@Override
public String getExtension() {
return "json5";
}
} }