mirror of
https://github.com/TotalFreedomMC/PlayerParticles.git
synced 2024-12-28 10:24:15 +00:00
Merge branch 'master' into version-compat
This commit is contained in:
parent
9567b06e23
commit
a82b4d125e
93 changed files with 1496 additions and 698 deletions
|
@ -1,88 +1,100 @@
|
|||
package dev.esophose.playerparticles.particles;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public enum ParticleEffect {
|
||||
|
||||
AMBIENT_ENTITY_EFFECT(ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
ANGRY_VILLAGER,
|
||||
ASH,
|
||||
BARRIER,
|
||||
BLOCK(ParticleProperty.REQUIRES_BLOCK_DATA),
|
||||
BUBBLE,
|
||||
BUBBLE_COLUMN_UP,
|
||||
BUBBLE_POP,
|
||||
CAMPFIRE_COSY_SMOKE,
|
||||
CAMPFIRE_SIGNAL_SMOKE,
|
||||
CLOUD,
|
||||
COMPOSTER,
|
||||
CRIMSON_SPORE,
|
||||
CRIT,
|
||||
CURRENT_DOWN,
|
||||
DAMAGE_INDICATOR,
|
||||
DOLPHIN,
|
||||
DRAGON_BREATH,
|
||||
DRIPPING_HONEY,
|
||||
DRIPPING_LAVA,
|
||||
DRIPPING_OBSIDIAN_TEAR,
|
||||
DRIPPING_WATER,
|
||||
DUST(ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
ELDER_GUARDIAN,
|
||||
ENCHANT,
|
||||
ENCHANTED_HIT,
|
||||
END_ROD,
|
||||
ENTITY_EFFECT(ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
EXPLOSION,
|
||||
EXPLOSION_EMITTER,
|
||||
FALLING_DUST(ParticleProperty.REQUIRES_BLOCK_DATA),
|
||||
FALLING_HONEY,
|
||||
FALLING_LAVA,
|
||||
FALLING_NECTAR,
|
||||
FALLING_OBSIDIAN_TEAR,
|
||||
FALLING_WATER,
|
||||
FIREWORK,
|
||||
FISHING,
|
||||
FLAME,
|
||||
FLASH,
|
||||
FOOTSTEP,
|
||||
HAPPY_VILLAGER,
|
||||
HEART,
|
||||
INSTANT_EFFECT,
|
||||
ITEM(ParticleProperty.REQUIRES_ITEM_DATA),
|
||||
ITEM_SLIME,
|
||||
ITEM_SNOWBALL,
|
||||
LANDING_HONEY,
|
||||
LANDING_LAVA,
|
||||
LANDING_OBSIDIAN_TEAR,
|
||||
LARGE_SMOKE,
|
||||
LAVA,
|
||||
MYCELIUM,
|
||||
NAUTILUS,
|
||||
NOTE(ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
POOF,
|
||||
PORTAL,
|
||||
RAIN,
|
||||
SMOKE,
|
||||
SNEEZE,
|
||||
SOUL,
|
||||
SOUL_FIRE_FLAME,
|
||||
SPELL, // The Minecraft internal name for this is actually "effect", but that's the command name, so it's SPELL for the plugin instead
|
||||
SPIT,
|
||||
SPLASH,
|
||||
SQUID_INK,
|
||||
SWEEP_ATTACK,
|
||||
TOTEM_OF_UNDYING,
|
||||
UNDERWATER,
|
||||
WARPED_SPORE,
|
||||
WITCH;
|
||||
AMBIENT_ENTITY_EFFECT(Collections.singletonList("BEACON"), ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
ANGRY_VILLAGER(Collections.singletonList("IRON_DOOR")),
|
||||
ASH(Collections.singletonList("BLACKSTONE")),
|
||||
BARRIER(Collections.singletonList("BARRIER")),
|
||||
BLOCK(Collections.singletonList("STONE"), ParticleProperty.REQUIRES_BLOCK_DATA),
|
||||
BUBBLE(Arrays.asList("BUBBLE_CORAL", "GLASS")),
|
||||
BUBBLE_COLUMN_UP(Collections.singletonList("MAGMA_BLOCK")),
|
||||
BUBBLE_POP(Collections.singletonList("BUBBLE_CORAL_FAN")),
|
||||
CAMPFIRE_COSY_SMOKE(Collections.singletonList("CAMPFIRE")),
|
||||
CAMPFIRE_SIGNAL_SMOKE(Collections.singletonList("REDSTONE_TORCH")),
|
||||
CLOUD(Arrays.asList("WHITE_WOOL", "WOOL")),
|
||||
COMPOSTER(Collections.singletonList("COMPOSTER")),
|
||||
CRIMSON_SPORE(Collections.singletonList("CRIMSON_SPORE")),
|
||||
CRIT(Collections.singletonList("IRON_SWORD")),
|
||||
CURRENT_DOWN(Collections.singletonList("SOUL_SAND")),
|
||||
DAMAGE_INDICATOR(Collections.singletonList("BOW")),
|
||||
DOLPHIN(Collections.singletonList("DOLPHIN_SPAWN_EGG")),
|
||||
DRAGON_BREATH(Arrays.asList("DRAGON_BREATH", "DRAGONS_BREATH")),
|
||||
DRIPPING_HONEY(Collections.singletonList("BEE_NEST")),
|
||||
DRIPPING_LAVA(Collections.singletonList("LAVA_BUCKET")),
|
||||
DRIPPING_OBSIDIAN_TEAR(Collections.singletonList("CRYING_OBSIDIAN")),
|
||||
DRIPPING_WATER(Collections.singletonList("WATER_BUCKET")),
|
||||
DUST(Collections.singletonList("REDSTONE"), ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
ELDER_GUARDIAN(Arrays.asList("ELDER_GUARDIAN_SPAWN_EGG", "PRISMARINE_CRYSTALS")),
|
||||
ENCHANT(Arrays.asList("ENCHANTING_TABLE", "ENCHANTMENT_TABLE")),
|
||||
ENCHANTED_HIT(Collections.singletonList("DIAMOND_SWORD")),
|
||||
END_ROD(Collections.singletonList("END_ROD")),
|
||||
ENTITY_EFFECT(Collections.singletonList("GLOWSTONE_DUST"), ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
EXPLOSION(Arrays.asList("FIRE_CHARGE", "FIREBALL")),
|
||||
EXPLOSION_EMITTER(Collections.singletonList("TNT")),
|
||||
FALLING_DUST(Collections.singletonList("SAND"), ParticleProperty.REQUIRES_BLOCK_DATA),
|
||||
FALLING_HONEY(Collections.singletonList("HONEY_BOTTLE")),
|
||||
FALLING_LAVA(Collections.singletonList("RED_DYE")),
|
||||
FALLING_NECTAR(Collections.singletonList("HONEYCOMB")),
|
||||
FALLING_OBSIDIAN_TEAR(Collections.singletonList("ANCIENT_DEBRIS")),
|
||||
FALLING_WATER(Collections.singletonList("BLUE_DYE")),
|
||||
FIREWORK(Arrays.asList("FIREWORK_ROCKET", "FIREWORK")),
|
||||
FISHING(Collections.singletonList("FISHING_ROD")),
|
||||
FLAME(Collections.singletonList("BLAZE_POWDER")),
|
||||
FLASH(Collections.singletonList("GOLD_INGOT")),
|
||||
FOOTSTEP(Collections.singletonList("GRASS")),
|
||||
HAPPY_VILLAGER(Arrays.asList("DARK_OAK_DOOR_ITEM", "DARK_OAK_DOOR")),
|
||||
HEART(Arrays.asList("POPPY", "RED_ROSE")),
|
||||
INSTANT_EFFECT(Arrays.asList("SPLASH_POTION", "POTION")),
|
||||
ITEM(Collections.singletonList("ITEM_FRAME"), ParticleProperty.REQUIRES_ITEM_DATA),
|
||||
ITEM_SLIME(Collections.singletonList("SLIME_BALL")),
|
||||
ITEM_SNOWBALL(Arrays.asList("SNOWBALL", "SNOW_BALL")),
|
||||
LANDING_HONEY(Collections.singletonList("HONEY_BLOCK")),
|
||||
LANDING_LAVA(Collections.singletonList("ORANGE_DYE")),
|
||||
LANDING_OBSIDIAN_TEAR(Collections.singletonList("NETHERITE_BLOCK")),
|
||||
LARGE_SMOKE(Arrays.asList("COBWEB", "WEB")),
|
||||
LAVA(Collections.singletonList("MAGMA_CREAM")),
|
||||
MYCELIUM(Arrays.asList("MYCELIUM", "MYCEL")),
|
||||
NAUTILUS(Collections.singletonList("HEART_OF_THE_SEA")),
|
||||
NOTE(Collections.singletonList("NOTE_BLOCK"), ParticleProperty.REQUIRES_COLOR_DATA),
|
||||
POOF(Arrays.asList("FIREWORK_STAR", "FIREWORK_CHARGE")),
|
||||
PORTAL(Collections.singletonList("OBSIDIAN")),
|
||||
RAIN(Arrays.asList("PUFFERFISH_BUCKET", "LAPIS_BLOCK")),
|
||||
REVERSE_PORTAL(Collections.singletonList("FLINT_AND_STEEL")),
|
||||
SMOKE(Collections.singletonList("TORCH")),
|
||||
SNEEZE(Collections.singletonList("BAMBOO")),
|
||||
SOUL(Collections.singletonList("SOUL_LANTERN")),
|
||||
SOUL_FIRE_FLAME(Collections.singletonList("SOUL_CAMPFIRE")),
|
||||
SPELL(Arrays.asList("POTION", "GLASS_BOTTLE")), // The Minecraft internal name for this is actually "effect", but that's the command name, so it's SPELL for the plugin instead
|
||||
SPIT(Arrays.asList("LLAMA_SPAWN_EGG", "PUMPKIN_SEEDS")),
|
||||
SPLASH(Arrays.asList("SALMON", "FISH", "RAW_FISH")),
|
||||
SQUID_INK(Collections.singletonList("INK_SAC")),
|
||||
SWEEP_ATTACK(Arrays.asList("GOLDEN_SWORD", "GOLD_SWORD")),
|
||||
TOTEM_OF_UNDYING(Arrays.asList("TOTEM_OF_UNDYING", "TOTEM")),
|
||||
UNDERWATER(Arrays.asList("TURTLE_HELMET", "SPONGE")),
|
||||
WARPED_SPORE(Collections.singletonList("WARPED_FUNGUS")),
|
||||
WHITE_ASH(Collections.singletonList("BASALT")),
|
||||
WITCH(Collections.singletonList("CAULDRON"));
|
||||
|
||||
private List<ParticleProperty> properties;
|
||||
private List<String> defaultIconMaterialNames;
|
||||
|
||||
ParticleEffect(ParticleProperty... properties) {
|
||||
ParticleEffect(List<String> defaultIconMaterialNames, ParticleProperty... properties) {
|
||||
this.defaultIconMaterialNames = defaultIconMaterialNames;
|
||||
this.properties = Arrays.asList(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Material icon that represents this style in the GUI
|
||||
*/
|
||||
public List<String> getGuiIconMaterialNames() {
|
||||
return this.defaultIconMaterialNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this particle effect has a specific property
|
||||
*
|
||||
|
|
|
@ -21,11 +21,14 @@ dependencies {
|
|||
shadow 'me.clip:placeholderapi:2.10.4'
|
||||
shadow 'org.xerial:sqlite-jdbc:3.23.1'
|
||||
shadow 'com.comphenix.protocol:ProtocolLib:4.5.0'
|
||||
shadow 'com.googlecode.json-simple:json-simple:1.1.1'
|
||||
|
||||
// Dependencies that will be shaded into the jar
|
||||
implementation 'org.slf4j:slf4j-api:1.7.25'
|
||||
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
||||
implementation 'com.zaxxer:HikariCP:3.2.0'
|
||||
implementation 'org.bstats:bstats-bukkit-lite:1.7'
|
||||
implementation 'org.codemc.worldguardwrapper:worldguardwrapper:1.1.6-SNAPSHOT'
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
|
|
@ -3,14 +3,8 @@
|
|||
* + Add ability to create/manage fixed effects from the GUI
|
||||
* * Convert fixed effect ids into names
|
||||
*/
|
||||
|
||||
package dev.esophose.playerparticles;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
||||
import dev.esophose.playerparticles.gui.hook.PlayerChatHook;
|
||||
import dev.esophose.playerparticles.hook.ParticlePlaceholderExpansion;
|
||||
import dev.esophose.playerparticles.hook.PlaceholderAPIHook;
|
||||
|
@ -28,21 +22,15 @@ import dev.esophose.playerparticles.manager.PermissionManager;
|
|||
import dev.esophose.playerparticles.manager.PluginUpdateManager;
|
||||
import dev.esophose.playerparticles.particles.listener.PPlayerCombatListener;
|
||||
import dev.esophose.playerparticles.particles.listener.PPlayerMovementListener;
|
||||
import dev.esophose.playerparticles.util.Metrics;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.awt.Color;
|
||||
import dev.esophose.playerparticles.util.LegacyMetrics;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import net.minecraft.server.v1_15_R1.PacketDataSerializer;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutTitle;
|
||||
import org.bstats.bukkit.MetricsLite;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
/**
|
||||
* @author Esophose
|
||||
|
@ -69,6 +57,12 @@ public class PlayerParticles extends JavaPlugin {
|
|||
*/
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (!NMSUtil.isSpigot()) {
|
||||
this.getLogger().severe("This plugin is only compatible with Spigot and other forks. CraftBukkit is not supported. Disabling PlayerParticles.");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
|
||||
this.reload();
|
||||
|
||||
PluginManager pm = Bukkit.getPluginManager();
|
||||
|
@ -76,80 +70,16 @@ public class PlayerParticles extends JavaPlugin {
|
|||
pm.registerEvents(new PPlayerCombatListener(), this);
|
||||
pm.registerEvents(new PlayerChatHook(), this);
|
||||
|
||||
if (Setting.SEND_METRICS.getBoolean())
|
||||
new Metrics(this);
|
||||
if (Setting.SEND_METRICS.getBoolean()) {
|
||||
if (NMSUtil.getVersionNumber() > 7) {
|
||||
new MetricsLite(this, 3531);
|
||||
} else {
|
||||
new LegacyMetrics(this);
|
||||
}
|
||||
}
|
||||
|
||||
if (PlaceholderAPIHook.enabled())
|
||||
new ParticlePlaceholderExpansion(this).register();
|
||||
|
||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
new BukkitRunnable() {
|
||||
private LinkedList<String> queue = new LinkedList<>();
|
||||
private String message = "Snapshot 20w17a Chat Hex Code Colors!";
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (queue.size() >= message.length())
|
||||
queue.poll();
|
||||
|
||||
Color color = getRainbowColor();
|
||||
String hex = String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue());
|
||||
queue.add(hex);
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append("[");
|
||||
boolean isFirst = true;
|
||||
for (int i = 0; i < queue.size(); i++) {
|
||||
if (!isFirst)
|
||||
stringBuilder.append(",");
|
||||
isFirst = false;
|
||||
|
||||
stringBuilder.append("{");
|
||||
stringBuilder.append("\"color\":\"").append(queue.get(i)).append("\",");
|
||||
stringBuilder.append("\"text\":\"").append(message.charAt(i)).append("\"");
|
||||
stringBuilder.append("}");
|
||||
}
|
||||
stringBuilder.append("]");
|
||||
|
||||
PacketContainer timePacket = protocolManager.createPacket(PacketType.fromClass(PacketPlayOutTitle.class));
|
||||
timePacket.getTitleActions().write(0, TitleAction.TIMES);
|
||||
timePacket.getIntegers().write(0, 0).write(1, 20).write(2, 0);
|
||||
|
||||
PacketDataSerializer dataSerializer = new PacketDataSerializer(Unpooled.buffer());
|
||||
try {
|
||||
PacketPlayOutTitle titlePacket = new PacketPlayOutTitle() {
|
||||
@Override
|
||||
public void b(PacketDataSerializer var0) {
|
||||
var0.a(EnumTitleAction.TITLE);
|
||||
var0.a(stringBuilder.toString());
|
||||
}
|
||||
};
|
||||
titlePacket.b(dataSerializer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[dataSerializer.readableBytes()];
|
||||
dataSerializer.readBytes(bytes);
|
||||
|
||||
Bukkit.getOnlinePlayers().forEach(x -> {
|
||||
try {
|
||||
protocolManager.sendServerPacket(x, timePacket);
|
||||
protocolManager.sendWirePacket(x, 0x50, bytes);
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}.runTaskTimer(this, 0, 1);
|
||||
|
||||
PlayerChatHook.setup();
|
||||
}
|
||||
|
||||
private float hue = 0;
|
||||
private Color getRainbowColor() {
|
||||
this.hue = (this.hue + 4) % 362;
|
||||
return Color.getHSBColor(this.hue / 360F, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -180,16 +110,6 @@ public class PlayerParticles extends JavaPlugin {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file which contains this plugin
|
||||
* Exposes the JavaPlugin.getFile() method
|
||||
*
|
||||
* @return File containing this plugin
|
||||
*/
|
||||
public File getJarFile() {
|
||||
return this.getFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the plugin
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
package dev.esophose.playerparticles.api;
|
||||
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.manager.DataManager;
|
||||
import dev.esophose.playerparticles.manager.GuiManager;
|
||||
import dev.esophose.playerparticles.manager.ParticleManager;
|
||||
import dev.esophose.playerparticles.manager.ParticleStyleManager;
|
||||
import dev.esophose.playerparticles.particles.ConsolePPlayer;
|
||||
import dev.esophose.playerparticles.particles.FixedParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.ParticleGroup;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
@ -22,7 +21,9 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -51,12 +52,21 @@ public final class PlayerParticlesAPI {
|
|||
/**
|
||||
* @return the instance of the PlayerParticlesAPI
|
||||
*/
|
||||
@NotNull
|
||||
public static PlayerParticlesAPI getInstance() {
|
||||
if (INSTANCE == null)
|
||||
INSTANCE = new PlayerParticlesAPI();
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the currently installed version of the plugin
|
||||
*/
|
||||
@NotNull
|
||||
public String getVersion() {
|
||||
return this.playerParticles.getDescription().getVersion();
|
||||
}
|
||||
|
||||
//region Get PPlayer
|
||||
|
||||
/**
|
||||
|
@ -441,6 +451,7 @@ public final class PlayerParticlesAPI {
|
|||
* @param player The player to remove from
|
||||
* @return The number of particles removed or null if failed
|
||||
*/
|
||||
@Nullable
|
||||
public Integer resetActivePlayerParticles(@NotNull Player player) {
|
||||
DataManager dataManager = this.playerParticles.getManager(DataManager.class);
|
||||
PPlayer pplayer = this.getPPlayer(player);
|
||||
|
@ -453,6 +464,28 @@ public final class PlayerParticlesAPI {
|
|||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to reset the active particles for the given player name.
|
||||
* This works even if the player is offline.
|
||||
*
|
||||
* @param playerName The name of the player to reset the active particles for
|
||||
* @param successConsumer The callback to execute when finished
|
||||
*/
|
||||
public void resetActivePlayerParticles(@NotNull String playerName, @Nullable Consumer<Boolean> successConsumer) {
|
||||
Objects.requireNonNull(playerName);
|
||||
|
||||
if (successConsumer == null)
|
||||
successConsumer = success -> {};
|
||||
|
||||
Player player = Bukkit.getPlayer(playerName);
|
||||
if (player != null) {
|
||||
this.resetActivePlayerParticles(player);
|
||||
successConsumer.accept(true);
|
||||
} else {
|
||||
this.playerParticles.getManager(DataManager.class).resetActiveParticleGroup(playerName, successConsumer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all active particles from a player
|
||||
*
|
||||
|
@ -1033,30 +1066,4 @@ public final class PlayerParticlesAPI {
|
|||
|
||||
//endregion
|
||||
|
||||
//region Registering Custom Styles
|
||||
|
||||
/**
|
||||
* Registers a particle style with the plugin
|
||||
*
|
||||
* @param particleStyle The particle style to register
|
||||
*/
|
||||
public void registerParticleStyle(@NotNull ParticleStyle particleStyle) {
|
||||
Objects.requireNonNull(particleStyle);
|
||||
|
||||
this.playerParticles.getManager(ParticleStyleManager.class).registerStyle(particleStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an event-based particle style with the plugin
|
||||
*
|
||||
* @param particleStyle The particle style to register
|
||||
*/
|
||||
public void registerEventParticleStyle(@NotNull ParticleStyle particleStyle) {
|
||||
Objects.requireNonNull(particleStyle);
|
||||
|
||||
this.playerParticles.getManager(ParticleStyleManager.class).registerEventStyle(particleStyle);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ import dev.esophose.playerparticles.particles.ParticleGroup;
|
|||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.api.PlayerParticlesAPI;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import dev.esophose.playerparticles.util.StringPlaceholders;
|
||||
|
|
|
@ -10,8 +10,8 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.api.PlayerParticlesAPI;
|
||||
import dev.esophose.playerparticles.particles.ParticleProperty;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import dev.esophose.playerparticles.util.StringPlaceholders;
|
||||
|
|
|
@ -10,8 +10,8 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.api.PlayerParticlesAPI;
|
||||
import dev.esophose.playerparticles.particles.ParticleProperty;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import dev.esophose.playerparticles.util.StringPlaceholders;
|
||||
|
|
|
@ -8,6 +8,7 @@ import dev.esophose.playerparticles.particles.PPlayer;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class GUICommandModule implements CommandModule {
|
||||
|
||||
|
@ -45,7 +46,7 @@ public class GUICommandModule implements CommandModule {
|
|||
return;
|
||||
}
|
||||
|
||||
guiManager.openDefault(pplayer);
|
||||
Bukkit.getScheduler().runTask(PlayerParticles.getInstance(), () -> guiManager.openDefault(pplayer));
|
||||
}
|
||||
|
||||
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
|
||||
|
|
|
@ -55,7 +55,9 @@ public class RemoveCommandModule implements CommandModule {
|
|||
} else { // Removing by effect/style name
|
||||
ParticleEffect effect = particleManager.getEffectFromName(args[0]);
|
||||
ParticleStyle style = ParticleStyle.fromName(args[0]);
|
||||
|
||||
|
||||
boolean removed = false;
|
||||
|
||||
if (effect != null) {
|
||||
Set<Integer> toRemove = new HashSet<>();
|
||||
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
|
||||
|
@ -64,14 +66,18 @@ public class RemoveCommandModule implements CommandModule {
|
|||
toRemove.add(id);
|
||||
for (int id : toRemove)
|
||||
activeGroup.getParticles().remove(id);
|
||||
|
||||
|
||||
if (toRemove.size() > 0) {
|
||||
PlayerParticlesAPI.getInstance().savePlayerParticleGroup(pplayer.getPlayer(), activeGroup);
|
||||
localeManager.sendMessage(pplayer, "remove-effect-success", StringPlaceholders.builder("amount", toRemove.size()).addPlaceholder("effect", particleManager.getEffectSettings(effect).getName()).build());
|
||||
} else {
|
||||
removed = true;
|
||||
} else if (style == null) {
|
||||
localeManager.sendMessage(pplayer, "remove-effect-none", StringPlaceholders.single("effect", particleManager.getEffectSettings(effect).getName()));
|
||||
return;
|
||||
}
|
||||
} else if (style != null) {
|
||||
}
|
||||
|
||||
if (style != null) {
|
||||
Set<Integer> toRemove = new HashSet<>();
|
||||
ParticleGroup activeGroup = pplayer.getActiveParticleGroup();
|
||||
for (int id : activeGroup.getParticles().keySet())
|
||||
|
@ -79,15 +85,23 @@ public class RemoveCommandModule implements CommandModule {
|
|||
toRemove.add(id);
|
||||
for (int id : toRemove)
|
||||
activeGroup.getParticles().remove(id);
|
||||
|
||||
|
||||
if (toRemove.size() > 0) {
|
||||
PlayerParticlesAPI.getInstance().savePlayerParticleGroup(pplayer.getPlayer(), activeGroup);
|
||||
localeManager.sendMessage(pplayer, "remove-style-success", StringPlaceholders.builder("amount", toRemove.size()).addPlaceholder("style", style.getName()).build());
|
||||
} else {
|
||||
removed = true;
|
||||
} else if (effect == null) {
|
||||
localeManager.sendMessage(pplayer, "remove-style-none", StringPlaceholders.single("style", style.getName()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!removed) {
|
||||
if (effect != null && style != null) {
|
||||
localeManager.sendMessage(pplayer, "remove-effect-style-none", StringPlaceholders.single("name", style.getName()));
|
||||
} else {
|
||||
localeManager.sendMessage(pplayer, "remove-unknown", StringPlaceholders.single("name", args[0]));
|
||||
}
|
||||
} else {
|
||||
localeManager.sendMessage(pplayer, "remove-unknown", StringPlaceholders.single("name", args[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package dev.esophose.playerparticles.command;
|
||||
|
||||
import dev.esophose.playerparticles.manager.LocaleManager;
|
||||
import dev.esophose.playerparticles.manager.PermissionManager;
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.ParticleGroup;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
|
@ -8,16 +9,43 @@ import dev.esophose.playerparticles.api.PlayerParticlesAPI;
|
|||
import dev.esophose.playerparticles.util.StringPlaceholders;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
public class ResetCommandModule implements CommandModule {
|
||||
|
||||
public void onCommandExecute(PPlayer pplayer, String[] args) {
|
||||
int particleCount = pplayer.getActiveParticles().size();
|
||||
PlayerParticlesAPI.getInstance().savePlayerParticleGroup(pplayer.getPlayer(), ParticleGroup.getDefaultGroup());
|
||||
PlayerParticles.getInstance().getManager(LocaleManager.class).sendMessage(pplayer, "reset-success", StringPlaceholders.single("amount", particleCount));
|
||||
}
|
||||
LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class);
|
||||
|
||||
boolean isConsole = pplayer.getPlayer() == null;
|
||||
if (isConsole && args.length == 0) {
|
||||
localeManager.sendCustomMessage(Bukkit.getConsoleSender(), "&cOnly players can use this command. Did you mean to use '/pp reset [other]'?");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 0 || !PlayerParticles.getInstance().getManager(PermissionManager.class).canResetOthers(pplayer)) {
|
||||
Integer particleCount = PlayerParticlesAPI.getInstance().resetActivePlayerParticles(pplayer.getPlayer());
|
||||
if (particleCount != null)
|
||||
localeManager.sendMessage(pplayer, "reset-success", StringPlaceholders.single("amount", particleCount));
|
||||
} else {
|
||||
PlayerParticlesAPI.getInstance().resetActivePlayerParticles(args[0], success -> {
|
||||
if (success) {
|
||||
localeManager.sendMessage(pplayer, "reset-others-success", StringPlaceholders.single("other", args[0]));
|
||||
} else {
|
||||
localeManager.sendMessage(pplayer, "reset-others-none", StringPlaceholders.single("other", args[0]));
|
||||
}
|
||||
});
|
||||
}}
|
||||
|
||||
public List<String> onTabComplete(PPlayer pplayer, String[] args) {
|
||||
if (args.length == 1 && PlayerParticles.getInstance().getManager(PermissionManager.class).canResetOthers(pplayer)) {
|
||||
List<String> replacements = Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList());
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
StringUtil.copyPartialMatches(args[0], replacements, suggestions);
|
||||
return suggestions;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
@ -30,7 +58,7 @@ public class ResetCommandModule implements CommandModule {
|
|||
}
|
||||
|
||||
public String getArguments() {
|
||||
return "";
|
||||
return "[other]";
|
||||
}
|
||||
|
||||
public boolean requiresEffectsAndStyles() {
|
||||
|
@ -38,7 +66,7 @@ public class ResetCommandModule implements CommandModule {
|
|||
}
|
||||
|
||||
public boolean canConsoleExecute() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package dev.esophose.playerparticles.database;
|
|||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
@ -19,7 +20,7 @@ public class MySQLConnector implements DatabaseConnector {
|
|||
config.setJdbcUrl("jdbc:mysql://" + hostname + ":" + port + "/" + database + "?useSSL=" + useSSL);
|
||||
config.setUsername(username);
|
||||
config.setPassword(password);
|
||||
config.setMaximumPoolSize(2);
|
||||
config.setMaximumPoolSize(Setting.MYSQL_CONNECTION_POOL_SIZE.getInt());
|
||||
|
||||
try {
|
||||
this.hikari = new HikariDataSource(config);
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
package dev.esophose.playerparticles.event;
|
||||
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* An event that gets called during the PlayerParticles style registration
|
||||
*/
|
||||
public class ParticleStyleRegistrationEvent extends Event {
|
||||
|
||||
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||
|
||||
private Map<String, ParticleStyle> registeredStyles;
|
||||
private Map<String, ParticleStyle> registeredEventStyles;
|
||||
|
||||
public ParticleStyleRegistrationEvent() {
|
||||
this.registeredStyles = new HashMap<>();
|
||||
this.registeredEventStyles = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An unmodifiable map of registered styles keyed by the style internal name
|
||||
*/
|
||||
public Map<String, ParticleStyle> getRegisteredStyles() {
|
||||
return Collections.unmodifiableMap(this.registeredStyles);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An unmodifiable map of registered event styles keyed by the style internal name
|
||||
*/
|
||||
public Map<String, ParticleStyle> getRegisteredEventStyles() {
|
||||
return Collections.unmodifiableMap(this.registeredEventStyles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a ParticleStyle, overwriting any existing styles with the same name
|
||||
*
|
||||
* @param style The ParticleStyle to register
|
||||
* @return true if registered without replacing an existing style, false if an existing style was replaced
|
||||
*/
|
||||
public boolean registerStyle(ParticleStyle style) {
|
||||
if (this.registeredEventStyles.containsKey(style.getInternalName())) {
|
||||
this.registeredEventStyles.remove(style.getInternalName());
|
||||
this.registeredStyles.put(style.getInternalName(), style);
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.registeredStyles.put(style.getInternalName(), style) == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an event-based ParticleStyle, overwriting any existing styles with the same name.
|
||||
* Styles registered with this method bypass the normal update loop, and must instead be spawned manually.
|
||||
*
|
||||
* @param style The ParticleStyle to register
|
||||
* @return true if registered without replacing an existing style, false if an existing style was replaced
|
||||
*/
|
||||
public boolean registerEventStyle(ParticleStyle style) {
|
||||
if (this.registeredStyles.containsKey(style.getInternalName())) {
|
||||
this.registeredStyles.remove(style.getInternalName());
|
||||
this.registeredEventStyles.put(style.getInternalName(), style);
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.registeredEventStyles.put(style.getInternalName(), style) == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters a ParticleStyle
|
||||
*
|
||||
* @param internalName The internal name of the ParticleStyle to unregister
|
||||
* @return true if a style was unregistered, false otherwise
|
||||
*/
|
||||
public boolean unregisterStyle(String internalName) {
|
||||
return this.registeredStyles.remove(internalName) != null || this.registeredEventStyles.remove(internalName) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLER_LIST;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package dev.esophose.playerparticles.gui;
|
|||
import dev.esophose.playerparticles.gui.GuiInventoryEditData.ColorData;
|
||||
import dev.esophose.playerparticles.hook.PlaceholderAPIHook;
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.bukkit.ChatColor;
|
||||
|
@ -107,7 +108,9 @@ public class GuiActionButton {
|
|||
if (this.colors[0].getMaterial() != null) { // Use Materials
|
||||
itemStack = new ItemStack(this.colors[this.iconIndex].getMaterial());
|
||||
} else { // Use Dyes
|
||||
itemStack = new Dye(this.colors[this.iconIndex].getDyeColor()).toItemStack(1);
|
||||
Dye dye = new Dye();
|
||||
dye.setColor(this.colors[this.iconIndex].getDyeColor());
|
||||
itemStack = dye.toItemStack(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,7 +118,8 @@ public class GuiActionButton {
|
|||
if (itemMeta != null) {
|
||||
itemMeta.setDisplayName(PlaceholderAPIHook.applyPlaceholders(pplayer.getPlayer(), this.name));
|
||||
itemMeta.setLore(parseLore(pplayer, this.lore));
|
||||
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS);
|
||||
if (NMSUtil.getVersionNumber() > 7)
|
||||
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS);
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package dev.esophose.playerparticles.gui;
|
|||
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import java.util.ArrayList;
|
||||
|
@ -12,12 +13,11 @@ import org.bukkit.Sound;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
public abstract class GuiInventory implements InventoryHolder {
|
||||
public abstract class GuiInventory {
|
||||
|
||||
protected enum BorderColor {
|
||||
WHITE(0, "WHITE_STAINED_GLASS_PANE"),
|
||||
|
@ -57,7 +57,8 @@ public abstract class GuiInventory implements InventoryHolder {
|
|||
ItemMeta meta = borderIcon.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(" ");
|
||||
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_ENCHANTS);
|
||||
if (NMSUtil.getVersionNumber() > 7)
|
||||
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_ENCHANTS);
|
||||
borderIcon.setItemMeta(meta);
|
||||
}
|
||||
|
||||
|
@ -156,7 +157,11 @@ public abstract class GuiInventory implements InventoryHolder {
|
|||
button.handleClick(isShiftClick);
|
||||
if (Setting.GUI_BUTTON_SOUND.getBoolean() && event.getWhoClicked() instanceof Player) {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 0.5f, 1);
|
||||
if (NMSUtil.getVersionNumber() > 8) {
|
||||
player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 0.5f, 1);
|
||||
} else {
|
||||
player.playSound(player.getLocation(), Sound.valueOf("CLICK"), 0.5f, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import dev.esophose.playerparticles.particles.PPlayer;
|
|||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.particles.ParticleProperty;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import dev.esophose.playerparticles.util.StringPlaceholders;
|
||||
|
|
|
@ -40,7 +40,7 @@ public class GuiInventoryEditEffect extends GuiInventory {
|
|||
ParticleEffectSettings effectSettings = particleManager.getEffectSettings(effect);
|
||||
GuiActionButton selectButton = new GuiActionButton(
|
||||
slot,
|
||||
GuiIcon.EFFECT.get(effectSettings.getInternalName()),
|
||||
effectSettings.getGuiIconMaterial(),
|
||||
localeManager.getLocaleMessage("gui-color-icon-name") + ParticleUtils.formatName(effectSettings.getName()),
|
||||
new String[]{localeManager.getLocaleMessage("gui-color-info") + localeManager.getLocaleMessage("gui-select-effect-description", StringPlaceholders.single("effect", ParticleUtils.formatName(effectSettings.getName())))},
|
||||
(button, isShiftClick) -> {
|
||||
|
|
|
@ -36,7 +36,7 @@ public class GuiInventoryEditStyle extends GuiInventory {
|
|||
ParticleStyle style = stylesUserHasPermissionFor.get(i);
|
||||
GuiActionButton selectButton = new GuiActionButton(
|
||||
slot,
|
||||
GuiIcon.STYLE.get(style.getInternalName()),
|
||||
style.getGuiIconMaterial(),
|
||||
localeManager.getLocaleMessage("gui-color-icon-name") + ParticleUtils.formatName(style.getName()),
|
||||
new String[]{localeManager.getLocaleMessage("gui-color-info") + localeManager.getLocaleMessage("gui-select-style-description", StringPlaceholders.single("style", ParticleUtils.formatName(style.getName())))},
|
||||
(button, isShiftClick) -> {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package dev.esophose.playerparticles.gui.hook;
|
||||
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import dev.esophose.playerparticles.manager.LocaleManager;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import dev.esophose.playerparticles.util.StringPlaceholders;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
|
@ -25,7 +27,7 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
|
|||
* Initializes all the static values for this class
|
||||
*/
|
||||
public static void setup() {
|
||||
hooks = new HashSet<>();
|
||||
hooks = Collections.synchronizedSet(new HashSet<>());
|
||||
if (hookTask != null)
|
||||
hookTask.cancel();
|
||||
hookTask = new PlayerChatHook().runTaskTimer(PlayerParticles.getInstance(), 0, 20);
|
||||
|
@ -42,7 +44,7 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
|
|||
if (hook.getPlayerUUID().equals(event.getPlayer().getUniqueId())) {
|
||||
event.setCancelled(true);
|
||||
hooks.remove(hook);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(PlayerParticles.getInstance(), () -> hook.triggerCallback(event.getMessage()));
|
||||
hook.triggerCallback(event.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -53,30 +55,44 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
|
|||
*/
|
||||
public void run() {
|
||||
Set<PlayerChatHookData> hooksToRemove = new HashSet<>();
|
||||
|
||||
|
||||
for (PlayerChatHookData hook : hooks) {
|
||||
hook.decrementHookLength();
|
||||
if (hook.timedOut()) {
|
||||
hook.triggerCallback(null);
|
||||
hooksToRemove.add(hook);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Player player = Bukkit.getPlayer(hook.getPlayerUUID());
|
||||
if (player == null) {
|
||||
hooksToRemove.remove(hook);
|
||||
} else {
|
||||
LocaleManager localeManager = PlayerParticles.getInstance().getManager(LocaleManager.class);
|
||||
if (NMSUtil.getVersionNumber() == 9) {
|
||||
if (hook.getMaxHookLength() == hook.getTimeRemaining())
|
||||
player.sendMessage(localeManager.getLocaleMessage("gui-save-group-hotbar-message", StringPlaceholders.single("seconds", hook.getTimeRemaining())));
|
||||
String message = localeManager.getLocaleMessage("gui-save-group-hotbar-message", StringPlaceholders.single("seconds", hook.getTimeRemaining()));
|
||||
|
||||
if (NMSUtil.getVersionNumber() >= 11) {
|
||||
switch (Setting.GUI_GROUP_CREATION_MESSAGE_DISPLAY_AREA.getString().toUpperCase()) {
|
||||
case "ACTION_BAR":
|
||||
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(localeManager.getLocaleMessage("gui-save-group-hotbar-message", StringPlaceholders.single("seconds", hook.getTimeRemaining()))));
|
||||
break;
|
||||
case "TITLE":
|
||||
player.sendTitle("", message, 5, 40, 10);
|
||||
break;
|
||||
default:
|
||||
if (hook.getMaxHookLength() == hook.getTimeRemaining())
|
||||
player.sendMessage(message);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(localeManager.getLocaleMessage("gui-save-group-hotbar-message", StringPlaceholders.single("seconds", hook.getTimeRemaining()))));
|
||||
if (hook.getMaxHookLength() == hook.getTimeRemaining())
|
||||
player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
hook.decrementHookLength();
|
||||
}
|
||||
|
||||
for (PlayerChatHookData hookToRemove : hooksToRemove)
|
||||
|
||||
for (PlayerChatHookData hookToRemove : hooksToRemove)
|
||||
hooks.remove(hookToRemove);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ public class ParticlePlaceholderExpansion extends PlaceholderExpansion {
|
|||
return String.valueOf(pplayer.isMoving());
|
||||
case "is_in_combat":
|
||||
return String.valueOf(pplayer.isInCombat());
|
||||
case "is_in_allowed_region":
|
||||
return String.valueOf(pplayer.isInAllowedRegion());
|
||||
case "can_see_particles":
|
||||
return String.valueOf(pplayer.canSeeParticles());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package dev.esophose.playerparticles.hook;
|
||||
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.codemc.worldguardwrapper.WorldGuardWrapper;
|
||||
import org.codemc.worldguardwrapper.region.IWrappedRegion;
|
||||
|
||||
public class WorldGuardHook {
|
||||
|
||||
private static Boolean enabled;
|
||||
private static WorldGuardWrapper worldGuardWrapper;
|
||||
|
||||
/**
|
||||
* @return true if WorldGuard is enabled, otherwise false
|
||||
*/
|
||||
public static boolean enabled() {
|
||||
if (enabled != null)
|
||||
return enabled;
|
||||
|
||||
enabled = Bukkit.getPluginManager().getPlugin("WorldGuard") != null;
|
||||
if (enabled)
|
||||
worldGuardWrapper = WorldGuardWrapper.getInstance();
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a location is in a region that allows particles to spawn
|
||||
*
|
||||
* @param location The location to check
|
||||
* @return true if the location is in an allowed region, otherwise false
|
||||
*/
|
||||
public static boolean isInAllowedRegion(Location location) {
|
||||
if (!enabled())
|
||||
return true;
|
||||
|
||||
Set<IWrappedRegion> regions = worldGuardWrapper.getRegions(location);
|
||||
|
||||
List<String> disallowedRegionIds = Setting.WORLDGUARD_DISALLOWED_REGIONS.getStringList();
|
||||
if (regions.stream().map(IWrappedRegion::getId).anyMatch(disallowedRegionIds::contains))
|
||||
return false;
|
||||
|
||||
if (Setting.WORLDGUARD_USE_ALLOWED_REGIONS.getBoolean()) {
|
||||
List<String> allowedRegionIds = Setting.WORLDGUARD_ALLOWED_REGIONS.getStringList();
|
||||
return regions.stream().map(IWrappedRegion::getId).anyMatch(allowedRegionIds::contains);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -118,6 +118,7 @@ public class EnglishLocale implements Locale {
|
|||
this.put("remove-effect-none", "&cYou do not have any particles applied with the effect &b%effect%&c!");
|
||||
this.put("remove-style-success", "&aRemoved &b%amount% &aof your particles with the style of &b%style%&a!");
|
||||
this.put("remove-style-none", "&cYou do not have any particles applied with the style &b%style%&c!");
|
||||
this.put("remove-effect-style-none", "&cYou do not have any particles applied with the effect or style &b%name%&c!");
|
||||
this.put("remove-unknown", "&cAn effect or style with the name of &b%name% &cdoes not exist!");
|
||||
|
||||
this.put("#10", "List Messages");
|
||||
|
@ -166,6 +167,8 @@ public class EnglishLocale implements Locale {
|
|||
|
||||
this.put("#17", "Reset Message");
|
||||
this.put("reset-success", "&aRemoved &b%amount% &aactive particle(s)!");
|
||||
this.put("reset-others-success", "&aRemoved particles for &b%other%&a!");
|
||||
this.put("reset-others-none", "&eNo particles were removed for &b%other%&e.");
|
||||
|
||||
this.put("#18", "Fixed Create Messages");
|
||||
this.put("fixed-create-missing-args", "&cUnable to create fixed effect, you are missing &b%amount% &crequired arguments!");
|
||||
|
|
|
@ -118,6 +118,7 @@ public class FrenchLocale implements Locale {
|
|||
this.put("remove-effect-none", "&cVous n'avez pas de particules appliquées avec l'effet &b%effect% &c!");
|
||||
this.put("remove-style-success", "&aSuppression &b%amount% &ade votre particule avec le style &b%style% &a!");
|
||||
this.put("remove-style-none", "&cVous n'avez pas de particules appliquées avec le style &b%style% &c!");
|
||||
this.put("remove-effect-style-none", "&cVous n'avez pas de particules appliquées avec l'effet ou le style &b%name% &c!");
|
||||
this.put("remove-unknown", "&cL'effect avec le nom ou le style &b%name% &cn'existe pas !");
|
||||
|
||||
this.put("#10", "List Messages");
|
||||
|
@ -166,6 +167,8 @@ public class FrenchLocale implements Locale {
|
|||
|
||||
this.put("#17", "Reset Message");
|
||||
this.put("reset-success", "&b%amount% &aparticule(s) actives supprimées !");
|
||||
this.put("reset-others-success", "&aParticules enlevées pour &b%other%&a !");
|
||||
this.put("reset-others-none", "&eAucune particule n'a été enlevée pour &b%other%&e.");
|
||||
|
||||
this.put("#18", "Fixed Create Messages");
|
||||
this.put("fixed-create-missing-args", "&cImpossible de créer un effet fixe, vous oubliez des arguments : &b%amount%");
|
||||
|
|
|
@ -118,6 +118,7 @@ public class GermanLocale implements Locale {
|
|||
this.put("remove-effect-none", "&cSie haben keine Partikel mit dem Effekt &b%effect%&cangelegt!");
|
||||
this.put("remove-style-success", "&b%amount% &adeiner Partikel im Stil von &b%style% &aentfernt!");
|
||||
this.put("remove-style-none", "&cSie haben keine Partikel mit dem Stil &b%style%&cangelegt!");
|
||||
this.put("remove-effect-style-none", "&cSie haben keine Partikel mit der Wirkung oder dem Stil &b%name% &cangewendet!");
|
||||
this.put("remove-unknown", "&cEs existiert kein Effekt oder Stil mit dem Namen &b%name%&c!");
|
||||
|
||||
this.put("#10", "List Messages");
|
||||
|
@ -166,6 +167,8 @@ public class GermanLocale implements Locale {
|
|||
|
||||
this.put("#17", "Reset Message");
|
||||
this.put("reset-success", "&b%amount% &aaktive Partikel entfernt!");
|
||||
this.put("reset-others-success", "&aEntfertigte Partikel für &b%other%&a!");
|
||||
this.put("reset-others-none", "&eFür &b%other%&e wurden keine Partikel entfernt.");
|
||||
|
||||
this.put("#18", "Fixed Create Messages");
|
||||
this.put("fixed-create-missing-args", "&cFixer Effekt kann nicht erstellt werden, es fehlen &b%amount% &cerforderliche Argumente!");
|
||||
|
@ -240,6 +243,7 @@ public class GermanLocale implements Locale {
|
|||
this.put("gui-color-icon-name", "&a");
|
||||
this.put("gui-color-info", "&e");
|
||||
this.put("gui-color-subtext", "&b");
|
||||
this.put("gui-color-unavailable", "&c");
|
||||
|
||||
this.put("#28", "GUI Info Messages");
|
||||
this.put("gui-commands-info", "Informationen zu Befehlen finden Sie mit Hilfe von &b/pp help");
|
||||
|
|
|
@ -118,6 +118,7 @@ public class RussianLocale implements Locale {
|
|||
this.put("remove-effect-none", "&cУ Вас нет каких-либо частиц с эффектом &b%effect%&c!");
|
||||
this.put("remove-style-success", "&aКоличество удалённых частиц - &b%amount% &a, стилей - &b%style%&a!");
|
||||
this.put("remove-style-none", "&cУ Вас нет каких-либо частиц со стилем &b%style%&c!");
|
||||
this.put("remove-effect-style-none", "&cУ вас нет никаких частиц с эффектом или стилем &b%name%&c!");
|
||||
this.put("remove-unknown", "&cЭффект или стиль под названием &b%name% &cне существует!");
|
||||
|
||||
this.put("#10", "List Messages");
|
||||
|
@ -166,6 +167,8 @@ public class RussianLocale implements Locale {
|
|||
|
||||
this.put("#17", "Reset Message");
|
||||
this.put("reset-success", "&aУдалено &aактивных частиц - &b%amount%!");
|
||||
this.put("reset-others-success", "&aУдаленные частицы для &b%other%&a!");
|
||||
this.put("reset-others-none", "&eНикакие частицы не были удалены для &b%other% &e.");
|
||||
|
||||
this.put("#18", "Fixed Create Messages");
|
||||
this.put("fixed-create-missing-args", "&cНевозможно создать эффект, не введено запрашиваемых аргументов - &b%amount%!");
|
||||
|
|
|
@ -118,6 +118,7 @@ public class SimplifiedChineseLocale implements Locale {
|
|||
this.put("remove-effect-none", "&c你没有使用特效&b%effect%&c的粒子!");
|
||||
this.put("remove-style-success", "&已成功删除&b%amount%&a个使用了风格&b%style%&a的粒子!");
|
||||
this.put("remove-style-none", "&c你没有已使用风格&b%style%&c的粒子!");
|
||||
this.put("remove-effect-style-none", "&c您没有应用任何颗粒效果或样式&b%name%&c!");
|
||||
this.put("remove-unknown", "&c名为&b%name%&c的特效或风格不存在!");
|
||||
|
||||
this.put("#10", "List Messages");
|
||||
|
@ -166,6 +167,8 @@ public class SimplifiedChineseLocale implements Locale {
|
|||
|
||||
this.put("#17", "Reset Message");
|
||||
this.put("reset-success", "&a已删除&b%amount%个&a激活的粒子特效!");
|
||||
this.put("reset-others-success", "&a已删除&b%other%&a的颗粒!");
|
||||
this.put("reset-others-none", "&e没有除去&b%other%&e的颗粒.");
|
||||
|
||||
this.put("#18", "Fixed Create Messages");
|
||||
this.put("fixed-create-missing-args", "&c无法创建定点特效, 缺少 &b%amount% &c必要参数!");
|
||||
|
@ -243,7 +246,7 @@ public class SimplifiedChineseLocale implements Locale {
|
|||
this.put("gui-color-unavailable", "&c");
|
||||
|
||||
this.put("#28", "GUI Info Messages");
|
||||
this.put("gui-commands-info", "商人 &b/pp help 查看指令帮助");
|
||||
this.put("gui-commands-info", "输入 &b/pp help 查看指令帮助");
|
||||
this.put("gui-back-button", "返回");
|
||||
this.put("gui-next-page-button", "下一页 (%start%/%end%)");
|
||||
this.put("gui-previous-page-button", "上一页 (%start%/%end%)");
|
||||
|
|
|
@ -118,6 +118,7 @@ public class VietnameseLocale implements Locale {
|
|||
this.put("remove-effect-none", "&cBạn không có bất kì Hạt hiệu ứng nào để áp dụng hiệu ứng &b%effect%&c!");
|
||||
this.put("remove-style-success", "&aĐã xóa &b%amount% &aHạt hiệu ứng của bạn với style &b%style%&a!");
|
||||
this.put("remove-style-none", "&cBạn không có bất kì Hạt hiệu ứng nào để áp dụng style &b%style%&c!");
|
||||
this.put("remove-effect-style-none", "&cBạn không có bất kỳ hạt nào được áp dụng với hiệu ứng hoặc kiểu %name%&c!");
|
||||
this.put("remove-unknown", "&cEffect hoặc Style với tên &b%name% &ckhông tồn tại!");
|
||||
|
||||
this.put("#10", "List Messages");
|
||||
|
@ -166,6 +167,8 @@ public class VietnameseLocale implements Locale {
|
|||
|
||||
this.put("#17", "Reset Message");
|
||||
this.put("reset-success", "&aĐã xóa &b%amount% &aHạt hiệu ứng hoạt động!");
|
||||
this.put("reset-others-success", "&aCác hạt bị loại bỏ cho &b%other%&a!");
|
||||
this.put("reset-others-none", "&eKhông có hạt nào được loại bỏ cho &b%other%&e.");
|
||||
|
||||
this.put("#18", "Fixed Create Messages");
|
||||
this.put("fixed-create-missing-args", "&cKhông thể tạo Hiệu ứng cố định, bạn đã quên &b%amount% &cđối số yêu cầu!");
|
||||
|
|
|
@ -26,8 +26,8 @@ import dev.esophose.playerparticles.command.WorldsCommandModule;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
|
|
@ -16,11 +16,11 @@ import org.bukkit.Material;
|
|||
public class ConfigurationManager extends Manager {
|
||||
|
||||
private static final String[] HEADER = new String[] {
|
||||
" _________ __ __________ __ __ __ _________",
|
||||
" \\______ \\ | _____ ___ __ __________\\______ \\_____ ________/ |_|__| ____ | | ____ ______ \\______ \\",
|
||||
" | ___/ | \\__ \\< | |/ __ \\_ __ \\ ___/\\__ \\\\_ __ \\ __\\ |/ ___\\| | _/ __ \\ / ___/ / /",
|
||||
" | | | |__/ __ \\\\___ \\ ___/| | \\/ | / __ \\| | \\/| | | \\ \\___| |_\\ ___/ \\___ \\ / /",
|
||||
" |____| |____(____ / ____|\\___ >__| |____| (____ /__| |__| |__|\\___ >____/\\___ >____ > /____/",
|
||||
" _________ __ __________ __ __ __",
|
||||
" \\______ \\ | _____ ___ __ __________\\______ \\_____ ________/ |_|__| ____ | | ____ ______",
|
||||
" | ___/ | \\__ \\< | |/ __ \\_ __ \\ ___/\\__ \\\\_ __ \\ __\\ |/ ___\\| | _/ __ \\ / ___/",
|
||||
" | | | |__/ __ \\\\___ \\ ___/| | \\/ | / __ \\| | \\/| | | \\ \\___| |_\\ ___/ \\___ \\",
|
||||
" |____| |____(____ / ____|\\___ >__| |____| (____ /__| |__| |__|\\___ >____/\\___ >____ >",
|
||||
" \\/\\/ \\/ \\/ \\/ \\/ \\/"
|
||||
};
|
||||
|
||||
|
@ -41,9 +41,9 @@ public class ConfigurationManager extends Manager {
|
|||
GUI_PRESETS_ONLY("gui-presets-only", false, "If true, only the preset groups will be available in the GUI", "Permissions to open the GUI will change to only open if the user has any preset groups available"),
|
||||
GUI_CLOSE_AFTER_GROUP_SELECTED("gui-close-after-group-selected", true, "If true, the GUI will close after selecting a group (either saved or preset)"),
|
||||
GUI_BUTTON_SOUND("gui-button-sound", true, "If clicking a GUI button should make a noise"),
|
||||
TOGGLE_ON_MOVE("toggle-on-move", false, "If true, styles will not display while the player is moving", "They will instead have the effect displayed at their feet", "Note: Not all styles abide by this rule, but most will"),
|
||||
TOGGLE_ON_MOVE("toggle-on-move", "NONE", "Valid values: DISPLAY_FEET, DISPLAY_NORMAL, DISPLAY_OVERHEAD, HIDE, NONE", "DISPLAY_FEET will display particles using the feet style while moving", "DISPLAY_NORMAL will display particles using the normal style while moving", "DISPLAY_OVERHEAD will display particles using the overhead style while moving", "HIDE will hide particles while moving", "NONE will make this setting do nothing", "Note: You can change what styles follow this setting in their individual setting files"),
|
||||
TOGGLE_ON_MOVE_DELAY("toggle-on-move-delay", 9, "The time (in ticks) a player has to be standing still before they are considered to be stopped", "This setting has no effect if toggle-on-move is set to false", "The value must be a positive whole number"),
|
||||
TOGGLE_ON_COMBAT("toggle-on-combat", false, "If true, particles will be completely disabled while the player is in combat"),
|
||||
TOGGLE_ON_COMBAT("toggle-on-combat", false, "If true, particles will be completely disabled while the player is in combat", "Note: You can change what styles follow this setting in their individual setting files"),
|
||||
TOGGLE_ON_COMBAT_DELAY("toggle-on-combat-delay", 15, "The time (in seconds) a player has to not be damaged/attacked to be considered out of combat", "This setting has no effect if toggle-on-combat is set to false", "The value must be a positive whole number"),
|
||||
DISABLED_WORLDS("disabled-worlds", Collections.singletonList("disabled_world_name"), "A list of worlds that the plugin is disabled in"),
|
||||
MAX_PARTICLES("max-particles", 3, "The maximum number of particles a player can apply at once", "The GUI will only display up to 21, don't set this any higher than that"),
|
||||
|
@ -55,7 +55,17 @@ public class ConfigurationManager extends Manager {
|
|||
PARTICLE_RENDER_RANGE_FIXED_EFFECT("particle-render-range-fixed-effect", 192, "From how many blocks away should a player be able to see the particles from a fixed effect?"),
|
||||
RAINBOW_CYCLE_SPEED("rainbow-cycle-speed", 2, "How many out of 360 hue ticks to move per game tick", "Higher values make the rainbow cycle faster", "Note: Must be a positive whole number"),
|
||||
DUST_SIZE("dust-size", 1.0, "How large should dust particles appear?", "Note: Can include decimals", "Only works in 1.13+"),
|
||||
GUI_GROUP_CREATION_MESSAGE_DISPLAY_AREA("gui-group-creation-message-display-area", "ACTION_BAR", "Valid values: ACTION_BAR, TITLE, CHAT", "Where should the GUI group creation countdown message be displayed?", "Note: Server versions less than 1.11.2 will always use CHAT"),
|
||||
|
||||
OVERRIDE_PARTICLE_VERSION("override-particle-version", -1, "Allows you to override the version of Minecraft that will be assumed for spawning particles", "This should follow this format: 9, 12, 15, etc. 9 means 1.9, 14 means 1.14... and so on"),
|
||||
|
||||
WORLDGUARD_SETTINGS("worldguard-settings", null, "Settings for WorldGuard", "If WorldGuard is not installed, these settings will do nothing"),
|
||||
WORLDGUARD_USE_ALLOWED_REGIONS("worldguard-settings.use-allowed-regions", false, "If true, particles will only be able to spawn if they are in an allowed region and not a disallowed region", "If false, particles will be able to spawn as long as they are not in a disallowed region"),
|
||||
WORLDGUARD_ALLOWED_REGIONS("worldguard-settings.allowed-regions", Arrays.asList("example_region_1", "example_region_2"), "Regions that particles will be allowed to spawn in"),
|
||||
WORLDGUARD_DISALLOWED_REGIONS("worldguard-settings.disallowed-regions", Arrays.asList("example_region_3", "example_region_4"), "Regions that particles will be blocked from spawning in", "This overrides allowed regions if they overlap"),
|
||||
WORLDGUARD_CHECK_INTERVAL("worldguard-settings.check-interval", 10, "How often to check if a player is in a region that allows spawning particles", "Measured in ticks"),
|
||||
WORLDGUARD_ENABLE_BYPASS_PERMISSION("worldguard-settings.enable-bypass-permission", false, "If true, the permission playerparticles.worldguard.bypass will allow", "the player to bypass the region requirements"),
|
||||
|
||||
MYSQL_SETTINGS("mysql-settings", null, "Settings for if you want to use MySQL for data management"),
|
||||
MYSQL_ENABLED("mysql-settings.enabled", false, "Enable MySQL", "If false, SQLite will be used instead"),
|
||||
MYSQL_HOSTNAME("mysql-settings.hostname", "", "MySQL Database Hostname"),
|
||||
|
@ -63,14 +73,16 @@ public class ConfigurationManager extends Manager {
|
|||
MYSQL_DATABASE_NAME("mysql-settings.database-name", "", "MySQL Database Name"),
|
||||
MYSQL_USER_NAME("mysql-settings.user-name", "", "MySQL Database User Name"),
|
||||
MYSQL_USER_PASSWORD("mysql-settings.user-password", "", "MySQL Database User Password"),
|
||||
MYSQL_TABLE_PREFIX("mysql-settings.table-prefix", PlayerParticles.getInstance().getDescription().getName().toLowerCase() + "_", "The prefix of the tables in the database", "Do not change this after tables have already been created or you will have data loss"),
|
||||
MYSQL_USE_SSL("mysql-settings.use-ssl", false, "If the database connection should use SSL", "You should enable this if your database supports SSL"),
|
||||
MYSQL_CONNECTION_POOL_SIZE("mysql-settings.connection-pool-size", 5, "The size of the connection pool to the database", "Not recommended to go below 2 or above 5"),
|
||||
|
||||
GUI_ICON("gui-icon", null,
|
||||
"This configuration option allows you to change any of the GUI",
|
||||
"icons to whatever block/item you want.",
|
||||
"This configuration option allows you to change the GUI",
|
||||
"icons to whatever block/item you want. If you want to change an effect",
|
||||
"or style icon, use their respective config files.",
|
||||
"Notes: If any of the block/item names are invalid the icon in the GUI",
|
||||
"will be the barrier icon to show that it failed to load.",
|
||||
"Do NOT change the particle/style name",
|
||||
"You MUST use the Spigot-given name for it to work. You can see",
|
||||
"all the Spigot-given names at the link below:",
|
||||
"https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html",
|
||||
|
@ -87,105 +99,7 @@ public class ConfigurationManager extends Manager {
|
|||
GUI_ICON_MISC_EDIT_EFFECT("gui-icon.misc.edit_effect", Arrays.asList("FIREWORK_ROCKET", "FIREWORK")),
|
||||
GUI_ICON_MISC_EDIT_STYLE("gui-icon.misc.edit_style", Collections.singletonList("NETHER_STAR")),
|
||||
GUI_ICON_MISC_EDIT_DATA("gui-icon.misc.edit_data", Collections.singletonList("BOOK")),
|
||||
GUI_ICON_MISC_RESET("gui-icon.misc.reset", Collections.singletonList("BARRIER")),
|
||||
GUI_ICON_EFFECT("gui-icon.effect", null),
|
||||
GUI_ICON_EFFECT_AMBIENT_ENTITY_EFFECT("gui-icon.effect.ambient_entity_effect", Collections.singletonList("BEACON")),
|
||||
GUI_ICON_EFFECT_ANGRY_VILLAGER("gui-icon.effect.angry_villager", Collections.singletonList("IRON_DOOR")),
|
||||
GUI_ICON_EFFECT_BARRIER("gui-icon.effect.barrier", Collections.singletonList("BARRIER")),
|
||||
GUI_ICON_EFFECT_BLOCK("gui-icon.effect.block", Collections.singletonList("STONE")),
|
||||
GUI_ICON_EFFECT_BUBBLE("gui-icon.effect.bubble", Arrays.asList("BUBBLE_CORAL", "GLASS")),
|
||||
GUI_ICON_EFFECT_BUBBLE_COLUMN_UP("gui-icon.effect.bubble_column_up", Collections.singletonList("MAGMA_BLOCK")),
|
||||
GUI_ICON_EFFECT_BUBBLE_POP("gui-icon.effect.bubble_pop", Collections.singletonList("BUBBLE_CORAL_FAN")),
|
||||
GUI_ICON_EFFECT_CAMPFIRE_COSY_SMOKE("gui-icon.effect.campfire_cosy_smoke", Collections.singletonList("CAMPFIRE")),
|
||||
GUI_ICON_EFFECT_CAMPFIRE_SIGNAL_SMOKE("gui-icon.effect.campfire_signal_smoke", Collections.singletonList("REDSTONE_TORCH")),
|
||||
GUI_ICON_EFFECT_CLOUD("gui-icon.effect.cloud", Arrays.asList("WHITE_WOOL", "WOOL")),
|
||||
GUI_ICON_EFFECT_COMPOSTER("gui-icon.effect.composter", Collections.singletonList("COMPOSTER")),
|
||||
GUI_ICON_EFFECT_CRIT("gui-icon.effect.crit", Collections.singletonList("IRON_SWORD")),
|
||||
GUI_ICON_EFFECT_CURRENT_DOWN("gui-icon.effect.current_down", Collections.singletonList("SOUL_SAND")),
|
||||
GUI_ICON_EFFECT_DAMAGE_INDICATOR("gui-icon.effect.damage_indicator", Collections.singletonList("BOW")),
|
||||
GUI_ICON_EFFECT_DOLPHIN("gui-icon.effect.dolphin", Collections.singletonList("DOLPHIN_SPAWN_EGG")),
|
||||
GUI_ICON_EFFECT_DRAGON_BREATH("gui-icon.effect.dragon_breath", Arrays.asList("DRAGON_BREATH", "DRAGONS_BREATH")),
|
||||
GUI_ICON_EFFECT_DRIPPING_HONEY("gui-icon.effect.dripping_honey", Collections.singletonList("BEE_NEST")),
|
||||
GUI_ICON_EFFECT_DRIPPING_LAVA("gui-icon.effect.dripping_lava", Collections.singletonList("LAVA_BUCKET")),
|
||||
GUI_ICON_EFFECT_DRIPPING_WATER("gui-icon.effect.dripping_water", Collections.singletonList("WATER_BUCKET")),
|
||||
GUI_ICON_EFFECT_DUST("gui-icon.effect.dust", Collections.singletonList("REDSTONE")),
|
||||
GUI_ICON_EFFECT_ELDER_GUARDIAN("gui-icon.effect.elder_guardian", Arrays.asList("ELDER_GUARDIAN_SPAWN_EGG", "PRISMARINE_CRYSTALS")),
|
||||
GUI_ICON_EFFECT_ENCHANT("gui-icon.effect.enchant", Arrays.asList("ENCHANTING_TABLE", "ENCHANTMENT_TABLE")),
|
||||
GUI_ICON_EFFECT_ENCHANTED_HIT("gui-icon.effect.enchanted_hit", Collections.singletonList("DIAMOND_SWORD")),
|
||||
GUI_ICON_EFFECT_END_ROD("gui-icon.effect.end_rod", Collections.singletonList("END_ROD")),
|
||||
GUI_ICON_EFFECT_ENTITY_EFFECT("gui-icon.effect.entity_effect", Collections.singletonList("GLOWSTONE_DUST")),
|
||||
GUI_ICON_EFFECT_EXPLOSION("gui-icon.effect.explosion", Arrays.asList("FIRE_CHARGE", "FIREBALL")),
|
||||
GUI_ICON_EFFECT_EXPLOSION_EMITTER("gui-icon.effect.explosion_emitter", Collections.singletonList("TNT")),
|
||||
GUI_ICON_EFFECT_FALLING_DUST("gui-icon.effect.falling_dust", Collections.singletonList("SAND")),
|
||||
GUI_ICON_EFFECT_FALLING_HONEY("gui-icon.effect.falling_honey", Collections.singletonList("HONEY_BOTTLE")),
|
||||
GUI_ICON_EFFECT_FALLING_LAVA("gui-icon.effect.falling_lava", Collections.singletonList("RED_DYE")),
|
||||
GUI_ICON_EFFECT_FALLING_NECTAR("gui-icon.effect.falling_nectar", Collections.singletonList("HONEYCOMB")),
|
||||
GUI_ICON_EFFECT_FALLING_WATER("gui-icon.effect.falling_water", Collections.singletonList("BLUE_DYE")),
|
||||
GUI_ICON_EFFECT_FIREWORK("gui-icon.effect.firework", Arrays.asList("FIREWORK_ROCKET", "FIREWORK")),
|
||||
GUI_ICON_EFFECT_FISHING("gui-icon.effect.fishing", Collections.singletonList("FISHING_ROD")),
|
||||
GUI_ICON_EFFECT_FLAME("gui-icon.effect.flame", Collections.singletonList("BLAZE_POWDER")),
|
||||
GUI_ICON_EFFECT_FLASH("gui-icon.effect.flash", Collections.singletonList("GOLD_INGOT")),
|
||||
GUI_ICON_EFFECT_FOOTSTEP("gui-icon.effect.footstep", Collections.singletonList("GRASS")),
|
||||
GUI_ICON_EFFECT_HAPPY_VILLAGER("gui-icon.effect.happy_villager", Arrays.asList("DARK_OAK_DOOR_ITEM", "DARK_OAK_DOOR")),
|
||||
GUI_ICON_EFFECT_HEART("gui-icon.effect.heart", Arrays.asList("POPPY", "RED_ROSE")),
|
||||
GUI_ICON_EFFECT_INSTANT_EFFECT("gui-icon.effect.instant_effect", Arrays.asList("SPLASH_POTION", "POTION")),
|
||||
GUI_ICON_EFFECT_ITEM("gui-icon.effect.item", Collections.singletonList("ITEM_FRAME")),
|
||||
GUI_ICON_EFFECT_ITEM_SLIME("gui-icon.effect.item_slime", Collections.singletonList("SLIME_BALL")),
|
||||
GUI_ICON_EFFECT_ITEM_SNOWBALL("gui-icon.effect.item_snowball", Arrays.asList("SNOWBALL", "SNOW_BALL")),
|
||||
GUI_ICON_EFFECT_LARGE_SMOKE("gui-icon.effect.large_smoke", Arrays.asList("COBWEB", "WEB")),
|
||||
GUI_ICON_EFFECT_LANDING_HONEY("gui-icon.effect.landing_honey", Collections.singletonList("HONEY_BLOCK")),
|
||||
GUI_ICON_EFFECT_LANDING_LAVA("gui-icon.effect.landing_lava", Collections.singletonList("ORANGE_DYE")),
|
||||
GUI_ICON_EFFECT_LAVA("gui-icon.effect.lava", Collections.singletonList("MAGMA_CREAM")),
|
||||
GUI_ICON_EFFECT_MYCELIUM("gui-icon.effect.mycelium", Arrays.asList("MYCELIUM", "MYCEL")),
|
||||
GUI_ICON_EFFECT_NAUTILUS("gui-icon.effect.nautilus", Collections.singletonList("HEART_OF_THE_SEA")),
|
||||
GUI_ICON_EFFECT_NOTE("gui-icon.effect.note", Collections.singletonList("NOTE_BLOCK")),
|
||||
GUI_ICON_EFFECT_POOF("gui-icon.effect.poof", Arrays.asList("FIREWORK_STAR", "FIREWORK_CHARGE")),
|
||||
GUI_ICON_EFFECT_PORTAL("gui-icon.effect.portal", Collections.singletonList("OBSIDIAN")),
|
||||
GUI_ICON_EFFECT_RAIN("gui-icon.effect.rain", Arrays.asList("PUFFERFISH_BUCKET", "LAPIS_BLOCK")),
|
||||
GUI_ICON_EFFECT_SMOKE("gui-icon.effect.smoke", Collections.singletonList("TORCH")),
|
||||
GUI_ICON_EFFECT_SNEEZE("gui-icon.effect.sneeze", Collections.singletonList("BAMBOO")),
|
||||
GUI_ICON_EFFECT_SPELL("gui-icon.effect.spell", Arrays.asList("POTION", "GLASS_BOTTLE")),
|
||||
GUI_ICON_EFFECT_SPIT("gui-icon.effect.spit", Arrays.asList("LLAMA_SPAWN_EGG", "PUMPKIN_SEEDS")),
|
||||
GUI_ICON_EFFECT_SPLASH("gui-icon.effect.splash", Arrays.asList("SALMON", "FISH", "RAW_FISH")),
|
||||
GUI_ICON_EFFECT_SQUID_INK("gui-icon.effect.squid_ink", Collections.singletonList("INK_SAC")),
|
||||
GUI_ICON_EFFECT_SWEEP_ATTACK("gui-icon.effect.sweep_attack", Arrays.asList("GOLDEN_SWORD", "GOLD_SWORD")),
|
||||
GUI_ICON_EFFECT_TOTEM_OF_UNDYING("gui-icon.effect.totem_of_undying", Arrays.asList("TOTEM_OF_UNDYING", "TOTEM")),
|
||||
GUI_ICON_EFFECT_UNDERWATER("gui-icon.effect.underwater", Arrays.asList("TURTLE_HELMET", "SPONGE")),
|
||||
GUI_ICON_EFFECT_WITCH("gui-icon.effect.witch", Collections.singletonList("CAULDRON")),
|
||||
GUI_ICON_STYLE("gui-icon.style", null),
|
||||
GUI_ICON_STYLE_ARROWS("gui-icon.style.arrows", Collections.singletonList("BOW")),
|
||||
GUI_ICON_STYLE_BATMAN("gui-icon.style.batman", Arrays.asList("BAT_SPAWN_EGG", "COAL")),
|
||||
GUI_ICON_STYLE_BEAM("gui-icon.style.beam", Collections.singletonList("POWERED_RAIL")),
|
||||
GUI_ICON_STYLE_BLOCKBREAK("gui-icon.style.blockbreak", Collections.singletonList("IRON_PICKAXE")),
|
||||
GUI_ICON_STYLE_BLOCKPLACE("gui-icon.style.blockplace", Arrays.asList("OAK_PLANKS", "WOOD")),
|
||||
GUI_ICON_STYLE_CELEBRATION("gui-icon.style.celebration", Arrays.asList("FIREWORK_ROCKET", "FIREWORK")),
|
||||
GUI_ICON_STYLE_CHAINS("gui-icon.style.chains", Collections.singletonList("TRIPWIRE_HOOK")),
|
||||
GUI_ICON_STYLE_COMPANION("gui-icon.style.companion", Collections.singletonList("NAME_TAG")),
|
||||
GUI_ICON_STYLE_CUBE("gui-icon.style.cube", Collections.singletonList("STONE")),
|
||||
GUI_ICON_STYLE_FEET("gui-icon.style.feet", Collections.singletonList("GRASS")),
|
||||
GUI_ICON_STYLE_HALO("gui-icon.style.halo", Arrays.asList("END_PORTAL_FRAME", "ENDER_PORTAL_FRAME")),
|
||||
GUI_ICON_STYLE_HURT("gui-icon.style.hurt", Collections.singletonList("CACTUS")),
|
||||
GUI_ICON_STYLE_INVOCATION("gui-icon.style.invocation", Arrays.asList("ENDER_EYE", "EYE_OF_ENDER")),
|
||||
GUI_ICON_STYLE_MOVE("gui-icon.style.move", Arrays.asList("PISTON", "PISTON_BASE")),
|
||||
GUI_ICON_STYLE_NORMAL("gui-icon.style.normal", Collections.singletonList("DIRT")),
|
||||
GUI_ICON_STYLE_ORBIT("gui-icon.style.orbit", Arrays.asList("ENCHANTING_TABLE", "ENCHANTMENT_TABLE")),
|
||||
GUI_ICON_STYLE_OVERHEAD("gui-icon.style.overhead", Collections.singletonList("GLOWSTONE")),
|
||||
GUI_ICON_STYLE_POINT("gui-icon.style.point", Collections.singletonList("STONE_BUTTON")),
|
||||
GUI_ICON_STYLE_POPPER("gui-icon.style.popper", Arrays.asList("POPPED_CHORUS_FRUIT", "CHORUS_FRUIT_POPPED")),
|
||||
GUI_ICON_STYLE_PULSE("gui-icon.style.pulse", Arrays.asList("REDSTONE_TORCH", "REDSTONE_TORCH_ON")),
|
||||
GUI_ICON_STYLE_QUADHELIX("gui-icon.style.quadhelix", Arrays.asList("NAUTILUS_SHELL", "ACTIVATOR_RAIL")),
|
||||
GUI_ICON_STYLE_RINGS("gui-icon.style.rings", Arrays.asList("LEAD", "LEASH")),
|
||||
GUI_ICON_STYLE_SPHERE("gui-icon.style.sphere", Arrays.asList("HEART_OF_THE_SEA", "SNOWBALL", "SNOW_BALL")),
|
||||
GUI_ICON_STYLE_SPIN("gui-icon.style.spin", Collections.singletonList("BEACON")),
|
||||
GUI_ICON_STYLE_SPIRAL("gui-icon.style.spiral", Collections.singletonList("HOPPER")),
|
||||
GUI_ICON_STYLE_SWORDS("gui-icon.style.swords", Collections.singletonList("IRON_SWORD")),
|
||||
GUI_ICON_STYLE_THICK("gui-icon.style.thick", Arrays.asList("COBWEB", "WEB")),
|
||||
GUI_ICON_STYLE_TRAIL("gui-icon.style.trail", Collections.singletonList("GHAST_TEAR")),
|
||||
GUI_ICON_STYLE_TWINS("gui-icon.style.twins", Arrays.asList("OAK_FENCE", "FENCE")),
|
||||
GUI_ICON_STYLE_VORTEX("gui-icon.style.vortex", Collections.singletonList("GLOWSTONE_DUST")),
|
||||
GUI_ICON_STYLE_WHIRL("gui-icon.style.whirl", Collections.singletonList("FEATHER")),
|
||||
GUI_ICON_STYLE_WHIRLWIND("gui-icon.style.whirlwind", Collections.singletonList("STRING")),
|
||||
GUI_ICON_STYLE_WINGS("gui-icon.style.wings", Collections.singletonList("ELYTRA"));
|
||||
GUI_ICON_MISC_RESET("gui-icon.misc.reset", Collections.singletonList("BARRIER"));
|
||||
|
||||
private final String key;
|
||||
private final Object defaultValue;
|
||||
|
@ -245,7 +159,7 @@ public class ConfigurationManager extends Manager {
|
|||
*/
|
||||
public String getString() {
|
||||
this.loadValue();
|
||||
return (String) this.value;
|
||||
return String.valueOf(this.value);
|
||||
}
|
||||
|
||||
private double getNumber() {
|
||||
|
@ -386,10 +300,7 @@ public class ConfigurationManager extends Manager {
|
|||
EDIT_EFFECT,
|
||||
EDIT_STYLE,
|
||||
EDIT_DATA,
|
||||
RESET,
|
||||
|
||||
EFFECT,
|
||||
STYLE;
|
||||
RESET;
|
||||
|
||||
private Map<String, Material> materials;
|
||||
|
||||
|
@ -407,17 +318,6 @@ public class ConfigurationManager extends Manager {
|
|||
return this.getInternal("gui-icon.misc." + this.name().toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Material for a subsection of this icon in the config.yml
|
||||
* Tries to get from cache first, otherwise loads it
|
||||
*
|
||||
* @param subsection The name of the icon in the section
|
||||
* @return The Material for this Icon
|
||||
*/
|
||||
public Material get(String subsection) {
|
||||
return this.getInternal("gui-icon." + this.name().toLowerCase() + "." + subsection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Material for this icon
|
||||
* Tries to get from cache first, otherwise loads it
|
||||
|
@ -441,7 +341,7 @@ public class ConfigurationManager extends Manager {
|
|||
}
|
||||
|
||||
if (material == null)
|
||||
material = Material.BARRIER;
|
||||
material = ParticleUtils.FALLBACK_MATERIAL;
|
||||
|
||||
this.materials.put(configPath, material);
|
||||
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
package dev.esophose.playerparticles.manager;
|
||||
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.database.DatabaseConnector;
|
||||
import dev.esophose.playerparticles.database.MySQLConnector;
|
||||
import dev.esophose.playerparticles.database.SQLiteConnector;
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import dev.esophose.playerparticles.particles.ConsolePPlayer;
|
||||
import dev.esophose.playerparticles.particles.FixedParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.ParticleGroup;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -27,6 +26,7 @@ import java.util.function.Consumer;
|
|||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
|
||||
/**
|
||||
|
@ -81,13 +81,10 @@ public class DataManager extends Manager {
|
|||
* @return The PPlayer from cache
|
||||
*/
|
||||
public PPlayer getPPlayer(UUID playerUUID) {
|
||||
Collection<PPlayer> pplayers;
|
||||
synchronized (pplayers = this.playerParticles.getManager(ParticleManager.class).getPPlayers()) { // Under rare circumstances, the PPlayers list can be changed while it's looping
|
||||
for (PPlayer pp : pplayers)
|
||||
if (pp.getUniqueId().equals(playerUUID))
|
||||
return pp;
|
||||
return null;
|
||||
}
|
||||
for (PPlayer pp : this.playerParticles.getManager(ParticleManager.class).getPPlayers())
|
||||
if (pp.getUniqueId().equals(playerUUID))
|
||||
return pp;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,12 +250,8 @@ public class DataManager extends Manager {
|
|||
}
|
||||
|
||||
this.sync(() -> {
|
||||
synchronized (loadedPPlayer) {
|
||||
if (this.getPPlayer(playerUUID) == null) { // Make sure the PPlayer still isn't added, since this is async it's possible it got ran twice
|
||||
this.playerParticles.getManager(ParticleManager.class).addPPlayer(loadedPPlayer); // This will be fine now since loadedPPlayer is synchronized
|
||||
callback.accept(loadedPPlayer);
|
||||
}
|
||||
}
|
||||
this.playerParticles.getManager(ParticleManager.class).addPPlayer(loadedPPlayer);
|
||||
callback.accept(loadedPPlayer);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -312,6 +305,7 @@ public class DataManager extends Manager {
|
|||
|
||||
this.async(() -> this.databaseConnector.connect((connection) -> {
|
||||
String groupUUID;
|
||||
boolean existingGroup;
|
||||
|
||||
String groupUUIDQuery = "SELECT uuid FROM " + this.getTablePrefix() + "group WHERE owner_uuid = ? AND name = ?";
|
||||
try (PreparedStatement statement = connection.prepareStatement(groupUUIDQuery)) {
|
||||
|
@ -321,21 +315,25 @@ public class DataManager extends Manager {
|
|||
ResultSet result = statement.executeQuery();
|
||||
if (result.next()) { // Clear out particles from existing group
|
||||
groupUUID = result.getString("uuid");
|
||||
|
||||
String particlesDeleteQuery = "DELETE FROM " + this.getTablePrefix() + "particle WHERE group_uuid = ?";
|
||||
PreparedStatement particlesDeleteStatement = connection.prepareStatement(particlesDeleteQuery);
|
||||
particlesDeleteStatement.setString(1, result.getString("uuid"));
|
||||
|
||||
particlesDeleteStatement.executeUpdate();
|
||||
existingGroup = true;
|
||||
} else { // Create new group
|
||||
groupUUID = UUID.randomUUID().toString();
|
||||
existingGroup = false;
|
||||
}
|
||||
}
|
||||
|
||||
String groupCreateQuery = "INSERT INTO " + this.getTablePrefix() + "group (uuid, owner_uuid, name) VALUES (?, ?, ?)";
|
||||
PreparedStatement groupCreateStatement = connection.prepareStatement(groupCreateQuery);
|
||||
if (existingGroup) {
|
||||
String particlesDeleteQuery = "DELETE FROM " + this.getTablePrefix() + "particle WHERE group_uuid = ?";
|
||||
try (PreparedStatement particlesDeleteStatement = connection.prepareStatement(particlesDeleteQuery)) {
|
||||
particlesDeleteStatement.setString(1, groupUUID);
|
||||
particlesDeleteStatement.executeUpdate();
|
||||
}
|
||||
} else {
|
||||
String groupCreateQuery = "INSERT INTO " + this.getTablePrefix() + "group (uuid, owner_uuid, name) VALUES (?, ?, ?)";
|
||||
try (PreparedStatement groupCreateStatement = connection.prepareStatement(groupCreateQuery)) {
|
||||
groupCreateStatement.setString(1, groupUUID);
|
||||
groupCreateStatement.setString(2, playerUUID.toString());
|
||||
groupCreateStatement.setString(3, group.getName());
|
||||
|
||||
groupCreateStatement.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
@ -403,6 +401,27 @@ public class DataManager extends Manager {
|
|||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to reset the active particle group for the given player name.
|
||||
* This works even if the player is offline.
|
||||
*
|
||||
* @param playerName The name of the player to reset the active particle group for
|
||||
* @param callback The callback to execute when finished, true for successful, otherwise false
|
||||
*/
|
||||
public void resetActiveParticleGroup(String playerName, Consumer<Boolean> callback) {
|
||||
this.async(() -> this.databaseConnector.connect((connection) -> {
|
||||
@SuppressWarnings("deprecation")
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerName);
|
||||
|
||||
String query = "DELETE FROM " + this.getTablePrefix() + "particle WHERE group_uuid IN (SELECT uuid FROM " + this.getTablePrefix() + "group WHERE owner_uuid = ? AND name = ?)";
|
||||
try (PreparedStatement statement = connection.prepareStatement(query)) {
|
||||
statement.setString(1, offlinePlayer.getUniqueId().toString());
|
||||
statement.setString(2, ParticleGroup.DEFAULT_NAME);
|
||||
callback.accept(statement.executeUpdate() > 0);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a fixed effect to save data
|
||||
* Does not perform a check to see if a fixed effect with this id already exists
|
||||
|
@ -554,7 +573,11 @@ public class DataManager extends Manager {
|
|||
* @return the prefix to be used by all table names
|
||||
*/
|
||||
public String getTablePrefix() {
|
||||
return this.playerParticles.getDescription().getName().toLowerCase() + '_';
|
||||
if (this.databaseConnector instanceof MySQLConnector) {
|
||||
return Setting.MYSQL_TABLE_PREFIX.getString();
|
||||
} else {
|
||||
return this.playerParticles.getDescription().getName().toLowerCase() + '_';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import dev.esophose.playerparticles.gui.GuiInventoryDefault;
|
|||
import dev.esophose.playerparticles.gui.GuiInventoryLoadPresetGroups;
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -25,7 +26,7 @@ public class GuiManager extends Manager implements Listener, Runnable {
|
|||
public GuiManager(PlayerParticles playerParticles) {
|
||||
super(playerParticles);
|
||||
|
||||
this.guiInventories = new ArrayList<>();
|
||||
this.guiInventories = Collections.synchronizedList(new ArrayList<>());
|
||||
this.guiTask = null;
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, this.playerParticles);
|
||||
|
@ -108,15 +109,17 @@ public class GuiManager extends Manager implements Listener, Runnable {
|
|||
* @param pplayer The PPlayer to open the GUI screen for
|
||||
*/
|
||||
public void openDefault(PPlayer pplayer) {
|
||||
GuiInventory inventoryToOpen;
|
||||
if (!Setting.GUI_PRESETS_ONLY.getBoolean()) {
|
||||
inventoryToOpen = new GuiInventoryDefault(pplayer);
|
||||
} else {
|
||||
inventoryToOpen = new GuiInventoryLoadPresetGroups(pplayer, true);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(this.playerParticles, () -> {
|
||||
GuiInventory inventoryToOpen;
|
||||
if (!Setting.GUI_PRESETS_ONLY.getBoolean()) {
|
||||
inventoryToOpen = new GuiInventoryDefault(pplayer);
|
||||
} else {
|
||||
inventoryToOpen = new GuiInventoryLoadPresetGroups(pplayer, true);
|
||||
}
|
||||
|
||||
this.guiInventories.add(inventoryToOpen);
|
||||
Bukkit.getScheduler().runTask(this.playerParticles, () -> pplayer.getPlayer().openInventory(inventoryToOpen.getInventory()));
|
||||
pplayer.getPlayer().openInventory(inventoryToOpen.getInventory());
|
||||
this.guiInventories.add(inventoryToOpen);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,8 +128,10 @@ public class GuiManager extends Manager implements Listener, Runnable {
|
|||
* @param nextInventory The GuiInventory to transition to
|
||||
*/
|
||||
public void transition(GuiInventory nextInventory) {
|
||||
this.guiInventories.add(nextInventory);
|
||||
Bukkit.getScheduler().runTask(this.playerParticles, () -> nextInventory.getPPlayer().getPlayer().openInventory(nextInventory.getInventory()));
|
||||
Bukkit.getScheduler().runTask(this.playerParticles, () -> {
|
||||
nextInventory.getPPlayer().getPlayer().openInventory(nextInventory.getInventory());
|
||||
this.guiInventories.add(nextInventory);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,14 +146,5 @@ public class GuiManager extends Manager implements Listener, Runnable {
|
|||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a GuiInventory from guiInventories by a PPlayer
|
||||
*
|
||||
* @param pplayer The PPlayer who owns the GuiInventory
|
||||
*/
|
||||
private void removeGuiInventory(PPlayer pplayer) {
|
||||
this.guiInventories.removeIf(x -> x.getPPlayer().getUniqueId().equals(pplayer.getUniqueId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -124,6 +124,9 @@ public class LocaleManager extends Manager {
|
|||
* @param stringPlaceholders The placeholders to apply
|
||||
*/
|
||||
public void sendMessage(CommandSender sender, String messageKey, StringPlaceholders stringPlaceholders) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
sender.sendMessage(this.getLocaleMessage("prefix") + this.getLocaleMessage(messageKey, stringPlaceholders));
|
||||
}
|
||||
|
||||
|
@ -135,6 +138,9 @@ public class LocaleManager extends Manager {
|
|||
* @param stringPlaceholders The placeholders to apply
|
||||
*/
|
||||
public void sendMessage(PPlayer pplayer, String messageKey, StringPlaceholders stringPlaceholders) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
pplayer.getUnderlyingExecutor().sendMessage(this.parsePlaceholders(pplayer.getPlayer(), this.getLocaleMessage("prefix") + this.getLocaleMessage(messageKey, stringPlaceholders)));
|
||||
}
|
||||
|
||||
|
@ -145,6 +151,9 @@ public class LocaleManager extends Manager {
|
|||
* @param messageKey The message key of the Locale to send
|
||||
*/
|
||||
public void sendMessage(CommandSender sender, String messageKey) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
this.sendMessage(sender, messageKey, StringPlaceholders.empty());
|
||||
}
|
||||
|
||||
|
@ -155,6 +164,9 @@ public class LocaleManager extends Manager {
|
|||
* @param messageKey The message key of the Locale to send
|
||||
*/
|
||||
public void sendMessage(PPlayer pplayer, String messageKey) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
this.sendMessage(pplayer, messageKey, StringPlaceholders.empty());
|
||||
}
|
||||
|
||||
|
@ -166,6 +178,9 @@ public class LocaleManager extends Manager {
|
|||
* @param stringPlaceholders The placeholders to apply
|
||||
*/
|
||||
public void sendSimpleMessage(CommandSender sender, String messageKey, StringPlaceholders stringPlaceholders) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
sender.sendMessage(this.getLocaleMessage(messageKey, stringPlaceholders));
|
||||
}
|
||||
|
||||
|
@ -177,6 +192,9 @@ public class LocaleManager extends Manager {
|
|||
* @param stringPlaceholders The placeholders to apply
|
||||
*/
|
||||
public void sendSimpleMessage(PPlayer pplayer, String messageKey, StringPlaceholders stringPlaceholders) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
pplayer.getUnderlyingExecutor().sendMessage(this.parsePlaceholders(pplayer.getPlayer(), this.getLocaleMessage(messageKey, stringPlaceholders)));
|
||||
}
|
||||
|
||||
|
@ -187,6 +205,9 @@ public class LocaleManager extends Manager {
|
|||
* @param messageKey The message key of the Locale to send
|
||||
*/
|
||||
public void sendSimpleMessage(CommandSender sender, String messageKey) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
this.sendMessage(sender, messageKey, StringPlaceholders.empty());
|
||||
}
|
||||
|
||||
|
@ -197,6 +218,9 @@ public class LocaleManager extends Manager {
|
|||
* @param messageKey The message key of the Locale to send
|
||||
*/
|
||||
public void sendSimpleMessage(PPlayer pplayer, String messageKey) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
this.sendMessage(pplayer, messageKey, StringPlaceholders.empty());
|
||||
}
|
||||
|
||||
|
@ -207,6 +231,9 @@ public class LocaleManager extends Manager {
|
|||
* @param message The message to send
|
||||
*/
|
||||
public void sendCustomMessage(CommandSender sender, String message) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
|
@ -217,6 +244,9 @@ public class LocaleManager extends Manager {
|
|||
* @param message The message to send
|
||||
*/
|
||||
public void sendCustomMessage(PPlayer pplayer, String message) {
|
||||
if (!Setting.MESSAGES_ENABLED.getBoolean())
|
||||
return;
|
||||
|
||||
this.sendCustomMessage(pplayer.getUnderlyingExecutor(), this.parsePlaceholders(pplayer.getPlayer(), message));
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import dev.esophose.playerparticles.particles.ParticleGroupPreset;
|
|||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.particles.ParticleProperty;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.util.inputparser.InputParser;
|
||||
import java.io.File;
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
package dev.esophose.playerparticles.manager;
|
||||
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.hook.WorldGuardHook;
|
||||
import dev.esophose.playerparticles.manager.ConfigurationManager.Setting;
|
||||
import dev.esophose.playerparticles.nms.wrapper.ParticleHandler;
|
||||
import dev.esophose.playerparticles.particles.ConsolePPlayer;
|
||||
import dev.esophose.playerparticles.particles.FixedParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.ParticleEffectSettings;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.PParticle;
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.color.ParticleColor;
|
||||
import dev.esophose.playerparticles.particles.data.ParticleColor;
|
||||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.particles.ParticleProperty;
|
||||
|
@ -58,6 +59,11 @@ public class ParticleManager extends Manager implements Listener, Runnable {
|
|||
*/
|
||||
private BukkitTask particleTask;
|
||||
|
||||
/**
|
||||
* The task that checks player worldguard region statuses
|
||||
*/
|
||||
private BukkitTask worldGuardTask;
|
||||
|
||||
private ParticleHandler particleHandler;
|
||||
private Map<ParticleEffect, ParticleEffectSettings> supportedParticleEffects;
|
||||
|
||||
|
@ -85,6 +91,11 @@ public class ParticleManager extends Manager implements Listener, Runnable {
|
|||
if (this.particleTask != null)
|
||||
this.particleTask.cancel();
|
||||
|
||||
if (this.worldGuardTask != null) {
|
||||
this.worldGuardTask.cancel();
|
||||
this.worldGuardTask = null;
|
||||
}
|
||||
|
||||
int overrideVersion = Setting.OVERRIDE_PARTICLE_VERSION.getInt();
|
||||
VersionMapping versionMapping = VersionMapping.getVersionMapping(overrideVersion != -1 ? overrideVersion : NMSUtil.getVersionNumber());
|
||||
this.particleHandler = NMSUtil.getHandler(versionMapping);
|
||||
|
@ -95,8 +106,13 @@ public class ParticleManager extends Manager implements Listener, Runnable {
|
|||
|
||||
Bukkit.getScheduler().runTaskLater(this.playerParticles, () -> {
|
||||
long ticks = Setting.TICKS_PER_PARTICLE.getLong();
|
||||
this.particleTask = Bukkit.getScheduler().runTaskTimerAsynchronously(this.playerParticles, this, 5, ticks);
|
||||
}, 1);
|
||||
this.particleTask = Bukkit.getScheduler().runTaskTimerAsynchronously(this.playerParticles, this, 0, ticks);
|
||||
|
||||
if (WorldGuardHook.enabled()) {
|
||||
long worldGuardTicks = Setting.WORLDGUARD_CHECK_INTERVAL.getLong();
|
||||
this.worldGuardTask = Bukkit.getScheduler().runTaskTimer(this.playerParticles, this::updateWorldGuardStatuses, 0, worldGuardTicks);
|
||||
}
|
||||
}, 5);
|
||||
|
||||
this.particlePlayers.clear();
|
||||
DataManager dataManager = this.playerParticles.getManager(DataManager.class);
|
||||
|
@ -179,7 +195,7 @@ public class ParticleManager extends Manager implements Listener, Runnable {
|
|||
|
||||
// Don't show their particles if they are in spectator mode
|
||||
// Don't spawn particles if the world doesn't allow it
|
||||
if (player != null && player.getGameMode() != GameMode.SPECTATOR && permissionManager.isWorldEnabled(player.getWorld().getName()))
|
||||
if (player != null && (NMSUtil.getVersionNumber() < 8 || player.getGameMode() != GameMode.SPECTATOR) && permissionManager.isWorldEnabled(player.getWorld().getName()))
|
||||
for (ParticlePair particles : pplayer.getActiveParticles())
|
||||
this.displayParticles(pplayer, particles, player.getLocation().clone().add(0, 1, 0));
|
||||
|
||||
|
@ -191,6 +207,25 @@ public class ParticleManager extends Manager implements Listener, Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the WorldGuard region statuses for players
|
||||
*/
|
||||
private void updateWorldGuardStatuses() {
|
||||
PermissionManager permissionManager = this.playerParticles.getManager(PermissionManager.class);
|
||||
|
||||
for (PPlayer pplayer : this.particlePlayers.values()) {
|
||||
Player player = pplayer.getPlayer();
|
||||
if (player == null)
|
||||
continue;
|
||||
|
||||
boolean inAllowedRegion = WorldGuardHook.isInAllowedRegion(player.getLocation());
|
||||
if (!inAllowedRegion && Setting.WORLDGUARD_ENABLE_BYPASS_PERMISSION.getBoolean())
|
||||
inAllowedRegion = permissionManager.hasWorldGuardBypass(player);
|
||||
|
||||
pplayer.setInAllowedRegion(inAllowedRegion);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays particles at the given player location with their settings
|
||||
*
|
||||
|
@ -200,17 +235,36 @@ public class ParticleManager extends Manager implements Listener, Runnable {
|
|||
*/
|
||||
private void displayParticles(PPlayer pplayer, ParticlePair particle, Location location) {
|
||||
if (!this.playerParticles.getManager(ParticleStyleManager.class).isEventHandled(particle.getStyle())) {
|
||||
if (Setting.TOGGLE_ON_COMBAT.getBoolean() && pplayer.isInCombat())
|
||||
if (Setting.TOGGLE_ON_COMBAT.getBoolean() && particle.getStyle().canToggleWithCombat() && pplayer.isInCombat())
|
||||
return;
|
||||
|
||||
List<PParticle> particles;
|
||||
if (Setting.TOGGLE_ON_MOVE.getBoolean() && particle.getStyle().canToggleWithMovement() && pplayer.isMoving()) {
|
||||
particles = DefaultStyles.FEET.getParticles(particle, location);
|
||||
} else {
|
||||
particles = particle.getStyle().getParticles(particle, location);
|
||||
if (!pplayer.isInAllowedRegion())
|
||||
return;
|
||||
|
||||
if (particle.getStyle().canToggleWithMovement() && pplayer.isMoving()) {
|
||||
switch (Setting.TOGGLE_ON_MOVE.getString().toUpperCase()) {
|
||||
case "DISPLAY_FEET":
|
||||
case "TRUE": // Old default value, keep here for legacy config compatibility
|
||||
for (PParticle pparticle : DefaultStyles.FEET.getParticles(particle, location))
|
||||
this.displayParticles(particle, pparticle, particle.getStyle().hasLongRangeVisibility(), pplayer.getPlayer());
|
||||
return;
|
||||
case "DISPLAY_NORMAL":
|
||||
for (PParticle pparticle : DefaultStyles.NORMAL.getParticles(particle, location))
|
||||
this.displayParticles(particle, pparticle, particle.getStyle().hasLongRangeVisibility(), pplayer.getPlayer());
|
||||
return;
|
||||
case "DISPLAY_OVERHEAD":
|
||||
for (PParticle pparticle : DefaultStyles.OVERHEAD.getParticles(particle, location))
|
||||
this.displayParticles(particle, pparticle, particle.getStyle().hasLongRangeVisibility(), pplayer.getPlayer());
|
||||
return;
|
||||
case "NONE":
|
||||
case "FALSE": // Old default value, keep here for legacy config compatibility
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (PParticle pparticle : particles)
|
||||
for (PParticle pparticle : particle.getStyle().getParticles(particle, location))
|
||||
this.displayParticles(particle, pparticle, particle.getStyle().hasLongRangeVisibility(), pplayer.getPlayer());
|
||||
}
|
||||
}
|
||||
|
@ -218,19 +272,27 @@ public class ParticleManager extends Manager implements Listener, Runnable {
|
|||
/**
|
||||
* An alternative method used for event styles
|
||||
*
|
||||
* @param source The player the particles are spawning from, nullable for special cases
|
||||
* @param pplayer The PPlayer the particles are spawning from, nullable for special cases
|
||||
* @param world The world the particles are spawning in
|
||||
* @param particle The ParticlePair to use for getting particle settings
|
||||
* @param particles The particles to display
|
||||
* @param isLongRange If the particle can be viewed from long range
|
||||
*/
|
||||
public void displayParticles(Player source, World world, ParticlePair particle, List<PParticle> particles, boolean isLongRange) {
|
||||
public void displayParticles(PPlayer pplayer, World world, ParticlePair particle, List<PParticle> particles, boolean isLongRange) {
|
||||
PermissionManager permissionManager = this.playerParticles.getManager(PermissionManager.class);
|
||||
if ((source != null && source.getGameMode() == GameMode.SPECTATOR) || !permissionManager.isWorldEnabled(world.getName()))
|
||||
|
||||
Player player = null;
|
||||
if (pplayer != null) {
|
||||
if (!pplayer.isInAllowedRegion())
|
||||
return;
|
||||
player = pplayer.getPlayer();
|
||||
}
|
||||
|
||||
if ((player != null && (NMSUtil.getVersionNumber() < 8 || player.getGameMode() == GameMode.SPECTATOR)) || !permissionManager.isWorldEnabled(world.getName()))
|
||||
return;
|
||||
|
||||
for (PParticle pparticle : particles)
|
||||
this.displayParticles(particle, pparticle, isLongRange, source);
|
||||
this.displayParticles(particle, pparticle, isLongRange, player);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package dev.esophose.playerparticles.manager;
|
||||
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.event.ParticleStyleRegistrationEvent;
|
||||
import dev.esophose.playerparticles.styles.DefaultStyles;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class ParticleStyleManager extends Manager {
|
||||
|
||||
|
@ -20,12 +24,49 @@ public class ParticleStyleManager extends Manager {
|
|||
|
||||
this.styles = new ArrayList<>();
|
||||
this.eventStyles = new ArrayList<>();
|
||||
DefaultStyles.registerStyles(this);
|
||||
|
||||
DefaultStyles.initStyles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
// Styles List is never reset so you don't need to re-register styles each time the plugin reloads
|
||||
this.styles.clear();
|
||||
this.eventStyles.clear();
|
||||
|
||||
// Call registration event
|
||||
// We use this event internally, so no other action needs to be done for us to register the default styles
|
||||
ParticleStyleRegistrationEvent event = new ParticleStyleRegistrationEvent();
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
|
||||
Collection<ParticleStyle> eventStyles = event.getRegisteredEventStyles().values();
|
||||
List<ParticleStyle> styles = new ArrayList<>(event.getRegisteredStyles().values());
|
||||
styles.addAll(eventStyles);
|
||||
styles.sort(Comparator.comparing(ParticleStyle::getName));
|
||||
|
||||
for (ParticleStyle style : styles) {
|
||||
try {
|
||||
if (style == null)
|
||||
throw new IllegalArgumentException("Tried to register a null style");
|
||||
|
||||
if (style.getInternalName() == null || style.getInternalName().trim().isEmpty())
|
||||
throw new IllegalArgumentException("Tried to register a style with a null or empty name: '" + style.getInternalName() + "'");
|
||||
|
||||
for (ParticleStyle testAgainst : this.styles) {
|
||||
if (testAgainst.equals(style)) {
|
||||
throw new IllegalArgumentException("Tried to register the same style twice: '" + style.getInternalName() + "'");
|
||||
} else if (testAgainst.getInternalName().equalsIgnoreCase(style.getInternalName())) {
|
||||
throw new IllegalArgumentException("Tried to register two styles with the same internal name spelling: '" + style.getInternalName() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
this.styles.add(style);
|
||||
|
||||
if (eventStyles.contains(style))
|
||||
this.eventStyles.add(style);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -33,41 +74,6 @@ public class ParticleStyleManager extends Manager {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a style that is put into the plugin's update loop
|
||||
*
|
||||
* @param style The style to add
|
||||
*/
|
||||
public void registerStyle(ParticleStyle style) {
|
||||
if (style == null) {
|
||||
throw new IllegalArgumentException("Tried to register a null style");
|
||||
}
|
||||
|
||||
if (style.getInternalName() == null || style.getInternalName().trim().equals("")) {
|
||||
throw new IllegalArgumentException("Tried to register a style with a null or empty name: '" + style.getInternalName() + "'");
|
||||
}
|
||||
|
||||
for (ParticleStyle testAgainst : this.styles) {
|
||||
if (testAgainst.equals(style)) {
|
||||
throw new IllegalArgumentException("Tried to register the same style twice: '" + style.getInternalName() + "'");
|
||||
} else if (testAgainst.getInternalName().equalsIgnoreCase(style.getInternalName())) {
|
||||
throw new IllegalArgumentException("Tried to register two styles with the same internal name spelling: '" + style.getInternalName() + "'");
|
||||
}
|
||||
}
|
||||
|
||||
this.styles.add(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a style that isn't updated on the normal update loop
|
||||
*
|
||||
* @param style The style to register
|
||||
*/
|
||||
public void registerEventStyle(ParticleStyle style) {
|
||||
this.registerStyle(style);
|
||||
this.eventStyles.add(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if a given style is customly handled
|
||||
*
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.bukkit.command.ConsoleCommandSender;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
public class PermissionManager extends Manager {
|
||||
|
@ -29,17 +30,24 @@ public class PermissionManager extends Manager {
|
|||
STYLE("style"),
|
||||
|
||||
FIXED("fixed"),
|
||||
FIXED_MAX("fixed.max"),
|
||||
FIXED_UNLIMITED("fixed.unlimited"),
|
||||
FIXED_CLEAR("fixed.clear"),
|
||||
FIXED_TELEPORT("fixed.teleport"),
|
||||
|
||||
RELOAD("reload"),
|
||||
OVERRIDE("override"),
|
||||
RESET_OTHERS("reset.others"),
|
||||
|
||||
GUI("gui"),
|
||||
|
||||
|
||||
PARTICLES_MAX("particles.max"),
|
||||
PARTICLES_UNLIMITED("particles.unlimited"),
|
||||
GROUPS_UNLIMITED("groups.unlimited");
|
||||
|
||||
GROUPS_MAX("groups.max"),
|
||||
GROUPS_UNLIMITED("groups.unlimited"),
|
||||
|
||||
WORLDGUARD_BYPASS("worldguard.bypass");;
|
||||
|
||||
private final String permissionString;
|
||||
|
||||
|
@ -69,6 +77,11 @@ public class PermissionManager extends Manager {
|
|||
String permission = PERMISSION_PREFIX + this.permissionString + '.' + subPermission;
|
||||
return p.hasPermission(permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return PERMISSION_PREFIX + this.permissionString;
|
||||
}
|
||||
}
|
||||
|
||||
public PermissionManager(PlayerParticles playerParticles) {
|
||||
|
@ -87,6 +100,9 @@ public class PermissionManager extends Manager {
|
|||
// Effects
|
||||
Map<String, Boolean> effectPermissions = new HashMap<>();
|
||||
for (ParticleEffect effect : particleManager.getEnabledEffects()) {
|
||||
if (particleManager.getEffectSettings(effect) == null)
|
||||
continue;
|
||||
|
||||
Permission permission = new Permission("playerparticles.effect." + particleManager.getEffectSettings(effect).getInternalName());
|
||||
pluginManager.addPermission(permission);
|
||||
effectPermissions.put(permission.getName(), true);
|
||||
|
@ -109,6 +125,7 @@ public class PermissionManager extends Manager {
|
|||
|
||||
// Fixed
|
||||
pluginManager.addPermission(new Permission("playerparticles.fixed"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.fixed.max"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.fixed.unlimited"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.fixed.clear"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.fixed.teleport"));
|
||||
|
@ -116,10 +133,18 @@ public class PermissionManager extends Manager {
|
|||
// Misc
|
||||
pluginManager.addPermission(new Permission("playerparticles.reload"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.override"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.reset.others"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.gui"));
|
||||
|
||||
pluginManager.addPermission(new Permission("playerparticles.particles.max"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.particles.unlimited"));
|
||||
|
||||
pluginManager.addPermission(new Permission("playerparticles.groups.max"));
|
||||
pluginManager.addPermission(new Permission("playerparticles.groups.unlimited"));
|
||||
|
||||
// WorldGuard
|
||||
pluginManager.addPermission(new Permission("playerparticles.worldguard.bypass"));
|
||||
|
||||
// Register all non-child permissions
|
||||
Map<String, Boolean> childPermissions = new HashMap<>();
|
||||
for (Permission permission : allPermissions) {
|
||||
|
@ -155,7 +180,7 @@ public class PermissionManager extends Manager {
|
|||
if (executor != pplayer)
|
||||
return false;
|
||||
|
||||
return pplayer.getActiveParticles().size() >= Setting.MAX_PARTICLES.getInt();
|
||||
return pplayer.getActiveParticles().size() >= this.getPermissionAmount(pplayer.getUnderlyingExecutor(), PPermission.PARTICLES_MAX, Setting.MAX_PARTICLES.getInt());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,7 +197,7 @@ public class PermissionManager extends Manager {
|
|||
if (executor != pplayer)
|
||||
return false;
|
||||
|
||||
return executor.getParticleGroups().size() - 1 >= Setting.MAX_GROUPS.getInt();
|
||||
return executor.getParticleGroups().size() - 1 >= this.getPermissionAmount(pplayer.getUnderlyingExecutor(), PPermission.GROUPS_MAX, Setting.MAX_GROUPS.getInt());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,7 +210,7 @@ public class PermissionManager extends Manager {
|
|||
if (PPermission.GROUPS_UNLIMITED.check(pplayer.getUnderlyingExecutor()))
|
||||
return true;
|
||||
|
||||
return Setting.MAX_GROUPS.getInt() != 0;
|
||||
return this.getPermissionAmount(pplayer.getUnderlyingExecutor(), PPermission.GROUPS_MAX, Setting.MAX_GROUPS.getInt()) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,7 +227,7 @@ public class PermissionManager extends Manager {
|
|||
if (executor != pplayer)
|
||||
return false;
|
||||
|
||||
return pplayer.getFixedEffectIds().size() >= Setting.MAX_FIXED_EFFECTS.getInt();
|
||||
return pplayer.getFixedEffectIds().size() >= this.getPermissionAmount(pplayer.getUnderlyingExecutor(), PPermission.FIXED_MAX, Setting.MAX_FIXED_EFFECTS.getInt());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,7 +253,7 @@ public class PermissionManager extends Manager {
|
|||
if (executor != pplayer)
|
||||
return Integer.MAX_VALUE;
|
||||
|
||||
return Setting.MAX_PARTICLES.getInt();
|
||||
return this.getPermissionAmount(pplayer.getUnderlyingExecutor(), PPermission.PARTICLES_MAX, Setting.MAX_PARTICLES.getInt());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,6 +275,16 @@ public class PermissionManager extends Manager {
|
|||
return Setting.DISABLED_WORLDS.getStringList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player can reset another offline player's particles
|
||||
*
|
||||
* @param player The player to check the permission for
|
||||
* @return True if the player has permission, otherwise false
|
||||
*/
|
||||
public boolean canResetOthers(PPlayer player) {
|
||||
return PPermission.RESET_OTHERS.check(player.getUnderlyingExecutor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has permission to use an effect
|
||||
*
|
||||
|
@ -397,10 +432,10 @@ public class PermissionManager extends Manager {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks if a player can use /ppo
|
||||
* Checks if a CommandSender can use /ppo
|
||||
*
|
||||
* @param sender The CommandSender to check
|
||||
* @return If the player can use /ppo
|
||||
* @return If the sender can use /ppo
|
||||
*/
|
||||
public boolean canOverride(CommandSender sender) {
|
||||
if (this.isConsole(sender))
|
||||
|
@ -409,6 +444,16 @@ public class PermissionManager extends Manager {
|
|||
return PPermission.OVERRIDE.check(sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has the WorldGuard bypass permission
|
||||
*
|
||||
* @param player The Player to check
|
||||
* @return If the player has the WorldGuard bypass permission
|
||||
*/
|
||||
public boolean hasWorldGuardBypass(Player player) {
|
||||
return PPermission.WORLDGUARD_BYPASS.check(player);
|
||||
}
|
||||
|
||||
private boolean isConsole(PPlayer pplayer) {
|
||||
return this.isConsole(pplayer.getUnderlyingExecutor());
|
||||
}
|
||||
|
@ -429,4 +474,17 @@ public class PermissionManager extends Manager {
|
|||
return pplayer;
|
||||
}
|
||||
|
||||
private int getPermissionAmount(Permissible permissible, PPermission permission, int lowerBound) {
|
||||
int amount = lowerBound;
|
||||
for (PermissionAttachmentInfo info : permissible.getEffectivePermissions()) {
|
||||
String target = info.getPermission().toLowerCase();
|
||||
if (target.startsWith(permission.toString()) && info.getValue()) {
|
||||
try {
|
||||
amount = Math.max(amount, Integer.parseInt(target.substring(target.lastIndexOf('.') + 1)));
|
||||
} catch (NumberFormatException ignored) { }
|
||||
}
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,11 @@ public class PPlayer {
|
|||
*/
|
||||
private boolean inCombat;
|
||||
|
||||
/**
|
||||
* If the player is in an allowed region
|
||||
*/
|
||||
private boolean inAllowedRegion;
|
||||
|
||||
/**
|
||||
* Constructs a new PPlayer
|
||||
*
|
||||
|
@ -64,6 +69,7 @@ public class PPlayer {
|
|||
this.particlesHidden = particlesHidden;
|
||||
this.isMoving = false;
|
||||
this.inCombat = false;
|
||||
this.inAllowedRegion = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +109,7 @@ public class PPlayer {
|
|||
/**
|
||||
* Gets if the Player can see particles spawned by the plugin or not
|
||||
*
|
||||
* @return True if the player can see particles, otherwise false
|
||||
* @return true if the player can see particles, otherwise false
|
||||
*/
|
||||
public boolean canSeeParticles() {
|
||||
return !this.particlesHidden;
|
||||
|
@ -112,7 +118,7 @@ public class PPlayer {
|
|||
/**
|
||||
* Sets if the player can see particles spawned by the plugin or not
|
||||
*
|
||||
* @param hidden True if the player can see particles, otherwise false
|
||||
* @param hidden true if the player can see particles, otherwise false
|
||||
*/
|
||||
public void setParticlesHidden(boolean hidden) {
|
||||
this.particlesHidden = hidden;
|
||||
|
@ -130,7 +136,7 @@ public class PPlayer {
|
|||
/**
|
||||
* Sets the player's movement state
|
||||
*
|
||||
* @param isMoving True if the player is moving, otherwise false if they are standing still
|
||||
* @param isMoving true if the player is moving, otherwise false if they are standing still
|
||||
*/
|
||||
public void setMoving(boolean isMoving) {
|
||||
this.isMoving = isMoving;
|
||||
|
@ -139,7 +145,7 @@ public class PPlayer {
|
|||
/**
|
||||
* Gets if a player is moving
|
||||
*
|
||||
* @return True if the player is moving
|
||||
* @return true if the player is moving
|
||||
*/
|
||||
public boolean isMoving() {
|
||||
return this.isMoving;
|
||||
|
@ -148,7 +154,7 @@ public class PPlayer {
|
|||
/**
|
||||
* Sets the player's combat state
|
||||
*
|
||||
* @param inCombat True if the player is in combat, otherwise false
|
||||
* @param inCombat true if the player is in combat, otherwise false
|
||||
*/
|
||||
public void setInCombat(boolean inCombat) {
|
||||
this.inCombat = inCombat;
|
||||
|
@ -157,12 +163,28 @@ public class PPlayer {
|
|||
/**
|
||||
* Gets if a player is in combat
|
||||
*
|
||||
* @return True if the player is in combat
|
||||
* @return true if the player is in combat
|
||||
*/
|
||||
public boolean isInCombat() {
|
||||
return this.inCombat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the player's region state
|
||||
*
|
||||
* @param inAllowedRegion true if the player is in an allowed region, otherwise false
|
||||
*/
|
||||
public void setInAllowedRegion(boolean inAllowedRegion) {
|
||||
this.inAllowedRegion = inAllowedRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the player is in an allowed region, otherwise false
|
||||
*/
|
||||
public boolean isInAllowedRegion() {
|
||||
return this.inAllowedRegion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ParticleGroup this player has by its name
|
||||
*
|
||||
|
|
|
@ -7,6 +7,7 @@ import dev.esophose.playerparticles.util.ParticleUtils;
|
|||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class ParticleEffectSettings {
|
||||
|
||||
|
@ -19,6 +20,7 @@ public class ParticleEffectSettings {
|
|||
|
||||
private String effectName;
|
||||
private boolean enabled;
|
||||
private Material guiIconMaterial;
|
||||
|
||||
public ParticleEffectSettings(ParticleEffect particleEffect) {
|
||||
this.particleEffect = particleEffect;
|
||||
|
@ -40,6 +42,7 @@ public class ParticleEffectSettings {
|
|||
|
||||
boolean changed = this.setIfNotExists("effect-name", this.getInternalName(), "The name the effect will display as");
|
||||
changed |= this.setIfNotExists("enabled", this.enabledByDefault, "If the effect is enabled or not");
|
||||
changed |= this.setIfNotExists("gui-icon-material", this.particleEffect.getGuiIconMaterialNames());
|
||||
|
||||
if (changed)
|
||||
this.config.save();
|
||||
|
@ -56,6 +59,7 @@ public class ParticleEffectSettings {
|
|||
|
||||
this.effectName = this.config.getString("effect-name");
|
||||
this.enabled = this.config.getBoolean("enabled");
|
||||
this.guiIconMaterial = ParticleUtils.closestMatchWithFallback(true, this.config.getStringList("gui-icon-material").toArray(new String[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,6 +99,13 @@ public class ParticleEffectSettings {
|
|||
return this.effectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Material icon that represents this style in the GUI
|
||||
*/
|
||||
public Material getGuiIconMaterial() {
|
||||
return this.guiIconMaterial;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this effect is enabled, otherwise false
|
||||
*/
|
||||
|
|
|
@ -3,9 +3,9 @@ package dev.esophose.playerparticles.particles;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.manager.LocaleManager;
|
||||
import dev.esophose.playerparticles.manager.ParticleManager;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.color.ParticleColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.ParticleColor;
|
||||
import dev.esophose.playerparticles.styles.DefaultStyles;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package dev.esophose.playerparticles.particles.color;
|
||||
package dev.esophose.playerparticles.particles.data;
|
||||
|
||||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
import java.util.Objects;
|
|
@ -1,4 +1,4 @@
|
|||
package dev.esophose.playerparticles.particles.color;
|
||||
package dev.esophose.playerparticles.particles.data;
|
||||
|
||||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
import java.util.Objects;
|
|
@ -1,4 +1,4 @@
|
|||
package dev.esophose.playerparticles.particles.color;
|
||||
package dev.esophose.playerparticles.particles.data;
|
||||
|
||||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
@ -55,10 +56,7 @@ public class PPlayerCombatListener implements Listener {
|
|||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerAttack(EntityDamageByEntityEvent event) {
|
||||
if (!Setting.TOGGLE_ON_COMBAT.getBoolean())
|
||||
return;
|
||||
|
||||
if (!(event.getEntity() instanceof Player))
|
||||
if (event.getEntity().getType() != EntityType.PLAYER)
|
||||
return;
|
||||
|
||||
Player attacker;
|
||||
|
|
|
@ -11,22 +11,37 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class PPlayerMovementListener implements Listener {
|
||||
|
||||
private static final int CHECK_INTERVAL = 3;
|
||||
private Map<UUID, Integer> timeSinceLastMovement = new HashMap<>();
|
||||
private Map<UUID, Integer> timeSinceLastMovement;
|
||||
private Map<UUID, Vector> previousVectors;
|
||||
|
||||
public PPlayerMovementListener() {
|
||||
DataManager dataManager = PlayerParticles.getInstance().getManager(DataManager.class);
|
||||
this.timeSinceLastMovement = new HashMap<>();
|
||||
this.previousVectors = new HashMap<>();
|
||||
|
||||
Bukkit.getScheduler().runTaskTimer(PlayerParticles.getInstance(), () -> {
|
||||
if (!Setting.TOGGLE_ON_MOVE.getBoolean())
|
||||
return;
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
UUID playerUUID = player.getUniqueId();
|
||||
Vector previousVector = this.previousVectors.get(playerUUID);
|
||||
Location currentLocation = player.getLocation();
|
||||
Vector currentVector = new Vector(currentLocation.getBlockX(), currentLocation.getBlockY(), currentLocation.getBlockZ());
|
||||
this.previousVectors.put(playerUUID, currentVector);
|
||||
|
||||
if (previousVector == null || !previousVector.equals(currentVector)) {
|
||||
if (!this.timeSinceLastMovement.containsKey(playerUUID)) {
|
||||
this.timeSinceLastMovement.put(playerUUID, 0);
|
||||
} else {
|
||||
this.timeSinceLastMovement.replace(playerUUID, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<UUID> toRemove = new ArrayList<>();
|
||||
|
||||
|
@ -47,27 +62,4 @@ public class PPlayerMovementListener implements Listener {
|
|||
}, 0, CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to detect if the player is moving
|
||||
*
|
||||
* @param event The event
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (!Setting.TOGGLE_ON_MOVE.getBoolean())
|
||||
return;
|
||||
|
||||
Location to = event.getTo();
|
||||
Location from = event.getFrom();
|
||||
if (to == null || (to.getBlockX() == from.getBlockX() && to.getBlockY() == from.getBlockY() && to.getBlockZ() == from.getBlockZ()))
|
||||
return;
|
||||
|
||||
UUID playerUUID = event.getPlayer().getUniqueId();
|
||||
if (!this.timeSinceLastMovement.containsKey(playerUUID)) {
|
||||
this.timeSinceLastMovement.put(playerUUID, 0);
|
||||
} else {
|
||||
this.timeSinceLastMovement.replace(playerUUID, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import dev.esophose.playerparticles.PlayerParticles;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import org.bukkit.Material;
|
||||
|
||||
public abstract class DefaultParticleStyle implements ParticleStyle {
|
||||
|
||||
|
@ -15,18 +17,22 @@ public abstract class DefaultParticleStyle implements ParticleStyle {
|
|||
private String internalStyleName;
|
||||
private boolean canBeFixedByDefault;
|
||||
private boolean canToggleWithMovementByDefault;
|
||||
private boolean canToggleWithCombatByDefault;
|
||||
private double fixedEffectOffsetByDefault;
|
||||
|
||||
private String styleName;
|
||||
private boolean enabled;
|
||||
private boolean canBeFixed;
|
||||
private boolean canToggleWithMovement;
|
||||
private boolean canToggleWithCombat;
|
||||
private double fixedEffectOffset;
|
||||
private Material guiIconMaterial;
|
||||
|
||||
public DefaultParticleStyle(String internalStyleName, boolean canBeFixedByDefault, boolean canToggleWithMovementByDefault, double fixedEffectOffsetByDefault) {
|
||||
this.internalStyleName = internalStyleName;
|
||||
this.canBeFixedByDefault = canBeFixedByDefault;
|
||||
this.canToggleWithMovementByDefault = canToggleWithMovementByDefault;
|
||||
this.canToggleWithCombatByDefault = true;
|
||||
this.fixedEffectOffsetByDefault = fixedEffectOffsetByDefault;
|
||||
this.playerParticles = PlayerParticles.getInstance();
|
||||
|
||||
|
@ -49,7 +55,9 @@ public abstract class DefaultParticleStyle implements ParticleStyle {
|
|||
this.setIfNotExists("enabled", true, "If the style is enabled or not");
|
||||
this.setIfNotExists("can-be-fixed", this.canBeFixedByDefault, "If the style can be used in /pp fixed");
|
||||
this.setIfNotExists("can-toggle-with-movement", this.canToggleWithMovementByDefault, "If the style will only be shown at the player's feet while moving");
|
||||
this.setIfNotExists("can-toggle-with-combat", this.canToggleWithCombatByDefault, "If particles for this style will be hidden if the player is in combat");
|
||||
this.setIfNotExists("fixed-effect-offset", this.fixedEffectOffsetByDefault, "How far vertically to offset the style position for fixed effects");
|
||||
this.setIfNotExists("gui-icon-material", this.getGuiIconMaterialNames(), "The material of the icon to display in the GUI");
|
||||
|
||||
this.setDefaultSettings(this.config);
|
||||
|
||||
|
@ -70,7 +78,9 @@ public abstract class DefaultParticleStyle implements ParticleStyle {
|
|||
this.enabled = this.config.getBoolean("enabled");
|
||||
this.canBeFixed = this.config.getBoolean("can-be-fixed");
|
||||
this.canToggleWithMovement = this.config.getBoolean("can-toggle-with-movement");
|
||||
this.canToggleWithCombat = this.config.getBoolean("can-toggle-with-combat");
|
||||
this.fixedEffectOffset = this.config.getDouble("fixed-effect-offset");
|
||||
this.guiIconMaterial = ParticleUtils.closestMatchWithFallback(true, this.config.getStringList("gui-icon-material").toArray(new String[0]));
|
||||
|
||||
this.loadSettings(this.config);
|
||||
}
|
||||
|
@ -102,14 +112,19 @@ public abstract class DefaultParticleStyle implements ParticleStyle {
|
|||
return this.enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getInternalName() {
|
||||
return this.internalStyleName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getName() {
|
||||
return this.styleName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getInternalName() {
|
||||
return this.internalStyleName;
|
||||
public final Material getGuiIconMaterial() {
|
||||
return this.guiIconMaterial;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -122,11 +137,21 @@ public abstract class DefaultParticleStyle implements ParticleStyle {
|
|||
return this.canToggleWithMovement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean canToggleWithCombat() {
|
||||
return this.canToggleWithCombat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double getFixedEffectOffset() {
|
||||
return this.fixedEffectOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A list of Strings to try to turn into Materials
|
||||
*/
|
||||
protected abstract List<String> getGuiIconMaterialNames();
|
||||
|
||||
/**
|
||||
* Sets the default settings for this style
|
||||
*
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package dev.esophose.playerparticles.styles;
|
||||
|
||||
import dev.esophose.playerparticles.event.ParticleStyleRegistrationEvent;
|
||||
import dev.esophose.playerparticles.manager.ParticleStyleManager;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
public class DefaultStyles {
|
||||
public class DefaultStyles implements Listener {
|
||||
|
||||
/**
|
||||
* All the styles that are available by default from this plugin
|
||||
|
@ -21,6 +24,7 @@ public class DefaultStyles {
|
|||
public static final ParticleStyle COMPANION = new ParticleStyleCompanion();
|
||||
public static final ParticleStyle CUBE = new ParticleStyleCube();
|
||||
public static final ParticleStyle FEET = new ParticleStyleFeet();
|
||||
public static final ParticleStyle FISHING = new ParticleStyleFishing();
|
||||
public static final ParticleStyle HALO = new ParticleStyleHalo();
|
||||
public static final ParticleStyle HURT = new ParticleStyleHurt();
|
||||
public static final ParticleStyle INVOCATION = new ParticleStyleInvocation();
|
||||
|
@ -37,6 +41,7 @@ public class DefaultStyles {
|
|||
public static final ParticleStyle SPIN = new ParticleStyleSpin();
|
||||
public static final ParticleStyle SPIRAL = new ParticleStyleSpiral();
|
||||
public static final ParticleStyle SWORDS = new ParticleStyleSwords();
|
||||
public static final ParticleStyle TELEPORT = new ParticleStyleTeleport();
|
||||
public static final ParticleStyle THICK = new ParticleStyleThick();
|
||||
public static final ParticleStyle TRAIL = new ParticleStyleTrail();
|
||||
public static final ParticleStyle TWINS = new ParticleStyleTwins();
|
||||
|
@ -46,58 +51,65 @@ public class DefaultStyles {
|
|||
public static final ParticleStyle WINGS = new ParticleStyleWings();
|
||||
|
||||
/**
|
||||
* Registers all the default styles to the ParticleStyleManager
|
||||
* Registered in alphabetical order
|
||||
*
|
||||
* @param particleStyleManager The ParticleStyleManager instance
|
||||
* Initializes all the default styles
|
||||
*/
|
||||
public static void registerStyles(ParticleStyleManager particleStyleManager) {
|
||||
particleStyleManager.registerStyle(ARROWS);
|
||||
particleStyleManager.registerStyle(BATMAN);
|
||||
particleStyleManager.registerStyle(BEAM);
|
||||
particleStyleManager.registerEventStyle(BLOCKBREAK);
|
||||
particleStyleManager.registerEventStyle(BLOCKPLACE);
|
||||
particleStyleManager.registerStyle(CELEBRATION);
|
||||
particleStyleManager.registerStyle(CHAINS);
|
||||
particleStyleManager.registerStyle(COMPANION);
|
||||
particleStyleManager.registerStyle(CUBE);
|
||||
particleStyleManager.registerStyle(FEET);
|
||||
particleStyleManager.registerStyle(HALO);
|
||||
particleStyleManager.registerEventStyle(HURT);
|
||||
particleStyleManager.registerStyle(INVOCATION);
|
||||
particleStyleManager.registerEventStyle(MOVE);
|
||||
particleStyleManager.registerStyle(NORMAL);
|
||||
particleStyleManager.registerStyle(ORBIT);
|
||||
particleStyleManager.registerStyle(OVERHEAD);
|
||||
particleStyleManager.registerStyle(POINT);
|
||||
particleStyleManager.registerStyle(POPPER);
|
||||
particleStyleManager.registerStyle(PULSE);
|
||||
particleStyleManager.registerStyle(QUADHELIX);
|
||||
particleStyleManager.registerStyle(RINGS);
|
||||
particleStyleManager.registerStyle(SPHERE);
|
||||
particleStyleManager.registerStyle(SPIN);
|
||||
particleStyleManager.registerStyle(SPIRAL);
|
||||
particleStyleManager.registerEventStyle(SWORDS);
|
||||
particleStyleManager.registerStyle(THICK);
|
||||
particleStyleManager.registerEventStyle(TRAIL);
|
||||
particleStyleManager.registerStyle(TWINS);
|
||||
particleStyleManager.registerStyle(VORTEX);
|
||||
particleStyleManager.registerStyle(WHIRL);
|
||||
particleStyleManager.registerStyle(WHIRLWIND);
|
||||
particleStyleManager.registerStyle(WINGS);
|
||||
public static void initStyles() {
|
||||
// Register event
|
||||
Bukkit.getPluginManager().registerEvents(new DefaultStyles(), PlayerParticles.getInstance());
|
||||
|
||||
// Register their events
|
||||
// Register style events
|
||||
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
PlayerParticles playerParticles = PlayerParticles.getInstance();
|
||||
pluginManager.registerEvents((Listener) ARROWS, playerParticles);
|
||||
pluginManager.registerEvents((Listener) BLOCKBREAK, playerParticles);
|
||||
pluginManager.registerEvents((Listener) BLOCKPLACE, playerParticles);
|
||||
pluginManager.registerEvents((Listener) FISHING, playerParticles);
|
||||
pluginManager.registerEvents((Listener) HURT, playerParticles);
|
||||
pluginManager.registerEvents((Listener) MOVE, playerParticles);
|
||||
pluginManager.registerEvents((Listener) SWORDS, playerParticles);
|
||||
pluginManager.registerEvents((Listener) TELEPORT, playerParticles);
|
||||
pluginManager.registerEvents((Listener) TRAIL, playerParticles);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onParticleStyleRegistration(ParticleStyleRegistrationEvent event) {
|
||||
event.registerStyle(ARROWS);
|
||||
event.registerStyle(BATMAN);
|
||||
event.registerStyle(BEAM);
|
||||
event.registerEventStyle(BLOCKBREAK);
|
||||
event.registerEventStyle(BLOCKPLACE);
|
||||
event.registerStyle(CELEBRATION);
|
||||
event.registerStyle(CHAINS);
|
||||
event.registerStyle(COMPANION);
|
||||
event.registerStyle(CUBE);
|
||||
event.registerStyle(FEET);
|
||||
event.registerStyle(FISHING);
|
||||
event.registerStyle(HALO);
|
||||
event.registerEventStyle(HURT);
|
||||
event.registerStyle(INVOCATION);
|
||||
event.registerEventStyle(MOVE);
|
||||
event.registerStyle(NORMAL);
|
||||
event.registerStyle(ORBIT);
|
||||
event.registerStyle(OVERHEAD);
|
||||
event.registerStyle(POINT);
|
||||
event.registerStyle(POPPER);
|
||||
event.registerStyle(PULSE);
|
||||
event.registerStyle(QUADHELIX);
|
||||
event.registerStyle(RINGS);
|
||||
event.registerStyle(SPHERE);
|
||||
event.registerStyle(SPIN);
|
||||
event.registerStyle(SPIRAL);
|
||||
event.registerEventStyle(SWORDS);
|
||||
event.registerEventStyle(TELEPORT);
|
||||
event.registerStyle(THICK);
|
||||
event.registerEventStyle(TRAIL);
|
||||
event.registerStyle(TWINS);
|
||||
event.registerStyle(VORTEX);
|
||||
event.registerStyle(WHIRL);
|
||||
event.registerStyle(WHIRLWIND);
|
||||
event.registerStyle(WINGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the settings for all default styles
|
||||
*
|
||||
|
|
|
@ -4,8 +4,10 @@ import dev.esophose.playerparticles.manager.ParticleStyleManager;
|
|||
import dev.esophose.playerparticles.particles.PParticle;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.util.ParticleUtils;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
||||
public interface ParticleStyle {
|
||||
|
||||
|
@ -42,6 +44,13 @@ public interface ParticleStyle {
|
|||
return this.getInternalName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Material icon that represents this style in the GUI
|
||||
*/
|
||||
default Material getGuiIconMaterial() {
|
||||
return ParticleUtils.FALLBACK_MATERIAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the style can be used in a FixedParticleEffect
|
||||
*
|
||||
|
@ -50,13 +59,22 @@ public interface ParticleStyle {
|
|||
boolean canBeFixed();
|
||||
|
||||
/**
|
||||
* Gets if the style can be replaced with DefaultStyles.FEET when the player is moving
|
||||
* Gets if the style can be displayed differently based on the toggle-on-move setting when the player is moving
|
||||
*
|
||||
* @return True if it can be, otherwise False
|
||||
*/
|
||||
default boolean canToggleWithMovement() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the style can be hidden if the player is in combat with the toggle-on-combat setting
|
||||
*
|
||||
* @return True if it can be, otherwise False
|
||||
*/
|
||||
default boolean canToggleWithCombat() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Y-axis offset to be applied when using '/pp fixed create looking'
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package dev.esophose.playerparticles.styles;
|
||||
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.particles.PParticle;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
|
@ -15,7 +18,7 @@ import org.bukkit.event.entity.ProjectileLaunchEvent;
|
|||
|
||||
public class ParticleStyleArrows extends DefaultParticleStyle implements Listener {
|
||||
|
||||
private List<Projectile> projectiles = new ArrayList<>();
|
||||
private List<Projectile> projectiles;
|
||||
|
||||
private int maxArrowsPerPlayer;
|
||||
private boolean onlySpawnIfFlying;
|
||||
|
@ -24,6 +27,17 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
|
|||
|
||||
public ParticleStyleArrows() {
|
||||
super("arrows", false, false, 0);
|
||||
|
||||
this.projectiles = new ArrayList<>();
|
||||
|
||||
// Removes all arrows that are considered dead
|
||||
Bukkit.getScheduler().runTaskTimer(PlayerParticles.getInstance(), () -> {
|
||||
for (int i = this.projectiles.size() - 1; i >= 0; i--) {
|
||||
Projectile projectile = this.projectiles.get(i);
|
||||
if ((this.arrowTrackingTime != -1 && projectile.getTicksLived() >= this.arrowTrackingTime) || !projectile.isValid() || projectile.getShooter() == null)
|
||||
this.projectiles.remove(i);
|
||||
}
|
||||
}, 0L, 5L);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,8 +45,9 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
|
|||
List<PParticle> particles = new ArrayList<>();
|
||||
|
||||
int count = 0;
|
||||
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 projectile = this.projectiles.get(i);
|
||||
List<Projectile> listCopy = new ArrayList<>(this.projectiles); // Copy in case of modification while looping due to async
|
||||
for (int i = listCopy.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 projectile = listCopy.get(i);
|
||||
if (this.onlySpawnIfFlying && projectile.isOnGround())
|
||||
continue;
|
||||
|
||||
|
@ -48,16 +63,9 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
|
|||
return particles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all arrows that are considered dead
|
||||
*/
|
||||
@Override
|
||||
public void updateTimers() {
|
||||
for (int i = this.projectiles.size() - 1; i >= 0; i--) {
|
||||
Projectile projectile = this.projectiles.get(i);
|
||||
if ((this.arrowTrackingTime != -1 && projectile.getTicksLived() >= this.arrowTrackingTime) || projectile.isDead() || !projectile.isValid() || projectile.getShooter() == null)
|
||||
this.projectiles.remove(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,6 +73,11 @@ public class ParticleStyleArrows extends DefaultParticleStyle implements Listene
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("BOW");
|
||||
}
|
||||
|
||||
/**
|
||||
* The event used to get all projectiles fired by players
|
||||
* Adds all projectiles fired from players to the array
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.VectorUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
@ -120,6 +121,11 @@ public class ParticleStyleBatman extends DefaultParticleStyle {
|
|||
this.step = (this.step + 1) % this.spawnDelay; // Only spawn once per second
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("BAT_SPAWN_EGG", "COAL");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("spawn-delay", 20, "The number of ticks to wait between particle spawns");
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -46,6 +47,11 @@ public class ParticleStyleBeam extends DefaultParticleStyle {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("POWERED_RAIL");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("points", 16, "The number of points in the circle");
|
||||
|
|
|
@ -8,6 +8,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -43,6 +44,11 @@ public class ParticleStyleBlockBreak extends DefaultParticleStyle implements Lis
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("IRON_PICKAXE");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("particle-amount", 10, "The number of particles to spawn");
|
||||
|
@ -63,11 +69,12 @@ public class ParticleStyleBlockBreak extends DefaultParticleStyle implements Lis
|
|||
|
||||
Player player = event.getPlayer();
|
||||
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
|
||||
if (pplayer != null) {
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKBREAK)) {
|
||||
Location loc = event.getBlock().getLocation().clone();
|
||||
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.BLOCKBREAK.getParticles(particle, loc), false);
|
||||
}
|
||||
if (pplayer == null)
|
||||
return;
|
||||
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKBREAK)) {
|
||||
Location loc = event.getBlock().getLocation().clone();
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.BLOCKBREAK.getParticles(particle, loc), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -43,6 +44,11 @@ public class ParticleStyleBlockPlace extends DefaultParticleStyle implements Lis
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("OAK_PLANKS", "WOOD");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("particle-amount", 10, "The number of particles to spawn");
|
||||
|
@ -63,11 +69,12 @@ public class ParticleStyleBlockPlace extends DefaultParticleStyle implements Lis
|
|||
|
||||
Player player = event.getPlayer();
|
||||
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
|
||||
if (pplayer != null) {
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKPLACE)) {
|
||||
Location loc = event.getBlock().getLocation().clone();
|
||||
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.BLOCKPLACE.getParticles(particle, loc), false);
|
||||
}
|
||||
if (pplayer == null)
|
||||
return;
|
||||
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.BLOCKPLACE)) {
|
||||
Location loc = event.getBlock().getLocation().clone();
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.BLOCKPLACE.getParticles(particle, loc), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
@ -59,7 +61,7 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
|
|||
Random random = new Random();
|
||||
for (PPlayer pplayer : particleManager.getPPlayers()) {
|
||||
Player player = pplayer.getPlayer();
|
||||
if (player != null && player.getGameMode() != GameMode.SPECTATOR && permissionManager.isWorldEnabled(player.getWorld().getName()))
|
||||
if (player != null && (NMSUtil.getVersionNumber() < 8 || player.getGameMode() != GameMode.SPECTATOR) && permissionManager.isWorldEnabled(player.getWorld().getName()))
|
||||
for (ParticlePair particle : pplayer.getActiveParticles())
|
||||
if (particle.getStyle() == this)
|
||||
this.spawnFirework(player.getLocation(), pplayer, pplayer.getPlayer(), particle, random);
|
||||
|
@ -71,6 +73,11 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("FIREWORK_ROCKET", "FIREWORK");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("spawn-frequency", 15, "How many ticks to wait between spawns");
|
||||
|
@ -122,7 +129,7 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
|
|||
trail.setEffect(ParticleStyleCelebration.this.fuseEffect);
|
||||
trail.setStyle(DefaultStyles.CELEBRATION);
|
||||
|
||||
particleManager.displayParticles(player, this.location.getWorld(), trail, Collections.singletonList(new PParticle(this.location)), true);
|
||||
particleManager.displayParticles(pplayer, this.location.getWorld(), trail, Collections.singletonList(new PParticle(this.location)), true);
|
||||
|
||||
this.location.add(0, ParticleStyleCelebration.this.fuseSpacing, 0);
|
||||
} else {
|
||||
|
@ -139,7 +146,7 @@ public class ParticleStyleCelebration extends DefaultParticleStyle {
|
|||
|
||||
particles.add(new PParticle(this.location.clone().add(dx, dy, dz)));
|
||||
}
|
||||
particleManager.displayParticles(player, this.location.getWorld(), particle, particles, true);
|
||||
particleManager.displayParticles(pplayer, this.location.getWorld(), particle, particles, true);
|
||||
|
||||
this.cancel();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import dev.esophose.playerparticles.particles.PParticle;
|
|||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -34,6 +35,11 @@ public class ParticleStyleChains extends DefaultParticleStyle {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("TRIPWIRE_HOOK");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("chain-particle-amount", 8, "The number of particles per chain");
|
||||
|
|
|
@ -28,6 +28,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
@ -71,6 +72,11 @@ public class ParticleStyleCompanion extends DefaultParticleStyle {
|
|||
this.step++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("NAME_TAG");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("particle-amount", 150, "The number of total particles in the animation cycle");
|
||||
|
|
|
@ -28,6 +28,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.VectorUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
@ -96,6 +97,11 @@ public class ParticleStyleCube extends DefaultParticleStyle {
|
|||
this.step++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("STONE");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("edge-length", 2.0, "The length (in blocks) of the edges of the cube");
|
||||
|
|
|
@ -4,6 +4,7 @@ import dev.esophose.playerparticles.particles.PParticle;
|
|||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -31,6 +32,11 @@ public class ParticleStyleFeet extends DefaultParticleStyle {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("GRASS");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("feet-offset", -0.95, "How far to offset the player location vertically");
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package dev.esophose.playerparticles.styles;
|
||||
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.particles.PParticle;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerFishEvent;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
||||
public class ParticleStyleFishing extends DefaultParticleStyle implements Listener {
|
||||
|
||||
// I hate legacy versions. The Spigot API changed the PlayerFishEvent#getHook method from returning a Fish to a FishHook in 1.13
|
||||
private static Method PlayerFishEvent_getHook;
|
||||
static {
|
||||
try {
|
||||
PlayerFishEvent_getHook = PlayerFishEvent.class.getDeclaredMethod("getHook");
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Projectile> projectiles;
|
||||
|
||||
public ParticleStyleFishing() {
|
||||
super("fishing", false, false, 0);
|
||||
|
||||
this.projectiles = new HashSet<>();
|
||||
|
||||
// Removes all fish hooks that are considered dead
|
||||
Bukkit.getScheduler().runTaskTimer(PlayerParticles.getInstance(), () -> this.projectiles.removeIf(x -> !x.isValid()), 0L, 5L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PParticle> getParticles(ParticlePair particle, Location location) {
|
||||
List<PParticle> particles = new ArrayList<>();
|
||||
|
||||
List<Projectile> listCopy = new ArrayList<>(this.projectiles); // Copy in case of modification while looping due to async
|
||||
for (Projectile projectile : listCopy) {
|
||||
ProjectileSource shooter = projectile.getShooter();
|
||||
if (shooter instanceof Player && ((Player) shooter).getUniqueId().equals(particle.getOwnerUniqueId()))
|
||||
particles.add(new PParticle(projectile.getLocation(), 0.05F, 0.05F, 0.05F, 0.0F));
|
||||
}
|
||||
|
||||
return particles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTimers() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("FISHING_ROD");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLongRangeVisibility() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerFish(PlayerFishEvent event) {
|
||||
// Done through a string switch for 1.9.4 compatibility
|
||||
switch (event.getState().toString()) {
|
||||
case "FISHING":
|
||||
try {
|
||||
this.projectiles.add((Projectile) PlayerFishEvent_getHook.invoke(event));
|
||||
} catch (ReflectiveOperationException ignored) { }
|
||||
break;
|
||||
case "CAUGHT_FISH":
|
||||
case "CAUGHT_ENTITY":
|
||||
case "REEL_IN":
|
||||
try {
|
||||
this.projectiles.remove((Projectile) PlayerFishEvent_getHook.invoke(event));
|
||||
} catch (ReflectiveOperationException ignored) { }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadSettings(CommentedFileConfiguration config) {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -43,6 +44,11 @@ public class ParticleStyleHalo extends DefaultParticleStyle {
|
|||
this.skipNextSpawn = !this.skipNextSpawn;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("END_PORTAL_FRAME", "ENDER_PORTAL_FRAME");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("particle-amount", 16, "The number of points in the halo");
|
||||
|
|
|
@ -8,6 +8,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -49,12 +50,17 @@ public class ParticleStyleHurt extends DefaultParticleStyle implements Listener
|
|||
if (pplayer != null) {
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.HURT)) {
|
||||
Location loc = player.getLocation().clone().add(0, 1, 0);
|
||||
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.HURT.getParticles(particle, loc), false);
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.HURT.getParticles(particle, loc), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("CACTUS");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("thick-multiplier", 3, "How much to multiply the particles by", "This style uses the same spawning as the 'thick' style");
|
||||
|
|
|
@ -6,6 +6,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -97,6 +98,11 @@ public class ParticleStyleInvocation extends DefaultParticleStyle {
|
|||
this.circleStep = (this.circleStep + 1) % this.numSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("ENDER_EYE", "EYE_OF_ENDER");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("spinning-points", 6, "The number of points that spin around the circle in each direction");
|
||||
|
|
|
@ -8,6 +8,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -39,6 +40,11 @@ public class ParticleStyleMove extends DefaultParticleStyle implements Listener
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("PISTON", "PISTON_BASE");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("multiplier", 1, "The multiplier for the number of particles to spawn", "This style uses the same spawning as the 'normal' style");
|
||||
|
@ -55,12 +61,13 @@ public class ParticleStyleMove extends DefaultParticleStyle implements Listener
|
|||
|
||||
Player player = event.getPlayer();
|
||||
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
|
||||
if (pplayer != null) {
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.MOVE)) {
|
||||
Location loc = player.getLocation().clone();
|
||||
loc.setY(loc.getY() + 0.05);
|
||||
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.MOVE.getParticles(particle, loc), false);
|
||||
}
|
||||
if (pplayer == null)
|
||||
return;
|
||||
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.MOVE)) {
|
||||
Location loc = player.getLocation().clone();
|
||||
loc.setY(loc.getY() + 0.05);
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.MOVE.getParticles(particle, loc), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
|||
import dev.esophose.playerparticles.particles.PParticle;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -59,6 +60,11 @@ public class ParticleStyleNormal extends DefaultParticleStyle {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("DIRT");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -36,6 +37,11 @@ public class ParticleStyleOrbit extends DefaultParticleStyle {
|
|||
this.step = (this.step + 1) % this.numSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("ENCHANTING_TABLE", "ENCHANTMENT_TABLE");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("orbs", 3, "The number of orbs that orbit the player");
|
||||
|
|
|
@ -4,6 +4,7 @@ import dev.esophose.playerparticles.particles.PParticle;
|
|||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -33,6 +34,11 @@ public class ParticleStyleOverhead extends DefaultParticleStyle {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("GLOWSTONE");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("head-offset", 1.75, "How far to offset the player location vertically");
|
||||
|
|
|
@ -25,6 +25,11 @@ public class ParticleStylePoint extends DefaultParticleStyle {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("STONE_BUTTON");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("player-offset", 1.5, "How far to offset the player location vertically");
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
@ -51,6 +52,11 @@ public class ParticleStylePopper extends DefaultParticleStyle {
|
|||
this.step = (this.step + 1) % this.maxStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("POPPED_CHORUS_FRUIT", "CHORUS_FRUIT_POPPED", "PUMPKIN_SEEDS");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("radius", 1.0, "The radius at the bottom of the vortex");
|
||||
|
|
|
@ -6,6 +6,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -77,6 +78,11 @@ public class ParticleStylePulse extends DefaultParticleStyle {
|
|||
this.step = (this.step + 1) % this.numSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("REDSTONE_TORCH", "REDSTONE_TORCH_ON");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("points", 50, "The number of points to spawn in the pulse circle");
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -51,6 +52,11 @@ public class ParticleStyleQuadhelix extends DefaultParticleStyle {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("NAUTILUS_SHELL", "ACTIVATOR_RAIL");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("orbs", 4, "The number of orbs to spawn");
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -38,6 +39,11 @@ public class ParticleStyleRings extends DefaultParticleStyle {
|
|||
this.step = (this.step + 1) % this.maxStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("LEAD", "LEASH");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("particles-per-ring", 32, "The number of particles that will spawn for each ring");
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -40,6 +41,11 @@ public class ParticleStyleSphere extends DefaultParticleStyle {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("HEART_OF_THE_SEA", "SNOWBALL", "SNOW_BALL");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("density", 15, "The number of particles to spawn per tick");
|
||||
|
|
|
@ -35,6 +35,11 @@ public class ParticleStyleSpin extends DefaultParticleStyle {
|
|||
this.step = (this.step + 1) % this.maxSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("BEACON");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("particles-per-rotation", 30, "The number of particles to spawn per rotation");
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -37,6 +38,11 @@ public class ParticleStyleSpiral extends DefaultParticleStyle {
|
|||
this.stepX++;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("HOPPER");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("particles", 12, "The number of particles to spawn around the player");
|
||||
|
|
|
@ -7,8 +7,10 @@ import dev.esophose.playerparticles.particles.PPlayer;
|
|||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
@ -17,16 +19,18 @@ import org.bukkit.event.EventHandler;
|
|||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class ParticleStyleSwords extends DefaultParticleStyle implements Listener {
|
||||
|
||||
private static final List<String> SWORD_NAMES;
|
||||
private static final List<String> DEFAULT_SWORD_NAMES;
|
||||
|
||||
private int multiplier;
|
||||
private List<String> swordNames;
|
||||
|
||||
static {
|
||||
SWORD_NAMES = new ArrayList<>();
|
||||
SWORD_NAMES.addAll(Arrays.asList("WOOD_SWORD", "STONE_SWORD", "IRON_SWORD", "GOLD_SWORD", "GOLDEN_SWORD", "DIAMOND_SWORD", "TRIDENT"));
|
||||
DEFAULT_SWORD_NAMES = new ArrayList<>();
|
||||
DEFAULT_SWORD_NAMES.addAll(Arrays.asList("WOOD_SWORD", "WOODEN_SWORD", "STONE_SWORD", "IRON_SWORD", "GOLD_SWORD", "GOLDEN_SWORD", "DIAMOND_SWORD", "TRIDENT"));
|
||||
}
|
||||
|
||||
public ParticleStyleSwords() {
|
||||
|
@ -48,14 +52,21 @@ public class ParticleStyleSwords extends DefaultParticleStyle implements Listene
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("IRON_SWORD");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("multiplier", 15, "The multiplier for the number of particles to spawn", "This style uses the same spawning as the 'normal' style");
|
||||
this.setIfNotExists("sword-materials", DEFAULT_SWORD_NAMES, "The materails that are considered swords", "Set to [] to allow everything to be considered a sword", "Use AIR to allow a bare hand to be considered a sword");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadSettings(CommentedFileConfiguration config) {
|
||||
this.multiplier = config.getInt("multiplier");
|
||||
this.swordNames = config.getStringList("sword-materials");
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
|
@ -66,13 +77,32 @@ public class ParticleStyleSwords extends DefaultParticleStyle implements Listene
|
|||
Player player = (Player) event.getDamager();
|
||||
LivingEntity entity = (LivingEntity) event.getEntity();
|
||||
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
|
||||
if (pplayer != null && SWORD_NAMES.contains(player.getInventory().getItemInMainHand().getType().name())) {
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.SWORDS)) {
|
||||
Location loc = entity.getLocation().clone().add(0, 1, 0);
|
||||
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.SWORDS.getParticles(particle, loc), false);
|
||||
}
|
||||
if (pplayer == null)
|
||||
return;
|
||||
|
||||
if (NMSUtil.getVersionNumber() > 8) {
|
||||
if (!this.isSword(player.getInventory().getItemInMainHand()))
|
||||
return;
|
||||
} else {
|
||||
if (!this.isSword(player.getInventory().getItemInHand()))
|
||||
return;
|
||||
}
|
||||
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.SWORDS)) {
|
||||
Location loc = entity.getLocation().clone().add(0, 1, 0);
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.SWORDS.getParticles(particle, loc), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSword(ItemStack itemStack) {
|
||||
if (this.swordNames.isEmpty())
|
||||
return true;
|
||||
|
||||
if (itemStack == null)
|
||||
return this.swordNames.contains("AIR");
|
||||
|
||||
return this.swordNames.contains(itemStack.getType().name());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
package dev.esophose.playerparticles.styles;
|
||||
|
||||
import dev.esophose.playerparticles.PlayerParticles;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.manager.DataManager;
|
||||
import dev.esophose.playerparticles.manager.ParticleManager;
|
||||
import dev.esophose.playerparticles.particles.PParticle;
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
|
||||
public class ParticleStyleTeleport extends DefaultParticleStyle implements Listener {
|
||||
|
||||
private boolean before;
|
||||
private boolean after;
|
||||
|
||||
private float amount;
|
||||
private float spread;
|
||||
private float speed;
|
||||
|
||||
public ParticleStyleTeleport() {
|
||||
super("teleport", false, false, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PParticle> getParticles(ParticlePair particle, Location location) {
|
||||
List<PParticle> particles = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < this.amount; i++)
|
||||
particles.add(new PParticle(location, this.spread, this.spread, this.spread, this.speed));
|
||||
|
||||
return particles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTimers() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("ENDER_PEARL");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("before", true, "Spawn the particles at the teleporting position");
|
||||
this.setIfNotExists("after", true, "Spawn the particles after the teleport in the new position");
|
||||
this.setIfNotExists("amount", 25, "The number of particles to spawn");
|
||||
this.setIfNotExists("spread", 0.5, "How much to spread the particles");
|
||||
this.setIfNotExists("speed", 0.05, "If the particle supports speed, how much speed to apply");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadSettings(CommentedFileConfiguration config) {
|
||||
this.before = config.getBoolean("before");
|
||||
this.after = config.getBoolean("after");
|
||||
this.amount = config.getFloat("amount");
|
||||
this.spread = config.getFloat("spread");
|
||||
this.speed = config.getFloat("speed");
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event) {
|
||||
TeleportCause cause = event.getCause();
|
||||
if (cause == TeleportCause.UNKNOWN)
|
||||
return;
|
||||
|
||||
ParticleManager particleManager = PlayerParticles.getInstance().getManager(ParticleManager.class);
|
||||
|
||||
Player player = event.getPlayer();
|
||||
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
|
||||
if (pplayer == null)
|
||||
return;
|
||||
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.TELEPORT)) {
|
||||
if (this.before) {
|
||||
Location loc1 = player.getLocation().clone();
|
||||
loc1.setY(loc1.getY() + 1);
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc1), false);
|
||||
}
|
||||
|
||||
if (this.after) {
|
||||
Bukkit.getScheduler().runTaskLater(PlayerParticles.getInstance(), () -> {
|
||||
Location loc2 = player.getLocation().clone();
|
||||
loc2.setY(loc2.getY() + 1);
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TELEPORT.getParticles(particle, loc2), false);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import dev.esophose.playerparticles.particles.PParticle;
|
|||
import dev.esophose.playerparticles.particles.ParticlePair;
|
||||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -30,6 +31,11 @@ public class ParticleStyleThick extends DefaultParticleStyle {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("COBWEB", "WEB");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("multiplier", 1, "The multiplier for the number of particles to spawn", "This style uses the same spawning as the 'normal' style");
|
||||
|
|
|
@ -36,6 +36,11 @@ public class ParticleStyleTrail extends DefaultParticleStyle implements Listener
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("GHAST_TEAR");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("player-offset", 0.0, "How far to offset the player location vertically");
|
||||
|
@ -56,12 +61,13 @@ public class ParticleStyleTrail extends DefaultParticleStyle implements Listener
|
|||
|
||||
Player player = event.getPlayer();
|
||||
PPlayer pplayer = PlayerParticles.getInstance().getManager(DataManager.class).getPPlayer(player.getUniqueId());
|
||||
if (pplayer != null) {
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.TRAIL)) {
|
||||
Location loc = player.getLocation().clone();
|
||||
loc.setY(loc.getY() + 1);
|
||||
particleManager.displayParticles(player, player.getWorld(), particle, DefaultStyles.TRAIL.getParticles(particle, loc), false);
|
||||
}
|
||||
if (pplayer == null)
|
||||
return;
|
||||
|
||||
for (ParticlePair particle : pplayer.getActiveParticlesForStyle(DefaultStyles.TRAIL)) {
|
||||
Location loc = player.getLocation().clone();
|
||||
loc.setY(loc.getY() + 1);
|
||||
particleManager.displayParticles(pplayer, player.getWorld(), particle, DefaultStyles.TRAIL.getParticles(particle, loc), false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -56,6 +57,11 @@ public class ParticleStyleTwins extends DefaultParticleStyle {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("OAK_FENCE", "FENCE");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("orbs", 2, "The number of particle orbs to spawn");
|
||||
|
|
|
@ -28,6 +28,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
@ -66,6 +67,11 @@ public class ParticleStyleVortex extends DefaultParticleStyle {
|
|||
this.step = (this.step + 1) % this.maxStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("GLOWSTONE_DUST");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("radius", 2.0, "The bottom radius of the vortex");
|
||||
|
|
|
@ -6,6 +6,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -74,6 +75,11 @@ public class ParticleStyleWhirl extends DefaultParticleStyle {
|
|||
this.step = (this.step + Math.PI * 2 / this.numSteps) % this.numSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("FEATHER");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("rays", 2, "The number of rays to spawn");
|
||||
|
|
|
@ -6,6 +6,7 @@ import dev.esophose.playerparticles.particles.ParticlePair;
|
|||
import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
||||
import dev.esophose.playerparticles.util.MathL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
|
@ -74,6 +75,11 @@ public class ParticleStyleWhirlwind extends DefaultParticleStyle {
|
|||
this.step = (this.step + Math.PI * 2 / this.numSteps) % this.numSteps;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Collections.singletonList("STRING");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("rays", 3, "The number of rays to spawn");
|
||||
|
|
|
@ -6,6 +6,8 @@ import dev.esophose.playerparticles.config.CommentedFileConfiguration;
|
|||
import dev.esophose.playerparticles.util.MathL;
|
||||
import dev.esophose.playerparticles.util.VectorUtils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.util.Vector;
|
||||
|
@ -41,6 +43,11 @@ public class ParticleStyleWings extends DefaultParticleStyle {
|
|||
this.spawnTimer %= this.spawnDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> getGuiIconMaterialNames() {
|
||||
return Arrays.asList("ELYTRA", "RAW_CHICKEN");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultSettings(CommentedFileConfiguration config) {
|
||||
this.setIfNotExists("spawn-delay", 3, "The number of ticks to wait between particle spawns");
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
package dev.esophose.playerparticles.util;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
@ -27,6 +24,8 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
/**
|
||||
* bStats collects some data for plugin authors.
|
||||
|
@ -34,7 +33,7 @@ import org.bukkit.plugin.ServicePriority;
|
|||
* Check out https://bStats.org/ to learn more about bStats!
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||
public class Metrics {
|
||||
public class LegacyMetrics {
|
||||
|
||||
static {
|
||||
// You can use the property to disable the check in your test environment
|
||||
|
@ -44,7 +43,7 @@ public class Metrics {
|
|||
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
|
||||
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
|
||||
// We want to make sure nobody just copy & pastes the example and use the wrong package names
|
||||
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
if (LegacyMetrics.class.getPackage().getName().equals(defaultPackage) || LegacyMetrics.class.getPackage().getName().equals(examplePackage)) {
|
||||
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +78,7 @@ public class Metrics {
|
|||
*
|
||||
* @param plugin The plugin which stats should be submitted.
|
||||
*/
|
||||
public Metrics(Plugin plugin) {
|
||||
public LegacyMetrics(Plugin plugin) {
|
||||
if (plugin == null) {
|
||||
throw new IllegalArgumentException("Plugin cannot be null!");
|
||||
}
|
||||
|
@ -119,10 +118,8 @@ public class Metrics {
|
|||
// Load the data
|
||||
serverUUID = config.getString("serverUuid");
|
||||
logFailedRequests = config.getBoolean("logFailedRequests", false);
|
||||
this.enabled = config.getBoolean("enabled", true);
|
||||
logSentData = config.getBoolean("logSentData", false);
|
||||
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
|
||||
if (this.enabled) {
|
||||
enabled = config.getBoolean("enabled", true);
|
||||
if (enabled) {
|
||||
boolean found = false;
|
||||
// Search for all other bStats Metrics classes to see if we are the first one
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
|
@ -133,10 +130,10 @@ public class Metrics {
|
|||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
// Register our service
|
||||
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
|
||||
Bukkit.getServicesManager().register(LegacyMetrics.class, this, plugin, ServicePriority.Normal);
|
||||
if (!found) {
|
||||
// We are the first!
|
||||
this.startSubmitting();
|
||||
startSubmitting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +144,7 @@ public class Metrics {
|
|||
* @return Whether bStats is enabled or not.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return this.enabled;
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,13 +155,13 @@ public class Metrics {
|
|||
timer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!Metrics.this.plugin.isEnabled()) { // Plugin was disabled
|
||||
if (!plugin.isEnabled()) { // Plugin was disabled
|
||||
timer.cancel();
|
||||
return;
|
||||
}
|
||||
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
|
||||
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
|
||||
Bukkit.getScheduler().runTask(Metrics.this.plugin, Metrics.this::submitData);
|
||||
Bukkit.getScheduler().runTask(plugin, () -> submitData());
|
||||
}
|
||||
}, 1000 * 60 * 5, 1000 * 60 * 30);
|
||||
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
|
||||
|
@ -178,15 +175,16 @@ public class Metrics {
|
|||
*
|
||||
* @return The plugin specific data.
|
||||
*/
|
||||
public JsonObject getPluginData() {
|
||||
JsonObject data = new JsonObject();
|
||||
public JSONObject getPluginData() {
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
String pluginName = this.plugin.getDescription().getName();
|
||||
String pluginVersion = this.plugin.getDescription().getVersion();
|
||||
String pluginName = plugin.getDescription().getName();
|
||||
String pluginVersion = plugin.getDescription().getVersion();
|
||||
|
||||
data.addProperty("pluginName", pluginName); // Append the name of the plugin
|
||||
data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
data.add("customCharts", new JsonArray());
|
||||
data.put("pluginName", pluginName); // Append the name of the plugin
|
||||
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
|
||||
JSONArray customCharts = new JSONArray();
|
||||
data.put("customCharts", customCharts);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -196,7 +194,7 @@ public class Metrics {
|
|||
*
|
||||
* @return The server specific data.
|
||||
*/
|
||||
private JsonObject getServerData() {
|
||||
private JSONObject getServerData() {
|
||||
// Minecraft specific data
|
||||
int playerAmount;
|
||||
try {
|
||||
|
@ -211,7 +209,6 @@ public class Metrics {
|
|||
}
|
||||
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
|
||||
String bukkitVersion = Bukkit.getVersion();
|
||||
String bukkitName = Bukkit.getName();
|
||||
|
||||
// OS/Java specific data
|
||||
String javaVersion = System.getProperty("java.version");
|
||||
|
@ -220,20 +217,19 @@ public class Metrics {
|
|||
String osVersion = System.getProperty("os.version");
|
||||
int coreCount = Runtime.getRuntime().availableProcessors();
|
||||
|
||||
JsonObject data = new JsonObject();
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
data.addProperty("serverUUID", serverUUID);
|
||||
data.put("serverUUID", serverUUID);
|
||||
|
||||
data.addProperty("playerAmount", playerAmount);
|
||||
data.addProperty("onlineMode", onlineMode);
|
||||
data.addProperty("bukkitVersion", bukkitVersion);
|
||||
data.addProperty("bukkitName", bukkitName);
|
||||
data.put("playerAmount", playerAmount);
|
||||
data.put("onlineMode", onlineMode);
|
||||
data.put("bukkitVersion", bukkitVersion);
|
||||
|
||||
data.addProperty("javaVersion", javaVersion);
|
||||
data.addProperty("osName", osName);
|
||||
data.addProperty("osArch", osArch);
|
||||
data.addProperty("osVersion", osVersion);
|
||||
data.addProperty("coreCount", coreCount);
|
||||
data.put("javaVersion", javaVersion);
|
||||
data.put("osName", osName);
|
||||
data.put("osArch", osArch);
|
||||
data.put("osVersion", osVersion);
|
||||
data.put("coreCount", coreCount);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -242,9 +238,9 @@ public class Metrics {
|
|||
* Collects the data and sends it afterwards.
|
||||
*/
|
||||
private void submitData() {
|
||||
final JsonObject data = this.getServerData();
|
||||
final JSONObject data = getServerData();
|
||||
|
||||
JsonArray pluginData = new JsonArray();
|
||||
JSONArray pluginData = new JSONArray();
|
||||
// Search for all other bStats Metrics classes to get their plugin data
|
||||
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
|
||||
try {
|
||||
|
@ -252,43 +248,27 @@ public class Metrics {
|
|||
|
||||
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
|
||||
try {
|
||||
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
|
||||
if (plugin instanceof JsonObject) {
|
||||
pluginData.add((JsonObject) plugin);
|
||||
} else { // old bstats version compatibility
|
||||
try {
|
||||
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
|
||||
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
|
||||
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
|
||||
jsonStringGetter.setAccessible(true);
|
||||
String jsonString = (String) jsonStringGetter.invoke(plugin);
|
||||
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
|
||||
pluginData.add(object);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
// minecraft version 1.14+
|
||||
if (logFailedRequests) {
|
||||
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
|
||||
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException ignored) { }
|
||||
}
|
||||
|
||||
data.add("plugins", pluginData);
|
||||
data.put("plugins", pluginData);
|
||||
|
||||
// Create a new thread for the connection to the bStats server
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(this.plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
this.plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + this.plugin.getName(), e);
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// Send the data
|
||||
sendData(plugin, data);
|
||||
} catch (Exception e) {
|
||||
// Something went wrong! :(
|
||||
if (logFailedRequests) {
|
||||
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
@ -301,7 +281,7 @@ public class Metrics {
|
|||
* @param data The data to send.
|
||||
* @throws Exception If the request failed.
|
||||
*/
|
||||
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
|
||||
private static void sendData(Plugin plugin, JSONObject data) throws Exception {
|
||||
if (data == null) {
|
||||
throw new IllegalArgumentException("Data cannot be null!");
|
||||
}
|
|
@ -40,4 +40,16 @@ public final class NMSUtil {
|
|||
return cachedVersionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the server is running Spigot or a fork, false otherwise
|
||||
*/
|
||||
public static boolean isSpigot() {
|
||||
try {
|
||||
Class.forName("org.spigotmc.SpigotConfig");
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,10 +6,17 @@ import org.apache.commons.lang.WordUtils;
|
|||
import org.bukkit.Material;
|
||||
|
||||
public final class ParticleUtils {
|
||||
|
||||
|
||||
public final static Material FALLBACK_MATERIAL;
|
||||
private static List<String> blockMaterials, itemMaterials;
|
||||
|
||||
static {
|
||||
if (NMSUtil.getVersionNumber() > 7) {
|
||||
FALLBACK_MATERIAL = Material.BARRIER;
|
||||
} else {
|
||||
FALLBACK_MATERIAL = Material.BEDROCK;
|
||||
}
|
||||
|
||||
blockMaterials = new ArrayList<>();
|
||||
itemMaterials = new ArrayList<>();
|
||||
|
||||
|
@ -43,19 +50,19 @@ public final class ParticleUtils {
|
|||
* Finds a block/item as a material from a list of possible strings
|
||||
* Contains a fallback to the barrier icon just in case
|
||||
*
|
||||
* @param barrierFallback If the material should fall back to barrier
|
||||
* @param fallback If the material should fall back to barrier
|
||||
* @param input A list of material names
|
||||
* @return The first matching material
|
||||
*/
|
||||
public static Material closestMatchWithFallback(boolean barrierFallback, String... input) {
|
||||
public static Material closestMatchWithFallback(boolean fallback, String... input) {
|
||||
for (String name : input) {
|
||||
Material mat = closestMatch(name);
|
||||
if (mat != null)
|
||||
return mat;
|
||||
}
|
||||
|
||||
if (barrierFallback)
|
||||
return Material.BARRIER;
|
||||
if (fallback)
|
||||
return FALLBACK_MATERIAL;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ package dev.esophose.playerparticles.util.inputparser;
|
|||
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.ParticleEffect;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.styles.ParticleStyle;
|
||||
import dev.esophose.playerparticles.util.inputparser.parsable.ParsableMaterial;
|
||||
import dev.esophose.playerparticles.util.inputparser.parsable.ParsableNoteColor;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package dev.esophose.playerparticles.util.inputparser.parsable;
|
||||
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.util.NMSUtil;
|
||||
import dev.esophose.playerparticles.util.inputparser.Parsable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -9,10 +12,22 @@ import org.bukkit.Location;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ParsableLocation extends Parsable<Location> {
|
||||
|
||||
private static Method LivingEntity_getTargetBlock;
|
||||
static {
|
||||
if (NMSUtil.getVersionNumber() < 8) {
|
||||
try {
|
||||
LivingEntity_getTargetBlock = LivingEntity.class.getDeclaredMethod("getTargetBlock", HashSet.class, int.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ParsableLocation() {
|
||||
super(Location.class);
|
||||
}
|
||||
|
@ -23,7 +38,18 @@ public class ParsableLocation extends Parsable<Location> {
|
|||
|
||||
Player player = pplayer.getPlayer();
|
||||
if (player != null && input.equalsIgnoreCase("looking")) {
|
||||
Block targetBlock = player.getTargetBlock((Set<Material>) null, 8); // Need the Set<Material> cast for 1.9 support
|
||||
Block targetBlock;
|
||||
if (NMSUtil.getVersionNumber() > 7) {
|
||||
targetBlock = player.getTargetBlock((Set<Material>) null, 8); // Need the Set<Material> cast for 1.9 support
|
||||
} else {
|
||||
try {
|
||||
targetBlock = (Block) LivingEntity_getTargetBlock.invoke(player, null, 8);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
targetBlock = player.getLocation().getBlock();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
int maxDistanceSqrd = 6 * 6;
|
||||
if (targetBlock.getLocation().distanceSquared(player.getLocation()) > maxDistanceSqrd)
|
||||
return null; // Looking at a block too far away
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package dev.esophose.playerparticles.util.inputparser.parsable;
|
||||
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.color.NoteColor;
|
||||
import dev.esophose.playerparticles.particles.data.NoteColor;
|
||||
import dev.esophose.playerparticles.util.inputparser.Parsable;
|
||||
import java.util.List;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package dev.esophose.playerparticles.util.inputparser.parsable;
|
||||
|
||||
import dev.esophose.playerparticles.particles.PPlayer;
|
||||
import dev.esophose.playerparticles.particles.color.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.particles.data.OrdinaryColor;
|
||||
import dev.esophose.playerparticles.util.inputparser.Parsable;
|
||||
import java.awt.Color;
|
||||
import java.util.Collections;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
name: PlayerParticles
|
||||
main: dev.esophose.playerparticles.PlayerParticles
|
||||
version: @version@
|
||||
api-version: 1.13
|
||||
version: '@version@'
|
||||
api-version: '1.13'
|
||||
description: Display particles around your player and blocks using customized styles and data!
|
||||
author: Esophose
|
||||
website: https://www.spigotmc.org/resources/playerparticles.40261/
|
||||
softdepend: [PlaceholderAPI]
|
||||
softdepend: [PlaceholderAPI, WorldGuard, WorldEdit]
|
||||
commands:
|
||||
pp:
|
||||
description: The main PlayerParticles command. By default, opens the GUI.
|
||||
|
|
|
@ -51,7 +51,7 @@ raincloud:
|
|||
style: 'overhead'
|
||||
data: ''
|
||||
2:
|
||||
effect: 'rain'
|
||||
effect: 'dripping_water'
|
||||
style: 'overhead'
|
||||
data: ''
|
||||
rainbows:
|
||||
|
|
|
@ -10,7 +10,7 @@ For information about how to use the plugin or API within the plugin, please ref
|
|||
### Server Compatibility
|
||||
This plugin is compatible with [Spigot](https://www.spigotmc.org/) and any forks, I recommend using [Paper](https://papermc.io/).
|
||||
Using CraftBukkit will not work.
|
||||
The versions of Minecraft that are currently supported are 1.9.4-1.15.x. Support for 1.8.8 will not be added.
|
||||
The versions of Minecraft that are currently supported are `1.15.2-1.7.10`.
|
||||
|
||||
### Compilation
|
||||
|
||||
|
|
|
@ -51,6 +51,11 @@ dependencies {
|
|||
|
||||
shadowJar {
|
||||
archiveClassifier.set(null)
|
||||
|
||||
relocate('org.bstats', 'dev.esophose.playerparticles.libs.bstats')
|
||||
relocate('org.slf4j', 'dev.esophose.playerparticles.libs.slf4j')
|
||||
relocate('com.zaxxer.hikari', 'dev.esophose.playerparticles.libs.hikaricp')
|
||||
relocate('org.codemc.worldguardwrapper', 'dev.esophose.playerparticles.libs.worldguardwrapper')
|
||||
}
|
||||
|
||||
jar {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
rootProject.name = 'PlayerParticles'
|
||||
rootProject.name = 'playerparticles'
|
||||
|
||||
include(':Plugin')
|
||||
project(':Plugin').projectDir = file('Plugin')
|
||||
|
|
Loading…
Reference in a new issue