diff --git a/src/main/java/ru/bclib/BCLib.java b/src/main/java/ru/bclib/BCLib.java index 5c30710d..1189f4e9 100644 --- a/src/main/java/ru/bclib/BCLib.java +++ b/src/main/java/ru/bclib/BCLib.java @@ -1,6 +1,8 @@ package ru.bclib; +import net.fabricmc.api.EnvType; import net.fabricmc.api.ModInitializer; +import net.fabricmc.loader.api.FabricLoader; import ru.bclib.util.Logger; public class BCLib implements ModInitializer { @@ -9,4 +11,12 @@ public class BCLib implements ModInitializer { @Override public void onInitialize() {} + + public static boolean isDevEnvironment() { + return FabricLoader.getInstance().isDevelopmentEnvironment(); + } + + public static boolean isClient() { + return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT; + } } diff --git a/src/main/java/ru/bclib/config/CategoryConfig.java b/src/main/java/ru/bclib/config/CategoryConfig.java new file mode 100644 index 00000000..ae2fb2e2 --- /dev/null +++ b/src/main/java/ru/bclib/config/CategoryConfig.java @@ -0,0 +1,10 @@ +package ru.bclib.config; + +public class CategoryConfig extends IdConfig { + + public CategoryConfig(String modID, String group) { + super(modID, group, (id, category) -> { + return new ConfigKey(id.getPath(), id.getNamespace(), category); + }); + } +} diff --git a/src/main/java/ru/bclib/config/Config.java b/src/main/java/ru/bclib/config/Config.java new file mode 100644 index 00000000..968c45d7 --- /dev/null +++ b/src/main/java/ru/bclib/config/Config.java @@ -0,0 +1,153 @@ +package ru.bclib.config; + +import org.jetbrains.annotations.Nullable; + +import ru.bclib.BCLib; +import ru.bclib.config.ConfigKeeper.BooleanEntry; +import ru.bclib.config.ConfigKeeper.Entry; +import ru.bclib.config.ConfigKeeper.FloatEntry; +import ru.bclib.config.ConfigKeeper.IntegerEntry; +import ru.bclib.config.ConfigKeeper.RangeEntry; +import ru.bclib.config.ConfigKeeper.StringEntry; + +public abstract class Config { + protected final ConfigKeeper keeper; + + protected abstract void registerEntries(); + + public Config(String modID, String group) { + this.keeper = new ConfigKeeper(modID, group); + this.registerEntries(); + } + + public void saveChanges() { + this.keeper.save(); + } + + @Nullable + public > E getEntry(ConfigKey key, Class type) { + return this.keeper.getEntry(key, type); + } + + @Nullable + public > T getDefault(ConfigKey key, Class type) { + Entry entry = keeper.getEntry(key, type); + return entry != null ? entry.getDefault() : null; + } + + protected String getString(ConfigKey key, String defaultValue) { + String str = keeper.getValue(key, StringEntry.class); + if (str == null) { + StringEntry entry = keeper.registerEntry(key, new StringEntry(defaultValue)); + return entry.getValue(); + } + return str != null ? str : defaultValue; + } + + protected String getString(ConfigKey key) { + String str = keeper.getValue(key, StringEntry.class); + return str != null ? str : ""; + } + + protected boolean setString(ConfigKey key, String value) { + try { + StringEntry entry = keeper.getEntry(key, StringEntry.class); + if (entry == null) return false; + entry.setValue(value); + return true; + } catch (NullPointerException ex) { + BCLib.LOGGER.catching(ex); + } + return false; + } + + protected int getInt(ConfigKey key, int defaultValue) { + Integer val = keeper.getValue(key, IntegerEntry.class); + if (val == null) { + IntegerEntry entry = keeper.registerEntry(key, new IntegerEntry(defaultValue)); + return entry.getValue(); + } + return val != null ? val : defaultValue; + } + + protected int getInt(ConfigKey key) { + Integer val = keeper.getValue(key, IntegerEntry.class); + return val != null ? val : 0; + } + + protected boolean setInt(ConfigKey key, int value) { + try { + IntegerEntry entry = keeper.getEntry(key, IntegerEntry.class); + if (entry == null) return false; + entry.setValue(value); + return true; + } catch (NullPointerException ex) { + BCLib.LOGGER.catching(ex); + } + return false; + } + + protected , RE extends RangeEntry> boolean setRanged(ConfigKey key, T value, Class type) { + try { + RangeEntry entry = keeper.getEntry(key, type); + if (entry == null) return false; + entry.setValue(value); + return true; + } catch (NullPointerException | ClassCastException ex) { + BCLib.LOGGER.catching(ex); + } + return false; + } + + protected float getFloat(ConfigKey key, float defaultValue) { + Float val = keeper.getValue(key, FloatEntry.class); + if (val == null) { + FloatEntry entry = keeper.registerEntry(key, new FloatEntry(defaultValue)); + return entry.getValue(); + } + return val; + } + + protected float getFloat(ConfigKey key) { + Float val = keeper.getValue(key, FloatEntry.class); + return val != null ? val : 0.0F; + } + + protected boolean setFloat(ConfigKey key, float value) { + try { + FloatEntry entry = keeper.getEntry(key, FloatEntry.class); + if (entry == null) return false; + entry.setValue(value); + return true; + } catch (NullPointerException ex) { + BCLib.LOGGER.catching(ex); + } + return false; + } + + protected boolean getBoolean(ConfigKey key, boolean defaultValue) { + Boolean val = keeper.getValue(key, BooleanEntry.class); + if (val == null) { + BooleanEntry entry = keeper.registerEntry(key, new BooleanEntry(defaultValue)); + return entry.getValue(); + } + return val; + } + + protected boolean getBoolean(ConfigKey key) { + Boolean val = keeper.getValue(key, BooleanEntry.class); + return val != null ? val : false; + } + + protected boolean setBoolean(ConfigKey key, boolean value) { + try { + BooleanEntry entry = keeper.getEntry(key, BooleanEntry.class); + if (entry == null) return false; + entry.setValue(value); + return true; + } catch (NullPointerException ex) { + BCLib.LOGGER.catching(ex); + } + return false; + } +} diff --git a/src/main/java/ru/bclib/config/ConfigKeeper.java b/src/main/java/ru/bclib/config/ConfigKeeper.java new file mode 100644 index 00000000..0fc7f049 --- /dev/null +++ b/src/main/java/ru/bclib/config/ConfigKeeper.java @@ -0,0 +1,320 @@ +package ru.bclib.config; + +import java.lang.reflect.Type; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import com.google.common.collect.Maps; +import com.google.common.reflect.TypeToken; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import net.minecraft.util.GsonHelper; +import ru.bclib.util.JsonFactory; + +public final class ConfigKeeper { + private final Map> configEntries = Maps.newHashMap(); + private final JsonObject configObject; + private final ConfigWriter writer; + + private boolean changed = false; + + public ConfigKeeper(String modID, String group) { + this.writer = new ConfigWriter(modID, group); + this.configObject = writer.load(); + } + + public void save() { + if (!changed) return; + this.writer.save(); + this.changed = false; + } + + private > void initializeEntry(ConfigKey key, E entry) { + if (configObject == null) { + return; + } + String[] path = key.getPath(); + JsonObject obj = configObject; + + if (!key.isRoot()) { + for (String group : path) { + JsonElement element = obj.get(group); + if (element == null || !element.isJsonObject()) { + element = new JsonObject(); + obj.add(group, element); + } + obj = element.getAsJsonObject(); + } + } + + String paramKey = key.getEntry(); + paramKey += " [default: " + entry.getDefault() + "]"; + + this.changed |= entry.setLocation(obj, paramKey); + } + + private > void storeValue(E entry, T value) { + if (configObject == null) { + return; + } + T val = entry.getValue(); + if (value.equals(val)) return; + entry.toJson(value); + this.changed = true; + } + + private > T getValue(E entry) { + if (!entry.hasLocation()) { + return entry.getDefault(); + } + return entry.fromJson(); + } + + @Nullable + public > E getEntry(ConfigKey key, Class type) { + Entry entry = this.configEntries.get(key); + if (type.isInstance(entry)) { + return type.cast(entry); + } + return null; + } + + @Nullable + public > T getValue(ConfigKey key, Class type) { + Entry entry = this.getEntry(key, type); + if (entry == null) { + return null; + } + return entry.getValue(); + } + + public > E registerEntry(ConfigKey key, E entry) { + entry.setWriter(value -> this.storeValue(entry, value)); + entry.setReader(() -> { + return this.getValue(entry); + }); + this.initializeEntry(key, entry); + this.configEntries.put(key, entry); + return entry; + } + + public static class BooleanEntry extends Entry { + + public BooleanEntry(Boolean defaultValue) { + super(defaultValue); + } + + @Override + public Boolean fromJson() { + return GsonHelper.getAsBoolean(location, key, defaultValue); + } + + @Override + public void toJson(Boolean value) { + this.location.addProperty(key, value); + } + } + + public static class FloatEntry extends Entry { + + public FloatEntry(Float defaultValue) { + super(defaultValue); + } + + @Override + public Float fromJson() { + return GsonHelper.getAsFloat(location, key, defaultValue); + } + + @Override + public void toJson(Float value) { + this.location.addProperty(key, value); + } + } + + public static class FloatRange extends RangeEntry { + + public FloatRange(Float defaultValue, float minVal, float maxVal) { + super(defaultValue, minVal, maxVal); + } + + @Override + public Float fromJson() { + return GsonHelper.getAsFloat(location, key, defaultValue); + } + + @Override + public void toJson(Float value) { + this.location.addProperty(key, value); + } + } + + public static class IntegerEntry extends Entry { + + public IntegerEntry(Integer defaultValue) { + super(defaultValue); + } + + @Override + public Integer getDefault() { + return this.defaultValue; + } + + @Override + public Integer fromJson() { + return GsonHelper.getAsInt(location, key, defaultValue); + } + + @Override + public void toJson(Integer value) { + this.location.addProperty(key, value); + } + } + + public static class IntegerRange extends RangeEntry { + + public IntegerRange(Integer defaultValue, int minVal, int maxVal) { + super(defaultValue, minVal, maxVal); + } + + @Override + public Integer fromJson() { + return GsonHelper.getAsInt(location, key, defaultValue); + } + + @Override + public void toJson(Integer value) { + this.location.addProperty(key, value); + } + } + + public static class StringEntry extends Entry { + + public StringEntry(String defaultValue) { + super(defaultValue); + } + + @Override + public String fromJson() { + return GsonHelper.getAsString(location, key, defaultValue); + } + + @Override + public void toJson(String value) { + this.location.addProperty(key, value); + } + + } + + public static class EnumEntry> extends Entry { + + private final Type type; + + public EnumEntry(T defaultValue) { + super(defaultValue); + TypeToken token = new TypeToken() { + private static final long serialVersionUID = 1L; + }; + this.type = token.getType(); + } + + @Override + public T getDefault() { + return this.defaultValue; + } + + @Override + public T fromJson() { + return JsonFactory.GSON.fromJson(location.get(key), type); + } + + @Override + public void toJson(T value) { + location.addProperty(key, JsonFactory.GSON.toJson(value, type)); + } + } + + public static abstract class RangeEntry> extends Entry { + + private final T min, max; + + public RangeEntry(T defaultValue, T minVal, T maxVal) { + super(defaultValue); + this.min = minVal; + this.max = maxVal; + } + + @Override + public void setValue(T value) { + super.setValue(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 Consumer writer; + protected Supplier reader; + protected JsonObject location; + protected String key; + + public abstract T fromJson(); + + public abstract void toJson(T value); + + public Entry(T defaultValue) { + this.defaultValue = defaultValue; + } + + protected void setWriter(Consumer writer) { + this.writer = writer; + } + + protected void setReader(Supplier reader) { + this.reader = reader; + } + + protected boolean setLocation(JsonObject location, String key) { + this.location = location; + this.key = key; + if (!location.has(key)) { + this.toJson(defaultValue); + return true; + } + return false; + } + + protected boolean hasLocation() { + return this.location != null && + this.key != null; + } + + public T getValue() { + return this.reader.get(); + } + + public void setValue(T value) { + this.writer.accept(value); + } + + public T getDefault() { + return this.defaultValue; + } + + public void setDefault() { + this.setValue(defaultValue); + } + } +} diff --git a/src/main/java/ru/bclib/config/ConfigKey.java b/src/main/java/ru/bclib/config/ConfigKey.java new file mode 100644 index 00000000..ed8b570d --- /dev/null +++ b/src/main/java/ru/bclib/config/ConfigKey.java @@ -0,0 +1,85 @@ +package ru.bclib.config; + +import net.minecraft.resources.ResourceLocation; + +public class ConfigKey { + private final String path[]; + private final String entry; + private final boolean root; + + public ConfigKey(String entry, String... path) { + this.validate(entry); + this.path = path; + this.entry = entry; + this.root = path.length == 0 || (path.length == 1 && path[0].isEmpty()); + } + + public ConfigKey(String entry, ResourceLocation path) { + this(entry, path.getNamespace(), path.getPath()); + } + + public String[] getPath() { + return path; + } + + public String getEntry() { + return entry; + } + + public boolean isRoot() { + return root; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + path.hashCode(); + result = prime * result + entry.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof ConfigKey)) { + return false; + } + ConfigKey other = (ConfigKey) obj; + if (other.path.length != path.length) { + return false; + } + for (int i = 0; i < path.length; i++) { + if (!path[i].equals(other.path[i])) { + return false; + } + } + if (!entry.equals(other.entry)) { + return false; + } + return true; + } + + @Override + public String toString() { + if (root) { + return String.format("[root]:%s", entry); + } + String p = path[0]; + for (int i = 1; i < path.length; i++) { + p += "." + path[i]; + } + return String.format("%s:%s", p, entry); + } + + private void validate(String entry) { + if (entry == null) { + throw new NullPointerException("Config key must be not null!"); + } + if (entry.isEmpty()) { + throw new IndexOutOfBoundsException("Config key must be not empty!"); + } + } +} diff --git a/src/main/java/ru/bclib/config/ConfigWriter.java b/src/main/java/ru/bclib/config/ConfigWriter.java new file mode 100644 index 00000000..ed4e125b --- /dev/null +++ b/src/main/java/ru/bclib/config/ConfigWriter.java @@ -0,0 +1,63 @@ +package ru.bclib.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.bclib.util.JsonFactory; + +public class ConfigWriter { + private final static Path GAME_CONFIG_DIR = FabricLoader.getInstance().getConfigDir(); + + private final File configFile; + private JsonObject configObject; + + public ConfigWriter(String modID, String configFile) { + this.configFile = new File(new File(GAME_CONFIG_DIR.toFile(), modID), configFile + ".json"); + File parent = this.configFile.getParentFile(); + if (!parent.exists()) { + parent.mkdirs(); + } + this.load(); + } + + public JsonObject getConfig() { + return configObject; + } + + public void save() { + if (configObject == null) { + return; + } + save(configFile, configObject); + } + + public JsonObject load() { + if (configObject == null) { + configObject = load(configFile); + } + return configObject; + } + + public void save(JsonElement config) { + this.configObject = config.getAsJsonObject(); + save(configFile, config); + } + + public static JsonObject load(File configFile) { + return JsonFactory.getJsonObject(configFile); + } + + public static void save(File configFile, JsonElement config) { + JsonFactory.storeJson(configFile, config); + } + + public static String scrubFileName(String input) { + input = input.replaceAll("[/\\ ]+", "_"); + input = input.replaceAll("[,:&\"\\|\\<\\>\\?\\*]", "_"); + return input; + } +} diff --git a/src/main/java/ru/bclib/config/EntryConfig.java b/src/main/java/ru/bclib/config/EntryConfig.java new file mode 100644 index 00000000..0b22de86 --- /dev/null +++ b/src/main/java/ru/bclib/config/EntryConfig.java @@ -0,0 +1,9 @@ +package ru.bclib.config; + +public class EntryConfig extends IdConfig { + public EntryConfig(String modID, String group) { + super(modID, group, (id, entry) -> { + return new ConfigKey(entry, id); + }); + } +} diff --git a/src/main/java/ru/bclib/config/IdConfig.java b/src/main/java/ru/bclib/config/IdConfig.java new file mode 100644 index 00000000..379d8551 --- /dev/null +++ b/src/main/java/ru/bclib/config/IdConfig.java @@ -0,0 +1,92 @@ +package ru.bclib.config; + +import java.util.function.BiFunction; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.resources.ResourceLocation; +import ru.bclib.config.ConfigKeeper.Entry; +import ru.bclib.config.ConfigKeeper.FloatRange; +import ru.bclib.config.ConfigKeeper.IntegerRange; + +public class IdConfig extends Config { + protected final BiFunction keyFactory; + + public IdConfig(String modID, String group, BiFunction keyFactory) { + super(modID, group); + this.keyFactory = keyFactory; + } + + @Override + protected void registerEntries() {} + + protected ConfigKey createKey(ResourceLocation id, String key) { + return this.keyFactory.apply(id, key); + } + + @Nullable + public > E getEntry(ResourceLocation id, String key, Class type) { + return this.getEntry(createKey(id, key), type); + } + + @Nullable + public > T getDefault(ResourceLocation id, String key, Class type) { + return this.getDefault(createKey(id, key), type); + } + + public String getString(ResourceLocation id, String key, String defaultValue) { + return this.getString(createKey(id, key), defaultValue); + } + + public String getString(ResourceLocation id, String key) { + return this.getString(createKey(id, key)); + } + + public boolean setString(ResourceLocation id, String key, String value) { + return this.setString(createKey(id, key), value); + } + + public int getInt(ResourceLocation id, String key, int defaultValue) { + return this.getInt(createKey(id, key), defaultValue); + } + + public int getInt(ResourceLocation id, String key) { + return this.getInt(createKey(id, key)); + } + + public boolean setInt(ResourceLocation id, String key, int value) { + return this.setInt(createKey(id, key), value); + } + + public boolean setRangedInt(ResourceLocation id, String key, int value) { + return this.setRanged(createKey(id, key), value, IntegerRange.class); + } + + public boolean setRangedFloat(ResourceLocation id, String key, float value) { + return this.setRanged(createKey(id, key), value, FloatRange.class); + } + + public float getFloat(ResourceLocation id, String key, float defaultValue) { + return this.getFloat(createKey(id, key), defaultValue); + } + + public float getFloat(ResourceLocation id, String key) { + return this.getFloat(createKey(id, key)); + } + + public boolean setFloat(ResourceLocation id, String key, float value) { + return this.setFloat(createKey(id, key), value); + } + + public boolean getBoolean(ResourceLocation id, String key, boolean defaultValue) { + return this.getBoolean(createKey(id, key), defaultValue); + } + + public boolean getBoolean(ResourceLocation id, String key) { + return this.getBoolean(createKey(id, key)); + } + + public boolean setBoolean(ResourceLocation id, String key, boolean value) { + return this.setBoolean(createKey(id, key), value); + } +} diff --git a/src/main/java/ru/bclib/config/PathConfig.java b/src/main/java/ru/bclib/config/PathConfig.java new file mode 100644 index 00000000..3f7bc3e9 --- /dev/null +++ b/src/main/java/ru/bclib/config/PathConfig.java @@ -0,0 +1,149 @@ +package ru.bclib.config; + +import org.jetbrains.annotations.Nullable; + +import ru.bclib.config.ConfigKeeper.Entry; +import ru.bclib.config.ConfigKeeper.FloatRange; +import ru.bclib.config.ConfigKeeper.IntegerRange; + +public class PathConfig extends Config { + + public PathConfig(String modID, String group) { + super(modID, group); + } + + @Override + protected void registerEntries() {} + + protected ConfigKey createKey(String category, String key) { + return new ConfigKey(key, category.split("\\.")); + } + + protected ConfigKey createKey(String key) { + return createKey("", key); + } + + @Nullable + public > E getEntry(String category, String key, Class type) { + return this.getEntry(createKey(category, key), type); + } + + @Nullable + public > T getDefault(String category, String key, Class type) { + return this.getDefault(createKey(category, key), type); + } + + public String getString(String category, String key, String defaultValue) { + return this.getString(createKey(category, key), defaultValue); + } + + public String getString(String category, String key) { + return this.getString(createKey(category, key)); + } + + public boolean setString(String category, String key, String value) { + return this.setString(createKey(category, key), value); + } + + public int getInt(String category, String key, int defaultValue) { + return this.getInt(createKey(category, key), defaultValue); + } + + public int getInt(String category, String key) { + return this.getInt(createKey(category, key)); + } + + public boolean setInt(String category, String key, int value) { + return this.setInt(createKey(category, key), value); + } + + public boolean setRangedInt(String category, String key, int value) { + return this.setRanged(createKey(category, key), value, IntegerRange.class); + } + + public boolean setRangedFloat(String category, String key, float value) { + return this.setRanged(createKey(category, key), value, FloatRange.class); + } + + public float getFloat(String category, String key, float defaultValue) { + return this.getFloat(createKey(category, key), defaultValue); + } + + public float getFloat(String category, String key) { + return this.getFloat(createKey(category, key)); + } + + public boolean setFloat(String category, String key, float value) { + return this.setFloat(createKey(category, key), value); + } + + public boolean getBoolean(String category, String key, boolean defaultValue) { + return this.getBoolean(createKey(category, key), defaultValue); + } + + public boolean getBoolean(String category, String key) { + return this.getBoolean(createKey(category, key)); + } + + public boolean setBoolean(String category, String key, boolean value) { + return this.setBoolean(createKey(category, key), value); + } + + // From Root + + public String getStringRoot(String key, String defaultValue) { + return this.getString(createKey(key), defaultValue); + } + + public String getStringRoot(String key) { + return this.getString(createKey(key)); + } + + public boolean setStringRoot(String key, String value) { + return this.setString(createKey(key), value); + } + + public int getIntRoot(String key, int defaultValue) { + return this.getInt(createKey(key), defaultValue); + } + + public int getIntRoot(String key) { + return this.getInt(createKey(key)); + } + + public boolean setIntRoot(String key, int value) { + return this.setInt(createKey(key), value); + } + + public boolean setRangedIntRoot(String key, int value) { + return this.setRanged(createKey(key), value, IntegerRange.class); + } + + public boolean setRangedFloatRoot(String key, float value) { + return this.setRanged(createKey(key), value, FloatRange.class); + } + + public float getFloatRoot(String key, float defaultValue) { + return this.getFloat(createKey(key), defaultValue); + } + + public float getFloatRoot(String key) { + return this.getFloat(createKey(key)); + } + + public boolean setFloatRoot(String key, float value) { + return this.setFloat(createKey(key), value); + } + + public boolean getBooleanRoot(String key, boolean defaultValue) { + return this.getBoolean(createKey(key), defaultValue); + } + + public boolean getBooleanRoot(String key) { + return this.getBoolean(createKey(key)); + } + + public boolean setBooleanRoot(String key, boolean value) { + return this.setBoolean(createKey(key), value); + } +} diff --git a/src/main/java/ru/bclib/sdf/SDF.java b/src/main/java/ru/bclib/sdf/SDF.java index ca89f7e3..396850de 100644 --- a/src/main/java/ru/bclib/sdf/SDF.java +++ b/src/main/java/ru/bclib/sdf/SDF.java @@ -17,8 +17,8 @@ import net.minecraft.core.Direction; import net.minecraft.world.level.ServerLevelAccessor; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; -import ru.bclib.structures.StructureWorld; import ru.bclib.util.BlocksHelper; +import ru.bclib.world.structures.StructureWorld; public abstract class SDF { private List> postProcesses = Lists.newArrayList(); diff --git a/src/main/java/ru/bclib/util/JsonFactory.java b/src/main/java/ru/bclib/util/JsonFactory.java new file mode 100644 index 00000000..9397f32c --- /dev/null +++ b/src/main/java/ru/bclib/util/JsonFactory.java @@ -0,0 +1,93 @@ +package ru.bclib.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 ru.bclib.BCLib; + +public class JsonFactory { + public final static Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + public static JsonObject getJsonObject(InputStream stream) { + try { + Reader reader = new InputStreamReader(stream); + JsonElement json = loadJson(reader); + if (json != null && json.isJsonObject()) { + JsonObject jsonObject = json.getAsJsonObject(); + return jsonObject != null ? jsonObject : new JsonObject(); + } + } + catch (Exception ex) { + BCLib.LOGGER.catching(ex); + } + return new JsonObject(); + } + + public static JsonObject getJsonObject(File jsonFile) { + if (jsonFile.exists()) { + JsonElement json = loadJson(jsonFile); + if (json != null && json.isJsonObject()) { + JsonObject jsonObject = json.getAsJsonObject(); + return jsonObject != null ? jsonObject : new 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) { + BCLib.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) { + BCLib.LOGGER.catching(ex); + } + } + + public static int getInt(JsonObject object, String member, int def) { + JsonElement elem = object.get(member); + return elem == null ? def : elem.getAsInt(); + } + + public static float getFloat(JsonObject object, String member, float def) { + JsonElement elem = object.get(member); + return elem == null ? def : elem.getAsFloat(); + } + + public static boolean getBoolean(JsonObject object, String member, boolean def) { + JsonElement elem = object.get(member); + return elem == null ? def : elem.getAsBoolean(); + } + + public static String getString(JsonObject object, String member, String def) { + JsonElement elem = object.get(member); + return elem == null ? def : elem.getAsString(); + } +} diff --git a/src/main/java/ru/bclib/world/structures/BCLStructureFeature.java b/src/main/java/ru/bclib/world/structures/BCLStructureFeature.java new file mode 100644 index 00000000..581f0b60 --- /dev/null +++ b/src/main/java/ru/bclib/world/structures/BCLStructureFeature.java @@ -0,0 +1,42 @@ +package ru.bclib.world.structures; + +import java.util.Random; + +import net.fabricmc.fabric.api.structure.v1.FabricStructureBuilder; +import net.minecraft.data.BuiltinRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature; +import net.minecraft.world.level.levelgen.feature.StructureFeature; +import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration; + +public class BCLStructureFeature { + private static final Random RANDOM = new Random(354); + private final StructureFeature structure; + private final ConfiguredStructureFeature featureConfigured; + private final GenerationStep.Decoration featureStep; + + public BCLStructureFeature(ResourceLocation id, StructureFeature structure, GenerationStep.Decoration step, int spacing, int separation) { + this.featureStep = step; + this.structure = FabricStructureBuilder.create(id, structure) + .step(step) + .defaultConfig(spacing, separation, RANDOM.nextInt(8192)) + .register(); + + this.featureConfigured = this.structure.configured(NoneFeatureConfiguration.NONE); + + BuiltinRegistries.register(BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE, id, this.featureConfigured); + } + + public StructureFeature getStructure() { + return structure; + } + + public ConfiguredStructureFeature getFeatureConfigured() { + return featureConfigured; + } + + public GenerationStep.Decoration getFeatureStep() { + return featureStep; + } +} diff --git a/src/main/java/ru/bclib/structures/StructureWorld.java b/src/main/java/ru/bclib/world/structures/StructureWorld.java similarity index 95% rename from src/main/java/ru/bclib/structures/StructureWorld.java rename to src/main/java/ru/bclib/world/structures/StructureWorld.java index 78b1c05f..af49651b 100644 --- a/src/main/java/ru/bclib/structures/StructureWorld.java +++ b/src/main/java/ru/bclib/world/structures/StructureWorld.java @@ -1,4 +1,4 @@ -package ru.bclib.structures; +package ru.bclib.world.structures; import java.util.Map;