From 0f1edba5f1b2c74078a9bb6acce54815ac4503fa Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 8 Oct 2018 18:05:08 -0700 Subject: [PATCH] save settings --- src/api/java/baritone/api/BaritoneAPI.java | 2 + src/api/java/baritone/api/Settings.java | 2 + .../java/baritone/api/utils/SettingsUtil.java | 137 ++++++++++++++++++ .../utils/ExampleBaritoneControl.java | 3 + 4 files changed, 144 insertions(+) create mode 100644 src/api/java/baritone/api/utils/SettingsUtil.java diff --git a/src/api/java/baritone/api/BaritoneAPI.java b/src/api/java/baritone/api/BaritoneAPI.java index 7497454ee..29238ea77 100644 --- a/src/api/java/baritone/api/BaritoneAPI.java +++ b/src/api/java/baritone/api/BaritoneAPI.java @@ -21,6 +21,7 @@ import baritone.api.behavior.*; import baritone.api.cache.IWorldProvider; import baritone.api.cache.IWorldScanner; import baritone.api.event.listener.IGameEventListener; +import baritone.api.utils.SettingsUtil; import java.util.Iterator; import java.util.ServiceLoader; @@ -44,6 +45,7 @@ public final class BaritoneAPI { baritone = instances.next(); settings = new Settings(); + SettingsUtil.readAndApply(settings); } public static IFollowBehavior getFollowBehavior() { diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index f69ee6dc1..fcf84b3a7 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -497,6 +497,7 @@ public class Settings { public class Setting { public T value; + public final T defaultValue; private String name; private final Class klass; @@ -506,6 +507,7 @@ public class Settings { throw new IllegalArgumentException("Cannot determine value type class from null"); } this.value = value; + this.defaultValue = value; this.klass = (Class) value.getClass(); } diff --git a/src/api/java/baritone/api/utils/SettingsUtil.java b/src/api/java/baritone/api/utils/SettingsUtil.java new file mode 100644 index 000000000..219c17f79 --- /dev/null +++ b/src/api/java/baritone/api/utils/SettingsUtil.java @@ -0,0 +1,137 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.utils; + +import baritone.api.Settings; +import net.minecraft.client.Minecraft; +import net.minecraft.item.Item; +import net.minecraft.util.ResourceLocation; + +import java.awt.*; +import java.io.File; +import java.io.FileOutputStream; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class SettingsUtil { + private static final File settingsFile = new File(new File(Minecraft.getMinecraft().gameDir, "baritone"), "settings.txt"); + + private static final Map, SettingsIO> map; + + public static void readAndApply(Settings settings) { + try (Scanner scan = new Scanner(settingsFile)) { + while (scan.hasNextLine()) { + String line = scan.nextLine(); + if (line.isEmpty()) { + continue; + } + if (line.startsWith("#") || line.startsWith("//")) { + continue; + } + int space = line.indexOf(" "); + if (space == -1) { + System.out.println("Skipping invalid line with no space: " + line); + continue; + } + String settingName = line.substring(0, space).trim().toLowerCase(); + String settingValue = line.substring(space).trim(); + try { + parseAndApply(settings, settingName, settingValue); + } catch (Exception ex) { + ex.printStackTrace(); + System.out.println("Unable to parse line " + line); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!"); + } + } + + public static synchronized void save(Settings settings) { + try (FileOutputStream out = new FileOutputStream(settingsFile)) { + for (Settings.Setting setting : settings.allSettings) { + if (setting.get() == null) { + System.out.println("NULL SETTING?" + setting.getName()); + continue; + } + if (setting.getName().equals("logger")) { + continue; // NO + } + SettingsIO io = map.get(setting.getValueClass()); + if (io == null) { + throw new IllegalStateException("Missing " + setting.getValueClass() + " " + setting + " " + setting.getName()); + } + out.write((setting.getName() + " " + io.toString.apply(setting.get()) + "\n").getBytes()); + } + } catch (Exception ex) { + ex.printStackTrace(); + System.out.println("Exception while saving Baritone settings!"); + } + } + + private static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException { + Settings.Setting setting = settings.byLowerName.get(settingName); + if (setting == null) { + throw new IllegalStateException("No setting by that name"); + } + Class intendedType = setting.getValueClass(); + SettingsIO ioMethod = map.get(intendedType); + Object parsed = ioMethod.parser.apply(settingValue); + if (!intendedType.isInstance(parsed)) { + throw new IllegalStateException(ioMethod + " parser returned incorrect type, expected " + intendedType + " got " + parsed + " which is " + parsed.getClass()); + } + setting.value = parsed; + } + + private enum SettingsIO { + DOUBLE(Double.class, Double::parseDouble), + BOOLEAN(Boolean.class, Boolean::parseBoolean), + INTEGER(Integer.class, Integer::parseInt), + FLOAT(Float.class, Float::parseFloat), + LONG(Long.class, Long::parseLong), + + ITEM_LIST(ArrayList.class, str -> Stream.of(str.split(",")).map(Item::getByNameOrId).collect(Collectors.toCollection(ArrayList::new)), list -> ((ArrayList) list).stream().map(Item.REGISTRY::getNameForObject).map(ResourceLocation::toString).collect(Collectors.joining(","))), + COLOR(Color.class, str -> new Color(Integer.parseInt(str.split(",")[0]), Integer.parseInt(str.split(",")[1]), Integer.parseInt(str.split(",")[2])), color -> color.getRed() + "," + color.getGreen() + "," + color.getBlue()); + + + Class klass; + Function parser; + Function toString; + + SettingsIO(Class klass, Function parser) { + this(klass, parser, Object::toString); + } + + SettingsIO(Class klass, Function parser, Function toString) { + this.klass = klass; + this.parser = parser::apply; + this.toString = x -> toString.apply((T) x); + } + } + + static { + HashMap, SettingsIO> tempMap = new HashMap<>(); + for (SettingsIO type : SettingsIO.values()) { + tempMap.put(type.klass, type); + } + map = Collections.unmodifiableMap(tempMap); + } +} diff --git a/src/main/java/baritone/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java index cca6e3a2f..683ec62bc 100644 --- a/src/main/java/baritone/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java @@ -23,6 +23,7 @@ import baritone.api.cache.IWaypoint; import baritone.api.event.events.ChatEvent; import baritone.api.pathing.goals.*; import baritone.api.pathing.movement.ActionCosts; +import baritone.api.utils.SettingsUtil; import baritone.behavior.Behavior; import baritone.behavior.FollowBehavior; import baritone.behavior.MineBehavior; @@ -79,6 +80,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper { setting.value ^= true; event.cancel(); logDirect("Toggled " + setting.getName() + " to " + setting.value); + SettingsUtil.save(Baritone.settings()); return; } } @@ -112,6 +114,7 @@ public class ExampleBaritoneControl extends Behavior implements Helper { event.cancel(); return; } + SettingsUtil.save(Baritone.settings()); logDirect(setting.toString()); event.cancel(); return;