diff --git a/build.gradle b/build.gradle index 600dfad..fb7afbe 100644 --- a/build.gradle +++ b/build.gradle @@ -4,9 +4,8 @@ plugins { id 'idea' id 'com.github.johnrengelman.shadow' version '4.0.4' } - group = 'me.skymc' -version = '4.73' +version = '4.75' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -28,11 +27,11 @@ dependencies { exclude(module: 'slf4j-log4j12') exclude(module: 'log4j') } - compile group: 'com.google.code.gson', name: 'gson', version: '2.7' shadow group: 'com.zaxxer', name: 'HikariCP', version: '3.1.0' shadow group: 'org.javalite', name: 'activejdbc', version: '2.0' + compile group: 'org.ow2.asm', name: 'asm', version: '7.0-beta' + compile group: 'com.google.code.gson', name: 'gson', version: '2.7' shadow group: 'com.h2database', name: 'h2', version: '1.4.197' - compile group: 'org.ow2.asm', name: 'asm', version: '6.1.1' shadow group: 'me.clip', name: 'placeholderapi', version: '2.8.4' shadow group: 'net.objecthunter', name: 'exp4j', version: '0.4.8' shadow group: 'org.scala-lang', name: 'scala-library', version: '2.12.8' @@ -42,4 +41,17 @@ dependencies { shadowJar { // 免得 MANIFEST.MF 里面刷一堆 lib 难看 taskActions.removeIf { it.actionClassName.contains 'configureShadowTask' } +} + +processResources { + inputs.property "version", project.version + + from(sourceSets.main.resources.srcDirs) { + include 'plugin.yml' + expand 'version': project.version + } + + from(sourceSets.main.resources.srcDirs) { + exclude 'plugin.yml' + } } \ No newline at end of file diff --git a/src/main/resources/Addons/TabooLibDeprecated b/src/main/resources/Addons/TabooLibDeprecated index 5d14287..bf21513 100644 Binary files a/src/main/resources/Addons/TabooLibDeprecated and b/src/main/resources/Addons/TabooLibDeprecated differ diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7e12bd5..71b5d29 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: TabooLib main: me.skymc.taboolib.Main -version: ${project.version} +version: ${version} authors: - 坏黑 diff --git a/src/main/scala/com/ilummc/eagletdl/AlreadyStartException.java b/src/main/scala/com/ilummc/eagletdl/AlreadyStartException.java index 13919a0..2e1e0bc 100644 --- a/src/main/scala/com/ilummc/eagletdl/AlreadyStartException.java +++ b/src/main/scala/com/ilummc/eagletdl/AlreadyStartException.java @@ -1,4 +1,5 @@ package com.ilummc.eagletdl; public class AlreadyStartException extends RuntimeException { + } diff --git a/src/main/scala/com/ilummc/tlib/util/Ref.java b/src/main/scala/com/ilummc/tlib/util/Ref.java index c896491..bd9c35b 100644 --- a/src/main/scala/com/ilummc/tlib/util/Ref.java +++ b/src/main/scala/com/ilummc/tlib/util/Ref.java @@ -12,7 +12,6 @@ import sun.reflect.Reflection; import javax.annotation.concurrent.ThreadSafe; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; diff --git a/src/main/scala/com/ilummc/tlibscala/runtime/RichPlayer.scala b/src/main/scala/com/ilummc/tlibscala/runtime/RichPlayer.scala index 213c576..448a8b7 100644 --- a/src/main/scala/com/ilummc/tlibscala/runtime/RichPlayer.scala +++ b/src/main/scala/com/ilummc/tlibscala/runtime/RichPlayer.scala @@ -32,9 +32,9 @@ class RichPlayer(private val player: Player) extends RichOfflinePlayer(player) { def displaySidebarUnranked(title: String, elements: String*): Unit = ScoreboardUtil.unrankedSidebarDisplay(player, elements: _*) - @deprecated def openSign(block: Block): Unit = SignUtils.openSign(player, block) + def openSign(block: Block): Unit = SignUtils.openSign(player, block) - @deprecated def openSign(lines: Array[String], id: String): Unit = SignUtils.openSign(player, lines, id) + def openSign(lines: Array[String], id: String): Unit = SignUtils.openSign(player, lines, id) //todo TagDataHandler @@ -42,11 +42,9 @@ class RichPlayer(private val player: Player) extends RichOfflinePlayer(player) { def removePermission(perm: String): Unit = PermissionUtils.removePermission(player, perm) - def sendTitle(title: String, subtitle: String, fadein: Int, stay: Int, fadeout: Int): Unit = - TitleUtils.sendTitle(player, title, subtitle, fadein, stay, fadeout) + def sendTitle(title: String, subtitle: String, fadein: Int, stay: Int, fadeout: Int): Unit = TitleUtils.sendTitle(player, title, subtitle, fadein, stay, fadeout) - def sendTitle(p: Player, title: String, fadeint: Int, stayt: Int, fadeoutt: Int, subtitle: String, fadeinst: Int, stayst: Int, fadeoutst: Int): Unit = - TitleUtils.sendTitle(p, title, fadeint, stayt, fadeoutt, subtitle, fadeinst, stayst, fadeoutst) + def sendTitle(p: Player, title: String, fadeint: Int, stayt: Int, fadeoutt: Int, subtitle: String, fadeinst: Int, stayst: Int, fadeoutst: Int): Unit = TitleUtils.sendTitle(p, title, fadeint, stayt, fadeoutt, subtitle, fadeinst, stayst, fadeoutst) def openAnvil(): Unit = AnvilContainerAPI.openAnvil(player) diff --git a/src/main/scala/me/skymc/taboolib/Main.java b/src/main/scala/me/skymc/taboolib/Main.java index c036d92..627ab6e 100644 --- a/src/main/scala/me/skymc/taboolib/Main.java +++ b/src/main/scala/me/skymc/taboolib/Main.java @@ -17,7 +17,6 @@ import me.skymc.taboolib.playerdata.DataUtils; import me.skymc.taboolib.socket.TabooLibClient; import me.skymc.taboolib.socket.TabooLibServer; import me.skymc.taboolib.string.language2.Language2; -import me.skymc.taboolib.update.UpdateTask; import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; @@ -141,10 +140,6 @@ public class Main extends JavaPlugin { started = true; // 载入语言文件 exampleLanguage2 = new Language2("Language2", this); - // 更新检测 - if (!TabooLib.isSilent()) { - new UpdateTask(); - } } @Override diff --git a/src/main/scala/me/skymc/taboolib/TabooLibLoader.java b/src/main/scala/me/skymc/taboolib/TabooLibLoader.java index 115cb10..8d4ada2 100644 --- a/src/main/scala/me/skymc/taboolib/TabooLibLoader.java +++ b/src/main/scala/me/skymc/taboolib/TabooLibLoader.java @@ -154,15 +154,18 @@ public class TabooLibLoader implements Listener { static void setupDatabase() { DataUtils.addPluginData("TabooLibrary", null); - Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL); - TabooLibDatabase.init(); + Main.setStorageType(Main.StorageType.LOCAL); +// Main.setStorageType(Main.getInst().getConfig().getBoolean("MYSQL.ENABLE") ? Main.StorageType.SQL : Main.StorageType.LOCAL); +// TabooLibDatabase.init(); } static void setupAddons() { TabooLib.instance().saveResource("Addons/TabooLibDeprecated", true); // 傻逼 Gradle 的 shadow 插件会将所有 jar 排除 // https://github.com/johnrengelman/shadow/issues/276 - new File(TabooLib.instance().getDataFolder(), "Addons/TabooLibDeprecated").renameTo(new File(TabooLib.instance().getDataFolder(), "Addons/TabooLibDeprecated.jar")); + File from = new File(TabooLib.instance().getDataFolder(), "Addons/TabooLibDeprecated"); + from.renameTo(new File(TabooLib.instance().getDataFolder(), "Addons/TabooLibDeprecated.jar")); + from.delete(); File file = new File(TabooLib.instance().getDataFolder(), "Addons"); if (file.exists()) { Arrays.stream(file.listFiles()).forEach(listFile -> TDependencyLoader.addToPath(TabooLib.instance(), listFile)); diff --git a/src/main/scala/me/skymc/taboolib/client/LogClient.java b/src/main/scala/me/skymc/taboolib/client/LogClient.java deleted file mode 100644 index 2daf023..0000000 --- a/src/main/scala/me/skymc/taboolib/client/LogClient.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.skymc.taboolib.client; - -import javax.swing.*; -import javax.swing.border.BevelBorder; -import java.awt.*; -import java.text.SimpleDateFormat; - -@Deprecated -public class LogClient extends JFrame { - - /** - * DEFAULT VERSION UID - */ - private static final long serialVersionUID = 1L; - private JTextArea textArea = new JTextArea(); - private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); - - public LogClient(String title) { - super(title); - - // DEFAULT CLOSE OPERATION - setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - - // SETTINGS - final JScrollPane scrollPane = new JScrollPane(); - scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED)); - scrollPane.setViewportView(textArea); - getContentPane().add(scrollPane, BorderLayout.CENTER); - - setSize(700, 500); - setVisible(true); - - // CON'T EDIT - textArea.setEditable(false); - textArea.setFont(new Font("黑体", 0, 18)); - - textArea.setBackground(Color.black); - textArea.setForeground(Color.LIGHT_GRAY); - - addString(title); - addString(""); - } - - public void addString(String a) { - textArea.append(a + '\n'); - textArea.setSelectionStart(textArea.getText().length()); - } - - public void info(String a) { - textArea.append("[" + sdf.format(System.currentTimeMillis()) + " INFO]: " + a + '\n'); - textArea.setSelectionStart(textArea.getText().length()); - } - - public void warn(String a) { - textArea.append("[" + sdf.format(System.currentTimeMillis()) + " WARN]: " + a + '\n'); - textArea.setSelectionStart(textArea.getText().length()); - } -} diff --git a/src/main/scala/me/skymc/taboolib/cloud/TCloudLoader.java b/src/main/scala/me/skymc/taboolib/cloud/TCloudLoader.java index 4be5c95..c498e7f 100644 --- a/src/main/scala/me/skymc/taboolib/cloud/TCloudLoader.java +++ b/src/main/scala/me/skymc/taboolib/cloud/TCloudLoader.java @@ -9,6 +9,7 @@ import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.cloud.expansion.Expansion; import me.skymc.taboolib.cloud.expansion.ExpansionType; import me.skymc.taboolib.common.function.TFunction; +import me.skymc.taboolib.common.schedule.TSchedule; import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.plugin.PluginUtils; import org.bukkit.Bukkit; @@ -41,6 +42,7 @@ public class TCloudLoader { } } + @TSchedule(async = true, period = 20 * 60 * 60) public static void refresh() { Bukkit.getScheduler().runTaskAsynchronously(TabooLib.instance(), () -> { long time = System.currentTimeMillis(); diff --git a/src/main/scala/me/skymc/taboolib/commands/SubCommand.java b/src/main/scala/me/skymc/taboolib/commands/SubCommand.java deleted file mode 100644 index a4397bb..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/SubCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.skymc.taboolib.commands; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -@Deprecated -public abstract class SubCommand { - - public CommandSender sender; - public String[] args; - - public boolean returnValue = false; - - public SubCommand(CommandSender sender, String[] args) { - this.sender = sender; - this.args = args; - } - - public boolean setReturn(boolean returnValue) { - return this.returnValue = returnValue; - } - - public boolean isPlayer() { - return sender instanceof Player; - } - - public boolean command() { - return returnValue; - } - - public String getArgs(int size) { - return IntStream.range(size, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim(); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/SubCommandExecutor.java b/src/main/scala/me/skymc/taboolib/commands/SubCommandExecutor.java deleted file mode 100644 index 2633b0a..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/SubCommandExecutor.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.skymc.taboolib.commands; - -import org.bukkit.command.CommandSender; - -@Deprecated -public interface SubCommandExecutor { - - boolean command(CommandSender sender, String[] args); - -} diff --git a/src/main/scala/me/skymc/taboolib/commands/TabooLibMainCommand.java b/src/main/scala/me/skymc/taboolib/commands/TabooLibMainCommand.java index 6582ea4..c95429c 100644 --- a/src/main/scala/me/skymc/taboolib/commands/TabooLibMainCommand.java +++ b/src/main/scala/me/skymc/taboolib/commands/TabooLibMainCommand.java @@ -116,6 +116,11 @@ public class TabooLibMainCommand extends BaseMainCommand { @CommandRegister(priority = 3) BaseSubCommand itemInfo = new BaseSubCommand() { + @Override + public boolean hideInHelp() { + return true; + } + @Override public String getLabel() { return "itemInfo"; diff --git a/src/main/scala/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java b/src/main/scala/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java index caefc18..de03b95 100644 --- a/src/main/scala/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java +++ b/src/main/scala/me/skymc/taboolib/commands/builder/SimpleCommandBuilder.java @@ -1,6 +1,7 @@ package me.skymc.taboolib.commands.builder; import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import me.skymc.taboolib.commands.builder.type.CompleterCommand; import me.skymc.taboolib.commands.builder.type.CompleterTab; import me.skymc.taboolib.commands.internal.TCommandHandler; @@ -119,8 +120,22 @@ public class SimpleCommandBuilder { aliases, permission, permissionMessage, - (sender, command, s, args) -> completerCommand.execute(sender, args), - (sender, command, s, args) -> completerTab.execute(sender, args), + (sender, command, s, args) -> { + try { + return completerCommand.execute(sender, args); + } catch (Throwable t) { + t.printStackTrace(); + } + return false; + }, + (sender, command, s, args) -> { + try { + return completerTab.execute(sender, args); + } catch (Throwable t) { + t.printStackTrace(); + } + return Lists.newArrayList(); + }, silence); build = true; return this; diff --git a/src/main/scala/me/skymc/taboolib/commands/language/Language2Command.java b/src/main/scala/me/skymc/taboolib/commands/language/Language2Command.java deleted file mode 100644 index 6cc56cc..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/language/Language2Command.java +++ /dev/null @@ -1,78 +0,0 @@ -package me.skymc.taboolib.commands.language; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.commands.builder.SimpleCommandBuilder; -import me.skymc.taboolib.common.loader.Instantiable; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018年2月13日 下午5:11:01 - */ -@Instantiable("Language2Command") -public class Language2Command { - - public Language2Command() { - SimpleCommandBuilder.create("language2", TabooLib.instance()) - .aliases("lang2") - .permission("taboolib.admin") - .execute((sender, args) -> { - if (args.length == 0) { - TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.HELP", "langauge2"); - } else if ("reload".equalsIgnoreCase(args[0])) { - reload(sender); - } else if ("send".equalsIgnoreCase(args[0])) { - send(sender, args); - } - return true; - }).build(); - } - - private void send(CommandSender sender, String[] args) { - if (args.length < 3) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - } else { - long time = System.currentTimeMillis(); - Language2Value value = getLanguage2Value(args); - - if ("ALL".equalsIgnoreCase(args[1])) { - value.broadcast(); - } else { - Player player = Bukkit.getPlayerExact(args[1]); - if (player == null) { - TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.INVALID-PLAYER", args[1]); - } else { - value.send(player); - } - } - - if (sender instanceof Player && ((Player) sender).getItemInHand().getType().equals(Material.COMMAND)) { - TLocale.sendTo(sender, "COMMANDS.LANGUAGE2.SUCCESS-SEND", String.valueOf(System.currentTimeMillis() - time)); - } - } - } - - private Language2Value getLanguage2Value(String[] args) { - Language2Value value = Main.getExampleLanguage2().get(args[2]); - if (args.length > 3) { - int i = 0; - for (String variable : args[3].split("\\|")) { - value.addPlaceholder("$" + i++, variable); - } - } - return value; - } - - private void reload(CommandSender sender) { - TLocale.sendTo(sender, "COMMANDS.RELOAD.LOADING"); - long time = System.currentTimeMillis(); - Main.getExampleLanguage2().reload(); - TLocale.sendTo(sender, "COMMANDS.RELOAD.SUCCESS-ELAPSED-TIME", String.valueOf(System.currentTimeMillis() - time)); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/AttributesCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/AttributesCommand.java deleted file mode 100644 index 1ec3bf4..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/AttributesCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import org.bukkit.command.CommandSender; - -import java.util.Arrays; - -public class AttributesCommand extends SubCommand { - - public AttributesCommand(CommandSender sender, String[] args) { - super(sender, args); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ATTRIBUTES.HEAD"); - - Arrays.stream(new String[]{"damage", "speed", "attackspeed", "health", "knockback", "armor", "luck"}).forEach(attribute -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ATTRIBUTES.BODY", attribute)); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ATTRIBUTES.FOOT"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/EnchantCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/EnchantCommand.java deleted file mode 100644 index b0331eb..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/EnchantCommand.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import org.bukkit.command.CommandSender; -import org.bukkit.enchantments.Enchantment; - -import java.util.Arrays; - -public class EnchantCommand extends SubCommand { - - @SuppressWarnings("deprecation") - public EnchantCommand(CommandSender sender, String[] args) { - super(sender, args); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.HEAD"); - - Arrays.stream(Enchantment.values()).forEach(enchant -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.BODY", String.valueOf(enchant.getId()), enchant.getName())); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.FOOT"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/FlagCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/FlagCommand.java deleted file mode 100644 index 05af222..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/FlagCommand.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import org.bukkit.command.CommandSender; -import org.bukkit.inventory.ItemFlag; - -import java.util.Arrays; - -public class FlagCommand extends SubCommand { - - public FlagCommand(CommandSender sender, String[] args) { - super(sender, args); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.FLAGS.HEAD"); - - Arrays.stream(ItemFlag.values()).forEach(itemFlag -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ENCHANTS.BODY", itemFlag.name())); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.FLAGS.FOOT"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/ImportCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/ImportCommand.java deleted file mode 100644 index 077e847..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/ImportCommand.java +++ /dev/null @@ -1,50 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.Main.StorageType; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.fileutils.ConfigUtils; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.util.Objects; - -public class ImportCommand extends SubCommand { - - public ImportCommand(CommandSender sender, String[] args) { - super(sender, args); - - if (isPlayer()) { - TLocale.sendTo(sender, "COMMANDS.GLOBAL.ONLY-PLAYER"); - return; - } - - if (Main.getStorageType() == StorageType.LOCAL) { - TLocale.Logger.warn("COMMANDS.GLOBAL.ONLY-STORAGE-SQL"); - return; - } - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.CLEARING"); - Main.getConnection().truncateTable(Main.getTablePrefix() + "_playerdata"); - - if (!Main.getPlayerDataFolder().exists()) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.EMPTYDATA"); - return; - } - - int size = Objects.requireNonNull(Main.getPlayerDataFolder().listFiles()).length; - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.IMPORTING-START", String.valueOf(size)); - - int loop = 1; - for (File file : Objects.requireNonNull(Main.getPlayerDataFolder().listFiles())) { - Main.getConnection().intoValue(Main.getTablePrefix() + "_playerdata", file.getName().replace(".yml", ""), ConfigUtils.encodeYAML(YamlConfiguration.loadConfiguration(file))); - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.IMPORTING-PROGRESS", file.getName().replace(".yml", ""), String.valueOf(loop), String.valueOf(size)); - loop++; - } - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.IMPORTDATA.SUCCESS"); - } - -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/InfoCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/InfoCommand.java deleted file mode 100644 index 1eae955..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/InfoCommand.java +++ /dev/null @@ -1,31 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.itemnbtapi.NBTItem; -import me.skymc.taboolib.json.JSONReader; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -public class InfoCommand extends SubCommand { - - @SuppressWarnings("deprecation") - public InfoCommand(CommandSender sender, String[] args) { - super(sender, args); - if (isPlayer()) { - Player player = (Player) sender; - if (player.getItemInHand().getType().equals(Material.AIR)) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.INVALID-ITEM"); - } else { - NBTItem nbt = new NBTItem(player.getItemInHand()); - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.INFO.ITEM-INFO", - player.getItemInHand().getType().name(), - ItemUtils.getCustomName(player.getItemInHand()), - player.getItemInHand().getTypeId() + ":" + player.getItemInHand().getDurability(), - JSONReader.formatJson(nbt.asNBTString())); - } - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/ItemCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/ItemCommand.java deleted file mode 100644 index 7d13386..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/ItemCommand.java +++ /dev/null @@ -1,63 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.other.NumberUtils; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.HashMap; - -public class ItemCommand extends SubCommand { - - public ItemCommand(CommandSender sender, String[] args) { - super(sender, args); - - if (args.length < 2) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-NAME"); - return; - } - - if (ItemUtils.getCacheItem(args[1]) == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-ITEM", args[1]); - return; - } - - Player player; - Integer amount = 1; - ItemStack item = ItemUtils.getCacheItem(args[1]).clone(); - - if (args.length > 2) { - player = Bukkit.getPlayerExact(args[2]); - if (player == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-PLAYER", args[2]); - return; - } - } else if (sender instanceof Player) { - player = (Player) sender; - } else { - TLocale.sendTo(sender, "COMMANDS.GLOBAL.ONLY-PLAYER"); - return; - } - - if (args.length > 3) { - amount = NumberUtils.getInteger(args[3]); - if (amount < 1) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.INVALID-NUMBER"); - return; - } - } - item.setAmount(amount); - - HashMap map = player.getInventory().addItem(item); - if (map.size() > 0) { - player.getWorld().dropItem(player.getLocation(), item); - } - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.ITEM.SUCCESS", player.getName()); - setReturn(true); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/ItemListCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/ItemListCommand.java deleted file mode 100644 index dcf062d..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/ItemListCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.commands.taboolib.listener.ListenerItemListCommand; -import me.skymc.taboolib.other.NumberUtils; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018年2月4日 下午8:08:22 - */ -public class ItemListCommand extends SubCommand { - - public ItemListCommand(CommandSender sender, String[] args) { - super(sender, args); - if (isPlayer()) { - if (args.length == 1) { - ListenerItemListCommand.openInventory((Player) sender, 1); - } else { - ListenerItemListCommand.openInventory((Player) sender, NumberUtils.getInteger(args[1])); - } - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/PotionCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/PotionCommand.java deleted file mode 100644 index cdd3e3c..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/PotionCommand.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import org.bukkit.command.CommandSender; -import org.bukkit.potion.PotionEffectType; - -public class PotionCommand extends SubCommand { - - @SuppressWarnings("deprecation") - public PotionCommand(CommandSender sender, String[] args) { - super(sender, args); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.POTIONS.HEAD"); - - for (PotionEffectType potionEffectType : PotionEffectType.values()) { - if (potionEffectType != null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.POTIONS.BODY", String.valueOf(potionEffectType.getId()), potionEffectType.getName()); - } - } - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.POTIONS.FOOT"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/SaveCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/SaveCommand.java deleted file mode 100644 index 667d84a..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/SaveCommand.java +++ /dev/null @@ -1,89 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.Main; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.fileutils.ConfigUtils; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.message.ChatCatcher; -import me.skymc.taboolib.message.ChatCatcher.Catcher; -import me.skymc.taboolib.message.MsgUtils; -import me.skymc.taboolib.playerdata.DataUtils; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -/** - * @author sky - */ -public class SaveCommand extends SubCommand { - - public SaveCommand(CommandSender sender, String[] args) { - super(sender, args); - if (!(sender instanceof Player)) { - TLocale.sendTo(sender, "COMMANDS.GLOBAL.ONLY-PLAYER"); - return; - } - - if (args.length < 2) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.INVALID-NAME"); - return; - } - - if (((Player) sender).getItemInHand().getType().equals(Material.AIR)) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.INVALID-ITEM"); - return; - } - - if (ItemUtils.getItemCachesFinal().containsKey(args[1])) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.INVALID-ITEM-FINAL-EXISTS"); - return; - } - - if (ItemUtils.getItemCaches().containsKey(args[1])) { - // 检查聊天引导 - if (ChatCatcher.contains((Player) sender)) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-EXISTS"); - return; - } - - ChatCatcher.call((Player) sender, new Catcher() { - - @Override - public void cancel() { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-QUIT"); - } - - @Override - public Catcher before() { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-BEFORE", args[1]); - return this; - } - - @SuppressWarnings("deprecation") - @Override - public boolean after(String message) { - if ("yes".equalsIgnoreCase(message)) { - saveItem(args[1], ((Player) sender).getItemInHand()); - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.SUCCESS", args[1]); - } else { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SAVE.GUIDE-QUIT"); - } - return false; - } - }); - } else { - saveItem(args[1], ((Player) sender).getItemInHand()); - MsgUtils.send(sender, "物品 &f" + args[1] + " &7已保存"); - } - } - - private void saveItem(String name, ItemStack item) { - FileConfiguration conf = ConfigUtils.load(Main.getInst(), ItemUtils.getItemCacheFile()); - conf.set(name + ".bukkit", item); - DataUtils.saveConfiguration(conf, ItemUtils.getItemCacheFile()); - ItemUtils.reloadItemCache(); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/SlotCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/SlotCommand.java deleted file mode 100644 index 4897a70..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/SlotCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import org.bukkit.command.CommandSender; - -import java.util.Arrays; - -public class SlotCommand extends SubCommand { - - public SlotCommand(CommandSender sender, String[] args) { - super(sender, args); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SLOTS.HEAD"); - - Arrays.stream(new String[]{"mainhand", "offhand", "feet", "legs", "chest", "head", "all"}).forEach(slots -> TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SLOTS.BODY", slots)); - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.SLOTS.FOOT"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/SoundsCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/SoundsCommand.java deleted file mode 100644 index 2d2f63f..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/SoundsCommand.java +++ /dev/null @@ -1,27 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.commands.taboolib.listener.ListenerSoundsCommand; -import me.skymc.taboolib.other.NumberUtils; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018-03-18 21:02:26 - */ -public class SoundsCommand extends SubCommand { - - public SoundsCommand(CommandSender sender, String[] args) { - super(sender, args); - if (isPlayer()) { - if (args.length == 1) { - ListenerSoundsCommand.openInventory((Player) sender, 1, null); - } else if (args.length == 2) { - ListenerSoundsCommand.openInventory((Player) sender, NumberUtils.getInteger(args[1]), null); - } else { - ListenerSoundsCommand.openInventory((Player) sender, NumberUtils.getInteger(args[1]), args[2]); - } - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagDeleteCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/TagDeleteCommand.java deleted file mode 100644 index 1e7d565..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagDeleteCommand.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.itagapi.TagDataHandler; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018-03-19 23:13:35 - */ -public class TagDeleteCommand extends SubCommand { - - public TagDeleteCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length < 2) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - return; - } - - Player player = Bukkit.getPlayerExact(args[1]); - if (player == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]); - return; - } - - TagDataHandler.getHandler().reset(player); - - if (sender instanceof Player) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-DELETE", args[1]); - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagDisplayCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/TagDisplayCommand.java deleted file mode 100644 index 8808e6d..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagDisplayCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.itagapi.TagDataHandler; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018-03-19 23:13:35 - */ -public class TagDisplayCommand extends SubCommand { - - public TagDisplayCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length < 3) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - return; - } - - Player player = Bukkit.getPlayerExact(args[1]); - if (player == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]); - return; - } - - String value = TLocale.Translate.setPlaceholders(player, getArgs(2)); - TagDataHandler.getHandler().setDisplay(player, value); - - if (sender instanceof Player) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-DISPLAY-SET", args[1], value); - } - } - -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagPrefixCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/TagPrefixCommand.java deleted file mode 100644 index 895be34..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagPrefixCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.itagapi.TagDataHandler; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018-03-19 23:13:35 - */ -public class TagPrefixCommand extends SubCommand { - - public TagPrefixCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length < 3) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - return; - } - - Player player = Bukkit.getPlayerExact(args[1]); - if (player == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]); - return; - } - - String value = TLocale.Translate.setPlaceholders(player, getArgs(2)); - TagDataHandler.getHandler().setPrefix(player, value); - - if (sender instanceof Player) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-PREFIX-SET", args[1], value); - } - } - -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagSuffixCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/TagSuffixCommand.java deleted file mode 100644 index 08d5b9f..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/TagSuffixCommand.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.itagapi.TagDataHandler; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018-03-19 23:13:35 - */ -public class TagSuffixCommand extends SubCommand { - - public TagSuffixCommand(CommandSender sender, String[] args) { - super(sender, args); - if (args.length < 3) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.UNKNOWN"); - return; - } - - Player player = Bukkit.getPlayerExact(args[1]); - if (player == null) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.INVALID-PLAYER", args[1]); - return; - } - - String value = TLocale.Translate.setPlaceholders(player, getArgs(2)); - TagDataHandler.getHandler().setSuffix(player, value); - - if (sender instanceof Player) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.PLAYERTAG.SUCCESS-SUFFIX-SET", args[1], value); - } - } - -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/VariableGetCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/VariableGetCommand.java deleted file mode 100644 index 7688b43..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/VariableGetCommand.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.database.GlobalDataManager; -import org.bukkit.command.CommandSender; - -/** - * @author sky - */ -public class VariableGetCommand extends SubCommand { - - public VariableGetCommand(CommandSender sender, String[] args) { - super(sender, args); - - if (args.length < 3) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.INSUFFICIENT"); - return; - } - - if (!("-a".equals(args[1]) || "-s".equals(args[1]))) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.READ-ERROR-TYPE"); - return; - } - - Long time = System.currentTimeMillis(); - String value = null; - - if ("-s".equals(args[1])) { - value = GlobalDataManager.getVariable(args[2], null); - } else if ("-a".equals(args[1])) { - value = GlobalDataManager.getVariableAsynchronous(args[2], null); - } - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.READ-SUCCESS", String.valueOf(System.currentTimeMillis() - time)); - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.READ-RESULT", value == null ? "null" : value); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/VariableSetCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/VariableSetCommand.java deleted file mode 100644 index d1f9634..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/VariableSetCommand.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.skymc.taboolib.commands.taboolib; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.commands.SubCommand; -import me.skymc.taboolib.database.GlobalDataManager; -import org.bukkit.command.CommandSender; - -public class VariableSetCommand extends SubCommand { - - public VariableSetCommand(CommandSender sender, String[] args) { - super(sender, args); - - if (args.length < 4) { - TLocale.sendTo(sender, "COMMANDS.PARAMETER.INSUFFICIENT"); - return; - } - - if (!("-a".equals(args[1]) || "-s".equals(args[1]))) { - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.WRITE-ERROR-TYPE"); - return; - } - - Long time = System.currentTimeMillis(); - String value = getArgs(3); - - if ("-s".equals(args[1])) { - GlobalDataManager.setVariable(args[2], value); - } else if ("-a".equals(args[1])) { - GlobalDataManager.setVariableAsynchronous(args[2], value); - } - - TLocale.sendTo(sender, "COMMANDS.TABOOLIB.VARIABLE.WRITE-SUCCESS", String.valueOf(System.currentTimeMillis() - time)); - setReturn(true); - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java deleted file mode 100644 index 0346b2f..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/listener/ListenerItemListCommand.java +++ /dev/null @@ -1,107 +0,0 @@ -package me.skymc.taboolib.commands.taboolib.listener; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.inventory.InventoryUtil; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.listener.TListener; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; - -/** - * @author sky - * @since 2018年2月4日 下午4:35:00 - */ -@TListener -public class ListenerItemListCommand implements Listener { - - /** - * 打开物品库界面 - * - * @param player - * @param page - */ - public static void openInventory(Player player, int page) { - ItemLibraryHolder holder = new ItemLibraryHolder(page); - Inventory inventory = Bukkit.createInventory(holder, 54, TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.MENU.TITLE", String.valueOf(page))); - - LinkedHashMap map = new LinkedHashMap<>(); - map.putAll(ItemUtils.getItemCachesFinal()); - map.putAll(ItemUtils.getItemCaches()); - - int loop = 0; - for (String name : map.keySet()) { - if (loop >= (page - 1) * 28) { - if (loop < page * 28) { - int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 28)); - ItemStack item = map.get(name).clone(); - ItemMeta meta = item.getItemMeta(); - List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); - lore.addAll(TLocale.asStringList("COMMANDS.TABOOLIB.ITEMLIST.MENU.LORE", name)); - meta.setLore(lore); - item.setItemMeta(meta); - inventory.setItem(slot, item); - holder.ITEMS_DATA.put(slot, name); - } else { - break; - } - } - loop++; - } - - if (page > 1) { - inventory.setItem(47, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.MENU.BACK"))); - } - if (((int) Math.ceil(map.size() / 28D)) > page) { - inventory.setItem(51, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.ITEMLIST.MENU.NEXT"))); - } - player.openInventory(inventory); - } - - @EventHandler - public void inventoryClick(InventoryClickEvent e) { - if (e.getInventory().getHolder() instanceof ItemLibraryHolder) { - e.setCancelled(true); - - if (e.getCurrentItem() == null || e.getCurrentItem().getType().equals(Material.AIR) || e.getRawSlot() >= e.getInventory().getSize()) { - return; - } - - int i = e.getRawSlot(); - if (i == 47) { - openInventory((Player) e.getWhoClicked(), ((ItemLibraryHolder) e.getInventory().getHolder()).PAGE - 1); - } else if (i == 51) { - openInventory((Player) e.getWhoClicked(), ((ItemLibraryHolder) e.getInventory().getHolder()).PAGE + 1); - } else { - e.getWhoClicked().getInventory().addItem(ItemUtils.getCacheItem(((ItemLibraryHolder) e.getInventory().getHolder()).ITEMS_DATA.get(e.getRawSlot()))); - } - } - } - - public static class ItemLibraryHolder implements InventoryHolder { - - public final int PAGE; - public final HashMap ITEMS_DATA = new HashMap<>(); - - public ItemLibraryHolder(int page) { - this.PAGE = page; - } - - @Override - public Inventory getInventory() { - return null; - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java b/src/main/scala/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java deleted file mode 100644 index 3c42a88..0000000 --- a/src/main/scala/me/skymc/taboolib/commands/taboolib/listener/ListenerSoundsCommand.java +++ /dev/null @@ -1,119 +0,0 @@ -package me.skymc.taboolib.commands.taboolib.listener; - -import com.ilummc.tlib.resources.TLocale; -import me.skymc.taboolib.inventory.InventoryUtil; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.listener.TListener; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.stream.Collectors; - -/** - * @author sky - * @since 2018年2月4日 下午4:35:00 - */ -@TListener -public class ListenerSoundsCommand implements Listener { - - public static void openInventory(Player player, int page, String search) { - if (page < 1) { - page = 1; - } - - SoundLibraryHolder holder = new SoundLibraryHolder(page, search); - Inventory inventory = Bukkit.createInventory(holder, 54, TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.TITLE", String.valueOf(page))); - List soundFilter = Arrays.stream(Sound.values()).filter(sound -> search == null || sound.name().contains(search.toUpperCase())).collect(Collectors.toList()); - List soundLore = TLocale.asStringList("COMMANDS.TABOOLIB.SOUNDS.MENU.LORE"); - - int loop = 0; - for (Sound sound : soundFilter) { - if (loop >= (page - 1) * 28) { - if (loop < page * 28) { - int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 28)); - ItemStack item = new ItemStack(Material.MAP); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName("§f§n" + sound); - meta.setLore(soundLore); - item.setItemMeta(meta); - inventory.setItem(slot, item); - holder.SOUNDS_DATA.put(slot, sound); - } else { - break; - } - } - loop++; - } - - if (page > 1) { - inventory.setItem(47, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.BACK"))); - } - if (((int) Math.ceil(Sound.values().length / 28D)) > page) { - inventory.setItem(51, ItemUtils.setName(new ItemStack(Material.ARROW), TLocale.asString("COMMANDS.TABOOLIB.SOUNDS.MENU.NEXT"))); - } - - if (!(player.getOpenInventory().getTopInventory().getHolder() instanceof SoundLibraryHolder)) { - TLocale.sendTo(player, "COMMANDS.TABOOLIB.SOUNDS.RESULT.SEARCH", (search == null ? "*" : search), String.valueOf(soundFilter.size())); - } - player.openInventory(inventory); - } - - @EventHandler - public void inventoryClick(InventoryClickEvent e) { - if (e.getInventory().getHolder() instanceof SoundLibraryHolder) { - e.setCancelled(true); - - if (e.getCurrentItem() == null || e.getCurrentItem().getType().equals(Material.AIR) || e.getRawSlot() >= e.getInventory().getSize()) { - return; - } - - SoundLibraryHolder soundLibraryHolder = ((SoundLibraryHolder) e.getInventory().getHolder()); - int i = e.getRawSlot(); - if (i == 47) { - openInventory((Player) e.getWhoClicked(), soundLibraryHolder.PAGE - 1, soundLibraryHolder.SEARCH); - } else if (i == 51) { - openInventory((Player) e.getWhoClicked(), soundLibraryHolder.PAGE + 1, soundLibraryHolder.SEARCH); - } else { - Sound sound = soundLibraryHolder.SOUNDS_DATA.get(e.getRawSlot()); - if (e.getClick().isKeyboardClick()) { - ((Player) e.getWhoClicked()).playSound(e.getWhoClicked().getLocation(), sound, 1f, 0f); - } else if (e.getClick().isLeftClick()) { - ((Player) e.getWhoClicked()).playSound(e.getWhoClicked().getLocation(), sound, 1f, 1f); - } else if (e.getClick().isRightClick()) { - ((Player) e.getWhoClicked()).playSound(e.getWhoClicked().getLocation(), sound, 1f, 2f); - } else if (e.getClick().isCreativeAction()) { - TLocale.sendTo(e.getWhoClicked(), "COMMANDS.TABOOLIB.SOUNDS.RESULT.COPY", sound.name()); - } - } - } - } - - public static class SoundLibraryHolder implements InventoryHolder { - - public final int PAGE; - public final String SEARCH; - public final HashMap SOUNDS_DATA = new HashMap<>(); - - public SoundLibraryHolder(int page, String search) { - this.PAGE = page; - this.SEARCH = search; - } - - @Override - public Inventory getInventory() { - return null; - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/common/inject/TInjectLoader.java b/src/main/scala/me/skymc/taboolib/common/inject/TInjectLoader.java index 7151031..c8907bd 100644 --- a/src/main/scala/me/skymc/taboolib/common/inject/TInjectLoader.java +++ b/src/main/scala/me/skymc/taboolib/common/inject/TInjectLoader.java @@ -20,7 +20,7 @@ import java.util.Map; */ public class TInjectLoader implements TabooLibLoader.Loader { - private static Map, TInjectTask> injectTypes = Maps.newHashMap(); + private static Map, TInjectTask> injectTypes = Maps.newLinkedHashMap(); static { // Instance Inject @@ -50,11 +50,7 @@ public class TInjectLoader implements TabooLibLoader.Loader { // TConfiguration Inject injectTypes.put(TConfiguration.class, (plugin, field, args, instance) -> { try { - if (args.length == 0) { - TLogger.getGlobalLogger().error("Invalid inject arguments: " + field.getName() + " (" + field.getType().getName() + ")"); - } else { - field.set(instance, TConfiguration.createInResource(plugin, args[0])); - } + field.set(instance, TConfiguration.createInResource(plugin, args.length == 0 ? "config.yml" : args[0])); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java b/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java index 51749e6..008fd74 100644 --- a/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java +++ b/src/main/scala/me/skymc/taboolib/common/nms/NMSHandler.java @@ -1,7 +1,5 @@ package me.skymc.taboolib.common.nms; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.commands.builder.SimpleCommandBuilder; import me.skymc.taboolib.common.function.TFunction; import me.skymc.taboolib.common.versioncontrol.SimpleVersionControl; import org.bukkit.entity.Player; @@ -21,11 +19,6 @@ public abstract class NMSHandler { } catch (Exception e) { e.printStackTrace(); } - SimpleCommandBuilder.create("title", TabooLib.instance()) - .execute((sender, args) -> { - handler.sendTitle((Player) sender, "TabooLib", 10, 40, 10, "author Bkm016", 10, 40, 10); - return true; - }).build(); } abstract public void sendTitle(Player player, String title, int titleFadein, int titleStay, int titleFadeout, String subtitle, int subtitleFadein, int subtitleStay, int subtitleFadeout); diff --git a/src/main/scala/me/skymc/taboolib/common/serialize/TSerializable.java b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializable.java new file mode 100644 index 0000000..2529adf --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializable.java @@ -0,0 +1,20 @@ +package me.skymc.taboolib.common.serialize; + +/** + * @Author 坏黑 + * @Since 2019-03-08 17:28 + */ +public interface TSerializable { + + void read(String fieldName, String value); + + String write(String fieldName, Object value); + + default void read(String value) { + TSerializer.read(this, value); + } + + default String write() { + return TSerializer.write(this); + } +} \ No newline at end of file diff --git a/src/main/scala/me/skymc/taboolib/common/serialize/TSerializer.java b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializer.java new file mode 100644 index 0000000..d89ce4b --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializer.java @@ -0,0 +1,149 @@ +package me.skymc.taboolib.common.serialize; + +import ch.njol.skript.classes.ConfigurationSerializer; +import com.google.gson.*; +import org.bukkit.configuration.serialization.ConfigurationSerializable; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Optional; + +/** + * @Author 坏黑 + * @Since 2019-03-08 17:31 + */ +public class TSerializer { + + public static T read(String value, Class type) { + return ConfigurationSerializer.deserializeCS(value, type); + } + + public static TSerializable read(TSerializable serializable, String serializedString) { + try { + JsonObject jsonObject = (JsonObject) new JsonParser().parse(serializedString); + if (jsonObject.has("serializeObject")) { + JsonObject serializeObject = jsonObject.getAsJsonObject("serializeObject"); + for (Map.Entry jsonElementEntry : serializeObject.entrySet()) { + try { + Field declaredField = serializable.getClass().getDeclaredField(jsonElementEntry.getKey()); + declaredField.setAccessible(true); + Optional serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(declaredField.getType())).findFirst(); + if (serializer.isPresent()) { + declaredField.set(serializable, serializer.get().getSerializer().read(jsonElementEntry.getValue().getAsString())); + } else { + serializable.read(jsonElementEntry.getKey(), jsonElementEntry.getValue().getAsString()); + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + } catch (Throwable t) { + t.printStackTrace(); + } + return serializable; + } + + public static String write(ConfigurationSerializable serializable) { + return ConfigurationSerializer.serializeCS(serializable); + } + + public static String write(TSerializable serializable) { + JsonObject jsonObject = new JsonObject(); + JsonObject serializeObject = new JsonObject(); + for (Field declaredField : serializable.getClass().getDeclaredFields()) { + try { + if (!Modifier.isStatic(declaredField.getModifiers())) { + declaredField.setAccessible(true); + Optional serializer = Arrays.stream(TSerializerElementGeneral.values()).filter(serializerElements -> serializerElements.getSerializer().matches(declaredField.getType())).findFirst(); + Object o = declaredField.get(serializable); + if (o == null) { + continue; + } + if (serializer.isPresent()) { + serializeObject.addProperty(declaredField.getName(), serializer.get().getSerializer().write(o)); + } else { + Optional.ofNullable(serializable.write(declaredField.getName(), o)).ifPresent(value -> serializeObject.addProperty(declaredField.getName(), value)); + } + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + jsonObject.add("serializeObject", serializeObject); + return jsonObject.toString(); + } + + public static void readMap(Map map, String serializedString, TSerializerElementGeneral elementKey, TSerializerElementGeneral elementValue) { + readMap(map, serializedString, elementKey.getSerializer(), elementValue.getSerializer()); + } + + public static void readMap(Map map, String serializedString, TSerializerElement elementKey, TSerializerElement elementValue) { + try { + JsonObject jsonObject = (JsonObject) new JsonParser().parse(serializedString); + for (Map.Entry jsonElementEntry : jsonObject.entrySet()) { + try { + map.put(elementKey.read(jsonElementEntry.getKey()), elementValue.read(jsonElementEntry.getValue().getAsString())); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static String writeMap(Map map, TSerializerElementGeneral elementKey, TSerializerElementGeneral elementValue) { + return writeMap(map, elementKey.getSerializer(), elementValue.getSerializer()); + } + + public static String writeMap(Map map, TSerializerElement elementKey, TSerializerElement elementValue) { + JsonObject jsonObject = new JsonObject(); + for (Map.Entry entry : map.entrySet()) { + try { + jsonObject.addProperty(elementKey.write(entry.getKey()), elementValue.write(entry.getValue())); + } catch (Throwable t) { + t.printStackTrace(); + } + } + return jsonObject.toString(); + } + + public static void readCollection(Collection collection, String serializedString, TSerializerElementGeneral elementValue) { + readCollection(collection, serializedString, elementValue.getSerializer()); + } + + public static void readCollection(Collection collection, String serializedString, TSerializerElement elementValue) { + try { + JsonArray jsonArray = (JsonArray) new JsonParser().parse(serializedString); + for (JsonElement jsonElement : jsonArray) { + try { + collection.add(elementValue.read(jsonElement.getAsString())); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } catch (Throwable t) { + t.printStackTrace(); + } + } + + public static String writeCollection(Collection collection, TSerializerElementGeneral elementValue) { + return writeCollection(collection, elementValue.getSerializer()); + } + + public static String writeCollection(Collection collection, TSerializerElement elementValue) { + JsonArray jsonArray = new JsonArray(); + for (Object object : collection) { + try { + jsonArray.add(new JsonPrimitive(elementValue.write(object))); + } catch (Throwable t) { + t.printStackTrace(); + } + } + return jsonArray.toString(); + } +} diff --git a/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerElement.java b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerElement.java new file mode 100644 index 0000000..3232eab --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerElement.java @@ -0,0 +1,15 @@ +package me.skymc.taboolib.common.serialize; + +/** + * @Author 坏黑 + * @Since 2019-03-08 17:28 + */ +public interface TSerializerElement { + + T read(String value); + + String write(Object value); + + boolean matches(Class objectClass); + +} \ No newline at end of file diff --git a/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerElementGeneral.java b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerElementGeneral.java new file mode 100644 index 0000000..c6bd743 --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerElementGeneral.java @@ -0,0 +1,217 @@ +package me.skymc.taboolib.common.serialize; + +import ch.njol.skript.classes.ConfigurationSerializer; +import me.skymc.taboolib.other.NumberUtils; +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import java.util.Objects; + +/** + * @Author 坏黑 + * @Since 2019-03-10 18:49 + */ +public enum TSerializerElementGeneral { + + STRING(new TSerializerElement() { + + @Override + public String read(String value) { + return String.valueOf(value); + } + + @Override + public String write(Object value) { + return Objects.toString(value); + } + + @Override + public boolean matches(Class objectClass) { + return String.class.equals(objectClass); + } + }), + + INT(new TSerializerElement() { + + @Override + public Integer read(String value) { + try { + return Integer.parseInt(value); + } catch (Throwable t) { + t.printStackTrace(); + } + return 0; + } + + @Override + public String write(Object value) { + return Objects.toString(value); + } + + @Override + public boolean matches(Class objectClass) { + return Integer.class.equals(objectClass) || Integer.TYPE.equals(objectClass); + } + }), + + LONG(new TSerializerElement() { + + @Override + public Long read(String value) { + try { + return Long.parseLong(value); + } catch (Throwable t) { + t.printStackTrace(); + } + return 0L; + } + + @Override + public String write(Object value) { + return Objects.toString(value); + } + + @Override + public boolean matches(Class objectClass) { + return Long.class.equals(objectClass) || Long.TYPE.equals(objectClass); + } + }), + + SHORT(new TSerializerElement() { + + @Override + public Short read(String value) { + try { + return Short.parseShort(value); + } catch (Throwable t) { + t.printStackTrace(); + } + return (short) 0; + } + + @Override + public String write(Object value) { + return Objects.toString(value); + } + + @Override + public boolean matches(Class objectClass) { + return Short.class.equals(objectClass) || Short.TYPE.equals(objectClass); + } + }), + + DOUBLE(new TSerializerElement() { + + @Override + public Double read(String value) { + try { + return Double.parseDouble(value); + } catch (Throwable t) { + t.printStackTrace(); + } + return 0D; + } + + @Override + public String write(Object value) { + return Objects.toString(value); + } + + @Override + public boolean matches(Class objectClass) { + return Double.class.equals(objectClass) || Boolean.TYPE.equals(objectClass); + } + }), + + FLOAT(new TSerializerElement() { + + @Override + public Float read(String value) { + try { + return Float.parseFloat(value); + } catch (Throwable t) { + t.printStackTrace(); + } + return 0f; + } + + @Override + public String write(Object value) { + return Objects.toString(value); + } + + @Override + public boolean matches(Class objectClass) { + return Float.class.equals(objectClass) || Float.TYPE.equals(objectClass); + } + }), + + BOOLEAN(new TSerializerElement() { + + @Override + public Boolean read(String value) { + try { + return NumberUtils.getBooleanAbbreviation(value); + } catch (Throwable t) { + t.printStackTrace(); + } + return false; + } + + @Override + public String write(Object value) { + return Objects.toString(value); + } + + @Override + public boolean matches(Class objectClass) { + return Boolean.class.equals(objectClass) || Boolean.TYPE.equals(objectClass); + } + }), + + ITEM_STACK(new TSerializerElement() { + + @Override + public ItemStack read(String value) { + return ConfigurationSerializer.deserializeCS(value, ItemStack.class); + } + + @Override + public String write(Object value) { + return ConfigurationSerializer.serializeCS((ItemStack) value); + } + + @Override + public boolean matches(Class objectClass) { + return ItemStack.class.equals(objectClass); + } + }), + + LOCATION(new TSerializerElement() { + + @Override + public Location read(String value) { + return ConfigurationSerializer.deserializeCS(value, Location.class); + } + + @Override + public String write(Object value) { + return ConfigurationSerializer.serializeCS((Location) value); + } + + @Override + public boolean matches(Class objectClass) { + return Location.class.equals(objectClass); + } + }); + + private TSerializerElement serializer; + + TSerializerElementGeneral(TSerializerElement serializer) { + this.serializer = serializer; + } + + public TSerializerElement getSerializer() { + return serializer; + } +} \ No newline at end of file diff --git a/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerExample.java b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerExample.java new file mode 100644 index 0000000..1d5d8a5 --- /dev/null +++ b/src/main/scala/me/skymc/taboolib/common/serialize/TSerializerExample.java @@ -0,0 +1,85 @@ +package me.skymc.taboolib.common.serialize; + +import com.google.common.collect.Lists; + +import java.util.Collection; +import java.util.List; + +/** + * @Author 坏黑 + * @Since 2019-04-01 17:49 + */ +public class TSerializerExample { + + public static void main(String[] args) { + // 创建对象 + SimpleData date = new SimpleData(); + // 修改参数 + date.number = 100; + // 序列化 + String value = date.write(); + // 打印 + System.out.println(value); + // 创建新的对象 + SimpleData dataCopy = new SimpleData(); + // 反序列化 + dataCopy.read(value); + // 打印 + System.out.println(dataCopy); + } + + /** + * 创建序列化类 + * 实现 TSerializable 接口 + */ + public static class SimpleData implements TSerializable { + + /** + * 基本类型不需要手动进行序列化 + * 包含: String、int、short、long、double、float、boolean、ItemStack、Location + */ + private String text; + private int number; + /** + * 特殊类型需要进行手动序列化 + * 本工具提供了基本容器的序列化方法 + */ + private List list = Lists.newArrayList(); + + /** + * 基本类型不会执行以下两个方法 + * 由 TSerializer 自动进行序列化和反序列化步骤 + */ + @Override + public void read(String fieldName, String value) { + switch (fieldName) { + case "list": { + // List 类型可以直接通过 TSerializer 提供的预设方法进行反序列化 + TSerializer.readCollection(list, value, TSerializerElementGeneral.DOUBLE); + break; + } + default: + } + } + + @Override + public String write(String fieldName, Object value) { + switch (fieldName) { + case "list": { + // 序列化同理 + return TSerializer.writeCollection((Collection) value, TSerializerElementGeneral.DOUBLE); + } + } + return null; + } + + @Override + public String toString() { + return "SimpleData{" + + "text='" + text + '\'' + + ", number=" + number + + ", list=" + list + + '}'; + } + } +} diff --git a/src/main/scala/me/skymc/taboolib/damage/DamageUtils.java b/src/main/scala/me/skymc/taboolib/damage/DamageUtils.java deleted file mode 100644 index 1ffdd99..0000000 --- a/src/main/scala/me/skymc/taboolib/damage/DamageUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.skymc.taboolib.damage; - -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.event.entity.EntityDamageByEntityEvent; - -/** - * @author sky - */ -public class DamageUtils { - - public static Player getAttackerInDamageEvent(EntityDamageByEntityEvent e) { - if (e.getDamager() instanceof Player) { - return (Player) e.getDamager(); - } else if (e.getDamager() instanceof Projectile && ((Projectile) e.getDamager()).getShooter() instanceof Player) { - return (Player) ((Projectile) e.getDamager()).getShooter(); - } else { - return null; - } - } - - // ********************************* - // - // Deprecated - // - // ********************************* - - @Deprecated - public static void damage(Player player, LivingEntity victim, double damage) { - dmg(player, victim, damage); - } - - @Deprecated - public static void damage(Player player, Entity victim, double damage) { - dmg(player, (LivingEntity) victim, damage); - } - - @Deprecated - public static void dmg(LivingEntity attacker, LivingEntity victim, double damage) { - attacker.damage(damage, victim); - } -} diff --git a/src/main/scala/me/skymc/taboolib/fileutils/EncodeUtils.java b/src/main/scala/me/skymc/taboolib/fileutils/EncodeUtils.java deleted file mode 100644 index 9897b37..0000000 --- a/src/main/scala/me/skymc/taboolib/fileutils/EncodeUtils.java +++ /dev/null @@ -1,114 +0,0 @@ -package me.skymc.taboolib.fileutils; - -import java.io.*; -import java.nio.charset.Charset; -import java.nio.charset.UnsupportedCharsetException; - -/** - * @author Unknown - */ -public class EncodeUtils { - - /** - * 把指定文件或目录转换成指定的编码 - * - * @param fileName 要转换的文件 - * @param fromCharsetName 源文件的编码 - * @param toCharsetName 要转换的编码 - * @throws Exception - */ - public static void convert(String fileName, String fromCharsetName, String toCharsetName) throws Exception { - convert(new File(fileName), fromCharsetName, toCharsetName, null); - } - - /** - * 把指定文件或目录转换成指定的编码 - * - * @param file 要转换的文件或目录 - * @param fromCharsetName 源文件的编码 - * @param toCharsetName 要转换的编码 - * @throws Exception - */ - public static void convert(File file, String fromCharsetName, String toCharsetName) throws Exception { - convert(file, fromCharsetName, toCharsetName, null); - } - - /** - * 把指定文件或目录转换成指定的编码 - * - * @param fromCharsetName 源文件的编码 - * @param toCharsetName 转换的编码 - * @param filter 文件名过滤器 - * @throws Exception - */ - public static void convert(String fileName, String fromCharsetName, String toCharsetName, FilenameFilter filter) throws Exception { - convert(new File(fileName), fromCharsetName, toCharsetName, filter); - } - - /** - * 把指定文件或目录转换成指定的编码 - * - * @param file 要转换的文件或目录 - * @param fromCharsetName 源文件的编码 - * @param toCharsetName 要转换的编码 - * @param filter 文件名过滤器 - * @throws Exception - */ - public static void convert(File file, String fromCharsetName, String toCharsetName, FilenameFilter filter) throws Exception { - if (file.isDirectory()) { - File[] fileList; - if (filter == null) { - fileList = file.listFiles(); - } else { - fileList = file.listFiles(filter); - } - for (File f : fileList) { - convert(f, fromCharsetName, toCharsetName, filter); - } - } else { - if (filter == null || filter.accept(file.getParentFile(), file.getName())) { - String fileContent = getFileContentFromCharset(file, fromCharsetName); - saveFile2Charset(file, toCharsetName, fileContent); - } - } - } - - /** - * 以指定编码方式读取文件,返回文件内容 - * - * @param file 要转换的文件 - * @param fromCharsetName 源文件的编码 - * @return - * @throws Exception - */ - public static String getFileContentFromCharset(File file, String fromCharsetName) throws Exception { - if (!Charset.isSupported(fromCharsetName)) { - throw new UnsupportedCharsetException(fromCharsetName); - } - InputStream inputStream = new FileInputStream(file); - InputStreamReader reader = new InputStreamReader(inputStream, fromCharsetName); - char[] chs = new char[(int) file.length()]; - reader.read(chs); - String str = new String(chs).trim(); - reader.close(); - return str; - } - - /** - * 以指定编码方式写文本文件,存在会覆盖 - * - * @param file 要写入的文件 - * @param toCharsetName 要转换的编码 - * @param content 文件内容 - * @throws Exception - */ - public static void saveFile2Charset(File file, String toCharsetName, String content) throws Exception { - if (!Charset.isSupported(toCharsetName)) { - throw new UnsupportedCharsetException(toCharsetName); - } - OutputStream outputStream = new FileOutputStream(file); - OutputStreamWriter outWrite = new OutputStreamWriter(outputStream, toCharsetName); - outWrite.write(content); - outWrite.close(); - } -} diff --git a/src/main/scala/me/skymc/taboolib/particle/EffLib.java b/src/main/scala/me/skymc/taboolib/particle/EffLib.java index e9a1cfc..b9e4c95 100644 --- a/src/main/scala/me/skymc/taboolib/particle/EffLib.java +++ b/src/main/scala/me/skymc/taboolib/particle/EffLib.java @@ -2,10 +2,7 @@ package me.skymc.taboolib.particle; import me.skymc.taboolib.methods.ReflectionUtils; import me.skymc.taboolib.methods.ReflectionUtils.PackageType; -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.Location; -import org.bukkit.Material; +import org.bukkit.*; import org.bukkit.entity.Player; import org.bukkit.util.Vector; @@ -39,1589 +36,1594 @@ import java.util.Map.Entry; * *

* It would be nice if you provide credit to me if you use this class in a published project - * + * * @author DarkBlade12 * @version 1.7 */ public enum EffLib { - - /** - * A particle effect which is displayed by exploding tnt and creepers: - *

    - *
  • It looks like a white cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - EXPLOSION_NORMAL("explode", 0, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by exploding ghast fireballs and wither skulls: - *
    - *
  • It looks like a gray ball which is fading away - *
  • The speed value slightly influences the size of this particle effect - *
- */ - EXPLOSION_LARGE("largeexplode", 1, -1), - /** - * A particle effect which is displayed by exploding tnt and creepers: - *
    - *
  • It looks like a crowd of gray balls which are fading away - *
  • The speed value has no influence on this particle effect - *
- */ - EXPLOSION_HUGE("hugeexplosion", 2, -1), - /** - * A particle effect which is displayed by launching fireworks: - *
    - *
  • It looks like a white star which is sparkling - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - FIREWORKS_SPARK("fireworksSpark", 3, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by swimming entities and arrows in water: - *
    - *
  • It looks like a bubble - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - WATER_BUBBLE("bubble", 4, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_WATER), - /** - * A particle effect which is displayed by swimming entities and shaking wolves: - *
    - *
  • It looks like a blue drop - *
  • The speed value has no influence on this particle effect - *
- */ - WATER_SPLASH("splash", 5, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed on water when fishing: - *
    - *
  • It looks like a blue droplet - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - WATER_WAKE("wake", 6, 7, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by water: - *
    - *
  • It looks like a tiny blue square - *
  • The speed value has no influence on this particle effect - *
- */ - SUSPENDED("suspended", 7, -1, ParticleProperty.REQUIRES_WATER), - /** - * A particle effect which is displayed by air when close to bedrock and the in the void: - *
    - *
  • It looks like a tiny gray square - *
  • The speed value has no influence on this particle effect - *
- */ - SUSPENDED_DEPTH("depthSuspend", 8, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed when landing a critical hit and by arrows: - *
    - *
  • It looks like a light brown cross - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - CRIT("crit", 9, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed when landing a hit with an enchanted weapon: - *
    - *
  • It looks like a cyan star - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - CRIT_MAGIC("magicCrit", 10, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by primed tnt, torches, droppers, dispensers, end portals, brewing stands and monster spawners: - *
    - *
  • It looks like a little gray cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - SMOKE_NORMAL("smoke", 11, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by fire, minecarts with furnace and blazes: - *
    - *
  • It looks like a large gray cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - SMOKE_LARGE("largesmoke", 12, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed when splash potions or bottles o' enchanting hit something: - *
    - *
  • It looks like a white swirl - *
  • The speed value causes the particle to only move upwards when set to 0 - *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 - *
- */ - SPELL("spell", 13, -1), - /** - * A particle effect which is displayed when instant splash potions hit something: - *
    - *
  • It looks like a white cross - *
  • The speed value causes the particle to only move upwards when set to 0 - *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 - *
- */ - SPELL_INSTANT("instantSpell", 14, -1), - /** - * A particle effect which is displayed by entities with active potion effects: - *
    - *
  • It looks like a colored swirl - *
  • The speed value causes the particle to be colored black when set to 0 - *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed - *
- */ - SPELL_MOB("mobSpell", 15, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed by entities with active potion effects applied through a beacon: - *
    - *
  • It looks like a transparent colored swirl - *
  • The speed value causes the particle to be always colored black when set to 0 - *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed - *
- */ - SPELL_MOB_AMBIENT("mobSpellAmbient", 16, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed by witches: - *
    - *
  • It looks like a purple cross - *
  • The speed value causes the particle to only move upwards when set to 0 - *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 - *
- */ - SPELL_WITCH("witchMagic", 17, -1), - /** - * A particle effect which is displayed by blocks beneath a water source: - *
    - *
  • It looks like a blue drip - *
  • The speed value has no influence on this particle effect - *
- */ - DRIP_WATER("dripWater", 18, -1), - /** - * A particle effect which is displayed by blocks beneath a lava source: - *
    - *
  • It looks like an orange drip - *
  • The speed value has no influence on this particle effect - *
- */ - DRIP_LAVA("dripLava", 19, -1), - /** - * A particle effect which is displayed when attacking a villager in a village: - *
    - *
  • It looks like a cracked gray heart - *
  • The speed value has no influence on this particle effect - *
- */ - VILLAGER_ANGRY("angryVillager", 20, -1), - /** - * A particle effect which is displayed when using bone meal and trading with a villager in a village: - *
    - *
  • It looks like a green star - *
  • The speed value has no influence on this particle effect - *
- */ - VILLAGER_HAPPY("happyVillager", 21, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by mycelium: - *
    - *
  • It looks like a tiny gray square - *
  • The speed value has no influence on this particle effect - *
- */ - TOWN_AURA("townaura", 22, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by note blocks: - *
    - *
  • It looks like a colored note - *
  • The speed value causes the particle to be colored green when set to 0 - *
- */ - NOTE("note", 23, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed by nether portals, endermen, ender pearls, eyes of ender, ender chests and dragon eggs: - *
    - *
  • It looks like a purple cloud - *
  • The speed value influences the spread of this particle effect - *
- */ - PORTAL("portal", 24, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by enchantment tables which are nearby bookshelves: - *
    - *
  • It looks like a cryptic white letter - *
  • The speed value influences the spread of this particle effect - *
- */ - ENCHANTMENT_TABLE("enchantmenttable", 25, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by torches, active furnaces, magma cubes and monster spawners: - *
    - *
  • It looks like a tiny flame - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - FLAME("flame", 26, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by lava: - *
    - *
  • It looks like a spark - *
  • The speed value has no influence on this particle effect - *
- */ - LAVA("lava", 27, -1), - /** - * A particle effect which is currently unused: - *
    - *
  • It looks like a transparent gray square - *
  • The speed value has no influence on this particle effect - *
- */ - FOOTSTEP("footstep", 28, -1), - /** - * A particle effect which is displayed when a mob dies: - *
    - *
  • It looks like a large white cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - CLOUD("cloud", 29, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by redstone ore, powered redstone, redstone torches and redstone repeaters: - *
    - *
  • It looks like a tiny colored cloud - *
  • The speed value causes the particle to be colored red when set to 0 - *
- */ - REDSTONE("reddust", 30, -1, ParticleProperty.COLORABLE), - /** - * A particle effect which is displayed when snowballs hit a block: - *
    - *
  • It looks like a little piece with the snowball texture - *
  • The speed value has no influence on this particle effect - *
- */ - SNOWBALL("snowballpoof", 31, -1), - /** - * A particle effect which is currently unused: - *
    - *
  • It looks like a tiny white cloud - *
  • The speed value influences the velocity at which the particle flies off - *
- */ - SNOW_SHOVEL("snowshovel", 32, -1, ParticleProperty.DIRECTIONAL), - /** - * A particle effect which is displayed by slimes: - *
    - *
  • It looks like a tiny part of the slimeball icon - *
  • The speed value has no influence on this particle effect - *
- */ - SLIME("slime", 33, -1), - /** - * A particle effect which is displayed when breeding and taming animals: - *
    - *
  • It looks like a red heart - *
  • The speed value has no influence on this particle effect - *
- */ - HEART("heart", 34, -1), - /** - * A particle effect which is displayed by barriers: - *
    - *
  • It looks like a red box with a slash through it - *
  • The speed value has no influence on this particle effect - *
- */ - BARRIER("barrier", 35, 8), - /** - * A particle effect which is displayed when breaking a tool or eggs hit a block: - *
    - *
  • It looks like a little piece with an item texture - *
- */ - ITEM_CRACK("iconcrack", 36, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), - /** - * A particle effect which is displayed when breaking blocks or sprinting: - *
    - *
  • It looks like a little piece with a block texture - *
  • The speed value has no influence on this particle effect - *
- */ - BLOCK_CRACK("blockcrack", 37, -1, ParticleProperty.REQUIRES_DATA), - /** - * A particle effect which is displayed when falling: - *
    - *
  • It looks like a little piece with a block texture - *
- */ - BLOCK_DUST("blockdust", 38, 7, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), - /** - * A particle effect which is displayed when rain hits the ground: - *
    - *
  • It looks like a blue droplet - *
  • The speed value has no influence on this particle effect - *
- */ - WATER_DROP("droplet", 39, 8), - /** - * A particle effect which is currently unused: - *
    - *
  • It has no visual effect - *
- */ - ITEM_TAKE("take", 40, 8), - /** - * A particle effect which is displayed by elder guardians: - *
    - *
  • It looks like the shape of the elder guardian - *
  • The speed value has no influence on this particle effect - *
  • The offset values have no influence on this particle effect - *
- */ - MOB_APPEARANCE("mobappearance", 41, 8), - - /** - * 龙息 - */ + + /** + * A particle effect which is displayed by exploding tnt and creepers: + *
    + *
  • It looks like a white cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + EXPLOSION_NORMAL("explode", 0, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by exploding ghast fireballs and wither skulls: + *
    + *
  • It looks like a gray ball which is fading away + *
  • The speed value slightly influences the size of this particle effect + *
+ */ + EXPLOSION_LARGE("largeexplode", 1, -1), + /** + * A particle effect which is displayed by exploding tnt and creepers: + *
    + *
  • It looks like a crowd of gray balls which are fading away + *
  • The speed value has no influence on this particle effect + *
+ */ + EXPLOSION_HUGE("hugeexplosion", 2, -1), + /** + * A particle effect which is displayed by launching fireworks: + *
    + *
  • It looks like a white star which is sparkling + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + FIREWORKS_SPARK("fireworksSpark", 3, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by swimming entities and arrows in water: + *
    + *
  • It looks like a bubble + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + WATER_BUBBLE("bubble", 4, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_WATER), + /** + * A particle effect which is displayed by swimming entities and shaking wolves: + *
    + *
  • It looks like a blue drop + *
  • The speed value has no influence on this particle effect + *
+ */ + WATER_SPLASH("splash", 5, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed on water when fishing: + *
    + *
  • It looks like a blue droplet + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + WATER_WAKE("wake", 6, 7, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by water: + *
    + *
  • It looks like a tiny blue square + *
  • The speed value has no influence on this particle effect + *
+ */ + SUSPENDED("suspended", 7, -1, ParticleProperty.REQUIRES_WATER), + /** + * A particle effect which is displayed by air when close to bedrock and the in the void: + *
    + *
  • It looks like a tiny gray square + *
  • The speed value has no influence on this particle effect + *
+ */ + SUSPENDED_DEPTH("depthSuspend", 8, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed when landing a critical hit and by arrows: + *
    + *
  • It looks like a light brown cross + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + CRIT("crit", 9, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed when landing a hit with an enchanted weapon: + *
    + *
  • It looks like a cyan star + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + CRIT_MAGIC("magicCrit", 10, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by primed tnt, torches, droppers, dispensers, end portals, brewing stands and monster spawners: + *
    + *
  • It looks like a little gray cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + SMOKE_NORMAL("smoke", 11, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by fire, minecarts with furnace and blazes: + *
    + *
  • It looks like a large gray cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + SMOKE_LARGE("largesmoke", 12, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed when splash potions or bottles o' enchanting hit something: + *
    + *
  • It looks like a white swirl + *
  • The speed value causes the particle to only move upwards when set to 0 + *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 + *
+ */ + SPELL("spell", 13, -1), + /** + * A particle effect which is displayed when instant splash potions hit something: + *
    + *
  • It looks like a white cross + *
  • The speed value causes the particle to only move upwards when set to 0 + *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 + *
+ */ + SPELL_INSTANT("instantSpell", 14, -1), + /** + * A particle effect which is displayed by entities with active potion effects: + *
    + *
  • It looks like a colored swirl + *
  • The speed value causes the particle to be colored black when set to 0 + *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed + *
+ */ + SPELL_MOB("mobSpell", 15, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed by entities with active potion effects applied through a beacon: + *
    + *
  • It looks like a transparent colored swirl + *
  • The speed value causes the particle to be always colored black when set to 0 + *
  • The particle color gets lighter when increasing the speed and darker when decreasing the speed + *
+ */ + SPELL_MOB_AMBIENT("mobSpellAmbient", 16, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed by witches: + *
    + *
  • It looks like a purple cross + *
  • The speed value causes the particle to only move upwards when set to 0 + *
  • Only the motion on the y-axis can be controlled, the motion on the x- and z-axis are multiplied by 0.1 when setting the values to 0 + *
+ */ + SPELL_WITCH("witchMagic", 17, -1), + /** + * A particle effect which is displayed by blocks beneath a water source: + *
    + *
  • It looks like a blue drip + *
  • The speed value has no influence on this particle effect + *
+ */ + DRIP_WATER("dripWater", 18, -1), + /** + * A particle effect which is displayed by blocks beneath a lava source: + *
    + *
  • It looks like an orange drip + *
  • The speed value has no influence on this particle effect + *
+ */ + DRIP_LAVA("dripLava", 19, -1), + /** + * A particle effect which is displayed when attacking a villager in a village: + *
    + *
  • It looks like a cracked gray heart + *
  • The speed value has no influence on this particle effect + *
+ */ + VILLAGER_ANGRY("angryVillager", 20, -1), + /** + * A particle effect which is displayed when using bone meal and trading with a villager in a village: + *
    + *
  • It looks like a green star + *
  • The speed value has no influence on this particle effect + *
+ */ + VILLAGER_HAPPY("happyVillager", 21, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by mycelium: + *
    + *
  • It looks like a tiny gray square + *
  • The speed value has no influence on this particle effect + *
+ */ + TOWN_AURA("townaura", 22, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by note blocks: + *
    + *
  • It looks like a colored note + *
  • The speed value causes the particle to be colored green when set to 0 + *
+ */ + NOTE("note", 23, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed by nether portals, endermen, ender pearls, eyes of ender, ender chests and dragon eggs: + *
    + *
  • It looks like a purple cloud + *
  • The speed value influences the spread of this particle effect + *
+ */ + PORTAL("portal", 24, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by enchantment tables which are nearby bookshelves: + *
    + *
  • It looks like a cryptic white letter + *
  • The speed value influences the spread of this particle effect + *
+ */ + ENCHANTMENT_TABLE("enchantmenttable", 25, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by torches, active furnaces, magma cubes and monster spawners: + *
    + *
  • It looks like a tiny flame + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + FLAME("flame", 26, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by lava: + *
    + *
  • It looks like a spark + *
  • The speed value has no influence on this particle effect + *
+ */ + LAVA("lava", 27, -1), + /** + * A particle effect which is currently unused: + *
    + *
  • It looks like a transparent gray square + *
  • The speed value has no influence on this particle effect + *
+ */ + FOOTSTEP("footstep", 28, -1), + /** + * A particle effect which is displayed when a mob dies: + *
    + *
  • It looks like a large white cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + CLOUD("cloud", 29, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by redstone ore, powered redstone, redstone torches and redstone repeaters: + *
    + *
  • It looks like a tiny colored cloud + *
  • The speed value causes the particle to be colored red when set to 0 + *
+ */ + REDSTONE("reddust", 30, -1, ParticleProperty.COLORABLE), + /** + * A particle effect which is displayed when snowballs hit a block: + *
    + *
  • It looks like a little piece with the snowball texture + *
  • The speed value has no influence on this particle effect + *
+ */ + SNOWBALL("snowballpoof", 31, -1), + /** + * A particle effect which is currently unused: + *
    + *
  • It looks like a tiny white cloud + *
  • The speed value influences the velocity at which the particle flies off + *
+ */ + SNOW_SHOVEL("snowshovel", 32, -1, ParticleProperty.DIRECTIONAL), + /** + * A particle effect which is displayed by slimes: + *
    + *
  • It looks like a tiny part of the slimeball icon + *
  • The speed value has no influence on this particle effect + *
+ */ + SLIME("slime", 33, -1), + /** + * A particle effect which is displayed when breeding and taming animals: + *
    + *
  • It looks like a red heart + *
  • The speed value has no influence on this particle effect + *
+ */ + HEART("heart", 34, -1), + /** + * A particle effect which is displayed by barriers: + *
    + *
  • It looks like a red box with a slash through it + *
  • The speed value has no influence on this particle effect + *
+ */ + BARRIER("barrier", 35, 8), + /** + * A particle effect which is displayed when breaking a tool or eggs hit a block: + *
    + *
  • It looks like a little piece with an item texture + *
+ */ + ITEM_CRACK("iconcrack", 36, -1, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), + /** + * A particle effect which is displayed when breaking blocks or sprinting: + *
    + *
  • It looks like a little piece with a block texture + *
  • The speed value has no influence on this particle effect + *
+ */ + BLOCK_CRACK("blockcrack", 37, -1, ParticleProperty.REQUIRES_DATA), + /** + * A particle effect which is displayed when falling: + *
    + *
  • It looks like a little piece with a block texture + *
+ */ + BLOCK_DUST("blockdust", 38, 7, ParticleProperty.DIRECTIONAL, ParticleProperty.REQUIRES_DATA), + /** + * A particle effect which is displayed when rain hits the ground: + *
    + *
  • It looks like a blue droplet + *
  • The speed value has no influence on this particle effect + *
+ */ + WATER_DROP("droplet", 39, 8), + /** + * A particle effect which is currently unused: + *
    + *
  • It has no visual effect + *
+ */ + ITEM_TAKE("take", 40, 8), + /** + * A particle effect which is displayed by elder guardians: + *
    + *
  • It looks like the shape of the elder guardian + *
  • The speed value has no influence on this particle effect + *
  • The offset values have no influence on this particle effect + *
+ */ + MOB_APPEARANCE("mobappearance", 41, 8), + + /** + * 龙息 + */ DRAGON_BREATH("dragonbreath", 42, 9), - + /** * 末地烛 */ END_ROD("endrod", 43, 9), - + /** * 伤害 */ DAMAGE_INDICATOR("damageIndicator", 44, 9), - + /** * 挥砍 */ SWEEP_ATTACK("sweepAttack", 45, 9), - /** - * 不死图腾 - */ - TOTEM("totem", 46, 11); - - private static final Map NAME_MAP = new HashMap<>(); - private static final Map ID_MAP = new HashMap<>(); - private final String name; - private final int id; - private final int requiredVersion; - private final List properties; - - // Initialize map for quick name and id lookup - static { - for (EffLib effect : values()) { - NAME_MAP.put(effect.name, effect); - ID_MAP.put(effect.id, effect); - } - } - - /** - * Construct a new particle effect - * - * @param name Name of this particle effect - * @param id Id of this particle effect - * @param requiredVersion Version which is required (1.x) - * @param properties Properties of this particle effect - */ - EffLib(String name, int id, int requiredVersion, ParticleProperty... properties) { - this.name = name; - this.id = id; - this.requiredVersion = requiredVersion; - this.properties = Arrays.asList(properties); - } - - /** - * Returns the name of this particle effect - * - * @return The name - */ - public String getName() { - return name; - } - - /** - * Returns the id of this particle effect - * - * @return The id - */ - public int getId() { - return id; - } - - /** - * Returns the required version for this particle effect (1.x) - * - * @return The required version - */ - public int getRequiredVersion() { - return requiredVersion; - } - - /** - * Determine if this particle effect has a specific property - * - * @return Whether it has the property or not - */ - public boolean hasProperty(ParticleProperty property) { - return properties.contains(property); - } - - /** - * Determine if this particle effect is supported by your current server version - * - * @return Whether the particle effect is supported or not - */ - public boolean isSupported() { - return requiredVersion == -1 || ParticlePacket.getVersion() >= requiredVersion; - } - - /** - * Returns the particle effect with the given name - * - * @param name Name of the particle effect - * @return The particle effect - */ - public static EffLib fromName(String name) { - for (Entry entry : NAME_MAP.entrySet()) { - if (!entry.getKey().equalsIgnoreCase(name)) { - continue; - } - return entry.getValue(); - } - return null; - } - - /** - * Returns the particle effect with the given id - * - * @param id Id of the particle effect - * @return The particle effect - */ - public static EffLib fromId(int id) { - for (Entry entry : ID_MAP.entrySet()) { - if (entry.getKey() != id) { - continue; - } - return entry.getValue(); - } - return null; - } - - /** - * Determine if water is at a certain location - * - * @param location Location to check - * @return Whether water is at this location or not - */ - private static boolean isWater(Location location) { - Material material = location.getBlock().getType(); - return material == Material.WATER || material == Material.STATIONARY_WATER; - } - - /** - * Determine if the distance between @param location and one of the players exceeds 256 - * - * @param location Location to check - * @return Whether the distance exceeds 256 or not - */ - private static boolean isLongDistance(Location location, List players) { - String world = location.getWorld().getName(); - for (Player player : players) { - Location playerLocation = player.getLocation(); - if (!world.equals(playerLocation.getWorld().getName()) || playerLocation.distanceSquared(location) < 65536) { - continue; - } - return true; - } - return false; - } - - /** - * Determine if the data type for a particle effect is correct - * - * @param effect Particle effect - * @param data Particle data - * @return Whether the data type is correct or not - */ - private static boolean isDataCorrect(EffLib effect, ParticleData data) { - return ((effect == BLOCK_CRACK || effect == BLOCK_DUST) && data instanceof BlockData) || (effect == ITEM_CRACK && data instanceof ItemData); - } - - /** - * Determine if the color type for a particle effect is correct - * - * @param effect Particle effect - * @param color Particle color - * @return Whether the color type is correct or not - */ - private static boolean isColorCorrect(EffLib effect, ParticleColor color) { - return ((effect == SPELL_MOB || effect == SPELL_MOB_AMBIENT || effect == REDSTONE) && color instanceof OrdinaryColor) || (effect == NOTE && color instanceof NoteColor); - } - - /** - * Displays a particle effect which is only visible for all players within a certain range in the world of @param center - * - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect requires water and none is at the center location - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, null).sendTo(center, range); - } - - /** - * Displays a particle effect which is only visible for the specified players - * - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect requires water and none is at the center location - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null).sendTo(center, players); - } - - /** - * Displays a particle effect which is only visible for the specified players - * - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect requires water and none is at the center location - * @see #display(float, float, float, float, int, Location, List) - */ - public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - display(offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); - } - - /** - * Displays a single particle which flies into a determined direction and is only visible for all players within a certain range in the world of @param center - * - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location - * @see ParticlePacket#ParticlePacket(EffLib, Vector, float, boolean, ParticleData) - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (!hasProperty(ParticleProperty.DIRECTIONAL)) { - throw new IllegalArgumentException("This particle effect is not directional"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, direction, speed, range > 256, null).sendTo(center, range); - } - - /** - * Displays a single particle which flies into a determined direction and is only visible for the specified players - * - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location - * @see ParticlePacket#ParticlePacket(EffLib, Vector, float, boolean, ParticleData) - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect requires additional data"); - } - if (!hasProperty(ParticleProperty.DIRECTIONAL)) { - throw new IllegalArgumentException("This particle effect is not directional"); - } - if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { - throw new IllegalArgumentException("There is no water at the center location"); - } - new ParticlePacket(this, direction, speed, isLongDistance(center, players), null).sendTo(center, players); - } - - /** - * Displays a single particle which flies into a determined direction and is only visible for the specified players - * - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect requires additional data - * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location - * @see #display(Vector, float, Location, List) - */ - public void display(Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { - display(direction, speed, center, Arrays.asList(players)); - } - - /** - * Displays a single particle which is colored and only visible for all players within a certain range in the world of @param center - * - * @param color Color of the particle - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect - * @see ParticlePacket#ParticlePacket(EffLib, ParticleColor, boolean) - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(ParticleColor color, Location center, double range) throws ParticleVersionException, ParticleColorException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.COLORABLE)) { - throw new ParticleColorException("This particle effect is not colorable"); - } - if (!isColorCorrect(this, color)) { - throw new ParticleColorException("The particle color type is incorrect"); - } - new ParticlePacket(this, color, range > 256).sendTo(center, range); - } - - /** - * Displays a single particle which is colored and only visible for the specified players - * - * @param color Color of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect - * @see ParticlePacket#ParticlePacket(EffLib, ParticleColor, boolean) - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(ParticleColor color, Location center, List players) throws ParticleVersionException, ParticleColorException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.COLORABLE)) { - throw new ParticleColorException("This particle effect is not colorable"); - } - if (!isColorCorrect(this, color)) { - throw new ParticleColorException("The particle color type is incorrect"); - } - new ParticlePacket(this, color, isLongDistance(center, players)).sendTo(center, players); - } - - /** - * Displays a single particle which is colored and only visible for the specified players - * - * @param color Color of the particle - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect - * @see #display(ParticleColor, Location, List) - */ - public void display(ParticleColor color, Location center, Player... players) throws ParticleVersionException, ParticleColorException { - display(color, center, Arrays.asList(players)); - } - - /** - * Displays a particle effect which requires additional data and is only visible for all players within a certain range in the world of @param center - * - * @param data Data of the effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, data).sendTo(center, range); - } - - /** - * Displays a particle effect which requires additional data and is only visible for the specified players - * - * @param data Data of the effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data).sendTo(center, players); - } - - /** - * Displays a particle effect which requires additional data and is only visible for the specified players - * - * @param data Data of the effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see #display(ParticleData, float, float, float, float, int, Location, List) - */ - public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException { - display(data, offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); - } - - /** - * Displays a single particle which requires additional data that flies into a determined direction and is only visible for all players within a certain range in the world of @param center - * - * @param data Data of the effect - * @param direction Direction of the particle - * @param speed Display speed of the particles - * @param center Center location of the effect - * @param range Range of the visibility - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, double) - */ - public void display(ParticleData data, Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, direction, speed, range > 256, data).sendTo(center, range); - } - - /** - * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players - * - * @param data Data of the effect - * @param direction Direction of the particle - * @param speed Display speed of the particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see ParticlePacket - * @see ParticlePacket#sendTo(Location, List) - */ - public void display(ParticleData data, Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException { - if (!isSupported()) { - throw new ParticleVersionException("This particle effect is not supported by your server version"); - } - if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { - throw new ParticleDataException("This particle effect does not require additional data"); - } - if (!isDataCorrect(this, data)) { - throw new ParticleDataException("The particle data type is incorrect"); - } - new ParticlePacket(this, direction, speed, isLongDistance(center, players), data).sendTo(center, players); - } - - /** - * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players - * - * @param data Data of the effect - * @param direction Direction of the particle - * @param speed Display speed of the particles - * @param center Center location of the effect - * @param players Receivers of the effect - * @throws ParticleVersionException If the particle effect is not supported by the server version - * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect - * @see #display(ParticleData, Vector, float, Location, List) - */ - public void display(ParticleData data, Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException { - display(data, direction, speed, center, Arrays.asList(players)); - } - - /** - * Represents the property of a particle effect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public enum ParticleProperty { - /** - * The particle effect requires water to be displayed - */ - REQUIRES_WATER, - /** - * The particle effect requires block or item data to be displayed - */ - REQUIRES_DATA, - /** - * The particle effect uses the offsets as direction values - */ - DIRECTIONAL, - /** - * The particle effect uses the offsets as color values - */ - COLORABLE - } - - /** - * Represents the particle data for effects like {@link EffLib#ITEM_CRACK}, {@link EffLib#BLOCK_CRACK} and {@link EffLib#BLOCK_DUST} - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - public static abstract class ParticleData { - private final Material material; - private final byte data; - private final int[] packetData; - - /** - * Construct a new particle data - * - * @param material Material of the item/block - * @param data Data value of the item/block - */ - @SuppressWarnings("deprecation") - public ParticleData(Material material, byte data) { - this.material = material; - this.data = data; - this.packetData = new int[] { material.getId(), data }; - } - - /** - * Returns the material of this data - * - * @return The material - */ - public Material getMaterial() { - return material; - } - - /** - * Returns the data value of this data - * - * @return The data value - */ - public byte getData() { - return data; - } - - /** - * Returns the data as an int array for packet construction - * - * @return The data for the packet - */ - public int[] getPacketData() { - return packetData; - } - - /** - * Returns the data as a string for pre 1.8 versions - * - * @return The data string for the packet - */ - public String getPacketDataString() { - return "_" + packetData[0] + "_" + packetData[1]; - } - } - - /** - * Represents the item data for the {@link EffLib#ITEM_CRACK} effect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - public static final class ItemData extends ParticleData { - /** - * Construct a new item data - * - * @param material Material of the item - * @param data Data value of the item - * @see ParticleData#ParticleData(Material, byte) - */ - public ItemData(Material material, byte data) { - super(material, data); - } - } - - /** - * Represents the block data for the {@link EffLib#BLOCK_CRACK} and {@link EffLib#BLOCK_DUST} effects - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - public static final class BlockData extends ParticleData { - /** - * Construct a new block data - * - * @param material Material of the block - * @param data Data value of the block - * @throws IllegalArgumentException If the material is not a block - * @see ParticleData#ParticleData(Material, byte) - */ - public BlockData(Material material, byte data) throws IllegalArgumentException { - super(material, data); - if (!material.isBlock()) { - throw new IllegalArgumentException("The material is not a block"); - } - } - } - - /** - * Represents the color for effects like {@link EffLib#SPELL_MOB}, {@link EffLib#SPELL_MOB_AMBIENT}, {@link EffLib#REDSTONE} and {@link EffLib#NOTE} - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public static abstract class ParticleColor { - /** - * Returns the value for the offsetX field - * - * @return The offsetX value - */ - public abstract float getValueX(); - - /** - * Returns the value for the offsetY field - * - * @return The offsetY value - */ - public abstract float getValueY(); - - /** - * Returns the value for the offsetZ field - * - * @return The offsetZ value - */ - public abstract float getValueZ(); - } - - /** - * Represents the color for effects like {@link EffLib#SPELL_MOB}, {@link EffLib#SPELL_MOB_AMBIENT} and {@link EffLib#NOTE} - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public static final class OrdinaryColor extends ParticleColor { - private final int red; - private final int green; - private final int blue; - - /** - * Construct a new ordinary color - * - * @param red Red value of the RGB format - * @param green Green value of the RGB format - * @param blue Blue value of the RGB format - * @throws IllegalArgumentException If one of the values is lower than 0 or higher than 255 - */ - public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException { - if (red < 0) { - throw new IllegalArgumentException("The red value is lower than 0"); - } - if (red > 255) { - throw new IllegalArgumentException("The red value is higher than 255"); - } - this.red = red; - if (green < 0) { - throw new IllegalArgumentException("The green value is lower than 0"); - } - if (green > 255) { - throw new IllegalArgumentException("The green value is higher than 255"); - } - this.green = green; - if (blue < 0) { - throw new IllegalArgumentException("The blue value is lower than 0"); - } - if (blue > 255) { - throw new IllegalArgumentException("The blue value is higher than 255"); - } - this.blue = blue; - } - - /** - * Construct a new ordinary color - * - * @param color Bukkit color - */ - public OrdinaryColor(Color color) { - this(color.getRed(), color.getGreen(), color.getBlue()); - } - - /** - * Returns the red value of the RGB format - * - * @return The red value - */ - public int getRed() { - return red; - } - - /** - * Returns the green value of the RGB format - * - * @return The green value - */ - public int getGreen() { - return green; - } - - /** - * Returns the blue value of the RGB format - * - * @return The blue value - */ - public int getBlue() { - return blue; - } - - /** - * Returns the red value divided by 255 - * - * @return The offsetX value - */ - @Override - public float getValueX() { - return red / 255F; - } - - /** - * Returns the green value divided by 255 - * - * @return The offsetY value - */ - @Override - public float getValueY() { - return green / 255F; - } - - /** - * Returns the blue value divided by 255 - * - * @return The offsetZ value - */ - @Override - public float getValueZ() { - return blue / 255F; - } - } - - /** - * Represents the color for the {@link EffLib#NOTE} effect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - public static final class NoteColor extends ParticleColor { - private final int note; - - /** - * Construct a new note color - * - * @param note Note id which determines color - * @throws IllegalArgumentException If the note value is lower than 0 or higher than 24 - */ - public NoteColor(int note) throws IllegalArgumentException { - if (note < 0) { - throw new IllegalArgumentException("The note value is lower than 0"); - } - if (note > 24) { - throw new IllegalArgumentException("The note value is higher than 24"); - } - this.note = note; - } - - /** - * Returns the note value divided by 24 - * - * @return The offsetX value - */ - @Override - public float getValueX() { - return note / 24F; - } - - /** - * Returns zero because the offsetY value is unused - * - * @return zero - */ - @Override - public float getValueY() { - return 0; - } - - /** - * Returns zero because the offsetZ value is unused - * - * @return zero - */ - @Override - public float getValueZ() { - return 0; - } - - } - - /** - * Represents a runtime exception that is thrown either if the displayed particle effect requires data and has none or vice-versa or if the data type is incorrect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - private static final class ParticleDataException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new particle data exception - * - * @param message Message that will be logged - */ - public ParticleDataException(String message) { - super(message); - } - } - - /** - * Represents a runtime exception that is thrown either if the displayed particle effect is not colorable or if the particle color type is incorrect - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.7 - */ - private static final class ParticleColorException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new particle color exception - * - * @param message Message that will be logged - */ - public ParticleColorException(String message) { - super(message); - } - } - - /** - * Represents a runtime exception that is thrown if the displayed particle effect requires a newer version - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.6 - */ - private static final class ParticleVersionException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new particle version exception - * - * @param message Message that will be logged - */ - public ParticleVersionException(String message) { - super(message); - } - } - - /** - * Represents a particle effect packet with all attributes which is used for sending packets to the players - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.5 - */ - public static final class ParticlePacket { - private static int version; - private static Class enumParticle; - private static Constructor packetConstructor; - private static Method getHandle; - private static Field playerConnection; - private static Method sendPacket; - private static boolean initialized; - private final EffLib effect; - private float offsetX; - private final float offsetY; - private final float offsetZ; - private final float speed; - private final int amount; - private final boolean longDistance; - private final ParticleData data; - private Object packet; - - /** - * Construct a new particle packet - * - * @param effect Particle effect - * @param offsetX Maximum distance particles can fly away from the center on the x-axis - * @param offsetY Maximum distance particles can fly away from the center on the y-axis - * @param offsetZ Maximum distance particles can fly away from the center on the z-axis - * @param speed Display speed of the particles - * @param amount Amount of particles - * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 - * @param data Data of the effect - * @throws IllegalArgumentException If the speed or amount is lower than 0 - * @see #initialize() - */ - public ParticlePacket(EffLib effect, float offsetX, float offsetY, float offsetZ, float speed, int amount, boolean longDistance, ParticleData data) throws IllegalArgumentException { - initialize(); - if (speed < 0) { - throw new IllegalArgumentException("The speed is lower than 0"); - } - if (amount < 0) { - throw new IllegalArgumentException("The amount is lower than 0"); - } - this.effect = effect; - this.offsetX = offsetX; - this.offsetY = offsetY; - this.offsetZ = offsetZ; - this.speed = speed; - this.amount = amount; - this.longDistance = longDistance; - this.data = data; - } - - /** - * Construct a new particle packet of a single particle flying into a determined direction - * - * @param effect Particle effect - * @param direction Direction of the particle - * @param speed Display speed of the particle - * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 - * @param data Data of the effect - * @throws IllegalArgumentException If the speed is lower than 0 - */ - public ParticlePacket(EffLib effect, Vector direction, float speed, boolean longDistance, ParticleData data) throws IllegalArgumentException { - this(effect, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), speed, 0, longDistance, data); - } - - /** - * Construct a new particle packet of a single colored particle - * - * @param effect Particle effect - * @param color Color of the particle - * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 - */ - public ParticlePacket(EffLib effect, ParticleColor color, boolean longDistance) { - this(effect, color.getValueX(), color.getValueY(), color.getValueZ(), 1, 0, longDistance, null); - if (effect == EffLib.REDSTONE && color instanceof OrdinaryColor && ((OrdinaryColor) color).getRed() == 0) { - offsetX = Float.MIN_NORMAL; - } - } - - /** - * Initializes {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} and sets {@link #initialized} to true if it succeeds - *

- * Note: These fields only have to be initialized once, so it will return if {@link #initialized} is already set to true - * - * @throws VersionIncompatibleException if your bukkit version is not supported by this library - */ - public static void initialize() throws VersionIncompatibleException { - if (initialized) { - return; - } - try { - version = Integer.valueOf(PackageType.getServerVersion().split("_")[1]); - if (version > 7) { - enumParticle = PackageType.MINECRAFT_SERVER.getClass("EnumParticle"); - } - Class packetClass = PackageType.MINECRAFT_SERVER.getClass(version < 7 ? "Packet63WorldParticles" : "PacketPlayOutWorldParticles"); - packetConstructor = ReflectionUtils.getConstructor(packetClass); - getHandle = ReflectionUtils.getMethod("CraftPlayer", PackageType.CRAFTBUKKIT_ENTITY, "getHandle"); - playerConnection = ReflectionUtils.getField("EntityPlayer", PackageType.MINECRAFT_SERVER, false, "playerConnection"); - sendPacket = ReflectionUtils.getMethod(playerConnection.getType(), "sendPacket", PackageType.MINECRAFT_SERVER.getClass("Packet")); - } catch (Exception exception) { - throw new VersionIncompatibleException("Your current bukkit version seems to be incompatible with this library", exception); - } - initialized = true; - } - - /** - * Returns the version of your server (1.x) - * - * @return The version number - */ - public static int getVersion() { - if (!initialized) { - initialize(); - } - return version; - } - - /** - * Determine if {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} are initialized - * - * @return Whether these fields are initialized or not - * @see #initialize() - */ - public static boolean isInitialized() { - return initialized; - } - - /** - * Initializes {@link #packet} with all set values - * - * @param center Center location of the effect - * @throws PacketInstantiationException If instantion fails due to an unknown error - */ - private void initializePacket(Location center) throws PacketInstantiationException { - if (packet != null) { - return; - } - try { - packet = packetConstructor.newInstance(); - if (version < 8) { - String name = effect.getName(); - if (data != null) { - name += data.getPacketDataString(); - } - ReflectionUtils.setValue(packet, true, "a", name); - } else { - ReflectionUtils.setValue(packet, true, "a", enumParticle.getEnumConstants()[effect.getId()]); - ReflectionUtils.setValue(packet, true, "j", longDistance); - if (data != null) { - int[] packetData = data.getPacketData(); - ReflectionUtils.setValue(packet, true, "k", effect == EffLib.ITEM_CRACK ? packetData : new int[] { packetData[0] | (packetData[1] << 12) }); - } - } - ReflectionUtils.setValue(packet, true, "b", (float) center.getX()); - ReflectionUtils.setValue(packet, true, "c", (float) center.getY()); - ReflectionUtils.setValue(packet, true, "d", (float) center.getZ()); - ReflectionUtils.setValue(packet, true, "e", offsetX); - ReflectionUtils.setValue(packet, true, "f", offsetY); - ReflectionUtils.setValue(packet, true, "g", offsetZ); - ReflectionUtils.setValue(packet, true, "h", speed); - ReflectionUtils.setValue(packet, true, "i", amount); - } catch (Exception exception) { - throw new PacketInstantiationException("Packet instantiation failed", exception); - } - } - - /** - * Sends the packet to a single player and caches it - * - * @param center Center location of the effect - * @param player Receiver of the packet - * @throws PacketInstantiationException If instantion fails due to an unknown error - * @throws PacketSendingException If sending fails due to an unknown error - * @see #initializePacket(Location) - */ - public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException { - initializePacket(center); - try { - sendPacket.invoke(playerConnection.get(getHandle.invoke(player)), packet); - } catch (Exception exception) { - throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception); - } - } - - /** - * Sends the packet to all players in the list - * - * @param center Center location of the effect - * @param players Receivers of the packet - * @throws IllegalArgumentException If the player list is empty - * @see #sendTo(Location center, Player player) - */ - public void sendTo(Location center, List players) throws IllegalArgumentException { - if (players.isEmpty()) { - throw new IllegalArgumentException("The player list is empty"); - } - for (Player player : players) { - sendTo(center, player); - } - } - - /** - * Sends the packet to all players in a certain range - * - * @param center Center location of the effect - * @param range Range in which players will receive the packet (Maximum range for particles is usually 16, but it can differ for some types) - * @throws IllegalArgumentException If the range is lower than 1 - * @see #sendTo(Location center, Player player) - */ - public void sendTo(Location center, double range) throws IllegalArgumentException { - if (range < 1) { - throw new IllegalArgumentException("The range is lower than 1"); - } - String worldName = center.getWorld().getName(); - double squared = range * range; - for (Player player : Bukkit.getOnlinePlayers()) { - if (!player.getWorld().getName().equals(worldName) || player.getLocation().distanceSquared(center) > squared) { - continue; - } - sendTo(center, player); - } - } - - /** - * Represents a runtime exception that is thrown if a bukkit version is not compatible with this library - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.5 - */ - private static final class VersionIncompatibleException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new version incompatible exception - * - * @param message Message that will be logged - * @param cause Cause of the exception - */ - public VersionIncompatibleException(String message, Throwable cause) { - super(message, cause); - } - } - - /** - * Represents a runtime exception that is thrown if packet instantiation fails - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.4 - */ - private static final class PacketInstantiationException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new packet instantiation exception - * - * @param message Message that will be logged - * @param cause Cause of the exception - */ - public PacketInstantiationException(String message, Throwable cause) { - super(message, cause); - } - } - - /** - * Represents a runtime exception that is thrown if packet sending fails - *

- * This class is part of the ParticleEffect Library and follows the same usage conditions - * - * @author DarkBlade12 - * @since 1.4 - */ - private static final class PacketSendingException extends RuntimeException { - private static final long serialVersionUID = 3203085387160737484L; - - /** - * Construct a new packet sending exception - * - * @param message Message that will be logged - * @param cause Cause of the exception - */ - public PacketSendingException(String message, Throwable cause) { - super(message, cause); - } - } - } + /** + * 掉落方块 + */ + FALLING_DUST("falling_dust", 46, 11, ParticleProperty.REQUIRES_DATA), + + /** + * 不死图腾 + */ + TOTEM("totem", 47, 11); + + private static final Map NAME_MAP = new HashMap<>(); + private static final Map ID_MAP = new HashMap<>(); + private final String name; + private final int id; + private final int requiredVersion; + private final List properties; + + // Initialize map for quick name and id lookup + static { + for (EffLib effect : values()) { + NAME_MAP.put(effect.name, effect); + ID_MAP.put(effect.id, effect); + } + } + + /** + * Construct a new particle effect + * + * @param name Name of this particle effect + * @param id Id of this particle effect + * @param requiredVersion Version which is required (1.x) + * @param properties Properties of this particle effect + */ + EffLib(String name, int id, int requiredVersion, ParticleProperty... properties) { + this.name = name; + this.id = id; + this.requiredVersion = requiredVersion; + this.properties = Arrays.asList(properties); + } + + /** + * Returns the name of this particle effect + * + * @return The name + */ + public String getName() { + return name; + } + + /** + * Returns the id of this particle effect + * + * @return The id + */ + public int getId() { + return id; + } + + /** + * Returns the required version for this particle effect (1.x) + * + * @return The required version + */ + public int getRequiredVersion() { + return requiredVersion; + } + + /** + * Determine if this particle effect has a specific property + * + * @return Whether it has the property or not + */ + public boolean hasProperty(ParticleProperty property) { + return properties.contains(property); + } + + /** + * Determine if this particle effect is supported by your current server version + * + * @return Whether the particle effect is supported or not + */ + public boolean isSupported() { + return requiredVersion == -1 || ParticlePacket.getVersion() >= requiredVersion; + } + + /** + * Returns the particle effect with the given name + * + * @param name Name of the particle effect + * @return The particle effect + */ + public static EffLib fromName(String name) { + for (Entry entry : NAME_MAP.entrySet()) { + if (!entry.getKey().equalsIgnoreCase(name)) { + continue; + } + return entry.getValue(); + } + return null; + } + + /** + * Returns the particle effect with the given id + * + * @param id Id of the particle effect + * @return The particle effect + */ + public static EffLib fromId(int id) { + for (Entry entry : ID_MAP.entrySet()) { + if (entry.getKey() != id) { + continue; + } + return entry.getValue(); + } + return null; + } + + /** + * Determine if water is at a certain location + * + * @param location Location to check + * @return Whether water is at this location or not + */ + private static boolean isWater(Location location) { + Material material = location.getBlock().getType(); + return material == Material.WATER || material == Material.STATIONARY_WATER; + } + + /** + * Determine if the distance between @param location and one of the players exceeds 256 + * + * @param location Location to check + * @return Whether the distance exceeds 256 or not + */ + private static boolean isLongDistance(Location location, List players) { + String world = location.getWorld().getName(); + for (Player player : players) { + Location playerLocation = player.getLocation(); + if (!world.equals(playerLocation.getWorld().getName()) || playerLocation.distanceSquared(location) < 65536) { + continue; + } + return true; + } + return false; + } + + /** + * Determine if the data type for a particle effect is correct + * + * @param effect Particle effect + * @param data Particle data + * @return Whether the data type is correct or not + */ + private static boolean isDataCorrect(EffLib effect, ParticleData data) { + return ((effect == BLOCK_CRACK || effect == BLOCK_DUST) && data instanceof BlockData) || (effect == ITEM_CRACK && data instanceof ItemData); + } + + /** + * Determine if the color type for a particle effect is correct + * + * @param effect Particle effect + * @param color Particle color + * @return Whether the color type is correct or not + */ + private static boolean isColorCorrect(EffLib effect, ParticleColor color) { + return ((effect == SPELL_MOB || effect == SPELL_MOB_AMBIENT || effect == REDSTONE) && color instanceof OrdinaryColor) || (effect == NOTE && color instanceof NoteColor); + } + + /** + * Displays a particle effect which is only visible for all players within a certain range in the world of @param center + * + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect requires water and none is at the center location + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, null).sendTo(center, range); + } + + /** + * Displays a particle effect which is only visible for the specified players + * + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect requires water and none is at the center location + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), null).sendTo(center, players); + } + + /** + * Displays a particle effect which is only visible for the specified players + * + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect requires water and none is at the center location + * @see #display(float, float, float, float, int, Location, List) + */ + public void display(float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + display(offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); + } + + /** + * Displays a single particle which flies into a determined direction and is only visible for all players within a certain range in the world of @param center + * + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location + * @see ParticlePacket#ParticlePacket(EffLib, Vector, float, boolean, ParticleData) + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (!hasProperty(ParticleProperty.DIRECTIONAL)) { + throw new IllegalArgumentException("This particle effect is not directional"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, direction, speed, range > 256, null).sendTo(center, range); + } + + /** + * Displays a single particle which flies into a determined direction and is only visible for the specified players + * + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location + * @see ParticlePacket#ParticlePacket(EffLib, Vector, float, boolean, ParticleData) + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect requires additional data"); + } + if (!hasProperty(ParticleProperty.DIRECTIONAL)) { + throw new IllegalArgumentException("This particle effect is not directional"); + } + if (hasProperty(ParticleProperty.REQUIRES_WATER) && !isWater(center)) { + throw new IllegalArgumentException("There is no water at the center location"); + } + new ParticlePacket(this, direction, speed, isLongDistance(center, players), null).sendTo(center, players); + } + + /** + * Displays a single particle which flies into a determined direction and is only visible for the specified players + * + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect requires additional data + * @throws IllegalArgumentException If the particle effect is not directional or if it requires water and none is at the center location + * @see #display(Vector, float, Location, List) + */ + public void display(Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException, IllegalArgumentException { + display(direction, speed, center, Arrays.asList(players)); + } + + /** + * Displays a single particle which is colored and only visible for all players within a certain range in the world of @param center + * + * @param color Color of the particle + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect + * @see ParticlePacket#ParticlePacket(EffLib, ParticleColor, boolean) + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(ParticleColor color, Location center, double range) throws ParticleVersionException, ParticleColorException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.COLORABLE)) { + throw new ParticleColorException("This particle effect is not colorable"); + } + if (!isColorCorrect(this, color)) { + throw new ParticleColorException("The particle color type is incorrect"); + } + new ParticlePacket(this, color, range > 256).sendTo(center, range); + } + + /** + * Displays a single particle which is colored and only visible for the specified players + * + * @param color Color of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect + * @see ParticlePacket#ParticlePacket(EffLib, ParticleColor, boolean) + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(ParticleColor color, Location center, List players) throws ParticleVersionException, ParticleColorException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.COLORABLE)) { + throw new ParticleColorException("This particle effect is not colorable"); + } + if (!isColorCorrect(this, color)) { + throw new ParticleColorException("The particle color type is incorrect"); + } + new ParticlePacket(this, color, isLongDistance(center, players)).sendTo(center, players); + } + + /** + * Displays a single particle which is colored and only visible for the specified players + * + * @param color Color of the particle + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect + * @see #display(ParticleColor, Location, List) + */ + public void display(ParticleColor color, Location center, Player... players) throws ParticleVersionException, ParticleColorException { + display(color, center, Arrays.asList(players)); + } + + /** + * Displays a particle effect which requires additional data and is only visible for all players within a certain range in the world of @param center + * + * @param data Data of the effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, double range) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, range > 256, data).sendTo(center, range); + } + + /** + * Displays a particle effect which requires additional data and is only visible for the specified players + * + * @param data Data of the effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, List players) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, offsetX, offsetY, offsetZ, speed, amount, isLongDistance(center, players), data).sendTo(center, players); + } + + /** + * Displays a particle effect which requires additional data and is only visible for the specified players + * + * @param data Data of the effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see #display(ParticleData, float, float, float, float, int, Location, List) + */ + public void display(ParticleData data, float offsetX, float offsetY, float offsetZ, float speed, int amount, Location center, Player... players) throws ParticleVersionException, ParticleDataException { + display(data, offsetX, offsetY, offsetZ, speed, amount, center, Arrays.asList(players)); + } + + /** + * Displays a single particle which requires additional data that flies into a determined direction and is only visible for all players within a certain range in the world of @param center + * + * @param data Data of the effect + * @param direction Direction of the particle + * @param speed Display speed of the particles + * @param center Center location of the effect + * @param range Range of the visibility + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, double) + */ + public void display(ParticleData data, Vector direction, float speed, Location center, double range) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, direction, speed, range > 256, data).sendTo(center, range); + } + + /** + * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players + * + * @param data Data of the effect + * @param direction Direction of the particle + * @param speed Display speed of the particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see ParticlePacket + * @see ParticlePacket#sendTo(Location, List) + */ + public void display(ParticleData data, Vector direction, float speed, Location center, List players) throws ParticleVersionException, ParticleDataException { + if (!isSupported()) { + throw new ParticleVersionException("This particle effect is not supported by your server version"); + } + if (!hasProperty(ParticleProperty.REQUIRES_DATA)) { + throw new ParticleDataException("This particle effect does not require additional data"); + } + if (!isDataCorrect(this, data)) { + throw new ParticleDataException("The particle data type is incorrect"); + } + new ParticlePacket(this, direction, speed, isLongDistance(center, players), data).sendTo(center, players); + } + + /** + * Displays a single particle which requires additional data that flies into a determined direction and is only visible for the specified players + * + * @param data Data of the effect + * @param direction Direction of the particle + * @param speed Display speed of the particles + * @param center Center location of the effect + * @param players Receivers of the effect + * @throws ParticleVersionException If the particle effect is not supported by the server version + * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect + * @see #display(ParticleData, Vector, float, Location, List) + */ + public void display(ParticleData data, Vector direction, float speed, Location center, Player... players) throws ParticleVersionException, ParticleDataException { + display(data, direction, speed, center, Arrays.asList(players)); + } + + /** + * Represents the property of a particle effect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public enum ParticleProperty { + /** + * The particle effect requires water to be displayed + */ + REQUIRES_WATER, + /** + * The particle effect requires block or item data to be displayed + */ + REQUIRES_DATA, + /** + * The particle effect uses the offsets as direction values + */ + DIRECTIONAL, + /** + * The particle effect uses the offsets as color values + */ + COLORABLE + } + + /** + * Represents the particle data for effects like {@link EffLib#ITEM_CRACK}, {@link EffLib#BLOCK_CRACK} and {@link EffLib#BLOCK_DUST} + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + public static abstract class ParticleData { + private final Material material; + private final byte data; + private final int[] packetData; + + /** + * Construct a new particle data + * + * @param material Material of the item/block + * @param data Data value of the item/block + */ + @SuppressWarnings("deprecation") + public ParticleData(Material material, byte data) { + this.material = material; + this.data = data; + this.packetData = new int[] {material.getId(), data}; + } + + /** + * Returns the material of this data + * + * @return The material + */ + public Material getMaterial() { + return material; + } + + /** + * Returns the data value of this data + * + * @return The data value + */ + public byte getData() { + return data; + } + + /** + * Returns the data as an int array for packet construction + * + * @return The data for the packet + */ + public int[] getPacketData() { + return packetData; + } + + /** + * Returns the data as a string for pre 1.8 versions + * + * @return The data string for the packet + */ + public String getPacketDataString() { + return "_" + packetData[0] + "_" + packetData[1]; + } + } + + /** + * Represents the item data for the {@link EffLib#ITEM_CRACK} effect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + public static final class ItemData extends ParticleData { + /** + * Construct a new item data + * + * @param material Material of the item + * @param data Data value of the item + * @see ParticleData#ParticleData(Material, byte) + */ + public ItemData(Material material, byte data) { + super(material, data); + } + } + + /** + * Represents the block data for the {@link EffLib#BLOCK_CRACK} and {@link EffLib#BLOCK_DUST} effects + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + public static final class BlockData extends ParticleData { + /** + * Construct a new block data + * + * @param material Material of the block + * @param data Data value of the block + * @throws IllegalArgumentException If the material is not a block + * @see ParticleData#ParticleData(Material, byte) + */ + public BlockData(Material material, byte data) throws IllegalArgumentException { + super(material, data); + if (!material.isBlock()) { + throw new IllegalArgumentException("The material is not a block"); + } + } + } + + /** + * Represents the color for effects like {@link EffLib#SPELL_MOB}, {@link EffLib#SPELL_MOB_AMBIENT}, {@link EffLib#REDSTONE} and {@link EffLib#NOTE} + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public static abstract class ParticleColor { + /** + * Returns the value for the offsetX field + * + * @return The offsetX value + */ + public abstract float getValueX(); + + /** + * Returns the value for the offsetY field + * + * @return The offsetY value + */ + public abstract float getValueY(); + + /** + * Returns the value for the offsetZ field + * + * @return The offsetZ value + */ + public abstract float getValueZ(); + } + + /** + * Represents the color for effects like {@link EffLib#SPELL_MOB}, {@link EffLib#SPELL_MOB_AMBIENT} and {@link EffLib#NOTE} + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public static final class OrdinaryColor extends ParticleColor { + private final int red; + private final int green; + private final int blue; + + /** + * Construct a new ordinary color + * + * @param red Red value of the RGB format + * @param green Green value of the RGB format + * @param blue Blue value of the RGB format + * @throws IllegalArgumentException If one of the values is lower than 0 or higher than 255 + */ + public OrdinaryColor(int red, int green, int blue) throws IllegalArgumentException { + if (red < 0) { + throw new IllegalArgumentException("The red value is lower than 0"); + } + if (red > 255) { + throw new IllegalArgumentException("The red value is higher than 255"); + } + this.red = red; + if (green < 0) { + throw new IllegalArgumentException("The green value is lower than 0"); + } + if (green > 255) { + throw new IllegalArgumentException("The green value is higher than 255"); + } + this.green = green; + if (blue < 0) { + throw new IllegalArgumentException("The blue value is lower than 0"); + } + if (blue > 255) { + throw new IllegalArgumentException("The blue value is higher than 255"); + } + this.blue = blue; + } + + /** + * Construct a new ordinary color + * + * @param color Bukkit color + */ + public OrdinaryColor(Color color) { + this(color.getRed(), color.getGreen(), color.getBlue()); + } + + /** + * Returns the red value of the RGB format + * + * @return The red value + */ + public int getRed() { + return red; + } + + /** + * Returns the green value of the RGB format + * + * @return The green value + */ + public int getGreen() { + return green; + } + + /** + * Returns the blue value of the RGB format + * + * @return The blue value + */ + public int getBlue() { + return blue; + } + + /** + * Returns the red value divided by 255 + * + * @return The offsetX value + */ + @Override + public float getValueX() { + return red / 255F; + } + + /** + * Returns the green value divided by 255 + * + * @return The offsetY value + */ + @Override + public float getValueY() { + return green / 255F; + } + + /** + * Returns the blue value divided by 255 + * + * @return The offsetZ value + */ + @Override + public float getValueZ() { + return blue / 255F; + } + } + + /** + * Represents the color for the {@link EffLib#NOTE} effect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + public static final class NoteColor extends ParticleColor { + private final int note; + + /** + * Construct a new note color + * + * @param note Note id which determines color + * @throws IllegalArgumentException If the note value is lower than 0 or higher than 24 + */ + public NoteColor(int note) throws IllegalArgumentException { + if (note < 0) { + throw new IllegalArgumentException("The note value is lower than 0"); + } + if (note > 24) { + throw new IllegalArgumentException("The note value is higher than 24"); + } + this.note = note; + } + + /** + * Returns the note value divided by 24 + * + * @return The offsetX value + */ + @Override + public float getValueX() { + return note / 24F; + } + + /** + * Returns zero because the offsetY value is unused + * + * @return zero + */ + @Override + public float getValueY() { + return 0; + } + + /** + * Returns zero because the offsetZ value is unused + * + * @return zero + */ + @Override + public float getValueZ() { + return 0; + } + + } + + /** + * Represents a runtime exception that is thrown either if the displayed particle effect requires data and has none or vice-versa or if the data type is incorrect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + private static final class ParticleDataException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new particle data exception + * + * @param message Message that will be logged + */ + public ParticleDataException(String message) { + super(message); + } + } + + /** + * Represents a runtime exception that is thrown either if the displayed particle effect is not colorable or if the particle color type is incorrect + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.7 + */ + private static final class ParticleColorException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new particle color exception + * + * @param message Message that will be logged + */ + public ParticleColorException(String message) { + super(message); + } + } + + /** + * Represents a runtime exception that is thrown if the displayed particle effect requires a newer version + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.6 + */ + private static final class ParticleVersionException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new particle version exception + * + * @param message Message that will be logged + */ + public ParticleVersionException(String message) { + super(message); + } + } + + /** + * Represents a particle effect packet with all attributes which is used for sending packets to the players + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.5 + */ + public static final class ParticlePacket { + private static int version; + private static Class enumParticle; + private static Constructor packetConstructor; + private static Method getHandle; + private static Field playerConnection; + private static Method sendPacket; + private static boolean initialized; + private final EffLib effect; + private float offsetX; + private final float offsetY; + private final float offsetZ; + private final float speed; + private final int amount; + private final boolean longDistance; + private final ParticleData data; + private Object packet; + + /** + * Construct a new particle packet + * + * @param effect Particle effect + * @param offsetX Maximum distance particles can fly away from the center on the x-axis + * @param offsetY Maximum distance particles can fly away from the center on the y-axis + * @param offsetZ Maximum distance particles can fly away from the center on the z-axis + * @param speed Display speed of the particles + * @param amount Amount of particles + * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 + * @param data Data of the effect + * @throws IllegalArgumentException If the speed or amount is lower than 0 + * @see #initialize() + */ + public ParticlePacket(EffLib effect, float offsetX, float offsetY, float offsetZ, float speed, int amount, boolean longDistance, ParticleData data) throws IllegalArgumentException { + initialize(); + if (speed < 0) { + throw new IllegalArgumentException("The speed is lower than 0"); + } + if (amount < 0) { + throw new IllegalArgumentException("The amount is lower than 0"); + } + this.effect = effect; + this.offsetX = offsetX; + this.offsetY = offsetY; + this.offsetZ = offsetZ; + this.speed = speed; + this.amount = amount; + this.longDistance = longDistance; + this.data = data; + } + + /** + * Construct a new particle packet of a single particle flying into a determined direction + * + * @param effect Particle effect + * @param direction Direction of the particle + * @param speed Display speed of the particle + * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 + * @param data Data of the effect + * @throws IllegalArgumentException If the speed is lower than 0 + */ + public ParticlePacket(EffLib effect, Vector direction, float speed, boolean longDistance, ParticleData data) throws IllegalArgumentException { + this(effect, (float) direction.getX(), (float) direction.getY(), (float) direction.getZ(), speed, 0, longDistance, data); + } + + /** + * Construct a new particle packet of a single colored particle + * + * @param effect Particle effect + * @param color Color of the particle + * @param longDistance Indicates whether the maximum distance is increased from 256 to 65536 + */ + public ParticlePacket(EffLib effect, ParticleColor color, boolean longDistance) { + this(effect, color.getValueX(), color.getValueY(), color.getValueZ(), 1, 0, longDistance, null); + if (effect == EffLib.REDSTONE && color instanceof OrdinaryColor && ((OrdinaryColor) color).getRed() == 0) { + offsetX = Float.MIN_NORMAL; + } + } + + /** + * Initializes {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} and sets {@link #initialized} to true if it succeeds + *

+ * Note: These fields only have to be initialized once, so it will return if {@link #initialized} is already set to true + * + * @throws VersionIncompatibleException if your bukkit version is not supported by this library + */ + public static void initialize() throws VersionIncompatibleException { + if (initialized) { + return; + } + try { + version = Integer.valueOf(PackageType.getServerVersion().split("_")[1]); + if (version > 7) { + enumParticle = PackageType.MINECRAFT_SERVER.getClass("EnumParticle"); + } + Class packetClass = PackageType.MINECRAFT_SERVER.getClass(version < 7 ? "Packet63WorldParticles" : "PacketPlayOutWorldParticles"); + packetConstructor = ReflectionUtils.getConstructor(packetClass); + getHandle = ReflectionUtils.getMethod("CraftPlayer", PackageType.CRAFTBUKKIT_ENTITY, "getHandle"); + playerConnection = ReflectionUtils.getField("EntityPlayer", PackageType.MINECRAFT_SERVER, false, "playerConnection"); + sendPacket = ReflectionUtils.getMethod(playerConnection.getType(), "sendPacket", PackageType.MINECRAFT_SERVER.getClass("Packet")); + } catch (Exception exception) { + throw new VersionIncompatibleException("Your current bukkit version seems to be incompatible with this library", exception); + } + initialized = true; + } + + /** + * Returns the version of your server (1.x) + * + * @return The version number + */ + public static int getVersion() { + if (!initialized) { + initialize(); + } + return version; + } + + /** + * Determine if {@link #packetConstructor}, {@link #getHandle}, {@link #playerConnection} and {@link #sendPacket} are initialized + * + * @return Whether these fields are initialized or not + * @see #initialize() + */ + public static boolean isInitialized() { + return initialized; + } + + /** + * Initializes {@link #packet} with all set values + * + * @param center Center location of the effect + * @throws PacketInstantiationException If instantion fails due to an unknown error + */ + private void initializePacket(Location center) throws PacketInstantiationException { + if (packet != null) { + return; + } + try { + packet = packetConstructor.newInstance(); + if (version < 8) { + String name = effect.getName(); + if (data != null) { + name += data.getPacketDataString(); + } + ReflectionUtils.setValue(packet, true, "a", name); + } else { + ReflectionUtils.setValue(packet, true, "a", enumParticle.getEnumConstants()[effect.getId()]); + ReflectionUtils.setValue(packet, true, "j", longDistance); + if (data != null) { + int[] packetData = data.getPacketData(); + ReflectionUtils.setValue(packet, true, "k", effect == EffLib.ITEM_CRACK ? packetData : new int[] {packetData[0] | (packetData[1] << 12)}); + } + } + ReflectionUtils.setValue(packet, true, "b", (float) center.getX()); + ReflectionUtils.setValue(packet, true, "c", (float) center.getY()); + ReflectionUtils.setValue(packet, true, "d", (float) center.getZ()); + ReflectionUtils.setValue(packet, true, "e", offsetX); + ReflectionUtils.setValue(packet, true, "f", offsetY); + ReflectionUtils.setValue(packet, true, "g", offsetZ); + ReflectionUtils.setValue(packet, true, "h", speed); + ReflectionUtils.setValue(packet, true, "i", amount); + } catch (Exception exception) { + throw new PacketInstantiationException("Packet instantiation failed", exception); + } + } + + /** + * Sends the packet to a single player and caches it + * + * @param center Center location of the effect + * @param player Receiver of the packet + * @throws PacketInstantiationException If instantion fails due to an unknown error + * @throws PacketSendingException If sending fails due to an unknown error + * @see #initializePacket(Location) + */ + public void sendTo(Location center, Player player) throws PacketInstantiationException, PacketSendingException { + initializePacket(center); + try { + sendPacket.invoke(playerConnection.get(getHandle.invoke(player)), packet); + } catch (Exception exception) { + throw new PacketSendingException("Failed to send the packet to player '" + player.getName() + "'", exception); + } + } + + /** + * Sends the packet to all players in the list + * + * @param center Center location of the effect + * @param players Receivers of the packet + * @throws IllegalArgumentException If the player list is empty + * @see #sendTo(Location center, Player player) + */ + public void sendTo(Location center, List players) throws IllegalArgumentException { + if (players.isEmpty()) { + throw new IllegalArgumentException("The player list is empty"); + } + for (Player player : players) { + sendTo(center, player); + } + } + + /** + * Sends the packet to all players in a certain range + * + * @param center Center location of the effect + * @param range Range in which players will receive the packet (Maximum range for particles is usually 16, but it can differ for some types) + * @throws IllegalArgumentException If the range is lower than 1 + * @see #sendTo(Location center, Player player) + */ + public void sendTo(Location center, double range) throws IllegalArgumentException { + if (range < 1) { + throw new IllegalArgumentException("The range is lower than 1"); + } + String worldName = center.getWorld().getName(); + double squared = range * range; + for (Player player : Bukkit.getOnlinePlayers()) { + if (!player.getWorld().getName().equals(worldName) || player.getLocation().distanceSquared(center) > squared) { + continue; + } + sendTo(center, player); + } + } + + /** + * Represents a runtime exception that is thrown if a bukkit version is not compatible with this library + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.5 + */ + private static final class VersionIncompatibleException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new version incompatible exception + * + * @param message Message that will be logged + * @param cause Cause of the exception + */ + public VersionIncompatibleException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Represents a runtime exception that is thrown if packet instantiation fails + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.4 + */ + private static final class PacketInstantiationException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new packet instantiation exception + * + * @param message Message that will be logged + * @param cause Cause of the exception + */ + public PacketInstantiationException(String message, Throwable cause) { + super(message, cause); + } + } + + /** + * Represents a runtime exception that is thrown if packet sending fails + *

+ * This class is part of the ParticleEffect Library and follows the same usage conditions + * + * @author DarkBlade12 + * @since 1.4 + */ + private static final class PacketSendingException extends RuntimeException { + private static final long serialVersionUID = 3203085387160737484L; + + /** + * Construct a new packet sending exception + * + * @param message Message that will be logged + * @param cause Cause of the exception + */ + public PacketSendingException(String message, Throwable cause) { + super(message, cause); + } + } + } } \ No newline at end of file diff --git a/src/main/scala/me/skymc/taboolib/sound/SoundPack.java b/src/main/scala/me/skymc/taboolib/sound/SoundPack.java index 1b7490b..aad0c6c 100644 --- a/src/main/scala/me/skymc/taboolib/sound/SoundPack.java +++ b/src/main/scala/me/skymc/taboolib/sound/SoundPack.java @@ -1,68 +1,94 @@ package me.skymc.taboolib.sound; +import me.skymc.taboolib.TabooLib; +import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Sound; import org.bukkit.entity.Player; public class SoundPack { private Sound sound; - private Float a; - private Float b; + private float a; + private float b; + private int delay; + /** + * ENTITY_VILLAGER_NO-0-0 + */ public SoundPack() { this.sound = Sound.valueOf(SoundUtils.getModifiedSound("ENTITY_VILLAGER_NO")); - this.a = 1f; - this.b = 1f; + this.a = 1.0F; + this.b = 1.0F; } - public SoundPack(Sound sound, Float a, Float b) { + public SoundPack(Sound sound, float a, float b) { + this(sound, a, b, 0); + } + + public SoundPack(Sound sound, float a, float b, int delay) { this.sound = sound; this.a = a; this.b = b; + this.delay = delay; } public SoundPack(String s) { + parse(s); + } + + public void play(Player p) { + Bukkit.getScheduler().runTaskLater(TabooLib.instance(), () -> p.playSound(p.getLocation(), this.sound, this.a, this.b), delay); + } + + public void play(Location l) { + Bukkit.getScheduler().runTaskLater(TabooLib.instance(), () -> l.getWorld().playSound(l, this.sound, this.a, this.b), delay); + } + + public void parse(String s) { try { - sound = Sound.valueOf(SoundUtils.getModifiedSound(s.split("-")[0])); - a = Float.valueOf(s.split("-")[1]); - b = Float.valueOf(s.split("-")[2]); - } catch (Exception e) { + String[] split = s.split("-"); + this.sound = Sound.valueOf(SoundUtils.getModifiedSound(split[0])); + this.a = Float.parseFloat(split[1]); + this.b = Float.parseFloat(split[2]); + this.delay = split.length > 3 ? Integer.parseInt(split[3]) : 0; + } catch (Exception var3) { this.sound = Sound.valueOf(SoundUtils.getModifiedSound("ENTITY_VILLAGER_NO")); - this.a = 1f; - this.b = 1f; + this.a = 1.0F; + this.b = 1.0F; + this.delay = 0; } } + // ********************************* + // + // Getter and Setter + // + // ********************************* + public Sound getSound() { return sound; } - public Float getA() { + public float getA() { return a; } - public Float getB() { + public float getB() { return b; } - public void play(Player p) { - p.playSound(p.getLocation(), sound, a, b); - } - - public void parse(String s) { - try { - sound = Sound.valueOf(SoundUtils.getModifiedSound(s.split("-")[0])); - a = Float.valueOf(s.split("-")[1]); - b = Float.valueOf(s.split("-")[2]); - } catch (Exception e) { - this.sound = Sound.valueOf(SoundUtils.getModifiedSound("ENTITY_VILLAGER_NO")); - this.a = 1f; - this.b = 1f; - } + public int getDelay() { + return delay; } @Override public String toString() { - return sound.name() + "-" + a + "-" + b; + return "SoundPack{" + + "sound=" + sound + + ", a=" + a + + ", b=" + b + + ", delay=" + delay + + '}'; } } diff --git a/src/main/scala/me/skymc/taboolib/string/Language.java b/src/main/scala/me/skymc/taboolib/string/Language.java deleted file mode 100644 index 9310b22..0000000 --- a/src/main/scala/me/skymc/taboolib/string/Language.java +++ /dev/null @@ -1,126 +0,0 @@ -package me.skymc.taboolib.string; - -import com.google.common.base.Charsets; -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStreamReader; -import java.util.Collections; -import java.util.List; - -@Deprecated -public class Language { - - private FileConfiguration conf = null; - private String langName; - private Plugin plugin; - - public Language(Plugin plugin) { - this("zh_CN", plugin, false); - } - - public Language(String name, Plugin plugin) { - this(name, plugin, false); - } - - public Language(String name, Plugin plugin, boolean utf8) { - this.plugin = plugin; - this.langName = name; - - File file = new File(getLanguageDir(), name + ".yml"); - if (!file.exists()) { - plugin.saveResource("Language/" + name + ".yml", true); - } - - if (utf8) { - reloadUTF8(this.langName); - } else { - reload(this.langName); - } - } - - public FileConfiguration getConfiguration() { - return conf; - } - - public void send(CommandSender sender, String key) { - sender.sendMessage(get(key)); - } - - public void send(Player player, String key) { - player.sendMessage(get(key)); - } - - public void sendList(CommandSender sender, String key) { - List list = getList(key); - for (String msg : list) { - sender.sendMessage(msg); - } - } - - public void sendList(Player player, String key) { - List list = getList(key); - for (String msg : list) { - player.sendMessage(msg); - } - } - - public String get(String key) { - if (conf == null || conf.getString(key) == null) { - return "§4[Language \"" + key + "\" Not Found]"; - } - return conf.getString(key).replace("&", "§"); - } - - public List getList(String key) { - if (conf == null || conf.getString(key) == null) { - return Collections.singletonList("§4[Language \"" + key + "\" Not Found]"); - } - List list = conf.getStringList(key); - for (int i = 0; i < list.size(); i++) { - list.set(i, list.get(i).replace("&", "§")); - } - return list; - } - - public void reload() { - reload(langName); - } - - public void reload(String name) { - File langFile = new File(getLanguageDir(), name + ".yml"); - if (!langFile.exists()) { - MsgUtils.warn("语言文件 " + langName + " 不存在, 请更改配置文件"); - return; - } - conf = YamlConfiguration.loadConfiguration(langFile); - } - - public void reloadUTF8(String name) { - File langFile = new File(getLanguageDir(), name + ".yml"); - if (!langFile.exists()) { - MsgUtils.warn("语言文件 " + langName + " 不存在, 请更改配置文件"); - return; - } - try { - conf = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(langFile), Charsets.UTF_8)); - } catch (FileNotFoundException e) { - conf = new YamlConfiguration(); - } - } - - private File getLanguageDir() { - File dir = new File(plugin.getDataFolder(), "Language"); - if (!dir.exists()) { - dir.mkdirs(); - } - return dir; - } -} \ No newline at end of file diff --git a/src/main/scala/me/skymc/taboolib/string/LanguagePack.java b/src/main/scala/me/skymc/taboolib/string/LanguagePack.java deleted file mode 100644 index 6ea3efc..0000000 --- a/src/main/scala/me/skymc/taboolib/string/LanguagePack.java +++ /dev/null @@ -1,104 +0,0 @@ -package me.skymc.taboolib.string; - -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.Plugin; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -@Deprecated -public class LanguagePack { - - private File filedir; - private File file; - - private FileConfiguration fileconf; - - private String name; - private Plugin plugin; - - private HashMap> lang = new HashMap<>(); - - public LanguagePack(String name, Plugin plugin) { - this.plugin = plugin; - this.name = name; - - filedir = new File(plugin.getDataFolder(), "Languages"); - if (!filedir.exists()) { - filedir.mkdir(); - } - - file = new File(filedir, name + ".yml"); - if (!file.exists()) { - try { - file.createNewFile(); - } catch (IOException e) { - MsgUtils.Console("&8[" + plugin.getName() + "]&4 载入语言文件出错"); - } - } - - fileconf = YamlConfiguration.loadConfiguration(file); - reloadLanguage(); - - MsgUtils.Console("&8[" + plugin.getName() + "]&7 载入语言文件&f: " + name + ".yml"); - } - - public File getLanguageFile() { - return file; - } - - public File getLanguageDir() { - return filedir; - } - - public FileConfiguration getLanguageConfiguration() { - return fileconf; - } - - public HashMap> getLanguage() { - return lang; - } - - public String getLanguageName() { - return name; - } - - public Plugin getLanguagePlugin() { - return plugin; - } - - public void reloadLanguage(String name) { - - file = new File(filedir, name + ".yml"); - if (!file.exists()) { - try { - file.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - fileconf = YamlConfiguration.loadConfiguration(file); - reloadLanguage(); - } - - public void reloadLanguage() { - lang.clear(); - - for (String key : fileconf.getConfigurationSection("").getKeys(false)) { - - List _lang = new ArrayList<>(); - fileconf.getStringList(key).forEach(x -> _lang.add(x.replace("&", "§") - .replace("$plugin_name", plugin.getDescription().getName()) - .replace("$plugin_authors", plugin.getDescription().getAuthors().toString()) - .replace("$plugin_version", plugin.getDescription().getVersion()))); - - lang.put(key, _lang); - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/LanguageUtils.java b/src/main/scala/me/skymc/taboolib/string/LanguageUtils.java deleted file mode 100644 index 2e4d935..0000000 --- a/src/main/scala/me/skymc/taboolib/string/LanguageUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -package me.skymc.taboolib.string; - -import me.skymc.taboolib.message.MsgUtils; -import org.bukkit.plugin.Plugin; - -import java.io.File; -import java.util.Collections; -import java.util.List; - -@Deprecated -public class LanguageUtils { - - public static String a(LanguagePack l, String key) { - if (l.getLanguage().containsKey(key)) { - return l.getLanguage().get(key).get(0); - } - return ""; - } - - public static List b(LanguagePack l, String key) { - if (l.getLanguage().containsKey(key)) { - return l.getLanguage().get(key); - } - return Collections.singletonList(""); - } - - public static void saveLanguageFile(String name, Plugin plugin) { - if (!new File(new File(plugin.getDataFolder(), "Languages"), name + ".yml").exists()) { - plugin.saveResource("Languages/" + name + ".yml", true); - MsgUtils.Console("&8[" + plugin.getName() + "]&7 生成语言文件&f: " + name + ".yml"); - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/PatternUtils.java b/src/main/scala/me/skymc/taboolib/string/PatternUtils.java deleted file mode 100644 index 0eeeea3..0000000 --- a/src/main/scala/me/skymc/taboolib/string/PatternUtils.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.skymc.taboolib.string; - -@Deprecated -public class PatternUtils { - - @Deprecated - public static String doubleNumber = "((\\-|\\+)?\\d+(\\.\\d+)?)"; - @Deprecated - public static String doubleNumber2 = "(\\d+(\\.\\d+)?)"; - - public static String doubleNumber3 = "((?:\\-|\\+)?\\d+(?:\\.\\d+)?)"; - - public static String consolidateStrings(final String[] args, final int start) { - StringBuilder ret = new StringBuilder(args[start]); - - if (args.length > start + 1) { - for (int i = start + 1; i < args.length; ++i) { - ret.append(" ").append(args[i]); - } - } - return ret.toString(); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/Language2.java b/src/main/scala/me/skymc/taboolib/string/language2/Language2.java deleted file mode 100644 index 7516212..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/Language2.java +++ /dev/null @@ -1,102 +0,0 @@ -package me.skymc.taboolib.string.language2; - -import com.ilummc.tlib.resources.TLocale; -import me.clip.placeholderapi.PlaceholderAPI; -import me.skymc.taboolib.fileutils.ConfigUtils; -import org.bukkit.Bukkit; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; - -import java.io.File; - -/** - * @author sky - * @since 2018年2月13日 下午2:37:07 - */ -public class Language2 { - - private FileConfiguration configuration; - private File languageFile; - private File languageFolder; - private Plugin plugin; - private String languageName; - - public Language2(Plugin plugin) { - this("zh_CN", plugin); - } - - public Language2(String languageName, Plugin plugin) { - this.languageName = languageName; - this.plugin = plugin; - reload(languageName); - } - - public FileConfiguration getConfiguration() { - return configuration; - } - - public File getLanguageFile() { - return languageFile; - } - - public File getLanguageFolder() { - return languageFolder; - } - - public Plugin getPlugin() { - return plugin; - } - - public String getLanguageName() { - return languageName; - } - - public Language2Value get(String key) { - return new Language2Value(this, key); - } - - public Language2Value get(String key, String... placeholder) { - Language2Value value = new Language2Value(this, key); - for (int i = 0; i < placeholder.length; i++) { - value.addPlaceholder("$" + i, placeholder[i]); - } - return value; - } - - public void reload() { - reload(this.languageName); - } - - public void reload(String languageName) { - createFolder(plugin); - languageName = formatName(languageName); - languageFile = new File(languageFolder, languageName); - if (!languageFile.exists()) { - if (plugin.getResource("Language2/" + languageName) == null) { - TLocale.Logger.error("LANGUAGE2.FAIL-NOTFOUND-FILE", languageName); - } else { - plugin.saveResource("Language2/" + languageName, true); - } - } - configuration = ConfigUtils.load(plugin, languageFile); - } - - public String setPlaceholderAPI(Player player, String string) { - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null && player != null) { - return PlaceholderAPI.setPlaceholders(player, string); - } - return string; - } - - private String formatName(String name) { - return name.contains(".yml") ? name : name + ".yml"; - } - - private void createFolder(Plugin plugin) { - languageFolder = new File(plugin.getDataFolder(), "Language2"); - if (!languageFolder.exists()) { - languageFolder.mkdir(); - } - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/Language2Format.java b/src/main/scala/me/skymc/taboolib/string/language2/Language2Format.java deleted file mode 100644 index 6fba600..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/Language2Format.java +++ /dev/null @@ -1,152 +0,0 @@ -package me.skymc.taboolib.string.language2; - -import me.skymc.taboolib.string.language2.value.*; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; - -/** - * @author sky - * @since 2018-03-08 22:45:56 - */ -public class Language2Format implements Language2Line { - - private Language2Value language2Value; - private List language2Lines = new ArrayList<>(); - - public Language2Format(Player player, Language2Value value) { - language2Value = value; - // 语言类型 - Language2Type type = Language2Type.TEXT; - // 递交数据 - List values = new LinkedList<>(); - - // 遍历内容 - for (String line : value.getLanguageValue()) { - // 文本类型 - if (line.contains("[text]")) { - // 递交数据 - parseValue(player, values, type); - // 更改类型 - type = Language2Type.TEXT; - } - // 大标题 - else if (line.contains("[title]")) { - // 递交数据 - parseValue(player, values, type); - // 更改类型 - type = Language2Type.TITLE; - } - // 小标题 - else if (line.contains("[action]")) { - // 递交数据 - parseValue(player, values, type); - // 更改类型 - type = Language2Type.ACTION; - } - // JSON - else if (line.contains("[json]")) { - // 递交数据 - parseValue(player, values, type); - // 更改类型 - type = Language2Type.JSON; - } - // JSON2 - else if (line.contains("[json2]")) { - // 递交数据 - parseValue(player, values, type); - // 更改类型 - type = Language2Type.JSON2; - } - // 音效 - else if (line.contains("[sound]")) { - // 递交数据 - parseValue(player, values, type); - // 更改类型 - type = Language2Type.SOUND; - } - // 书本 - else if (line.contains("[book]")) { - // 递交数据 - parseValue(player, values, type); - // 更改类型 - type = Language2Type.BOOK; - } else if (line.contains("[return]")) { - // 递交数据 - parseValue(player, values, type); - } - // 默认 - else { - // 追加内容 - values.add(line); - } - } - } - - public Language2Value getLanguage2Value() { - return language2Value; - } - - public List getLanguage2Lines() { - return language2Lines; - } - - /** - * 识别内容 - * - * @param player 玩家 - * @param list 数据 - * @param type 类型 - */ - private void parseValue(Player player, List list, Language2Type type) { - if (list.size() == 0) { - return; - } - // 变量转换 - List listPlaceholder = language2Value.setPlaceholder(list, player); - // 大标题 - switch (type) { - case TITLE: - language2Lines.add(new Language2Title(this, listPlaceholder)); - break; - // 小标题 - case ACTION: - language2Lines.add(new Language2Action(this, listPlaceholder)); - break; - // JSON - case JSON: - language2Lines.add(new Language2Json(this, listPlaceholder, player)); - break; - // JSON2 - case JSON2: - language2Lines.add(new Language2Json2(this, listPlaceholder, player)); - break; - // 音效 - case SOUND: - language2Lines.add(new Language2Sound(this, listPlaceholder)); - break; - // 书本 - case BOOK: - language2Lines.add(new Language2Book(this, listPlaceholder, player)); - break; - default: - language2Lines.add(new Language2Text(this, listPlaceholder)); - break; - } - // 清理数据 - list.clear(); - listPlaceholder.clear(); - } - - @Override - public void send(Player player) { - language2Lines.forEach(line -> line.send(player)); - } - - @Override - public void console() { - language2Lines.forEach(Language2Line::console); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/Language2Line.java b/src/main/scala/me/skymc/taboolib/string/language2/Language2Line.java deleted file mode 100644 index fb0c640..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/Language2Line.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.skymc.taboolib.string.language2; - -import org.bukkit.entity.Player; - -/** - * @author sky - * @since 2018-03-08 23:36:22 - */ -public interface Language2Line { - - void send(Player player); - - void console(); - -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/Language2Type.java b/src/main/scala/me/skymc/taboolib/string/language2/Language2Type.java deleted file mode 100644 index c7fbda8..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/Language2Type.java +++ /dev/null @@ -1,43 +0,0 @@ -package me.skymc.taboolib.string.language2; - -/** - * @author sky - * @since 2018年2月13日 下午3:14:00 - */ -public enum Language2Type { - - /** - * 一般文本 - */ - TEXT, - - /** - * JSON 文本 - */ - JSON, - - /** - * JSON2 文本 - */ - JSON2, - - /** - * 大标题 - */ - TITLE, - - /** - * 小标题 - */ - ACTION, - - /** - * 音效 - */ - SOUND, - - /** - * 书本 - */ - BOOK -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/Language2Value.java b/src/main/scala/me/skymc/taboolib/string/language2/Language2Value.java deleted file mode 100644 index 98f9982..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/Language2Value.java +++ /dev/null @@ -1,216 +0,0 @@ -package me.skymc.taboolib.string.language2; - -import me.skymc.taboolib.string.language2.value.Language2Text; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.IntStream; - -/** - * @author sky - * @since 2018年2月13日 下午3:05:15 - */ -public class Language2Value { - - private Language2 language; - - private String languageKey; - - private List languageValue; - - private LinkedHashMap placeholder = new LinkedHashMap<>(); - - private boolean enablePlaceholderAPI = false; - - /** - * 构造方法 - */ - public Language2Value(Language2 language, String languageKey) { - // 如果语言文件不存在 - if (language == null || languageKey == null) { - languageValue = Arrays.asList(ChatColor.DARK_RED + "[]", "[return]"); - return; - } - - // 如果语言文本不存在 - if (!language.getConfiguration().contains(languageKey)) { - languageValue = Arrays.asList(ChatColor.DARK_RED + "[]", "[return]"); - return; - } - - // 如果不是集合类型 - if (language.getConfiguration().get(languageKey) instanceof List) { - // 设置文本 - languageValue = asColored(language.getConfiguration().getStringList(languageKey)); - // 追加结尾 - languageValue.add("[return]"); - // 是否启用PAPI - if (languageValue.get(0).contains("[papi]")) { - enablePlaceholderAPI = true; - } - } else { - // 设置文本 - languageValue = Arrays.asList(ChatColor.translateAlternateColorCodes('&', language.getConfiguration().getString(languageKey)), "[return]"); - } - - // 初始化变量 - this.language = language; - this.languageKey = languageKey; - } - - public Language2 getLanguage() { - return language; - } - - public String getLanguageKey() { - return languageKey; - } - - public List getLanguageValue() { - return languageValue; - } - - public LinkedHashMap getPlaceholder() { - return placeholder; - } - - public boolean isEnablePlaceholderAPI() { - return enablePlaceholderAPI; - } - - /** - * 向玩家发送信息 - * - * @param player - */ - public void send(Player player) { - new Language2Format(player, this).send(player); - } - - /** - * 向玩家发送信息 - * - * @param players 玩家 - */ - public void send(List players) { - players.forEach(this::send); - } - - /** - * 向指令发送者发送信息 - * - * @param sender - */ - public void send(CommandSender sender) { - if (sender instanceof Player) { - send((Player) sender); - } else { - console(); - } - } - - /** - * 全服公告 - */ - public void broadcast() { - send(new ArrayList<>(Bukkit.getOnlinePlayers())); - } - - /** - * 发送到后台 - */ - public void console() { - new Language2Format(null, this).console(); - } - - /** - * 获取文本 - * - * @return - */ - public String asString() { - Language2Format format = new Language2Format(null, this); - if (format.getLanguage2Lines().get(0) instanceof Language2Text) { - Language2Text text = (Language2Text) format.getLanguage2Lines().get(0); - return setPlaceholder(text.getText().get(0), null); - } else { - return languageValue.size() == 0 ? ChatColor.DARK_RED + "[]" : setPlaceholder(languageValue.get(0), null); - } - } - - /** - * 获取文本集合 - * - * @return - */ - public List asStringList() { - Language2Format format = new Language2Format(null, this); - if (format.getLanguage2Lines().get(0) instanceof Language2Text) { - Language2Text text = (Language2Text) format.getLanguage2Lines().get(0); - return setPlaceholder(text.getText(), null); - } else { - return Collections.singletonList(languageValue.size() == 0 ? ChatColor.DARK_RED + "[]" : setPlaceholder(languageValue.get(0), null)); - } - } - - /** - * 变量替换 - * - * @param value 替换文本 - * @param player 检测玩家 - * @return String - */ - public String setPlaceholder(String value, Player player) { - for (Entry entry : placeholder.entrySet()) { - value = value.replace(entry.getKey(), entry.getValue()); - } - return isEnablePlaceholderAPI() ? this.language.setPlaceholderAPI(player, value) : value; - } - - /** - * 变量替换 - * - * @param list 替换集合 - * @param player 检测玩家 - * @return {@link List} - */ - public List setPlaceholder(List list, Player player) { - List _list = new ArrayList<>(list); - for (int i = 0; i < _list.size(); i++) { - _list.set(i, setPlaceholder(_list.get(i), player)); - } - return _list; - } - - /** - * 变量替换构造 - * - * @param key 键 - * @param value 值 - * @return {@link Language2Value} - */ - public Language2Value addPlaceholder(String key, String value) { - this.placeholder.put(key, value); - return this; - } - - /** - * 替换颜色 - * - * @param list - * @return - */ - public List asColored(List list) { - IntStream.range(0, list.size()).forEach(i -> list.set(i, ChatColor.translateAlternateColorCodes('&', list.get(i)))); - return list; - } - - @Override - public String toString() { - return asString(); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Action.java b/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Action.java deleted file mode 100644 index 0f1816a..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Action.java +++ /dev/null @@ -1,100 +0,0 @@ -package me.skymc.taboolib.string.language2.value; - -import me.skymc.taboolib.Main; -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.display.ActionUtils; -import me.skymc.taboolib.other.NumberUtils; -import me.skymc.taboolib.string.language2.Language2Format; -import me.skymc.taboolib.string.language2.Language2Line; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.util.List; - -/** - * @author sky - * @since 2018年2月13日 下午3:58:07 - */ -public class Language2Action implements Language2Line { - - private static final String KEY_TEXT = " text: "; - private static final String KEY_STAY = " repeat: "; - - private String text = ""; - - private int repeat = 1; - - private Language2Value value; - - public Language2Action(Language2Format format, List list) { - // 变量初始化 - this.value = format.getLanguage2Value(); - // 遍历文本 - for (String message : list) { - try { - // 动作栏提示 - if (message.startsWith(KEY_TEXT)) { - text = message.substring(KEY_TEXT.length()); - } - // 持续时间 - if (message.startsWith(KEY_STAY)) { - repeat = NumberUtils.getInteger(message.substring(KEY_STAY.length())); - } - } catch (Exception e) { - // 识别异常 - text = ChatColor.DARK_RED + "[]"; - } - } - - // 检查重复次数 - if (repeat < 0) { - repeat = 1; - text = ChatColor.DARK_RED + "[]"; - } - } - - public String getText() { - return text; - } - - public int getRepeat() { - return repeat; - } - - public Language2Value getValue() { - return value; - } - - /** - * 发送给玩家 - * - * @param player 玩家 - */ - @Override - public void send(Player player) { - // 检查版本 - if (TabooLib.getVerint() < 10800) { - player.sendMessage(ChatColor.DARK_RED + "[]"); - } else { - new BukkitRunnable() { - int times = 0; - - @Override - public void run() { - ActionUtils.send(player, text); - if ((times += 1) >= repeat) { - cancel(); - } - } - }.runTaskTimer(Main.getInst(), 0, 20); - } - } - - @Override - public void console() { - Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[]"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Book.java b/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Book.java deleted file mode 100644 index f2118a3..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Book.java +++ /dev/null @@ -1,242 +0,0 @@ -package me.skymc.taboolib.string.language2.value; - -import com.ilummc.tlib.bungee.api.chat.BaseComponent; -import com.ilummc.tlib.bungee.api.chat.ClickEvent; -import com.ilummc.tlib.bungee.api.chat.HoverEvent; -import com.ilummc.tlib.bungee.api.chat.TextComponent; -import me.skymc.taboolib.bookformatter.BookFormatter; -import me.skymc.taboolib.bookformatter.action.ClickAction; -import me.skymc.taboolib.bookformatter.action.HoverAction; -import me.skymc.taboolib.bookformatter.builder.BookBuilder; -import me.skymc.taboolib.bookformatter.builder.PageBuilder; -import me.skymc.taboolib.bookformatter.builder.TextBuilder; -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.other.NumberUtils; -import me.skymc.taboolib.string.VariableFormatter; -import me.skymc.taboolib.string.language2.Language2Format; -import me.skymc.taboolib.string.language2.Language2Line; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; -import java.util.regex.Pattern; - -/** - * @author sky - * @since 2018-03-10 15:55:28 - */ -public class Language2Book implements Language2Line { - - private static final String KEY_TEXT = " text: "; - private static final String KEY_COMMAND = " command: "; - private static final String KEY_SUGGEST = " suggest: "; - private static final String KEY_URL = " url: "; - private static final String KEY_PAGE = " page: "; - private static final String KEY_SHOWTEXT = " showtext: "; - private static final String KEY_SHOWITEM = " showitem: "; - private static final String KEY_OPTION = "@option:"; - private static final Pattern pattern = Pattern.compile("<@(\\S+)>"); - - private Player player; - - private Language2Value value; - - private HashMap options = new HashMap<>(); - - private BookBuilder book; - - public Language2Book(Language2Format format, List list, Player player) { - // 变量 - this.player = player; - this.value = format.getLanguage2Value(); - this.book = BookFormatter.writtenBook(); - // 设置 - formatOptions(list); - // 内容 - PageBuilder page = new PageBuilder(); - // 遍历内容 - for (String line : list) { - // 翻页 - if (line.equals("[page]")) { - book.addPages(page.build()); - page = new PageBuilder(); - } - // 设置 - else if (line.startsWith("@option")) { - break; - } else { - for (VariableFormatter.Variable variable : new VariableFormatter(line, pattern).find().getVariableList()) { - if (variable.isVariable()) { - String node = variable.getText().substring(1); - if (!options.containsKey(node)) { - page.add("§4[]"); - } else { - TextBuilder builder = options.get(node); - BaseComponent component = new TextComponent(builder.getText()); - if (builder.getHover() != null) { - component.setHoverEvent(new HoverEvent(builder.getHover().action(), builder.getHover().value())); - } - if (builder.getClick() != null) { - component.setClickEvent(new ClickEvent(builder.getClick().action(), builder.getClick().value())); - } - page.add(component); - } - } else { - page.add(variable.getText()); - } - } - page.newLine(); - } - } - // 结尾 - book.addPages(page.build()); - } - - - @Override - public void send(Player player) { - BookFormatter.forceOpen(player, book.build()); - } - - @Override - public void console() { - Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[]"); - } - - // ********************************* - // - // Getter and Setter - // - // ********************************* - - public static Pattern getPattern() { - return pattern; - } - - public Player getPlayer() { - return player; - } - - public Language2Value getValue() { - return value; - } - - public HashMap getOptions() { - return options; - } - - public BookBuilder getBook() { - return book; - } - - // ********************************* - // - // Private Methods - // - // ********************************* - - private List> getBookPages(List source) { - List> list = new ArrayList<>(); - for (String line : removeOption(source)) { - if (line.equalsIgnoreCase("[page]")) { - list.add(new ArrayList<>()); - } else { - getLatestList(list).add(line); - } - } - return list; - } - - public List getLatestList(List> list) { - if (list.size() == 0) { - List newList = new ArrayList<>(); - list.add(newList); - return newList; - } else { - return list.get(list.size() - 1); - } - } - - public List removeOption(List source) { - List list = new ArrayList<>(); - for (String line : source) { - if (!line.contains("@option")) { - list.add(line); - } else { - return list; - } - } - return list; - } - - private void formatOptions(List list) { - // 获取书本设置 - HashMap> _options = getOptions(list); - for (Entry> entry : _options.entrySet()) { - TextBuilder builder = new TextBuilder(); - // 遍历内容 - for (String _option : entry.getValue()) { - if (_option.startsWith(KEY_TEXT)) { - builder.text(_option.substring(KEY_TEXT.length())); - } else if (_option.startsWith(KEY_COMMAND)) { - builder.onClick(ClickAction.runCommand(_option.substring(KEY_COMMAND.length()))); - } else if (_option.startsWith(KEY_SUGGEST)) { - builder.onClick(ClickAction.suggestCommand(_option.substring(KEY_SUGGEST.length()))); - } else if (_option.startsWith(KEY_URL)) { - try { - builder.onClick(ClickAction.openUrl(_option.substring(KEY_URL.length()))); - } catch (Exception e) { - builder.text("§4[]"); - } - } else if (_option.startsWith(KEY_PAGE)) { - builder.onClick(ClickAction.changePage(NumberUtils.getInteger(_option.substring(KEY_PAGE.length())))); - } else if (_option.startsWith(KEY_SHOWTEXT)) { - builder.onHover(HoverAction.showText(_option.substring(KEY_SHOWTEXT.length()))); - } else if (_option.startsWith(KEY_SHOWITEM)) { - ItemStack item = ItemUtils.getCacheItem(_option.substring(KEY_SHOWITEM.length())); - if (item == null) { - item = new ItemStack(Material.STONE); - } - builder.onHover(HoverAction.showItem(item)); - } - } - options.put(entry.getKey(), builder); - } - } - - private HashMap> getOptions(List list) { - HashMap> options_source = new HashMap<>(); - List option = new ArrayList<>(); - // 遍历 - String optionName = null; - boolean start = false; - // 遍历所有代码 - for (String line : list) { - if (line.startsWith(KEY_OPTION)) { - // 如果已经开始检测 - if (start) { - // 返回源码 - options_source.put(optionName, new ArrayList<>(option)); - // 清除源码 - option.clear(); - } - // 标签 - start = true; - // 当前设置名称 - optionName = line.substring(KEY_OPTION.length()); - } else if (start) { - option.add(line); - } - } - // 返回最后设置 - options_source.put(optionName, option); - return options_source; - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Json.java b/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Json.java deleted file mode 100644 index 42e6f5b..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Json.java +++ /dev/null @@ -1,174 +0,0 @@ -package me.skymc.taboolib.string.language2.value; - -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.jsonformatter.JSONFormatter; -import me.skymc.taboolib.jsonformatter.click.ClickEvent; -import me.skymc.taboolib.jsonformatter.click.OpenUrlEvent; -import me.skymc.taboolib.jsonformatter.click.RunCommandEvent; -import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent; -import me.skymc.taboolib.jsonformatter.hover.HoverEvent; -import me.skymc.taboolib.jsonformatter.hover.ShowItemEvent; -import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; -import me.skymc.taboolib.string.language2.Language2Format; -import me.skymc.taboolib.string.language2.Language2Line; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.List; - -/** - * @author sky - * @since 2018年2月13日 下午4:11:33 - */ -public class Language2Json implements Language2Line { - - private static final String KEY_TEXT = " text: "; - private static final String KEY_COMMAND = " command: "; - private static final String KEY_SUGGEST = " suggest: "; - private static final String KEY_URL = " url: "; - private static final String KEY_ITEM = " item: "; - - private Player player; - - private Language2Value value; - - private JSONFormatter json = new JSONFormatter(); - - private StringBuffer text = new StringBuffer(); - - public Language2Json(Language2Format format, List list, Player player) { - // 首次检测 - boolean isFirst = true; - boolean isBreak = false; - - // 变量初始化 - this.value = format.getLanguage2Value(); - this.player = player; - - // 动作初始化 - ClickEvent clickEvent = null; - HoverEvent hoverEvent = null; - - // 文本初始化 - String current = ChatColor.DARK_RED + "[]"; - - // 遍历文本 - for (String message : list) { - try { - // 如果是显示文本 - if (message.startsWith(KEY_TEXT)) { - hoverEvent = new ShowTextEvent(message.replace("||", "\n").substring(KEY_TEXT.length())); - } - // 显示物品 - else if (message.startsWith(KEY_ITEM)) { - ItemStack item = ItemUtils.getCacheItem(message.substring(KEY_ITEM.length())); - if (item == null) { - item = new ItemStack(Material.STONE); - } - hoverEvent = new ShowItemEvent(item); - } - // 执行指令 - else if (message.startsWith(KEY_COMMAND)) { - clickEvent = new RunCommandEvent(message.substring(KEY_COMMAND.length())); - } - // 打印指令 - else if (message.startsWith(KEY_SUGGEST)) { - clickEvent = new SuggestCommandEvent(message.substring(KEY_SUGGEST.length())); - } - // 打开连接 - else if (message.startsWith(KEY_URL)) { - clickEvent = new OpenUrlEvent(message.substring(KEY_URL.length())); - } - // 换行 - else if ("[break]".equals(message)) { - append(current, clickEvent, hoverEvent); - // 删除动作 - clickEvent = null; - hoverEvent = null; - // 换行 - json.newLine(); - // 标记 - isBreak = true; - } - // 新内容 - else { - if (!isFirst && !isBreak) { - append(current, clickEvent, hoverEvent); - // 删除动作 - clickEvent = null; - hoverEvent = null; - } - // 更新 - current = message; - // 标记 - isFirst = false; - isBreak = false; - } - } catch (Exception e) { - // 识别异常 - json.append(ChatColor.DARK_RED + "[]"); - } - } - // 追加 - append(current, clickEvent, hoverEvent); - } - - public Player getPlayer() { - return player; - } - - public Language2Value getValue() { - return value; - } - - public JSONFormatter getJson() { - return json; - } - - public StringBuffer getText() { - return text; - } - - /** - * 发送给玩家 - * - * @param player 玩家 - */ - @Override - public void send(Player player) { - json.send(player); - } - - @Override - public void console() { - Bukkit.getConsoleSender().sendMessage(text.toString()); - } - - /** - * 追加 JSON 内容 - * - * @param current 文本 - * @param hoverEvent 显示动作 - */ - private void append(String current, ClickEvent clickEvent, HoverEvent hoverEvent) { - if (clickEvent == null && hoverEvent == null) { - // 纯文本 - json.append(current); - } else if (clickEvent != null && hoverEvent == null) { - // 纯点击 - json.appendClick(current, clickEvent); - } else if (clickEvent == null && hoverEvent != null) { - // 纯显示 - json.appendHover(current, hoverEvent); - } else { - // 全部 - json.appendHoverClick(current, hoverEvent, clickEvent); - } - // 追加显示文本 - text.append(current); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Json2.java b/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Json2.java deleted file mode 100644 index 2d08958..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Json2.java +++ /dev/null @@ -1,214 +0,0 @@ -package me.skymc.taboolib.string.language2.value; - -import me.skymc.taboolib.inventory.ItemUtils; -import me.skymc.taboolib.jsonformatter.JSONFormatter; -import me.skymc.taboolib.jsonformatter.click.ClickEvent; -import me.skymc.taboolib.jsonformatter.click.OpenUrlEvent; -import me.skymc.taboolib.jsonformatter.click.RunCommandEvent; -import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent; -import me.skymc.taboolib.jsonformatter.hover.HoverEvent; -import me.skymc.taboolib.jsonformatter.hover.ShowItemEvent; -import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent; -import me.skymc.taboolib.string.language2.Language2Format; -import me.skymc.taboolib.string.language2.Language2Line; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author sky - * @since 2018-03-10 15:55:28 - */ -public class Language2Json2 implements Language2Line { - - private static final String KEY_TEXT = " text: "; - private static final String KEY_COMMAND = " command: "; - private static final String KEY_SUGGEST = " suggest: "; - private static final String KEY_URL = " url: "; - private static final String KEY_SHOWTEXT = " showtext: "; - private static final String KEY_SHOWITEM = " showitem: "; - private static final String KEY_OPTION = "@option:"; - private static final Pattern pattern = Pattern.compile("<@(\\S+)>"); - - private Player player; - - private Language2Value value; - - private HashMap options = new HashMap<>(); - - private JSONFormatter json = new JSONFormatter(); - - public Language2Json2(Language2Format format, List list, Player player) { - // 变量 - this.player = player; - this.value = format.getLanguage2Value(); - - // 获取书本设置 - formatOptions(list); - // 遍历内容 - int lineNumber = 0; - int lineNumberEnd = getLineNumberEnd(list); - for (String line : list) { - if (line.startsWith("@option")) { - break; - } else { - Matcher matcher = pattern.matcher(line); - boolean find = false; - while (matcher.find()) { - find = true; - String optionName = matcher.group(1); - String optionFullName = "<@" + matcher.group(1) + ">"; - // 判断设置是否存在 - if (!options.containsKey(optionName)) { - json.append("§4[]"); - } else { - String[] line_split = line.split(optionFullName); - try { - // 单独一行 - if (line_split.length == 0) { - json.append(options.get(optionName)); - } else { - // 前段 - json.append(line_split[0]); - // 变量 - json.append(options.get(optionName)); - // 后段 - if (line_split.length >= 2) { - // 获取文本 - StringBuilder sb = new StringBuilder(); - for (int i = 1; i < line_split.length; i++) { - sb.append(line_split[i]).append(optionFullName); - } - // 更改文本 - line = sb.substring(0, sb.length() - optionFullName.length()); - // 如果后段还有变量 - if (!pattern.matcher(line).find()) { - json.append(line_split[1]); - } - } - } - } catch (Exception e) { - json.append("§4[]"); - } - } - } - if (!find) { - json.append(line); - } - if (++lineNumber < lineNumberEnd) { - json.newLine(); - } - } - } - } - - public Player getPlayer() { - return player; - } - - public Language2Value getValue() { - return value; - } - - public HashMap getOptions() { - return options; - } - - public JSONFormatter getJson() { - return json; - } - - private int getLineNumberEnd(List list) { - int line = list.size(); - for (int i = 0; i < list.size(); i++) { - if (list.get(i).startsWith("@option")) { - return i; - } - } - return line; - } - - private void formatOptions(List list) { - HashMap> _options = getOptions(list); - for (Entry> entry : _options.entrySet()) { - JSONFormatter jsonFormatter = new JSONFormatter(); - String current = ChatColor.DARK_RED + "[]"; - ClickEvent clickEvent = null; - HoverEvent hoverEvent = null; - for (String _option : entry.getValue()) { - if (_option.startsWith(KEY_TEXT)) { - current = _option.substring(KEY_TEXT.length()); - } else if (_option.startsWith(KEY_COMMAND)) { - clickEvent = new RunCommandEvent(_option.substring(KEY_COMMAND.length())); - } else if (_option.startsWith(KEY_SUGGEST)) { - clickEvent = new SuggestCommandEvent(_option.substring(KEY_SUGGEST.length())); - } else if (_option.startsWith(KEY_URL)) { - clickEvent = new OpenUrlEvent(_option.substring(KEY_URL.length())); - } else if (_option.startsWith(KEY_SHOWTEXT)) { - hoverEvent = new ShowTextEvent(_option.replace("||", "\n").substring(KEY_SHOWTEXT.length())); - } else if (_option.startsWith(KEY_SHOWITEM)) { - ItemStack item = ItemUtils.getCacheItem(_option.substring(KEY_SHOWITEM.length())); - if (item == null) { - item = new ItemStack(Material.STONE); - } - hoverEvent = new ShowItemEvent(item); - } - } - append(jsonFormatter, current, clickEvent, hoverEvent); - options.put(entry.getKey(), jsonFormatter); - } - } - - private void append(JSONFormatter json, String current, ClickEvent clickEvent, HoverEvent hoverEvent) { - if (clickEvent == null && hoverEvent == null) { - json.append(current); - } else if (clickEvent != null && hoverEvent == null) { - json.appendClick(current, clickEvent); - } else if (clickEvent == null) { - json.appendHover(current, hoverEvent); - } else { - json.appendHoverClick(current, hoverEvent, clickEvent); - } - } - - private HashMap> getOptions(List list) { - HashMap> options_source = new HashMap<>(); - List option = new ArrayList<>(); - String optionName = null; - boolean start = false; - for (String line : list) { - if (line.startsWith(KEY_OPTION)) { - if (start) { - options_source.put(optionName, new ArrayList<>(option)); - option.clear(); - } - start = true; - optionName = line.substring(KEY_OPTION.length()); - } else if (start) { - option.add(line); - } - } - options_source.put(optionName, option); - return options_source; - } - - @Override - public void send(Player player) { - json.send(player); - } - - @Override - public void console() { - Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[]"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Sound.java b/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Sound.java deleted file mode 100644 index 957ca2e..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Sound.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.skymc.taboolib.string.language2.value; - -import me.skymc.taboolib.sound.SoundPack; -import me.skymc.taboolib.string.language2.Language2Format; -import me.skymc.taboolib.string.language2.Language2Line; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author sky - * @since 2018-03-08 22:43:27 - */ -public class Language2Sound implements Language2Line { - - private List sounds = new ArrayList<>(); - - private Language2Value value; - - public Language2Sound(Language2Format format, List list) { - this.value = format.getLanguage2Value(); - list.forEach(line -> sounds.add(new SoundPack(line))); - } - - public List getSounds() { - return sounds; - } - - public Language2Value getValue() { - return value; - } - - @Override - public void send(Player player) { - sounds.forEach(sound -> sound.play(player)); - } - - @Override - public void console() { - Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[]"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Text.java b/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Text.java deleted file mode 100644 index a5db632..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Text.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.skymc.taboolib.string.language2.value; - -import me.skymc.taboolib.string.language2.Language2Format; -import me.skymc.taboolib.string.language2.Language2Line; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author sky - * @since 2018-03-08 22:43:27 - */ -public class Language2Text implements Language2Line { - - private List text = new ArrayList<>(); - - private Language2Value value; - - public List getText() { - return text; - } - - public Language2Value getValue() { - return value; - } - - public Language2Text(Language2Format format, List list) { - this.value = format.getLanguage2Value(); - text.addAll(list); - } - - @Override - public void send(Player player) { - text.forEach(player::sendMessage); - } - - @Override - public void console() { - text.forEach(line -> Bukkit.getConsoleSender().sendMessage(line)); - } -} diff --git a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Title.java b/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Title.java deleted file mode 100644 index 257bf33..0000000 --- a/src/main/scala/me/skymc/taboolib/string/language2/value/Language2Title.java +++ /dev/null @@ -1,103 +0,0 @@ -package me.skymc.taboolib.string.language2.value; - -import me.skymc.taboolib.TabooLib; -import me.skymc.taboolib.display.TitleUtils; -import me.skymc.taboolib.string.language2.Language2Format; -import me.skymc.taboolib.string.language2.Language2Line; -import me.skymc.taboolib.string.language2.Language2Value; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.entity.Player; - -import java.util.List; - -/** - * @author sky - * @since 2018年2月13日 下午3:58:07 - */ -public class Language2Title implements Language2Line { - - private static final String KEY_TITLE = " title: "; - private static final String KEY_SUBTITLE = " subtitle: "; - private static final String KEY_STAYRULE = " stay: "; - - private String title = ""; - - private String subtitle = ""; - - private int fade1 = 0; - - private int fade2 = 0; - - private int stay = 20; - - private Language2Value value; - - public Language2Title(Language2Format format, List list) { - // 变量初始化 - this.value = format.getLanguage2Value(); - // 遍历文本 - for (String message : list) { - try { - // 大标题 - if (message.startsWith(KEY_TITLE)) { - title = message.substring(KEY_TITLE.length()); - } - // 小标题 - else if (message.startsWith(KEY_SUBTITLE)) { - subtitle = message.substring(KEY_SUBTITLE.length()); - } - // 持续时间 - else if (message.startsWith(KEY_STAYRULE)) { - String rule = message.substring(KEY_STAYRULE.length()); - fade1 = Integer.valueOf(rule.split("\\|")[0]); - stay = Integer.valueOf(rule.split("\\|")[1]); - fade2 = Integer.valueOf(rule.split("\\|")[2]); - } - } catch (Exception e) { - // 识别异常 - title = ChatColor.DARK_RED + "[]"; - subtitle = ChatColor.DARK_RED + "[]"; - } - } - } - - public String getTitle() { - return title; - } - - public String getSubtitle() { - return subtitle; - } - - public int getFade1() { - return fade1; - } - - public int getFade2() { - return fade2; - } - - public int getStay() { - return stay; - } - - public Language2Value getValue() { - return value; - } - - @Override - public void send(Player player) { - // 检查版本 - if (TabooLib.getVerint() < 10800) { - player.sendMessage(ChatColor.DARK_RED + "[]"); - } else { - TitleUtils.sendTitle(player, title, subtitle, fade1, stay, fade2); - } - } - - @Override - public void console() { - Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[]"); - } -} diff --git a/src/main/scala/me/skymc/taboolib/support/SupportWorldGuard.java b/src/main/scala/me/skymc/taboolib/support/SupportWorldGuard.java index 11141b5..f28fc62 100644 --- a/src/main/scala/me/skymc/taboolib/support/SupportWorldGuard.java +++ b/src/main/scala/me/skymc/taboolib/support/SupportWorldGuard.java @@ -8,12 +8,9 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.stream.Collectors; /** @@ -21,6 +18,8 @@ import java.util.stream.Collectors; */ public class SupportWorldGuard { + public static final SupportWorldGuard INSTANCE = new SupportWorldGuard(); + private WorldGuardPlugin worldGuard; public SupportWorldGuard() { diff --git a/src/main/scala/me/skymc/taboolib/update/UpdateTask.java b/src/main/scala/me/skymc/taboolib/update/UpdateTask.java index ad3c22b..be4bba4 100644 --- a/src/main/scala/me/skymc/taboolib/update/UpdateTask.java +++ b/src/main/scala/me/skymc/taboolib/update/UpdateTask.java @@ -6,11 +6,11 @@ import com.google.gson.JsonParser; import com.ilummc.tlib.resources.TLocale; import me.skymc.taboolib.Main; import me.skymc.taboolib.TabooLib; +import me.skymc.taboolib.common.schedule.TSchedule; import me.skymc.taboolib.fileutils.FileUtils; import me.skymc.taboolib.player.PlayerUtils; import me.skymc.taboolib.plugin.PluginUtils; import org.bukkit.Bukkit; -import org.bukkit.scheduler.BukkitRunnable; import java.io.*; @@ -34,46 +34,41 @@ public class UpdateTask { } }; - public UpdateTask() { - new BukkitRunnable() { - - @Override - public void run() { - if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK", true)) { - return; - } - for (int i = 0; i < updateLocation.length; i++) { - String[] location = updateLocation[i]; - String value = FileUtils.getStringFromURL(location[0], null); - if (value == null) { - continue; - } - JsonElement json = new JsonParser().parse(value); - if (json.isJsonArray()) { - JsonObject releaseData = json.getAsJsonArray().get(0).getAsJsonObject(); - updateLocationUsing = i; - newVersion = releaseData.get("tag_name").getAsDouble(); - // 获取文件长度 - for (JsonElement assetData : releaseData.getAsJsonArray("assets")) { - if (assetData instanceof JsonObject && ((JsonObject) assetData).get("name").getAsString().equals("TabooLib-" + newVersion + ".jar")) { - length = ((JsonObject) assetData).get("size").getAsInt(); - } - } - if (TabooLib.getPluginVersion() >= newVersion) { - TLocale.Logger.info("UPDATETASK.VERSION-LATEST"); - } else { - TLocale.Logger.info("UPDATETASK.VERSION-OUTDATED", String.valueOf(TabooLib.getPluginVersion()), String.valueOf(newVersion)); - // 是否启用启动下载 - if (Main.getInst().getConfig().getBoolean("UPDATE-DOWNLOAD", false)) { - Bukkit.getScheduler().runTask(TabooLib.instance(), () -> updatePlugin(true, false)); - } - } - return; - } - } - TLocale.Logger.error("UPDATETASK.VERSION-FAIL"); + @TSchedule(async = true, delay = 100, period = 20 * 60 * 60 * 6) + static void update() { + if (!Main.getInst().getConfig().getBoolean("UPDATE-CHECK", true)) { + return; + } + for (int i = 0; i < updateLocation.length; i++) { + String[] location = updateLocation[i]; + String value = FileUtils.getStringFromURL(location[0], null); + if (value == null) { + continue; } - }.runTaskTimerAsynchronously(Main.getInst(), 100, 20 * 60 * 60 * 6); + JsonElement json = new JsonParser().parse(value); + if (json.isJsonArray()) { + JsonObject releaseData = json.getAsJsonArray().get(0).getAsJsonObject(); + updateLocationUsing = i; + newVersion = releaseData.get("tag_name").getAsDouble(); + // 获取文件长度 + for (JsonElement assetData : releaseData.getAsJsonArray("assets")) { + if (assetData instanceof JsonObject && ((JsonObject) assetData).get("name").getAsString().equals("TabooLib-" + newVersion + ".jar")) { + length = ((JsonObject) assetData).get("size").getAsInt(); + } + } + if (TabooLib.getPluginVersion() >= newVersion) { + TLocale.Logger.info("UPDATETASK.VERSION-LATEST"); + } else { + TLocale.Logger.info("UPDATETASK.VERSION-OUTDATED", String.valueOf(TabooLib.getPluginVersion()), String.valueOf(newVersion)); + // 是否启用启动下载 + if (Main.getInst().getConfig().getBoolean("UPDATE-DOWNLOAD", false)) { + Bukkit.getScheduler().runTask(TabooLib.instance(), () -> updatePlugin(true, false)); + } + } + return; + } + } + TLocale.Logger.error("UPDATETASK.VERSION-FAIL"); } public static boolean isHaveUpdate() {