14 Commits

Author SHA1 Message Date
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
YouHaveTrouble 3833c5ce43 link to modrinth 2024-06-05 20:22:49 +02:00
YouHaveTrouble fec112511c Merge remote-tracking branch 'origin/master' 2024-06-05 20:19:39 +02:00
YouHaveTrouble c65e68dcfc bump version 2024-06-05 20:12:47 +02:00
YouHaveTrouble b7587970c0 command to display which plugins have hooks registered 2024-06-05 20:12:24 +02:00
YouHaveTrouble 48f5c337d7 no need for remapping :) 2024-06-05 20:11:02 +02:00
YouHaveTrouble 6017feccec Update readme.md 2024-04-18 10:28:29 +02:00
granny 31fa7b02b9 add logs when registering services (#2)
* add logs when registering services

* Update YardWatch.java
2024-04-18 10:27:34 +02:00
YouHaveTrouble eb9ebb1fb3 add LWC to softdepends 2024-04-16 21:59:40 +02:00
YouHaveTrouble bea339f701 bump version 2024-04-16 19:58:16 +02:00
Ryder Belserion 34964d30cd Adds towny and superiorskyblock support (#1)
* Stash changes

* Add superiorskyblock2 support

* Add as a soft depend

* Fix skyblock support

* Add palmers towny support

* Turned off wildcard imports

* Update readme

* Update .gitignore

* Add new line

* Add new line
2024-04-16 19:57:08 +02:00
10 changed files with 390 additions and 9 deletions
+2
View File
@@ -5,6 +5,8 @@
*.ipr
*.iws
server
# IntelliJ
out/
+33 -3
View File
@@ -6,7 +6,7 @@
<groupId>me.youhavetrouble</groupId>
<artifactId>YardWatch</artifactId>
<version>1.0</version>
<version>1.3.0</version>
<packaging>jar</packaging>
<name>YardWatch</name>
@@ -15,6 +15,7 @@
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<yardwatch.api.version>2.0.0</yardwatch.api.version>
</properties>
<url>https://youhavetrouble.me</url>
@@ -39,6 +40,15 @@
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<paperweight-mappings-namespace>mojang</paperweight-mappings-namespace>
</manifestEntries>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
@@ -52,6 +62,10 @@
</build>
<repositories>
<repository>
<id>bg-software</id>
<url>https://repo.bg-software.com/repository/api/</url>
</repository>
<repository>
<id>papermc-repo</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
@@ -76,6 +90,10 @@
<id>ender-zone</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository>
<repository>
<id>glaremasters repo</id>
<url>https://repo.glaremasters.me/repository/towny/</url>
</repository>
</repositories>
<dependencies>
@@ -88,7 +106,7 @@
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.4-SNAPSHOT</version>
<version>7.0.9-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.bstats</groupId>
@@ -100,7 +118,7 @@
<dependency>
<groupId>com.github.YouHaveTrouble</groupId>
<artifactId>YardWatchAPI</artifactId>
<version>2.0.0</version>
<version>${yardwatch.api.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
@@ -109,6 +127,12 @@
<version>16.18.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.bgsoftware</groupId>
<artifactId>SuperiorSkyblockAPI</artifactId>
<version>2023.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.griefcraft</groupId>
<artifactId>lwc</artifactId>
@@ -121,5 +145,11 @@
<version>1.6.9.5-U0.6.33</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.palmergames.bukkit.towny</groupId>
<artifactId>towny</artifactId>
<version>0.100.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
+9 -5
View File
@@ -3,19 +3,23 @@ Implementation of [YardWatchAPI](https://github.com/YouHaveTrouble/YardWatchAPI)
of supported plugins implements the API itself, then this plugin will stop providing its implementation to allow the
plugin to take over.
If you're a developer looking for information how to implement YardWatchAPI in your plugin, see
[YardWatchAPI](https://github.com/YouHaveTrouble/YardWatchAPI)
## Downloads
You can download YardWatch plugin on [Modrinth](https://modrinth.com/plugin/yardwatch).
## Requirements
- Java 17
- Minecraft 1.16+
## Implementations for:
- GriefPrevention (v16+)
- WorldGuard (7.0.0+)
- LWCX
- FactionsUUID
- [GriefPrevention (v16+)](https://www.spigotmc.org/resources/griefprevention.1884/)
- [WorldGuard (7.0.0+)](https://enginehub.org/worldguard#downloads)
- [LWCX](https://www.spigotmc.org/resources/lwc-extended.69551/)
- [FactionsUUID](https://www.spigotmc.org/resources/factionsuuid.1035/)
- [SuperiorSkyBlock](https://bg-software.com/superiorskyblock/)
- [Towny](https://github.com/TownyAdvanced/Towny)
## 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)!
@@ -1,45 +1,91 @@
package me.youhavetrouble.yardwatch;
import com.google.common.io.Resources;
import me.youhavetrouble.yardwatch.commands.YardWatchCommand;
import me.youhavetrouble.yardwatch.hooks.FactionsUUIDProtection;
import me.youhavetrouble.yardwatch.hooks.GriefPreventionProtection;
import me.youhavetrouble.yardwatch.hooks.LWCXProtection;
import me.youhavetrouble.yardwatch.hooks.SuperiorSkyBlockProtection;
import me.youhavetrouble.yardwatch.hooks.TownyProtection;
import me.youhavetrouble.yardwatch.hooks.WorldGuardProtection;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
import java.net.URL;
import java.util.List;
@SuppressWarnings("UnstableApiUsage")
public final class YardWatch extends JavaPlugin {
private static String yardWatchApiVersion = "Unknown";
@Override
public void onEnable() {
try {
URL url = Resources.getResource("apiversion.txt");
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");
if (command != null) {
command.setExecutor(new YardWatchCommand(this));
}
if (shouldRegisterService("WorldGuard")) {
getLogger().info("Registering WorldGuard service.");
getServer().getServicesManager().register(
Protection.class, new WorldGuardProtection(this), this, ServicePriority.Normal
);
}
if (shouldRegisterService("GriefPrevention")) {
getLogger().info("Registering GriefPrevention service.");
getServer().getServicesManager().register(
Protection.class, new GriefPreventionProtection(this), this, ServicePriority.Normal
);
}
if (shouldRegisterService("LWC")) {
getLogger().info("Registering LWC service.");
getServer().getServicesManager().register(
Protection.class, new LWCXProtection(this), this, ServicePriority.Normal
);
}
if (shouldRegisterService("Factions")) {
getLogger().info("Registering Factions service.");
getServer().getServicesManager().register(
Protection.class, new FactionsUUIDProtection(this), this, ServicePriority.Normal
);
}
if (shouldRegisterService("SuperiorSkyblock2")) {
getLogger().info("Registering SuperiorSkyblock2 service.");
getServer().getServicesManager().register(
Protection.class, new SuperiorSkyBlockProtection(this), this, ServicePriority.Normal
);
}
if (shouldRegisterService("Towny")) {
getLogger().info("Registering Towny service.");
getServer().getServicesManager().register(
Protection.class, new TownyProtection(this), this, ServicePriority.Normal
);
}
List<RegisteredServiceProvider<?>> registrations = getServer().getServicesManager().getRegistrations(this);
if (registrations.isEmpty()) {
getLogger().info("Registered 0 services. This plugin can be safely removed.");
} else {
getLogger().info("Successfully registered " + registrations.size() + " services.");
}
}
/**
@@ -63,4 +109,8 @@ public final class YardWatch extends JavaPlugin {
public void onDisable() {
getServer().getServicesManager().unregisterAll(this);
}
public static String getYardWatchApiVersion() {
return yardWatchApiVersion;
}
}
@@ -0,0 +1,110 @@
package me.youhavetrouble.yardwatch.commands;
import me.youhavetrouble.yardwatch.Protection;
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.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
public class YardWatchCommand implements TabExecutor {
private final YardWatch plugin;
private final String version;
public YardWatchCommand(YardWatch plugin) {
this.plugin = plugin;
this.version = plugin.getDescription().getVersion();
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (args.length == 0) {
sendDefault(sender);
return true;
}
if (args[0].equalsIgnoreCase("hooks")) {
sendHooks(sender);
return true;
} else if (args[0].equalsIgnoreCase("query")) {
queryProtection(sender);
return true;
}
return false;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
List<String> completions = new ArrayList<>();
if (args.length == 1) {
completions.add("hooks");
completions.add("query");
return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>());
}
return completions;
}
private void sendDefault(CommandSender sender) {
sender.sendMessage(String.format("YardWatch %s (Implementing YardWatch API %s)", version, YardWatch.getYardWatchApiVersion()));
}
private void sendHooks(CommandSender sender) {
Map<String, Integer> hooks = new HashMap<>();
Collection<RegisteredServiceProvider<Protection>> protections = plugin.getServer().getServicesManager().getRegistrations(Protection.class);
for (RegisteredServiceProvider<Protection> protection : protections) {
hooks.merge(protection.getPlugin().getName(), 1, Integer::sum);
}
if (hooks.isEmpty()) {
sender.sendMessage("No hooks registered.");
return;
}
sender.sendMessage("Hooks:");
for (Map.Entry<String, Integer> entry : hooks.entrySet()) {
String hook = entry.getValue() == 1 ? "hook" : "hooks";
sender.sendMessage(String.format("%s -> %s %s registered", entry.getKey(), entry.getValue(), hook));
}
}
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);
}
}
}
@@ -0,0 +1,93 @@
package me.youhavetrouble.yardwatch.hooks;
import com.bgsoftware.superiorskyblock.api.SuperiorSkyblockAPI;
import com.bgsoftware.superiorskyblock.api.island.BlockChangeResult;
import com.bgsoftware.superiorskyblock.api.island.Island;
import com.bgsoftware.superiorskyblock.api.island.IslandPrivilege;
import com.bgsoftware.superiorskyblock.api.wrappers.SuperiorPlayer;
import me.youhavetrouble.yardwatch.Protection;
import me.youhavetrouble.yardwatch.YardWatch;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.banner.PatternType;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
public class SuperiorSkyBlockProtection implements Protection {
private final YardWatch plugin;
public SuperiorSkyBlockProtection(YardWatch plugin) {
this.plugin = plugin;
}
@Override
public boolean isEnabled() {
return this.plugin.getServer().getPluginManager().isPluginEnabled("SuperiorSkyblock2");
}
@Override
public boolean isProtected(Location location) {
if (!isEnabled()) return false;
Island island = SuperiorSkyblockAPI.getIslandAt(location);
return island != null;
}
@Override
public boolean canBreakBlock(Player player, BlockState blockState) {
if (!isEnabled()) return true;
Location location = blockState.getLocation();
Island island = SuperiorSkyblockAPI.getIslandAt(location);
return island == null || island.hasPermission(player, IslandPrivilege.getByName("BREAK"));
}
@Override
public boolean canPlaceBlock(Player player, Location location) {
if (!isEnabled()) return true;
Island island = SuperiorSkyblockAPI.getIslandAt(location);
return island == null || island.hasPermission(player, IslandPrivilege.getByName("INTERACT"));
}
@Override
public boolean canInteract(Player player, BlockState blockState) {
if (!isEnabled()) return true;
Location location = blockState.getLocation();
Island island = SuperiorSkyblockAPI.getIslandAt(location);
return island == null || island.hasPermission(player, IslandPrivilege.getByName("INTERACT"));
}
@Override
public boolean canInteract(Player player, Entity target) {
if (!isEnabled()) return true;
Location location = target.getLocation();
Island island = SuperiorSkyblockAPI.getIslandAt(location);
return island == null || island.hasPermission(player, IslandPrivilege.getByName("INTERACT")) || island.hasPermission(player, IslandPrivilege.getByName("USE"));
}
@Override
public boolean canDamage(Entity damager, Entity target) {
if (!isEnabled()) return true;
if (!(damager instanceof Player attacker)) return true;
Location location = target.getLocation();
Island island = SuperiorSkyblockAPI.getIslandAt(location);
return island == null || island.hasPermission(attacker, IslandPrivilege.getByName("INTERACT"));
}
}
@@ -0,0 +1,80 @@
package me.youhavetrouble.yardwatch.hooks;
import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownBlock;
import com.palmergames.bukkit.towny.object.TownyPermission;
import com.palmergames.bukkit.towny.utils.CombatUtil;
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;
public class TownyProtection implements Protection {
private final YardWatch plugin;
private final TownyAPI api;
public TownyProtection(YardWatch plugin) {
this.plugin = plugin;
this.api = TownyAPI.getInstance();
}
@Override
public boolean isEnabled() {
return this.plugin.getServer().getPluginManager().isPluginEnabled("Towny");
}
@Override
public boolean isProtected(Location location) {
if (!isEnabled()) return false;
TownBlock town = this.api.getTownBlock(location);
return town != null;
}
@Override
public boolean canBreakBlock(Player player, BlockState blockState) {
return canInteract(player, blockState);
}
@Override
public boolean canPlaceBlock(Player player, Location location) {
return canInteract(player, location.getBlock().getState(true));
}
@Override
public boolean canInteract(Player player, BlockState blockState) {
if (!isEnabled()) return true;
Location location = blockState.getLocation();
TownBlock town = this.api.getTownBlock(location);
Resident resident = this.api.getResident(player.getUniqueId());
return town == null || town.hasResident(resident) || town.hasTrustedResident(resident);
}
@Override
public boolean canInteract(Player player, Entity target) {
return canInteract(player, target.getLocation().getBlock().getState(true));
}
@Override
public boolean canDamage(Entity damager, Entity target) {
if (!isEnabled()) return true;
if (!(damager instanceof Player)) return true;
Location location = target.getLocation();
TownBlock town = this.api.getTownBlock(location);
return town == null || CombatUtil.preventPvP(town.getWorld(), town);
}
}
@@ -4,6 +4,8 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
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.regions.RegionContainer;
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);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
return query.testBuild(wgLocation, null);
return query.testBuild(wgLocation, Associables.constant(Association.NON_MEMBER));
}
@Override
+1
View File
@@ -0,0 +1 @@
${yardwatch.api.version}
+9
View File
@@ -12,3 +12,12 @@ softdepend:
- "GriefPrevention"
- "Towny"
- "Factions"
- "SuperiorSkyblock2"
- "LWC"
commands:
yardwatch:
description: "YardWatch command"
usage: "/yardwatch <arg>"
permission: "yardwatch.command"
aliases:
- "yw"