diff --git a/api/pom.xml b/api/pom.xml index 64f2467..85c256e 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -7,7 +7,7 @@ org.codemc.worldguardwrapper worldguardwrapper-parent - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT worldguardwrapper-api diff --git a/api/src/main/java/org/codemc/worldguardwrapper/handler/IHandler.java b/api/src/main/java/org/codemc/worldguardwrapper/handler/IHandler.java new file mode 100644 index 0000000..7ea22ae --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/handler/IHandler.java @@ -0,0 +1,32 @@ +package org.codemc.worldguardwrapper.handler; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.codemc.worldguardwrapper.flag.WrappedState; +import org.codemc.worldguardwrapper.region.IWrappedRegion; +import org.codemc.worldguardwrapper.region.IWrappedRegionSet; + +import java.util.Set; + +public interface IHandler { + + default void initialize(Player player, Location current, IWrappedRegionSet regionSet) { + } + + default boolean testMoveTo(Player player, Location from, Location to, IWrappedRegionSet regionSet, String moveType) { + return true; + } + + default boolean onCrossBoundary(Player player, Location from, Location to, IWrappedRegionSet toSet, + Set entered, Set exited, String moveType) { + return true; + } + + default void tick(Player player, IWrappedRegionSet regionSet) { + } + + default WrappedState getInvincibility(Player player) { + return null; + } + +} diff --git a/api/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java b/api/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java index 3d5cb58..6a96f97 100644 --- a/api/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java +++ b/api/src/main/java/org/codemc/worldguardwrapper/implementation/IWorldGuardImplementation.java @@ -6,12 +6,15 @@ import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.codemc.worldguardwrapper.flag.IWrappedFlag; +import org.codemc.worldguardwrapper.handler.IHandler; import org.codemc.worldguardwrapper.region.IWrappedRegion; +import org.codemc.worldguardwrapper.region.IWrappedRegionSet; import org.codemc.worldguardwrapper.selection.ICuboidSelection; import org.codemc.worldguardwrapper.selection.IPolygonalSelection; import org.codemc.worldguardwrapper.selection.ISelection; import java.util.*; +import java.util.function.Supplier; public interface IWorldGuardImplementation { @@ -29,6 +32,8 @@ public interface IWorldGuardImplementation { */ int getApiVersion(); + void registerHandler(Supplier factory); + /** * Query a flag's value for a given player at a given location. * @@ -117,6 +122,14 @@ public interface IWorldGuardImplementation { */ Set getRegions(@NonNull Location minimum, @NonNull Location maximum); + /** + * Get the applicable region set at the given location- + * + * @param location The location + * @return The region set + */ + Optional getRegionSet(@NonNull Location location); + /** * Add a region. If only two points are given, a cuboid region will be created. * @@ -142,7 +155,7 @@ public interface IWorldGuardImplementation { /** * Add a region for the given selection. - * + * * @param id The region ID * @param selection The selection for the region's volume * @return The added region diff --git a/api/src/main/java/org/codemc/worldguardwrapper/region/IWrappedRegionSet.java b/api/src/main/java/org/codemc/worldguardwrapper/region/IWrappedRegionSet.java new file mode 100644 index 0000000..2967a1c --- /dev/null +++ b/api/src/main/java/org/codemc/worldguardwrapper/region/IWrappedRegionSet.java @@ -0,0 +1,26 @@ +package org.codemc.worldguardwrapper.region; + +import org.bukkit.OfflinePlayer; +import org.codemc.worldguardwrapper.flag.IWrappedFlag; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; + +public interface IWrappedRegionSet extends Iterable { + + boolean isVirtual(); + + Optional queryValue(OfflinePlayer subject, IWrappedFlag flag); + + Collection queryAllValues(OfflinePlayer subject, IWrappedFlag flag); + + boolean isOwnerOfAll(OfflinePlayer player); + + boolean isMemberOfAll(OfflinePlayer player); + + int size(); + + Set getRegions(); + +} diff --git a/implementation/legacy/pom.xml b/implementation/legacy/pom.xml index 7936abb..e9b66a4 100644 --- a/implementation/legacy/pom.xml +++ b/implementation/legacy/pom.xml @@ -7,7 +7,7 @@ org.codemc.worldguardwrapper worldguardwrapper-implementation - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT worldguardwrapper-implementation-legacy @@ -28,7 +28,7 @@ ${project.groupId} worldguardwrapper-api - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT provided diff --git a/implementation/legacy/src/main/java/org/codemc/worldguardwrapper/implementation/legacy/WorldGuardImplementation.java b/implementation/legacy/src/main/java/org/codemc/worldguardwrapper/implementation/legacy/WorldGuardImplementation.java index a00f048..acd42f1 100644 --- a/implementation/legacy/src/main/java/org/codemc/worldguardwrapper/implementation/legacy/WorldGuardImplementation.java +++ b/implementation/legacy/src/main/java/org/codemc/worldguardwrapper/implementation/legacy/WorldGuardImplementation.java @@ -1,5 +1,6 @@ package org.codemc.worldguardwrapper.implementation.legacy; +import com.google.common.collect.Iterators; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -16,21 +17,25 @@ import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import lombok.NonNull; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.codemc.worldguardwrapper.flag.IWrappedFlag; +import org.codemc.worldguardwrapper.handler.IHandler; import org.codemc.worldguardwrapper.implementation.IWorldGuardImplementation; import org.codemc.worldguardwrapper.implementation.legacy.flag.AbstractWrappedFlag; import org.codemc.worldguardwrapper.implementation.legacy.region.WrappedRegion; import org.codemc.worldguardwrapper.implementation.legacy.utility.WorldGuardFlagUtilities; import org.codemc.worldguardwrapper.implementation.legacy.utility.WorldGuardVectorUtilities; import org.codemc.worldguardwrapper.region.IWrappedRegion; +import org.codemc.worldguardwrapper.region.IWrappedRegionSet; import org.codemc.worldguardwrapper.selection.ICuboidSelection; import org.codemc.worldguardwrapper.selection.IPolygonalSelection; import org.codemc.worldguardwrapper.selection.ISelection; import java.util.*; +import java.util.function.Supplier; import java.util.stream.Collectors; public class WorldGuardImplementation implements IWorldGuardImplementation { @@ -47,8 +52,9 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { } } - private Optional wrapPlayer(Player player) { - return Optional.ofNullable(player).map(bukkitPlayer -> worldGuardPlugin.wrapPlayer(player)); + private Optional wrapPlayer(OfflinePlayer player) { + return Optional.ofNullable(player).map(bukkitPlayer -> bukkitPlayer.isOnline() ? + worldGuardPlugin.wrapPlayer((Player) bukkitPlayer) : worldGuardPlugin.wrapOfflinePlayer(bukkitPlayer)); } private Optional getWorldManager(@NonNull World world) { @@ -69,6 +75,64 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { .orElse(null), flag)); } + private IWrappedRegionSet wrapRegionSet(@NonNull World world, @NonNull ApplicableRegionSet regionSet) { + return new IWrappedRegionSet() { + + @SuppressWarnings("NullableProblems") + @Override + public Iterator iterator() { + return Iterators.transform(regionSet.iterator(), region -> new WrappedRegion(world, region)); + } + + @Override + public boolean isVirtual() { + return regionSet.isVirtual(); + } + + @Override + public Optional queryValue(OfflinePlayer subject, IWrappedFlag flag) { + LocalPlayer subjectHandle = wrapPlayer(subject).orElse(null); + AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; + return Optional.ofNullable(regionSet.queryValue(subjectHandle, wrappedFlag.getHandle())) + .flatMap(wrappedFlag::fromWGValue); + } + + @Override + public Collection queryAllValues(OfflinePlayer subject, IWrappedFlag flag) { + LocalPlayer subjectHandle = wrapPlayer(subject).orElse(null); + AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; + return regionSet.queryAllValues(subjectHandle, wrappedFlag.getHandle()).stream() + .map(wrappedFlag::fromWGValue) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + + @Override + public boolean isOwnerOfAll(OfflinePlayer player) { + LocalPlayer playerHandle = wrapPlayer(player).orElse(null); + return regionSet.isOwnerOfAll(playerHandle); + } + + @Override + public boolean isMemberOfAll(OfflinePlayer player) { + LocalPlayer playerHandle = wrapPlayer(player).orElse(null); + return regionSet.isMemberOfAll(playerHandle); + } + + @Override + public int size() { + return regionSet.size(); + } + + @Override + public Set getRegions() { + return regionSet.getRegions().stream() + .map(region -> new WrappedRegion(world, region)).collect(Collectors.toSet()); + } + }; + } + @Override public JavaPlugin getWorldGuardPlugin() { return WorldGuardPlugin.inst(); @@ -79,6 +143,11 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { return -6; } + @Override + public void registerHandler(Supplier factory) { + throw new UnsupportedOperationException("Custom flag handlers aren't supported in this version of WorldGuard!"); + } + @Override public Optional> getFlag(String name, Class type) { for (Flag currentFlag : DefaultFlag.getFlags()) { @@ -92,7 +161,8 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { @Override public Optional queryFlag(Player player, Location location, IWrappedFlag flag) { AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; - return queryValue(player, location, wrappedFlag.getHandle()).flatMap(value -> wrappedFlag.fromWGValue(value)); + + return queryValue(player, location, wrappedFlag.getHandle()).flatMap(wrappedFlag::fromWGValue); } @Override @@ -118,7 +188,7 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { Map.Entry, Object> wrapped = WorldGuardFlagUtilities.wrap(flag, value); flags.put(wrapped.getKey(), wrapped.getValue()); } catch (IllegalArgumentException e) { - continue; // Unsupported flag type + // Unsupported flag type } } } @@ -176,6 +246,11 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { return set; } + @Override + public Optional getRegionSet(@NonNull Location location) { + return getApplicableRegions(location).map(regionSet -> wrapRegionSet(location.getWorld(), regionSet)); + } + @Override public Optional addRegion(String id, List points, int minY, int maxY) { ProtectedRegion region; diff --git a/implementation/pom.xml b/implementation/pom.xml index 24c57b6..fc68cd4 100644 --- a/implementation/pom.xml +++ b/implementation/pom.xml @@ -7,7 +7,7 @@ org.codemc.worldguardwrapper worldguardwrapper-parent - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT worldguardwrapper-implementation diff --git a/implementation/v6/pom.xml b/implementation/v6/pom.xml index 5446f6c..02d5cc1 100644 --- a/implementation/v6/pom.xml +++ b/implementation/v6/pom.xml @@ -7,7 +7,7 @@ org.codemc.worldguardwrapper worldguardwrapper-implementation - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT worldguardwrapper-implementation-v6 @@ -28,7 +28,7 @@ ${project.groupId} worldguardwrapper-api - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT provided 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 19c1d6e..302135e 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,5 +1,8 @@ package org.codemc.worldguardwrapper.implementation.v6; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterators; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -15,25 +18,33 @@ import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.session.MoveType; +import com.sk89q.worldguard.session.Session; +import com.sk89q.worldguard.session.handler.Handler; import lombok.NonNull; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.util.Vector; import org.codemc.worldguardwrapper.flag.IWrappedFlag; import org.codemc.worldguardwrapper.flag.WrappedState; +import org.codemc.worldguardwrapper.handler.IHandler; import org.codemc.worldguardwrapper.implementation.IWorldGuardImplementation; import org.codemc.worldguardwrapper.implementation.v6.flag.AbstractWrappedFlag; import org.codemc.worldguardwrapper.implementation.v6.region.WrappedRegion; import org.codemc.worldguardwrapper.implementation.v6.utility.WorldGuardFlagUtilities; import org.codemc.worldguardwrapper.implementation.v6.utility.WorldGuardVectorUtilities; import org.codemc.worldguardwrapper.region.IWrappedRegion; +import org.codemc.worldguardwrapper.region.IWrappedRegionSet; import org.codemc.worldguardwrapper.selection.ICuboidSelection; import org.codemc.worldguardwrapper.selection.IPolygonalSelection; import org.codemc.worldguardwrapper.selection.ISelection; +import javax.annotation.Nullable; import java.util.*; +import java.util.function.Supplier; import java.util.stream.Collectors; public class WorldGuardImplementation implements IWorldGuardImplementation { @@ -52,8 +63,9 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { flagRegistry = worldGuardPlugin.getFlagRegistry(); } - private Optional wrapPlayer(Player player) { - return Optional.ofNullable(player).map(bukkitPlayer -> worldGuardPlugin.wrapPlayer(player)); + private Optional wrapPlayer(OfflinePlayer player) { + return Optional.ofNullable(player).map(bukkitPlayer -> bukkitPlayer.isOnline() ? + worldGuardPlugin.wrapPlayer((Player) bukkitPlayer) : worldGuardPlugin.wrapOfflinePlayer(bukkitPlayer)); } private Optional getWorldManager(@NonNull World world) { @@ -74,6 +86,64 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { .orElse(null), flag)); } + private IWrappedRegionSet wrapRegionSet(@NonNull World world, @NonNull ApplicableRegionSet regionSet) { + return new IWrappedRegionSet() { + + @SuppressWarnings("NullableProblems") + @Override + public Iterator iterator() { + return Iterators.transform(regionSet.iterator(), region -> new WrappedRegion(world, region)); + } + + @Override + public boolean isVirtual() { + return regionSet.isVirtual(); + } + + @Override + public Optional queryValue(OfflinePlayer subject, IWrappedFlag flag) { + LocalPlayer subjectHandle = wrapPlayer(subject).orElse(null); + AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; + return Optional.ofNullable(regionSet.queryValue(subjectHandle, wrappedFlag.getHandle())) + .flatMap(wrappedFlag::fromWGValue); + } + + @Override + public Collection queryAllValues(OfflinePlayer subject, IWrappedFlag flag) { + LocalPlayer subjectHandle = wrapPlayer(subject).orElse(null); + AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; + return regionSet.queryAllValues(subjectHandle, wrappedFlag.getHandle()).stream() + .map(wrappedFlag::fromWGValue) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + + @Override + public boolean isOwnerOfAll(OfflinePlayer player) { + LocalPlayer playerHandle = wrapPlayer(player).orElse(null); + return regionSet.isOwnerOfAll(playerHandle); + } + + @Override + public boolean isMemberOfAll(OfflinePlayer player) { + LocalPlayer playerHandle = wrapPlayer(player).orElse(null); + return regionSet.isMemberOfAll(playerHandle); + } + + @Override + public int size() { + return regionSet.size(); + } + + @Override + public Set getRegions() { + return regionSet.getRegions().stream() + .map(region -> new WrappedRegion(world, region)).collect(Collectors.toSet()); + } + }; + } + @Override public JavaPlugin getWorldGuardPlugin() { return WorldGuardPlugin.inst(); @@ -84,6 +154,49 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { return 6; } + @Override + public void registerHandler(Supplier factory) { + worldGuardPlugin.getSessionManager().registerHandler(new Handler.Factory() { + @Override + public Handler create(Session session) { + IHandler handler = factory.get(); + return new Handler(session) { + @Override + public void initialize(Player player, Location current, ApplicableRegionSet set) { + handler.initialize(player, current, wrapRegionSet(current.getWorld(), set)); + } + + @Override + public boolean testMoveTo(Player player, Location from, Location to, ApplicableRegionSet toSet, MoveType moveType) { + return handler.testMoveTo(player, from, to, wrapRegionSet(to.getWorld(), toSet), moveType.name()); + } + + @Override + public boolean onCrossBoundary(Player player, Location from, Location to, ApplicableRegionSet toSet, Set entered, Set exited, MoveType moveType) { + Set mappedEntered = ImmutableSet.copyOf(Collections2.transform(entered, region -> new WrappedRegion(to.getWorld(), region))); + Set mappedExited = ImmutableSet.copyOf(Collections2.transform(exited, region -> new WrappedRegion(from.getWorld(), region))); + return handler.onCrossBoundary(player, from, to, wrapRegionSet(to.getWorld(), toSet), mappedEntered, mappedExited, moveType.name()); + } + + @Override + public void tick(Player player, ApplicableRegionSet set) { + handler.tick(player, wrapRegionSet(player.getWorld(), set)); + } + + @Nullable + @Override + public StateFlag.State getInvincibility(Player player) { + WrappedState state = handler.getInvincibility(player); + if (state == null) { + return null; + } + return state == WrappedState.ALLOW ? StateFlag.State.ALLOW : StateFlag.State.DENY; + } + }; + } + }, null); + } + @Override public Optional> getFlag(String name, Class type) { return Optional.ofNullable(flagRegistry.get(name)) @@ -93,7 +206,7 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { @Override public Optional queryFlag(Player player, Location location, IWrappedFlag flag) { AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; - return queryValue(player, location, wrappedFlag.getHandle()).flatMap(value -> wrappedFlag.fromWGValue(value)); + return queryValue(player, location, wrappedFlag.getHandle()).flatMap(wrappedFlag::fromWGValue); } @Override @@ -119,7 +232,7 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { Map.Entry, Object> wrapped = WorldGuardFlagUtilities.wrap(flag, value); flags.put(wrapped.getKey(), wrapped.getValue()); } catch (IllegalArgumentException e) { - continue; // Unsupported flag type + // Unsupported flag type } } } @@ -128,7 +241,7 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { return flags; } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public Optional> registerFlag(String name, Class type, T defaultValue) { final Flag flag; @@ -203,6 +316,11 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { return set; } + @Override + public Optional getRegionSet(@NonNull Location location) { + return getApplicableRegions(location).map(regionSet -> wrapRegionSet(location.getWorld(), regionSet)); + } + @Override public Optional addRegion(String id, List points, int minY, int maxY) { ProtectedRegion region; diff --git a/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/utility/WorldGuardFlagUtilities.java b/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/utility/WorldGuardFlagUtilities.java index 5836f49..4bc66dc 100644 --- a/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/utility/WorldGuardFlagUtilities.java +++ b/implementation/v6/src/main/java/org/codemc/worldguardwrapper/implementation/v6/utility/WorldGuardFlagUtilities.java @@ -65,6 +65,7 @@ public class WorldGuardFlagUtilities { public Map.Entry, Object> wrap(Flag flag, Object value) { IWrappedFlag wrappedFlag = wrapFixType(flag, value.getClass()); + //noinspection OptionalGetWithoutIsPresent Object wrappedValue = ((AbstractWrappedFlag) wrappedFlag).fromWGValue(value).get(); // value is non-null return Maps.immutableEntry(wrappedFlag, wrappedValue); } diff --git a/implementation/v7/pom.xml b/implementation/v7/pom.xml index c1ee260..d618040 100644 --- a/implementation/v7/pom.xml +++ b/implementation/v7/pom.xml @@ -7,7 +7,7 @@ org.codemc.worldguardwrapper worldguardwrapper-implementation - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT worldguardwrapper-implementation-v7 @@ -28,7 +28,7 @@ ${project.groupId} worldguardwrapper-api - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT provided 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 673fe06..c8c4e9b 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,8 @@ package org.codemc.worldguardwrapper.implementation.v7; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterators; import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -20,24 +23,32 @@ import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion; +import com.sk89q.worldguard.session.MoveType; +import com.sk89q.worldguard.session.Session; +import com.sk89q.worldguard.session.handler.Handler; import lombok.NonNull; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.util.Vector; import org.codemc.worldguardwrapper.flag.IWrappedFlag; import org.codemc.worldguardwrapper.flag.WrappedState; +import org.codemc.worldguardwrapper.handler.IHandler; import org.codemc.worldguardwrapper.implementation.IWorldGuardImplementation; import org.codemc.worldguardwrapper.implementation.v7.flag.AbstractWrappedFlag; import org.codemc.worldguardwrapper.implementation.v7.region.WrappedRegion; import org.codemc.worldguardwrapper.implementation.v7.utility.WorldGuardFlagUtilities; import org.codemc.worldguardwrapper.region.IWrappedRegion; +import org.codemc.worldguardwrapper.region.IWrappedRegionSet; import org.codemc.worldguardwrapper.selection.ICuboidSelection; import org.codemc.worldguardwrapper.selection.IPolygonalSelection; import org.codemc.worldguardwrapper.selection.ISelection; +import javax.annotation.Nullable; import java.util.*; +import java.util.function.Supplier; import java.util.stream.Collectors; public class WorldGuardImplementation implements IWorldGuardImplementation { @@ -58,8 +69,9 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { } } - private Optional wrapPlayer(Player player) { - return Optional.ofNullable(player).map(bukkitPlayer -> worldGuardPlugin.wrapPlayer(player)); + private Optional wrapPlayer(OfflinePlayer player) { + return Optional.ofNullable(player).map(bukkitPlayer -> bukkitPlayer.isOnline() ? + worldGuardPlugin.wrapPlayer((Player) bukkitPlayer) : worldGuardPlugin.wrapOfflinePlayer(bukkitPlayer)); } private Optional getWorldManager(@NonNull World world) { @@ -80,6 +92,64 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { .orElse(null), flag)); } + private IWrappedRegionSet wrapRegionSet(@NonNull World world, @NonNull ApplicableRegionSet regionSet) { + return new IWrappedRegionSet() { + + @SuppressWarnings("NullableProblems") + @Override + public Iterator iterator() { + return Iterators.transform(regionSet.iterator(), region -> new WrappedRegion(world, region)); + } + + @Override + public boolean isVirtual() { + return regionSet.isVirtual(); + } + + @Override + public Optional queryValue(OfflinePlayer subject, IWrappedFlag flag) { + LocalPlayer subjectHandle = wrapPlayer(subject).orElse(null); + AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; + return Optional.ofNullable(regionSet.queryValue(subjectHandle, wrappedFlag.getHandle())) + .flatMap(wrappedFlag::fromWGValue); + } + + @Override + public Collection queryAllValues(OfflinePlayer subject, IWrappedFlag flag) { + LocalPlayer subjectHandle = wrapPlayer(subject).orElse(null); + AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; + return regionSet.queryAllValues(subjectHandle, wrappedFlag.getHandle()).stream() + .map(wrappedFlag::fromWGValue) + .filter(Optional::isPresent) + .map(Optional::get) + .collect(Collectors.toList()); + } + + @Override + public boolean isOwnerOfAll(OfflinePlayer player) { + LocalPlayer playerHandle = wrapPlayer(player).orElse(null); + return regionSet.isOwnerOfAll(playerHandle); + } + + @Override + public boolean isMemberOfAll(OfflinePlayer player) { + LocalPlayer playerHandle = wrapPlayer(player).orElse(null); + return regionSet.isMemberOfAll(playerHandle); + } + + @Override + public int size() { + return regionSet.size(); + } + + @Override + public Set getRegions() { + return regionSet.getRegions().stream() + .map(region -> new WrappedRegion(world, region)).collect(Collectors.toSet()); + } + }; + } + @Override public JavaPlugin getWorldGuardPlugin() { return WorldGuardPlugin.inst(); @@ -90,6 +160,59 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { return 7; } + @Override + public void registerHandler(Supplier factory) { + core.getPlatform().getSessionManager().registerHandler(new Handler.Factory() { + @Override + public Handler create(Session session) { + IHandler handler = factory.get(); + return new Handler(session) { + @Override + public void initialize(LocalPlayer player, com.sk89q.worldedit.util.Location current, ApplicableRegionSet set) { + Player bukkitPlayer = BukkitAdapter.adapt(player); + Location bukkitLocation = BukkitAdapter.adapt(current); + handler.initialize(bukkitPlayer, bukkitLocation, wrapRegionSet(bukkitLocation.getWorld(), set)); + } + + @Override + public boolean testMoveTo(LocalPlayer player, com.sk89q.worldedit.util.Location from, com.sk89q.worldedit.util.Location to, ApplicableRegionSet toSet, MoveType moveType) { + Player bukkitPlayer = BukkitAdapter.adapt(player); + Location bukkitFrom = BukkitAdapter.adapt(from); + Location bukkitTo = BukkitAdapter.adapt(to); + return handler.testMoveTo(bukkitPlayer, bukkitFrom, bukkitTo, wrapRegionSet(bukkitTo.getWorld(), toSet), moveType.name()); + } + + @Override + public boolean onCrossBoundary(LocalPlayer player, com.sk89q.worldedit.util.Location from, com.sk89q.worldedit.util.Location to, ApplicableRegionSet toSet, Set entered, Set exited, MoveType moveType) { + Player bukkitPlayer = BukkitAdapter.adapt(player); + Location bukkitFrom = BukkitAdapter.adapt(from); + Location bukkitTo = BukkitAdapter.adapt(to); + Set mappedEntered = ImmutableSet.copyOf(Collections2.transform(entered, region -> new WrappedRegion(bukkitTo.getWorld(), region))); + Set mappedExited = ImmutableSet.copyOf(Collections2.transform(exited, region -> new WrappedRegion(bukkitFrom.getWorld(), region))); + return handler.onCrossBoundary(bukkitPlayer, bukkitFrom, bukkitTo, wrapRegionSet(bukkitTo.getWorld(), toSet), mappedEntered, mappedExited, moveType.name()); + } + + @Override + public void tick(LocalPlayer player, ApplicableRegionSet set) { + Player bukkitPlayer = BukkitAdapter.adapt(player); + handler.tick(bukkitPlayer, wrapRegionSet(bukkitPlayer.getWorld(), set)); + } + + @Nullable + @Override + public StateFlag.State getInvincibility(LocalPlayer player) { + Player bukkitPlayer = BukkitAdapter.adapt(player); + WrappedState state = handler.getInvincibility(bukkitPlayer); + if (state == null) { + return null; + } + return state == WrappedState.ALLOW ? StateFlag.State.ALLOW : StateFlag.State.DENY; + } + }; + } + }, null); + } + @Override public Optional> getFlag(String name, Class type) { return Optional.ofNullable(flagRegistry.get(name)) @@ -99,7 +222,7 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { @Override public Optional queryFlag(Player player, Location location, IWrappedFlag flag) { AbstractWrappedFlag wrappedFlag = (AbstractWrappedFlag) flag; - return queryValue(player, location, wrappedFlag.getHandle()).flatMap(value -> wrappedFlag.fromWGValue(value)); + return queryValue(player, location, wrappedFlag.getHandle()).flatMap(wrappedFlag::fromWGValue); } @Override @@ -125,7 +248,7 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { Map.Entry, Object> wrapped = WorldGuardFlagUtilities.wrap(flag, value); flags.put(wrapped.getKey(), wrapped.getValue()); } catch (IllegalArgumentException e) { - continue; // Unsupported flag type + // Unsupported flag type } } } @@ -134,7 +257,7 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { return flags; } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public Optional> registerFlag(String name, Class type, T defaultValue) { final Flag flag; @@ -209,6 +332,11 @@ public class WorldGuardImplementation implements IWorldGuardImplementation { .collect(Collectors.toSet()); } + @Override + public Optional getRegionSet(@NonNull Location location) { + return Optional.empty(); + } + @Override public Optional addRegion(String id, List points, int minY, int maxY) { ProtectedRegion region; diff --git a/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/utility/WorldGuardFlagUtilities.java b/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/utility/WorldGuardFlagUtilities.java index 1950b36..acaf867 100644 --- a/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/utility/WorldGuardFlagUtilities.java +++ b/implementation/v7/src/main/java/org/codemc/worldguardwrapper/implementation/v7/utility/WorldGuardFlagUtilities.java @@ -4,7 +4,7 @@ import com.google.common.collect.Maps; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldguard.protection.flags.Flag; import com.sk89q.worldguard.protection.flags.StateFlag; - +import lombok.experimental.UtilityClass; import org.bukkit.Location; import org.bukkit.util.Vector; import org.codemc.worldguardwrapper.flag.IWrappedFlag; @@ -13,10 +13,7 @@ import org.codemc.worldguardwrapper.implementation.v7.flag.AbstractWrappedFlag; import org.codemc.worldguardwrapper.implementation.v7.flag.WrappedPrimitiveFlag; import org.codemc.worldguardwrapper.implementation.v7.flag.WrappedStatusFlag; -import lombok.experimental.UtilityClass; - import java.util.Map; -import java.util.Optional; @UtilityClass public class WorldGuardFlagUtilities { @@ -65,6 +62,7 @@ public class WorldGuardFlagUtilities { public Map.Entry, Object> wrap(Flag flag, Object value) { IWrappedFlag wrappedFlag = wrapFixType(flag, value.getClass()); + //noinspection OptionalGetWithoutIsPresent Object wrappedValue = ((AbstractWrappedFlag) wrappedFlag).fromWGValue(value).get(); // value is non-null return Maps.immutableEntry(wrappedFlag, wrappedValue); } diff --git a/library/pom.xml b/library/pom.xml index 9b914c5..22144aa 100644 --- a/library/pom.xml +++ b/library/pom.xml @@ -7,7 +7,7 @@ org.codemc.worldguardwrapper worldguardwrapper-parent - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT worldguardwrapper @@ -18,22 +18,22 @@ ${project.groupId} worldguardwrapper-api - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT ${project.groupId} worldguardwrapper-implementation-legacy - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT ${project.groupId} worldguardwrapper-implementation-v6 - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT ${project.groupId} worldguardwrapper-implementation-v7 - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT diff --git a/pom.xml b/pom.xml index 1425ed2..47bdb49 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.codemc.worldguardwrapper worldguardwrapper-parent - 1.1.9-SNAPSHOT + 1.2.0-SNAPSHOT pom @@ -51,7 +51,7 @@ UTF-8 UTF-8 1.8 - 1.15.2-R0.1-SNAPSHOT + 1.16.3-R0.1-SNAPSHOT @@ -89,7 +89,7 @@ org.projectlombok lombok - 1.18.12 + 1.18.16 provided