diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 1ff07e9c..e6726321 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -29,6 +29,8 @@ dependencies { compileOnlyApi("com.fastasyncworldedit:FastAsyncWorldEdit-Core") compileOnly("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT") + compileOnly("net.thenextlvl.core:paper:2.3.0-pre4") + api("net.thenextlvl:nbt:3.0.0-pre1") api("net.thenextlvl.core:files:3.0.0") api(platform("com.intellectualsites.bom:bom-newest:1.55")) diff --git a/api/src/main/java/net/thenextlvl/protect/flag/Flag.java b/api/src/main/java/net/thenextlvl/protect/flag/Flag.java index 1294ddcf..761b6dbe 100644 --- a/api/src/main/java/net/thenextlvl/protect/flag/Flag.java +++ b/api/src/main/java/net/thenextlvl/protect/flag/Flag.java @@ -1,34 +1,73 @@ package net.thenextlvl.protect.flag; +import com.google.common.base.Preconditions; +import com.mojang.brigadier.arguments.ArgumentType; import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.Keyed; +import org.jetbrains.annotations.Contract; import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; -/** - * Represents a flag with a specific value type. - * - * @param The type of the flag value. - */ -public interface Flag extends Comparable<@NonNull Flag> { - /** - * Retrieves the {@link Key} associated with this flag. - * - * @return the Key of the flag - */ - @NonNull - Key key(); - - /** - * Retrieves the type of the flag value. - * - * @return the type of the flag value - */ - @NonNull - Class type(); - - /** - * Retrieves the default value for a flag. - * - * @return The default value for the flag. - */ - T defaultValue(); +public abstract class Flag implements Keyed, Comparable<@NonNull Flag> { + private final @NonNull Key key; + private final T defaultValue; + private final T protectedValue; + private final boolean nullable; + + protected Flag(@NonNull Key key, @Nullable T defaultValue, @Nullable T protectedValue, boolean nullable) { + Preconditions.checkArgument(nullable || defaultValue != null, "Default value must be non-null if flag is not nullable"); + this.key = key; + this.defaultValue = defaultValue; + this.protectedValue = protectedValue; + this.nullable = nullable; + } + + protected Flag(@NonNull Key key, @NonNull T defaultValue, @Nullable T protectedValue) { + this(key, defaultValue, protectedValue, false); + } + + protected Flag(@NonNull Key key, @Nullable T defaultValue, boolean nullable) { + this(key, defaultValue, null, nullable); + } + + protected Flag(@NonNull Key key, @NonNull T defaultValue) { + this(key, defaultValue, null, false); + } + + protected Flag(@NonNull Key key) { + this(key, null, true); + } + + @Contract(pure = true) + public abstract @NonNull Class getValueType(); + + @Contract(value = " -> new", pure = true) + public abstract @NonNull ArgumentType getArgumentType(); + + @Override + @Contract(pure = true) + public @NonNull Key key() { + return key; + } + + @Contract(pure = true) + public T getDefaultValue() { + return defaultValue; + } + + @Contract(pure = true) + public T getProtectedValue() { + return protectedValue; + } + + @Contract(pure = true) + public boolean isNullable() { + return nullable; + } + + @Override + @Contract(pure = true) + public int compareTo(@NonNull Flag flag) { + return key.compareTo(flag.key()); + } } diff --git a/api/src/main/java/net/thenextlvl/protect/flag/FlagRegistry.java b/api/src/main/java/net/thenextlvl/protect/flag/FlagRegistry.java index 650d1588..67815558 100644 --- a/api/src/main/java/net/thenextlvl/protect/flag/FlagRegistry.java +++ b/api/src/main/java/net/thenextlvl/protect/flag/FlagRegistry.java @@ -1,10 +1,11 @@ package net.thenextlvl.protect.flag; import net.kyori.adventure.key.Key; -import net.kyori.adventure.key.KeyPattern; import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Unmodifiable; import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.NullMarked; import java.util.Optional; import java.util.Set; @@ -13,118 +14,61 @@ * FlagRegistry is an interface that provides methods for managing registered flags. */ public interface FlagRegistry { + @NonNull + @Unmodifiable + @Contract(pure = true) + Set<@NonNull Flag> getFlags(); - /** - * Retrieves the set of flags associated with this FlagRegistry. - * - * @return a Set of flags associated with the FlagRegistry - */ - @NullMarked - Set> getFlags(); + @NonNull + @Unmodifiable + @Contract(pure = true) + Set<@NonNull Flag> getFlags(Plugin plugin); /** - * Retrieves the set of flags associated with the given plugin. + * Retrieves the flag associated with the given key. * - * @param plugin the plugin for which to retrieve the flags - * @return a set of flags associated with the plugin + * @param key the key of the flag to retrieve + * @param the type of the flag + * @return an {@code Optional} containing the flag, or empty if no flag was found */ - @NullMarked - Set> getFlags(Plugin plugin); + @Contract(pure = true) + > @NonNull Optional<@NonNull T> getFlag(Key key); /** - * Retrieves the flag associated with the given Key. + * Registers a new flag with the specified plugin. * - * @param key the Key of the flag to retrieve - * @param the type of the flag value - * @return an Optional containing the flag, or an empty Optional if no flag was found + * @param plugin the plugin registering the flag + * @return {@code true} if the flag was registered, {@code false} otherwise */ - @NullMarked - Optional> getFlag(Key key); + boolean register(@NonNull Plugin plugin, @NonNull Flag flag); - /** - * Registers a new flag with the specified plugin, name, and default value. - * - * @param the type of the flag value - * @param plugin the plugin registering the flag - * @param name the name of the flag - * @param defaultValue the default value of the flag - * @return the registered flag - * @throws IllegalStateException if a flag by the same plugin with the same name is already registered - * @see #register(Plugin, Class, String, Object) - */ - @NullMarked - @SuppressWarnings("unchecked") - default Flag register(Plugin plugin, @KeyPattern.Value String name, T defaultValue) throws IllegalStateException { - return register(plugin, (Class) defaultValue.getClass(), name, defaultValue); + default boolean register(@NonNull Flag flag) { + return register(JavaPlugin.getProvidingPlugin(flag.getClass()), flag); } /** - * Registers a new flag with the specified plugin, type, name, and default value. - * - * @param the type of the flag value - * @param plugin the plugin registering the flag - * @param type the class type of the flag value - * @param name the name of the flag - * @param defaultValue the default value of the flag - * @return the registered flag - * @throws IllegalStateException if a flag by the same plugin with the same name is already registered - */ - @NonNull Flag register(@NonNull Plugin plugin, @NonNull Class type, - @KeyPattern.Value String name, T defaultValue - ) throws IllegalStateException; - - /** - * Registers a new protection flag with the specified plugin, name, default value, and protected value. + * Unregisters the given flag. * - * @param the type of the flag value - * @param plugin the plugin registering the flag - * @param name the name of the flag - * @param defaultValue the default value of the flag - * @param protectedValue the protected value of the flag, which is typically opposite to the default value - * @return the registered protection flag - * @throws IllegalStateException if a flag by the same plugin with the same name is already registered - * @see #register(Plugin, Class, String, Object, Object) + * @param flag the flag to unregister + * @return {@code true} if the flag was unregistered, {@code false} otherwise */ - @NullMarked - @SuppressWarnings("unchecked") - default ProtectionFlag register(Plugin plugin, @KeyPattern.Value String name, T defaultValue, T protectedValue) throws IllegalStateException { - return register(plugin, (Class) defaultValue.getClass(), name, defaultValue, protectedValue); + default boolean unregister(@NonNull Flag flag) { + return unregister(flag.key()); } /** - * Registers a new protection flag with the specified plugin, name, default value, and protected value. - *

- * protectedValue defines (generally the opposite of defaultValue) what the flag value is to protect against it, - * for example, taking the flag 'explosions', protectedValue would be false and defaultValue true - *

- * {@code var explosions = register(plugin, Boolean.class, "explosions", true, false);} - * - * @param the type of the flag value - * @param plugin the plugin registering the flag - * @param type the class type of the flag value - * @param name the name of the flag - * @param defaultValue the default value of the flag - * @param protectedValue the protected value of the flag, which is typically opposite to the default value - * @return the registered protection flag - * @throws IllegalStateException if a flag by the same plugin with the same name is already registered - */ - @NonNull ProtectionFlag register(@NonNull Plugin plugin, @NonNull Class type, - @KeyPattern.Value @NonNull String name, T defaultValue, T protectedValue - ) throws IllegalStateException; - - /** - * Unregisters a flag identified by the given Key. + * Unregisters the flag by the given key. * - * @param flag the Key of the flag to unregister - * @return true if the flag was unregistered, false otherwise + * @param key the key of the flag to unregister + * @return {@code true} if the flag was unregistered, {@code false} otherwise */ - boolean unregister(@NonNull Key flag); + boolean unregister(@NonNull Key key); /** * Unregisters all flags associated with the specified plugin. * * @param plugin the plugin for which to unregister flags - * @return true if any flag was unregistered, false otherwise + * @return {@code true} if any flag was unregistered, {@code false} otherwise */ boolean unregisterAll(@NonNull Plugin plugin); } diff --git a/api/src/main/java/net/thenextlvl/protect/flag/ProtectionFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/ProtectionFlag.java deleted file mode 100644 index 2151b78d..00000000 --- a/api/src/main/java/net/thenextlvl/protect/flag/ProtectionFlag.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.thenextlvl.protect.flag; - -/** - * Represents a protection flag with a specific value type. - * - * @param The type of the flag value. - */ -public interface ProtectionFlag extends Flag { - /** - * Retrieves the protected value associated with this flag. - * - * @return the protected value of the flag - */ - T protectedValue(); -} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/collection/CollectionFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/collection/CollectionFlag.java new file mode 100644 index 00000000..3f436d35 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/collection/CollectionFlag.java @@ -0,0 +1,18 @@ +package net.thenextlvl.protect.flag.collection; + +import net.kyori.adventure.key.Key; +import net.thenextlvl.protect.flag.Flag; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Collection; + +public abstract class CollectionFlag> extends Flag { + protected CollectionFlag(@NonNull Key key, @NonNull T defaultValue, @Nullable T protectedValue) { + super(key, defaultValue, protectedValue, false); + } + + protected CollectionFlag(@NonNull Key key, @NonNull T defaultValue) { + this(key, defaultValue, null); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/collection/ListFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/collection/ListFlag.java new file mode 100644 index 00000000..53cfe700 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/collection/ListFlag.java @@ -0,0 +1,17 @@ +package net.thenextlvl.protect.flag.collection; + +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.List; + +public abstract class ListFlag extends CollectionFlag> { + public ListFlag(@NonNull Key key, @NonNull List defaultValue, @Nullable List protectedValue) { + super(key, defaultValue, protectedValue); + } + + public ListFlag(@NonNull Key key, @NonNull List defaultValue) { + super(key, defaultValue); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/collection/SetFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/collection/SetFlag.java new file mode 100644 index 00000000..4ac3fb66 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/collection/SetFlag.java @@ -0,0 +1,17 @@ +package net.thenextlvl.protect.flag.collection; + +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Set; + +public abstract class SetFlag extends CollectionFlag> { + public SetFlag(@NonNull Key key, @NonNull Set defaultValue, @Nullable Set protectedValue) { + super(key, defaultValue, protectedValue); + } + + public SetFlag(@NonNull Key key, @NonNull Set defaultValue) { + super(key, defaultValue); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/location/LocationFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/location/LocationFlag.java new file mode 100644 index 00000000..ec669a67 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/location/LocationFlag.java @@ -0,0 +1,56 @@ +package net.thenextlvl.protect.flag.location; + +import com.mojang.brigadier.arguments.ArgumentType; +import io.papermc.paper.command.brigadier.argument.ArgumentTypes; +import io.papermc.paper.command.brigadier.argument.CustomArgumentType; +import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver; +import net.kyori.adventure.key.Key; +import net.thenextlvl.protect.flag.Flag; +import org.bukkit.Location; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +public final class LocationFlag extends Flag { + public LocationFlag(@NonNull Key key, @Nullable Location defaultValue, @Nullable Location protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public LocationFlag(@NonNull Key key, @NonNull Location defaultValue, @Nullable Location protectedValue) { + super(key, defaultValue, protectedValue); + } + + public LocationFlag(@NonNull Key key, @Nullable Location defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public LocationFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return Location.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return new LocationArgumentType(); + } + + @NullMarked + private static final class LocationArgumentType implements CustomArgumentType.Converted { + @Override + public Location convert(FinePositionResolver nativeType) { + // var resolver = context.getArgument("value", FinePositionResolver.class); + // var area = context.getArgument("area", Area.class); + // return resolver.resolve(context.getSource()).toLocation(area.getWorld()); + return null; // fixme + } + + @Override + public ArgumentType getNativeType() { + return ArgumentTypes.finePosition(); + } + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/BooleanFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/BooleanFlag.java new file mode 100644 index 00000000..59835dbe --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/BooleanFlag.java @@ -0,0 +1,35 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.BoolArgumentType; +import net.kyori.adventure.key.Key; +import net.thenextlvl.protect.flag.Flag; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +import java.util.Objects; + +public final class BooleanFlag extends Flag { + public BooleanFlag(@NonNull Key key, @NonNull Boolean defaultValue, @Nullable Boolean protectedValue) { + super(key, defaultValue, protectedValue, false); + } + + public BooleanFlag(@NonNull Key key, @NonNull Boolean defaultValue) { + this(key, defaultValue, null); + } + + @Override + public @NonNull Boolean getDefaultValue() { + return Objects.requireNonNull(super.getDefaultValue()); + } + + @Override + public @NonNull Class getValueType() { + return Boolean.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return BoolArgumentType.bool(); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/ByteFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/ByteFlag.java new file mode 100644 index 00000000..f9c1dc14 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/ByteFlag.java @@ -0,0 +1,50 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import io.papermc.paper.command.brigadier.argument.CustomArgumentType; +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +public final class ByteFlag extends NumberFlag { + public ByteFlag(@NonNull Key key, @Nullable Byte defaultValue, @Nullable Byte protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public ByteFlag(@NonNull Key key, @NonNull Byte defaultValue, @Nullable Byte protectedValue) { + super(key, defaultValue, protectedValue); + } + + public ByteFlag(@NonNull Key key, @Nullable Byte defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public ByteFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return Byte.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return new ByteArgumentType(); + } + + @NullMarked + private static final class ByteArgumentType implements CustomArgumentType.Converted { + @Override + public Byte convert(Integer nativeType) { + return nativeType.byteValue(); + } + + @Override + public ArgumentType getNativeType() { + return IntegerArgumentType.integer(Byte.MIN_VALUE, Byte.MAX_VALUE); + } + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/DoubleFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/DoubleFlag.java new file mode 100644 index 00000000..d9e66d54 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/DoubleFlag.java @@ -0,0 +1,35 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.DoubleArgumentType; +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public final class DoubleFlag extends NumberFlag { + public DoubleFlag(@NonNull Key key, @Nullable Double defaultValue, @Nullable Double protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public DoubleFlag(@NonNull Key key, @NonNull Double defaultValue, @Nullable Double protectedValue) { + super(key, defaultValue, protectedValue); + } + + public DoubleFlag(@NonNull Key key, @Nullable Double defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public DoubleFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return Double.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return DoubleArgumentType.doubleArg(); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/EnumFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/EnumFlag.java new file mode 100644 index 00000000..3fb338b1 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/EnumFlag.java @@ -0,0 +1,43 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import core.paper.command.argument.EnumArgumentType; +import core.paper.command.argument.codec.EnumStringCodec; +import net.kyori.adventure.key.Key; +import net.thenextlvl.protect.flag.Flag; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public final class EnumFlag> extends Flag { + private final @NonNull Class type; + + public EnumFlag(@NonNull Key key, @NonNull Class type, @Nullable T defaultValue, @Nullable T protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + this.type = type; + } + + public EnumFlag(@NonNull Key key, @NonNull Class type, @NonNull T defaultValue, @Nullable T protectedValue) { + super(key, defaultValue, protectedValue); + this.type = type; + } + + public EnumFlag(@NonNull Key key, @NonNull Class type, @Nullable T defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + this.type = type; + } + + public EnumFlag(@NonNull Key key, @NonNull Class type) { + super(key); + this.type = type; + } + + @Override + public @NonNull Class getValueType() { + return type; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return EnumArgumentType.of(getValueType(), EnumStringCodec.lowerHyphen()); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/FloatFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/FloatFlag.java new file mode 100644 index 00000000..60e896f0 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/FloatFlag.java @@ -0,0 +1,35 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.FloatArgumentType; +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public final class FloatFlag extends NumberFlag { + public FloatFlag(@NonNull Key key, @Nullable Float defaultValue, @Nullable Float protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public FloatFlag(@NonNull Key key, @NonNull Float defaultValue, @Nullable Float protectedValue) { + super(key, defaultValue, protectedValue); + } + + public FloatFlag(@NonNull Key key, @Nullable Float defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public FloatFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return Float.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return FloatArgumentType.floatArg(); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/IntegerFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/IntegerFlag.java new file mode 100644 index 00000000..4594dcd1 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/IntegerFlag.java @@ -0,0 +1,35 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public final class IntegerFlag extends NumberFlag { + public IntegerFlag(@NonNull Key key, @Nullable Integer defaultValue, @Nullable Integer protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public IntegerFlag(@NonNull Key key, @NonNull Integer defaultValue, @Nullable Integer protectedValue) { + super(key, defaultValue, protectedValue); + } + + public IntegerFlag(@NonNull Key key, @Nullable Integer defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public IntegerFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return Integer.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return IntegerArgumentType.integer(); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/LongFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/LongFlag.java new file mode 100644 index 00000000..981bbc2b --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/LongFlag.java @@ -0,0 +1,35 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.LongArgumentType; +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public final class LongFlag extends NumberFlag { + public LongFlag(@NonNull Key key, @Nullable Long defaultValue, @Nullable Long protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public LongFlag(@NonNull Key key, @NonNull Long defaultValue, @Nullable Long protectedValue) { + super(key, defaultValue, protectedValue); + } + + public LongFlag(@NonNull Key key, @Nullable Long defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public LongFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return Long.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return LongArgumentType.longArg(); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/NumberFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/NumberFlag.java new file mode 100644 index 00000000..9032b815 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/NumberFlag.java @@ -0,0 +1,24 @@ +package net.thenextlvl.protect.flag.standard; + +import net.kyori.adventure.key.Key; +import net.thenextlvl.protect.flag.Flag; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public abstract class NumberFlag extends Flag { + protected NumberFlag(@NonNull Key key, @Nullable T defaultValue, @Nullable T protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + protected NumberFlag(@NonNull Key key, @NonNull T defaultValue, @Nullable T protectedValue) { + super(key, defaultValue, protectedValue); + } + + protected NumberFlag(@NonNull Key key, @Nullable T defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + protected NumberFlag(@NonNull Key key) { + super(key); + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/ShortFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/ShortFlag.java new file mode 100644 index 00000000..118f618c --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/ShortFlag.java @@ -0,0 +1,50 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import io.papermc.paper.command.brigadier.argument.CustomArgumentType; +import net.kyori.adventure.key.Key; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +public final class ShortFlag extends NumberFlag { + public ShortFlag(@NonNull Key key, @Nullable Short defaultValue, @Nullable Short protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public ShortFlag(@NonNull Key key, @NonNull Short defaultValue, @Nullable Short protectedValue) { + super(key, defaultValue, protectedValue); + } + + public ShortFlag(@NonNull Key key, @Nullable Short defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public ShortFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return Short.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return new ShortArgumentType(); + } + + @NullMarked + private static final class ShortArgumentType implements CustomArgumentType.Converted { + @Override + public Short convert(Integer nativeType) { + return nativeType.shortValue(); + } + + @Override + public ArgumentType getNativeType() { + return IntegerArgumentType.integer(Short.MIN_VALUE, Short.MAX_VALUE); + } + } +} diff --git a/api/src/main/java/net/thenextlvl/protect/flag/standard/StringFlag.java b/api/src/main/java/net/thenextlvl/protect/flag/standard/StringFlag.java new file mode 100644 index 00000000..672feb31 --- /dev/null +++ b/api/src/main/java/net/thenextlvl/protect/flag/standard/StringFlag.java @@ -0,0 +1,36 @@ +package net.thenextlvl.protect.flag.standard; + +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.arguments.StringArgumentType; +import net.kyori.adventure.key.Key; +import net.thenextlvl.protect.flag.Flag; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public final class StringFlag extends Flag { + public StringFlag(@NonNull Key key, @Nullable String defaultValue, @Nullable String protectedValue, boolean nullable) { + super(key, defaultValue, protectedValue, nullable); + } + + public StringFlag(@NonNull Key key, @NonNull String defaultValue, @Nullable String protectedValue) { + super(key, defaultValue, protectedValue); + } + + public StringFlag(@NonNull Key key, @Nullable String defaultValue, boolean nullable) { + super(key, defaultValue, nullable); + } + + public StringFlag(@NonNull Key key) { + super(key); + } + + @Override + public @NonNull Class getValueType() { + return String.class; + } + + @Override + public @NonNull ArgumentType getArgumentType() { + return StringArgumentType.string(); + } +} diff --git a/plugin/src/main/java/net/thenextlvl/protect/ProtectPlugin.java b/plugin/src/main/java/net/thenextlvl/protect/ProtectPlugin.java index 89770d4b..3827ea5a 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/ProtectPlugin.java +++ b/plugin/src/main/java/net/thenextlvl/protect/ProtectPlugin.java @@ -14,6 +14,7 @@ import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.thenextlvl.nbt.serialization.NBT; import net.thenextlvl.protect.adapter.area.CuboidAreaAdapter; @@ -49,7 +50,10 @@ import net.thenextlvl.protect.flag.CraftFlagRegistry; import net.thenextlvl.protect.flag.Flag; import net.thenextlvl.protect.flag.FlagRegistry; -import net.thenextlvl.protect.flag.ProtectionFlag; +import net.thenextlvl.protect.flag.standard.BooleanFlag; +import net.thenextlvl.protect.flag.standard.EnumFlag; +import net.thenextlvl.protect.flag.standard.LongFlag; +import net.thenextlvl.protect.flag.standard.StringFlag; import net.thenextlvl.protect.listener.AreaListener; import net.thenextlvl.protect.listener.ConnectionListener; import net.thenextlvl.protect.listener.EntityListener; @@ -89,7 +93,7 @@ public class ProtectPlugin extends JavaPlugin { private final PluginVersionChecker versionChecker = new PluginVersionChecker(this); private final CollisionController collisionController = new CollisionController(); - + private final CraftProtectionService protectionService = new CraftProtectionService(this); private final CraftFlagRegistry flagRegistry = new CraftFlagRegistry(); private final CraftAreaProvider areaProvider = new CraftAreaProvider(this); @@ -236,58 +240,67 @@ public ComponentBundle bundle() { .build(); public class Flags { - public final Flag<@Nullable Long> time = flagRegistry().register(ProtectPlugin.this, Long.class, "time", null); - public final Flag<@Nullable String> farewell = flagRegistry().register(ProtectPlugin.this, String.class, "farewell", null); - public final Flag<@Nullable String> farewellActionbar = flagRegistry().register(ProtectPlugin.this, String.class, "farewell_actionbar", null); - public final Flag<@Nullable String> farewellTitle = flagRegistry().register(ProtectPlugin.this, String.class, "farewell_title", null); - public final Flag<@Nullable String> greetings = flagRegistry().register(ProtectPlugin.this, String.class, "greetings", null); - public final Flag<@Nullable String> greetingsActionbar = flagRegistry().register(ProtectPlugin.this, String.class, "greetings_actionbar", null); - public final Flag<@Nullable String> greetingsTitle = flagRegistry().register(ProtectPlugin.this, String.class, "greetings_title", null); - public final Flag<@Nullable WeatherType> weather = flagRegistry().register(ProtectPlugin.this, WeatherType.class, "weather", null); - - public final Flag areaEnter = flagRegistry().register(ProtectPlugin.this, "enter", true); - public final Flag areaLeave = flagRegistry().register(ProtectPlugin.this, "leave", true); - public final Flag damage = flagRegistry().register(ProtectPlugin.this, "damage", true); - public final Flag entityItemDrop = flagRegistry().register(ProtectPlugin.this, "entity_item_drop", true); - public final Flag entityItemPickup = flagRegistry().register(ProtectPlugin.this, "entity_item_pickup", true); - public final Flag gameEvents = flagRegistry().register(ProtectPlugin.this, "game_events", true); - public final Flag gravity = flagRegistry().register(ProtectPlugin.this, "gravity", true); - public final Flag hunger = flagRegistry().register(ProtectPlugin.this, "hunger", true); - public final Flag liquidFlow = flagRegistry().register(ProtectPlugin.this, "liquid_flow", true); - public final Flag naturalEntitySpawn = flagRegistry().register(ProtectPlugin.this, "natural_entity_spawn", true); - public final Flag notifyFailedInteractions = flagRegistry().register(ProtectPlugin.this, "notify_failed_interactions", false); - public final Flag physics = flagRegistry().register(ProtectPlugin.this, "physics", true); - public final Flag redstone = flagRegistry().register(ProtectPlugin.this, "redstone", true); - public final Flag shoot = flagRegistry().register(ProtectPlugin.this, "shoot", true); - - public final ProtectionFlag armorStandManipulate = flagRegistry().register(ProtectPlugin.this, "armor_stand_manipulate", true, false); - public final ProtectionFlag blockAbsorb = flagRegistry().register(ProtectPlugin.this, "block_absorb", true, false); - public final ProtectionFlag blockBurning = flagRegistry().register(ProtectPlugin.this, "block_burning", true, false); - public final ProtectionFlag blockDrying = flagRegistry().register(ProtectPlugin.this, "block_drying", true, false); - public final ProtectionFlag blockFading = flagRegistry().register(ProtectPlugin.this, "block_fading", true, false); - public final ProtectionFlag blockFertilize = flagRegistry().register(ProtectPlugin.this, "block_fertilize", true, false); - public final ProtectionFlag blockForming = flagRegistry().register(ProtectPlugin.this, "block_forming", true, false); - public final ProtectionFlag blockGrowth = flagRegistry().register(ProtectPlugin.this, "block_growth", true, false); - public final ProtectionFlag blockIgniting = flagRegistry().register(ProtectPlugin.this, "block_igniting", true, false); - public final ProtectionFlag blockMoisturising = flagRegistry().register(ProtectPlugin.this, "block_moisturising", true, false); - public final ProtectionFlag blockSpread = flagRegistry().register(ProtectPlugin.this, "block_spread", true, false); - public final ProtectionFlag cauldronEvaporation = flagRegistry().register(ProtectPlugin.this, "cauldron_evaporation", true, false); - public final ProtectionFlag cauldronExtinguishEntity = flagRegistry().register(ProtectPlugin.this, "cauldron_extinguish_entity", true, false); - public final ProtectionFlag collisions = flagRegistry().register(ProtectPlugin.this, "collisions", true, false); - public final ProtectionFlag cropTrample = flagRegistry().register(ProtectPlugin.this, "crop_trample", true, false); - public final ProtectionFlag destroy = flagRegistry().register(ProtectPlugin.this, "destroy", true, false); - public final ProtectionFlag entityAttackEntity = flagRegistry().register(ProtectPlugin.this, "entity_attack_entity", true, false); - public final ProtectionFlag entityAttackPlayer = flagRegistry().register(ProtectPlugin.this, "entity_attack_player", true, false); - public final ProtectionFlag entityInteract = flagRegistry().register(ProtectPlugin.this, "entity_interact", true, false); - public final ProtectionFlag entityShear = flagRegistry().register(ProtectPlugin.this, "entity_shear", true, false); - public final ProtectionFlag explosions = flagRegistry().register(ProtectPlugin.this, "explosions", true, false); - public final ProtectionFlag interact = flagRegistry().register(ProtectPlugin.this, "interact", true, false); - public final ProtectionFlag leavesDecay = flagRegistry().register(ProtectPlugin.this, "leaves_decay", true, false); - public final ProtectionFlag naturalCauldronFill = flagRegistry().register(ProtectPlugin.this, "natural_cauldron_fill", true, false); - public final ProtectionFlag physicalInteract = flagRegistry().register(ProtectPlugin.this, "physical_interact", true, false); - public final ProtectionFlag place = flagRegistry().register(ProtectPlugin.this, "place", true, false); - public final ProtectionFlag playerAttackEntity = flagRegistry().register(ProtectPlugin.this, "player_attack_entity", true, false); - public final ProtectionFlag playerAttackPlayer = flagRegistry().register(ProtectPlugin.this, "player_attack_player", true, false); - public final ProtectionFlag playerItemDrop = flagRegistry().register(ProtectPlugin.this, "player_item_drop", true, false); + public final LongFlag time = register(new LongFlag(key("time"))); + public final StringFlag farewell = register(new StringFlag(key("farewell"))); + public final StringFlag farewellActionbar = register(new StringFlag(key("farewell_actionbar"))); + public final StringFlag farewellTitle = register(new StringFlag(key("farewell_title"))); + public final StringFlag greetings = register(new StringFlag(key("greetings"))); + public final StringFlag greetingsActionbar = register(new StringFlag(key("greetings_actionbar"))); + public final StringFlag greetingsTitle = register(new StringFlag(key("greetings_title"))); + public final EnumFlag<@Nullable WeatherType> weather = register(new EnumFlag<>(key("weather"), WeatherType.class)); + + public final BooleanFlag areaEnter = register(new BooleanFlag(key("enter"), true)); + public final BooleanFlag areaLeave = register(new BooleanFlag(key("leave"), true)); + public final BooleanFlag damage = register(new BooleanFlag(key("damage"), true)); + public final BooleanFlag entityItemDrop = register(new BooleanFlag(key("entity_item_drop"), true)); + public final BooleanFlag entityItemPickup = register(new BooleanFlag(key("entity_item_pickup"), true)); + public final BooleanFlag gameEvents = register(new BooleanFlag(key("game_events"), true)); + public final BooleanFlag gravity = register(new BooleanFlag(key("gravity"), true)); + public final BooleanFlag hunger = register(new BooleanFlag(key("hunger"), true)); + public final BooleanFlag liquidFlow = register(new BooleanFlag(key("liquid_flow"), true)); + public final BooleanFlag naturalEntitySpawn = register(new BooleanFlag(key("natural_entity_spawn"), true)); + public final BooleanFlag notifyFailedInteractions = register(new BooleanFlag(key("notify_failed_interactions"), false)); + public final BooleanFlag physics = register(new BooleanFlag(key("physics"), true)); + public final BooleanFlag redstone = register(new BooleanFlag(key("redstone"), true)); + public final BooleanFlag shoot = register(new BooleanFlag(key("shoot"), true)); + + public final BooleanFlag armorStandManipulate = register(new BooleanFlag(key("armor_stand_manipulate"), true, false)); + public final BooleanFlag blockAbsorb = register(new BooleanFlag(key("block_absorb"), true, false)); + public final BooleanFlag blockBurning = register(new BooleanFlag(key("block_burning"), true, false)); + public final BooleanFlag blockDrying = register(new BooleanFlag(key("block_drying"), true, false)); + public final BooleanFlag blockFading = register(new BooleanFlag(key("block_fading"), true, false)); + public final BooleanFlag blockFertilize = register(new BooleanFlag(key("block_fertilize"), true, false)); + public final BooleanFlag blockForming = register(new BooleanFlag(key("block_forming"), true, false)); + public final BooleanFlag blockGrowth = register(new BooleanFlag(key("block_growth"), true, false)); + public final BooleanFlag blockIgniting = register(new BooleanFlag(key("block_igniting"), true, false)); + public final BooleanFlag blockMoisturising = register(new BooleanFlag(key("block_moisturising"), true, false)); + public final BooleanFlag blockSpread = register(new BooleanFlag(key("block_spread"), true, false)); + public final BooleanFlag cauldronEvaporation = register(new BooleanFlag(key("cauldron_evaporation"), true, false)); + public final BooleanFlag cauldronExtinguishEntity = register(new BooleanFlag(key("cauldron_extinguish_entity"), true, false)); + public final BooleanFlag collisions = register(new BooleanFlag(key("collisions"), true, false)); + public final BooleanFlag cropTrample = register(new BooleanFlag(key("crop_trample"), true, false)); + public final BooleanFlag destroy = register(new BooleanFlag(key("destroy"), true, false)); + public final BooleanFlag entityAttackEntity = register(new BooleanFlag(key("entity_attack_entity"), true, false)); + public final BooleanFlag entityAttackPlayer = register(new BooleanFlag(key("entity_attack_player"), true, false)); + public final BooleanFlag entityInteract = register(new BooleanFlag(key("entity_interact"), true, false)); + public final BooleanFlag entityShear = register(new BooleanFlag(key("entity_shear"), true, false)); + public final BooleanFlag explosions = register(new BooleanFlag(key("explosions"), true, false)); + public final BooleanFlag interact = register(new BooleanFlag(key("interact"), true, false)); + public final BooleanFlag leavesDecay = register(new BooleanFlag(key("leaves_decay"), true, false)); + public final BooleanFlag naturalCauldronFill = register(new BooleanFlag(key("natural_cauldron_fill"), true, false)); + public final BooleanFlag physicalInteract = register(new BooleanFlag(key("physical_interact"), true, false)); + public final BooleanFlag place = register(new BooleanFlag(key("place"), true, false)); + public final BooleanFlag playerAttackEntity = register(new BooleanFlag(key("player_attack_entity"), true, false)); + public final BooleanFlag playerAttackPlayer = register(new BooleanFlag(key("player_attack_player"), true, false)); + public final BooleanFlag playerItemDrop = register(new BooleanFlag(key("player_item_drop"), true, false)); + + private > T register(T flag) { + flagRegistry.register(ProtectPlugin.this, flag); + return flag; + } + + private Key key(@KeyPattern.Value String name) { + return Key.key("protect", name); + } } } diff --git a/plugin/src/main/java/net/thenextlvl/protect/adapter/other/FlagsAdapter.java b/plugin/src/main/java/net/thenextlvl/protect/adapter/other/FlagsAdapter.java index bd4eb546..50e1ec65 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/adapter/other/FlagsAdapter.java +++ b/plugin/src/main/java/net/thenextlvl/protect/adapter/other/FlagsAdapter.java @@ -30,7 +30,7 @@ public FlagsAdapter(ProtectPlugin plugin) { compound.forEach((key, value) -> { var namespace = Key.key(key); var flag = plugin.flagRegistry().getFlag(namespace).orElse(null); - if (flag != null) flags.put(flag, context.deserialize(value, flag.type())); + if (flag != null) flags.put(flag, context.deserialize(value, flag.getValueType())); else plugin.getComponentLogger().error("Unknown flag: {}", key); }); return flags; @@ -41,7 +41,7 @@ public Tag serialize(Map, @Nullable Object> flags, TagSerializationConte var tag = CompoundTag.empty(); flags.forEach((flag, value) -> { if (value == null) return; - var serialized = context.serialize(value, flag.type()); + var serialized = context.serialize(value, flag.getValueType()); tag.add(flag.key().asString(), serialized); }); return tag; diff --git a/plugin/src/main/java/net/thenextlvl/protect/area/CraftArea.java b/plugin/src/main/java/net/thenextlvl/protect/area/CraftArea.java index 9986eee3..2d4eaa2b 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/area/CraftArea.java +++ b/plugin/src/main/java/net/thenextlvl/protect/area/CraftArea.java @@ -168,7 +168,7 @@ public T getFlag(@NonNull Flag flag) { var value = (T) getFlags().get(flag); if (value != null) return value; return getParent().map(area -> area.getFlag(flag)) - .orElseGet(flag::defaultValue); + .orElseGet(flag::getDefaultValue); } @Override diff --git a/plugin/src/main/java/net/thenextlvl/protect/command/AreaFlagCommand.java b/plugin/src/main/java/net/thenextlvl/protect/command/AreaFlagCommand.java index a9814edb..36b3c79c 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/command/AreaFlagCommand.java +++ b/plugin/src/main/java/net/thenextlvl/protect/command/AreaFlagCommand.java @@ -1,23 +1,11 @@ package net.thenextlvl.protect.command; import com.mojang.brigadier.Command; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.arguments.BoolArgumentType; -import com.mojang.brigadier.arguments.DoubleArgumentType; -import com.mojang.brigadier.arguments.FloatArgumentType; -import com.mojang.brigadier.arguments.IntegerArgumentType; -import com.mojang.brigadier.arguments.LongArgumentType; -import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.ArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import core.paper.command.argument.EnumArgumentType; -import core.paper.command.argument.codec.EnumStringCodec; import io.papermc.paper.command.brigadier.CommandSourceStack; import io.papermc.paper.command.brigadier.Commands; -import io.papermc.paper.command.brigadier.argument.ArgumentTypes; -import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver; import net.kyori.adventure.text.minimessage.tag.resolver.Formatter; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.thenextlvl.protect.ProtectPlugin; @@ -26,29 +14,9 @@ import net.thenextlvl.protect.command.argument.FlagArgumentType; import net.thenextlvl.protect.command.argument.FlagProviderArgumentType; import net.thenextlvl.protect.flag.Flag; -import org.bukkit.Location; -import org.bukkit.WeatherType; import org.bukkit.plugin.Plugin; -import java.util.Map; -import java.util.function.Supplier; - class AreaFlagCommand { - private static final Map, Converter> argumentTypes = Map.of( - Boolean.class, new Converter(BoolArgumentType::bool), - Double.class, new Converter(DoubleArgumentType::doubleArg), - Float.class, new Converter(FloatArgumentType::floatArg), - Integer.class, new Converter(IntegerArgumentType::integer), - Long.class, new Converter(LongArgumentType::longArg), - String.class, new Converter(StringArgumentType::string), - Location.class, new Converter(ArgumentTypes::finePosition, (type, context) -> { - var resolver = context.getArgument("value", FinePositionResolver.class); - var area = context.getArgument("area", Area.class); - return resolver.resolve(context.getSource()).toLocation(area.getWorld()); - }), - WeatherType.class, new Converter(() -> EnumArgumentType.of(WeatherType.class, EnumStringCodec.lowerHyphen())) - ); - public static LiteralArgumentBuilder create(ProtectPlugin plugin) { return Commands.literal("flag") .requires(stack -> stack.getSender().hasPermission("protect.command.area.flag")) @@ -89,23 +57,20 @@ public static LiteralArgumentBuilder create(ProtectPlugin pl }); } - private static ArgumentBuilder set( ProtectPlugin plugin) { + private static ArgumentBuilder set(ProtectPlugin plugin) { var command = Commands.literal("set") .requires(stack -> stack.getSender().hasPermission("protect.command.area.flag.set")); plugin.flagRegistry().getRegistry().values().forEach(flags -> flags.forEach(flag -> { - var converter = argumentTypes.get(flag.type()); - if (converter == null) { - plugin.getComponentLogger().error("No argument type for flag type: {}", flag.type().getName()); - } else command.then(Commands.literal(flag.key().asString()) - .then(Commands.argument("value", converter.type().get()) + command.then(Commands.literal(flag.key().asString()) + .then(Commands.argument("value", flag.getArgumentType()) .then(Commands.argument("area", new AreaArgumentType(plugin)) .executes(context -> { var area = context.getArgument("area", Area.class); - return set(context, converter.resolver(), flag, area, plugin); + return set(context, flag, area, plugin); })) .executes(context -> { var location = context.getSource().getLocation(); - return set(context, converter.resolver(), flag, plugin.areaProvider().getArea(location), plugin); + return set(context, flag, plugin.areaProvider().getArea(location), plugin); }))); })); return command; @@ -152,9 +117,8 @@ private static int list(CommandContext context, Plugin provi return Command.SINGLE_SUCCESS; } - @SuppressWarnings({"unchecked", "rawtypes"}) - private static int set(CommandContext context, Resolver resolver, Flag flag, Area area, ProtectPlugin plugin) throws CommandSyntaxException { - var value = resolver.resolve(flag.type(), context); + private static int set(CommandContext context, Flag flag, Area area, ProtectPlugin plugin) { + var value = context.getArgument("value", flag.getValueType()); var message = area.setFlag(flag, value) ? "area.flag.set" : "nothing.changed"; plugin.bundle().sendMessage(context.getSource().getSender(), message, Placeholder.parsed("area", area.getName()), @@ -171,18 +135,4 @@ private static int reset(CommandContext context, Area area, Placeholder.parsed("flag", flag.key().asString())); return Command.SINGLE_SUCCESS; } - - private record Converter( - Supplier> type, - Resolver resolver - ) { - public Converter(Supplier> supplier) { - this(supplier, (type, context) -> context.getArgument("value", type)); - } - } - - @FunctionalInterface - public interface Resolver { - T resolve(Class type, CommandContext context) throws CommandSyntaxException; - } } diff --git a/plugin/src/main/java/net/thenextlvl/protect/command/AreaProtectCommand.java b/plugin/src/main/java/net/thenextlvl/protect/command/AreaProtectCommand.java index 3ae8fab0..66660556 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/command/AreaProtectCommand.java +++ b/plugin/src/main/java/net/thenextlvl/protect/command/AreaProtectCommand.java @@ -10,7 +10,7 @@ import net.thenextlvl.protect.ProtectPlugin; import net.thenextlvl.protect.area.Area; import net.thenextlvl.protect.command.argument.AreaArgumentType; -import net.thenextlvl.protect.flag.ProtectionFlag; +import net.thenextlvl.protect.flag.Flag; class AreaProtectCommand { public static LiteralArgumentBuilder create(ProtectPlugin plugin) { @@ -25,7 +25,7 @@ public static LiteralArgumentBuilder create(ProtectPlugin pl private static int unprotect(CommandContext context, ProtectPlugin plugin) { var area = context.getArgument("area", Area.class); var changes = plugin.flagRegistry().getFlags().stream() - .filter(flag -> flag instanceof ProtectionFlag) + .filter(flag -> flag.getProtectedValue() != null) .filter(area::removeFlag) .count(); var message = changes > 0 ? "area.unprotected" : "nothing.changed"; @@ -39,9 +39,8 @@ private static int unprotect(CommandContext context, Protect private static int protect(CommandContext context, ProtectPlugin plugin) { var area = context.getArgument("area", Area.class); var changes = plugin.flagRegistry().getFlags().stream() - .filter(flag -> flag instanceof ProtectionFlag) - .map(flag -> (ProtectionFlag) flag) - .filter(flag -> area.setFlag(flag, flag.protectedValue())) + .map(flag -> (Flag) flag) + .filter(flag -> area.setFlag(flag, flag.getProtectedValue())) .count(); var message = changes > 0 ? "area.protected" : "nothing.changed"; plugin.bundle().sendMessage(context.getSource().getSender(), message, diff --git a/plugin/src/main/java/net/thenextlvl/protect/flag/CraftFlag.java b/plugin/src/main/java/net/thenextlvl/protect/flag/CraftFlag.java deleted file mode 100644 index 2d689789..00000000 --- a/plugin/src/main/java/net/thenextlvl/protect/flag/CraftFlag.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.thenextlvl.protect.flag; - -import net.kyori.adventure.key.Key; -import org.jspecify.annotations.NonNull; - -import java.util.Objects; - -public record CraftFlag( - @NonNull Key key, - @NonNull Class type, - T defaultValue -) implements Flag { - - @Override - public int compareTo(@NonNull Flag flag) { - return key().compareTo(flag.key()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CraftFlag craftFlag)) return false; - return Objects.equals(key, craftFlag.key); - } - - @Override - public int hashCode() { - return Objects.hashCode(key); - } -} diff --git a/plugin/src/main/java/net/thenextlvl/protect/flag/CraftFlagRegistry.java b/plugin/src/main/java/net/thenextlvl/protect/flag/CraftFlagRegistry.java index 4100f76c..c9060be5 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/flag/CraftFlagRegistry.java +++ b/plugin/src/main/java/net/thenextlvl/protect/flag/CraftFlagRegistry.java @@ -3,12 +3,15 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.key.KeyPattern; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.Unmodifiable; import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.NullMarked; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.function.Function; -import java.util.stream.Collectors; public class CraftFlagRegistry implements FlagRegistry { private final Map>> registry = new HashMap<>(); @@ -17,46 +20,32 @@ public Map>> getRegistry() { return registry; } - @Override - @NullMarked - public Set> getFlags() { - return registry.values().stream() - .flatMap(Collection::stream) - .collect(Collectors.toSet()); + @SuppressWarnings("PatternValidation") + private > T register(@NonNull Plugin plugin, @KeyPattern.Value @NonNull String name, @NonNull Function function) { + var key = Key.key(plugin.getName().replace("-", "_").toLowerCase(), name); + var flag = function.apply(key); + if (registry.computeIfAbsent(plugin, p -> new HashSet<>()).add(flag)) return flag; + throw new IllegalStateException("Already registered flag: " + key); } @Override - @NullMarked - public Set> getFlags(Plugin plugin) { - return registry.get(plugin); + public @NonNull @Unmodifiable Set<@NonNull Flag> getFlags() { + return Set.of(); } @Override - @NullMarked - @SuppressWarnings("unchecked") - public Optional> getFlag(Key key) { - return getFlags().stream() - .filter(flag -> flag.key().equals(key)) - .map(flag -> (Flag) flag) - .findAny(); + public @NonNull @Unmodifiable Set<@NonNull Flag> getFlags(Plugin plugin) { + return Set.of(); } @Override - public @NonNull Flag register(@NonNull Plugin plugin, @NonNull Class type, @KeyPattern.Value @NonNull String name, T defaultValue) throws IllegalStateException { - return register(plugin, name, key -> new CraftFlag<>(key, type, defaultValue)); + public @NonNull > Optional<@NonNull T> getFlag(Key key) { + return Optional.empty(); } @Override - public @NonNull ProtectionFlag register(@NonNull Plugin plugin, @NonNull Class type, @KeyPattern.Value @NonNull String name, T defaultValue, T protectedValue) throws IllegalStateException { - return register(plugin, name, key -> new CraftProtectionFlag<>(key, type, defaultValue, protectedValue)); - } - - @SuppressWarnings("PatternValidation") - private > T register(@NonNull Plugin plugin, @KeyPattern.Value @NonNull String name, @NonNull Function function) { - var key = Key.key(plugin.getName().replace("-", "_").toLowerCase(), name); - var flag = function.apply(key); - if (registry.computeIfAbsent(plugin, p -> new HashSet<>()).add(flag)) return flag; - throw new IllegalStateException("Already registered flag: " + key); + public boolean register(@NonNull Plugin plugin, @NonNull Flag flag) { + return false; } @Override diff --git a/plugin/src/main/java/net/thenextlvl/protect/flag/CraftProtectionFlag.java b/plugin/src/main/java/net/thenextlvl/protect/flag/CraftProtectionFlag.java deleted file mode 100644 index 943cc142..00000000 --- a/plugin/src/main/java/net/thenextlvl/protect/flag/CraftProtectionFlag.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.thenextlvl.protect.flag; - -import net.kyori.adventure.key.Key; -import org.jspecify.annotations.NonNull; - -import java.util.Objects; - -public record CraftProtectionFlag( - @NonNull Key key, - @NonNull Class type, - T defaultValue, T protectedValue -) implements ProtectionFlag { - - @Override - public int compareTo(@NonNull Flag flag) { - return key().compareTo(flag.key()); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof CraftProtectionFlag craftFlag)) return false; - return Objects.equals(key, craftFlag.key); - } - - @Override - public int hashCode() { - return Objects.hashCode(key); - } -} diff --git a/plugin/src/main/java/net/thenextlvl/protect/listener/EntityListener.java b/plugin/src/main/java/net/thenextlvl/protect/listener/EntityListener.java index cf4029e6..c0facdb5 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/listener/EntityListener.java +++ b/plugin/src/main/java/net/thenextlvl/protect/listener/EntityListener.java @@ -161,6 +161,7 @@ public void onEntityChangeBlock(EntityChangeBlockEvent event) { private boolean isInteractionRestricted(Entity source, Entity target, Flag flag) { var first = plugin.areaProvider().getArea(source); + var flag1 = first.getFlag(flag); if (first.getFlag(flag) && first.isPermitted(source.getUniqueId())) return false; var second = plugin.areaProvider().getArea(target); if (second.getFlag(flag) && second.isPermitted(source.getUniqueId())) return false; diff --git a/plugin/src/main/java/net/thenextlvl/protect/listener/NexoListener.java b/plugin/src/main/java/net/thenextlvl/protect/listener/NexoListener.java index 8fc66198..673d6d10 100644 --- a/plugin/src/main/java/net/thenextlvl/protect/listener/NexoListener.java +++ b/plugin/src/main/java/net/thenextlvl/protect/listener/NexoListener.java @@ -3,23 +3,25 @@ import com.nexomc.nexo.api.events.furniture.NexoFurnitureBreakEvent; import com.nexomc.nexo.api.events.furniture.NexoFurnitureInteractEvent; import com.nexomc.nexo.api.events.furniture.NexoFurniturePlaceEvent; +import net.kyori.adventure.key.Key; import net.thenextlvl.protect.ProtectPlugin; -import net.thenextlvl.protect.flag.ProtectionFlag; +import net.thenextlvl.protect.flag.standard.BooleanFlag; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; public class NexoListener implements Listener { + private final BooleanFlag furnitureBreak = new BooleanFlag(Key.key("nexo", "furniture_break"), true, false); + private final BooleanFlag furniturePlace = new BooleanFlag(Key.key("furniture_place"), true, false); + private final BooleanFlag furnitureInteract = new BooleanFlag(Key.key("furniture_interact"), true, false); + private final ProtectPlugin plugin; - private final ProtectionFlag furnitureBreak; - private final ProtectionFlag furniturePlace; - private final ProtectionFlag furnitureInteract; public NexoListener(ProtectPlugin plugin, Plugin nexo) { - this.furnitureBreak = plugin.flagRegistry().register(nexo, "furniture_break", true, false); - this.furniturePlace = plugin.flagRegistry().register(nexo, "furniture_place", true, false); - this.furnitureInteract = plugin.flagRegistry().register(nexo, "furniture_interact", true, false); + plugin.flagRegistry().register(nexo, this.furnitureBreak); + plugin.flagRegistry().register(nexo, this.furniturePlace); + plugin.flagRegistry().register(nexo, this.furnitureInteract); this.plugin = plugin; }