forked from Clones/Controlify
vanilla keybind override and config system
This commit is contained in:
@ -0,0 +1,81 @@
|
||||
package dev.isxander.controlify.config;
|
||||
|
||||
import com.google.gson.*;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.ControllerConfig;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
|
||||
public class ControlifyConfig {
|
||||
public static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("controlify.json");
|
||||
|
||||
private static final Gson GSON = new GsonBuilder()
|
||||
.serializeNulls()
|
||||
.setPrettyPrinting()
|
||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||
.create();
|
||||
|
||||
private static JsonObject config = new JsonObject();
|
||||
|
||||
public static void save() {
|
||||
try {
|
||||
generateConfig();
|
||||
|
||||
Files.deleteIfExists(CONFIG_PATH);
|
||||
Files.writeString(CONFIG_PATH, GSON.toJson(config), StandardOpenOption.CREATE_NEW, StandardOpenOption.TRUNCATE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to save config!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
if (!Files.exists(CONFIG_PATH)) {
|
||||
save();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
applyConfig(GSON.fromJson(Files.readString(CONFIG_PATH), JsonObject.class));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Failed to load config!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateConfig() {
|
||||
JsonObject configCopy = config.deepCopy(); // we use the old config, so we don't lose disconnected controller data
|
||||
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
// `add` replaces if already existing
|
||||
configCopy.add(controller.guid(), generateControllerConfig(controller));
|
||||
}
|
||||
|
||||
config = configCopy;
|
||||
}
|
||||
|
||||
private static JsonObject generateControllerConfig(Controller controller) {
|
||||
JsonObject object = new JsonObject();
|
||||
|
||||
object.add("config", GSON.toJsonTree(controller.config()));
|
||||
object.add("bindings", controller.bindings().toJson());
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
private static void applyConfig(JsonObject object) {
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
var settings = object.getAsJsonObject(controller.guid());
|
||||
if (settings != null) {
|
||||
applyControllerConfig(controller, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void applyControllerConfig(Controller controller, JsonObject object) {
|
||||
controller.config().overwrite(GSON.fromJson(object.getAsJsonObject("config"), ControllerConfig.class));
|
||||
controller.bindings().fromJson(object.getAsJsonObject("bindings"));
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package dev.isxander.controlify.config.gui;
|
||||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
|
||||
public class ModMenuIntegration implements ModMenuApi {
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
return YACLHelper::generateConfigScreen;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package dev.isxander.controlify.config.gui;
|
||||
|
||||
import dev.isxander.controlify.config.ControlifyConfig;
|
||||
import dev.isxander.controlify.controller.Controller;
|
||||
import dev.isxander.controlify.controller.ControllerConfig;
|
||||
import dev.isxander.yacl.api.ConfigCategory;
|
||||
import dev.isxander.yacl.api.Option;
|
||||
import dev.isxander.yacl.api.OptionGroup;
|
||||
import dev.isxander.yacl.api.YetAnotherConfigLib;
|
||||
import dev.isxander.yacl.gui.controllers.slider.FloatSliderController;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public class YACLHelper {
|
||||
public static Screen generateConfigScreen(Screen parent) {
|
||||
var yacl = YetAnotherConfigLib.createBuilder()
|
||||
.title(Component.literal("Controlify"))
|
||||
.save(ControlifyConfig::save);
|
||||
|
||||
for (var controller : Controller.CONTROLLERS.values()) {
|
||||
var category = ConfigCategory.createBuilder();
|
||||
|
||||
var customName = controller.config().customName;
|
||||
category.name(Component.literal(customName == null ? controller.name() : customName));
|
||||
|
||||
var config = controller.config();
|
||||
var def = ControllerConfig.DEFAULT;
|
||||
var configGroup = OptionGroup.createBuilder()
|
||||
.name(Component.translatable("controlify.gui.group.config"))
|
||||
.tooltip(Component.translatable("controlify.gui.group.config.tooltip"))
|
||||
.option(Option.createBuilder(float.class)
|
||||
.name(Component.translatable("controlify.gui.left_stick_deadzone"))
|
||||
.tooltip(Component.translatable("controlify.gui.left_stick_deadzone.tooltip"))
|
||||
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
||||
.binding(def.leftStickDeadzone, () -> config.leftStickDeadzone, v -> config.leftStickDeadzone = v)
|
||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.02f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||
.build())
|
||||
.option(Option.createBuilder(float.class)
|
||||
.name(Component.translatable("controlify.gui.right_stick_deadzone"))
|
||||
.tooltip(Component.translatable("controlify.gui.right_stick_deadzone.tooltip"))
|
||||
.tooltip(Component.translatable("controlify.gui.stickdrift_warning").withStyle(ChatFormatting.RED))
|
||||
.binding(def.rightStickDeadzone, () -> config.rightStickDeadzone, v -> config.rightStickDeadzone = v)
|
||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.02f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||
.build())
|
||||
.option(Option.createBuilder(float.class)
|
||||
.name(Component.translatable("controlify.gui.left_trigger_threshold"))
|
||||
.tooltip(Component.translatable("controlify.gui.left_trigger_threshold.tooltip"))
|
||||
.binding(def.leftTriggerActivationThreshold, () -> config.leftTriggerActivationThreshold, v -> config.leftTriggerActivationThreshold = v)
|
||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||
.build())
|
||||
.option(Option.createBuilder(float.class)
|
||||
.name(Component.translatable("controlify.gui.right_trigger_threshold"))
|
||||
.tooltip(Component.translatable("controlify.gui.right_trigger_threshold.tooltip"))
|
||||
.binding(def.rightTriggerActivationThreshold, () -> config.rightTriggerActivationThreshold, v -> config.rightTriggerActivationThreshold = v)
|
||||
.controller(opt -> new FloatSliderController(opt, 0, 1, 0.05f, v -> Component.literal(String.format("%.0f%%", v*100))))
|
||||
.build());
|
||||
category.group(configGroup.build());
|
||||
|
||||
yacl.category(category.build());
|
||||
}
|
||||
|
||||
return yacl.build().generateScreen(parent);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user