From 26a9e4eba808d759c3c1e41277f56df02bee1dbf Mon Sep 17 00:00:00 2001 From: Driftay Date: Tue, 14 May 2019 22:07:59 -0400 Subject: [PATCH] Added alot --- .../java/com/massivecraft/factions/Conf.java | 1 + .../com/massivecraft/factions/Faction.java | 4 + .../factions/cmd/CmdSetStrikes.java | 83 ++ .../massivecraft/factions/cmd/CmdShow.java | 1 + .../massivecraft/factions/cmd/CmdStrike.java | 52 + .../massivecraft/factions/cmd/FCmdRoot.java | 10 +- .../listeners/FactionsBlockListener.java | 1007 +++++++++-------- .../factions/struct/Permission.java | 2 + .../factions/zcore/persist/MemoryFaction.java | 9 + .../massivecraft/factions/zcore/util/TL.java | 14 + .../factions/zcore/util/TagReplacer.java | 5 + src/main/resources/config.yml | 21 + 12 files changed, 735 insertions(+), 474 deletions(-) create mode 100644 src/main/java/com/massivecraft/factions/cmd/CmdSetStrikes.java create mode 100644 src/main/java/com/massivecraft/factions/cmd/CmdStrike.java diff --git a/src/main/java/com/massivecraft/factions/Conf.java b/src/main/java/com/massivecraft/factions/Conf.java index c44342f2..47435bfb 100644 --- a/src/main/java/com/massivecraft/factions/Conf.java +++ b/src/main/java/com/massivecraft/factions/Conf.java @@ -81,6 +81,7 @@ public class Conf { public static String truceChatFormat = ChatColor.DARK_PURPLE + "%s:" + ChatColor.WHITE + " %s"; public static String modChatFormat = ChatColor.RED + "%s:" + ChatColor.WHITE + " %s"; public static int stealthFlyCheckRadius = 32; + public static boolean gracePeriod = false; public static boolean noEnderpearlsInFly = false; public static boolean broadcastDescriptionChanges = false; public static boolean broadcastTagChanges = false; diff --git a/src/main/java/com/massivecraft/factions/Faction.java b/src/main/java/com/massivecraft/factions/Faction.java index 6467f7dc..f8d69bab 100644 --- a/src/main/java/com/massivecraft/factions/Faction.java +++ b/src/main/java/com/massivecraft/factions/Faction.java @@ -73,6 +73,10 @@ public interface Faction extends EconomyParticipator { void ban(FPlayer target, FPlayer banner); + int getStrikes(); + + void setStrikes(int strikes); + void unban(FPlayer player); boolean isBanned(FPlayer player); diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdSetStrikes.java b/src/main/java/com/massivecraft/factions/cmd/CmdSetStrikes.java new file mode 100644 index 00000000..3bf37f4c --- /dev/null +++ b/src/main/java/com/massivecraft/factions/cmd/CmdSetStrikes.java @@ -0,0 +1,83 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.FPlayers; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdSetStrikes extends FCommand { + + + public CmdSetStrikes() { + super(); + this.aliases.add("setstrikes"); + this.aliases.add("setstrike"); + + this.requiredArgs.add("set,give,remove"); + this.requiredArgs.add("faction"); + this.requiredArgs.add("# of strikes"); + this.requiredArgs.add("reason"); + + + this.errorOnToManyArgs = false; + //this.optionalArgs + + this.permission = Permission.SETSTRIKES.node; + + this.disableOnLock = true; + + senderMustBePlayer = false; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeColeader = false; + senderMustBeAdmin = false; + } + + + @Override + public void perform() { + Faction faction = Factions.getInstance().getByTag(args.get(1)); + boolean success = false; + if (faction == null) { + fme.msg(TL.COMMAND_SETSTRIKES_FAILURE.toString().replace("{faction}", args.get(1))); + } + if (args.get(0).equalsIgnoreCase("set")) { + faction.setStrikes(argAsInt(2)); + success = true; + } else if (args.get(0).equalsIgnoreCase("give")) { + faction.setStrikes(faction.getStrikes() + argAsInt(2)); + success = true; + } else if (args.get(0).equalsIgnoreCase("take")) { + faction.setStrikes(faction.getStrikes() - argAsInt(2)); + success = true; + } + if (success) { + for (FPlayer fPlayer : FPlayers.getInstance().getOnlinePlayers()) { + fPlayer.msg(TL.COMMAND_SETSTRIKES_BROADCAST.toString() + .replace("{faction}", faction.getTag()) + .replace("{reason}", getReason())); + } + fme.msg(TL.COMMAND_SETSTRIKES_SUCCESS.toString() + .replace("{faction}", faction.getTag()) + .replace("{strikes}", faction.getStrikes() + "")); + } + } + + private String getReason() { + String reason = ""; + for (int i = 3; i < args.size(); i++) { + reason += args.get(i) + " "; + } + return reason; + } + + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_SETSTRIKES_DESCRIPTION; + } + + +} diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdShow.java b/src/main/java/com/massivecraft/factions/cmd/CmdShow.java index ee437b55..ffc547b2 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdShow.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdShow.java @@ -25,6 +25,7 @@ public class CmdShow extends FCommand { defaults.add("Description: {description}"); defaults.add("Joining: {joining} {peaceful}"); defaults.add("Land / Power / Maxpower: {chunks} / {power} / {maxPower}"); + defaults.add("Faction Strikes: {strikes}"); defaults.add("Founded: {create-date}"); defaults.add("This faction is permanent, remaining even with no members."); defaults.add("Land value: {land-value} {land-refund}"); diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdStrike.java b/src/main/java/com/massivecraft/factions/cmd/CmdStrike.java new file mode 100644 index 00000000..b68ff79b --- /dev/null +++ b/src/main/java/com/massivecraft/factions/cmd/CmdStrike.java @@ -0,0 +1,52 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.Factions; +import com.massivecraft.factions.zcore.util.TL; + +public class CmdStrike extends FCommand { + + + public CmdStrike() { + super(); + + this.aliases.add("strike"); + this.aliases.add("strikes"); + + this.optionalArgs.put("faction", "tag"); + + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeAdmin = false; + } + + + @Override + public void perform() { + if (args.size() == 0) { + if (myFaction.isWilderness()) { + fme.msg(TL.COMMAND_STRIKE_NEEDFACTION); + return; + } + fme.msg(TL.COMMAND_STRIKE_MESSAGE.toString().replace("{faction}", fme.getFaction().getTag()).replace("{strikes}", fme.getFaction().getStrikes() + "")); + return; + } + Faction faction = Factions.getInstance().getByTag(args.get(0)); + if (faction != null) { + fme.msg(TL.COMMAND_STRIKE_MESSAGE.toString().replace("{faction}", faction.getTag()).replace("{strikes}", faction.getStrikes() + "")); + } else { + fme.msg(TL.COMMAND_STRIKE_NOTFOUND.toString().replace("{faction}", args.get(0))); + } + } + + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_STUCK_DESCRIPTION; + } + + +} diff --git a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java index e94b5b6f..6945656a 100644 --- a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java +++ b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java @@ -23,6 +23,7 @@ public class FCmdRoot extends FCommand { public CmdDescription cmdDescription = new CmdDescription(); public CmdDisband cmdDisband = new CmdDisband(); public CmdFocus cmdFocus = new CmdFocus(); + public CmdGrace cmdGrace = new CmdGrace(); public CmdHelp cmdHelp = new CmdHelp(); public CmdHome cmdHome = new CmdHome(); public CmdInvite cmdInvite = new CmdInvite(); @@ -104,6 +105,8 @@ public class FCmdRoot extends FCommand { public CmdTntFill cmdTntFill = new CmdTntFill(); public CmdChest cmdChest = new CmdChest(); public CmdSetBanner cmdSetBanner = new CmdSetBanner(); + public CmdStrike cmdStrike = new CmdStrike(); + public CmdSetStrikes cmdSetStrikes = new CmdSetStrikes(); public FCmdRoot() { @@ -140,7 +143,8 @@ public class FCmdRoot extends FCommand { this.addSubCommand(this.cmdDeinvite); this.addSubCommand(this.cmdDescription); this.addSubCommand(this.cmdDisband); - + this.addSubCommand(this.cmdStrike); + this.addSubCommand(this.cmdSetStrikes); this.addSubCommand(this.cmdHelp); this.addSubCommand(this.cmdHome); this.addSubCommand(this.cmdInvite); @@ -217,6 +221,10 @@ public class FCmdRoot extends FCommand { this.addSubCommand(this.cmdChest); this.addSubCommand(this.cmdSetBanner); + if (SavageFactions.plugin.getConfig().getBoolean("f-grace.Enabled")) { + this.addSubCommand(this.cmdGrace); + } + if (Bukkit.getServer().getPluginManager().getPlugin("CoreProtect") != null) { SavageFactions.plugin.log("Found CoreProtect, enabling Inspect"); diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java index 967b39f1..d945a696 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -22,6 +22,8 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.*; import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; @@ -33,477 +35,536 @@ import java.util.List; public class FactionsBlockListener implements Listener { - public static HashMap bannerLocations = new HashMap<>(); - private HashMap bannerCooldownMap = new HashMap<>(); - - public static boolean playerCanBuildDestroyBlock(Player player, Location location, String action, boolean justCheck) { - String name = player.getName(); - - if (Conf.playersWhoBypassAllProtection.contains(name)) - return true; - - FPlayer me = FPlayers.getInstance().getById(player.getUniqueId().toString()); - Faction myFaction = me.getFaction(); - if (me.isAdminBypassing()) - return true; - - FLocation loc = new FLocation(location); - Faction otherFaction = Board.getInstance().getFactionAt(loc); - - if (otherFaction.isWilderness()) { - if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) - return true; - - if (!Conf.wildernessDenyBuild || Conf.worldsNoWildernessProtection.contains(location.getWorld().getName())) - return true; // This is not faction territory. Use whatever you like here. - - if (!justCheck) - me.msg("You can't " + action + " in the wilderness."); - - return false; - } else if (otherFaction.isSafeZone()) { - if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) - return true; - - if (!Conf.safeZoneDenyBuild || Permission.MANAGE_SAFE_ZONE.has(player)) - return true; - - if (!justCheck) - me.msg("You can't " + action + " in a safe zone."); - - return false; - } else if (otherFaction.isWarZone()) { - if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) - return true; - - if (!Conf.warZoneDenyBuild || Permission.MANAGE_WAR_ZONE.has(player)) - return true; - - if (!justCheck) - me.msg("You can't " + action + " in a war zone."); - - return false; - } else if (!otherFaction.getId().equals(myFaction.getId())) { // If the faction target is not my own - if (SavageFactions.plugin.getConfig().getBoolean("hcf.raidable", false) && otherFaction.getLandRounded() > otherFaction.getPowerRounded()) - return true; - // Get faction pain build access relation to me - boolean pain = !justCheck && otherFaction.getAccess(me, PermissableAction.PAIN_BUILD) == Access.ALLOW; - return CheckActionState(otherFaction, loc, me, PermissableAction.fromString(action), pain); - } else if (otherFaction.getId().equals(myFaction.getId())) { - boolean pain = !justCheck && myFaction.getAccess(me, PermissableAction.PAIN_BUILD) == Access.ALLOW; - return CheckActionState(myFaction, loc, me, PermissableAction.fromString(action), pain); - } - - // Something failed prevent build - return false; - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onBlockPlace(BlockPlaceEvent event) { - if (!event.canBuild()) { - return; - } - - // special case for flint&steel, which should only be prevented by DenyUsage list - if (event.getBlockPlaced().getType() == Material.FIRE) { - return; - } - - if (!playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "build", false)) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onBlockFromTo(BlockFromToEvent event) { - if (!Conf.handleExploitLiquidFlow) { - return; - } - if (event.getBlock().isLiquid()) { - if (event.getToBlock().isEmpty()) { - Faction from = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); - Faction to = Board.getInstance().getFactionAt(new FLocation(event.getToBlock())); - if (from == to) { - // not concerned with inter-faction events - return; - } - // from faction != to faction - if (to.isNormal()) { - if (from.isNormal() && from.getRelationTo(to).isAlly()) { - return; - } - event.setCancelled(true); - } - } - } - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onBlockDamage(BlockDamageEvent event) { - if (event.getInstaBreak() && !playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "destroy", false)) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onBlockPistonExtend(BlockPistonExtendEvent event) { - if (!Conf.pistonProtectionThroughDenyBuild) { - return; - } - - Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); - - // target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air - Block targetBlock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1); - - // if potentially pushing into air/water/lava in another territory, we need to check it out - if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && !canPistonMoveBlock(pistonFaction, targetBlock.getLocation())) { - event.setCancelled(true); - } - - /* - * note that I originally was testing the territory of each affected block, but since I found that pistons can only push - * up to 12 blocks and the width of any territory is 16 blocks, it should be safe (and much more lightweight) to test - * only the final target block as done above - */ - } - - @EventHandler - public void onVaultPlace(BlockPlaceEvent e) { - if (e.getItemInHand().getType() == Material.CHEST) { - ItemStack vault = SavageFactions.plugin.createItem(Material.CHEST, 1, (short) 0, SavageFactions.plugin.color(SavageFactions.plugin.getConfig().getString("fvault.Item.Name")), SavageFactions.plugin.colorList(SavageFactions.plugin.getConfig().getStringList("fvault.Item.Lore"))); - if (e.getItemInHand().isSimilar(vault)) { - FPlayer fme = FPlayers.getInstance().getByPlayer(e.getPlayer()); - if (fme.getFaction().getVault() != null) { - fme.msg(TL.COMMAND_GETVAULT_ALREADYSET); - e.setCancelled(true); - return; - } - FLocation flocation = new FLocation(e.getBlockPlaced().getLocation()); - if (Board.getInstance().getFactionAt(flocation) != fme.getFaction()) { - fme.msg(TL.COMMAND_GETVAULT_INVALIDLOCATION); - e.setCancelled(true); - return; - } - Block start = e.getBlockPlaced(); - int radius = 1; - for (double x = start.getLocation().getX() - radius; x <= start.getLocation().getX() + radius; x++) { - for (double y = start.getLocation().getY() - radius; y <= start.getLocation().getY() + radius; y++) { - for (double z = start.getLocation().getZ() - radius; z <= start.getLocation().getZ() + radius; z++) { - Location blockLoc = new Location(e.getPlayer().getWorld(), x, y, z); - if (blockLoc.getX() == start.getLocation().getX() && blockLoc.getY() == start.getLocation().getY() && blockLoc.getZ() == start.getLocation().getZ()) { - continue; - } - - Material blockMaterial = blockLoc.getBlock().getType(); - - if (blockMaterial == Material.CHEST || (SavageFactions.plugin.getConfig().getBoolean("fvault.No-Hoppers-near-vault") && blockMaterial == Material.HOPPER)) { - e.setCancelled(true); - fme.msg(TL.COMMAND_GETVAULT_CHESTNEAR); - return; - } - } - } - } - - fme.msg(TL.COMMAND_GETVAULT_SUCCESS); - fme.getFaction().setVault(e.getBlockPlaced().getLocation()); - - } - } - } - - @EventHandler - public void onHopperPlace(BlockPlaceEvent e) { - - if (e.getItemInHand().getType() != Material.HOPPER && !SavageFactions.plugin.getConfig().getBoolean("fvault.No-Hoppers-near-vault")) { - return; - } - - Faction factionAt = Board.getInstance().getFactionAt(new FLocation(e.getBlockPlaced().getLocation())); - - if (factionAt.isWilderness() || factionAt.getVault() == null) { - return; - } - - - FPlayer fme = FPlayers.getInstance().getByPlayer(e.getPlayer()); - - Block start = e.getBlockPlaced(); - int radius = 1; - for (double x = start.getLocation().getX() - radius; x <= start.getLocation().getX() + radius; x++) { - for (double y = start.getLocation().getY() - radius; y <= start.getLocation().getY() + radius; y++) { - for (double z = start.getLocation().getZ() - radius; z <= start.getLocation().getZ() + radius; z++) { - Location blockLoc = new Location(e.getPlayer().getWorld(), x, y, z); - if (blockLoc.getX() == start.getLocation().getX() && blockLoc.getY() == start.getLocation().getY() && blockLoc.getZ() == start.getLocation().getZ()) { - continue; - } - - if (blockLoc.getBlock().getType() == Material.CHEST) { - if (factionAt.getVault().equals(blockLoc)) { - e.setCancelled(true); - fme.msg(TL.COMMAND_VAULT_NO_HOPPER); - return; - } - } - } - } - } - - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onBlockPistonRetract(BlockPistonRetractEvent event) { - // if not a sticky piston, retraction should be fine - if (!event.isSticky() || !Conf.pistonProtectionThroughDenyBuild) { - return; - } - - Location targetLoc = event.getRetractLocation(); - Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(targetLoc)); - - // Check if the piston is moving in a faction's territory. This disables pistons entirely in faction territory. - if (otherFaction.isNormal() && SavageFactions.plugin.getConfig().getBoolean("disable-pistons-in-territory", false)) { - event.setCancelled(true); - return; - } - - // if potentially retracted block is just air/water/lava, no worries - if (targetLoc.getBlock().isEmpty() || targetLoc.getBlock().isLiquid()) { - return; - } - - Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); - - if (!canPistonMoveBlock(pistonFaction, targetLoc)) { - event.setCancelled(true); - } - } - - @EventHandler - public void onBannerPlace(BlockPlaceEvent e) { - if (SavageFactions.plugin.mc17) { - return; - } - - if (e.getItemInHand().getType() == SavageFactions.plugin.BANNER) { - ItemStack bannerInHand = e.getItemInHand(); - FPlayer fme = FPlayers.getInstance().getByPlayer(e.getPlayer()); - ItemStack warBanner = fme.getFaction().getBanner(); - if (warBanner != null) { - ItemMeta warmeta = warBanner.getItemMeta(); - warmeta.setDisplayName(SavageFactions.plugin.color(SavageFactions.plugin.getConfig().getString("fbanners.Item.Name"))); - warmeta.setLore(SavageFactions.plugin.colorList(SavageFactions.plugin.getConfig().getStringList("fbanners.Item.Lore"))); - warBanner.setItemMeta(warmeta); - } else { - warBanner = SavageFactions.plugin.createItem(SavageFactions.plugin.BANNER, 1, (short) 1, SavageFactions.plugin.getConfig().getString("fbanners.Item.Name"), SavageFactions.plugin.getConfig().getStringList("fbanners.Item.Lore")); - } - if (warBanner.isSimilar(bannerInHand)) { - - if (fme.getFaction().isWilderness()) { - fme.msg(TL.WARBANNER_NOFACTION); - e.setCancelled(true); - return; - } - int bannerTime = SavageFactions.plugin.getConfig().getInt("fbanners.Banner-Time") * 20; - - Location placedLoc = e.getBlockPlaced().getLocation(); - FLocation fplacedLoc = new FLocation(placedLoc); - if ((Board.getInstance().getFactionAt(fplacedLoc).isWarZone() && SavageFactions.plugin.getConfig().getBoolean("fbanners.Placeable.Warzone")) - || (fme.getFaction().getRelationTo(Board.getInstance().getFactionAt(fplacedLoc)) == Relation.ENEMY) && SavageFactions.plugin.getConfig().getBoolean("fbanners.Placeable.Enemy")) { - if (bannerCooldownMap.containsKey(fme.getTag())) { - fme.msg(TL.WARBANNER_COOLDOWN); - e.setCancelled(true); - return; - } - for (FPlayer fplayer : fme.getFaction().getFPlayers()) { - // if (fplayer == fme) { continue; } //Idk if I wanna not send the title to the player - fplayer.getPlayer().sendTitle(SavageFactions.plugin.color(fme.getTag() + " Placed A WarBanner!"), SavageFactions.plugin.color("&7use &c/f tpbanner&7 to tp to the banner!"), 10, 70, 20); - } - - bannerCooldownMap.put(fme.getTag(), true); - bannerLocations.put(fme.getTag(), e.getBlockPlaced().getLocation()); - final int bannerCooldown = SavageFactions.plugin.getConfig().getInt("fbanners.Banner-Place-Cooldown"); - final ArmorStand as = (ArmorStand) e.getBlockPlaced().getLocation().add(0.5, 1, 0.5).getWorld().spawnEntity(e.getBlockPlaced().getLocation().add(0.5, 1, 0.5), EntityType.ARMOR_STAND); //Spawn the ArmorStand - as.setVisible(false); //Makes the ArmorStand invisible - as.setGravity(false); //Make sure it doesn't fall - as.setCanPickupItems(false); //I'm not sure what happens if you leave this as it is, but you might as well disable it - as.setCustomName(SavageFactions.plugin.color(SavageFactions.plugin.getConfig().getString("fbanners.BannerHolo").replace("{Faction}", fme.getTag()))); //Set this to the text you want - as.setCustomNameVisible(true); //This makes the text appear no matter if your looking at the entity or not - final ArmorStand armorStand = as; - final String tag = fme.getTag(); - Bukkit.getScheduler().scheduleSyncDelayedTask(SavageFactions.plugin, () -> bannerCooldownMap.remove(tag), Long.parseLong(bannerCooldown + "")); - final Block banner = e.getBlockPlaced(); - final Material bannerType = banner.getType(); - final Faction bannerFaction = fme.getFaction(); - banner.getWorld().strikeLightningEffect(banner.getLocation()); - // e.getPlayer().getWorld().playSound(e.getPlayer().getLocation(), Sound.ENTITY_LIGHTNING_IMPACT,2.0F,0.5F); - final int radius = SavageFactions.plugin.getConfig().getInt("fbanners.Banner-Effect-Radius"); - final List effects = SavageFactions.plugin.getConfig().getStringList("fbanners.Effects"); - final int affectorTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(SavageFactions.plugin, () -> { - - for (Entity e1 : banner.getLocation().getWorld().getNearbyEntities(banner.getLocation(), radius, 255, radius)) { - if (e1 instanceof Player) { - Player player = (Player) e1; - FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); - if (fplayer.getFaction() == bannerFaction) { - for (String effect : effects) { - String[] components = effect.split(":"); - player.addPotionEffect(new PotionEffect(PotionEffectType.getByName(components[0]), 100, Integer.parseInt(components[1]))); - } - ParticleEffect.LAVA.display(1, 1, 1, 1, 10, banner.getLocation(), 16); - ParticleEffect.FLAME.display(1, 1, 1, 1, 10, banner.getLocation(), 16); - - if (banner.getType() != bannerType) { - banner.setType(bannerType); - } - } - } - } - }, 0L, 20L); - Bukkit.getScheduler().scheduleSyncDelayedTask(SavageFactions.plugin, () -> { - banner.setType(Material.AIR); - as.remove(); - banner.getWorld().strikeLightningEffect(banner.getLocation()); - Bukkit.getScheduler().cancelTask(affectorTask); - bannerLocations.remove(bannerFaction.getTag()); - }, Long.parseLong(bannerTime + "")); - } else { - fme.msg(TL.WARBANNER_INVALIDLOC); - e.setCancelled(true); - } - } - } - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onFrostWalker(EntityBlockFormEvent event) { - if (event.getEntity() == null || event.getEntity().getType() != EntityType.PLAYER || event.getBlock() == null) { - return; - } - - Player player = (Player) event.getEntity(); - Location location = event.getBlock().getLocation(); - - // only notify every 10 seconds - FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); - boolean justCheck = fPlayer.getLastFrostwalkerMessage() + 10000 > System.currentTimeMillis(); - if (!justCheck) { - fPlayer.setLastFrostwalkerMessage(); - } - - // Check if they have build permissions here. If not, block this from happening. - if (!playerCanBuildDestroyBlock(player, location, "frostwalk", justCheck)) { - event.setCancelled(true); - } - } - - private boolean canPistonMoveBlock(Faction pistonFaction, Location target) { - - Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(target)); - - if (pistonFaction == otherFaction) { - return true; - } - - if (otherFaction.isWilderness()) { - return !Conf.wildernessDenyBuild || Conf.worldsNoWildernessProtection.contains(target.getWorld().getName()); - - } else if (otherFaction.isSafeZone()) { - return !Conf.safeZoneDenyBuild; - - } else if (otherFaction.isWarZone()) { - return !Conf.warZoneDenyBuild; - - } - - Relation rel = pistonFaction.getRelationTo(otherFaction); - - return !rel.confDenyBuild(otherFaction.hasPlayersOnline()); - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onBlockBreak(BlockBreakEvent event) { - if (!playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "destroy", false)) { - event.setCancelled(true); - return; - } - FPlayer fme = FPlayers.getInstance().getByPlayer(event.getPlayer()); - if (!fme.hasFaction()) { - return; - } - if (event.getBlock().getType() == SavageFactions.plugin.MOB_SPANWER) { - if (!fme.isAdminBypassing()) { - Access access = fme.getFaction().getAccess(fme, PermissableAction.SPAWNER); - if (access != Access.ALLOW && fme.getRole() != Role.LEADER) { - fme.msg(TL.GENERIC_FPERM_NOPERMISSION, "mine spawners"); - return; - } - } - } - } - - @EventHandler - public void onFarmLandDamage(EntityChangeBlockEvent event) { - if (event.getEntity() instanceof Player) { - Player player = (Player) event.getEntity(); - if (!playerCanBuildDestroyBlock(player, event.getBlock().getLocation(), PermissableAction.DESTROY.name(), true)) { - FPlayer me = FPlayers.getInstance().getById(player.getUniqueId().toString()); - Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock().getLocation())); - Faction myFaction = me.getFaction(); - - me.msg("You can't jump on farmland in the territory of " + otherFaction.getTag(myFaction)); - event.setCancelled(true); - } - } - } - - /// - /// This checks if the current player can execute an action based on it's factions access and surroundings - /// It will grant access in the following priorities: - /// - If Faction Land is Owned and the Owner is the current player, or player is faction leader. - /// - If Faction Land is not Owned and my access value is not set to DENY - /// - If none of the filters above matches, then we consider access is set to ALLOW|UNDEFINED - /// This check does not performs any kind of bypass check (i.e.: me.isAdminBypassing()) - /// - /// The player entity which the check will be made upon - /// The Faction player object related to the player - /// The World location where the action is being executed - /// The faction of the player being checked - /// The current's faction access permission for the action - /// Determine whether we should hurt the player when access is denied - private static boolean CheckPlayerAccess(Player player, FPlayer me, FLocation loc, Faction myFaction, Access access, PermissableAction action, boolean shouldHurt) { - boolean landOwned = (myFaction.doesLocationHaveOwnersSet(loc) && !myFaction.getOwnerList(loc).isEmpty()); - if ((landOwned && myFaction.getOwnerListString(loc).contains(player.getName())) || (me.getRole() == Role.LEADER && me.getFactionId().equals(myFaction.getId()))) return true; - else if (landOwned && !myFaction.getOwnerListString(loc).contains(player.getName())) { - me.msg(TL.ACTIONS_OWNEDTERRITORYDENY.toString().replace("{owners}", myFaction.getOwnerListString(loc))); - if (shouldHurt) { - player.damage(Conf.actionDeniedPainAmount); - me.msg(TL.ACTIONS_NOPERMISSIONPAIN.toString().replace("{action}", action.toString()).replace("{faction}", Board.getInstance().getFactionAt(loc).getTag(myFaction))); - } - return false; - } else if (!landOwned && access == Access.DENY) { // If land is not owned but access is set to DENY anyway - if (shouldHurt) { - player.damage(Conf.actionDeniedPainAmount); - me.msg(TL.ACTIONS_NOPERMISSIONPAIN.toString().replace("{action}", action.toString()).replace("{faction}", Board.getInstance().getFactionAt(loc).getTag(myFaction))); - } - me.msg(TL.ACTIONS_NOPERMISSION.toString().replace("{faction}", myFaction.getTag(me.getFaction())).replace("{action}", action.toString())); - return false; - } else if (access == Access.ALLOW) return true; - me.msg(TL.ACTIONS_NOPERMISSION.toString().replace("{faction}", myFaction.getTag(me.getFaction())).replace("{action}", action.toString())); - return false; - } - - private static boolean CheckActionState(Faction target, FLocation location, FPlayer me, PermissableAction action, boolean pain) { - if (Conf.ownedAreasEnabled && target.doesLocationHaveOwnersSet(location) && !target.playerHasOwnershipRights(me, location)) { - // If pain should be applied - if (pain && Conf.ownedAreaPainBuild) me.msg(TL.ACTIONS_OWNEDTERRITORYPAINDENY.toString().replace("{action}", action.toString()).replace("{faction}", target.getOwnerListString(location))); - if (Conf.ownedAreaDenyBuild && pain) return false; - else if (Conf.ownedAreaDenyBuild) { - me.msg(TL.ACTIONS_NOPERMISSION.toString().replace("{faction}", target.getTag(me.getFaction())).replace("{action}", action.toString())); - return false; - } - } - return CheckPlayerAccess(me.getPlayer(), me, location, target, target.getAccess(me, action), action, pain); - } + public static HashMap bannerLocations = new HashMap<>(); + private HashMap bannerCooldownMap = new HashMap<>(); + + public static boolean playerCanBuildDestroyBlock(Player player, Location location, String action, boolean justCheck) { + String name = player.getName(); + + if (Conf.playersWhoBypassAllProtection.contains(name)) + return true; + + FPlayer me = FPlayers.getInstance().getById(player.getUniqueId().toString()); + Faction myFaction = me.getFaction(); + if (me.isAdminBypassing()) + return true; + + FLocation loc = new FLocation(location); + Faction otherFaction = Board.getInstance().getFactionAt(loc); + + if (otherFaction.isWilderness()) { + if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) + return true; + + if (!Conf.wildernessDenyBuild || Conf.worldsNoWildernessProtection.contains(location.getWorld().getName())) + return true; // This is not faction territory. Use whatever you like here. + + if (!justCheck) + me.msg("You can't " + action + " in the wilderness."); + + return false; + } else if (otherFaction.isSafeZone()) { + if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) + return true; + + if (!Conf.safeZoneDenyBuild || Permission.MANAGE_SAFE_ZONE.has(player)) + return true; + + if (!justCheck) + me.msg("You can't " + action + " in a safe zone."); + + return false; + } else if (otherFaction.isWarZone()) { + if (Conf.worldGuardBuildPriority && Worldguard.playerCanBuild(player, location)) + return true; + + if (!Conf.warZoneDenyBuild || Permission.MANAGE_WAR_ZONE.has(player)) + return true; + + if (!justCheck) + me.msg("You can't " + action + " in a war zone."); + + return false; + } else if (!otherFaction.getId().equals(myFaction.getId())) { // If the faction target is not my own + if (SavageFactions.plugin.getConfig().getBoolean("hcf.raidable", false) && otherFaction.getLandRounded() > otherFaction.getPowerRounded()) + return true; + // Get faction pain build access relation to me + boolean pain = !justCheck && otherFaction.getAccess(me, PermissableAction.PAIN_BUILD) == Access.ALLOW; + return CheckActionState(otherFaction, loc, me, PermissableAction.fromString(action), pain); + } else if (otherFaction.getId().equals(myFaction.getId())) { + boolean pain = !justCheck && myFaction.getAccess(me, PermissableAction.PAIN_BUILD) == Access.ALLOW; + return CheckActionState(myFaction, loc, me, PermissableAction.fromString(action), pain); + } + + // Something failed prevent build + return false; + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockPlace(BlockPlaceEvent event) { + if (!event.canBuild()) { + return; + } + + // special case for flint&steel, which should only be prevented by DenyUsage list + if (event.getBlockPlaced().getType() == Material.FIRE) { + return; + } + + if (!playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "build", false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockFromTo(BlockFromToEvent event) { + if (!Conf.handleExploitLiquidFlow) { + return; + } + if (event.getBlock().isLiquid()) { + if (event.getToBlock().isEmpty()) { + Faction from = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); + Faction to = Board.getInstance().getFactionAt(new FLocation(event.getToBlock())); + if (from == to) { + // not concerned with inter-faction events + return; + } + // from faction != to faction + if (to.isNormal()) { + if (from.isNormal() && from.getRelationTo(to).isAlly()) { + return; + } + event.setCancelled(true); + } + } + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockDamage(BlockDamageEvent event) { + if (event.getInstaBreak() && !playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "destroy", false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockPistonExtend(BlockPistonExtendEvent event) { + if (!Conf.pistonProtectionThroughDenyBuild) { + return; + } + + Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); + + // target end-of-the-line empty (air) block which is being pushed into, including if piston itself would extend into air + Block targetBlock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1); + + // if potentially pushing into air/water/lava in another territory, we need to check it out + if ((targetBlock.isEmpty() || targetBlock.isLiquid()) && !canPistonMoveBlock(pistonFaction, targetBlock.getLocation())) { + event.setCancelled(true); + } + + /* + * note that I originally was testing the territory of each affected block, but since I found that pistons can only push + * up to 12 blocks and the width of any territory is 16 blocks, it should be safe (and much more lightweight) to test + * only the target block as done above + */ + } + + @EventHandler + public void onVaultPlace(BlockPlaceEvent e) { + if (e.getItemInHand().getType() == Material.CHEST) { + ItemStack vault = SavageFactions.plugin.createItem(Material.CHEST, 1, (short) 0, SavageFactions.plugin.color(SavageFactions.plugin.getConfig().getString("fvault.Item.Name")), SavageFactions.plugin.colorList(SavageFactions.plugin.getConfig().getStringList("fvault.Item.Lore"))); + if (e.getItemInHand().isSimilar(vault)) { + FPlayer fme = FPlayers.getInstance().getByPlayer(e.getPlayer()); + if (fme.getFaction().getVault() != null) { + fme.msg(TL.COMMAND_GETVAULT_ALREADYSET); + e.setCancelled(true); + return; + } + FLocation flocation = new FLocation(e.getBlockPlaced().getLocation()); + if (Board.getInstance().getFactionAt(flocation) != fme.getFaction()) { + fme.msg(TL.COMMAND_GETVAULT_INVALIDLOCATION); + e.setCancelled(true); + return; + } + Block start = e.getBlockPlaced(); + int radius = 1; + for (double x = start.getLocation().getX() - radius; x <= start.getLocation().getX() + radius; x++) { + for (double y = start.getLocation().getY() - radius; y <= start.getLocation().getY() + radius; y++) { + for (double z = start.getLocation().getZ() - radius; z <= start.getLocation().getZ() + radius; z++) { + Location blockLoc = new Location(e.getPlayer().getWorld(), x, y, z); + if (blockLoc.getX() == start.getLocation().getX() && blockLoc.getY() == start.getLocation().getY() && blockLoc.getZ() == start.getLocation().getZ()) { + continue; + } + + Material blockMaterial = blockLoc.getBlock().getType(); + + if (blockMaterial == Material.CHEST || (SavageFactions.plugin.getConfig().getBoolean("fvault.No-Hoppers-near-vault") && blockMaterial == Material.HOPPER)) { + e.setCancelled(true); + fme.msg(TL.COMMAND_GETVAULT_CHESTNEAR); + return; + } + } + } + } + + fme.msg(TL.COMMAND_GETVAULT_SUCCESS); + fme.getFaction().setVault(e.getBlockPlaced().getLocation()); + + } + } + } + + @EventHandler + public void onHopperPlace(BlockPlaceEvent e) { + + if (e.getItemInHand().getType() != Material.HOPPER && !SavageFactions.plugin.getConfig().getBoolean("fvault.No-Hoppers-near-vault")) { + return; + } + + Faction factionAt = Board.getInstance().getFactionAt(new FLocation(e.getBlockPlaced().getLocation())); + + if (factionAt.isWilderness() || factionAt.getVault() == null) { + return; + } + + + FPlayer fme = FPlayers.getInstance().getByPlayer(e.getPlayer()); + + Block start = e.getBlockPlaced(); + int radius = 1; + for (double x = start.getLocation().getX() - radius; x <= start.getLocation().getX() + radius; x++) { + for (double y = start.getLocation().getY() - radius; y <= start.getLocation().getY() + radius; y++) { + for (double z = start.getLocation().getZ() - radius; z <= start.getLocation().getZ() + radius; z++) { + Location blockLoc = new Location(e.getPlayer().getWorld(), x, y, z); + if (blockLoc.getX() == start.getLocation().getX() && blockLoc.getY() == start.getLocation().getY() && blockLoc.getZ() == start.getLocation().getZ()) { + continue; + } + + if (blockLoc.getBlock().getType() == Material.CHEST) { + if (factionAt.getVault().equals(blockLoc)) { + e.setCancelled(true); + fme.msg(TL.COMMAND_VAULT_NO_HOPPER); + return; + } + } + } + } + } + + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockPistonRetract(BlockPistonRetractEvent event) { + // if not a sticky piston, retraction should be fine + if (!event.isSticky() || !Conf.pistonProtectionThroughDenyBuild) { + return; + } + + Location targetLoc = event.getRetractLocation(); + Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(targetLoc)); + + // Check if the piston is moving in a faction's territory. This disables pistons entirely in faction territory. + if (otherFaction.isNormal() && SavageFactions.plugin.getConfig().getBoolean("disable-pistons-in-territory", false)) { + event.setCancelled(true); + return; + } + + // if potentially retracted block is just air/water/lava, no worries + if (targetLoc.getBlock().isEmpty() || targetLoc.getBlock().isLiquid()) { + return; + } + + Faction pistonFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); + + if (!canPistonMoveBlock(pistonFaction, targetLoc)) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBannerPlace(BlockPlaceEvent e) { + if (SavageFactions.plugin.mc17) { + return; + } + + if (e.getItemInHand().getType() == SavageFactions.plugin.BANNER) { + ItemStack bannerInHand = e.getItemInHand(); + FPlayer fme = FPlayers.getInstance().getByPlayer(e.getPlayer()); + ItemStack warBanner = fme.getFaction().getBanner(); + if (warBanner != null) { + ItemMeta warmeta = warBanner.getItemMeta(); + warmeta.setDisplayName(SavageFactions.plugin.color(SavageFactions.plugin.getConfig().getString("fbanners.Item.Name"))); + warmeta.setLore(SavageFactions.plugin.colorList(SavageFactions.plugin.getConfig().getStringList("fbanners.Item.Lore"))); + warBanner.setItemMeta(warmeta); + } else { + warBanner = SavageFactions.plugin.createItem(SavageFactions.plugin.BANNER, 1, (short) 1, SavageFactions.plugin.getConfig().getString("fbanners.Item.Name"), SavageFactions.plugin.getConfig().getStringList("fbanners.Item.Lore")); + } + if (warBanner.isSimilar(bannerInHand)) { + + if (fme.getFaction().isWilderness()) { + fme.msg(TL.WARBANNER_NOFACTION); + e.setCancelled(true); + return; + } + int bannerTime = SavageFactions.plugin.getConfig().getInt("fbanners.Banner-Time") * 20; + + Location placedLoc = e.getBlockPlaced().getLocation(); + FLocation fplacedLoc = new FLocation(placedLoc); + if ((Board.getInstance().getFactionAt(fplacedLoc).isWarZone() && SavageFactions.plugin.getConfig().getBoolean("fbanners.Placeable.Warzone")) + || (fme.getFaction().getRelationTo(Board.getInstance().getFactionAt(fplacedLoc)) == Relation.ENEMY) && SavageFactions.plugin.getConfig().getBoolean("fbanners.Placeable.Enemy")) { + if (bannerCooldownMap.containsKey(fme.getTag())) { + fme.msg(TL.WARBANNER_COOLDOWN); + e.setCancelled(true); + return; + } + for (FPlayer fplayer : fme.getFaction().getFPlayers()) { + // if (fplayer == fme) { continue; } //Idk if I wanna not send the title to the player + fplayer.getPlayer().sendTitle(SavageFactions.plugin.color(fme.getTag() + " Placed A WarBanner!"), SavageFactions.plugin.color("&7use &c/f tpbanner&7 to tp to the banner!"), 10, 70, 20); + } + + bannerCooldownMap.put(fme.getTag(), true); + bannerLocations.put(fme.getTag(), e.getBlockPlaced().getLocation()); + int bannerCooldown = SavageFactions.plugin.getConfig().getInt("fbanners.Banner-Place-Cooldown"); + ArmorStand as = (ArmorStand) e.getBlockPlaced().getLocation().add(0.5, 1, 0.5).getWorld().spawnEntity(e.getBlockPlaced().getLocation().add(0.5, 1, 0.5), EntityType.ARMOR_STAND); //Spawn the ArmorStand + as.setVisible(false); //Makes the ArmorStand invisible + as.setGravity(false); //Make sure it doesn't fall + as.setCanPickupItems(false); //I'm not sure what happens if you leave this as it is, but you might as well disable it + as.setCustomName(SavageFactions.plugin.color(SavageFactions.plugin.getConfig().getString("fbanners.BannerHolo").replace("{Faction}", fme.getTag()))); //Set this to the text you want + as.setCustomNameVisible(true); //This makes the text appear no matter if your looking at the entity or not + ArmorStand armorStand = as; + String tag = fme.getTag(); + Bukkit.getScheduler().scheduleSyncDelayedTask(SavageFactions.plugin, () -> bannerCooldownMap.remove(tag), Long.parseLong(bannerCooldown + "")); + Block banner = e.getBlockPlaced(); + Material bannerType = banner.getType(); + Faction bannerFaction = fme.getFaction(); + banner.getWorld().strikeLightningEffect(banner.getLocation()); + // e.getPlayer().getWorld().playSound(e.getPlayer().getLocation(), Sound.ENTITY_LIGHTNING_IMPACT,2.0F,0.5F); + int radius = SavageFactions.plugin.getConfig().getInt("fbanners.Banner-Effect-Radius"); + List effects = SavageFactions.plugin.getConfig().getStringList("fbanners.Effects"); + int affectorTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(SavageFactions.plugin, () -> { + + for (Entity e1 : banner.getLocation().getWorld().getNearbyEntities(banner.getLocation(), radius, 255, radius)) { + if (e1 instanceof Player) { + Player player = (Player) e1; + FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); + if (fplayer.getFaction() == bannerFaction) { + for (String effect : effects) { + String[] components = effect.split(":"); + player.addPotionEffect(new PotionEffect(PotionEffectType.getByName(components[0]), 100, Integer.parseInt(components[1]))); + } + ParticleEffect.LAVA.display(1, 1, 1, 1, 10, banner.getLocation(), 16); + ParticleEffect.FLAME.display(1, 1, 1, 1, 10, banner.getLocation(), 16); + + if (banner.getType() != bannerType) { + banner.setType(bannerType); + } + } + } + } + }, 0L, 20L); + Bukkit.getScheduler().scheduleSyncDelayedTask(SavageFactions.plugin, () -> { + banner.setType(Material.AIR); + as.remove(); + banner.getWorld().strikeLightningEffect(banner.getLocation()); + Bukkit.getScheduler().cancelTask(affectorTask); + bannerLocations.remove(bannerFaction.getTag()); + }, Long.parseLong(bannerTime + "")); + } else { + fme.msg(TL.WARBANNER_INVALIDLOC); + e.setCancelled(true); + } + } + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onFrostWalker(EntityBlockFormEvent event) { + if (event.getEntity() == null || event.getEntity().getType() != EntityType.PLAYER || event.getBlock() == null) { + return; + } + + Player player = (Player) event.getEntity(); + Location location = event.getBlock().getLocation(); + + // only notify every 10 seconds + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + boolean justCheck = fPlayer.getLastFrostwalkerMessage() + 10000 > System.currentTimeMillis(); + if (!justCheck) { + fPlayer.setLastFrostwalkerMessage(); + } + + // Check if they have build permissions here. If not, block this from happening. + if (!playerCanBuildDestroyBlock(player, location, "frostwalk", justCheck)) { + event.setCancelled(true); + } + } + + @EventHandler + public void onFallingBlock(EntityChangeBlockEvent event) { + if(!SavageFactions.plugin.getConfig().getBoolean("Falling-Block-Fix.Enabled")) + return; + + Faction faction = Board.getInstance().getFactionAt(new FLocation(event.getBlock())); + if (faction.isWarZone() || faction.isSafeZone()) { + event.getBlock().setType(Material.AIR); + event.setCancelled(true); + } + } + + //Grace + @EventHandler + public void onBreak(EntityExplodeEvent e) { + if (!SavageFactions.plugin.getConfig().getBoolean("f-grace.Enabled")) + return; + + if (!graceisEnabled()) { + e.setCancelled(true); + } + } + + @EventHandler + public void entityDamage(EntityDamageEvent e) { + if (!SavageFactions.plugin.getConfig().getBoolean("f-grace.Enabled")) + return; + + if (!graceisEnabled()) { + if (e.getEntity() instanceof com.sk89q.worldedit.entity.Player) { + if (e.getCause() == EntityDamageEvent.DamageCause.PROJECTILE) { + e.setCancelled(true); + } + } + } + } + + @EventHandler + public void onTNTPlace(BlockPlaceEvent e1) { + FPlayer fp = FPlayers.getInstance().getByPlayer(e1.getPlayer()); + if (!SavageFactions.plugin.getConfig().getBoolean("f-grace.Enabled")) + return; + + if (!graceisEnabled() && !fp.isAdminBypassing()) { + if (e1.getBlock().getType().equals(Material.TNT)) { + e1.setCancelled(true); + + fp.msg(TL.COMMAND_GRACE_ENABLED, e1.getBlockPlaced().getType().toString()); + } + } + } + + public static boolean graceisEnabled() { + return Conf.gracePeriod; + } + + + private boolean canPistonMoveBlock(Faction pistonFaction, Location target) { + + Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(target)); + + if (pistonFaction == otherFaction) { + return true; + } + + if (otherFaction.isWilderness()) { + return !Conf.wildernessDenyBuild || Conf.worldsNoWildernessProtection.contains(target.getWorld().getName()); + + } else if (otherFaction.isSafeZone()) { + return !Conf.safeZoneDenyBuild; + + } else if (otherFaction.isWarZone()) { + return !Conf.warZoneDenyBuild; + + } + + Relation rel = pistonFaction.getRelationTo(otherFaction); + + return !rel.confDenyBuild(otherFaction.hasPlayersOnline()); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onBlockBreak(BlockBreakEvent event) { + if (!playerCanBuildDestroyBlock(event.getPlayer(), event.getBlock().getLocation(), "destroy", false)) { + event.setCancelled(true); + return; + } + FPlayer fme = FPlayers.getInstance().getByPlayer(event.getPlayer()); + if (!fme.hasFaction()) { + return; + } + if (event.getBlock().getType() == SavageFactions.plugin.MOB_SPANWER) { + if (!fme.isAdminBypassing()) { + Access access = fme.getFaction().getAccess(fme, PermissableAction.SPAWNER); + if (access != Access.ALLOW && fme.getRole() != Role.LEADER) { + fme.msg(TL.GENERIC_FPERM_NOPERMISSION, "mine spawners"); + return; + } + } + } + } + + @EventHandler + public void onFarmLandDamage(EntityChangeBlockEvent event) { + if (event.getEntity() instanceof Player) { + Player player = (Player) event.getEntity(); + if (!playerCanBuildDestroyBlock(player, event.getBlock().getLocation(), PermissableAction.DESTROY.name(), true)) { + FPlayer me = FPlayers.getInstance().getById(player.getUniqueId().toString()); + Faction otherFaction = Board.getInstance().getFactionAt(new FLocation(event.getBlock().getLocation())); + Faction myFaction = me.getFaction(); + + me.msg("You can't jump on farmland in the territory of " + otherFaction.getTag(myFaction)); + event.setCancelled(true); + } + } + } + + /// + /// This checks if the current player can execute an action based on it's factions access and surroundings + /// It will grant access in the following priorities: + /// - If Faction Land is Owned and the Owner is the current player, or player is faction leader. + /// - If Faction Land is not Owned and my access value is not set to DENY + /// - If none of the filters above matches, then we consider access is set to ALLOW|UNDEFINED + /// This check does not performs any kind of bypass check (i.e.: me.isAdminBypassing()) + /// + /// The player entity which the check will be made upon + /// The Faction player object related to the player + /// The World location where the action is being executed + /// The faction of the player being checked + /// The current's faction access permission for the action + /// Determine whether we should hurt the player when access is denied + private static boolean CheckPlayerAccess(Player player, FPlayer me, FLocation loc, Faction myFaction, Access access, PermissableAction action, boolean shouldHurt) { + boolean landOwned = (myFaction.doesLocationHaveOwnersSet(loc) && !myFaction.getOwnerList(loc).isEmpty()); + if ((landOwned && myFaction.getOwnerListString(loc).contains(player.getName())) || (me.getRole() == Role.LEADER && me.getFactionId().equals(myFaction.getId()))) + return true; + else if (landOwned && !myFaction.getOwnerListString(loc).contains(player.getName())) { + me.msg(TL.ACTIONS_OWNEDTERRITORYDENY.toString().replace("{owners}", myFaction.getOwnerListString(loc))); + if (shouldHurt) { + player.damage(Conf.actionDeniedPainAmount); + me.msg(TL.ACTIONS_NOPERMISSIONPAIN.toString().replace("{action}", action.toString()).replace("{faction}", Board.getInstance().getFactionAt(loc).getTag(myFaction))); + } + return false; + } else if (!landOwned && access == Access.DENY) { // If land is not owned but access is set to DENY anyway + if (shouldHurt) { + player.damage(Conf.actionDeniedPainAmount); + me.msg(TL.ACTIONS_NOPERMISSIONPAIN.toString().replace("{action}", action.toString()).replace("{faction}", Board.getInstance().getFactionAt(loc).getTag(myFaction))); + } + me.msg(TL.ACTIONS_NOPERMISSION.toString().replace("{faction}", myFaction.getTag(me.getFaction())).replace("{action}", action.toString())); + return false; + } else if (access == Access.ALLOW) return true; + me.msg(TL.ACTIONS_NOPERMISSION.toString().replace("{faction}", myFaction.getTag(me.getFaction())).replace("{action}", action.toString())); + return false; + } + + private static boolean CheckActionState(Faction target, FLocation location, FPlayer me, PermissableAction action, boolean pain) { + if (Conf.ownedAreasEnabled && target.doesLocationHaveOwnersSet(location) && !target.playerHasOwnershipRights(me, location)) { + // If pain should be applied + if (pain && Conf.ownedAreaPainBuild) + me.msg(TL.ACTIONS_OWNEDTERRITORYPAINDENY.toString().replace("{action}", action.toString()).replace("{faction}", target.getOwnerListString(location))); + if (Conf.ownedAreaDenyBuild && pain) return false; + else if (Conf.ownedAreaDenyBuild) { + me.msg(TL.ACTIONS_NOPERMISSION.toString().replace("{faction}", target.getTag(me.getFaction())).replace("{action}", action.toString())); + return false; + } + } + return CheckPlayerAccess(me.getPlayer(), me, location, target, target.getAccess(me, action), action, pain); + } } diff --git a/src/main/java/com/massivecraft/factions/struct/Permission.java b/src/main/java/com/massivecraft/factions/struct/Permission.java index c174df31..1ae6952e 100644 --- a/src/main/java/com/massivecraft/factions/struct/Permission.java +++ b/src/main/java/com/massivecraft/factions/struct/Permission.java @@ -31,6 +31,7 @@ public enum Permission { DISBAND_ANY("disband.any"), FLY("fly"), FOCUS("focus"), + GRACE("grace"), HELP("help"), HOME("home"), INVITE("invite"), @@ -77,6 +78,7 @@ public enum Permission { SAVE("save"), SETHOME("sethome"), SETHOME_ANY("sethome.any"), + SETSTRIKES("setstrikes"), SHOW("show"), STATUS("status"), STEALTH("stealth"), diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java index 4b325e5c..7a2ce25f 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java @@ -68,6 +68,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { Inventory chest; Map bannerSerialized; private long lastDeath; + private int strikes = 0; // -------------------------------------------- // // Construct @@ -117,6 +118,14 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { resetPerms(); // Reset on new Faction so it has default values. } + public int getStrikes() { + return strikes; + } + + public void setStrikes(int strikes) { + this.strikes = strikes; + } + public HashMap> getAnnouncements() { return this.announcements; } diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TL.java b/src/main/java/com/massivecraft/factions/zcore/util/TL.java index 969a606a..0ddf6190 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TL.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TL.java @@ -317,6 +317,10 @@ public enum TL { COMMAND_FWARP_PASSWORD_REQUIRED("&c&l[!]&c Warp Password:"), COMMAND_FWARP_PASSWORD_TIMEOUT("&c&l[!]&7 Warp password &ccanceled"), + COMMAND_GRACE_DESCRIPTION("Toggles Grace Period on/off"), + COMMAND_GRACE_ENABLED("&cYou cannot place &e%s &cwhile grace period is active!"), + COMMAND_GRACE_TOGGLE("&8ยป &7Grace period is now &c%1$s"), + COMMAND_HINT_PERMISSION("&aYou can manage your factions permissions using &7/f perms"), COMMAND_HOME_DISABLED("&c&l[!]&7 Sorry, Faction homes are &cdisabled on this server."), @@ -605,6 +609,16 @@ public enum TL { COMMAND_SETMAXVAULTS_DESCRIPTION("Set max vaults for a Faction."), COMMAND_SETMAXVAULTS_SUCCESS("&aSet max vaults for &e%s &ato &b%d"), + COMMAND_SETSTRIKES_FAILURE("&c&l[!]&7 &c{faction} does not exist."), + COMMAND_SETSTRIKES_BROADCAST("&c&l[!]&7 &c{faction} has received a strike for {reason}"), + COMMAND_SETSTRIKES_SUCCESS("&c&l[!]&7 &c{faction}'s&7 new strikes are &c{strikes}"), + COMMAND_SETSTRIKES_DESCRIPTION("Set a faction's points"), + + COMMAND_STRIKE_MESSAGE("&c&l[!] &7{faction} has {strikes} strikes."), + COMMAND_STRIKE_NOTFOUND("&c&l[!] &7{faction} does not exist."), + COMMAND_STRIKE_NEEDFACTION("&c&l[!] &7&cYou need to join a faction to view your own!"), + COMMAND_STRIKE_DESCRIPTION("Give a faction strikes."), + COMMAND_VAULT_DESCRIPTION("Open your placed faction vault!"), COMMAND_VAULT_INVALID("&c&l[!]&7 Your vault was either&c claimed&7, &cbroken&7, or has&c not been&7 placed yet."), COMMAND_VAULT_OPENING("&c&l[!]&7 Opening faction vault."), diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java b/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java index 3392ec7d..ff3bea5b 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java @@ -6,6 +6,7 @@ import com.massivecraft.factions.struct.Relation; import org.apache.commons.lang.time.DurationFormatUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.dynmap.snakeyaml.nodes.Tag; import java.util.ArrayList; import java.util.List; @@ -72,6 +73,7 @@ public enum TagReplacer { FACTION_KILLS(TagType.FACTION, "{faction-kills}"), FACTION_DEATHS(TagType.FACTION, "{faction-deaths}"), FACTION_BANCOUNT(TagType.FACTION, "{faction-bancount}"), + FACTION_STRIKES(TagType.FACTION, "{strikes}"), /** * General variables, require no faction or player @@ -255,6 +257,9 @@ public enum TagReplacer { return String.valueOf(fac.getDeaths()); case FACTION_BANCOUNT: return String.valueOf(fac.getBannedPlayers().size()); + case FACTION_STRIKES: + return String.valueOf(fac.getStrikes()); + default: } return null; diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 1e84826b..13289e80 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -280,6 +280,7 @@ show: - '&6 * &eOwner &7{leader}' - '&6 * &eDescription &7{description}' - '&6 * &eLand / Power / Max Power: &7{chunks} &8/ &7{power} &8/ &7{maxPower}' + - '&6 * &eFaction Strikes: &7{strikes}' - '&6 * &eFounded &7{create-date}' - '&6 * &eBalance &f{faction-balance}' - '&6 * &eAllies &c{allies-list}' @@ -753,6 +754,26 @@ fnear: Enabled: true Radius: 50 +############################################################ +# +------------------------------------------------------+ # +# | Falling Block Fix | # +# +------------------------------------------------------+ # +############################################################ +#Enabling this will disallow falling blocks to be in spawn. +#Meaning people cannot shoot cannons into spawn and stack sand +#Recommended: true +Falling-Block-Fix: + enabled: true + +############################################################ +# +------------------------------------------------------+ # +# | Faction GracePeriod | # +# +------------------------------------------------------+ # +############################################################ + +f-grace: + Enabled: true + ############################################################ # +------------------------------------------------------+ # # | Faction Focus | #