Merge pull request #17 from Esophose/v6.4

v6.4
This commit is contained in:
Esophose 2019-04-28 15:00:31 -06:00 committed by GitHub
commit 2a474faa88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
63 changed files with 2143 additions and 2224 deletions

46
.gitignore vendored
View file

@ -21,14 +21,15 @@ $RECYCLE.BIN/
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Personal stuff
@ -38,16 +39,19 @@ Icon
/.settings
/doc
/target
/images
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
images/
/images
/build
/.idea
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
images/
*.iml

View file

@ -1,5 +1,18 @@
== UPDATING WILL DELETE YOUR CONFIG.YML ==
* Create a backup of your config.yml if you wish to import all your old settings!
=== v6.4 ===
+ Added support for Minecraft 1.14
+ Added 1.14 effects: 'campfire_cosy_smoke', 'campfire_signal_smoke', 'composter', 'falling_lava', 'falling_water', 'landing_lava', 'sneeze'
+ Added pages for effects, styles, and data in the GUI
+ Added setting 'gui-close-after-group-selected' to the config.yml
+ Added setting 'gui-presets-only' to the config.yml
+ Added Vietnamese translation file (vi_VN.lang)
+ Added support for vanish plugins as long as they use the Spigot hidden player API properly
* Fixed a whole bunch of errors in the fr_FR.lang file
* Fixed '/pp add' item data parameter being ignored
* Fixed an error with the GUI chat hook for creating a new group in 1.9
* Fixed players being able to load saved groups they no longer have permission for
* Fixed support for newline characters in GUI messages in some cases
=== v6.3 ===
+ Added the ability to remove particles by id/effect/style using '/pp remove <id>|<effect>|<style>'
+ Added new styles 'popper', 'pulse', 'twins', 'whirl', and 'whirlwind'

124
pom.xml
View file

@ -2,10 +2,10 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.esophose.playerparticles</groupId>
<artifactId>PlayerParticles</artifactId>
<version>6.3</version>
<version>6.4</version>
<name>PlayerParticles</name>
<url>https://github.com/Esophose/PlayerParticles</url>
<description>Display particles around your player using customized styles and data!</description>
<description>Display particles around your player and blocks using customized styles and data!</description>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
@ -31,7 +31,7 @@
<version>3.1.0</version>
<executions>
<execution>
<id>1.13</id>
<id>shaded</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
@ -42,6 +42,7 @@
<include>com.zaxxer:HikariCP</include>
<include>org.slf4j:slf4j-api</include>
<include>org.slf4j:slf4j-nop</include>
<include>com.googlecode.json-simple:json-simple</include>
</includes>
</artifactSet>
<filters>
@ -54,115 +55,7 @@
</excludes>
</filter>
</filters>
<outputFile>C:\Users\Esophose\Desktop\Spigot Dev Servers\1.13\plugins\update\PlayerParticles v${project.version}.jar</outputFile>
</configuration>
</execution>
<execution>
<id>1.12</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.zaxxer:HikariCP</include>
<include>org.slf4j:slf4j-api</include>
<include>org.slf4j:slf4j-nop</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<outputFile>C:\Users\Esophose\Desktop\Spigot Dev Servers\1.12\plugins\update\PlayerParticles v${project.version}.jar</outputFile>
</configuration>
</execution>
<execution>
<id>1.11</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.zaxxer:HikariCP</include>
<include>org.slf4j:slf4j-api</include>
<include>org.slf4j:slf4j-nop</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<outputFile>C:\Users\Esophose\Desktop\Spigot Dev Servers\1.11\plugins\update\PlayerParticles v${project.version}.jar</outputFile>
</configuration>
</execution>
<execution>
<id>1.10</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.zaxxer:HikariCP</include>
<include>org.slf4j:slf4j-api</include>
<include>org.slf4j:slf4j-nop</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<outputFile>C:\Users\Esophose\Desktop\Spigot Dev Servers\1.10\plugins\update\PlayerParticles v${project.version}.jar</outputFile>
</configuration>
</execution>
<execution>
<id>1.9</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.zaxxer:HikariCP</include>
<include>org.slf4j:slf4j-api</include>
<include>org.slf4j:slf4j-nop</include>
</includes>
</artifactSet>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<outputFile>C:\Users\Esophose\Desktop\Spigot Dev Servers\1.9\plugins\update\PlayerParticles v${project.version}.jar</outputFile>
<outputFile>./target/PlayerParticles_v${project.version}.jar</outputFile>
</configuration>
</execution>
</executions>
@ -200,10 +93,15 @@
<artifactId>sqlite-jdbc</artifactId>
<version>3.23.1</version>
</dependency>
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.13.2-R0.1-SNAPSHOT</version>
<version>1.14-R0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View file

@ -1,10 +1,14 @@
/*
* TODO: v6.4+
* + Add new style(s) 'wings_<type>', multiple new wing types: fairy, demon
* TODO: v6.4
* + Add ability to create/manage fixed effects from the GUI
* * Convert fixed effect ids into names
* + Add command '/pp fixed teleport <id>' that requires the permission playerparticles.fixed.teleport
* + Add named colors to the color data
* * Clean up duplicated command parsing
*/
/*
* TODO: v6.5
* + Add effect/style name customization through config files
* + Add effect/style settings folder that lets you disable effects/style and edit style properties
*/
@ -34,6 +38,7 @@ import com.esophose.playerparticles.manager.SettingManager;
import com.esophose.playerparticles.manager.SettingManager.PSetting;
import com.esophose.playerparticles.particles.PPlayerMovementListener;
import com.esophose.playerparticles.styles.DefaultStyles;
import com.esophose.playerparticles.updater.DataUpdater;
import com.esophose.playerparticles.updater.PluginUpdateListener;
import com.esophose.playerparticles.updater.Updater;
import com.esophose.playerparticles.util.Metrics;
@ -65,7 +70,7 @@ public class PlayerParticles extends JavaPlugin {
* Executes essential tasks for starting up the plugin
*/
public void onEnable() {
pluginInstance = (PlayerParticles)Bukkit.getServer().getPluginManager().getPlugin("PlayerParticles");
pluginInstance = (PlayerParticles) Bukkit.getServer().getPluginManager().getPlugin("PlayerParticles");
this.registerCommands();
@ -76,23 +81,23 @@ public class PlayerParticles extends JavaPlugin {
pm.registerEvents(new PPlayerMovementListener(), this);
pm.registerEvents(new PlayerChatHook(), this);
saveDefaultConfig();
this.saveDefaultConfig();
double configVersion = PSetting.VERSION.getDouble();
double currentVersion = Double.parseDouble(getDescription().getVersion());
double currentVersion = Double.parseDouble(this.getDescription().getVersion());
boolean updatePluginSettings = configVersion < currentVersion;
if (updatePluginSettings) {
configureDatabase(PSetting.DATABASE_ENABLE.getBoolean());
this.configureDatabase(PSetting.DATABASE_ENABLE.getBoolean());
DataUpdater.updateData(configVersion, currentVersion);
databaseConnector.closeConnection();
databaseConnector = null;
this.databaseConnector.closeConnection();
this.databaseConnector = null;
File configFile = new File(getDataFolder(), "config.yml");
File configFile = new File(this.getDataFolder(), "config.yml");
if (configFile.exists()) {
configFile.delete();
}
saveDefaultConfig();
reloadConfig();
getLogger().warning("The config.yml has been updated to v" + getDescription().getVersion() + "!");
this.saveDefaultConfig();
this.reloadConfig();
this.getLogger().warning("The config.yml has been updated to v" + this.getDescription().getVersion() + "!");
}
if (PSetting.CHECK_UPDATES.getBoolean()) {
@ -123,7 +128,7 @@ public class PlayerParticles extends JavaPlugin {
* Close all users with an open PlayerParticles GUI
*/
public void onDisable() {
databaseConnector.closeConnection();
this.databaseConnector.closeConnection();
GuiHandler.forceCloseAllOpenGUIs();
}
@ -150,18 +155,18 @@ public class PlayerParticles extends JavaPlugin {
this.reloadConfig();
// If not null, plugin is already loaded
if (particleTask != null) {
particleTask.cancel();
particleTask = null;
databaseConnector.closeConnection();
databaseConnector = null;
if (this.particleTask != null) {
this.particleTask.cancel();
this.particleTask = null;
this.databaseConnector.closeConnection();
this.databaseConnector = null;
GuiHandler.forceCloseAllOpenGUIs();
} else {
DefaultStyles.registerStyles(); // Only ever load styles once
}
// 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());
this.configureDatabase(PSetting.DATABASE_ENABLE.getBoolean());
DataUpdater.tryCreateTables();
SettingManager.reload();
@ -172,7 +177,7 @@ public class PlayerParticles extends JavaPlugin {
PlayerChatHook.setup();
ParticleManager.refreshData();
startParticleTask();
this.startParticleTask();
}
/**
@ -190,7 +195,7 @@ public class PlayerParticles extends JavaPlugin {
* @return The DatabaseConnector
*/
public DatabaseConnector getDBConnector() {
return databaseConnector;
return this.databaseConnector;
}
/**
@ -210,20 +215,19 @@ public class PlayerParticles extends JavaPlugin {
*/
private void configureDatabase(boolean useMySql) {
if (useMySql) {
databaseConnector = new MySqlDatabaseConnector();
this.databaseConnector = new MySqlDatabaseConnector();
} else {
try {
Class.forName("org.sqlite.JDBC"); // This is required to put here for Spigot 1.9 and 1.10 for some reason
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
databaseConnector = new SqliteDatabaseConnector(this.getDataFolder().getAbsolutePath());
this.databaseConnector = new SqliteDatabaseConnector(this.getDataFolder().getAbsolutePath());
}
if (!databaseConnector.isInitialized()) {
getLogger().severe("Unable to connect to the MySQL database! Is your login information correct? Falling back to SQLite database instead.");
configureDatabase(false);
return;
if (!this.databaseConnector.isInitialized()) {
this.getLogger().severe("Unable to connect to the MySQL database! Is your login information correct? Falling back to SQLite database instead.");
this.configureDatabase(false);
}
}
@ -232,13 +236,10 @@ public class PlayerParticles extends JavaPlugin {
* Run in the synchronous task so it starts after all plugins have loaded, including extensions
*/
private void startParticleTask() {
final Plugin playerParticles = this;
new BukkitRunnable() {
public void run() {
long ticks = PSetting.TICKS_PER_PARTICLE.getLong();
particleTask = new ParticleManager().runTaskTimer(playerParticles, 5, ticks);
}
}.runTaskLater(playerParticles, 1);
Bukkit.getScheduler().runTaskLater(pluginInstance, () -> {
long ticks = PSetting.TICKS_PER_PARTICLE.getLong();
this.particleTask = new ParticleManager().runTaskTimer(pluginInstance, 5, ticks);
}, 1);
}
}

View file

@ -67,7 +67,7 @@ public class AddCommandModule implements CommandModule {
} else if (args[2].equalsIgnoreCase("random")) {
noteColorData = new NoteColor(98);
} else {
int note = -1;
int note;
try {
note = Integer.parseInt(args[2]);
} catch (Exception e) {
@ -88,9 +88,7 @@ public class AddCommandModule implements CommandModule {
} else if (args[2].equalsIgnoreCase("random")) {
colorData = new OrdinaryColor(998, 998, 998);
} else {
int r = -1;
int g = -1;
int b = -1;
int r, g, b;
try {
r = Integer.parseInt(args[2]);
@ -131,7 +129,7 @@ public class AddCommandModule implements CommandModule {
}
ParticleGroup group = pplayer.getActiveParticleGroup();
ParticlePair newParticle = new ParticlePair(pplayer.getUniqueId(), pplayer.getNextActiveParticleId(), effect, style, blockData, blockData, colorData, noteColorData);
ParticlePair newParticle = new ParticlePair(pplayer.getUniqueId(), pplayer.getNextActiveParticleId(), effect, style, itemData, blockData, colorData, noteColorData);
group.getParticles().add(newParticle);
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
@ -144,18 +142,18 @@ public class AddCommandModule implements CommandModule {
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
Player p = pplayer.getPlayer();
List<String> matches = new ArrayList<String>();
List<String> matches = new ArrayList<>();
if (args.length <= 1) { // Effect name
if (args.length == 0) matches = PermissionManager.getEffectNamesUserHasPermissionFor(p);
else StringUtil.copyPartialMatches(args[0], PermissionManager.getEffectNamesUserHasPermissionFor(p), matches);
} else if (args.length == 2) { // Style name
StringUtil.copyPartialMatches(args[1], PermissionManager.getStyleNamesUserHasPermissionFor(p), matches);
} else if (args.length >= 3) { // Data
} else { // Data
ParticleEffect effect = ParticleEffect.fromName(args[0]);
if (effect != null) {
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
List<String> possibleValues = new ArrayList<String>();
List<String> possibleValues = new ArrayList<>();
if (effect == ParticleEffect.NOTE) { // Note data
if (args.length == 3) {
possibleValues.add("<0-24>");
@ -178,9 +176,9 @@ public class AddCommandModule implements CommandModule {
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
} else if (args.length == 3 && effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) { // Block material
matches = StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllBlockMaterials(), matches);
StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllBlockMaterials(), matches);
} else if (effect == ParticleEffect.ITEM) { // Item material
matches = StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllItemMaterials(), matches);
StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllItemMaterials(), matches);
}
}
}

View file

@ -14,7 +14,7 @@ public interface CommandModule {
* @param pplayer The PPlayer who executed this command
* @param args The arguments to this command
*/
public void onCommandExecute(PPlayer pplayer, String[] args);
void onCommandExecute(PPlayer pplayer, String[] args);
/**
* Called when a player tries to tab complete this command
@ -23,35 +23,35 @@ public interface CommandModule {
* @param args Arguments typed so far
* @return A list of possible argument values
*/
public List<String> onTabComplete(PPlayer pplayer, String[] args);
List<String> onTabComplete(PPlayer pplayer, String[] args);
/**
* Gets the name of this command
*
* @return The name of this command
*/
public String getName();
String getName();
/**
* Gets the Lang description of this command
*
* @return The description of this command
*/
public Lang getDescription();
Lang getDescription();
/**
* Gets any arguments this command has
*
* @return The arguments this command has
*/
public String getArguments();
String getArguments();
/**
* True if this command requires the player to have any effects
*
* @return If the player must have effects to use this command
*/
public boolean requiresEffects();
boolean requiresEffects();
/**
* Displays a command's usage to the player
@ -59,7 +59,7 @@ public interface CommandModule {
* @param pplayer The PPlayer to display the command usage to
* @param command The command to display usage for
*/
public static void printUsage(PPlayer pplayer, CommandModule command) {
static void printUsage(PPlayer pplayer, CommandModule command) {
LangManager.sendMessage(pplayer, Lang.COMMAND_DESCRIPTIONS_USAGE, command.getName(), command.getArguments());
}
@ -69,7 +69,7 @@ public interface CommandModule {
* @param pplayer The PPlayer to display the command usage to
* @param command The command to display usage for
*/
public static void printUsageWithDescription(PPlayer pplayer, CommandModule command) {
static void printUsageWithDescription(PPlayer pplayer, CommandModule command) {
if (command.getArguments().length() == 0) {
LangManager.sendSimpleMessage(pplayer, Lang.COMMAND_DESCRIPTIONS_HELP_1, command.getName(), LangManager.getText(command.getDescription()));
} else {

View file

@ -12,7 +12,7 @@ public interface CommandModuleSecondary {
* @param sender The CommandSender who executed this command
* @param args The arguments to this command
*/
public void onCommandExecute(CommandSender sender, String[] args);
void onCommandExecute(CommandSender sender, String[] args);
/**
* Called when a player tries to tab complete this command
@ -21,6 +21,6 @@ public interface CommandModuleSecondary {
* @param args Arguments typed so far
* @return A list of possible argument values
*/
public List<String> onTabComplete(CommandSender sender, String[] args);
List<String> onTabComplete(CommandSender sender, String[] args);
}

View file

@ -43,7 +43,7 @@ public class DataCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
List<String> matches = new ArrayList<String>();
List<String> matches = new ArrayList<>();
if (args.length <= 1) {
if (args.length == 0) matches = PermissionManager.getEffectNamesUserHasPermissionFor(pplayer.getPlayer());
else StringUtil.copyPartialMatches(args[0], PermissionManager.getEffectNamesUserHasPermissionFor(pplayer.getPlayer()), matches);

View file

@ -29,7 +29,7 @@ public class EditCommandModule implements CommandModule {
return;
}
int id = -1;
int id;
try {
id = Integer.parseInt(args[0]);
} catch (Exception e) {
@ -48,19 +48,17 @@ public class EditCommandModule implements CommandModule {
}
String[] cmdArgs = new String[args.length - 2];
for (int i = 2; i < args.length; i++) {
cmdArgs[i - 2] = args[i];
}
System.arraycopy(args, 2, cmdArgs, 0, args.length - 2);
switch (args[1].toLowerCase()) {
case "effect":
editEffect(pplayer, id, cmdArgs);
this.editEffect(pplayer, id, cmdArgs);
break;
case "style":
editStyle(pplayer, id, cmdArgs);
this.editStyle(pplayer, id, cmdArgs);
break;
case "data":
editData(pplayer, id, cmdArgs);
this.editData(pplayer, id, cmdArgs);
break;
default:
LangManager.sendMessage(pplayer, Lang.EDIT_INVALID_PROPERTY, args[1]);
@ -148,7 +146,7 @@ public class EditCommandModule implements CommandModule {
} else if (args[0].equalsIgnoreCase("random")) {
noteColorData = new NoteColor(98);
} else {
int note = -1;
int note;
try {
note = Integer.parseInt(args[0]);
} catch (Exception e) {
@ -169,9 +167,7 @@ public class EditCommandModule implements CommandModule {
} else if (args[0].equalsIgnoreCase("random")) {
colorData = new OrdinaryColor(998, 998, 998);
} else {
int r = -1;
int g = -1;
int b = -1;
int r, g, b;
try {
r = Integer.parseInt(args[0]);
@ -229,8 +225,8 @@ public class EditCommandModule implements CommandModule {
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
Player p = pplayer.getPlayer();
List<String> matches = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
List<String> matches = new ArrayList<>();
List<String> ids = new ArrayList<>();
for (ParticlePair particles : pplayer.getActiveParticles())
ids.add(String.valueOf(particles.getId()));
@ -244,11 +240,11 @@ public class EditCommandModule implements CommandModule {
int id = -1;
try {
id = Integer.parseInt(args[0]);
} catch (Exception e) { }
} catch (Exception ignored) { }
if (pplayer.getActiveParticle(id) != null) {
if (args.length == 2) {
List<String> possibleValues = new ArrayList<String>();
List<String> possibleValues = new ArrayList<>();
possibleValues.add("effect");
possibleValues.add("style");
possibleValues.add("data");
@ -266,7 +262,7 @@ public class EditCommandModule implements CommandModule {
case "data":
ParticleEffect effect = pplayer.getActiveParticle(id).getEffect();
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
List<String> possibleValues = new ArrayList<String>();
List<String> possibleValues = new ArrayList<>();
if (effect == ParticleEffect.NOTE) { // Note data
if (args.length == 3) {
possibleValues.add("<0-24>");
@ -289,9 +285,9 @@ public class EditCommandModule implements CommandModule {
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
} else if (args.length == 3 && effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) { // Block material
matches = StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllBlockMaterials(), matches);
StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllBlockMaterials(), matches);
} else if (effect == ParticleEffect.ITEM) { // Item material
matches = StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllItemMaterials(), matches);
StringUtil.copyPartialMatches(args[2], ParticleUtils.getAllItemMaterials(), matches);
}
}
break;

View file

@ -21,20 +21,20 @@ public class EffectsCommandModule implements CommandModule {
return;
}
String toSend = "";
StringBuilder toSend = new StringBuilder();
for (String name : effectList) {
toSend += name + ", ";
toSend.append(name).append(", ");
}
if (toSend.endsWith(", ")) {
toSend = toSend.substring(0, toSend.length() - 2);
if (toSend.toString().endsWith(", ")) {
toSend = new StringBuilder(toSend.substring(0, toSend.length() - 2));
}
LangManager.sendMessage(pplayer, Lang.EFFECT_LIST, toSend);
LangManager.sendMessage(pplayer, Lang.EFFECT_LIST, toSend.toString());
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -52,28 +52,26 @@ public class FixedCommandModule implements CommandModule {
String cmd = args[0];
String[] cmdArgs = new String[args.length - 1];
for (int i = 1; i < args.length; i++) {
cmdArgs[i - 1] = args[i];
}
System.arraycopy(args, 1, cmdArgs, 0, args.length - 1);
switch (cmd.toLowerCase()) {
case "create":
handleCreate(pplayer, p, cmdArgs);
this.handleCreate(pplayer, p, cmdArgs);
return;
case "edit":
handleEdit(pplayer, p, cmdArgs);
this.handleEdit(pplayer, p, cmdArgs);
return;
case "remove":
handleRemove(pplayer, p, cmdArgs);
this.handleRemove(pplayer, p, cmdArgs);
return;
case "list":
handleList(pplayer, p, cmdArgs);
this.handleList(pplayer, p, cmdArgs);
return;
case "info":
handleInfo(pplayer, p, cmdArgs);
this.handleInfo(pplayer, p, cmdArgs);
return;
case "clear":
handleClear(pplayer, p, cmdArgs);
this.handleClear(pplayer, p, cmdArgs);
return;
default:
LangManager.sendMessage(pplayer, Lang.FIXED_INVALID_COMMAND);
@ -85,10 +83,10 @@ public class FixedCommandModule implements CommandModule {
LangManager.sendMessage(pplayer, Lang.COMMAND_DESCRIPTION_FIXED_CLEAR);
}
}
/**
* Handles the command /pp fixed create
*
*
* @param pplayer The PPlayer
* @param p The Player
* @param args The command arguments
@ -105,29 +103,28 @@ public class FixedCommandModule implements CommandModule {
return;
}
double xPos = -1, yPos = -1, zPos = -1;
double xPos, yPos, zPos;
if (args[0].equalsIgnoreCase("looking")) {
Block targetBlock = p.getTargetBlock((Set<Material>)null, 8);
Block targetBlock = p.getTargetBlock((Set<Material>) null, 8);
int maxDistanceSqrd = 6 * 6;
if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) {
LangManager.sendMessage(pplayer, Lang.FIXED_CREATE_LOOKING_TOO_FAR);
return;
}
Location blockLocation = targetBlock.getLocation().clone().add(0.5, 0.5, 0.5); // Center of block
xPos = blockLocation.getX();
yPos = blockLocation.getY();
zPos = blockLocation.getZ();
// Pad the args with the coordinates so we don't have to adjust all the indices
String[] paddedArgs = new String[args.length + 2];
paddedArgs[0] = String.valueOf(xPos);
paddedArgs[1] = String.valueOf(yPos);
paddedArgs[2] = String.valueOf(zPos);
for (int i = 1; i < args.length; i++)
paddedArgs[i + 2] = args[i];
System.arraycopy(args, 1, paddedArgs, 3, args.length - 1);
args = paddedArgs;
} else {
try {
@ -200,7 +197,7 @@ public class FixedCommandModule implements CommandModule {
} else if (args[5].equalsIgnoreCase("random")) {
noteColorData = new NoteColor(98);
} else {
int note = -1;
int note;
try {
note = Integer.parseInt(args[5]);
} catch (Exception e) {
@ -221,9 +218,7 @@ public class FixedCommandModule implements CommandModule {
} else if (args[5].equalsIgnoreCase("random")) {
colorData = new OrdinaryColor(998, 998, 998);
} else {
int r = -1;
int g = -1;
int b = -1;
int r, g, b;
try {
r = Integer.parseInt(args[5]);
@ -244,7 +239,7 @@ public class FixedCommandModule implements CommandModule {
}
} else if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) {
Material material = null;
Material material;
try {
material = ParticleUtils.closestMatch(args[5]);
if (material == null) material = Material.matchMaterial(args[5]);
@ -256,7 +251,7 @@ public class FixedCommandModule implements CommandModule {
blockData = material;
} else if (effect == ParticleEffect.ITEM) {
Material material = null;
Material material;
try {
material = ParticleUtils.closestMatch(args[5]);
if (material == null) material = Material.matchMaterial(args[5]);
@ -278,10 +273,10 @@ public class FixedCommandModule implements CommandModule {
LangManager.sendMessage(pplayer, Lang.FIXED_CREATE_SUCCESS);
DataManager.saveFixedEffect(fixedEffect);
}
/**
* Handles the command /pp fixed edit
*
*
* @param pplayer The PPlayer
* @param p The Player
* @param args The command arguments
@ -291,202 +286,207 @@ public class FixedCommandModule implements CommandModule {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_MISSING_ARGS);
return;
}
int id = -1;
int id;
try {
id = Integer.parseInt(args[0]);
} catch (Exception ex) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_INVALID_ID);
return;
}
FixedParticleEffect fixedEffect = pplayer.getFixedEffectById(id);
if (fixedEffect == null) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_INVALID_ID);
return;
}
String editType = args[1].toLowerCase();
if (editType.equals("location")) {
double xPos = -1, yPos = -1, zPos = -1;
if (args[2].equalsIgnoreCase("looking")) {
Block targetBlock = p.getTargetBlock((Set<Material>)null, 8);
int maxDistanceSqrd = 6 * 6;
if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_LOOKING_TOO_FAR);
switch (editType) {
case "location":
double xPos, yPos, zPos;
if (args[2].equalsIgnoreCase("looking")) {
Block targetBlock = p.getTargetBlock((Set<Material>) null, 8);
int maxDistanceSqrd = 6 * 6;
if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_LOOKING_TOO_FAR);
return;
}
Location blockLocation = targetBlock.getLocation().clone().add(0.5, 0.5, 0.5); // Center of block
xPos = blockLocation.getX();
yPos = blockLocation.getY();
zPos = blockLocation.getZ();
} else {
try {
if (args[2].startsWith("~")) {
if (args[2].equals("~")) xPos = p.getLocation().getX();
else xPos = p.getLocation().getX() + Double.parseDouble(args[2].substring(1));
} else {
xPos = Double.parseDouble(args[2]);
}
if (args[3].startsWith("~")) {
if (args[3].equals("~")) yPos = p.getLocation().getY() + 1;
else yPos = p.getLocation().getY() + 1 + Double.parseDouble(args[3].substring(1));
} else {
yPos = Double.parseDouble(args[3]);
}
if (args[4].startsWith("~")) {
if (args[4].equals("~")) zPos = p.getLocation().getZ();
else zPos = p.getLocation().getZ() + Double.parseDouble(args[4].substring(1));
} else {
zPos = Double.parseDouble(args[4]);
}
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_INVALID_COORDS);
return;
}
}
double distanceFromEffect = p.getLocation().distance(new Location(p.getWorld(), xPos, yPos, zPos));
int maxCreationDistance = PermissionManager.getMaxFixedEffectCreationDistance();
if (maxCreationDistance != 0 && distanceFromEffect > maxCreationDistance) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_OUT_OF_RANGE, maxCreationDistance);
return;
}
Location blockLocation = targetBlock.getLocation().clone().add(0.5, 0.5, 0.5); // Center of block
xPos = blockLocation.getX();
yPos = blockLocation.getY();
zPos = blockLocation.getZ();
} else {
try {
if (args[2].startsWith("~")) {
if (args[2].equals("~")) xPos = p.getLocation().getX();
else xPos = p.getLocation().getX() + Double.parseDouble(args[2].substring(1));
} else {
xPos = Double.parseDouble(args[2]);
}
if (args[3].startsWith("~")) {
if (args[3].equals("~")) yPos = p.getLocation().getY() + 1;
else yPos = p.getLocation().getY() + 1 + Double.parseDouble(args[3].substring(1));
} else {
yPos = Double.parseDouble(args[3]);
}
if (args[4].startsWith("~")) {
if (args[4].equals("~")) zPos = p.getLocation().getZ();
else zPos = p.getLocation().getZ() + Double.parseDouble(args[4].substring(1));
} else {
zPos = Double.parseDouble(args[4]);
}
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_INVALID_COORDS);
fixedEffect.setCoordinates(xPos, yPos, zPos);
break;
case "effect": {
ParticleEffect effect = ParticleEffect.fromName(args[2]);
if (effect == null) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_EFFECT_INVALID, args[2]);
return;
} else if (!PermissionManager.hasEffectPermission(pplayer.getPlayer(), effect)) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_EFFECT_NO_PERMISSION, effect.getName());
return;
}
}
double distanceFromEffect = p.getLocation().distance(new Location(p.getWorld(), xPos, yPos, zPos));
int maxCreationDistance = PermissionManager.getMaxFixedEffectCreationDistance();
if (maxCreationDistance != 0 && distanceFromEffect > maxCreationDistance) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_OUT_OF_RANGE, maxCreationDistance);
return;
fixedEffect.getParticlePair().setEffect(effect);
break;
}
fixedEffect.setCoordinates(xPos, yPos, zPos);
} else if (editType.equals("effect")) {
ParticleEffect effect = ParticleEffect.fromName(args[2]);
if (effect == null) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_EFFECT_INVALID, args[2]);
return;
} else if (!PermissionManager.hasEffectPermission(pplayer.getPlayer(), effect)) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_EFFECT_NO_PERMISSION, effect.getName());
return;
}
fixedEffect.getParticlePair().setEffect(effect);
} else if (editType.equals("style")) {
ParticleStyle style = ParticleStyle.fromName(args[2]);
if (style == null) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_STYLE_INVALID, args[2]);
return;
} else if (!PermissionManager.hasStylePermission(pplayer.getPlayer(), style)) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_STYLE_NO_PERMISSION, style.getName());
return;
} else if (!style.canBeFixed()) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_STYLE_NON_FIXABLE, style.getName());
return;
}
fixedEffect.getParticlePair().setStyle(style);
} else if (editType.equals("data")) {
Material itemData = null;
Material blockData = null;
OrdinaryColor colorData = null;
NoteColor noteColorData = null;
ParticleEffect effect = fixedEffect.getParticlePair().getEffect();
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
if (effect == ParticleEffect.NOTE) {
if (args[2].equalsIgnoreCase("rainbow")) {
noteColorData = new NoteColor(99);
} else if (args[2].equalsIgnoreCase("random")) {
noteColorData = new NoteColor(98);
case "style":
ParticleStyle style = ParticleStyle.fromName(args[2]);
if (style == null) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_STYLE_INVALID, args[2]);
return;
} else if (!PermissionManager.hasStylePermission(pplayer.getPlayer(), style)) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_STYLE_NO_PERMISSION, style.getName());
return;
} else if (!style.canBeFixed()) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_STYLE_NON_FIXABLE, style.getName());
return;
}
fixedEffect.getParticlePair().setStyle(style);
break;
case "data": {
Material itemData = null;
Material blockData = null;
OrdinaryColor colorData = null;
NoteColor noteColorData = null;
ParticleEffect effect = fixedEffect.getParticlePair().getEffect();
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
if (effect == ParticleEffect.NOTE) {
if (args[2].equalsIgnoreCase("rainbow")) {
noteColorData = new NoteColor(99);
} else if (args[2].equalsIgnoreCase("random")) {
noteColorData = new NoteColor(98);
} else {
int note;
try {
note = Integer.parseInt(args[2]);
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
if (note < 0 || note > 24) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
noteColorData = new NoteColor(note);
}
} else {
int note = -1;
if (args[2].equalsIgnoreCase("rainbow")) {
colorData = new OrdinaryColor(999, 999, 999);
} else if (args[2].equalsIgnoreCase("random")) {
colorData = new OrdinaryColor(998, 998, 998);
} else {
int r, g, b;
try {
r = Integer.parseInt(args[2]);
g = Integer.parseInt(args[3]);
b = Integer.parseInt(args[4]);
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
colorData = new OrdinaryColor(r, g, b);
}
}
} else if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) {
Material material;
try {
note = Integer.parseInt(args[2]);
material = ParticleUtils.closestMatch(args[2]);
if (material == null) material = Material.matchMaterial(args[2]);
if (material == null || !material.isBlock()) throw new Exception();
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
if (note < 0 || note > 24) {
blockData = material;
} else if (effect == ParticleEffect.ITEM) {
Material material;
try {
material = ParticleUtils.closestMatch(args[2]);
if (material == null) material = Material.matchMaterial(args[2]);
if (material == null || material.isBlock()) throw new Exception();
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
noteColorData = new NoteColor(note);
itemData = material;
}
} else {
if (args[2].equalsIgnoreCase("rainbow")) {
colorData = new OrdinaryColor(999, 999, 999);
} else if (args[2].equalsIgnoreCase("random")) {
colorData = new OrdinaryColor(998, 998, 998);
} else {
int r = -1;
int g = -1;
int b = -1;
try {
r = Integer.parseInt(args[2]);
g = Integer.parseInt(args[3]);
b = Integer.parseInt(args[4]);
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
colorData = new OrdinaryColor(r, g, b);
}
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_NONE);
return;
}
} else if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) {
Material material = null;
try {
material = ParticleUtils.closestMatch(args[2]);
if (material == null) material = Material.matchMaterial(args[2]);
if (material == null || !material.isBlock()) throw new Exception();
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
blockData = material;
} else if (effect == ParticleEffect.ITEM) {
Material material = null;
try {
material = ParticleUtils.closestMatch(args[2]);
if (material == null) material = Material.matchMaterial(args[2]);
if (material == null || material.isBlock()) throw new Exception();
} catch (Exception e) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_ERROR);
return;
}
itemData = material;
}
} else {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_DATA_NONE);
return;
fixedEffect.getParticlePair().setColor(colorData);
fixedEffect.getParticlePair().setNoteColor(noteColorData);
fixedEffect.getParticlePair().setItemMaterial(itemData);
fixedEffect.getParticlePair().setBlockMaterial(blockData);
break;
}
fixedEffect.getParticlePair().setColor(colorData);
fixedEffect.getParticlePair().setNoteColor(noteColorData);
fixedEffect.getParticlePair().setItemMaterial(itemData);
fixedEffect.getParticlePair().setBlockMaterial(blockData);
} else {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_INVALID_PROPERTY);
return;
default:
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_INVALID_PROPERTY);
return;
}
DataManager.updateFixedEffect(fixedEffect);
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_SUCCESS, editType, id);
}
/**
* Handles the command /pp fixed remove
*
*
* @param pplayer The PPlayer
* @param p The Player
* @param args The command arguments
@ -497,7 +497,7 @@ public class FixedCommandModule implements CommandModule {
return;
}
int id = -1;
int id;
try {
id = Integer.parseInt(args[0]);
} catch (Exception e) {
@ -512,10 +512,10 @@ public class FixedCommandModule implements CommandModule {
LangManager.sendMessage(pplayer, Lang.FIXED_REMOVE_INVALID, id);
}
}
/**
* Handles the command /pp fixed list
*
*
* @param pplayer The PPlayer
* @param p The Player
* @param args The command arguments
@ -529,20 +529,20 @@ public class FixedCommandModule implements CommandModule {
return;
}
String msg = "";
StringBuilder msg = new StringBuilder();
boolean first = true;
for (int id : ids) {
if (!first) msg += ", ";
if (!first) msg.append(", ");
else first = false;
msg += id;
msg.append(id);
}
LangManager.sendMessage(pplayer, Lang.FIXED_LIST_SUCCESS, msg);
LangManager.sendMessage(pplayer, Lang.FIXED_LIST_SUCCESS, msg.toString());
}
/**
* Handles the command /pp fixed info
*
*
* @param pplayer The PPlayer
* @param p The Player
* @param args The command arguments
@ -553,7 +553,7 @@ public class FixedCommandModule implements CommandModule {
return;
}
int id = -1;
int id;
try {
id = Integer.parseInt(args[0]);
} catch (Exception e) {
@ -570,7 +570,7 @@ public class FixedCommandModule implements CommandModule {
ParticlePair particle = fixedEffect.getParticlePair();
DecimalFormat df = new DecimalFormat("0.##"); // Decimal formatter so the coords aren't super long
LangManager.sendMessage(pplayer, // @formatter:off
LangManager.sendMessage(pplayer,
Lang.FIXED_INFO_SUCCESS,
fixedEffect.getId(),
fixedEffect.getLocation().getWorld().getName(),
@ -580,12 +580,12 @@ public class FixedCommandModule implements CommandModule {
particle.getEffect().getName(),
particle.getStyle().getName(),
particle.getDataString()
); // @formatter:on
);
}
/**
* Handles the command /pp fixed clear
*
*
* @param pplayer The PPlayer
* @param p The Player
* @param args The command arguments
@ -601,7 +601,7 @@ public class FixedCommandModule implements CommandModule {
return;
}
int radius = -1;
int radius;
try {
radius = Math.abs(Integer.parseInt(args[0]));
} catch (Exception e) {
@ -609,11 +609,11 @@ public class FixedCommandModule implements CommandModule {
return;
}
ArrayList<FixedParticleEffect> fixedEffectsToRemove = new ArrayList<FixedParticleEffect>();
ArrayList<FixedParticleEffect> fixedEffectsToRemove = new ArrayList<>();
for (PPlayer ppl : ParticleManager.getPPlayers())
for (FixedParticleEffect fixedEffect : ppl.getFixedParticles())
if (fixedEffect.getLocation().getWorld().equals(p.getLocation().getWorld()) && fixedEffect.getLocation().distance(p.getLocation()) <= radius)
if (fixedEffect.getLocation().getWorld().equals(p.getLocation().getWorld()) && fixedEffect.getLocation().distance(p.getLocation()) <= radius)
fixedEffectsToRemove.add(fixedEffect);
for (FixedParticleEffect fixedEffect : fixedEffectsToRemove)
@ -624,160 +624,156 @@ public class FixedCommandModule implements CommandModule {
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
Player p = pplayer.getPlayer();
List<String> matches = new ArrayList<String>();
String[] subCommands = new String[] { "create", "edit", "remove", "list", "info", "clear" };
List<String> matches = new ArrayList<>();
if (args.length <= 1) {
List<String> possibleCmds = new ArrayList<String>(Arrays.asList(subCommands));
List<String> possibleCmds = new ArrayList<>(Arrays.asList("create", "edit", "remove", "list", "info", "clear"));
if (args.length == 0) matches = possibleCmds;
else StringUtil.copyPartialMatches(args[0], possibleCmds, matches);
} else {
switch (args[0].toLowerCase()) {
case "create":
if (args.length >= 2 && args.length <= 4) {
List<String> possibleValues = new ArrayList<String>();
if (args.length == 4) {
possibleValues.add("~");
}
if (args.length == 3) {
possibleValues.add("~ ~");
}
if (args.length == 2) {
possibleValues.add("~ ~ ~");
possibleValues.add("looking");
}
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
}
// Pad arguments if the first coordinate is "looking"
if (args.length > 1 && args[1].equalsIgnoreCase("looking")) {
String[] paddedArgs = new String[args.length + 2];
paddedArgs[0] = paddedArgs[1] = paddedArgs[2] = paddedArgs[3] = "";
for (int i = 2; i < args.length; i++)
paddedArgs[i + 2] = args[i];
args = paddedArgs;
}
if (args.length == 5) {
StringUtil.copyPartialMatches(args[4], PermissionManager.getEffectNamesUserHasPermissionFor(p), matches);
} else if (args.length == 6) {
StringUtil.copyPartialMatches(args[5], PermissionManager.getFixableStyleNamesUserHasPermissionFor(p), matches);
} else if (args.length >= 7) {
ParticleEffect effect = ParticleEffect.fromName(args[4]);
if (effect != null) {
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
List<String> possibleValues = new ArrayList<String>();
if (effect == ParticleEffect.NOTE) { // Note data
if (args.length == 7) {
possibleValues.add("<0-24>");
possibleValues.add("rainbow");
possibleValues.add("random");
}
} else { // Color data
if (args.length <= 9 && !args[2].equalsIgnoreCase("rainbow") && !args[2].equalsIgnoreCase("random")) {
possibleValues.add("<0-255>");
}
if (args.length <= 8 && !args[2].equalsIgnoreCase("rainbow") && !args[2].equalsIgnoreCase("random")) {
possibleValues.add("<0-255> <0-255>");
}
if (args.length <= 7) {
possibleValues.add("<0-255> <0-255> <0-255>");
possibleValues.add("rainbow");
possibleValues.add("random");
}
}
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
} else if (args.length == 7 && effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) { // Block material
matches = StringUtil.copyPartialMatches(args[6], ParticleUtils.getAllBlockMaterials(), matches);
} else if (effect == ParticleEffect.ITEM) { // Item material
matches = StringUtil.copyPartialMatches(args[6], ParticleUtils.getAllItemMaterials(), matches);
}
}
}
}
break;
case "edit":
if (args.length == 2) {
StringUtil.copyPartialMatches(args[1], pplayer.getFixedEffectIds().stream().map((x) -> String.valueOf(x)).collect(Collectors.toList()), matches);
} else if (args.length == 3) {
String[] validProperties = new String[] { "location", "effect", "style", "data" };
StringUtil.copyPartialMatches(args[2], Arrays.asList(validProperties), matches);
} else if (args.length > 3) {
String property = args[2].toLowerCase();
if (property.equals("location")) {
List<String> possibleValues = new ArrayList<String>();
if (args.length == 6 && !args[3].equalsIgnoreCase("looking")) {
case "create":
if (args.length <= 4) {
List<String> possibleValues = new ArrayList<>();
if (args.length == 4) {
possibleValues.add("~");
}
if (args.length == 5 && !args[3].equalsIgnoreCase("looking")) {
if (args.length == 3) {
possibleValues.add("~ ~");
}
if (args.length == 4) {
if (args.length == 2) {
possibleValues.add("~ ~ ~");
possibleValues.add("looking");
}
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
} else if (property.equals("effect") && args.length == 4) {
StringUtil.copyPartialMatches(args[3], PermissionManager.getEffectNamesUserHasPermissionFor(p), matches);
} else if (property.equals("style") && args.length == 4) {
StringUtil.copyPartialMatches(args[3], PermissionManager.getFixableStyleNamesUserHasPermissionFor(p), matches);
} else if (property.equals("data")) {
int id = -1;
try {
id = Integer.parseInt(args[1]);
} catch (Exception e) { }
FixedParticleEffect fixedEffect = pplayer.getFixedEffectById(id);
if (fixedEffect != null) {
ParticleEffect effect = fixedEffect.getParticlePair().getEffect();
}
// Pad arguments if the first coordinate is "looking"
if (args[1].equalsIgnoreCase("looking")) {
String[] paddedArgs = new String[args.length + 2];
paddedArgs[0] = paddedArgs[1] = paddedArgs[2] = paddedArgs[3] = "";
System.arraycopy(args, 2, paddedArgs, 4, args.length - 2);
args = paddedArgs;
}
if (args.length == 5) {
StringUtil.copyPartialMatches(args[4], PermissionManager.getEffectNamesUserHasPermissionFor(p), matches);
} else if (args.length == 6) {
StringUtil.copyPartialMatches(args[5], PermissionManager.getFixableStyleNamesUserHasPermissionFor(p), matches);
} else if (args.length >= 7) {
ParticleEffect effect = ParticleEffect.fromName(args[4]);
if (effect != null) {
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
List<String> possibleValues = new ArrayList<String>();
List<String> possibleValues = new ArrayList<>();
if (effect == ParticleEffect.NOTE) { // Note data
if (args.length == 4) {
if (args.length == 7) {
possibleValues.add("<0-24>");
possibleValues.add("rainbow");
possibleValues.add("random");
}
} else { // Color data
if (args.length == 6 && !args[3].equalsIgnoreCase("rainbow") && !args[3].equalsIgnoreCase("random")) {
if (args.length <= 9 && !args[2].equalsIgnoreCase("rainbow") && !args[2].equalsIgnoreCase("random")) {
possibleValues.add("<0-255>");
}
if (args.length == 5 && !args[3].equalsIgnoreCase("rainbow") && !args[3].equalsIgnoreCase("random")) {
if (args.length <= 8 && !args[2].equalsIgnoreCase("rainbow") && !args[2].equalsIgnoreCase("random")) {
possibleValues.add("<0-255> <0-255>");
}
if (args.length == 4) {
if (args.length <= 7) {
possibleValues.add("<0-255> <0-255> <0-255>");
possibleValues.add("rainbow");
possibleValues.add("random");
}
}
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
} else if (args.length == 4 && effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
} else if (args.length == 7 && effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) { // Block material
matches = StringUtil.copyPartialMatches(args[3], ParticleUtils.getAllBlockMaterials(), matches);
StringUtil.copyPartialMatches(args[6], ParticleUtils.getAllBlockMaterials(), matches);
} else if (effect == ParticleEffect.ITEM) { // Item material
matches = StringUtil.copyPartialMatches(args[3], ParticleUtils.getAllItemMaterials(), matches);
StringUtil.copyPartialMatches(args[6], ParticleUtils.getAllItemMaterials(), matches);
}
}
}
}
}
break;
case "remove":
StringUtil.copyPartialMatches(args[1], pplayer.getFixedEffectIds().stream().map((x) -> String.valueOf(x)).collect(Collectors.toList()), matches);
break;
case "list":
break;
case "info":
StringUtil.copyPartialMatches(args[1], pplayer.getFixedEffectIds().stream().map((x) -> String.valueOf(x)).collect(Collectors.toList()), matches);
break;
case "clear":
matches.add("<radius>");
break;
break;
case "edit":
if (args.length == 2) {
StringUtil.copyPartialMatches(args[1], pplayer.getFixedEffectIds().stream().map(String::valueOf).collect(Collectors.toList()), matches);
} else if (args.length == 3) {
String[] validProperties = new String[] { "location", "effect", "style", "data" };
StringUtil.copyPartialMatches(args[2], Arrays.asList(validProperties), matches);
} else {
String property = args[2].toLowerCase();
if (property.equals("location")) {
List<String> possibleValues = new ArrayList<String>();
if (args.length == 6 && !args[3].equalsIgnoreCase("looking")) {
possibleValues.add("~");
}
if (args.length == 5 && !args[3].equalsIgnoreCase("looking")) {
possibleValues.add("~ ~");
}
if (args.length == 4) {
possibleValues.add("~ ~ ~");
possibleValues.add("looking");
}
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
} else if (property.equals("effect") && args.length == 4) {
StringUtil.copyPartialMatches(args[3], PermissionManager.getEffectNamesUserHasPermissionFor(p), matches);
} else if (property.equals("style") && args.length == 4) {
StringUtil.copyPartialMatches(args[3], PermissionManager.getFixableStyleNamesUserHasPermissionFor(p), matches);
} else if (property.equals("data")) {
int id = -1;
try {
id = Integer.parseInt(args[1]);
} catch (Exception e) { }
FixedParticleEffect fixedEffect = pplayer.getFixedEffectById(id);
if (fixedEffect != null) {
ParticleEffect effect = fixedEffect.getParticlePair().getEffect();
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
List<String> possibleValues = new ArrayList<>();
if (effect == ParticleEffect.NOTE) { // Note data
if (args.length == 4) {
possibleValues.add("<0-24>");
possibleValues.add("rainbow");
possibleValues.add("random");
}
} else { // Color data
if (args.length == 6 && !args[3].equalsIgnoreCase("rainbow") && !args[3].equalsIgnoreCase("random")) {
possibleValues.add("<0-255>");
}
if (args.length == 5 && !args[3].equalsIgnoreCase("rainbow") && !args[3].equalsIgnoreCase("random")) {
possibleValues.add("<0-255> <0-255>");
}
if (args.length == 4) {
possibleValues.add("<0-255> <0-255> <0-255>");
possibleValues.add("rainbow");
possibleValues.add("random");
}
}
StringUtil.copyPartialMatches(args[args.length - 1], possibleValues, matches);
} else if (args.length == 4 && effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (effect == ParticleEffect.BLOCK || effect == ParticleEffect.FALLING_DUST) { // Block material
StringUtil.copyPartialMatches(args[3], ParticleUtils.getAllBlockMaterials(), matches);
} else if (effect == ParticleEffect.ITEM) { // Item material
StringUtil.copyPartialMatches(args[3], ParticleUtils.getAllItemMaterials(), matches);
}
}
}
}
}
break;
case "remove":
case "info":
StringUtil.copyPartialMatches(args[1], pplayer.getFixedEffectIds().stream().map(String::valueOf).collect(Collectors.toList()), matches);
break;
case "clear":
matches.add("<radius>");
break;
case "list":
break;
}
}
return matches;
}

View file

@ -6,6 +6,8 @@ import java.util.List;
import com.esophose.playerparticles.gui.GuiHandler;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.ParticleGroupPresetManager;
import com.esophose.playerparticles.manager.SettingManager.PSetting;
import com.esophose.playerparticles.manager.PermissionManager;
import com.esophose.playerparticles.particles.PPlayer;
@ -25,8 +27,10 @@ public class GUICommandModule implements CommandModule {
}
return;
}
if (PermissionManager.getEffectNamesUserHasPermissionFor(pplayer.getPlayer()).isEmpty()) {
if (PSetting.GUI_PRESETS_ONLY.getBoolean() && ParticleGroupPresetManager.getPresetGroupsForPlayer(pplayer.getPlayer()).isEmpty()) {
return;
} else if (PermissionManager.getEffectNamesUserHasPermissionFor(pplayer.getPlayer()).isEmpty()) {
if (byDefault) {
LangManager.sendMessage(pplayer, Lang.COMMAND_ERROR_UNKNOWN);
} else {
@ -39,7 +43,7 @@ public class GUICommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -5,6 +5,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.esophose.playerparticles.manager.DataManager;
@ -20,7 +21,7 @@ import com.esophose.playerparticles.particles.ParticlePair;
public class GroupCommandModule implements CommandModule {
public void onCommandExecute(PPlayer pplayer, String[] args) {
List<String> validCommands = Arrays.asList(new String[] { "save", "load", "remove", "info", "list" });
List<String> validCommands = Arrays.asList("save", "load", "remove", "info", "list");
if (args.length == 0 || !validCommands.contains(args[0])) {
LangManager.sendMessage(pplayer, Lang.COMMAND_DESCRIPTION_GROUP_SAVE);
LangManager.sendMessage(pplayer, Lang.COMMAND_DESCRIPTION_GROUP_LOAD);
@ -37,19 +38,19 @@ public class GroupCommandModule implements CommandModule {
switch (args[0].toLowerCase()) {
case "save":
onSave(pplayer, args[1].toLowerCase());
this.onSave(pplayer, args[1].toLowerCase());
break;
case "load":
onLoad(pplayer, args[1].toLowerCase());
this.onLoad(pplayer, args[1].toLowerCase());
break;
case "remove":
onRemove(pplayer, args[1].toLowerCase());
this.onRemove(pplayer, args[1].toLowerCase());
break;
case "info":
onInfo(pplayer, args[1].toLowerCase());
this.onInfo(pplayer, args[1].toLowerCase());
break;
case "list":
onList(pplayer);
this.onList(pplayer);
break;
default:
LangManager.sendMessage(pplayer, Lang.COMMAND_DESCRIPTION_GROUP_SAVE);
@ -95,7 +96,7 @@ public class GroupCommandModule implements CommandModule {
ParticleGroup group = pplayer.getParticleGroupByName(groupName);
boolean groupUpdated = false;
if (group == null) {
List<ParticlePair> particles = new ArrayList<ParticlePair>();
List<ParticlePair> particles = new ArrayList<>();
for (ParticlePair particle : pplayer.getActiveParticles())
particles.add(particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group
group = new ParticleGroup(groupName, particles);
@ -144,6 +145,11 @@ public class GroupCommandModule implements CommandModule {
group = presetGroup.getGroup();
isPreset = true;
}
if (!group.canPlayerUse(pplayer.getPlayer())) {
LangManager.sendMessage(pplayer, Lang.GROUP_NO_PERMISSION, groupName);
return;
}
// Empty out the active group and fill it with clones from the target group
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
@ -237,39 +243,40 @@ public class GroupCommandModule implements CommandModule {
private void onList(PPlayer pplayer) {
List<ParticleGroup> groups = pplayer.getParticleGroups();
groups.sort(Comparator.comparing(ParticleGroup::getName));
String groupsList = "";
Player player = pplayer.getPlayer();
StringBuilder groupsList = new StringBuilder();
for (ParticleGroup group : groups)
if (!group.getName().equals(ParticleGroup.DEFAULT_NAME))
groupsList += group.getName() + ", ";
groupsList.append(group.getName()).append(", ");
if (groupsList.endsWith(", "))
groupsList = groupsList.substring(0, groupsList.length() - 2);
if (groupsList.toString().endsWith(", "))
groupsList = new StringBuilder(groupsList.substring(0, groupsList.length() - 2));
String presetsList = "";
StringBuilder presetsList = new StringBuilder();
for (ParticleGroupPreset group : ParticleGroupPresetManager.getPresetGroupsForPlayer(pplayer.getPlayer()))
presetsList += group.getGroup().getName() + ", ";
presetsList.append(group.getGroup().getName()).append(", ");
if (presetsList.endsWith(", "))
presetsList = presetsList.substring(0, presetsList.length() - 2);
if (presetsList.toString().endsWith(", "))
presetsList = new StringBuilder(presetsList.substring(0, presetsList.length() - 2));
if (groupsList.isEmpty() && presetsList.isEmpty()) {
if ((groupsList.length() == 0) && (presetsList.length() == 0)) {
LangManager.sendMessage(pplayer, Lang.GROUP_LIST_NONE);
return;
}
if (!groupsList.isEmpty()) {
LangManager.sendMessage(pplayer, Lang.GROUP_LIST_OUTPUT, groupsList);
if (groupsList.length() > 0) {
LangManager.sendMessage(pplayer, Lang.GROUP_LIST_OUTPUT, groupsList.toString());
}
if (!presetsList.isEmpty()) {
LangManager.sendMessage(pplayer, Lang.GROUP_LIST_PRESETS, presetsList);
if (presetsList.length() > 0) {
LangManager.sendMessage(pplayer, Lang.GROUP_LIST_PRESETS, presetsList.toString());
}
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
List<String> matches = new ArrayList<String>();
List<String> subCommands = Arrays.asList(new String[] { "save", "load", "remove", "info", "list" });
List<String> matches = new ArrayList<>();
List<String> subCommands = Arrays.asList("save", "load", "remove", "info", "list");
if (args.length <= 1) {
if (args.length == 0) matches = subCommands;
@ -278,7 +285,7 @@ public class GroupCommandModule implements CommandModule {
if (args[0].equalsIgnoreCase("save")) {
matches.add("<groupName>");
} else {
List<String> groupNames = new ArrayList<String>();
List<String> groupNames = new ArrayList<>();
for (ParticleGroup group : pplayer.getParticleGroups())
if (!group.getName().equals(ParticleGroup.DEFAULT_NAME))
groupNames.add(group.getName());
@ -305,7 +312,7 @@ public class GroupCommandModule implements CommandModule {
}
public boolean requiresEffects() {
return true;
return false;
}
}

View file

@ -19,7 +19,7 @@ public class HelpCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -31,7 +31,7 @@ public class ListCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -58,10 +58,10 @@ public class OtherCommandModule implements CommandModuleSecondary {
}
public List<String> onTabComplete(CommandSender sender, String[] args) {
List<String> completions = new ArrayList<String>();
List<String> completions = new ArrayList<>();
if (args.length < 2) {
List<String> playerNames = new ArrayList<String>();
List<String> playerNames = new ArrayList<>();
for (Player player : Bukkit.getOnlinePlayers())
playerNames.add(player.getName());

View file

@ -27,7 +27,7 @@ public class ParticleCommandHandler implements CommandExecutor, TabCompleter {
private static CommandModuleSecondary ppoCommand;
static {
commands = new ArrayList<CommandModule>();
commands = new ArrayList<>();
commands.add(new AddCommandModule());
commands.add(new DataCommandModule());
@ -78,7 +78,7 @@ public class ParticleCommandHandler implements CommandExecutor, TabCompleter {
* @return All available command names
*/
public static List<String> getCommandNames() {
List<String> commandNames = new ArrayList<String>();
List<String> commandNames = new ArrayList<>();
for (CommandModule cmd : commands)
commandNames.add(cmd.getName());
return commandNames;
@ -137,15 +137,15 @@ public class ParticleCommandHandler implements CommandExecutor, TabCompleter {
*/
public List<String> onTabComplete(CommandSender sender, Command cmd, String alias, String[] args) {
if (cmd.getName().equalsIgnoreCase("pp")) {
if (!(sender instanceof Player)) return new ArrayList<String>();
if (!(sender instanceof Player)) return new ArrayList<>();
PPlayer pplayer = DataManager.getPPlayer(((Player) sender).getUniqueId());
if (pplayer == null) return new ArrayList<String>();
if (pplayer == null) return new ArrayList<>();
if (args.length <= 1) {
CommandModule commandModule = findMatchingCommand(""); // Get the default command module
return commandModule.onTabComplete(pplayer, args);
} else if (args.length >= 2) {
} else {
CommandModule commandModule = findMatchingCommand(args[0]);
if (commandModule != null) {
String[] cmdArgs = Arrays.copyOfRange(args, 1, args.length);
@ -156,7 +156,7 @@ public class ParticleCommandHandler implements CommandExecutor, TabCompleter {
return ppoCommand.onTabComplete(sender, args);
}
return new ArrayList<String>();
return new ArrayList<>();
}
}

View file

@ -22,7 +22,7 @@ public class ReloadCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -26,7 +26,7 @@ public class RemoveCommandModule implements CommandModule {
}
if (StringUtils.isNumeric(args[0])) { // Removing by ID
int id = -1;
int id;
try {
id = Integer.parseInt(args[0]);
} catch (Exception ex) {
@ -99,8 +99,8 @@ public class RemoveCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
List<String> matches = new ArrayList<String>();
Set<String> removeBy = new HashSet<String>();
List<String> matches = new ArrayList<>();
Set<String> removeBy = new HashSet<>();
for (ParticlePair particle : pplayer.getActiveParticles()) {
removeBy.add(String.valueOf(particle.getId()));
@ -108,7 +108,7 @@ public class RemoveCommandModule implements CommandModule {
removeBy.add(particle.getStyle().getName());
}
if (args.length == 0) return new ArrayList<String>(removeBy);
if (args.length == 0) return new ArrayList<>(removeBy);
StringUtil.copyPartialMatches(args[0], removeBy, matches);
return matches;

View file

@ -18,7 +18,7 @@ public class ResetCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -16,20 +16,20 @@ public class StylesCommandModule implements CommandModule {
Player p = pplayer.getPlayer();
List<String> styleNames = PermissionManager.getStyleNamesUserHasPermissionFor(p);
String toSend = "";
StringBuilder toSend = new StringBuilder();
for (String name : styleNames) {
toSend += name + ", ";
toSend.append(name).append(", ");
}
if (toSend.endsWith(", ")) {
toSend = toSend.substring(0, toSend.length() - 2);
if (toSend.toString().endsWith(", ")) {
toSend = new StringBuilder(toSend.substring(0, toSend.length() - 2));
}
LangManager.sendMessage(pplayer, Lang.STYLE_LIST, toSend);
LangManager.sendMessage(pplayer, Lang.STYLE_LIST, toSend.toString());
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -22,7 +22,7 @@ public class ToggleCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -18,7 +18,7 @@ public class VersionCommandModule implements CommandModule {
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -16,17 +16,17 @@ public class WorldsCommandModule implements CommandModule {
return;
}
String worlds = "";
StringBuilder worlds = new StringBuilder();
for (String s : PermissionManager.getDisabledWorlds()) {
worlds += s + ", ";
worlds.append(s).append(", ");
}
if (worlds.length() > 2) worlds = worlds.substring(0, worlds.length() - 2);
if (worlds.length() > 2) worlds = new StringBuilder(worlds.substring(0, worlds.length() - 2));
LangManager.sendCustomMessage(pplayer, LangManager.getText(Lang.DISABLED_WORLDS) + " " + worlds);
}
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
return new ArrayList<String>();
return new ArrayList<>();
}
public String getName() {

View file

@ -10,25 +10,25 @@ public interface DatabaseConnector {
*
* @return If the connection is created or not
*/
public boolean isInitialized();
boolean isInitialized();
/**
* Closes all open connections to the database
*/
public void closeConnection();
void closeConnection();
/**
* Executes a callback with a Connection passed and automatically closes it when finished
*
* @param callback The callback to execute once the connection is retrieved
*/
public void connect(ConnectionCallback callback);
void connect(ConnectionCallback callback);
/**
* Allows Lambda expressions to be used to reduce duplicated code for getting connections
*/
public static interface ConnectionCallback {
public void execute(Connection connection) throws SQLException;
interface ConnectionCallback {
void execute(Connection connection) throws SQLException;
}
}

View file

@ -11,7 +11,7 @@ import com.zaxxer.hikari.HikariDataSource;
public class MySqlDatabaseConnector implements DatabaseConnector {
private HikariDataSource hikari;
private boolean initializedSuccessfully = false;
private boolean initializedSuccessfully;
public MySqlDatabaseConnector() {
String hostname = PSetting.DATABASE_HOSTNAME.getString();
@ -19,12 +19,13 @@ public class MySqlDatabaseConnector implements DatabaseConnector {
String database = PSetting.DATABASE_NAME.getString();
String user = PSetting.DATABASE_USER_NAME.getString();
String pass = PSetting.DATABASE_USER_PASSWORD.getString();
boolean useSSL = PSetting.DATABASE_USE_SSL.getBoolean();
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://" + hostname + ":" + port + "/" + database);
config.setJdbcUrl("jdbc:mysql://" + hostname + ":" + port + "/" + database + "?useSSL=" + useSSL);
config.setUsername(user);
config.setPassword(pass);
config.setMaximumPoolSize(5);
config.setMaximumPoolSize(3);
try {
this.hikari = new HikariDataSource(config);

View file

@ -3,6 +3,7 @@ package com.esophose.playerparticles.gui;
import java.util.ArrayList;
import java.util.List;
import com.esophose.playerparticles.util.NMSUtil;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag;
@ -98,7 +99,6 @@ public class GuiActionButton {
*
* @return The icon ItemStack for the GUI
*/
@SuppressWarnings("deprecation")
public ItemStack getIcon() {
ItemStack itemStack;
if (this.icons != null) {
@ -112,12 +112,12 @@ public class GuiActionButton {
}
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.setDisplayName(this.name);
itemMeta.setLore(parseLore(this.lore));
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS);
itemStack.setItemMeta(itemMeta);
if (itemMeta != null) {
itemMeta.setDisplayName(this.name);
itemMeta.setLore(parseLore(this.lore));
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS);
itemStack.setItemMeta(itemMeta);
}
return itemStack;
}
@ -125,10 +125,9 @@ public class GuiActionButton {
/**
* Executes the onClick callback passed in the constructor
*
* @param button The button that was clicked
* @param isShiftClick If the player was holding shift when they clicked
*/
public void handleClick(GuiActionButton button, boolean isShiftClick) {
public void handleClick(boolean isShiftClick) {
if (this.onClick != null)
this.onClick.execute(this, isShiftClick);
}
@ -158,7 +157,7 @@ public class GuiActionButton {
* @return A parsed list of lore text
*/
public static List<String> parseLore(String... lore) {
List<String> parsedLore = new ArrayList<String>();
List<String> parsedLore = new ArrayList<>();
for (String line : lore) {
// Try to maintain the color going to the next line if it's split
// If there is no color, just ignore it
@ -168,7 +167,7 @@ public class GuiActionButton {
}
// Split the lore along \n onto a new line if any exist
String[] splitLines = line.split("\\\\n");
String[] splitLines = line.split("\n");
for (String parsedLine : splitLines) {
if (ChatColor.stripColor(parsedLine).isEmpty()) continue;
parsedLore.add(lineColor + parsedLine);
@ -181,8 +180,8 @@ public class GuiActionButton {
* Allows button click callbacks as parameters
*/
@FunctionalInterface
public static interface GuiActionButtonClickCallback {
public void execute(GuiActionButton button, boolean isShiftClick);
public interface GuiActionButtonClickCallback {
void execute(GuiActionButton button, boolean isShiftClick);
}
}

View file

@ -23,7 +23,7 @@ import com.esophose.playerparticles.particles.PPlayer;
*/
public class GuiHandler extends BukkitRunnable implements Listener {
private static List<GuiInventory> guiInventories = new ArrayList<GuiInventory>();
private static List<GuiInventory> guiInventories = new ArrayList<>();
private static BukkitTask guiTask = null;
/**
@ -40,7 +40,7 @@ public class GuiHandler extends BukkitRunnable implements Listener {
* Removes entries from playerGuiInventories if the player no longer has the inventory open or is offline
*/
public void run() {
List<GuiInventory> toRemoveList = new ArrayList<GuiInventory>();
List<GuiInventory> toRemoveList = new ArrayList<>();
for (GuiInventory inventory : guiInventories) {
PPlayer pplayer = DataManager.getPPlayer(inventory.getPPlayer().getUniqueId());
@ -112,10 +112,15 @@ public class GuiHandler extends BukkitRunnable implements Listener {
public static void openDefault(PPlayer pplayer) {
removeGuiInventory(pplayer);
GuiInventoryDefault defaultInventory = new GuiInventoryDefault(pplayer);
guiInventories.add(defaultInventory);
pplayer.getPlayer().openInventory(defaultInventory.getInventory());
GuiInventory inventoryToOpen;
if (!PSetting.GUI_PRESETS_ONLY.getBoolean()) {
inventoryToOpen = new GuiInventoryDefault(pplayer);
} else {
inventoryToOpen = new GuiInventoryLoadPresetGroups(pplayer, true);
}
guiInventories.add(inventoryToOpen);
pplayer.getPlayer().openInventory(inventoryToOpen.getInventory());
}
/**

View file

@ -22,14 +22,25 @@ public abstract class GuiInventory implements InventoryHolder {
protected enum BorderColor {
WHITE(0, "WHITE_STAINED_GLASS_PANE"),
ORANGE(1, "ORANGE_STAINED_GLASS_PANE"),
RED(14, "RED_STAINED_GLASS_PANE"),
MAGENTA(2, "MAGENTA_STAINED_GLASS_PANE"),
LIGHT_BLUE(3, "LIGHT_BLUE_STAINED_GLASS_PANE"),
YELLOW(4, "YELLOW_STAINED_GLASS_PANE"),
LIME(5, "LIME_STAINED_GLASS_PANE"),
PINK(6, "PINK_STAINED_GLASS_PANE"),
GRAY(7, "GRAY_STAINED_GLASS_PANE"),
LIGHT_GRAY(8, "LIGHT_GRAY_STAINED_GLASS_PANE"),
CYAN(9, "CYAN_STAINED_GLASS_PANE"),
PURPLE(10, "PURPLE_STAINED_GLASS_PANE"),
BLUE(11, "BLUE_STAINED_GLASS_PANE"),
BROWN(12, "BROWN_STAINED_GLASS_PANE"),
GREEN(13, "GREEN_STAINED_GLASS_PANE");
GREEN(13, "GREEN_STAINED_GLASS_PANE"),
RED(14, "RED_STAINED_GLASS_PANE"),
BLACK(15, "BLACK_STAINED_GLASS_PANE");
private short data;
private Material material;
private BorderColor(int data, String materialName) {
BorderColor(int data, String materialName) {
this.data = (short)data;
this.material = ParticleUtils.closestMatch(materialName);
}
@ -44,9 +55,11 @@ public abstract class GuiInventory implements InventoryHolder {
}
ItemMeta meta = borderIcon.getItemMeta();
meta.setDisplayName(" ");
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_ENCHANTS);
borderIcon.setItemMeta(meta);
if (meta != null) {
meta.setDisplayName(" ");
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_ENCHANTS);
borderIcon.setItemMeta(meta);
}
return borderIcon;
}
@ -60,7 +73,7 @@ public abstract class GuiInventory implements InventoryHolder {
public GuiInventory(PPlayer pplayer, Inventory inventory) {
this.pplayer = pplayer;
this.inventory = inventory;
this.actionButtons = new ArrayList<GuiActionButton>();
this.actionButtons = new ArrayList<>();
}
/**
@ -110,7 +123,7 @@ public abstract class GuiInventory implements InventoryHolder {
* Populates the Inventory with the contents of actionButtons
*/
protected void populate() {
for (GuiActionButton button : actionButtons) {
for (GuiActionButton button : this.actionButtons) {
this.inventory.setItem(button.getSlot(), button.getIcon());
}
}
@ -140,12 +153,10 @@ public abstract class GuiInventory implements InventoryHolder {
for (GuiActionButton button : this.actionButtons) {
if (button.getSlot() == slot) {
button.handleClick(button, isShiftClick);
if (PSetting.GUI_BUTTON_SOUND.getBoolean()) {
if (event.getWhoClicked() instanceof Player) {
Player player = (Player) event.getWhoClicked();
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 0.5f, 1);
}
button.handleClick(isShiftClick);
if (PSetting.GUI_BUTTON_SOUND.getBoolean() && event.getWhoClicked() instanceof Player) {
Player player = (Player) event.getWhoClicked();
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 0.5f, 1);
}
break;
}
@ -153,8 +164,8 @@ public abstract class GuiInventory implements InventoryHolder {
}
@FunctionalInterface
public static interface GuiInventoryEditFinishedCallback {
public void execute();
public interface GuiInventoryEditFinishedCallback {
void execute();
}
}

View file

@ -1,14 +1,5 @@
package com.esophose.playerparticles.gui;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.SkullType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import com.esophose.playerparticles.manager.DataManager;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
@ -20,15 +11,23 @@ import com.esophose.playerparticles.particles.ParticleEffect.ParticleProperty;
import com.esophose.playerparticles.particles.ParticleGroup;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.util.ParticleUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.SkullType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("deprecation")
public class GuiInventoryDefault extends GuiInventory {
public GuiInventoryDefault(PPlayer pplayer) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_PLAYERPARTICLES)));
this.fillBorder(BorderColor.WHITE);
// PPlayer information icon
ItemStack headIcon;
Material playerHead = ParticleUtils.closestMatch("PLAYER_HEAD");
@ -39,25 +38,27 @@ public class GuiInventoryDefault extends GuiInventory {
}
SkullMeta currentIconMeta = (SkullMeta) headIcon.getItemMeta();
currentIconMeta.setDisplayName(LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + pplayer.getPlayer().getName());
String[] currentIconLore = new String[] {
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_ACTIVE_PARTICLES, pplayer.getActiveParticles().size()),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVED_GROUPS, pplayer.getParticleGroups().size() - 1),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_FIXED_EFFECTS, pplayer.getFixedEffectIds().size()),
" ",
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_COMMANDS_INFO)
};
currentIconMeta.setLore(GuiActionButton.parseLore(currentIconLore));
currentIconMeta.setOwner(pplayer.getPlayer().getName());
headIcon.setItemMeta(currentIconMeta);
if (currentIconMeta != null) {
currentIconMeta.setDisplayName(LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + pplayer.getPlayer().getName());
String[] currentIconLore = new String[]{
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_ACTIVE_PARTICLES, pplayer.getActiveParticles().size()),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVED_GROUPS, pplayer.getParticleGroups().size() - 1),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_FIXED_EFFECTS, pplayer.getFixedEffectIds().size()),
" ",
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_COMMANDS_INFO)
};
currentIconMeta.setLore(GuiActionButton.parseLore(currentIconLore));
currentIconMeta.setOwner(pplayer.getPlayer().getName());
headIcon.setItemMeta(currentIconMeta);
}
this.inventory.setItem(13, headIcon);
// Define what slots to put the icons at based on what other slots are visible
boolean manageGroupsVisible = PermissionManager.canPlayerSaveGroups(pplayer);
boolean loadPresetGroupVisible = !ParticleGroupPresetManager.getPresetGroupsForPlayer(pplayer.getPlayer()).isEmpty();
int manageParticlesSlot = -1, manageGroupsSlot = -1, loadPresetGroupSlot = -1;
if (!manageGroupsVisible && !loadPresetGroupVisible) {
manageParticlesSlot = 22;
} else if (!manageGroupsVisible) {
@ -71,157 +72,157 @@ public class GuiInventoryDefault extends GuiInventory {
manageGroupsSlot = 22;
loadPresetGroupSlot = 24;
}
// Manage Your Particles button
GuiActionButton manageYourParticlesButton = new GuiActionButton(manageParticlesSlot,
GuiIcon.PARTICLES.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES_DESCRIPTION) },
(button, isShiftClick) -> {
GuiHandler.transition(new GuiInventoryManageParticles(pplayer));
});
GuiActionButton manageYourParticlesButton = new GuiActionButton(
manageParticlesSlot,
GuiIcon.PARTICLES.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES_DESCRIPTION)},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryManageParticles(pplayer)));
this.actionButtons.add(manageYourParticlesButton);
// Manage Your Groups button
if (manageGroupsVisible) {
GuiActionButton manageYourGroupsButton = new GuiActionButton(manageGroupsSlot,
GuiIcon.GROUPS.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS_DESCRIPTION) },
(button, isShiftClick) -> {
GuiHandler.transition(new GuiInventoryManageGroups(pplayer));
});
GuiActionButton manageYourGroupsButton = new GuiActionButton(
manageGroupsSlot,
GuiIcon.GROUPS.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS_DESCRIPTION)},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryManageGroups(pplayer)));
this.actionButtons.add(manageYourGroupsButton);
}
// Load Preset Groups
if (loadPresetGroupVisible) {
GuiActionButton loadPresetGroups = new GuiActionButton(loadPresetGroupSlot,
GuiIcon.PRESET_GROUPS.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP_DESCRIPTION) },
(button, isShiftClick) -> {
GuiHandler.transition(new GuiInventoryLoadPresetGroups(pplayer));
});
GuiActionButton loadPresetGroups = new GuiActionButton(
loadPresetGroupSlot,
GuiIcon.PRESET_GROUPS.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP_DESCRIPTION)},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryLoadPresetGroups(pplayer, false)));
this.actionButtons.add(loadPresetGroups);
}
final ParticlePair editingParticle = pplayer.getPrimaryParticle();
boolean canEditPrimaryStyleAndData = pplayer.getActiveParticle(1) != null;
boolean doesEffectUseData = editingParticle.getEffect().hasProperty(ParticleProperty.COLORABLE) || editingParticle.getEffect().hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA);
// Edit Primary Effect
GuiActionButton editPrimaryEffect = new GuiActionButton(38,
GuiIcon.EDIT_EFFECT.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_EFFECT),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_EFFECT_DESCRIPTION) },
(button, isShiftClick) -> {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<GuiInventoryEditFinishedCallback>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
if (canEditPrimaryStyleAndData) {
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setEffect(editingParticle.getEffect());
break;
}
}
} else {
group.getParticles().add(editingParticle);
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
callbacks.get(1).execute();
});
GuiActionButton editPrimaryEffect = new GuiActionButton(
38,
GuiIcon.EDIT_EFFECT.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_EFFECT),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_EFFECT_DESCRIPTION)},
(button, isShiftClick) -> {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, 1, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
if (canEditPrimaryStyleAndData) {
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setEffect(editingParticle.getEffect());
break;
}
}
} else {
group.getParticles().add(editingParticle);
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
callbacks.get(1).execute();
});
this.actionButtons.add(editPrimaryEffect);
// Edit Primary Style
String[] editPrimaryStyleLore;
if (canEditPrimaryStyleAndData) {
editPrimaryStyleLore = new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE_DESCRIPTION) };
editPrimaryStyleLore = new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE_DESCRIPTION)};
} else {
editPrimaryStyleLore = new String[] {
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE_MISSING_EFFECT)
editPrimaryStyleLore = new String[]{
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE_MISSING_EFFECT)
};
}
GuiActionButton editPrimaryStyle = new GuiActionButton(40,
GuiIcon.EDIT_STYLE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE),
editPrimaryStyleLore,
(button, isShiftClick) -> {
if (!canEditPrimaryStyleAndData) return;
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<GuiInventoryEditFinishedCallback>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setStyle(editingParticle.getStyle());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
callbacks.get(1).execute();
});
GuiActionButton editPrimaryStyle = new GuiActionButton(
40,
GuiIcon.EDIT_STYLE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_STYLE),
editPrimaryStyleLore,
(button, isShiftClick) -> {
if (!canEditPrimaryStyleAndData) return;
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, 1, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setStyle(editingParticle.getStyle());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
callbacks.get(1).execute();
});
this.actionButtons.add(editPrimaryStyle);
// Edit Primary Data
String[] editPrimaryDataLore;
if (canEditPrimaryStyleAndData && doesEffectUseData) {
editPrimaryDataLore = new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_DESCRIPTION) };
editPrimaryDataLore = new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_DESCRIPTION)};
} else if (canEditPrimaryStyleAndData) {
editPrimaryDataLore = new String[] {
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_UNAVAILABLE)
editPrimaryDataLore = new String[]{
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_UNAVAILABLE)
};
} else {
editPrimaryDataLore = new String[] {
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_MISSING_EFFECT)
editPrimaryDataLore = new String[]{
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA_MISSING_EFFECT)
};
}
GuiActionButton editPrimaryData = new GuiActionButton(42,
GuiIcon.EDIT_DATA.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA),
editPrimaryDataLore,
(button, isShiftClick) -> {
if (!canEditPrimaryStyleAndData || !doesEffectUseData) return;
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<GuiInventoryEditFinishedCallback>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditData(pplayer, editingParticle, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setColor(editingParticle.getColor());
particle.setNoteColor(editingParticle.getNoteColor());
particle.setItemMaterial(editingParticle.getItemMaterial());
particle.setBlockMaterial(editingParticle.getBlockMaterial());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
callbacks.get(1).execute();
});
GuiActionButton editPrimaryData = new GuiActionButton(
42,
GuiIcon.EDIT_DATA.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_PRIMARY_DATA),
editPrimaryDataLore,
(button, isShiftClick) -> {
if (!canEditPrimaryStyleAndData || !doesEffectUseData) return;
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditData(pplayer, editingParticle, 1, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setColor(editingParticle.getColor());
particle.setNoteColor(editingParticle.getNoteColor());
particle.setItemMaterial(editingParticle.getItemMaterial());
particle.setBlockMaterial(editingParticle.getBlockMaterial());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
callbacks.get(1).execute();
});
this.actionButtons.add(editPrimaryData);
this.populate();
}

View file

@ -1,18 +1,5 @@
package com.esophose.playerparticles.gui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
@ -22,79 +9,120 @@ import com.esophose.playerparticles.particles.ParticleEffect.NoteColor;
import com.esophose.playerparticles.particles.ParticleEffect.OrdinaryColor;
import com.esophose.playerparticles.particles.ParticleEffect.ParticleProperty;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.util.NMSUtil;
import com.esophose.playerparticles.util.ParticleUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
@SuppressWarnings("deprecation")
public class GuiInventoryEditData extends GuiInventory {
private static Random RANDOM = new Random();
private static List<Material> BLOCK_MATERIALS, ITEM_MATERIALS;
private static ColorData[] colorMapping;
private static ColorData[] rainbowColorMapping;
private static ColorData[] noteColorMapping;
private static ColorData[] noteColorMapping, noteColorMappingOld;
static {
colorMapping = new ColorData[] {
new ColorData(DyeColor.RED, ParticleUtils.closestMatch("ROSE_RED"), new OrdinaryColor(255, 0, 0), Lang.GUI_EDIT_DATA_COLOR_RED),
new ColorData(DyeColor.ORANGE, ParticleUtils.closestMatch("ORANGE_DYE"), new OrdinaryColor(255, 140, 0), Lang.GUI_EDIT_DATA_COLOR_ORANGE),
new ColorData(DyeColor.YELLOW, ParticleUtils.closestMatch("DANDELION_YELLOW"), new OrdinaryColor(255, 255, 0), Lang.GUI_EDIT_DATA_COLOR_YELLOW),
new ColorData(DyeColor.LIME, ParticleUtils.closestMatch("LIME_DYE"), new OrdinaryColor(50, 205, 50), Lang.GUI_EDIT_DATA_COLOR_LIME_GREEN),
new ColorData(DyeColor.GREEN, ParticleUtils.closestMatch("CACTUS_GREEN"), new OrdinaryColor(0, 128, 0), Lang.GUI_EDIT_DATA_COLOR_GREEN),
new ColorData(DyeColor.BLUE, ParticleUtils.closestMatch("LAPIS_LAZULI"), new OrdinaryColor(0, 0, 255), Lang.GUI_EDIT_DATA_COLOR_BLUE),
new ColorData(DyeColor.CYAN, ParticleUtils.closestMatch("CYAN_DYE"), new OrdinaryColor(0, 139, 139), Lang.GUI_EDIT_DATA_COLOR_CYAN),
new ColorData(DyeColor.LIGHT_BLUE, ParticleUtils.closestMatch("LIGHT_BLUE_DYE"), new OrdinaryColor(173, 216, 230), Lang.GUI_EDIT_DATA_COLOR_LIGHT_BLUE),
new ColorData(DyeColor.PURPLE, ParticleUtils.closestMatch("PURPLE_DYE"), new OrdinaryColor(138, 43, 226), Lang.GUI_EDIT_DATA_COLOR_PURPLE),
new ColorData(DyeColor.MAGENTA, ParticleUtils.closestMatch("MAGENTA_DYE"), new OrdinaryColor(202, 31, 123), Lang.GUI_EDIT_DATA_COLOR_MAGENTA),
new ColorData(DyeColor.PINK, ParticleUtils.closestMatch("PINK_DYE"), new OrdinaryColor(255, 182, 193), Lang.GUI_EDIT_DATA_COLOR_PINK),
new ColorData(DyeColor.BROWN, ParticleUtils.closestMatch("COCOA_BEANS"), new OrdinaryColor(139, 69, 19), Lang.GUI_EDIT_DATA_COLOR_BROWN),
new ColorData(DyeColor.BLACK, ParticleUtils.closestMatch("INK_SAC"), new OrdinaryColor(0, 0, 0), Lang.GUI_EDIT_DATA_COLOR_BLACK),
new ColorData(DyeColor.GRAY, ParticleUtils.closestMatch("GRAY_DYE"), new OrdinaryColor(128, 128, 128), Lang.GUI_EDIT_DATA_COLOR_GRAY),
new ColorData(DyeColor.getByDyeData((byte)7), ParticleUtils.closestMatch("LIGHT_GRAY_DYE"), new OrdinaryColor(192, 192, 192), Lang.GUI_EDIT_DATA_COLOR_LIGHT_GRAY),
new ColorData(DyeColor.WHITE, ParticleUtils.closestMatch("BONE_MEAL"), new OrdinaryColor(255, 255, 255), Lang.GUI_EDIT_DATA_COLOR_WHITE),
colorMapping = new ColorData[]{
new ColorData(DyeColor.RED, ParticleUtils.closestMatchWithFallback(false, "RED_DYE", "ROSE_RED"), new OrdinaryColor(255, 0, 0), Lang.GUI_EDIT_DATA_COLOR_RED),
new ColorData(DyeColor.ORANGE, ParticleUtils.closestMatchWithFallback(false, "ORANGE_DYE"), new OrdinaryColor(255, 140, 0), Lang.GUI_EDIT_DATA_COLOR_ORANGE),
new ColorData(DyeColor.YELLOW, ParticleUtils.closestMatchWithFallback(false, "YELLOW_DYE", "DANDELION_YELLOW"), new OrdinaryColor(255, 255, 0), Lang.GUI_EDIT_DATA_COLOR_YELLOW),
new ColorData(DyeColor.LIME, ParticleUtils.closestMatchWithFallback(false, "LIME_DYE"), new OrdinaryColor(50, 205, 50), Lang.GUI_EDIT_DATA_COLOR_LIME_GREEN),
new ColorData(DyeColor.GREEN, ParticleUtils.closestMatchWithFallback(false, "GREEN_DYE", "CACTUS_GREEN"), new OrdinaryColor(0, 128, 0), Lang.GUI_EDIT_DATA_COLOR_GREEN),
new ColorData(DyeColor.BLUE, ParticleUtils.closestMatchWithFallback(false, "BLUE_DYE", "LAPIS_LAZULI"), new OrdinaryColor(0, 0, 255), Lang.GUI_EDIT_DATA_COLOR_BLUE),
new ColorData(DyeColor.CYAN, ParticleUtils.closestMatchWithFallback(false, "CYAN_DYE"), new OrdinaryColor(0, 139, 139), Lang.GUI_EDIT_DATA_COLOR_CYAN),
new ColorData(DyeColor.LIGHT_BLUE, ParticleUtils.closestMatchWithFallback(false, "LIGHT_BLUE_DYE"), new OrdinaryColor(173, 216, 230), Lang.GUI_EDIT_DATA_COLOR_LIGHT_BLUE),
new ColorData(DyeColor.PURPLE, ParticleUtils.closestMatchWithFallback(false, "PURPLE_DYE"), new OrdinaryColor(138, 43, 226), Lang.GUI_EDIT_DATA_COLOR_PURPLE),
new ColorData(DyeColor.MAGENTA, ParticleUtils.closestMatchWithFallback(false, "MAGENTA_DYE"), new OrdinaryColor(202, 31, 123), Lang.GUI_EDIT_DATA_COLOR_MAGENTA),
new ColorData(DyeColor.PINK, ParticleUtils.closestMatchWithFallback(false, "PINK_DYE"), new OrdinaryColor(255, 182, 193), Lang.GUI_EDIT_DATA_COLOR_PINK),
new ColorData(DyeColor.BROWN, ParticleUtils.closestMatchWithFallback(false, "BROWN_DYE", "COCOA_BEANS"), new OrdinaryColor(139, 69, 19), Lang.GUI_EDIT_DATA_COLOR_BROWN),
new ColorData(DyeColor.BLACK, ParticleUtils.closestMatchWithFallback(false, "BLACK_DYE", "INK_SAC"), new OrdinaryColor(0, 0, 0), Lang.GUI_EDIT_DATA_COLOR_BLACK),
new ColorData(DyeColor.GRAY, ParticleUtils.closestMatchWithFallback(false, "GRAY_DYE"), new OrdinaryColor(128, 128, 128), Lang.GUI_EDIT_DATA_COLOR_GRAY),
new ColorData(DyeColor.getByDyeData((byte) 7), ParticleUtils.closestMatchWithFallback(false, "LIGHT_GRAY_DYE"), new OrdinaryColor(192, 192, 192), Lang.GUI_EDIT_DATA_COLOR_LIGHT_GRAY),
new ColorData(DyeColor.WHITE, ParticleUtils.closestMatchWithFallback(false, "WHITE_DYE", "BONE_MEAL"), new OrdinaryColor(255, 255, 255), Lang.GUI_EDIT_DATA_COLOR_WHITE),
};
rainbowColorMapping = new ColorData[] {
colorMapping[0], // Red
colorMapping[1], // Orange
colorMapping[2], // Yellow
colorMapping[3], // Lime
colorMapping[7], // Light Blue
colorMapping[5], // Blue
colorMapping[8] // Purple
rainbowColorMapping = new ColorData[]{
colorMapping[0], // Red
colorMapping[1], // Orange
colorMapping[2], // Yellow
colorMapping[3], // Lime
colorMapping[7], // Light Blue
colorMapping[6], // Cyan
colorMapping[5], // Blue
colorMapping[8], // Purple
colorMapping[9] // Magenta
};
// Note: This is supposed to be a rainbow but there's actually a bug in Minecraft since 1.8 that makes a bunch of them gray
noteColorMapping = new ColorData[] {
colorMapping[7], // Light Blue
colorMapping[7], // Light Blue
colorMapping[13], // Gray
colorMapping[10], // Pink
colorMapping[9], // Magenta
colorMapping[9], // Magenta
colorMapping[0], // Red
colorMapping[2], // Yellow
colorMapping[2], // Yellow
colorMapping[14], // Light Gray
colorMapping[13], // Gray
colorMapping[6], // Cyan
colorMapping[6], // Cyan
colorMapping[6], // Cyan
colorMapping[5], // Blue
colorMapping[8], // Purple
colorMapping[8], // Purple
colorMapping[8], // Purple
colorMapping[13], // Gray
colorMapping[4], // Green
colorMapping[3], // Lime
colorMapping[2], // Yellow
colorMapping[4], // Green
colorMapping[7], // Light Blue
colorMapping[7] // Light Blue
noteColorMapping = new ColorData[]{
rainbowColorMapping[3], // 0 Lime
rainbowColorMapping[3], // 1 Lime
rainbowColorMapping[2], // 2 Yellow
rainbowColorMapping[1], // 3 Orange
rainbowColorMapping[1], // 4 Orange
rainbowColorMapping[0], // 5 Red
rainbowColorMapping[0], // 6 Red
rainbowColorMapping[0], // 7 Red
rainbowColorMapping[8], // 8 Magenta
rainbowColorMapping[8], // 9 Magenta
rainbowColorMapping[7], // 10 Purple
rainbowColorMapping[7], // 11 Purple
rainbowColorMapping[7], // 12 Purple
rainbowColorMapping[6], // 13 Blue
rainbowColorMapping[6], // 14 Blue
rainbowColorMapping[6], // 15 Blue
rainbowColorMapping[6], // 16 Blue
rainbowColorMapping[5], // 17 Cyan
rainbowColorMapping[5], // 18 Cyan
rainbowColorMapping[5], // 20 Lime
rainbowColorMapping[5], // 21 Lime
rainbowColorMapping[5], // 22 Lime
rainbowColorMapping[5], // 23 Lime
rainbowColorMapping[5] // 24 Lime
};
BLOCK_MATERIALS = new ArrayList<Material>();
ITEM_MATERIALS = new ArrayList<Material>();
// Note: Minecraft 1.8 through 1.13 had screwed up note color values, they were thankfully fixed in 1.14
noteColorMappingOld = new ColorData[]{
colorMapping[7], // 0 Light Blue
colorMapping[7], // 1 Light Blue
colorMapping[13], // 2 Gray
colorMapping[10], // 3 Pink
colorMapping[9], // 4 Magenta
colorMapping[9], // 5 Magenta
colorMapping[0], // 6 Red
colorMapping[2], // 7 Yellow
colorMapping[2], // 8 Yellow
colorMapping[14], // 9 Light Gray
colorMapping[13], // 10 Gray
colorMapping[6], // 11 Cyan
colorMapping[6], // 12 Cyan
colorMapping[6], // 13 Cyan
colorMapping[5], // 14 Blue
colorMapping[8], // 15 Purple
colorMapping[8], // 16 Purple
colorMapping[8], // 17 Purple
colorMapping[13], // 18 Gray
colorMapping[4], // 19 Green
colorMapping[3], // 20 Lime
colorMapping[2], // 21 Yellow
colorMapping[4], // 22 Green
colorMapping[7], // 23 Light Blue
colorMapping[7] // 24 Light Blue
};
BLOCK_MATERIALS = new ArrayList<>();
ITEM_MATERIALS = new ArrayList<>();
Inventory tempInventory = Bukkit.createInventory(null, 9);
for (Material mat : Material.values()) {
// Verify an ItemStack of the material can be placed into an inventory. In 1.12 and up this can easily be checked with mat.isItem(), but that doesn't exist pre-1.12
@ -111,223 +139,314 @@ public class GuiInventoryEditData extends GuiInventory {
}
}
public GuiInventoryEditData(PPlayer pplayer, ParticlePair editingParticle, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
public GuiInventoryEditData(PPlayer pplayer, ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_SELECT_DATA)));
this.fillBorder(BorderColor.MAGENTA);
ParticleEffect pe = editingParticle.getEffect();
if (pe.hasProperty(ParticleProperty.COLORABLE)) {
if (pe == ParticleEffect.NOTE) { // Note data
this.populateNoteData(editingParticle, callbackList, callbackListPosition);
this.populateNoteData(editingParticle, pageNumber, callbackList, callbackListPosition);
} else { // Color data
this.populateColorData(editingParticle, callbackList, callbackListPosition);
this.populateColorData(editingParticle, pageNumber, callbackList, callbackListPosition);
}
} else if (pe.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
if (pe == ParticleEffect.ITEM) { // Item data
this.populateItemData(editingParticle, callbackList, callbackListPosition);
this.populateItemData(editingParticle, pageNumber, callbackList, callbackListPosition);
} else { // Block data
this.populateBlockData(editingParticle, callbackList, callbackListPosition);
this.populateBlockData(editingParticle, pageNumber, callbackList, callbackListPosition);
}
}
// Back Button
GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GuiIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> {
callbackList.get(callbackListPosition - 1).execute();
});
GuiActionButton backButton = new GuiActionButton(
INVENTORY_SIZE - 1,
GuiIcon.BACK.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON),
new String[]{},
(button, isShiftClick) -> callbackList.get(callbackListPosition - 1).execute());
this.actionButtons.add(backButton);
this.populate();
}
/**
* Populates the Inventory with available color data options
*
* @param editingParticle The ParticlePair that's being edited
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
*
* @param editingParticle The ParticlePair that's being edited
* @param pageNumber The current page number
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
* @param callbackListPosition The index of the callbackList we're currently at
*/
private void populateColorData(ParticlePair editingParticle, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
private void populateColorData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
int index = 10;
int nextWrap = 17;
for (int i = 0; i < colorMapping.length; i++) {
ColorData colorData = colorMapping[i];
for (ColorData colorData : colorMapping) {
String formattedDisplayColor = ChatColor.RED.toString() + colorData.getOrdinaryColor().getRed() + " " + ChatColor.GREEN + colorData.getOrdinaryColor().getGreen() + " " + ChatColor.AQUA + colorData.getOrdinaryColor().getBlue();
// Color Data Buttons
GuiActionButton setColorButton = new GuiActionButton(index,
colorData,
colorData.getName(),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, formattedDisplayColor) },
(button, isShiftClick) -> {
editingParticle.setColor(colorData.getOrdinaryColor());
callbackList.get(callbackListPosition + 1).execute();
});
GuiActionButton setColorButton = new GuiActionButton(
index,
colorData,
colorData.getName(),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, formattedDisplayColor)},
(button, isShiftClick) -> {
editingParticle.setColor(colorData.getOrdinaryColor());
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setColorButton);
index++;
if (index == nextWrap) { // Loop around border
nextWrap += 9;
index += 2;
index += 2;
}
}
// Rainbow Color Data Button
GuiActionButton setRainbowColorButton = new GuiActionButton(39,
rainbowColorMapping,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RAINBOW),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RAINBOW)) },
(button, isShiftClick) -> {
editingParticle.setColor(new OrdinaryColor(999, 999, 999));
callbackList.get(callbackListPosition + 1).execute();
});
GuiActionButton setRainbowColorButton = new GuiActionButton(
39,
rainbowColorMapping,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RAINBOW),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RAINBOW))},
(button, isShiftClick) -> {
editingParticle.setColor(new OrdinaryColor(999, 999, 999));
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setRainbowColorButton);
// Rainbow Color Data Button
List<ColorData> randomizedColorsList = Arrays.asList(colorMapping.clone());
Collections.shuffle(randomizedColorsList);
ColorData[] randomizedColors = new ColorData[randomizedColorsList.size()];
randomizedColors = randomizedColorsList.toArray(randomizedColors);
GuiActionButton setRandomColorButton = new GuiActionButton(41,
randomizedColors,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RANDOM),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RANDOM)) },
(button, isShiftClick) -> {
editingParticle.setColor(new OrdinaryColor(998, 998, 998));
callbackList.get(callbackListPosition + 1).execute();
});
randomizedColors,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RANDOM),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RANDOM))},
(button, isShiftClick) -> {
editingParticle.setColor(new OrdinaryColor(998, 998, 998));
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setRandomColorButton);
}
/**
* Populates the Inventory with available note data options
*
* @param editingParticle The ParticlePair that's being edited
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
*
* @param editingParticle The ParticlePair that's being edited
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
* @param pageNumber The current page number
* @param callbackListPosition The index of the callbackList we're currently at
*/
private void populateNoteData(ParticlePair editingParticle, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
for (int i = 0; i < noteColorMapping.length; i++) {
ColorData colorData = noteColorMapping[i];
private void populateNoteData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
int numberOfItems = noteColorMapping.length;
int itemsPerPage = 14;
int maxPages = (int) Math.ceil((double) numberOfItems / itemsPerPage);
int slot = 10;
int nextWrap = 17;
int maxSlot = 25;
for (int i = (pageNumber - 1) * itemsPerPage; i < numberOfItems; i++) {
ColorData colorData = NMSUtil.getVersionNumber() > 13 ? noteColorMapping[i] : noteColorMappingOld[i];
String formattedDisplayName = LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_SELECT_DATA_NOTE, i) + " (" + colorData.getName() + LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + ")";
String formattedDescription = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.GUI_SELECT_DATA_NOTE, i));
// Note Color Buttons
int noteIndex = i;
GuiActionButton setColorButton = new GuiActionButton(i,
colorData,
formattedDisplayName,
new String[] { formattedDescription },
(button, isShiftClick) -> {
editingParticle.setNoteColor(new NoteColor(noteIndex));
callbackList.get(callbackListPosition + 1).execute();
});
GuiActionButton setColorButton = new GuiActionButton(
slot,
colorData,
formattedDisplayName,
new String[]{formattedDescription},
(button, isShiftClick) -> {
editingParticle.setNoteColor(new NoteColor(noteIndex));
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setColorButton);
slot++;
if (slot == nextWrap) { // Loop around border
nextWrap += 9;
slot += 2;
}
if (slot > maxSlot) break; // Overflowed the available space
}
// Rainbow Note Data Button
GuiActionButton setRainbowColorButton = new GuiActionButton(39,
rainbowColorMapping,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RAINBOW),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RAINBOW)) },
(button, isShiftClick) -> {
editingParticle.setNoteColor(new NoteColor(99));
callbackList.get(callbackListPosition + 1).execute();
});
GuiActionButton setRainbowColorButton = new GuiActionButton(
39,
rainbowColorMapping,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RAINBOW),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RAINBOW))},
(button, isShiftClick) -> {
editingParticle.setNoteColor(new NoteColor(99));
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setRainbowColorButton);
// Rainbow Note Data Button
List<ColorData> randomizedColorsList = Arrays.asList(colorMapping.clone());
Collections.shuffle(randomizedColorsList);
ColorData[] randomizedColors = new ColorData[randomizedColorsList.size()];
randomizedColors = randomizedColorsList.toArray(randomizedColors);
GuiActionButton setRandomColorButton = new GuiActionButton(41,
randomizedColors,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RANDOM),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RANDOM)) },
(button, isShiftClick) -> {
editingParticle.setNoteColor(new NoteColor(98));
callbackList.get(callbackListPosition + 1).execute();
});
GuiActionButton setRandomColorButton = new GuiActionButton(
41,
randomizedColors,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.RANDOM),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, LangManager.getText(Lang.RANDOM))},
(button, isShiftClick) -> {
editingParticle.setNoteColor(new NoteColor(98));
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setRandomColorButton);
// Previous page button
if (pageNumber != 1) {
GuiActionButton previousPageButton = new GuiActionButton(
INVENTORY_SIZE - 6,
GuiIcon.PREVIOUS_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PREVIOUS_PAGE_BUTTON, pageNumber - 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditData(this.pplayer, editingParticle, pageNumber - 1, callbackList, callbackListPosition)));
this.actionButtons.add(previousPageButton);
}
// Next page button
if (pageNumber != maxPages) {
GuiActionButton nextPageButton = new GuiActionButton(
INVENTORY_SIZE - 4,
GuiIcon.NEXT_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_NEXT_PAGE_BUTTON, pageNumber + 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditData(this.pplayer, editingParticle, pageNumber + 1, callbackList, callbackListPosition)));
this.actionButtons.add(nextPageButton);
}
}
/**
* Populates the Inventory with available item data options
*
* @param editingParticle The ParticlePair that's being edited
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
*
* @param editingParticle The ParticlePair that's being edited
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
* @param pageNumber The current page number
* @param callbackListPosition The index of the callbackList we're currently at
*/
private void populateItemData(ParticlePair editingParticle, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
List<Material> materialBag = new ArrayList<Material>();
while (materialBag.size() < 36) { // Grab 36 random materials that are an item
Material randomMaterial = ITEM_MATERIALS.get(RANDOM.nextInt(ITEM_MATERIALS.size()));
if (!materialBag.contains(randomMaterial)) materialBag.add(randomMaterial);
}
for (int i = 0; i < materialBag.size(); i++) {
private void populateItemData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
int numberOfItems = ITEM_MATERIALS.size();
int itemsPerPage = 28;
int maxPages = (int) Math.ceil((double) numberOfItems / itemsPerPage);
int slot = 10;
int nextWrap = 17;
int maxSlot = 43;
for (int i = (pageNumber - 1) * itemsPerPage; i < numberOfItems; i++) {
// Item Data Button
Material material = materialBag.get(i);
GuiActionButton setRainbowColorButton = new GuiActionButton(i,
material,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + material.name().toLowerCase(),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, material.name().toLowerCase()) },
(button, isShiftClick) -> {
editingParticle.setItemMaterial(material);
callbackList.get(callbackListPosition + 1).execute();
});
Material material = ITEM_MATERIALS.get(i);
GuiActionButton setRainbowColorButton = new GuiActionButton(
slot,
material,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + material.name().toLowerCase(),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, material.name().toLowerCase())},
(button, isShiftClick) -> {
editingParticle.setItemMaterial(material);
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setRainbowColorButton);
slot++;
if (slot == nextWrap) { // Loop around border
nextWrap += 9;
slot += 2;
}
if (slot > maxSlot) break; // Overflowed the available space
}
// Previous page button
if (pageNumber != 1) {
GuiActionButton previousPageButton = new GuiActionButton(
INVENTORY_SIZE - 6,
GuiIcon.PREVIOUS_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PREVIOUS_PAGE_BUTTON, pageNumber - 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditData(this.pplayer, editingParticle, pageNumber - 1, callbackList, callbackListPosition)));
this.actionButtons.add(previousPageButton);
}
// Next page button
if (pageNumber != maxPages) {
GuiActionButton nextPageButton = new GuiActionButton(
INVENTORY_SIZE - 4,
GuiIcon.NEXT_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_NEXT_PAGE_BUTTON, pageNumber + 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditData(this.pplayer, editingParticle, pageNumber + 1, callbackList, callbackListPosition)));
this.actionButtons.add(nextPageButton);
}
// Randomize Button, re-randomizes the icons
GuiActionButton randomizeButton = new GuiActionButton(45,
GuiIcon.RANDOMIZE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_SELECT_DATA_RANDOMIZE_ITEMS),
new String[] { LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_SELECT_DATA_RANDOMIZE_ITEMS_DESCRIPTION) },
(block, isShiftClick) -> {
callbackList.get(callbackListPosition).execute(); // Just reopen the same inventory
});
this.actionButtons.add(randomizeButton);
}
/**
* Populates the Inventory with available block data options
*
* @param editingParticle The ParticlePair that's being edited
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
*
* @param editingParticle The ParticlePair that's being edited
* @param callbackList The List of GuiInventoryEditFinishedCallbacks
* @param pageNumber The current page number
* @param callbackListPosition The index of the callbackList we're currently at
*/
private void populateBlockData(ParticlePair editingParticle, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
List<Material> materialBag = new ArrayList<Material>();
while (materialBag.size() < 36) { // Grab 36 random materials that are an item
Material randomMaterial = BLOCK_MATERIALS.get(RANDOM.nextInt(BLOCK_MATERIALS.size()));
if (!materialBag.contains(randomMaterial)) materialBag.add(randomMaterial);
}
for (int i = 0; i < materialBag.size(); i++) {
private void populateBlockData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
int numberOfItems = BLOCK_MATERIALS.size();
int itemsPerPage = 28;
int maxPages = (int) Math.ceil((double) numberOfItems / itemsPerPage);
int slot = 10;
int nextWrap = 17;
int maxSlot = 43;
for (int i = (pageNumber - 1) * itemsPerPage; i < numberOfItems; i++) {
// Item Data Button
Material material = materialBag.get(i);
GuiActionButton setRainbowColorButton = new GuiActionButton(i,
material,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + material.name().toLowerCase(),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, material.name().toLowerCase()) },
(button, isShiftClick) -> {
editingParticle.setBlockMaterial(material);
callbackList.get(callbackListPosition + 1).execute();
});
Material material = BLOCK_MATERIALS.get(i);
GuiActionButton setRainbowColorButton = new GuiActionButton(
slot,
material,
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + material.name().toLowerCase(),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_DATA_DESCRIPTION, material.name().toLowerCase())},
(button, isShiftClick) -> {
editingParticle.setBlockMaterial(material);
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(setRainbowColorButton);
slot++;
if (slot == nextWrap) { // Loop around border
nextWrap += 9;
slot += 2;
}
if (slot > maxSlot) break; // Overflowed the available space
}
// Previous page button
if (pageNumber != 1) {
GuiActionButton previousPageButton = new GuiActionButton(
INVENTORY_SIZE - 6,
GuiIcon.PREVIOUS_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PREVIOUS_PAGE_BUTTON, pageNumber - 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditData(this.pplayer, editingParticle, pageNumber - 1, callbackList, callbackListPosition)));
this.actionButtons.add(previousPageButton);
}
// Next page button
if (pageNumber != maxPages) {
GuiActionButton nextPageButton = new GuiActionButton(
INVENTORY_SIZE - 4,
GuiIcon.NEXT_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_NEXT_PAGE_BUTTON, pageNumber + 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditData(this.pplayer, editingParticle, pageNumber + 1, callbackList, callbackListPosition)));
this.actionButtons.add(nextPageButton);
}
// Randomize Button, re-randomizes the icons
GuiActionButton randomizeButton = new GuiActionButton(45,
GuiIcon.RANDOMIZE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_SELECT_DATA_RANDOMIZE_BLOCKS),
new String[] { LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_SELECT_DATA_RANDOMIZE_BLOCKS_DESCRIPTION) },
(block, isShiftClick) -> {
callbackList.get(callbackListPosition).execute(); // Just reopen the same inventory
});
this.actionButtons.add(randomizeButton);
}
/**
* A data class used for storing information about the color data
*/
@ -336,44 +455,44 @@ public class GuiInventoryEditData extends GuiInventory {
private Material material;
private OrdinaryColor ordinaryColor;
private Lang name;
public ColorData(DyeColor dyeColor, Material material, OrdinaryColor ordinaryColor, Lang name) {
this.dyeColor = dyeColor;
this.material = material;
this.ordinaryColor = ordinaryColor;
this.name = name;
}
/**
* Get the DyeColor
*
* Get the DyeColor
*
* @return The DyeColor
*/
public DyeColor getDyeColor() {
return this.dyeColor;
}
/**
* Get the Material representing this color
*
*
* @return The Material
*/
public Material getMaterial() {
return this.material;
}
/**
* Get the OrdinaryColor representing this color
*
*
* @return The OrdinaryColor
*/
public OrdinaryColor getOrdinaryColor() {
return this.ordinaryColor;
}
/**
* Get the name of this color
*
*
* @return The name of this color
*/
public String getName() {

View file

@ -1,9 +1,5 @@
package com.esophose.playerparticles.gui;
import java.util.List;
import org.bukkit.Bukkit;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.PermissionManager;
@ -12,33 +8,78 @@ import com.esophose.playerparticles.particles.PPlayer;
import com.esophose.playerparticles.particles.ParticleEffect;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.util.ParticleUtils;
import org.bukkit.Bukkit;
import java.util.List;
public class GuiInventoryEditEffect extends GuiInventory {
public GuiInventoryEditEffect(PPlayer pplayer, ParticlePair editingParticle, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
public GuiInventoryEditEffect(PPlayer pplayer, ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_SELECT_EFFECT)));
this.fillBorder(BorderColor.LIGHT_BLUE);
// Select Effect Buttons
List<ParticleEffect> effectsUserHasPermissionFor = PermissionManager.getEffectsUserHasPermissionFor(pplayer.getPlayer());
for (int i = 0; i < effectsUserHasPermissionFor.size(); i++) {
int numberOfItems = effectsUserHasPermissionFor.size();
int itemsPerPage = 28;
int maxPages = (int) Math.ceil((double) numberOfItems / itemsPerPage);
int slot = 10;
int nextWrap = 17;
int maxSlot = 43;
for (int i = (pageNumber - 1) * itemsPerPage; i < numberOfItems; i++) {
ParticleEffect effect = effectsUserHasPermissionFor.get(i);
GuiActionButton selectButton = new GuiActionButton(i,
GuiIcon.EFFECT.get(effect.getName()),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + ParticleUtils.formatName(effect.getName()),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, ParticleUtils.formatName(effect.getName())) },
(button, isShiftClick) -> {
editingParticle.setEffect(effect);
callbackList.get(callbackListPosition + 1).execute();
});
GuiActionButton selectButton = new GuiActionButton(
slot,
GuiIcon.EFFECT.get(effect.getName()),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + ParticleUtils.formatName(effect.getName()),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, ParticleUtils.formatName(effect.getName()))},
(button, isShiftClick) -> {
editingParticle.setEffect(effect);
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(selectButton);
slot++;
if (slot == nextWrap) { // Loop around border
nextWrap += 9;
slot += 2;
}
if (slot > maxSlot) break; // Overflowed the available space
}
// Back Button
GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GuiIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> {
callbackList.get(callbackListPosition - 1).execute();
});
GuiActionButton backButton = new GuiActionButton(
INVENTORY_SIZE - 1,
GuiIcon.BACK.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON),
new String[]{},
(button, isShiftClick) -> callbackList.get(callbackListPosition - 1).execute());
this.actionButtons.add(backButton);
// Previous page button
if (pageNumber != 1) {
GuiActionButton previousPageButton = new GuiActionButton(
INVENTORY_SIZE - 6,
GuiIcon.PREVIOUS_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PREVIOUS_PAGE_BUTTON, pageNumber - 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, pageNumber - 1, callbackList, callbackListPosition)));
this.actionButtons.add(previousPageButton);
}
// Next page button
if (pageNumber != maxPages) {
GuiActionButton nextPageButton = new GuiActionButton(
INVENTORY_SIZE - 4,
GuiIcon.NEXT_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_NEXT_PAGE_BUTTON, pageNumber + 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, pageNumber + 1, callbackList, callbackListPosition)));
this.actionButtons.add(nextPageButton);
}
this.populate();
}

View file

@ -1,10 +1,5 @@
package com.esophose.playerparticles.gui;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import com.esophose.playerparticles.manager.DataManager;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
@ -13,114 +8,123 @@ import com.esophose.playerparticles.particles.PPlayer;
import com.esophose.playerparticles.particles.ParticleEffect.ParticleProperty;
import com.esophose.playerparticles.particles.ParticleGroup;
import com.esophose.playerparticles.particles.ParticlePair;
import org.bukkit.Bukkit;
import java.util.ArrayList;
import java.util.List;
public class GuiInventoryEditParticle extends GuiInventory {
public GuiInventoryEditParticle(PPlayer pplayer, ParticlePair editingParticle) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_EDITING_PARTICLE, editingParticle.getId())));
this.fillBorder(BorderColor.RED);
// Particle Info Icon
String particleInfo = LangManager.getText(Lang.GUI_PARTICLE_INFO, editingParticle.getId(), editingParticle.getEffect().getName(), editingParticle.getStyle().getName(), editingParticle.getDataString());
GuiActionButton particleInfoIcon = new GuiActionButton(13,
GuiIcon.PARTICLES.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_PARTICLE_NAME, editingParticle.getId()),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + particleInfo },
(button, isShiftClick) -> {});
GuiActionButton particleInfoIcon = new GuiActionButton(
13,
GuiIcon.PARTICLES.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_PARTICLE_NAME, editingParticle.getId()),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + particleInfo},
(button, isShiftClick) -> { });
this.actionButtons.add(particleInfoIcon);
// Edit Effect Button
GuiActionButton editEffectButton = new GuiActionButton(38,
GuiIcon.EDIT_EFFECT.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_EFFECT),
new String[] { LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_EDIT_EFFECT_DESCRIPTION) },
(button, isShiftClick) -> {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<GuiInventoryEditFinishedCallback>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setEffect(editingParticle.getEffect());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle));
});
callbacks.get(1).execute();
});
GuiActionButton editEffectButton = new GuiActionButton(
38,
GuiIcon.EDIT_EFFECT.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_EFFECT),
new String[]{LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_EDIT_EFFECT_DESCRIPTION)},
(button, isShiftClick) -> {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, 1, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setEffect(editingParticle.getEffect());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle));
});
callbacks.get(1).execute();
});
this.actionButtons.add(editEffectButton);
// Edit Style Button
GuiActionButton editStyleButton = new GuiActionButton(40,
GuiIcon.EDIT_STYLE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_STYLE),
new String[] { LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_EDIT_STYLE_DESCRIPTION) },
(button, isShiftClick) -> {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<GuiInventoryEditFinishedCallback>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setStyle(editingParticle.getStyle());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle));
});
callbacks.get(1).execute();
});
GuiActionButton editStyleButton = new GuiActionButton(40,
GuiIcon.EDIT_STYLE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_STYLE),
new String[]{LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_EDIT_STYLE_DESCRIPTION)},
(button, isShiftClick) -> {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, 1, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setStyle(editingParticle.getStyle());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle));
});
callbacks.get(1).execute();
});
this.actionButtons.add(editStyleButton);
// Edit Data Button
boolean usesData = editingParticle.getEffect().hasProperty(ParticleProperty.COLORABLE) || editingParticle.getEffect().hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA);
GuiActionButton editDataButton = new GuiActionButton(42,
GuiIcon.EDIT_DATA.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_DATA),
usesData ? new String[] { LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_EDIT_DATA_DESCRIPTION) } :
new String[] { LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_DATA_UNAVAILABLE) },
(button, isShiftClick) -> {
if (usesData) {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<GuiInventoryEditFinishedCallback>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditData(pplayer, editingParticle, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setColor(editingParticle.getColor());
particle.setNoteColor(editingParticle.getNoteColor());
particle.setItemMaterial(editingParticle.getItemMaterial());
particle.setBlockMaterial(editingParticle.getBlockMaterial());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle));
});
callbacks.get(1).execute();
}
});
GuiActionButton editDataButton = new GuiActionButton(42,
GuiIcon.EDIT_DATA.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_EDIT_DATA),
usesData ? new String[]{LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_EDIT_DATA_DESCRIPTION)} :
new String[]{LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_EDIT_DATA_UNAVAILABLE)},
(button, isShiftClick) -> {
if (usesData) {
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditData(pplayer, editingParticle, 1, callbacks, 1)));
callbacks.add(() -> {
ParticleGroup group = pplayer.getActiveParticleGroup();
for (ParticlePair particle : group.getParticles()) {
if (particle.getId() == editingParticle.getId()) {
particle.setColor(editingParticle.getColor());
particle.setNoteColor(editingParticle.getNoteColor());
particle.setItemMaterial(editingParticle.getItemMaterial());
particle.setBlockMaterial(editingParticle.getBlockMaterial());
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, editingParticle));
});
callbacks.get(1).execute();
}
});
this.actionButtons.add(editDataButton);
// Back Button
GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GuiIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> {
GuiHandler.transition(new GuiInventoryManageParticles(pplayer));
});
GuiActionButton backButton = new GuiActionButton(
INVENTORY_SIZE - 1,
GuiIcon.BACK.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryManageParticles(pplayer)));
this.actionButtons.add(backButton);
this.populate();
}

View file

@ -1,9 +1,5 @@
package com.esophose.playerparticles.gui;
import java.util.List;
import org.bukkit.Bukkit;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.PermissionManager;
@ -12,33 +8,78 @@ import com.esophose.playerparticles.particles.PPlayer;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.styles.api.ParticleStyle;
import com.esophose.playerparticles.util.ParticleUtils;
import org.bukkit.Bukkit;
import java.util.List;
public class GuiInventoryEditStyle extends GuiInventory {
public GuiInventoryEditStyle(PPlayer pplayer, ParticlePair editingParticle, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
public GuiInventoryEditStyle(PPlayer pplayer, ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_SELECT_STYLE)));
this.fillBorder(BorderColor.BLUE);
// Select Style Buttons
List<ParticleStyle> stylesUserHasPermissionFor = PermissionManager.getStylesUserHasPermissionFor(pplayer.getPlayer());
for (int i = 0; i < stylesUserHasPermissionFor.size(); i++) {
int numberOfItems = stylesUserHasPermissionFor.size();
int itemsPerPage = 28;
int maxPages = (int) Math.ceil((double) numberOfItems / itemsPerPage);
int slot = 10;
int nextWrap = 17;
int maxSlot = 43;
for (int i = (pageNumber - 1) * itemsPerPage; i < numberOfItems; i++) {
ParticleStyle style = stylesUserHasPermissionFor.get(i);
GuiActionButton selectButton = new GuiActionButton(i,
GuiIcon.STYLE.get(style.getName()),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + ParticleUtils.formatName(style.getName()),
new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, ParticleUtils.formatName(style.getName())) },
(button, isShiftClick) -> {
editingParticle.setStyle(style);
callbackList.get(callbackListPosition + 1).execute();
});
GuiActionButton selectButton = new GuiActionButton(
slot,
GuiIcon.STYLE.get(style.getName()),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + ParticleUtils.formatName(style.getName()),
new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SELECT_EFFECT_DESCRIPTION, ParticleUtils.formatName(style.getName()))},
(button, isShiftClick) -> {
editingParticle.setStyle(style);
callbackList.get(callbackListPosition + 1).execute();
});
this.actionButtons.add(selectButton);
slot++;
if (slot == nextWrap) { // Loop around border
nextWrap += 9;
slot += 2;
}
if (slot > maxSlot) break; // Overflowed the available space
}
// Back Button
GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GuiIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> {
callbackList.get(callbackListPosition - 1).execute();
});
GuiActionButton backButton = new GuiActionButton(
INVENTORY_SIZE - 1,
GuiIcon.BACK.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON),
new String[]{},
(button, isShiftClick) -> callbackList.get(callbackListPosition - 1).execute());
this.actionButtons.add(backButton);
// Previous page button
if (pageNumber != 1) {
GuiActionButton previousPageButton = new GuiActionButton(
INVENTORY_SIZE - 6,
GuiIcon.PREVIOUS_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PREVIOUS_PAGE_BUTTON, pageNumber - 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, pageNumber - 1, callbackList, callbackListPosition)));
this.actionButtons.add(previousPageButton);
}
// Next page button
if (pageNumber != maxPages) {
GuiActionButton nextPageButton = new GuiActionButton(
INVENTORY_SIZE - 4,
GuiIcon.NEXT_PAGE.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_NEXT_PAGE_BUTTON, pageNumber + 1, maxPages),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, pageNumber + 1, callbackList, callbackListPosition)));
this.actionButtons.add(nextPageButton);
}
this.populate();
}

View file

@ -1,44 +1,50 @@
package com.esophose.playerparticles.gui;
import java.util.Comparator;
import java.util.List;
import org.bukkit.Bukkit;
import com.esophose.playerparticles.manager.DataManager;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.ParticleGroupPresetManager;
import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
import com.esophose.playerparticles.manager.SettingManager.PSetting;
import com.esophose.playerparticles.particles.PPlayer;
import com.esophose.playerparticles.particles.ParticleGroup;
import com.esophose.playerparticles.particles.ParticleGroupPreset;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.util.ParticleUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.Comparator;
import java.util.List;
public class GuiInventoryLoadPresetGroups extends GuiInventory {
public GuiInventoryLoadPresetGroups(PPlayer pplayer) {
public GuiInventoryLoadPresetGroups(PPlayer pplayer, boolean isEndPoint) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_LOAD_A_PRESET_GROUP)));
this.fillBorder(BorderColor.GREEN);
Player player = pplayer.getPlayer();
int index = 10;
int nextWrap = 17;
int maxIndex = 43;
List<ParticleGroupPreset> groups = ParticleGroupPresetManager.getPresetGroupsForPlayer(pplayer.getPlayer());
for (ParticleGroupPreset group : groups) {
if (!group.getGroup().canPlayerUse(player))
continue;
List<ParticlePair> particles = group.getGroup().getParticles();
particles.sort(Comparator.comparingInt(ParticlePair::getId));
String[] lore = new String[particles.size() + 1];
lore[0] = LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_LOAD, particles.size());
int i = 1;
for (ParticlePair particle : particles) {
lore[i] = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), ParticleUtils.formatName(particle.getEffect().getName()), ParticleUtils.formatName(particle.getStyle().getName()), particle.getDataString());
i++;
}
}
// Load Group Buttons
GuiActionButton groupButton = new GuiActionButton(index, group.getGuiIcon(), LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + group.getDisplayName(), lore, (button, isShiftClick) -> {
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
@ -46,25 +52,43 @@ public class GuiInventoryLoadPresetGroups extends GuiInventory {
for (ParticlePair particle : particles)
activeGroup.getParticles().add(particle.clone());
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
pplayer.getPlayer().closeInventory();
if (PSetting.GUI_CLOSE_AFTER_GROUP_SELECTED.getBoolean()) {
pplayer.getPlayer().closeInventory();
}
});
this.actionButtons.add(groupButton);
index++;
if (index == nextWrap) { // Loop around border
nextWrap += 9;
index += 2;
index += 2;
}
if (index > maxIndex) break; // Overflowed the available space
}
// Back Button
GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GuiIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> {
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
this.actionButtons.add(backButton);
if (!isEndPoint) {
// Back Button
GuiActionButton backButton = new GuiActionButton(
INVENTORY_SIZE - 1, GuiIcon.BACK.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
this.actionButtons.add(backButton);
} else {
// Reset Particles Button
GuiActionButton resetParticles = new GuiActionButton(
49,
GuiIcon.RESET.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_RESET_PARTICLES),
new String[]{LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_RESET_PARTICLES_DESCRIPTION)},
(button, isShiftClick) -> {
// Reset particles
DataManager.saveParticleGroup(pplayer.getUniqueId(), ParticleGroup.getDefaultGroup());
});
this.actionButtons.add(resetParticles);
}
this.populate();
}

View file

@ -1,42 +1,42 @@
package com.esophose.playerparticles.gui;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.bukkit.Bukkit;
import com.esophose.playerparticles.gui.hook.PlayerChatHook;
import com.esophose.playerparticles.gui.hook.PlayerChatHookData;
import com.esophose.playerparticles.manager.DataManager;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.PermissionManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.PermissionManager;
import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
import com.esophose.playerparticles.manager.SettingManager.PSetting;
import com.esophose.playerparticles.particles.PPlayer;
import com.esophose.playerparticles.particles.ParticleGroup;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.util.ParticleUtils;
import org.bukkit.Bukkit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class GuiInventoryManageGroups extends GuiInventory {
public GuiInventoryManageGroups(PPlayer pplayer) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_MANAGE_YOUR_GROUPS)));
this.fillBorder(BorderColor.BROWN);
int index = 10;
int nextWrap = 17;
int maxIndex = 35;
List<ParticleGroup> groups = pplayer.getParticleGroups();
groups.sort(Comparator.comparing(ParticleGroup::getName));
for (ParticleGroup group : groups) {
if (group.getName().equals(ParticleGroup.DEFAULT_NAME)) continue;
List<ParticlePair> particles = group.getParticles();
particles.sort(Comparator.comparingInt(ParticlePair::getId));
String[] lore = new String[particles.size() + 2];
lore[0] = LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_LOAD, particles.size());
int i = 1;
@ -45,109 +45,120 @@ public class GuiInventoryManageGroups extends GuiInventory {
i++;
}
lore[i] = LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SHIFT_CLICK_TO_DELETE);
// Load Group Buttons
GuiActionButton groupButton = new GuiActionButton(index, GuiIcon.GROUPS.get(), LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + group.getName(), lore, (button, isShiftClick) -> {
if (isShiftClick) {
DataManager.removeParticleGroup(pplayer.getUniqueId(), group);
this.actionButtons.remove(button);
this.inventory.setItem(button.getSlot(), null);
} else {
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
activeGroup.getParticles().clear();
for (ParticlePair particle : particles)
activeGroup.getParticles().add(particle.clone());
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
pplayer.getPlayer().closeInventory();
}
});
GuiActionButton groupButton = new GuiActionButton(
index,
GuiIcon.GROUPS.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + group.getName(),
lore,
(button, isShiftClick) -> {
if (isShiftClick) {
DataManager.removeParticleGroup(pplayer.getUniqueId(), group);
this.actionButtons.remove(button);
this.inventory.setItem(button.getSlot(), null);
} else {
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
activeGroup.getParticles().clear();
for (ParticlePair particle : particles)
activeGroup.getParticles().add(particle.clone());
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
if (PSetting.GUI_CLOSE_AFTER_GROUP_SELECTED.getBoolean()) {
pplayer.getPlayer().closeInventory();
}
}
});
this.actionButtons.add(groupButton);
index++;
if (index == nextWrap) { // Loop around border
nextWrap += 9;
index += 2;
index += 2;
}
if (index > maxIndex) break; // Overflowed the available space
}
boolean hasReachedMax = PermissionManager.hasPlayerReachedMaxGroups(pplayer);
boolean hasParticles = !pplayer.getActiveParticles().isEmpty();
String[] lore;
if (hasReachedMax) {
lore = new String[] {
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SAVE_GROUP_FULL)
lore = new String[]{
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SAVE_GROUP_FULL)
};
} else if (!hasParticles) {
lore = new String[] {
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SAVE_GROUP_NO_PARTICLES)
lore = new String[]{
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SAVE_GROUP_NO_PARTICLES)
};
} else {
lore = new String[] { LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION) };
lore = new String[]{LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_SAVE_GROUP_DESCRIPTION)};
}
// Save Group Button
GuiActionButton saveGroupButton = new GuiActionButton(40,
GuiIcon.CREATE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_SAVE_GROUP),
lore,
(button, isShiftClick) -> {
if (hasReachedMax || !hasParticles) return;
PlayerChatHook.addHook(new PlayerChatHookData(pplayer.getUniqueId(), 15, (textEntered) -> {
if (textEntered == null || textEntered.equalsIgnoreCase("cancel")) {
GuiHandler.transition(new GuiInventoryManageGroups(pplayer));
} else {
String groupName = textEntered.split(" ")[0];
// Check that the groupName isn't the reserved name
if (groupName.equalsIgnoreCase(ParticleGroup.DEFAULT_NAME)) {
LangManager.sendMessage(pplayer, Lang.GROUP_RESERVED);
return;
}
// The database column can only hold up to 100 characters, cut it off there
if (groupName.length() >= 100) {
groupName = groupName.substring(0, 100);
}
// Use the existing group if available, otherwise create a new one
ParticleGroup group = pplayer.getParticleGroupByName(groupName);
boolean groupUpdated = false;
if (group == null) {
List<ParticlePair> particles = new ArrayList<ParticlePair>();
for (ParticlePair particle : pplayer.getActiveParticles())
particles.add(particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group
group = new ParticleGroup(groupName, particles);
} else {
groupUpdated = true;
}
// Apply changes and notify player
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
if (groupUpdated) {
LangManager.sendMessage(pplayer, Lang.GROUP_SAVE_SUCCESS_OVERWRITE, groupName);
} else {
LangManager.sendMessage(pplayer, Lang.GROUP_SAVE_SUCCESS, groupName);
}
GuiHandler.transition(new GuiInventoryManageGroups(pplayer));
}
}));
pplayer.getPlayer().closeInventory();
});
GuiActionButton saveGroupButton = new GuiActionButton(
40,
GuiIcon.CREATE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_SAVE_GROUP),
lore,
(button, isShiftClick) -> {
if (hasReachedMax || !hasParticles) return;
PlayerChatHook.addHook(new PlayerChatHookData(pplayer.getUniqueId(), 15, (textEntered) -> {
if (textEntered == null || textEntered.equalsIgnoreCase("cancel")) {
GuiHandler.transition(new GuiInventoryManageGroups(pplayer));
} else {
String groupName = textEntered.split(" ")[0];
// Check that the groupName isn't the reserved name
if (groupName.equalsIgnoreCase(ParticleGroup.DEFAULT_NAME)) {
LangManager.sendMessage(pplayer, Lang.GROUP_RESERVED);
return;
}
// The database column can only hold up to 100 characters, cut it off there
if (groupName.length() >= 100) {
groupName = groupName.substring(0, 100);
}
// Use the existing group if available, otherwise create a new one
ParticleGroup group = pplayer.getParticleGroupByName(groupName);
boolean groupUpdated = false;
if (group == null) {
List<ParticlePair> particles = new ArrayList<ParticlePair>();
for (ParticlePair particle : pplayer.getActiveParticles())
particles.add(particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group
group = new ParticleGroup(groupName, particles);
} else {
groupUpdated = true;
}
// Apply changes and notify player
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
if (groupUpdated) {
LangManager.sendMessage(pplayer, Lang.GROUP_SAVE_SUCCESS_OVERWRITE, groupName);
} else {
LangManager.sendMessage(pplayer, Lang.GROUP_SAVE_SUCCESS, groupName);
}
GuiHandler.transition(new GuiInventoryManageGroups(pplayer));
}
}));
pplayer.getPlayer().closeInventory();
});
this.actionButtons.add(saveGroupButton);
// Back Button
GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GuiIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> {
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
GuiActionButton backButton = new GuiActionButton(
INVENTORY_SIZE - 1,
GuiIcon.BACK.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
this.actionButtons.add(backButton);
this.populate();
}

View file

@ -1,128 +1,132 @@
package com.esophose.playerparticles.gui;
import com.esophose.playerparticles.manager.DataManager;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.PermissionManager;
import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
import com.esophose.playerparticles.particles.PPlayer;
import com.esophose.playerparticles.particles.ParticleEffect.ParticleProperty;
import com.esophose.playerparticles.particles.ParticleGroup;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.util.ParticleUtils;
import org.bukkit.Bukkit;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.bukkit.Bukkit;
import com.esophose.playerparticles.manager.DataManager;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.PermissionManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import com.esophose.playerparticles.manager.SettingManager.GuiIcon;
import com.esophose.playerparticles.particles.PPlayer;
import com.esophose.playerparticles.particles.ParticleGroup;
import com.esophose.playerparticles.particles.ParticlePair;
import com.esophose.playerparticles.particles.ParticleEffect.ParticleProperty;
import com.esophose.playerparticles.util.ParticleUtils;
public class GuiInventoryManageParticles extends GuiInventory {
public GuiInventoryManageParticles(PPlayer pplayer) {
super(pplayer, Bukkit.createInventory(pplayer.getPlayer(), INVENTORY_SIZE, LangManager.getText(Lang.GUI_MANAGE_YOUR_PARTICLES)));
this.fillBorder(BorderColor.ORANGE);
// Manage/Delete Particle Buttons
List<ParticlePair> particles = pplayer.getActiveParticles();
particles.sort(Comparator.comparingInt(ParticlePair::getId));
int index = 10;
int nextWrap = 17;
int maxIndex = 35;
for (ParticlePair particle : particles) {
GuiActionButton selectButton = new GuiActionButton(index,
GuiIcon.PARTICLES.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_PARTICLE_NAME, particle.getId()),
new String[] {
LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_EDIT_PARTICLE, particles.size()),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), ParticleUtils.formatName(particle.getEffect().getName()), ParticleUtils.formatName(particle.getStyle().getName()), particle.getDataString()),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SHIFT_CLICK_TO_DELETE)
},
(button, isShiftClick) -> {
if (!isShiftClick) {
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, particle));
} else {
// Delete particle
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
for (ParticlePair pp : activeGroup.getParticles()) {
if (pp.getId() == particle.getId()) {
activeGroup.getParticles().remove(pp);
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
// Update inventory to reflect deletion
this.actionButtons.remove(button);
this.inventory.setItem(button.getSlot(), null);
}
});
GuiActionButton selectButton = new GuiActionButton(
index,
GuiIcon.PARTICLES.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_PARTICLE_NAME, particle.getId()),
new String[]{
LangManager.getText(Lang.GUI_COLOR_SUBTEXT) + LangManager.getText(Lang.GUI_CLICK_TO_EDIT_PARTICLE, particles.size()),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_PARTICLE_INFO, particle.getId(), ParticleUtils.formatName(particle.getEffect().getName()), ParticleUtils.formatName(particle.getStyle().getName()), particle.getDataString()),
LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_SHIFT_CLICK_TO_DELETE)
},
(button, isShiftClick) -> {
if (!isShiftClick) {
GuiHandler.transition(new GuiInventoryEditParticle(pplayer, particle));
} else {
// Delete particle
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
for (ParticlePair pp : activeGroup.getParticles()) {
if (pp.getId() == particle.getId()) {
activeGroup.getParticles().remove(pp);
break;
}
}
DataManager.saveParticleGroup(pplayer.getUniqueId(), activeGroup);
// Update inventory to reflect deletion
this.actionButtons.remove(button);
this.inventory.setItem(button.getSlot(), null);
}
});
this.actionButtons.add(selectButton);
index++;
if (index == nextWrap) { // Loop around border
nextWrap += 9;
index += 2;
index += 2;
}
if (index > maxIndex) break; // Overflowed the available space
}
// Create New Particle Button
boolean canCreate = pplayer.getActiveParticles().size() < PermissionManager.getMaxParticlesAllowed(pplayer.getPlayer());
String lore = LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_CREATE_PARTICLE_DESCRIPTION);
GuiActionButton createNewParticle = new GuiActionButton(38,
GuiIcon.CREATE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_CREATE_PARTICLE),
canCreate ? new String[] { lore } : new String[] { lore, LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_CREATE_PARTICLE_UNAVAILABLE) },
(button, isShiftClick) -> {
if (!canCreate) return;
ParticlePair editingParticle = ParticlePair.getNextDefault(pplayer);
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<GuiInventoryEditFinishedCallback>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryManageParticles(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, callbacks, 1)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, callbacks, 2)));
callbacks.add(() -> {
if (editingParticle.getEffect().hasProperty(ParticleProperty.COLORABLE) || editingParticle.getEffect().hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
GuiHandler.transition(new GuiInventoryEditData(pplayer, editingParticle, callbacks, 3));
} else {
callbacks.get(4).execute();
}
});
callbacks.add(() -> {
// Save new particle
ParticleGroup group = pplayer.getActiveParticleGroup();
group.getParticles().add(editingParticle);
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
// Reopen the manage particle inventory
GuiHandler.transition(new GuiInventoryManageParticles(pplayer));
});
callbacks.get(1).execute();
});
GuiActionButton createNewParticle = new GuiActionButton(
38,
GuiIcon.CREATE.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_CREATE_PARTICLE),
canCreate ? new String[]{lore} : new String[]{lore, LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_CREATE_PARTICLE_UNAVAILABLE)},
(button, isShiftClick) -> {
if (!canCreate) return;
ParticlePair editingParticle = ParticlePair.getNextDefault(pplayer);
List<GuiInventoryEditFinishedCallback> callbacks = new ArrayList<>();
callbacks.add(() -> GuiHandler.transition(new GuiInventoryManageParticles(pplayer)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditEffect(pplayer, editingParticle, 1, callbacks, 1)));
callbacks.add(() -> GuiHandler.transition(new GuiInventoryEditStyle(pplayer, editingParticle, 1, callbacks, 2)));
callbacks.add(() -> {
if (editingParticle.getEffect().hasProperty(ParticleProperty.COLORABLE) || editingParticle.getEffect().hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
GuiHandler.transition(new GuiInventoryEditData(pplayer, editingParticle, 1, callbacks, 3));
} else {
callbacks.get(4).execute();
}
});
callbacks.add(() -> {
// Save new particle
ParticleGroup group = pplayer.getActiveParticleGroup();
group.getParticles().add(editingParticle);
DataManager.saveParticleGroup(pplayer.getUniqueId(), group);
// Reopen the manage particle inventory
GuiHandler.transition(new GuiInventoryManageParticles(pplayer));
});
callbacks.get(1).execute();
});
this.actionButtons.add(createNewParticle);
// Reset Particles Button
GuiActionButton resetParticles = new GuiActionButton(42,
GuiIcon.RESET.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_RESET_PARTICLES),
new String[] { LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_RESET_PARTICLES_DESCRIPTION) },
(button, isShiftClick) -> {
// Reset particles
DataManager.saveParticleGroup(pplayer.getUniqueId(), ParticleGroup.getDefaultGroup());
// Reopen this same inventory to refresh it
GuiHandler.transition(new GuiInventoryManageParticles(pplayer));
});
GuiIcon.RESET.get(),
LangManager.getText(Lang.GUI_COLOR_ICON_NAME) + LangManager.getText(Lang.GUI_RESET_PARTICLES),
new String[]{LangManager.getText(Lang.GUI_COLOR_UNAVAILABLE) + LangManager.getText(Lang.GUI_RESET_PARTICLES_DESCRIPTION)},
(button, isShiftClick) -> {
// Reset particles
DataManager.saveParticleGroup(pplayer.getUniqueId(), ParticleGroup.getDefaultGroup());
// Reopen this same inventory to refresh it
GuiHandler.transition(new GuiInventoryManageParticles(pplayer));
});
this.actionButtons.add(resetParticles);
// Back Button
GuiActionButton backButton = new GuiActionButton(INVENTORY_SIZE - 1, GuiIcon.BACK.get(), LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON), new String[] {}, (button, isShiftClick) -> {
GuiHandler.transition(new GuiInventoryDefault(pplayer));
});
GuiActionButton backButton = new GuiActionButton(
INVENTORY_SIZE - 1,
GuiIcon.BACK.get(),
LangManager.getText(Lang.GUI_COLOR_INFO) + LangManager.getText(Lang.GUI_BACK_BUTTON),
new String[]{},
(button, isShiftClick) -> GuiHandler.transition(new GuiInventoryDefault(pplayer)));
this.actionButtons.add(backButton);
this.populate();
}

View file

@ -3,6 +3,7 @@ package com.esophose.playerparticles.gui.hook;
import java.util.HashSet;
import java.util.Set;
import com.esophose.playerparticles.util.NMSUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -27,13 +28,12 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
* Initializes all the static values for this class
*/
public static void setup() {
hooks = new HashSet<PlayerChatHookData>();
hooks = new HashSet<>();
if (hookTask != null)
hookTask.cancel();
hookTask = new PlayerChatHook().runTaskTimer(PlayerParticles.getPlugin(), 0, 20);
}
/**
* Called when a player sends a message in chat
*
@ -44,8 +44,8 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
for (PlayerChatHookData hook : hooks) {
if (hook.getPlayerUUID().equals(event.getPlayer().getUniqueId())) {
event.setCancelled(true);
hook.triggerCallback(event.getMessage());
hooks.remove(hook);
Bukkit.getScheduler().scheduleSyncDelayedTask(PlayerParticles.getPlugin(), () -> hook.triggerCallback(event.getMessage()));
return;
}
}
@ -55,7 +55,7 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
* Ticked every second to decrease the seconds remaining on each hook
*/
public void run() {
Set<PlayerChatHookData> hooksToRemove = new HashSet<PlayerChatHookData>();
Set<PlayerChatHookData> hooksToRemove = new HashSet<>();
for (PlayerChatHookData hook : hooks) {
hook.decrementHookLength();
@ -69,7 +69,12 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
if (player == null) {
hooksToRemove.remove(hook);
} else {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(LangManager.getText(Lang.GUI_SAVE_GROUP_HOTBAR_MESSAGE, hook.getTimeRemaining())));
if (NMSUtil.getVersionNumber() == 9) {
if (hook.getMaxHookLength() == hook.getTimeRemaining())
player.sendMessage(LangManager.getText(Lang.GUI_SAVE_GROUP_HOTBAR_MESSAGE, hook.getTimeRemaining()));
} else {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(LangManager.getText(Lang.GUI_SAVE_GROUP_HOTBAR_MESSAGE, hook.getTimeRemaining())));
}
}
}
@ -84,7 +89,7 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
*/
public static void addHook(PlayerChatHookData newHook) {
for (PlayerChatHookData hook : hooks) {
if (hook.getPlayerUUID().equals(hook.getPlayerUUID())) {
if (hook.getPlayerUUID().equals(newHook.getPlayerUUID())) {
hooks.remove(hook);
break;
}

View file

@ -5,11 +5,13 @@ import java.util.UUID;
public class PlayerChatHookData {
private UUID playerUUID;
private int maxHookLength;
private int hookLength;
private PlayerChatHookCallback hookCallback;
public PlayerChatHookData(UUID playerUUID, int hookLength, PlayerChatHookCallback hookCallback) {
this.playerUUID = playerUUID;
this.maxHookLength = hookLength;
this.hookLength = hookLength;
this.hookCallback = hookCallback;
}
@ -38,6 +40,15 @@ public class PlayerChatHookData {
public boolean timedOut() {
return this.hookLength <= 0;
}
/**
* Gets the max length of the hook
*
* @return The max length of the hook
*/
public int getMaxHookLength() {
return this.maxHookLength;
}
/**
* Gets how much time is remaining on the hook
@ -61,8 +72,8 @@ public class PlayerChatHookData {
* Allows simple hooking into the player chat for a specific time interval
*/
@FunctionalInterface
public static interface PlayerChatHookCallback {
public void onPlayerChat(String textEntered);
public interface PlayerChatHookCallback {
void onPlayerChat(String textEntered);
}
}

View file

@ -6,6 +6,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.scheduler.BukkitRunnable;
@ -27,14 +28,14 @@ import com.esophose.playerparticles.util.ParticleUtils;
public class DataManager {
private DataManager() {
}
/**
* Gets a PPlayer from cache
* This method should be used over the other one unless you absolutely need the PPlayer and you don't care about waiting
* You should always check for a null result when using this method
*
*
* @param playerUUID The PPlayer to get
* @return The PPlayer from cache
*/
@ -42,7 +43,7 @@ public class DataManager {
List<PPlayer> pplayers = ParticleManager.getPPlayers();
synchronized (pplayers) { // Under rare circumstances, the PPlayers list can be changed while it's looping
for (PPlayer pp : pplayers)
if (pp.getUniqueId().equals(playerUUID))
if (pp.getUniqueId().equals(playerUUID))
return pp;
return null;
}
@ -50,7 +51,7 @@ public class DataManager {
/**
* Gets a player from the save data, creates one if it doesn't exist and caches it
*
*
* @param playerUUID The pplayer to get
* @param callback The callback to execute with the found pplayer, or a newly generated one
*/
@ -72,26 +73,26 @@ public class DataManager {
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 " +
"JOIN pp_particle p ON g.uuid = p.group_uuid " +
"WHERE g.owner_uuid = ?"; // @formatter:on
try (PreparedStatement statement = connection.prepareStatement(groupQuery)) {
statement.setString(1, playerUUID.toString());
@ -105,8 +106,8 @@ public class DataManager {
int id = result.getInt("id");
ParticleEffect effect = ParticleEffect.fromName(result.getString("effect"));
ParticleStyle style = ParticleStyle.fromName(result.getString("style"));
Material itemMaterial = ParticleUtils.closestMatchWithFallback(result.getString("item_material"));
Material blockMaterial = ParticleUtils.closestMatchWithFallback(result.getString("block_material"));
Material itemMaterial = ParticleUtils.closestMatchWithFallback(true, result.getString("item_material"));
Material blockMaterial = ParticleUtils.closestMatchWithFallback(true, result.getString("block_material"));
NoteColor noteColor = new NoteColor(result.getInt("note"));
OrdinaryColor color = new OrdinaryColor(result.getInt("r"), result.getInt("g"), result.getInt("b"));
ParticlePair particle = new ParticlePair(playerUUID, id, effect, style, itemMaterial, blockMaterial, color, noteColor);
@ -123,7 +124,7 @@ public class DataManager {
// Add the particle to a new group if one didn't already exist
if (!groupAlreadyExists) {
List<ParticlePair> particles = new ArrayList<ParticlePair>();
List<ParticlePair> particles = new ArrayList<>();
particles.add(particle);
ParticleGroup newGroup = new ParticleGroup(groupName, particles);
groups.add(newGroup);
@ -133,7 +134,7 @@ public class DataManager {
// Load fixed effects
String fixedQuery = "SELECT f.id AS f_id, f.world, f.xPos, f.yPos, f.zPos, p.id AS p_id, p.effect, p.style, p.item_material, p.block_material, p.note, p.r, p.g, p.b FROM pp_fixed f " + // @formatter:off
"JOIN pp_particle p ON f.particle_uuid = p.uuid " +
"JOIN pp_particle p ON f.particle_uuid = p.uuid " +
"WHERE f.owner_uuid = ?"; // @formatter:on
try (PreparedStatement statement = connection.prepareStatement(fixedQuery)) {
statement.setString(1, playerUUID.toString());
@ -151,8 +152,8 @@ public class DataManager {
int particleId = result.getInt("p_id");
ParticleEffect effect = ParticleEffect.fromName(result.getString("effect"));
ParticleStyle style = ParticleStyle.fromName(result.getString("style"));
Material itemMaterial = ParticleUtils.closestMatchWithFallback(result.getString("item_material"));
Material blockMaterial = ParticleUtils.closestMatchWithFallback(result.getString("block_material"));
Material itemMaterial = ParticleUtils.closestMatchWithFallback(true, result.getString("item_material"));
Material blockMaterial = ParticleUtils.closestMatchWithFallback(true, result.getString("block_material"));
NoteColor noteColor = new NoteColor(result.getInt("note"));
OrdinaryColor color = new OrdinaryColor(result.getInt("r"), result.getInt("g"), result.getInt("b"));
ParticlePair particle = new ParticlePair(playerUUID, particleId, effect, style, itemMaterial, blockMaterial, color, noteColor);
@ -160,7 +161,7 @@ public class DataManager {
fixedParticles.add(new FixedParticleEffect(playerUUID, fixedEffectId, worldName, xPos, yPos, zPos, particle));
}
}
// If there aren't any groups then this is a brand new PPlayer and we need to save a new active group for them
boolean activeGroupExists = false;
for (ParticleGroup group : groups) {
@ -170,14 +171,14 @@ public class DataManager {
}
}
if (!activeGroupExists) {
ParticleGroup activeGroup = new ParticleGroup(ParticleGroup.DEFAULT_NAME, new ArrayList<ParticlePair>());
if (!activeGroupExists) {
ParticleGroup activeGroup = new ParticleGroup(ParticleGroup.DEFAULT_NAME, new ArrayList<>());
saveParticleGroup(playerUUID, activeGroup);
groups.add(activeGroup);
}
PPlayer loadedPPlayer = new PPlayer(playerUUID, groups, fixedParticles, particlesHidden);
sync(() -> {
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
@ -189,111 +190,101 @@ public class DataManager {
});
});
}
/**
* Loads all PPlayers from the database that own FixedParticleEffects
*/
public static void loadFixedEffects() {
async(() -> {
PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String query = "SELECT DISTINCT owner_uuid FROM pp_fixed";
try (PreparedStatement statement = connection.prepareStatement(query)) {
ResultSet result = statement.executeQuery();
while (result.next()) {
UUID playerUUID = UUID.fromString(result.getString("owner_uuid"));
sync(() -> {
getPPlayer(playerUUID, (pplayer) -> { });
});
}
async(() -> PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String query = "SELECT DISTINCT owner_uuid FROM pp_fixed";
try (PreparedStatement statement = connection.prepareStatement(query)) {
ResultSet result = statement.executeQuery();
while (result.next()) {
UUID playerUUID = UUID.fromString(result.getString("owner_uuid"));
sync(() -> getPPlayer(playerUUID, (pplayer) -> { }));
}
});
});
}
}));
}
/**
* Updates the particles_hidden setting in the database and for the PPlayer
*
*
* @param playerUUID The player to hide PlayerParticles from
* @param particlesHidden True if the particles should be hidden, otherwise False
*/
public static void updateSettingParticlesHidden(UUID playerUUID, boolean particlesHidden) {
async(() -> {
PlayerParticles.getPlugin().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);
});
async(() -> PlayerParticles.getPlugin().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.
*
*
* @param playerUUID The owner of the group
* @param group The group to create/update
*/
public static void saveParticleGroup(UUID playerUUID, ParticleGroup group) {
async(() -> {
PlayerParticles.getPlugin().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());
async(() -> PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String groupUUID;
ResultSet result = statement.executeQuery();
if (result.next()) { // Clear out particles from existing group
groupUUID = result.getString("uuid");
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 particlesDeleteQuery = "DELETE FROM pp_particle WHERE group_uuid = ?";
PreparedStatement particlesDeleteStatement = connection.prepareStatement(particlesDeleteQuery);
particlesDeleteStatement.setString(1, result.getString("uuid"));
ResultSet result = statement.executeQuery();
if (result.next()) { // Clear out particles from existing group
groupUUID = result.getString("uuid");
particlesDeleteStatement.executeUpdate();
} else { // Create new group
groupUUID = UUID.randomUUID().toString();
String particlesDeleteQuery = "DELETE FROM pp_particle WHERE group_uuid = ?";
PreparedStatement particlesDeleteStatement = connection.prepareStatement(particlesDeleteQuery);
particlesDeleteStatement.setString(1, result.getString("uuid"));
String groupCreateQuery = "INSERT INTO pp_group (uuid, owner_uuid, name) VALUES (?, ?, ?)";
PreparedStatement groupCreateStatement = connection.prepareStatement(groupCreateQuery);
groupCreateStatement.setString(1, groupUUID);
groupCreateStatement.setString(2, playerUUID.toString());
groupCreateStatement.setString(3, group.getName());
particlesDeleteStatement.executeUpdate();
} else { // Create new group
groupUUID = UUID.randomUUID().toString();
groupCreateStatement.executeUpdate();
}
String groupCreateQuery = "INSERT INTO pp_group (uuid, owner_uuid, name) VALUES (?, ?, ?)";
PreparedStatement groupCreateStatement = connection.prepareStatement(groupCreateQuery);
groupCreateStatement.setString(1, groupUUID);
groupCreateStatement.setString(2, playerUUID.toString());
groupCreateStatement.setString(3, group.getName());
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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement particlesStatement = connection.prepareStatement(createParticlesQuery)) {
for (ParticlePair particle : group.getParticles()) {
particlesStatement.setString(1, UUID.randomUUID().toString());
particlesStatement.setString(2, groupUUID);
particlesStatement.setInt(3, particle.getId());
particlesStatement.setString(4, particle.getEffect().getName());
particlesStatement.setString(5, particle.getStyle().getName());
particlesStatement.setString(6, particle.getItemMaterial().name());
particlesStatement.setString(7, particle.getBlockMaterial().name());
particlesStatement.setInt(8, particle.getNoteColor().getNote());
particlesStatement.setInt(9, particle.getColor().getRed());
particlesStatement.setInt(10, particle.getColor().getGreen());
particlesStatement.setInt(11, particle.getColor().getBlue());
particlesStatement.addBatch();
}
particlesStatement.executeBatch();
}
// 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);
particlesStatement.setInt(3, particle.getId());
particlesStatement.setString(4, particle.getEffect().getName());
particlesStatement.setString(5, particle.getStyle().getName());
particlesStatement.setString(6, particle.getItemMaterial().name());
particlesStatement.setString(7, particle.getBlockMaterial().name());
particlesStatement.setInt(8, particle.getNoteColor().getNote());
particlesStatement.setInt(9, particle.getColor().getRed());
particlesStatement.setInt(10, particle.getColor().getGreen());
particlesStatement.setInt(11, particle.getColor().getBlue());
particlesStatement.addBatch();
}
});
});
particlesStatement.executeBatch();
}
}));
getPPlayer(playerUUID, (pplayer) -> {
for (ParticleGroup existing : pplayer.getParticleGroups()) {
@ -308,137 +299,127 @@ public class DataManager {
/**
* Removes a ParticleGroup
*
*
* @param playerUUID The owner of the group
* @param group The group to remove
*/
public static void removeParticleGroup(UUID playerUUID, ParticleGroup group) {
async(() -> {
PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String groupQuery = "SELECT * FROM pp_group WHERE owner_uuid = ? AND name = ?";
String particleDeleteQuery = "DELETE FROM pp_particle WHERE group_uuid = ?";
String groupDeleteQuery = "DELETE FROM pp_group WHERE uuid = ?";
async(() -> PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String groupQuery = "SELECT * FROM pp_group WHERE owner_uuid = ? AND name = ?";
String particleDeleteQuery = "DELETE FROM pp_particle WHERE group_uuid = ?";
String groupDeleteQuery = "DELETE FROM pp_group WHERE uuid = ?";
// Execute group uuid query
String groupUUID = null;
try (PreparedStatement statement = connection.prepareStatement(groupQuery)) {
statement.setString(1, playerUUID.toString());
statement.setString(2, group.getName());
// Execute group uuid query
String groupUUID = null;
try (PreparedStatement statement = connection.prepareStatement(groupQuery)) {
statement.setString(1, playerUUID.toString());
statement.setString(2, group.getName());
ResultSet result = statement.executeQuery();
if (result.next()) {
groupUUID = result.getString("uuid");
}
ResultSet result = statement.executeQuery();
if (result.next()) {
groupUUID = result.getString("uuid");
}
}
// Execute particle delete update
try (PreparedStatement statement = connection.prepareStatement(particleDeleteQuery)) {
statement.setString(1, groupUUID);
// Execute particle delete update
try (PreparedStatement statement = connection.prepareStatement(particleDeleteQuery)) {
statement.setString(1, groupUUID);
statement.executeUpdate();
}
statement.executeUpdate();
}
// Execute group delete update
try (PreparedStatement statement = connection.prepareStatement(groupDeleteQuery)) {
statement.setString(1, groupUUID);
// Execute group delete update
try (PreparedStatement statement = connection.prepareStatement(groupDeleteQuery)) {
statement.setString(1, groupUUID);
statement.executeUpdate();
}
});
});
statement.executeUpdate();
}
}));
getPPlayer(playerUUID, (pplayer) -> {
pplayer.getParticleGroups().remove(group);
});
getPPlayer(playerUUID, (pplayer) -> pplayer.getParticleGroups().remove(group));
}
/**
* Saves a fixed effect to save data
* Does not perform a check to see if a fixed effect with this id already exists
*
*
* @param fixedEffect The fixed effect to save
*/
public static void saveFixedEffect(FixedParticleEffect fixedEffect) {
async(() -> {
PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String particleUUID = UUID.randomUUID().toString();
async(() -> PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String particleUUID = UUID.randomUUID().toString();
String particleQuery = "INSERT INTO pp_particle (uuid, group_uuid, id, effect, style, item_material, block_material, note, r, g, b) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(particleQuery)) {
ParticlePair particle = fixedEffect.getParticlePair();
statement.setString(1, particleUUID);
statement.setNull(2, java.sql.Types.VARCHAR);
statement.setInt(3, fixedEffect.getId());
statement.setString(4, particle.getEffect().getName());
statement.setString(5, particle.getStyle().getName());
statement.setString(6, particle.getItemMaterial().name());
statement.setString(7, particle.getBlockMaterial().name());
statement.setInt(8, particle.getNoteColor().getNote());
statement.setInt(9, particle.getColor().getRed());
statement.setInt(10, particle.getColor().getGreen());
statement.setInt(11, particle.getColor().getBlue());
statement.executeUpdate();
}
String particleQuery = "INSERT INTO pp_particle (uuid, group_uuid, id, effect, style, item_material, block_material, note, r, g, b) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(particleQuery)) {
ParticlePair particle = fixedEffect.getParticlePair();
statement.setString(1, particleUUID);
statement.setNull(2, java.sql.Types.VARCHAR);
statement.setInt(3, fixedEffect.getId());
statement.setString(4, particle.getEffect().getName());
statement.setString(5, particle.getStyle().getName());
statement.setString(6, particle.getItemMaterial().name());
statement.setString(7, particle.getBlockMaterial().name());
statement.setInt(8, particle.getNoteColor().getNote());
statement.setInt(9, particle.getColor().getRed());
statement.setInt(10, particle.getColor().getGreen());
statement.setInt(11, particle.getColor().getBlue());
statement.executeUpdate();
}
String fixedEffectQuery = "INSERT INTO pp_fixed (owner_uuid, id, particle_uuid, world, xPos, yPos, zPos) VALUES (?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(fixedEffectQuery)) {
statement.setString(1, fixedEffect.getOwnerUniqueId().toString());
statement.setInt(2, fixedEffect.getId());
statement.setString(3, particleUUID);
statement.setString(4, fixedEffect.getLocation().getWorld().getName());
statement.setDouble(5, fixedEffect.getLocation().getX());
statement.setDouble(6, fixedEffect.getLocation().getY());
statement.setDouble(7, fixedEffect.getLocation().getZ());
statement.executeUpdate();
}
});
});
String fixedEffectQuery = "INSERT INTO pp_fixed (owner_uuid, id, particle_uuid, world, xPos, yPos, zPos) VALUES (?, ?, ?, ?, ?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(fixedEffectQuery)) {
statement.setString(1, fixedEffect.getOwnerUniqueId().toString());
statement.setInt(2, fixedEffect.getId());
statement.setString(3, particleUUID);
statement.setString(4, fixedEffect.getLocation().getWorld().getName());
statement.setDouble(5, fixedEffect.getLocation().getX());
statement.setDouble(6, fixedEffect.getLocation().getY());
statement.setDouble(7, fixedEffect.getLocation().getZ());
statement.executeUpdate();
}
}));
getPPlayer(fixedEffect.getOwnerUniqueId(), (pplayer) -> {
pplayer.addFixedEffect(fixedEffect);
});
getPPlayer(fixedEffect.getOwnerUniqueId(), (pplayer) -> pplayer.addFixedEffect(fixedEffect));
}
/**
* Updates a fixed effect's particle values
*
*
* @param fixedEffect The fixed effect to update
*/
public static void updateFixedEffect(FixedParticleEffect fixedEffect) {
async(() -> {
PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
// Update fixed effect
String fixedEffectQuery = "UPDATE pp_fixed SET xPos = ?, yPos = ?, zPos = ? WHERE owner_uuid = ? AND id = ?";
try (PreparedStatement statement = connection.prepareStatement(fixedEffectQuery)) {
statement.setDouble(1, fixedEffect.getLocation().getX());
statement.setDouble(2, fixedEffect.getLocation().getY());
statement.setDouble(3, fixedEffect.getLocation().getZ());
statement.setString(4, fixedEffect.getOwnerUniqueId().toString());
statement.setInt(5, fixedEffect.getId());
statement.executeUpdate();
}
// Update particle
String particleUpdateQuery = "UPDATE pp_particle " +
"SET effect = ?, style = ?, item_material = ?, block_material = ?, note = ?, r = ?, g = ?, b = ? " +
"WHERE uuid = (SELECT particle_uuid FROM pp_fixed WHERE owner_uuid = ? AND id = ?)";
try (PreparedStatement statement = connection.prepareStatement(particleUpdateQuery)) {
ParticlePair particle = fixedEffect.getParticlePair();
statement.setString(1, particle.getEffect().getName());
statement.setString(2, particle.getStyle().getName());
statement.setString(3, particle.getItemMaterial().name());
statement.setString(4, particle.getBlockMaterial().name());
statement.setInt(5, particle.getNoteColor().getNote());
statement.setInt(6, particle.getColor().getRed());
statement.setInt(7, particle.getColor().getGreen());
statement.setInt(8, particle.getColor().getBlue());
statement.setString(9, fixedEffect.getOwnerUniqueId().toString());
statement.setInt(10, fixedEffect.getId());
statement.executeUpdate();
}
});
});
async(() -> PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
// Update fixed effect
String fixedEffectQuery = "UPDATE pp_fixed SET xPos = ?, yPos = ?, zPos = ? WHERE owner_uuid = ? AND id = ?";
try (PreparedStatement statement = connection.prepareStatement(fixedEffectQuery)) {
statement.setDouble(1, fixedEffect.getLocation().getX());
statement.setDouble(2, fixedEffect.getLocation().getY());
statement.setDouble(3, fixedEffect.getLocation().getZ());
statement.setString(4, fixedEffect.getOwnerUniqueId().toString());
statement.setInt(5, fixedEffect.getId());
statement.executeUpdate();
}
// Update particle
String particleUpdateQuery = "UPDATE pp_particle " +
"SET effect = ?, style = ?, item_material = ?, block_material = ?, note = ?, r = ?, g = ?, b = ? " +
"WHERE uuid = (SELECT particle_uuid FROM pp_fixed WHERE owner_uuid = ? AND id = ?)";
try (PreparedStatement statement = connection.prepareStatement(particleUpdateQuery)) {
ParticlePair particle = fixedEffect.getParticlePair();
statement.setString(1, particle.getEffect().getName());
statement.setString(2, particle.getStyle().getName());
statement.setString(3, particle.getItemMaterial().name());
statement.setString(4, particle.getBlockMaterial().name());
statement.setInt(5, particle.getNoteColor().getNote());
statement.setInt(6, particle.getColor().getRed());
statement.setInt(7, particle.getColor().getGreen());
statement.setInt(8, particle.getColor().getBlue());
statement.setString(9, fixedEffect.getOwnerUniqueId().toString());
statement.setInt(10, fixedEffect.getId());
statement.executeUpdate();
}
}));
getPPlayer(fixedEffect.getOwnerUniqueId(), (pplayer) -> {
pplayer.removeFixedEffect(fixedEffect.getId());
pplayer.addFixedEffect(fixedEffect);
@ -448,51 +429,47 @@ public class DataManager {
/**
* Deletes a fixed effect from save data
* Does not perform a check to see if a fixed effect with this id already exists
*
*
* @param playerUUID The player who owns the effect
* @param id The id of the effect to remove
*/
public static void removeFixedEffect(UUID playerUUID, int id) {
async(() -> {
PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String particleUUID = null;
async(() -> PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
String particleUUID = null;
String particleUUIDQuery = "SELECT particle_uuid FROM pp_fixed WHERE owner_uuid = ? AND id = ?";
try (PreparedStatement statement = connection.prepareStatement(particleUUIDQuery)) {
statement.setString(1, playerUUID.toString());
statement.setInt(2, id);
String particleUUIDQuery = "SELECT particle_uuid FROM pp_fixed WHERE owner_uuid = ? AND id = ?";
try (PreparedStatement statement = connection.prepareStatement(particleUUIDQuery)) {
statement.setString(1, playerUUID.toString());
statement.setInt(2, id);
ResultSet result = statement.executeQuery();
if (result.next()) {
particleUUID = result.getString("particle_uuid");
}
ResultSet result = statement.executeQuery();
if (result.next()) {
particleUUID = result.getString("particle_uuid");
}
}
String particleDeleteQuery = "DELETE FROM pp_particle WHERE uuid = ?";
try (PreparedStatement statement = connection.prepareStatement(particleDeleteQuery)) {
statement.setString(1, particleUUID);
String particleDeleteQuery = "DELETE FROM pp_particle WHERE uuid = ?";
try (PreparedStatement statement = connection.prepareStatement(particleDeleteQuery)) {
statement.setString(1, particleUUID);
statement.executeUpdate();
}
statement.executeUpdate();
}
String fixedEffectDeleteQuery = "DELETE FROM pp_fixed WHERE owner_uuid = ? AND id = ?";
try (PreparedStatement statement = connection.prepareStatement(fixedEffectDeleteQuery)) {
statement.setString(1, playerUUID.toString());
statement.setInt(2, id);
String fixedEffectDeleteQuery = "DELETE FROM pp_fixed WHERE owner_uuid = ? AND id = ?";
try (PreparedStatement statement = connection.prepareStatement(fixedEffectDeleteQuery)) {
statement.setString(1, playerUUID.toString());
statement.setInt(2, id);
statement.executeUpdate();
}
});
});
statement.executeUpdate();
}
}));
getPPlayer(playerUUID, (pplayer) -> {
pplayer.removeFixedEffect(id);
});
getPPlayer(playerUUID, (pplayer) -> pplayer.removeFixedEffect(id));
}
/**
* Asynchronizes the callback with it's own thread
*
*
* @param asyncCallback The callback to run on a separate thread
*/
private static void async(SyncInterface asyncCallback) {
@ -505,7 +482,7 @@ public class DataManager {
/**
* Synchronizes the callback with the main thread
*
*
* @param syncCallback The callback to run on the main thread
*/
private static void sync(SyncInterface syncCallback) {
@ -520,16 +497,16 @@ public class DataManager {
* Provides an easy way to run a section of code either synchronously or asynchronously using a callback
*/
@FunctionalInterface
private static interface SyncInterface {
public void execute();
private interface SyncInterface {
void execute();
}
/**
* Allows callbacks to be passed between configuration methods and executed for returning objects after database queries
*/
@FunctionalInterface
public static interface ConfigurationCallback<T> {
public void execute(T obj);
public interface ConfigurationCallback<T> {
void execute(T obj);
}
}

View file

@ -22,7 +22,7 @@ public class LangManager {
/**
* Contains the location in the .lang file of every chat message
*/
public static enum Lang { // @formatter:off
public enum Lang { // @formatter:off
// Command Errors
COMMAND_ERROR_NO_EFFECTS,
@ -92,6 +92,7 @@ public class LangManager {
// Group Command
GROUP_INVALID,
GROUP_NO_PERMISSION,
GROUP_PRESET_NO_PERMISSION,
GROUP_RESERVED,
GROUP_NO_NAME,
@ -231,6 +232,8 @@ public class LangManager {
GUI_COLOR_UNAVAILABLE,
GUI_COMMANDS_INFO,
GUI_BACK_BUTTON,
GUI_NEXT_PAGE_BUTTON,
GUI_PREVIOUS_PAGE_BUTTON,
GUI_CLICK_TO_LOAD,
GUI_SHIFT_CLICK_TO_DELETE,
GUI_PARTICLE_INFO,
@ -281,10 +284,6 @@ public class LangManager {
GUI_SELECT_DATA,
GUI_SELECT_DATA_DESCRIPTION,
GUI_SELECT_DATA_NOTE,
GUI_SELECT_DATA_RANDOMIZE_ITEMS,
GUI_SELECT_DATA_RANDOMIZE_ITEMS_DESCRIPTION,
GUI_SELECT_DATA_RANDOMIZE_BLOCKS,
GUI_SELECT_DATA_RANDOMIZE_BLOCKS_DESCRIPTION,
GUI_EDIT_DATA_COLOR_RED,
GUI_EDIT_DATA_COLOR_ORANGE,
GUI_EDIT_DATA_COLOR_YELLOW,
@ -375,7 +374,7 @@ public class LangManager {
File targetLangFile = new File(pluginDataFolder.getAbsolutePath() + "/lang/" + langFileName);
// TODO: Move this somewhere else
Set<String> defaultLangFileNames = new HashSet<String>();
Set<String> defaultLangFileNames = new HashSet<>();
defaultLangFileNames.add("en_US.lang");
defaultLangFileNames.add("fr_FR.lang");
defaultLangFileNames.add("vi_VN.lang");

View file

@ -42,7 +42,7 @@ public class ParticleGroupPresetManager {
* Loads the preset groups from the preset_groups.yml file
*/
public static void reload() {
presetGroups = new ArrayList<ParticleGroupPreset>();
presetGroups = new ArrayList<>();
File pluginDataFolder = PlayerParticles.getPlugin().getDataFolder();
File groupsFile = new File(pluginDataFolder.getAbsolutePath() + File.separator + FILE_NAME);
@ -61,7 +61,7 @@ public class ParticleGroupPresetManager {
Set<String> groupNames = groupsYaml.getKeys(false);
for (String groupName : groupNames) {
try {
List<ParticlePair> particles = new ArrayList<ParticlePair>();
List<ParticlePair> particles = new ArrayList<>();
String displayName = "";
Material guiIcon = Material.ENDER_CHEST;
String permission = "";
@ -120,7 +120,7 @@ public class ParticleGroupPresetManager {
if (args[0].equalsIgnoreCase("rainbow")) {
noteColorData = new NoteColor(99);
} else {
int note = -1;
int note;
try {
note = Integer.parseInt(args[0]);
} catch (Exception e) {
@ -139,9 +139,7 @@ public class ParticleGroupPresetManager {
if (args[0].equalsIgnoreCase("rainbow")) {
colorData = new OrdinaryColor(999, 999, 999);
} else {
int r = -1;
int g = -1;
int b = -1;
int r, g, b;
try {
r = Integer.parseInt(args[0]);
@ -181,7 +179,7 @@ public class ParticleGroupPresetManager {
}
}
particles.add(new ParticlePair(null, id, effect, style, blockData, blockData, colorData, noteColorData));
particles.add(new ParticlePair(null, id, effect, style, itemData, blockData, colorData, noteColorData));
}
presetGroups.add(new ParticleGroupPreset(displayName, guiIcon, permission, allowPermissionOverride, new ParticleGroup(groupName, particles)));

View file

@ -32,7 +32,7 @@ public class ParticleManager extends BukkitRunnable implements Listener {
/**
* The list containing all the loaded PPlayer info
*/
private static List<PPlayer> particlePlayers = new ArrayList<PPlayer>();
private static List<PPlayer> particlePlayers = new ArrayList<>();
/**
* Rainbow particle effect hue and note color used for rainbow colorable effects
@ -106,15 +106,15 @@ public class ParticleManager extends BukkitRunnable implements Listener {
// Don't show their particles if they are in spectator mode
// Don't spawn particles if the world doesn't allow it
if (player != null && player.getGameMode() != GameMode.SPECTATOR && !PermissionManager.isWorldDisabled(player.getWorld().getName()))
if (player != null && player.getGameMode() != GameMode.SPECTATOR && PermissionManager.isWorldEnabled(player.getWorld().getName()))
for (ParticlePair particles : pplayer.getActiveParticles())
displayParticles(pplayer, particles, player.getLocation().clone().add(0, 1, 0));
this.displayParticles(pplayer, particles, player.getLocation().clone().add(0, 1, 0));
// Loop for FixedParticleEffects
// Don't spawn particles if the world doesn't allow it
for (FixedParticleEffect effect : pplayer.getFixedParticles())
if (!PermissionManager.isWorldDisabled(effect.getLocation().getWorld().getName()))
displayFixedParticleEffect(effect);
if (PermissionManager.isWorldEnabled(effect.getLocation().getWorld().getName()))
this.displayFixedParticleEffect(effect);
}
}
@ -129,10 +129,10 @@ public class ParticleManager extends BukkitRunnable implements Listener {
if (!ParticleStyleManager.isCustomHandled(particle.getStyle())) {
if (PSetting.TOGGLE_ON_MOVE.getBoolean() && particle.getStyle().canToggleWithMovement() && pplayer.isMoving()) {
for (PParticle pparticle : DefaultStyles.FEET.getParticles(particle, location))
ParticleEffect.display(particle, pparticle, false);
ParticleEffect.display(particle, pparticle, false, pplayer.getPlayer());
} else {
for (PParticle pparticle : particle.getStyle().getParticles(particle, location))
ParticleEffect.display(particle, pparticle, false);
ParticleEffect.display(particle, pparticle, false, pplayer.getPlayer());
}
}
}
@ -145,7 +145,7 @@ public class ParticleManager extends BukkitRunnable implements Listener {
*/
public static void displayParticles(ParticlePair particle, List<PParticle> particles) {
for (PParticle pparticle : particles)
ParticleEffect.display(particle, pparticle, false);
ParticleEffect.display(particle, pparticle, false, Bukkit.getPlayer(particle.getOwnerUniqueId()));
}
/**
@ -156,7 +156,7 @@ public class ParticleManager extends BukkitRunnable implements Listener {
private void displayFixedParticleEffect(FixedParticleEffect fixedEffect) {
ParticlePair particle = fixedEffect.getParticlePair();
for (PParticle pparticle : particle.getStyle().getParticles(particle, fixedEffect.getLocation().clone().add(0, particle.getStyle().getFixedEffectOffset(), 0)))
ParticleEffect.display(particle, pparticle, true);
ParticleEffect.display(particle, pparticle, true, null);
}
/**

View file

@ -37,7 +37,7 @@ public class PermissionManager {
private final String permissionString;
private PPermission(String permissionString) {
PPermission(String permissionString) {
this.permissionString = permissionString;
}
@ -149,13 +149,13 @@ public class PermissionManager {
}
/**
* Checks if a world is disabled for particles to spawn in
* Checks if a world is enabled for particles to spawn in
*
* @param world The world name to check
* @return True if the world is disabled
*/
public static boolean isWorldDisabled(String world) {
return getDisabledWorlds().contains(world);
public static boolean isWorldEnabled(String world) {
return !getDisabledWorlds().contains(world);
}
/**
@ -200,7 +200,7 @@ public class PermissionManager {
* @return A String List of all effect names the given player has permission for
*/
public static List<String> getEffectNamesUserHasPermissionFor(Player p) {
List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<>();
for (ParticleEffect pe : ParticleEffect.getSupportedEffects())
if (hasEffectPermission(p, pe))
list.add(pe.getName());
@ -214,7 +214,7 @@ public class PermissionManager {
* @return A String List of all style names the given player has permission for
*/
public static List<String> getStyleNamesUserHasPermissionFor(Player p) {
List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<>();
for (ParticleStyle ps : ParticleStyleManager.getStyles())
if (hasStylePermission(p, ps))
list.add(ps.getName());
@ -228,7 +228,7 @@ public class PermissionManager {
* @return A String List of all fixable style names the given player has permission for
*/
public static List<String> getFixableStyleNamesUserHasPermissionFor(Player p) {
List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<>();
for (ParticleStyle ps : ParticleStyleManager.getStyles())
if (ps.canBeFixed() && hasStylePermission(p, ps))
list.add(ps.getName());
@ -242,7 +242,7 @@ public class PermissionManager {
* @return A List of all effects the given player has permission for
*/
public static List<ParticleEffect> getEffectsUserHasPermissionFor(Player p) {
List<ParticleEffect> list = new ArrayList<ParticleEffect>();
List<ParticleEffect> list = new ArrayList<>();
for (ParticleEffect pe : ParticleEffect.getSupportedEffects())
if (hasEffectPermission(p, pe))
list.add(pe);
@ -256,7 +256,7 @@ public class PermissionManager {
* @return A List of all styles the given player has permission for
*/
public static List<ParticleStyle> getStylesUserHasPermissionFor(Player p) {
List<ParticleStyle> list = new ArrayList<ParticleStyle>();
List<ParticleStyle> list = new ArrayList<>();
for (ParticleStyle ps : ParticleStyleManager.getStyles())
if (hasStylePermission(p, ps))
list.add(ps);

View file

@ -32,7 +32,10 @@ public class SettingManager {
TICKS_PER_PARTICLE(PSettingType.LONG),
CHECK_UPDATES(PSettingType.BOOLEAN),
SEND_METRICS(PSettingType.BOOLEAN),
GUI_ENABLED(PSettingType.BOOLEAN),
GUI_PRESETS_ONLY(PSettingType.BOOLEAN),
GUI_CLOSE_AFTER_GROUP_SELECTED(PSettingType.BOOLEAN),
GUI_BUTTON_SOUND(PSettingType.BOOLEAN),
TOGGLE_ON_MOVE(PSettingType.BOOLEAN),
@ -51,6 +54,7 @@ public class SettingManager {
DATABASE_NAME(PSettingType.STRING),
DATABASE_USER_NAME(PSettingType.STRING),
DATABASE_USER_PASSWORD(PSettingType.STRING),
DATABASE_USE_SSL(PSettingType.BOOLEAN),
MAX_FIXED_EFFECTS(PSettingType.INTEGER),
MAX_FIXED_EFFECT_CREATION_DISTANCE(PSettingType.INTEGER),
@ -68,7 +72,7 @@ public class SettingManager {
private final PSettingType settingType;
private Object value = null;
private PSetting(PSettingType settingType) {
PSetting(PSettingType settingType) {
this.settingType = settingType;
}
@ -184,11 +188,12 @@ public class SettingManager {
GROUPS,
PRESET_GROUPS,
BACK,
NEXT_PAGE,
PREVIOUS_PAGE,
CREATE,
EDIT_EFFECT,
EDIT_STYLE,
EDIT_DATA,
RANDOMIZE,
RESET,
EFFECT,
@ -196,8 +201,8 @@ public class SettingManager {
private Map<String, Material> materials;
private GuiIcon() {
this.materials = new HashMap<String, Material>();
GuiIcon() {
this.materials = new HashMap<>();
}
/**
@ -261,7 +266,7 @@ public class SettingManager {
* Resets the setting's value so it will be fetched from the config the next time it's needed
*/
private void resetDefault() {
this.materials = new HashMap<String, Material>();
this.materials = new HashMap<>();
}
}

View file

@ -168,7 +168,7 @@ public class PPlayer {
* @return A List of ParticlePairs with a matching style
*/
public List<ParticlePair> getActiveParticlesForStyle(ParticleStyle style) {
List<ParticlePair> matches = new ArrayList<ParticlePair>();
List<ParticlePair> matches = new ArrayList<>();
for (ParticlePair pair : this.getActiveParticles())
if (pair.getStyle().equals(style))
matches.add(pair);
@ -216,7 +216,7 @@ public class PPlayer {
* @return A List of Integer ids this player's fixed effects have
*/
public List<Integer> getFixedEffectIds() {
List<Integer> ids = new ArrayList<Integer>();
List<Integer> ids = new ArrayList<>();
for (FixedParticleEffect fixedEffect : this.fixedParticles)
ids.add(fixedEffect.getId());
return ids;

View file

@ -6,11 +6,11 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.scheduler.BukkitRunnable;
import com.esophose.playerparticles.PlayerParticles;
import com.esophose.playerparticles.manager.DataManager;
@ -19,31 +19,29 @@ import com.esophose.playerparticles.manager.SettingManager.PSetting;
public class PPlayerMovementListener implements Listener {
private static final int CHECK_INTERVAL = 3;
private Map<UUID, Integer> timeSinceLastMovement = new HashMap<UUID, Integer>();
private Map<UUID, Integer> timeSinceLastMovement = new HashMap<>();
public PPlayerMovementListener() {
new BukkitRunnable() {
public void run() {
if (!PSetting.TOGGLE_ON_MOVE.getBoolean()) return;
List<UUID> toRemove = new ArrayList<UUID>();
for (UUID uuid : timeSinceLastMovement.keySet()) {
PPlayer pplayer = DataManager.getPPlayer(uuid);
if (pplayer == null) {
toRemove.add(uuid);
} else {
int standingTime = timeSinceLastMovement.get(uuid);
pplayer.setMoving(standingTime < PSetting.TOGGLE_ON_MOVE_DELAY.getInt());
if (standingTime < PSetting.TOGGLE_ON_MOVE_DELAY.getInt())
timeSinceLastMovement.replace(uuid, standingTime + CHECK_INTERVAL);
}
Bukkit.getScheduler().runTaskTimer(PlayerParticles.getPlugin(), () -> {
if (!PSetting.TOGGLE_ON_MOVE.getBoolean()) return;
List<UUID> toRemove = new ArrayList<>();
for (UUID uuid : this.timeSinceLastMovement.keySet()) {
PPlayer pplayer = DataManager.getPPlayer(uuid);
if (pplayer == null) {
toRemove.add(uuid);
} else {
int standingTime = this.timeSinceLastMovement.get(uuid);
pplayer.setMoving(standingTime < PSetting.TOGGLE_ON_MOVE_DELAY.getInt());
if (standingTime < PSetting.TOGGLE_ON_MOVE_DELAY.getInt())
this.timeSinceLastMovement.replace(uuid, standingTime + CHECK_INTERVAL);
}
for (UUID uuid : toRemove)
timeSinceLastMovement.remove(uuid);
}
}.runTaskTimer(PlayerParticles.getPlugin(), 0, CHECK_INTERVAL);
for (UUID uuid : toRemove)
this.timeSinceLastMovement.remove(uuid);
}, 0, CHECK_INTERVAL);
}
/**
@ -57,10 +55,10 @@ public class PPlayerMovementListener implements Listener {
if (event.getTo().getBlockX() == event.getFrom().getBlockX() && event.getTo().getBlockY() == event.getFrom().getBlockY() && event.getTo().getBlockZ() == event.getFrom().getBlockZ()) return;
UUID playerUUID = event.getPlayer().getUniqueId();
if (!timeSinceLastMovement.containsKey(playerUUID)) {
timeSinceLastMovement.put(playerUUID, 0);
if (!this.timeSinceLastMovement.containsKey(playerUUID)) {
this.timeSinceLastMovement.put(playerUUID, 0);
} else {
timeSinceLastMovement.replace(playerUUID, 0);
this.timeSinceLastMovement.replace(playerUUID, 0);
}
}

View file

@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.esophose.playerparticles.util.NMSUtil;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
@ -32,7 +33,10 @@ public enum ParticleEffect {
BUBBLE("WATER_BUBBLE", "WATER_BUBBLE"),
BUBBLE_COLUMN_UP("BUBBLE_COLUMN_UP", null),
BUBBLE_POP("BUBBLE_POP", null),
CAMPFIRE_COSY_SMOKE("CAMPFIRE_COSY_SMOKE", null),
CAMPFIRE_SIGNAL_SMOKE("CAMPFIRE_SIGNAL_SMOKE", null),
CLOUD("CLOUD", "CLOUD"),
COMPOSTER("COMPOSTER", null),
CRIT("CRIT", "CRIT"),
CURRENT_DOWN("CURRENT_DOWN", null),
DAMAGE_INDICATOR("DAMAGE_INDICATOR", "DAMAGE_INDICATOR"),
@ -49,9 +53,12 @@ public enum ParticleEffect {
EXPLOSION("EXPLOSION_LARGE", "EXPLOSION_LARGE"),
EXPLOSION_EMITTER("EXPLOSION_HUGE", "EXPLOSION_HUGE"),
FALLING_DUST("FALLING_DUST", "FALLING_DUST", ParticleProperty.REQUIRES_MATERIAL_DATA),
FALLING_LAVA("FALLING_LAVA", null),
FALLING_WATER("FALLING_WATER", null),
FIREWORK("FIREWORKS_SPARK", "FIREWORKS_SPARK"),
FISHING("WATER_WAKE", "WATER_WAKE"),
FLAME("FLAME", "FLAME"),
// FLASH("FLASH", null), // Also no thank you
FOOTSTEP(null, "FOOTSTEP"), // Removed in Minecraft 1.13 :(
HAPPY_VILLAGER("VILLAGER_HAPPY", "VILLAGER_HAPPY"),
HEART("HEART", "HEART"),
@ -59,6 +66,7 @@ public enum ParticleEffect {
ITEM("ITEM_CRACK", "ITEM_CRACK", ParticleProperty.REQUIRES_MATERIAL_DATA),
ITEM_SLIME("SLIME", "SLIME"),
ITEM_SNOWBALL("SNOWBALL", "SNOWBALL"),
LANDING_LAVA("LANDING_LAVA", null),
LARGE_SMOKE("SMOKE_LARGE", "SMOKE_LARGE"),
LAVA("LAVA", "LAVA"),
MYCELIUM("TOWN_AURA", "TOWN_AURA"),
@ -68,6 +76,7 @@ public enum ParticleEffect {
PORTAL("PORTAL", "PORTAL"),
RAIN("WATER_DROP", "WATER_DROP"),
SMOKE("SMOKE_NORMAL", "SMOKE_NORMAL"),
SNEEZE("SNEEZE", null),
SPELL("SPELL", "SPELL"), // The Minecraft internal name for this is actually "effect", but that's the command name, so it's SPELL for the plugin instead
SPIT("SPIT", "SPIT"),
SPLASH("WATER_SPLASH", "WATER_SPLASH"),
@ -78,7 +87,7 @@ public enum ParticleEffect {
WITCH("SPELL_WITCH", "SPELL_WTICH");
public static boolean VERSION_13; // This is a particle unique to Minecraft 1.13, this is a reliable way of telling what server version is running
private static final Map<String, ParticleEffect> NAME_MAP = new HashMap<String, ParticleEffect>();
private static final Map<String, ParticleEffect> NAME_MAP = new HashMap<>();
private static Constructor<?> DustOptions_CONSTRUCTOR;
private static Method createBlockData_METHOD;
private final Particle internalEnum;
@ -87,15 +96,19 @@ public enum ParticleEffect {
// Initialize map for quick name and id lookup
// Initialize Minecraft 1.13 related variables
static {
for (ParticleEffect effect : values()) {
NAME_MAP.put(effect.getName(), effect);
}
for (ParticleEffect effect : values())
if (effect.isSupported())
NAME_MAP.put(effect.getName(), effect);
try {
VERSION_13 = Particle.valueOf("NAUTILUS") != null;
DustOptions_CONSTRUCTOR = Particle.REDSTONE.getDataType().getConstructor(Color.class, float.class);
createBlockData_METHOD = Material.class.getMethod("createBlockData");
} catch (Exception e) {
if (NMSUtil.getVersionNumber() > 12) {
VERSION_13 = true;
try {
DustOptions_CONSTRUCTOR = Particle.REDSTONE.getDataType().getConstructor(Color.class, float.class);
createBlockData_METHOD = Material.class.getMethod("createBlockData");
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
DustOptions_CONSTRUCTOR = null;
createBlockData_METHOD = null;
VERSION_13 = false;
@ -109,7 +122,7 @@ public enum ParticleEffect {
* @param enumNameLegacy Name of the Particle Enum when the server version is less than 1.13
* @param properties Properties of this particle effect
*/
private ParticleEffect(String enumName, String enumNameLegacy, ParticleProperty... properties) {
ParticleEffect(String enumName, String enumNameLegacy, ParticleProperty... properties) {
this.properties = Arrays.asList(properties);
Particle matchingEnum = null;
@ -167,9 +180,10 @@ public enum ParticleEffect {
* @return Supported effects
*/
public static List<ParticleEffect> getSupportedEffects() {
List<ParticleEffect> effects = new ArrayList<ParticleEffect>();
List<ParticleEffect> effects = new ArrayList<>();
for (ParticleEffect pe : values())
if (pe.isSupported()) effects.add(pe);
if (pe.isSupported())
effects.add(pe);
return effects;
}
@ -195,17 +209,18 @@ public enum ParticleEffect {
* @param particle The ParticlePair, given the effect/style/data
* @param pparticle The particle spawn information
* @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
*/
public static void display(ParticlePair particle, PParticle pparticle, boolean isFixedEffect) {
public static void display(ParticlePair particle, PParticle pparticle, boolean isFixedEffect, Player owner) {
ParticleEffect effect = particle.getEffect();
int count = pparticle.isDirectional() ? 0 : 1;
if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect);
effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect, owner);
} else if (effect.hasProperty(ParticleProperty.COLORABLE)) {
effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect);
effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect, owner);
} else {
effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), count, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect);
effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), count, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect, owner);
}
}
@ -219,15 +234,16 @@ public enum ParticleEffect {
* @param amount Amount of particles
* @param center Center location of the effect
* @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @throws ParticleDataException If the particle effect requires additional data
*/
public void display(double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect) throws ParticleDataException {
if (hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
public void display(double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect, Player owner) throws ParticleDataException {
if (this.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
throw new ParticleDataException("This particle effect requires additional data");
}
for (Player player : getPlayersInRange(center, isFixedEffect)) {
player.spawnParticle(internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed);
for (Player player : this.getPlayersInRange(center, isFixedEffect, owner)) {
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed);
}
}
@ -237,10 +253,11 @@ public enum ParticleEffect {
* @param color Color of the particle
* @param center Center location of the effect
* @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
*/
public void display(ParticleColor color, Location center, boolean isFixedEffect) throws ParticleColorException {
if (!hasProperty(ParticleProperty.COLORABLE)) {
public void display(ParticleColor color, Location center, boolean isFixedEffect, Player owner) throws ParticleColorException {
if (!this.hasProperty(ParticleProperty.COLORABLE)) {
throw new ParticleColorException("This particle effect is not colorable");
}
@ -249,17 +266,15 @@ public enum ParticleEffect {
Object dustData = null;
try { // The DustData class doesn't exist in Minecraft versions less than 1.13... so this is disgusting... but it works great
dustData = DustOptions_CONSTRUCTOR.newInstance(Color.fromRGB(dustColor.getRed(), dustColor.getGreen(), dustColor.getBlue()), 1); // Wait, you can change the size of these now??? AWESOME! I might implement this in the future!
} catch (Exception e) {
}
} catch (Exception ignored) { }
for (Player player : getPlayersInRange(center, isFixedEffect)) {
player.spawnParticle(internalEnum, center.getX(), center.getY(), center.getZ(), 1, 0, 0, 0, 0, dustData);
for (Player player : this.getPlayersInRange(center, isFixedEffect, owner)) {
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), 1, 0, 0, 0, 0, dustData);
}
} else {
for (Player player : getPlayersInRange(center, isFixedEffect)) {
for (Player player : this.getPlayersInRange(center, isFixedEffect, owner)) {
// Minecraft clients require that you pass a non-zero value if the Red value should be zero
player.spawnParticle(internalEnum, center.getX(), center.getY(), center.getZ(), 0, this == ParticleEffect.DUST && color.getValueX() == 0 ? Float.MIN_VALUE : color.getValueX(), color.getValueY(), color.getValueZ(), 1);
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), 0, this == ParticleEffect.DUST && color.getValueX() == 0 ? Float.MIN_VALUE : color.getValueX(), color.getValueY(), color.getValueZ(), 1);
}
}
}
@ -277,30 +292,27 @@ public enum ParticleEffect {
* @param amount Amount of particles
* @param center Center location of the effect
* @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
*/
public void display(Material spawnMaterial, double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect) throws ParticleDataException {
if (!hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
public void display(Material spawnMaterial, double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect, Player owner) throws ParticleDataException {
if (!this.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
throw new ParticleDataException("This particle effect does not require additional data");
}
Object extraData = null;
if (internalEnum.getDataType().getTypeName().equals("org.bukkit.block.data.BlockData")) {
if (this.internalEnum.getDataType().getTypeName().equals("org.bukkit.block.data.BlockData")) {
try { // The Material.createBlockData() method doesn't exist in Minecraft versions less than 1.13... so this is disgusting... but it works great
extraData = createBlockData_METHOD.invoke(spawnMaterial);
} catch (Exception e) {
}
} else if (internalEnum.getDataType() == ItemStack.class) {
} catch (Exception ignored) { }
} else if (this.internalEnum.getDataType() == ItemStack.class) {
extraData = new ItemStack(spawnMaterial);
} else if (internalEnum.getDataType() == MaterialData.class) {
} else if (this.internalEnum.getDataType() == MaterialData.class) {
extraData = new MaterialData(spawnMaterial); // Deprecated, only used in versions < 1.13
} else {
extraData = null;
}
for (Player player : getPlayersInRange(center, isFixedEffect))
player.spawnParticle(internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed, extraData);
for (Player player : this.getPlayersInRange(center, isFixedEffect, owner))
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed, extraData);
}
/**
@ -308,14 +320,18 @@ public enum ParticleEffect {
*
* @param center The center of the radius to check around
* @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @return A List of Players within the particle display range
*/
private List<Player> getPlayersInRange(Location center, boolean isFixedEffect) {
List<Player> players = new ArrayList<Player>();
private List<Player> getPlayersInRange(Location center, boolean isFixedEffect, Player owner) {
List<Player> players = new ArrayList<>();
int range = !isFixedEffect ? PSetting.PARTICLE_RENDER_RANGE_PLAYER.getInt() : PSetting.PARTICLE_RENDER_RANGE_FIXED_EFFECT.getInt();
for (PPlayer pplayer : ParticleManager.getPPlayers()) {
Player p = pplayer.getPlayer();
if (!isFixedEffect && !p.canSee(owner))
continue;
if (p != null && pplayer.canSeeParticles() && p.getWorld().equals(center.getWorld()) && center.distanceSquared(p.getLocation()) <= range * range) {
players.add(p);
}
@ -333,7 +349,7 @@ public enum ParticleEffect {
* @author DarkBlade12
* @since 1.7
*/
public static enum ParticleProperty {
public enum ParticleProperty {
/**
* The particle effect requires block or item material data to be displayed
*/
@ -341,7 +357,7 @@ public enum ParticleEffect {
/**
* The particle effect uses the offsets as color values
*/
COLORABLE;
COLORABLE
}
/**
@ -438,7 +454,7 @@ public enum ParticleEffect {
* @return The red value
*/
public int getRed() {
return red;
return this.red;
}
/**
@ -447,7 +463,7 @@ public enum ParticleEffect {
* @return The green value
*/
public int getGreen() {
return green;
return this.green;
}
/**
@ -456,7 +472,7 @@ public enum ParticleEffect {
* @return The blue value
*/
public int getBlue() {
return blue;
return this.blue;
}
/**
@ -466,8 +482,8 @@ public enum ParticleEffect {
*/
@Override
public float getValueX() {
if (red == 999 || red == 998) return 0F;
return (float) red / 255F;
if (this.red == 999 || this.red == 998) return 0F;
return (float) this.red / 255F;
}
/**
@ -477,8 +493,8 @@ public enum ParticleEffect {
*/
@Override
public float getValueY() {
if (green == 999 || green == 998) return 0F;
return (float) green / 255F;
if (this.green == 999 || this.green == 998) return 0F;
return (float) this.green / 255F;
}
/**
@ -488,8 +504,8 @@ public enum ParticleEffect {
*/
@Override
public float getValueZ() {
if (blue == 999 || blue == 998) return 0F;
return (float) blue / 255F;
if (this.blue == 999 || this.blue == 998) return 0F;
return (float) this.blue / 255F;
}
}

View file

@ -1,5 +1,8 @@
package com.esophose.playerparticles.particles;
import com.esophose.playerparticles.manager.PermissionManager;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
@ -40,7 +43,30 @@ public class ParticleGroup {
* @return The default empty active ParticleGroup
*/
public static ParticleGroup getDefaultGroup() {
return new ParticleGroup(DEFAULT_NAME, new ArrayList<ParticlePair>());
return new ParticleGroup(DEFAULT_NAME, new ArrayList<>());
}
/**
* Checks if a player has permission to use this particle group
*
* @param player The player to check
* @return True if the player has permission
*/
public boolean canPlayerUse(Player player) {
// Make sure the player has permission for the number of particles in this group
if (PermissionManager.getMaxParticlesAllowed(player) < this.particles.size())
return false;
// Make sure the player has permission for all effects/styles in the group
for (ParticlePair particle : this.particles) {
if (!PermissionManager.hasEffectPermission(player, particle.getEffect()))
return false;
if (!PermissionManager.hasStylePermission(player, particle.getStyle()))
return false;
}
return true;
}
}

View file

@ -280,7 +280,7 @@ public class ParticlePair {
-1,
ParticleEffect.FLAME,
DefaultStyles.NORMAL,
ParticleUtils.closestMatchWithFallback("IRON_SHOVEL", "IRON_SPADE"),
ParticleUtils.closestMatchWithFallback(true, "IRON_SHOVEL", "IRON_SPADE"),
Material.STONE,
new OrdinaryColor(0, 0, 0),
new NoteColor(0)); // @formatter:on
@ -297,7 +297,7 @@ public class ParticlePair {
pplayer.getNextActiveParticleId(),
ParticleEffect.FLAME,
DefaultStyles.NORMAL,
ParticleUtils.closestMatchWithFallback("IRON_SHOVEL", "IRON_SPADE"),
ParticleUtils.closestMatchWithFallback(true, "IRON_SHOVEL", "IRON_SPADE"),
Material.STONE,
new OrdinaryColor(0, 0, 0),
new NoteColor(0)); // @formatter:on

View file

@ -41,13 +41,13 @@ public class ParticleStyleCelebration implements ParticleStyle {
Random random = new Random();
for (PPlayer pplayer : ParticleManager.getPPlayers()) {
Player player = pplayer.getPlayer();
if (player != null && player.getGameMode() != GameMode.SPECTATOR && !PermissionManager.isWorldDisabled(player.getWorld().getName()))
if (player != null && player.getGameMode() != GameMode.SPECTATOR && PermissionManager.isWorldEnabled(player.getWorld().getName()))
for (ParticlePair particle : pplayer.getActiveParticles())
if (particle.getStyle() == this)
spawnFirework(player.getLocation(), pplayer, particle, random);
for (FixedParticleEffect fixedEffect : pplayer.getFixedParticles())
if (fixedEffect.getParticlePair().getStyle() == this && !PermissionManager.isWorldDisabled(fixedEffect.getLocation().getWorld().getName()))
if (fixedEffect.getParticlePair().getStyle() == this && PermissionManager.isWorldEnabled(fixedEffect.getLocation().getWorld().getName()))
spawnFirework(fixedEffect.getLocation(), pplayer, fixedEffect.getParticlePair(), random);
}
}

View file

@ -15,40 +15,40 @@ public interface ParticleStyle {
* @param location The central location of the particles
* @return A List of PParticles to spawn
*/
public List<PParticle> getParticles(ParticlePair particle, Location location);
List<PParticle> getParticles(ParticlePair particle, Location location);
/**
* Used to update timers for animations, called once per particle tick
*/
public void updateTimers();
void updateTimers();
/**
* The name of the style
*
* @return The style's name
*/
public String getName();
String getName();
/**
* Gets if the style can be used in a FixedParticleEffect
*
* @return If the style can be used in a FixedParticleEffect
*/
public boolean canBeFixed();
boolean canBeFixed();
/**
* Gets if the style can be replaced with DefaultStyles.FEET when the player is moving
*
* @return True if it can be, otherwise False
*/
public boolean canToggleWithMovement();
boolean canToggleWithMovement();
/**
* The Y-axis offset to be applied when using '/pp fixed create looking'
*
* @return How far to move the style up or down to get it centered on the block properly
*/
public double getFixedEffectOffset();
double getFixedEffectOffset();
/**
* Gets the ParticleStyle with the name given, returns null if not found
@ -56,7 +56,7 @@ public interface ParticleStyle {
* @param styleName The name of the style to search for
* @return The ParticleStyle with a matching name
*/
public static ParticleStyle fromName(String styleName) {
static ParticleStyle fromName(String styleName) {
for (ParticleStyle style : ParticleStyleManager.getStyles())
if (style.getName().equalsIgnoreCase(styleName))
return style;

View file

@ -10,8 +10,8 @@ public class ParticleStyleManager {
/**
* Arrays that contain all registered styles
*/
private static List<ParticleStyle> styles = new ArrayList<ParticleStyle>();
private static List<ParticleStyle> customHandledStyles = new ArrayList<ParticleStyle>();
private static List<ParticleStyle> styles = new ArrayList<>();
private static List<ParticleStyle> customHandledStyles = new ArrayList<>();
/**
* Registers a style that is put into the plugin's update loop

View file

@ -1,7 +1,9 @@
package com.esophose.playerparticles;
package com.esophose.playerparticles.updater;
import java.sql.Statement;
import com.esophose.playerparticles.PlayerParticles;
/**
* 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
@ -12,7 +14,7 @@ public class DataUpdater {
* Checks to make sure all the correct database tables exist
* If they don't, create them
*/
protected static void tryCreateTables() {
public static void tryCreateTables() {
PlayerParticles.getPlugin().getDBConnector().connect((connection) -> {
try (Statement createStatement = connection.createStatement()) {
createStatement.addBatch("CREATE TABLE IF NOT EXISTS pp_settings (player_uuid VARCHAR(36), particles_hidden TINYINT)");
@ -30,7 +32,7 @@ public class DataUpdater {
* @param configVersion The old version of the plugin
* @param currentVersion The current version of the plugin
*/
protected static void updateData(double configVersion, double currentVersion) {
public 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...");
@ -39,7 +41,7 @@ public class DataUpdater {
updateFrom_legacy_to_current();
} else if (configVersion == 5.3) {
updateFrom_5_3_to_current();
} else if (configVersion == 6.0) {
} else {
PlayerParticles.getPlugin().getLogger().warning("Found nothing to update.");
}

View file

@ -1,24 +1,27 @@
package com.esophose.playerparticles.updater;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import com.esophose.playerparticles.PlayerParticles;
import com.esophose.playerparticles.manager.LangManager;
import com.esophose.playerparticles.manager.LangManager.Lang;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
public class PluginUpdateListener implements Listener {
/**
* Called when a player joins and notifies ops if an update is available
*
*
* @param e The join event
*/
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
if (e.getPlayer().isOp() && PlayerParticles.getPlugin().getUpdateVersion() != null) {
LangManager.sendCommandSenderMessage(e.getPlayer(), Lang.UPDATE_AVAILABLE, PlayerParticles.getPlugin().getUpdateVersion(), PlayerParticles.getPlugin().getDescription().getVersion());
LangManager.sendCommandSenderMessage(
e.getPlayer(),
Lang.UPDATE_AVAILABLE,
PlayerParticles.getPlugin().getUpdateVersion(),
PlayerParticles.getPlugin().getDescription().getVersion());
}
}

View file

@ -1,29 +1,5 @@
package com.esophose.playerparticles.util;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
import javax.net.ssl.HttpsURLConnection;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@ -33,12 +9,25 @@ import org.bukkit.plugin.ServicePriority;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
/**
* bStats collects some data for plugin authors.
* <p>
* Check out https://bStats.org/ to learn more about bStats!
*/
@SuppressWarnings("unchecked")
@SuppressWarnings({"WeakerAccess", "unused"})
public class Metrics {
static {
@ -79,9 +68,6 @@ public class Metrics {
// The plugin
private final Plugin plugin;
// A list with all custom charts
private final List<CustomChart> charts = new ArrayList<>();
/**
* Class constructor.
*
@ -125,12 +111,9 @@ public class Metrics {
}
// Load the data
enabled = config.getBoolean("enabled", true);
serverUUID = config.getString("serverUuid");
logFailedRequests = config.getBoolean("logFailedRequests", false);
logSentData = config.getBoolean("logSentData", false);
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
enabled = config.getBoolean("enabled", true);
if (enabled) {
boolean found = false;
// Search for all other bStats Metrics classes to see if we are the first one
@ -159,18 +142,6 @@ public class Metrics {
return enabled;
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
if (chart == null) {
throw new IllegalArgumentException("Chart cannot be null!");
}
charts.add(chart);
}
/**
* Starts the Scheduler which submits our data every 30 minutes.
*/
@ -208,14 +179,6 @@ public class Metrics {
data.put("pluginName", pluginName); // Append the name of the plugin
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
JSONArray customCharts = new JSONArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
JSONObject chart = customChart.getRequestJsonObject();
if (chart == null) { // If the chart is null, we skip it
continue;
}
customCharts.add(chart);
}
data.put("customCharts", customCharts);
return data;
@ -281,7 +244,8 @@ public class Metrics {
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
}
}
} catch (NoSuchFieldException ignored) { }
}
@ -375,334 +339,4 @@ public class Metrics {
return outputStream.toByteArray();
}
/**
* Represents a custom chart.
*/
public static abstract class CustomChart {
// The id of the chart
final String chartId;
/**
* Class constructor.
*
* @param chartId The id of the chart.
*/
CustomChart(String chartId) {
if (chartId == null || chartId.isEmpty()) {
throw new IllegalArgumentException("ChartId cannot be null or empty!");
}
this.chartId = chartId;
}
private JSONObject getRequestJsonObject() {
JSONObject chart = new JSONObject();
chart.put("chartId", chartId);
try {
JSONObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
chart.put("data", data);
} catch (Throwable t) {
if (logFailedRequests) {
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return chart;
}
protected abstract JSONObject getChartData() throws Exception;
}
/**
* Represents a custom simple pie.
*/
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
data.put("value", value);
return data;
}
}
/**
* Represents a custom advanced pie.
*/
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom drilldown pie.
*/
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JSONObject value = new JSONObject();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.put(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.put(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom single line chart.
*/
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
data.put("value", value);
return data;
}
}
/**
* Represents a custom multi line chart.
*/
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom simple bar chart.
*/
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
JSONArray categoryValues = new JSONArray();
categoryValues.add(entry.getValue());
values.put(entry.getKey(), categoryValues);
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom advanced bar chart.
*/
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
continue; // Skip this invalid
}
allSkipped = false;
JSONArray categoryValues = new JSONArray();
for (int categoryValue : entry.getValue()) {
categoryValues.add(categoryValue);
}
values.put(entry.getKey(), categoryValues);
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
}

View file

@ -0,0 +1,36 @@
package com.esophose.playerparticles.util;
import org.bukkit.Bukkit;
public class NMSUtil {
private static String cachedVersion = null;
private static int cachedVersionNumber = -1;
/**
* Gets the server version
*
* @return The server version
*/
public static String getVersion() {
if (cachedVersion == null) {
String name = Bukkit.getServer().getClass().getPackage().getName();
cachedVersion = name.substring(name.lastIndexOf('.') + 1) + ".";
}
return cachedVersion;
}
/**
* Gets the server version major release number
*
* @return The server version major release number
*/
public static int getVersionNumber() {
if (cachedVersionNumber == -1) {
String name = getVersion().substring(3);
cachedVersionNumber = Integer.valueOf(name.substring(0, name.length() - 4));
}
return cachedVersionNumber;
}
}

View file

@ -50,16 +50,19 @@ public class ParticleUtils {
* Finds a block/item as a material from a list of possible strings
* Contains a fallback to the barrier icon just in case
*
* @param barrierFallback If the material should fall back to barrier
* @param input A list of material names
* @return The first matching material
*/
public static Material closestMatchWithFallback(String... input) {
public static Material closestMatchWithFallback(boolean barrierFallback, String... input) {
Material mat = null;
for (String name : input) {
mat = closestMatch(name);
if (mat != null) return mat;
if (mat != null)
return mat;
}
if (mat == null) mat = Material.BARRIER;
if (barrierFallback)
mat = Material.BARRIER;
return mat;
}

View file

@ -13,7 +13,7 @@
# This value is the version of the plugin that last modified the config file
# Changing this value manually will likely result in data loss and errors!
# Do not change this manually unless specifically told to by the plugin author
version: 6.3
version: 6.4
# Check for new versions of the plugin
# Default: true
@ -46,6 +46,15 @@ message-prefix: '&7[&3PlayerParticles&7]'
# Default: true
gui-enabled: true
# If true, only the preset groups will be available in the GUI
# Permissions to open the GUI will change to only open if the user has any preset groups available
# Default: false
gui-presets-only: false
# If true, the GUI will close after selecting a group (either saved or preset)
# Default: true
gui-close-after-group-selected: true
# If clicking a GUI button should make a noise
# Default: true
gui-button-sound: true
@ -148,6 +157,11 @@ database-user-name: ''
# Default: ''
database-user-password: ''
# If the database connection should use SSL
# You should enable this if your database supports SSL
# Default: false
database-use-ssl: false
# =================================================================== #
# GUI ICON SETTINGS #
# This configuration option allows you to change any of the GUI #
@ -173,6 +187,10 @@ gui-icon:
- ENDER_CHEST
back:
- ARROW
next_page:
- PAPER
previous_page:
- PAPER
create:
- WRITABLE_BOOK
- BOOK_AND_QUILL
@ -183,8 +201,6 @@ gui-icon:
- NETHER_STAR
edit_data:
- BOOK
randomize:
- HOPPER
reset:
- BARRIER
effect:
@ -203,9 +219,15 @@ gui-icon:
- MAGMA_BLOCK
bubble_pop:
- BUBBLE_CORAL_FAN
campfire_cosy_smoke:
- CAMPFIRE
campfire_signal_smoke:
- REDSTONE_TORCH
cloud:
- WHITE_WOOL
- WOOL
composter:
- COMPOSTER
crit:
- IRON_SWORD
current_down:
@ -239,6 +261,10 @@ gui-icon:
- TNT
falling_dust:
- SAND
falling_lava:
- RED_DYE
falling_water:
- BLUE_DYE
firework:
- FIREWORK_ROCKET
- FIREWORK
@ -266,6 +292,8 @@ gui-icon:
large_smoke:
- COBWEB
- WEB
landing_lava:
- ORANGE_DYE
lava:
- MAGMA_CREAM
mycelium:
@ -285,6 +313,8 @@ gui-icon:
- LAPIS_BLOCK
smoke:
- TORCH
sneeze:
- BAMBOO
spell:
- POTION
- GLASS_BOTTLE

View file

@ -78,6 +78,7 @@ edit-success-data: "&aYour particle with an ID of &b{0} &ahas had its data chang
# Group Command
group-invalid: "&cA saved group or preset group does not exist with the name &b{0}&c!"
group-no-permission: "&cYou are missing permission for an effect or style to use the group &b{0}&c!"
group-preset-no-permission: "&cYou are missing permission for an effect or style to use the preset group &b{0}&c!"
group-reserved: "&cThe group name &bactive &cis reserved and cannot be used!"
group-no-name: "&cYou did not provide a group name! &b/pp {0} <groupName>"
@ -217,6 +218,8 @@ gui-color-subtext: "&b"
gui-color-unavailable: "&c"
gui-commands-info: "Find info about commands with &b/pp help"
gui-back-button: "Go Back"
gui-next-page-button: "Next Page ({0}/{1})"
gui-previous-page-button: "Previous Page ({0}/{1})"
gui-click-to-load: "Click to load the following {0} particle(s):"
gui-shift-click-to-delete: "Shift click to delete"
gui-particle-info: " - ID: &b{0} &eEffect: &b{1} &eStyle: &b{2} &eData: &b{3}"
@ -267,10 +270,6 @@ gui-select-style-description: "Sets the particle style to &b{0}"
gui-select-data: "Select Particle Data"
gui-select-data-description: "Sets the particle data to &b{0}"
gui-select-data-note: "note #{0}"
gui-select-data-randomize-items: "Randomize Items"
gui-select-data-randomize-items-description: "Randomizes the items displayed"
gui-select-data-randomize-blocks: "Randomize Blocks"
gui-select-data-randomize-blocks-description: "Randomizes the blocks displayed"
gui-edit-data-color-red: "&cred"
gui-edit-data-color-orange: "&6orange"
gui-edit-data-color-yellow: "&eyellow"

View file

@ -8,10 +8,10 @@
# * PLEASE MAKE YOUR OWN .lang FILE IF YOU WANT CUSTOM MESSAGES! #
# * This file will be overridden almost every plugin update! #
# ================================================================ #
# Translator: maxime_n2
# Translator: maxime_n2 & SevenX
# Command Errors
command-error-no-effects: "&cVous n avez pas la permission d utiliser cette commande."
command-error-no-effects: "&cVous n'avez pas la permission d'utiliser cette commande."
command-error-unknown: "&cCommande inconnue, utilisez &b/pp help &cpour afficher la liste des commandes disponibles pour ce plugin."
# Command Descriptions
@ -19,87 +19,88 @@ command-descriptions: "&eLes commandes suivantes sont disponibles :"
command-descriptions-usage: "&e/pp {0} {1}"
command-descriptions-help-1: "&7> &b/pp {0} &e- {1}"
command-descriptions-help-2: "&7> &b/pp {0} {1} &e- {2}"
command-descriptions-help-other: "&7> &b/ppo <player> <command> &e- Exécute une commande /pp en tant qu un autre joueur."
command-descriptions-help-other: "&7> &b/ppo <player> <command> &e- Exécute une commande /pp en tant qu'un autre joueur."
command-description-add: "Ajoutez une nouvelle particule"
command-description-data: "Voir les paramètres utilisées par la particule"
command-description-default: "Commande principale. Par défaut elle ouvre l interface."
command-description-default: "Commande principale. Par défaut elle ouvre l'interface."
command-description-edit: "Modifiez une particule"
command-description-effects: "Affichez une liste des effets utilisés"
command-description-fixed: "Gérez vos effets fixes"
command-description-group: "Gérez vos groupes d effets"
command-description-gui: "Affichez l interface pour modifier facilement les effets"
command-description-help: "Affichez le menu d aide... Vous y êtes déjà !"
command-description-info: "Voir la description d une de vos particules actives"
command-description-group: "Gérez vos groupes d'effets"
command-description-gui: "Affichez l'interface pour modifier facilement les effets"
command-description-help: "Affichez le menu d'aide... Vous y êtes déjà !"
command-description-info: "Voir la description d'une de vos particules actives"
command-description-list: "Listez les IDs de vos particules actives"
command-description-reload: "Rechargez le fichier config.yml et de langue"
command-description-remove: "Supprimez vos particules actives."
command-description-reset: "Supprimez toutes vos particules actives"
command-description-styles: "Affichez une liste des styles de particules que vous utilisez"
command-description-toggle: "Activez ou déativez vos particules actives"
command-description-toggle: "Activez ou désactivez vos particules actives"
command-description-version: "Affichez la version du plugin et son créateur"
command-description-worlds: "Voir les mondes où ce plugin n est pas autorisé"
command-description-worlds: "Voir les mondes où ce plugin n'est pas autorisé"
# Sub-Command Usage
command-description-fixed-create: "&e/pp fixed create <<x> <y> <z>|<looking>> <effect> <style> [data] - Créez une particule fixe"
command-description-fixed-edit: "&e/pp fixed edit <id> <effect|style|data> <args> - Modifiez une partie d une particule fixe par son ID"
command-description-fixed-edit: "&e/pp fixed edit <id> <effect|style|data> <args> - Modifiez une partie d'une particule fixe par son ID"
command-description-fixed-remove: "&e/pp fixed remove <ID> - Supprimez une particule fixe par son ID"
command-description-fixed-list: "&e/pp fixed list - Affiche l ID de tous vos effets fixes"
command-description-fixed-info: "&e/pp fixed info <ID> - Voir des informations sur l une de vos particules fixe"
command-description-fixed-clear: "&e/pp fixed clear <radius> - Supprimez tous les effets fixe de tous les joueurs d un rayon"
command-description-fixed-list: "&e/pp fixed list - Affiche l'ID de tous vos effets fixes"
command-description-fixed-info: "&e/pp fixed info <ID> - Voir des informations sur l'une de vos particules fixe"
command-description-fixed-clear: "&e/pp fixed clear <radius> - Supprimez tous les effets fixe de tous les joueurs d'un rayon"
command-description-group-save: "&e/pp group save <name> - Sauvegardez toutes les particules actives dans un nouveau groupe"
command-description-group-load: "&e/pp group load <name> - Chargez toutes les particules sauvegardées dans un groupe"
command-description-group-remove: "&e/pp group remove <name> - Supprimez un groupe que vous avez créé"
command-description-group-list: "&e/pp group list <name> - Voir toutes les particules sauvegardées d un groupe que vous avez créé"
command-description-group-list: "&e/pp group list <name> - Voir toutes les particules sauvegardées d'un groupe que vous avez créé"
command-description-group-info: "&e/pp group info <name> - Voir toutes les particules sauvegardées du groupe"
# Command ID Lookup
id-invalid: "&cL ID rentrée n est pas valide, il doit être un nombre entier positif"
id-unknown: "&cVous n avez pas de particules appliquées avec : &b{0} &c!"
id-invalid: "&cL'ID rentrée n'est pas valide, il doit être un nombre entier positif"
id-unknown: "&cVous n'avez pas de particules appliquées avec : &b{0} &c!"
# Other Command
other-no-permission: "&cVous n avez pas la permission pour exécuter une commande /pp en tant qu un autre joueur."
other-no-permission: "&cVous n'avez pas la permission pour exécuter une commande /pp en tant qu'un autre joueur."
other-missing-args: "&cVous oubliez des arguments dans votre commande. &b/ppo <player> <command>"
other-unknown-player: "&cLe joueur &b{0} &cn a pas été trouvé. Il doit être en ligne."
other-unknown-player: "&cLe joueur &b{0} &cn'a pas été trouvé. Il doit être en ligne."
other-unknown-command: "&cLa commande &b/pp {0} &cn existe pas."
other-success: "&Commande /pp exécutée. &b{0}&e. Retour de la commande :"
# Add Command
add-reached-max: "Impossible d appliquer la particule, vous avez atteint la limite de particules qui est de &b{0} &c!"
add-particle-applied: "&aUne nouvelle particule est appliquée avec l effet &b{0}&a, le style &b{1}&a, et les paramètres &b{2} &a!"
add-reached-max: "Impossible d'appliquer la particule, vous avez atteint la limite de particules qui est de &b{0} &c!"
add-particle-applied: "&aUne nouvelle particule est appliquée avec l'effet &b{0}&a, le style &b{1}&a, et les paramètres &b{2} &a!"
# Data Command
data-no-args: "&cVous oubliez des arguments dans l effet. Utilisation de la commande: &b/pp data <effect>"
data-no-args: "&cVous oubliez des arguments dans l'effet. Utilisation de la commande: &b/pp data <effect>"
# Edit Command
edit-invalid-property: "cLa propriété &b{0} &cest interdite. Propriétés valides : &beffect&c, &bstyle&c, &bdata"
edit-success-effect: "&aVotre particule avec l ID de &b{0} &aa son effet changé à &b{1} &a!"
edit-success-style: "&aVotre particule avec l ID de &b{0} &aa son style changé à &b{1} &a!"
edit-success-data: "&aVotre particule avec l ID de &b{0} &aa ses paramètres changés à &b{1} &a!"
edit-success-effect: "&aVotre particule avec l'ID de &b{0} &aa son effet changé à &b{1} &a!"
edit-success-style: "&aVotre particule avec l'ID de &b{0} &aa son style changé à &b{1} &a!"
edit-success-data: "&aVotre particule avec l'ID de &b{0} &aa ses paramètres changés à &b{1} &a!"
# Group Command
group-invalid: "&cUn groupe ou un preset de groupe sauvegardé n existe pas avec le nom &b{0} &c!"
group-preset-no-permission: "&cVous oubliez une permission pour un style ou un effet afin d utiliser les persets du groupe &b{0} &c!"
group-invalid: "&cUn groupe ou un preset de groupe sauvegardé n'existe pas avec le nom &b{0} &c!"
group-no-permission: "&cVous oubliez une permission pour un style ou un effet afin d'utiliser les groupe &b{0} &c!"
group-preset-no-permission: "&cVous oubliez une permission pour un style ou un effet afin d'utiliser les presets du groupe &b{0} &c!"
group-reserved: "&cLe nom de groupe &bactive &cest réservé et ne peut pas être utiliser !"
group-no-name: "&cVous n avez pas rentré de nom de groupe ! &b/pp {0} <groupName>"
group-no-name: "&cVous n'avez pas rentré de nom de groupe ! &b/pp {0} <groupName>"
group-save-reached-max: "&cImpossible de sauvegarder le groupe, vous avez atteint le nombre maximun de groupes !"
group-save-no-particles: "&cImpossible de sauvegarder le groupe, vous n avez pas appliqué de particules !"
group-save-success: "&aVos particules actuelles on été sauvegardées sous le nom de groupe &b{0} &a!"
group-save-no-particles: "&cImpossible de sauvegarder le groupe, vous n'avez pas appliqué de particules !"
group-save-success: "&aVos particules actuelles ont été sauvegardées sous le nom de groupe &b{0} &a!"
group-save-success-overwrite: "&aLe groupe &b{0} &aa été mis à jour avec vos particules actuelle !"
group-load-success: "&b{0} &aparticule(s) appliqués venant du groupe sauvegardé nommé &b{1} &a!"
group-load-preset-success: "&b{0} &aparticule(s) appliqués venant du preset sauvegardé nommé &b{1} &a!"
group-remove-preset: "&cVous ne pouvez pas supprimer un groupe de presets !"
group-remove-success: "&aGroupe de particules &b{0} &asupprimé !"
group-info-header: "&eLe groupe &b{0} &eposséde les particules suivantes :"
group-list-none: "&eVous n avez pas de groupes de particules sauvegardés !"
group-list-none: "&eVous n'avez pas de groupes de particules sauvegardés !"
group-list-output: "&eVous avez ces groupes suivants sauvegardés : &b{0}"
group-list-presets: "&eCes presets de groupes suivants sont disponibles : &b{0}"
# Reload Command
reload-success: "&aLe plugin a été rechargé..."
reload-no-permission: "&cVous n avez pas la permission pour recharger la configuration de ce plugin !"
reload-no-permission: "&cVous n'avez pas la permission pour recharger la configuration de ce plugin !"
# Remove Command
remove-no-args: "&cVous n avez pas rentrer d ID à supprimer ! &b/pp remove <ID>"
remove-no-args: "&cVous n'avez pas rentrer d'ID à supprimer ! &b/pp remove <ID>"
remove-id-success: "&aVotre particule avec l'ID &b{0} &aa été supprimée !"
remove-effect-success: "&aSuppression de &b{0} &ade votre particule avec l'effet &b{1} &a!"
remove-effect-none: "&cVous n'avez pas de particules appliquées avec l'effet &b{0} &c!"
@ -108,7 +109,7 @@ remove-style-none: "&cVous n'avez pas de particules appliquées avec le style &b
remove-unknown: "&cL'effect avec le nom ou le style &b{0} &cn'existe pas !"
# List Command
list-none: "&eVous n avez pas de particules actives."
list-none: "&eVous n'avez pas de particules actives."
list-you-have: "&eVous avez les particules suivantes appliquées :"
list-output: "&eID: &b{0} &eEffet: &b{1} &eStyle: &b{2} &eParamètre: &b{3}"
@ -123,31 +124,31 @@ rainbow: "&cr&6a&ei&an&bb&9o&dw"
random: "aléatoire"
# Effects
effect-no-permission: "&cVous n avez pas la permission pour utiliser la particule &b{0} &c!"
effect-invalid: "&cL effet &b{0} &cn existe pas ! Utilisez &b/pp effects &cpour afficher les effets disponibles."
effect-no-permission: "&cVous n'avez pas la permission pour utiliser la particule &b{0} &c!"
effect-invalid: "&cL'effet &b{0} &cn existe pas ! Utilisez &b/pp effects &cpour afficher les effets disponibles."
effect-list: "&eVous pouvez utiliser les effets suivants : &b{0}"
effect-list-empty: "&cVous n avez pas la permission pour utiliser des effets !"
effect-list-empty: "&cVous n'avez pas la permission pour utiliser des effets !"
# Styles
style-no-permission: "&cVous n avez pas la permission pour utiliser le style &b{0} &c!"
style-event-spawning-info: "&eNote: Le style &b{0} &efait apparaitre des particules seulement lors d évènements spécifiques."
style-invalid: "&cLe style &b{0} &cn existe pas ! Utilisez &b/pp styles &cpour afficher les styles disponibles."
style-no-permission: "&cVous n'avez pas la permission pour utiliser le style &b{0} &c!"
style-event-spawning-info: "&eNote: Le style &b{0} &efait apparaitre des particules seulement lors d'évènements spécifiques."
style-invalid: "&cLe style &b{0} &cn'existe pas ! Utilisez &b/pp styles &cpour afficher les styles disponibles."
style-list: "&eVous pouvez utiliser les styles suivants : &b{0}"
# Data
data-usage-none: "&eL effet &b{0} &en est pas paramétrable."
data-usage-block: "&eL effet &b{0} &erequière l ID du bloc ! &bFormat: <blockName>"
data-usage-item: "&eL effet &b{0} &erequière l ID de l item ! &bFormat: <itemName>"
data-usage-color: "&eL effet &b{0} &erequière l ID de la couleur ! &bFormat: <<0-255> <0-255> <0-255>>|<rainbow>|<random>"
data-usage-note: "&eL effet&b{0} &erequière l ID de la note ! &bFormat: <0-24>|<rainbow>|<random>"
data-invalid-block: "&cL ID du bloc que vous avez rentré n est pas valide ! &bFormat: <blockName>"
data-invalid-item: "&cL ID de l item que vous avez rentré n est pas valide ! &bFormat: <itemName>"
data-invalid-color: "&cL ID de la couleur que vous avez rentré n est pas valide ! &bFormat: <<0-255> <0-255> <0-255>>|<rainbow>|<random>"
data-invalid-note: "&cL ID du bloc que vous avez rentré n est pas valide ! &bFormat: <0-24>|<rainbow>|<random>"
data-invalid-material-not-item: "&cL ID &b{0} &cne correspond pas à un item !"
data-invalid-material-not-block: "&cL ID &b{0} &cne correspond pas à un bloc !"
data-invalid-material-item: "&cL ID &b{0} n existe pas !"
data-invalid-material-block: "&cL ID&b{0} n existe pas !"
data-usage-none: "&eL'effet &b{0} &en'est pas paramétrable."
data-usage-block: "&eL'effet &b{0} &erequière l'ID du bloc ! &bFormat: <blockName>"
data-usage-item: "&eL'effet &b{0} &erequière l'ID de l'item ! &bFormat: <itemName>"
data-usage-color: "&eL'effet &b{0} &erequière l'ID de la couleur ! &bFormat: <<0-255> <0-255> <0-255>>|<rainbow>|<random>"
data-usage-note: "&eL'effet&b{0} &erequière l'ID de la note ! &bFormat: <0-24>|<rainbow>|<random>"
data-invalid-block: "&cL'ID du bloc que vous avez rentré n'est pas valide ! &bFormat: <blockName>"
data-invalid-item: "&cL'ID de l'item que vous avez rentré n'est pas valide ! &bFormat: <itemName>"
data-invalid-color: "&cL'ID de la couleur que vous avez rentré n'est pas valide ! &bFormat: <<0-255> <0-255> <0-255>>|<rainbow>|<random>"
data-invalid-note: "&cL'ID du bloc que vous avez rentré n'est pas valide ! &bFormat: <0-24>|<rainbow>|<random>"
data-invalid-material-not-item: "&cL'ID &b{0} &cne correspond pas à un item !"
data-invalid-material-not-block: "&cL'ID &b{0} &cne correspond pas à un bloc !"
data-invalid-material-item: "&cL'ID &b{0} n'existe pas !"
data-invalid-material-block: "&cL'ID&b{0} n'existe pas !"
# Worlds
disabled-worlds: "&eLes particules sont désactivées dans ces mondes : &b{0}"
@ -161,48 +162,48 @@ fixed-create-missing-args: "&cImpossible de créer un effet fixe, vous oubliez d
fixed-create-invalid-coords: "&cImpossible de créer un effet fixe, coordonnées invalides !"
fixed-create-out-of-range: "&cImpossible de créer un effet fixe, Vous devez être à &b{0} &cblocs de la position rentrée !"
fixed-create-looking-too-far: "&cImpossible de créer un effet fixe, vous êtes trop loin du bloc que vous regardez !"
fixed-create-effect-invalid: "&cImpossible de créer un effet fixe, l effet &b{0} &cn existe pas !"
fixed-create-effect-no-permission: "&cImpossible de créer un effet fixe, vous n avez pas la permission pour utiliser le style &b{0} &c!"
fixed-create-style-invalid: "&cImpossible de créer un effet fixe, le style &b{0} &cn existe pas!"
fixed-create-style-no-permission: "&cImpossible de créer un effet fixe, vous n avez pas la permission pour utiliser le style &b{0} &c!"
fixed-create-style-non-fixable: "&cImpossible de créer un effet fixe, le style &b{0} &cne peut pas être utilisé en tant qu effet fixe !"
fixed-create-data-error: "&cImpossible de créer un effet fixe, l ID rentrée n est pas valide ! Utilisez &b/pp data <effect> &cpour afficher les IDs valides."
fixed-create-success: "&aL effet fixe à été créer."
fixed-create-effect-invalid: "&cImpossible de créer un effet fixe, l effet &b{0} &cn'existe pas !"
fixed-create-effect-no-permission: "&cImpossible de créer un effet fixe, vous n'avez pas la permission pour utiliser le style &b{0} &c!"
fixed-create-style-invalid: "&cImpossible de créer un effet fixe, le style &b{0} &cn'existe pas!"
fixed-create-style-no-permission: "&cImpossible de créer un effet fixe, vous n'avez pas la permission pour utiliser le style &b{0} &c!"
fixed-create-style-non-fixable: "&cImpossible de créer un effet fixe, le style &b{0} &cne peut pas être utilisé en tant qu'effet fixe !"
fixed-create-data-error: "&cImpossible de créer un effet fixe, l'ID rentrée n'est pas valide ! Utilisez &b/pp data <effect> &cpour afficher les IDs valides."
fixed-create-success: "&aL'effet fixe à été créer."
fixed-edit-missing-args: "&cImpossible de modifier l effet fixe, vous oubliez des arguments !"
fixed-edit-invalid-id: "&cImpossible de modifier l effet fixe, ID incorrecte !"
fixed-edit-invalid-property: "&cImpossible de modifier l effet fixe, argument incorrecte ! Seuls localisation, effet, style, et paramètre sont valides."
fixed-edit-invalid-coords: "&cImpossible de modifier l effet fixe, coordonnée incorrecte !"
fixed-edit-out-of-range: "&cImpossible de modifier l effet fixe, vous devez être à &b{0} &cblocs de l emplacement désiré !"
fixed-edit-looking-too-far: "&cImpossible de modifier l effet fixe, vous êtes trop loin du bloc que vous regardez !"
fixed-edit-effect-invalid: "&cImpossible de modifier l effet fixe, l effet &b{0} &cn existe pas !"
fixed-edit-effect-no-permission: "&cImpossible de modifier l effet fixe, vous n avez pas la permission pour utiliser l effet &b{0} &c!"
fixed-edit-style-invalid: "&cImpossible de modifier l effet fixe, le style &b{0} &cn existe pas !"
fixed-edit-style-no-permission: "&cImpossible de modifier l effet fixe, vous n avez pas la permission pour utiliser le style &b{0} &c!"
fixed-edit-style-non-fixable: "&cImpossible de modifier l effet fixe, the style &b{0} &cne peut pas être utilisé dans des effets fixes !"
fixed-edit-data-error: "&cImpossible de modifier l effet fixe, paramètre incorrecte ! Utilisez &b/pp data <effect> pour afficher les paramètres valides."
fixed-edit-data-none: "&cImpossible de modifier l effet fixe, l effet ne requière pas de paramètres !"
fixed-edit-success: "&aMise à jour de &b{0} &ade l effet fixe avec l ID &b{1} &a!"
fixed-edit-missing-args: "&cImpossible de modifier l'effet fixe, vous oubliez des arguments !"
fixed-edit-invalid-id: "&cImpossible de modifier l'effet fixe, ID incorrecte !"
fixed-edit-invalid-property: "&cImpossible de modifier l'effet fixe, argument incorrect ! Seuls localisation, effet, style, et paramètre sont valides."
fixed-edit-invalid-coords: "&cImpossible de modifier l'effet fixe, coordonnée incorrecte !"
fixed-edit-out-of-range: "&cImpossible de modifier l'effet fixe, vous devez être à &b{0} &cblocs de l'emplacement désiré !"
fixed-edit-looking-too-far: "&cImpossible de modifier l'effet fixe, vous êtes trop loin du bloc que vous regardez !"
fixed-edit-effect-invalid: "&cImpossible de modifier l'effet fixe, l'effet &b{0} &cn'existe pas !"
fixed-edit-effect-no-permission: "&cImpossible de modifier l'effet fixe, vous n'avez pas la permission pour utiliser l'effet &b{0} &c!"
fixed-edit-style-invalid: "&cImpossible de modifier l'effet fixe, le style &b{0} &cn'existe pas !"
fixed-edit-style-no-permission: "&cImpossible de modifier l'effet fixe, vous n'avez pas la permission pour utiliser le style &b{0} &c!"
fixed-edit-style-non-fixable: "&cImpossible de modifier l'effet fixe, the style &b{0} &cne peut pas être utilisé dans des effets fixes !"
fixed-edit-data-error: "&cImpossible de modifier l'effet fixe, paramètre incorrect ! Utilisez &b/pp data <effect> pour afficher les paramètres valides."
fixed-edit-data-none: "&cImpossible de modifier l'effet fixe, l'effet ne requière pas de paramètres !"
fixed-edit-success: "&aMise à jour de &b{0} &ade l'effet fixe avec l'ID &b{1} &a!"
fixed-remove-invalid: "&cImpossible de supprimer l effet fixe, vous n avez pas d effets fixes avec l ID &b{0} &c!"
fixed-remove-no-args: "&cVous n avez pas rentrer d ID à supprimer !"
fixed-remove-args-invalid: "&cImpossible de supprimer, l ID doit être un nombre !"
fixed-remove-success: "&aTous vos effets fixes avec l ID &b{0} &aont été supprimés !"
fixed-remove-invalid: "&cImpossible de supprimer l'effet fixe, vous n'avez pas d effets fixes avec l'ID &b{0} &c!"
fixed-remove-no-args: "&cVous n'avez pas rentrer d'ID à supprimer !"
fixed-remove-args-invalid: "&cImpossible de supprimer, l'ID doit être un nombre !"
fixed-remove-success: "&aTous vos effets fixes avec l'ID &b{0} &aont été supprimés !"
fixed-list-none: "&eVous n avez pas d effets fixes !"
fixed-list-none: "&eVous n'avez pas d'effets fixes !"
fixed-list-success: "&eVous avez des effets fixes avec ces IDs :&b{0}"
fixed-info-invalid: "&cImpossible de obtenir l information, vous n avez pas de particules fixes avec l ID &b{0}& c!"
fixed-info-no-args: "&cVous n avez pas rentrée d ID pour obtenir d infomations !"
fixed-info-invalid-args: "&cImpossible d obtenir l information, vous n avez pas de particules fixes avec l ID, l ID spécifiée doit être un nombre !"
fixed-info-invalid: "&cImpossible d'obtenir l'information, vous n'avez pas de particules fixes avec l'ID &b{0}& c!"
fixed-info-no-args: "&cVous n'avez pas rentrée d'ID pour obtenir d'infomations !"
fixed-info-invalid-args: "&cImpossible d'obtenir l'information, vous n'avez pas de particules fixes avec l'ID, l'ID spécifiée doit être un nombre !"
fixed-info-success: "&eID: &b{0} &eWorld: &b{1} &eX: &b{2} &eY: &b{3} &eZ: &b{4} &eEffect: &b{5} &eStyle: &b{6} &eData: &b{7}"
fixed-clear-no-permission: "&cVous n avez la permission pour supprimer les effets proches !"
fixed-clear-no-args: "&cVous n avez pas rentré de rayon !"
fixed-clear-invalid-args: "&cLe rayon rentré n est pas valide, il doit être un nombre rond !"
fixed-clear-success: "&b{0} &aeffets on été supprimés dans un rayon &b{1} &cblocs !"
fixed-clear-no-permission: "&cVous n'avez la permission pour supprimer les effets proches !"
fixed-clear-no-args: "&cVous n'avez pas rentré de rayon !"
fixed-clear-invalid-args: "&cLe rayon rentré n'est pas valide, il doit être un nombre rond !"
fixed-clear-success: "&b{0} &aeffets ont été supprimés dans un rayon &b{1} &cblocs !"
fixed-no-permission: "&cVous n avez pas la permission d ajouter des effets fixes !"
fixed-no-permission: "&cVous n'avez pas la permission d'ajouter des effets fixes !"
fixed-max-reached: "&cVous avez atteint le nombre maximum de particules fixes !"
fixed-invalid-command: "&cArguments invalides pour la commande &b/pp fixed&c!"
@ -210,13 +211,15 @@ fixed-invalid-command: "&cArguments invalides pour la commande &b/pp fixed&c!"
update-available: "&eLa version (&b{0}&e) est disponible ! vous utilisez la version &bv{1}&d. https://www.spigotmc.org/resources/playerparticles.40261/"
# GUI
gui-disabled: "&cL interface du plugin à été désactivée !"
gui-disabled: "&cL'interface du plugin à été désactivée !"
gui-color-icon-name: "&a"
gui-color-info: "&e"
gui-color-subtext: "&b"
gui-color-unavailable: "&c"
gui-commands-info: "Affichez des informations avec &b/pp help"
gui-back-button: "Retour en arrière"
gui-next-page-button: "Page Suivante ({0}/{1})"
gui-previous-page-button: "Page Précédente ({0}/{1})"
gui-click-to-load: "Cliquez pour charger : {0}"
gui-shift-click-to-delete: "Touche SHIFT + clic-gauche pour effacer un effet"
gui-particle-info: " - ID: &b{0} &eEffet: &b{1} &eStyle: &b{2} &eParamètre: &b{3}"
@ -224,14 +227,14 @@ gui-playerparticles: "PlayerParticles"
gui-active-particles: "Particules actives: &b{0}"
gui-saved-groups: "Groupes sauvegardés: &b{0}"
gui-fixed-effects: "Effets fixes: &b{0}"
gui-edit-primary-effect: "Editez l effet primaire"
gui-edit-primary-effect: "Editez l'effet primaire"
gui-edit-primary-effect-description: "Editez l effet d une de vos particules primaire"
gui-edit-primary-style: "Editez le style primaire"
gui-edit-primary-style-missing-effect: "Vous devez d abord sélectionner un effet !"
gui-edit-primary-style-description: "Editez le style d une particule primaire"
gui-edit-primary-data: "Editez les paramètres d une particules primaire"
gui-edit-primary-data-missing-effect: "Vous devez d abord sélectionner un effet"
gui-edit-primary-data-unavailable: "Votre effet primaire n est pas paramétrable"
gui-edit-primary-style-missing-effect: "Vous devez d'abord sélectionner un effet !"
gui-edit-primary-style-description: "Editez le style d'une particule primaire"
gui-edit-primary-data: "Editez les paramètres d'une particules primaire"
gui-edit-primary-data-missing-effect: "Vous devez d'abord sélectionner un effet"
gui-edit-primary-data-unavailable: "Votre effet primaire n'est pas paramétrable"
gui-edit-primary-data-description: "Editer les paramères de votre effet primaire"
gui-manage-your-particles: "Gérez vos particules"
gui-manage-your-particles-description: "Créez, éditez, et supprimez vos particules"
@ -240,7 +243,7 @@ gui-manage-your-groups-description: "Créez, éditez, et supprimez vos groupes p
gui-load-a-preset-group: "Chargez un groupe de presets"
gui-load-a-preset-group-description: "Chargez un groupe de particules déjà fait"
gui-save-group: "Sauvegardez un nouveau groupe"
gui-save-group-description: "Cliquez pour sauvegardez un nouveau groupe. Vous allez être invité\na écrire un nouveau nom dans le tchat."
gui-save-group-description: "Cliquez pour sauvegardez un nouveau groupe. Vous allez être invité\nà écrire un nouveau nom dans le tchat."
gui-save-group-full: "Vous avez atteint le nombre maximal de groupe !"
gui-save-group-no-particles: "Vous avez aucunes particules appliquées"
gui-save-group-hotbar-message: "&eTapez &b1 &enom dans le tchat pour le nouveau nom du groupe. Tapez &ccancel&e pour annuler. (&b{0}&es restants)"
@ -249,8 +252,8 @@ gui-reset-particles-description: "Supprimez vos particules actives"
gui-particle-name: "Particule #{0}"
gui-click-to-edit-particle: "Cliquez pour éditer cette particule"
gui-editing-particle: "Edition particule #{0}"
gui-edit-effect: "Editez l effet"
gui-edit-effect-description: "Cliquez pour éditer l effet de cette particule"
gui-edit-effect: "Editez l'effet"
gui-edit-effect-description: "Cliquez pour éditer l'effet de cette particule"
gui-edit-style: "Editez le style"
gui-edit-style-description: "Cliquez pour éditer le style de cette particule"
gui-edit-data: "Editez les paramères"
@ -267,10 +270,6 @@ gui-select-style-description: "Mets le style de la particule à &b{0}"
gui-select-data: "Sélectionnez les paramètres"
gui-select-data-description: "Mets les paramètres de la particule à &b{0}"
gui-select-data-note: "note #{0}"
gui-select-data-randomize-items: "Mélangez les items"
gui-select-data-randomize-items-description: "Mélangez les items affichés"
gui-select-data-randomize-blocks: "Mélangez les blocs"
gui-select-data-randomize-blocks-description: "Mélangez les blocs affichés"
gui-edit-data-color-red: "&crouge"
gui-edit-data-color-orange: "&6orange"
gui-edit-data-color-yellow: "&ejaune"

View file

@ -78,6 +78,7 @@ edit-success-data: "&aHạt hiệu ứng của bạn với ID &b{0} &ađã thanh
# Group Command
group-invalid: "&cMột Group đã lưu hoặc Preset Group không được tìm thấy với tên &b{0}&c!"
group-no-permission: "&cBạn không có quyền for 1 effect, style để sử dụng nhóm sẵn &b{0}&c!"
group-preset-no-permission: "&cBạn không có quyền for 1 effect, style để sử dụng nhóm cài sẵn &b{0}&c!"
group-reserved: "&cGroup tên &bactive &ckhông thể được sử dụng!"
group-no-name: "&cBạn đã không cung cấp tên group! &b/pp {0} <groupName>"
@ -95,8 +96,8 @@ group-list-output: "&eBạn đã lưu các Group sau: &b{0}"
group-list-presets: "&eCác preset group có sẵn: &b{0}"
# Reload Command
reload-success: "&aCác plugin đã được tải lại!"
reload-no-permission: "&cBạn không có quyền tải lại các cài đặt plugin!"
reload-success: "&aĐã tải lại plugins!"
reload-no-permission: "&cBạn không có quyền để tải lại plugins!"
# Remove Command
remove-no-args: "&cBạn không chỉ định IDs để xóa! &b/pp remove <ID>"
@ -217,6 +218,8 @@ gui-color-subtext: "&b"
gui-color-unavailable: "&c"
gui-commands-info: "Hiển thị thêm các lệnh bằng cách gõ &b/pp help"
gui-back-button: "Quay trở về"
gui-next-page-button: "Trang tiếp theo ({0}/{1})"
gui-previous-page-button: "Trang trước ({0}/{1})"
gui-click-to-load: "Nhấn để tải {0} Hạt hiệu ứng sau:"
gui-shift-click-to-delete: "Shift Click để xóa"
gui-particle-info: " - ID: &b{0} &eEffect: &b{1} &eStyle: &b{2} &eData: &b{3}"
@ -267,10 +270,6 @@ gui-select-style-description: "Thiết lập Kiểu hiệu ứng của Hạt th
gui-select-data: "Chọn Dữ liệu của Hạt"
gui-select-data-description: "Thiết lập DỮ liệu của Hạt thành &b{0}"
gui-select-data-note: "note #{0}"
gui-select-data-randomize-items: "Vật phẩm ngẫu nhiên"
gui-select-data-randomize-items-description: "Đã hiển thị vật phẩm ngẫu nhiên"
gui-select-data-randomize-blocks: "Khối ngẫu nhiên"
gui-select-data-randomize-blocks-description: "Đã hiển thị khối ngẫu nhiên"
gui-edit-data-color-red: "&cĐỏ mạnh mẽ"
gui-edit-data-color-orange: "&6Cam dịu dàng"
gui-edit-data-color-yellow: "&eVàng yêu thương"

View file

@ -1,8 +1,8 @@
name: PlayerParticles
main: com.esophose.playerparticles.PlayerParticles
version: 6.3
version: 6.4
api-version: 1.13
description: Display particles around your player using customized styles and data!
description: Display particles around your player and blocks using customized styles and data!
author: Esophose
website: https://www.spigotmc.org/resources/playerparticles.40261/
commands:
@ -10,3 +10,4 @@ commands:
description: The main PlayerParticles command. By default, opens the GUI.
ppo:
description: Allows executing a /pp command for another player.
permission: playerparticles.other