Reorganized Imports/Packages
This commit is contained in:
parent
cb9459f176
commit
3ee10482ab
721 changed files with 34873 additions and 33558 deletions
10
src/main/java/org/betterx/bclib/config/CategoryConfig.java
Normal file
10
src/main/java/org/betterx/bclib/config/CategoryConfig.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
package org.betterx.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);
|
||||
});
|
||||
}
|
||||
}
|
92
src/main/java/org/betterx/bclib/config/ClientConfig.java
Normal file
92
src/main/java/org/betterx/bclib/config/ClientConfig.java
Normal file
|
@ -0,0 +1,92 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.dataexchange.handler.autosync.AutoSync;
|
||||
|
||||
public class ClientConfig extends NamedPathConfig {
|
||||
public static final ConfigToken<Boolean> SUPPRESS_EXPERIMENTAL_DIALOG = ConfigToken.Boolean(false,
|
||||
"suppressExperimentalDialogOnLoad",
|
||||
"ui");
|
||||
|
||||
@ConfigUI(topPadding = 12)
|
||||
public static final ConfigToken<Boolean> ENABLED = ConfigToken.Boolean(true, "enabled", AutoSync.SYNC_CATEGORY);
|
||||
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final DependendConfigToken<Boolean> ACCEPT_CONFIGS = DependendConfigToken.Boolean(true,
|
||||
"acceptConfigs",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final DependendConfigToken<Boolean> ACCEPT_FILES = DependendConfigToken.Boolean(true,
|
||||
"acceptFiles",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final DependendConfigToken<Boolean> ACCEPT_MODS = DependendConfigToken.Boolean(false,
|
||||
"acceptMods",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final DependendConfigToken<Boolean> DISPLAY_MOD_INFO = DependendConfigToken.Boolean(true,
|
||||
"displayModInfo",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
|
||||
@ConfigUI(topPadding = 12)
|
||||
public static final ConfigToken<Boolean> DEBUG_HASHES = ConfigToken.Boolean(false,
|
||||
"debugHashes",
|
||||
AutoSync.SYNC_CATEGORY);
|
||||
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final ConfigToken<Boolean> CUSTOM_FOG_RENDERING = ConfigToken.Boolean(true,
|
||||
"customFogRendering",
|
||||
"rendering");
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final ConfigToken<Boolean> NETHER_THICK_FOG = ConfigToken.Boolean(true,
|
||||
"netherThickFog",
|
||||
"rendering");
|
||||
|
||||
public ClientConfig() {
|
||||
super(BCLib.MOD_ID, "client", false);
|
||||
}
|
||||
|
||||
public boolean shouldPrintDebugHashes() {
|
||||
return get(DEBUG_HASHES);
|
||||
}
|
||||
|
||||
public boolean isAllowingAutoSync() {
|
||||
return get(ENABLED);
|
||||
}
|
||||
|
||||
public boolean isAcceptingMods() {
|
||||
return get(ACCEPT_MODS) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean isAcceptingConfigs() {
|
||||
return get(ACCEPT_CONFIGS) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean isAcceptingFiles() {
|
||||
return get(ACCEPT_FILES) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean isShowingModInfo() {
|
||||
return get(DISPLAY_MOD_INFO) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean suppressExperimentalDialog() {
|
||||
return get(SUPPRESS_EXPERIMENTAL_DIALOG);
|
||||
}
|
||||
|
||||
public boolean netherThickFog() {
|
||||
return get(NETHER_THICK_FOG);
|
||||
}
|
||||
|
||||
public boolean renderCustomFog() {
|
||||
return get(CUSTOM_FOG_RENDERING);
|
||||
}
|
||||
}
|
234
src/main/java/org/betterx/bclib/config/Config.java
Normal file
234
src/main/java/org/betterx/bclib/config/Config.java
Normal file
|
@ -0,0 +1,234 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.api.dataexchange.SyncFileHash;
|
||||
import org.betterx.bclib.api.dataexchange.handler.autosync.AutoSyncID;
|
||||
import org.betterx.bclib.api.dataexchange.handler.autosync.FileContentWrapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class Config {
|
||||
protected final static Map<AutoSyncID, Config> AUTO_SYNC_CONFIGS = new HashMap<>();
|
||||
public static final String CONFIG_SYNC_PREFIX = "CONFIG_";
|
||||
protected final ConfigKeeper keeper;
|
||||
protected final boolean autoSync;
|
||||
public final String configID;
|
||||
|
||||
protected abstract void registerEntries();
|
||||
|
||||
protected Config(String modID, String group) {
|
||||
this(modID, group, true, false);
|
||||
}
|
||||
|
||||
protected Config(String modID, String group, boolean autoSync) {
|
||||
this(modID, group, autoSync, false);
|
||||
}
|
||||
|
||||
protected Config(String modID, String group, boolean autoSync, boolean diffContent) {
|
||||
configID = modID + "." + group;
|
||||
this.keeper = new ConfigKeeper(modID, group);
|
||||
this.registerEntries();
|
||||
this.autoSync = autoSync;
|
||||
|
||||
if (autoSync) {
|
||||
final String uid = CONFIG_SYNC_PREFIX + configID;
|
||||
final AutoSyncID aid = new AutoSyncID(BCLib.MOD_ID, uid);
|
||||
if (diffContent)
|
||||
DataExchangeAPI.addAutoSyncFile(aid.modID, aid.uniqueID, keeper.getConfigFile(), this::compareForSync);
|
||||
else
|
||||
DataExchangeAPI.addAutoSyncFile(aid.modID, aid.uniqueID, keeper.getConfigFile());
|
||||
|
||||
AUTO_SYNC_CONFIGS.put(aid, this);
|
||||
BCLib.LOGGER.info("Added Config " + configID + " to auto sync (" + (diffContent
|
||||
? "content diff"
|
||||
: "file hash") + ")");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean compareForSync(SyncFileHash clientHash, SyncFileHash serverHash, FileContentWrapper content) {
|
||||
//identical hashes => nothing to do
|
||||
if (clientHash.equals(serverHash)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return keeper.compareAndUpdateForSync(content);
|
||||
}
|
||||
|
||||
public void saveChanges() {
|
||||
this.keeper.save();
|
||||
}
|
||||
|
||||
public static void reloadSyncedConfig(AutoSyncID aid, File file) {
|
||||
Config cfg = AUTO_SYNC_CONFIGS.get(aid);
|
||||
if (cfg != null) {
|
||||
cfg.reload();
|
||||
}
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
this.keeper.reload();
|
||||
BCLib.LOGGER.info("Did Reload " + keeper.getConfigFile());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, E extends ConfigKeeper.Entry<T>> E getEntry(ConfigKey key, Class<E> type) {
|
||||
return this.keeper.getEntry(key, type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, E extends ConfigKeeper.Entry<T>> T getDefault(ConfigKey key, Class<E> type) {
|
||||
ConfigKeeper.Entry<T> entry = keeper.getEntry(key, type);
|
||||
return entry != null ? entry.getDefault() : null;
|
||||
}
|
||||
|
||||
protected String getString(ConfigKey key, String defaultValue) {
|
||||
String str = keeper.getValue(key, ConfigKeeper.StringEntry.class);
|
||||
if (str == null) {
|
||||
ConfigKeeper.StringEntry entry = keeper.registerEntry(key, new ConfigKeeper.StringEntry(defaultValue));
|
||||
return entry.getValue();
|
||||
}
|
||||
return str != null ? str : defaultValue;
|
||||
}
|
||||
|
||||
protected String getString(ConfigKey key) {
|
||||
String str = keeper.getValue(key, ConfigKeeper.StringEntry.class);
|
||||
return str != null ? str : "";
|
||||
}
|
||||
|
||||
protected boolean setString(ConfigKey key, String value) {
|
||||
try {
|
||||
ConfigKeeper.StringEntry entry = keeper.getEntry(key, ConfigKeeper.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, ConfigKeeper.IntegerEntry.class);
|
||||
if (val == null) {
|
||||
ConfigKeeper.IntegerEntry entry = keeper.registerEntry(key, new ConfigKeeper.IntegerEntry(defaultValue));
|
||||
return entry.getValue();
|
||||
}
|
||||
return val != null ? val : defaultValue;
|
||||
}
|
||||
|
||||
protected int getInt(ConfigKey key) {
|
||||
Integer val = keeper.getValue(key, ConfigKeeper.IntegerEntry.class);
|
||||
return val != null ? val : 0;
|
||||
}
|
||||
|
||||
protected boolean setInt(ConfigKey key, int value) {
|
||||
try {
|
||||
ConfigKeeper.IntegerEntry entry = keeper.getEntry(key, ConfigKeeper.IntegerEntry.class);
|
||||
if (entry == null) return false;
|
||||
entry.setValue(value);
|
||||
return true;
|
||||
} catch (NullPointerException ex) {
|
||||
BCLib.LOGGER.catching(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected <T extends Comparable<T>, RE extends ConfigKeeper.RangeEntry<T>> boolean setRanged(ConfigKey key,
|
||||
T value,
|
||||
Class<RE> type) {
|
||||
try {
|
||||
ConfigKeeper.RangeEntry<T> 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, ConfigKeeper.FloatEntry.class);
|
||||
if (val == null) {
|
||||
ConfigKeeper.FloatEntry entry = keeper.registerEntry(key, new ConfigKeeper.FloatEntry(defaultValue));
|
||||
return entry.getValue();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
protected float getFloat(ConfigKey key) {
|
||||
Float val = keeper.getValue(key, ConfigKeeper.FloatEntry.class);
|
||||
return val != null ? val : 0.0F;
|
||||
}
|
||||
|
||||
protected boolean setFloat(ConfigKey key, float value) {
|
||||
try {
|
||||
ConfigKeeper.FloatEntry entry = keeper.getEntry(key, ConfigKeeper.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, ConfigKeeper.BooleanEntry.class);
|
||||
if (val == null) {
|
||||
ConfigKeeper.BooleanEntry entry = keeper.registerEntry(key, new ConfigKeeper.BooleanEntry(defaultValue));
|
||||
return entry.getValue();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
protected boolean getBoolean(ConfigKey key) {
|
||||
Boolean val = keeper.getValue(key, ConfigKeeper.BooleanEntry.class);
|
||||
return val != null ? val : false;
|
||||
}
|
||||
|
||||
protected boolean setBoolean(ConfigKey key, boolean value) {
|
||||
try {
|
||||
ConfigKeeper.BooleanEntry entry = keeper.getEntry(key, ConfigKeeper.BooleanEntry.class);
|
||||
if (entry == null) return false;
|
||||
entry.setValue(value);
|
||||
return true;
|
||||
} catch (NullPointerException ex) {
|
||||
BCLib.LOGGER.catching(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected List<String> getStringArray(ConfigKey key, List<String> defaultValue) {
|
||||
List<String> str = keeper.getValue(key, ConfigKeeper.StringArrayEntry.class);
|
||||
if (str == null) {
|
||||
ConfigKeeper.StringArrayEntry entry = keeper.registerEntry(key,
|
||||
new ConfigKeeper.StringArrayEntry(defaultValue));
|
||||
return entry.getValue();
|
||||
}
|
||||
return str != null ? str : defaultValue;
|
||||
}
|
||||
|
||||
protected List<String> getStringArray(ConfigKey key) {
|
||||
List<String> str = keeper.getValue(key, ConfigKeeper.StringArrayEntry.class);
|
||||
return str != null ? str : new ArrayList<>(0);
|
||||
}
|
||||
|
||||
protected boolean setStringArray(ConfigKey key, List<String> value) {
|
||||
try {
|
||||
ConfigKeeper.StringArrayEntry entry = keeper.getEntry(key, ConfigKeeper.StringArrayEntry.class);
|
||||
if (entry == null) return false;
|
||||
entry.setValue(value);
|
||||
return true;
|
||||
} catch (NullPointerException ex) {
|
||||
BCLib.LOGGER.catching(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
457
src/main/java/org/betterx/bclib/config/ConfigKeeper.java
Normal file
457
src/main/java/org/betterx/bclib/config/ConfigKeeper.java
Normal file
|
@ -0,0 +1,457 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import net.minecraft.util.GsonHelper;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.betterx.bclib.api.dataexchange.handler.autosync.FileContentWrapper;
|
||||
import org.betterx.bclib.util.JsonFactory;
|
||||
import org.betterx.bclib.util.Pair;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class ConfigKeeper {
|
||||
private final Map<ConfigKey, Entry<?>> configEntries = Maps.newHashMap();
|
||||
private final ConfigWriter writer;
|
||||
|
||||
private JsonObject configObject;
|
||||
private boolean changed = false;
|
||||
|
||||
public ConfigKeeper(String modID, String group) {
|
||||
this.writer = new ConfigWriter(modID, group);
|
||||
this.configObject = writer.load();
|
||||
}
|
||||
|
||||
public File getConfigFile() {
|
||||
return this.writer.getConfigFile();
|
||||
}
|
||||
|
||||
boolean compareAndUpdateForSync(FileContentWrapper content) {
|
||||
ByteArrayInputStream inputStream = content.getInputStream();
|
||||
final JsonObject other = JsonFactory.getJsonObject(inputStream);
|
||||
|
||||
boolean changed = this.compareAndUpdateForSync(other);
|
||||
if (changed) {
|
||||
OutputStream outStream = content.getEmptyOutputStream();
|
||||
JsonFactory.storeJson(outStream, this.configObject);
|
||||
content.syncWithOutputStream();
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
boolean compareAndUpdateForSync(JsonObject other) {
|
||||
return compareAndUpdateForSync(this.configObject, other);
|
||||
}
|
||||
|
||||
private static Pair<JsonElement, Pair<String, String>> find(JsonObject json, Pair<String, String> key) {
|
||||
for (var entry : json.entrySet()) {
|
||||
final Pair<String, String> otherKey = ConfigKey.realKey(entry.getKey());
|
||||
if (otherKey.first.equals(key.first)) return new Pair<>(entry.getValue(), otherKey);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for content based auto-sync.
|
||||
*
|
||||
* @param me - When called in AutoSync this represents the content of the client.
|
||||
* @param other - When called in AutoSync, this represents the content of the server
|
||||
* @return {@code true} if content was changed
|
||||
*/
|
||||
static boolean compareAndUpdateForSync(JsonObject me, JsonObject other) {
|
||||
boolean changed = false;
|
||||
for (var otherEntry : other.entrySet()) {
|
||||
final Pair<String, String> otherKey = ConfigKey.realKey(otherEntry.getKey());
|
||||
final JsonElement otherValue = otherEntry.getValue();
|
||||
|
||||
Pair<JsonElement, Pair<String, String>> temp = find(me, otherKey);
|
||||
//we already have an entry
|
||||
if (temp != null) {
|
||||
final Pair<String, String> myKey = temp.second;
|
||||
final JsonElement myValue = temp.first;
|
||||
|
||||
if ((otherValue.isJsonNull() && !myValue.isJsonNull()) || (otherValue.isJsonPrimitive() && !myValue.isJsonPrimitive()) || (otherValue.isJsonObject() && !myValue.isJsonObject()) || (otherValue.isJsonArray() && !myValue.isJsonArray())) {
|
||||
//types are different => replace with "server"-version in other
|
||||
changed = true;
|
||||
me.add(myKey.first + myKey.second, otherValue);
|
||||
} else if (otherValue.isJsonPrimitive() || otherValue.isJsonArray() || otherValue.isJsonNull()) {
|
||||
if (!otherValue.equals(myValue)) {
|
||||
changed = true;
|
||||
me.add(myKey.first + myKey.second, otherValue);
|
||||
}
|
||||
} else if (otherValue.isJsonObject()) {
|
||||
changed |= compareAndUpdateForSync(myValue.getAsJsonObject(), otherValue.getAsJsonObject());
|
||||
}
|
||||
} else { //no entry, just copy the value from other
|
||||
if (!otherValue.isJsonNull()) {
|
||||
changed = true;
|
||||
temp = find(me, otherKey);
|
||||
me.add(otherKey.first + otherKey.second, otherValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
public void save() {
|
||||
if (!changed) return;
|
||||
this.writer.save();
|
||||
this.changed = false;
|
||||
}
|
||||
|
||||
void reload() {
|
||||
this.configObject = this.writer.reload();
|
||||
this.configEntries.clear();
|
||||
this.changed = false;
|
||||
}
|
||||
|
||||
private <T, E extends Entry<T>> 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();
|
||||
if (entry.hasDefaultInName()) {
|
||||
paramKey += " [default: " + entry.getDefault() + "]";
|
||||
}
|
||||
|
||||
this.changed |= entry.setLocation(obj, paramKey);
|
||||
}
|
||||
|
||||
private <T, E extends Entry<T>> 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, E extends Entry<T>> T getValue(E entry) {
|
||||
if (!entry.hasLocation()) {
|
||||
return entry.getDefault();
|
||||
}
|
||||
return entry.fromJson();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, E extends Entry<T>> E getEntry(ConfigKey key, Class<E> type) {
|
||||
Entry<?> entry = this.configEntries.get(key);
|
||||
if (type.isInstance(entry)) {
|
||||
return type.cast(entry);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, E extends Entry<T>> T getValue(ConfigKey key, Class<E> type) {
|
||||
Entry<T> entry = this.getEntry(key, type);
|
||||
if (entry == null) {
|
||||
return null;
|
||||
}
|
||||
return entry.getValue();
|
||||
}
|
||||
|
||||
public <T, E extends Entry<T>> 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<Boolean> {
|
||||
|
||||
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<Float> {
|
||||
|
||||
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<Float> {
|
||||
|
||||
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<Integer> {
|
||||
|
||||
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<Integer> {
|
||||
|
||||
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<String> {
|
||||
|
||||
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 abstract class ArrayEntry<T> extends Entry<List<T>> {
|
||||
public ArrayEntry(List<T> defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
protected abstract T getValue(JsonElement element);
|
||||
protected abstract void add(JsonArray array, T element);
|
||||
|
||||
private JsonArray toArray(List<T> input) {
|
||||
final JsonArray array = new JsonArray();
|
||||
input.forEach(s -> add(array, s));
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> fromJson() {
|
||||
final JsonArray resArray = GsonHelper.getAsJsonArray(location, key, toArray(defaultValue));
|
||||
final List<T> res = new ArrayList<>(resArray.size());
|
||||
resArray.forEach(e -> res.add(getValue(e)));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toJson(List<T> value) {
|
||||
this.location.add(key, toArray(value));
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringArrayEntry extends ArrayEntry<String> {
|
||||
public StringArrayEntry(List<String> defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getValue(JsonElement el) {
|
||||
return el.getAsString();
|
||||
}
|
||||
|
||||
protected void add(JsonArray array, String el) {
|
||||
array.add(el);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasDefaultInName() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static class EnumEntry<T extends Enum<T>> extends Entry<T> {
|
||||
private final Type type;
|
||||
|
||||
public EnumEntry(T defaultValue) {
|
||||
super(defaultValue);
|
||||
TypeToken<T> token = new TypeToken<T>() {
|
||||
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<T extends Comparable<T>> extends Entry<T> {
|
||||
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<T> {
|
||||
protected final T defaultValue;
|
||||
protected Consumer<T> writer;
|
||||
protected Supplier<T> 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<T> writer) {
|
||||
this.writer = writer;
|
||||
}
|
||||
|
||||
protected void setReader(Supplier<T> 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);
|
||||
}
|
||||
|
||||
protected boolean hasDefaultInName() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
97
src/main/java/org/betterx/bclib/config/ConfigKey.java
Normal file
97
src/main/java/org/betterx/bclib/config/ConfigKey.java
Normal file
|
@ -0,0 +1,97 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import org.betterx.bclib.util.Pair;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
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 + Arrays.hashCode(path);
|
||||
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;
|
||||
}
|
||||
}
|
||||
return entry.equals(other.entry);
|
||||
}
|
||||
|
||||
@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!");
|
||||
}
|
||||
}
|
||||
|
||||
public static Pair<String, String> realKey(@NotNull String key) {
|
||||
String[] parts = key.split("\\[default:", 2);
|
||||
if (parts.length == 1) {
|
||||
return new Pair(parts[0].trim(), "");
|
||||
} else if (parts.length == 2) {
|
||||
return new Pair(parts[0].trim(), " " + ("[default:" + parts[1]).trim());
|
||||
}
|
||||
return new Pair(key, "");
|
||||
}
|
||||
}
|
25
src/main/java/org/betterx/bclib/config/ConfigUI.java
Normal file
25
src/main/java/org/betterx/bclib/config/ConfigUI.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface ConfigUI {
|
||||
/**
|
||||
* When {@code true}, this option will not generate UI-Elements.
|
||||
*/
|
||||
boolean hide() default false;
|
||||
|
||||
/**
|
||||
* When a Widget is generated for this option, it will be indented by this Value
|
||||
*/
|
||||
int leftPadding() default 0;
|
||||
|
||||
/**
|
||||
* When a Widget is generated for this option, it will be indented by this Value
|
||||
*/
|
||||
int topPadding() default 0;
|
||||
}
|
72
src/main/java/org/betterx/bclib/config/ConfigWriter.java
Normal file
72
src/main/java/org/betterx/bclib/config/ConfigWriter.java
Normal file
|
@ -0,0 +1,72 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.betterx.bclib.util.JsonFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
||||
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(GAME_CONFIG_DIR.resolve(modID).toFile(), configFile + ".json");
|
||||
File parent = this.configFile.getParentFile();
|
||||
if (!parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
this.load();
|
||||
}
|
||||
|
||||
File getConfigFile() {
|
||||
return this.configFile;
|
||||
}
|
||||
|
||||
public JsonObject getConfig() {
|
||||
return configObject;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
if (configObject == null) {
|
||||
return;
|
||||
}
|
||||
save(configFile, configObject);
|
||||
}
|
||||
|
||||
JsonObject reload() {
|
||||
configObject = load(configFile);
|
||||
return 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;
|
||||
}
|
||||
}
|
42
src/main/java/org/betterx/bclib/config/Configs.java
Normal file
42
src/main/java/org/betterx/bclib/config/Configs.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class Configs {
|
||||
// Client and Server-Config must be the first entries. They are not part of the Auto-Sync process
|
||||
// But will be needed by other Auto-Sync Config-Files
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static final ClientConfig CLIENT_CONFIG = new ClientConfig();
|
||||
public static final ServerConfig SERVER_CONFIG = new ServerConfig();
|
||||
|
||||
public static final GeneratorConfig GENERATOR_CONFIG = new GeneratorConfig();
|
||||
public static final MainConfig MAIN_CONFIG = new MainConfig();
|
||||
|
||||
public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes");
|
||||
public static final PathConfig BIOMES_CONFIG = new PathConfig(BCLib.MOD_ID, "biomes", false);
|
||||
|
||||
public static final String MAIN_PATCH_CATEGORY = "patches";
|
||||
|
||||
public static void save() {
|
||||
MAIN_CONFIG.saveChanges();
|
||||
RECIPE_CONFIG.saveChanges();
|
||||
GENERATOR_CONFIG.saveChanges();
|
||||
BIOMES_CONFIG.saveChanges();
|
||||
}
|
||||
|
||||
static {
|
||||
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("end_land_biomes", "force_include"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST));
|
||||
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("end_void_biomes", "force_include"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST));
|
||||
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("nether_biomes", "force_include"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST));
|
||||
BIOMES_CONFIG.keeper.registerEntry(new ConfigKey("nether_biomes", "force_exclude"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST));
|
||||
}
|
||||
}
|
9
src/main/java/org/betterx/bclib/config/EntryConfig.java
Normal file
9
src/main/java/org/betterx/bclib/config/EntryConfig.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
public class EntryConfig extends IdConfig {
|
||||
public EntryConfig(String modID, String group) {
|
||||
super(modID, group, (id, entry) -> {
|
||||
return new ConfigKey(entry, id);
|
||||
});
|
||||
}
|
||||
}
|
18
src/main/java/org/betterx/bclib/config/GeneratorConfig.java
Normal file
18
src/main/java/org/betterx/bclib/config/GeneratorConfig.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
public class GeneratorConfig extends NamedPathConfig {
|
||||
public static final ConfigToken<Boolean> USE_OLD_GENERATOR = ConfigToken.Boolean(false,
|
||||
"useOldBiomeGenerator",
|
||||
"options");
|
||||
|
||||
|
||||
public GeneratorConfig() {
|
||||
super(BCLib.MOD_ID, "generator", false);
|
||||
}
|
||||
|
||||
public boolean useOldGenerator() {
|
||||
return get(USE_OLD_GENERATOR);
|
||||
}
|
||||
}
|
89
src/main/java/org/betterx/bclib/config/IdConfig.java
Normal file
89
src/main/java/org/betterx/bclib/config/IdConfig.java
Normal file
|
@ -0,0 +1,89 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class IdConfig extends Config {
|
||||
protected final BiFunction<ResourceLocation, String, ConfigKey> keyFactory;
|
||||
|
||||
public IdConfig(String modID, String group, BiFunction<ResourceLocation, String, ConfigKey> 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 <T, E extends ConfigKeeper.Entry<T>> E getEntry(ResourceLocation id, String key, Class<E> type) {
|
||||
return this.getEntry(createKey(id, key), type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, E extends ConfigKeeper.Entry<T>> T getDefault(ResourceLocation id, String key, Class<E> 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, ConfigKeeper.IntegerRange.class);
|
||||
}
|
||||
|
||||
public boolean setRangedFloat(ResourceLocation id, String key, float value) {
|
||||
return this.setRanged(createKey(id, key), value, ConfigKeeper.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);
|
||||
}
|
||||
}
|
28
src/main/java/org/betterx/bclib/config/MainConfig.java
Normal file
28
src/main/java/org/betterx/bclib/config/MainConfig.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
public class MainConfig extends NamedPathConfig {
|
||||
public static final ConfigToken<Boolean> APPLY_PATCHES = ConfigToken.Boolean(true,
|
||||
"applyPatches",
|
||||
Configs.MAIN_PATCH_CATEGORY);
|
||||
|
||||
@ConfigUI(leftPadding = 8)
|
||||
public static final ConfigToken<Boolean> REPAIR_BIOMES = DependendConfigToken.Boolean(true,
|
||||
"repairBiomesOnLoad",
|
||||
Configs.MAIN_PATCH_CATEGORY,
|
||||
(config) -> config.get(
|
||||
APPLY_PATCHES));
|
||||
|
||||
public MainConfig() {
|
||||
super(BCLib.MOD_ID, "main", true, true);
|
||||
}
|
||||
|
||||
public boolean applyPatches() {
|
||||
return get(APPLY_PATCHES);
|
||||
}
|
||||
|
||||
public boolean repairBiomes() {
|
||||
return get(REPAIR_BIOMES);
|
||||
}
|
||||
}
|
270
src/main/java/org/betterx/bclib/config/NamedPathConfig.java
Normal file
270
src/main/java/org/betterx/bclib/config/NamedPathConfig.java
Normal file
|
@ -0,0 +1,270 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class NamedPathConfig extends PathConfig {
|
||||
public static class ConfigTokenDescription<T> {
|
||||
public final ConfigToken<T> token;
|
||||
public final String internalName;
|
||||
public final Boolean hidden;
|
||||
public final int leftPadding;
|
||||
public final int topPadding;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ConfigTokenDescription(Field fl) throws IllegalAccessException {
|
||||
token = (ConfigToken<T>) fl.get(null);
|
||||
internalName = fl.getName();
|
||||
|
||||
ConfigUI ui = fl.getAnnotation(ConfigUI.class);
|
||||
if (ui != null) {
|
||||
this.hidden = ui.hide();
|
||||
leftPadding = ui.leftPadding();
|
||||
topPadding = ui.topPadding();
|
||||
} else {
|
||||
this.hidden = false;
|
||||
this.leftPadding = 0;
|
||||
topPadding = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
StringBuilder path = new StringBuilder();
|
||||
for (String p : token.getPath()) {
|
||||
path.append(".")
|
||||
.append(p);
|
||||
|
||||
}
|
||||
path.append(".").append(token.getEntry());
|
||||
return path.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class DependendConfigToken<T> extends ConfigToken<T> {
|
||||
protected final Predicate<NamedPathConfig> dependenciesTrue;
|
||||
|
||||
protected DependendConfigToken(Class<?> type,
|
||||
T defaultValue,
|
||||
String entry,
|
||||
ResourceLocation path,
|
||||
Predicate<NamedPathConfig> dependenciesTrue) {
|
||||
this(type, defaultValue, entry, new String[]{path.getNamespace(), path.getPath()}, dependenciesTrue);
|
||||
}
|
||||
|
||||
protected DependendConfigToken(Class<?> type,
|
||||
T defaultValue,
|
||||
String entry,
|
||||
String path,
|
||||
Predicate<NamedPathConfig> dependenciesTrue) {
|
||||
super(type, defaultValue, entry, path);
|
||||
this.dependenciesTrue = dependenciesTrue;
|
||||
}
|
||||
|
||||
protected DependendConfigToken(Class<?> type,
|
||||
T defaultValue,
|
||||
String entry,
|
||||
String[] path,
|
||||
Predicate<NamedPathConfig> dependenciesTrue) {
|
||||
super(type, defaultValue, entry, path);
|
||||
this.dependenciesTrue = dependenciesTrue;
|
||||
}
|
||||
|
||||
public boolean dependenciesTrue(NamedPathConfig config) {
|
||||
return dependenciesTrue.test(config);
|
||||
}
|
||||
|
||||
public static DependendConfigToken<Boolean> Boolean(boolean defaultValue,
|
||||
String entry,
|
||||
String path,
|
||||
Predicate<NamedPathConfig> dependenciesTrue) {
|
||||
return new DependendConfigToken<Boolean>(ConfigKeeper.BooleanEntry.class,
|
||||
defaultValue,
|
||||
entry,
|
||||
path,
|
||||
dependenciesTrue);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ConfigToken<T> extends ConfigKey {
|
||||
public final T defaultValue;
|
||||
public final Class<?> type;
|
||||
|
||||
protected ConfigToken(Class<?> type, T defaultValue, String entry, ResourceLocation path) {
|
||||
this(type, defaultValue, entry, path.getNamespace(), path.getPath());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ConfigToken(Class<?> type, T defaultValue, String entry, String... path) {
|
||||
super(entry, path);
|
||||
this.defaultValue = defaultValue;
|
||||
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public boolean dependenciesTrue(NamedPathConfig config) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ConfigToken<Boolean> Boolean(boolean defaultValue, String entry, String path) {
|
||||
return new ConfigToken<Boolean>(ConfigKeeper.BooleanEntry.class, defaultValue, entry, path);
|
||||
}
|
||||
|
||||
public static ConfigToken<Integer> Int(int defaultValue, String entry, String path) {
|
||||
return new ConfigToken<Integer>(ConfigKeeper.IntegerEntry.class, defaultValue, entry, path);
|
||||
}
|
||||
|
||||
public static ConfigToken<Float> Float(float defaultValue, String entry, String path) {
|
||||
return new ConfigToken<Float>(ConfigKeeper.FloatEntry.class, defaultValue, entry, path);
|
||||
}
|
||||
|
||||
public static ConfigToken<String> String(String defaultValue, String entry, String path) {
|
||||
return new ConfigToken<String>(ConfigKeeper.StringEntry.class, defaultValue, entry, path);
|
||||
}
|
||||
|
||||
public static ConfigToken<List<String>> StringArray(List<String> defaultValue, String entry, String path) {
|
||||
return new ConfigToken<List<String>>(ConfigKeeper.StringArrayEntry.class, defaultValue, entry, path);
|
||||
}
|
||||
}
|
||||
|
||||
public NamedPathConfig(String modID, String group, boolean autoSync, boolean diffContent) {
|
||||
super(modID, group, autoSync, diffContent);
|
||||
onInit();
|
||||
}
|
||||
|
||||
public NamedPathConfig(String modID, String group, boolean autoSync) {
|
||||
super(modID, group, autoSync);
|
||||
onInit();
|
||||
}
|
||||
|
||||
public NamedPathConfig(String modID, String group) {
|
||||
super(modID, group);
|
||||
onInit();
|
||||
}
|
||||
|
||||
public List<ConfigTokenDescription<?>> getAllOptions() {
|
||||
List<ConfigTokenDescription<?>> res = new LinkedList<>();
|
||||
for (Field fl : this.getClass().getDeclaredFields()) {
|
||||
int modifiers = fl.getModifiers();
|
||||
if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && ConfigToken.class.isAssignableFrom(fl.getType())) {
|
||||
try {
|
||||
res.add(new ConfigTokenDescription<>(fl));
|
||||
} catch (IllegalAccessException e) {
|
||||
BCLib.LOGGER.error("Could not access " + fl);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected void onInit() {
|
||||
getAllOptions().forEach(e -> get(e.token));
|
||||
this.saveChanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* The value without any check of {@link DependendConfigToken}
|
||||
* <p>
|
||||
* In most cases you probably want to use {@link #get(ConfigToken)}, we use this Method if we
|
||||
* present the actual value of the Settings from the Config File without any additional processing.
|
||||
*
|
||||
* @param what The Option you want to get
|
||||
* @param <T> The Type of the Option
|
||||
* @return The Value of the Option (without checking the {@link DependendConfigToken}):
|
||||
*/
|
||||
public <T> T getRaw(ConfigToken<T> what) {
|
||||
return _get(what, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* The value of an Option
|
||||
*
|
||||
* @param what he Option you want to get
|
||||
* @param <T> The Type of the Option
|
||||
* @return The Value of the Option. If this option is a {@link DependendConfigToken}, the returned value
|
||||
* may not be the value from the config File. For Example, on a {@link Boolean}-Type the result is always false
|
||||
* if {@link DependendConfigToken#dependenciesTrue} returns {@code false}.
|
||||
*/
|
||||
public <T> T get(ConfigToken<T> what) {
|
||||
return _get(what, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T _get(ConfigToken<T> what, boolean raw) {
|
||||
//TODO: Check if we can make config fully Generic to avoid runtime type checks...
|
||||
if (ConfigKeeper.BooleanEntry.class.isAssignableFrom(what.type)) {
|
||||
return (T) _getBoolean((ConfigToken<Boolean>) what, raw);
|
||||
}
|
||||
if (ConfigKeeper.IntegerEntry.class.isAssignableFrom(what.type)) {
|
||||
return (T) _getInt((ConfigToken<Integer>) what);
|
||||
}
|
||||
if (ConfigKeeper.FloatEntry.class.isAssignableFrom(what.type)) {
|
||||
return (T) _getFloat((ConfigToken<Float>) what);
|
||||
}
|
||||
if (ConfigKeeper.StringEntry.class.isAssignableFrom(what.type)) {
|
||||
return (T) _getString((ConfigToken<String>) what);
|
||||
}
|
||||
if (ConfigKeeper.StringArrayEntry.class.isAssignableFrom(what.type)) {
|
||||
return (T) _getStringArray((ConfigToken<List<String>>) what);
|
||||
}
|
||||
return this._get(what);
|
||||
}
|
||||
|
||||
private <T> T _get(ConfigToken<T> what) {
|
||||
BCLib.LOGGER.error(what + " has unsupported Type.");
|
||||
return what.defaultValue;
|
||||
}
|
||||
|
||||
public void set(ConfigToken<Boolean> what, boolean value) {
|
||||
this.setBoolean(what, value);
|
||||
}
|
||||
|
||||
private Boolean _getBoolean(ConfigToken<Boolean> what, boolean raw) {
|
||||
if (!raw && !what.dependenciesTrue(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.getBoolean(what, what.defaultValue);
|
||||
}
|
||||
|
||||
public void set(ConfigToken<Integer> what, int value) {
|
||||
this.setInt(what, value);
|
||||
}
|
||||
|
||||
private Integer _getInt(ConfigToken<Integer> what) {
|
||||
return this.getInt(what, what.defaultValue);
|
||||
}
|
||||
|
||||
public void set(ConfigToken<Float> what, float value) {
|
||||
this.setFloat(what, value);
|
||||
}
|
||||
|
||||
private Float _getFloat(ConfigToken<Float> what) {
|
||||
return this.getFloat(what, what.defaultValue);
|
||||
}
|
||||
|
||||
public void set(ConfigToken<String> what, String value) {
|
||||
this.setString(what, value);
|
||||
}
|
||||
|
||||
private String _getString(ConfigToken<String> what) {
|
||||
return this.getString(what, what.defaultValue);
|
||||
}
|
||||
|
||||
public void set(ConfigToken<List<String>> what, List<String> value) {
|
||||
this.setStringArray(what, value);
|
||||
}
|
||||
|
||||
private List<String> _getStringArray(ConfigToken<List<String>> what) {
|
||||
return this.getStringArray(what, what.defaultValue);
|
||||
}
|
||||
|
||||
|
||||
}
|
166
src/main/java/org/betterx/bclib/config/PathConfig.java
Normal file
166
src/main/java/org/betterx/bclib/config/PathConfig.java
Normal file
|
@ -0,0 +1,166 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PathConfig extends Config {
|
||||
public PathConfig(String modID, String group, boolean autoSync, boolean diffContent) {
|
||||
super(modID, group, autoSync, diffContent);
|
||||
}
|
||||
|
||||
public PathConfig(String modID, String group, boolean autoSync) {
|
||||
super(modID, group, autoSync);
|
||||
}
|
||||
|
||||
public PathConfig(String modID, String group) {
|
||||
super(modID, group);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerEntries() {
|
||||
}
|
||||
|
||||
protected static ConfigKey createKey(String category, String key) {
|
||||
return new ConfigKey(key, category.split("\\."));
|
||||
}
|
||||
|
||||
protected static ConfigKey createKey(String key) {
|
||||
return createKey("", key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, E extends ConfigKeeper.Entry<T>> E getEntry(String category, String key, Class<E> type) {
|
||||
return this.getEntry(createKey(category, key), type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T, E extends ConfigKeeper.Entry<T>> T getDefault(String category, String key, Class<E> 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, ConfigKeeper.IntegerRange.class);
|
||||
}
|
||||
|
||||
public boolean setRangedFloat(String category, String key, float value) {
|
||||
return this.setRanged(createKey(category, key), value, ConfigKeeper.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);
|
||||
}
|
||||
|
||||
public List<String> getStringArray(String category, String key, List<String> defaultValue) {
|
||||
return this.getStringArray(createKey(category, key), defaultValue);
|
||||
}
|
||||
|
||||
public List<String> getStringArray(String category, String key) {
|
||||
return this.getStringArray(createKey(category, key));
|
||||
}
|
||||
|
||||
public boolean setStringArray(String category, String key, List<String> value) {
|
||||
return this.setStringArray(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, ConfigKeeper.IntegerRange.class);
|
||||
}
|
||||
|
||||
public boolean setRangedFloatRoot(String key, float value) {
|
||||
return this.setRanged(createKey(key), value, ConfigKeeper.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);
|
||||
}
|
||||
}
|
74
src/main/java/org/betterx/bclib/config/ServerConfig.java
Normal file
74
src/main/java/org/betterx/bclib/config/ServerConfig.java
Normal file
|
@ -0,0 +1,74 @@
|
|||
package org.betterx.bclib.config;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.dataexchange.handler.autosync.AutoSync;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ServerConfig extends NamedPathConfig {
|
||||
public static final ConfigToken<Boolean> ENABLED = ConfigToken.Boolean(true, "enabled", AutoSync.SYNC_CATEGORY);
|
||||
public static final DependendConfigToken<Boolean> OFFER_CONFIGS = DependendConfigToken.Boolean(true,
|
||||
"offerConfigs",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
public static final DependendConfigToken<Boolean> OFFER_FILES = DependendConfigToken.Boolean(true,
|
||||
"offerFiles",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
public static final DependendConfigToken<Boolean> OFFER_MODS = DependendConfigToken.Boolean(true,
|
||||
"offerMods",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
public static final DependendConfigToken<Boolean> OFFER_ALL_MODS = DependendConfigToken.Boolean(false,
|
||||
"offerAllMods",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
OFFER_MODS));
|
||||
public static final DependendConfigToken<Boolean> SEND_ALL_MOD_INFO = DependendConfigToken.Boolean(false,
|
||||
"sendAllModInfo",
|
||||
AutoSync.SYNC_CATEGORY,
|
||||
(config) -> config.get(
|
||||
ENABLED));
|
||||
|
||||
|
||||
public static final ConfigToken<List<String>> ADDITIONAL_MODS = ConfigToken.StringArray(new ArrayList<>(0),
|
||||
"additionalMods",
|
||||
AutoSync.SYNC_CATEGORY);
|
||||
public static final ConfigToken<List<String>> EXCLUDED_MODS = ConfigToken.StringArray(new ArrayList<>(0),
|
||||
"excludeMods",
|
||||
AutoSync.SYNC_CATEGORY);
|
||||
|
||||
|
||||
public ServerConfig() {
|
||||
super(BCLib.MOD_ID, "server", false);
|
||||
}
|
||||
|
||||
public boolean isAllowingAutoSync() {
|
||||
return get(ENABLED);
|
||||
}
|
||||
|
||||
public boolean isOfferingConfigs() {
|
||||
return get(OFFER_CONFIGS) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean isOfferingFiles() {
|
||||
return get(OFFER_FILES) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean isOfferingMods() {
|
||||
return get(OFFER_MODS) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean isOfferingAllMods() {
|
||||
return get(OFFER_ALL_MODS) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean isOfferingInfosForMods() {
|
||||
return get(SEND_ALL_MOD_INFO) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue