Merge pull request #32 from Esophose/async

Asynchronize most of the plugin
This commit is contained in:
Esophose 2020-02-18 02:01:14 -07:00 committed by GitHub
commit 71d106666a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 146 additions and 138 deletions

View file

@ -16,12 +16,12 @@ import dev.esophose.playerparticles.particles.ParticlePair;
import dev.esophose.playerparticles.styles.ParticleStyle; import dev.esophose.playerparticles.styles.ParticleStyle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -525,7 +525,7 @@ public final class PlayerParticlesAPI {
Objects.requireNonNull(groupName); Objects.requireNonNull(groupName);
Objects.requireNonNull(particles); Objects.requireNonNull(particles);
Map<Integer, ParticlePair> mappedParticles = new HashMap<>(); Map<Integer, ParticlePair> mappedParticles = new ConcurrentHashMap<>();
particles.forEach(x -> mappedParticles.put(x.getId(), x)); particles.forEach(x -> mappedParticles.put(x.getId(), x));
ParticleGroup particleGroup = new ParticleGroup(groupName.toLowerCase(), mappedParticles); ParticleGroup particleGroup = new ParticleGroup(groupName.toLowerCase(), mappedParticles);
return this.savePlayerParticleGroup(player, particleGroup); return this.savePlayerParticleGroup(player, particleGroup);

View file

@ -13,9 +13,9 @@ import dev.esophose.playerparticles.util.StringPlaceholders;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil; import org.bukkit.util.StringUtil;
@ -101,7 +101,7 @@ public class GroupCommandModule implements CommandModule {
ParticleGroup group = pplayer.getParticleGroupByName(groupName); ParticleGroup group = pplayer.getParticleGroupByName(groupName);
boolean groupUpdated = false; boolean groupUpdated = false;
if (group == null) { if (group == null) {
Map<Integer, ParticlePair> particles = new HashMap<>(); Map<Integer, ParticlePair> particles = new ConcurrentHashMap<>();
for (ParticlePair particle : pplayer.getActiveParticles()) for (ParticlePair particle : pplayer.getActiveParticles())
particles.put(particle.getId(), particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group particles.put(particle.getId(), particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group
group = new ParticleGroup(groupName, particles); group = new ParticleGroup(groupName, particles);

View file

@ -9,11 +9,13 @@ import dev.esophose.playerparticles.particles.ParticleEffect;
import dev.esophose.playerparticles.styles.DefaultStyles; import dev.esophose.playerparticles.styles.DefaultStyles;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit;
public class ReloadCommandModule implements CommandModule { public class ReloadCommandModule implements CommandModule {
public void onCommandExecute(PPlayer pplayer, String[] args) { public void onCommandExecute(PPlayer pplayer, String[] args) {
PlayerParticles playerParticles = PlayerParticles.getInstance(); PlayerParticles playerParticles = PlayerParticles.getInstance();
Bukkit.getScheduler().runTask(playerParticles, () -> {
LocaleManager localeManager = playerParticles.getManager(LocaleManager.class); LocaleManager localeManager = playerParticles.getManager(LocaleManager.class);
if (playerParticles.getManager(PermissionManager.class).canReloadPlugin(pplayer.getUnderlyingExecutor())) { if (playerParticles.getManager(PermissionManager.class).canReloadPlugin(pplayer.getUnderlyingExecutor())) {
playerParticles.reload(); playerParticles.reload();
@ -24,6 +26,7 @@ public class ReloadCommandModule implements CommandModule {
} else { } else {
localeManager.sendMessage(pplayer, "reload-no-permission"); localeManager.sendMessage(pplayer, "reload-no-permission");
} }
});
} }
public List<String> onTabComplete(PPlayer pplayer, String[] args) { public List<String> onTabComplete(PPlayer pplayer, String[] args) {

View file

@ -1,10 +1,12 @@
package dev.esophose.playerparticles.gui; package dev.esophose.playerparticles.gui;
import dev.esophose.playerparticles.PlayerParticles;
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting; import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
import dev.esophose.playerparticles.particles.PPlayer; import dev.esophose.playerparticles.particles.PPlayer;
import dev.esophose.playerparticles.util.ParticleUtils; import dev.esophose.playerparticles.util.ParticleUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -161,4 +163,8 @@ public abstract class GuiInventory implements InventoryHolder {
} }
} }
public void close() {
Bukkit.getScheduler().runTask(PlayerParticles.getInstance(), () -> this.pplayer.getPlayer().closeInventory());
}
} }

View file

@ -63,9 +63,8 @@ public class GuiInventoryLoadPresetGroups extends GuiInventory {
} }
PlayerParticlesAPI.getInstance().savePlayerParticleGroup(pplayer.getPlayer(), activeGroup); PlayerParticlesAPI.getInstance().savePlayerParticleGroup(pplayer.getPlayer(), activeGroup);
if (Setting.GUI_CLOSE_AFTER_GROUP_SELECTED.getBoolean()) { if (Setting.GUI_CLOSE_AFTER_GROUP_SELECTED.getBoolean())
pplayer.getPlayer().closeInventory(); this.close();
}
}); });
this.actionButtons.add(groupButton); this.actionButtons.add(groupButton);

View file

@ -16,9 +16,9 @@ import dev.esophose.playerparticles.util.ParticleUtils;
import dev.esophose.playerparticles.util.StringPlaceholders; import dev.esophose.playerparticles.util.StringPlaceholders;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
public class GuiInventoryManageGroups extends GuiInventory { public class GuiInventoryManageGroups extends GuiInventory {
@ -76,9 +76,8 @@ public class GuiInventoryManageGroups extends GuiInventory {
activeGroup.getParticles().put(particle.getId(), particle.clone()); activeGroup.getParticles().put(particle.getId(), particle.clone());
PlayerParticlesAPI.getInstance().savePlayerParticleGroup(pplayer.getPlayer(), activeGroup); PlayerParticlesAPI.getInstance().savePlayerParticleGroup(pplayer.getPlayer(), activeGroup);
if (Setting.GUI_CLOSE_AFTER_GROUP_SELECTED.getBoolean()) { if (Setting.GUI_CLOSE_AFTER_GROUP_SELECTED.getBoolean())
pplayer.getPlayer().closeInventory(); this.close();
}
} }
}); });
this.actionButtons.add(groupButton); this.actionButtons.add(groupButton);
@ -138,7 +137,7 @@ public class GuiInventoryManageGroups extends GuiInventory {
ParticleGroup group = pplayer.getParticleGroupByName(groupName); ParticleGroup group = pplayer.getParticleGroupByName(groupName);
boolean groupUpdated = false; boolean groupUpdated = false;
if (group == null) { if (group == null) {
Map<Integer, ParticlePair> particles = new HashMap<>(); Map<Integer, ParticlePair> particles = new ConcurrentHashMap<>();
for (ParticlePair particle : pplayer.getActiveParticles()) for (ParticlePair particle : pplayer.getActiveParticles())
particles.put(particle.getId(), particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group particles.put(particle.getId(), particle.clone()); // Make sure the ParticlePairs aren't the same references in both the active and saved group
group = new ParticleGroup(groupName, particles); group = new ParticleGroup(groupName, particles);
@ -157,7 +156,7 @@ public class GuiInventoryManageGroups extends GuiInventory {
guiManager.transition(new GuiInventoryManageGroups(pplayer)); guiManager.transition(new GuiInventoryManageGroups(pplayer));
} }
})); }));
pplayer.getPlayer().closeInventory(); this.close();
}); });
this.actionButtons.add(saveGroupButton); this.actionButtons.add(saveGroupButton);

View file

@ -146,16 +146,17 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
return true; return true;
} }
Bukkit.getScheduler().runTaskAsynchronously(this.playerParticles, () -> {
String[] cmdArgs = args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]; String[] cmdArgs = args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0];
if (!commandModule.canConsoleExecute()) { if (!commandModule.canConsoleExecute()) {
if (!(sender instanceof Player)) { if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "Error: This command can only be executed by a player."); sender.sendMessage(ChatColor.RED + "Error: This command can only be executed by a player.");
return true; return;
} }
} else if (sender instanceof ConsoleCommandSender) { } else if (sender instanceof ConsoleCommandSender) {
commandModule.onCommandExecute(PlayerParticlesAPI.getInstance().getConsolePPlayer(), cmdArgs); commandModule.onCommandExecute(PlayerParticlesAPI.getInstance().getConsolePPlayer(), cmdArgs);
return true; return;
} }
Player p = (Player) sender; Player p = (Player) sender;
@ -168,8 +169,11 @@ public class CommandManager extends Manager implements CommandExecutor, TabCompl
commandModule.onCommandExecute(pplayer, cmdArgs); commandModule.onCommandExecute(pplayer, cmdArgs);
} }
}); });
});
return true;
} else if (cmd.getName().equalsIgnoreCase("ppo")) { } else if (cmd.getName().equalsIgnoreCase("ppo")) {
this.ppoCommand.onCommandExecute(sender, args); Bukkit.getScheduler().runTaskAsynchronously(this.playerParticles, () -> this.ppoCommand.onCommandExecute(sender, args));
} }
return true; return true;

View file

@ -18,11 +18,11 @@ import dev.esophose.playerparticles.util.ParticleUtils;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -106,8 +106,8 @@ public class DataManager extends Manager {
} }
this.async(() -> { this.async(() -> {
Map<String, ParticleGroup> groups = new HashMap<>(); Map<String, ParticleGroup> groups = new ConcurrentHashMap<>();
Map<Integer, FixedParticleEffect> fixedParticles = new HashMap<>(); Map<Integer, FixedParticleEffect> fixedParticles = new ConcurrentHashMap<>();
this.databaseConnector.connect((connection) -> { this.databaseConnector.connect((connection) -> {
// Load settings // Load settings
@ -133,9 +133,9 @@ public class DataManager extends Manager {
} }
// Load particle groups // Load particle groups
String groupQuery = "SELECT * FROM " + this.getTablePrefix() + "group g " + // @formatter:off String groupQuery = "SELECT * FROM " + this.getTablePrefix() + "group g " +
"JOIN " + this.getTablePrefix() + "particle p ON g.uuid = p.group_uuid " + "JOIN " + this.getTablePrefix() + "particle p ON g.uuid = p.group_uuid " +
"WHERE g.owner_uuid = ?"; // @formatter:on "WHERE g.owner_uuid = ?";
try (PreparedStatement statement = connection.prepareStatement(groupQuery)) { try (PreparedStatement statement = connection.prepareStatement(groupQuery)) {
statement.setString(1, playerUUID.toString()); statement.setString(1, playerUUID.toString());
@ -172,7 +172,7 @@ public class DataManager extends Manager {
// Add the particle to a new group if one didn't already exist // Add the particle to a new group if one didn't already exist
if (!groupAlreadyExists) { if (!groupAlreadyExists) {
HashMap<Integer, ParticlePair> particles = new HashMap<>(); Map<Integer, ParticlePair> particles = new ConcurrentHashMap<>();
if (!invalid) if (!invalid)
particles.put(particle.getId(), particle); particles.put(particle.getId(), particle);
ParticleGroup newGroup = new ParticleGroup(groupName, particles); ParticleGroup newGroup = new ParticleGroup(groupName, particles);
@ -190,9 +190,9 @@ public class DataManager extends Manager {
} }
// Load fixed effects // 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 " + this.getTablePrefix() + "fixed f " + // @formatter:off 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 " + this.getTablePrefix() + "fixed f " +
"JOIN " + this.getTablePrefix() + "particle p ON f.particle_uuid = p.uuid " + "JOIN " + this.getTablePrefix() + "particle p ON f.particle_uuid = p.uuid " +
"WHERE f.owner_uuid = ?"; // @formatter:on "WHERE f.owner_uuid = ?";
try (PreparedStatement statement = connection.prepareStatement(fixedQuery)) { try (PreparedStatement statement = connection.prepareStatement(fixedQuery)) {
statement.setString(1, playerUUID.toString()); statement.setString(1, playerUUID.toString());
@ -240,7 +240,7 @@ public class DataManager extends Manager {
} }
if (!activeGroupExists) { if (!activeGroupExists) {
ParticleGroup activeGroup = new ParticleGroup(ParticleGroup.DEFAULT_NAME, new HashMap<>()); ParticleGroup activeGroup = new ParticleGroup(ParticleGroup.DEFAULT_NAME, new ConcurrentHashMap<>());
this.saveParticleGroup(playerUUID, activeGroup); this.saveParticleGroup(playerUUID, activeGroup);
groups.put(activeGroup.getName(), activeGroup); groups.put(activeGroup.getName(), activeGroup);
} }
@ -522,12 +522,16 @@ public class DataManager extends Manager {
} }
/** /**
* Asynchronizes the callback with it's own thread * Asynchronizes the callback with it's own thread unless it is already not on the main thread
* *
* @param asyncCallback The callback to run on a separate thread * @param asyncCallback The callback to run on a separate thread
*/ */
private void async(Runnable asyncCallback) { private void async(Runnable asyncCallback) {
if (Bukkit.isPrimaryThread()) {
Bukkit.getScheduler().runTaskAsynchronously(this.playerParticles, asyncCallback); Bukkit.getScheduler().runTaskAsynchronously(this.playerParticles, asyncCallback);
} else {
asyncCallback.run();
}
} }
/** /**

View file

@ -14,16 +14,20 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
public class GuiManager extends Manager implements Listener, Runnable { public class GuiManager extends Manager implements Listener, Runnable {
private List<GuiInventory> guiInventories = new ArrayList<>(); private List<GuiInventory> guiInventories;
private BukkitTask guiTask = null; private BukkitTask guiTask;
public GuiManager(PlayerParticles playerParticles) { public GuiManager(PlayerParticles playerParticles) {
super(playerParticles); super(playerParticles);
this.guiInventories = new ArrayList<>();
this.guiTask = null;
Bukkit.getPluginManager().registerEvents(this, this.playerParticles); Bukkit.getPluginManager().registerEvents(this, this.playerParticles);
} }
@ -41,46 +45,36 @@ public class GuiManager extends Manager implements Listener, Runnable {
/** /**
* Ticks GuiInventories * Ticks GuiInventories
* Removes entries from playerGuiInventories if the player no longer has the inventory open or is offline
*/ */
public void run() { public void run() {
List<GuiInventory> toRemoveList = new ArrayList<>(); this.guiInventories.forEach(GuiInventory::onTick);
for (GuiInventory inventory : this.guiInventories) {
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(inventory.getPPlayer().getUniqueId());
if (pplayer == null) {
toRemoveList.add(inventory);
continue;
}
Player player = Bukkit.getPlayer(inventory.getPPlayer().getUniqueId());
if (player == null) {
toRemoveList.add(inventory);
continue;
}
if (!inventory.getInventory().equals(player.getOpenInventory().getTopInventory())) {
toRemoveList.add(inventory);
continue;
}
inventory.onTick();
}
for (GuiInventory inventory : toRemoveList)
this.guiInventories.remove(inventory);
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void onInventoryClick(InventoryClickEvent event) { public void onInventoryClick(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) return; if (!(event.getWhoClicked() instanceof Player))
Player player = (Player)event.getWhoClicked(); return;
Player player = (Player) event.getWhoClicked();
GuiInventory inventory = this.getGuiInventory(player); GuiInventory inventory = this.getGuiInventory(player);
if (inventory == null) return; if (inventory == null)
return;
event.setCancelled(true); event.setCancelled(true);
inventory.onClick(event); Bukkit.getScheduler().runTaskAsynchronously(this.playerParticles, () -> inventory.onClick(event));
}
@EventHandler(priority = EventPriority.HIGH)
public void onInventoryClose(InventoryCloseEvent event) {
if (!(event.getPlayer() instanceof Player))
return;
Player player = (Player) event.getPlayer();
GuiInventory inventory = this.getGuiInventory(player);
if (inventory == null)
return;
this.guiInventories.remove(inventory);
} }
/** /**
@ -114,8 +108,6 @@ public class GuiManager extends Manager implements Listener, Runnable {
* @param pplayer The PPlayer to open the GUI screen for * @param pplayer The PPlayer to open the GUI screen for
*/ */
public void openDefault(PPlayer pplayer) { public void openDefault(PPlayer pplayer) {
this.removeGuiInventory(pplayer);
GuiInventory inventoryToOpen; GuiInventory inventoryToOpen;
if (!Setting.GUI_PRESETS_ONLY.getBoolean()) { if (!Setting.GUI_PRESETS_ONLY.getBoolean()) {
inventoryToOpen = new GuiInventoryDefault(pplayer); inventoryToOpen = new GuiInventoryDefault(pplayer);
@ -124,7 +116,7 @@ public class GuiManager extends Manager implements Listener, Runnable {
} }
this.guiInventories.add(inventoryToOpen); this.guiInventories.add(inventoryToOpen);
pplayer.getPlayer().openInventory(inventoryToOpen.getInventory()); Bukkit.getScheduler().runTask(this.playerParticles, () -> pplayer.getPlayer().openInventory(inventoryToOpen.getInventory()));
} }
/** /**
@ -133,9 +125,8 @@ public class GuiManager extends Manager implements Listener, Runnable {
* @param nextInventory The GuiInventory to transition to * @param nextInventory The GuiInventory to transition to
*/ */
public void transition(GuiInventory nextInventory) { public void transition(GuiInventory nextInventory) {
this.removeGuiInventory(nextInventory.getPPlayer());
this.guiInventories.add(nextInventory); this.guiInventories.add(nextInventory);
nextInventory.getPPlayer().getPlayer().openInventory(nextInventory.getInventory()); Bukkit.getScheduler().runTask(this.playerParticles, () -> nextInventory.getPPlayer().getPlayer().openInventory(nextInventory.getInventory()));
} }
/** /**
@ -145,10 +136,10 @@ public class GuiManager extends Manager implements Listener, Runnable {
* @return The GuiInventory belonging to the Player, if any * @return The GuiInventory belonging to the Player, if any
*/ */
private GuiInventory getGuiInventory(Player player) { private GuiInventory getGuiInventory(Player player) {
for (GuiInventory inventory : this.guiInventories) return this.guiInventories.stream()
if (inventory.getPPlayer().getUniqueId().equals(player.getUniqueId())) .filter(x -> x.getPPlayer().getUniqueId().equals(player.getUniqueId()))
return inventory; .findFirst()
return null; .orElse(null);
} }
/** /**
@ -157,12 +148,7 @@ public class GuiManager extends Manager implements Listener, Runnable {
* @param pplayer The PPlayer who owns the GuiInventory * @param pplayer The PPlayer who owns the GuiInventory
*/ */
private void removeGuiInventory(PPlayer pplayer) { private void removeGuiInventory(PPlayer pplayer) {
for (GuiInventory inventory : this.guiInventories) { this.guiInventories.removeIf(x -> x.getPPlayer().getUniqueId().equals(pplayer.getUniqueId()));
if (inventory.getPPlayer().getUniqueId().equals(pplayer.getUniqueId())) {
this.guiInventories.remove(inventory);
break;
}
}
} }
} }

View file

@ -13,11 +13,11 @@ import dev.esophose.playerparticles.particles.ParticlePair;
import dev.esophose.playerparticles.styles.DefaultStyles; import dev.esophose.playerparticles.styles.DefaultStyles;
import java.awt.Color; import java.awt.Color;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
@ -35,23 +35,29 @@ public class ParticleManager extends Manager implements Listener, Runnable {
/** /**
* The map containing all the loaded PPlayer info * The map containing all the loaded PPlayer info
*/ */
private Map<UUID, PPlayer> particlePlayers = new HashMap<>(); private final Map<UUID, PPlayer> particlePlayers;
/** /**
* The task that spawns the particles * The task that spawns the particles
*/ */
private BukkitTask particleTask = null; private BukkitTask particleTask;
/** /**
* Rainbow particle effect hue and note color used for rainbow colorable effects * Rainbow particle effect hue and note color used for rainbow colorable effects
*/ */
private int hue = 0; private int hue;
private int note = 0; private int note;
private final Random random = new Random(); private final Random random;
public ParticleManager(PlayerParticles playerParticles) { public ParticleManager(PlayerParticles playerParticles) {
super(playerParticles); super(playerParticles);
this.particlePlayers = new ConcurrentHashMap<>();
this.particleTask = null;
this.hue = 0;
this.note = 0;
this.random = new Random();
Bukkit.getPluginManager().registerEvents(this, this.playerParticles); Bukkit.getPluginManager().registerEvents(this, this.playerParticles);
} }
@ -62,7 +68,7 @@ public class ParticleManager extends Manager implements Listener, Runnable {
Bukkit.getScheduler().runTaskLater(this.playerParticles, () -> { Bukkit.getScheduler().runTaskLater(this.playerParticles, () -> {
long ticks = Setting.TICKS_PER_PARTICLE.getLong(); long ticks = Setting.TICKS_PER_PARTICLE.getLong();
this.particleTask = Bukkit.getScheduler().runTaskTimer(this.playerParticles, this, 5, ticks); this.particleTask = Bukkit.getScheduler().runTaskTimerAsynchronously(this.playerParticles, this, 5, ticks);
}, 1); }, 1);
this.particlePlayers.clear(); this.particlePlayers.clear();

View file

@ -77,6 +77,10 @@ public class PermissionManager extends Manager {
// Register plugin permissions to Bukkit // Register plugin permissions to Bukkit
PluginManager pluginManager = Bukkit.getPluginManager(); PluginManager pluginManager = Bukkit.getPluginManager();
// Don't register the permissions if we already have, could have happened because of a reload?
if (pluginManager.getPermission("playerparticles.*") != null)
return;
Set<Permission> allPermissions = new HashSet<>(); Set<Permission> allPermissions = new HashSet<>();
// Effects // Effects

View file

@ -1,6 +1,6 @@
package dev.esophose.playerparticles.particles; package dev.esophose.playerparticles.particles;
import java.util.HashMap; import java.util.Collections;
import java.util.UUID; import java.util.UUID;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -9,7 +9,7 @@ public class OtherPPlayer extends PPlayer {
private CommandSender sender; private CommandSender sender;
public OtherPPlayer(CommandSender sender) { public OtherPPlayer(CommandSender sender) {
super(UUID.randomUUID(), new HashMap<>(), new HashMap<>(), false); super(UUID.randomUUID(), Collections.emptyMap(), Collections.emptyMap(), false);
this.sender = sender; this.sender = sender;
} }

View file

@ -2,8 +2,8 @@ package dev.esophose.playerparticles.particles;
import dev.esophose.playerparticles.PlayerParticles; import dev.esophose.playerparticles.PlayerParticles;
import dev.esophose.playerparticles.manager.PermissionManager; import dev.esophose.playerparticles.manager.PermissionManager;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ParticleGroup { public class ParticleGroup {
@ -42,7 +42,7 @@ public class ParticleGroup {
* @return The default empty active ParticleGroup * @return The default empty active ParticleGroup
*/ */
public static ParticleGroup getDefaultGroup() { public static ParticleGroup getDefaultGroup() {
return new ParticleGroup(DEFAULT_NAME, new HashMap<>()); return new ParticleGroup(DEFAULT_NAME, new ConcurrentHashMap<>());
} }
/** /**

View file

@ -1,8 +1,6 @@
package dev.esophose.playerparticles.styles; package dev.esophose.playerparticles.styles;
import dev.esophose.playerparticles.PlayerParticles;
import dev.esophose.playerparticles.config.CommentedFileConfiguration; import dev.esophose.playerparticles.config.CommentedFileConfiguration;
import dev.esophose.playerparticles.manager.ParticleManager;
import dev.esophose.playerparticles.particles.PParticle; import dev.esophose.playerparticles.particles.PParticle;
import dev.esophose.playerparticles.particles.ParticlePair; import dev.esophose.playerparticles.particles.ParticlePair;
import java.util.ArrayList; import java.util.ArrayList;
@ -17,17 +15,15 @@ import org.bukkit.event.entity.ProjectileLaunchEvent;
public class ParticleStyleArrows extends DefaultParticleStyle implements Listener { public class ParticleStyleArrows extends DefaultParticleStyle implements Listener {
private List<Projectile> arrows = new ArrayList<>(); private List<Projectile> projectiles = new ArrayList<>();
private int maxArrowsPerPlayer; private int maxArrowsPerPlayer;
private boolean onlySpawnIfFlying; private boolean onlySpawnIfFlying;
private List<String> arrowEntityNames; private List<String> projectileEntityNames;
private ParticleManager particleManager; private int arrowTrackingTime;
public ParticleStyleArrows() { public ParticleStyleArrows() {
super("arrows", false, false, 0); super("arrows", false, false, 0);
this.particleManager = PlayerParticles.getInstance().getManager(ParticleManager.class);
} }
@Override @Override
@ -35,13 +31,13 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
List<PParticle> particles = new ArrayList<>(); List<PParticle> particles = new ArrayList<>();
int count = 0; int count = 0;
for (int i = this.arrows.size() - 1; i >= 0; i--) { // Loop backwards so the last-fired arrows are the ones that have particles if they go over the max for (int i = this.projectiles.size() - 1; i >= 0; i--) { // Loop backwards so the last-fired projectiles are the ones that have particles if they go over the max
Projectile arrow = this.arrows.get(i); Projectile projectile = this.projectiles.get(i);
if (this.onlySpawnIfFlying && arrow.isOnGround()) if (this.onlySpawnIfFlying && projectile.isOnGround())
continue; continue;
if (arrow.getShooter() != null && ((Player) arrow.getShooter()).getUniqueId().equals(particle.getOwnerUniqueId())) { if (projectile.getShooter() != null && ((Player) projectile.getShooter()).getUniqueId().equals(particle.getOwnerUniqueId())) {
particles.add(new PParticle(arrow.getLocation(), 0.05F, 0.05F, 0.05F, 0.0F)); particles.add(new PParticle(projectile.getLocation(), 0.05F, 0.05F, 0.05F, 0.0F));
count++; count++;
} }
@ -57,10 +53,10 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
*/ */
@Override @Override
public void updateTimers() { public void updateTimers() {
for (int i = this.arrows.size() - 1; i >= 0; i--) { for (int i = this.projectiles.size() - 1; i >= 0; i--) {
Projectile arrow = this.arrows.get(i); Projectile projectile = this.projectiles.get(i);
if (arrow.getTicksLived() >= 1200 || arrow.isDead() || !arrow.isValid() || arrow.getShooter() == null) if ((this.arrowTrackingTime != -1 && projectile.getTicksLived() >= this.arrowTrackingTime) || projectile.isDead() || !projectile.isValid() || projectile.getShooter() == null)
this.arrows.remove(i); this.projectiles.remove(i);
} }
} }
@ -81,8 +77,8 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
return; return;
String entityName = event.getEntity().getType().name(); String entityName = event.getEntity().getType().name();
if (this.arrowEntityNames.contains(entityName)) if (this.projectileEntityNames.contains(entityName))
this.arrows.add(event.getEntity()); this.projectiles.add(event.getEntity());
} }
@Override @Override
@ -90,13 +86,15 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
this.setIfNotExists("max-arrows-per-player", 10, "The max number of arrows that will spawn particles per player"); this.setIfNotExists("max-arrows-per-player", 10, "The max number of arrows that will spawn particles per player");
this.setIfNotExists("only-spawn-if-flying", false, "Only spawn particles while the arrow is still in the air"); this.setIfNotExists("only-spawn-if-flying", false, "Only spawn particles while the arrow is still in the air");
this.setIfNotExists("arrow-entities", Arrays.asList("ARROW", "SPECTRAL_ARROW", "TIPPED_ARROW"), "The name of the projectile entities that are counted as arrows"); this.setIfNotExists("arrow-entities", Arrays.asList("ARROW", "SPECTRAL_ARROW", "TIPPED_ARROW"), "The name of the projectile entities that are counted as arrows");
this.setIfNotExists("arrow-tracking-time", 1200, "The maximum number of ticks to track an arrow for", "Set to -1 to disable (not recommended)");
} }
@Override @Override
protected void loadSettings(CommentedFileConfiguration config) { protected void loadSettings(CommentedFileConfiguration config) {
this.maxArrowsPerPlayer = config.getInt("max-arrows-per-player"); this.maxArrowsPerPlayer = config.getInt("max-arrows-per-player");
this.onlySpawnIfFlying = config.getBoolean("only-spawn-if-flying"); this.onlySpawnIfFlying = config.getBoolean("only-spawn-if-flying");
this.arrowEntityNames = config.getStringList("arrow-entities"); this.projectileEntityNames = config.getStringList("arrow-entities");
this.arrowTrackingTime = config.getInt("arrow-tracking-time");
} }
} }

View file

@ -62,11 +62,11 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
if (player != null && player.getGameMode() != GameMode.SPECTATOR && permissionManager.isWorldEnabled(player.getWorld().getName())) if (player != null && player.getGameMode() != GameMode.SPECTATOR && permissionManager.isWorldEnabled(player.getWorld().getName()))
for (ParticlePair particle : pplayer.getActiveParticles()) for (ParticlePair particle : pplayer.getActiveParticles())
if (particle.getStyle() == this) if (particle.getStyle() == this)
this.spawnFirework(player.getLocation(), pplayer, particle, random); this.spawnFirework(player.getLocation(), pplayer, pplayer.getPlayer(), particle, random);
for (FixedParticleEffect fixedEffect : pplayer.getFixedParticles()) for (FixedParticleEffect fixedEffect : pplayer.getFixedParticles())
if (fixedEffect.getParticlePair().getStyle() == this && permissionManager.isWorldEnabled(fixedEffect.getLocation().getWorld().getName())) if (fixedEffect.getParticlePair().getStyle() == this && permissionManager.isWorldEnabled(fixedEffect.getLocation().getWorld().getName()))
this.spawnFirework(fixedEffect.getLocation(), pplayer, fixedEffect.getParticlePair(), random); this.spawnFirework(fixedEffect.getLocation(), pplayer, null, fixedEffect.getParticlePair(), random);
} }
} }
} }
@ -102,14 +102,13 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
this.fuseEffect = ParticleEffect.FIREWORK; this.fuseEffect = ParticleEffect.FIREWORK;
} }
private void spawnFirework(final Location location, final PPlayer pplayer, final ParticlePair particle, final Random random) { private void spawnFirework(final Location location, final PPlayer pplayer, final Player player, final ParticlePair particle, final Random random) {
double angle = random.nextDouble() * Math.PI * 2; double angle = random.nextDouble() * Math.PI * 2;
double distanceFrom = this.baseDistanceFrom + random.nextDouble() * this.distanceFromRandomizer; double distanceFrom = this.baseDistanceFrom + random.nextDouble() * this.distanceFromRandomizer;
double dx = MathL.sin(angle) * distanceFrom; double dx = MathL.sin(angle) * distanceFrom;
double dz = MathL.cos(angle) * distanceFrom; double dz = MathL.cos(angle) * distanceFrom;
final Location loc = location.clone().add(dx, 1, dz); final Location loc = location.clone().add(dx, 1, dz);
final int fuse = this.baseFuseLength + random.nextInt(this.fuseLengthRandomizer); final int fuse = this.baseFuseLength + random.nextInt(this.fuseLengthRandomizer);
Player player = pplayer.getPlayer();
ParticleManager particleManager = PlayerParticles.getInstance().getManager(ParticleManager.class); ParticleManager particleManager = PlayerParticles.getInstance().getManager(ParticleManager.class);
new BukkitRunnable() { new BukkitRunnable() {

View file

@ -53,12 +53,12 @@ public class ParticleStyleMove extends DefaultParticleStyle implements Listener
public void onPlayerMove(PlayerMoveEvent event) { public void onPlayerMove(PlayerMoveEvent event) {
ParticleManager particleManager = PlayerParticles.getInstance().getManager(ParticleManager.class); ParticleManager particleManager = PlayerParticles.getInstance().getManager(ParticleManager.class);
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(event.getPlayer().getUniqueId()); Player player = event.getPlayer();
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
if (pplayer != null) { if (pplayer != null) {
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.MOVE)) { for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.MOVE)) {
Location loc = event.getPlayer().getLocation().clone(); Location loc = player.getLocation().clone();
loc.setY(loc.getY() + 0.05); loc.setY(loc.getY() + 0.05);
Player player = event.getPlayer();
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.MOVE.getParticles(particle, loc), false); particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.MOVE.getParticles(particle, loc), false);
} }
} }