settings system
This commit is contained in:
1 parent
c7739f1963
commit
92f40c36b8
9 files changed
+863
-21
No files matched your search
@@ -0,0 +1,170 @@
|
||||
package carpet.settings;
|
||||
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class ParsedRule<T> implements Comparable<ParsedRule> {
|
||||
public final Rule rule;
|
||||
public final Field field;
|
||||
|
||||
public final String name;
|
||||
public final String description;
|
||||
public final ImmutableList<String> extraInfo;
|
||||
public final ImmutableList<RuleCategory> categories;
|
||||
public final ImmutableList<String> options;
|
||||
public boolean isStrict;
|
||||
public final Class<T> type;
|
||||
public final List<Validator<T>> validators;
|
||||
public final T defaultValue;
|
||||
public final String defaultAsString;
|
||||
|
||||
public static <T> T callConstructor(Class<T> cls) {
|
||||
try {
|
||||
Constructor<T> constr = cls.getDeclaredConstructor();
|
||||
constr.setAccessible(true);
|
||||
return constr.newInstance();
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
ParsedRule(Field field, Rule rule) {
|
||||
this.rule = rule;
|
||||
this.field = field;
|
||||
this.name = rule.name().isEmpty() ? field.getName() : rule.name();
|
||||
this.type = (Class<T>) field.getType();
|
||||
this.description = rule.desc();
|
||||
this.isStrict = rule.strict();
|
||||
this.extraInfo = ImmutableList.copyOf(rule.extra());
|
||||
this.categories = ImmutableList.copyOf(rule.category());
|
||||
this.validators = new ArrayList<>();
|
||||
for (Class v : rule.validate())
|
||||
{
|
||||
this.validators.add((Validator<T>) callConstructor(v));
|
||||
}
|
||||
if (categories.contains(RuleCategory.COMMANDS))
|
||||
this.validators.add(callConstructor(Validator._COMMAND.class));
|
||||
|
||||
this.defaultValue = get();
|
||||
this.defaultAsString = convertToString(this.defaultValue);
|
||||
if (this.type == boolean.class) {
|
||||
this.isStrict = true; // it has no sense otherwise
|
||||
this.options = ImmutableList.of("true", "false");
|
||||
} else if (this.type.isEnum()) {
|
||||
this.isStrict = true; // it has no sense otherwise
|
||||
this.options = Arrays.stream(this.type.getEnumConstants()).map(e -> ((Enum) e).name().toLowerCase(Locale.ROOT)).collect(ImmutableList.toImmutableList());
|
||||
} else {
|
||||
this.options = ImmutableList.copyOf(rule.options());
|
||||
}
|
||||
if (isStrict)
|
||||
this.validators.add(callConstructor(Validator._STRICT.class));
|
||||
}
|
||||
|
||||
|
||||
public ParsedRule<T> set(ServerCommandSource source, String value) {
|
||||
//if locked - prevent
|
||||
if (type == String.class)
|
||||
{
|
||||
return set(source, (T) value, value);
|
||||
}
|
||||
else if (type == boolean.class)
|
||||
{
|
||||
return set(source, (T) (Object) Boolean.parseBoolean(value), value);
|
||||
}
|
||||
else if (type == int.class)
|
||||
{
|
||||
return set(source, (T) (Object) Integer.parseInt(value), value);
|
||||
}
|
||||
else if (type.isEnum())
|
||||
{
|
||||
String ucValue = value.toUpperCase(Locale.ROOT);
|
||||
return set(source, (T) (Object) Enum.valueOf((Class<? extends Enum>) type, ucValue), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Messenger.m(source, "r Unknown type " + type.getSimpleName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public ParsedRule<T> set(ServerCommandSource source, T value, String stringValue) {
|
||||
try {
|
||||
for (Validator<T> validator : this.validators)
|
||||
{
|
||||
boolean allowed = validator.validate(source, this, value, stringValue);
|
||||
if (!allowed)
|
||||
{
|
||||
Messenger.m(source, "r Wrong value for " + name + ": " + stringValue);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
this.field.set(null, value);
|
||||
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
Messenger.m(source, "r Unable to access setting for "+name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public T get() {
|
||||
try {
|
||||
return (T) this.field.get(null);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getAsString() {
|
||||
return convertToString(get());
|
||||
}
|
||||
|
||||
public boolean getBoolValue() {
|
||||
if (type == boolean.class) return (Boolean) get();
|
||||
if (type.isAssignableFrom(Number.class)) return ((Number) get()).doubleValue() > 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return defaultValue.equals(get());
|
||||
}
|
||||
|
||||
public void resetToDefault(ServerCommandSource source) {
|
||||
set(source, defaultValue, defaultAsString);
|
||||
}
|
||||
|
||||
|
||||
private static String convertToString(Object value) {
|
||||
if (value instanceof Enum) return ((Enum) value).name().toLowerCase(Locale.ROOT);
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj.getClass() == ParsedRule.class && ((ParsedRule) obj).name.equals(this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.name.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ParsedRule o) {
|
||||
return this.name.compareTo(o.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name + ": " + getAsString();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user