add file sync

This commit is contained in:
2025-11-07 11:21:15 +01:00
parent 5230e11f20
commit 8bc465bb8f
11 changed files with 148 additions and 26 deletions

View File

@@ -9,11 +9,20 @@ base {
archivesName = project.archives_base_name archivesName = project.archives_base_name
} }
repositories {
maven {
name = "Terraformers"
url = "https://maven.terraformersmc.com/"
}
}
dependencies { dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}" minecraft "com.mojang:minecraft:${project.minecraft_version}"
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}"
modImplementation("com.terraformersmc:modmenu:16.0.0-rc.1")
} }
processResources { processResources {

View File

@@ -1,10 +1,19 @@
package com.kasetoatz.dumbassconfig; package com.kasetoatz.dumbassconfig;
import com.kasetoatz.dumbassconfig.options.Option; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.kasetoatz.dumbassconfig.options.AbstractOption;
import com.kasetoatz.dumbassconfig.ui.ConfigScreen; import com.kasetoatz.dumbassconfig.ui.ConfigScreen;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.crash.CrashException;
import net.minecraft.util.crash.CrashReport;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
public class DumbassConfig public class DumbassConfig
@@ -24,8 +33,15 @@ public class DumbassConfig
public static int BACKGROUND_COLOR_1 = 0x50555555; public static int BACKGROUND_COLOR_1 = 0x50555555;
public static int BACKGROUND_COLOR_2 = 0x50333333; public static int BACKGROUND_COLOR_2 = 0x50333333;
private final ArrayList<Option<?>> options = new ArrayList<>(); private final ArrayList<AbstractOption<?>> options = new ArrayList<>();
private ConfigScreen ui; private ConfigScreen ui;
private final Path file;
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
private DumbassConfig(String filename)
{
this.file = FabricLoader.getInstance().getConfigDir().resolve(filename.endsWith(".json") ? filename : filename + ".json");
}
public Screen getUI(Screen parent) public Screen getUI(Screen parent)
{ {
@@ -33,9 +49,52 @@ public class DumbassConfig
return this.ui; return this.ui;
} }
public static Builder builder(Text uiTitle) private void load()
{ {
return new Builder(uiTitle); if (!Files.exists(this.file))
{
this.save();
return;
}
try
{
String json = Files.readString(this.file);
JsonObject data = this.gson.fromJson(json, JsonObject.class);
for (AbstractOption<?> option : this.options)
{
if (data.has(option.getKey()))
{
option.fromJson(data.get(option.getKey()));
}
}
this.save();
}
catch (IOException exc)
{
throw new CrashException(CrashReport.create(exc, "Loading config file."));
}
}
public void save()
{
try
{
JsonObject data = new JsonObject();
for (AbstractOption<?> option : this.options)
{
data.add(option.getKey(), this.gson.toJsonTree(option.getValue()));
}
Files.writeString(this.file, this.gson.toJson(data));
}
catch (IOException exc)
{
throw new CrashException(CrashReport.create(exc, "Saving config file."));
}
}
public static Builder builder(Text uiTitle, String filename)
{
return new Builder(uiTitle, filename);
} }
public static class Builder public static class Builder
@@ -43,13 +102,13 @@ public class DumbassConfig
private final DumbassConfig config; private final DumbassConfig config;
private final Text uiTitle; private final Text uiTitle;
private Builder(Text uiTitle) private Builder(Text uiTitle, String filename)
{ {
this.config = new DumbassConfig(); this.config = new DumbassConfig(filename);
this.uiTitle = uiTitle; this.uiTitle = uiTitle;
} }
public Builder withOption(Option<?> option) public Builder withOption(AbstractOption<?> option)
{ {
this.config.options.add(option); this.config.options.add(option);
return this; return this;
@@ -57,7 +116,9 @@ public class DumbassConfig
public DumbassConfig build() public DumbassConfig build()
{ {
this.config.load();
this.config.ui = new ConfigScreen(uiTitle, this.config.options); this.config.ui = new ConfigScreen(uiTitle, this.config.options);
this.config.ui.setSaveCallback(this.config::save);
return this.config; return this.config;
} }
} }

View File

@@ -0,0 +1,23 @@
package com.kasetoatz.dumbassconfig;
import com.kasetoatz.dumbassconfig.options.BoolOption;
import com.kasetoatz.dumbassconfig.options.FloatOption;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import net.minecraft.text.Text;
public class Test implements ModMenuApi
{
public static final BoolOption TEST_BOOL_OPT = new BoolOption("TEST", "test_bool_opt", false);
public static final FloatOption TEST_FLOAT_OPT = new FloatOption("TEST", "test_float_opt", 1.F);
DumbassConfig config = DumbassConfig.builder(Text.literal("Test Screen"), "test.json")
.withOption(TEST_BOOL_OPT)
.withOption(TEST_FLOAT_OPT)
.build();
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory()
{
return config::getUI;
}
}

View File

@@ -3,9 +3,9 @@ package com.kasetoatz.dumbassconfig.options;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public abstract class ButtonOption<T> extends Option<T> public abstract class AbstractButtonOption<T> extends AbstractOption<T>
{ {
public ButtonOption(String text, String key, T defaultValue) public AbstractButtonOption(String text, String key, T defaultValue)
{ {
super(text, key, defaultValue); super(text, key, defaultValue);
} }

View File

@@ -8,18 +8,18 @@ import net.minecraft.text.Text;
import static com.kasetoatz.dumbassconfig.DumbassConfig.INVALID_INPUT_COLOR; import static com.kasetoatz.dumbassconfig.DumbassConfig.INVALID_INPUT_COLOR;
import static com.kasetoatz.dumbassconfig.DumbassConfig.VALID_INPUT_COLOR; import static com.kasetoatz.dumbassconfig.DumbassConfig.VALID_INPUT_COLOR;
public abstract class InputOption<T> extends Option<T> public abstract class AbstractInputOption<T> extends AbstractOption<T>
{ {
public InputField textField; public InputField textField;
private Validator<T> validator; private Validator<T> validator;
public InputOption(String text, String key, T defaultValue, Validator<T> validator) public AbstractInputOption(String text, String key, T defaultValue, Validator<T> validator)
{ {
super(text, key, defaultValue); super(text, key, defaultValue);
this.validator = validator; this.validator = validator;
} }
public InputOption(String text, String key, T defaultValue) public AbstractInputOption(String text, String key, T defaultValue)
{ {
super(text, key, defaultValue); super(text, key, defaultValue);
} }

View File

@@ -1,15 +1,16 @@
package com.kasetoatz.dumbassconfig.options; package com.kasetoatz.dumbassconfig.options;
import com.google.gson.JsonElement;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public abstract class Option<T> public abstract class AbstractOption<T>
{ {
private final Text text; private final Text text;
private final String key; private final String key;
private final T defaultValue; private final T defaultValue;
private T value; private T value;
public Option(String text, String key, T defaultValue) public AbstractOption(String text, String key, T defaultValue)
{ {
this.text = Text.of(text); this.text = Text.of(text);
this.key = key; this.key = key;
@@ -41,4 +42,6 @@ public abstract class Option<T>
{ {
this.value = value; this.value = value;
} }
public abstract void fromJson(JsonElement element);
} }

View File

@@ -1,12 +1,13 @@
package com.kasetoatz.dumbassconfig.options; package com.kasetoatz.dumbassconfig.options;
import com.google.gson.JsonElement;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import static com.kasetoatz.dumbassconfig.DumbassConfig.BOOLEAN_FALSE_COLOR; import static com.kasetoatz.dumbassconfig.DumbassConfig.BOOLEAN_FALSE_COLOR;
import static com.kasetoatz.dumbassconfig.DumbassConfig.BOOLEAN_TRUE_COLOR; import static com.kasetoatz.dumbassconfig.DumbassConfig.BOOLEAN_TRUE_COLOR;
public class BoolOption extends ButtonOption<Boolean> public class BoolOption extends AbstractButtonOption<Boolean>
{ {
public BoolOption(String text, String key, boolean defaultValue) public BoolOption(String text, String key, boolean defaultValue)
{ {
@@ -25,4 +26,10 @@ public class BoolOption extends ButtonOption<Boolean>
this.setValue(!this.getValue()); this.setValue(!this.getValue());
button.setMessage(this.getButtonText()); button.setMessage(this.getButtonText());
} }
@Override
public void fromJson(JsonElement element)
{
this.setValue(element.getAsBoolean());
}
} }

View File

@@ -1,8 +1,9 @@
package com.kasetoatz.dumbassconfig.options; package com.kasetoatz.dumbassconfig.options;
import com.google.gson.JsonElement;
import com.kasetoatz.dumbassconfig.options.validators.Validator; import com.kasetoatz.dumbassconfig.options.validators.Validator;
public class FloatOption extends InputOption<Float> public class FloatOption extends AbstractInputOption<Float>
{ {
public FloatOption(String text, String key, Float defaultValue, Validator<Float> validator) public FloatOption(String text, String key, Float defaultValue, Validator<Float> validator)
{ {
@@ -37,4 +38,10 @@ public class FloatOption extends InputOption<Float>
{ {
this.onChange((text.isEmpty() || text.equals(".") || text.equals("-")) ? 0.F : Float.parseFloat(text)); this.onChange((text.isEmpty() || text.equals(".") || text.equals("-")) ? 0.F : Float.parseFloat(text));
} }
@Override
public void fromJson(JsonElement element)
{
this.setValue(element.getAsFloat());
}
} }

View File

@@ -1,8 +1,8 @@
package com.kasetoatz.dumbassconfig.ui; package com.kasetoatz.dumbassconfig.ui;
import com.kasetoatz.dumbassconfig.options.ButtonOption; import com.kasetoatz.dumbassconfig.options.AbstractButtonOption;
import com.kasetoatz.dumbassconfig.options.InputOption; import com.kasetoatz.dumbassconfig.options.AbstractInputOption;
import com.kasetoatz.dumbassconfig.options.Option; import com.kasetoatz.dumbassconfig.options.AbstractOption;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.widget.*; import net.minecraft.client.gui.widget.*;
@@ -51,15 +51,15 @@ public class ConfigEntryList extends ElementListWidget<ConfigEntry>
super.renderWidget(context, mouseX, mouseY, delta); super.renderWidget(context, mouseX, mouseY, delta);
} }
public void add(Option<?> option) public void add(AbstractOption<?> option)
{ {
ConfigEntry entry = new ConfigEntry(); ConfigEntry entry = new ConfigEntry();
entry.add(new TextWidget(option.getText(), this.client.textRenderer)); entry.add(new TextWidget(option.getText(), this.client.textRenderer));
if (option instanceof ButtonOption<?> buttonOption) if (option instanceof AbstractButtonOption<?> buttonOption)
{ {
entry.add(ButtonWidget.builder(buttonOption.getButtonText(), buttonOption::onClick).build()); entry.add(ButtonWidget.builder(buttonOption.getButtonText(), buttonOption::onClick).build());
} }
else if (option instanceof InputOption<?> inputOption) else if (option instanceof AbstractInputOption<?> inputOption)
{ {
inputOption.textField = new InputField(this.client.textRenderer, inputOption.getText()); inputOption.textField = new InputField(this.client.textRenderer, inputOption.getText());
inputOption.textField.setText(inputOption.getValue().toString()); inputOption.textField.setText(inputOption.getValue().toString());

View File

@@ -1,6 +1,6 @@
package com.kasetoatz.dumbassconfig.ui; package com.kasetoatz.dumbassconfig.ui;
import com.kasetoatz.dumbassconfig.options.Option; import com.kasetoatz.dumbassconfig.options.AbstractOption;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ThreePartsLayoutWidget; import net.minecraft.client.gui.widget.ThreePartsLayoutWidget;
@@ -15,11 +15,12 @@ import static com.kasetoatz.dumbassconfig.DumbassConfig.ENTRY_HEIGHT;
public class ConfigScreen extends Screen public class ConfigScreen extends Screen
{ {
private Screen parent; private Screen parent;
private final List<Option<?>> options; private final List<AbstractOption<?>> options;
private final ThreePartsLayoutWidget layout = new ThreePartsLayoutWidget(this); private final ThreePartsLayoutWidget layout = new ThreePartsLayoutWidget(this);
private ConfigEntryList body; private ConfigEntryList body;
private Runnable saveCallback;
public ConfigScreen(Text title, List<Option<?>> options) public ConfigScreen(Text title, List<AbstractOption<?>> options)
{ {
super(title); super(title);
this.options = options; this.options = options;
@@ -30,12 +31,17 @@ public class ConfigScreen extends Screen
this.parent = parent; this.parent = parent;
} }
public void setSaveCallback(Runnable callback)
{
this.saveCallback = callback;
}
@Override @Override
protected void init() protected void init()
{ {
this.layout.addHeader(this.title, this.textRenderer); this.layout.addHeader(this.title, this.textRenderer);
this.body = new ConfigEntryList(this.client, this.layout.getWidth(), this.layout.getContentHeight(), this.layout.getHeaderHeight(), ENTRY_HEIGHT); this.body = new ConfigEntryList(this.client, this.layout.getWidth(), this.layout.getContentHeight(), this.layout.getHeaderHeight(), ENTRY_HEIGHT);
for (Option<?> option : this.options) for (AbstractOption<?> option : this.options)
{ {
this.body.add(option); this.body.add(option);
} }
@@ -58,6 +64,7 @@ public class ConfigScreen extends Screen
@Override @Override
public void close() public void close()
{ {
this.saveCallback.run();
if (this.client != null) if (this.client != null)
{ {
this.client.setScreen(this.parent); this.client.setScreen(this.parent);

View File

@@ -9,6 +9,11 @@
"license": "MIT", "license": "MIT",
"icon": "icon.png", "icon": "icon.png",
"environment": "client", "environment": "client",
"entrypoints": {
"modmenu": [
"com.kasetoatz.dumbassconfig.Test"
]
},
"depends": { "depends": {
"fabricloader": ">=${loader_version}", "fabricloader": ">=${loader_version}",
"fabric": "*", "fabric": "*",