Internal Configuration Improvements

The ConfigurationManager now runs on a callback-based system. These
calls will become async soon to help improve performance while in
database mode. Minor bug fix with GUI and fix some missing semantics.
This commit is contained in:
Esophose 2018-03-02 02:47:24 -07:00
parent 1f24740e0a
commit 900d6785be
12 changed files with 781 additions and 575 deletions

View file

@ -266,7 +266,7 @@ public class PPlayer {
}
}
}
return "None";
return "none";
}
/**

View file

@ -22,8 +22,8 @@ import com.esophose.playerparticles.manager.PermissionManager;
public class ParticleCommandCompleter implements TabCompleter {
private final String[] COMMANDS = { "help", "gui", "effect", "effects", "style", "styles", "worlds", "version", "fixed", "reset" };
private final String[] FIXED_COMMANDS = { "create", "remove", "list", "info" };
private static final String[] COMMANDS = { "help", "gui", "effect", "effects", "style", "styles", "data", "fixed", "reset", "worlds", "version" };
private static final String[] FIXED_COMMANDS = { "create", "remove", "list", "info" };
/**
* Activated when a user pushes tab in chat prefixed with /pp
@ -57,5 +57,9 @@ public class ParticleCommandCompleter implements TabCompleter {
}
return completions;
}
public static String[] getCommandsList() {
return COMMANDS;
}
}

View file

@ -43,6 +43,16 @@ import com.esophose.playerparticles.styles.api.ParticleStyleManager;
import com.esophose.playerparticles.util.ParticleUtils;
public class ParticleCommandExecutor implements CommandExecutor {
/**
* A list of all valid commands
*/
private static List<String> validCommands;
static {
validCommands = new ArrayList<String>();
validCommands.addAll(Arrays.asList(ParticleCommandCompleter.getCommandsList()));
}
/**
* Called when a player executes a /pp command
@ -57,36 +67,48 @@ public class ParticleCommandExecutor implements CommandExecutor {
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (!(sender instanceof Player)) return true;
Player p = (Player) sender;
if (args.length == 0) {
onGUI(p, true);
return true;
} else {
String[] cmdArgs = new String[0];
if (args.length >= 2) cmdArgs = Arrays.copyOfRange(args, 1, args.length);
}
if (!validCommands.contains(args[0].toLowerCase())) {
MessageManager.sendMessage(p, MessageType.INVALID_ARGUMENTS);
return true;
}
String[] cmdArgs = new String[0];
if (args.length >= 2) cmdArgs = Arrays.copyOfRange(args, 1, args.length);
// Commands that don't require access to any effects
switch (args[0].toLowerCase()) {
case "help":
onHelp(p);
return true;
case "worlds":
onWorlds(p);
return true;
case "version":
onVersion(p);
return true;
case "effects":
onEffects(p);
return true;
case "styles":
onStyles(p);
return true;
case "style":
onStyle(p, cmdArgs);
return true;
}
// Commands that require access to effects
if (PermissionManager.getEffectsUserHasPermissionFor(p).size() != 1) {
switch (args[0].toLowerCase()) {
case "help":
onHelp(p);
break;
case "worlds":
onWorlds(p);
break;
case "version":
onVersion(p);
break;
case "effect":
onEffect(p, cmdArgs);
break;
case "effects":
onEffects(p);
break;
case "style":
onStyle(p, cmdArgs);
break;
case "styles":
onStyles(p);
break;
case "data":
onData(p, cmdArgs);
break;
@ -99,11 +121,12 @@ public class ParticleCommandExecutor implements CommandExecutor {
case "gui":
onGUI(p, false);
break;
default:
MessageManager.sendMessage(p, MessageType.INVALID_ARGUMENTS);
}
return true;
} else {
MessageManager.sendMessage(p, MessageType.NO_PARTICLES);
}
return true;
}
/**
@ -165,7 +188,12 @@ public class ParticleCommandExecutor implements CommandExecutor {
* @param args The arguments for the command
*/
private void onData(Player p, String[] args) {
ParticleEffect effect = ConfigManager.getInstance().getPPlayer(p.getUniqueId(), true).getParticleEffect();
if (PermissionManager.getEffectsUserHasPermissionFor(p).size() == 1) {
return;
}
ParticleEffect effect = ConfigManager.getInstance().getPPlayer(p.getUniqueId()).getParticleEffect();
if ((!effect.hasProperty(ParticleProperty.REQUIRES_DATA) && !effect.hasProperty(ParticleProperty.COLORABLE)) || args.length == 0) {
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
if (effect == ParticleEffect.NOTE) {
@ -386,6 +414,11 @@ public class ParticleCommandExecutor implements CommandExecutor {
* @param p The player who used the command
*/
private void onEffects(Player p) {
if (PermissionManager.getEffectsUserHasPermissionFor(p).size() == 1) {
MessageManager.sendMessage(p, MessageType.NO_PARTICLES);
return;
}
String toSend = MessageType.USE.getMessage() + " ";
for (ParticleEffect effect : ParticleEffect.getSupportedEffects()) {
if (PermissionManager.hasEffectPermission(p, effect)) {
@ -396,10 +429,7 @@ public class ParticleCommandExecutor implements CommandExecutor {
if (toSend.endsWith(", ")) {
toSend = toSend.substring(0, toSend.length() - 2);
}
if (toSend.equals(MessageType.USE.getMessage() + " " + ParticleEffect.NONE.getName())) {
MessageManager.sendMessage(p, MessageType.NO_PARTICLES);
return;
}
MessageManager.sendCustomMessage(p, toSend);
MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.PARTICLE_USAGE.getMessage());
}
@ -411,6 +441,10 @@ public class ParticleCommandExecutor implements CommandExecutor {
* @param args The arguments for the command
*/
private void onStyle(Player p, String[] args) {
if (PermissionManager.getStylesUserHasPermissionFor(p).size() == 1) {
MessageManager.sendMessage(p, MessageType.NO_STYLES);
return;
}
if (args.length == 0) {
MessageManager.sendMessage(p, MessageType.INVALID_TYPE_STYLE);
return;
@ -439,6 +473,11 @@ public class ParticleCommandExecutor implements CommandExecutor {
* @param p The player who used the command
*/
private void onStyles(Player p) {
if (PermissionManager.getStylesUserHasPermissionFor(p).size() == 1) {
MessageManager.sendMessage(p, MessageType.NO_STYLES);
return;
}
String toSend = MessageType.USE.getMessage() + " ";
for (ParticleStyle style : ParticleStyleManager.getStyles()) {
if (PermissionManager.hasStylePermission(p, style)) {
@ -449,10 +488,7 @@ public class ParticleCommandExecutor implements CommandExecutor {
if (toSend.endsWith(", ")) {
toSend = toSend.substring(0, toSend.length() - 2);
}
if (toSend.equals(MessageType.USE.getMessage() + " " + DefaultStyles.NONE.getName().toLowerCase())) {
MessageManager.sendMessage(p, MessageType.NO_STYLES);
return;
}
MessageManager.sendCustomMessage(p, toSend);
MessageManager.sendCustomMessage(p, MessageType.USAGE.getMessage() + " " + MessageType.STYLE_USAGE.getMessage());
}
@ -488,188 +524,200 @@ public class ParticleCommandExecutor implements CommandExecutor {
args = cmdArgs;
if (cmd.equalsIgnoreCase("create")) {
if (ConfigManager.getInstance().hasPlayerReachedMaxFixedEffects(p.getUniqueId())) {
MessageManager.sendMessage(p, MessageType.MAX_FIXED_EFFECTS_REACHED);
return;
}
if (args.length < 5) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_MISSING_ARGS, (5 - args.length) + "");
return;
}
double xPos = -1, yPos = -1, zPos = -1;
try {
if (args[0].startsWith("~")) {
if (args[0].equals("~")) xPos = p.getLocation().getX();
else xPos = p.getLocation().getX() + Double.parseDouble(args[0].substring(1));
} else {
xPos = Double.parseDouble(args[0]);
String[] f_args = args;
ConfigManager.getInstance().hasPlayerReachedMaxFixedEffects(p.getUniqueId(), (reachedMax) -> {
if (reachedMax) {
MessageManager.sendMessage(p, MessageType.MAX_FIXED_EFFECTS_REACHED);
return;
}
if (f_args.length < 5) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_MISSING_ARGS, (5 - f_args.length) + "");
return;
}
if (args[1].startsWith("~")) {
if (args[1].equals("~")) yPos = p.getLocation().getY() + 1;
else yPos = p.getLocation().getY() + 1 + Double.parseDouble(args[1].substring(1));
} else {
yPos = Double.parseDouble(args[1]);
}
if (args[2].startsWith("~")) {
if (args[2].equals("~")) zPos = p.getLocation().getZ();
else zPos = p.getLocation().getZ() + Double.parseDouble(args[2].substring(1));
} else {
zPos = Double.parseDouble(args[2]);
}
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_INVALID_COORDS);
return;
}
double distanceFromEffect = p.getLocation().distance(new Location(p.getWorld(), xPos, yPos, zPos));
int maxCreationDistance = ConfigManager.getInstance().getMaxFixedEffectCreationDistance();
if (maxCreationDistance != 0 && distanceFromEffect > maxCreationDistance) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_OUT_OF_RANGE, maxCreationDistance + "");
return;
}
ParticleEffect effect = ParticleManager.effectFromString(args[3]);
if (effect == null) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_INVALID_EFFECT, args[3]);
return;
} else if (!PermissionManager.hasEffectPermission(p, effect)) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_NO_PERMISSION_EFFECT, effect.getName());
return;
}
ParticleStyle style = ParticleStyleManager.styleFromString(args[4]);
if (style == null) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_INVALID_STYLE, args[4]);
return;
} else if (!PermissionManager.hasStylePermission(p, style)) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_NO_PERMISSION_STYLE, args[4]);
return;
}
if (!style.canBeFixed()) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_NON_FIXABLE_STYLE, style.getName());
return;
}
ItemData itemData = null;
BlockData blockData = null;
OrdinaryColor colorData = null;
NoteColor noteColorData = null;
if (args.length > 5) {
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
if (effect == ParticleEffect.NOTE) {
if (args[5].equalsIgnoreCase("rainbow")) {
noteColorData = new NoteColor(99);
} else {
int note = -1;
try {
note = Integer.parseInt(args[5]);
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "note");
return;
}
if (note < 0 || note > 23) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "note");
return;
}
noteColorData = new NoteColor(note);
}
double xPos = -1, yPos = -1, zPos = -1;
try {
if (f_args[0].startsWith("~")) {
if (f_args[0].equals("~")) xPos = p.getLocation().getX();
else xPos = p.getLocation().getX() + Double.parseDouble(f_args[0].substring(1));
} else {
if (args[5].equalsIgnoreCase("rainbow")) {
colorData = new OrdinaryColor(999, 999, 999);
xPos = Double.parseDouble(f_args[0]);
}
if (f_args[1].startsWith("~")) {
if (f_args[1].equals("~")) yPos = p.getLocation().getY() + 1;
else yPos = p.getLocation().getY() + 1 + Double.parseDouble(f_args[1].substring(1));
} else {
yPos = Double.parseDouble(f_args[1]);
}
if (f_args[2].startsWith("~")) {
if (f_args[2].equals("~")) zPos = p.getLocation().getZ();
else zPos = p.getLocation().getZ() + Double.parseDouble(f_args[2].substring(1));
} else {
zPos = Double.parseDouble(f_args[2]);
}
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_INVALID_COORDS);
return;
}
double distanceFromEffect = p.getLocation().distance(new Location(p.getWorld(), xPos, yPos, zPos));
int maxCreationDistance = ConfigManager.getInstance().getMaxFixedEffectCreationDistance();
if (maxCreationDistance != 0 && distanceFromEffect > maxCreationDistance) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_OUT_OF_RANGE, maxCreationDistance + "");
return;
}
ParticleEffect effect = ParticleManager.effectFromString(f_args[3]);
if (effect == null) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_INVALID_EFFECT, f_args[3]);
return;
} else if (!PermissionManager.hasEffectPermission(p, effect)) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_NO_PERMISSION_EFFECT, effect.getName());
return;
}
ParticleStyle style = ParticleStyleManager.styleFromString(f_args[4]);
if (style == null) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_INVALID_STYLE, f_args[4]);
return;
} else if (!PermissionManager.hasStylePermission(p, style)) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_NO_PERMISSION_STYLE, f_args[4]);
return;
}
if (!style.canBeFixed()) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_NON_FIXABLE_STYLE, style.getName());
return;
}
ItemData itemData = null;
BlockData blockData = null;
OrdinaryColor colorData = null;
NoteColor noteColorData = null;
if (f_args.length > 5) {
if (effect.hasProperty(ParticleProperty.COLORABLE)) {
if (effect == ParticleEffect.NOTE) {
if (f_args[5].equalsIgnoreCase("rainbow")) {
noteColorData = new NoteColor(99);
} else {
int note = -1;
try {
note = Integer.parseInt(f_args[5]);
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "note");
return;
}
if (note < 0 || note > 23) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "note");
return;
}
noteColorData = new NoteColor(note);
}
} else {
int r = -1;
int g = -1;
int b = -1;
if (f_args[5].equalsIgnoreCase("rainbow")) {
colorData = new OrdinaryColor(999, 999, 999);
} else {
int r = -1;
int g = -1;
int b = -1;
try {
r = Integer.parseInt(f_args[5]);
g = Integer.parseInt(f_args[6]);
b = Integer.parseInt(f_args[7]);
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "color");
return;
}
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "color");
return;
}
colorData = new OrdinaryColor(r, g, b);
}
}
} else if (effect.hasProperty(ParticleProperty.REQUIRES_DATA)) {
if (effect == ParticleEffect.BLOCK_CRACK || effect == ParticleEffect.BLOCK_DUST || effect == ParticleEffect.FALLING_DUST) {
Material material = null;
int data = -1;
try {
r = Integer.parseInt(args[5]);
g = Integer.parseInt(args[6]);
b = Integer.parseInt(args[7]);
material = ParticleUtils.closestMatch(f_args[5]);
if (material == null) material = Material.matchMaterial(f_args[5]);
if (material == null) throw new Exception();
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "color");
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "block");
return;
}
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "color");
try {
data = Integer.parseInt(f_args[6]);
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "block");
return;
}
colorData = new OrdinaryColor(r, g, b);
if (data < 0 || data > 15 || !material.isBlock()) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "block");
return;
}
blockData = new BlockData(material, (byte) data);
} else if (effect == ParticleEffect.ITEM_CRACK) {
Material material = null;
int data = -1;
try {
material = ParticleUtils.closestMatch(f_args[5]);
if (material == null) material = Material.matchMaterial(f_args[5]);
if (material == null) throw new Exception();
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "item");
return;
}
try {
data = Integer.parseInt(f_args[6]);
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "item");
return;
}
if (data < 0 || data > 15 || material.isBlock()) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "item");
return;
}
itemData = new ItemData(material, (byte) data);
}
}
} else if (effect.hasProperty(ParticleProperty.REQUIRES_DATA)) {
if (effect == ParticleEffect.BLOCK_CRACK || effect == ParticleEffect.BLOCK_DUST || effect == ParticleEffect.FALLING_DUST) {
Material material = null;
int data = -1;
try {
material = ParticleUtils.closestMatch(args[5]);
if (material == null) material = Material.matchMaterial(args[5]);
if (material == null) throw new Exception();
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "block");
return;
}
try {
data = Integer.parseInt(args[6]);
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "block");
return;
}
if (data < 0 || data > 15 || !material.isBlock()) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "block");
return;
}
blockData = new BlockData(material, (byte) data);
} else if (effect == ParticleEffect.ITEM_CRACK) {
Material material = null;
int data = -1;
try {
material = ParticleUtils.closestMatch(args[5]);
if (material == null) material = Material.matchMaterial(args[5]);
if (material == null) throw new Exception();
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "item");
return;
}
try {
data = Integer.parseInt(args[6]);
} catch (Exception e) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "item");
return;
}
if (data < 0 || data > 15 || material.isBlock()) {
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_DATA_ERROR, "item");
return;
}
itemData = new ItemData(material, (byte) data);
}
}
}
FixedParticleEffect fixedEffect = new FixedParticleEffect(p.getUniqueId(), // @formatter:off
ConfigManager.getInstance().getNextFixedEffectId(p.getUniqueId()),
p.getLocation().getWorld().getName(), xPos, yPos, zPos,
effect, style, itemData, blockData, colorData, noteColorData); // @formatter:on
// If somebody knows how to avoid this, please create a pull request
final double f_xPos = xPos, f_yPos = yPos, f_zPos = zPos;
final ItemData f_itemData = itemData;
final BlockData f_blockData = blockData;
final OrdinaryColor f_colorData = colorData;
final NoteColor f_noteData = noteColorData;
ConfigManager.getInstance().getNextFixedEffectId(p.getUniqueId(), (nextFixedEffectId) -> {
FixedParticleEffect fixedEffect = new FixedParticleEffect(p.getUniqueId(), // @formatter:off
nextFixedEffectId,
p.getLocation().getWorld().getName(), f_xPos, f_yPos, f_zPos,
effect, style, f_itemData, f_blockData, f_colorData, f_noteData); // @formatter:on
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_SUCCESS);
ConfigManager.getInstance().saveFixedEffect(fixedEffect);
MessageManager.sendMessage(p, MessageType.CREATE_FIXED_SUCCESS);
ConfigManager.getInstance().saveFixedEffect(fixedEffect);
});
});
} else if (cmd.equalsIgnoreCase("remove")) {
if (args.length < 1) {
MessageManager.sendMessage(p, MessageType.REMOVE_FIXED_NO_ARGS);
@ -684,29 +732,33 @@ public class ParticleCommandExecutor implements CommandExecutor {
return;
}
if (ConfigManager.getInstance().removeFixedEffect(p.getUniqueId(), id)) {
MessageManager.sendMessage(p, MessageType.REMOVE_FIXED_SUCCESS, id + "");
} else {
MessageManager.sendMessage(p, MessageType.REMOVE_FIXED_NONEXISTANT, id + "");
}
final int f_id = id;
ConfigManager.getInstance().removeFixedEffect(p.getUniqueId(), id, (successful) -> {
if (successful) {
MessageManager.sendMessage(p, MessageType.REMOVE_FIXED_SUCCESS, f_id + "");
} else {
MessageManager.sendMessage(p, MessageType.REMOVE_FIXED_NONEXISTANT, f_id + "");
}
});
} else if (cmd.equalsIgnoreCase("list")) {
List<Integer> ids = ConfigManager.getInstance().getFixedEffectIdsForPlayer(p.getUniqueId());
Collections.sort(ids);
ConfigManager.getInstance().getFixedEffectIdsForPlayer(p.getUniqueId(), (ids) -> {
Collections.sort(ids);
if (ids.isEmpty()) {
MessageManager.sendMessage(p, MessageType.LIST_FIXED_NONE);
return;
}
if (ids.isEmpty()) {
MessageManager.sendMessage(p, MessageType.LIST_FIXED_NONE);
return;
}
String msg = MessageType.LIST_FIXED_SUCCESS.getMessage();
boolean first = true;
for (int id : ids) {
if (!first) msg += ", ";
else first = false;
msg += id;
}
String msg = MessageType.LIST_FIXED_SUCCESS.getMessage();
boolean first = true;
for (int id : ids) {
if (!first) msg += ", ";
else first = false;
msg += id;
}
MessageManager.sendCustomMessage(p, msg);
MessageManager.sendCustomMessage(p, msg);
});
} else if (cmd.equalsIgnoreCase("info")) {
if (args.length < 1) {
MessageManager.sendMessage(p, MessageType.INFO_FIXED_NO_ARGS);
@ -720,25 +772,27 @@ public class ParticleCommandExecutor implements CommandExecutor {
MessageManager.sendMessage(p, MessageType.INFO_FIXED_INVALID_ARGS);
return;
}
final int f_id = id;
ConfigManager.getInstance().getFixedEffectForPlayerById(p.getUniqueId(), id, (fixedEffect) -> {
if (fixedEffect == null) {
MessageManager.sendMessage(p, MessageType.INFO_FIXED_NONEXISTANT, f_id + "");
return;
}
FixedParticleEffect fixedEffect = ConfigManager.getInstance().getFixedEffectForPlayerById(p.getUniqueId(), id);
if (fixedEffect == null) {
MessageManager.sendMessage(p, MessageType.INFO_FIXED_NONEXISTANT, id + "");
return;
}
DecimalFormat df = new DecimalFormat("0.##"); // Decimal formatter so the coords aren't super long
String listMessage = MessageType.INFO_FIXED_INFO.getMessage() // @formatter:off
.replaceAll("\\{0\\}", fixedEffect.getId() + "")
.replaceAll("\\{1\\}", fixedEffect.getLocation().getWorld().getName())
.replaceAll("\\{2\\}", df.format(fixedEffect.getLocation().getX()) + "")
.replaceAll("\\{3\\}", df.format(fixedEffect.getLocation().getY()) + "")
.replaceAll("\\{4\\}", df.format(fixedEffect.getLocation().getZ()) + "")
.replaceAll("\\{5\\}", fixedEffect.getParticleEffect().getName())
.replaceAll("\\{6\\}", fixedEffect.getParticleStyle().getName())
.replaceAll("\\{7\\}", fixedEffect.getParticleDataString()); // @formatter:on
MessageManager.sendCustomMessage(p, listMessage);
DecimalFormat df = new DecimalFormat("0.##"); // Decimal formatter so the coords aren't super long
String listMessage = MessageType.INFO_FIXED_INFO.getMessage() // @formatter:off
.replaceAll("\\{0\\}", fixedEffect.getId() + "")
.replaceAll("\\{1\\}", fixedEffect.getLocation().getWorld().getName())
.replaceAll("\\{2\\}", df.format(fixedEffect.getLocation().getX()) + "")
.replaceAll("\\{3\\}", df.format(fixedEffect.getLocation().getY()) + "")
.replaceAll("\\{4\\}", df.format(fixedEffect.getLocation().getZ()) + "")
.replaceAll("\\{5\\}", fixedEffect.getParticleEffect().getName())
.replaceAll("\\{6\\}", fixedEffect.getParticleStyle().getName())
.replaceAll("\\{7\\}", fixedEffect.getParticleDataString()); // @formatter:on
MessageManager.sendCustomMessage(p, listMessage);
});
} else if (cmd.equalsIgnoreCase("clear")) {
if (!p.hasPermission("playerparticles.fixed.clear")) {
MessageManager.sendMessage(p, MessageType.CLEAR_FIXED_NO_PERMISSION);
@ -763,8 +817,8 @@ public class ParticleCommandExecutor implements CommandExecutor {
for (FixedParticleEffect fixedEffect : ParticleManager.fixedParticleEffects)
if (fixedEffect.getLocation().getWorld() == p.getLocation().getWorld() && fixedEffect.getLocation().distance(p.getLocation()) <= radius) fixedEffectsToRemove.add(fixedEffect);
for (FixedParticleEffect fixedEffect : fixedEffectsToRemove)
ConfigManager.getInstance().removeFixedEffect(fixedEffect.getOwnerUniqueId(), fixedEffect.getId());
for (FixedParticleEffect fixedEffect : fixedEffectsToRemove)
ConfigManager.getInstance().removeFixedEffect(fixedEffect.getOwnerUniqueId(), fixedEffect.getId(), (successful) -> { });
String clearMessage = MessageType.CLEAR_FIXED_SUCCESS.getMessage() // @formatter:off
.replaceAll("\\{0\\}", fixedEffectsToRemove.size() + "")
@ -804,7 +858,9 @@ public class ParticleCommandExecutor implements CommandExecutor {
MessageManager.sendMessage(p, MessageType.GUI_BY_DEFAULT);
}
PlayerParticlesGui.changeState(ConfigManager.getInstance().getPPlayer(p.getUniqueId(), true), GuiState.DEFAULT);
ConfigManager.getInstance().getPPlayer(p.getUniqueId(), (pplayer) -> {
PlayerParticlesGui.changeState(pplayer, GuiState.DEFAULT);
});
}
}

View file

@ -17,9 +17,9 @@
* + Add new style 'blockplace'
* + Add new style 'hurt'
* + Add new style 'swords'
* + Switch over to Spigot Particle API
* + Switch database management system, make async
* + Make database queries async
* + Command to force set an effect/style for a player
* + Tab completion for fixed effects
*/
/*
@ -34,8 +34,10 @@
* Plugin is now built against Java 1.8.0_161 and Spigot 1.9.4
* Servers running Java 7 are no longer supported. Please upgrade to Java 8 if you haven't yet.
* Rewrote database connection system, should fix any memory leaks from before
* Reduced particle render distance from 512 to 150, you won't notice a difference
* Performance improvements with database loading
* Reduced particle render distance from 512 to 192 (12 chunks), you won't notice a difference
* Database management should no longer contain memory leaks
* Fixed missing command 'fixed' from '/pp help' list
* Fixed missing command 'fixed' from tab completion
*/
package com.esophose.playerparticles;
@ -43,6 +45,7 @@ package com.esophose.playerparticles;
import java.io.File;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
@ -130,7 +133,7 @@ public class PlayerParticles extends JavaPlugin {
if (useMySQL) {
mySQL.closeConnection();
}
PlayerParticlesGui.forceCloseAllOpenGUIs();
}
@ -163,40 +166,44 @@ public class PlayerParticles extends JavaPlugin {
if (getConfig().getBoolean("database-enable")) {
mySQL = new DatabaseManager(getConfig());
useMySQL = true; // If something goes wrong this will be set to false
useMySQL = mySQL.isInitialized(); // If something goes wrong, this will be set to false
if (!useMySQL) return; // Break out, couldn't set up the database connection
// @formatter:off
try (ResultSet res = mySQL.querySQL("SHOW TABLES LIKE 'pp_users'")) {
if (res.next()) { // Add the new fixed table and rename some columns
try (ResultSet res2 = mySQL.querySQL("SHOW TABLES LIKE 'pp_fixed'")) {
if (!res2.next()) { // Using an old database, update to the new one
mySQL.updateSQL("CREATE TABLE pp_fixed (uuid VARCHAR(36), player_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(32), style VARCHAR(32), worldName VARCHAR(50), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE);" +
"ALTER TABLE pp_data_item CHANGE player_uuid uuid VARCHAR(36);" +
"ALTER TABLE pp_data_block CHANGE player_uuid uuid VARCHAR(36);" +
"ALTER TABLE pp_data_color CHANGE player_uuid uuid VARCHAR(36);" +
"ALTER TABLE pp_data_note CHANGE player_uuid uuid VARCHAR(36);");
// Queries are purposely not run in an asynchronous task, this is on plugin startup and shouldn't affect the end users
mySQL.connect((connection) -> { // @formatter:off
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("SHOW TABLES LIKE 'pp_users'")) {
if (res.next()) { // Database is already created
try (Statement statement2 = connection.createStatement();
ResultSet res2 = statement2.executeQuery("SHOW TABLES LIKE 'pp_fixed'")) {
if (!res2.next()) { // Is the current database of an old version?
mySQL.updateSQL("CREATE TABLE pp_fixed (uuid VARCHAR(36), player_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(32), style VARCHAR(32), worldName VARCHAR(50), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE);" +
"ALTER TABLE pp_data_item CHANGE player_uuid uuid VARCHAR(36);" +
"ALTER TABLE pp_data_block CHANGE player_uuid uuid VARCHAR(36);" +
"ALTER TABLE pp_data_color CHANGE player_uuid uuid VARCHAR(36);" +
"ALTER TABLE pp_data_note CHANGE player_uuid uuid VARCHAR(36);");
}
}
} catch (Exception e) {
throw e; // Try-catch block here is just for auto closure
} else { // Database isn't created yet
mySQL.updateSQL("CREATE TABLE pp_users (player_uuid VARCHAR(36), effect VARCHAR(32), style VARCHAR(32));" +
"CREATE TABLE pp_fixed (uuid VARCHAR(36), player_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(32), style VARCHAR(32), worldName VARCHAR(50), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE);" +
"CREATE TABLE pp_data_item (uuid VARCHAR(36), material VARCHAR(32), data SMALLINT);" +
"CREATE TABLE pp_data_block (uuid VARCHAR(36), material VARCHAR(32), data SMALLINT);" +
"CREATE TABLE pp_data_color (uuid VARCHAR(36), r SMALLINT, g SMALLINT, b SMALLINT);" +
"CREATE TABLE pp_data_note (uuid VARCHAR(36), note SMALLINT);");
}
} else { // No database is set up yet, create it
mySQL.updateSQL("CREATE TABLE pp_users (player_uuid VARCHAR(36), effect VARCHAR(32), style VARCHAR(32));" +
"CREATE TABLE pp_fixed (uuid VARCHAR(36), player_uuid VARCHAR(36), id SMALLINT, effect VARCHAR(32), style VARCHAR(32), worldName VARCHAR(50), xPos DOUBLE, yPos DOUBLE, zPos DOUBLE);" +
"CREATE TABLE pp_data_item (uuid VARCHAR(36), material VARCHAR(32), data SMALLINT);" +
"CREATE TABLE pp_data_block (uuid VARCHAR(36), material VARCHAR(32), data SMALLINT);" +
"CREATE TABLE pp_data_color (uuid VARCHAR(36), r SMALLINT, g SMALLINT, b SMALLINT);" +
"CREATE TABLE pp_data_note (uuid VARCHAR(36), note SMALLINT);"
);
} catch (SQLException e) {
getLogger().info("Failed to connect to the MySQL Database! Check to see if your login information is correct!");
getLogger().info("Additional information: " + e.getMessage());
useMySQL = false;
}
} catch (SQLException e) {
getLogger().info("Failed to connect to the MySQL Database! Check to see if your login information is correct!");
getLogger().info("Additional information: " + e.getMessage());
useMySQL = false;
return;
} // @formatter:on
});
} else {
useMySQL = false;
}
} // @formatter:on
}
/**

View file

@ -251,11 +251,16 @@ public class PlayerParticlesGui extends BukkitRunnable implements Listener {
List<UUID> toRemoveList = new ArrayList<UUID>();
for (Map.Entry<UUID, GuiInventory> entry : playerGuiInventories.entrySet()) {
PPlayer pplayer = ConfigManager.getInstance().getPPlayer(entry.getKey(), false);
Player player = Bukkit.getPlayer(pplayer.getUniqueId());
UUID playerUUID = entry.getKey();
PPlayer pplayer = ConfigManager.getInstance().getPPlayer(playerUUID);
if (pplayer == null) {
toRemoveList.add(playerUUID);
continue;
}
Player player = Bukkit.getPlayer(playerUUID);
if (player == null) {
toRemoveList.add(pplayer.getUniqueId());
toRemoveList.add(playerUUID);
continue;
}
@ -570,9 +575,15 @@ public class PlayerParticlesGui extends BukkitRunnable implements Listener {
if (guiInventory == null || !guiInventory.getInventory().equals(e.getView().getTopInventory())) return; // Make sure it is the right inventory
PPlayer pplayer = ConfigManager.getInstance().getPPlayer(player.getUniqueId(), false);
e.setCancelled(true); // In the PlayerParticles GUI, can't let them take anything out
if (!guiInventory.getInventory().equals(e.getClickedInventory())) return; // Clicked bottom inventory
e.setCancelled(true);
PPlayer pplayer = ConfigManager.getInstance().getPPlayer(player.getUniqueId());
if (pplayer == null) {
player.closeInventory();
return;
}
ItemStack clicked = e.getCurrentItem();
if (clicked == null || clicked.getType() == Material.AIR) return; // Clicked on an empty slot, do nothing

View file

@ -12,6 +12,7 @@ import java.io.File;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -49,7 +50,7 @@ public class ConfigManager {
/**
* The configuration used to edit the .yaml file
*/
private FileConfiguration config;
private FileConfiguration playerDataYaml;
/**
* The disabled worlds cached for quick access
@ -90,7 +91,7 @@ public class ConfigManager {
}
}
config = YamlConfiguration.loadConfiguration(file);
playerDataYaml = YamlConfiguration.loadConfiguration(file);
}
}
@ -99,50 +100,61 @@ public class ConfigManager {
*/
private void save() {
try {
config.save(file);
playerDataYaml.save(file);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 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
*/
public PPlayer getPPlayer(UUID playerUUID) {
for (PPlayer pp : ParticleManager.particlePlayers)
if (pp.getUniqueId() == playerUUID)
return pp;
return null;
}
/**
* Gets a player from the save data, creates one if it doesn't exist and adds it to the list
* Gets a player from the save data, creates one if it doesn't exist and caches it
*
* @param playerUUID The pplayer to get
* @param createIfNotFound Creates the pplayer to the processing queue if they are not already in it
* @return The found pplayer, or a newly generated one
* @param callback The callback to execute with the found pplayer, or a newly generated one
*/
public PPlayer getPPlayer(UUID playerUUID, boolean createIfNotFound) {
for (PPlayer pp : ParticleManager.particlePlayers) {
if (pp.getUniqueId() == playerUUID) return pp;
public void getPPlayer(UUID playerUUID, ConfigurationCallback<PPlayer> callback) {
// Try to get them from cache first
PPlayer fromCache = getPPlayer(playerUUID);
if (fromCache != null) {
callback.execute(fromCache);
return;
}
PPlayer alreadySavedPPlayer = buildPPlayer(playerUUID, false); // If they exist, get them from the database
if (alreadySavedPPlayer != null) {
ParticleManager.particlePlayers.add(alreadySavedPPlayer);
return alreadySavedPPlayer;
}
if (createIfNotFound && Bukkit.getPlayer(playerUUID) != null) {
PPlayer pplayer = buildPPlayer(playerUUID, true); // Build a new PPlayer and store them in the config
// Either get an existing one from the database, or create a new one
buildPPlayer(playerUUID, true, (pplayer) -> {
ParticleManager.particlePlayers.add(pplayer);
return pplayer;
}
return null; // Not requesting a new PPlayer and nothing was found, return null
callback.execute(pplayer);
});
}
/**
* Gets a PPlayer matching the UUID given
* One will be created if it doesn't exist
* If createIfNotFound is true, one will be created if it doesn't exist
*
* @param playerUUID The UUID to match the PPlayer to
* @return A newly built pplayer
* @param createIfNotFound If true, creates a new PPlayer if the requested one doesn't exist
* @param callback The callback to execute with the built PPlayer
*/
private PPlayer buildPPlayer(UUID playerUUID, boolean createIfNotFound) {
private void buildPPlayer(UUID playerUUID, boolean createIfNotFound, ConfigurationCallback<PPlayer> callback) {
if (!PlayerParticles.useMySQL) {
if (config.getString(playerUUID.toString() + ".style.name") != null) {
ConfigurationSection section = config.getConfigurationSection(playerUUID.toString());
if (playerDataYaml.contains(playerUUID.toString())) {
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerUUID.toString());
ConfigurationSection effectSection = section.getConfigurationSection("effect");
ConfigurationSection styleSection = section.getConfigurationSection("style");
ConfigurationSection itemDataSection = section.getConfigurationSection("itemData");
@ -157,42 +169,50 @@ public class ConfigManager {
OrdinaryColor particleColorData = new OrdinaryColor(colorDataSection.getInt("r"), colorDataSection.getInt("g"), colorDataSection.getInt("b"));
NoteColor particleNoteColorData = new NoteColor(noteColorDataSection.getInt("note"));
return new PPlayer(playerUUID, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData);
} else if (createIfNotFound) {
callback.execute(new PPlayer(playerUUID, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData));
return;
}
if (createIfNotFound) {
// Didn't find an existing PPlayer, create and return a new one
PPlayer pplayer = PPlayer.getNewPPlayer(playerUUID);
saveNewPPlayer(pplayer);
return pplayer;
callback.execute(pplayer);
}
} else {
String id = playerUUID.toString(); // @formatter:off
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT * FROM pp_users u " +
"JOIN pp_data_item i ON u.player_uuid = i.uuid " +
"JOIN pp_data_block b ON u.player_uuid = b.uuid " +
"JOIN pp_data_color c ON u.player_uuid = c.uuid " +
"JOIN pp_data_note n ON u.player_uuid = n.uuid " +
"WHERE u.player_uuid = '" + id + "'")) { // @formatter:on
PlayerParticles.mySQL.connect((connection) -> {
String query = "SELECT * FROM pp_users u " +
"JOIN pp_data_item i ON u.player_uuid = i.uuid " +
"JOIN pp_data_block b ON u.player_uuid = b.uuid " +
"JOIN pp_data_color c ON u.player_uuid = c.uuid " +
"JOIN pp_data_note n ON u.player_uuid = n.uuid " +
"WHERE u.player_uuid = '" + id + "'";
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery(query)) {
if (res.next()) {
ParticleEffect particleEffect = ParticleEffect.fromName(res.getString("u.effect"));
ParticleStyle particleStyle = ParticleStyleManager.styleFromString(res.getString("u.style"));
ItemData particleItemData = new ItemData(Material.matchMaterial(res.getString("i.material")), res.getByte("i.data"));
BlockData particleBlockData = new BlockData(Material.matchMaterial(res.getString("b.material")), res.getByte("b.data"));
OrdinaryColor particleColorData = new OrdinaryColor(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b"));
NoteColor particleNoteColorData = new NoteColor(res.getByte("n.note"));
if (res.next()) {
ParticleEffect particleEffect = ParticleEffect.fromName(res.getString("u.effect"));
ParticleStyle particleStyle = ParticleStyleManager.styleFromString(res.getString("u.style"));
ItemData particleItemData = new ItemData(Material.matchMaterial(res.getString("i.material")), res.getByte("i.data"));
BlockData particleBlockData = new BlockData(Material.matchMaterial(res.getString("b.material")), res.getByte("b.data"));
OrdinaryColor particleColorData = new OrdinaryColor(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b"));
NoteColor particleNoteColorData = new NoteColor(res.getByte("n.note"));
return new PPlayer(playerUUID, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData);
} else if (createIfNotFound) {
PPlayer pplayer = PPlayer.getNewPPlayer(playerUUID);
saveNewPPlayer(pplayer);
return pplayer;
callback.execute(new PPlayer(playerUUID, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData));
return;
}
if (createIfNotFound) {
// Didn't find an existing PPlayer, create and return a new one
PPlayer pplayer = PPlayer.getNewPPlayer(playerUUID);
saveNewPPlayer(pplayer);
callback.execute(pplayer);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
});
}
// This should only be returned if there is a database or config error
return null;
}
/**
@ -202,18 +222,18 @@ public class ConfigManager {
*/
public void saveNewPPlayer(PPlayer pplayer) {
if (!PlayerParticles.useMySQL) {
if (!config.isConfigurationSection(pplayer.getUniqueId().toString())) {
if (!playerDataYaml.isConfigurationSection(pplayer.getUniqueId().toString())) {
String id = pplayer.getUniqueId().toString();
config.createSection(id);
config.createSection(id + ".effect");
config.createSection(id + ".style");
config.createSection(id + ".itemData");
config.createSection(id + ".blockData");
config.createSection(id + ".colorData");
config.createSection(id + ".noteColorData");
playerDataYaml.createSection(id);
playerDataYaml.createSection(id + ".effect");
playerDataYaml.createSection(id + ".style");
playerDataYaml.createSection(id + ".itemData");
playerDataYaml.createSection(id + ".blockData");
playerDataYaml.createSection(id + ".colorData");
playerDataYaml.createSection(id + ".noteColorData");
}
ConfigurationSection section = config.getConfigurationSection(pplayer.getUniqueId().toString());
ConfigurationSection section = playerDataYaml.getConfigurationSection(pplayer.getUniqueId().toString());
ConfigurationSection effectSection = section.getConfigurationSection("effect");
ConfigurationSection styleSection = section.getConfigurationSection("style");
ConfigurationSection itemDataSection = section.getConfigurationSection("itemData");
@ -234,44 +254,61 @@ public class ConfigManager {
save();
} else {
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT * FROM pp_users WHERE player_uuid = '" + pplayer.getUniqueId() + "'")) {
if (res.next()) {
throw new RuntimeException("The user " + pplayer.getUniqueId() + " is already in the database. They can not be added.");
} else { // @formatter:off
PlayerParticles.mySQL.updateSQL("INSERT INTO pp_users (player_uuid, effect, style) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
"'" + pplayer.getParticleEffect().getName() + "', " +
"'" + pplayer.getParticleStyle().getName() + "'" +
"); " +
"INSERT INTO pp_data_item (uuid, material, data) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
"'" + pplayer.getItemData().getMaterial().name() + "', " +
pplayer.getItemData().getData() +
"); " +
"INSERT INTO pp_data_block (uuid, material, data) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
"'" + pplayer.getBlockData().getMaterial().name() + "', " +
pplayer.getBlockData().getData() +
"); " +
"INSERT INTO pp_data_color (uuid, r, g, b) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
pplayer.getColorData().getRed() + ", " +
pplayer.getColorData().getGreen() + ", " +
pplayer.getColorData().getBlue() +
"); " +
"INSERT INTO pp_data_note (uuid, note) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
(byte) (pplayer.getNoteColorData().getValueX() * 24) +
");"
);
} // @formatter:on
} catch (SQLException e) {
e.printStackTrace();
}
PlayerParticles.mySQL.connect((connection) -> {
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("SELECT * FROM pp_users WHERE player_uuid = '" + pplayer.getUniqueId() + "'")) {
if (!res.next()) {
PlayerParticles.mySQL.updateSQL("INSERT INTO pp_users (player_uuid, effect, style) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
"'" + pplayer.getParticleEffect().getName() + "', " +
"'" + pplayer.getParticleStyle().getName() + "'" +
"); " +
"INSERT INTO pp_data_item (uuid, material, data) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
"'" + pplayer.getItemData().getMaterial().name() + "', " +
pplayer.getItemData().getData() +
"); " +
"INSERT INTO pp_data_block (uuid, material, data) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
"'" + pplayer.getBlockData().getMaterial().name() + "', " +
pplayer.getBlockData().getData() +
"); " +
"INSERT INTO pp_data_color (uuid, r, g, b) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
pplayer.getColorData().getRed() + ", " +
pplayer.getColorData().getGreen() + ", " +
pplayer.getColorData().getBlue() +
"); " +
"INSERT INTO pp_data_note (uuid, note) VALUES (" +
"'" + pplayer.getUniqueId().toString() + "', " +
(byte) (pplayer.getNoteColorData().getValueX() * 24) +
");"
);
} else {
throw new RuntimeException("The user " + pplayer.getUniqueId() + " is already in the database. They can not be added.");
}
}
});
}
ParticleManager.updateIfContains(pplayer); // Update the player in case this is a /pp reset
}
/**
* Loads a PPlayer and caches it
*
* @param playerUUID The pplayer to load
*/
public void loadPPlayer(UUID playerUUID) {
for (PPlayer pplayer : ParticleManager.particlePlayers)
if (pplayer.getUniqueId() == playerUUID)
return;
buildPPlayer(playerUUID, false, (pplayer) -> {
ParticleManager.particlePlayers.add(pplayer);
});
}
/**
* Resets all saved information about a PPlayer
@ -296,9 +333,8 @@ public class ConfigManager {
* @param particleEffect The effect that is being saved
*/
public void savePPlayer(UUID playerUUID, ParticleEffect particleEffect) {
PPlayer pplayer = getPPlayer(playerUUID, true);
if (!PlayerParticles.useMySQL) {
ConfigurationSection section = config.getConfigurationSection(playerUUID.toString() + ".effect");
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerUUID.toString() + ".effect");
section.set("name", particleEffect.getName());
save();
} else {
@ -308,7 +344,10 @@ public class ConfigManager {
e.printStackTrace();
}
}
pplayer.setParticleEffect(particleEffect);
getPPlayer(playerUUID, (pplayer) -> {
pplayer.setParticleEffect(particleEffect);
});
}
/**
@ -318,9 +357,8 @@ public class ConfigManager {
* @param particleStyle The style that is being saved
*/
public void savePPlayer(UUID playerUUID, ParticleStyle particleStyle) {
PPlayer pplayer = getPPlayer(playerUUID, true);
if (!PlayerParticles.useMySQL) {
ConfigurationSection section = config.getConfigurationSection(playerUUID.toString() + ".style");
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerUUID.toString() + ".style");
section.set("name", particleStyle.getName());
save();
} else {
@ -330,7 +368,10 @@ public class ConfigManager {
e.printStackTrace();
}
}
pplayer.setParticleStyle(particleStyle);
getPPlayer(playerUUID, (pplayer) -> {
pplayer.setParticleStyle(particleStyle);
});
}
/**
@ -340,9 +381,8 @@ public class ConfigManager {
* @param particleItemData The data that is being saved
*/
public void savePPlayer(UUID playerUUID, ItemData particleItemData) {
PPlayer pplayer = getPPlayer(playerUUID, true);
if (!PlayerParticles.useMySQL) {
ConfigurationSection section = config.getConfigurationSection(playerUUID.toString() + ".itemData");
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerUUID.toString() + ".itemData");
section.set("material", particleItemData.getMaterial().name());
section.set("data", particleItemData.getData());
save();
@ -353,7 +393,10 @@ public class ConfigManager {
e.printStackTrace();
}
}
pplayer.setItemData(particleItemData);
getPPlayer(playerUUID, (pplayer) -> {
pplayer.setItemData(particleItemData);
});
}
/**
@ -363,9 +406,8 @@ public class ConfigManager {
* @param particleBlockData The data that is being saved
*/
public void savePPlayer(UUID playerUUID, BlockData particleBlockData) {
PPlayer pplayer = getPPlayer(playerUUID, true);
if (!PlayerParticles.useMySQL) {
ConfigurationSection section = config.getConfigurationSection(playerUUID.toString() + ".blockData");
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerUUID.toString() + ".blockData");
section.set("material", particleBlockData.getMaterial().name());
section.set("data", particleBlockData.getData());
save();
@ -376,7 +418,10 @@ public class ConfigManager {
e.printStackTrace();
}
}
pplayer.setBlockData(particleBlockData);
getPPlayer(playerUUID, (pplayer) -> {
pplayer.setBlockData(particleBlockData);
});
}
/**
@ -386,9 +431,8 @@ public class ConfigManager {
* @param particleColorData The data that is being saved
*/
public void savePPlayer(UUID playerUUID, OrdinaryColor particleColorData) {
PPlayer pplayer = getPPlayer(playerUUID, true);
if (!PlayerParticles.useMySQL) {
ConfigurationSection section = config.getConfigurationSection(playerUUID.toString() + ".colorData");
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerUUID.toString() + ".colorData");
section.set("r", particleColorData.getRed());
section.set("g", particleColorData.getGreen());
section.set("b", particleColorData.getBlue());
@ -400,7 +444,10 @@ public class ConfigManager {
e.printStackTrace();
}
}
pplayer.setColorData(particleColorData);
getPPlayer(playerUUID, (pplayer) -> {
pplayer.setColorData(particleColorData);
});
}
/**
@ -410,9 +457,8 @@ public class ConfigManager {
* @param particleNoteColorData The data that is being saved
*/
public void savePPlayer(UUID playerUUID, NoteColor particleNoteColorData) {
PPlayer pplayer = getPPlayer(playerUUID, true);
if (!PlayerParticles.useMySQL) {
ConfigurationSection section = config.getConfigurationSection(playerUUID.toString() + ".noteColorData");
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerUUID.toString() + ".noteColorData");
section.set("note", (byte) (particleNoteColorData.getValueX() * 24));
save();
} else {
@ -422,7 +468,10 @@ public class ConfigManager {
e.printStackTrace();
}
}
pplayer.setNoteColorData(particleNoteColorData);
getPPlayer(playerUUID, (pplayer) -> {
pplayer.setNoteColorData(particleNoteColorData);
});
}
/**
@ -432,8 +481,8 @@ public class ConfigManager {
*/
public void saveFixedEffect(FixedParticleEffect fixedEffect) {
if (!PlayerParticles.useMySQL) {
if (!config.isConfigurationSection(fixedEffect.getOwnerUniqueId().toString() + ".fixedEffect." + fixedEffect.getId())) {
ConfigurationSection baseSection = config.createSection(fixedEffect.getOwnerUniqueId().toString() + ".fixedEffect." + fixedEffect.getId());
if (!playerDataYaml.isConfigurationSection(fixedEffect.getOwnerUniqueId().toString() + ".fixedEffect." + fixedEffect.getId())) {
ConfigurationSection baseSection = playerDataYaml.createSection(fixedEffect.getOwnerUniqueId().toString() + ".fixedEffect." + fixedEffect.getId());
baseSection.createSection("effect");
baseSection.createSection("style");
@ -446,7 +495,7 @@ public class ConfigManager {
return;
}
ConfigurationSection section = config.getConfigurationSection(fixedEffect.getOwnerUniqueId().toString() + ".fixedEffect." + fixedEffect.getId());
ConfigurationSection section = playerDataYaml.getConfigurationSection(fixedEffect.getOwnerUniqueId().toString() + ".fixedEffect." + fixedEffect.getId());
ConfigurationSection effectSection = section.getConfigurationSection("effect");
ConfigurationSection styleSection = section.getConfigurationSection("style");
ConfigurationSection itemDataSection = section.getConfigurationSection("itemData");
@ -471,11 +520,17 @@ public class ConfigManager {
noteColorDataSection.set("note", (byte) (fixedEffect.getNoteColorData().getValueX() * 24));
save();
ParticleManager.addFixedEffect(fixedEffect);
} else {
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT * FROM pp_fixed WHERE player_uuid = '" + fixedEffect.getOwnerUniqueId() + "' AND id = " + fixedEffect.getId())) {
if (res.next()) {
System.out.println("Tried to create a fixed effect with ID " + fixedEffect.getId() + " that already in the database!");
} else { // @formatter:off
PlayerParticles.mySQL.connect((connection) -> {
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("SELECT * FROM pp_fixed WHERE player_uuid = '" + fixedEffect.getOwnerUniqueId() + "' AND id = " + fixedEffect.getId())) {
if (res.next()) {
System.out.println("Tried to create a fixed effect with ID " + fixedEffect.getId() + " that already in the database!");
return;
}
String fixedEffectUUID = UUID.randomUUID().toString();
PlayerParticles.mySQL.updateSQL("INSERT INTO pp_fixed (uuid, player_uuid, id, effect, style, worldName, xPos, yPos, zPos) VALUES (" +
@ -510,13 +565,11 @@ public class ConfigManager {
(byte) (fixedEffect.getNoteColorData().getValueX() * 24) +
");"
);
} // @formatter:on
} catch (SQLException e) {
e.printStackTrace();
}
ParticleManager.addFixedEffect(fixedEffect);
}
});
}
ParticleManager.addFixedEffect(fixedEffect);
}
/**
@ -526,20 +579,28 @@ public class ConfigManager {
* @param id The id of the effect to remove
* @return If the effect was removed
*/
public boolean removeFixedEffect(UUID playerUUID, int id) {
public void removeFixedEffect(UUID playerUUID, int id, ConfigurationCallback<Boolean> callback) {
if (!PlayerParticles.useMySQL) {
if (!config.isConfigurationSection(playerUUID.toString() + ".fixedEffect." + id)) {
return false;
if (!playerDataYaml.isConfigurationSection(playerUUID.toString() + ".fixedEffect." + id)) {
callback.execute(false);
return;
}
config.set(playerUUID.toString() + ".fixedEffect." + id, null);
playerDataYaml.set(playerUUID.toString() + ".fixedEffect." + id, null);
save();
ParticleManager.removeFixedEffectForPlayer(playerUUID, id);
callback.execute(true);
} else {
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT uuid FROM pp_fixed WHERE player_uuid = '" + playerUUID.toString() + "' AND id = " + id)) {
if (!res.next()) {
return false;
} else { // @formatter:off
PlayerParticles.mySQL.connect((connection) -> {
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("SELECT uuid FROM pp_fixed WHERE player_uuid = '" + playerUUID.toString() + "' AND id = " + id)) {
if (!res.next()) {
callback.execute(false);
return;
}
String uuid = res.getString("uuid");
PlayerParticles.mySQL.updateSQL("DELETE FROM pp_fixed WHERE uuid = '" + uuid + "';" +
"DELETE FROM pp_data_item WHERE uuid = '" + uuid + "';" +
@ -547,15 +608,11 @@ public class ConfigManager {
"DELETE FROM pp_data_color WHERE uuid = '" + uuid + "';" +
"DELETE FROM pp_data_note WHERE uuid = '" + uuid + "';"
);
} // @formatter:on
} catch (SQLException e) {
e.printStackTrace();
return false;
}
ParticleManager.removeFixedEffectForPlayer(playerUUID, id);
callback.execute(true);
}
});
}
ParticleManager.removeFixedEffectForPlayer(playerUUID, id);
return true;
}
/**
@ -565,7 +622,7 @@ public class ConfigManager {
*/
public void resetFixedEffects(UUID playerUUID) {
if (!PlayerParticles.useMySQL) {
config.set(playerUUID.toString() + ".fixedEffect", null);
playerDataYaml.set(playerUUID.toString() + ".fixedEffect", null);
save();
} else {
try { // @formatter:off
@ -588,17 +645,17 @@ public class ConfigManager {
*
* @return A list of all saved fixed particle effects
*/
public List<FixedParticleEffect> getAllFixedEffects() {
public void getAllFixedEffects(ConfigurationCallback<List<FixedParticleEffect>> callback) {
if (!PlayerParticles.useMySQL) {
List<FixedParticleEffect> fixedEffects = new ArrayList<FixedParticleEffect>();
Set<String> playerKeys = config.getKeys(false);
Set<String> playerKeys = playerDataYaml.getKeys(false);
for (String playerKey : playerKeys) {
if (config.isConfigurationSection(playerKey + ".fixedEffect")) {
Set<String> fixedEffectKeys = config.getConfigurationSection(playerKey + ".fixedEffect").getKeys(false);
if (playerDataYaml.isConfigurationSection(playerKey + ".fixedEffect")) {
Set<String> fixedEffectKeys = playerDataYaml.getConfigurationSection(playerKey + ".fixedEffect").getKeys(false);
for (String fixedEffectKey : fixedEffectKeys) {
ConfigurationSection section = config.getConfigurationSection(playerKey + ".fixedEffect." + fixedEffectKey);
ConfigurationSection section = playerDataYaml.getConfigurationSection(playerKey + ".fixedEffect." + fixedEffectKey);
ConfigurationSection effectSection = section.getConfigurationSection("effect");
ConfigurationSection styleSection = section.getConfigurationSection("style");
ConfigurationSection itemDataSection = section.getConfigurationSection("itemData");
@ -623,39 +680,40 @@ public class ConfigManager {
}
}
return fixedEffects;
callback.execute(fixedEffects);
} else { // @formatter:off
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT * FROM pp_fixed f " +
"JOIN pp_data_item i ON f.uuid = i.uuid " +
"JOIN pp_data_block b ON f.uuid = b.uuid " +
"JOIN pp_data_color c ON f.uuid = c.uuid " +
"JOIN pp_data_note n ON f.uuid = n.uuid")) { // @formatter:on
PlayerParticles.mySQL.connect((connection) -> {
String query = "SELECT * FROM pp_fixed f " +
"JOIN pp_data_item i ON f.uuid = i.uuid " +
"JOIN pp_data_block b ON f.uuid = b.uuid " +
"JOIN pp_data_color c ON f.uuid = c.uuid " +
"JOIN pp_data_note n ON f.uuid = n.uuid";
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery(query)) {
List<FixedParticleEffect> fixedEffects = new ArrayList<FixedParticleEffect>();
List<FixedParticleEffect> fixedEffects = new ArrayList<FixedParticleEffect>();
while (res.next()) {
UUID pplayerUUID = UUID.fromString(res.getString("f.player_uuid"));
int id = res.getInt("f.id");
String worldName = res.getString("f.worldName");
double xPos = res.getDouble("f.xPos");
double yPos = res.getDouble("f.yPos");
double zPos = res.getDouble("f.zPos");
ParticleEffect particleEffect = ParticleManager.effectFromString(res.getString("f.effect"));
ParticleStyle particleStyle = ParticleStyleManager.styleFromString(res.getString("f.style"));
ItemData particleItemData = new ItemData(Material.matchMaterial(res.getString("i.material")), res.getByte("i.data"));
BlockData particleBlockData = new BlockData(Material.matchMaterial(res.getString("b.material")), res.getByte("b.data"));
OrdinaryColor particleColorData = new OrdinaryColor(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b"));
NoteColor particleNoteColorData = new NoteColor(res.getByte("n.note"));
fixedEffects.add(new FixedParticleEffect(pplayerUUID, id, worldName, xPos, yPos, zPos, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData));
}
while (res.next()) {
UUID pplayerUUID = UUID.fromString(res.getString("f.player_uuid"));
int id = res.getInt("f.id");
String worldName = res.getString("f.worldName");
double xPos = res.getDouble("f.xPos");
double yPos = res.getDouble("f.yPos");
double zPos = res.getDouble("f.zPos");
ParticleEffect particleEffect = ParticleManager.effectFromString(res.getString("f.effect"));
ParticleStyle particleStyle = ParticleStyleManager.styleFromString(res.getString("f.style"));
ItemData particleItemData = new ItemData(Material.matchMaterial(res.getString("i.material")), res.getByte("i.data"));
BlockData particleBlockData = new BlockData(Material.matchMaterial(res.getString("b.material")), res.getByte("b.data"));
OrdinaryColor particleColorData = new OrdinaryColor(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b"));
NoteColor particleNoteColorData = new NoteColor(res.getByte("n.note"));
fixedEffects.add(new FixedParticleEffect(pplayerUUID, id, worldName, xPos, yPos, zPos, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData));
callback.execute(fixedEffects);
}
return fixedEffects;
} catch (SQLException e) {
e.printStackTrace();
}
});
}
return null; // Something went wrong somewhere
}
/**
@ -665,10 +723,10 @@ public class ConfigManager {
* @param id The id for the effect to get
* @return The effect if one exists
*/
public FixedParticleEffect getFixedEffectForPlayerById(UUID pplayerUUID, int id) {
public void getFixedEffectForPlayerById(UUID pplayerUUID, int id, ConfigurationCallback<FixedParticleEffect> callback) {
if (!PlayerParticles.useMySQL) {
if (config.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect." + id)) {
ConfigurationSection section = config.getConfigurationSection(pplayerUUID + ".fixedEffect." + id);
if (playerDataYaml.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect." + id)) {
ConfigurationSection section = playerDataYaml.getConfigurationSection(pplayerUUID + ".fixedEffect." + id);
ConfigurationSection effectSection = section.getConfigurationSection("effect");
ConfigurationSection styleSection = section.getConfigurationSection("style");
ConfigurationSection itemDataSection = section.getConfigurationSection("itemData");
@ -686,35 +744,37 @@ public class ConfigManager {
BlockData particleBlockData = new BlockData(Material.matchMaterial(blockDataSection.getString("material")), (byte) blockDataSection.getInt("data"));
OrdinaryColor particleColorData = new OrdinaryColor(colorDataSection.getInt("r"), colorDataSection.getInt("g"), colorDataSection.getInt("b"));
NoteColor particleNoteColorData = new NoteColor(noteColorDataSection.getInt("note"));
return new FixedParticleEffect(pplayerUUID, id, worldName, xPos, yPos, zPos, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData);
callback.execute(new FixedParticleEffect(pplayerUUID, id, worldName, xPos, yPos, zPos, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData));
}
} else { // @formatter:off
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT * FROM pp_fixed f " +
"JOIN pp_data_item i ON f.uuid = i.uuid " +
"JOIN pp_data_block b ON f.uuid = b.uuid " +
"JOIN pp_data_color c ON f.uuid = c.uuid " +
"JOIN pp_data_note n ON f.uuid = n.uuid " +
"WHERE f.player_uuid = '" + pplayerUUID.toString() + "' AND f.id = '" + id + "'")) { // @formatter:on
} else {
PlayerParticles.mySQL.connect((connection) -> { // @formatter:off
String query = "SELECT * FROM pp_fixed f " +
"JOIN pp_data_item i ON f.uuid = i.uuid " +
"JOIN pp_data_block b ON f.uuid = b.uuid " +
"JOIN pp_data_color c ON f.uuid = c.uuid " +
"JOIN pp_data_note n ON f.uuid = n.uuid " +
"WHERE f.player_uuid = '" + pplayerUUID.toString() + "' AND f.id = '" + id + "'"; // @formatter:on
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery(query)) {
if (res.next()) {
String worldName = res.getString("f.worldName");
double xPos = res.getDouble("f.xPos");
double yPos = res.getDouble("f.yPos");
double zPos = res.getDouble("f.zPos");
ParticleEffect particleEffect = ParticleManager.effectFromString(res.getString("f.effect"));
ParticleStyle particleStyle = ParticleStyleManager.styleFromString(res.getString("f.style"));
ItemData particleItemData = new ItemData(Material.matchMaterial(res.getString("i.material")), res.getByte("i.data"));
BlockData particleBlockData = new BlockData(Material.matchMaterial(res.getString("b.material")), res.getByte("b.data"));
OrdinaryColor particleColorData = new OrdinaryColor(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b"));
NoteColor particleNoteColorData = new NoteColor(res.getByte("n.note"));
if (res.next()) {
String worldName = res.getString("f.worldName");
double xPos = res.getDouble("f.xPos");
double yPos = res.getDouble("f.yPos");
double zPos = res.getDouble("f.zPos");
ParticleEffect particleEffect = ParticleManager.effectFromString(res.getString("f.effect"));
ParticleStyle particleStyle = ParticleStyleManager.styleFromString(res.getString("f.style"));
ItemData particleItemData = new ItemData(Material.matchMaterial(res.getString("i.material")), res.getByte("i.data"));
BlockData particleBlockData = new BlockData(Material.matchMaterial(res.getString("b.material")), res.getByte("b.data"));
OrdinaryColor particleColorData = new OrdinaryColor(res.getInt("c.r"), res.getInt("c.g"), res.getInt("c.b"));
NoteColor particleNoteColorData = new NoteColor(res.getByte("n.note"));
return new FixedParticleEffect(pplayerUUID, id, worldName, xPos, yPos, zPos, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData);
callback.execute(new FixedParticleEffect(pplayerUUID, id, worldName, xPos, yPos, zPos, particleEffect, particleStyle, particleItemData, particleBlockData, particleColorData, particleNoteColorData));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
});
}
return null; // No effect was found with the id specified
}
/**
@ -723,27 +783,33 @@ public class ConfigManager {
* @param pplayerUUID The player
* @return A list of all fixed effect ids for the given player
*/
public List<Integer> getFixedEffectIdsForPlayer(UUID pplayerUUID) {
List<Integer> ids = new ArrayList<Integer>();
public void getFixedEffectIdsForPlayer(UUID pplayerUUID, ConfigurationCallback<List<Integer>> callback) {
if (!PlayerParticles.useMySQL) {
if (config.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect")) {
Set<String> keys = config.getConfigurationSection(pplayerUUID.toString() + ".fixedEffect").getKeys(false);
List<Integer> ids = new ArrayList<Integer>();
if (playerDataYaml.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect")) {
Set<String> keys = playerDataYaml.getConfigurationSection(pplayerUUID.toString() + ".fixedEffect").getKeys(false);
for (String key : keys) {
ids.add(Integer.parseInt(key));
}
}
callback.execute(ids);
} else {
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT id FROM pp_fixed WHERE player_uuid = '" + pplayerUUID.toString() + "'")) {
while (res.next()) {
ids.add(res.getInt(1));
PlayerParticles.mySQL.connect((connection) -> {
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("SELECT id FROM pp_fixed WHERE player_uuid = '" + pplayerUUID.toString() + "'")) {
List<Integer> ids = new ArrayList<Integer>();
while (res.next()) {
ids.add(res.getInt(1));
}
callback.execute(ids);
}
} catch (SQLException e) {
e.printStackTrace();
}
});
}
return ids;
}
/**
@ -752,28 +818,31 @@ public class ConfigManager {
* @param pplayerUUID The player to check
* @return If the player can create any more fixed effects
*/
public boolean hasPlayerReachedMaxFixedEffects(UUID pplayerUUID) {
public void hasPlayerReachedMaxFixedEffects(UUID pplayerUUID, ConfigurationCallback<Boolean> callback) {
if (maxFixedEffects == -1) { // Initialize on the fly
maxFixedEffects = PlayerParticles.getPlugin().getConfig().getInt("max-fixed-effects");
}
if (Bukkit.getPlayer(pplayerUUID).hasPermission("playerparticles.fixed.unlimited")) return false;
if (!PlayerParticles.useMySQL) {
if (config.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect")) {
return config.getConfigurationSection(pplayerUUID.toString() + ".fixedEffect").getKeys(false).size() >= maxFixedEffects;
} else return false;
} else {
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT COUNT(1) FROM pp_fixed WHERE player_uuid = '" + pplayerUUID.toString() + "'")) {
if (res.next()) {
return res.getInt(1) >= maxFixedEffects;
} else return false;
} catch (SQLException e) {
e.printStackTrace();
}
if (Bukkit.getPlayer(pplayerUUID).hasPermission("playerparticles.fixed.unlimited")) {
callback.execute(false);
return;
}
return true; // Something went wrong, pretend they reached the max
if (!PlayerParticles.useMySQL) {
if (playerDataYaml.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect")) {
callback.execute(playerDataYaml.getConfigurationSection(pplayerUUID.toString() + ".fixedEffect").getKeys(false).size() >= maxFixedEffects);
} else callback.execute(false);
} else {
PlayerParticles.mySQL.connect((connection) -> {
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("SELECT COUNT(1) FROM pp_fixed WHERE player_uuid = '" + pplayerUUID.toString() + "'")) {
if (res.next()) {
callback.execute(res.getInt(1) >= maxFixedEffects);
} else callback.execute(false);
}
});
}
}
/**
@ -782,27 +851,47 @@ public class ConfigManager {
* @param pplayerUUID The player to get the Id for
* @return The smallest available Id the player can use
*/
public int getNextFixedEffectId(UUID pplayerUUID) {
Set<String> idsSet = new HashSet<String>();
public void getNextFixedEffectId(UUID pplayerUUID, ConfigurationCallback<Integer> callback) {
if (!PlayerParticles.useMySQL) {
if (!config.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect")) return 1;
idsSet = config.getConfigurationSection(pplayerUUID.toString() + ".fixedEffect").getKeys(false);
} else {
try (ResultSet res = PlayerParticles.mySQL.querySQL("SELECT id FROM pp_fixed WHERE player_uuid = '" + pplayerUUID.toString() + "'")) {
while (res.next()) {
idsSet.add(res.getInt(1) + "");
}
} catch (SQLException e) {
e.printStackTrace();
if (!playerDataYaml.isConfigurationSection(pplayerUUID.toString() + ".fixedEffect")) {
callback.execute(1);
return;
}
}
Set<String> idsSet = playerDataYaml.getConfigurationSection(pplayerUUID.toString() + ".fixedEffect").getKeys(false);
if (idsSet.isEmpty()) callback.execute(1);
int[] ids = new int[idsSet.size()];
int i = 0;
for (String key : idsSet)
ids[i++] = Integer.parseInt(key);
if (idsSet.isEmpty()) return 1;
int[] ids = new int[idsSet.size()];
int i = 0;
for (String key : idsSet)
ids[i++] = Integer.parseInt(key);
return ParticleUtils.getSmallestPositiveInt(ids);
callback.execute(ParticleUtils.getSmallestPositiveInt(ids));
} else {
PlayerParticles.mySQL.connect((connection) -> {
try (Statement statement = connection.createStatement();
ResultSet res = statement.executeQuery("SELECT id FROM pp_fixed WHERE player_uuid = '" + pplayerUUID.toString() + "'")) {
Set<String> idsSet = new HashSet<String>();
while (res.next())
idsSet.add(res.getInt(1) + "");
if (idsSet.isEmpty()) {
callback.execute(1);
return;
}
int[] ids = new int[idsSet.size()];
int i = 0;
for (String key : idsSet)
ids[i++] = Integer.parseInt(key);
callback.execute(ParticleUtils.getSmallestPositiveInt(ids));
}
});
}
}
/**
@ -833,10 +922,17 @@ public class ConfigManager {
* @return All world names that are disabled
*/
public List<String> getDisabledWorlds() {
if (disabledWorlds == null) {
if (disabledWorlds == null) { // Initialize on the fly
disabledWorlds = PlayerParticles.getPlugin().getConfig().getStringList("disabled-worlds");
}
return disabledWorlds;
}
/**
* Allows callbacks to be passed between configuration methods and executed for returning objects after database queries
*/
public static interface ConfigurationCallback<T> {
public void execute(T obj);
}
}

View file

@ -1,18 +1,19 @@
package com.esophose.playerparticles.manager;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.bukkit.configuration.file.FileConfiguration;
import com.esophose.playerparticles.PlayerParticles;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
public class DatabaseManager {
private HikariDataSource hikari;
private boolean initializedSuccessfully = false;
public DatabaseManager(FileConfiguration pluginConfig) {
String hostname = pluginConfig.getString("database-hostname");
@ -25,34 +26,56 @@ public class DatabaseManager {
config.setJdbcUrl("jdbc:mysql://" + hostname + ":" + port + "/" + database);
config.setUsername(user);
config.setPassword(pass);
config.setMaximumPoolSize(10);
config.setMaximumPoolSize(5);
hikari = new HikariDataSource(config);
try {
hikari = new HikariDataSource(config);
initializedSuccessfully = true;
} catch (Exception ex) {
initializedSuccessfully = false;
}
}
/**
* Checks if the connection to the database has been created
*
* @return If the connection is created or not
*/
public boolean isInitialized() {
return initializedSuccessfully;
}
/**
* Closes all connections to the database
*/
public void closeConnection() {
hikari.close();
}
public ResultSet querySQL(String query) throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet result = null;
try {
connection = hikari.getConnection();
statement = connection.createStatement();
result = statement.executeQuery(query);
/**
* Executes a callback with a Connection passed
* Automatically closes connection
* You need to close any resulting Statements or ResultSets on your own
*
* @param callback The callback to execute once the connection is retrieved
* @return
* @throws SQLException
*/
public void connect(ConnectionCallback callback) {
try (Connection connection = hikari.getConnection()) {
callback.execute(connection);
} catch (SQLException ex) {
throw ex;
} finally {
try { if (connection != null) connection.close(); } catch (Exception ex) { };
try { if (statement != null) statement.close(); } catch (Exception ex) { };
PlayerParticles.getPlugin().getLogger().warning("An error occurred retrieving a database connection: " + ex.getMessage());
}
return result;
}
/**
* Executes an update statement and cleans up all resources
*
* @param query The update statement to run
* @return
* @throws SQLException
*/
public int updateSQL(String query) throws SQLException {
Connection connection = null;
Statement statement = null;
@ -84,5 +107,12 @@ public class DatabaseManager {
try { if (statement != null) statement.close(); } catch (Exception ex) { };
}
}
/**
* Allows Lambda expressions to be used to reduce duplicated code for getting connections
*/
public static interface ConnectionCallback {
public void execute(Connection connection) throws SQLException;
}
}

View file

@ -57,7 +57,7 @@ public class ParticleManager extends BukkitRunnable implements Listener {
*/
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
ConfigManager.getInstance().getPPlayer(e.getPlayer().getUniqueId(), false);
ConfigManager.getInstance().loadPPlayer(e.getPlayer().getUniqueId());
}
/**
@ -67,14 +67,18 @@ public class ParticleManager extends BukkitRunnable implements Listener {
*/
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {
particlePlayers.remove(ConfigManager.getInstance().getPPlayer(e.getPlayer().getUniqueId(), false));
PPlayer pplayer = ConfigManager.getInstance().getPPlayer(e.getPlayer().getUniqueId());
if (pplayer != null)
particlePlayers.remove(pplayer);
}
/**
* Adds all fixed effects from the config
*/
public static void addAllFixedEffects() {
fixedParticleEffects.addAll(ConfigManager.getInstance().getAllFixedEffects());
ConfigManager.getInstance().getAllFixedEffects((fixedEffects) -> {
fixedParticleEffects.addAll(fixedEffects);
});
}
/**
@ -83,9 +87,9 @@ public class ParticleManager extends BukkitRunnable implements Listener {
* @param pplayerUUID The pplayer to remove the fixed effects from
*/
public static void removeAllFixedEffectsForPlayer(UUID pplayerUUID) {
for (int i = fixedParticleEffects.size() - 1; i >= 0; i--) {
if (fixedParticleEffects.get(i).getOwnerUniqueId().equals(pplayerUUID)) fixedParticleEffects.remove(i);
}
for (int i = fixedParticleEffects.size() - 1; i >= 0; i--)
if (fixedParticleEffects.get(i).getOwnerUniqueId().equals(pplayerUUID))
fixedParticleEffects.remove(i);
}
/**
@ -104,9 +108,9 @@ public class ParticleManager extends BukkitRunnable implements Listener {
* @param id The id of the fixed effect to remove
*/
public static void removeFixedEffectForPlayer(UUID pplayerUUID, int id) {
for (int i = fixedParticleEffects.size() - 1; i >= 0; i--) {
if (fixedParticleEffects.get(i).getOwnerUniqueId().equals(pplayerUUID) && fixedParticleEffects.get(i).getId() == id) fixedParticleEffects.remove(i);
}
for (int i = fixedParticleEffects.size() - 1; i >= 0; i--)
if (fixedParticleEffects.get(i).getOwnerUniqueId().equals(pplayerUUID) && fixedParticleEffects.get(i).getId() == id)
fixedParticleEffects.remove(i);
}
/**
@ -115,9 +119,8 @@ public class ParticleManager extends BukkitRunnable implements Listener {
*/
public static void refreshPPlayers() {
particlePlayers.clear();
for (Player player : Bukkit.getOnlinePlayers()) {
ConfigManager.getInstance().getPPlayer(player.getUniqueId(), false);
}
for (Player player : Bukkit.getOnlinePlayers())
ConfigManager.getInstance().loadPPlayer(player.getUniqueId());
}
/**

View file

@ -86,7 +86,9 @@ public class FixedParticleEffect {
this.particleColorData = colorData;
this.particleNoteColorData = noteColorData;
PPlayer owner = ConfigManager.getInstance().getPPlayer(this.pplayerUUID, true);
// The PPlayer must be loaded
ConfigManager.getInstance().loadPPlayer(pplayerUUID);
PPlayer owner = ConfigManager.getInstance().getPPlayer(this.pplayerUUID);
// Check nulls, if any are null set them to the PPlayer's values
if (this.particleItemData == null) this.particleItemData = owner.getItemData();

View file

@ -334,12 +334,9 @@ public enum ParticleEffect {
private List<Player> getPlayersInRange(Location center) {
List<Player> players = new ArrayList<Player>();
for (Player p : Bukkit.getOnlinePlayers()) {
if (!p.getWorld().equals(center.getWorld())) continue;
if (center.distanceSquared(p.getLocation()) <= PARTICLE_DISPLAY_RANGE_SQUARED) {
for (Player p : Bukkit.getOnlinePlayers())
if (p.getWorld().equals(center.getWorld()) && center.distanceSquared(p.getLocation()) <= PARTICLE_DISPLAY_RANGE_SQUARED)
players.add(p);
}
}
return players;
}

View file

@ -23,7 +23,7 @@ public class ParticleStyleMove extends ParticleStyleNone implements Listener {
*/
@EventHandler
public void onPlayerMove(PlayerMoveEvent e) {
PPlayer pplayer = ConfigManager.getInstance().getPPlayer(e.getPlayer().getUniqueId(), false);
PPlayer pplayer = ConfigManager.getInstance().getPPlayer(e.getPlayer().getUniqueId());
if (pplayer != null && pplayer.getParticleStyle() == DefaultStyles.MOVE) {
if (PermissionManager.hasStylePermission(e.getPlayer(), DefaultStyles.MOVE)) {
Location loc = e.getPlayer().getLocation();

View file

@ -190,8 +190,8 @@ message-use: '&eYou can use:&b'
message-usage: '&eUsage:'
# Available Commands
# Default: '&eAvailable commands: &beffect, effects, style, styles, data, reset, gui, worlds, version, help'
message-available-commands: '&eAvailable commands: &beffect, effects, style, styles, data, reset, gui, worlds, version, help'
# Default: '&eAvailable commands: &beffect, effects, style, styles, data, fixed, reset, gui, worlds, version, help'
message-available-commands: '&eAvailable commands: &beffect, effects, style, styles, data, fixed, reset, gui, worlds, version, help'
# Disabled Worlds
# Default: '&eParticles are disabled in these worlds:&b'