10 Commits

Author SHA1 Message Date
YouHaveTrouble acaf8ac233 bump version 2025-09-27 23:14:23 +02:00
Matt Baxter c30c3ee7c9 Improve FUUID support: (#7)
Don't waste time if not in an enabled world.
Fixes test for protection that would always return true.
Fixes block use test to use more proper method.
2025-09-27 23:12:52 +02:00
YouHaveTrouble a2d676044c add plotsquared to implementation list 2024-08-14 20:54:56 +02:00
YouHaveTrouble 813702596a bump version 2024-08-14 20:37:26 +02:00
Ryder Belserion 6ba3acf5f6 Add plotsquared protection (#6)
* getState() is already true

* add plotsquared protection

* check if isProtected first

* check if owned plot is not null

* move isProtected up one

* remove comments
2024-08-14 20:36:37 +02:00
Ryder Belserion d9ea1265bf Resource apiversion.txt not found on startup (#5)
* fix resource apiversion.txt not found

* add whitespace back
2024-08-05 08:41:57 +02:00
YouHaveTrouble 5c942e72c3 bump version 2024-07-19 18:56:14 +02:00
YouHaveTrouble 27bb0e49e7 display api version in /yw command feedback 2024-07-19 18:55:24 +02:00
YouHaveTrouble 8aba8ea79d update wg depend and dump YardWatch API version into a resource file 2024-07-19 18:55:06 +02:00
Hüseyin Serhat Han afdb3a0e3e Query command & Worldguard null parameter exception fix (#4)
* query command + fix wg exception

* remove empty statement and unused imports

* added feedback for case when there are no protections in queried location

---------

Co-authored-by: YouHaveTrouble <youhavetrouble@youhavetrouble.me>
2024-07-19 17:49:25 +02:00
9 changed files with 202 additions and 10 deletions
+22 -3
View File
@@ -6,7 +6,7 @@
<groupId>me.youhavetrouble</groupId> <groupId>me.youhavetrouble</groupId>
<artifactId>YardWatch</artifactId> <artifactId>YardWatch</artifactId>
<version>1.2.0</version> <version>1.4.1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>YardWatch</name> <name>YardWatch</name>
@@ -15,6 +15,7 @@
<properties> <properties>
<java.version>17</java.version> <java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<yardwatch.api.version>2.0.0</yardwatch.api.version>
</properties> </properties>
<url>https://youhavetrouble.me</url> <url>https://youhavetrouble.me</url>
@@ -95,6 +96,18 @@
</repository> </repository>
</repositories> </repositories>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.intellectualsites.bom</groupId>
<artifactId>bom-newest</artifactId>
<version>1.48</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.destroystokyo.paper</groupId> <groupId>com.destroystokyo.paper</groupId>
@@ -105,7 +118,7 @@
<dependency> <dependency>
<groupId>com.sk89q.worldguard</groupId> <groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId> <artifactId>worldguard-bukkit</artifactId>
<version>7.0.4-SNAPSHOT</version> <version>7.0.9-SNAPSHOT</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.bstats</groupId> <groupId>org.bstats</groupId>
@@ -117,7 +130,7 @@
<dependency> <dependency>
<groupId>com.github.YouHaveTrouble</groupId> <groupId>com.github.YouHaveTrouble</groupId>
<artifactId>YardWatchAPI</artifactId> <artifactId>YardWatchAPI</artifactId>
<version>2.0.0</version> <version>${yardwatch.api.version}</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -150,5 +163,11 @@
<version>0.100.1.0</version> <version>0.100.1.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>com.intellectualsites.plotsquared</groupId>
<artifactId>plotsquared-core</artifactId>
<version>7.3.8</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>
+1
View File
@@ -20,6 +20,7 @@ You can download YardWatch plugin on [Modrinth](https://modrinth.com/plugin/yard
- [FactionsUUID](https://www.spigotmc.org/resources/factionsuuid.1035/) - [FactionsUUID](https://www.spigotmc.org/resources/factionsuuid.1035/)
- [SuperiorSkyBlock](https://bg-software.com/superiorskyblock/) - [SuperiorSkyBlock](https://bg-software.com/superiorskyblock/)
- [Towny](https://github.com/TownyAdvanced/Towny) - [Towny](https://github.com/TownyAdvanced/Towny)
- [PlotSquared (6.0.0+)](https://www.spigotmc.org/resources/plotsquared.1177/)
## Plugin you're using is not implementing YardWatchAPI? ## Plugin you're using is not implementing YardWatchAPI?
Contact the plugin developer and send them [here](https://github.com/YouHaveTrouble/YardWatchAPI/blob/master/readme.md)! Contact the plugin developer and send them [here](https://github.com/YouHaveTrouble/YardWatchAPI/blob/master/readme.md)!
@@ -1,9 +1,11 @@
package me.youhavetrouble.yardwatch; package me.youhavetrouble.yardwatch;
import com.google.common.io.Resources;
import me.youhavetrouble.yardwatch.commands.YardWatchCommand; import me.youhavetrouble.yardwatch.commands.YardWatchCommand;
import me.youhavetrouble.yardwatch.hooks.FactionsUUIDProtection; import me.youhavetrouble.yardwatch.hooks.FactionsUUIDProtection;
import me.youhavetrouble.yardwatch.hooks.GriefPreventionProtection; import me.youhavetrouble.yardwatch.hooks.GriefPreventionProtection;
import me.youhavetrouble.yardwatch.hooks.LWCXProtection; import me.youhavetrouble.yardwatch.hooks.LWCXProtection;
import me.youhavetrouble.yardwatch.hooks.PlotSquaredProtection;
import me.youhavetrouble.yardwatch.hooks.SuperiorSkyBlockProtection; import me.youhavetrouble.yardwatch.hooks.SuperiorSkyBlockProtection;
import me.youhavetrouble.yardwatch.hooks.TownyProtection; import me.youhavetrouble.yardwatch.hooks.TownyProtection;
import me.youhavetrouble.yardwatch.hooks.WorldGuardProtection; import me.youhavetrouble.yardwatch.hooks.WorldGuardProtection;
@@ -13,13 +15,28 @@ import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
import java.net.URL;
import java.util.List; import java.util.List;
@SuppressWarnings("UnstableApiUsage")
public final class YardWatch extends JavaPlugin { public final class YardWatch extends JavaPlugin {
private static String yardWatchApiVersion = "Unknown";
@Override @Override
public void onEnable() { public void onEnable() {
try {
final URL url = getClassLoader().getResource("apiversion.txt");
if (url != null) {
yardWatchApiVersion = Resources.toString(url, com.google.common.base.Charsets.UTF_8);
}
} catch (IOException e) {
getLogger().warning("Failed to read YardWatch API version.");
}
PluginCommand command = getCommand("yardwatch"); PluginCommand command = getCommand("yardwatch");
if (command != null) { if (command != null) {
command.setExecutor(new YardWatchCommand(this)); command.setExecutor(new YardWatchCommand(this));
@@ -67,6 +84,13 @@ public final class YardWatch extends JavaPlugin {
); );
} }
if (shouldRegisterService("PlotSquared")) {
getLogger().info("Registering PlotSquared service.");
getServer().getServicesManager().register(
Protection.class, new PlotSquaredProtection(this), this, ServicePriority.Normal
);
}
List<RegisteredServiceProvider<?>> registrations = getServer().getServicesManager().getRegistrations(this); List<RegisteredServiceProvider<?>> registrations = getServer().getServicesManager().getRegistrations(this);
if (registrations.isEmpty()) { if (registrations.isEmpty()) {
getLogger().info("Registered 0 services. This plugin can be safely removed."); getLogger().info("Registered 0 services. This plugin can be safely removed.");
@@ -96,4 +120,8 @@ public final class YardWatch extends JavaPlugin {
public void onDisable() { public void onDisable() {
getServer().getServicesManager().unregisterAll(this); getServer().getServicesManager().unregisterAll(this);
} }
public static String getYardWatchApiVersion() {
return yardWatchApiVersion;
}
} }
@@ -2,9 +2,13 @@ package me.youhavetrouble.yardwatch.commands;
import me.youhavetrouble.yardwatch.Protection; import me.youhavetrouble.yardwatch.Protection;
import me.youhavetrouble.yardwatch.YardWatch; import me.youhavetrouble.yardwatch.YardWatch;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import org.bukkit.Location;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor; import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -34,6 +38,9 @@ public class YardWatchCommand implements TabExecutor {
if (args[0].equalsIgnoreCase("hooks")) { if (args[0].equalsIgnoreCase("hooks")) {
sendHooks(sender); sendHooks(sender);
return true; return true;
} else if (args[0].equalsIgnoreCase("query")) {
queryProtection(sender);
return true;
} }
return false; return false;
@@ -45,6 +52,7 @@ public class YardWatchCommand implements TabExecutor {
if (args.length == 1) { if (args.length == 1) {
completions.add("hooks"); completions.add("hooks");
completions.add("query");
return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>()); return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>());
} }
@@ -52,7 +60,7 @@ public class YardWatchCommand implements TabExecutor {
} }
private void sendDefault(CommandSender sender) { private void sendDefault(CommandSender sender) {
sender.sendMessage("YardWatch " + version); sender.sendMessage(String.format("YardWatch %s (Implementing YardWatch API %s)", version, YardWatch.getYardWatchApiVersion()));
} }
private void sendHooks(CommandSender sender) { private void sendHooks(CommandSender sender) {
@@ -72,4 +80,31 @@ public class YardWatchCommand implements TabExecutor {
} }
} }
private void queryProtection(CommandSender sender) {
if (!(sender instanceof Player player)) {
sender.sendMessage(("You must be a player to use this command!"));
return;
}
Location location = player.getLocation();
sender.sendMessage("Protections at " + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ());
Collection<RegisteredServiceProvider<Protection>> protections = plugin.getServer().getServicesManager().getRegistrations(Protection.class);
if (protections.isEmpty()) {
sender.sendMessage("No protections registered at " + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ());
return;
}
for (RegisteredServiceProvider<Protection> protection : protections) {
Component component = Component.text(protection.getPlugin().getName()).append(Component.text(" isProtected " + protection.getProvider().isProtected(location)))
.hoverEvent(HoverEvent.showText(
Component.text(protection.getProvider().toString())
.append(Component.newline())
.append(Component.text("canPlaceBlock " + protection.getProvider().canPlaceBlock(player, location))
.append(Component.newline())
.append(Component.text("canBreakBlock " + protection.getProvider().canBreakBlock(player, location.getBlock().getState())))
.append(Component.newline())
.append(Component.text("canInteract " + protection.getProvider().canInteract(player, location.getBlock().getState())))
)));
sender.sendMessage(component);
}
}
} }
@@ -35,12 +35,13 @@ public class FactionsUUIDProtection implements Protection {
if (!FactionsPlugin.getInstance().worldUtil().isEnabled(location.getWorld())) return false; if (!FactionsPlugin.getInstance().worldUtil().isEnabled(location.getWorld())) return false;
FLocation fLocation = new FLocation(location); FLocation fLocation = new FLocation(location);
Faction faction = Board.getInstance().getFactionAt(fLocation); Faction faction = Board.getInstance().getFactionAt(fLocation);
return faction != null; return !faction.isWilderness();
} }
@Override @Override
public boolean canBreakBlock(Player player, BlockState blockState) { public boolean canBreakBlock(Player player, BlockState blockState) {
if (!isEnabled()) return true; if (!isEnabled()) return true;
if (!FactionsPlugin.getInstance().worldUtil().isEnabled(blockState.getWorld())) return true;
return FactionsBlockListener.playerCanBuildDestroyBlock( return FactionsBlockListener.playerCanBuildDestroyBlock(
player, player,
blockState.getLocation(), blockState.getLocation(),
@@ -52,6 +53,7 @@ public class FactionsUUIDProtection implements Protection {
@Override @Override
public boolean canPlaceBlock(Player player, Location location) { public boolean canPlaceBlock(Player player, Location location) {
if (!isEnabled()) return true; if (!isEnabled()) return true;
if (!FactionsPlugin.getInstance().worldUtil().isEnabled(location.getWorld())) return true;
return FactionsBlockListener.playerCanBuildDestroyBlock( return FactionsBlockListener.playerCanBuildDestroyBlock(
player, player,
location, location,
@@ -63,18 +65,26 @@ public class FactionsUUIDProtection implements Protection {
@Override @Override
public boolean canInteract(Player player, BlockState blockState) { public boolean canInteract(Player player, BlockState blockState) {
if (!isEnabled()) return true; if (!isEnabled()) return true;
return FactionsPlayerListener.canInteractHere(player, blockState.getLocation()); if (!FactionsPlugin.getInstance().worldUtil().isEnabled(blockState.getWorld())) return true;
return FactionsPlayerListener.canUseBlock(
player,
blockState.getType(),
blockState.getLocation(),
true
);
} }
@Override @Override
public boolean canInteract(Player player, Entity target) { public boolean canInteract(Player player, Entity target) {
if (!isEnabled()) return true; if (!isEnabled()) return true;
if (!FactionsPlugin.getInstance().worldUtil().isEnabled(target)) return true;
return FactionsEntityListener.canInteractHere(player, target.getLocation()); return FactionsEntityListener.canInteractHere(player, target.getLocation());
} }
@Override @Override
public boolean canDamage(Entity damager, Entity target) { public boolean canDamage(Entity damager, Entity target) {
if (!isEnabled()) return true; if (!isEnabled()) return true;
if (!FactionsPlugin.getInstance().worldUtil().isEnabled(target)) return true;
return FactionsEntityListener.canDamage(damager, target, false); return FactionsEntityListener.canDamage(damager, target, false);
} }
} }
@@ -0,0 +1,97 @@
package me.youhavetrouble.yardwatch.hooks;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.flag.implementations.PvpFlag;
import me.youhavetrouble.yardwatch.Protection;
import me.youhavetrouble.yardwatch.YardWatch;
import org.bukkit.Location;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
public class PlotSquaredProtection implements Protection {
private final YardWatch plugin;
public PlotSquaredProtection(YardWatch plugin) {
this.plugin = plugin;
}
@Override
public boolean isEnabled() {
return this.plugin.getServer().getPluginManager().isPluginEnabled("PlotSquared");
}
@Override
public boolean isProtected(final Location location) {
if (!isEnabled()) return false;
final com.plotsquared.core.location.Location arg1 = getLocation(location);
return arg1.isPlotArea() || arg1.isPlotRoad() || arg1.isUnownedPlotArea() || arg1.getOwnedPlot() != null;
}
@Override
public boolean canBreakBlock(final Player player, final BlockState blockState) {
if (!isEnabled()) return true;
final Location blockLocation = blockState.getLocation();
final com.plotsquared.core.location.@NonNull Location location = getLocation(blockLocation);
final Plot plot = location.getOwnedPlot();
if (plot == null) return isProtected(blockLocation);
return plot.isAdded(player.getUniqueId());
}
@Override
public boolean canPlaceBlock(final Player player, final Location location) {
return canBreakBlock(player, location.getBlock().getState());
}
@Override
public boolean canInteract(final Player player, final BlockState blockState) {
if (!isEnabled()) return true;
final Location location = blockState.getLocation();
com.plotsquared.core.location.@NonNull Location plotLocation = getLocation(location);
final Plot plot = plotLocation.getOwnedPlot();
if (plot == null) return isProtected(location);
return plot.isAdded(player.getUniqueId());
}
@Override
public boolean canInteract(final Player player, final Entity target) {
return canInteract(player, target.getLocation().getBlock().getState());
}
@Override
public boolean canDamage(final Entity damager, final Entity target) {
if (!isEnabled() || !(damager instanceof Player)) return true;
final Location location = target.getLocation();
com.plotsquared.core.location.@NonNull Location plotLocation = getLocation(location);
final Plot plot = plotLocation.getOwnedPlot();
if (plot == null) return isProtected(location);
return plot.getFlag(PvpFlag.class);
}
private com.plotsquared.core.location.@NonNull Location getLocation(final Location location) {
final String world = location.getWorld().getName();
final int x = (int) location.getX();
final int y = (int) location.getY();
final int z = (int) location.getZ();
return com.plotsquared.core.location.Location.at(world, x, y, z);
}
}
@@ -3,7 +3,6 @@ package me.youhavetrouble.yardwatch.hooks;
import com.palmergames.bukkit.towny.TownyAPI; import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownBlock; import com.palmergames.bukkit.towny.object.TownBlock;
import com.palmergames.bukkit.towny.object.TownyPermission;
import com.palmergames.bukkit.towny.utils.CombatUtil; import com.palmergames.bukkit.towny.utils.CombatUtil;
import me.youhavetrouble.yardwatch.Protection; import me.youhavetrouble.yardwatch.Protection;
import me.youhavetrouble.yardwatch.YardWatch; import me.youhavetrouble.yardwatch.YardWatch;
@@ -45,7 +44,7 @@ public class TownyProtection implements Protection {
@Override @Override
public boolean canPlaceBlock(Player player, Location location) { public boolean canPlaceBlock(Player player, Location location) {
return canInteract(player, location.getBlock().getState(true)); return canInteract(player, location.getBlock().getState());
} }
@Override @Override
@@ -63,7 +62,7 @@ public class TownyProtection implements Protection {
@Override @Override
public boolean canInteract(Player player, Entity target) { public boolean canInteract(Player player, Entity target) {
return canInteract(player, target.getLocation().getBlock().getState(true)); return canInteract(player, target.getLocation().getBlock().getState());
} }
@Override @Override
@@ -4,6 +4,8 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.LocalPlayer; import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin; import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.Association;
import com.sk89q.worldguard.protection.association.Associables;
import com.sk89q.worldguard.protection.flags.Flags; import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.regions.RegionContainer; import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery; import com.sk89q.worldguard.protection.regions.RegionQuery;
@@ -34,7 +36,7 @@ public class WorldGuardProtection implements Protection {
com.sk89q.worldedit.util.Location wgLocation = BukkitAdapter.adapt(location); com.sk89q.worldedit.util.Location wgLocation = BukkitAdapter.adapt(location);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery(); RegionQuery query = container.createQuery();
return query.testBuild(wgLocation, null); return query.testBuild(wgLocation, Associables.constant(Association.NON_MEMBER));
} }
@Override @Override
+1
View File
@@ -0,0 +1 @@
${yardwatch.api.version}