diff --git a/pom.xml b/pom.xml index ab5f5034..f3336fad 100644 --- a/pom.xml +++ b/pom.xml @@ -47,6 +47,10 @@ com.google.gson com.massivecraft.factions.shade.com.google.gson + + com.darkblade12 + com.massivecraft.factions.shade.com.darkblade12 + @@ -63,9 +67,9 @@ - org.inventivetalent - particleapi - 2.1.1 + com.darkblade12 + particleeffect + 1.7.0-SNAPSHOT org.spigotmc diff --git a/src/main/java/com/massivecraft/factions/FPlayer.java b/src/main/java/com/massivecraft/factions/FPlayer.java index 2a37d3df..0ef0d232 100644 --- a/src/main/java/com/massivecraft/factions/FPlayer.java +++ b/src/main/java/com/massivecraft/factions/FPlayer.java @@ -159,6 +159,23 @@ public interface FPlayer extends EconomyParticipator { public boolean hasMoney(int amt); + + // Fly Checks + + public Boolean canflyinWilderness(); + + public Boolean canflyinWarzone(); + + public Boolean canflyinSafezone(); + + public Boolean canflyinEnemy(); + + public Boolean canflyinAlly(); + + public Boolean canflyinTruce(); + + public Boolean canflyinNeutral(); + // ------------------------------- // Relation and relation colors // ------------------------------- diff --git a/src/main/java/com/massivecraft/factions/MassiveStats.java b/src/main/java/com/massivecraft/factions/MassiveStats.java new file mode 100644 index 00000000..8d65fc8c --- /dev/null +++ b/src/main/java/com/massivecraft/factions/MassiveStats.java @@ -0,0 +1,498 @@ +package com.massivecraft.factions; + +/* + * Copyright 2018 (c) Massive Statistics LLC - All Rights Reserved + * This file may only be used in conjunction with the 'MassiveStats' service. + */ + + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitRunnable; + +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; + +/** + * MassiveStats collects plugin and server information for plugin authors. + * You can learn more at our website: https://www.massivestats.com/ + * + * @author Sam Jakob Harker, Brianna Hazel O'Keefe + * @version 3.0 + */ +@SuppressWarnings("all") +public class MassiveStats implements Listener { + + /* START: MASSIVESTATS SETTINGS */ + public static final int CLIENT_VERSION = 0; // v3.0 + public static final String API_URL = "https://report.massivestats.com/v2/"; + + public static final String MASSIVE_UPDATE_PERMISSION = "massivestats.update"; + /* END: MASSIVESTATS SETTINGS */ + private final JavaPlugin plugin; + private MassiveStatsUpdateTask task = null; + private int pingInterval; + private MassiveStatsDataResponse lastResponse; + private boolean listenerDisabled; + private Class jsonElement; + private Class jsonParser; + private Class jsonObject; + private Class jsonPrimitive; + + /** + * @param plugin The plugin you wish to collect data for. + * @author Sam Jakob Harker + */ + public MassiveStats(JavaPlugin plugin) { + this(plugin, 900); // default value: 900 seconds (= 15 minutes) + } + + /** + * @param plugin The plugin you wish to collect data for. + * @param pingInterval Duration between requests. + * @author Sam Jakob Harker + */ + public MassiveStats(JavaPlugin plugin, int pingInterval) { + try { + jsonElement = Class.forName("com.google.gson.JsonElement"); + jsonParser = Class.forName("com.google.gson.JsonParser"); + jsonObject = Class.forName("com.google.gson.JsonObject"); + jsonPrimitive = Class.forName("com.google.gson.JsonPrimitive"); + } catch (ClassNotFoundException ex) { + // Gson not included in classpath (so use NMS version) + try { + jsonElement = Class.forName("net.minecraft.util.com.google.gson.JsonElement"); + jsonParser = Class.forName("net.minecraft.util.com.google.gson.JsonParser"); + jsonObject = Class.forName("net.minecraft.util.com.google.gson.JsonObject"); + jsonPrimitive = Class.forName("net.minecraft.util.com.google.gson.JsonPrimitive"); + } catch (ClassNotFoundException ignored) { + Bukkit.getLogger().severe("MassiveStats could not find an instance/version of Gson to use."); + this.plugin = null; + return; + } + } + + // Ensure the pingInterval that is set is reasonable. + if (pingInterval < 10 || pingInterval > 86400) { + pingInterval = 900; + } + + // Ensure that a plugin instance has been provided. + if (plugin == null) { + throw new IllegalArgumentException("You must provide a plugin for MassiveStats to collect data for!"); + } + + // Set the ping interval. + this.pingInterval = pingInterval; + // Set the plugin reference. + this.plugin = plugin; + // and start sending data to the MassiveStats server immediately. + start(); + + // Register join/leave events for the plugin + Bukkit.getServer().getPluginManager().registerEvents(this, plugin); + } + + /** + * Gets whether or not the built-in MassiveStats {@link org.bukkit.event.player.PlayerJoinEvent} listener is enabled. + * + * @return Whether or not the MassiveStats listener is enabled. + */ + public boolean isListenerDisabled() { + return listenerDisabled; + } + + /** + * Sets whether or not the built-in MassiveStats {@link org.bukkit.event.player.PlayerJoinEvent} listener is enabled. + * + * @param listenerDisabled Whether or not the MassiveStats listener is enabled. + */ + public void setListenerDisabled(boolean listenerDisabled) { + this.listenerDisabled = listenerDisabled; + } + + /** + * Start the MassiveStats reporting timer. + * If the timer is already running, this method will do nothing. + * + * @author Sam Jakob Harker + */ + public void start() { + if (this.plugin == null) { + Bukkit.getLogger().severe("MassiveStats could not find an instance/version of Gson to use and thus cannot start."); + return; + } + + if (task == null) { + // If the API endpoint URL is invalid, don't start a new task to prevent the user from being spammed. + try { + new URL(MassiveStats.API_URL); + } catch (MalformedURLException ex) { + getPlugin() + .getLogger().warning("You have specified an invalid API endpoint for MassiveStats."); + return; + } + + task = new MassiveStatsUpdateTask(this); + task.runTaskTimerAsynchronously(plugin, 0L, pingInterval * 20L); + } + } + + /** + * Stop the MassiveStats reporting timer. + * Requests will no longer be sent to the server - or until {@link #start()} is invoked. + * + * @author Sam Jakob Harker + */ + public void stop() { + if (task == null) { + return; + } + + task.cancel(); + task = null; + } + + /** + * Returns the duration, in seconds, that MassiveStats will wait before sending another request to the server. + * + * @return Duration between requests. + * @author Sam Jakob Harker + */ + public int getPingInterval() { + return pingInterval; + } + + /** + * Sets the duration, in seconds, that MassiveStats should wait before sending another request to the server. + * + * @param pingInterval Duration between requests. + * @author Sam Jakob Harker + */ + public void setPingInterval(int pingInterval) { + this.pingInterval = pingInterval; + + stop(); + start(); + } + + /** + * Returns the plugin that this MassiveStats instance is collecting data for. + * + * @return MassiveStats instance plugin. + * @author Sam Jakob Harker + */ + public JavaPlugin getPlugin() { + return plugin; + } + + /** + * Returns the contents of the last response from the MassiveStats server. + * + * @return MassiveStats server response. + * @author Sam Jakob Harker + */ + public MassiveStatsDataResponse getLastResponse() { + return lastResponse; + } + + void setLastResponse(MassiveStatsDataResponse lastResponse) { + this.lastResponse = lastResponse; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + // Ensure the listener should be active + if (lastResponse == null || listenerDisabled) { + return; + } + + // Of course, only notify the user if the plugin is not up to date. + if (lastResponse.isUpToDate()) { + return; + } + + // and only notify operators - or players with the correct permission. + if (!event.getPlayer().isOp() && !event.getPlayer().hasPermission(MassiveStats.MASSIVE_UPDATE_PERMISSION)) { + return; + } + + event.getPlayer().sendMessage(lastResponse.getUpdateMessage()); + } + + Class getJsonElement() { + return jsonElement; + } + + Class getJsonParser() { + return jsonParser; + } + + Class getJsonObject() { + return jsonObject; + } + + Class getJsonPrimitive() { + return jsonPrimitive; + } + +} + +class MassiveStatsUpdateTask extends BukkitRunnable { + + private final MassiveStats instance; + + MassiveStatsUpdateTask(MassiveStats requester) { + instance = requester; + } + + @Override + @SuppressWarnings("all") + public void run() { + try { + // Generate the request payload and serialize it as JSON. + String payload = new MassiveStatsDataRequest(instance).serialize(); + + // Then create a new HttpsUrlConnection to the API server and open it. + HttpsURLConnection connection = (HttpsURLConnection) new URL(MassiveStats.API_URL).openConnection(); + + // Ensure that we don't hang the server with our 'dang shenanigans'. + connection.setConnectTimeout(2500); + connection.setReadTimeout(3500); + + // Set the all-important request headers before we begin POSTing... + connection.setRequestMethod("POST"); + connection.setRequestProperty("Accept", "application/json"); + connection.setRequestProperty("Content-Type", "application/json; charset=utf-8"); + connection.setRequestProperty("User-Agent", "Massive/" + MassiveStats.CLIENT_VERSION); + + // Open the output stream, write the payload, and then close the stream. + connection.setDoOutput(true); + DataOutputStream output = new DataOutputStream(connection.getOutputStream()); + output.writeBytes(payload); + output.flush(); + output.close(); + + // Ensure that the server was happy with our data. + int responseCode = connection.getResponseCode(); + if (responseCode != 200) { + throw new IOException(); + } + + // Now, read the server's response to our payload... + BufferedReader input = new BufferedReader(new InputStreamReader(connection.getInputStream())); + StringBuilder response = new StringBuilder(); + + // ...line by line. + String line; + while ((line = input.readLine()) != null) { + response.append(line); + } + input.close(); + + // Now, we parse the JSON object. + try { + if (response.toString().contains("ERR_DATA_MISSING")) { + Bukkit.getLogger().severe("MassiveStats has encountered an error for the following plugin: " + + instance.getPlugin().getName()); + instance.stop(); + return; + } + + Object parser = instance.getJsonParser().newInstance(); + + // JsonElement + Object serverResponseRaw = + parser.getClass().getMethod("parse", String.class).invoke(parser, response.toString()); + + // JsonObject + Object serverResponse = serverResponseRaw.getClass().getMethod("getAsJsonObject", null) + .invoke(serverResponseRaw, null); + + Method serverResponseGet = instance.getJsonObject().getMethod("get", String.class); + + Method getAsBoolean = + instance.getJsonPrimitive().getMethod("getAsBoolean", null); + Method getAsString = + instance.getJsonPrimitive().getMethod("getAsString", null); + + if (serverResponseGet.invoke(serverResponse, "upToDate") == null) { + Bukkit.getLogger().severe("MassiveStats has encountered an error for the following plugin: " + + instance.getPlugin().getName()); + instance.stop(); + return; + } + + if (serverResponseGet.invoke(serverResponse, "notice") != null) { + Bukkit.getLogger().severe( + (String) getAsString.invoke(serverResponseGet.invoke(serverResponse, "notice")) + ); + instance.stop(); + return; + } + + boolean upToDate = (boolean) getAsBoolean.invoke(serverResponseGet.invoke(serverResponse, "upToDate"), null); + String latestVersion = (String) getAsString.invoke(serverResponseGet.invoke(serverResponse, "latestVersion"), null); + String updateMessage = ChatColor.translateAlternateColorCodes( + '&', (String) getAsString.invoke(serverResponseGet.invoke(serverResponse, "updateMessage"), null) + ); + + instance.setLastResponse(new MassiveStatsDataResponse( + upToDate, latestVersion, updateMessage + )); + + } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { + instance.getPlugin() + .getLogger().warning("MassiveStats returned an invalid response for this plugin."); + } + + // Finally, call an event to mark the update. + } catch (MalformedURLException ex) { + instance.getPlugin() + .getLogger().warning("You have specified an invalid API endpoint for MassiveStats."); + } catch (IOException ex) { + instance.getPlugin() + .getLogger().warning("MassiveStats was unable to communicate with its API endpoint."); + } + } + +} + +class MassiveStatsDataRequest { + + private Object jsonObject; + + MassiveStatsDataRequest(MassiveStats requester) { + try { + jsonObject = requester.getJsonObject().newInstance(); + + Method add = + requester.getJsonObject().newInstance().getClass().getMethod("add", String.class, requester.getJsonElement()); + Method addPropertyString = + requester.getJsonObject().newInstance().getClass().getMethod("addProperty", String.class, String.class); + Method addPropertyNumber = + requester.getJsonObject().newInstance().getClass().getMethod("addProperty", String.class, Number.class); + Method addPropertyBoolean = + requester.getJsonObject().newInstance().getClass().getMethod("addProperty", String.class, Boolean.class); + + addPropertyNumber.invoke(jsonObject, "now", System.currentTimeMillis()); + + /* PLUGIN DATA */ + Object pluginObject = jsonObject.getClass().newInstance(); + addPropertyString.invoke(pluginObject, "name", requester.getPlugin().getDescription().getName()); + addPropertyString.invoke(pluginObject, "version", requester.getPlugin().getDescription().getVersion()); + add.invoke(jsonObject, "plugin", pluginObject); + + /* SERVER DATA */ + Object minecraftServerObject = jsonObject.getClass().newInstance(); + addPropertyNumber.invoke(minecraftServerObject, "players", Bukkit.getServer().getOnlinePlayers().size()); + addPropertyBoolean.invoke(minecraftServerObject, "onlineMode", Bukkit.getServer().getOnlineMode()); + addPropertyString.invoke(minecraftServerObject, "version", Bukkit.getServer().getVersion()); + + Object javaServerObject = jsonObject.getClass().newInstance(); + addPropertyString.invoke(javaServerObject, "version", System.getProperty("java.version")); + + Object osServerObject = jsonObject.getClass().newInstance(); + addPropertyString.invoke(osServerObject, "name", System.getProperty("os.name")); + addPropertyString.invoke(osServerObject, "arch", System.getProperty("os.arch")); + addPropertyString.invoke(osServerObject, "version", System.getProperty("os.version")); + + Object hardwareServerObject = jsonObject.getClass().newInstance(); + addPropertyNumber.invoke(hardwareServerObject, "cores", Runtime.getRuntime().availableProcessors()); + + Object serverObject = jsonObject.getClass().newInstance(); + add.invoke(serverObject, "minecraft", minecraftServerObject); + add.invoke(serverObject, "java", javaServerObject); + add.invoke(serverObject, "os", osServerObject); + add.invoke(serverObject, "hardware", hardwareServerObject); + + add.invoke(jsonObject, "server", serverObject); + + /* MASSIVE DATA */ + Object massiveObject = jsonObject.getClass().newInstance(); + addPropertyNumber.invoke(massiveObject, "version", MassiveStats.CLIENT_VERSION); + addPropertyNumber.invoke(massiveObject, "pingInterval", requester.getPingInterval()); + + //object.add("Massive", massiveObject); + add.invoke(jsonObject, "Massive", massiveObject); + } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { + e.printStackTrace(); + } + } + + @SuppressWarnings("all") + public String serialize() { + //return object.toString(); + try { + Method toString = jsonObject.getClass().getMethod("toString", null); + return (String) toString.invoke(jsonObject); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); + } + + return null; + } + +} + +@SuppressWarnings("unused") +final class MassiveStatsDataResponse { + + private final boolean isUpToDate; + private final String newVersion; + private final String updateMessage; + + MassiveStatsDataResponse(boolean isUpToDate, String newVersion, String updateMessage) { + this.isUpToDate = isUpToDate; + + if (!isUpToDate) { + this.newVersion = newVersion; + this.updateMessage = updateMessage; + return; + } + + this.newVersion = null; + this.updateMessage = null; + } + + /** + * Indicates whether or not this version of the plugin is the latest. + * True = This is the latest version of the plugin. + * False = There is an update available. + * + * @return Whether or not there is an update available. + */ + public boolean isUpToDate() { + return isUpToDate; + } + + /** + * Gets the name of the latest version. If this is the latest version, it returns null. + * + * @return The name of the latest version. + */ + public String getLatestVersion() { + return newVersion; + } + + /** + * Gets the message to display, convincing the user to update to the new version of the plugin. + * + * @return The update message to display. + */ + public String getUpdateMessage() { + return updateMessage; + } + +} \ No newline at end of file diff --git a/src/main/java/com/massivecraft/factions/P.java b/src/main/java/com/massivecraft/factions/P.java index 3637c439..8eb00298 100644 --- a/src/main/java/com/massivecraft/factions/P.java +++ b/src/main/java/com/massivecraft/factions/P.java @@ -139,6 +139,8 @@ public class P extends MPlugin { // start up task which runs the autoLeaveAfterDaysOfInactivity routine startAutoLeaveTask(false); + //massive stats + MassiveStats massive = new MassiveStats(this); mc17 = Bukkit.getServer().getClass().getPackage().getName().contains("1.7"); diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdFly.java b/src/main/java/com/massivecraft/factions/cmd/CmdFly.java index dc3e9514..efb22dee 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdFly.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdFly.java @@ -1,5 +1,6 @@ package com.massivecraft.factions.cmd; +import com.darkblade12.particleeffect.ParticleEffect; import com.massivecraft.factions.*; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Relation; @@ -9,7 +10,6 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.inventivetalent.particle.ParticleEffect; import java.util.HashMap; import java.util.Iterator; @@ -19,8 +19,8 @@ public class CmdFly extends FCommand { public static HashMap flyMap = new HashMap(); - public int id = -1; - public int flyid = -1; + public static int id = -1; + public static int flyid = -1; public CmdFly() { super(); this.aliases.add("fly"); @@ -156,7 +156,7 @@ public class CmdFly extends FCommand { } - public void startParticles(){ + public static void startParticles() { id = Bukkit.getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { @Override public void run() { @@ -169,7 +169,8 @@ public class CmdFly extends FCommand { continue; } - ParticleEffect.CLOUD.send(Bukkit.getOnlinePlayers(), player.getLocation().add(0, -0.35, 0), 0, 0, 0, 0, 3, 16); + + ParticleEffect.CLOUD.display(0, 0, 0, 0, 1, player.getLocation().add(0, -0.35, 0), 16); } if (flyMap.keySet().size() == 0){ @@ -180,7 +181,7 @@ public class CmdFly extends FCommand { }, 10L, 10L); } - public void startFlyCheck(){ + public static void startFlyCheck() { flyid = Bukkit.getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { @Override public void run() { @@ -210,7 +211,7 @@ public class CmdFly extends FCommand { if (Board.getInstance().getFactionAt(myFloc) != myFaction) { if (!checkBypassPerms(fPlayer,player,toFac)){ fPlayer.setFlying(false); - flyMap.remove(name); + itr.remove(); continue; } @@ -224,8 +225,7 @@ public class CmdFly extends FCommand { } - - private boolean checkBypassPerms(FPlayer fplayer, Player player,Faction toFac){ + private static boolean checkBypassPerms(FPlayer fplayer, Player player, Faction toFac) { if (player.hasPermission("factions.fly.wilderness") && toFac.isWilderness()){ return true; } @@ -250,7 +250,7 @@ public class CmdFly extends FCommand { return false; } - public void checkTaskState(){ + public static void checkTaskState() { if (flyMap.keySet().size() == 0) { Bukkit.getScheduler().cancelTask(flyid); flyid = -1; @@ -258,9 +258,6 @@ public class CmdFly extends FCommand { } - - - private void toggleFlight(final boolean toggle, final Player player) { if (!toggle) { fme.setFlying(false); diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java b/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java index 84028d41..91cf278f 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdSeeChunk.java @@ -1,6 +1,7 @@ package com.massivecraft.factions.cmd; +import com.darkblade12.particleeffect.ParticleEffect; import com.massivecraft.factions.FLocation; import com.massivecraft.factions.P; import com.massivecraft.factions.struct.Permission; @@ -11,7 +12,6 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.entity.Player; -import org.inventivetalent.particle.ParticleEffect; import java.util.Arrays; import java.util.HashMap; @@ -29,6 +29,7 @@ public class CmdSeeChunk extends FCommand { private int taskID = -1; + //I remade it cause of people getting mad that I had the same seechunk as drtshock @@ -46,7 +47,8 @@ public class CmdSeeChunk extends FCommand { this.useParticles = p.getConfig().getBoolean("see-chunk.particles", true); interval = P.p.getConfig().getLong("see-chunk.interval", 10L); - effect = ParticleEffect.valueOf(P.p.getConfig().getString("see-chunk.particle", "REDSTONE")); + effect = ParticleEffect.fromName(P.p.getConfig().getString("see-chunk.particle", "REDSTONE")); + } @Override @@ -101,6 +103,7 @@ public class CmdSeeChunk extends FCommand { blockZ = chunkZ * 16; showPillar(me, world, blockX, blockZ); + blockX = chunkX * 16 + 15; blockZ = chunkZ * 16; showPillar(me, world, blockX, blockZ); @@ -123,8 +126,10 @@ public class CmdSeeChunk extends FCommand { } if (useParticles) { - //api didnt seem to have anything for a single player, so I used a one player list :P - effect.send(onePlayer, loc, 0, 0, 0, 0, 1, 50); + + this.effect.display(0, 0, 0, 0, 3, loc, player); + + } else { int typeId = blockY % 5 == 0 ? Material.REDSTONE_LAMP_ON.getId() : Material.STAINED_GLASS.getId(); VisualizeUtil.addLocation(player, loc, typeId); @@ -132,6 +137,7 @@ public class CmdSeeChunk extends FCommand { } } + @Override public TL getUsageTranslation() { return TL.GENERIC_PLACEHOLDER; diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdShow.java b/src/main/java/com/massivecraft/factions/cmd/CmdShow.java index 62809c11..2e59332b 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdShow.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdShow.java @@ -1,13 +1,13 @@ package com.massivecraft.factions.cmd; -import com.massivecraft.factions.*; +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.Faction; +import com.massivecraft.factions.P; import com.massivecraft.factions.struct.Permission; -import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.util.TL; import com.massivecraft.factions.zcore.util.TagReplacer; import com.massivecraft.factions.zcore.util.TagUtil; import mkremins.fanciful.FancyMessage; -import org.bukkit.Bukkit; import java.util.ArrayList; import java.util.List; @@ -19,7 +19,6 @@ public class CmdShow extends FCommand { public CmdShow() { this.aliases.add("show"); this.aliases.add("who"); - this.aliases.add("f"); // add defaults to /f show in case config doesnt have it defaults.add("{header}"); @@ -48,7 +47,6 @@ public class CmdShow extends FCommand { @Override public void perform() { Faction faction = myFaction; - if (this.argIsSet(0)) { faction = this.argAsFaction(0); } @@ -56,11 +54,6 @@ public class CmdShow extends FCommand { return; } - if (!fme.hasFaction() && fme.getFaction() == faction){ - fme.msg(TL.COMMAND_SHOW_NEEDFACTION); - return; - } - if (fme != null && !fme.getPlayer().hasPermission("factions.show.bypassexempt") && P.p.getConfig().getStringList("show-exempt").contains(faction.getTag())) { msg(TL.COMMAND_SHOW_EXEMPT); @@ -76,65 +69,6 @@ public class CmdShow extends FCommand { if (show == null || show.isEmpty()) { show = defaults; } - /* for (int i = 0; i <= show.size()-1; i ++){ - if (show.get(i).contains("{description}")){ - show.set(i,show.get(i).replace("{description}",faction.getDescription())); - } - if (show.get(i).contains("{online-list}")){ - String message = ""; - StringBuilder string = new StringBuilder(message); - for (FPlayer fPlayer : faction.getFPlayers()){ - Bukkit.broadcastMessage(fPlayer.getTag()); - if (fPlayer.getPlayer().isOnline()){ - String prefix = ""; - if (fPlayer.getRole() == Role.ADMIN){ - prefix = Conf.prefixAdmin; - } - if (fPlayer.getRole() == Role.COLEADER){ - prefix = Conf.prefixCoLeader; - } - if (fPlayer.getRole() == Role.MODERATOR){ - prefix = Conf.prefixMod; - } - if (fPlayer.getRole() == Role.NORMAL){ - prefix = Conf.prefixNormal; - } - if (fPlayer.getRole() == Role.RECRUIT){ - prefix = Conf.prefixRecruit; - } - string.append(prefix + fPlayer.getName() + ","); - } - if (string.toString().equals("")) { continue; } - show.set(i,show.get(i).replace("{online-list}",string.toString())); - } - } - if (show.get(i).contains("{offline-list}")){ - String message = ""; - StringBuilder string = new StringBuilder(message); - for (FPlayer fPlayer : faction.getFPlayers()){ - if (!fPlayer.getPlayer().isOnline()){ - String prefix = ""; - if (fPlayer.getRole() == Role.ADMIN){ - prefix = Conf.prefixAdmin; - } - if (fPlayer.getRole() == Role.COLEADER){ - prefix = Conf.prefixCoLeader; - } - if (fPlayer.getRole() == Role.MODERATOR){ - prefix = Conf.prefixMod; - } - if (fPlayer.getRole() == Role.NORMAL){ - prefix = Conf.prefixNormal; - } - if (fPlayer.getRole() == Role.RECRUIT){ - prefix = Conf.prefixRecruit; - } - string.append(prefix + fPlayer.getName() + ","); - } - show.set(i,show.get(i).replace("{offline-list}",string.toString())); - } - } - }*/ if (!faction.isNormal()) { String tag = faction.getTag(fme); @@ -154,9 +88,11 @@ public class CmdShow extends FCommand { continue; // Due to minimal f show. } - parsed = TagUtil.parsePlaceholders(fme.getPlayer(), parsed); + if (fme != null) { + parsed = TagUtil.parsePlaceholders(fme.getPlayer(), parsed); + } - if (TagUtil.hasFancy(parsed)) { + if (fme != null && TagUtil.hasFancy(parsed)) { List fancy = TagUtil.parseFancy(faction, fme, parsed); if (fancy != null) { sendFancyMessage(fancy); diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java index 2e5c9a6e..8fd419f4 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsEntityListener.java @@ -99,7 +99,17 @@ public class FactionsEntityListener implements Listener { Entity damagee = sub.getEntity(); Entity damager = sub.getDamager(); - + if (damagee instanceof Player) { + if (damager instanceof Player) { + FPlayer fdamager = FPlayers.getInstance().getByPlayer((Player) damager); + FPlayer fdamagee = FPlayers.getInstance().getByPlayer((Player) damagee); + if ((fdamagee.getRelationTo(fdamager) == Relation.ALLY) || + (fdamagee.getRelationTo(fdamager) == Relation.TRUCE) || + (fdamagee.getFaction() == fdamager.getFaction())) { + return; + } + } + } if (damagee != null && damagee instanceof Player) { cancelFStuckTeleport((Player) damagee); cancelFFly((Player) damagee); @@ -587,17 +597,20 @@ public class FactionsEntityListener implements Listener { public void onBowHit(EntityDamageByEntityEvent e){ if (e.getDamager() instanceof Projectile){ if (e.getEntity() instanceof Player){ - Player damager = (Player) ((Projectile) e.getDamager()).getShooter(); - Player victim = (Player) e.getEntity(); - FPlayer fdamager = FPlayers.getInstance().getByPlayer(damager); - FPlayer fvictim = FPlayers.getInstance().getByPlayer(victim); - if (fvictim.getRelationTo(fdamager) == Relation.TRUCE){ - fdamager.msg(TL.PLAYER_PVP_CANTHURT, fvictim.describeTo(fdamager)); - e.setCancelled(true); - } - if (fvictim.getRelationTo(fdamager) == Relation.ENEMY) { - if (fvictim.isFlying()) { - fvictim.setFFlying(false, true); + Projectile arrow = ((Projectile) e.getDamager()); + if (arrow.getShooter() instanceof Player) { + Player damager = (Player) ((Projectile) e.getDamager()).getShooter(); + Player victim = (Player) e.getEntity(); + FPlayer fdamager = FPlayers.getInstance().getByPlayer(damager); + FPlayer fvictim = FPlayers.getInstance().getByPlayer(victim); + if (fvictim.getRelationTo(fdamager) == Relation.TRUCE) { + fdamager.msg(TL.PLAYER_PVP_CANTHURT, fvictim.describeTo(fdamager)); + e.setCancelled(true); + } + if (fvictim.getRelationTo(fdamager) == Relation.ENEMY) { + if (fvictim.isFlying()) { + fvictim.setFFlying(false, true); + } } } } diff --git a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java index fb6b9b6b..3891f61f 100644 --- a/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java +++ b/src/main/java/com/massivecraft/factions/listeners/FactionsPlayerListener.java @@ -1,5 +1,6 @@ package com.massivecraft.factions.listeners; +import com.darkblade12.particleeffect.ParticleEffect; import com.massivecraft.factions.*; import com.massivecraft.factions.cmd.CmdFly; import com.massivecraft.factions.cmd.CmdSeeChunk; @@ -41,7 +42,6 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.util.NumberConversions; -import org.inventivetalent.particle.ParticleEffect; import java.util.*; import java.util.logging.Level; @@ -240,6 +240,22 @@ public class FactionsPlayerListener implements Listener { 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(); + } + } + } + // Holds the next time a player can have a map shown. private HashMap showTimes = new HashMap<>(); @@ -289,26 +305,27 @@ public class FactionsPlayerListener implements Listener { me.getPlayer().sendTitle(P.p.color(title), P.p.color(subTitle)); } // enable fly :) - if (me.hasFaction()) { + if (me.hasFaction() && !me.isFlying()) { if (factionTo == me.getFaction()) { - if (P.p.getConfig().getBoolean("ffly.AutoEnable")) { - CmdFly Fly = new CmdFly(); - me.setFlying(true); - Fly.flyMap.put(player.getName(), true); - if (Fly.id == -1) { - if (P.p.getConfig().getBoolean("ffly.Particles.Enabled")) { - Fly.startParticles(); - } - } - if (Fly.flyid == -1) { - Fly.startFlyCheck(); - } - } + enableFly(me); } + // bypass checks + if ((factionTo.isWilderness() && me.canflyinWilderness()) || + (factionTo.isWarZone() && me.canflyinWarzone()) || + (factionTo.isSafeZone() && me.canflyinSafezone()) || + (factionTo.getRelationTo(me) == Relation.ENEMY && me.canflyinEnemy()) || + (factionTo.getRelationTo(me) == Relation.ALLY && me.canflyinAlly()) || + (factionTo.getRelationTo(me) == Relation.TRUCE && me.canflyinTruce()) || + (factionTo.getRelationTo(me) == Relation.NEUTRAL && me.canflyinNeutral())) { + enableFly(me); + } + } } + + if (me.isMapAutoUpdating()) { if (showTimes.containsKey(player.getUniqueId()) && (showTimes.get(player.getUniqueId()) > System.currentTimeMillis())) { if (P.p.getConfig().getBoolean("findfactionsexploit.log", false)) { @@ -371,6 +388,7 @@ public class FactionsPlayerListener implements Listener { } + HashMap bannerCooldownMap = new HashMap<>(); public static HashMap bannerLocations = new HashMap<>(); @EventHandler @@ -437,8 +455,8 @@ public class FactionsPlayerListener implements Listener { String[] components = effect.split(":"); player.addPotionEffect(new PotionEffect(PotionEffectType.getByName(components[0]),100,Integer.parseInt(components[1]))); } - ParticleEffect.FLAME.send(Bukkit.getOnlinePlayers(), banner.getLocation(), 1, 1, 1, 1, 10, 16); - ParticleEffect.LAVA.send(Bukkit.getOnlinePlayers(), banner.getLocation(), 1, 1, 1, 1, 10, 16); + 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); 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 64c75919..e9b6cafe 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java @@ -1130,6 +1130,79 @@ public abstract class MemoryFPlayer implements FPlayer { return false; } + @Override + public Boolean canflyinWilderness() { + if (getPlayer().hasPermission("factions.fly.wilderness")) { + return true; + } else { + return false; + } + + } + + @Override + public Boolean canflyinWarzone() { + if (getPlayer().hasPermission("factions.fly.warzone")) { + return true; + } else { + return false; + } + + } + + + @Override + public Boolean canflyinSafezone() { + if (getPlayer().hasPermission("factions.fly.safezone")) { + return true; + } else { + return false; + } + + } + + @Override + public Boolean canflyinEnemy() { + if (getPlayer().hasPermission("factions.fly.enemy")) { + return true; + } else { + return false; + } + + } + + @Override + public Boolean canflyinAlly() { + if (getPlayer().hasPermission("factions.fly.ally")) { + return true; + } else { + return false; + } + + } + + @Override + public Boolean canflyinTruce() { + if (getPlayer().hasPermission("factions.fly.truce")) { + return true; + } else { + return false; + } + + } + + @Override + public Boolean canflyinNeutral() { + if (getPlayer().hasPermission("factions.fly.neutral")) { + return true; + } else { + return false; + } + + } + + + @Override public String getRolePrefix() { 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 06001322..47cf61bb 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java @@ -279,6 +279,9 @@ public enum TagReplacer { * @return if the raw line contains this enums variable */ public boolean contains(String toSearch) { + if (tag == null) { + return false; + } return toSearch.contains(tag); } 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 7c053913..c73ae8b8 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TextUtil.java @@ -239,4 +239,4 @@ public class TextUtil { } return ret; } -} +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 3f7cb90d..95e959f3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -858,7 +858,8 @@ see-chunk: # Interval between when particles are sent # setting to 10 makes it a constant heartbeat effect # setting to 5, makes it almost solid ( looks better imo but is more intensive) - interval: 10 + interval: 20 + ############################################################ # +------------------------------------------------------+ # diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c4521885..666fe791 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Factions -version: ${project.version}-SF-1.0.19 +version: ${project.version}-SF-1.0.21 crea main: com.massivecraft.factions.P authors: [Olof Larsson, Brett Flannigan, drtshock, ProSavage] softdepend: [PlayerVaults, PlaceholderAPI, MVdWPlaceholderAPI, PermissionsEx, Permissions, Essentials, EssentialsChat, HeroChat, iChat, LocalAreaChat, LWC, nChat, ChatManager, CAPI, AuthMe, Vault, Spout, WorldEdit, WorldGuard, AuthDB, CaptureThePoints, CombatTag, dynmap, FactionsTop]