9
0
mirror of https://github.com/LeavesMC/Leaves.git synced 2025-12-29 20:09:23 +00:00

Config Modify

This commit is contained in:
violetc
2025-02-17 16:44:43 +08:00
parent e58f6364ef
commit a55a6201a5
10 changed files with 228 additions and 69 deletions

View File

@@ -121,17 +121,17 @@ public final class LeavesConfig {
}
}
@RemovedConfig(name = "unable-fakeplayer-names", category = "fakeplayer", convert = ListConfigValidator.STRING.class, transform = true)
@GlobalConfig(value = "unable-fakeplayer-names", validator = ListConfigValidator.STRING.class)
@RemovedConfig(name = "unable-fakeplayer-names", category = "fakeplayer", transform = true)
@GlobalConfig(value = "unable-fakeplayer-names")
public List<String> unableNames = List.of("player-name");
@GlobalConfig(value = "limit", validator = IntConfigValidator.class)
@GlobalConfig(value = "limit")
public int limit = 10;
@GlobalConfig(value = "prefix", validator = StringConfigValidator.class)
@GlobalConfig(value = "prefix")
public String prefix = "";
@GlobalConfig(value = "suffix", validator = StringConfigValidator.class)
@GlobalConfig(value = "suffix")
public String suffix = "";
@GlobalConfig(value = "regen-amount", validator = RegenAmountValidator.class)
@@ -196,6 +196,10 @@ public final class LeavesConfig {
@RemovedConfig(name = "redstone-wire-dont-connect-if-on-trapdoor", category = {"modify", "minecraft-old"}, transform = true)
@GlobalConfig("redstone-wire-dont-connect-if-on-trapdoor")
public boolean redstoneDontCantOnTrapDoor = false;
@RemovedConfig(name = "old-block-entity-behaviour", category = {"modify", "minecraft-old"}, transform = true)
@GlobalConfig("old-block-entity-behaviour")
public boolean oldBlockEntityBehaviour = false;
}
@RemovedConfig(name = "shears-in-dispenser-can-zero-amount", category = {}, transform = true)
@@ -252,9 +256,6 @@ public final class LeavesConfig {
@GlobalConfig("fix-fortress-mob-spawn")
public boolean fixFortressMobSpawn = false;
@GlobalConfig("old-block-entity-behaviour")
public boolean oldBlockEntityBehaviour = false;
@GlobalConfig("old-hopper-suck-in-behavior")
public boolean oldHopperSuckInBehavior = false;
@@ -283,19 +284,19 @@ public final class LeavesConfig {
@GlobalConfig("no-chunk-load")
public boolean noChunk = false;
@GlobalConfig(value = "no-chunk-height", validator = DoubleConfigValidator.class)
@GlobalConfig(value = "no-chunk-height")
public double noChunkHeight = 500.0D;
@GlobalConfig(value = "no-chunk-speed", validator = DoubleConfigValidator.class)
@GlobalConfig(value = "no-chunk-speed")
public double noChunkSpeed = -1.0D;
@GlobalConfig("message")
public boolean noChunkMes = true;
@GlobalConfig(value = "message-start", validator = StringConfigValidator.class)
@GlobalConfig(value = "message-start")
public String noChunkStartMes = "Flight enter cruise mode";
@GlobalConfig(value = "message-end", validator = StringConfigValidator.class)
@GlobalConfig(value = "message-end")
public String noChunkEndMes = "Flight exit cruise mode";
}
@@ -692,7 +693,7 @@ public final class LeavesConfig {
@GlobalConfig("quota")
public boolean useQuota = false;
@GlobalConfig(value = "quota-limit", validator = IntConfigValidator.class)
@GlobalConfig(value = "quota-limit")
public int quotaLimit = 40000000;
}
@@ -713,16 +714,13 @@ public final class LeavesConfig {
}
}
@RemovedConfig(name = "pca-sync-player-entity", category = "protocol", convert = PcaPlayerEntityValidator.class, transform = true)
@GlobalConfig(value = "pca-sync-player-entity", validator = PcaPlayerEntityValidator.class)
@RemovedConfig(name = "pca-sync-player-entity", category = "protocol", transform = true)
@GlobalConfig(value = "pca-sync-player-entity")
public PcaPlayerEntityType syncPlayerEntity = PcaPlayerEntityType.OPS;
public enum PcaPlayerEntityType {
NOBODY, BOT, OPS, OPS_AND_SELF, EVERYONE
}
private static class PcaPlayerEntityValidator extends EnumConfigValidator<PcaPlayerEntityType> {
}
}
public AppleSkinConfig appleskin = new AppleSkinConfig();
@@ -780,7 +778,7 @@ public final class LeavesConfig {
@GlobalConfig("xaero-map-protocol")
public boolean xaeroMapProtocol = false;
@GlobalConfig(value = "xaero-map-server-id", validator = IntConfigValidator.class)
@GlobalConfig(value = "xaero-map-server-id")
public int xaeroMapServerID = new Random().nextInt();
@GlobalConfig("leaves-carpet-support")
@@ -832,7 +830,7 @@ public final class LeavesConfig {
@GlobalConfig("allow-experimental")
public Boolean allowExperimental = false;
@GlobalConfig(value = "time", lock = true, validator = ListConfigValidator.STRING.class)
@GlobalConfig(value = "time", lock = true)
public List<String> updateTime = List.of("14:00", "2:00");
}
@@ -896,7 +894,7 @@ public final class LeavesConfig {
}
}
@GlobalConfig(value = "server-mod-name", validator = StringConfigValidator.class)
@GlobalConfig(value = "server-mod-name")
public String serverModName = "Leaves";
@GlobalConfig("bstats-privacy-mode")
@@ -929,16 +927,13 @@ public final class LeavesConfig {
@GlobalConfigCategory("linear")
public static class LinearConfig {
@GlobalConfig(value = "version", lock = true, validator = LinearVersionValidator.class)
@GlobalConfig(value = "version", lock = true)
public org.leavesmc.leaves.region.linear.LinearVersion version = org.leavesmc.leaves.region.linear.LinearVersion.V2;
private static class LinearVersionValidator extends EnumConfigValidator<org.leavesmc.leaves.region.linear.LinearVersion> {
}
@GlobalConfig(value = "auto-convert-anvil-to-linear", lock = true)
public boolean autoConvertAnvilToLinear = false;
@GlobalConfig(value = "flush-max-threads", lock = true, validator = IntConfigValidator.class)
@GlobalConfig(value = "flush-max-threads", lock = true)
public int flushThreads = 6;
public int getLinearFlushThreads() {
@@ -949,7 +944,7 @@ public final class LeavesConfig {
}
}
@GlobalConfig(value = "flush-delay-ms", lock = true, validator = IntConfigValidator.class)
@GlobalConfig(value = "flush-delay-ms", lock = true)
public int flushDelayMs = 100;
@GlobalConfig(value = "use-virtual-thread", lock = true)

View File

@@ -0,0 +1,65 @@
package org.leavesmc.leaves.config;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
public class AutoConfigTransformer implements ConfigTransformer<Object, Object> {
@NotNull
@Contract("_ -> new")
public static ConfigTransformer<?, ?> createValidator(@NotNull Field field) {
return new SimpleConfigTransformer(AutoConfigValidator.createValidator(field));
}
@Override
public Object transform(Object from) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Object stringConvert(String value) throws IllegalArgumentException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Class<Object> getFieldClass() {
throw new UnsupportedOperationException("Not supported yet.");
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static class SimpleConfigTransformer implements ConfigTransformer<Object, Object> {
private final ConfigValidator validator;
public SimpleConfigTransformer(ConfigValidator<?> validator) {
this.validator = validator;
}
@Override
public Object transform(Object o) {
return o;
}
@Override
public Object stringConvert(String value) throws IllegalArgumentException {
return validator.stringConvert(value);
}
@Override
public Object loadConvert(Object value) throws IllegalArgumentException {
return validator.loadConvert(value);
}
@Override
public Object saveConvert(Object value) {
return validator.saveConvert(value);
}
@Override
public Class<Object> getFieldClass() {
return validator.getFieldClass();
}
}
}

View File

@@ -0,0 +1,68 @@
package org.leavesmc.leaves.config;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
public final class AutoConfigValidator implements ConfigValidator<Object> {
private static final Map<Class<?>, Supplier<ConfigValidator<?>>> BASE_VALIDATOR = new HashMap<>();
static {
BASE_VALIDATOR.put(Boolean.class, ConfigValidatorImpl.BooleanConfigValidator::new);
BASE_VALIDATOR.put(boolean.class, ConfigValidatorImpl.BooleanConfigValidator::new);
BASE_VALIDATOR.put(Integer.class, ConfigValidatorImpl.IntConfigValidator::new);
BASE_VALIDATOR.put(int.class, ConfigValidatorImpl.IntConfigValidator::new);
BASE_VALIDATOR.put(Double.class, ConfigValidatorImpl.DoubleConfigValidator::new);
BASE_VALIDATOR.put(double.class, ConfigValidatorImpl.DoubleConfigValidator::new);
BASE_VALIDATOR.put(String.class, ConfigValidatorImpl.StringConfigValidator::new);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public static ConfigValidator<?> createValidator(@NotNull Field field) {
Class<?> fieldType = field.getType();
if (BASE_VALIDATOR.containsKey(fieldType)) {
return BASE_VALIDATOR.get(fieldType).get();
}
if (List.class.isAssignableFrom(fieldType)) {
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType parameterizedType) {
Type[] typeArgs = parameterizedType.getActualTypeArguments();
if (typeArgs.length > 0 && typeArgs[0] instanceof Class<?> genericClass) {
if (genericClass.equals(String.class)) {
return new ConfigValidatorImpl.ListConfigValidator.STRING();
}
throw new IllegalArgumentException("List type " + genericClass.getTypeName() + " is not supported.");
}
}
throw new IllegalArgumentException("List type " + genericType.getTypeName() + " is not supported.");
}
if (fieldType.isEnum()) {
return new ConfigValidatorImpl.EnumConfigValidator<>((Class<Enum>) fieldType);
}
throw new IllegalArgumentException("Can't find validator for type " + fieldType.getName());
}
@Override
public Object stringConvert(String value) throws IllegalArgumentException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public Class<Object> getFieldClass() {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@@ -1,7 +1,8 @@
package org.leavesmc.leaves.config;
public interface ConfigConverter<E> {
E convert(String value) throws IllegalArgumentException;
E stringConvert(String value) throws IllegalArgumentException;
@SuppressWarnings("unchecked")
default E loadConvert(Object value) throws IllegalArgumentException {

View File

@@ -0,0 +1,5 @@
package org.leavesmc.leaves.config;
public interface ConfigTransformer<FROM, TO> extends ConfigConverter<FROM> {
TO transform(FROM from);
}

View File

@@ -10,7 +10,7 @@ import java.util.Locale;
public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
private Class<E> fieldClass;
protected Class<E> fieldClass;
@SuppressWarnings("unchecked")
public ConfigValidatorImpl() {
@@ -31,7 +31,7 @@ public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
public static class BooleanConfigValidator extends ConfigValidatorImpl<Boolean> {
@Override
public Boolean convert(String value) throws IllegalArgumentException {
public Boolean stringConvert(String value) throws IllegalArgumentException {
return Boolean.parseBoolean(value);
}
@@ -43,21 +43,21 @@ public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
public static class IntConfigValidator extends ConfigValidatorImpl<Integer> {
@Override
public Integer convert(String value) throws IllegalArgumentException {
public Integer stringConvert(String value) throws IllegalArgumentException {
return Integer.parseInt(value);
}
}
public static class StringConfigValidator extends ConfigValidatorImpl<String> {
@Override
public String convert(String value) throws IllegalArgumentException {
public String stringConvert(String value) throws IllegalArgumentException {
return value;
}
}
public static class DoubleConfigValidator extends ConfigValidatorImpl<Double> {
@Override
public Double convert(String value) throws IllegalArgumentException {
public Double stringConvert(String value) throws IllegalArgumentException {
return Double.parseDouble(value);
}
}
@@ -67,32 +67,40 @@ public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
}
@Override
public List<E> convert(String value) throws IllegalArgumentException {
public List<E> stringConvert(String value) throws IllegalArgumentException {
throw new IllegalArgumentException("not support"); // TODO
}
}
public abstract static class EnumConfigValidator<E extends Enum<E>> extends ConfigValidatorImpl<E> {
public static class EnumConfigValidator<E extends Enum<E>> extends ConfigValidatorImpl<E> {
private final List<String> enumValues;
public EnumConfigValidator() {
super();
public EnumConfigValidator(@NotNull Class<E> enumClass) {
this.fieldClass = enumClass;
this.enumValues = new ArrayList<>() {{
for (E e : getFieldClass().getEnumConstants()) {
for (E e : enumClass.getEnumConstants()) {
add(e.name().toLowerCase(Locale.ROOT));
}
}};
}
public EnumConfigValidator() {
this.enumValues = new ArrayList<>() {{
for (E e : fieldClass.getEnumConstants()) {
add(e.name().toLowerCase(Locale.ROOT));
}
}};
}
@Override
public E convert(@NotNull String value) throws IllegalArgumentException {
public E stringConvert(@NotNull String value) throws IllegalArgumentException {
return Enum.valueOf(getFieldClass(), value.toUpperCase(Locale.ROOT));
}
@Override
public E loadConvert(@NotNull Object value) throws IllegalArgumentException {
return this.convert(value.toString());
return this.stringConvert(value.toString());
}
@Override

View File

@@ -12,5 +12,5 @@ public @interface GlobalConfig {
boolean lock() default false;
Class<? extends ConfigValidator<?>> validator() default ConfigValidatorImpl.BooleanConfigValidator.class;
Class<? extends ConfigValidator<?>> validator() default AutoConfigValidator.class;
}

View File

@@ -6,7 +6,6 @@ import org.jetbrains.annotations.Nullable;
import org.leavesmc.leaves.LeavesConfig;
import org.leavesmc.leaves.LeavesLogger;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
@@ -113,7 +112,7 @@ public class GlobalConfigManager {
return verifiedConfigs.keySet();
}
public record RemovedVerifiedConfig(ConfigConverter<?> convert, boolean transform, Field field, Object upstreamField, String path) {
public record RemovedVerifiedConfig(ConfigTransformer<? super Object, ? super Object> transformer, boolean transform, Field field, Object upstreamField, String path) {
public void run() {
if (transform) {
@@ -121,9 +120,10 @@ public class GlobalConfigManager {
Object savedValue = LeavesConfig.config.get(path);
if (savedValue != null) {
try {
if (savedValue.getClass() != convert.getFieldClass()) {
savedValue = convert.loadConvert(savedValue);
if (savedValue.getClass() != transformer.getFieldClass()) {
savedValue = transformer.loadConvert(savedValue);
}
savedValue = transformer.transform(savedValue);
field.set(upstreamField, savedValue);
} catch (IllegalAccessException | IllegalArgumentException e) {
LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e);
@@ -144,16 +144,14 @@ public class GlobalConfigManager {
}
path.append(config.name());
ConfigConverter<?> converter = null;
ConfigTransformer<? super Object, ? super Object> transformer = null;
try {
Constructor<? extends ConfigConverter<?>> constructor = config.convert().getDeclaredConstructor();
constructor.setAccessible(true);
converter = constructor.newInstance();
transformer = createTransformer(config.transformer(), field);
} catch (Exception e) {
LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e);
}
return new RemovedVerifiedConfig(converter, config.transform(), field, upstreamField, path.toString());
return new RemovedVerifiedConfig(transformer, config.transform(), field, upstreamField, path.toString());
}
}
@@ -162,7 +160,7 @@ public class GlobalConfigManager {
public void set(String stringValue) throws IllegalArgumentException {
Object value;
try {
value = validator.convert(stringValue);
value = validator.stringConvert(stringValue);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("value parse error: " + e.getMessage());
}
@@ -210,7 +208,6 @@ public class GlobalConfigManager {
return value.toString();
}
@SuppressWarnings("unchecked")
@NotNull
@Contract("_, _, _, _ -> new")
public static VerifiedConfig build(@NotNull GlobalConfig config, @NotNull Field field, @Nullable Object upstreamField, @NotNull String upstreamPath) {
@@ -218,9 +215,7 @@ public class GlobalConfigManager {
ConfigValidator<? super Object> validator;
try {
Constructor<? extends ConfigValidator<?>> constructor = config.validator().getDeclaredConstructor();
constructor.setAccessible(true);
validator = (ConfigValidator<? super Object>) constructor.newInstance();
validator = createValidator(config.validator(), field);
} catch (Exception e) {
LeavesLogger.LOGGER.severe("Failure to load leaves config" + path, e);
throw new RuntimeException();
@@ -229,4 +224,26 @@ public class GlobalConfigManager {
return new VerifiedConfig(validator, config.lock(), field, upstreamField, path);
}
}
@SuppressWarnings("unchecked")
private static ConfigValidator<? super Object> createValidator(@NotNull Class<? extends ConfigValidator<?>> clazz, Field field) throws Exception {
if (clazz.equals(AutoConfigValidator.class)) {
return (ConfigValidator<? super Object>) AutoConfigValidator.createValidator(field);
} else {
var constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
return (ConfigValidator<? super Object>) constructor.newInstance();
}
}
@SuppressWarnings("unchecked")
private static ConfigTransformer<? super Object, ? super Object> createTransformer(@NotNull Class<? extends ConfigTransformer<?, ?>> clazz, Field field) throws Exception {
if (clazz.equals(AutoConfigTransformer.class)) {
return (ConfigTransformer<? super Object, ? super Object>) AutoConfigTransformer.createValidator(field);
} else {
var constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
return (ConfigTransformer<? super Object, ? super Object>) constructor.newInstance();
}
}
}

View File

@@ -16,7 +16,7 @@ public @interface RemovedConfig {
boolean transform() default false;
Class<? extends ConfigConverter<?>> convert() default ConfigValidatorImpl.BooleanConfigValidator.class;
Class<? extends ConfigTransformer<?, ?>> transformer() default AutoConfigTransformer.class;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)