mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-28 19:39:22 +00:00
Configurable force peaceful mode switch type list (#423)
This commit is contained in:
@@ -4,6 +4,7 @@ import com.destroystokyo.paper.util.SneakyThrow;
|
||||
import io.papermc.paper.configuration.GlobalConfiguration;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -24,14 +25,18 @@ import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRules;
|
||||
import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeature;
|
||||
import org.leavesmc.leaves.protocol.bladeren.BladerenProtocol.LeavesFeatureSet;
|
||||
import org.leavesmc.leaves.region.RegionFileFormat;
|
||||
import org.leavesmc.leaves.util.ForcePeacefulModeSwitchType;
|
||||
import org.leavesmc.leaves.util.MathUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public final class LeavesConfig {
|
||||
|
||||
@@ -531,14 +536,38 @@ public final class LeavesConfig {
|
||||
@GlobalConfig("fast-resume")
|
||||
public boolean fastResume = false;
|
||||
|
||||
@GlobalConfig(value = "force-peaceful-mode", validator = ForcePeacefulModeValidator.class)
|
||||
public int forcePeacefulMode = -1;
|
||||
public ForcePeacefulModeSwitchConfig peacefulModeSwitch = new ForcePeacefulModeSwitchConfig();
|
||||
|
||||
private static class ForcePeacefulModeValidator extends IntConfigValidator {
|
||||
@Override
|
||||
public void verify(Integer old, Integer value) throws IllegalArgumentException {
|
||||
for (ServerLevel level : MinecraftServer.getServer().getAllLevels()) {
|
||||
level.chunkSource.peacefulModeSwitchTick = value;
|
||||
@GlobalConfigCategory("force-peaceful-mode-switch")
|
||||
public static class ForcePeacefulModeSwitchConfig {
|
||||
@RemovedConfig(name = "force-peaceful-mode", category = "modify", transform = true)
|
||||
@GlobalConfig(value = "tick", validator = TickValidator.class)
|
||||
public int tick = -1;
|
||||
|
||||
private static class TickValidator extends IntConfigValidator {
|
||||
@Override
|
||||
public void verify(Integer old, Integer value) throws IllegalArgumentException {
|
||||
for (ServerLevel level : MinecraftServer.getServer().getAllLevels()) {
|
||||
level.chunkSource.peacefulModeSwitchTick = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@GlobalConfig(value = "types", validator = TypeValidator.class)
|
||||
public List<ForcePeacefulModeSwitchType> types = List.of(ForcePeacefulModeSwitchType.BLAZE, ForcePeacefulModeSwitchType.WITHER, ForcePeacefulModeSwitchType.SHULKER, ForcePeacefulModeSwitchType.WARDEN);
|
||||
public Set<Class<? extends Entity>> classTypes = new HashSet<>();
|
||||
|
||||
private static class TypeValidator extends ListConfigValidator.ENUM<ForcePeacefulModeSwitchType> {
|
||||
@Override
|
||||
public void verify(List<ForcePeacefulModeSwitchType> old, @NotNull List<ForcePeacefulModeSwitchType> value) throws IllegalArgumentException {
|
||||
Set<Class<? extends Entity>> classes = new HashSet<>();
|
||||
for (ForcePeacefulModeSwitchType type : value) {
|
||||
classes.add(type.getEntityClass());
|
||||
}
|
||||
LeavesConfig.modify.peacefulModeSwitch.classTypes = classes;
|
||||
for (ServerLevel level : MinecraftServer.getServer().getAllLevels()) {
|
||||
level.chunkSource.peacefulModeSwitchEntityTypes = classes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,6 @@ public class AutoConfigTransformer implements ConfigTransformer<Object, Object>
|
||||
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> {
|
||||
|
||||
@@ -56,10 +51,5 @@ public class AutoConfigTransformer implements ConfigTransformer<Object, Object>
|
||||
public Object saveConvert(Object value) {
|
||||
return validator.saveConvert(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Object> getFieldClass() {
|
||||
return validator.getFieldClass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ public final class AutoConfigValidator implements ConfigValidator<Object> {
|
||||
if (typeArgs.length > 0 && typeArgs[0] instanceof Class<?> genericClass) {
|
||||
if (genericClass.equals(String.class)) {
|
||||
return new ConfigValidatorImpl.ListConfigValidator.STRING();
|
||||
} else if (genericClass.isEnum()) {
|
||||
return new ConfigValidatorImpl.ListConfigValidator.ENUM<>((Class<Enum>) genericClass);
|
||||
}
|
||||
throw new IllegalArgumentException("List type " + genericClass.getTypeName() + " is not supported.");
|
||||
}
|
||||
@@ -60,9 +62,4 @@ public final class AutoConfigValidator implements ConfigValidator<Object> {
|
||||
public Object stringConvert(String value) throws IllegalArgumentException {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Object> getFieldClass() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,4 @@ public interface ConfigConverter<E> {
|
||||
default Object saveConvert(E value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
Class<E> getFieldClass();
|
||||
}
|
||||
|
||||
@@ -7,29 +7,12 @@ import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
|
||||
|
||||
protected Class<E> fieldClass;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigValidatorImpl() {
|
||||
Type superClass = getClass().getGenericSuperclass();
|
||||
if (superClass instanceof ParameterizedType) {
|
||||
Type[] actualTypeArguments = ((ParameterizedType) superClass).getActualTypeArguments();
|
||||
if (actualTypeArguments[0] instanceof Class) {
|
||||
this.fieldClass = (Class<E>) actualTypeArguments[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<E> getFieldClass() {
|
||||
return fieldClass;
|
||||
}
|
||||
|
||||
public static class BooleanConfigValidator extends ConfigValidatorImpl<Boolean> {
|
||||
|
||||
@Override
|
||||
public Boolean stringConvert(String value) throws IllegalArgumentException {
|
||||
return Boolean.parseBoolean(value);
|
||||
@@ -63,21 +46,68 @@ public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
|
||||
}
|
||||
|
||||
public abstract static class ListConfigValidator<E> extends ConfigValidatorImpl<List<E>> {
|
||||
|
||||
public static class STRING extends ListConfigValidator<String> {
|
||||
public STRING() {
|
||||
super(new StringConfigValidator());
|
||||
}
|
||||
}
|
||||
|
||||
public static class ENUM<E extends Enum<E>> extends ListConfigValidator<E> {
|
||||
public ENUM() {
|
||||
super(null);
|
||||
this.elementValidator = new EnumConfigValidator<E>(getTypeArgument(getClass(), ENUM.class, Class::isEnum));
|
||||
}
|
||||
|
||||
public ENUM(@NotNull Class<E> enumClass) {
|
||||
super(new EnumConfigValidator<>(enumClass));
|
||||
}
|
||||
}
|
||||
|
||||
protected ConfigValidator<E> elementValidator;
|
||||
|
||||
public ListConfigValidator(ConfigValidator<E> elementValidator) {
|
||||
this.elementValidator = elementValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> loadConvert(Object value) throws IllegalArgumentException {
|
||||
if (elementValidator == null) {
|
||||
throw new IllegalArgumentException("element validator is null");
|
||||
}
|
||||
if (value instanceof List<?> list) {
|
||||
return list.stream().map(elementValidator::loadConvert).collect(Collectors.toList());
|
||||
} else {
|
||||
throw new IllegalArgumentException("value is not a list");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveConvert(List<E> value) {
|
||||
if (elementValidator == null) {
|
||||
throw new IllegalArgumentException("element validator is null");
|
||||
}
|
||||
return value.stream().map(elementValidator::saveConvert).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> stringConvert(String value) throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException("not support"); // TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> valueSuggest() {
|
||||
return List.of("<NOT SUPPORT>");
|
||||
}
|
||||
}
|
||||
|
||||
public static class EnumConfigValidator<E extends Enum<E>> extends ConfigValidatorImpl<E> {
|
||||
|
||||
protected Class<E> enumClass;
|
||||
private final List<String> enumValues;
|
||||
|
||||
public EnumConfigValidator(@NotNull Class<E> enumClass) {
|
||||
this.fieldClass = enumClass;
|
||||
this.enumClass = enumClass;
|
||||
this.enumValues = new ArrayList<>() {{
|
||||
for (E e : enumClass.getEnumConstants()) {
|
||||
add(e.name().toLowerCase(Locale.ROOT));
|
||||
@@ -86,8 +116,9 @@ public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
|
||||
}
|
||||
|
||||
public EnumConfigValidator() {
|
||||
this.enumClass = getTypeArgument(getClass(), EnumConfigValidator.class, Class::isEnum);
|
||||
this.enumValues = new ArrayList<>() {{
|
||||
for (E e : fieldClass.getEnumConstants()) {
|
||||
for (E e : enumClass.getEnumConstants()) {
|
||||
add(e.name().toLowerCase(Locale.ROOT));
|
||||
}
|
||||
}};
|
||||
@@ -95,7 +126,7 @@ public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
|
||||
|
||||
@Override
|
||||
public E stringConvert(@NotNull String value) throws IllegalArgumentException {
|
||||
return Enum.valueOf(getFieldClass(), value.toUpperCase(Locale.ROOT));
|
||||
return Enum.valueOf(enumClass, value.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,4 +144,22 @@ public abstract class ConfigValidatorImpl<E> implements ConfigValidator<E> {
|
||||
return enumValues;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <E> Class<E> getTypeArgument(Class<?> startClass, Class<?> rawType, Function<Class<?>, Boolean> check) {
|
||||
Type currentClass = startClass;
|
||||
while (currentClass instanceof Class<?> clazz) {
|
||||
Type genericSuperclass = clazz.getGenericSuperclass();
|
||||
if (genericSuperclass instanceof ParameterizedType parameterizedType) {
|
||||
if (rawType.equals(parameterizedType.getRawType())) {
|
||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||
if (actualTypeArguments.length > 0 && actualTypeArguments[0] instanceof Class<?> parameterizedClass && (check == null || check.apply(parameterizedClass))) {
|
||||
return (Class<E>) parameterizedClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
currentClass = genericSuperclass;
|
||||
}
|
||||
throw new IllegalArgumentException("Can't find type argument of " + startClass.getName() + " for " + rawType.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,12 +103,8 @@ public class GlobalConfigManager {
|
||||
throw new IllegalArgumentException("?");
|
||||
}
|
||||
|
||||
if (savedValue.getClass() != validator.getFieldClass()) {
|
||||
savedValue = validator.loadConvert(savedValue);
|
||||
}
|
||||
|
||||
savedValue = validator.loadConvert(savedValue);
|
||||
validator.verify(null, savedValue);
|
||||
|
||||
field.set(upstreamField, savedValue);
|
||||
} catch (IllegalArgumentException | ClassCastException e) {
|
||||
LeavesConfig.config.set(path, defValue);
|
||||
|
||||
@@ -48,10 +48,7 @@ public record VerifiedConfig(ConfigValidator<? super Object> validator, boolean
|
||||
Object savedValue = LeavesConfig.config.get(path);
|
||||
try {
|
||||
if (savedValue != null) {
|
||||
if (validator.getFieldClass() != savedValue.getClass()) {
|
||||
savedValue = validator.loadConvert(savedValue);
|
||||
}
|
||||
|
||||
savedValue = validator.loadConvert(savedValue);
|
||||
if (!savedValue.equals(value)) {
|
||||
return value.toString() + "(" + savedValue + " after restart)";
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@ public record VerifiedRemovedConfig(ConfigTransformer<? super Object, ? super Ob
|
||||
Object savedValue = LeavesConfig.config.get(path);
|
||||
if (savedValue != null) {
|
||||
try {
|
||||
if (savedValue.getClass() != transformer.getFieldClass()) {
|
||||
savedValue = transformer.loadConvert(savedValue);
|
||||
}
|
||||
savedValue = transformer.loadConvert(savedValue);
|
||||
savedValue = transformer.transform(savedValue);
|
||||
field.set(upstreamField, savedValue);
|
||||
} catch (IllegalAccessException | IllegalArgumentException e) {
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.leavesmc.leaves.util;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.monster.*;
|
||||
import net.minecraft.world.entity.monster.breeze.Breeze;
|
||||
import net.minecraft.world.entity.monster.hoglin.Hoglin;
|
||||
import net.minecraft.world.entity.monster.piglin.Piglin;
|
||||
import net.minecraft.world.entity.monster.piglin.PiglinBrute;
|
||||
import net.minecraft.world.entity.monster.warden.Warden;
|
||||
import net.minecraft.world.entity.boss.wither.WitherBoss;
|
||||
|
||||
public enum ForcePeacefulModeSwitchType {
|
||||
BLAZE(Blaze.class),
|
||||
CREEPER(Creeper.class),
|
||||
DROWNED(Drowned.class),
|
||||
ELDER_GUARDIAN(ElderGuardian.class),
|
||||
ENDERMAN(EnderMan.class),
|
||||
ENDERMITE(Endermite.class),
|
||||
EVOKER(Evoker.class),
|
||||
GHAST(Ghast.class),
|
||||
GIANT(Giant.class),
|
||||
GUARDIAN(Guardian.class),
|
||||
HOGLIN(Hoglin.class),
|
||||
HUSK(Husk.class),
|
||||
ILLUSIONER(Illusioner.class),
|
||||
MAGMA_CUBE(MagmaCube.class),
|
||||
PHANTOM(Phantom.class),
|
||||
PIGLIN(Piglin.class),
|
||||
PIGLIN_BRUTE(PiglinBrute.class),
|
||||
PILLAGER(Pillager.class),
|
||||
RAVAGER(Ravager.class),
|
||||
SHULKER(Shulker.class),
|
||||
SILVERFISH(Silverfish.class),
|
||||
SKELETON(Skeleton.class),
|
||||
SLIME(Slime.class),
|
||||
SPIDER(Spider.class),
|
||||
STRAY(Stray.class),
|
||||
VEX(Vex.class),
|
||||
VINDICATOR(Vindicator.class),
|
||||
WARDEN(Warden.class),
|
||||
WITCH(Witch.class),
|
||||
WITHER_SKELETON(WitherSkeleton.class),
|
||||
ZOGLIN(Zoglin.class),
|
||||
ZOMBIE(Zombie.class),
|
||||
ZOMBIE_VILLAGER(ZombieVillager.class),
|
||||
ZOMBIFIED_PIGLIN(ZombifiedPiglin.class),
|
||||
WITHER(WitherBoss.class),
|
||||
CAVE_SPIDER(CaveSpider.class),
|
||||
BREEZE(Breeze.class),
|
||||
BOGGED(Bogged.class);
|
||||
|
||||
private final Class<? extends Entity> entityClass;
|
||||
|
||||
ForcePeacefulModeSwitchType(Class<? extends Entity> entityClass) {
|
||||
this.entityClass = entityClass;
|
||||
}
|
||||
|
||||
public Class<? extends Entity> getEntityClass() {
|
||||
return entityClass;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user