diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java index e3b188055..4ef6d63ab 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/SimpleClans.java @@ -10,6 +10,7 @@ import net.sacredlabyrinth.phaed.simpleclans.managers.*; import net.sacredlabyrinth.phaed.simpleclans.migrations.BbMigration; import net.sacredlabyrinth.phaed.simpleclans.migrations.ChatFormatMigration; +import net.sacredlabyrinth.phaed.simpleclans.migrations.IgnoredListMigration; import net.sacredlabyrinth.phaed.simpleclans.migrations.LanguageMigration; import net.sacredlabyrinth.phaed.simpleclans.proxy.BungeeManager; import net.sacredlabyrinth.phaed.simpleclans.proxy.ProxyManager; @@ -102,6 +103,7 @@ public void onEnable() { new LanguageMigration(this).migrate(); settingsManager = new SettingsManager(this); new BbMigration(settingsManager); + new IgnoredListMigration(settingsManager); new ChatFormatMigration(settingsManager); languageResource = new LanguageResource(); this.hasUUID = UUIDMigration.canReturnUUID(); diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java index 0b4b7d2ab..61f92e07b 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/listeners/LandProtection.java @@ -63,10 +63,7 @@ public LandProtection(@NotNull SimpleClans plugin) { public void registerListeners() { registerListener(BlockBreakEvent.class, (event, cancel) -> { Block block = event.getBlock(); - if (settingsManager.getIgnoredList(BREAK).contains(block.getType().name())) { - return; - } - if (protectionManager.can(BREAK, block.getLocation(), event.getPlayer())) { + if (protectionManager.can(BREAK, block.getLocation(), event.getPlayer(), block, null)) { event.setCancelled(cancel); } }); @@ -98,27 +95,18 @@ public void registerListeners() { }); registerListener(BlockPlaceEvent.class, (event, cancel) -> { Block block = event.getBlock(); - if (settingsManager.getIgnoredList(PLACE).contains(block.getType().name())) { - return; - } - if (protectionManager.can(PLACE, block.getLocation(), event.getPlayer())) { + if (protectionManager.can(PLACE, block.getLocation(), event.getPlayer(), block, null)) { event.setCancelled(cancel); } }); registerListener(PlayerBucketEmptyEvent.class, (event, cancel) -> { Block block = event.getBlockClicked(); - if (settingsManager.getIgnoredList(PLACE).contains(block.getType().name())) { - return; - } if (protectionManager.can(PLACE, block.getLocation(), event.getPlayer())) { event.setCancelled(cancel); } }); registerListener(PlayerBucketFillEvent.class, (event, cancel) -> { Block block = event.getBlockClicked().getRelative(event.getBlockFace()); - if (settingsManager.getIgnoredList(BREAK).contains(block.getType().name())) { - return; - } if (protectionManager.can(BREAK, block.getLocation(), event.getPlayer())) { event.setCancelled(cancel); } @@ -148,7 +136,7 @@ public void registerListeners() { if (victim == null) { return; } - if (protectionManager.can(DAMAGE, event.getEntity().getLocation(), attacker, victim)) { + if (protectionManager.can(DAMAGE, event.getEntity().getLocation(), attacker, null, victim)) { event.setCancelled(cancel); } }); @@ -231,7 +219,7 @@ public void registerCreateLandEvent(ProtectionProvider provider, @Nullable Class } for (ClanPlayer member : clan.getMembers()) { Set lands = protectionManager.getLandsOf(Bukkit.getOfflinePlayer(member.getUniqueId()), player.getWorld()); - if (lands.size() > 0) { + if (!lands.isEmpty()) { cancelWithMessage(player, event, "only.one.land.per.clan"); return; } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java index 014f7a348..d483960c8 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/ProtectionManager.java @@ -13,6 +13,7 @@ import org.bukkit.Location; import org.bukkit.OfflinePlayer; import org.bukkit.World; +import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; @@ -26,6 +27,8 @@ import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.debug; import static net.sacredlabyrinth.phaed.simpleclans.SimpleClans.lang; import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.ConfigField.*; +import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.IgnoredType.LAND; +import static net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager.IgnoredType.WAR; public class ProtectionManager { @@ -104,10 +107,22 @@ public Set getLandsOf(@NotNull OfflinePlayer player, @NotNull World world) } public boolean can(@NotNull Action action, @NotNull Location location, @NotNull Player player) { - return can(action, location, player, null); + return can(action, location, player, null, null); } - public boolean can(@NotNull Action action, @NotNull Location location, @NotNull Player player, @Nullable Player other) { + /** + * Checks if the specified action is allowed at the given location for the players involved. + * + * @param action The action to be performed. + * @param location The location where the action is to be performed. + * @param player The player performing the action. + * @param involvedBlock the block involved in the action (can be null). + * @param other The other player involved in the action (can be null). + * @return true if the action is allowed, false otherwise. + * @see Action + */ + public boolean can(@NotNull Action action, @NotNull Location location, + @NotNull Player player, @Nullable Block involvedBlock, @Nullable Player other) { for (Land land : getLandsAt(location)) { for (UUID owner : land.getOwners()) { if (owner == null) { @@ -119,8 +134,8 @@ public boolean can(@NotNull Action action, @NotNull Location location, @NotNull } else { involved = player; } - if (isWarringAndAllowed(action, owner, involved) || - isSameClanAndAllowed(action, owner, involved, land.getId())) { + if (isWarringAndAllowed(action, owner, involved, involvedBlock) || + isSameClanAndAllowed(action, owner, involved, land.getId(), involvedBlock)) { return true; } } @@ -213,10 +228,12 @@ private void clearWars() { } } - private boolean isSameClanAndAllowed(Action action, UUID owner, Player involved, String landId) { - if (!settingsManager.is(LAND_SHARING)) { + private boolean isSameClanAndAllowed(Action action, UUID owner, Player involved, String landId, @Nullable Block block) { + if (!settingsManager.is(LAND_SHARING) || + block != null && settingsManager.ignoredIn(LAND, action, block)) { return false; } + ClanPlayer cp = clanManager.getCreateClanPlayer(owner); Clan involvedClan = clanManager.getClanByPlayerUniqueId(involved.getUniqueId()); if (cp.getClan() == null || !cp.getClan().equals(involvedClan)) { @@ -225,10 +242,12 @@ private boolean isSameClanAndAllowed(Action action, UUID owner, Player involved, return cp.isAllowed(action, landId); } - private boolean isWarringAndAllowed(@NotNull Action action, @NotNull UUID owner, @NotNull Player involved) { - if (!settingsManager.isActionAllowedInWar(action) || !settingsManager.is(ENABLE_WAR)) { + private boolean isWarringAndAllowed(@NotNull Action action, @NotNull UUID owner, @NotNull Player involved, @Nullable Block block) { + if (!settingsManager.isActionAllowedInWar(action) || !settingsManager.is(ENABLE_WAR) + || block != null && settingsManager.ignoredIn(WAR, action, block)) { return false; } + Clan ownerClan = clanManager.getClanByPlayerUniqueId(owner); Clan involvedClan = clanManager.getClanByPlayerUniqueId(involved.getUniqueId()); if (ownerClan == null || involvedClan == null) { @@ -246,7 +265,7 @@ private void registerProviders() { } catch (ClassNotFoundException ex) { logger.log(Level.WARNING, String.format("Provider %s not found!", className), ex); } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | - IllegalAccessException ex) { + IllegalAccessException ex) { logger.log(Level.WARNING, String.format("Error instantiating provider %s", className), ex); } if (instance instanceof ProtectionProvider) { diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java index 0c75c9147..a2c692e1d 100644 --- a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/managers/SettingsManager.java @@ -5,6 +5,8 @@ import net.sacredlabyrinth.phaed.simpleclans.SimpleClans; import net.sacredlabyrinth.phaed.simpleclans.utils.ChatUtils; import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.plugin.Plugin; @@ -235,10 +237,25 @@ public boolean isActionAllowedInWar(@NotNull ProtectionManager.Action action) { return is(ConfigField.valueOf("WAR_ACTIONS_" + action.name())); } + @Deprecated public List getIgnoredList(@NotNull ProtectionManager.Action action) { return getStringList(ConfigField.valueOf("WAR_LISTENERS_IGNORED_LIST_" + action.name())); } + public boolean ignoredIn(IgnoredType type, @NotNull ProtectionManager.Action action, @NotNull Block block) { + ConfigField configField = valueOf(type.name() + "_LISTENERS_IGNORED_LISTS"); + ConfigurationSection section = getConfig().getConfigurationSection(configField.path + "." + action.name()); + if (section == null) { + return false; + } + + if (section.getBoolean("invert")) { + return section.getStringList("blocks").contains(block.getType().name()); + } else { + return !section.getStringList("blocks").contains(block.getType().name()); + } + } + @NotNull public RankingType getRankingType() { try { @@ -341,8 +358,12 @@ public enum ConfigField { LAND_SHARING("war-and-protection.land-sharing", true), LAND_PROTECTION_PROVIDERS("war-and-protection.protection-providers"), WAR_LISTENERS_PRIORITY("war-and-protection.listeners.priority", "HIGHEST"), + @Deprecated WAR_LISTENERS_IGNORED_LIST_PLACE("war-and-protection.listeners.ignored-list.PLACE"), + @Deprecated WAR_LISTENERS_IGNORED_LIST_BREAK("war-and-protection.listeners.ignored-list.BREAK"), + WAR_LISTENERS_IGNORED_LISTS("war-and-protection.listeners.ignored-lists.war"), + LAND_LISTENERS_IGNORED_LISTS("war-and-protection.listeners.ignored-lists.land"), LAND_SET_BASE_ONLY_IN_LAND("war-and-protection.set-base-only-in-land", false), WAR_NORMAL_EXPIRATION_TIME("war-and-protection.war-normal-expiration-time", 0), WAR_DISCONNECT_EXPIRATION_TIME("war-and-protection.war-disconnect-expiration-time", 0), @@ -607,4 +628,8 @@ public enum ConfigField { defaultValue = null; } } + + public enum IgnoredType { + WAR, LAND + } } diff --git a/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/IgnoredListMigration.java b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/IgnoredListMigration.java new file mode 100644 index 000000000..45983f6b4 --- /dev/null +++ b/src/main/java/net/sacredlabyrinth/phaed/simpleclans/migrations/IgnoredListMigration.java @@ -0,0 +1,17 @@ +package net.sacredlabyrinth.phaed.simpleclans.migrations; + +import net.sacredlabyrinth.phaed.simpleclans.managers.SettingsManager; + +public class IgnoredListMigration extends ConfigMigration { + + public IgnoredListMigration(SettingsManager settingsManager) { + super(settingsManager); + } + + @Override + public void migrate() { + if (config.contains("war-and-protection.listeners.ignored-list")) { + config.set("war-and-protection.listeners.ignored-list", null); + } + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index eb88d3b30..e51f43e58 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -66,11 +66,25 @@ war-and-protection: - GriefPreventionProvider listeners: priority: HIGHEST - ignored-list: - PLACE: - - "PLAYER_HEAD" - BREAK: - - "EMERALD_BLOCK" + ignored-lists: + land: + PLACE: + invert: false + blocks: + - "PLAYER_HEAD" + BREAK: + invert: true + blocks: + - "EMERALD_BLOCK" + war: + PLACE: + invert: false + blocks: + - "PLAYER_HEAD" + BREAK: + invert: true + blocks: + - "EMERALD_BLOCK" set-base-only-in-land: false war-normal-expiration-time: 0 war-disconnect-expiration-time: 0