Some api stuff for config and updated readme to add json

This commit is contained in:
coolGi2007
2022-04-29 23:30:25 +09:30
parent 4310721640
commit e116b891a8
5 changed files with 140 additions and 39 deletions
+4 -1
View File
@@ -17,5 +17,8 @@ It should be automatically included when pulling the full mod.
XZ for Java (data compression)\ XZ for Java (data compression)\
https://tukaani.org/xz/java.html https://tukaani.org/xz/java.html
Toml for Java (config handeling)\ Toml for Java (config handling)\
https://github.com/TheElectronWill/night-config https://github.com/TheElectronWill/night-config
Json for Java (config handling)\
https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
@@ -9,7 +9,6 @@ import com.seibel.lod.core.config.types.ConfigEntry;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -43,13 +42,15 @@ public class ConfigBase {
acceptableInputs.add(Long.class); acceptableInputs.add(Long.class);
// acceptableInputs.add(Float.class); // acceptableInputs.add(Float.class);
acceptableInputs.add(String.class); acceptableInputs.add(String.class);
acceptableInputs.add(HashMap.class); // TODO[CONFIG]: This is handled separately to check the first input is String and the second input is valid acceptableInputs.add(Map.class); // TODO[CONFIG]: This is handled separately to check the first input is String and the second input is valid
} }
/** Disables the minimum and maximum of a variable */ /** Disables the minimum and maximum of a variable */
public static boolean disableMinMax = false; // Very fun to use public static boolean disableMinMax = false; // Very fun to use
public static final List<AbstractConfigType<?, ?>> entries = new ArrayList<>(); public static final List<AbstractConfigType<?, ?>> entries = new ArrayList<>();
public static final int configVersion = 1;
public static void init(Class<?> config) { public static void init(Class<?> config) {
addAcceptableInputs(); // Add all of the acceptable stuff to the acceptableInputs list addAcceptableInputs(); // Add all of the acceptable stuff to the acceptableInputs list
initNestedClass(config, ""); // Init root category initNestedClass(config, ""); // Init root category
@@ -90,12 +90,12 @@ public class ConfigFileHandling {
// Save an entry // Save an entry
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static void saveEntry(ConfigEntry<?> entry, CommentedFileConfig workConfig) { public static void saveEntry(ConfigEntry<?> entry, CommentedFileConfig workConfig) {
if (!entry.getAppearance().showInFile) if (!entry.getAppearance().showInFile) return;
return;
if (!entry.get().getClass().isAssignableFrom(HashMap.class)) { if (ConfigTypeConverters.convertObjects.containsKey(entry.getType())) {
workConfig.set(entry.getNameWCategory(), entry.get()); workConfig.set(entry.getNameWCategory(), ConfigTypeConverters.convertToString(entry.getType(), entry.getTrueValue()));
} else { } else {
workConfig.set(entry.getNameWCategory(), getStringFromHashMap((HashMap<String, ?>) entry.get())); workConfig.set(entry.getNameWCategory(), entry.getTrueValue());
} }
} }
@@ -108,28 +108,21 @@ public class ConfigFileHandling {
} }
// Loads an entry // Loads an entry
@SuppressWarnings("unchecked") // Suppress due to its always safe. (I think. See reasons below.) @SuppressWarnings("unchecked") // Suppress due to its always safe
public static <T> void loadEntry(ConfigEntry<T> entry, CommentedFileConfig workConfig) { public static <T> void loadEntry(ConfigEntry<T> entry, CommentedFileConfig workConfig) {
if (!entry.getAppearance().showInFile) if (!entry.getAppearance().showInFile) return;
return;
if (workConfig.contains(entry.getNameWCategory())) { if (workConfig.contains(entry.getNameWCategory())) {
try { try {
if (entry.get().getClass().isEnum()) { if (entry.getType().isEnum()) {
// Safe cast due to above checking that <T> is indeed a Enum entry.setWTSave((T) ( workConfig.getEnum(entry.getNameWCategory(), (Class<? extends Enum>) entry.getType()) ));
// And the second cast back to <T> is safe due to the template } else if (ConfigTypeConverters.convertObjects.containsKey(entry.getType())) {
entry.setWTSave((T) ( entry.setWTSave((T) ConfigTypeConverters.convertFromString(entry.getType(), workConfig.get(entry.getNameWCategory())));
workConfig.getEnum(entry.getNameWCategory(), (Class<? extends Enum>) entry.get().getClass())
));
} else if (entry.getType().isAssignableFrom(HashMap.class)) {
entry.setWTSave((T) getHashMapFromString(workConfig.get(entry.getNameWCategory())));
} else { } else {
entry.setWTSave((T) workConfig.get(entry.getNameWCategory())); entry.setWTSave((T) workConfig.get(entry.getNameWCategory()));
if (entry.isValid() == 0) if (entry.isValid() == 0) return;
return; else if (entry.isValid() == -1) entry.setWTSave(entry.getMin());
else if (entry.isValid() == -1) else if (entry.isValid() == 1) entry.setWTSave(entry.getMax());
entry.setWTSave(entry.getMin());
else if (entry.isValid() == 1)
entry.setWTSave(entry.getMax());
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -176,29 +169,53 @@ public class ConfigFileHandling {
} }
} }
// Stuff for converting HashMap's and String's (uses json)
public static String getStringFromHashMap(HashMap<String, ?> item) {
JSONObject jsonObject = new JSONObject();
for (int i=0; i< item.size(); i++) { // ========== API (server) STUFF ========== //
jsonObject.put(item.keySet().toArray()[i], item.get(item.keySet().toArray()[i])); @SuppressWarnings("unchecked")
/** ALWAYS CLEAR WHEN NOT ON SERVER!!!! */
public static void clearApiValues() {
for (AbstractConfigType<?, ?> entry : ConfigBase.entries) {
if (ConfigEntry.class.isAssignableFrom(entry.getClass()) && ((ConfigEntry) entry).useApiOverwrite) {
((ConfigEntry) entry).setApiValue(null);
}
}
}
@SuppressWarnings("unchecked")
public static String exportApiValues() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("configVersion", ConfigBase.configVersion);
for (AbstractConfigType<?, ?> entry : ConfigBase.entries) {
if (ConfigEntry.class.isAssignableFrom(entry.getClass()) && ((ConfigEntry) entry).useApiOverwrite) {
if (ConfigTypeConverters.convertObjects.containsKey(entry.getType())) {
jsonObject.put(entry.getNameWCategory(), ConfigTypeConverters.convertToString(entry.getType(), ((ConfigEntry<?>) entry).getTrueValue()));
} else {
jsonObject.put(entry.getNameWCategory(), ((ConfigEntry<?>) entry).getTrueValue());
}
}
} }
return jsonObject.toJSONString(); return jsonObject.toJSONString();
} }
public static <T> HashMap<String, ?> getHashMapFromString(String s) { @SuppressWarnings("unchecked") // Suppress due to its always safe
HashMap<String, T> map = new HashMap<>(); public static void importApiValues(String values) {
JSONObject jsonObject = null; JSONObject jsonObject = null;
try { try {
jsonObject = (JSONObject) new JSONParser().parse(s); jsonObject = (JSONObject) new JSONParser().parse(values);
} catch (ParseException p) { } catch (ParseException p) {
p.printStackTrace(); p.printStackTrace();
} }
for (int i = 0; i < jsonObject.keySet().toArray().length; i++) { // Importing code
map.put((String) jsonObject.keySet().toArray()[i], (T) jsonObject.get(jsonObject.keySet().toArray()[i])); for (AbstractConfigType<?, ?> entry : ConfigBase.entries) {
if (ConfigEntry.class.isAssignableFrom(entry.getClass()) && ((ConfigEntry) entry).useApiOverwrite) {
Object jsonItem = jsonObject.get(entry.getNameWCategory());
if (entry.getType().isEnum()) {
((ConfigEntry) entry).setApiValue(Enum.valueOf((Class<? extends Enum>) entry.getType(), jsonItem.toString()));
} else if (ConfigTypeConverters.convertObjects.containsKey(entry.getType())) {
((ConfigEntry) entry).setApiValue(ConfigTypeConverters.convertFromString(entry.getType(), jsonItem.toString()));
} else {
((ConfigEntry) entry).setApiValue(jsonItem);
}
}
} }
return map;
} }
} }
@@ -0,0 +1,74 @@
package com.seibel.lod.core.config.file;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.util.HashMap;
import java.util.Map;
public class ConfigTypeConverters {
// Once you've made a converter add it to here where the first value is the type you want to convert and the 2nd value is the converter
public static final Map<Class, ConverterBase> convertObjects = new HashMap<Class, ConverterBase>() {{
put(Map.class, new MapConverter());
}};
public static String convertToString(Class clazz, Object value) {
try {
return convertObjects.get(clazz).convertToString(value);
} catch (Exception e) {
System.out.println("Type [" + clazz.toString() + "] isnt a convertable value in the config file handler");
return null;
}
}
public static Object convertFromString(Class clazz, String value) {
try {
return convertObjects.get(clazz).convertFromString(value);
} catch (Exception e) {
System.out.println("Type [" + clazz.toString() + "] isnt a convertable value in the config file handler");
return null;
}
}
/**
* The converter should extend this
*/
public static abstract class ConverterBase {
public abstract String convertToString(Object value);
public abstract Object convertFromString(String value);
}
@SuppressWarnings("unchecked")
public static class MapConverter extends ConverterBase {
@Override
public String convertToString(Object item) {
Map<String, Object> mapObject = (Map<String, Object>) item;
JSONObject jsonObject = new JSONObject();
for (int i = 0; i < mapObject.size(); i++) {
jsonObject.put(mapObject.keySet().toArray()[i], mapObject.get(mapObject.keySet().toArray()[i]));
}
return jsonObject.toJSONString();
}
@Override
public Map<String, Object> convertFromString(String s) {
Map<String, Object> map = new HashMap<>();
JSONObject jsonObject = null;
try {
jsonObject = (JSONObject) new JSONParser().parse(s);
} catch (ParseException p) {
p.printStackTrace();
}
for (int i = 0; i < jsonObject.keySet().toArray().length; i++) {
map.put((String) jsonObject.keySet().toArray()[i], jsonObject.get(jsonObject.keySet().toArray()[i]));
}
return map;
}
}
}
@@ -16,7 +16,7 @@ public class ConfigEntry<T> extends AbstractConfigType<T, ConfigEntry<T>> {
private T min; private T min;
private T max; private T max;
// Stuff for server overwrites // Stuff for server overwrites
private final boolean useApiOverwrite; public final boolean useApiOverwrite;
private T apiValue; private T apiValue;
/** Creates the entry */ /** Creates the entry */
@@ -35,6 +35,9 @@ public class ConfigEntry<T> extends AbstractConfigType<T, ConfigEntry<T>> {
return this.defaultValue; return this.defaultValue;
} }
public void setApiValue(T newApiValue) {
this.apiValue = newApiValue;
}
@Override @Override
public void set(T newValue) { public void set(T newValue) {
this.value = newValue; this.value = newValue;
@@ -46,6 +49,9 @@ public class ConfigEntry<T> extends AbstractConfigType<T, ConfigEntry<T>> {
return apiValue; return apiValue;
return value; return value;
} }
public T getTrueValue() {
return value;
}
public MinDefaultMax<T> getMinValueMax() { public MinDefaultMax<T> getMinValueMax() {
return new MinDefaultMax<T>(min, value, max); return new MinDefaultMax<T>(min, value, max);