diff --git a/dough-protection/pom.xml b/dough-protection/pom.xml index fa2e72ee..1b41349a 100644 --- a/dough-protection/pom.xml +++ b/dough-protection/pom.xml @@ -63,6 +63,10 @@ william278-repo https://repo.william278.net/snapshots/ + + towny-repo + https://repo.glaremasters.me/repository/towny/ + @@ -157,9 +161,9 @@ - com.github.LlmDl - Towny - 1b86d017c5 + com.palmergames.bukkit.towny + towny + 0.100.3.0 provided @@ -282,6 +286,14 @@ 1.0.580 provided + + + + com.github.jwkerr + Quarters + e9ed8a133a + provided + diff --git a/dough-protection/src/main/java/io/github/bakedlibs/dough/protection/ProtectionManager.java b/dough-protection/src/main/java/io/github/bakedlibs/dough/protection/ProtectionManager.java index bebd5b33..b6acf920 100644 --- a/dough-protection/src/main/java/io/github/bakedlibs/dough/protection/ProtectionManager.java +++ b/dough-protection/src/main/java/io/github/bakedlibs/dough/protection/ProtectionManager.java @@ -9,6 +9,7 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import io.github.bakedlibs.dough.protection.modules.*; import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.block.Block; @@ -18,24 +19,6 @@ import io.github.bakedlibs.dough.common.DoughLogger; import io.github.bakedlibs.dough.protection.loggers.CoreProtectLogger; import io.github.bakedlibs.dough.protection.loggers.LogBlockLogger; -import io.github.bakedlibs.dough.protection.modules.BentoBoxProtectionModule; -import io.github.bakedlibs.dough.protection.modules.BlockLockerProtectionModule; -import io.github.bakedlibs.dough.protection.modules.BoltProtectionModule; -import io.github.bakedlibs.dough.protection.modules.ChestProtectProtectionModule; -import io.github.bakedlibs.dough.protection.modules.FactionsUUIDProtectionModule; -import io.github.bakedlibs.dough.protection.modules.FunnyGuildsProtectionModule; -import io.github.bakedlibs.dough.protection.modules.GriefPreventionProtectionModule; -import io.github.bakedlibs.dough.protection.modules.HuskTownsProtectionModule; -import io.github.bakedlibs.dough.protection.modules.HuskClaimsProtectionModule; -import io.github.bakedlibs.dough.protection.modules.LWCProtectionModule; -import io.github.bakedlibs.dough.protection.modules.LandsProtectionModule; -import io.github.bakedlibs.dough.protection.modules.LocketteProtectionModule; -import io.github.bakedlibs.dough.protection.modules.PlotSquaredProtectionModule; -import io.github.bakedlibs.dough.protection.modules.PreciousStonesProtectionModule; -import io.github.bakedlibs.dough.protection.modules.RedProtectProtectionModule; -import io.github.bakedlibs.dough.protection.modules.ShopChestProtectionModule; -import io.github.bakedlibs.dough.protection.modules.TownyProtectionModule; -import io.github.bakedlibs.dough.protection.modules.WorldGuardProtectionModule; /** * This Class provides a nifty API for plugins to query popular protection plugins. @@ -80,7 +63,6 @@ private void loadModuleImplementations(Plugin plugin) { // We sadly cannot use ModuleName::new as this would load the class into memory prematurely registerModule(pm, "WorldGuard", worldGuard -> new WorldGuardProtectionModule(worldGuard)); - registerModule(pm, "Towny", towny -> new TownyProtectionModule(towny)); registerModule(pm, "GriefPrevention", griefPrevention -> new GriefPreventionProtectionModule(griefPrevention)); registerModule(pm, "LWC", lwc -> new LWCProtectionModule(lwc)); registerModule(pm, "PreciousStones", preciousStones -> new PreciousStonesProtectionModule(preciousStones)); @@ -98,6 +80,13 @@ private void loadModuleImplementations(Plugin plugin) { registerModule(pm, "HuskClaims", huskClaims -> new HuskClaimsProtectionModule(huskClaims)); registerModule(pm, "Bolt", bolt -> new BoltProtectionModule(bolt)); + // If Quarters is installed, the QuartersProtectionModule must be enabled instead of the Towny module. + if (pm.isPluginEnabled("Quarters")) { + registerModule(pm, "Quarters", quarters -> new QuartersProtectionModule(quarters)); + } else { + registerModule(pm, "Towny", towny -> new TownyProtectionModule(towny)); + } + /* * The following Plugins work by utilising one of the above listed * Plugins in the background. diff --git a/dough-protection/src/main/java/io/github/bakedlibs/dough/protection/modules/QuartersProtectionModule.java b/dough-protection/src/main/java/io/github/bakedlibs/dough/protection/modules/QuartersProtectionModule.java new file mode 100644 index 00000000..f69e94e1 --- /dev/null +++ b/dough-protection/src/main/java/io/github/bakedlibs/dough/protection/modules/QuartersProtectionModule.java @@ -0,0 +1,107 @@ +package io.github.bakedlibs.dough.protection.modules; + +import au.lupine.quarters.api.manager.QuarterManager; +import au.lupine.quarters.object.entity.Quarter; +import com.palmergames.bukkit.towny.TownyAPI; +import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.TownyPermission.ActionType; +import com.palmergames.bukkit.towny.utils.PlayerCacheUtil; +import io.github.bakedlibs.dough.protection.Interaction; +import io.github.bakedlibs.dough.protection.ProtectionModule; +import org.bukkit.Location; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import javax.annotation.Nonnull; + + +/** + * Protection handling module for Quarters, a Towny add-on. + * If Quarters is installed on a server, this module must be registered + * instead of the Towny module. + * + * @author galacticwarrior9 + */ +public class QuartersProtectionModule implements ProtectionModule { + + private final Plugin plugin; + + public QuartersProtectionModule(@Nonnull Plugin plugin) { + this.plugin = plugin; + } + + @Override + public Plugin getPlugin() { + return plugin; + } + + @Override + public void load() { + // We don't need to load any APIs, everything is static + } + + @Override + public boolean hasPermission(OfflinePlayer p, Location l, Interaction action) { + if (!(p instanceof Player)) { + return false; + } + return isInteractionAllowed((Player) p, convert(action), l); + } + + private boolean isInteractionAllowed(Player player, ActionType type, Location l) { + boolean allowedInUnderlyingPlot = PlayerCacheUtil.getCachePermission(player, l, l.getBlock().getType(), type); + Quarter quarter = QuarterManager.getInstance().getQuarter(l); + if (quarter == null) { + return allowedInUnderlyingPlot; + } + + Resident resident = TownyAPI.getInstance().getResident(player.getUniqueId()); + if (resident == null) { + return true; + } + + return quarter.testPermission(convertToQuartersAction(type), resident); + } + + /** + * Returns the corresponding Towny {@link ActionType} from the dough {@link Interaction} + * + * @param action The dough {@link Interaction} + * @return The corresponding Towny {@link ActionType} + */ + private ActionType convert(Interaction action) { + switch (action) { + case INTERACT_BLOCK: + return ActionType.SWITCH; + case INTERACT_ENTITY: + case ATTACK_PLAYER: + case ATTACK_ENTITY: + return ActionType.ITEM_USE; + case BREAK_BLOCK: + return ActionType.DESTROY; + case PLACE_BLOCK: + default: + return ActionType.BUILD; + } + } + + /** + * Returns the corresponding Quarters {@link au.lupine.quarters.object.state.ActionType} from the Towny {@link ActionType} + * + * @param action The Towny {@link ActionType} + * @return The corresponding Quarters {@link au.lupine.quarters.object.state.ActionType} + */ + private au.lupine.quarters.object.state.ActionType convertToQuartersAction(ActionType action) { + switch (action) { + case DESTROY: + return au.lupine.quarters.object.state.ActionType.DESTROY; + case ITEM_USE: + return au.lupine.quarters.object.state.ActionType.ITEM_USE; + case SWITCH: + return au.lupine.quarters.object.state.ActionType.SWITCH; + default: + return au.lupine.quarters.object.state.ActionType.BUILD; + } + } +}