From 143daad9e63b59c8add70df1a677fccc97f76585 Mon Sep 17 00:00:00 2001 From: ProSavage Date: Thu, 12 Jul 2018 11:11:07 -0500 Subject: [PATCH] F map autoupdate during flying fixed. --- .../java/com/massivecraft/factions/Board.java | 10 +- .../java/com/massivecraft/factions/Conf.java | 85 +- .../com/massivecraft/factions/FLocation.java | 113 +- .../com/massivecraft/factions/FPlayer.java | 3 - .../com/massivecraft/factions/FPlayers.java | 4 +- .../com/massivecraft/factions/Factions.java | 24 +- .../java/com/massivecraft/factions/P.java | 58 +- .../com/massivecraft/factions/cmd/CmdBan.java | 1 - .../massivecraft/factions/cmd/CmdChat.java | 8 +- .../massivecraft/factions/cmd/CmdClaim.java | 2 +- .../massivecraft/factions/cmd/CmdCoords.java | 11 +- .../com/massivecraft/factions/cmd/CmdFly.java | 121 +- .../massivecraft/factions/cmd/CmdHelp.java | 12 +- .../massivecraft/factions/cmd/CmdInspect.java | 9 +- .../factions/cmd/CmdLowPower.java | 13 +- .../factions/cmd/CmdMoneyBalance.java | 1 - .../massivecraft/factions/cmd/CmdPerm.java | 1 - .../factions/cmd/CmdSeeChunk.java | 10 +- .../factions/cmd/CmdShowClaims.java | 35 +- .../massivecraft/factions/cmd/CmdTntFill.java | 94 +- .../massivecraft/factions/cmd/CmdUnclaim.java | 2 +- .../massivecraft/factions/cmd/CmdVault.java | 35 +- .../massivecraft/factions/cmd/FCmdRoot.java | 10 +- .../massivecraft/factions/cmd/FCommand.java | 12 +- .../factions/event/FPlayerJoinEvent.java | 8 +- .../factions/event/FPlayerLeaveEvent.java | 10 +- .../factions/event/FactionCreateEvent.java | 8 +- .../factions/event/FactionEvent.java | 8 +- .../factions/event/FactionRelationEvent.java | 4 +- .../factions/integration/Econ.java | 14 +- .../integration/dynmap/DynmapStyle.java | 140 +- .../integration/dynmap/EngineDynmap.java | 130 +- .../integration/dynmap/TempAreaMarker.java | 54 +- .../integration/dynmap/TempMarker.java | 26 +- .../listeners/FactionsBlockListener.java | 234 +- .../listeners/FactionsEntityListener.java | 14 +- .../listeners/FactionsExploitListener.java | 8 +- .../listeners/FactionsPlayerListener.java | 1296 ++++--- .../scoreboards/BufferedObjective.java | 25 +- .../factions/scoreboards/FScoreboard.java | 28 +- .../factions/scoreboards/FTeamWrapper.java | 26 +- .../factions/struct/ChatMode.java | 2 +- .../massivecraft/factions/struct/Role.java | 20 +- .../factions/util/AsciiCompass.java | 86 +- .../util/ClipPlaceholderAPIManager.java | 2 - .../factions/util/EnumTypeAdapter.java | 27 +- .../factions/util/InventoryUtil.java | 9 +- .../massivecraft/factions/util/MiscUtil.java | 6 +- .../util/Particles/ParticleEffect.java | 3122 ++++++++--------- .../util/PermissionsMapTypeAdapter.java | 2 - .../factions/util/SpiralTask.java | 16 +- .../massivecraft/factions/util/WarpGUI.java | 10 +- .../massivecraft/factions/zcore/MCommand.java | 55 +- .../massivecraft/factions/zcore/MPlugin.java | 59 +- .../zcore/fperms/PermissableAction.java | 21 +- .../fperms/gui/PermissableActionGUI.java | 8 +- .../fperms/gui/PermissableRelationGUI.java | 5 +- .../zcore/fupgrades/FUpgradesGUI.java | 17 +- .../factions/zcore/nbtapi/NBTCompound.java | 12 +- .../factions/zcore/nbtapi/NBTContainer.java | 10 +- .../factions/zcore/nbtapi/NBTItem.java | 16 +- .../zcore/nbtapi/NBTReflectionUtil.java | 29 +- .../factions/zcore/nbtapi/NBTType.java | 12 +- .../zcore/nbtapi/utils/MinecraftVersion.java | 8 +- .../factions/zcore/persist/MemoryBoard.java | 112 +- .../factions/zcore/persist/MemoryFPlayer.java | 239 +- .../factions/zcore/persist/MemoryFaction.java | 225 +- .../zcore/persist/json/JSONFPlayers.java | 13 +- .../zcore/persist/json/JSONFactions.java | 19 +- .../factions/zcore/util/DiscUtil.java | 18 +- .../massivecraft/factions/zcore/util/TL.java | 6 +- .../factions/zcore/util/TagReplacer.java | 58 +- .../factions/zcore/util/TextUtil.java | 124 +- .../factions/zcore/util/UUIDFetcher.java | 44 +- 74 files changed, 3460 insertions(+), 3659 deletions(-) diff --git a/src/main/java/com/massivecraft/factions/Board.java b/src/main/java/com/massivecraft/factions/Board.java index 27ac3cee..4d147fb0 100644 --- a/src/main/java/com/massivecraft/factions/Board.java +++ b/src/main/java/com/massivecraft/factions/Board.java @@ -11,11 +11,6 @@ import java.util.Set; public abstract class Board { protected static Board instance = getBoardImpl(); - //----------------------------------------------// - // Get and Set - //----------------------------------------------// - public abstract String getIdAt(FLocation flocation); - private static Board getBoardImpl() { switch (Conf.backEnd) { case JSON: @@ -28,6 +23,11 @@ public abstract class Board { return instance; } + //----------------------------------------------// + // Get and Set + //----------------------------------------------// + public abstract String getIdAt(FLocation flocation); + public abstract Faction getFactionAt(FLocation flocation); public abstract void setIdAt(String id, FLocation flocation); diff --git a/src/main/java/com/massivecraft/factions/Conf.java b/src/main/java/com/massivecraft/factions/Conf.java index 79b408e0..02b1cd8e 100644 --- a/src/main/java/com/massivecraft/factions/Conf.java +++ b/src/main/java/com/massivecraft/factions/Conf.java @@ -10,21 +10,26 @@ import java.util.*; public class Conf { + // Region Style + public static final transient String DYNMAP_STYLE_LINE_COLOR = "#00FF00"; + public static final transient double DYNMAP_STYLE_LINE_OPACITY = 0.8D; + public static final transient int DYNMAP_STYLE_LINE_WEIGHT = 3; + public static final transient String DYNMAP_STYLE_FILL_COLOR = "#00FF00"; + public static final transient double DYNMAP_STYLE_FILL_OPACITY = 0.35D; + public static final transient String DYNMAP_STYLE_HOME_MARKER = "greenflag"; + public static final transient boolean DYNMAP_STYLE_BOOST = false; public static List baseCommandAliases = new ArrayList<>(); public static boolean allowNoSlashCommand = true; - // Colors public static ChatColor colorMember = ChatColor.GREEN; public static ChatColor colorAlly = ChatColor.LIGHT_PURPLE; public static ChatColor colorTruce = ChatColor.DARK_PURPLE; public static ChatColor colorNeutral = ChatColor.WHITE; public static ChatColor colorEnemy = ChatColor.RED; - public static ChatColor colorPeaceful = ChatColor.GOLD; public static ChatColor colorWilderness = ChatColor.GRAY; public static ChatColor colorSafezone = ChatColor.GOLD; public static ChatColor colorWar = ChatColor.DARK_RED; - // Power public static double powerPlayerMax = 10.0; public static double powerPlayerMin = -10.0; @@ -35,32 +40,24 @@ public class Conf { public static double powerOfflineLossPerDay = 0.0; // players will lose this much power per day offline public static double powerOfflineLossLimit = 0.0; // players will no longer lose power from being offline once their power drops to this amount or less public static double powerFactionMax = 0.0; // if greater than 0, the cap on how much power a faction can have (additional power from players beyond that will act as a "buffer" of sorts) - public static String prefixAdmin = "***"; public static String prefixCoLeader = "**"; public static String prefixMod = "*"; public static String prefixRecruit = "-"; public static String prefixNormal = "+"; - public static int factionTagLengthMin = 3; public static int factionTagLengthMax = 10; public static boolean factionTagForceUpperCase = false; - public static boolean newFactionsDefaultOpen = false; - // when faction membership hits this limit, players will no longer be able to join using /f join; default is 0, no limit public static int factionMemberLimit = 0; - // what faction ID to start new players in when they first join the server; default is 0, "no faction" public static String newPlayerStartingFactionID = "0"; - public static boolean showMapFactionKey = true; public static boolean showNeutralFactionsOnMap = true; public static boolean showEnemyFactionsOnMap = true; - // Disallow joining/leaving/kicking while power is negative public static boolean canLeaveWithNegativePower = true; - // Configuration for faction-only chat public static boolean factionOnlyChat = true; // Configuration on the Faction tag in chat messages. @@ -78,24 +75,18 @@ public class Conf { public static String allianceChatFormat = ChatColor.LIGHT_PURPLE + "%s:" + ChatColor.WHITE + " %s"; public static String truceChatFormat = ChatColor.DARK_PURPLE + "%s:" + ChatColor.WHITE + " %s"; public static String modChatFormat = ChatColor.RED + "%s:" + ChatColor.WHITE + " %s"; - public static int enemyFlyCheckRadius = 16; public static boolean noEnderpearlsInFly = false; - public static boolean broadcastDescriptionChanges = false; public static boolean broadcastTagChanges = false; - public static double saveToFileEveryXMinutes = 30.0; - public static double autoLeaveAfterDaysOfInactivity = 10.0; public static double autoLeaveRoutineRunsEveryXMinutes = 5.0; public static int autoLeaveRoutineMaxMillisecondsPerTick = 5; // 1 server tick is roughly 50ms, so default max 10% of a tick public static boolean removePlayerDataWhenBanned = true; public static boolean autoLeaveDeleteFPlayerData = true; // Let them just remove player from Faction. - public static boolean worldGuardChecking = false; public static boolean worldGuardBuildPriority = false; - // server logging options public static boolean logFactionCreate = true; public static boolean logFactionDisband = true; @@ -106,14 +97,12 @@ public class Conf { public static boolean logLandUnclaims = true; public static boolean logMoneyTransactions = true; public static boolean logPlayerCommands = true; - // prevent some potential exploits public static boolean handleExploitObsidianGenerators = true; public static boolean handleExploitEnderPearlClipping = true; public static boolean handleExploitInteractionSpam = true; public static boolean handleExploitTNTWaterlog = false; public static boolean handleExploitLiquidFlow = false; - public static boolean homesEnabled = true; public static boolean homesMustBeInClaimedTerritory = true; public static boolean homesTeleportToOnDeath = true; @@ -126,43 +115,32 @@ public class Conf { public static boolean homesTeleportAllowedFromDifferentWorld = true; public static double homesTeleportAllowedEnemyDistance = 32.0; public static boolean homesTeleportIgnoreEnemiesIfInOwnTerritory = true; - public static boolean disablePVPBetweenNeutralFactions = false; public static boolean disablePVPForFactionlessPlayers = false; public static boolean enablePVPAgainstFactionlessInAttackersLand = false; - public static int noPVPDamageToOthersForXSecondsAfterLogin = 3; - public static boolean peacefulTerritoryDisablePVP = true; public static boolean peacefulTerritoryDisableMonsters = false; public static boolean peacefulTerritoryDisableBoom = false; public static boolean peacefulMembersDisablePowerLoss = true; - public static boolean permanentFactionsDisableLeaderPromotion = false; - public static boolean claimsMustBeConnected = false; public static boolean claimsCanBeUnconnectedIfOwnedByOtherFaction = true; public static int claimsRequireMinFactionMembers = 1; public static int claimedLandsMax = 0; public static int lineClaimLimit = 5; - // if someone is doing a radius claim and the process fails to claim land this many times in a row, it will exit public static int radiusClaimFailureLimit = 9; - public static double considerFactionsReallyOfflineAfterXMinutes = 0.0; - public static int actionDeniedPainAmount = 1; - // commands which will be prevented if the player is a member of a permanent faction public static Set permanentFactionMemberDenyCommands = new LinkedHashSet<>(); - // commands which will be prevented when in claimed territory of another faction public static Set territoryNeutralDenyCommands = new LinkedHashSet<>(); public static Set territoryEnemyDenyCommands = new LinkedHashSet<>(); public static Set territoryAllyDenyCommands = new LinkedHashSet<>(); public static Set warzoneDenyCommands = new LinkedHashSet<>(); public static Set wildernessDenyCommands = new LinkedHashSet<>(); - public static boolean territoryDenyBuild = true; public static boolean territoryDenyBuildWhenOffline = true; public static boolean territoryPainBuild = false; @@ -194,13 +172,11 @@ public class Conf { public static boolean territoryBlockTNTWhenOffline = false; public static boolean territoryDenyEndermanBlocks = true; public static boolean territoryDenyEndermanBlocksWhenOffline = true; - public static boolean safeZoneDenyBuild = true; public static boolean safeZoneDenyUseage = true; public static boolean safeZoneBlockTNT = true; public static boolean safeZonePreventAllDamageToPlayers = false; public static boolean safeZoneDenyEndermanBlocks = true; - public static boolean warZoneDenyBuild = true; public static boolean warZoneDenyUseage = true; public static boolean warZoneBlockCreepers = false; @@ -209,7 +185,6 @@ public class Conf { public static boolean warZonePowerLoss = true; public static boolean warZoneFriendlyFire = false; public static boolean warZoneDenyEndermanBlocks = true; - public static boolean wildernessDenyBuild = false; public static boolean wildernessDenyUseage = false; public static boolean wildernessBlockCreepers = false; @@ -217,7 +192,6 @@ public class Conf { public static boolean wildernessBlockTNT = false; public static boolean wildernessPowerLoss = true; public static boolean wildernessDenyEndermanBlocks = false; - // for claimed areas where further faction-member ownership can be defined public static boolean ownedAreasEnabled = true; public static int ownedAreasLimitPerFaction = 0; @@ -227,18 +201,14 @@ public class Conf { public static boolean ownedAreaPainBuild = false; public static boolean ownedAreaProtectMaterials = true; public static boolean ownedAreaDenyUseage = true; - public static boolean ownedMessageOnBorder = true; public static boolean ownedMessageInsideTerritory = true; public static boolean ownedMessageByChunk = false; - public static boolean pistonProtectionThroughDenyBuild = true; - public static Set territoryProtectedMaterials = EnumSet.noneOf(Material.class); public static Set territoryDenyUseageMaterials = EnumSet.noneOf(Material.class); public static Set territoryProtectedMaterialsWhenOffline = EnumSet.noneOf(Material.class); public static Set territoryDenyUseageMaterialsWhenOffline = EnumSet.noneOf(Material.class); - public static transient Set safeZoneNerfedCreatureTypes = EnumSet.noneOf(EntityType.class); // Economy settings public static boolean econEnabled = false; @@ -264,6 +234,11 @@ public class Conf { public static double econCostMap = 0.0; public static double econCostPower = 0.0; public static double econCostShow = 0.0; + + + // -------------------------------------------- // + // INTEGRATION: DYNMAP + // -------------------------------------------- // public static double econCostStuck = 0.0; public static double econCostOpen = 0.0; public static double econCostAlly = 0.0; @@ -271,27 +246,16 @@ public class Conf { public static double econCostEnemy = 0.0; public static double econCostNeutral = 0.0; public static double econCostNoBoom = 0.0; - - - // -------------------------------------------- // - // INTEGRATION: DYNMAP - // -------------------------------------------- // - // Should the dynmap intagration be used? public static boolean dynmapUse = false; - // Name of the Factions layer public static String dynmapLayerName = "Factions"; - // Should the layer be visible per default public static boolean dynmapLayerVisible = true; - // Ordering priority in layer menu (low goes before high - default is 0) public static int dynmapLayerPriority = 2; - // (optional) set minimum zoom level before layer is visible (0 = default, always visible) public static int dynmapLayerMinimumZoom = 0; - // Format for popup - substitute values for macros public static String dynmapDescription = "
\n" @@ -307,33 +271,19 @@ public class Conf { + "Bank: %money%
\n" + "
\n" + "
"; - // Enable the %money% macro. Only do this if you know your economy manager is thread-safe. public static boolean dynmapDescriptionMoney = false; - // Allow players in faction to see one another on Dynmap (only relevant if Dynmap has 'player-info-protected' enabled) public static boolean dynmapVisibilityByFaction = true; - // Optional setting to limit which regions to show. // If empty all regions are shown. // Specify Faction either by name or UUID. // To show all regions on a given world, add 'world:' to the list. public static Set dynmapVisibleFactions = new HashSet<>(); - // Optional setting to hide specific Factions. // Specify Faction either by name or UUID. // To hide all regions on a given world, add 'world:' to the list. public static Set dynmapHiddenFactions = new HashSet<>(); - - // Region Style - public static final transient String DYNMAP_STYLE_LINE_COLOR = "#00FF00"; - public static final transient double DYNMAP_STYLE_LINE_OPACITY = 0.8D; - public static final transient int DYNMAP_STYLE_LINE_WEIGHT = 3; - public static final transient String DYNMAP_STYLE_FILL_COLOR = "#00FF00"; - public static final transient double DYNMAP_STYLE_FILL_OPACITY = 0.35D; - public static final transient String DYNMAP_STYLE_HOME_MARKER = "greenflag"; - public static final transient boolean DYNMAP_STYLE_BOOST = false; - public static DynmapStyle dynmapDefaultStyle = new DynmapStyle() .setStrokeColor(DYNMAP_STYLE_LINE_COLOR) .setLineOpacity(DYNMAP_STYLE_LINE_OPACITY) @@ -375,6 +325,10 @@ public class Conf { public static int mapHeight = 17; public static int mapWidth = 49; public static transient char[] mapKeyChrs = "\\/#$%=&^ABCDEFGHJKLMNOPQRSTUVWXYZ1234567890abcdeghjmnopqrsuvwxyz?".toCharArray(); + // -------------------------------------------- // + // Persistance + // -------------------------------------------- // + private static transient Conf i = new Conf(); static { baseCommandAliases.add("f"); @@ -455,11 +409,6 @@ public class Conf { safeZoneNerfedCreatureTypes.add(EntityType.ZOMBIE); } - // -------------------------------------------- // - // Persistance - // -------------------------------------------- // - private static transient Conf i = new Conf(); - public static void load() { P.p.persist.loadOrSaveDefault(i, Conf.class, "conf"); } diff --git a/src/main/java/com/massivecraft/factions/FLocation.java b/src/main/java/com/massivecraft/factions/FLocation.java index 97a96a8f..d3f085ee 100644 --- a/src/main/java/com/massivecraft/factions/FLocation.java +++ b/src/main/java/com/massivecraft/factions/FLocation.java @@ -13,9 +13,6 @@ import java.util.Set; public class FLocation implements Serializable { private static final long serialVersionUID = -8292915234027387983L; private static final boolean worldBorderSupport; - private String worldName = "world"; - private int x = 0; - private int z = 0; static { boolean worldBorderClassPresent = false; @@ -28,6 +25,10 @@ public class FLocation implements Serializable { worldBorderSupport = worldBorderClassPresent; } + private String worldName = "world"; + private int x = 0; + private int z = 0; + //----------------------------------------------// // Constructors //----------------------------------------------// @@ -62,43 +63,6 @@ public class FLocation implements Serializable { // Getters and Setters //----------------------------------------------// - public String getWorldName() { - return worldName; - } - - public World getWorld() { - return Bukkit.getWorld(worldName); - } - - public void setWorldName(String worldName) { - this.worldName = worldName; - } - - public long getX() { - return x; - } - - public void setX(int x) { - this.x = x; - } - - public long getZ() { - return z; - } - - public void setZ(int z) { - this.z = z; - } - - public String getCoordString() { - return "" + x + "," + z; - } - - @Override - public String toString() { - return "[" + this.getWorldName() + "," + this.getCoordString() + "]"; - } - public static FLocation fromString(String string) { int index = string.indexOf(",", 0); int start = 1; @@ -110,10 +74,6 @@ public class FLocation implements Serializable { return new FLocation(worldName, x, y); } - //----------------------------------------------// - // Block/Chunk/Region Value Transformation - //----------------------------------------------// - // bit-shifting is used because it's much faster than standard division and multiplication public static int blockToChunk(int blockVal) { // 1 chunk is 16x16 blocks return blockVal >> 4; // ">> 4" == "/ 16" @@ -139,10 +99,63 @@ public class FLocation implements Serializable { return regionVal << 5; // "<< 5" == "* 32" } + public static HashSet getArea(FLocation from, FLocation to) { + HashSet ret = new HashSet<>(); + + for (long x : MiscUtil.range(from.getX(), to.getX())) { + for (long z : MiscUtil.range(from.getZ(), to.getZ())) { + ret.add(new FLocation(from.getWorldName(), (int) x, (int) z)); + } + } + + return ret; + } + + public String getWorldName() { + return worldName; + } + + public void setWorldName(String worldName) { + this.worldName = worldName; + } + + //----------------------------------------------// + // Block/Chunk/Region Value Transformation + //----------------------------------------------// + + public World getWorld() { + return Bukkit.getWorld(worldName); + } + + public long getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public long getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + + public String getCoordString() { + return "" + x + "," + z; + } + //----------------------------------------------// // Misc Geometry //----------------------------------------------// + @Override + public String toString() { + return "[" + this.getWorldName() + "," + this.getCoordString() + "]"; + } + public FLocation getRelative(int dx, int dz) { return new FLocation(this.worldName, this.x + dx, this.z + dz); } @@ -215,18 +228,6 @@ public class FLocation implements Serializable { return ret; } - public static HashSet getArea(FLocation from, FLocation to) { - HashSet ret = new HashSet<>(); - - for (long x : MiscUtil.range(from.getX(), to.getX())) { - for (long z : MiscUtil.range(from.getZ(), to.getZ())) { - ret.add(new FLocation(from.getWorldName(), (int) x, (int) z)); - } - } - - return ret; - } - //----------------------------------------------// // Comparison //----------------------------------------------// diff --git a/src/main/java/com/massivecraft/factions/FPlayer.java b/src/main/java/com/massivecraft/factions/FPlayer.java index c6040be1..cc8adfb1 100644 --- a/src/main/java/com/massivecraft/factions/FPlayer.java +++ b/src/main/java/com/massivecraft/factions/FPlayer.java @@ -332,7 +332,4 @@ public interface FPlayer extends EconomyParticipator { void clearWarmup(); - - - } \ No newline at end of file diff --git a/src/main/java/com/massivecraft/factions/FPlayers.java b/src/main/java/com/massivecraft/factions/FPlayers.java index bd4912ed..aca12183 100644 --- a/src/main/java/com/massivecraft/factions/FPlayers.java +++ b/src/main/java/com/massivecraft/factions/FPlayers.java @@ -9,8 +9,6 @@ import java.util.Collection; public abstract class FPlayers { protected static FPlayers instance = getFPlayersImpl(); - public abstract void clean(); - public static FPlayers getInstance() { return instance; } @@ -23,6 +21,8 @@ public abstract class FPlayers { return null; } + public abstract void clean(); + public abstract Collection getOnlinePlayers(); public abstract FPlayer getByPlayer(Player player); diff --git a/src/main/java/com/massivecraft/factions/Factions.java b/src/main/java/com/massivecraft/factions/Factions.java index 05e49121..285da06c 100644 --- a/src/main/java/com/massivecraft/factions/Factions.java +++ b/src/main/java/com/massivecraft/factions/Factions.java @@ -8,6 +8,18 @@ import java.util.Set; public abstract class Factions { protected static Factions instance = getFactionsImpl(); + public static Factions getInstance() { + return instance; + } + + private static Factions getFactionsImpl() { + switch (Conf.backEnd) { + case JSON: + return new JSONFactions(); + } + return null; + } + public abstract Faction getFactionById(String id); public abstract Faction getByTag(String str); @@ -39,17 +51,5 @@ public abstract class Factions { public abstract void forceSave(boolean sync); - public static Factions getInstance() { - return instance; - } - - private static Factions getFactionsImpl() { - switch (Conf.backEnd) { - case JSON: - return new JSONFactions(); - } - return null; - } - public abstract void load(); } diff --git a/src/main/java/com/massivecraft/factions/P.java b/src/main/java/com/massivecraft/factions/P.java index f95a9cb1..a3187935 100644 --- a/src/main/java/com/massivecraft/factions/P.java +++ b/src/main/java/com/massivecraft/factions/P.java @@ -49,13 +49,24 @@ public class P extends MPlugin { public static Permission perms = null; - public boolean PlaceholderApi; - - + // Commands + public FCmdRoot cmdBase; + public CmdAutoHelp cmdAutoHelp; + public boolean mc17 = false; + public boolean mc18 = false; + public boolean factionsFlight = false; ItemStack item = new ItemStack(Material.CAKE); // Persistence related private boolean locked = false; + private Integer AutoLeaveTask = null; + private boolean hookedPlayervaults; + private ClipPlaceholderAPIManager clipPlaceholderAPIManager; + private boolean mvdwPlaceholderAPIManager = false; + + public P() { + p = this; + } public boolean getLocked() { return this.locked; @@ -66,7 +77,6 @@ public class P extends MPlugin { this.setAutoSave(val); } - private Integer AutoLeaveTask = null; public void playSoundForAll(String sound) { for (Player pl : Bukkit.getOnlinePlayers()) { playSound(pl, sound); @@ -90,22 +100,6 @@ public class P extends MPlugin { sound = sound.split(":")[0]; p.playSound(p.getLocation(), Sound.valueOf(sound), pitch, 5.0F); } - // Commands - public FCmdRoot cmdBase; - public CmdAutoHelp cmdAutoHelp; - - private boolean hookedPlayervaults; - private ClipPlaceholderAPIManager clipPlaceholderAPIManager; - private boolean mvdwPlaceholderAPIManager = false; - - public P() { - p = this; - } - - public boolean mc17 = false; - public boolean mc18 = false; - public boolean factionsFlight = false; - @Override public void onEnable() { @@ -176,16 +170,13 @@ public class P extends MPlugin { getServer().getPluginManager().registerEvents(new FactionsExploitListener(), this); getServer().getPluginManager().registerEvents(new FactionsBlockListener(this), this); getServer().getPluginManager().registerEvents(new FUpgradesGUI(), this); - getServer().getPluginManager().registerEvents(new EXPUpgrade(),this); - getServer().getPluginManager().registerEvents(new CropUpgrades(),this); - getServer().getPluginManager().registerEvents(new SpawnerUpgrades(),this); + getServer().getPluginManager().registerEvents(new EXPUpgrade(), this); + getServer().getPluginManager().registerEvents(new CropUpgrades(), this); + getServer().getPluginManager().registerEvents(new SpawnerUpgrades(), this); // since some other plugins execute commands directly through this command interface, provide it this.getCommand(this.refCommand).setExecutor(this); - - - setupPlaceholderAPI(); postEnable(); this.loadSuccessful = true; @@ -245,7 +236,8 @@ public class P extends MPlugin { Type accessTypeAdatper = new TypeToken>>() { }.getType(); - return new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().enableComplexMapKeySerialization().excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE).registerTypeAdapter(accessTypeAdatper, new PermissionsMapTypeAdapter()).registerTypeAdapter(LazyLocation.class, new MyLocationTypeAdapter()).registerTypeAdapter(mapFLocToStringSetType, new MapFLocToStringSetTypeAdapter()).registerTypeAdapterFactory(EnumTypeAdapter.ENUM_FACTORY); } + return new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().enableComplexMapKeySerialization().excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE).registerTypeAdapter(accessTypeAdatper, new PermissionsMapTypeAdapter()).registerTypeAdapter(LazyLocation.class, new MyLocationTypeAdapter()).registerTypeAdapter(mapFLocToStringSetType, new MapFLocToStringSetTypeAdapter()).registerTypeAdapterFactory(EnumTypeAdapter.ENUM_FACTORY); + } @Override public void onDisable() { @@ -280,6 +272,7 @@ public class P extends MPlugin { //Board.getInstance().forceSave(); Not sure why this was there as it's called after the board is already saved. Conf.save(); } + public ItemStack createItem(Material material, int amount, short datavalue, String name, List lore) { ItemStack item = new ItemStack(material, amount, datavalue); ItemMeta meta = item.getItemMeta(); @@ -303,6 +296,7 @@ public class P extends MPlugin { Economy econ = rsp.getProvider(); return econ; } + @Override public boolean logPlayerCommands() { return Conf.logPlayerCommands; @@ -324,8 +318,8 @@ public class P extends MPlugin { return handleCommand(sender, cmd + " " + TextUtil.implode(Arrays.asList(split), " "), false); } - public void createTimedHologram(final Location location, String text, Long timeout){ - ArmorStand as = (ArmorStand) location.add(0.5,1,0.5).getWorld().spawnEntity(location, EntityType.ARMOR_STAND); //Spawn the ArmorStand + public void createTimedHologram(final Location location, String text, Long timeout) { + ArmorStand as = (ArmorStand) location.add(0.5, 1, 0.5).getWorld().spawnEntity(location, 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 @@ -338,7 +332,7 @@ public class P extends MPlugin { Bukkit.broadcastMessage("removing stand"); armorStand.remove(); } - },timeout*20); + }, timeout * 20); } @@ -442,8 +436,8 @@ public class P extends MPlugin { //colors a string list public List colorList(List lore) { - for (int i = 0; i <= lore.size()-1;i++){ - lore.set(i,color(lore.get(i))); + for (int i = 0; i <= lore.size() - 1; i++) { + lore.set(i, color(lore.get(i))); } return lore; } diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdBan.java b/src/main/java/com/massivecraft/factions/cmd/CmdBan.java index e2bc7210..10b351c7 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdBan.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdBan.java @@ -75,7 +75,6 @@ public class CmdBan extends FCommand { } - // Ban the user. myFaction.ban(target, fme); myFaction.deinvite(target); // can't hurt diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdChat.java b/src/main/java/com/massivecraft/factions/cmd/CmdChat.java index 6b169198..7c220eaf 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdChat.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdChat.java @@ -4,7 +4,6 @@ import com.massivecraft.factions.Conf; import com.massivecraft.factions.struct.ChatMode; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.zcore.util.TL; -import org.bukkit.Bukkit; public class CmdChat extends FCommand { @@ -38,7 +37,7 @@ public class CmdChat extends FCommand { if (modeString != null) { modeString = modeString.toLowerCase(); - if (modeString.startsWith("m")){ + if (modeString.startsWith("m")) { modeTarget = ChatMode.MOD; } else if (modeString.startsWith("p")) { modeTarget = ChatMode.PUBLIC; @@ -56,10 +55,9 @@ public class CmdChat extends FCommand { fme.setChatMode(modeTarget); - if (fme.getChatMode() == ChatMode.MOD) - { + if (fme.getChatMode() == ChatMode.MOD) { msg(TL.COMMAND_CHAT_MODE_MOD); - }else if (fme.getChatMode() == ChatMode.PUBLIC) { + } else if (fme.getChatMode() == ChatMode.PUBLIC) { msg(TL.COMMAND_CHAT_MODE_PUBLIC); } else if (fme.getChatMode() == ChatMode.ALLIANCE) { msg(TL.COMMAND_CHAT_MODE_ALLIANCE); diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdClaim.java b/src/main/java/com/massivecraft/factions/cmd/CmdClaim.java index 93e8da2e..34fcf283 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdClaim.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdClaim.java @@ -50,8 +50,8 @@ public class CmdClaim extends FCommand { } new SpiralTask(new FLocation(me), radius) { - private int failCount = 0; private final int limit = Conf.radiusClaimFailureLimit - 1; + private int failCount = 0; @Override public boolean work() { diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdCoords.java b/src/main/java/com/massivecraft/factions/cmd/CmdCoords.java index 2efc7e6e..e0776501 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdCoords.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdCoords.java @@ -4,11 +4,10 @@ import com.massivecraft.factions.FPlayer; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.zcore.util.TL; import org.bukkit.Location; -import org.bukkit.plugin.java.JavaPlugin; public class CmdCoords extends FCommand { - public CmdCoords(){ + public CmdCoords() { super(); this.aliases.add("coords"); this.aliases.add("coord"); @@ -24,11 +23,11 @@ public class CmdCoords extends FCommand { } @Override - public void perform(){ + public void perform() { Location location = fme.getPlayer().getLocation(); - String message = TL.COMMAND_COORDS_MESSAGE.toString().replace("{player}",fme.getPlayer().getDisplayName()).replace("{x}",(int) location.getX() + "") - .replace("{y}",(int) location.getY() + "").replace("{z}",(int) location.getZ() + "").replace("{world}",location.getWorld().getName()); - for (FPlayer fPlayer : fme.getFaction().getFPlayers()){ + String message = TL.COMMAND_COORDS_MESSAGE.toString().replace("{player}", fme.getPlayer().getDisplayName()).replace("{x}", (int) location.getX() + "") + .replace("{y}", (int) location.getY() + "").replace("{z}", (int) location.getZ() + "").replace("{world}", location.getWorld().getName()); + for (FPlayer fPlayer : fme.getFaction().getFPlayers()) { fPlayer.sendMessage(message); } } diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdFly.java b/src/main/java/com/massivecraft/factions/cmd/CmdFly.java index b3065d87..e253580f 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdFly.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdFly.java @@ -24,6 +24,7 @@ public class CmdFly extends FCommand { public static ConcurrentHashMap flyMap = new ConcurrentHashMap(); public static int id = -1; public static int flyid = -1; + public CmdFly() { super(); this.aliases.add("fly"); @@ -48,15 +49,15 @@ public class CmdFly extends FCommand { continue; } if (!P.p.mc17) { - if (player.getGameMode() == GameMode.SPECTATOR){ + if (player.getGameMode() == GameMode.SPECTATOR) { continue; } } - if (FPlayers.getInstance().getByPlayer(player).isVanished()){ + if (FPlayers.getInstance().getByPlayer(player).isVanished()) { continue; } - ParticleEffect.CLOUD.display((float) 0, (float) 0, (float) 0, (float) 0, 3, player.getLocation().add(0, -0.35, 0), 16); + ParticleEffect.CLOUD.display((float) 0, (float) 0, (float) 0, (float) 0, 3, player.getLocation().add(0, -0.35, 0), 16); } if (flyMap.keySet().size() == 0) { Bukkit.getScheduler().cancelTask(id); @@ -72,44 +73,44 @@ public class CmdFly extends FCommand { public void run() throws ConcurrentModificationException { //threw the exception for now, until I recode fly :( Cringe. checkTaskState(); if (flyMap.keySet().size() != 0) { - for (String name : flyMap.keySet()) { - if (name == null) { - continue; - } - Player player = Bukkit.getPlayer(name); - if (player == null) { - continue; - } - if (!player.isFlying()) { - continue; - } - FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); - if (fPlayer == null) { - continue; - } - if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { - continue; - } - Faction myFaction = fPlayer.getFaction(); - if (myFaction.isWilderness()) { + for (String name : flyMap.keySet()) { + if (name == null) { + continue; + } + Player player = Bukkit.getPlayer(name); + if (player == null) { + continue; + } + if (!player.isFlying()) { + continue; + } + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + if (fPlayer == null) { + continue; + } + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { + continue; + } + Faction myFaction = fPlayer.getFaction(); + if (myFaction.isWilderness()) { + fPlayer.setFlying(false); + flyMap.remove(name); + continue; + } + if (fPlayer.checkIfNearbyEnemies()) { + continue; + } + FLocation myFloc = new FLocation(player.getLocation()); + Faction toFac = Board.getInstance().getFactionAt(myFloc); + if (Board.getInstance().getFactionAt(myFloc) != myFaction) { + if (!checkBypassPerms(fPlayer, player, toFac)) { fPlayer.setFlying(false); flyMap.remove(name); continue; } - if (fPlayer.checkIfNearbyEnemies()) { - continue; - } - FLocation myFloc = new FLocation(player.getLocation()); - Faction toFac = Board.getInstance().getFactionAt(myFloc); - if (Board.getInstance().getFactionAt(myFloc) != myFaction) { - if (!checkBypassPerms(fPlayer, player, toFac)) { - fPlayer.setFlying(false); - flyMap.remove(name); - continue; - } - } - } + + } } } @@ -139,16 +140,23 @@ public class CmdFly extends FCommand { return ((player.hasPermission("factions.fly.neutral") || access == Access.ALLOW) && toFac.getRelationTo(fplayer.getFaction()) == Relation.NEUTRAL && !isSystemFaction(toFac)); } - public boolean isInFlightChecker(Player player) { - return flyMap.containsKey(player.getName()); - } - public static Boolean isSystemFaction(Faction faction) { return faction.isSafeZone() || faction.isWarZone() || faction.isWilderness(); } + public static void checkTaskState() { + if (flyMap.keySet().size() == 0) { + Bukkit.getScheduler().cancelTask(flyid); + flyid = -1; + } + } + + public boolean isInFlightChecker(Player player) { + return flyMap.containsKey(player.getName()); + } + @Override public void perform() { // Disabled by default. @@ -159,7 +167,7 @@ public class CmdFly extends FCommand { FLocation myfloc = new FLocation(me.getLocation()); Faction toFac = Board.getInstance().getFactionAt(myfloc); - if (Board.getInstance().getFactionAt(myfloc) != fme.getFaction()){ + if (Board.getInstance().getFactionAt(myfloc) != fme.getFaction()) { if (!me.hasPermission("factions.fly.wilderness") && toFac.isWilderness()) { fme.msg(TL.COMMAND_FLY_NO_ACCESS, Board.getInstance().getFactionAt(myfloc).getTag(fme)); return; @@ -193,17 +201,13 @@ public class CmdFly extends FCommand { } - - List entities = me.getNearbyEntities(16,256,16); - for (int i = 0; i <= entities.size() -1;i++) - { - if (entities.get(i) instanceof Player) - { + List entities = me.getNearbyEntities(16, 256, 16); + for (int i = 0; i <= entities.size() - 1; i++) { + if (entities.get(i) instanceof Player) { Player eplayer = (Player) entities.get(i); FPlayer efplayer = FPlayers.getInstance().getByPlayer(eplayer); - if (efplayer.getRelationTo(fme) == Relation.ENEMY) - { - fme.msg(TL.COMMAND_FLY_CHECK_ENEMY); + if (efplayer.getRelationTo(fme) == Relation.ENEMY) { + fme.msg(TL.COMMAND_FLY_CHECK_ENEMY); return; } } @@ -213,14 +217,7 @@ public class CmdFly extends FCommand { if (args.size() == 0) { toggleFlight(!fme.isFlying(), me); } else if (args.size() == 1) { - toggleFlight(argAsBool(0),me); - } - } - - public static void checkTaskState() { - if (flyMap.keySet().size() == 0) { - Bukkit.getScheduler().cancelTask(flyid); - flyid = -1; + toggleFlight(argAsBool(0), me); } } @@ -237,13 +234,13 @@ public class CmdFly extends FCommand { @Override public void run() { fme.setFlying(true); - flyMap.put(player.getName(),true); - if (id == -1){ - if (P.p.getConfig().getBoolean("ffly.Particles.Enabled")){ + flyMap.put(player.getName(), true); + if (id == -1) { + if (P.p.getConfig().getBoolean("ffly.Particles.Enabled")) { startParticles(); } } - if (flyid == -1){ + if (flyid == -1) { startFlyCheck(); } } diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdHelp.java b/src/main/java/com/massivecraft/factions/cmd/CmdHelp.java index 5f2034f4..ad4f741f 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdHelp.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdHelp.java @@ -13,6 +13,8 @@ import java.util.List; public class CmdHelp extends FCommand { + public ArrayList> helpPages; + public CmdHelp() { super(); this.aliases.add("help"); @@ -32,6 +34,10 @@ public class CmdHelp extends FCommand { senderMustBeAdmin = false; } + //----------------------------------------------// + // Build the help pages + //----------------------------------------------// + @Override public void perform() { if (P.p.getConfig().getBoolean("use-old-help", true)) { @@ -70,12 +76,6 @@ public class CmdHelp extends FCommand { } } - //----------------------------------------------// - // Build the help pages - //----------------------------------------------// - - public ArrayList> helpPages; - public void updateHelp() { helpPages = new ArrayList<>(); ArrayList pageLines; diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdInspect.java b/src/main/java/com/massivecraft/factions/cmd/CmdInspect.java index c6ffe90f..6b2af666 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdInspect.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdInspect.java @@ -3,9 +3,8 @@ package com.massivecraft.factions.cmd; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.zcore.util.TL; -public class CmdInspect extends FCommand -{ - public CmdInspect(){ +public class CmdInspect extends FCommand { + public CmdInspect() { super(); this.aliases.add("inspect"); this.aliases.add("ins"); @@ -22,8 +21,8 @@ public class CmdInspect extends FCommand @Override - public void perform(){ - if (fme.isInspectMode()){ + public void perform() { + if (fme.isInspectMode()) { fme.setInspectMode(false); msg(TL.COMMAND_INSPECT_DISABLED_MSG); } else { diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdLowPower.java b/src/main/java/com/massivecraft/factions/cmd/CmdLowPower.java index cc8e250b..8b35f45c 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdLowPower.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdLowPower.java @@ -2,12 +2,11 @@ package com.massivecraft.factions.cmd; import com.massivecraft.factions.Conf; import com.massivecraft.factions.FPlayer; -import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.zcore.util.TL; public class CmdLowPower extends FCommand { - public CmdLowPower(){ + public CmdLowPower() { super(); this.aliases.add("lowpower"); @@ -23,13 +22,13 @@ public class CmdLowPower extends FCommand { @Override - public void perform(){ + public void perform() { double maxPower = Conf.powerPlayerMax; String format = TL.COMMAND_LOWPOWER_FORMAT.toString(); - msg(TL.COMMAND_LOWPOWER_HEADER.toString().replace("{maxpower}",(int) maxPower + "")); - for (FPlayer fPlayer : fme.getFaction().getFPlayers()){ - if (fPlayer.getPower() < maxPower){ - sendMessage(format.replace("{player}",fPlayer.getName()).replace("{player_power}",(int) fPlayer.getPower() + "").replace("{maxpower}",(int) maxPower + "")); + msg(TL.COMMAND_LOWPOWER_HEADER.toString().replace("{maxpower}", (int) maxPower + "")); + for (FPlayer fPlayer : fme.getFaction().getFPlayers()) { + if (fPlayer.getPower() < maxPower) { + sendMessage(format.replace("{player}", fPlayer.getName()).replace("{player_power}", (int) fPlayer.getPower() + "").replace("{maxpower}", (int) maxPower + "")); } } } diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdMoneyBalance.java b/src/main/java/com/massivecraft/factions/cmd/CmdMoneyBalance.java index 5459b429..db30f81f 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdMoneyBalance.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdMoneyBalance.java @@ -1,6 +1,5 @@ package com.massivecraft.factions.cmd; -import com.earth2me.essentials.Console; import com.massivecraft.factions.Faction; import com.massivecraft.factions.integration.Econ; import com.massivecraft.factions.struct.Permission; diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdPerm.java b/src/main/java/com/massivecraft/factions/cmd/CmdPerm.java index 9ad44fa8..efd3b91b 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdPerm.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdPerm.java @@ -1,7 +1,6 @@ package com.massivecraft.factions.cmd; import com.massivecraft.factions.P; -import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.fperms.Access; diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java b/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java index 53bd3e36..93c07219 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java @@ -20,17 +20,15 @@ import java.util.List; public class CmdSeeChunk extends FCommand { - private boolean useParticles; - private int length; - - private ParticleEffect effect; //Used a hashmap cuz imma make a particle selection gui later, will store it where the boolean is rn. public static HashMap seeChunkMap = new HashMap<>(); Long interval = 10L; + private boolean useParticles; + private int length; + private ParticleEffect effect; private int taskID = -1; - //I remade it cause of people getting mad that I had the same seechunk as drtshock @@ -48,7 +46,7 @@ public class CmdSeeChunk extends FCommand { this.useParticles = p.getConfig().getBoolean("see-chunk.particles", true); interval = P.p.getConfig().getLong("see-chunk.interval", 10L); - if (effect == null){ + if (effect == null) { effect = ParticleEffect.REDSTONE; } diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdShowClaims.java b/src/main/java/com/massivecraft/factions/cmd/CmdShowClaims.java index d9f2a016..22e47e3a 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdShowClaims.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdShowClaims.java @@ -3,19 +3,12 @@ package com.massivecraft.factions.cmd; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import com.massivecraft.factions.FLocation; -import com.massivecraft.factions.Faction; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.zcore.util.TL; -import org.bukkit.World; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Set; +public class CmdShowClaims extends FCommand { -public class CmdShowClaims extends FCommand{ - - public CmdShowClaims(){ + public CmdShowClaims() { this.aliases.add("showclaims"); this.aliases.add("showclaim"); @@ -31,20 +24,20 @@ public class CmdShowClaims extends FCommand{ } @Override - public void perform(){ - sendMessage(TL.COMMAND_SHOWCLAIMS_HEADER.toString().replace("{faction}",fme.getFaction().describeTo(fme))); - ListMultimap chunkMap = ArrayListMultimap.create(); + public void perform() { + sendMessage(TL.COMMAND_SHOWCLAIMS_HEADER.toString().replace("{faction}", fme.getFaction().describeTo(fme))); + ListMultimap chunkMap = ArrayListMultimap.create(); String format = TL.COMMAND_SHOWCLAIMS_CHUNKSFORMAT.toString(); - for (FLocation fLocation : fme.getFaction().getAllClaims()){ - chunkMap.put(fLocation.getWorldName(),format.replace("{x}",fLocation.getX() + "").replace("{z}",fLocation.getZ() + "")); + for (FLocation fLocation : fme.getFaction().getAllClaims()) { + chunkMap.put(fLocation.getWorldName(), format.replace("{x}", fLocation.getX() + "").replace("{z}", fLocation.getZ() + "")); } - for (String world : chunkMap.keySet()){ - String message = TL.COMMAND_SHOWCLAIMS_FORMAT.toString().replace("{world}",world); - sendMessage(message.replace("{chunks}","")); // made {chunks} blank as I removed the placeholder and people wont update their config :shrug: + for (String world : chunkMap.keySet()) { + String message = TL.COMMAND_SHOWCLAIMS_FORMAT.toString().replace("{world}", world); + sendMessage(message.replace("{chunks}", "")); // made {chunks} blank as I removed the placeholder and people wont update their config :shrug: StringBuilder chunks = new StringBuilder(""); - for (String chunkString : chunkMap.get(world)){ + for (String chunkString : chunkMap.get(world)) { chunks.append(chunkString + ", "); - if (chunks.toString().length() >= 2000 ) { + if (chunks.toString().length() >= 2000) { sendMessage(chunks.toString()); chunks.setLength(0); } @@ -54,10 +47,6 @@ public class CmdShowClaims extends FCommand{ } - - - - } @Override diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdTntFill.java b/src/main/java/com/massivecraft/factions/cmd/CmdTntFill.java index 604ff658..ef59ef0c 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdTntFill.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdTntFill.java @@ -6,10 +6,8 @@ import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.fperms.Access; import com.massivecraft.factions.zcore.fperms.PermissableAction; import com.massivecraft.factions.zcore.util.TL; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.block.Block; import org.bukkit.block.Dispenser; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -18,7 +16,7 @@ import org.bukkit.inventory.PlayerInventory; public class CmdTntFill extends FCommand { - public CmdTntFill(){ + public CmdTntFill() { super(); this.aliases.add("tntfill"); @@ -35,23 +33,22 @@ public class CmdTntFill extends FCommand { } @Override - public void perform(){ + public void perform() { Access access = fme.getFaction().getAccess(fme, PermissableAction.TNTFILL); if (access.equals(Access.DENY)) { fme.msg(TL.GENERIC_NOPERMISSION, "tntfill"); } - msg(TL.COMMAND_TNTFILL_HEADER); - int radius = argAsInt(0,16); - int amount = argAsInt(1,16); - if (radius > P.p.getConfig().getInt("Tntfill.max-radius")){ - msg(TL.COMMAND_TNTFILL_RADIUSMAX.toString().replace("{max}",P.p.getConfig().getInt("Tntfill.max-radius") + "")); + int radius = argAsInt(0, 16); + int amount = argAsInt(1, 16); + if (radius > P.p.getConfig().getInt("Tntfill.max-radius")) { + msg(TL.COMMAND_TNTFILL_RADIUSMAX.toString().replace("{max}", P.p.getConfig().getInt("Tntfill.max-radius") + "")); return; } - if (amount > P.p.getConfig().getInt("Tntfill.max-amount")){ - msg(TL.COMMAND_TNTFILL_AMOUNTMAX.toString().replace("{max}",P.p.getConfig().getInt("Tntfill.max-amount") + "")); + if (amount > P.p.getConfig().getInt("Tntfill.max-amount")) { + msg(TL.COMMAND_TNTFILL_AMOUNTMAX.toString().replace("{max}", P.p.getConfig().getInt("Tntfill.max-amount") + "")); return; } int testNumber = -1; @@ -72,61 +69,58 @@ public class CmdTntFill extends FCommand { for (double y = start.getY() - radius; y <= start.getY() + radius; y++) { for (double z = start.getZ() - radius; z <= start.getZ() + radius; z++) { Location blockLoc = new Location(start.getWorld(), x, y, z); - if (blockLoc.getBlock().getState() instanceof Dispenser){ - Dispenser disp = (Dispenser) blockLoc.getBlock().getState(); - Inventory dispenser = disp.getInventory(); - if (canHold(dispenser,amount)){ - int fullStacks = amount / 64; - int remainderAmt = amount % 64; - if (!inventoryContains(me.getInventory(), new ItemStack(Material.TNT,amount))){ - if (!fme.getRole().isAtLeast(Role.MODERATOR)){ + if (blockLoc.getBlock().getState() instanceof Dispenser) { + Dispenser disp = (Dispenser) blockLoc.getBlock().getState(); + Inventory dispenser = disp.getInventory(); + if (canHold(dispenser, amount)) { + int fullStacks = amount / 64; + int remainderAmt = amount % 64; + if (!inventoryContains(me.getInventory(), new ItemStack(Material.TNT, amount))) { + if (!fme.getRole().isAtLeast(Role.MODERATOR)) { + msg(TL.COMMAND_TNTFILL_NOTENOUGH); + sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}", amount + "").replace("{dispensers}", counter + "")); + me.updateInventory(); + return; + } else if (bankMode) { + //msg(TL.COMMAND_TNTFILL_MOD.toString().replace("{role}",fme.getRole().nicename)); + bankMode = true; + removeFromBank(amount); + if (!inventoryContains(me.getInventory(), new ItemStack(Material.TNT, amount))) { msg(TL.COMMAND_TNTFILL_NOTENOUGH); - sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}",amount + "").replace("{dispensers}",counter+ "")); + sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}", amount + "").replace("{dispensers}", counter + "")); me.updateInventory(); return; - } else if (bankMode){ - //msg(TL.COMMAND_TNTFILL_MOD.toString().replace("{role}",fme.getRole().nicename)); - bankMode = true; - removeFromBank(amount); - if (!inventoryContains(me.getInventory(), new ItemStack(Material.TNT,amount))){ - msg(TL.COMMAND_TNTFILL_NOTENOUGH); - sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}",amount + "").replace("{dispensers}",counter+ "")); - me.updateInventory(); - return; - } } } - ItemStack tnt64 = new ItemStack(Material.TNT, 64); - for (int i = 0; i <= fullStacks - 1; i++) { - dispenser.addItem(tnt64); - takeTnt(64); - } - if (remainderAmt != 0) { - ItemStack tnt = new ItemStack(Material.TNT, remainderAmt); - dispenser.addItem(tnt); - takeTnt(remainderAmt); - } - //sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}",amount + "").replace("{x}",(int) x + "").replace("{y}",(int) y + "").replace("{z}",(int) z + "")); - counter++; } + ItemStack tnt64 = new ItemStack(Material.TNT, 64); + for (int i = 0; i <= fullStacks - 1; i++) { + dispenser.addItem(tnt64); + takeTnt(64); + } + if (remainderAmt != 0) { + ItemStack tnt = new ItemStack(Material.TNT, remainderAmt); + dispenser.addItem(tnt); + takeTnt(remainderAmt); + } + //sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}",amount + "").replace("{x}",(int) x + "").replace("{y}",(int) y + "").replace("{z}",(int) z + "")); + counter++; + } } } } } if (bankMode) { - msg(TL.COMMAND_TNTFILL_MOD.toString().replace("{role}",fme.getRole().nicename)); + msg(TL.COMMAND_TNTFILL_MOD.toString().replace("{role}", fme.getRole().nicename)); } - sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}",amount + "").replace("{dispensers}",counter+ "")); + sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}", amount + "").replace("{dispensers}", counter + "")); me.updateInventory(); - - - } - private void removeFromBank(int amount){ + private void removeFromBank(int amount) { int testNumber = -1; try { testNumber = Integer.parseInt(args.get(1)); @@ -164,7 +158,7 @@ public class CmdTntFill extends FCommand { me.updateInventory(); } - public void takeTnt(int amount){ + public void takeTnt(int amount) { Inventory inv = me.getInventory(); int invTnt = 0; for (int i = 0; i <= inv.getSize(); i++) { @@ -187,7 +181,7 @@ public class CmdTntFill extends FCommand { removeFromInventory(me.getInventory(), tnt); } - public boolean canHold(Inventory inventory, int amount){ + public boolean canHold(Inventory inventory, int amount) { int fullStacks = amount / 64; int remainderAmt = amount % 64; if ((remainderAmt == 0 && getEmptySlots(me) <= fullStacks)) { diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdUnclaim.java b/src/main/java/com/massivecraft/factions/cmd/CmdUnclaim.java index ef1eb4a8..285b4d9c 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdUnclaim.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdUnclaim.java @@ -49,8 +49,8 @@ public class CmdUnclaim extends FCommand { } new SpiralTask(new FLocation(me), radius) { - private int failCount = 0; private final int limit = Conf.radiusClaimFailureLimit - 1; + private int failCount = 0; @Override public boolean work() { diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdVault.java b/src/main/java/com/massivecraft/factions/cmd/CmdVault.java index 67594c55..bf97b8a7 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdVault.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdVault.java @@ -1,25 +1,15 @@ package com.massivecraft.factions.cmd; -import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; -import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; -import com.drtshock.playervaults.vaultmanagement.VaultOperations; -import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; import com.massivecraft.factions.Board; -import com.massivecraft.factions.Conf; import com.massivecraft.factions.FLocation; import com.massivecraft.factions.P; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.zcore.fperms.Access; import com.massivecraft.factions.zcore.fperms.PermissableAction; import com.massivecraft.factions.zcore.util.TL; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Chest; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.event.Listener; import org.bukkit.inventory.Inventory; public class CmdVault extends FCommand { @@ -39,45 +29,44 @@ public class CmdVault extends FCommand { senderMustBeAdmin = false; } - @Override + @Override public void perform() { - if (!P.p.getConfig().getBoolean("fvault.Enabled")){ + if (!P.p.getConfig().getBoolean("fvault.Enabled")) { fme.sendMessage("This command is disabled!"); return; } - Access access = fme.getFaction().getAccess(fme, PermissableAction.VAULT); + Access access = fme.getFaction().getAccess(fme, PermissableAction.VAULT); if (access.equals(Access.DENY)) { fme.msg(TL.GENERIC_NOPERMISSION, "vault"); return; } - if (fme.isInVault()){ + if (fme.isInVault()) { me.closeInventory(); return; } fme.setInVault(true); Location vaultLocation = fme.getFaction().getVault(); - if (vaultLocation == null){ + if (vaultLocation == null) { fme.msg(TL.COMMAND_VAULT_INVALID); return; } - FLocation vaultFLocation = new FLocation(vaultLocation); - if (Board.getInstance().getFactionAt(vaultFLocation) != fme.getFaction()){ + FLocation vaultFLocation = new FLocation(vaultLocation); + if (Board.getInstance().getFactionAt(vaultFLocation) != fme.getFaction()) { fme.getFaction().setVault(null); fme.msg(TL.COMMAND_VAULT_INVALID); return; } - if (vaultLocation.getBlock().getType() != Material.CHEST){ + if (vaultLocation.getBlock().getType() != Material.CHEST) { fme.getFaction().setVault(null); fme.msg(TL.COMMAND_VAULT_INVALID); return; } - Chest chest = (Chest) vaultLocation.getBlock().getState(); - Inventory chestInv = chest.getBlockInventory(); - fme.msg(TL.COMMAND_VAULT_OPENING); - me.openInventory(chestInv); - + Chest chest = (Chest) vaultLocation.getBlock().getState(); + Inventory chestInv = chest.getBlockInventory(); + fme.msg(TL.COMMAND_VAULT_OPENING); + me.openInventory(chestInv); } diff --git a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java index ea0619a4..e1b676f2 100644 --- a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java +++ b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java @@ -213,7 +213,7 @@ public class FCmdRoot extends FCommand { this.addSubCommand(this.cmdSetBanner); - if (Bukkit.getServer().getPluginManager().getPlugin("CoreProtect") != null){ + if (Bukkit.getServer().getPluginManager().getPlugin("CoreProtect") != null) { P.p.log("Found CoreProtect, enabling Inspect"); this.addSubCommand(this.cmdInspect); } else { @@ -231,10 +231,10 @@ public class FCmdRoot extends FCommand { } if (P.p.isHookedPlayervaults()) { P.p.log("Found playervaults hook, adding /f vault and /f setmaxvault commands."); - // this.addSubCommand(new CmdSetMaxVaults()); - // this.addSubCommand(new CmdVault()); - }else{ - // this.addSubCommand(new CmdVault()); + // this.addSubCommand(new CmdSetMaxVaults()); + // this.addSubCommand(new CmdVault()); + } else { + // this.addSubCommand(new CmdVault()); } } diff --git a/src/main/java/com/massivecraft/factions/cmd/FCommand.java b/src/main/java/com/massivecraft/factions/cmd/FCommand.java index 761994d2..46e41bd3 100644 --- a/src/main/java/com/massivecraft/factions/cmd/FCommand.java +++ b/src/main/java/com/massivecraft/factions/cmd/FCommand.java @@ -100,7 +100,7 @@ public abstract class FCommand extends MCommand

{ return false; } - if (this.senderMustBeColeader && !fme.getRole().isAtLeast(Role.COLEADER)){ + if (this.senderMustBeColeader && !fme.getRole().isAtLeast(Role.COLEADER)) { sender.sendMessage(p.txt.parse("Only faction coleaders can %s.", this.getHelpShort())); return false; } @@ -111,7 +111,6 @@ public abstract class FCommand extends MCommand

{ } - return true; } @@ -266,14 +265,11 @@ public abstract class FCommand extends MCommand

{ return true; } - if (you.getRole().equals(Role.ADMIN)) - { + if (you.getRole().equals(Role.ADMIN)) { i.sendMessage(p.txt.parse("Only the faction admin can do that.")); - } - else if ((you.getRole().equals(Role.COLEADER))) - { - if (i == you){ + } else if ((you.getRole().equals(Role.COLEADER))) { + if (i == you) { return true; } else { i.sendMessage(p.txt.parse("Coleaders can't control each other...")); diff --git a/src/main/java/com/massivecraft/factions/event/FPlayerJoinEvent.java b/src/main/java/com/massivecraft/factions/event/FPlayerJoinEvent.java index ce3148ac..fd9617da 100644 --- a/src/main/java/com/massivecraft/factions/event/FPlayerJoinEvent.java +++ b/src/main/java/com/massivecraft/factions/event/FPlayerJoinEvent.java @@ -12,10 +12,6 @@ public class FPlayerJoinEvent extends FactionPlayerEvent implements Cancellable PlayerJoinReason reason; boolean cancelled = false; - public enum PlayerJoinReason { - CREATE, LEADER, COMMAND - } - public FPlayerJoinEvent(FPlayer fp, Faction f, PlayerJoinReason r) { super(f, fp); reason = r; @@ -39,4 +35,8 @@ public class FPlayerJoinEvent extends FactionPlayerEvent implements Cancellable public void setCancelled(boolean c) { cancelled = c; } + + public enum PlayerJoinReason { + CREATE, LEADER, COMMAND + } } \ No newline at end of file diff --git a/src/main/java/com/massivecraft/factions/event/FPlayerLeaveEvent.java b/src/main/java/com/massivecraft/factions/event/FPlayerLeaveEvent.java index a080a6a6..e9b764d9 100644 --- a/src/main/java/com/massivecraft/factions/event/FPlayerLeaveEvent.java +++ b/src/main/java/com/massivecraft/factions/event/FPlayerLeaveEvent.java @@ -6,12 +6,8 @@ import org.bukkit.event.Cancellable; public class FPlayerLeaveEvent extends FactionPlayerEvent implements Cancellable { - private PlayerLeaveReason reason; boolean cancelled = false; - - public enum PlayerLeaveReason { - KICKED, DISBAND, RESET, JOINOTHER, LEAVE, BANNED - } + private PlayerLeaveReason reason; public FPlayerLeaveEvent(FPlayer p, Faction f, PlayerLeaveReason r) { super(f, p); @@ -37,4 +33,8 @@ public class FPlayerLeaveEvent extends FactionPlayerEvent implements Cancellable // Don't let them cancel factions disbanding. cancelled = reason != PlayerLeaveReason.DISBAND && reason != PlayerLeaveReason.RESET && c; } + + public enum PlayerLeaveReason { + KICKED, DISBAND, RESET, JOINOTHER, LEAVE, BANNED + } } \ No newline at end of file diff --git a/src/main/java/com/massivecraft/factions/event/FactionCreateEvent.java b/src/main/java/com/massivecraft/factions/event/FactionCreateEvent.java index 0afc612c..afdd1ab4 100644 --- a/src/main/java/com/massivecraft/factions/event/FactionCreateEvent.java +++ b/src/main/java/com/massivecraft/factions/event/FactionCreateEvent.java @@ -24,6 +24,10 @@ public class FactionCreateEvent extends Event implements Cancellable { this.cancelled = false; } + public static HandlerList getHandlerList() { + return handlers; + } + public FPlayer getFPlayer() { return FPlayers.getInstance().getByPlayer(sender); } @@ -36,10 +40,6 @@ public class FactionCreateEvent extends Event implements Cancellable { return handlers; } - public static HandlerList getHandlerList() { - return handlers; - } - @Override public boolean isCancelled() { return cancelled; diff --git a/src/main/java/com/massivecraft/factions/event/FactionEvent.java b/src/main/java/com/massivecraft/factions/event/FactionEvent.java index 53c87fd8..dea34adb 100644 --- a/src/main/java/com/massivecraft/factions/event/FactionEvent.java +++ b/src/main/java/com/massivecraft/factions/event/FactionEvent.java @@ -16,6 +16,10 @@ public class FactionEvent extends Event { this.faction = faction; } + public static HandlerList getHandlerList() { + return handlers; + } + /** * Get the Faction involved in the event. * @@ -29,8 +33,4 @@ public class FactionEvent extends Event { return handlers; } - public static HandlerList getHandlerList() { - return handlers; - } - } diff --git a/src/main/java/com/massivecraft/factions/event/FactionRelationEvent.java b/src/main/java/com/massivecraft/factions/event/FactionRelationEvent.java index a9b6a2f5..93b6cab2 100644 --- a/src/main/java/com/massivecraft/factions/event/FactionRelationEvent.java +++ b/src/main/java/com/massivecraft/factions/event/FactionRelationEvent.java @@ -24,11 +24,11 @@ public class FactionRelationEvent extends Event { frel = rel; } - public HandlerList getHandlers() { + public static HandlerList getHandlerList() { return handlers; } - public static HandlerList getHandlerList() { + public HandlerList getHandlers() { return handlers; } diff --git a/src/main/java/com/massivecraft/factions/integration/Econ.java b/src/main/java/com/massivecraft/factions/integration/Econ.java index 52e1bc64..63900c3f 100644 --- a/src/main/java/com/massivecraft/factions/integration/Econ.java +++ b/src/main/java/com/massivecraft/factions/integration/Econ.java @@ -23,6 +23,7 @@ import java.util.logging.Level; public class Econ { + private static final DecimalFormat format = new DecimalFormat(TL.ECON_FORMAT.toString()); private static Economy econ = null; public static void setup() { @@ -61,7 +62,6 @@ public class Econ { return econ != null; } - public static void modifyUniverseMoney(double delta) { if (!shouldBeUsed()) { return; @@ -369,16 +369,16 @@ public class Econ { return amount; } - // calculate refund amount for all owned land - public static double calculateTotalLandRefund(int ownedLand) { - return calculateTotalLandValue(ownedLand) * Conf.econClaimRefundMultiplier; - } - // -------------------------------------------- // // Standard account management methods // -------------------------------------------- // + // calculate refund amount for all owned land + public static double calculateTotalLandRefund(int ownedLand) { + return calculateTotalLandValue(ownedLand) * Conf.econClaimRefundMultiplier; + } + public static boolean hasAccount(String name) { return econ.hasAccount(name); } @@ -387,8 +387,6 @@ public class Econ { return econ.getBalance(account); } - private static final DecimalFormat format = new DecimalFormat(TL.ECON_FORMAT.toString()); - public static String getFriendlyBalance(UUID uuid) { OfflinePlayer offline = Bukkit.getOfflinePlayer(uuid); if (offline.getName() == null) { diff --git a/src/main/java/com/massivecraft/factions/integration/dynmap/DynmapStyle.java b/src/main/java/com/massivecraft/factions/integration/dynmap/DynmapStyle.java index e34d78cd..7fb28c15 100644 --- a/src/main/java/com/massivecraft/factions/integration/dynmap/DynmapStyle.java +++ b/src/main/java/com/massivecraft/factions/integration/dynmap/DynmapStyle.java @@ -8,89 +8,16 @@ public class DynmapStyle { // -------------------------------------------- // public String lineColor = null; - - public int getLineColor() { - return getColor(coalesce(this.lineColor, Conf.dynmapDefaultStyle.lineColor, Conf.DYNMAP_STYLE_LINE_COLOR)); - } - - public DynmapStyle setStrokeColor(String strokeColor) { - this.lineColor = strokeColor; - return this; - } - public Double lineOpacity = null; - - public double getLineOpacity() { - return coalesce(this.lineOpacity, Conf.dynmapDefaultStyle.lineOpacity, Conf.DYNMAP_STYLE_LINE_OPACITY); - } - - public DynmapStyle setLineOpacity(Double strokeOpacity) { - this.lineOpacity = strokeOpacity; - return this; - } - public Integer lineWeight = null; - - public int getLineWeight() { - return coalesce(this.lineWeight, Conf.dynmapDefaultStyle.lineWeight, Conf.DYNMAP_STYLE_LINE_WEIGHT); - } - - public DynmapStyle setLineWeight(Integer strokeWeight) { - this.lineWeight = strokeWeight; - return this; - } - public String fillColor = null; - - public int getFillColor() { - return getColor(coalesce(this.fillColor, Conf.dynmapDefaultStyle.fillColor, Conf.DYNMAP_STYLE_FILL_COLOR)); - } - - public DynmapStyle setFillColor(String fillColor) { - this.fillColor = fillColor; - return this; - } - public Double fillOpacity = null; - - public double getFillOpacity() { - return coalesce(this.fillOpacity, Conf.dynmapDefaultStyle.fillOpacity, Conf.DYNMAP_STYLE_FILL_OPACITY); - } - - public DynmapStyle setFillOpacity(Double fillOpacity) { - this.fillOpacity = fillOpacity; - return this; - } - // NOTE: We just return the string here. We do not return the resolved Dynmap MarkerIcon object. // The reason is we use this class in the MConf. For serialization to work Dynmap would have to be loaded and we can't require that. // Using dynmap is optional. public String homeMarker = null; - - public String getHomeMarker() { - return coalesce(this.homeMarker, Conf.dynmapDefaultStyle.homeMarker, Conf.DYNMAP_STYLE_HOME_MARKER); - } - - public DynmapStyle setHomeMarker(String homeMarker) { - this.homeMarker = homeMarker; - return this; - } - public Boolean boost = null; - public boolean getBoost() { - return coalesce(this.boost, Conf.dynmapDefaultStyle.boost, Conf.DYNMAP_STYLE_BOOST); - } - - public DynmapStyle setBoost(Boolean boost) { - this.boost = boost; - return this; - } - - // -------------------------------------------- // - // UTIL - // -------------------------------------------- // - @SafeVarargs public static T coalesce(T... items) { for (T item : items) { @@ -110,4 +37,71 @@ public class DynmapStyle { return ret; } + public int getLineColor() { + return getColor(coalesce(this.lineColor, Conf.dynmapDefaultStyle.lineColor, Conf.DYNMAP_STYLE_LINE_COLOR)); + } + + public DynmapStyle setStrokeColor(String strokeColor) { + this.lineColor = strokeColor; + return this; + } + + public double getLineOpacity() { + return coalesce(this.lineOpacity, Conf.dynmapDefaultStyle.lineOpacity, Conf.DYNMAP_STYLE_LINE_OPACITY); + } + + public DynmapStyle setLineOpacity(Double strokeOpacity) { + this.lineOpacity = strokeOpacity; + return this; + } + + public int getLineWeight() { + return coalesce(this.lineWeight, Conf.dynmapDefaultStyle.lineWeight, Conf.DYNMAP_STYLE_LINE_WEIGHT); + } + + public DynmapStyle setLineWeight(Integer strokeWeight) { + this.lineWeight = strokeWeight; + return this; + } + + public int getFillColor() { + return getColor(coalesce(this.fillColor, Conf.dynmapDefaultStyle.fillColor, Conf.DYNMAP_STYLE_FILL_COLOR)); + } + + public DynmapStyle setFillColor(String fillColor) { + this.fillColor = fillColor; + return this; + } + + public double getFillOpacity() { + return coalesce(this.fillOpacity, Conf.dynmapDefaultStyle.fillOpacity, Conf.DYNMAP_STYLE_FILL_OPACITY); + } + + public DynmapStyle setFillOpacity(Double fillOpacity) { + this.fillOpacity = fillOpacity; + return this; + } + + public String getHomeMarker() { + return coalesce(this.homeMarker, Conf.dynmapDefaultStyle.homeMarker, Conf.DYNMAP_STYLE_HOME_MARKER); + } + + public DynmapStyle setHomeMarker(String homeMarker) { + this.homeMarker = homeMarker; + return this; + } + + // -------------------------------------------- // + // UTIL + // -------------------------------------------- // + + public boolean getBoost() { + return coalesce(this.boost, Conf.dynmapDefaultStyle.boost, Conf.DYNMAP_STYLE_BOOST); + } + + public DynmapStyle setBoost(Boolean boost) { + this.boost = boost; + return this; + } + } diff --git a/src/main/java/com/massivecraft/factions/integration/dynmap/EngineDynmap.java b/src/main/java/com/massivecraft/factions/integration/dynmap/EngineDynmap.java index b6923777..5dc9d7ab 100644 --- a/src/main/java/com/massivecraft/factions/integration/dynmap/EngineDynmap.java +++ b/src/main/java/com/massivecraft/factions/integration/dynmap/EngineDynmap.java @@ -41,17 +41,64 @@ public class EngineDynmap { // -------------------------------------------- // private static EngineDynmap i = new EngineDynmap(); + public DynmapAPI dynmapApi; + public MarkerAPI markerApi; + public MarkerSet markerset; + private EngineDynmap() { + } public static EngineDynmap getInstance() { return i; } - private EngineDynmap() { + public static String getHtmlPlayerString(Collection playersOfficersList) { + StringBuilder ret = new StringBuilder(); + for (FPlayer fplayer : playersOfficersList) { + if (ret.length() > 0) { + ret.append(", "); + } + ret.append(getHtmlPlayerName(fplayer)); + } + return ret.toString(); } - public DynmapAPI dynmapApi; - public MarkerAPI markerApi; - public MarkerSet markerset; + public static String getHtmlPlayerName(FPlayer fplayer) { + if (fplayer == null) { + return "none"; + } + return escapeHtml(fplayer.getName()); + } + + public static String escapeHtml(String string) { + StringBuilder out = new StringBuilder(Math.max(16, string.length())); + for (int i = 0; i < string.length(); i++) { + char c = string.charAt(i); + if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') { + out.append("&#"); + out.append((int) c); + out.append(';'); + } else { + out.append(c); + } + } + return out.toString(); + } + + // Thread Safe / Asynchronous: Yes + public static void info(String msg) { + String message = DYNMAP_INTEGRATION + msg; + System.out.println(message); + } + + // -------------------------------------------- // + // UPDATE: HOMES + // -------------------------------------------- // + + // Thread Safe / Asynchronous: Yes + public static void severe(String msg) { + String message = DYNMAP_INTEGRATION + ChatColor.RED.toString() + msg; + System.out.println(message); + } public void init() { Plugin dynmap = Bukkit.getServer().getPluginManager().getPlugin("dynmap"); @@ -94,6 +141,10 @@ public class EngineDynmap { }, 100L, 100L); } + // -------------------------------------------- // + // UPDATE: AREAS + // -------------------------------------------- // + // Thread Safe / Asynchronous: No public boolean updateCore() { // Get DynmapAPI @@ -138,10 +189,6 @@ public class EngineDynmap { return true; } - // -------------------------------------------- // - // UPDATE: HOMES - // -------------------------------------------- // - // Thread Safe / Asynchronous: Yes public Map createHomes() { Map ret = new HashMap<>(); @@ -208,7 +255,7 @@ public class EngineDynmap { } // -------------------------------------------- // - // UPDATE: AREAS + // UPDATE: PLAYERSET // -------------------------------------------- // // Thread Safe: YES @@ -449,6 +496,10 @@ public class EngineDynmap { return ret; } + // -------------------------------------------- // + // UTIL & SHARED + // -------------------------------------------- // + // Thread Safe: NO public void updateAreas(Map areas) { // Map Current @@ -482,10 +533,6 @@ public class EngineDynmap { } } - // -------------------------------------------- // - // UPDATE: PLAYERSET - // -------------------------------------------- // - // Thread Safe / Asynchronous: Yes public String createPlayersetId(Faction faction) { if (faction == null) { @@ -589,10 +636,6 @@ public class EngineDynmap { } } - // -------------------------------------------- // - // UTIL & SHARED - // -------------------------------------------- // - // Thread Safe / Asynchronous: Yes private String getDescription(Faction faction) { String ret = "

" + Conf.dynmapDescription + "
"; @@ -653,39 +696,6 @@ public class EngineDynmap { return ret; } - public static String getHtmlPlayerString(Collection playersOfficersList) { - StringBuilder ret = new StringBuilder(); - for (FPlayer fplayer : playersOfficersList) { - if (ret.length() > 0) { - ret.append(", "); - } - ret.append(getHtmlPlayerName(fplayer)); - } - return ret.toString(); - } - - public static String getHtmlPlayerName(FPlayer fplayer) { - if (fplayer == null) { - return "none"; - } - return escapeHtml(fplayer.getName()); - } - - public static String escapeHtml(String string) { - StringBuilder out = new StringBuilder(Math.max(16, string.length())); - for (int i = 0; i < string.length(); i++) { - char c = string.charAt(i); - if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') { - out.append("&#"); - out.append((int) c); - out.append(';'); - } else { - out.append(c); - } - } - return out.toString(); - } - // Thread Safe / Asynchronous: Yes private boolean isVisible(Faction faction, String world) { if (faction == null) { @@ -727,22 +737,6 @@ public class EngineDynmap { return Conf.dynmapDefaultStyle; } - // Thread Safe / Asynchronous: Yes - public static void info(String msg) { - String message = DYNMAP_INTEGRATION + msg; - System.out.println(message); - } - - // Thread Safe / Asynchronous: Yes - public static void severe(String msg) { - String message = DYNMAP_INTEGRATION + ChatColor.RED.toString() + msg; - System.out.println(message); - } - - enum Direction { - XPLUS, ZPLUS, XMINUS, ZMINUS - } - // Find all contiguous blocks, set in target and clear in source private int floodFillTarget(TileFlags source, TileFlags destination, int x, int y) { int cnt = 0; @@ -773,4 +767,8 @@ public class EngineDynmap { } return cnt; } + + enum Direction { + XPLUS, ZPLUS, XMINUS, ZMINUS + } } diff --git a/src/main/java/com/massivecraft/factions/integration/dynmap/TempAreaMarker.java b/src/main/java/com/massivecraft/factions/integration/dynmap/TempAreaMarker.java index ff98ba45..1346aad8 100644 --- a/src/main/java/com/massivecraft/factions/integration/dynmap/TempAreaMarker.java +++ b/src/main/java/com/massivecraft/factions/integration/dynmap/TempAreaMarker.java @@ -27,6 +27,32 @@ public class TempAreaMarker { // CREATE // -------------------------------------------- // + public static boolean equals(AreaMarker marker, double x[], double z[]) { + int length = marker.getCornerCount(); + + if (x.length != length) { + return false; + } + if (z.length != length) { + return false; + } + + for (int i = 0; i < length; i++) { + if (marker.getCornerX(i) != x[i]) { + return false; + } + if (marker.getCornerZ(i) != z[i]) { + return false; + } + } + + return true; + } + + // -------------------------------------------- // + // UPDATE + // -------------------------------------------- // + public AreaMarker create(MarkerSet markerset, String markerId) { AreaMarker ret = markerset.createAreaMarker(markerId, this.label, false, this.world, this.x, this.z, false // not persistent ); @@ -51,7 +77,7 @@ public class TempAreaMarker { } // -------------------------------------------- // - // UPDATE + // UTIL // -------------------------------------------- // public void update(AreaMarker marker) { @@ -87,30 +113,4 @@ public class TempAreaMarker { } } - // -------------------------------------------- // - // UTIL - // -------------------------------------------- // - - public static boolean equals(AreaMarker marker, double x[], double z[]) { - int length = marker.getCornerCount(); - - if (x.length != length) { - return false; - } - if (z.length != length) { - return false; - } - - for (int i = 0; i < length; i++) { - if (marker.getCornerX(i) != x[i]) { - return false; - } - if (marker.getCornerZ(i) != z[i]) { - return false; - } - } - - return true; - } - } diff --git a/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarker.java b/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarker.java index ee3bbd5e..b8eefdbe 100644 --- a/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarker.java +++ b/src/main/java/com/massivecraft/factions/integration/dynmap/TempMarker.java @@ -23,6 +23,18 @@ public class TempMarker { // CREATE // -------------------------------------------- // + public static MarkerIcon getMarkerIcon(MarkerAPI markerApi, String name) { + MarkerIcon ret = markerApi.getMarkerIcon(name); + if (ret == null) { + ret = markerApi.getMarkerIcon(Conf.DYNMAP_STYLE_HOME_MARKER); + } + return ret; + } + + // -------------------------------------------- // + // UPDATE + // -------------------------------------------- // + public Marker create(MarkerAPI markerApi, MarkerSet markerset, String markerId) { Marker ret = markerset.createMarker(markerId, this.label, this.world, this.x, this.y, this.z, getMarkerIcon(markerApi, this.iconName), false // not persistent ); @@ -37,7 +49,7 @@ public class TempMarker { } // -------------------------------------------- // - // UPDATE + // UTIL // -------------------------------------------- // public void update(MarkerAPI markerApi, Marker marker) { @@ -59,16 +71,4 @@ public class TempMarker { } } - // -------------------------------------------- // - // UTIL - // -------------------------------------------- // - - public static MarkerIcon getMarkerIcon(MarkerAPI markerApi, String name) { - MarkerIcon ret = markerApi.getMarkerIcon(name); - if (ret == null) { - ret = markerApi.getMarkerIcon(Conf.DYNMAP_STYLE_HOME_MARKER); - } - return ret; - } - } diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java index db992628..20468035 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsBlockListener.java @@ -26,6 +26,123 @@ public class FactionsBlockListener implements Listener { this.p = p; } + 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()); + 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; + } + if (P.p.getConfig().getBoolean("hcf.raidable", false) && otherFaction.getLandRounded() >= otherFaction.getPowerRounded()) { + return true; + } + + Faction myFaction = me.getFaction(); + Relation rel = myFaction.getRelationTo(otherFaction); + boolean online = otherFaction.hasPlayersOnline(); + boolean pain = !justCheck && rel.confPainBuild(online); + boolean deny = rel.confDenyBuild(online); + + // hurt the player for building/destroying in other territory? + if (pain) { + player.damage(Conf.actionDeniedPainAmount); + + if (!deny) { + me.msg("It is painful to try to " + action + " in the territory of " + otherFaction.getTag(myFaction)); + } + } + + Access access = otherFaction.getAccess(me, PermissableAction.fromString(action)); + if (access != null && access != Access.UNDEFINED) { + // TODO: Update this once new access values are added other than just allow / deny. + if (access == Access.DENY) { + me.msg(TL.GENERIC_NOPERMISSION, action); + return false; + } + + return true; // has to be allow + } + + // cancel building/destroying in other territory? + if (deny) { + if (!justCheck) { + me.msg("You can't " + action + " in the territory of " + otherFaction.getTag(myFaction)); + } + + return false; + } + + // Also cancel and/or cause pain if player doesn't have ownership rights for this claim + if (Conf.ownedAreasEnabled && (Conf.ownedAreaDenyBuild || Conf.ownedAreaPainBuild) && !otherFaction.playerHasOwnershipRights(me, loc)) { + if (!pain && Conf.ownedAreaPainBuild && !justCheck) { + player.damage(Conf.actionDeniedPainAmount); + + if (!Conf.ownedAreaDenyBuild) { + me.msg("It is painful to try to " + action + " in this territory, it is owned by: " + otherFaction.getOwnerListString(loc)); + } + } + if (Conf.ownedAreaDenyBuild) { + if (!justCheck) { + me.msg("You can't " + action + " in this territory, it is owned by: " + otherFaction.getOwnerListString(loc)); + } + + return false; + } + } + + return true; + } + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockPlace(BlockPlaceEvent event) { if (!event.canBuild()) { @@ -189,121 +306,4 @@ public class FactionsBlockListener implements Listener { return !rel.confDenyBuild(otherFaction.hasPlayersOnline()); } - - 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()); - 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; - } - if (P.p.getConfig().getBoolean("hcf.raidable", false) && otherFaction.getLandRounded() >= otherFaction.getPowerRounded()) { - return true; - } - - Faction myFaction = me.getFaction(); - Relation rel = myFaction.getRelationTo(otherFaction); - boolean online = otherFaction.hasPlayersOnline(); - boolean pain = !justCheck && rel.confPainBuild(online); - boolean deny = rel.confDenyBuild(online); - - // hurt the player for building/destroying in other territory? - if (pain) { - player.damage(Conf.actionDeniedPainAmount); - - if (!deny) { - me.msg("It is painful to try to " + action + " in the territory of " + otherFaction.getTag(myFaction)); - } - } - - Access access = otherFaction.getAccess(me, PermissableAction.fromString(action)); - if (access != null && access != Access.UNDEFINED) { - // TODO: Update this once new access values are added other than just allow / deny. - if (access == Access.DENY) { - me.msg(TL.GENERIC_NOPERMISSION, action); - return false; - } - - return true; // has to be allow - } - - // cancel building/destroying in other territory? - if (deny) { - if (!justCheck) { - me.msg("You can't " + action + " in the territory of " + otherFaction.getTag(myFaction)); - } - - return false; - } - - // Also cancel and/or cause pain if player doesn't have ownership rights for this claim - if (Conf.ownedAreasEnabled && (Conf.ownedAreaDenyBuild || Conf.ownedAreaPainBuild) && !otherFaction.playerHasOwnershipRights(me, loc)) { - if (!pain && Conf.ownedAreaPainBuild && !justCheck) { - player.damage(Conf.actionDeniedPainAmount); - - if (!Conf.ownedAreaDenyBuild) { - me.msg("It is painful to try to " + action + " in this territory, it is owned by: " + otherFaction.getOwnerListString(loc)); - } - } - if (Conf.ownedAreaDenyBuild) { - if (!justCheck) { - me.msg("You can't " + action + " in this territory, it is owned by: " + otherFaction.getOwnerListString(loc)); - } - - return false; - } - } - - return true; - } } diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java index 3a80dc09..717a1e23 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -29,6 +29,7 @@ import java.util.*; public class FactionsEntityListener implements Listener { + private static final Set badPotionEffects = new LinkedHashSet<>(Arrays.asList(PotionEffectType.BLINDNESS, PotionEffectType.CONFUSION, PotionEffectType.HARM, PotionEffectType.HUNGER, PotionEffectType.POISON, PotionEffectType.SLOW, PotionEffectType.SLOW_DIGGING, PotionEffectType.WEAKNESS, PotionEffectType.WITHER)); public P p; public FactionsEntityListener(P p) { @@ -142,7 +143,7 @@ public class FactionsEntityListener implements Listener { cancelFStuckTeleport((Player) damagee); cancelFFly((Player) damagee); FPlayer fplayer = FPlayers.getInstance().getByPlayer((Player) damagee); - if (fplayer.isInspectMode()){ + if (fplayer.isInspectMode()) { fplayer.setInspectMode(false); fplayer.msg(TL.COMMAND_INSPECT_DISABLED_MSG); } @@ -151,7 +152,7 @@ public class FactionsEntityListener implements Listener { cancelFStuckTeleport((Player) damager); cancelFFly((Player) damager); FPlayer fplayer = FPlayers.getInstance().getByPlayer((Player) damager); - if (fplayer.isInspectMode()){ + if (fplayer.isInspectMode()) { fplayer.setInspectMode(false); fplayer.msg(TL.COMMAND_INSPECT_DISABLED_MSG); } @@ -288,7 +289,6 @@ public class FactionsEntityListener implements Listener { // No condition retained, destroy the block! } - // mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityCombustByEntity(EntityCombustByEntityEvent event) { @@ -298,8 +298,6 @@ public class FactionsEntityListener implements Listener { } } - private static final Set badPotionEffects = new LinkedHashSet<>(Arrays.asList(PotionEffectType.BLINDNESS, PotionEffectType.CONFUSION, PotionEffectType.HARM, PotionEffectType.HUNGER, PotionEffectType.POISON, PotionEffectType.SLOW, PotionEffectType.SLOW_DIGGING, PotionEffectType.WEAKNESS, PotionEffectType.WITHER)); - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPotionSplashEvent(PotionSplashEvent event) { // see if the potion has a harmful effect @@ -659,9 +657,9 @@ public class FactionsEntityListener implements Listener { } @EventHandler - public void onBowHit(EntityDamageByEntityEvent e){ - if (e.getDamager() instanceof Projectile){ - if (e.getEntity() instanceof Player){ + public void onBowHit(EntityDamageByEntityEvent e) { + if (e.getDamager() instanceof Projectile) { + if (e.getEntity() instanceof Player) { Projectile arrow = ((Projectile) e.getDamager()); if (arrow.getShooter() instanceof Player) { Player damager = (Player) ((Projectile) e.getDamager()).getShooter(); diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsExploitListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsExploitListener.java index 1ce575a3..3de7ca5c 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsExploitListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsExploitListener.java @@ -13,6 +13,10 @@ import org.bukkit.event.player.PlayerTeleportEvent; public class FactionsExploitListener implements Listener { + public static boolean clippingThrough(Location target, Location from, double thickness) { + return ((from.getX() > target.getX() && (from.getX() - target.getX() < thickness)) || (target.getX() > from.getX() && (target.getX() - from.getX() < thickness)) || (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness)) || (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))); + } + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void obsidianGenerator(BlockFromToEvent event) { if (!Conf.handleExploitObsidianGenerators) { @@ -54,8 +58,4 @@ public class FactionsExploitListener implements Listener { event.setTo(target); } - - public static boolean clippingThrough(Location target, Location from, double thickness) { - return ((from.getX() > target.getX() && (from.getX() - target.getX() < thickness)) || (target.getX() > from.getX() && (target.getX() - from.getX() < thickness)) || (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness)) || (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))); - } } diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java index 536472e6..7a4a3f4b 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -52,7 +52,14 @@ import java.util.logging.Level; public class FactionsPlayerListener implements Listener { + public static HashMap bannerLocations = new HashMap<>(); + HashMap fallMap = new HashMap<>(); + HashMap bannerCooldownMap = new HashMap<>(); private P p; + // Holds the next time a player can have a map shown. + private HashMap showTimes = new HashMap<>(); + // for handling people who repeatedly spam attempts to open a door (or similar) in another faction's territory + private Map interactSpammers = new HashMap<>(); public FactionsPlayerListener(P p) { this.p = p; @@ -61,634 +68,12 @@ public class FactionsPlayerListener implements Listener { } } - @EventHandler - public void onVaultPlace(BlockPlaceEvent e) { - if (e.getItemInHand().getType() == Material.CHEST) { - ItemStack vault = P.p.createItem(Material.CHEST, 1, (short) 0, P.p.color(P.p.getConfig().getString("fvault.Item.Name")), P.p.colorList(P.p.getConfig().getStringList("fvault.Item.Lore"))); - if (e.getItemInHand().equals(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; - } - - if (blockLoc.getBlock().getType() == Material.CHEST) { - e.setCancelled(true); - fme.msg(TL.COMMAND_GETVAULT_CHESTNEAR); - return; - } - } - } - } - - fme.msg(TL.COMMAND_GETVAULT_SUCCESS); - fme.getFaction().setVault(e.getBlockPlaced().getLocation()); - - } - } - } - - - HashMap fallMap = new HashMap<>(); - - @EventHandler(priority = EventPriority.NORMAL) - public void onPlayerJoin(PlayerJoinEvent event) { - initPlayer(event.getPlayer()); - } - - private void initPlayer(Player player) { - // Make sure that all online players do have a fplayer. - final FPlayer me = FPlayers.getInstance().getByPlayer(player); - ((MemoryFPlayer) me).setName(player.getName()); - - // Update the lastLoginTime for this fplayer - me.setLastLoginTime(System.currentTimeMillis()); - - // Store player's current FLocation and notify them where they are - me.setLastStoodAt(new FLocation(player.getLocation())); - - me.login(); // set kills / deaths - - // Check for Faction announcements. Let's delay this so they actually see it. - Bukkit.getScheduler().runTaskLater(P.p, new Runnable() { - @Override - public void run() { - if (me.isOnline()) { - me.getFaction().sendUnreadAnnouncements(me); - } - } - }, 33L); // Don't ask me why. - - if (P.p.getConfig().getBoolean("scoreboard.default-enabled", false)) { - FScoreboard.init(me); - FScoreboard.get(me).setDefaultSidebar(new FDefaultSidebar(), P.p.getConfig().getInt("default-update-interval", 20)); - FScoreboard.get(me).setSidebarVisibility(me.showScoreboard()); - } - - Faction myFaction = me.getFaction(); - if (!myFaction.isWilderness()) { - for (FPlayer other : myFaction.getFPlayersWhereOnline(true)) { - if (other != me && other.isMonitoringJoins()) { - other.msg(TL.FACTION_LOGIN, me.getName()); - } - } - } - - - fallMap.put(me.getPlayer(), false); - Bukkit.getScheduler().scheduleSyncDelayedTask(P.p, new Runnable() { - @Override - public void run() { - if (fallMap.containsKey(me.getPlayer())) { - fallMap.remove(me.getPlayer()); - } - - } - }, 180L); - - - if (me.isSpyingChat() && !player.hasPermission(Permission.CHATSPY.node)) { - me.setSpyingChat(false); - P.p.log(Level.INFO, "Found %s spying chat without permission on login. Disabled their chat spying.", player.getName()); - } - - if (me.isAdminBypassing() && !player.hasPermission(Permission.BYPASS.node)) { - me.setIsAdminBypassing(false); - P.p.log(Level.INFO, "Found %s on admin Bypass without permission on login. Disabled it for them.", player.getName()); - } - - - // If they have the permission, don't let them autoleave. Bad inverted setter :\ - me.setAutoLeave(!player.hasPermission(Permission.AUTO_LEAVE_BYPASS.node)); - me.setTakeFallDamage(true); - } - - @EventHandler - public void onPlayerFall(EntityDamageEvent e) { - if (e.getEntity() instanceof Player) { - if (e.getCause() == EntityDamageEvent.DamageCause.FALL) { - Player player = (Player) e.getEntity(); - if (fallMap.containsKey(player)) { - e.setCancelled(true); - fallMap.remove(player); - } - } - } - } - - - @EventHandler(priority = EventPriority.NORMAL) - public void onPlayerQuit(PlayerQuitEvent event) { - FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer()); - - // Make sure player's power is up to date when they log off. - me.getPower(); - // and update their last login time to point to when the logged off, for auto-remove routine - me.setLastLoginTime(System.currentTimeMillis()); - - me.logout(); // cache kills / deaths - - // if player is waiting for fstuck teleport but leaves, remove - if (P.p.getStuckMap().containsKey(me.getPlayer().getUniqueId())) { - FPlayers.getInstance().getByPlayer(me.getPlayer()).msg(TL.COMMAND_STUCK_CANCELLED); - P.p.getStuckMap().remove(me.getPlayer().getUniqueId()); - P.p.getTimers().remove(me.getPlayer().getUniqueId()); - } - - Faction myFaction = me.getFaction(); - if (!myFaction.isWilderness()) { - myFaction.memberLoggedOff(); - } - - if (!myFaction.isWilderness()) { - for (FPlayer player : myFaction.getFPlayersWhereOnline(true)) { - if (player != me && player.isMonitoringJoins()) { - player.msg(TL.FACTION_LOGOUT, me.getName()); - } - } - } - - if (CmdSeeChunk.seeChunkMap.containsKey(event.getPlayer().getName())) { - CmdSeeChunk.seeChunkMap.remove(event.getPlayer().getName()); - } - - FScoreboard.remove(me); - } - - - public String parseAllPlaceholders(String string, Faction faction) { - string = string.replace("{Faction}", faction.getTag()) - .replace("{online}", faction.getOnlinePlayers().size() + "") - .replace("{offline}", faction.getFPlayers().size() - faction.getOnlinePlayers().size() + "") - .replace("{chunks}", faction.getAllClaims().size() + "") - .replace("{power}", faction.getPower() + "") - .replace("{leader}", faction.getFPlayerAdmin() + ""); - - - return string; - } - - public void enableFly(FPlayer me) { - if (P.p.getConfig().getBoolean("ffly.AutoEnable")) { - - me.setFlying(true); - CmdFly.flyMap.put(me.getName(), true); - if (CmdFly.id == -1) { - if (P.p.getConfig().getBoolean("ffly.Particles.Enabled")) { - CmdFly.startParticles(); - } - } - if (CmdFly.flyid == -1) { - CmdFly.startFlyCheck(); - } - } - } - - //inspect - @EventHandler - public void onInspect(PlayerInteractEvent e){ - if (e.getAction().name().contains("BLOCK")){ - FPlayer fplayer = FPlayers.getInstance().getByPlayer(e.getPlayer()); - if (!fplayer.isInspectMode()){ - return; - } - e.setCancelled(true); - if (!fplayer.isAdminBypassing()){ - if (!fplayer.hasFaction()){ - fplayer.setInspectMode(false); - fplayer.msg(TL.COMMAND_INSPECT_DISABLED_NOFAC); - return; - } - if (fplayer.getFaction() != Board.getInstance().getFactionAt(new FLocation(e.getPlayer().getLocation()))){ - fplayer.msg(TL.COMMAND_INSPECT_NOTINCLAIM); - return; - } - } else { - fplayer.msg(TL.COMMAND_INSPECT_BYPASS); - } - List info = CoreProtect.getInstance().getAPI().blockLookup(e.getClickedBlock(),0); - if (info.size() == 0) { - e.getPlayer().sendMessage(TL.COMMAND_INSPECT_NODATA.toString()); - return; - } - Player player = e.getPlayer(); - CoreProtectAPI coAPI = CoreProtect.getInstance().getAPI(); - player.sendMessage(TL.COMMAND_INSPECT_HEADER.toString().replace("{x}",e.getClickedBlock().getX() + "") - .replace("{y}",e.getClickedBlock().getY() + "") - .replace("{z}",e.getClickedBlock().getZ() + "")); - String rowFormat = TL.COMMAND_INSPECT_ROW.toString(); - for (int i = 0; i < info.size(); i++){ - CoreProtectAPI.ParseResult row = coAPI.parseResult(info.get(0)); - player.sendMessage(rowFormat - .replace("{time}",convertTime(row.getTime())) - .replace("{action}",row.getActionString()) - .replace("{player}",row.getPlayer()) - .replace("{block-type}",row.getType().toString().toLowerCase())); - } - } - } - - - //For disabling enderpearl throws - @EventHandler - public void onPearl(PlayerInteractEvent e) { - Player player = e.getPlayer(); - if (player.getItemInHand().getType() == Material.ENDER_PEARL) { - FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); - if (fPlayer.isFlying()) { - if (Conf.noEnderpearlsInFly) { - fPlayer.msg(TL.COMMAND_FLY_NO_EPEARL); - e.setCancelled(true); - } - } - } - } - - private String convertTime(int time) - { - String result = String.valueOf(Math.round((System.currentTimeMillis() / 1000L - time) / 36.0D) / 100.0D); - return (result.length() == 3 ? result + "0" : result) + "/hrs ago"; - } - - - @EventHandler - public void onCloseChest(InventoryCloseEvent e) { - if (e.getInventory().getTitle() == null) { - return; - } - - if (e.getInventory().getTitle().equalsIgnoreCase(P.p.color(P.p.getConfig().getString("fchest.Inventory-Title")))) { - FPlayers.getInstance().getByPlayer((Player) e.getPlayer()).getFaction().setChest(e.getInventory()); - } - } - - @EventHandler - public void onCloseChest(InventoryClickEvent e) { - if (e.getInventory().getTitle() == null || e.getClickedInventory() == null) { - return; - } - - if (e.getInventory().getTitle().equalsIgnoreCase(P.p.color(P.p.getConfig().getString("fchest.Inventory-Title")))) { - FPlayers.getInstance().getByPlayer((Player) e.getWhoClicked()).getFaction().setChest(e.getInventory()); - } - } - - // Holds the next time a player can have a map shown. - private HashMap showTimes = new HashMap<>(); - - @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) - public void onPlayerMove(PlayerMoveEvent event) { - Player player = event.getPlayer(); - FPlayer me = FPlayers.getInstance().getByPlayer(player); - - // clear visualization - if (event.getFrom().getBlockX() != event.getTo().getBlockX() || event.getFrom().getBlockY() != event.getTo().getBlockY() || event.getFrom().getBlockZ() != event.getTo().getBlockZ()) { - VisualizeUtil.clear(event.getPlayer()); - if (me.isWarmingUp()) { - me.clearWarmup(); - me.msg(TL.WARMUPS_CANCELLED); - } - } - - // quick check to make sure player is moving between chunks; good performance boost - if (event.getFrom().getBlockX() >> 4 == event.getTo().getBlockX() >> 4 && event.getFrom().getBlockZ() >> 4 == event.getTo().getBlockZ() >> 4 && event.getFrom().getWorld() == event.getTo().getWorld()) { - return; - } - - // Did we change coord? - FLocation from = me.getLastStoodAt(); - FLocation to = new FLocation(event.getTo()); - - if (from.equals(to)) { - return; - } - - // Yes we did change coord (: - - me.setLastStoodAt(to); - - // Did we change "host"(faction)? - Faction factionFrom = Board.getInstance().getFactionAt(from); - Faction factionTo = Board.getInstance().getFactionAt(to); - boolean changedFaction = (factionFrom != factionTo); - - - if (changedFaction) { - Bukkit.getServer().getPluginManager().callEvent(new FPlayerEnteredFactionEvent(factionTo,factionFrom,me)); - if (P.p.getConfig().getBoolean("Title.Show-Title")) { - String title = P.p.getConfig().getString("Title.Format.Title"); - title = title.replace("{Faction}", factionTo.getColorTo(me) + factionTo.getTag()); - title = parseAllPlaceholders(title, factionTo); - String subTitle = P.p.getConfig().getString("Title.Format.Subtitle").replace("{Description}", factionTo.getDescription()).replace("{Faction}", factionTo.getColorTo(me) + factionTo.getTag()); - subTitle = parseAllPlaceholders(subTitle, factionTo); - if (!P.p.mc17) { - if (!P.p.mc18) { - me.getPlayer().sendTitle(P.p.color(title), P.p.color(subTitle), P.p.getConfig().getInt("Title.Options.FadeInTime"), - P.p.getConfig().getInt("Title.Options.ShowTime"), - P.p.getConfig().getInt("Title.Options.FadeOutTime")); - } else { - me.getPlayer().sendTitle(P.p.color(title), P.p.color(subTitle)); - } - - - } - - } - - if (!P.p.factionsFlight) { - return; - } - - - // enable fly :) - if (me.hasFaction() && !me.isFlying()) { - if (factionTo == me.getFaction()) { - enableFly(me); - } - // bypass checks - Relation relationTo = factionTo.getRelationTo(me); - if ((factionTo.isWilderness() && me.canflyinWilderness()) || - (factionTo.isWarZone() && me.canflyinWarzone()) || - (factionTo.isSafeZone() && me.canflyinSafezone()) || - (relationTo == Relation.ENEMY && me.canflyinEnemy()) || - (relationTo == Relation.ALLY && me.canflyinAlly()) || - (relationTo == Relation.TRUCE && me.canflyinTruce()) || - (relationTo == Relation.NEUTRAL && me.canflyinNeutral() && !isSystemFaction(factionTo))) { - enableFly(me); - } - - } - } - - - - - if (me.isMapAutoUpdating()) { - Bukkit.broadcastMessage(""); - if (showTimes.containsKey(player.getUniqueId()) && (showTimes.get(player.getUniqueId()) > System.currentTimeMillis())) { - if (P.p.getConfig().getBoolean("findfactionsexploit.log", false)) { - P.p.log(Level.WARNING, "%s tried to show a faction map too soon and triggered exploit blocker.", player.getName()); - } - } else { - me.sendFancyMessage(Board.getInstance().getMap(me, to, player.getLocation().getYaw())); - showTimes.put(player.getUniqueId(), System.currentTimeMillis() + P.p.getConfig().getLong("findfactionsexploit.cooldown", 2000)); - } - } else { - Faction myFaction = me.getFaction(); - String ownersTo = myFaction.getOwnerListString(to); - - if (changedFaction) { - me.sendFactionHereMessage(factionFrom); - if (Conf.ownedAreasEnabled && Conf.ownedMessageOnBorder && myFaction == factionTo && !ownersTo.isEmpty()) { - me.sendMessage(TL.GENERIC_OWNERS.format(ownersTo)); - } - } else if (Conf.ownedAreasEnabled && Conf.ownedMessageInsideTerritory && myFaction == factionTo && !myFaction.isWilderness()) { - String ownersFrom = myFaction.getOwnerListString(from); - if (Conf.ownedMessageByChunk || !ownersFrom.equals(ownersTo)) { - if (!ownersTo.isEmpty()) { - me.sendMessage(TL.GENERIC_OWNERS.format(ownersTo)); - } else if (!TL.GENERIC_PUBLICLAND.toString().isEmpty()) { - me.sendMessage(TL.GENERIC_PUBLICLAND.toString()); - } - } - } - } - - if (me.getAutoClaimFor() != null) { - me.attemptClaim(me.getAutoClaimFor(), event.getTo(), true); - } else if (me.isAutoSafeClaimEnabled()) { - if (!Permission.MANAGE_SAFE_ZONE.has(player)) { - me.setIsAutoSafeClaimEnabled(false); - } else { - if (!Board.getInstance().getFactionAt(to).isSafeZone()) { - Board.getInstance().setFactionAt(Factions.getInstance().getSafeZone(), to); - me.msg(TL.PLAYER_SAFEAUTO); - } - } - } else if (me.isAutoWarClaimEnabled()) { - if (!Permission.MANAGE_WAR_ZONE.has(player)) { - me.setIsAutoWarClaimEnabled(false); - } else { - if (!Board.getInstance().getFactionAt(to).isWarZone()) { - Board.getInstance().setFactionAt(Factions.getInstance().getWarZone(), to); - me.msg(TL.PLAYER_WARAUTO); - } - } - } - } - - @EventHandler - public void onClose(InventoryCloseEvent e) { - FPlayer fme = FPlayers.getInstance().getById(e.getPlayer().getUniqueId().toString()); - if (fme.isInVault()) { - fme.setInVault(false); - } - - } - public static Boolean isSystemFaction(Faction faction) { return faction.isSafeZone() || faction.isWarZone() || faction.isWilderness(); } - - HashMap bannerCooldownMap = new HashMap<>(); - public static HashMap bannerLocations = new HashMap<>(); - @EventHandler - public void onBannerPlace(BlockPlaceEvent e){ - if (P.p.mc17) { - return; - } - - if (e.getItemInHand().getType() == Material.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(P.p.color(P.p.getConfig().getString("fbanners.Item.Name"))); - warmeta.setLore(P.p.colorList(P.p.getConfig().getStringList("fbanners.Item.Lore"))); - warBanner.setItemMeta(warmeta); - } else { - warBanner = P.p.createItem(Material.BANNER, 1, (short) 1, P.p.getConfig().getString("fbanners.Item.Name"), P.p.getConfig().getStringList("fbanners.Item.Lore")); - } - if (warBanner.isSimilar(bannerInHand)) { - - if (fme.getFaction().isWilderness()){ - fme.msg(TL.WARBANNER_NOFACTION); - e.setCancelled(true); - return; - } - int bannerTime = P.p.getConfig().getInt("fbanners.Banner-Time")*20; - - Location placedLoc = e.getBlockPlaced().getLocation(); - FLocation fplacedLoc = new FLocation(placedLoc); - if (Board.getInstance().getFactionAt(fplacedLoc).isWarZone() || fme.getFaction().getRelationTo(Board.getInstance().getFactionAt(fplacedLoc)) == Relation.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(P.p.color(fme.getTag() + " Placed A WarBanner!"),P.p.color("&7use &c/f tpbanner&7 to tp to the banner!")); - - } - bannerCooldownMap.put(fme.getTag(),true); - bannerLocations.put(fme.getTag(),e.getBlockPlaced().getLocation()); - final int bannerCooldown = P.p.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(P.p.color(P.p.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(P.p, new Runnable() { - @Override - public void run() { - 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 = P.p.getConfig().getInt("fbanners.Banner-Effect-Radius"); - final List effects = P.p.getConfig().getStringList("fbanners.Effects"); - final int affectorTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { - @Override - public void run() { - - for (Entity e : banner.getLocation().getWorld().getNearbyEntities(banner.getLocation(),radius,255,radius)){ - if (e instanceof Player){ - Player player = (Player) e; - 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(P.p, new Runnable() { - @Override - public void run() { - 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 onPlayerInteract(PlayerInteractEvent event) { - // only need to check right-clicks and physical as of MC 1.4+; good performance boost - if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) { - return; - } - - Block block = event.getClickedBlock(); - Player player = event.getPlayer(); - - if (block == null) { - return; // clicked in air, apparently - } - - if (!canPlayerUseBlock(player, block, false)) { - event.setCancelled(true); - if (Conf.handleExploitInteractionSpam) { - String name = player.getName(); - InteractAttemptSpam attempt = interactSpammers.get(name); - if (attempt == null) { - attempt = new InteractAttemptSpam(); - interactSpammers.put(name, attempt); - } - int count = attempt.increment(); - if (count >= 10) { - FPlayer me = FPlayers.getInstance().getByPlayer(player); - me.msg(TL.PLAYER_OUCH); - player.damage(NumberConversions.floor((double) count / 10)); - } - } - return; - } - - if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { - return; // only interested on right-clicks for below - } - - if (!playerCanUseItemHere(player, block.getLocation(), event.getMaterial(), false)) { - event.setCancelled(true); - } - } - - - // for handling people who repeatedly spam attempts to open a door (or similar) in another faction's territory - private Map interactSpammers = new HashMap<>(); - - private static class InteractAttemptSpam { - private int attempts = 0; - private long lastAttempt = System.currentTimeMillis(); - - // returns the current attempt count - public int increment() { - long Now = System.currentTimeMillis(); - if (Now > lastAttempt + 2000) { - attempts = 1; - } else { - attempts++; - } - lastAttempt = Now; - return attempts; - } - } - - public static boolean playerCanUseItemHere(Player player, Location location, Material material, boolean justCheck) { String name = player.getName(); if (Conf.playersWhoBypassAllProtection.contains(name)) { @@ -892,43 +277,6 @@ public class FactionsPlayerListener implements Listener { return true; } - @EventHandler(priority = EventPriority.HIGH) - public void onPlayerRespawn(PlayerRespawnEvent event) { - FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer()); - - me.getPower(); // update power, so they won't have gained any while dead - - Location home = me.getFaction().getHome(); - if (Conf.homesEnabled && - Conf.homesTeleportToOnDeath && - home != null && - (Conf.homesRespawnFromNoPowerLossWorlds || !Conf.worldsNoPowerLoss.contains(event.getPlayer().getWorld().getName()))) { - event.setRespawnLocation(home); - } - } - - // For some reason onPlayerInteract() sometimes misses bucket events depending on distance (something like 2-3 blocks away isn't detected), - // but these separate bucket events below always fire without fail - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) { - Block block = event.getBlockClicked(); - Player player = event.getPlayer(); - - if (!playerCanUseItemHere(player, block.getLocation(), event.getBucket(), false)) { - event.setCancelled(true); - } - } - - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) - public void onPlayerBucketFill(PlayerBucketFillEvent event) { - Block block = event.getBlockClicked(); - Player player = event.getPlayer(); - - if (!playerCanUseItemHere(player, block.getLocation(), event.getBucket(), false)) { - event.setCancelled(true); - } - } - public static boolean preventCommand(String fullCmd, Player player) { if ((Conf.territoryNeutralDenyCommands.isEmpty() && Conf.territoryEnemyDenyCommands.isEmpty() && Conf.permanentFactionMemberDenyCommands.isEmpty() && Conf.warzoneDenyCommands.isEmpty())) { return false; @@ -1002,6 +350,618 @@ public class FactionsPlayerListener implements Listener { return false; } + @EventHandler + public void onVaultPlace(BlockPlaceEvent e) { + if (e.getItemInHand().getType() == Material.CHEST) { + ItemStack vault = P.p.createItem(Material.CHEST, 1, (short) 0, P.p.color(P.p.getConfig().getString("fvault.Item.Name")), P.p.colorList(P.p.getConfig().getStringList("fvault.Item.Lore"))); + if (e.getItemInHand().equals(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; + } + + if (blockLoc.getBlock().getType() == Material.CHEST) { + e.setCancelled(true); + fme.msg(TL.COMMAND_GETVAULT_CHESTNEAR); + return; + } + } + } + } + + fme.msg(TL.COMMAND_GETVAULT_SUCCESS); + fme.getFaction().setVault(e.getBlockPlaced().getLocation()); + + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerJoin(PlayerJoinEvent event) { + initPlayer(event.getPlayer()); + } + + private void initPlayer(Player player) { + // Make sure that all online players do have a fplayer. + final FPlayer me = FPlayers.getInstance().getByPlayer(player); + ((MemoryFPlayer) me).setName(player.getName()); + + // Update the lastLoginTime for this fplayer + me.setLastLoginTime(System.currentTimeMillis()); + + // Store player's current FLocation and notify them where they are + me.setLastStoodAt(new FLocation(player.getLocation())); + + me.login(); // set kills / deaths + + // Check for Faction announcements. Let's delay this so they actually see it. + Bukkit.getScheduler().runTaskLater(P.p, new Runnable() { + @Override + public void run() { + if (me.isOnline()) { + me.getFaction().sendUnreadAnnouncements(me); + } + } + }, 33L); // Don't ask me why. + + if (P.p.getConfig().getBoolean("scoreboard.default-enabled", false)) { + FScoreboard.init(me); + FScoreboard.get(me).setDefaultSidebar(new FDefaultSidebar(), P.p.getConfig().getInt("default-update-interval", 20)); + FScoreboard.get(me).setSidebarVisibility(me.showScoreboard()); + } + + Faction myFaction = me.getFaction(); + if (!myFaction.isWilderness()) { + for (FPlayer other : myFaction.getFPlayersWhereOnline(true)) { + if (other != me && other.isMonitoringJoins()) { + other.msg(TL.FACTION_LOGIN, me.getName()); + } + } + } + + + fallMap.put(me.getPlayer(), false); + Bukkit.getScheduler().scheduleSyncDelayedTask(P.p, new Runnable() { + @Override + public void run() { + if (fallMap.containsKey(me.getPlayer())) { + fallMap.remove(me.getPlayer()); + } + + } + }, 180L); + + + if (me.isSpyingChat() && !player.hasPermission(Permission.CHATSPY.node)) { + me.setSpyingChat(false); + P.p.log(Level.INFO, "Found %s spying chat without permission on login. Disabled their chat spying.", player.getName()); + } + + if (me.isAdminBypassing() && !player.hasPermission(Permission.BYPASS.node)) { + me.setIsAdminBypassing(false); + P.p.log(Level.INFO, "Found %s on admin Bypass without permission on login. Disabled it for them.", player.getName()); + } + + + // If they have the permission, don't let them autoleave. Bad inverted setter :\ + me.setAutoLeave(!player.hasPermission(Permission.AUTO_LEAVE_BYPASS.node)); + me.setTakeFallDamage(true); + } + + @EventHandler + public void onPlayerFall(EntityDamageEvent e) { + if (e.getEntity() instanceof Player) { + if (e.getCause() == EntityDamageEvent.DamageCause.FALL) { + Player player = (Player) e.getEntity(); + if (fallMap.containsKey(player)) { + e.setCancelled(true); + fallMap.remove(player); + } + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerQuit(PlayerQuitEvent event) { + FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer()); + + // Make sure player's power is up to date when they log off. + me.getPower(); + // and update their last login time to point to when the logged off, for auto-remove routine + me.setLastLoginTime(System.currentTimeMillis()); + + me.logout(); // cache kills / deaths + + // if player is waiting for fstuck teleport but leaves, remove + if (P.p.getStuckMap().containsKey(me.getPlayer().getUniqueId())) { + FPlayers.getInstance().getByPlayer(me.getPlayer()).msg(TL.COMMAND_STUCK_CANCELLED); + P.p.getStuckMap().remove(me.getPlayer().getUniqueId()); + P.p.getTimers().remove(me.getPlayer().getUniqueId()); + } + + Faction myFaction = me.getFaction(); + if (!myFaction.isWilderness()) { + myFaction.memberLoggedOff(); + } + + if (!myFaction.isWilderness()) { + for (FPlayer player : myFaction.getFPlayersWhereOnline(true)) { + if (player != me && player.isMonitoringJoins()) { + player.msg(TL.FACTION_LOGOUT, me.getName()); + } + } + } + + if (CmdSeeChunk.seeChunkMap.containsKey(event.getPlayer().getName())) { + CmdSeeChunk.seeChunkMap.remove(event.getPlayer().getName()); + } + + FScoreboard.remove(me); + } + + public String parseAllPlaceholders(String string, Faction faction) { + string = string.replace("{Faction}", faction.getTag()) + .replace("{online}", faction.getOnlinePlayers().size() + "") + .replace("{offline}", faction.getFPlayers().size() - faction.getOnlinePlayers().size() + "") + .replace("{chunks}", faction.getAllClaims().size() + "") + .replace("{power}", faction.getPower() + "") + .replace("{leader}", faction.getFPlayerAdmin() + ""); + + + return string; + } + + public void enableFly(FPlayer me) { + if (P.p.getConfig().getBoolean("ffly.AutoEnable")) { + + me.setFlying(true); + CmdFly.flyMap.put(me.getName(), true); + if (CmdFly.id == -1) { + if (P.p.getConfig().getBoolean("ffly.Particles.Enabled")) { + CmdFly.startParticles(); + } + } + if (CmdFly.flyid == -1) { + CmdFly.startFlyCheck(); + } + } + } + + //inspect + @EventHandler + public void onInspect(PlayerInteractEvent e) { + if (e.getAction().name().contains("BLOCK")) { + FPlayer fplayer = FPlayers.getInstance().getByPlayer(e.getPlayer()); + if (!fplayer.isInspectMode()) { + return; + } + e.setCancelled(true); + if (!fplayer.isAdminBypassing()) { + if (!fplayer.hasFaction()) { + fplayer.setInspectMode(false); + fplayer.msg(TL.COMMAND_INSPECT_DISABLED_NOFAC); + return; + } + if (fplayer.getFaction() != Board.getInstance().getFactionAt(new FLocation(e.getPlayer().getLocation()))) { + fplayer.msg(TL.COMMAND_INSPECT_NOTINCLAIM); + return; + } + } else { + fplayer.msg(TL.COMMAND_INSPECT_BYPASS); + } + List info = CoreProtect.getInstance().getAPI().blockLookup(e.getClickedBlock(), 0); + if (info.size() == 0) { + e.getPlayer().sendMessage(TL.COMMAND_INSPECT_NODATA.toString()); + return; + } + Player player = e.getPlayer(); + CoreProtectAPI coAPI = CoreProtect.getInstance().getAPI(); + player.sendMessage(TL.COMMAND_INSPECT_HEADER.toString().replace("{x}", e.getClickedBlock().getX() + "") + .replace("{y}", e.getClickedBlock().getY() + "") + .replace("{z}", e.getClickedBlock().getZ() + "")); + String rowFormat = TL.COMMAND_INSPECT_ROW.toString(); + for (int i = 0; i < info.size(); i++) { + CoreProtectAPI.ParseResult row = coAPI.parseResult(info.get(0)); + player.sendMessage(rowFormat + .replace("{time}", convertTime(row.getTime())) + .replace("{action}", row.getActionString()) + .replace("{player}", row.getPlayer()) + .replace("{block-type}", row.getType().toString().toLowerCase())); + } + } + } + + //For disabling enderpearl throws + @EventHandler + public void onPearl(PlayerInteractEvent e) { + Player player = e.getPlayer(); + if (player.getItemInHand().getType() == Material.ENDER_PEARL) { + FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); + if (fPlayer.isFlying()) { + if (Conf.noEnderpearlsInFly) { + fPlayer.msg(TL.COMMAND_FLY_NO_EPEARL); + e.setCancelled(true); + } + } + } + } + + private String convertTime(int time) { + String result = String.valueOf(Math.round((System.currentTimeMillis() / 1000L - time) / 36.0D) / 100.0D); + return (result.length() == 3 ? result + "0" : result) + "/hrs ago"; + } + + @EventHandler + public void onCloseChest(InventoryCloseEvent e) { + if (e.getInventory().getTitle() == null) { + return; + } + + if (e.getInventory().getTitle().equalsIgnoreCase(P.p.color(P.p.getConfig().getString("fchest.Inventory-Title")))) { + FPlayers.getInstance().getByPlayer((Player) e.getPlayer()).getFaction().setChest(e.getInventory()); + } + } + + @EventHandler + public void onCloseChest(InventoryClickEvent e) { + if (e.getInventory().getTitle() == null || e.getClickedInventory() == null) { + return; + } + + if (e.getInventory().getTitle().equalsIgnoreCase(P.p.color(P.p.getConfig().getString("fchest.Inventory-Title")))) { + FPlayers.getInstance().getByPlayer((Player) e.getWhoClicked()).getFaction().setChest(e.getInventory()); + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public void onPlayerMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + FPlayer me = FPlayers.getInstance().getByPlayer(player); + + // clear visualization + if (event.getFrom().getBlockX() != event.getTo().getBlockX() || event.getFrom().getBlockY() != event.getTo().getBlockY() || event.getFrom().getBlockZ() != event.getTo().getBlockZ()) { + VisualizeUtil.clear(event.getPlayer()); + if (me.isWarmingUp()) { + me.clearWarmup(); + me.msg(TL.WARMUPS_CANCELLED); + } + } + + // quick check to make sure player is moving between chunks; good performance boost + if (event.getFrom().getBlockX() >> 4 == event.getTo().getBlockX() >> 4 && event.getFrom().getBlockZ() >> 4 == event.getTo().getBlockZ() >> 4 && event.getFrom().getWorld() == event.getTo().getWorld()) { + return; + } + + + // Did we change coord? + FLocation from = me.getLastStoodAt(); + FLocation to = new FLocation(event.getTo()); + + if (from.equals(to)) { + return; + } + + // Yes we did change coord (: + + me.setLastStoodAt(to); + + // Did we change "host"(faction)? + Faction factionFrom = Board.getInstance().getFactionAt(from); + Faction factionTo = Board.getInstance().getFactionAt(to); + boolean changedFaction = (factionFrom != factionTo); + + + if (changedFaction) { + Bukkit.getServer().getPluginManager().callEvent(new FPlayerEnteredFactionEvent(factionTo, factionFrom, me)); + if (P.p.getConfig().getBoolean("Title.Show-Title")) { + String title = P.p.getConfig().getString("Title.Format.Title"); + title = title.replace("{Faction}", factionTo.getColorTo(me) + factionTo.getTag()); + title = parseAllPlaceholders(title, factionTo); + String subTitle = P.p.getConfig().getString("Title.Format.Subtitle").replace("{Description}", factionTo.getDescription()).replace("{Faction}", factionTo.getColorTo(me) + factionTo.getTag()); + subTitle = parseAllPlaceholders(subTitle, factionTo); + if (!P.p.mc17) { + if (!P.p.mc18) { + me.getPlayer().sendTitle(P.p.color(title), P.p.color(subTitle), P.p.getConfig().getInt("Title.Options.FadeInTime"), + P.p.getConfig().getInt("Title.Options.ShowTime"), + P.p.getConfig().getInt("Title.Options.FadeOutTime")); + } else { + me.getPlayer().sendTitle(P.p.color(title), P.p.color(subTitle)); + } + + + } + + } + + if (!P.p.factionsFlight) { + return; + } + + + // enable fly :) + if (me.hasFaction() && !me.isFlying()) { + if (factionTo == me.getFaction()) { + enableFly(me); + } + // bypass checks + Relation relationTo = factionTo.getRelationTo(me); + if ((factionTo.isWilderness() && me.canflyinWilderness()) || + (factionTo.isWarZone() && me.canflyinWarzone()) || + (factionTo.isSafeZone() && me.canflyinSafezone()) || + (relationTo == Relation.ENEMY && me.canflyinEnemy()) || + (relationTo == Relation.ALLY && me.canflyinAlly()) || + (relationTo == Relation.TRUCE && me.canflyinTruce()) || + (relationTo == Relation.NEUTRAL && me.canflyinNeutral() && !isSystemFaction(factionTo))) { + enableFly(me); + } + + } + } + + + if (me.isMapAutoUpdating()) { + if (showTimes.containsKey(player.getUniqueId()) && (showTimes.get(player.getUniqueId()) > System.currentTimeMillis())) { + if (P.p.getConfig().getBoolean("findfactionsexploit.log", false)) { + P.p.log(Level.WARNING, "%s tried to show a faction map too soon and triggered exploit blocker.", player.getName()); + } + } else { + me.sendFancyMessage(Board.getInstance().getMap(me, to, player.getLocation().getYaw())); + showTimes.put(player.getUniqueId(), System.currentTimeMillis() + P.p.getConfig().getLong("findfactionsexploit.cooldown", 2000)); + } + } else { + Faction myFaction = me.getFaction(); + String ownersTo = myFaction.getOwnerListString(to); + if (changedFaction) { + me.sendFactionHereMessage(factionFrom); + if (Conf.ownedAreasEnabled && Conf.ownedMessageOnBorder && myFaction == factionTo && !ownersTo.isEmpty()) { + me.sendMessage(TL.GENERIC_OWNERS.format(ownersTo)); + } + } else if (Conf.ownedAreasEnabled && Conf.ownedMessageInsideTerritory && myFaction == factionTo && !myFaction.isWilderness()) { + String ownersFrom = myFaction.getOwnerListString(from); + if (Conf.ownedMessageByChunk || !ownersFrom.equals(ownersTo)) { + if (!ownersTo.isEmpty()) { + me.sendMessage(TL.GENERIC_OWNERS.format(ownersTo)); + } else if (!TL.GENERIC_PUBLICLAND.toString().isEmpty()) { + me.sendMessage(TL.GENERIC_PUBLICLAND.toString()); + } + } + } + } + + if (me.getAutoClaimFor() != null) { + me.attemptClaim(me.getAutoClaimFor(), event.getTo(), true); + } else if (me.isAutoSafeClaimEnabled()) { + if (!Permission.MANAGE_SAFE_ZONE.has(player)) { + me.setIsAutoSafeClaimEnabled(false); + } else { + if (!Board.getInstance().getFactionAt(to).isSafeZone()) { + Board.getInstance().setFactionAt(Factions.getInstance().getSafeZone(), to); + me.msg(TL.PLAYER_SAFEAUTO); + } + } + } else if (me.isAutoWarClaimEnabled()) { + if (!Permission.MANAGE_WAR_ZONE.has(player)) { + me.setIsAutoWarClaimEnabled(false); + } else { + if (!Board.getInstance().getFactionAt(to).isWarZone()) { + Board.getInstance().setFactionAt(Factions.getInstance().getWarZone(), to); + me.msg(TL.PLAYER_WARAUTO); + } + } + } + } + + @EventHandler + public void onClose(InventoryCloseEvent e) { + FPlayer fme = FPlayers.getInstance().getById(e.getPlayer().getUniqueId().toString()); + if (fme.isInVault()) { + fme.setInVault(false); + } + + } + + @EventHandler + public void onBannerPlace(BlockPlaceEvent e) { + if (P.p.mc17) { + return; + } + + if (e.getItemInHand().getType() == Material.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(P.p.color(P.p.getConfig().getString("fbanners.Item.Name"))); + warmeta.setLore(P.p.colorList(P.p.getConfig().getStringList("fbanners.Item.Lore"))); + warBanner.setItemMeta(warmeta); + } else { + warBanner = P.p.createItem(Material.BANNER, 1, (short) 1, P.p.getConfig().getString("fbanners.Item.Name"), P.p.getConfig().getStringList("fbanners.Item.Lore")); + } + if (warBanner.isSimilar(bannerInHand)) { + + if (fme.getFaction().isWilderness()) { + fme.msg(TL.WARBANNER_NOFACTION); + e.setCancelled(true); + return; + } + int bannerTime = P.p.getConfig().getInt("fbanners.Banner-Time") * 20; + + Location placedLoc = e.getBlockPlaced().getLocation(); + FLocation fplacedLoc = new FLocation(placedLoc); + if (Board.getInstance().getFactionAt(fplacedLoc).isWarZone() || fme.getFaction().getRelationTo(Board.getInstance().getFactionAt(fplacedLoc)) == Relation.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(P.p.color(fme.getTag() + " Placed A WarBanner!"), P.p.color("&7use &c/f tpbanner&7 to tp to the banner!")); + + } + bannerCooldownMap.put(fme.getTag(), true); + bannerLocations.put(fme.getTag(), e.getBlockPlaced().getLocation()); + final int bannerCooldown = P.p.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(P.p.color(P.p.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(P.p, new Runnable() { + @Override + public void run() { + 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 = P.p.getConfig().getInt("fbanners.Banner-Effect-Radius"); + final List effects = P.p.getConfig().getStringList("fbanners.Effects"); + final int affectorTask = Bukkit.getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { + @Override + public void run() { + + for (Entity e : banner.getLocation().getWorld().getNearbyEntities(banner.getLocation(), radius, 255, radius)) { + if (e instanceof Player) { + Player player = (Player) e; + 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(P.p, new Runnable() { + @Override + public void run() { + 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 onPlayerInteract(PlayerInteractEvent event) { + // only need to check right-clicks and physical as of MC 1.4+; good performance boost + if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) { + return; + } + + Block block = event.getClickedBlock(); + Player player = event.getPlayer(); + + if (block == null) { + return; // clicked in air, apparently + } + + if (!canPlayerUseBlock(player, block, false)) { + event.setCancelled(true); + if (Conf.handleExploitInteractionSpam) { + String name = player.getName(); + InteractAttemptSpam attempt = interactSpammers.get(name); + if (attempt == null) { + attempt = new InteractAttemptSpam(); + interactSpammers.put(name, attempt); + } + int count = attempt.increment(); + if (count >= 10) { + FPlayer me = FPlayers.getInstance().getByPlayer(player); + me.msg(TL.PLAYER_OUCH); + player.damage(NumberConversions.floor((double) count / 10)); + } + } + return; + } + + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; // only interested on right-clicks for below + } + + if (!playerCanUseItemHere(player, block.getLocation(), event.getMaterial(), false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerRespawn(PlayerRespawnEvent event) { + FPlayer me = FPlayers.getInstance().getByPlayer(event.getPlayer()); + + me.getPower(); // update power, so they won't have gained any while dead + + Location home = me.getFaction().getHome(); + if (Conf.homesEnabled && + Conf.homesTeleportToOnDeath && + home != null && + (Conf.homesRespawnFromNoPowerLossWorlds || !Conf.worldsNoPowerLoss.contains(event.getPlayer().getWorld().getName()))) { + event.setRespawnLocation(home); + } + } + + // For some reason onPlayerInteract() sometimes misses bucket events depending on distance (something like 2-3 blocks away isn't detected), + // but these separate bucket events below always fire without fail + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) { + Block block = event.getBlockClicked(); + Player player = event.getPlayer(); + + if (!playerCanUseItemHere(player, block.getLocation(), event.getBucket(), false)) { + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerBucketFill(PlayerBucketFillEvent event) { + Block block = event.getBlockClicked(); + Player player = event.getPlayer(); + + if (!playerCanUseItemHere(player, block.getLocation(), event.getBucket(), false)) { + event.setCancelled(true); + } + } + @EventHandler(priority = EventPriority.HIGH) public void onPlayerInteractGUI(InventoryClickEvent event) { if (event.getClickedInventory() == null) { @@ -1020,7 +980,6 @@ public class FactionsPlayerListener implements Listener { } } - @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerKick(PlayerKickEvent event) { FPlayer badGuy = FPlayers.getInstance().getByPlayer(event.getPlayer()); @@ -1048,4 +1007,21 @@ public class FactionsPlayerListener implements Listener { public void onFactionLeave(FPlayerLeaveEvent event) { FTeamWrapper.applyUpdatesLater(event.getFaction()); } + + private static class InteractAttemptSpam { + private int attempts = 0; + private long lastAttempt = System.currentTimeMillis(); + + // returns the current attempt count + public int increment() { + long Now = System.currentTimeMillis(); + if (Now > lastAttempt + 2000) { + attempts = 1; + } else { + attempts++; + } + lastAttempt = Now; + return attempts; + } + } } diff --git a/src/main/java/com/massivecraft/factions/scoreboards/BufferedObjective.java b/src/main/java/com/massivecraft/factions/scoreboards/BufferedObjective.java index 5f69c135..d21d3898 100644 --- a/src/main/java/com/massivecraft/factions/scoreboards/BufferedObjective.java +++ b/src/main/java/com/massivecraft/factions/scoreboards/BufferedObjective.java @@ -14,20 +14,6 @@ public class BufferedObjective { private static final Method addEntryMethod; private static final int MAX_LINE_LENGTH; - private final Scoreboard scoreboard; - private final String baseName; - - private Objective current; - private List currentTeams = new ArrayList<>(); - private String title; - private DisplaySlot displaySlot; - - private int objPtr; - private int teamPtr; - private boolean requiresUpdate = false; - - private final Map contents = new HashMap<>(); - static { // Check for long line support. // We require use of Spigot's `addEntry(String)` method on @@ -48,6 +34,17 @@ public class BufferedObjective { } } + private final Scoreboard scoreboard; + private final String baseName; + private final Map contents = new HashMap<>(); + private Objective current; + private List currentTeams = new ArrayList<>(); + private String title; + private DisplaySlot displaySlot; + private int objPtr; + private int teamPtr; + private boolean requiresUpdate = false; + public BufferedObjective(Scoreboard scoreboard) { this.scoreboard = scoreboard; this.baseName = createBaseName(); diff --git a/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java b/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java index f1626c26..2225137a 100644 --- a/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java +++ b/src/main/java/com/massivecraft/factions/scoreboards/FScoreboard.java @@ -22,6 +22,20 @@ public class FScoreboard { private FSidebarProvider temporaryProvider; private boolean removed = false; + private FScoreboard(FPlayer fplayer) { + this.fplayer = fplayer; + + if (isSupportedByServer()) { + this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); + this.bufferedObjective = new BufferedObjective(scoreboard); + + fplayer.getPlayer().setScoreboard(scoreboard); + } else { + this.scoreboard = null; + this.bufferedObjective = null; + } + } + // Glowstone doesn't support scoreboards. // All references to this and related workarounds can be safely // removed when scoreboards are supported. @@ -56,20 +70,6 @@ public class FScoreboard { return fscoreboards.get(FPlayers.getInstance().getByPlayer(player)); } - private FScoreboard(FPlayer fplayer) { - this.fplayer = fplayer; - - if (isSupportedByServer()) { - this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); - this.bufferedObjective = new BufferedObjective(scoreboard); - - fplayer.getPlayer().setScoreboard(scoreboard); - } else { - this.scoreboard = null; - this.bufferedObjective = null; - } - } - protected FPlayer getFPlayer() { return fplayer; } diff --git a/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java b/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java index 8efb92cb..e4bce572 100644 --- a/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java +++ b/src/main/java/com/massivecraft/factions/scoreboards/FTeamWrapper.java @@ -13,14 +13,22 @@ import java.util.*; public class FTeamWrapper { private static final Map wrappers = new HashMap<>(); private static final List tracking = new ArrayList<>(); - private static int factionTeamPtr; private static final Set updating = new HashSet<>(); - + private static int factionTeamPtr; private final Map teams = new HashMap<>(); private final String teamName; private final Faction faction; private final Set members = new HashSet<>(); + private FTeamWrapper(Faction faction) { + this.teamName = "faction_" + (factionTeamPtr++); + this.faction = faction; + + for (FScoreboard fboard : tracking) { + add(fboard); + } + } + public static void applyUpdatesLater(final Faction faction) { if (!FScoreboard.isSupportedByServer()) { return; @@ -130,16 +138,6 @@ public class FTeamWrapper { } } - - private FTeamWrapper(Faction faction) { - this.teamName = "faction_" + (factionTeamPtr++); - this.faction = faction; - - for (FScoreboard fboard : tracking) { - add(fboard); - } - } - private void add(FScoreboard fboard) { Scoreboard board = fboard.getScoreboard(); Team team = board.registerNewTeam(teamName); @@ -171,8 +169,8 @@ public class FTeamWrapper { String prefix = TL.DEFAULT_PREFIX.toString(); if (P.p.PlaceholderApi) { - prefix = PlaceholderAPI.setPlaceholders(fplayer.getPlayer(),prefix); - prefix = PlaceholderAPI.setBracketPlaceholders(fplayer.getPlayer(),prefix); + prefix = PlaceholderAPI.setPlaceholders(fplayer.getPlayer(), prefix); + prefix = PlaceholderAPI.setBracketPlaceholders(fplayer.getPlayer(), prefix); } prefix = prefix.replace("{relationcolor}", faction.getRelationTo(fplayer).getColor().toString()); prefix = prefix.replace("{faction}", faction.getTag().substring(0, Math.min("{faction}".length() + 16 - prefix.length(), faction.getTag().length()))); diff --git a/src/main/java/com/massivecraft/factions/struct/ChatMode.java b/src/main/java/com/massivecraft/factions/struct/ChatMode.java index 27804288..34536416 100644 --- a/src/main/java/com/massivecraft/factions/struct/ChatMode.java +++ b/src/main/java/com/massivecraft/factions/struct/ChatMode.java @@ -3,7 +3,7 @@ package com.massivecraft.factions.struct; import com.massivecraft.factions.zcore.util.TL; public enum ChatMode { - MOD(4,TL.CHAT_MOD), + MOD(4, TL.CHAT_MOD), FACTION(3, TL.CHAT_FACTION), ALLIANCE(2, TL.CHAT_ALLIANCE), TRUCE(1, TL.CHAT_TRUCE), diff --git a/src/main/java/com/massivecraft/factions/struct/Role.java b/src/main/java/com/massivecraft/factions/struct/Role.java index 239a15dd..eb7b3322 100644 --- a/src/main/java/com/massivecraft/factions/struct/Role.java +++ b/src/main/java/com/massivecraft/factions/struct/Role.java @@ -16,7 +16,7 @@ import java.util.List; public enum Role implements Permissable { ADMIN(4, TL.ROLE_ADMIN), - COLEADER(3,TL.ROLE_COLEADER), + COLEADER(3, TL.ROLE_COLEADER), MODERATOR(2, TL.ROLE_MODERATOR), NORMAL(1, TL.ROLE_NORMAL), RECRUIT(0, TL.ROLE_RECRUIT); @@ -32,14 +32,6 @@ public enum Role implements Permissable { this.translation = translation; } - public boolean isAtLeast(Role role) { - return this.value >= role.value; - } - - public boolean isAtMost(Role role) { - return this.value <= role.value; - } - public static Role getRelative(Role role, int relative) { return Role.getByValue(role.value + relative); } @@ -54,7 +46,7 @@ public enum Role implements Permissable { return MODERATOR; case 3: return COLEADER; - case 4: + case 4: return ADMIN; } @@ -81,6 +73,14 @@ public enum Role implements Permissable { return null; } + public boolean isAtLeast(Role role) { + return this.value >= role.value; + } + + public boolean isAtMost(Role role) { + return this.value <= role.value; + } + @Override public String toString() { return this.nicename; diff --git a/src/main/java/com/massivecraft/factions/util/AsciiCompass.java b/src/main/java/com/massivecraft/factions/util/AsciiCompass.java index f2d53e8b..a4149c94 100644 --- a/src/main/java/com/massivecraft/factions/util/AsciiCompass.java +++ b/src/main/java/com/massivecraft/factions/util/AsciiCompass.java @@ -7,49 +7,6 @@ import java.util.ArrayList; public class AsciiCompass { - public enum Point { - - N('N'), - NE('/'), - E('E'), - SE('\\'), - S('S'), - SW('/'), - W('W'), - NW('\\'); - - public final char asciiChar; - - Point(final char asciiChar) { - this.asciiChar = asciiChar; - } - - @Override - public String toString() { - return String.valueOf(this.asciiChar); - } - - public String getTranslation() { - if (this == N) { - return TL.COMPASS_SHORT_NORTH.toString(); - } - if (this == E) { - return TL.COMPASS_SHORT_EAST.toString(); - } - if (this == S) { - return TL.COMPASS_SHORT_SOUTH.toString(); - } - if (this == W) { - return TL.COMPASS_SHORT_WEST.toString(); - } - return toString(); - } - - public String toString(boolean isActive, ChatColor colorActive, String colorDefault) { - return (isActive ? colorActive : colorDefault) + getTranslation(); - } - } - public static Point getCompassPointForDirection(double inDegrees) { double degrees = (inDegrees - 180) % 360; if (degrees < 0) { @@ -107,4 +64,47 @@ public class AsciiCompass { public static ArrayList getAsciiCompass(double inDegrees, ChatColor colorActive, String colorDefault) { return getAsciiCompass(getCompassPointForDirection(inDegrees), colorActive, colorDefault); } + + public enum Point { + + N('N'), + NE('/'), + E('E'), + SE('\\'), + S('S'), + SW('/'), + W('W'), + NW('\\'); + + public final char asciiChar; + + Point(final char asciiChar) { + this.asciiChar = asciiChar; + } + + @Override + public String toString() { + return String.valueOf(this.asciiChar); + } + + public String getTranslation() { + if (this == N) { + return TL.COMPASS_SHORT_NORTH.toString(); + } + if (this == E) { + return TL.COMPASS_SHORT_EAST.toString(); + } + if (this == S) { + return TL.COMPASS_SHORT_SOUTH.toString(); + } + if (this == W) { + return TL.COMPASS_SHORT_WEST.toString(); + } + return toString(); + } + + public String toString(boolean isActive, ChatColor colorActive, String colorDefault) { + return (isActive ? colorActive : colorDefault) + getTranslation(); + } + } } diff --git a/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java b/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java index b147db5c..2a2b83ce 100644 --- a/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java +++ b/src/main/java/com/massivecraft/factions/util/ClipPlaceholderAPIManager.java @@ -39,8 +39,6 @@ public class ClipPlaceholderAPIManager extends PlaceholderExpansion implements R } - - // Relational placeholders @Override public String onPlaceholderRequest(Player p1, Player p2, String placeholder) { diff --git a/src/main/java/com/massivecraft/factions/util/EnumTypeAdapter.java b/src/main/java/com/massivecraft/factions/util/EnumTypeAdapter.java index c1e918d8..08e0cbf5 100644 --- a/src/main/java/com/massivecraft/factions/util/EnumTypeAdapter.java +++ b/src/main/java/com/massivecraft/factions/util/EnumTypeAdapter.java @@ -15,6 +15,7 @@ import java.util.Map; public final class EnumTypeAdapter> extends TypeAdapter { + public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory(); private final Map nameToConstant = new HashMap<>(); private final Map constantToName = new HashMap<>(); @@ -34,20 +35,6 @@ public final class EnumTypeAdapter> extends TypeAdapter { } } - public T read(JsonReader in) throws IOException { - if (in.peek() == JsonToken.NULL) { - in.nextNull(); - return null; - } - return nameToConstant.get(in.nextString()); - } - - public void write(JsonWriter out, T value) throws IOException { - out.value(value == null ? null : constantToName.get(value)); - } - - public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory(); - public static TypeAdapterFactory newEnumTypeHierarchyFactory() { return new TypeAdapterFactory() { @SuppressWarnings({"rawtypes", "unchecked"}) @@ -64,4 +51,16 @@ public final class EnumTypeAdapter> extends TypeAdapter { }; } + public T read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + return nameToConstant.get(in.nextString()); + } + + public void write(JsonWriter out, T value) throws IOException { + out.value(value == null ? null : constantToName.get(value)); + } + } diff --git a/src/main/java/com/massivecraft/factions/util/InventoryUtil.java b/src/main/java/com/massivecraft/factions/util/InventoryUtil.java index 6a5f3610..c9904c4f 100644 --- a/src/main/java/com/massivecraft/factions/util/InventoryUtil.java +++ b/src/main/java/com/massivecraft/factions/util/InventoryUtil.java @@ -1,12 +1,6 @@ package com.massivecraft.factions.util; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Item; -import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.util.io.BukkitObjectInputStream; import org.bukkit.util.io.BukkitObjectOutputStream; import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; @@ -14,7 +8,6 @@ import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.Map; public class InventoryUtil { @@ -24,7 +17,7 @@ public class InventoryUtil { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream); dataOutput.writeInt(items.length); - for (ItemStack item: items) { + for (ItemStack item : items) { dataOutput.writeObject(item); } dataOutput.close(); diff --git a/src/main/java/com/massivecraft/factions/util/MiscUtil.java b/src/main/java/com/massivecraft/factions/util/MiscUtil.java index f20c94b2..be517150 100644 --- a/src/main/java/com/massivecraft/factions/util/MiscUtil.java +++ b/src/main/java/com/massivecraft/factions/util/MiscUtil.java @@ -18,6 +18,9 @@ import java.util.logging.Level; public class MiscUtil { + /// TODO create tag whitelist!! + public static HashSet substanceChars = new HashSet<>(Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z")); + public static EntityType creatureTypeFromEntity(Entity entity) { if (!(entity instanceof Creature)) { return null; @@ -46,9 +49,6 @@ public class MiscUtil { return values; } - /// TODO create tag whitelist!! - public static HashSet substanceChars = new HashSet<>(Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z")); - public static String getComparisonString(String str) { StringBuilder ret = new StringBuilder(); diff --git a/src/main/java/com/massivecraft/factions/util/Particles/ParticleEffect.java b/src/main/java/com/massivecraft/factions/util/Particles/ParticleEffect.java index 19677958..c73d5847 100644 --- a/src/main/java/com/massivecraft/factions/util/Particles/ParticleEffect.java +++ b/src/main/java/com/massivecraft/factions/util/Particles/ParticleEffect.java @@ -37,1569 +37,1569 @@ import java.util.Map.Entry; * *

* It would be nice if you provide credit to me if you use this class in a published project - * + * * @author DarkBlade12 * @version 1.7 */ public enum ParticleEffect { - /** - * A particle effect which is displayed by exploding tnt and creepers: - *

    - *
  • It looks like a white cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - EXPLOSION_NORMAL("explode", 0, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by exploding ghast fireballs and wither skulls: - *
    - *
  • It looks like a gray ball which is fading away - *
  • The speed value slightly influences the size of this particle effect - *
- */ - EXPLOSION_LARGE("largeexplode", 1, -1), - /** - * A particle effect which is displayed by exploding tnt and creepers: - *
    - *
  • It looks like a crowd of gray balls which are fading away - *
  • The speed value has no influence on this particle effect - *
- */ - EXPLOSION_HUGE("hugeexplosion", 2, -1), - /** - * A particle effect which is displayed by launching fireworks: - *
    - *
  • It looks like a white star which is sparkling - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - FIREWORKS_SPARK("fireworksSpark", 3, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by swimming entities and arrows in water: - *
    - *
  • It looks like a bubble - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - WATER_BUBBLE("bubble", 4, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_WATER), - /** - * A particle effect which is displayed by swimming entities and shaking wolves: - *
    - *
  • It looks like a blue drop - *
  • The speed value has no influence on this particle effect - *
- */ - WATER_SPLASH("splash", 5, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed on water when fishing: - *
    - *
  • It looks like a blue droplet - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - WATER_WAKE("wake", 6, 7, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by water: - *
    - *
  • It looks like a tiny blue square - *
  • The speed value has no influence on this particle effect - *
- */ - SUSPENDED("suspended", 7, -1, ParticleProperty.REQUIRES_WATER), - /** - * A particle effect which is displayed by air when close to bedrock and the in the void: - *
    - *
  • It looks like a tiny gray square - *
  • The speed value has no influence on this particle effect - *
- */ - SUSPENDED_DEPTH("depthSuspend", 8, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed when landing a critical hit and by arrows: - *
    - *
  • It looks like a light brown cross - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - CRIT("crit", 9, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed when landing a hit with an enchanted weapon: - *
    - *
  • It looks like a cyan star - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - CRIT_MAGIC("magicCrit", 10, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by primed tnt, torches, droppers, dispensers, end portals, brewing stands and monster spawners: - *
    - *
  • It looks like a little gray cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - SMOKE_NORMAL("smoke", 11, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by fire, minecarts with furnace and blazes: - *
    - *
  • It looks like a large gray cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - SMOKE_LARGE("largesmoke", 12, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed when splash potions or bottles o' enchanting hit something: - *
    - *
  • It looks like a white swirl - *
  • The speed value causes the particle to only move upwards when set to 0 - *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 - *
- */ - SPELL("spell", 13, -1), - /** - * A particle effect which is displayed when instant splash potions hit something: - *
    - *
  • It looks like a white cross - *
  • The speed value causes the particle to only move upwards when set to 0 - *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 - *
- */ - SPELL_INSTANT("instantSpell", 14, -1), - /** - * A particle effect which is displayed by entities with active potion effects: - *
    - *
  • It looks like a colored swirl - *
  • The speed value causes the particle to be colored black when set to 0 - *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed - *
- */ - SPELL_MOB("mobSpell", 15, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed by entities with active potion effects applied through a beacon: - *
    - *
  • It looks like a transparent colored swirl - *
  • The speed value causes the particle to be always colored black when set to 0 - *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed - *
- */ - SPELL_MOB_AMBIENT("mobSpellAmbient", 16, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed by witches: - *
    - *
  • It looks like a purple cross - *
  • The speed value causes the particle to only move upwards when set to 0 - *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 - *
- */ - SPELL_WITCH("witchMagic", 17, -1), - /** - * A particle effect which is displayed by blocks beneath a water source: - *
    - *
  • It looks like a blue drip - *
  • The speed value has no influence on this particle effect - *
- */ - DRIP_WATER("dripWater", 18, -1), - /** - * A particle effect which is displayed by blocks beneath a lava source: - *
    - *
  • It looks like an orange drip - *
  • The speed value has no influence on this particle effect - *
- */ - DRIP_LAVA("dripLava", 19, -1), - /** - * A particle effect which is displayed when attacking a villager in a village: - *
    - *
  • It looks like a cracked gray heart - *
  • The speed value has no influence on this particle effect - *
- */ - VILLAGER_ANGRY("angryVillager", 20, -1), - /** - * A particle effect which is displayed when using bone meal and trading with a villager in a village: - *
    - *
  • It looks like a green star - *
  • The speed value has no influence on this particle effect - *
- */ - VILLAGER_HAPPY("happyVillager", 21, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by mycelium: - *
    - *
  • It looks like a tiny gray square - *
  • The speed value has no influence on this particle effect - *
- */ - TOWN_AURA("townaura", 22, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by note blocks: - *
    - *
  • It looks like a colored note - *
  • The speed value causes the particle to be colored green when set to 0 - *
- */ - NOTE("note", 23, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed by nether portals, endermen, ender pearls, eyes of ender, ender chests and dragon eggs: - *
    - *
  • It looks like a purple cloud - *
  • The speed value influences the spread of this particle effect - *
- */ - PORTAL("portal", 24, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by enchantment tables which are nearby bookshelves: - *
    - *
  • It looks like a cryptic white letter - *
  • The speed value influences the spread of this particle effect - *
- */ - ENCHANTMENT_TABLE("enchantmenttable", 25, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by torches, active furnaces, magma cubes and monster spawners: - *
    - *
  • It looks like a tiny flame - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - FLAME("flame", 26, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by lava: - *
    - *
  • It looks like a spark - *
  • The speed value has no influence on this particle effect - *
- */ - LAVA("lava", 27, -1), - /** - * A particle effect which is currently unused: - *
    - *
  • It looks like a transparent gray square - *
  • The speed value has no influence on this particle effect - *
- */ - FOOTSTEP("footstep", 28, -1), - /** - * A particle effect which is displayed when a mob dies: - *
    - *
  • It looks like a large white cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - CLOUD("cloud", 29, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by redstone ore, powered redstone, redstone torches and redstone repeaters: - *
    - *
  • It looks like a tiny colored cloud - *
  • The speed value causes the particle to be colored red when set to 0 - *
- */ - REDSTONE("reddust", 30, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed when snowballs hit a block: - *
    - *
  • It looks like a little piece with the snowball texture - *
  • The speed value has no influence on this particle effect - *
- */ - SNOWBALL("snowballpoof", 31, -1), - /** - * A particle effect which is currently unused: - *
    - *
  • It looks like a tiny white cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - SNOW_SHOVEL("snowshovel", 32, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by slimes: - *
    - *
  • It looks like a tiny part of the slimeball icon - *
  • The speed value has no influence on this particle effect - *
- */ - SLIME("slime", 33, -1), - /** - * A particle effect which is displayed when breeding and taming animals: - *
    - *
  • It looks like a red heart - *
  • The speed value has no influence on this particle effect - *
- */ - HEART("heart", 34, -1), - /** - * A particle effect which is displayed by barriers: - *
    - *
  • It looks like a red box with a slash through it - *
  • The speed value has no influence on this particle effect - *
- */ - BARRIER("barrier", 35, 8), - /** - * A particle effect which is displayed when breaking a tool or eggs hit a block: - *
    - *
  • It looks like a little piece with an item texture - *
- */ - ITEM_CRACK("iconcrack", 36, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), - /** - * A particle effect which is displayed when breaking blocks or sprinting: - *
    - *
  • It looks like a little piece with a block texture - *
  • The speed value has no influence on this particle effect - *
- */ - BLOCK_CRACK("blockcrack", 37, -1, ParticleProperty.REQUIRES_DATA), - /** - * A particle effect which is displayed when falling: - *
    - *
  • It looks like a little piece with a block texture - *
- */ - BLOCK_DUST("blockdust", 38, 7, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), - /** - * A particle effect which is displayed when rain hits the ground: - *
    - *
  • It looks like a blue droplet - *
  • The speed value has no influence on this particle effect - *
- */ - WATER_DROP("droplet", 39, 8), - /** - * A particle effect which is currently unused: - *
    - *
  • It has no visual effect - *
- */ - ITEM_TAKE("take", 40, 8), - /** - * A particle effect which is displayed by elder guardians: - *
    - *
  • It looks like the shape of the elder guardian - *
  • The speed value has no influence on this particle effect - *
  • The offset values have no influence on this particle effect - *
- */ - MOB_APPEARANCE("mobappearance", 41, 8); - - private static final Map NAME_MAP = new HashMap(); - private static final Map ID_MAP = new HashMap(); - - // Initialize map for quick name and id lookup - static { - for (ParticleEffect effect : values()) { - NAME_MAP.put(effect.name, effect); - ID_MAP.put(effect.id, effect); - } - } - - private final String name; - private final int id; - private final int requiredVersion; - private final List properties; - - /** - * Construct a new particle effect - * - * @param name Name of this particle effect - * @param id Id of this particle effect - * @param requiredVersion Version which is required (1.x) - * @param properties Properties of this particle effect - */ - private ParticleEffect(String name, int id, int requiredVersion, ParticleProperty... properties) { - this.name = name; - this.id = id; - this.requiredVersion = requiredVersion; - this.properties = Arrays.asList(properties); - } - - /** - * Returns the particle effect with the given name - * - * @param name Name of the particle effect - * @return The particle effect - */ - public static ParticleEffect fromName(String name) { - for (Entry entry : NAME_MAP.entrySet()) { - if (!entry.getKey().equalsIgnoreCase(name)) { - continue; - } - return entry.getValue(); - } - return null; - } - - /** - * Returns the particle effect with the given id - * - * @param id Id of the particle effect - * @return The particle effect - */ - public static ParticleEffect fromId(int id) { - for (Entry entry : ID_MAP.entrySet()) { - if (entry.getKey() != id) { - continue; - } - return entry.getValue(); - } - return null; - } - - /** - * Determine if water is at a certain location - * - * @param location Location to check - * @return Whether water is at this location or not - */ - private static boolean isWater(Location location) { - Material material = location.getBlock().getType(); - return material == Material.WATER || material == Material.STATIONARY_WATER; - } - - /** - * Determine if the distance between @param location and one of the players exceeds 256 - * - * @param location Location to check - * @return Whether the distance exceeds 256 or not - */ - private static boolean isLongDistance(Location location, List players) { - String world = location.getWorld().getName(); - for (Player player : players) { - Location playerLocation = player.getLocation(); - if (!world.equals(playerLocation.getWorld().getName()) || playerLocation.distanceSquared(location) < 65536) { - continue; - } - return true; - } - return false; - } - - /** - * Determine if the data type for a particle effect is correct - * - * @param effect Particle effect - * @param data Particle data - * @return Whether the data type is correct or not - */ - private static boolean isDataCorrect(ParticleEffect effect, ParticleData data) { - return ((effect == BLOCK_CRACK || effect == BLOCK_DUST) && data instanceof BlockData) || (effect == ITEM_CRACK && data instanceof ItemData); - } - - /** - * Determine if the color type for a particle effect is correct - * - * @param effect Particle effect - * @param color Particle color - * @return Whether the color type is correct or not - */ - private static boolean isColorCorrect(ParticleEffect effect, ParticleColor color) { - return ((effect == SPELL_MOB || effect == SPELL_MOB_AMBIENT || effect == REDSTONE) && color instanceof OrdinaryColor) || (effect == NOTE && color instanceof NoteColor); - } - - /** - * Returns the name of this particle effect - * - * @return The name - */ - public String getName() { - return name; - } - - /** - * Returns the id of this particle effect - * - * @return The id - */ - public int getId() { - return id; - } - - /** - * Returns the required version for this particle effect (1.x) - * - * @return The required version - */ - public int getRequiredVersion() { - return requiredVersion; - } - - /** - * Determine if this particle effect has a specific property - * - * @return Whether it has the property or not - */ - public boolean hasProperty(ParticleProperty property) { - return properties.contains(property); - } - - /** - * Determine if this particle effect is supported by your current server version - * - * @return Whether the particle effect is supported or not - */ - public boolean isSupported() { - if (requiredVersion == -1) { - return true; - } - return ParticlePacket.getVersion() >= requiredVersion; - } - - /** - * Displays a particle effect which is only visible for all players within a certain range in the world of @param center - * - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect requires water and none is at the center location - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, null).sendTo(center, range); - } - - /** - * Displays a particle effect which is only visible for the specified players - * - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect requires water and none is at the center location - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null).sendTo(center, players); - } - - /** - * Displays a particle effect which is only visible for the specified players - * - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect requires water and none is at the center location - * @see #display(float, float, float, float, int, Location, List) - */ - public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - display(offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); - } - - /** - * Displays a single particle which flies into a determined direction and is only visible for all players within a certain range in the world of @param center - * - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location - * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData) - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (!hasProperty(ParticleProperty.DIRECTIONAL)) { - throw new IllegalArgumentException("This particle effect is not directional"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, direction, speed, range > 256, null).sendTo(center, range); - } - - /** - * Displays a single particle which flies into a determined direction and is only visible for the specified players - * - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location - * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData) - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (!hasProperty(ParticleProperty.DIRECTIONAL)) { - throw new IllegalArgumentException("This particle effect is not directional"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, direction, speed, isLongDistance(center, players), null).sendTo(center, players); - } - - /** - * Displays a single particle which flies into a determined direction and is only visible for the specified players - * - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location - * @see #display(Vector, float, Location, List) - */ - public void display(Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - display(direction, speed, center, Arrays.asList(players)); - } - - /** - * Displays a single particle which is colored and only visible for all players within a certain range in the world of @param center - * - * @param color Color of the particle - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect - * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean) - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(ParticleColor color, Location center, double range) throws ParticleVersionException, ParticleColorException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.COLORABLE)) { - throw new ParticleColorException("This particle effect is not colorable"); - } - if (!isColorCorrect(this, color)) { - throw new ParticleColorException("The particle color type is incorrect"); - } - new ParticlePacket(this, color, range > 256).sendTo(center, range); - } - - /** - * Displays a single particle which is colored and only visible for the specified players - * - * @param color Color of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect - * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean) - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(ParticleColor color, Location center, List players) throws ParticleVersionException, ParticleColorException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.COLORABLE)) { - throw new ParticleColorException("This particle effect is not colorable"); - } - if (!isColorCorrect(this, color)) { - throw new ParticleColorException("The particle color type is incorrect"); - } - new ParticlePacket(this, color, isLongDistance(center, players)).sendTo(center, players); - } - - /** - * Displays a single particle which is colored and only visible for the specified players - * - * @param color Color of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect - * @see #display(ParticleColor, Location, List) - */ - public void display(ParticleColor color, Location center, Player... players) throws ParticleVersionException, ParticleColorException { - display(color, center, Arrays.asList(players)); - } - - /** - * Displays a particle effect which requires additional data and is only visible for all players within a certain range in the world of @param center - * - * @param data Data of the effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, data).sendTo(center, range); - } - - /** - * Displays a particle effect which requires additional data and is only visible for the specified players - * - * @param data Data of the effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data).sendTo(center, players); - } - - /** - * Displays a particle effect which requires additional data and is only visible for the specified players - * - * @param data Data of the effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see #display(ParticleData, float, float, float, float, int, Location, List) - */ - public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException { - display(data, offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); - } - - /** - * Displays a single particle which requires additional data that flies into a determined direction and is only visible for all players within a certain range in the world of @param center - * - * @param data Data of the effect - * @param direction Direction of the particle - * @param speed Display speed of the particles - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(ParticleData data, Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, direction, speed, range > 256, data).sendTo(center, range); - } - - /** - * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players - * - * @param data Data of the effect - * @param direction Direction of the particle - * @param speed Display speed of the particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(ParticleData data, Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, direction, speed, isLongDistance(center, players), data).sendTo(center, players); - } - - /** - * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players - * - * @param data Data of the effect - * @param direction Direction of the particle - * @param speed Display speed of the particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see #display(ParticleData, Vector, float, Location, List) - */ - public void display(ParticleData data, Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException { - display(data, direction, speed, center, Arrays.asList(players)); - } - - /** - * Represents the property of a particle effect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public static enum ParticleProperty { - /** - * The particle effect requires water to be displayed - */ - REQUIRES_WATER, - /** - * The particle effect requires block or item data to be displayed - */ - REQUIRES_DATA, - /** - * The particle effect uses the offsets as direction values - */ - DIRECTIONAL, - /** - * The particle effect uses the offsets as color values - */ - COLORABLE; - } - - /** - * Represents the particle data for effects like {@link ParticleEffect#ITEM_CRACK}, {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST} - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - public static abstract class ParticleData { - private final Material material; - private final byte data; - private final int[] packetData; - - /** - * Construct a new particle data - * - * @param material Material of the item/block - * @param data Data value of the item/block - */ - @SuppressWarnings("deprecation") - public ParticleData(Material material, byte data) { - this.material = material; - this.data = data; - this.packetData = new int[]{material.getId(), data}; - } - - /** - * Returns the material of this data - * - * @return The material - */ - public Material getMaterial() { - return material; - } - - /** - * Returns the data value of this data - * - * @return The data value - */ - public byte getData() { - return data; - } - - /** - * Returns the data as an int array for packet construction - * - * @return The data for the packet - */ - public int[] getPacketData() { - return packetData; - } - - /** - * Returns the data as a string for pre 1.8 versions - * - * @return The data string for the packet - */ - public String getPacketDataString() { - return "_" + packetData[0] + "_" + packetData[1]; - } - } - - /** - * Represents the item data for the {@link ParticleEffect#ITEM_CRACK} effect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - public static final class ItemData extends ParticleData { - /** - * Construct a new item data - * - * @param material Material of the item - * @param data Data value of the item - * @see ParticleData#ParticleData(Material, byte) - */ - public ItemData(Material material, byte data) { - super(material, data); - } - } - - /** - * Represents the block data for the {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST} effects - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - public static final class BlockData extends ParticleData { - /** - * Construct a new block data - * - * @param material Material of the block - * @param data Data value of the block - * @throws IllegalArgumentException If the material is not a block - * @see ParticleData#ParticleData(Material, byte) - */ - public BlockData(Material material, byte data) throws IllegalArgumentException { - super(material, data); - if (!material.isBlock()) { - throw new IllegalArgumentException("The material is not a block"); - } - } - } - - /** - * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT}, {@link ParticleEffect#REDSTONE} and {@link ParticleEffect#NOTE} - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public static abstract class ParticleColor { - /** - * Returns the value for the offsetX field - * - * @return The offsetX value - */ - public abstract float getValueX(); - - /** - * Returns the value for the offsetY field - * - * @return The offsetY value - */ - public abstract float getValueY(); - - /** - * Returns the value for the offsetZ field - * - * @return The offsetZ value - */ - public abstract float getValueZ(); - } - - /** - * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT} and {@link ParticleEffect#NOTE} - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public static final class OrdinaryColor extends ParticleColor { - private final int red; - private final int green; - private final int blue; - - /** - * Construct a new ordinary color - * - * @param red Red value of the RGB format - * @param green Green value of the RGB format - * @param blue Blue value of the RGB format - * @throws IllegalArgumentException If one of the values is lower than 0 or higher than 255 - */ - public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException { - if (red < 0) { - throw new IllegalArgumentException("The red value is lower than 0"); - } - if (red > 255) { - throw new IllegalArgumentException("The red value is higher than 255"); - } - this.red = red; - if (green < 0) { - throw new IllegalArgumentException("The green value is lower than 0"); - } - if (green > 255) { - throw new IllegalArgumentException("The green value is higher than 255"); - } - this.green = green; - if (blue < 0) { - throw new IllegalArgumentException("The blue value is lower than 0"); - } - if (blue > 255) { - throw new IllegalArgumentException("The blue value is higher than 255"); - } - this.blue = blue; - } - - /** - * Construct a new ordinary color - * - * @param color Bukkit color - */ - public OrdinaryColor(Color color) { - this(color.getRed(), color.getGreen(), color.getBlue()); - } - - /** - * Returns the red value of the RGB format - * - * @return The red value - */ - public int getRed() { - return red; - } - - /** - * Returns the green value of the RGB format - * - * @return The green value - */ - public int getGreen() { - return green; - } - - /** - * Returns the blue value of the RGB format - * - * @return The blue value - */ - public int getBlue() { - return blue; - } - - /** - * Returns the red value divided by 255 - * - * @return The offsetX value - */ - @Override - public float getValueX() { - return (float) red / 255F; - } - - /** - * Returns the green value divided by 255 - * - * @return The offsetY value - */ - @Override - public float getValueY() { - return (float) green / 255F; - } - - /** - * Returns the blue value divided by 255 - * - * @return The offsetZ value - */ - @Override - public float getValueZ() { - return (float) blue / 255F; - } - } - - /** - * Represents the color for the {@link ParticleEffect#NOTE} effect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public static final class NoteColor extends ParticleColor { - private final int note; - - /** - * Construct a new note color - * - * @param note Note id which determines color - * @throws IllegalArgumentException If the note value is lower than 0 or higher than 24 - */ - public NoteColor(int note) throws IllegalArgumentException { - if (note < 0) { - throw new IllegalArgumentException("The note value is lower than 0"); - } - if (note > 24) { - throw new IllegalArgumentException("The note value is higher than 24"); - } - this.note = note; - } - - /** - * Returns the note value divided by 24 - * - * @return The offsetX value - */ - @Override - public float getValueX() { - return (float) note / 24F; - } - - /** - * Returns zero because the offsetY value is unused - * - * @return zero - */ - @Override - public float getValueY() { - return 0; - } - - /** - * Returns zero because the offsetZ value is unused - * - * @return zero - */ - @Override - public float getValueZ() { - return 0; - } - - } - - /** - * Represents a runtime exception that is thrown either if the displayed particle effect requires data and has none or vice-versa or if the data type is incorrect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - private static final class ParticleDataException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new particle data exception - * - * @param message Message that will be logged - */ - public ParticleDataException(String message) { - super(message); - } - } - - /** - * Represents a runtime exception that is thrown either if the displayed particle effect is not colorable or if the particle color type is incorrect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - private static final class ParticleColorException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new particle color exception - * - * @param message Message that will be logged - */ - public ParticleColorException(String message) { - super(message); - } - } - - /** - * Represents a runtime exception that is thrown if the displayed particle effect requires a newer version - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - private static final class ParticleVersionException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new particle version exception - * - * @param message Message that will be logged - */ - public ParticleVersionException(String message) { - super(message); - } - } - - /** - * Represents a particle effect packet with all attributes which is used for sending packets to the players - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.5 - */ - public static final class ParticlePacket { - private static int version; - private static Class enumParticle; - private static Constructor packetConstructor; - private static Method getHandle; - private static Field playerConnection; - private static Method sendPacket; - private static boolean initialized; - private final ParticleEffect effect; - private final float offsetY; - private final float offsetZ; - private final float speed; - private final int amount; - private final boolean longDistance; - private final ParticleData data; - private float offsetX; - private Object packet; - - /** - * Construct a new particle packet - * - * @param effect Particle effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 - * @param data Data of the effect - * @throws IllegalArgumentException If the speed or amount is lower than 0 - * @see #initialize() - */ - public ParticlePacket(ParticleEffect effect, float offsetX, float offsetY, float offsetZ, float speed, int amount, boolean longDistance, ParticleData data) throws IllegalArgumentException { - initialize(); - if (speed < 0) { - throw new IllegalArgumentException("The speed is lower than 0"); - } - if (amount < 0) { - throw new IllegalArgumentException("The amount is lower than 0"); - } - this.effect = effect; - this.offsetX = offsetX; - this.offsetY = offsetY; - this.offsetZ = offsetZ; - this.speed = speed; - this.amount = amount; - this.longDistance = longDistance; - this.data = data; - } - - /** - * Construct a new particle packet of a single particle flying into a determined direction - * - * @param effect Particle effect - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 - * @param data Data of the effect - * @throws IllegalArgumentException If the speed is lower than 0 - */ - public ParticlePacket(ParticleEffect effect, Vector direction, float speed, boolean longDistance, ParticleData data) throws IllegalArgumentException { - this(effect, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), speed, 0, longDistance, data); - } - - /** - * Construct a new particle packet of a single colored particle - * - * @param effect Particle effect - * @param color Color of the particle - * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 - */ - public ParticlePacket(ParticleEffect effect, ParticleColor color, boolean longDistance) { - this(effect, color.getValueX(), color.getValueY(), color.getValueZ(), 1, 0, longDistance, null); - if (effect == ParticleEffect.REDSTONE && color instanceof OrdinaryColor && ((OrdinaryColor) color).getRed() == 0) { - offsetX = Float.MIN_NORMAL; - } - } - - /** - * Initializes {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} and sets {@link #initialized} to true if it succeeds - *

- * Note: These fields only have to be initialized once, so it will return if {@link #initialized} is already set to true - * - * @throws VersionIncompatibleException if your bukkit version is not supported by this library - */ - public static void initialize() throws VersionIncompatibleException { - if (initialized) { - return; - } - try { - version = Integer.parseInt(ReflectionUtils.PackageType.getServerVersion().split("_")[1]); - if (version > 7) { - enumParticle = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("EnumParticle"); - } - - Class packetClass = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass(version < 7 ? "Packet63WorldParticles" : "PacketPlayOutWorldParticles"); - - packetConstructor = ReflectionUtils.getConstructor(packetClass); - getHandle = ReflectionUtils.getMethod("CraftPlayer", ReflectionUtils.PackageType.CRAFTBUKKIT_ENTITY, "getHandle"); - playerConnection = ReflectionUtils.getField("EntityPlayer", ReflectionUtils.PackageType.MINECRAFT_SERVER, false, "playerConnection"); - sendPacket = ReflectionUtils.getMethod(playerConnection.getType(), "sendPacket", ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("Packet")); - } catch (Exception exception) { - throw new VersionIncompatibleException("Your current bukkit version seems to be incompatible with this library", exception); - } - initialized = true; - } - - /** - * Returns the version of your server (1.x) - * - * @return The version number - */ - public static int getVersion() { - if (!initialized) { - initialize(); - } - return version; - } - - /** - * Determine if {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} are initialized - * - * @return Whether these fields are initialized or not - * @see #initialize() - */ - public static boolean isInitialized() { - return initialized; - } - - /** - * Initializes {@link #packet} with all set values - * - * @param center Center location of the effect - * @throws PacketInstantiationException If instantion fails due to an unknown error - */ - private void initializePacket(Location center) throws PacketInstantiationException { - if (packet != null) { - return; - } - try { - packet = packetConstructor.newInstance(); - if (version < 8) { - String name = effect.getName(); - if (data != null) { - name += data.getPacketDataString(); - } - ReflectionUtils.setValue(packet, true, "a", name); - } else { - ReflectionUtils.setValue(packet, true, "a", enumParticle.getEnumConstants()[effect.getId()]); - ReflectionUtils.setValue(packet, true, "j", longDistance); - if (data != null) { - int[] packetData = data.getPacketData(); - ReflectionUtils.setValue(packet, true, "k", effect == ParticleEffect.ITEM_CRACK ? packetData : new int[]{packetData[0] | (packetData[1] << 12)}); - } - } - ReflectionUtils.setValue(packet, true, "b", (float) center.getX()); - ReflectionUtils.setValue(packet, true, "c", (float) center.getY()); - ReflectionUtils.setValue(packet, true, "d", (float) center.getZ()); - ReflectionUtils.setValue(packet, true, "e", offsetX); - ReflectionUtils.setValue(packet, true, "f", offsetY); - ReflectionUtils.setValue(packet, true, "g", offsetZ); - ReflectionUtils.setValue(packet, true, "h", speed); - ReflectionUtils.setValue(packet, true, "i", amount); - } catch (Exception exception) { - throw new PacketInstantiationException("Packet instantiation failed", exception); - } - } - - /** - * Sends the packet to a single player and caches it - * - * @param center Center location of the effect - * @param player Receiver of the packet - * @throws PacketInstantiationException If instantion fails due to an unknown error - * @throws PacketSendingException If sending fails due to an unknown error - * @see #initializePacket(Location) - */ - public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException { - initializePacket(center); - try { - sendPacket.invoke(playerConnection.get(getHandle.invoke(player)), packet); - } catch (Exception exception) { - throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception); - } - } - - /** - * Sends the packet to all players in the list - * - * @param center Center location of the effect - * @param players Receivers of the packet - * @throws IllegalArgumentException If the player list is empty - * @see #sendTo(Location center, Player player) - */ - public void sendTo(Location center, List players) throws IllegalArgumentException { - if (players.isEmpty()) { - throw new IllegalArgumentException("The player list is empty"); - } - for (Player player : players) { - sendTo(center, player); - } - } - - /** - * Sends the packet to all players in a certain range - * - * @param center Center location of the effect - * @param range Range in which players will receive the packet (Maximum range for particles is usually 16, but it can differ for some types) - * @throws IllegalArgumentException If the range is lower than 1 - * @see #sendTo(Location center, Player player) - */ - public void sendTo(Location center, double range) throws IllegalArgumentException { - if (range < 1) { - throw new IllegalArgumentException("The range is lower than 1"); - } - String worldName = center.getWorld().getName(); - double squared = range * range; - for (Player player : Bukkit.getOnlinePlayers()) { - if (!player.getWorld().getName().equals(worldName) || player.getLocation().distanceSquared(center) > squared) { - continue; - } - sendTo(center, player); - } - } - - /** - * Represents a runtime exception that is thrown if a bukkit version is not compatible with this library - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.5 - */ - private static final class VersionIncompatibleException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new version incompatible exception - * - * @param message Message that will be logged - * @param cause Cause of the exception - */ - public VersionIncompatibleException(String message, Throwable cause) { - super(message, cause); - } - } - - /** - * Represents a runtime exception that is thrown if packet instantiation fails - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.4 - */ - private static final class PacketInstantiationException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new packet instantiation exception - * - * @param message Message that will be logged - * @param cause Cause of the exception - */ - public PacketInstantiationException(String message, Throwable cause) { - super(message, cause); - } - } - - /** - * Represents a runtime exception that is thrown if packet sending fails - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.4 - */ - private static final class PacketSendingException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new packet sending exception - * - * @param message Message that will be logged - * @param cause Cause of the exception - */ - public PacketSendingException(String message, Throwable cause) { - super(message, cause); - } - } - } + /** + * A particle effect which is displayed by exploding tnt and creepers: + *

    + *
  • It looks like a white cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + EXPLOSION_NORMAL("explode", 0, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by exploding ghast fireballs and wither skulls: + *
    + *
  • It looks like a gray ball which is fading away + *
  • The speed value slightly influences the size of this particle effect + *
+ */ + EXPLOSION_LARGE("largeexplode", 1, -1), + /** + * A particle effect which is displayed by exploding tnt and creepers: + *
    + *
  • It looks like a crowd of gray balls which are fading away + *
  • The speed value has no influence on this particle effect + *
+ */ + EXPLOSION_HUGE("hugeexplosion", 2, -1), + /** + * A particle effect which is displayed by launching fireworks: + *
    + *
  • It looks like a white star which is sparkling + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + FIREWORKS_SPARK("fireworksSpark", 3, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by swimming entities and arrows in water: + *
    + *
  • It looks like a bubble + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + WATER_BUBBLE("bubble", 4, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_WATER), + /** + * A particle effect which is displayed by swimming entities and shaking wolves: + *
    + *
  • It looks like a blue drop + *
  • The speed value has no influence on this particle effect + *
+ */ + WATER_SPLASH("splash", 5, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed on water when fishing: + *
    + *
  • It looks like a blue droplet + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + WATER_WAKE("wake", 6, 7, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by water: + *
    + *
  • It looks like a tiny blue square + *
  • The speed value has no influence on this particle effect + *
+ */ + SUSPENDED("suspended", 7, -1, ParticleProperty.REQUIRES_WATER), + /** + * A particle effect which is displayed by air when close to bedrock and the in the void: + *
    + *
  • It looks like a tiny gray square + *
  • The speed value has no influence on this particle effect + *
+ */ + SUSPENDED_DEPTH("depthSuspend", 8, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed when landing a critical hit and by arrows: + *
    + *
  • It looks like a light brown cross + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + CRIT("crit", 9, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed when landing a hit with an enchanted weapon: + *
    + *
  • It looks like a cyan star + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + CRIT_MAGIC("magicCrit", 10, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by primed tnt, torches, droppers, dispensers, end portals, brewing stands and monster spawners: + *
    + *
  • It looks like a little gray cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + SMOKE_NORMAL("smoke", 11, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by fire, minecarts with furnace and blazes: + *
    + *
  • It looks like a large gray cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + SMOKE_LARGE("largesmoke", 12, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed when splash potions or bottles o' enchanting hit something: + *
    + *
  • It looks like a white swirl + *
  • The speed value causes the particle to only move upwards when set to 0 + *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 + *
+ */ + SPELL("spell", 13, -1), + /** + * A particle effect which is displayed when instant splash potions hit something: + *
    + *
  • It looks like a white cross + *
  • The speed value causes the particle to only move upwards when set to 0 + *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 + *
+ */ + SPELL_INSTANT("instantSpell", 14, -1), + /** + * A particle effect which is displayed by entities with active potion effects: + *
    + *
  • It looks like a colored swirl + *
  • The speed value causes the particle to be colored black when set to 0 + *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed + *
+ */ + SPELL_MOB("mobSpell", 15, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed by entities with active potion effects applied through a beacon: + *
    + *
  • It looks like a transparent colored swirl + *
  • The speed value causes the particle to be always colored black when set to 0 + *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed + *
+ */ + SPELL_MOB_AMBIENT("mobSpellAmbient", 16, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed by witches: + *
    + *
  • It looks like a purple cross + *
  • The speed value causes the particle to only move upwards when set to 0 + *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 + *
+ */ + SPELL_WITCH("witchMagic", 17, -1), + /** + * A particle effect which is displayed by blocks beneath a water source: + *
    + *
  • It looks like a blue drip + *
  • The speed value has no influence on this particle effect + *
+ */ + DRIP_WATER("dripWater", 18, -1), + /** + * A particle effect which is displayed by blocks beneath a lava source: + *
    + *
  • It looks like an orange drip + *
  • The speed value has no influence on this particle effect + *
+ */ + DRIP_LAVA("dripLava", 19, -1), + /** + * A particle effect which is displayed when attacking a villager in a village: + *
    + *
  • It looks like a cracked gray heart + *
  • The speed value has no influence on this particle effect + *
+ */ + VILLAGER_ANGRY("angryVillager", 20, -1), + /** + * A particle effect which is displayed when using bone meal and trading with a villager in a village: + *
    + *
  • It looks like a green star + *
  • The speed value has no influence on this particle effect + *
+ */ + VILLAGER_HAPPY("happyVillager", 21, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by mycelium: + *
    + *
  • It looks like a tiny gray square + *
  • The speed value has no influence on this particle effect + *
+ */ + TOWN_AURA("townaura", 22, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by note blocks: + *
    + *
  • It looks like a colored note + *
  • The speed value causes the particle to be colored green when set to 0 + *
+ */ + NOTE("note", 23, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed by nether portals, endermen, ender pearls, eyes of ender, ender chests and dragon eggs: + *
    + *
  • It looks like a purple cloud + *
  • The speed value influences the spread of this particle effect + *
+ */ + PORTAL("portal", 24, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by enchantment tables which are nearby bookshelves: + *
    + *
  • It looks like a cryptic white letter + *
  • The speed value influences the spread of this particle effect + *
+ */ + ENCHANTMENT_TABLE("enchantmenttable", 25, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by torches, active furnaces, magma cubes and monster spawners: + *
    + *
  • It looks like a tiny flame + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + FLAME("flame", 26, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by lava: + *
    + *
  • It looks like a spark + *
  • The speed value has no influence on this particle effect + *
+ */ + LAVA("lava", 27, -1), + /** + * A particle effect which is currently unused: + *
    + *
  • It looks like a transparent gray square + *
  • The speed value has no influence on this particle effect + *
+ */ + FOOTSTEP("footstep", 28, -1), + /** + * A particle effect which is displayed when a mob dies: + *
    + *
  • It looks like a large white cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + CLOUD("cloud", 29, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by redstone ore, powered redstone, redstone torches and redstone repeaters: + *
    + *
  • It looks like a tiny colored cloud + *
  • The speed value causes the particle to be colored red when set to 0 + *
+ */ + REDSTONE("reddust", 30, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed when snowballs hit a block: + *
    + *
  • It looks like a little piece with the snowball texture + *
  • The speed value has no influence on this particle effect + *
+ */ + SNOWBALL("snowballpoof", 31, -1), + /** + * A particle effect which is currently unused: + *
    + *
  • It looks like a tiny white cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + SNOW_SHOVEL("snowshovel", 32, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by slimes: + *
    + *
  • It looks like a tiny part of the slimeball icon + *
  • The speed value has no influence on this particle effect + *
+ */ + SLIME("slime", 33, -1), + /** + * A particle effect which is displayed when breeding and taming animals: + *
    + *
  • It looks like a red heart + *
  • The speed value has no influence on this particle effect + *
+ */ + HEART("heart", 34, -1), + /** + * A particle effect which is displayed by barriers: + *
    + *
  • It looks like a red box with a slash through it + *
  • The speed value has no influence on this particle effect + *
+ */ + BARRIER("barrier", 35, 8), + /** + * A particle effect which is displayed when breaking a tool or eggs hit a block: + *
    + *
  • It looks like a little piece with an item texture + *
+ */ + ITEM_CRACK("iconcrack", 36, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), + /** + * A particle effect which is displayed when breaking blocks or sprinting: + *
    + *
  • It looks like a little piece with a block texture + *
  • The speed value has no influence on this particle effect + *
+ */ + BLOCK_CRACK("blockcrack", 37, -1, ParticleProperty.REQUIRES_DATA), + /** + * A particle effect which is displayed when falling: + *
    + *
  • It looks like a little piece with a block texture + *
+ */ + BLOCK_DUST("blockdust", 38, 7, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), + /** + * A particle effect which is displayed when rain hits the ground: + *
    + *
  • It looks like a blue droplet + *
  • The speed value has no influence on this particle effect + *
+ */ + WATER_DROP("droplet", 39, 8), + /** + * A particle effect which is currently unused: + *
    + *
  • It has no visual effect + *
+ */ + ITEM_TAKE("take", 40, 8), + /** + * A particle effect which is displayed by elder guardians: + *
    + *
  • It looks like the shape of the elder guardian + *
  • The speed value has no influence on this particle effect + *
  • The offset values have no influence on this particle effect + *
+ */ + MOB_APPEARANCE("mobappearance", 41, 8); + + private static final Map NAME_MAP = new HashMap(); + private static final Map ID_MAP = new HashMap(); + + // Initialize map for quick name and id lookup + static { + for (ParticleEffect effect : values()) { + NAME_MAP.put(effect.name, effect); + ID_MAP.put(effect.id, effect); + } + } + + private final String name; + private final int id; + private final int requiredVersion; + private final List properties; + + /** + * Construct a new particle effect + * + * @param name Name of this particle effect + * @param id Id of this particle effect + * @param requiredVersion Version which is required (1.x) + * @param properties Properties of this particle effect + */ + private ParticleEffect(String name, int id, int requiredVersion, ParticleProperty... properties) { + this.name = name; + this.id = id; + this.requiredVersion = requiredVersion; + this.properties = Arrays.asList(properties); + } + + /** + * Returns the particle effect with the given name + * + * @param name Name of the particle effect + * @return The particle effect + */ + public static ParticleEffect fromName(String name) { + for (Entry entry : NAME_MAP.entrySet()) { + if (!entry.getKey().equalsIgnoreCase(name)) { + continue; + } + return entry.getValue(); + } + return null; + } + + /** + * Returns the particle effect with the given id + * + * @param id Id of the particle effect + * @return The particle effect + */ + public static ParticleEffect fromId(int id) { + for (Entry entry : ID_MAP.entrySet()) { + if (entry.getKey() != id) { + continue; + } + return entry.getValue(); + } + return null; + } + + /** + * Determine if water is at a certain location + * + * @param location Location to check + * @return Whether water is at this location or not + */ + private static boolean isWater(Location location) { + Material material = location.getBlock().getType(); + return material == Material.WATER || material == Material.STATIONARY_WATER; + } + + /** + * Determine if the distance between @param location and one of the players exceeds 256 + * + * @param location Location to check + * @return Whether the distance exceeds 256 or not + */ + private static boolean isLongDistance(Location location, List players) { + String world = location.getWorld().getName(); + for (Player player : players) { + Location playerLocation = player.getLocation(); + if (!world.equals(playerLocation.getWorld().getName()) || playerLocation.distanceSquared(location) < 65536) { + continue; + } + return true; + } + return false; + } + + /** + * Determine if the data type for a particle effect is correct + * + * @param effect Particle effect + * @param data Particle data + * @return Whether the data type is correct or not + */ + private static boolean isDataCorrect(ParticleEffect effect, ParticleData data) { + return ((effect == BLOCK_CRACK || effect == BLOCK_DUST) && data instanceof BlockData) || (effect == ITEM_CRACK && data instanceof ItemData); + } + + /** + * Determine if the color type for a particle effect is correct + * + * @param effect Particle effect + * @param color Particle color + * @return Whether the color type is correct or not + */ + private static boolean isColorCorrect(ParticleEffect effect, ParticleColor color) { + return ((effect == SPELL_MOB || effect == SPELL_MOB_AMBIENT || effect == REDSTONE) && color instanceof OrdinaryColor) || (effect == NOTE && color instanceof NoteColor); + } + + /** + * Returns the name of this particle effect + * + * @return The name + */ + public String getName() { + return name; + } + + /** + * Returns the id of this particle effect + * + * @return The id + */ + public int getId() { + return id; + } + + /** + * Returns the required version for this particle effect (1.x) + * + * @return The required version + */ + public int getRequiredVersion() { + return requiredVersion; + } + + /** + * Determine if this particle effect has a specific property + * + * @return Whether it has the property or not + */ + public boolean hasProperty(ParticleProperty property) { + return properties.contains(property); + } + + /** + * Determine if this particle effect is supported by your current server version + * + * @return Whether the particle effect is supported or not + */ + public boolean isSupported() { + if (requiredVersion == -1) { + return true; + } + return ParticlePacket.getVersion() >= requiredVersion; + } + + /** + * Displays a particle effect which is only visible for all players within a certain range in the world of @param center + * + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect requires water and none is at the center location + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, null).sendTo(center, range); + } + + /** + * Displays a particle effect which is only visible for the specified players + * + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect requires water and none is at the center location + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null).sendTo(center, players); + } + + /** + * Displays a particle effect which is only visible for the specified players + * + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect requires water and none is at the center location + * @see #display(float, float, float, float, int, Location, List) + */ + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + display(offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); + } + + /** + * Displays a single particle which flies into a determined direction and is only visible for all players within a certain range in the world of @param center + * + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location + * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData) + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (!hasProperty(ParticleProperty.DIRECTIONAL)) { + throw new IllegalArgumentException("This particle effect is not directional"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, direction, speed, range > 256, null).sendTo(center, range); + } + + /** + * Displays a single particle which flies into a determined direction and is only visible for the specified players + * + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location + * @see ParticlePacket#ParticlePacket(ParticleEffect, Vector, float, boolean, ParticleData) + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (!hasProperty(ParticleProperty.DIRECTIONAL)) { + throw new IllegalArgumentException("This particle effect is not directional"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, direction, speed, isLongDistance(center, players), null).sendTo(center, players); + } + + /** + * Displays a single particle which flies into a determined direction and is only visible for the specified players + * + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location + * @see #display(Vector, float, Location, List) + */ + public void display(Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + display(direction, speed, center, Arrays.asList(players)); + } + + /** + * Displays a single particle which is colored and only visible for all players within a certain range in the world of @param center + * + * @param color Color of the particle + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect + * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean) + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(ParticleColor color, Location center, double range) throws ParticleVersionException, ParticleColorException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.COLORABLE)) { + throw new ParticleColorException("This particle effect is not colorable"); + } + if (!isColorCorrect(this, color)) { + throw new ParticleColorException("The particle color type is incorrect"); + } + new ParticlePacket(this, color, range > 256).sendTo(center, range); + } + + /** + * Displays a single particle which is colored and only visible for the specified players + * + * @param color Color of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect + * @see ParticlePacket#ParticlePacket(ParticleEffect, ParticleColor, boolean) + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(ParticleColor color, Location center, List players) throws ParticleVersionException, ParticleColorException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.COLORABLE)) { + throw new ParticleColorException("This particle effect is not colorable"); + } + if (!isColorCorrect(this, color)) { + throw new ParticleColorException("The particle color type is incorrect"); + } + new ParticlePacket(this, color, isLongDistance(center, players)).sendTo(center, players); + } + + /** + * Displays a single particle which is colored and only visible for the specified players + * + * @param color Color of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect + * @see #display(ParticleColor, Location, List) + */ + public void display(ParticleColor color, Location center, Player... players) throws ParticleVersionException, ParticleColorException { + display(color, center, Arrays.asList(players)); + } + + /** + * Displays a particle effect which requires additional data and is only visible for all players within a certain range in the world of @param center + * + * @param data Data of the effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, data).sendTo(center, range); + } + + /** + * Displays a particle effect which requires additional data and is only visible for the specified players + * + * @param data Data of the effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data).sendTo(center, players); + } + + /** + * Displays a particle effect which requires additional data and is only visible for the specified players + * + * @param data Data of the effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see #display(ParticleData, float, float, float, float, int, Location, List) + */ + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException { + display(data, offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); + } + + /** + * Displays a single particle which requires additional data that flies into a determined direction and is only visible for all players within a certain range in the world of @param center + * + * @param data Data of the effect + * @param direction Direction of the particle + * @param speed Display speed of the particles + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(ParticleData data, Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, direction, speed, range > 256, data).sendTo(center, range); + } + + /** + * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players + * + * @param data Data of the effect + * @param direction Direction of the particle + * @param speed Display speed of the particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(ParticleData data, Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, direction, speed, isLongDistance(center, players), data).sendTo(center, players); + } + + /** + * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players + * + * @param data Data of the effect + * @param direction Direction of the particle + * @param speed Display speed of the particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see #display(ParticleData, Vector, float, Location, List) + */ + public void display(ParticleData data, Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException { + display(data, direction, speed, center, Arrays.asList(players)); + } + + /** + * Represents the property of a particle effect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public static enum ParticleProperty { + /** + * The particle effect requires water to be displayed + */ + REQUIRES_WATER, + /** + * The particle effect requires block or item data to be displayed + */ + REQUIRES_DATA, + /** + * The particle effect uses the offsets as direction values + */ + DIRECTIONAL, + /** + * The particle effect uses the offsets as color values + */ + COLORABLE; + } + + /** + * Represents the particle data for effects like {@link ParticleEffect#ITEM_CRACK}, {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST} + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + public static abstract class ParticleData { + private final Material material; + private final byte data; + private final int[] packetData; + + /** + * Construct a new particle data + * + * @param material Material of the item/block + * @param data Data value of the item/block + */ + @SuppressWarnings("deprecation") + public ParticleData(Material material, byte data) { + this.material = material; + this.data = data; + this.packetData = new int[]{material.getId(), data}; + } + + /** + * Returns the material of this data + * + * @return The material + */ + public Material getMaterial() { + return material; + } + + /** + * Returns the data value of this data + * + * @return The data value + */ + public byte getData() { + return data; + } + + /** + * Returns the data as an int array for packet construction + * + * @return The data for the packet + */ + public int[] getPacketData() { + return packetData; + } + + /** + * Returns the data as a string for pre 1.8 versions + * + * @return The data string for the packet + */ + public String getPacketDataString() { + return "_" + packetData[0] + "_" + packetData[1]; + } + } + + /** + * Represents the item data for the {@link ParticleEffect#ITEM_CRACK} effect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + public static final class ItemData extends ParticleData { + /** + * Construct a new item data + * + * @param material Material of the item + * @param data Data value of the item + * @see ParticleData#ParticleData(Material, byte) + */ + public ItemData(Material material, byte data) { + super(material, data); + } + } + + /** + * Represents the block data for the {@link ParticleEffect#BLOCK_CRACK} and {@link ParticleEffect#BLOCK_DUST} effects + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + public static final class BlockData extends ParticleData { + /** + * Construct a new block data + * + * @param material Material of the block + * @param data Data value of the block + * @throws IllegalArgumentException If the material is not a block + * @see ParticleData#ParticleData(Material, byte) + */ + public BlockData(Material material, byte data) throws IllegalArgumentException { + super(material, data); + if (!material.isBlock()) { + throw new IllegalArgumentException("The material is not a block"); + } + } + } + + /** + * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT}, {@link ParticleEffect#REDSTONE} and {@link ParticleEffect#NOTE} + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public static abstract class ParticleColor { + /** + * Returns the value for the offsetX field + * + * @return The offsetX value + */ + public abstract float getValueX(); + + /** + * Returns the value for the offsetY field + * + * @return The offsetY value + */ + public abstract float getValueY(); + + /** + * Returns the value for the offsetZ field + * + * @return The offsetZ value + */ + public abstract float getValueZ(); + } + + /** + * Represents the color for effects like {@link ParticleEffect#SPELL_MOB}, {@link ParticleEffect#SPELL_MOB_AMBIENT} and {@link ParticleEffect#NOTE} + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public static final class OrdinaryColor extends ParticleColor { + private final int red; + private final int green; + private final int blue; + + /** + * Construct a new ordinary color + * + * @param red Red value of the RGB format + * @param green Green value of the RGB format + * @param blue Blue value of the RGB format + * @throws IllegalArgumentException If one of the values is lower than 0 or higher than 255 + */ + public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException { + if (red < 0) { + throw new IllegalArgumentException("The red value is lower than 0"); + } + if (red > 255) { + throw new IllegalArgumentException("The red value is higher than 255"); + } + this.red = red; + if (green < 0) { + throw new IllegalArgumentException("The green value is lower than 0"); + } + if (green > 255) { + throw new IllegalArgumentException("The green value is higher than 255"); + } + this.green = green; + if (blue < 0) { + throw new IllegalArgumentException("The blue value is lower than 0"); + } + if (blue > 255) { + throw new IllegalArgumentException("The blue value is higher than 255"); + } + this.blue = blue; + } + + /** + * Construct a new ordinary color + * + * @param color Bukkit color + */ + public OrdinaryColor(Color color) { + this(color.getRed(), color.getGreen(), color.getBlue()); + } + + /** + * Returns the red value of the RGB format + * + * @return The red value + */ + public int getRed() { + return red; + } + + /** + * Returns the green value of the RGB format + * + * @return The green value + */ + public int getGreen() { + return green; + } + + /** + * Returns the blue value of the RGB format + * + * @return The blue value + */ + public int getBlue() { + return blue; + } + + /** + * Returns the red value divided by 255 + * + * @return The offsetX value + */ + @Override + public float getValueX() { + return (float) red / 255F; + } + + /** + * Returns the green value divided by 255 + * + * @return The offsetY value + */ + @Override + public float getValueY() { + return (float) green / 255F; + } + + /** + * Returns the blue value divided by 255 + * + * @return The offsetZ value + */ + @Override + public float getValueZ() { + return (float) blue / 255F; + } + } + + /** + * Represents the color for the {@link ParticleEffect#NOTE} effect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public static final class NoteColor extends ParticleColor { + private final int note; + + /** + * Construct a new note color + * + * @param note Note id which determines color + * @throws IllegalArgumentException If the note value is lower than 0 or higher than 24 + */ + public NoteColor(int note) throws IllegalArgumentException { + if (note < 0) { + throw new IllegalArgumentException("The note value is lower than 0"); + } + if (note > 24) { + throw new IllegalArgumentException("The note value is higher than 24"); + } + this.note = note; + } + + /** + * Returns the note value divided by 24 + * + * @return The offsetX value + */ + @Override + public float getValueX() { + return (float) note / 24F; + } + + /** + * Returns zero because the offsetY value is unused + * + * @return zero + */ + @Override + public float getValueY() { + return 0; + } + + /** + * Returns zero because the offsetZ value is unused + * + * @return zero + */ + @Override + public float getValueZ() { + return 0; + } + + } + + /** + * Represents a runtime exception that is thrown either if the displayed particle effect requires data and has none or vice-versa or if the data type is incorrect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + private static final class ParticleDataException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new particle data exception + * + * @param message Message that will be logged + */ + public ParticleDataException(String message) { + super(message); + } + } + + /** + * Represents a runtime exception that is thrown either if the displayed particle effect is not colorable or if the particle color type is incorrect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + private static final class ParticleColorException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new particle color exception + * + * @param message Message that will be logged + */ + public ParticleColorException(String message) { + super(message); + } + } + + /** + * Represents a runtime exception that is thrown if the displayed particle effect requires a newer version + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + private static final class ParticleVersionException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new particle version exception + * + * @param message Message that will be logged + */ + public ParticleVersionException(String message) { + super(message); + } + } + + /** + * Represents a particle effect packet with all attributes which is used for sending packets to the players + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.5 + */ + public static final class ParticlePacket { + private static int version; + private static Class enumParticle; + private static Constructor packetConstructor; + private static Method getHandle; + private static Field playerConnection; + private static Method sendPacket; + private static boolean initialized; + private final ParticleEffect effect; + private final float offsetY; + private final float offsetZ; + private final float speed; + private final int amount; + private final boolean longDistance; + private final ParticleData data; + private float offsetX; + private Object packet; + + /** + * Construct a new particle packet + * + * @param effect Particle effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 + * @param data Data of the effect + * @throws IllegalArgumentException If the speed or amount is lower than 0 + * @see #initialize() + */ + public ParticlePacket(ParticleEffect effect, float offsetX, float offsetY, float offsetZ, float speed, int amount, boolean longDistance, ParticleData data) throws IllegalArgumentException { + initialize(); + if (speed < 0) { + throw new IllegalArgumentException("The speed is lower than 0"); + } + if (amount < 0) { + throw new IllegalArgumentException("The amount is lower than 0"); + } + this.effect = effect; + this.offsetX = offsetX; + this.offsetY = offsetY; + this.offsetZ = offsetZ; + this.speed = speed; + this.amount = amount; + this.longDistance = longDistance; + this.data = data; + } + + /** + * Construct a new particle packet of a single particle flying into a determined direction + * + * @param effect Particle effect + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 + * @param data Data of the effect + * @throws IllegalArgumentException If the speed is lower than 0 + */ + public ParticlePacket(ParticleEffect effect, Vector direction, float speed, boolean longDistance, ParticleData data) throws IllegalArgumentException { + this(effect, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), speed, 0, longDistance, data); + } + + /** + * Construct a new particle packet of a single colored particle + * + * @param effect Particle effect + * @param color Color of the particle + * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 + */ + public ParticlePacket(ParticleEffect effect, ParticleColor color, boolean longDistance) { + this(effect, color.getValueX(), color.getValueY(), color.getValueZ(), 1, 0, longDistance, null); + if (effect == ParticleEffect.REDSTONE && color instanceof OrdinaryColor && ((OrdinaryColor) color).getRed() == 0) { + offsetX = Float.MIN_NORMAL; + } + } + + /** + * Initializes {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} and sets {@link #initialized} to true if it succeeds + *

+ * Note: These fields only have to be initialized once, so it will return if {@link #initialized} is already set to true + * + * @throws VersionIncompatibleException if your bukkit version is not supported by this library + */ + public static void initialize() throws VersionIncompatibleException { + if (initialized) { + return; + } + try { + version = Integer.parseInt(ReflectionUtils.PackageType.getServerVersion().split("_")[1]); + if (version > 7) { + enumParticle = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("EnumParticle"); + } + + Class packetClass = ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass(version < 7 ? "Packet63WorldParticles" : "PacketPlayOutWorldParticles"); + + packetConstructor = ReflectionUtils.getConstructor(packetClass); + getHandle = ReflectionUtils.getMethod("CraftPlayer", ReflectionUtils.PackageType.CRAFTBUKKIT_ENTITY, "getHandle"); + playerConnection = ReflectionUtils.getField("EntityPlayer", ReflectionUtils.PackageType.MINECRAFT_SERVER, false, "playerConnection"); + sendPacket = ReflectionUtils.getMethod(playerConnection.getType(), "sendPacket", ReflectionUtils.PackageType.MINECRAFT_SERVER.getClass("Packet")); + } catch (Exception exception) { + throw new VersionIncompatibleException("Your current bukkit version seems to be incompatible with this library", exception); + } + initialized = true; + } + + /** + * Returns the version of your server (1.x) + * + * @return The version number + */ + public static int getVersion() { + if (!initialized) { + initialize(); + } + return version; + } + + /** + * Determine if {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} are initialized + * + * @return Whether these fields are initialized or not + * @see #initialize() + */ + public static boolean isInitialized() { + return initialized; + } + + /** + * Initializes {@link #packet} with all set values + * + * @param center Center location of the effect + * @throws PacketInstantiationException If instantion fails due to an unknown error + */ + private void initializePacket(Location center) throws PacketInstantiationException { + if (packet != null) { + return; + } + try { + packet = packetConstructor.newInstance(); + if (version < 8) { + String name = effect.getName(); + if (data != null) { + name += data.getPacketDataString(); + } + ReflectionUtils.setValue(packet, true, "a", name); + } else { + ReflectionUtils.setValue(packet, true, "a", enumParticle.getEnumConstants()[effect.getId()]); + ReflectionUtils.setValue(packet, true, "j", longDistance); + if (data != null) { + int[] packetData = data.getPacketData(); + ReflectionUtils.setValue(packet, true, "k", effect == ParticleEffect.ITEM_CRACK ? packetData : new int[]{packetData[0] | (packetData[1] << 12)}); + } + } + ReflectionUtils.setValue(packet, true, "b", (float) center.getX()); + ReflectionUtils.setValue(packet, true, "c", (float) center.getY()); + ReflectionUtils.setValue(packet, true, "d", (float) center.getZ()); + ReflectionUtils.setValue(packet, true, "e", offsetX); + ReflectionUtils.setValue(packet, true, "f", offsetY); + ReflectionUtils.setValue(packet, true, "g", offsetZ); + ReflectionUtils.setValue(packet, true, "h", speed); + ReflectionUtils.setValue(packet, true, "i", amount); + } catch (Exception exception) { + throw new PacketInstantiationException("Packet instantiation failed", exception); + } + } + + /** + * Sends the packet to a single player and caches it + * + * @param center Center location of the effect + * @param player Receiver of the packet + * @throws PacketInstantiationException If instantion fails due to an unknown error + * @throws PacketSendingException If sending fails due to an unknown error + * @see #initializePacket(Location) + */ + public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException { + initializePacket(center); + try { + sendPacket.invoke(playerConnection.get(getHandle.invoke(player)), packet); + } catch (Exception exception) { + throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception); + } + } + + /** + * Sends the packet to all players in the list + * + * @param center Center location of the effect + * @param players Receivers of the packet + * @throws IllegalArgumentException If the player list is empty + * @see #sendTo(Location center, Player player) + */ + public void sendTo(Location center, List players) throws IllegalArgumentException { + if (players.isEmpty()) { + throw new IllegalArgumentException("The player list is empty"); + } + for (Player player : players) { + sendTo(center, player); + } + } + + /** + * Sends the packet to all players in a certain range + * + * @param center Center location of the effect + * @param range Range in which players will receive the packet (Maximum range for particles is usually 16, but it can differ for some types) + * @throws IllegalArgumentException If the range is lower than 1 + * @see #sendTo(Location center, Player player) + */ + public void sendTo(Location center, double range) throws IllegalArgumentException { + if (range < 1) { + throw new IllegalArgumentException("The range is lower than 1"); + } + String worldName = center.getWorld().getName(); + double squared = range * range; + for (Player player : Bukkit.getOnlinePlayers()) { + if (!player.getWorld().getName().equals(worldName) || player.getLocation().distanceSquared(center) > squared) { + continue; + } + sendTo(center, player); + } + } + + /** + * Represents a runtime exception that is thrown if a bukkit version is not compatible with this library + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.5 + */ + private static final class VersionIncompatibleException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new version incompatible exception + * + * @param message Message that will be logged + * @param cause Cause of the exception + */ + public VersionIncompatibleException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Represents a runtime exception that is thrown if packet instantiation fails + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.4 + */ + private static final class PacketInstantiationException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new packet instantiation exception + * + * @param message Message that will be logged + * @param cause Cause of the exception + */ + public PacketInstantiationException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Represents a runtime exception that is thrown if packet sending fails + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.4 + */ + private static final class PacketSendingException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new packet sending exception + * + * @param message Message that will be logged + * @param cause Cause of the exception + */ + public PacketSendingException(String message, Throwable cause) { + super(message, cause); + } + } + } } \ No newline at end of file diff --git a/src/main/java/com/massivecraft/factions/util/PermissionsMapTypeAdapter.java b/src/main/java/com/massivecraft/factions/util/PermissionsMapTypeAdapter.java index 080dd661..fe5e160d 100644 --- a/src/main/java/com/massivecraft/factions/util/PermissionsMapTypeAdapter.java +++ b/src/main/java/com/massivecraft/factions/util/PermissionsMapTypeAdapter.java @@ -15,8 +15,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; -import static com.massivecraft.factions.zcore.util.TL.ROLE_NORMAL; - public class PermissionsMapTypeAdapter implements JsonDeserializer>> { @Override diff --git a/src/main/java/com/massivecraft/factions/util/SpiralTask.java b/src/main/java/com/massivecraft/factions/util/SpiralTask.java index 866f09b6..6cde74f2 100644 --- a/src/main/java/com/massivecraft/factions/util/SpiralTask.java +++ b/src/main/java/com/massivecraft/factions/util/SpiralTask.java @@ -59,6 +59,10 @@ public abstract class SpiralTask implements Runnable { this.setTaskID(Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(P.p, this, 2, 2)); } + private static long now() { + return System.currentTimeMillis(); + } + /* * This is where the necessary work is done; you'll need to override this method with whatever you want * done at each chunk in the spiral pattern. @@ -88,16 +92,16 @@ public abstract class SpiralTask implements Runnable { return x; } - public final int getZ() { - return z; - } - /* * Below are the guts of the class, which you normally wouldn't need to mess with. */ + public final int getZ() { + return z; + } + public final void setTaskID(int ID) { if (ID == -1) { this.stop(); @@ -202,8 +206,4 @@ public abstract class SpiralTask implements Runnable { public final boolean valid() { return taskID != -1; } - - private static long now() { - return System.currentTimeMillis(); - } } diff --git a/src/main/java/com/massivecraft/factions/util/WarpGUI.java b/src/main/java/com/massivecraft/factions/util/WarpGUI.java index 913d317d..bb789bd8 100644 --- a/src/main/java/com/massivecraft/factions/util/WarpGUI.java +++ b/src/main/java/com/massivecraft/factions/util/WarpGUI.java @@ -24,18 +24,14 @@ import java.util.logging.Level; public class WarpGUI implements InventoryHolder, FactionGUI { + private final ConfigurationSection section; + int guiSize; private Inventory warpGUI; private FPlayer fme; - - int guiSize; - private HashMap warpSlots = new HashMap<>(); private int maxWarps; - private List dummySlots = new ArrayList<>(); - private final ConfigurationSection section; - public WarpGUI(FPlayer fme) { this.fme = fme; this.section = P.p.getConfig().getConfigurationSection("fwarp-gui"); @@ -114,7 +110,7 @@ public class WarpGUI implements InventoryHolder, FactionGUI { fme.setEnteringPassword(false, ""); } } - }, P.p.getConfig().getInt("fwarp-gui.password-timeout", 5)*20); + }, P.p.getConfig().getInt("fwarp-gui.password-timeout", 5) * 20); } } } diff --git a/src/main/java/com/massivecraft/factions/zcore/MCommand.java b/src/main/java/com/massivecraft/factions/zcore/MCommand.java index 6e5d50ec..a025bbbf 100644 --- a/src/main/java/com/massivecraft/factions/zcore/MCommand.java +++ b/src/main/java/com/massivecraft/factions/zcore/MCommand.java @@ -26,55 +26,28 @@ public abstract class MCommand { // The sub-commands to this command public List> subCommands; - - public void addSubCommand(MCommand subCommand) { - subCommand.commandChain.addAll(this.commandChain); - subCommand.commandChain.add(this); - this.subCommands.add(subCommand); - } - // The different names this commands will react to public List aliases; public boolean allowNoSlashAccess; - // Information on the args public List requiredArgs; public LinkedHashMap optionalArgs; public boolean errorOnToManyArgs = true; - - // FIELD: Help Short - // This field may be left blank and will in such case be loaded from the permissions node instead. - // Thus make sure the permissions node description is an action description like "eat hamburgers" or "do admin stuff". - private String helpShort; - - public void setHelpShort(String val) { - this.helpShort = val; - } - - public String getHelpShort() { - if (this.helpShort == null) { - return getUsageTranslation().toString(); - } - - return this.helpShort; - } - - public abstract TL getUsageTranslation(); - public List helpLong; public CommandVisibility visibility; - // Some information on permissions public boolean senderMustBePlayer; public String permission; - // Information available on execution of the command public CommandSender sender; // Will always be set public Player me; // Will only be set when the sender is a player public boolean senderIsConsole; public List args; // Will contain the arguments, or and empty list if there are none. public List> commandChain = new ArrayList<>(); // The command chain used to execute this command - + // FIELD: Help Short + // This field may be left blank and will in such case be loaded from the permissions node instead. + // Thus make sure the permissions node description is an action description like "eat hamburgers" or "do admin stuff". + private String helpShort; public MCommand(T p) { this.p = p; @@ -93,6 +66,26 @@ public abstract class MCommand { this.visibility = CommandVisibility.VISIBLE; } + public void addSubCommand(MCommand subCommand) { + subCommand.commandChain.addAll(this.commandChain); + subCommand.commandChain.add(this); + this.subCommands.add(subCommand); + } + + public String getHelpShort() { + if (this.helpShort == null) { + return getUsageTranslation().toString(); + } + + return this.helpShort; + } + + public void setHelpShort(String val) { + this.helpShort = val; + } + + public abstract TL getUsageTranslation(); + // The commandChain is a list of the parent command chain used to get to this command. public void execute(CommandSender sender, List args, List> commandChain) { // Set the execution-time specific variables diff --git a/src/main/java/com/massivecraft/factions/zcore/MPlugin.java b/src/main/java/com/massivecraft/factions/zcore/MPlugin.java index 9498df10..37b605f6 100644 --- a/src/main/java/com/massivecraft/factions/zcore/MPlugin.java +++ b/src/main/java/com/massivecraft/factions/zcore/MPlugin.java @@ -27,16 +27,32 @@ import java.util.logging.Level; public abstract class MPlugin extends JavaPlugin { + // Persist related + public final Gson gson = this.getGsonBuilder().create(); // Some utils public Persist persist; public TextUtil txt; public PermUtil perm; - - // Persist related - public final Gson gson = this.getGsonBuilder().create(); + public String refCommand = ""; + //holds f stuck taskids + public Map stuckMap = new HashMap<>(); + // These are not supposed to be used directly. + // They are loaded and used through the TextUtil instance for the plugin. + public Map rawTags = new LinkedHashMap<>(); + protected boolean loadSuccessful = false; private Integer saveTask = null; private boolean autoSave = true; - protected boolean loadSuccessful = false; + // Listeners + private MPluginSecretPlayerListener mPluginSecretPlayerListener; + + // Our stored base commands + private List> baseCommands = new ArrayList<>(); + // holds f stuck start times + private Map timers = new HashMap<>(); + // -------------------------------------------- // + // ENABLE + // -------------------------------------------- // + private long timeEnableStart; public boolean getAutoSave() { return this.autoSave; @@ -46,29 +62,10 @@ public abstract class MPlugin extends JavaPlugin { this.autoSave = val; } - public String refCommand = ""; - - // Listeners - private MPluginSecretPlayerListener mPluginSecretPlayerListener; - - // Our stored base commands - private List> baseCommands = new ArrayList<>(); - public List> getBaseCommands() { return this.baseCommands; } - // holds f stuck start times - private Map timers = new HashMap<>(); - - //holds f stuck taskids - public Map stuckMap = new HashMap<>(); - - // -------------------------------------------- // - // ENABLE - // -------------------------------------------- // - private long timeEnableStart; - public boolean preEnable() { log("=== ENABLE START ==="); timeEnableStart = System.currentTimeMillis(); @@ -193,28 +190,24 @@ public abstract class MPlugin extends JavaPlugin { log("Disabled"); } - public void suicide() { - log("Now I suicide!"); - this.getServer().getPluginManager().disablePlugin(this); - } - // -------------------------------------------- // // Some inits... // You are supposed to override these in the plugin if you aren't satisfied with the defaults // The goal is that you always will be satisfied though. // -------------------------------------------- // - public GsonBuilder getGsonBuilder() { - return new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE); + public void suicide() { + log("Now I suicide!"); + this.getServer().getPluginManager().disablePlugin(this); } // -------------------------------------------- // // LANG AND TAGS // -------------------------------------------- // - // These are not supposed to be used directly. - // They are loaded and used through the TextUtil instance for the plugin. - public Map rawTags = new LinkedHashMap<>(); + public GsonBuilder getGsonBuilder() { + return new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().serializeNulls().excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE); + } public void addRawTags() { this.rawTags.put("l", ""); // logo diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java b/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java index abee55d9..05f650d3 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java @@ -39,7 +39,8 @@ public enum PermissableAction { TNTFILL("tntfill"), WITHDRAW("withdraw"), CHEST("chest"), - SPAWNER("spawner"); + SPAWNER("spawner"), + CLAIM("claim"); private String name; @@ -47,15 +48,6 @@ public enum PermissableAction { this.name = name; } - /** - * Get the friendly name of this action. Used for editing in commands. - * - * @return friendly name of the action as a String. - */ - public String getName() { - return this.name; - } - /** * Case insensitive check for action. * @@ -72,6 +64,15 @@ public enum PermissableAction { return null; } + /** + * Get the friendly name of this action. Used for editing in commands. + * + * @return friendly name of the action as a String. + */ + public String getName() { + return this.name; + } + @Override public String toString() { return name; diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java index 0f4d8e45..e45fa8ed 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableActionGUI.java @@ -24,19 +24,15 @@ import java.util.logging.Level; public class PermissableActionGUI implements InventoryHolder, FactionGUI { + private final ConfigurationSection section; private Inventory actionGUI; private FPlayer fme; - private int guiSize; - private Permissable permissable; - private HashMap actionSlots = new HashMap<>(); private HashMap specialSlots = new HashMap<>(); private ArrayList usedDummySlots = new ArrayList<>(); - private final ConfigurationSection section; - public PermissableActionGUI(FPlayer fme, Permissable permissable) { this.fme = fme; this.permissable = permissable; @@ -198,7 +194,7 @@ public class PermissableActionGUI implements InventoryHolder, FactionGUI { } backButtonMeta.setLore(lore); - if (!P.p.mc17){ + if (!P.p.mc17) { backButtonMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS, ItemFlag.HIDE_ATTRIBUTES); } diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java index c2520bb0..7b9d976e 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/gui/PermissableRelationGUI.java @@ -26,15 +26,12 @@ import java.util.logging.Level; public class PermissableRelationGUI implements InventoryHolder, FactionGUI { + private final ConfigurationSection section; private Inventory relationGUI; private FPlayer fme; - private int guiSize; - private HashMap relationSlots = new HashMap<>(); - private final ConfigurationSection section; - public PermissableRelationGUI(FPlayer fme) { this.fme = fme; diff --git a/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradesGUI.java b/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradesGUI.java index 41f9ec31..d87eecac 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradesGUI.java +++ b/src/main/java/com/massivecraft/factions/zcore/fupgrades/FUpgradesGUI.java @@ -209,7 +209,6 @@ public class FUpgradesGUI implements Listener { } - } private void closeChests(Faction faction) { @@ -237,7 +236,9 @@ public class FUpgradesGUI implements Listener { ItemStack expItem = P.p.createItem(expMaterial, expAmt, expData, expName, expLore); if (expLevel >= 1) { ItemMeta itemMeta = expItem.getItemMeta(); - if (!P.p.mc17) { itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); } + if (!P.p.mc17) { + itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + } itemMeta.addEnchant(Enchantment.DURABILITY, 3, true); expItem.setItemMeta(itemMeta); } @@ -275,7 +276,9 @@ public class FUpgradesGUI implements Listener { cropItem.getItemMeta().setLore(cropLore); if (cropLevel >= 1) { ItemMeta itemMeta = cropItem.getItemMeta(); - if (!P.p.mc17) { itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); } + if (!P.p.mc17) { + itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + } itemMeta.addEnchant(Enchantment.DURABILITY, 3, true); cropItem.setItemMeta(itemMeta); } @@ -288,7 +291,9 @@ public class FUpgradesGUI implements Listener { spawnerItem.getItemMeta().setLore(spawnerLore); if (spawnerLevel >= 1) { ItemMeta itemMeta = spawnerItem.getItemMeta(); - if (!P.p.mc17) { itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); } + if (!P.p.mc17) { + itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + } itemMeta.addEnchant(Enchantment.DURABILITY, 3, true); spawnerItem.setItemMeta(itemMeta); } @@ -314,7 +319,9 @@ public class FUpgradesGUI implements Listener { if (chestlevel >= 1) { ItemMeta itemMeta = chestItem.getItemMeta(); - if (!P.p.mc17) { itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); } + if (!P.p.mc17) { + itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + } itemMeta.addEnchant(Enchantment.DURABILITY, 3, true); chestItem.setItemMeta(itemMeta); } diff --git a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTCompound.java b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTCompound.java index 2e64c644..fd23b971 100644 --- a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTCompound.java +++ b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTCompound.java @@ -1,9 +1,9 @@ package com.massivecraft.factions.zcore.nbtapi; -import java.util.Set; - import com.massivecraft.factions.zcore.nbtapi.utils.MinecraftVersion; +import java.util.Set; + public class NBTCompound { @@ -31,10 +31,10 @@ public class NBTCompound { return parent; } - public void mergeCompound(NBTCompound comp){ + public void mergeCompound(NBTCompound comp) { NBTReflectionUtil.addOtherNBTCompound(this, comp); } - + public void setString(String key, String value) { NBTReflectionUtil.setString(this, key, value); } @@ -185,8 +185,8 @@ public class NBTCompound { return result + "-" + key + ": " + getContent(key) + System.lineSeparator(); } } - - public String asNBTString(){ + + public String asNBTString() { return NBTReflectionUtil.gettoCompount(getCompound(), this).toString(); } diff --git a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTContainer.java b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTContainer.java index 6916e51c..5f17362e 100644 --- a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTContainer.java +++ b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTContainer.java @@ -1,6 +1,6 @@ package com.massivecraft.factions.zcore.nbtapi; -public class NBTContainer extends NBTCompound{ +public class NBTContainer extends NBTCompound { private Object nbt; @@ -8,17 +8,17 @@ public class NBTContainer extends NBTCompound{ super(null, null); nbt = NBTReflectionUtil.getNewNBTTag(); } - - protected NBTContainer(Object nbt){ + + protected NBTContainer(Object nbt) { super(null, null); this.nbt = nbt; } public NBTContainer(String nbtString) throws IllegalArgumentException { super(null, null); - try{ + try { nbt = NBTReflectionUtil.parseNBT(nbtString); - }catch(Exception ex){ + } catch (Exception ex) { ex.printStackTrace(); throw new IllegalArgumentException("Malformed Json: " + ex.getMessage()); } diff --git a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTItem.java b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTItem.java index 80e3b750..05af3314 100644 --- a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTItem.java +++ b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTItem.java @@ -11,6 +11,14 @@ public class NBTItem extends NBTCompound { bukkitItem = item.clone(); } + public static NBTContainer convertItemtoNBT(ItemStack item) { + return NBTReflectionUtil.convertNMSItemtoNBTCompound(NBTReflectionUtil.getNMSItemStack(item)); + } + + public static ItemStack convertNBTtoItem(NBTCompound comp) { + return NBTReflectionUtil.getBukkitItemStack(NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp)); + } + protected Object getCompound() { return NBTReflectionUtil.getItemRootNBTTagCompound(NBTReflectionUtil.getNMSItemStack(bukkitItem)); } @@ -26,13 +34,5 @@ public class NBTItem extends NBTCompound { protected void setItem(ItemStack item) { bukkitItem = item; } - - public static NBTContainer convertItemtoNBT(ItemStack item){ - return NBTReflectionUtil.convertNMSItemtoNBTCompound(NBTReflectionUtil.getNMSItemStack(item)); - } - - public static ItemStack convertNBTtoItem(NBTCompound comp){ - return NBTReflectionUtil.getBukkitItemStack(NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp)); - } } diff --git a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTReflectionUtil.java b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTReflectionUtil.java index ddb001d8..497f5808 100644 --- a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTReflectionUtil.java +++ b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTReflectionUtil.java @@ -1,5 +1,13 @@ package com.massivecraft.factions.zcore.nbtapi; +import com.massivecraft.factions.zcore.nbtapi.utils.GsonWrapper; +import com.massivecraft.factions.zcore.nbtapi.utils.MethodNames; +import com.massivecraft.factions.zcore.nbtapi.utils.MinecraftVersion; +import org.bukkit.Bukkit; +import org.bukkit.block.BlockState; +import org.bukkit.entity.Entity; +import org.bukkit.inventory.ItemStack; + import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; @@ -8,15 +16,6 @@ import java.lang.reflect.Method; import java.util.Set; import java.util.Stack; -import org.bukkit.Bukkit; -import org.bukkit.block.BlockState; -import org.bukkit.entity.Entity; -import org.bukkit.inventory.ItemStack; - -import com.massivecraft.factions.zcore.nbtapi.utils.GsonWrapper; -import com.massivecraft.factions.zcore.nbtapi.utils.MethodNames; -import com.massivecraft.factions.zcore.nbtapi.utils.MinecraftVersion; - // TODO: finish codestyle cleanup -sgdc3 public class NBTReflectionUtil { @@ -70,7 +69,7 @@ public class NBTReflectionUtil { return null; } } - + @SuppressWarnings("rawtypes") protected static Class getNMSItemStack() { try { @@ -106,7 +105,7 @@ public class NBTReflectionUtil { return null; } } - + @SuppressWarnings("rawtypes") protected static Class getMojangsonParser() { try { @@ -223,7 +222,7 @@ public class NBTReflectionUtil { } return null; } - + @SuppressWarnings({"unchecked"}) public static Object readNBTFile(FileInputStream stream) { @SuppressWarnings("rawtypes") @@ -281,7 +280,7 @@ public class NBTReflectionUtil { } return null; } - + @SuppressWarnings({"unchecked"}) public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) { @SuppressWarnings("rawtypes") @@ -294,7 +293,7 @@ public class NBTReflectionUtil { } return null; } - + @SuppressWarnings({"unchecked"}) public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) { @SuppressWarnings("rawtypes") @@ -434,7 +433,7 @@ public class NBTReflectionUtil { } return nbttag; } - + public static void addOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompound) { Object rootnbttag = comp.getCompound(); if (rootnbttag == null) { diff --git a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTType.java b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTType.java index 7abb4193..afa9d60a 100644 --- a/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTType.java +++ b/src/main/java/com/massivecraft/factions/zcore/nbtapi/NBTType.java @@ -14,14 +14,10 @@ public enum NBTType { NBTTagList(9), NBTTagCompound(10); - NBTType(int i) { - id = i; - } - private final int id; - public int getId() { - return id; + NBTType(int i) { + id = i; } public static NBTType valueOf(int id) { @@ -31,4 +27,8 @@ public enum NBTType { return NBTType.NBTTagEnd; } + public int getId() { + return id; + } + } diff --git a/src/main/java/com/massivecraft/factions/zcore/nbtapi/utils/MinecraftVersion.java b/src/main/java/com/massivecraft/factions/zcore/nbtapi/utils/MinecraftVersion.java index e4023eb2..41b92a39 100644 --- a/src/main/java/com/massivecraft/factions/zcore/nbtapi/utils/MinecraftVersion.java +++ b/src/main/java/com/massivecraft/factions/zcore/nbtapi/utils/MinecraftVersion.java @@ -21,10 +21,6 @@ public enum MinecraftVersion { this.versionId = versionId; } - public int getVersionId() { - return versionId; - } - public static MinecraftVersion getVersion() { if (version != null) { return version; @@ -57,4 +53,8 @@ public enum MinecraftVersion { return hasGsonSupport; } + public int getVersionId() { + return versionId; + } + } diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java index 19cd04cb..c58b60c6 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java @@ -20,51 +20,6 @@ import java.util.Map.Entry; public abstract class MemoryBoard extends Board { - public class MemoryBoardMap extends HashMap { - private static final long serialVersionUID = -6689617828610585368L; - - Multimap factionToLandMap = HashMultimap.create(); - - @Override - public String put(FLocation floc, String factionId) { - String previousValue = super.put(floc, factionId); - if (previousValue != null) { - factionToLandMap.remove(previousValue, floc); - } - - factionToLandMap.put(factionId, floc); - return previousValue; - } - - @Override - public String remove(Object key) { - String result = super.remove(key); - if (result != null) { - FLocation floc = (FLocation) key; - factionToLandMap.remove(result, floc); - } - - return result; - } - - @Override - public void clear() { - super.clear(); - factionToLandMap.clear(); - } - - public int getOwnedLandCount(String factionId) { - return factionToLandMap.get(factionId).size(); - } - - public void removeFaction(String factionId) { - Collection flocations = factionToLandMap.removeAll(factionId); - for (FLocation floc : flocations) { - super.remove(floc); - } - } - } - public MemoryBoardMap flocationIds = new MemoryBoardMap(); //----------------------------------------------// @@ -198,11 +153,6 @@ public abstract class MemoryBoard extends Board { return false; } - - //----------------------------------------------// - // Cleaner. Remove orphaned foreign keys - //----------------------------------------------// - public void clean() { Iterator> iter = flocationIds.entrySet().iterator(); while (iter.hasNext()) { @@ -214,14 +164,19 @@ public abstract class MemoryBoard extends Board { } } + //----------------------------------------------// - // Coord count + // Cleaner. Remove orphaned foreign keys //----------------------------------------------// public int getFactionCoordCount(String factionId) { return flocationIds.getOwnedLandCount(factionId); } + //----------------------------------------------// + // Coord count + //----------------------------------------------// + public int getFactionCoordCount(Faction faction) { return getFactionCoordCount(faction.getId()); } @@ -237,10 +192,6 @@ public abstract class MemoryBoard extends Board { return ret; } - //----------------------------------------------// - // Map generation - //----------------------------------------------// - /** * The map is relative to a coord and a faction north is in the direction of decreasing x east is in the direction * of decreasing z @@ -285,7 +236,7 @@ public abstract class MemoryBoard extends Board { FLocation flocationHere = topLeft.getRelative(dx, dz); Faction factionHere = getFactionAt(flocationHere); Relation relation = fplayer.getRelationTo(factionHere); - if (flocationHere.isOutsideWorldBorder(buffer)){ + if (flocationHere.isOutsideWorldBorder(buffer)) { row.then("-").color(ChatColor.BLACK).tooltip(TL.CLAIM_MAP_OUTSIDEBORDER.toString()); } else if (factionHere.isWilderness()) { row.then("-").color(Conf.colorWilderness); @@ -329,6 +280,10 @@ public abstract class MemoryBoard extends Board { return ret; } + //----------------------------------------------// + // Map generation + //----------------------------------------------// + private List oneLineToolTip(Faction faction, FPlayer to) { return Arrays.asList(faction.describeTo(to)); } @@ -386,4 +341,49 @@ public abstract class MemoryBoard extends Board { } public abstract void convertFrom(MemoryBoard old); + + public class MemoryBoardMap extends HashMap { + private static final long serialVersionUID = -6689617828610585368L; + + Multimap factionToLandMap = HashMultimap.create(); + + @Override + public String put(FLocation floc, String factionId) { + String previousValue = super.put(floc, factionId); + if (previousValue != null) { + factionToLandMap.remove(previousValue, floc); + } + + factionToLandMap.put(factionId, floc); + return previousValue; + } + + @Override + public String remove(Object key) { + String result = super.remove(key); + if (result != null) { + FLocation floc = (FLocation) key; + factionToLandMap.remove(result, floc); + } + + return result; + } + + @Override + public void clear() { + super.clear(); + factionToLandMap.clear(); + } + + public int getOwnedLandCount(String factionId) { + return factionToLandMap.get(factionId).size(); + } + + public void removeFaction(String factionId) { + Collection flocations = factionToLandMap.removeAll(factionId); + for (FLocation floc : flocations) { + super.remove(floc); + } + } + } } diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java index 0e61d591..1ad191bb 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java @@ -47,6 +47,7 @@ import java.util.UUID; public abstract class MemoryFPlayer implements FPlayer { + public boolean inVault = false; protected String factionId; protected Role role; protected String title; @@ -70,7 +71,6 @@ public abstract class MemoryFPlayer implements FPlayer { protected boolean isFlying = false; protected boolean enteringPassword = false; protected String enteringPasswordWarp = ""; - protected transient FLocation lastStoodAt = new FLocation(); // Where did this player stand the last time we checked? protected transient boolean mapAutoUpdating; protected transient Faction autoClaimFor; @@ -79,6 +79,56 @@ public abstract class MemoryFPlayer implements FPlayer { protected transient boolean loginPvpDisabled; protected transient long lastFrostwalkerMessage; protected transient boolean shouldTakeFallDamage = true; + boolean playerAlerts = false; + boolean inspectMode = false; + + public MemoryFPlayer() { + } + + public MemoryFPlayer(String id) { + this.id = id; + this.resetFactionData(false); + this.power = Conf.powerPlayerStarting; + this.lastPowerUpdateTime = System.currentTimeMillis(); + this.lastLoginTime = System.currentTimeMillis(); + this.mapAutoUpdating = false; + this.autoClaimFor = null; + this.autoSafeZoneEnabled = false; + this.autoWarZoneEnabled = false; + this.loginPvpDisabled = Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0; + this.powerBoost = 0.0; + this.showScoreboard = P.p.getConfig().getBoolean("scoreboard.default-enabled", false); + this.kills = 0; + this.deaths = 0; + this.mapHeight = Conf.mapHeight; + + if (!Conf.newPlayerStartingFactionID.equals("0") && Factions.getInstance().isValidFactionId(Conf.newPlayerStartingFactionID)) { + this.factionId = Conf.newPlayerStartingFactionID; + } + } + + public MemoryFPlayer(MemoryFPlayer other) { + this.factionId = other.factionId; + this.id = other.id; + this.power = other.power; + this.lastLoginTime = other.lastLoginTime; + this.mapAutoUpdating = other.mapAutoUpdating; + this.autoClaimFor = other.autoClaimFor; + this.autoSafeZoneEnabled = other.autoSafeZoneEnabled; + this.autoWarZoneEnabled = other.autoWarZoneEnabled; + this.loginPvpDisabled = other.loginPvpDisabled; + this.powerBoost = other.powerBoost; + this.role = other.role; + this.title = other.title; + this.chatMode = other.chatMode; + this.spyingChat = other.spyingChat; + this.lastStoodAt = other.lastStoodAt; + this.isAdminBypassing = other.isAdminBypassing; + this.showScoreboard = P.p.getConfig().getBoolean("scoreboard.default-enabled", true); + this.kills = other.kills; + this.deaths = other.deaths; + this.mapHeight = Conf.mapHeight; + } public void login() { this.kills = getPlayer().getStatistic(Statistic.PLAYER_KILLS); @@ -97,14 +147,6 @@ public abstract class MemoryFPlayer implements FPlayer { return Factions.getInstance().getFactionById(this.factionId); } - public String getFactionId() { - return this.factionId; - } - - public boolean hasFaction() { - return !factionId.equals("0"); - } - public void setFaction(Faction faction) { Faction oldFaction = this.getFaction(); if (oldFaction != null) { @@ -114,6 +156,14 @@ public abstract class MemoryFPlayer implements FPlayer { this.factionId = faction.getId(); } + public String getFactionId() { + return this.factionId; + } + + public boolean hasFaction() { + return !factionId.equals("0"); + } + public void setMonitorJoins(boolean monitor) { this.monitorJoins = monitor; } @@ -209,10 +259,6 @@ public abstract class MemoryFPlayer implements FPlayer { this.isAdminBypassing = val; } - public void setChatMode(ChatMode chatMode) { - this.chatMode = chatMode; - } - public ChatMode getChatMode() { if (this.factionId.equals("0") || !Conf.factionOnlyChat) { this.chatMode = ChatMode.PUBLIC; @@ -220,75 +266,35 @@ public abstract class MemoryFPlayer implements FPlayer { return chatMode; } - public void setIgnoreAllianceChat(boolean ignore) { - this.ignoreAllianceChat = ignore; + public void setChatMode(ChatMode chatMode) { + this.chatMode = chatMode; } public boolean isIgnoreAllianceChat() { return ignoreAllianceChat; } - public void setSpyingChat(boolean chatSpying) { - this.spyingChat = chatSpying; + public void setIgnoreAllianceChat(boolean ignore) { + this.ignoreAllianceChat = ignore; } public boolean isSpyingChat() { return spyingChat; } + public void setSpyingChat(boolean chatSpying) { + this.spyingChat = chatSpying; + } + + // -------------------------------------------- // + // Getters And Setters + // -------------------------------------------- // + // FIELD: account public String getAccountId() { return this.getId(); } - public MemoryFPlayer() { - } - - public MemoryFPlayer(String id) { - this.id = id; - this.resetFactionData(false); - this.power = Conf.powerPlayerStarting; - this.lastPowerUpdateTime = System.currentTimeMillis(); - this.lastLoginTime = System.currentTimeMillis(); - this.mapAutoUpdating = false; - this.autoClaimFor = null; - this.autoSafeZoneEnabled = false; - this.autoWarZoneEnabled = false; - this.loginPvpDisabled = Conf.noPVPDamageToOthersForXSecondsAfterLogin > 0; - this.powerBoost = 0.0; - this.showScoreboard = P.p.getConfig().getBoolean("scoreboard.default-enabled", false); - this.kills = 0; - this.deaths = 0; - this.mapHeight = Conf.mapHeight; - - if (!Conf.newPlayerStartingFactionID.equals("0") && Factions.getInstance().isValidFactionId(Conf.newPlayerStartingFactionID)) { - this.factionId = Conf.newPlayerStartingFactionID; - } - } - - public MemoryFPlayer(MemoryFPlayer other) { - this.factionId = other.factionId; - this.id = other.id; - this.power = other.power; - this.lastLoginTime = other.lastLoginTime; - this.mapAutoUpdating = other.mapAutoUpdating; - this.autoClaimFor = other.autoClaimFor; - this.autoSafeZoneEnabled = other.autoSafeZoneEnabled; - this.autoWarZoneEnabled = other.autoWarZoneEnabled; - this.loginPvpDisabled = other.loginPvpDisabled; - this.powerBoost = other.powerBoost; - this.role = other.role; - this.title = other.title; - this.chatMode = other.chatMode; - this.spyingChat = other.spyingChat; - this.lastStoodAt = other.lastStoodAt; - this.isAdminBypassing = other.isAdminBypassing; - this.showScoreboard = P.p.getConfig().getBoolean("scoreboard.default-enabled", true); - this.kills = other.kills; - this.deaths = other.deaths; - this.mapHeight = Conf.mapHeight; - } - public void resetFactionData(boolean doSpoutUpdate) { // clean up any territory ownership in old faction, if there is one if (factionId != null && Factions.getInstance().isValidFactionId(this.getFactionId())) { @@ -310,11 +316,6 @@ public abstract class MemoryFPlayer implements FPlayer { this.resetFactionData(true); } - // -------------------------------------------- // - // Getters And Setters - // -------------------------------------------- // - - public long getLastLoginTime() { return lastLoginTime; } @@ -336,6 +337,12 @@ public abstract class MemoryFPlayer implements FPlayer { this.mapAutoUpdating = mapAutoUpdating; } + //----------------------------------------------// + // Title, Name, Faction Tag and Chat + //----------------------------------------------// + + // Base: + public boolean hasLoginPvpDisabled() { if (!loginPvpDisabled) { return false; @@ -355,12 +362,6 @@ public abstract class MemoryFPlayer implements FPlayer { this.lastStoodAt = flocation; } - //----------------------------------------------// - // Title, Name, Faction Tag and Chat - //----------------------------------------------// - - // Base: - public String getTitle() { return this.hasFaction() ? title : TL.NOFACTION_PREFIX.toString(); } @@ -374,6 +375,8 @@ public abstract class MemoryFPlayer implements FPlayer { this.title = title; } + // Base concatenations: + public String getName() { if (this.name == null) { // Older versions of FactionsUUID don't save the name, @@ -393,7 +396,8 @@ public abstract class MemoryFPlayer implements FPlayer { return this.hasFaction() ? this.getFaction().getTag() : ""; } - // Base concatenations: + // Colored concatenations: + // These are used in information messages public String getNameAndSomething(String something) { String ret = this.role.getPrefix(); @@ -408,13 +412,13 @@ public abstract class MemoryFPlayer implements FPlayer { return this.getNameAndSomething(this.getTitle()); } + // Chat Tag: + // These are injected into the format of global chat messages. + public String getNameAndTag() { return this.getNameAndSomething(this.getTag()); } - // Colored concatenations: - // These are used in information messages - public String getNameAndTitle(Faction faction) { return this.getColorTo(faction) + this.getNameAndTitle(); } @@ -423,9 +427,6 @@ public abstract class MemoryFPlayer implements FPlayer { return this.getColorTo(fplayer) + this.getNameAndTitle(); } - // Chat Tag: - // These are injected into the format of global chat messages. - public String getChatTag() { return this.hasFaction() ? String.format(Conf.chatTagFormat, this.getRole().getPrefix() + this.getTag()) : TL.NOFACTION_PREFIX.toString(); } @@ -435,6 +436,10 @@ public abstract class MemoryFPlayer implements FPlayer { return this.hasFaction() ? this.getRelationTo(faction).getColor() + getChatTag() : ""; } + // ------------------------------- + // Relation and relation colors + // ------------------------------- + public String getChatTag(MemoryFPlayer fplayer) { return this.hasFaction() ? this.getColorTo(fplayer) + getChatTag() : ""; } @@ -448,10 +453,6 @@ public abstract class MemoryFPlayer implements FPlayer { } - // ------------------------------- - // Relation and relation colors - // ------------------------------- - @Override public String describeTo(RelationParticipator that, boolean ucfirst) { return RelationUtil.describeThatToMe(this, that, ucfirst); @@ -492,7 +493,6 @@ public abstract class MemoryFPlayer implements FPlayer { player.setHealth(player.getHealth() + amnt); } - //----------------------------------------------// // Power //----------------------------------------------// @@ -610,6 +610,10 @@ public abstract class MemoryFPlayer implements FPlayer { } } + // ------------------------------- + // Actions + // ------------------------------- + /** * Check if the scoreboard should be shown. Simple method to be used by above method. * @@ -630,10 +634,6 @@ public abstract class MemoryFPlayer implements FPlayer { this.showScoreboard = show; } - // ------------------------------- - // Actions - // ------------------------------- - public void leave(boolean makePay) { Faction myFaction = this.getFaction(); makePay = makePay && Econ.shouldBeUsed() && !this.isAdminBypassing(); @@ -724,10 +724,9 @@ public abstract class MemoryFPlayer implements FPlayer { if (Conf.worldGuardChecking && Worldguard.checkForRegionsInChunk(flocation)) { // Checks for WorldGuard regions in the chunk attempting to be claimed error = P.p.txt.parse(TL.CLAIM_PROTECTED.toString()); - } else if(flocation.isOutsideWorldBorder(P.p.getConfig().getInt("world-border.buffer", 0))){ + } else if (flocation.isOutsideWorldBorder(P.p.getConfig().getInt("world-border.buffer", 0))) { error = P.p.txt.parse(TL.CLAIM_OUTSIDEWORLDBORDER.toString()); - } - else if (Conf.worldsNoClaiming.contains(flocation.getWorldName())) { + } else if (Conf.worldsNoClaiming.contains(flocation.getWorldName())) { error = P.p.txt.parse(TL.CLAIM_DISABLED.toString()); } else if (this.isAdminBypassing()) { return true; @@ -794,8 +793,6 @@ public abstract class MemoryFPlayer implements FPlayer { return attemptClaim(forFaction, new FLocation(location), notifyFailure); } - boolean playerAlerts = false; - public boolean shouldBeSaved() { return this.hasFaction() || (this.getPowerRounded() != this.getPowerMaxRounded() && this.getPowerRounded() != (int) Math.round(Conf.powerPlayerStarting)); } @@ -873,20 +870,11 @@ public abstract class MemoryFPlayer implements FPlayer { isFlying = fly; } - - - - - - - - public boolean inVault = false; - - public boolean isInVault(){ + public boolean isInVault() { return inVault; } - public void setInVault(boolean status){ + public void setInVault(boolean status) { inVault = status; } @@ -921,14 +909,14 @@ public abstract class MemoryFPlayer implements FPlayer { enteringPasswordWarp = warp; } - public String getEnteringWarp() { - return enteringPasswordWarp; - } - // -------------------------------------------- // // Message Sending Helpers // -------------------------------------------- // + public String getEnteringWarp() { + return enteringPasswordWarp; + } + public void sendMessage(String msg) { if (msg.contains("{null}")) { return; // user wants this message to not send @@ -963,7 +951,7 @@ public abstract class MemoryFPlayer implements FPlayer { public void sendFancyMessage(List messages) { Player player = getPlayer(); - if (player == null || !player.isOnGround()) { + if (player == null) { return; } @@ -998,13 +986,13 @@ public abstract class MemoryFPlayer implements FPlayer { return id; } - public abstract void remove(); - @Override public void setId(String id) { this.id = id; } + public abstract void remove(); + @Override public void clearWarmup() { if (warmup != null) { @@ -1038,16 +1026,22 @@ public abstract class MemoryFPlayer implements FPlayer { } @Override - public boolean checkIfNearbyEnemies(){ + public boolean checkIfNearbyEnemies() { Player me = this.getPlayer(); int radius = Conf.enemyFlyCheckRadius; for (Entity e : me.getNearbyEntities(radius, 255, radius)) { - if (e == null) { continue; } + if (e == null) { + continue; + } if (e instanceof Player) { Player eplayer = (((Player) e).getPlayer()); - if (eplayer == null) { continue; } + if (eplayer == null) { + continue; + } FPlayer efplayer = FPlayers.getInstance().getByPlayer(eplayer); - if (efplayer == null) { continue; } + if (efplayer == null) { + continue; + } if (this.getRelationTo(efplayer).equals(Relation.ENEMY)) { this.setFlying(false); @@ -1071,7 +1065,6 @@ public abstract class MemoryFPlayer implements FPlayer { } - @Override public Boolean canflyinSafezone() { return getPlayer().hasPermission("factions.fly.safezone"); @@ -1102,15 +1095,13 @@ public abstract class MemoryFPlayer implements FPlayer { } - boolean inspectMode = false; - @Override - public boolean isInspectMode(){ + public boolean isInspectMode() { return inspectMode; } @Override - public void setInspectMode( boolean status){ + public void setInspectMode(boolean status) { inspectMode = status; } 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 3354a3c8..eed71f96 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java @@ -33,6 +33,11 @@ import static com.massivecraft.factions.util.InventoryUtil.InventoryToString; import static com.massivecraft.factions.util.InventoryUtil.StringToInventory; public abstract class MemoryFaction implements Faction, EconomyParticipator { + public HashMap rules = new HashMap(); + public int tnt; + public Location checkpoint; + public LazyLocation vault; + public HashMap upgrades = new HashMap<>(); protected String id = null; protected boolean peacefulExplosionsEnabled; protected boolean permanent; @@ -53,11 +58,61 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { protected HashMap> announcements = new HashMap<>(); protected ConcurrentHashMap warps = new ConcurrentHashMap<>(); protected ConcurrentHashMap warpPasswords = new ConcurrentHashMap<>(); - private long lastDeath; protected int maxVaults; protected Role defaultRole; protected Map> permissions = new HashMap<>(); protected Set bans = new HashSet<>(); + String chestSerialized = null; + Map bannerSerialized; + private long lastDeath; + + // -------------------------------------------- // + // Construct + // -------------------------------------------- // + public MemoryFaction() { + } + + public MemoryFaction(String id) { + this.id = id; + this.open = Conf.newFactionsDefaultOpen; + this.tag = "???"; + this.description = TL.GENERIC_DEFAULTDESCRIPTION.toString(); + this.lastPlayerLoggedOffTime = 0; + this.peaceful = false; + this.peacefulExplosionsEnabled = false; + this.permanent = false; + this.money = 0.0; + this.powerBoost = 0.0; + this.foundedDate = System.currentTimeMillis(); + this.maxVaults = Conf.defaultMaxVaults; + this.defaultRole = Role.RECRUIT; + + resetPerms(); // Reset on new Faction so it has default values. + } + + public MemoryFaction(MemoryFaction old) { + id = old.id; + peacefulExplosionsEnabled = old.peacefulExplosionsEnabled; + permanent = old.permanent; + tag = old.tag; + description = old.description; + open = old.open; + foundedDate = old.foundedDate; + peaceful = old.peaceful; + permanentPower = old.permanentPower; + home = old.home; + lastPlayerLoggedOffTime = old.lastPlayerLoggedOffTime; + money = old.money; + powerBoost = old.powerBoost; + relationWish = old.relationWish; + claimOwnership = old.claimOwnership; + fplayers = new HashSet<>(); + invites = old.invites; + announcements = old.announcements; + this.defaultRole = Role.NORMAL; + + resetPerms(); // Reset on new Faction so it has default values. + } public HashMap> getAnnouncements() { return this.announcements; @@ -184,51 +239,46 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return this.bans; } - public HashMap rules = new HashMap(); - - public String getRule(int index){ + public String getRule(int index) { if (rules.size() == 0) return null; return rules.get(index); } - public HashMap getRulesMap(){ + public HashMap getRulesMap() { return rules; } - public void setRule(int index,String rule) { - rules.put(index,rule); + public void setRule(int index, String rule) { + rules.put(index, rule); } - public void removeRule(int index){ - HashMap newRule = rules; + public void removeRule(int index) { + HashMap newRule = rules; newRule.remove(index); rules = newRule; } - public int tnt; - - public void addTnt(int amt){ + public void addTnt(int amt) { tnt += amt; } - public void takeTnt(int amt){ - tnt -=amt; + public void takeTnt(int amt) { + tnt -= amt; } - public int getTnt() { return tnt; } - - public Location checkpoint; - - public LazyLocation vault; + public int getTnt() { + return tnt; + } public Location getVault() { - if (vault == null){ + if (vault == null) { return null; } return vault.getLocation(); } - public void setVault(Location vaultLocation){ - if (vaultLocation == null){ + + public void setVault(Location vaultLocation) { + if (vaultLocation == null) { vault = null; return; } @@ -236,16 +286,13 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { vault = newlocation; } - public HashMap upgrades = new HashMap<>(); - - public int getUpgrade(String key){ - if (upgrades.keySet().contains(key)) { return upgrades.get(key);} + public int getUpgrade(String key) { + if (upgrades.keySet().contains(key)) { + return upgrades.get(key); + } return 0; } - String chestSerialized = null; - Map bannerSerialized; - @Override public Inventory getChest() { int level = getUpgrade("Chest"); @@ -278,8 +325,6 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { chestSerialized = InventoryToString(inventory.getContents()); } - - @Override public void setBannerPattern(ItemStack banner) { bannerSerialized = banner.serialize(); @@ -293,23 +338,24 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return ItemStack.deserialize(bannerSerialized); } - public void setUpgrades(String key,int level){ upgrades.put(key,level); } - - - public void setCheckpoint(Location location){ - checkpoint = location; + public void setUpgrades(String key, int level) { + upgrades.put(key, level); } - public Location getCheckpoint(){ + + public Location getCheckpoint() { return checkpoint; } + public void setCheckpoint(Location location) { + checkpoint = location; + } - public void clearRules(){ + public void clearRules() { rules.clear(); } - public void addRule(String rule){ - rules.put(rules.size(),rule); + public void addRule(String rule) { + rules.put(rules.size(), rule); } public boolean getOpen() { @@ -328,14 +374,14 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { this.peaceful = isPeaceful; } - public void setPeacefulExplosionsEnabled(boolean val) { - peacefulExplosionsEnabled = val; - } - public boolean getPeacefulExplosionsEnabled() { return this.peacefulExplosionsEnabled; } + public void setPeacefulExplosionsEnabled(boolean val) { + peacefulExplosionsEnabled = val; + } + public boolean noExplosionsInTerritory() { return this.peaceful && !peacefulExplosionsEnabled; } @@ -352,6 +398,13 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return this.tag; } + public void setTag(String str) { + if (Conf.factionTagForceUpperCase) { + str = str.toUpperCase(); + } + this.tag = str; + } + public String getTag(String prefix) { return prefix + this.tag; } @@ -370,14 +423,6 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return this.getTag(this.getColorTo(otherFplayer).toString()); } - public void setTag(String str) { - if (Conf.factionTagForceUpperCase) { - str = str.toUpperCase(); - } - this.tag = str; - } - - public String getComparisonTag() { return MiscUtil.getComparisonString(this.tag); } @@ -390,10 +435,6 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { this.description = value; } - public void setHome(Location home) { - this.home = new LazyLocation(home); - } - public boolean hasHome() { return this.getHome() != null; } @@ -403,6 +444,10 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return (this.home != null) ? this.home.getLocation() : null; } + public void setHome(Location home) { + this.home = new LazyLocation(home); + } + public long getFoundedDate() { if (this.foundedDate == 0) { setFoundedDate(System.currentTimeMillis()); @@ -434,7 +479,6 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return aid; } - public Integer getPermanentPower() { return this.permanentPower; } @@ -461,14 +505,18 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { } - public void setLastDeath(long time) { - this.lastDeath = time; - } - public long getLastDeath() { return this.lastDeath; } + // -------------------------------------------- // + // F Permissions stuff + // -------------------------------------------- // + + public void setLastDeath(long time) { + this.lastDeath = time; + } + public int getKills() { int kills = 0; for (FPlayer fp : getFPlayers()) { @@ -487,11 +535,6 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return deaths; } - // -------------------------------------------- // - // F Permissions stuff - // -------------------------------------------- // - - public Access getAccess(Permissable permissable, PermissableAction permissableAction) { if (permissable == null || permissableAction == null) { return Access.UNDEFINED; @@ -533,8 +576,6 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return Access.UNDEFINED; } - - public void setPermission(Permissable permissable, PermissableAction permissableAction, Access access) { Map accessMap = permissions.get(permissable); if (accessMap == null) { @@ -587,54 +628,6 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { this.defaultRole = role; } - // -------------------------------------------- // - // Construct - // -------------------------------------------- // - public MemoryFaction() { - } - - public MemoryFaction(String id) { - this.id = id; - this.open = Conf.newFactionsDefaultOpen; - this.tag = "???"; - this.description = TL.GENERIC_DEFAULTDESCRIPTION.toString(); - this.lastPlayerLoggedOffTime = 0; - this.peaceful = false; - this.peacefulExplosionsEnabled = false; - this.permanent = false; - this.money = 0.0; - this.powerBoost = 0.0; - this.foundedDate = System.currentTimeMillis(); - this.maxVaults = Conf.defaultMaxVaults; - this.defaultRole = Role.RECRUIT; - - resetPerms(); // Reset on new Faction so it has default values. - } - - public MemoryFaction(MemoryFaction old) { - id = old.id; - peacefulExplosionsEnabled = old.peacefulExplosionsEnabled; - permanent = old.permanent; - tag = old.tag; - description = old.description; - open = old.open; - foundedDate = old.foundedDate; - peaceful = old.peaceful; - permanentPower = old.permanentPower; - home = old.home; - lastPlayerLoggedOffTime = old.lastPlayerLoggedOffTime; - money = old.money; - powerBoost = old.powerBoost; - relationWish = old.relationWish; - claimOwnership = old.claimOwnership; - fplayers = new HashSet<>(); - invites = old.invites; - announcements = old.announcements; - this.defaultRole = Role.NORMAL; - - resetPerms(); // Reset on new Faction so it has default values. - } - // -------------------------------------------- // // Extra Getters And Setters // -------------------------------------------- // diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayers.java b/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayers.java index 302c9294..d6d43749 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayers.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFPlayers.java @@ -23,6 +23,12 @@ import java.util.logging.Level; public class JSONFPlayers extends MemoryFPlayers { // Info on how to persist private Gson gson; + private File file; + + public JSONFPlayers() { + file = new File(P.p.getDataFolder(), "players.json"); + gson = P.p.gson; + } public Gson getGson() { return gson; @@ -32,13 +38,6 @@ public class JSONFPlayers extends MemoryFPlayers { this.gson = gson; } - private File file; - - public JSONFPlayers() { - file = new File(P.p.getDataFolder(), "players.json"); - gson = P.p.gson; - } - public void convertFrom(MemoryFPlayers old) { this.fPlayers.putAll(Maps.transformValues(old.fPlayers, new Function() { @Override diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFactions.java b/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFactions.java index a157e485..d51d6217 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFactions.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFactions.java @@ -23,25 +23,24 @@ import java.util.logging.Level; public class JSONFactions extends MemoryFactions { // Info on how to persist private final Gson gson; + private final File file; + + public JSONFactions() { + this.file = new File(P.p.getDataFolder(), "factions.json"); + this.gson = P.p.gson; + this.nextId = 1; + } public Gson getGson() { return gson; } - private final File file; - - public File getFile() { - return file; - } - // -------------------------------------------- // // CONSTRUCTORS // -------------------------------------------- // - public JSONFactions() { - this.file = new File(P.p.getDataFolder(), "factions.json"); - this.gson = P.p.gson; - this.nextId = 1; + public File getFile() { + return file; } public void forceSave() { diff --git a/src/main/java/com/massivecraft/factions/zcore/util/DiscUtil.java b/src/main/java/com/massivecraft/factions/zcore/util/DiscUtil.java index f9aeb648..f3a39dd2 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/DiscUtil.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/DiscUtil.java @@ -20,7 +20,7 @@ public class DiscUtil { // -------------------------------------------- // // BYTE // -------------------------------------------- // - + private static HashMap locks = new HashMap<>(); public static byte[] readBytes(File file) throws IOException { int length = (int) file.length(); @@ -34,29 +34,27 @@ public class DiscUtil { return output; } + // -------------------------------------------- // + // STRING + // -------------------------------------------- // + public static void writeBytes(File file, byte[] bytes) throws IOException { FileOutputStream out = new FileOutputStream(file); out.write(bytes); out.close(); } - // -------------------------------------------- // - // STRING - // -------------------------------------------- // - public static void write(File file, String content) throws IOException { writeBytes(file, utf8(content)); } - public static String read(File file) throws IOException { - return utf8(readBytes(file)); - } - // -------------------------------------------- // // CATCH // -------------------------------------------- // - private static HashMap locks = new HashMap<>(); + public static String read(File file) throws IOException { + return utf8(readBytes(file)); + } public static boolean writeCatch(final File file, final String content, boolean sync) { String name = file.getName(); 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 ceb95dc3..fce3a66c 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TL.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TL.java @@ -730,7 +730,6 @@ public enum TL { COMMAND_RULES_CLEAR_SUCCESS("&cRule cleared successfully!"), - /** * Leaving - This is accessed through a command, and so it MAY need a COMMAND_* slug :s */ @@ -811,7 +810,6 @@ public enum TL { GENERIC_PLACEHOLDER(""), - WARBANNER_NOFACTION("&cYou need a faction to use a warbanner!"), WARBANNER_COOLDOWN("&cThe warbanner is on cooldown for your faction!"), WARBANNER_INVALIDLOC("&cYou can only use warbanners in enemy land or the warzone"), @@ -945,10 +943,10 @@ public enum TL { WARMUPS_ALREADY("&cYou are already warming up."), WARMUPS_CANCELLED("&cYou have cancelled your warmup."); + public static SimpleDateFormat sdf; + private static YamlConfiguration LANG; private String path; private String def; - private static YamlConfiguration LANG; - public static SimpleDateFormat sdf; /** * Lang enum constructor. 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 47cf61bb..973c6600 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java @@ -86,20 +86,31 @@ public enum TagReplacer { private TagType type; private String tag; - protected enum TagType { - FANCY(0), PLAYER(1), FACTION(2), GENERAL(3); - public int id; - - TagType(int id) { - this.id = id; - } - } - TagReplacer(TagType type, String tag) { this.type = type; this.tag = tag; } + /** + * Returns a list of all the variables we can use for this type
+ * + * @param type the type we want + * @return a list of all the variables with this type + */ + protected static List getByType(TagType type) { + List tagReplacers = new ArrayList<>(); + for (TagReplacer tagReplacer : TagReplacer.values()) { + if (type == TagType.FANCY) { + if (tagReplacer.type == TagType.FANCY) { + tagReplacers.add(tagReplacer); + } + } else if (tagReplacer.type.id >= type.id) { + tagReplacers.add(tagReplacer); + } + } + return tagReplacers; + } + /** * Protected access to this generic server related variable * @@ -245,26 +256,6 @@ public enum TagReplacer { return null; } - /** - * Returns a list of all the variables we can use for this type
- * - * @param type the type we want - * @return a list of all the variables with this type - */ - protected static List getByType(TagType type) { - List tagReplacers = new ArrayList<>(); - for (TagReplacer tagReplacer : TagReplacer.values()) { - if (type == TagType.FANCY) { - if (tagReplacer.type == TagType.FANCY) { - tagReplacers.add(tagReplacer); - } - } else if (tagReplacer.type.id >= type.id) { - tagReplacers.add(tagReplacer); - } - } - return tagReplacers; - } - /** * @param original raw line with variables * @param value what to replace var in raw line with @@ -293,4 +284,13 @@ public enum TagReplacer { public String getTag() { return this.tag; } + + protected enum TagType { + FANCY(0), PLAYER(1), FACTION(2), GENERAL(3); + public int id; + + TagType(int id) { + this.id = id; + } + } } diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java b/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java index 724a4355..b0bf9824 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java @@ -10,34 +10,23 @@ import java.util.regex.Pattern; public class TextUtil { - public Map tags; - - public TextUtil() { - this.tags = new HashMap<>(); - } + public static final transient Pattern patternTag = Pattern.compile("<([a-zA-Z0-9_]*)>"); + private final static String titleizeLine = repeat("-", 52); // -------------------------------------------- // // Top-level parsing functions. // -------------------------------------------- // - - public String parse(String str, Object... args) { - return String.format(this.parse(str), args); - } - - public String parse(String str) { - return this.parseTags(parseColor(str)); - } + private final static int titleizeBalance = -1; + public Map tags; // -------------------------------------------- // // Tag parsing // -------------------------------------------- // - public String parseTags(String str) { - return replaceTags(str, this.tags); + public TextUtil() { + this.tags = new HashMap<>(); } - public static final transient Pattern patternTag = Pattern.compile("<([a-zA-Z0-9_]*)>"); - public static String replaceTags(String str, Map tags) { StringBuffer ret = new StringBuffer(); Matcher matcher = patternTag.matcher(str); @@ -54,14 +43,6 @@ public class TextUtil { return ret.toString(); } - // -------------------------------------------- // - // Fancy parsing - // -------------------------------------------- // - - public FancyMessage parseFancy(String prefix) { - return toFancy(parse(prefix)); - } - public static FancyMessage toFancy(String first) { String text = ""; FancyMessage message = new FancyMessage(text); @@ -101,7 +82,7 @@ public class TextUtil { } // -------------------------------------------- // - // Color parsing + // Fancy parsing // -------------------------------------------- // public static String parseColor(String string) { @@ -118,6 +99,10 @@ public class TextUtil { return string; } + // -------------------------------------------- // + // Color parsing + // -------------------------------------------- // + public static String parseColorAcc(String string) { return string.replace("`e", "").replace("`r", ChatColor.RED.toString()).replace("`R", ChatColor.DARK_RED.toString()).replace("`y", ChatColor.YELLOW.toString()).replace("`Y", ChatColor.GOLD.toString()).replace("`g", ChatColor.GREEN.toString()).replace("`G", ChatColor.DARK_GREEN.toString()).replace("`a", ChatColor.AQUA.toString()).replace("`A", ChatColor.DARK_AQUA.toString()).replace("`b", ChatColor.BLUE.toString()).replace("`B", ChatColor.DARK_BLUE.toString()).replace("`p", ChatColor.LIGHT_PURPLE.toString()).replace("`P", ChatColor.DARK_PURPLE.toString()).replace("`k", ChatColor.BLACK.toString()).replace("`s", ChatColor.GRAY.toString()).replace("`S", ChatColor.DARK_GRAY.toString()).replace("`w", ChatColor.WHITE.toString()); } @@ -126,10 +111,6 @@ public class TextUtil { return string.replace("", "").replace("", "\u00A70").replace("", "\u00A71").replace("", "\u00A72").replace("", "\u00A73").replace("", "\u00A74").replace("", "\u00A75").replace("", "\u00A76").replace("", "\u00A77").replace("", "\u00A78").replace("", "\u00A79").replace("", "\u00A7a").replace("", "\u00A7b").replace("", "\u00A7c").replace("", "\u00A7d").replace("", "\u00A7e").replace("", "\u00A7f"); } - // -------------------------------------------- // - // Standard utils like UCFirst, implode and repeat. - // -------------------------------------------- // - public static String upperCaseFirst(String string) { return string.substring(0, 1).toUpperCase() + string.substring(1); } @@ -145,6 +126,10 @@ public class TextUtil { return ret.toString(); } + // -------------------------------------------- // + // Standard utils like UCFirst, implode and repeat. + // -------------------------------------------- // + public static String repeat(String s, int times) { if (times <= 0) { return ""; @@ -153,10 +138,6 @@ public class TextUtil { } } - // -------------------------------------------- // - // Material name tools - // -------------------------------------------- // - public static String getMaterialName(Material material) { return material.toString().replace('_', ' ').toLowerCase(); } @@ -165,12 +146,56 @@ public class TextUtil { return getMaterialName(Material.getMaterial(materialId)); } + // -------------------------------------------- // + // Material name tools + // -------------------------------------------- // + + public static String getBestStartWithCI(Collection candidates, String start) { + String ret = null; + int best = 0; + + start = start.toLowerCase(); + int minlength = start.length(); + for (String candidate : candidates) { + if (candidate.length() < minlength) { + continue; + } + if (!candidate.toLowerCase().startsWith(start)) { + continue; + } + + // The closer to zero the better + int lendiff = candidate.length() - minlength; + if (lendiff == 0) { + return candidate; + } + if (lendiff < best || best == 0) { + best = lendiff; + ret = candidate; + } + } + return ret; + } + + public String parse(String str, Object... args) { + return String.format(this.parse(str), args); + } + // -------------------------------------------- // // Paging and chrome-tools like titleize // -------------------------------------------- // - private final static String titleizeLine = repeat("-", 52); - private final static int titleizeBalance = -1; + public String parse(String str) { + return this.parseTags(parseColor(str)); + } + + public String parseTags(String str) { + return replaceTags(str, this.tags); + } + + public FancyMessage parseFancy(String prefix) { + return toFancy(parse(prefix)); + } public String titleize(String str) { String center = ChatColor.DARK_GRAY + "< " + parseTags("") + str + parseTags("") + ChatColor.DARK_GRAY + " >"; @@ -212,31 +237,4 @@ public class TextUtil { return ret; } - - public static String getBestStartWithCI(Collection candidates, String start) { - String ret = null; - int best = 0; - - start = start.toLowerCase(); - int minlength = start.length(); - for (String candidate : candidates) { - if (candidate.length() < minlength) { - continue; - } - if (!candidate.toLowerCase().startsWith(start)) { - continue; - } - - // The closer to zero the better - int lendiff = candidate.length() - minlength; - if (lendiff == 0) { - return candidate; - } - if (lendiff < best || best == 0) { - best = lendiff; - ret = candidate; - } - } - return ret; - } } \ No newline at end of file diff --git a/src/main/java/com/massivecraft/factions/zcore/util/UUIDFetcher.java b/src/main/java/com/massivecraft/factions/zcore/util/UUIDFetcher.java index 6970128b..adf3e3a2 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/UUIDFetcher.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/UUIDFetcher.java @@ -33,28 +33,6 @@ public class UUIDFetcher implements Callable> { this(names, true); } - public Map call() throws Exception { - Map uuidMap = new HashMap<>(); - int requests = (int) Math.ceil(names.size() / PROFILES_PER_REQUEST); - for (int i = 0; i < requests; i++) { - HttpURLConnection connection = createConnection(); - String body = JSONArray.toJSONString(names.subList(i * 100, Math.min((i + 1) * 100, names.size()))); - writeBody(connection, body); - JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream())); - for (Object profile : array) { - JSONObject jsonProfile = (JSONObject) profile; - String id = (String) jsonProfile.get("id"); - String name = (String) jsonProfile.get("name"); - UUID uuid = UUIDFetcher.getUUID(id); - uuidMap.put(name, uuid); - } - if (rateLimiting && i != requests - 1) { - Thread.sleep(100L); - } - } - return uuidMap; - } - private static void writeBody(HttpURLConnection connection, String body) throws Exception { OutputStream stream = connection.getOutputStream(); stream.write(body.getBytes()); @@ -97,4 +75,26 @@ public class UUIDFetcher implements Callable> { public static UUID getUUIDOf(String name) throws Exception { return new UUIDFetcher(Collections.singletonList(name)).call().get(name); } + + public Map call() throws Exception { + Map uuidMap = new HashMap<>(); + int requests = (int) Math.ceil(names.size() / PROFILES_PER_REQUEST); + for (int i = 0; i < requests; i++) { + HttpURLConnection connection = createConnection(); + String body = JSONArray.toJSONString(names.subList(i * 100, Math.min((i + 1) * 100, names.size()))); + writeBody(connection, body); + JSONArray array = (JSONArray) jsonParser.parse(new InputStreamReader(connection.getInputStream())); + for (Object profile : array) { + JSONObject jsonProfile = (JSONObject) profile; + String id = (String) jsonProfile.get("id"); + String name = (String) jsonProfile.get("name"); + UUID uuid = UUIDFetcher.getUUID(id); + uuidMap.put(name, uuid); + } + if (rateLimiting && i != requests - 1) { + Thread.sleep(100L); + } + } + return uuidMap; + } }