diff --git a/src/main/java/ru/betterend/BetterEnd.java b/src/main/java/ru/betterend/BetterEnd.java index 515fdba1..c351b1b9 100644 --- a/src/main/java/ru/betterend/BetterEnd.java +++ b/src/main/java/ru/betterend/BetterEnd.java @@ -2,10 +2,12 @@ package ru.betterend; import net.fabricmc.api.ModInitializer; import ru.betterend.registry.BiomeRegistry; +import ru.betterend.util.Logger; import ru.betterend.world.generator.BetterEndBiomeSource; public class BetterEnd implements ModInitializer { public static final String MOD_ID = "betterend"; + public static final Logger LOGGER = Logger.get(); @Override public void onInitialize() { diff --git a/src/main/java/ru/betterend/config/ClientConfig.java b/src/main/java/ru/betterend/config/ClientConfig.java new file mode 100644 index 00000000..b3ca436a --- /dev/null +++ b/src/main/java/ru/betterend/config/ClientConfig.java @@ -0,0 +1,37 @@ +package ru.betterend.config; + +import com.google.gson.JsonObject; + +public class ClientConfig extends Config { + + private static ClientConfig instance; + + public static ClientConfig get() { + if (instance == null) { + instance = new ClientConfig(); + } + + return instance; + } + + private ClientConfig() { + JsonObject config = ConfigWriter.load(); + if (config.size() > 0) { + KEEPER.fromJson(config); + } else { + ConfigWriter.save(KEEPER.toJson()); + } + } + + public void reloadFromDisk() { + JsonObject config = ConfigWriter.load(); + if (config.size() > 0) { + KEEPER.fromJson(config); + } + } + + @Override + public void saveChanges() { + ConfigWriter.save(KEEPER.toJson()); + } +} diff --git a/src/main/java/ru/betterend/config/Config.java b/src/main/java/ru/betterend/config/Config.java new file mode 100644 index 00000000..e1fab94e --- /dev/null +++ b/src/main/java/ru/betterend/config/Config.java @@ -0,0 +1,110 @@ +package ru.betterend.config; + +import ru.betterend.BetterEnd; +import ru.betterend.config.ConfigKeeper.*; + +public abstract class Config { + + protected final static ConfigKeeper KEEPER = ConfigKeeper.getInstance(); + + public abstract void saveChanges(); + + public > E getEntry(String key) { + return KEEPER.getEntry(key); + } + + public T getDefault(String key) { + Entry entry = KEEPER.getEntry(key); + return entry != null ? entry.getDefault() : null; + } + + public String getString(String key) { + String str = KEEPER.getValue(key); + return str != null ? str : ""; + } + + public boolean setString(String key, String value) { + try { + StringEntry entry = KEEPER.getEntry(key); + entry.setValue(value); + KEEPER.set(key, entry); + + return true; + } catch (NullPointerException ex) { + BetterEnd.LOGGER.catching(ex); + } + + return false; + } + + public int getInt(String key) { + Integer val = KEEPER.getValue(key); + return val != null ? val : 0; + } + + public boolean setInt(String key, int value) { + try { + IntegerEntry entry = KEEPER.getEntry(key); + entry.setValue(value); + KEEPER.set(key, entry); + + return true; + } catch (NullPointerException ex) { + BetterEnd.LOGGER.catching(ex); + } + + return false; + } + + public > boolean setRanged(String key, T value) { + try { + RangeEntry entry = KEEPER.getEntry(key); + entry.setValue(value); + KEEPER.set(key, entry); + + return true; + } catch (NullPointerException | ClassCastException ex) { + BetterEnd.LOGGER.catching(ex); + } + + return false; + } + + public float getFloat(String key) { + Float val = KEEPER.getValue(key); + return val != null ? val : 0.0F; + } + + public boolean setFloat(String key, float value) { + try { + FloatEntry entry = KEEPER.getEntry(key); + entry.setValue(value); + KEEPER.set(key, entry); + + return true; + } catch (NullPointerException ex) { + BetterEnd.LOGGER.catching(ex); + } + + return false; + } + + public boolean getBoolean(String key) { + Boolean val = KEEPER.getValue(key); + return val != null ? val : false; + } + + public boolean setBoolean(String key, boolean value) { + try { + BooleanEntry entry = KEEPER.getEntry(key); + entry.setValue(value); + KEEPER.set(key, entry); + + return true; + } catch (NullPointerException ex) { + BetterEnd.LOGGER.catching(ex); + } + + return false; + } +} diff --git a/src/main/java/ru/betterend/config/ConfigKeeper.java b/src/main/java/ru/betterend/config/ConfigKeeper.java new file mode 100644 index 00000000..0400d801 --- /dev/null +++ b/src/main/java/ru/betterend/config/ConfigKeeper.java @@ -0,0 +1,354 @@ +package ru.betterend.config; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import net.minecraft.util.JsonHelper; +import ru.betterend.BetterEnd; + +public final class ConfigKeeper { + + private static ConfigKeeper instance; + public static ConfigKeeper getInstance() { + if (instance == null) { + instance = new ConfigKeeper(); + } + return instance; + } + + private Map> configEntries = new HashMap<>(); + + private ConfigKeeper() {} + + @SuppressWarnings("unchecked") + public > E getEntry(String key) { + Entry entry = this.configEntries.get(key); + if (entry == null) { + BetterEnd.LOGGER.warning(String.format("Entry '%s' doesn't exists.", key)); + return null; + } + return (E) entry; + } + + public T getValue(String key) { + Entry entry = this.getEntry(key); + if (entry == null) { + BetterEnd.LOGGER.warning(String.format("Empty value will be returned.", key)); + return null; + } + return entry.getValue(); + } + + public void set(String key, Entry entry) { + configEntries.put(key, entry); + } + + public > void registerEntry(String key, T entry) { + configEntries.put(key, entry); + } + + public JsonElement toJson() { + JsonObject jsonObject = new JsonObject(); + + for (String param : configEntries.keySet()) { + jsonObject.addProperty(param, configEntries.get(param).asString()); + } + + return jsonObject; + } + + public void fromJson(JsonObject jsonObject) { + for (String param : configEntries.keySet()) { + if (jsonObject.has(param)) { + Entry entry = configEntries.get(param); + entry.fromString(JsonHelper.getString(jsonObject, param)); + } + } + } + + public static class BooleanEntry extends Entry { + + public BooleanEntry(Boolean defaultValue, Consumer consumer, Supplier supplier) { + super(defaultValue, consumer, supplier); + } + + @Override + public Boolean getValue() { + return this.getter.get(); + } + + @Override + public void setValue(Boolean value) { + this.setter.accept(value); + } + + @Override + public Boolean getDefault() { + return this.defaultValue; + } + + @Override + public String asString() { + return getValue() ? "true" : "false"; + } + + @Override + public void fromString(String value) { + setValue(value.equals("true") ? true : false); + } + + } + + public static class FloatEntry extends Entry { + + public FloatEntry(Float defaultValue, Consumer consumer, Supplier supplier) { + super(defaultValue, consumer, supplier); + } + + @Override + public Float getValue() { + return this.getter.get(); + } + + @Override + public void setValue(Float value) { + this.setter.accept(value); + } + + @Override + public Float getDefault() { + return this.defaultValue; + } + + @Override + public String asString() { + return Float.toString(getValue()); + } + + @Override + public void fromString(String value) { + setValue(Float.valueOf(value)); + } + + } + + public static class FloatRange extends RangeEntry { + + public FloatRange(Float defaultValue, Consumer consumer, Supplier supplier, Float minVal, Float maxVal) { + super(defaultValue, consumer, supplier, minVal, maxVal); + } + + @Override + public Float getValue() { + return this.getter.get(); + } + + @Override + public Float getDefault() { + return this.defaultValue; + } + + @Override + public void fromString(String value) { + setValue(Float.valueOf(value)); + } + + @Override + public String asString() { + return Float.toString(getValue()); + } + + } + + public static class IntegerEntry extends Entry { + + public IntegerEntry(Integer defaultValue, Consumer consumer, Supplier supplier) { + super(defaultValue, consumer, supplier); + } + + @Override + public Integer getValue() { + return this.getter.get(); + } + + @Override + public void setValue(Integer value) { + this.setter.accept(value); + } + + @Override + public Integer getDefault() { + return this.defaultValue; + } + + @Override + public String asString() { + return Integer.toString(getValue()); + } + + @Override + public void fromString(String value) { + setValue(Integer.valueOf(value)); + } + + } + + public static class IntegerRange extends RangeEntry { + + public IntegerRange(Integer defaultValue, Consumer consumer, Supplier supplier, Integer minVal, Integer maxVal) { + super(defaultValue, consumer, supplier, minVal, maxVal); + } + + @Override + public Integer getValue() { + return this.getter.get(); + } + + @Override + public Integer getDefault() { + return this.defaultValue; + } + + @Override + public void fromString(String value) { + setValue(Integer.valueOf(value)); + } + + @Override + public String asString() { + return Integer.toString(getValue()); + } + + } + + public static class StringEntry extends Entry { + + public StringEntry(String defaultValue, Consumer consumer, Supplier supplier) { + super(defaultValue, consumer, supplier); + } + + @Override + public String getValue() { + return this.getter.get(); + } + + @Override + public void setValue(String value) { + this.setter.accept(value); + } + + @Override + public String getDefault() { + return this.defaultValue; + } + + @Override + public String asString() { + return getValue(); + } + + @Override + public void fromString(String value) { + setValue(value); + } + + } + + public static class EnumEntry> extends Entry { + + public EnumEntry(T defaultValue, Consumer consumer, Supplier supplier) { + super(defaultValue, consumer, supplier); + } + + @Override + public T getValue() { + return this.getter.get(); + } + + @Override + public void setValue(T value) { + this.setter.accept(value); + } + + @SuppressWarnings("unchecked") + public boolean setValue(String name) { + try { + this.setter.accept((T) Enum.valueOf(this.defaultValue.getClass(), name)); + return true; + } catch(IllegalArgumentException ex) { + BetterEnd.LOGGER.catching(ex); + } + + return false; + } + + @Override + public T getDefault() { + return this.defaultValue; + } + + @Override + public String asString() { + return getValue().name(); + } + + @Override + public void fromString(String value) { + this.setValue(value); + } + } + + public static abstract class RangeEntry> extends Entry { + + private final T min, max; + + public RangeEntry(T defaultValue, Consumer consumer, Supplier supplier, T minVal, T maxVal) { + super(defaultValue, consumer, supplier); + + this.min = minVal; + this.max = maxVal; + } + + @Override + public void setValue(T value) { + this.setter.accept(value.compareTo(min) < 0 ? min : value.compareTo(max) > 0 ? max : value); + } + + public T minValue() { + return this.min; + } + + public T maxValue() { + return this.max; + } + } + + public static abstract class Entry { + + protected final T defaultValue; + + protected final Consumer setter; + protected final Supplier getter; + + public Entry (T defaultValue, Consumer consumer, Supplier supplier) { + this.defaultValue = defaultValue; + this.setter = consumer; + this.getter = supplier; + } + + public abstract T getValue(); + public abstract void setValue(T value); + public abstract T getDefault(); + public abstract void fromString(String value); + public abstract String asString(); + + public void setDefault() { + this.setter.accept(defaultValue); + } + } +} diff --git a/src/main/java/ru/betterend/config/ConfigWriter.java b/src/main/java/ru/betterend/config/ConfigWriter.java new file mode 100644 index 00000000..430be957 --- /dev/null +++ b/src/main/java/ru/betterend/config/ConfigWriter.java @@ -0,0 +1,36 @@ +package ru.betterend.config; + +import java.io.File; +import java.nio.file.Path; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import net.fabricmc.loader.api.FabricLoader; + +import ru.betterend.BetterEnd; +import ru.betterend.util.JsonFactory; + +public class ConfigWriter { + + private final static FabricLoader fabricLoader = FabricLoader.getInstance(); + private final static Path GAME_CONFIG_DIR = fabricLoader.getConfigDir(); + private final static File MOD_CONFIG_DIR = new File(GAME_CONFIG_DIR.toFile(), BetterEnd.MOD_ID); + private final static File CONFIG_FILE = new File(MOD_CONFIG_DIR, "settings.json"); + + private static JsonObject configObject; + + private ConfigWriter() {} + + public static JsonObject load() { + if (configObject == null) { + configObject = JsonFactory.getJsonObject(CONFIG_FILE); + } + + return configObject; + } + + public static void save(JsonElement config) { + JsonFactory.storeJson(CONFIG_FILE, config); + } +} diff --git a/src/main/java/ru/betterend/util/JsonFactory.java b/src/main/java/ru/betterend/util/JsonFactory.java new file mode 100644 index 00000000..b43ab53e --- /dev/null +++ b/src/main/java/ru/betterend/util/JsonFactory.java @@ -0,0 +1,89 @@ +package ru.betterend.util; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import net.minecraft.resource.Resource; + +import ru.betterend.BetterEnd; + +public class JsonFactory { + + public final static Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + public static JsonObject getJsonObject(String path) throws IOException { + try (InputStream is = JsonFactory.class.getResourceAsStream(path)) { + Reader reader = new InputStreamReader(is); + JsonObject jsonObject = loadJson(reader).getAsJsonObject(); + if (jsonObject == null) { + return new JsonObject(); + } + return jsonObject; + } + } + + public static JsonObject getJsonObject(Resource jsonSource) { + if (jsonSource != null) { + try (InputStream is = jsonSource.getInputStream()) { + Reader reader = new InputStreamReader(is); + JsonObject jsonObject = loadJson(reader).getAsJsonObject(); + if (jsonObject == null) { + return new JsonObject(); + } + return jsonObject; + } catch (IOException ex) { + BetterEnd.LOGGER.catching(ex); + return new JsonObject(); + } + } + + return new JsonObject(); + } + + public static JsonObject getJsonObject(File jsonFile) { + if (jsonFile.exists()) { + JsonObject jsonObject = loadJson(jsonFile).getAsJsonObject(); + if (jsonObject == null) { + return new JsonObject(); + } + return jsonObject; + } + + return new JsonObject(); + } + + public static JsonElement loadJson(File jsonFile) { + if (jsonFile.exists()) { + try (Reader reader = new FileReader(jsonFile)) { + return loadJson(reader); + } catch (Exception ex) { + BetterEnd.LOGGER.catching(ex); + } + } + return null; + } + + public static JsonElement loadJson(Reader reader) { + return GSON.fromJson(reader, JsonElement.class); + } + + public static void storeJson(File jsonFile, JsonElement jsonObject) { + try(FileWriter writer = new FileWriter(jsonFile)) { + String json = GSON.toJson(jsonObject); + writer.write(json); + writer.flush(); + } catch (IOException ex) { + BetterEnd.LOGGER.catching(ex); + } + } +} diff --git a/src/main/java/ru/betterend/util/LangUtil.java b/src/main/java/ru/betterend/util/LangUtil.java new file mode 100644 index 00000000..f2a16ed9 --- /dev/null +++ b/src/main/java/ru/betterend/util/LangUtil.java @@ -0,0 +1,37 @@ +package ru.betterend.util; + +import net.minecraft.client.resource.language.I18n; +import net.minecraft.text.TranslatableText; +import ru.betterend.BetterEnd; + +public class LangUtil { + private final static String MODID = BetterEnd.MOD_ID; + + public final static String CONFIG_ELEMENT = "configuration"; + + private String element; + + public LangUtil(String element) { + this.element = element; + } + + public void setElement(String key) { + this.element = key; + } + + public String getString(String key) { + return getString(element, key); + } + + public TranslatableText getText(String key) { + return getText(element, key); + } + + public static String getString(String element, String key) { + return I18n.translate(String.format("%s.%s.%s", MODID, element, key)); + } + + public static TranslatableText getText(String element, String key) { + return new TranslatableText(getString(element, key)); + } +} diff --git a/src/main/java/ru/betterend/util/Logger.java b/src/main/java/ru/betterend/util/Logger.java new file mode 100644 index 00000000..235f4fdb --- /dev/null +++ b/src/main/java/ru/betterend/util/Logger.java @@ -0,0 +1,68 @@ +package ru.betterend.util; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; + +import ru.betterend.BetterEnd; + +public final class Logger { + + private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger(); + + private String modPref = "[" + BetterEnd.MOD_ID + "] "; + + private Logger() {} + + public static Logger get() { + return new Logger(); + } + + public void log(Level level, String message) { + LOGGER.log(level, modPref + message); + } + + public void log(Level level, String message, Object... params) { + LOGGER.log(level, modPref + message, params); + } + + public void debug(Object message) { + this.log(Level.DEBUG, message.toString()); + } + + public void debug(Object message, Object... params) { + this.log(Level.DEBUG, message.toString(), params); + } + + public void catching(Throwable ex) { + this.error(ex.getLocalizedMessage()); + LOGGER.catching(ex); + } + + public void info(String message) { + this.log(Level.INFO, message); + } + + public void info(String message, Object... params) { + this.log(Level.INFO, message, params); + } + + public void warning(String message) { + this.log(Level.WARN, message); + } + + public void warning(String message, Object obj, Exception ex) { + LOGGER.warn(modPref + message, obj, ex); + } + + public void error(String message) { + this.log(Level.ERROR, message); + } + + public void error(String message, Object obj, Exception ex) { + LOGGER.error(modPref + message, obj, ex); + } + + public void error(String message, Exception ex) { + LOGGER.error(modPref + message, ex); + } +}