From f14af99fe1bb506a4f7d28dd1ec3a50e6a02348a Mon Sep 17 00:00:00 2001 From: Esophose Date: Thu, 15 Nov 2018 04:13:33 -0700 Subject: [PATCH] Add '/pp toggle', create DataUpdater (WIP) --- .../esophose/playerparticles/DataUpdater.java | 78 +++++++++++++++++++ .../playerparticles/PlayerParticles.java | 75 +++--------------- .../command/ParticleCommandHandler.java | 1 + .../command/ToggleCommandModule.java | 44 +++++++++++ .../database/MySqlDatabaseConnector.java | 14 ++-- .../database/SqliteDatabaseConnector.java | 2 +- .../playerparticles/manager/DataManager.java | 71 ++++++++++++++--- .../playerparticles/manager/LangManager.java | 5 ++ .../manager/ParticleManager.java | 2 +- .../playerparticles/particles/PPlayer.java | 27 ++++++- .../particles/ParticleEffect.java | 9 ++- src/lang/default.lang | 5 ++ 12 files changed, 245 insertions(+), 88 deletions(-) create mode 100644 src/com/esophose/playerparticles/DataUpdater.java create mode 100644 src/com/esophose/playerparticles/command/ToggleCommandModule.java diff --git a/src/com/esophose/playerparticles/DataUpdater.java b/src/com/esophose/playerparticles/DataUpdater.java new file mode 100644 index 0000000..3e3966d --- /dev/null +++ b/src/com/esophose/playerparticles/DataUpdater.java @@ -0,0 +1,78 @@ +package com.esophose.playerparticles; + +import java.sql.Statement; + +/** + * This class handles updating the SQLite or MySQL data from older versions to the current version + * Everything is purposely done on the main thread to prevent the plugin from starting before all the data is updated + */ +public class DataUpdater { + + /** + * Checks to make sure all the correct database tables exist + * If they don't, create them + */ + protected static void tryCreateTables() { + PlayerParticles.getDBConnector().connect((connection) -> { + try (Statement createStatement = connection.createStatement()) { + createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_settings (player_uuid VARCHAR(36), particles_hidden TINYINT)"); + createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_particle (uuid VARCHAR(36), group_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(100), style VARCHAR(100), item_material VARCHAR(100), block_material VARCHAR(100), note SMALLINT, r SMALLINT, g SMALLINT, b SMALLINT, PRIMARY KEY(uuid))"); + createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_group (uuid VARCHAR(36), owner_uuid VARCHAR(36), name VARCHAR(100), PRIMARY KEY(uuid))"); + createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_fixed (owner_uuid VARCHAR(36), id SMALLINT, particle_uuid VARCHAR(36), world VARCHAR(100), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE, PRIMARY KEY(owner_uuid, id), FOREIGN KEY(particle_uuid) REFERENCES pp_particle(uuid) ON DELETE CASCADE)"); + createStatement.executeBatch(); + } + }); + } + + /** + * Updates the plugin data from one version of the plugin to the current version + * + * @param configVersion The old version of the plugin + * @param currentVersion The current version of the plugin + */ + protected static void updateData(double configVersion, double currentVersion) { + if (configVersion == currentVersion) return; + + PlayerParticles.getPlugin().getLogger().warning("Starting to update SQLite/MySQL data from " + (configVersion < 5.3 ? "a legacy version" : "v" + configVersion) + " to v" + PlayerParticles.getPlugin().getDescription().getVersion() + ", this may take a while..."); + + if (configVersion < 5.3) { + updateFrom_legacy_to_current(); + } else if (configVersion == 5.3) { + updateFrom_5_3_to_current(); + } + + PlayerParticles.getPlugin().getLogger().warning("Finished updating SQLite/MySQL data from " + (configVersion < 5.3 ? "a legacy version" : "v" + configVersion) + " to v" + PlayerParticles.getPlugin().getDescription().getVersion()); + } + + /** + * Updates the data from versions older than v5.2 + */ + private static void updateFrom_legacy_to_current() { + PlayerParticles.getDBConnector().connect((connection) -> { + try (Statement statement = connection.createStatement()) { + statement.addBatch("DROP TABLE IF EXISTS pp_users"); + statement.addBatch("DROP TABLE IF EXISTS pp_fixed"); + statement.addBatch("DROP TABLE IF EXISTS pp_data_item"); + statement.addBatch("DROP TABLE IF EXISTS pp_data_block"); + statement.addBatch("DROP TABLE IF EXISTS pp_data_color"); + statement.addBatch("DROP TABLE IF EXISTS pp_data_note"); + statement.executeBatch(); + } + }); + } + + /** + * Updates the data from v5.3 to current + * Note: v5.3 was never officially released + */ + private static void updateFrom_5_3_to_current() { + PlayerParticles.getDBConnector().connect((connection) -> { + // Create player settings table + try (Statement statement = connection.createStatement()) { + String updateQuery = "CREATE TABLE IF NOT EXISTS pp_settings (player_uuid VARCHAR(36), particles_hidden TINYINT)"; + statement.executeUpdate(updateQuery); + } + }); + } + +} diff --git a/src/com/esophose/playerparticles/PlayerParticles.java b/src/com/esophose/playerparticles/PlayerParticles.java index 18e6a26..6984617 100644 --- a/src/com/esophose/playerparticles/PlayerParticles.java +++ b/src/com/esophose/playerparticles/PlayerParticles.java @@ -9,9 +9,6 @@ package com.esophose.playerparticles; import java.io.File; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; @@ -54,14 +51,7 @@ public class PlayerParticles extends JavaPlugin { private static BukkitTask particleTask = null; /** - * Registers all the styles available by default - * Saves the default config if it doesn't exist - * Registers the tab completer and the event listeners - * Checks if the config needs to be updated to the new version - * Makes sure the database is accessible - * Starts the particle spawning task - * Registers the command executor - * Checks for any updates if checking is enabled in the config + * Executes essential tasks for starting up the plugin */ public void onEnable() { pluginInstance = Bukkit.getServer().getPluginManager().getPlugin("PlayerParticles"); @@ -75,8 +65,14 @@ public class PlayerParticles extends JavaPlugin { saveDefaultConfig(); double configVersion = PSetting.VERSION.getDouble(); - boolean updatePluginSettings = configVersion < Double.parseDouble(getDescription().getVersion()); + double currentVersion = Double.parseDouble(getDescription().getVersion()); + boolean updatePluginSettings = configVersion < currentVersion; if (updatePluginSettings) { + configureDatabase(PSetting.DATABASE_ENABLE.getBoolean()); + DataUpdater.updateData(configVersion, currentVersion); + databaseConnector.closeConnection(); + databaseConnector = null; + File configFile = new File(getDataFolder(), "config.yml"); if (configFile.exists()) { configFile.delete(); @@ -134,7 +130,8 @@ public class PlayerParticles extends JavaPlugin { } // This runs before the SettingManager is reloaded, the credentials will not be stored in memory for more than a few milliseconds - configureDatabase(PSetting.DATABASE_ENABLE.getBoolean()); + configureDatabase(PSetting.DATABASE_ENABLE.getBoolean()); + DataUpdater.tryCreateTables(); SettingManager.reload(); LangManager.reload(updatePluginSettings); @@ -165,10 +162,7 @@ public class PlayerParticles extends JavaPlugin { } /** - * Checks if database-enable is true in the config, if it is then uses MySql - * Gets the database connection information from the config and tries to connect to the server - * Removes old table from previous versions of the plugin - * Creates new tables if they don't exist + * Determines if we should use MySQL or SQLite based on the useMySql parameter and if we were able to connect successfully * * @param useMySql If we should use MySQL as the database type, if false, uses SQLite */ @@ -189,53 +183,6 @@ public class PlayerParticles extends JavaPlugin { configureDatabase(false); return; } - - databaseConnector.connect((connection) -> { - // Check if pp_users exists, if it does, this is an old database schema that needs to be deleted - try { // @formatter:off - try (Statement statement = connection.createStatement()) { - String pp_usersQuery; - if (useMySql) { - pp_usersQuery = "SHOW TABLES LIKE 'pp_users'"; - } else { - pp_usersQuery = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'pp_users'"; - } - ResultSet result = statement.executeQuery(pp_usersQuery); - if (result.next()) { - statement.close(); - - Statement dropStatement = connection.createStatement(); - dropStatement.addBatch("DROP TABLE IF EXISTS pp_users"); - dropStatement.addBatch("DROP TABLE IF EXISTS pp_fixed"); - dropStatement.addBatch("DROP TABLE IF EXISTS pp_data_item"); - dropStatement.addBatch("DROP TABLE IF EXISTS pp_data_block"); - dropStatement.addBatch("DROP TABLE IF EXISTS pp_data_color"); - dropStatement.addBatch("DROP TABLE IF EXISTS pp_data_note"); - dropStatement.executeBatch(); - getLogger().warning("Deleted old " + (useMySql ? "MySQL" : "SQLite") + " database schema, it was out of date."); - } - } - - // Try to create the tables just in case they don't exist - try (Statement createStatement = connection.createStatement()) { - createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_particle (uuid VARCHAR(36), group_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(100), style VARCHAR(100), item_material VARCHAR(100), block_material VARCHAR(100), note SMALLINT, r SMALLINT, g SMALLINT, b SMALLINT, PRIMARY KEY(uuid))"); - createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_group (uuid VARCHAR(36), owner_uuid VARCHAR(36), name VARCHAR(100), PRIMARY KEY(uuid))"); - createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_fixed (owner_uuid VARCHAR(36), id SMALLINT, particle_uuid VARCHAR(36), world VARCHAR(100), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE, PRIMARY KEY(owner_uuid, id), FOREIGN KEY(particle_uuid) REFERENCES pp_particle(uuid) ON DELETE CASCADE)"); - int[] results = createStatement.executeBatch(); - if (results[0] + results[1] + results[2] > 0) { - getLogger().warning("Updated " + (useMySql ? "MySQL" : "SQLite") + " database schema."); - } - } - } catch (SQLException ex) { - ex.printStackTrace(); - if (useMySql) { - getLogger().severe("Unable to connect to the MySQL database! Is your login information correct? Falling back to SQLite database instead."); - configureDatabase(false); - } else { - getLogger().severe("Unable to connect to the SQLite database! This is a critical error, the plugin will be unable to save any data."); - } - } - }); // @formatter:on } /** diff --git a/src/com/esophose/playerparticles/command/ParticleCommandHandler.java b/src/com/esophose/playerparticles/command/ParticleCommandHandler.java index 8ac2485..265a523 100644 --- a/src/com/esophose/playerparticles/command/ParticleCommandHandler.java +++ b/src/com/esophose/playerparticles/command/ParticleCommandHandler.java @@ -41,6 +41,7 @@ public class ParticleCommandHandler implements CommandExecutor, TabCompleter { commands.add(new ResetCommandModule()); commands.add(new StyleCommandModule()); commands.add(new StylesCommandModule()); + commands.add(new ToggleCommandModule()); commands.add(new VersionCommandModule()); commands.add(new WorldsCommandModule()); } diff --git a/src/com/esophose/playerparticles/command/ToggleCommandModule.java b/src/com/esophose/playerparticles/command/ToggleCommandModule.java new file mode 100644 index 0000000..9070d8c --- /dev/null +++ b/src/com/esophose/playerparticles/command/ToggleCommandModule.java @@ -0,0 +1,44 @@ +package com.esophose.playerparticles.command; + +import java.util.ArrayList; +import java.util.List; + +import com.esophose.playerparticles.manager.DataManager; +import com.esophose.playerparticles.manager.LangManager; +import com.esophose.playerparticles.manager.LangManager.Lang; +import com.esophose.playerparticles.particles.PPlayer; + +public class ToggleCommandModule implements CommandModule { + + public void onCommandExecute(PPlayer pplayer, String[] args) { + boolean canSee = pplayer.canSeeParticles(); + DataManager.updateSettingParticlesHidden(pplayer.getUniqueId(), canSee); + + if (canSee) { + LangManager.sendMessage(pplayer, Lang.TOGGLE_OFF); + } else { + LangManager.sendMessage(pplayer, Lang.TOGGLE_ON); + } + } + + public List onTabComplete(PPlayer pplayer, String[] args) { + return new ArrayList(); + } + + public String getName() { + return "toggle"; + } + + public Lang getDescription() { + return Lang.COMMAND_DESCRIPTION_TOGGLE; + } + + public String getArguments() { + return ""; + } + + public boolean requiresEffects() { + return false; + } + +} diff --git a/src/com/esophose/playerparticles/database/MySqlDatabaseConnector.java b/src/com/esophose/playerparticles/database/MySqlDatabaseConnector.java index db77d13..b2d1348 100644 --- a/src/com/esophose/playerparticles/database/MySqlDatabaseConnector.java +++ b/src/com/esophose/playerparticles/database/MySqlDatabaseConnector.java @@ -27,26 +27,26 @@ public class MySqlDatabaseConnector implements DatabaseConnector { config.setMaximumPoolSize(5); try { - hikari = new HikariDataSource(config); - initializedSuccessfully = true; + this.hikari = new HikariDataSource(config); + this.initializedSuccessfully = true; } catch (Exception ex) { - initializedSuccessfully = false; + this.initializedSuccessfully = false; } } public boolean isInitialized() { - return initializedSuccessfully; + return this.initializedSuccessfully; } public void closeConnection() { - hikari.close(); + this.hikari.close(); } public void connect(ConnectionCallback callback) { - try (Connection connection = hikari.getConnection()) { + try (Connection connection = this.hikari.getConnection()) { callback.execute(connection); } catch (SQLException ex) { - PlayerParticles.getPlugin().getLogger().severe("An error occurred retrieving a mysql database connection: " + ex.getMessage()); + PlayerParticles.getPlugin().getLogger().severe("An error occurred retrieving a MySQL database connection: " + ex.getMessage()); } } diff --git a/src/com/esophose/playerparticles/database/SqliteDatabaseConnector.java b/src/com/esophose/playerparticles/database/SqliteDatabaseConnector.java index 610e7bd..17f18d3 100644 --- a/src/com/esophose/playerparticles/database/SqliteDatabaseConnector.java +++ b/src/com/esophose/playerparticles/database/SqliteDatabaseConnector.java @@ -27,7 +27,7 @@ public class SqliteDatabaseConnector implements DatabaseConnector { try (Connection connection = DriverManager.getConnection(this.connectionString)) { callback.execute(connection); } catch (SQLException ex) { - PlayerParticles.getPlugin().getLogger().severe("An error occurred retrieving an sqlite database connection: " + ex.getMessage()); + PlayerParticles.getPlugin().getLogger().severe("An error occurred retrieving an SQLite database connection: " + ex.getMessage()); } } diff --git a/src/com/esophose/playerparticles/manager/DataManager.java b/src/com/esophose/playerparticles/manager/DataManager.java index b098099..79e0813 100644 --- a/src/com/esophose/playerparticles/manager/DataManager.java +++ b/src/com/esophose/playerparticles/manager/DataManager.java @@ -39,7 +39,7 @@ public class DataManager { * @return The PPlayer from cache */ public static PPlayer getPPlayer(UUID playerUUID) { - for (PPlayer pp : ParticleManager.particlePlayers) + for (PPlayer pp : ParticleManager.getPPlayers()) if (pp.getUniqueId().equals(playerUUID)) return pp; return null; } @@ -63,6 +63,28 @@ public class DataManager { List fixedParticles = new ArrayList(); PlayerParticles.getDBConnector().connect((connection) -> { + // Load settings + boolean particlesHidden = false; + String settingsQuery = "SELECT particles_hidden FROM pp_settings WHERE player_uuid = ?"; + try (PreparedStatement statement = connection.prepareStatement(settingsQuery)) { + statement.setString(1, playerUUID.toString()); + + ResultSet result = statement.executeQuery(); + if (result.next()) { + particlesHidden = result.getBoolean("particles_hidden"); + } else { + statement.close(); + + String updateQuery = "INSERT INTO pp_settings (player_uuid, particles_hidden) VALUES (?, ?)"; + try (PreparedStatement updateStatement = connection.prepareStatement(updateQuery)) { + updateStatement.setString(1, playerUUID.toString()); + updateStatement.setBoolean(2, false); + + updateStatement.executeUpdate(); + } + } + } + // Load particle groups String groupQuery = "SELECT * FROM pp_group g " + // @formatter:off "JOIN pp_particle p ON g.uuid = p.group_uuid " + @@ -150,12 +172,14 @@ public class DataManager { groups.add(activeGroup); } - final PPlayer loadedPPlayer = new PPlayer(playerUUID, groups, fixedParticles); + PPlayer loadedPPlayer = new PPlayer(playerUUID, groups, fixedParticles, particlesHidden); sync(() -> { - if (getPPlayer(playerUUID) == null) { // Make sure the PPlayer still isn't added, since this is async it's possible it got ran twice - ParticleManager.particlePlayers.add(loadedPPlayer); - callback.execute(loadedPPlayer); + synchronized (loadedPPlayer) { + if (getPPlayer(playerUUID) == null) { // Make sure the PPlayer still isn't added, since this is async it's possible it got ran twice + ParticleManager.getPPlayers().add(loadedPPlayer); // This will be fine now since loadedPPlayer is synchronized + callback.execute(loadedPPlayer); + } } }); }); @@ -181,6 +205,30 @@ public class DataManager { }); }); } + + /** + * Updates the particles_hidden setting in the database and for the PPlayer + * + * @param playerUUID + * @param particlesHidden + */ + public static void updateSettingParticlesHidden(UUID playerUUID, boolean particlesHidden) { + async(() -> { + PlayerParticles.getDBConnector().connect((connection) -> { + String updateQuery = "UPDATE pp_settings SET particles_hidden = ? WHERE player_uuid = ?"; + try (PreparedStatement updateStatement = connection.prepareStatement(updateQuery)) { + updateStatement.setBoolean(1, particlesHidden); + updateStatement.setString(2, playerUUID.toString()); + + updateStatement.executeUpdate(); + } + }); + }); + + getPPlayer(playerUUID, (pplayer) -> { + pplayer.setParticlesHidden(particlesHidden); + }); + } /** * Saves a ParticleGroup. If it already exists, update it. @@ -191,13 +239,13 @@ public class DataManager { public static void saveParticleGroup(UUID playerUUID, ParticleGroup group) { async(() -> { PlayerParticles.getDBConnector().connect((connection) -> { + String groupUUID = null; + String groupUUIDQuery = "SELECT uuid FROM pp_group WHERE owner_uuid = ? AND name = ?"; try (PreparedStatement statement = connection.prepareStatement(groupUUIDQuery)) { statement.setString(1, playerUUID.toString()); statement.setString(2, group.getName()); - String groupUUID = null; - ResultSet result = statement.executeQuery(); if (result.next()) { // Clear out particles from existing group groupUUID = result.getString("uuid"); @@ -218,10 +266,11 @@ public class DataManager { groupCreateStatement.executeUpdate(); } - - // Fill group with new particles - String createParticlesQuery = "INSERT INTO pp_particle (uuid, group_uuid, id, effect, style, item_material, block_material, note, r, g, b) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - PreparedStatement particlesStatement = connection.prepareStatement(createParticlesQuery); + } + + // Fill group with new particles + String createParticlesQuery = "INSERT INTO pp_particle (uuid, group_uuid, id, effect, style, item_material, block_material, note, r, g, b) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + try (PreparedStatement particlesStatement = connection.prepareStatement(createParticlesQuery)) { for (ParticlePair particle : group.getParticles()) { particlesStatement.setString(1, UUID.randomUUID().toString()); particlesStatement.setString(2, groupUUID); diff --git a/src/com/esophose/playerparticles/manager/LangManager.java b/src/com/esophose/playerparticles/manager/LangManager.java index aded2a3..ee1f878 100644 --- a/src/com/esophose/playerparticles/manager/LangManager.java +++ b/src/com/esophose/playerparticles/manager/LangManager.java @@ -44,6 +44,7 @@ public class LangManager { COMMAND_DESCRIPTION_RESET, COMMAND_DESCRIPTION_STYLE, COMMAND_DESCRIPTION_STYLES, + COMMAND_DESCRIPTION_TOGGLE, COMMAND_DESCRIPTION_VERSION, COMMAND_DESCRIPTION_WORLDS, @@ -108,6 +109,10 @@ public class LangManager { LIST_YOU_HAVE, LIST_OUTPUT, + // Toggle Command + TOGGLE_ON, + TOGGLE_OFF, + // Rainbow RAINBOW, diff --git a/src/com/esophose/playerparticles/manager/ParticleManager.java b/src/com/esophose/playerparticles/manager/ParticleManager.java index 43e68de..e86f614 100644 --- a/src/com/esophose/playerparticles/manager/ParticleManager.java +++ b/src/com/esophose/playerparticles/manager/ParticleManager.java @@ -30,7 +30,7 @@ public class ParticleManager extends BukkitRunnable implements Listener { /** * The list containing all the loaded PPlayer info */ - public static List particlePlayers = new ArrayList(); + private static List particlePlayers = new ArrayList(); /** * Rainbow particle effect hue and note color used for rainbow colorable effects diff --git a/src/com/esophose/playerparticles/particles/PPlayer.java b/src/com/esophose/playerparticles/particles/PPlayer.java index 812d999..4e3ad65 100644 --- a/src/com/esophose/playerparticles/particles/PPlayer.java +++ b/src/com/esophose/playerparticles/particles/PPlayer.java @@ -26,6 +26,11 @@ public class PPlayer { * A List of FixedParticleEffects this user has applied */ private List fixedParticles; + + /** + * If True, the player will not see any particles spawned by the plugin + */ + private boolean particlesHidden; /** * Constructs a new PPlayer @@ -33,11 +38,13 @@ public class PPlayer { * @param uuid The player UUID * @param particleGroups The ParticleGroups this PPlayer has * @param fixedParticles The FixedParticleEffects this PPlayer has + * @param particlesHidden If this player has all particles hidden from view */ - public PPlayer(UUID uuid, List particleGroups, List fixedParticles) { + public PPlayer(UUID uuid, List particleGroups, List fixedParticles, boolean particlesHidden) { this.playerUUID = uuid; this.particleGroups = particleGroups; this.fixedParticles = fixedParticles; + this.particlesHidden = particlesHidden; } /** @@ -57,6 +64,24 @@ public class PPlayer { public Player getPlayer() { return Bukkit.getPlayer(this.playerUUID); } + + /** + * Gets if the Player can see particles spawned by the plugin or not + * + * @return True if the player can see particles, otherwise false + */ + public boolean canSeeParticles() { + return !this.particlesHidden; + } + + /** + * Sets if the player can see particles spawned by the plugin or not + * + * @param hidden True if the player can see particles, otherwise false + */ + public void setParticlesHidden(boolean hidden) { + this.particlesHidden = hidden; + } /** * Get a List of ParticleGroups this user has saved diff --git a/src/com/esophose/playerparticles/particles/ParticleEffect.java b/src/com/esophose/playerparticles/particles/ParticleEffect.java index 5082478..31b99f4 100644 --- a/src/com/esophose/playerparticles/particles/ParticleEffect.java +++ b/src/com/esophose/playerparticles/particles/ParticleEffect.java @@ -9,7 +9,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.Material; @@ -18,6 +17,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; +import com.esophose.playerparticles.manager.ParticleManager; import com.esophose.playerparticles.manager.SettingManager.PSetting; import com.esophose.playerparticles.styles.api.PParticle; @@ -314,9 +314,12 @@ public enum ParticleEffect { List players = new ArrayList(); int range = !isFixedEffect ? PSetting.PARTICLE_RENDER_RANGE_PLAYER.getInt() : PSetting.PARTICLE_RENDER_RANGE_FIXED_EFFECT.getInt(); - for (Player p : Bukkit.getOnlinePlayers()) - if (p.getWorld().equals(center.getWorld()) && center.distanceSquared(p.getLocation()) <= range * range) + for (PPlayer pplayer : ParticleManager.getPPlayers()) { + Player p = pplayer.getPlayer(); + if (pplayer.canSeeParticles() && p.getWorld().equals(center.getWorld()) && center.distanceSquared(p.getLocation()) <= range * range) { players.add(p); + } + } return players; } diff --git a/src/lang/default.lang b/src/lang/default.lang index 05cafde..5d5df10 100644 --- a/src/lang/default.lang +++ b/src/lang/default.lang @@ -30,6 +30,7 @@ command-description-remove: 'Removes one of your active particles' command-description-reset: 'Removes all your active particles' command-description-style: '&cThis command has been removed, use &b/pp help &cto find new commands' command-description-styles: 'Display a list of styles you can use' +command-description-toggle: 'Toggles particle visibility on/off' command-description-version: 'Display the current version of the plugin and the author' command-description-worlds: 'Find out what worlds particles are disabled in' @@ -94,6 +95,10 @@ list-none: '&eYou do not have any active particles!' list-you-have: '&eYou have the following particles applied:' list-output: '&eID: &b{0} &eEffect: &b{1} &eStyle: &b{2} &eData: &b{3}' +# Toggle Command +toggle-on: '&eParticles have been toggled &aON&e!' +toggle-off: '&eParticles have been toggled &cOFF&e!' + # Rainbow rainbow: '&cr&6a&ei&an&bb&9o&dw'