From c2414fd23e8f72a344c1357d949a6d41cbcf4deb Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 2 Aug 2018 16:13:10 +0200 Subject: [PATCH] Update flag API --- .../worldguardwrapper/flags/BooleanFlag.java | 44 ++++++++ .../worldguardwrapper/flags/DoubleFlag.java | 38 +++++++ .../worldguardwrapper/flags/EnumFlag.java | 49 +++++++++ .../worldguardwrapper/flags/IntegerFlag.java | 38 +++++++ .../worldguardwrapper/flags/LocationFlag.java | 101 ++++++++++++++++++ .../worldguardwrapper/flags/SetFlag.java | 81 ++++++++++++++ .../worldguardwrapper/flags/StringFlag.java | 34 ++++++ .../implementation/AbstractFlag.java | 70 ++++++++++++ .../IWorldGuardImplementation.java | 19 ++-- .../v6/WorldGuardImplementation.java | 76 ++++++++----- .../v7/WorldGuardImplementation.java | 81 +++++++++----- 11 files changed, 568 insertions(+), 63 deletions(-) create mode 100644 api/src/main/java/org/codemc/worldguardwrapper/flags/BooleanFlag.java create mode 100644 api/src/main/java/org/codemc/worldguardwrapper/flags/DoubleFlag.java create mode 100644 api/src/main/java/org/codemc/worldguardwrapper/flags/EnumFlag.java create mode 100644 api/src/main/java/org/codemc/worldguardwrapper/flags/IntegerFlag.java create mode 100644 api/src/main/java/org/codemc/worldguardwrapper/flags/LocationFlag.java create mode 100644 api/src/main/java/org/codemc/worldguardwrapper/flags/SetFlag.java create mode 100644 api/src/main/java/org/codemc/worldguardwrapper/flags/StringFlag.java create mode 100644 implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/AbstractFlag.java diff --git a/api/src/main/java/org/codemc/worldguardwrapper/flags/BooleanFlag.java b/api/src/main/java/org/codemc/worldguardwrapper/flags/BooleanFlag.java new file mode 100644 index 0000000..d83cfd2 --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/flags/BooleanFlag.java @@ -0,0 +1,44 @@ +package org.codemc.worldguardwrapper.flags; + +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; + +/** + * A flag that stores a boolean. + */ +public class BooleanFlag extends AbstractFlag { + + public BooleanFlag(String name) { + this(name, false); + } + + public BooleanFlag(String name, boolean defaultValue) { + super(name, boolean.class, defaultValue); + } + + @Override + public Object serialize(Boolean value) { + return value; + } + + @Override + public Boolean deserialize(Object serialized) { + return (Boolean) serialized; + } + + @Override + public Boolean parse(Player player, String userInput) { + if (userInput.equalsIgnoreCase("true") || userInput.equalsIgnoreCase("yes") + || userInput.equalsIgnoreCase("on") + || userInput.equalsIgnoreCase("1")) { + return true; + } else if (userInput.equalsIgnoreCase("false") || userInput.equalsIgnoreCase("no") + || userInput.equalsIgnoreCase("off") + || userInput.equalsIgnoreCase("0")) { + return false; + } else { + return null; + } + } + +} \ No newline at end of file diff --git a/api/src/main/java/org/codemc/worldguardwrapper/flags/DoubleFlag.java b/api/src/main/java/org/codemc/worldguardwrapper/flags/DoubleFlag.java new file mode 100644 index 0000000..dcaa0e2 --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/flags/DoubleFlag.java @@ -0,0 +1,38 @@ +package org.codemc.worldguardwrapper.flags; + +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; + +/** + * A flag that stores a double. + */ +public class DoubleFlag extends AbstractFlag { + + public DoubleFlag(String name) { + this(name, 0d); + } + + public DoubleFlag(String name, double defaultValue) { + super(name, double.class, defaultValue); + } + + @Override + public Object serialize(Double value) { + return value; + } + + @Override + public Double deserialize(Object serialized) { + if (serialized instanceof Number) { + return ((Number) serialized).doubleValue(); + } else { + return null; + } + } + + @Override + public Double parse(Player player, String userInput) { + return Double.parseDouble(userInput); + } + +} \ No newline at end of file diff --git a/api/src/main/java/org/codemc/worldguardwrapper/flags/EnumFlag.java b/api/src/main/java/org/codemc/worldguardwrapper/flags/EnumFlag.java new file mode 100644 index 0000000..275f560 --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/flags/EnumFlag.java @@ -0,0 +1,49 @@ +package org.codemc.worldguardwrapper.flags; + +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; + +/** + * A flag that stores an enum value. + */ +public class EnumFlag> extends AbstractFlag { + + private Class enumClass; + + public EnumFlag(String name, Class enumClass) { + this(name, enumClass, null); + } + + public EnumFlag(String name, Class enumClass, T defaultValue) { + super(name, enumClass, defaultValue); + } + + /** + * Get the enum class. + * + * @return The enum class + */ + public Class getEnumClass() { + return enumClass; + } + + @Override + public Object serialize(T value) { + return value.name(); + } + + @Override + public T deserialize(Object serialized) { + if (serialized instanceof String) { + return Enum.valueOf(enumClass, (String) serialized); + } else { + return null; + } + } + + @Override + public T parse(Player player, String userInput) { + return Enum.valueOf(enumClass, userInput); + } + +} \ No newline at end of file diff --git a/api/src/main/java/org/codemc/worldguardwrapper/flags/IntegerFlag.java b/api/src/main/java/org/codemc/worldguardwrapper/flags/IntegerFlag.java new file mode 100644 index 0000000..6cb92a2 --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/flags/IntegerFlag.java @@ -0,0 +1,38 @@ +package org.codemc.worldguardwrapper.flags; + +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; + +/** + * A flag that stores an integer. + */ +public class IntegerFlag extends AbstractFlag { + + public IntegerFlag(String name) { + this(name, 0); + } + + public IntegerFlag(String name, int defaultValue) { + super(name, int.class, defaultValue); + } + + @Override + public Object serialize(Integer value) { + return value; + } + + @Override + public Integer deserialize(Object serialized) { + if (serialized instanceof Number) { + return ((Number) serialized).intValue(); + } else { + return null; + } + } + + @Override + public Integer parse(Player player, String userInput) { + return Integer.parseInt(userInput); + } + +} \ No newline at end of file diff --git a/api/src/main/java/org/codemc/worldguardwrapper/flags/LocationFlag.java b/api/src/main/java/org/codemc/worldguardwrapper/flags/LocationFlag.java new file mode 100644 index 0000000..7079405 --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/flags/LocationFlag.java @@ -0,0 +1,101 @@ +package org.codemc.worldguardwrapper.flags; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; + +/** + * A flag that stores a bukkit location. + */ +public class LocationFlag extends AbstractFlag { + + public LocationFlag(String name) { + this(name, null); + } + + public LocationFlag(String name, Location defaultValue) { + super(name, Location.class, defaultValue); + } + + @Override + public Object serialize(Location value) { + Map map = new HashMap<>(); + + map.put("world", value.getWorld().getName()); + map.put("x", value.getX()); + map.put("y", value.getY()); + map.put("z", value.getZ()); + map.put("yaw", value.getYaw()); + map.put("pitch", value.getPitch()); + + return map; + } + + @Override + public Location deserialize(Object serialized) { + if (serialized instanceof Map) { + Map map = (Map) serialized; + + Object worldName = map.get("world"); + if (worldName == null) return null; + + Object x = map.get("x"); + if (x == null) return null; + + Object y = map.get("y"); + if (y == null) return null; + + Object z = map.get("z"); + if (z == null) return null; + + Object yaw = map.get("yaw"); + if (yaw == null) return null; + + Object pitch = map.get("pitch"); + if (pitch == null) return null; + + World world = Bukkit.getWorld(String.valueOf(worldName)); + if (world == null) return null; + + return new Location(world, toNumber(x), toNumber(y), toNumber(z), + (float) toNumber(yaw), (float) toNumber(pitch)); + } + return null; + } + + @Override + public Location parse(Player player, String userInput) { + if ("here".equalsIgnoreCase(userInput)) { + return player.getLocation(); + } else if ("none".equalsIgnoreCase(userInput)) { + return null; + } else { + String[] split = userInput.split(","); + if (split.length >= 3) { + final World world = player.getWorld(); + final double x = Double.parseDouble(split[0]); + final double y = Double.parseDouble(split[1]); + final double z = Double.parseDouble(split[2]); + final float yaw = split.length < 4 ? 0 : Float.parseFloat(split[3]); + final float pitch = split.length < 5 ? 0 : Float.parseFloat(split[4]); + + return new Location(world, x, y, z, yaw, pitch); + } + } + return null; + } + + private double toNumber(Object o) { + if (o instanceof Number) { + return ((Number) o).doubleValue(); + } else { + return 0; + } + } + +} \ No newline at end of file diff --git a/api/src/main/java/org/codemc/worldguardwrapper/flags/SetFlag.java b/api/src/main/java/org/codemc/worldguardwrapper/flags/SetFlag.java new file mode 100644 index 0000000..e697185 --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/flags/SetFlag.java @@ -0,0 +1,81 @@ +package org.codemc.worldguardwrapper.flags; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; + +/** + * A flag that stores a set of values of the sub flag's type. + */ +public class SetFlag extends AbstractFlag> { + + private AbstractFlag subFlag; + + public SetFlag(String name, AbstractFlag subFlag) { + this(name, new HashSet<>(), subFlag); + } + + @SuppressWarnings("unchecked") + public SetFlag(String name, Set defaultValue, AbstractFlag subFlag) { + super(name, (Class>) defaultValue.getClass(), defaultValue); + } + + /** + * Get the type of values stored in this flag. + * + * @return The stored flag type. + */ + public AbstractFlag getSubType() { + return subFlag; + } + + @Override + public Set deserialize(Object o) { + if (o instanceof Collection) { + Collection collection = (Collection) o; + Set items = new HashSet(); + + for (Object sub : collection) { + T item = subFlag.deserialize(sub); + if (item != null) { + items.add(item); + } + } + + return items; + } else { + return null; + } + } + + @Override + public Object serialize(Set o) { + List list = new ArrayList(); + for (T item : o) { + list.add(subFlag.serialize(item)); + } + + return list; + } + + @Override + public Set parse(Player player, String userInput) { + if (userInput.isEmpty()) { + return new HashSet<>(); + } else { + Set items = new HashSet<>(); + + for (String str : userInput.split(",")) { + items.add(subFlag.parse(player, str)); + } + + return items; + } + } + +} \ No newline at end of file diff --git a/api/src/main/java/org/codemc/worldguardwrapper/flags/StringFlag.java b/api/src/main/java/org/codemc/worldguardwrapper/flags/StringFlag.java new file mode 100644 index 0000000..c324a1b --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/flags/StringFlag.java @@ -0,0 +1,34 @@ +package org.codemc.worldguardwrapper.flags; + +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; + +/** + * A flag that stores a string. + */ +public class StringFlag extends AbstractFlag { + + public StringFlag(String name) { + this(name, ""); + } + + public StringFlag(String name, String defaultValue) { + super(name, String.class, defaultValue); + } + + @Override + public Object serialize(String value) { + return value; + } + + @Override + public String deserialize(Object serialized) { + return (String) serialized; + } + + @Override + public String parse(Player player, String userInput) { + return userInput; + } + +} \ No newline at end of file diff --git a/implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/AbstractFlag.java b/implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/AbstractFlag.java new file mode 100644 index 0000000..4a60c73 --- /dev/null +++ b/implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/AbstractFlag.java @@ -0,0 +1,70 @@ +package org.codemc.worldguardwrapper.implementation; + +import org.bukkit.entity.Player; + +import lombok.AllArgsConstructor; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@AllArgsConstructor +public abstract class AbstractFlag { + private @NonNull String name; + private @NonNull Class type; + private T defaultValue; + + /** + * Get the name of this flag. + * + * @return The name + */ + public String getName() { + return name; + } + + /** + * Get the type of this flag's value. + * + * @return The type + */ + public Class getType() { + return type; + } + + /** + * Get the default value of this flag. + * + * @return The default value (may be {@code null}) + */ + public T getDefaultValue() { + return defaultValue; + } + + /** + * Convert the value stored in this flag into a type that can be + * serialized into YAML. + * + * @param value The value + * @return The serialized type + */ + public abstract Object serialize(T value); + + /** + * Convert a raw object that was loaded (from a YAML file, for example) into the + * type that this flag uses. + * + * @param serialized The raw object + * @return The deserialized type + */ + public abstract T deserialize(Object serialized); + + /** + * Parse a given input to force it to a type compatible with the flag. + * + * @param player Player who entered the string. + * @param userInput Input string (e.g. a player input) + * @return A type compatible with the flag + */ + public abstract T parse(Player player, String userInput); + +} \ No newline at end of file diff --git a/implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java b/implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java index 70565e6..01dc719 100644 --- a/implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java +++ b/implementation/interface/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java @@ -1,27 +1,24 @@ package org.codemc.worldguardwrapper.implementation; -import lombok.NonNull; +import java.util.Optional; + import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; -import java.util.Optional; +import lombok.NonNull; public interface IWorldGuardImplementation { JavaPlugin getWorldGuardPlugin(); int getApiVersion(); - - // String flag - - Optional queryStringFlag(Player player, @NonNull Location location, @NonNull String flagId); - - boolean registerStringFlag(@NonNull String flagId, @NonNull String defaultValue); - - // State flag - + Optional queryStateFlag(Player player, @NonNull Location location, @NonNull String flagId); boolean registerStateFlag(@NonNull String flagId, @NonNull Boolean defaultValue); + + Optional queryFlag(Player player, @NonNull Location location, @NonNull AbstractFlag flag); + + boolean registerFlag(@NonNull AbstractFlag flag); } diff --git a/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/WorldGuardImplementation.java b/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/WorldGuardImplementation.java index bd57b0a..df22a38 100644 --- a/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/WorldGuardImplementation.java +++ b/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/WorldGuardImplementation.java @@ -1,22 +1,26 @@ package org.codemc.worldguardwrapper.implementation.v6; +import java.util.Optional; + import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.protection.ApplicableRegionSet; import com.sk89q.worldguard.protection.flags.Flag; +import com.sk89q.worldguard.protection.flags.FlagContext; +import com.sk89q.worldguard.protection.flags.InvalidFlagFormat; import com.sk89q.worldguard.protection.flags.StateFlag; -import com.sk89q.worldguard.protection.flags.StringFlag; import com.sk89q.worldguard.protection.flags.registry.FlagConflictException; import com.sk89q.worldguard.protection.flags.registry.FlagRegistry; import com.sk89q.worldguard.protection.managers.RegionManager; -import lombok.NonNull; + import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; import org.codemc.worldguardwrapper.implementation.AbstractWorldGuardImplementation; -import java.util.Optional; +import lombok.NonNull; public class WorldGuardImplementation extends AbstractWorldGuardImplementation { @@ -58,29 +62,6 @@ public class WorldGuardImplementation extends AbstractWorldGuardImplementation { return 6; } - // String flag - - @Override - public Optional queryStringFlag(Player player, @NonNull Location location, @NonNull String flagId) { - Flag flag = flagRegistry.get(flagId); - if (!(flag instanceof StringFlag)) { - return Optional.empty(); - } - return queryValue(player, location, (StringFlag) flag); - } - - @Override - public boolean registerStringFlag(@NonNull String flagId, @NonNull String defaultValue) { - try { - flagRegistry.register(new StringFlag(flagId, defaultValue)); - return true; - } catch (FlagConflictException ignored) { - } - return false; - } - - // State flag - @Override public Optional queryStateFlag(Player player, @NonNull Location location, @NonNull String flagId) { Flag flag = flagRegistry.get(flagId); @@ -99,4 +80,47 @@ public class WorldGuardImplementation extends AbstractWorldGuardImplementation { } return false; } + + @Override + @SuppressWarnings("unchecked") + public Optional queryFlag(Player player, Location location, AbstractFlag flag) { + Flag wgFlag = flagRegistry.get(flag.getName()); + Object value = queryValue(player, location, wgFlag).orElse(null); + if (flag.getType().isInstance(value)) { + return Optional.of((T) value); + } + return Optional.empty(); + } + + @Override + public boolean registerFlag(AbstractFlag flag) { + Flag wgFlag = new Flag(flag.getName()) { + @Override + public T getDefault() { + return flag.getDefaultValue(); + } + + @Override + public Object marshal(T o) { + return flag.serialize(o); + } + + @Override + public T unmarshal(Object o) { + return flag.deserialize(o); + } + + @Override + public T parseInput(FlagContext context) throws InvalidFlagFormat { + return flag.parse(context.getPlayerSender(), context.getUserInput()); + } + }; + + try { + flagRegistry.register(wgFlag); + return true; + } catch (FlagConflictException ignored) { + } + return false; + } } diff --git a/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/WorldGuardImplementation.java b/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/WorldGuardImplementation.java index 5fe5710..3f794fa 100644 --- a/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/WorldGuardImplementation.java +++ b/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/WorldGuardImplementation.java @@ -1,5 +1,7 @@ package org.codemc.worldguardwrapper.implementation.v7; +import java.util.Optional; + import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.WorldGuard; @@ -7,20 +9,23 @@ import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.internal.platform.WorldGuardPlatform; import com.sk89q.worldguard.protection.ApplicableRegionSet; import com.sk89q.worldguard.protection.flags.Flag; +import com.sk89q.worldguard.protection.flags.FlagContext; +import com.sk89q.worldguard.protection.flags.InvalidFlagFormat; import com.sk89q.worldguard.protection.flags.StateFlag; -import com.sk89q.worldguard.protection.flags.StringFlag; import com.sk89q.worldguard.protection.flags.registry.FlagConflictException; import com.sk89q.worldguard.protection.flags.registry.FlagRegistry; import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.RegionContainer; -import lombok.NonNull; + +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; +import org.codemc.worldguardwrapper.implementation.AbstractFlag; import org.codemc.worldguardwrapper.implementation.AbstractWorldGuardImplementation; -import java.util.Optional; +import lombok.NonNull; public class WorldGuardImplementation extends AbstractWorldGuardImplementation { @@ -40,6 +45,10 @@ public class WorldGuardImplementation extends AbstractWorldGuardImplementation { return Optional.ofNullable(player).map(bukkitPlayer -> plugin.wrapPlayer(player)); } + private Optional getPlayer(LocalPlayer player) { + return Optional.ofNullable(Bukkit.getPlayer(player.getUniqueId())); + } + private Optional getWorldManager(@NonNull World world) { return Optional.ofNullable(container.get(BukkitAdapter.adapt(world))); } @@ -66,29 +75,6 @@ public class WorldGuardImplementation extends AbstractWorldGuardImplementation { return 7; } - // String flag - - @Override - public Optional queryStringFlag(Player player, @NonNull Location location, @NonNull String flagId) { - Flag flag = flagRegistry.get(flagId); - if (!(flag instanceof StringFlag)) { - return Optional.empty(); - } - return queryValue(player, location, (StringFlag) flag); - } - - @Override - public boolean registerStringFlag(@NonNull String flagId, @NonNull String defaultValue) { - try { - flagRegistry.register(new StringFlag(flagId, defaultValue)); - return true; - } catch (FlagConflictException ignored) { - } - return false; - } - - // State flag - @Override public Optional queryStateFlag(Player player, @NonNull Location location, @NonNull String flagId) { Flag flag = flagRegistry.get(flagId); @@ -107,4 +93,47 @@ public class WorldGuardImplementation extends AbstractWorldGuardImplementation { } return false; } + + @Override + @SuppressWarnings("unchecked") + public Optional queryFlag(Player player, Location location, AbstractFlag flag) { + Flag wgFlag = flagRegistry.get(flag.getName()); + Object value = queryValue(player, location, wgFlag).orElse(null); + if (flag.getType().isInstance(value)) { + return Optional.of((T) value); + } + return Optional.empty(); + } + + @Override + public boolean registerFlag(AbstractFlag flag) { + Flag wgFlag = new Flag(flag.getName()) { + @Override + public T getDefault() { + return flag.getDefaultValue(); + } + + @Override + public Object marshal(T o) { + return flag.serialize(o); + } + + @Override + public T unmarshal(Object o) { + return flag.deserialize(o); + } + + @Override + public T parseInput(FlagContext context) throws InvalidFlagFormat { + return flag.parse(getPlayer(context.getPlayerSender()).get(), context.getUserInput()); + } + }; + + try { + flagRegistry.register(wgFlag); + return true; + } catch (FlagConflictException ignored) { + } + return false; + } }