pages = Lists.newArrayList();
+
+ public ItemStack getItem() {
+ ItemStack book = new ItemStack(Material.WRITTEN_BOOK);
+ BookMeta meta = (BookMeta) book.getItemMeta();
+ meta.setTitle(title);
+ meta.setAuthor(author);
+ BookUtils.setPagesAsPage(meta, pages);
+ book.setItemMeta(meta);
+ return book;
+ }
+}
diff --git a/book/src/main/java/cc/zoyn/core/book/BookUtils.java b/book/src/main/java/cc/zoyn/core/book/BookUtils.java
new file mode 100644
index 0000000..d6b173b
--- /dev/null
+++ b/book/src/main/java/cc/zoyn/core/book/BookUtils.java
@@ -0,0 +1,138 @@
+package cc.zoyn.core.book;
+
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.BookMeta;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static cc.zoyn.core.util.NMSUtils.*;
+import static cc.zoyn.core.util.reflect.ReflectionUtils.getFieldByFieldName;
+import static cc.zoyn.core.util.reflect.ReflectionUtils.getMethod;
+
+/**
+ * 书本 - 工具类
+ *
+ * 简易的打开一个带有特定json的书
+ *
+ * Easy to open a book with the specified json
+ *
+ * @author Zoyn
+ * @since 2017/?/?
+ */
+public final class BookUtils {
+
+ private static boolean initialised = false;
+ private static Method getHandle;
+ private static Method openBook;
+
+ static {
+ try {
+ getHandle = getMethod(getOBCClass("CraftPlayer"), "getHandle");
+ openBook = getMethod(getNMSClass("EntityPlayer"), "a", getNMSClass("ItemStack"), getNMSClass("EnumHand"));
+
+ initialised = true;
+ } catch (ReflectiveOperationException e) {
+ e.printStackTrace();
+ Bukkit.getServer().getLogger().warning("Cannot force open book!");
+ initialised = false;
+ }
+ }
+
+ // Prevent accidental construction
+ private BookUtils() {
+ }
+
+ public static boolean isInitialised() {
+ return initialised;
+ }
+
+ /**
+ * 打开一个虚拟的书
+ *
+ * open a virtual book
+ *
+ * @param item 给定的书
+ * @param player 给定的玩家
+ * @return return true if open book successfully
+ */
+ public static boolean openBook(Player player, ItemStack item) {
+ if (!initialised) {
+ return false;
+ }
+ ItemStack held = player.getInventory().getItemInMainHand();
+ try {
+ player.getInventory().setItemInMainHand(item);
+ sendPacket(item, player);
+ } catch (ReflectiveOperationException e) {
+ e.printStackTrace();
+ initialised = false;
+ }
+ player.getInventory().setItemInMainHand(held);
+ return initialised;
+ }
+
+ /**
+ * 打开一个虚拟的书
+ *
+ * open a virtual book
+ *
+ * @param player the player
+ * @param book a {@link Book} object
+ * @return return true if open book successfully
+ */
+ public static boolean openBook(Player player, Book book) {
+ return openBook(player, book.getItem());
+ }
+
+ /**
+ * 以JSON格式来设置书的页面
+ *
+ * use json to set the book pages
+ *
+ * @param metadata book's meta
+ * @param pages JSON lists
+ */
+ @SuppressWarnings("unchecked")
+ public static void setBookPagesAsJson(BookMeta metadata, List pages) {
+ List p;
+ Object page;
+ try {
+ p = (List) getFieldByFieldName(getOBCClass("CraftMetaBook"), "pages").get(metadata);
+ for (String text : pages) {
+ page = stringToIChatBaseComponent(text);
+ p.add(page);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 用{@link Page}来设置书的页面
+ *
+ * use {@link Page} to set the book page
+ *
+ * @param metadata book's meta
+ * @param pages {@link Page} lists
+ */
+ @SuppressWarnings("unchecked")
+ public static void setPagesAsPage(BookMeta metadata, List pages) {
+ setBookPagesAsJson(metadata, pages.stream()
+ .map(Page::toJsonString)
+ .collect(Collectors.toList()));
+ }
+
+ private static void sendPacket(ItemStack itemStack, Player p) throws ReflectiveOperationException {
+ Object entityplayer = getHandle.invoke(p);
+ Class> enumHand = getNMSClass("EnumHand");
+ Object[] enumArray = new Object[0];
+ if (enumHand != null) {
+ enumArray = enumHand.getEnumConstants();
+ }
+ openBook.invoke(entityplayer, getNMSItem(itemStack), enumArray[0]);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cc/zoyn/core/minecraft/JsonImpl.java b/book/src/main/java/cc/zoyn/core/book/JsonImpl.java
similarity index 98%
rename from src/main/java/cc/zoyn/core/minecraft/JsonImpl.java
rename to book/src/main/java/cc/zoyn/core/book/JsonImpl.java
index 698c8f6..54a9c25 100644
--- a/src/main/java/cc/zoyn/core/minecraft/JsonImpl.java
+++ b/book/src/main/java/cc/zoyn/core/book/JsonImpl.java
@@ -1,4 +1,4 @@
-package cc.zoyn.core.minecraft;
+package cc.zoyn.core.book;
import cc.zoyn.core.util.JsonBuilderUtils;
diff --git a/src/main/java/cc/zoyn/core/dto/Page.java b/book/src/main/java/cc/zoyn/core/book/Page.java
similarity index 87%
rename from src/main/java/cc/zoyn/core/dto/Page.java
rename to book/src/main/java/cc/zoyn/core/book/Page.java
index 80871cf..3fc9cd4 100644
--- a/src/main/java/cc/zoyn/core/dto/Page.java
+++ b/book/src/main/java/cc/zoyn/core/book/Page.java
@@ -1,8 +1,7 @@
-package cc.zoyn.core.dto;
+package cc.zoyn.core.book;
-import cc.zoyn.core.minecraft.JsonImpl;
+import com.google.common.collect.Lists;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -13,7 +12,7 @@
*/
public class Page {
- private List jsonParts = new ArrayList();
+ private List jsonParts = Lists.newArrayList();
/**
* 构造方法
@@ -53,7 +52,7 @@ public Page excuteCommandAndAddHover(String command, String... hover) {
* @return {@link Page}
*/
public Page excuteCommand(String command) {
- return onClick("run_command", command);
+ return onClick(command);
}
/**
@@ -80,7 +79,7 @@ public Page addHover(List texts) {
* @return {@link Page}
*/
public Page addHover(String text) {
- return onHover("show_text", text);
+ return onHover(text);
}
/**
@@ -131,13 +130,12 @@ private JsonImpl latest() {
/**
* 添加显示操作
*
- * @param name 悬浮显示
* @param data 显示内容
* @return {@link Page}
*/
- private Page onHover(String name, String data) {
+ private Page onHover(String data) {
JsonImpl latest = latest();
- latest.hoverActionName = name;
+ latest.hoverActionName = "show_text";
latest.hoverActionData = data;
return this;
}
@@ -145,13 +143,12 @@ private Page onHover(String name, String data) {
/**
* 添加点击操作
*
- * @param name 点击名称
* @param data 点击操作
* @return {@link Page}
*/
- private Page onClick(String name, String data) {
+ private Page onClick(String data) {
JsonImpl latest = latest();
- latest.clickActionName = name;
+ latest.clickActionName = "run_command";
latest.clickActionData = data;
return this;
}
diff --git a/common/pom.xml b/common/pom.xml
new file mode 100644
index 0000000..13e5e83
--- /dev/null
+++ b/common/pom.xml
@@ -0,0 +1,15 @@
+
+
+
+ May-Common-Library
+ cc.zoyn.core
+ 1.0.0
+
+ 4.0.0
+
+ common
+
+
+
\ No newline at end of file
diff --git a/common/src/main/java/cc/zoyn/core/Core.java b/common/src/main/java/cc/zoyn/core/Core.java
new file mode 100644
index 0000000..4925721
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/Core.java
@@ -0,0 +1,54 @@
+package cc.zoyn.core;
+
+import cc.zoyn.core.event.PlayerOpenBackpackEvent;
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.events.PacketAdapter;
+import com.comphenix.protocol.events.PacketEvent;
+import com.comphenix.protocol.wrappers.EnumWrappers;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.java.JavaPlugin;
+
+/**
+ * Main Class
+ *
+ * @author Zoyn
+ */
+public class Core extends JavaPlugin {
+
+ private static Core instance;
+
+ @Override
+ public void onEnable() {
+ instance = this;
+
+ // register channel
+ Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
+
+ // register packet listener
+ ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this, PacketType.Play.Client.CLIENT_COMMAND) {
+ @Override
+ public void onPacketReceiving(PacketEvent event) {
+ Player player = event.getPlayer();
+ if (event.getPacket().getClientCommands().read(0) == EnumWrappers.ClientCommand.OPEN_INVENTORY_ACHIEVEMENT) {
+ // call event
+ PlayerOpenBackpackEvent openBackpackEvent = new PlayerOpenBackpackEvent(player);
+ Bukkit.getPluginManager().callEvent(openBackpackEvent);
+ event.setCancelled(openBackpackEvent.isCancelled());
+ }
+ }
+ });
+ }
+
+ /**
+ * get Core instance
+ *
+ * @return {@link Core}
+ */
+ public static Core getInstance() {
+ return instance;
+ }
+
+
+}
diff --git a/src/main/java/cc/zoyn/core/builder/ItemStackBuilder.java b/common/src/main/java/cc/zoyn/core/builder/ItemStackBuilder.java
similarity index 91%
rename from src/main/java/cc/zoyn/core/builder/ItemStackBuilder.java
rename to common/src/main/java/cc/zoyn/core/builder/ItemStackBuilder.java
index d3f89bc..32cf944 100644
--- a/src/main/java/cc/zoyn/core/builder/ItemStackBuilder.java
+++ b/common/src/main/java/cc/zoyn/core/builder/ItemStackBuilder.java
@@ -1,12 +1,12 @@
package cc.zoyn.core.builder;
-import cc.zoyn.core.util.NBTUtils;
import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
public class ItemStackBuilder {
@@ -47,7 +47,7 @@ public ItemStackBuilder setLore(String... lore) {
}
public ItemStackBuilder clearLore() {
- currentMeta.setLore(Arrays.asList());
+ currentMeta.setLore(Collections.emptyList());
return this;
}
@@ -62,7 +62,7 @@ public ItemStackBuilder addHideFlag(ItemFlag... flag) {
}
public ItemStackBuilder setUnbreakable(boolean unBreakable) {
- NBTUtils.setUnbreakable(currentItem, unBreakable);
+ currentItem.getItemMeta().spigot().setUnbreakable(unBreakable);
return this;
}
diff --git a/common/src/main/java/cc/zoyn/core/builder/package-info.java b/common/src/main/java/cc/zoyn/core/builder/package-info.java
new file mode 100644
index 0000000..a4ced26
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/builder/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Add some useful Builder
+ *
+ * @author Zoyn
+ * @since 2017-12-09
+ */
+package cc.zoyn.core.builder;
\ No newline at end of file
diff --git a/common/src/main/java/cc/zoyn/core/event/PlayerOpenBackpackEvent.java b/common/src/main/java/cc/zoyn/core/event/PlayerOpenBackpackEvent.java
new file mode 100644
index 0000000..db47fac
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/event/PlayerOpenBackpackEvent.java
@@ -0,0 +1,43 @@
+package cc.zoyn.core.event;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+
+/**
+ * 当玩家打开自己的背包时触发本事件
+ *
+ * This event fires when the player opens his own backpack
+ *
+ * @author Zoyn
+ * @since 2018-01-07
+ */
+public class PlayerOpenBackpackEvent extends PlayerEvent implements Cancellable {
+
+ private static final HandlerList handlers = new HandlerList();
+ private boolean cancelled = false;
+
+ public PlayerOpenBackpackEvent(Player who) {
+ super(who);
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return cancelled;
+ }
+
+ @Override
+ public void setCancelled(boolean cancel) {
+ cancelled = cancel;
+ }
+
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+}
diff --git a/common/src/main/java/cc/zoyn/core/package-info.java b/common/src/main/java/cc/zoyn/core/package-info.java
new file mode 100644
index 0000000..3ace757
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Plugin Main Class
+ *
+ * @author Zoyn
+ * @since 2017-12-09
+ */
+package cc.zoyn.core;
\ No newline at end of file
diff --git a/src/main/java/cc/zoyn/core/util/ActionBarUtils.java b/common/src/main/java/cc/zoyn/core/util/ActionBarUtils.java
similarity index 53%
rename from src/main/java/cc/zoyn/core/util/ActionBarUtils.java
rename to common/src/main/java/cc/zoyn/core/util/ActionBarUtils.java
index 20aee9b..9c98915 100644
--- a/src/main/java/cc/zoyn/core/util/ActionBarUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/ActionBarUtils.java
@@ -11,36 +11,39 @@
import java.lang.reflect.InvocationTargetException;
/**
- * ActionBar - 工具类
+ * Easy to send an actionbar
*
* @author Zoyn
* @since 2016/?/?
*/
-public class ActionBarUtils {
+public final class ActionBarUtils {
+
+ // Prevent accidental construction
+ private ActionBarUtils() {
+ }
/**
* 给一名玩家发送actionbar
+ *
+ * send a actionbar to player
*
- * @param player 玩家
- * @param msg 信息
+ * @param player playerObj
+ * @param msg message
*/
public static void sendBar(Player player, String msg) {
- msg = ChatColor.translateAlternateColorCodes('&', msg);
- //获取Pl管理
- ProtocolManager pm = ProtocolLibrary.getProtocolManager();
- PacketContainer packet = pm.createPacket(PacketType.Play.Server.CHAT);
- //nms内封包结构为
- /* private IChatBaseComponent a;
- * public BaseComponent[] components; //可以不用填
- * private byte b;
- */
- //依次写入数据
- packet.getChatComponents().write(0, WrappedChatComponent.fromText(msg));
+ String translatedMessage = ChatColor.translateAlternateColorCodes('&', msg);
+
+ //get protocol manager instance
+ ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
+ PacketContainer packet = protocolManager.createPacket(PacketType.Play.Server.CHAT);
+
+ //write data
+ packet.getChatComponents().write(0, WrappedChatComponent.fromText(translatedMessage));
packet.getBytes().write(0, (byte) 2);
- //发送数据包
+ // send packet
try {
- pm.sendServerPacket(player, packet, false);
+ protocolManager.sendServerPacket(player, packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
diff --git a/common/src/main/java/cc/zoyn/core/util/BasicUtils.java b/common/src/main/java/cc/zoyn/core/util/BasicUtils.java
new file mode 100644
index 0000000..b12efbe
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/BasicUtils.java
@@ -0,0 +1,51 @@
+package cc.zoyn.core.util;
+
+import com.google.common.collect.Lists;
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.entity.Player;
+
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 基础 - 工具类
+ *
+ * @author Zoyn
+ * @since 2016/12/26
+ */
+public final class BasicUtils {
+
+ // Prevent accidental construction
+ private BasicUtils() {
+ }
+
+ /**
+ * Get the server all online players
+ *
+ * @return {@link List}
+ */
+ public static List getOnlinePlayers() {
+ List players = Lists.newArrayList();
+ List worlds = Bukkit.getWorlds();
+ worlds.forEach(world -> players.addAll(world.getPlayers()));
+ return players;
+ }
+
+ /**
+ * 将玩家名转换为UUID
+ *
+ * Convert player name to UUID
+ *
+ * @param name the player name
+ * @return {@link UUID}, the name of the corresponding uuid
+ */
+ public UUID translateNameToUUID(String name) {
+ final Player player = Bukkit.getPlayerExact(name);
+ if (player != null) {
+ return player.getUniqueId();
+ } else {
+ return UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes());
+ }
+ }
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/BungeeCordUtils.java b/common/src/main/java/cc/zoyn/core/util/BungeeCordUtils.java
new file mode 100644
index 0000000..3b1e5f0
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/BungeeCordUtils.java
@@ -0,0 +1,96 @@
+package cc.zoyn.core.util;
+
+import cc.zoyn.core.Core;
+import com.google.common.collect.Iterables;
+import com.google.common.io.ByteArrayDataOutput;
+import com.google.common.io.ByteStreams;
+import lombok.Getter;
+import org.apache.commons.lang3.Validate;
+import org.bukkit.entity.Player;
+
+
+/**
+ * BungeeCord - 工具类
+ *
+ * @author Zoyn
+ */
+public final class BungeeCordUtils {
+
+ private static volatile BungeeCordUtils instance;
+
+ // Prevent accidental construction
+ private BungeeCordUtils() {
+ }
+
+ public static BungeeCordUtils getInstance() {
+ if (instance == null) {
+ synchronized (BungeeCordUtils.class) {
+ if (instance == null) {
+ instance = new BungeeCordUtils();
+ }
+ }
+ }
+ return instance;
+ }
+
+ public static void sendData(BungeeCordTagType tagType, String... arguments) {
+ ByteArrayDataOutput out = ByteStreams.newDataOutput();
+
+ out.writeUTF(tagType.getText());
+ for (String argument : arguments) {
+ out.writeUTF(argument);
+ }
+
+ Player player = Iterables.getFirst(BasicUtils.getOnlinePlayers(), null);
+ Validate.notNull(player).sendPluginMessage(Core.getInstance(), "BungeeCord", out.toByteArray());
+ }
+
+ /**
+ * 将玩家传送至某子服
+ *
+ * @param playerName 名字
+ * @param serverName 服务器名
+ */
+ public static void playerConnectServer(String playerName, String serverName) {
+ sendData(BungeeCordTagType.CONNECT_OTHER, playerName, serverName);
+ }
+
+ /**
+ * 踢出一个玩家
+ *
+ * @param playerName 玩家名
+ * @param message 信息
+ */
+ public static void kickPlayer(String playerName, String message) {
+ sendData(BungeeCordTagType.KICK_PLAYER, playerName, message);
+ }
+
+ public static void sendMessageToPlayer(String playerName, String message) {
+ sendData(BungeeCordTagType.MESSAGE, playerName, message);
+ }
+
+
+ @Getter
+ public enum BungeeCordTagType {
+ CONNECT("Connect"),
+ CONNECT_OTHER("ConnectOther"),
+ IP("IP"),
+ PLAYER_COUNT("PlayerCount"),
+ PLAYER_LIST("PlayerList"),
+ GET_SERVERS("GetServers"),
+ MESSAGE("Message"),
+ KICK_PLAYER("KickPlayer");
+
+ private String text;
+
+ BungeeCordTagType(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+ }
+
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/ConfigurationUtils.java b/common/src/main/java/cc/zoyn/core/util/ConfigurationUtils.java
new file mode 100644
index 0000000..624a45c
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/ConfigurationUtils.java
@@ -0,0 +1,89 @@
+package cc.zoyn.core.util;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.yaml.snakeyaml.DumperOptions;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+
+/**
+ * 配置文件工具类
+ *
+ * @author Zoyn
+ * @since 2017-12-17
+ */
+public final class ConfigurationUtils {
+
+ // Prevent accidental construction
+ private ConfigurationUtils() {
+ }
+
+ /**
+ * 用路径读取Yml
+ *
+ * load Yml with the path
+ *
+ * @param path 路径
+ * @return 那个Yml的FileConfiguration对象
+ */
+ public static FileConfiguration loadYml(String path) {
+ return loadYml(new File(path));
+ }
+
+ /**
+ * 保存Yml
+ *
+ * save a Yml
+ *
+ * @param fileConfiguration 该Yml的FileConfiguration对象
+ * @param file 文件
+ */
+ public static void saveYml(FileConfiguration fileConfiguration, File file) {
+ try {
+ fileConfiguration.save(file);
+ } catch (IOException e) {
+ System.out.println("错误:" + e.toString());
+ }
+ }
+
+ /**
+ * 读取Yml
+ *
+ * load Yml with the file
+ *
+ * @param file 文件
+ * @return YML的FileConfiguration对象
+ */
+ public static FileConfiguration loadYml(File file) {
+ if (!file.exists()) {
+ try {
+ file.createNewFile();
+ } catch (IOException e) {
+ System.out.println("错误:" + e.toString());
+ }
+ }
+ FileConfiguration YML = YamlConfiguration.loadConfiguration(file);
+ DumperOptions yamlOptions = null;
+ try {
+ Field f = YamlConfiguration.class.getDeclaredField("yamlOptions");
+ f.setAccessible(true);
+ yamlOptions = new DumperOptions() {
+ public void setAllowUnicode(boolean allowUnicode) {
+ super.setAllowUnicode(false);
+ }
+
+ public void setLineBreak(LineBreak lineBreak) {
+ super.setLineBreak(LineBreak.getPlatformLineBreak());
+ }
+ };
+ yamlOptions.setLineBreak(DumperOptions.LineBreak.getPlatformLineBreak());
+ f.set(YML, yamlOptions);
+ } catch (ReflectiveOperationException ex) {
+ System.out.println("错误:" + ex.toString());
+ }
+ return YML;
+ }
+
+}
diff --git a/src/main/java/cc/zoyn/core/util/EntityUtils.java b/common/src/main/java/cc/zoyn/core/util/EntityUtils.java
similarity index 56%
rename from src/main/java/cc/zoyn/core/util/EntityUtils.java
rename to common/src/main/java/cc/zoyn/core/util/EntityUtils.java
index 81335b6..9668fb0 100644
--- a/src/main/java/cc/zoyn/core/util/EntityUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/EntityUtils.java
@@ -1,30 +1,31 @@
package cc.zoyn.core.util;
+import com.google.common.collect.Lists;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.BlockIterator;
-import java.util.ArrayList;
import java.util.List;
-public class EntityUtils {
+public final class EntityUtils {
+
+ // Prevent accidental construction
+ private EntityUtils() {
+ }
/**
* 取目标玩家
+ *
+ * get player target
*
* @param player 玩家
* @return 该玩家的目标玩家
*/
public static Player getTargetPlayer(Player player) {
- List nearbyE = player.getNearbyEntities(20.0D, 20.0D, 20.0D);
- ArrayList nearPlayers = new ArrayList();
- for (Entity e : nearbyE) {
- if ((e instanceof Player)) {
- nearPlayers.add((Player) e);
- }
- }
+ List nearPlayers = getNearbyPlayersList(player.getLocation(), 20D);
+
Player target = null;
BlockIterator bItr = new BlockIterator(player, 20);
while (bItr.hasNext()) {
@@ -48,37 +49,37 @@ public static Player getTargetPlayer(Player player) {
}
/**
- * 取附近的实体[返回数组]
+ * 取附近的实体
*
* @param loc 坐标
* @param radius 半径
- * @return 实体数组
+ * @return return a {@link Entity} array
*/
public static Entity[] getNearbyEntitiesArrays(Location loc, double radius) {
return getNearbyEntitiesList(loc, radius).toArray(new Entity[]{});
}
/**
- * 取附近的实体[返回List]
+ * 取附近的实体
*
* @param loc 坐标
* @param radius 半径
- * @return 实体集合
+ * @return {@link List}
*/
public static List getNearbyEntitiesList(Location loc, double radius) {
int Radius = (int) radius;
int chunkRadius = Radius < 16 ? 1 : (Radius - Radius % 16) / 16;
- List radiusEntities = new ArrayList();
+ List radiusEntities = Lists.newArrayList();
for (int chX = 0 - chunkRadius; chX <= chunkRadius; ++chX) {
for (int chZ = 0 - chunkRadius; chZ <= chunkRadius; ++chZ) {
int x = (int) loc.getX();
int y = (int) loc.getY();
int z = (int) loc.getZ();
- Entity[] entitys;
- int size = (entitys = (new Location(loc.getWorld(), (double) (x + chX * 16), (double) y,
+ Entity[] entities;
+ int size = (entities = (new Location(loc.getWorld(), (double) (x + chX * 16), (double) y,
(double) (z + chZ * 16))).getChunk().getEntities()).length;
for (int i = 0; i < size; i++) {
- Entity e = entitys[i];
+ Entity e = entities[i];
if (e.getLocation().distance(loc) <= radius && e.getLocation().getBlock() != loc.getBlock()) {
radiusEntities.add(e);
}
@@ -89,36 +90,18 @@ public static List getNearbyEntitiesList(Location loc, double radius) {
}
/**
- * 取附近的玩家 [返回List]
+ * 取附近的玩家
*
* @param loc 坐标
* @param radius 半径
- * @return 玩家集合
+ * @return {@link Player}
*/
public static List getNearbyPlayersList(Location loc, double radius) {
- int Radius = (int) radius;
- int chunkRadius = Radius < 16 ? 1 : (Radius - Radius % 16) / 16;
- List radiusEntities = new ArrayList();
- for (int chX = 0 - chunkRadius; chX <= chunkRadius; ++chX) {
- for (int chZ = 0 - chunkRadius; chZ <= chunkRadius; ++chZ) {
- int x = (int) loc.getX();
- int y = (int) loc.getY();
- int z = (int) loc.getZ();
- Entity[] entitys;
- int size = (entitys = (new Location(loc.getWorld(), (double) (x + chX * 16), (double) y,
- (double) (z + chZ * 16))).getChunk().getEntities()).length;
- for (int i = 0; i < size; i++) {
- Entity e = entitys[i];
- if (e.getLocation().distance(loc) <= radius && e.getLocation().getBlock() != loc.getBlock()) {
- radiusEntities.add(e);
- }
- }
- }
- }
- List players = new ArrayList();
- for (int i = 0; i < radiusEntities.size(); i++) {
- if (radiusEntities.get(i) instanceof Player) {
- players.add((Player) radiusEntities.get(i));
+ List radiusEntities = getNearbyEntitiesList(loc, radius);
+ List players = Lists.newArrayList();
+ for (Entity radiusEntity : radiusEntities) {
+ if (radiusEntity instanceof Player) {
+ players.add((Player) radiusEntity);
}
}
return players;
diff --git a/src/main/java/cc/zoyn/core/util/FileUtils.java b/common/src/main/java/cc/zoyn/core/util/FileUtils.java
similarity index 54%
rename from src/main/java/cc/zoyn/core/util/FileUtils.java
rename to common/src/main/java/cc/zoyn/core/util/FileUtils.java
index b6e4569..11245af 100644
--- a/src/main/java/cc/zoyn/core/util/FileUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/FileUtils.java
@@ -1,11 +1,6 @@
package cc.zoyn.core.util;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-import org.yaml.snakeyaml.DumperOptions;
-
import java.io.*;
-import java.lang.reflect.Field;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -14,7 +9,11 @@
*
* @author Zoyn
*/
-public class FileUtils {
+public final class FileUtils {
+
+ // Prevent accidental construction
+ private FileUtils() {
+ }
/**
* 移动 文件或者文件夹
@@ -40,7 +39,10 @@ public static void deleteFile(String filePath) {
}
if (file.isDirectory()) {
File[] list = file.listFiles();
-
+ // prevent forEach null
+ if (list == null) {
+ return;
+ }
for (File f : list) {
deleteFile(f.getAbsolutePath());
}
@@ -115,9 +117,14 @@ public static File createZips(String zipFileName, File... files) throws Exceptio
e.printStackTrace();
} finally {
try {
- bo.close();
+ if (bo != null) {
+ bo.close();
+ }
} finally {
- out.close(); // 输出流关闭
+ if (out != null) {
+ // 输出流关闭
+ out.close();
+ }
}
}
return outFile;
@@ -141,43 +148,43 @@ public static File createZip(String zipFileName, File inputFile) throws Exceptio
e.printStackTrace();
} finally {
try {
- bo.close();
+ if (bo != null) {
+ bo.close();
+ }
} finally {
- out.close(); // 输出流关闭
+ if (out != null) {
+ out.close(); // 输出流关闭
+ }
}
}
return outFile;
}
- private static void zip(ZipOutputStream out, File f, String base, BufferedOutputStream bo) throws Exception { // 方法重载
- if (f.isDirectory()) {
- File[] fl = f.listFiles();
- if (fl == null || fl.length == 0) {
+ private static void zip(ZipOutputStream out, File file, String base, BufferedOutputStream bo) throws Exception { // 方法重载
+ if (file.isDirectory()) {
+ File[] files = file.listFiles();
+ if (files == null || files.length == 0) {
out.putNextEntry(new ZipEntry(base + "/")); // 创建创建一个空的文件夹
} else {
- for (int i = 0; i < fl.length; i++) {
- zip(out, fl[i], base + "/" + fl[i].getName(), bo); // 递归遍历子文件夹
+ for (File fileTemp : files) {
+ zip(out, fileTemp, base + "/" + fileTemp.getName(), bo); // 递归遍历子文件夹
}
}
} else {
out.putNextEntry(new ZipEntry(base)); // 创建zip压缩进入 base 文件
- System.out.println(base);
- BufferedInputStream bi = new BufferedInputStream(new FileInputStream(f));
- try {
- write2Out(bi, out);
+ try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
+ write2Out(in, out);
} catch (IOException e) {
// Ignore
- } finally {
- bi.close();// 输入流关闭
}
}
}
private static void write2Out(InputStream input, OutputStream out) throws IOException {
byte[] b = new byte[1024];
- int c = 0;
+ int c;
while ((c = input.read(b)) != -1) {
out.write(b, 0, c);
out.flush();
@@ -185,90 +192,4 @@ private static void write2Out(InputStream input, OutputStream out) throws IOExce
out.flush();
}
- /**
- * 用路径读取Yml
- *
- * @param path 路径
- * @return 那个Yml的FileConfiguration对象
- */
- public static FileConfiguration loadYml(String path) {
- File file = new File(path);
- if (!file.exists()) {
- try {
- file.createNewFile();
- } catch (IOException e) {
- System.out.println("错误:" + e.toString());
- }
- }
- FileConfiguration YML = YamlConfiguration.loadConfiguration(file);
- DumperOptions yamlOptions = null;
- try {
- Field f = YamlConfiguration.class.getDeclaredField("yamlOptions");
- f.setAccessible(true);
- yamlOptions = new DumperOptions() {
- public void setAllowUnicode(boolean allowUnicode) {
- super.setAllowUnicode(false);
- }
-
- public void setLineBreak(DumperOptions.LineBreak lineBreak) {
- super.setLineBreak(DumperOptions.LineBreak.getPlatformLineBreak());
- }
- };
- yamlOptions.setLineBreak(DumperOptions.LineBreak.getPlatformLineBreak());
- f.set(YML, yamlOptions);
- } catch (ReflectiveOperationException ex) {
- System.out.println("错误:" + ex.toString());
- }
- return YamlConfiguration.loadConfiguration(new File(path));
- }
-
- /**
- * 保存Yml
- *
- * @param Filec 该Yml的FileConfiguration对象
- * @param file 文件
- */
- public static void saveYml(FileConfiguration Filec, File file) {
- try {
- Filec.save(file);
- } catch (IOException e) {
- System.out.println("错误:" + e.toString());
- }
- }
-
- /**
- * 读取Yml
- *
- * @param file 文件
- * @return YML的FileConfiguration对象
- */
- public static FileConfiguration loadYml(File file) {
- if (!file.exists()) {
- try {
- file.createNewFile();
- } catch (IOException e) {
- System.out.println("错误:" + e.toString());
- }
- }
- FileConfiguration YML = YamlConfiguration.loadConfiguration(file);
- DumperOptions yamlOptions = null;
- try {
- Field f = YamlConfiguration.class.getDeclaredField("yamlOptions");
- f.setAccessible(true);
- yamlOptions = new DumperOptions() {
- public void setAllowUnicode(boolean allowUnicode) {
- super.setAllowUnicode(false);
- }
-
- public void setLineBreak(DumperOptions.LineBreak lineBreak) {
- super.setLineBreak(DumperOptions.LineBreak.getPlatformLineBreak());
- }
- };
- yamlOptions.setLineBreak(DumperOptions.LineBreak.getPlatformLineBreak());
- f.set(YML, yamlOptions);
- } catch (ReflectiveOperationException ex) {
- System.out.println("错误:" + ex.toString());
- }
- return YML;
- }
}
diff --git a/src/main/java/cc/zoyn/core/util/InventoryUtils.java b/common/src/main/java/cc/zoyn/core/util/InventoryUtils.java
similarity index 64%
rename from src/main/java/cc/zoyn/core/util/InventoryUtils.java
rename to common/src/main/java/cc/zoyn/core/util/InventoryUtils.java
index 0411e48..d86c5ec 100644
--- a/src/main/java/cc/zoyn/core/util/InventoryUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/InventoryUtils.java
@@ -1,32 +1,55 @@
package cc.zoyn.core.util;
+import com.google.common.collect.Lists;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
+import java.util.List;
+
/**
* 物品栏工具类
*
* @author Zoyn
* @since 2016/?/?
*/
-public class InventoryUtils {
+public final class InventoryUtils {
+
+ // Prevent accidental construction
+ private InventoryUtils() {
+ }
+
+ /**
+ * 检查一个容器是否为空
+ *
+ * @param inventory 给定的容器
+ * @return 当容器为空时返回true
+ */
+ public static boolean isEmpty(Inventory inventory) {
+ List itemStacks = Lists.newArrayList(inventory.getContents());
+ for (ItemStack itemStack : itemStacks) {
+ if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
+ return false;
+ }
+ }
+ return true;
+ }
/**
* 检查玩家是否拥有某物品
*
- * @param player 玩家
- * @param is 物品(ItemStack类型)
+ * @param player 玩家
+ * @param itemStack 物品
* @return Boolean
*/
- public static boolean hasItem(Player player, ItemStack is) {
+ public static boolean hasItem(Player player, ItemStack itemStack) {
Inventory inventory = player.getInventory();
ItemStack[] invItem = inventory.getContents();
- int i = 0;
- if (i < invItem.length) {
- invItem[i].equals(is);
- return true;
+ for (ItemStack item : invItem) {
+ if (item.equals(itemStack)) {
+ return true;
+ }
}
return false;
}
diff --git a/src/main/java/cc/zoyn/core/enchantments/Glow.java b/common/src/main/java/cc/zoyn/core/util/ItemGlowUtils.java
similarity index 86%
rename from src/main/java/cc/zoyn/core/enchantments/Glow.java
rename to common/src/main/java/cc/zoyn/core/util/ItemGlowUtils.java
index 4c55104..a86d151 100644
--- a/src/main/java/cc/zoyn/core/enchantments/Glow.java
+++ b/common/src/main/java/cc/zoyn/core/util/ItemGlowUtils.java
@@ -1,4 +1,4 @@
-package cc.zoyn.core.enchantments;
+package cc.zoyn.core.util;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentTarget;
@@ -7,16 +7,21 @@
import java.lang.reflect.Field;
/**
- * 用于给予物品发光属性,无实际作用的一个附魔
+ * 用于给予物品发光的特性
*
* @author Zoyn
*/
-public class Glow extends Enchantment {
+public class ItemGlowUtils extends Enchantment {
+
+ static {
+ registerGlow();
+ }
/**
* 注册附魔
*/
public static void registerGlow() {
+
try {
Field f = Enchantment.class.getDeclaredField("acceptingNew");
f.setAccessible(true);
@@ -26,7 +31,8 @@ public static void registerGlow() {
}
}
- public Glow(int id) {
+
+ public ItemGlowUtils(int id) {
super(id);
}
diff --git a/src/main/java/cc/zoyn/core/util/ItemStackUtils.java b/common/src/main/java/cc/zoyn/core/util/ItemStackUtils.java
similarity index 68%
rename from src/main/java/cc/zoyn/core/util/ItemStackUtils.java
rename to common/src/main/java/cc/zoyn/core/util/ItemStackUtils.java
index f331833..eaea5e2 100644
--- a/src/main/java/cc/zoyn/core/util/ItemStackUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/ItemStackUtils.java
@@ -1,5 +1,7 @@
package cc.zoyn.core.util;
+import com.google.common.collect.Lists;
+import org.apache.commons.lang3.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
@@ -8,11 +10,14 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-public class ItemStackUtils {
+public final class ItemStackUtils {
+
+ // Prevent accidental construction
+ private ItemStackUtils() {
+ }
/**
* 附魔序列化
@@ -23,7 +28,7 @@ public class ItemStackUtils {
@SuppressWarnings("deprecation")
public static String getEnch(Set> set) {
StringBuilder enchs = new StringBuilder();
- for (Map.Entry ench : set) {
+ for (Entry ench : set) {
enchs.append(String.format("{id:%s,lvl:%s},", ench.getKey().getId(), ench.getValue()));
}
enchs.deleteCharAt(enchs.length() - 1);
@@ -53,17 +58,17 @@ public static int getLoreIndex(List lores, String lore) {
*
* @param is 物品(ItemStack类型)
* @param Line 行数
- * @param lore 要设置的Lore
+ * @param msg 要设置的Lore
*/
- public static void setLore(ItemStack is, int Line, String lore) {
- List lores = new ArrayList();
+ public static void setLore(ItemStack is, int Line, String msg) {
+ List lore = Lists.newArrayList();
if (is == null || is.getType() == Material.AIR) {
- throw new NullPointerException();
+ return;
}
if (is.getItemMeta().hasLore()) {
- lores.addAll(is.getItemMeta().getLore());
- lores.set((Line - 1), lore.replaceAll("&", "§"));
- is.getItemMeta().setLore(lores);
+ lore.addAll(is.getItemMeta().getLore());
+ lore.set((Line - 1), msg.replaceAll("&", "§"));
+ is.getItemMeta().setLore(lore);
is.setItemMeta(is.getItemMeta());
} else {
return;
@@ -73,28 +78,27 @@ public static void setLore(ItemStack is, int Line, String lore) {
/**
* 添加Lore
*
- * @param is 需要设置的物品
- * @param lore 待添加的String
+ * @param is 需要设置的物品
+ * @param msg 待添加的String
* @return 该物品的ItemStack对象
*/
- public static ItemStack addLore(ItemStack is, String lore) {
- if (is != null) {
- lore = ChatColor.translateAlternateColorCodes('&', lore);
- ItemMeta im = is.getItemMeta();
- if (im.hasLore()) {
- List l = im.getLore();
- l.add(lore);
- im.setLore(l);
- is.setItemMeta(im);
- return is;
- }
- List l = new ArrayList<>();
+ public static ItemStack addLore(ItemStack is, String msg) {
+ Validate.notNull(is);
+
+ String lore = ChatColor.translateAlternateColorCodes('&', msg);
+ ItemMeta im = is.getItemMeta();
+ if (im.hasLore()) {
+ List l = im.getLore();
l.add(lore);
im.setLore(l);
is.setItemMeta(im);
return is;
}
- throw new NullPointerException();
+ List l = new ArrayList<>();
+ l.add(lore);
+ im.setLore(l);
+ is.setItemMeta(im);
+ return is;
}
/**
@@ -106,9 +110,8 @@ public static ItemStack addLore(ItemStack is, String lore) {
* @return 该物品的ItemStack
*/
public static ItemStack replaceLore(ItemStack is, String old, String newString) {
- if (is == null) {
- throw new NullPointerException();
- }
+ Validate.notNull(is);
+
ItemMeta im = is.getItemMeta();
List lore = im.getLore();
if (!lore.contains(old)) {
diff --git a/src/main/java/cc/zoyn/core/util/JsonBuilderUtils.java b/common/src/main/java/cc/zoyn/core/util/JsonBuilderUtils.java
similarity index 93%
rename from src/main/java/cc/zoyn/core/util/JsonBuilderUtils.java
rename to common/src/main/java/cc/zoyn/core/util/JsonBuilderUtils.java
index de8b37f..09f2941 100644
--- a/src/main/java/cc/zoyn/core/util/JsonBuilderUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/JsonBuilderUtils.java
@@ -2,12 +2,11 @@
/**
* Json构建
- *
- * @author Zoyn
*/
-public class JsonBuilderUtils {
+public final class JsonBuilderUtils {
- public static final String[] REPLACEMENT_CHARS;
+ private static final String[] REPLACEMENT_CHARS;
+ private StringBuilder json;
static {
REPLACEMENT_CHARS = new String[128];
@@ -23,8 +22,6 @@ public class JsonBuilderUtils {
REPLACEMENT_CHARS['\f'] = "\\f";
}
- StringBuilder json;
-
public JsonBuilderUtils() {
json = new StringBuilder();
}
diff --git a/src/main/java/cc/zoyn/core/util/MathUtils.java b/common/src/main/java/cc/zoyn/core/util/MathUtils.java
similarity index 55%
rename from src/main/java/cc/zoyn/core/util/MathUtils.java
rename to common/src/main/java/cc/zoyn/core/util/MathUtils.java
index a94ee70..52943f8 100644
--- a/src/main/java/cc/zoyn/core/util/MathUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/MathUtils.java
@@ -1,17 +1,20 @@
package cc.zoyn.core.util;
import org.bukkit.Location;
-import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
-import java.util.ArrayList;
-import java.util.List;
+public final class MathUtils {
-public class MathUtils {
+ // Prevent accidental construction
+ private MathUtils() {
+ }
/**
- * 取两坐标点的距离
+ * Get two locations distance
+ *
+ * 取两坐标点的距离
+ *
* 使用空间两点距离公式计算: √(X2 - X1)^2 + (Y2 - Y1)^2 + (Z2 - Z1)^2
*
* @param location1 坐标1
@@ -23,6 +26,14 @@ public static double getDistance(Location location1, Location location2) {
return Math.sqrt(Math.pow(location1.getX() - location2.getX(), 2) + Math.pow(location1.getY() - location2.getY(), 2) + Math.pow(location1.getZ() - location2.getZ(), 2));
}
+ /**
+ * 使一个向量围绕Y轴旋转
+ * Make a vector rotate around Y axis
+ *
+ * @param v the vector
+ * @param angle the rotate angle
+ * @return {@link Vector}
+ */
public static Vector rotateAroundAxisY(Vector v, double angle) {
double cos = Math.cos(angle);
double sin = Math.sin(angle);
@@ -32,7 +43,7 @@ public static Vector rotateAroundAxisY(Vector v, double angle) {
}
/**
- * 取背后的向量
+ * 取坐标后的向量
*
* @param loc 坐标
* @return {@link Vector}
@@ -43,7 +54,13 @@ public static Vector getBackVector(Location loc) {
return new Vector(newX - loc.getX(), 0.0D, newZ - loc.getZ());
}
- public static String getCardinalDirection(Player player) {
+ /**
+ * get player's direction name
+ *
+ * @param player a player instance
+ * @return the direction name
+ */
+ public static String getDirectionName(Player player) {
double rotation = (player.getLocation().getYaw() - 90.0F) % 360.0F;
if (rotation < 0.0D) {
rotation += 360.0D;
@@ -63,39 +80,11 @@ public static String getCardinalDirection(Player player) {
/**
* 取第一个坐标到第二个坐标的向量
*
- * @param first_location 坐标1
- * @param second_location 坐标2
+ * @param firstLocation 坐标1
+ * @param secondLocation 坐标2
* @return {@link Vector}
*/
- public static Vector getVector(Location first_location, Location second_location) {
- Vector from = new Vector(first_location.getX(), first_location.getY(), first_location.getZ());
- Vector to = new Vector(second_location.getX(), second_location.getY(), second_location.getZ());
- return to.subtract(from);
- }
-
- /**
- * 取两点之间的方块List
- *
- * @param loc1 坐标1
- * @param loc2 坐标2
- * @return 方块集合
- */
- public static List blocksFromTwoPoints(Location loc1, Location loc2) {
- ArrayList blocks = new ArrayList();
- int topBlockX = loc1.getBlockX() < loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX();
- int bottomBlockX = loc1.getBlockX() > loc2.getBlockX() ? loc2.getBlockX() : loc1.getBlockX();
- int topBlockY = loc1.getBlockY() < loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY();
- int bottomBlockY = loc1.getBlockY() > loc2.getBlockY() ? loc2.getBlockY() : loc1.getBlockY();
- int topBlockZ = loc1.getBlockZ() < loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ();
- int bottomBlockZ = loc1.getBlockZ() > loc2.getBlockZ() ? loc2.getBlockZ() : loc1.getBlockZ();
- for (int x = bottomBlockX; x <= topBlockX; x++) {
- for (int z = bottomBlockZ; z <= topBlockZ; z++) {
- for (int y = bottomBlockY; y <= topBlockY; y++) {
- Block block = loc1.getWorld().getBlockAt(x, y, z);
- blocks.add(block);
- }
- }
- }
- return blocks;
+ public static Vector getVector(Location firstLocation, Location secondLocation) {
+ return secondLocation.subtract(firstLocation).toVector();
}
}
diff --git a/common/src/main/java/cc/zoyn/core/util/NMSUtils.java b/common/src/main/java/cc/zoyn/core/util/NMSUtils.java
new file mode 100644
index 0000000..9f937fa
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/NMSUtils.java
@@ -0,0 +1,233 @@
+package cc.zoyn.core.util;
+
+import cc.zoyn.core.util.reflect.ReflectionUtils;
+import org.apache.commons.lang3.Validate;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import static cc.zoyn.core.util.reflect.ReflectionUtils.*;
+
+/**
+ * Easy to use NMS
+ *
+ * @author Zoyn
+ * @since 2017/4/26
+ */
+public final class NMSUtils {
+
+ private static String version;
+ private static Field playerConnectionField;
+ private static Method sendPacketMethod;
+ private static Method asNMSCopyMethod;
+ private static Method asBukkitCopyMethod;
+ private static Method stringAsIChatBaseComponentMethod;
+ private static Method craftBukkitEntityPlayerGetHandleMethod;
+
+ // Prevent accidental construction
+ private NMSUtils() {
+ }
+
+ static {
+ // org.bukkit.craftbukkit.vX_XX_RX;
+ version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
+
+ // initial
+ try {
+ playerConnectionField = getFieldByFieldName(getNMSClass("EntityPlayer"), "playerConnection");
+ sendPacketMethod = getMethod(getNMSClass("PlayerConnection"), "sendPacket", getNMSClass("Packet"));
+ asNMSCopyMethod = getMethod(getOBCClass("inventory.CraftItemStack"), "asNMSCopy", ItemStack.class);
+ asBukkitCopyMethod = getMethod(getOBCClass("inventory.CraftItemStack"), "asBukkitCopy", getNMSClass("ItemStack"));
+ stringAsIChatBaseComponentMethod = getMethod(getNMSClass("IChatBaseComponent$ChatSerializer"), "a", String.class);
+ craftBukkitEntityPlayerGetHandleMethod = getMethod(getOBCClass("entity.CraftPlayer"), "getHandle");
+ } catch (NoSuchMethodException | NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 取服务器版本 如 v1_10_R1
+ *
+ * get the server version, returns a string similar to v1_10_R1
+ *
+ * @return server version
+ */
+ public static String getVersion() {
+ return version;
+ }
+
+ /**
+ * 取 org.bukkit.craftbukkit 包下的类对象
+ *
+ * get org.bukkit.craftbukkit's class object
+ *
+ * @param className a class's name in the package obc
+ * @return {@link Class}
+ */
+ public static Class> getOBCClass(String className) {
+ try {
+ return Class.forName("org.bukkit.craftbukkit." + NMSUtils.getVersion() + "." + className);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 将NMSItem转换为BukkitItem
+ *
+ * Convert NMS Item to Bukkit Item
+ *
+ * @param nmsItem the NMSItem Object
+ * @return {@link Object}
+ */
+ public static Object getBukkitItem(Object nmsItem) {
+ if (asBukkitCopyMethod == null) {
+ try {
+ asNMSCopyMethod = getMethod(getOBCClass("inventory.CraftItemStack"), "asNMSCopy", ItemStack.class);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ return invokeMethod(asBukkitCopyMethod, null, nmsItem);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 取物品的 NMS 对象
+ *
+ * get a item's nms object
+ *
+ * @param itemStack a itemStack object
+ * @return {@link Object}
+ */
+ public static Object getNMSItem(ItemStack itemStack) {
+ Validate.notNull(itemStack);
+
+ if (asNMSCopyMethod == null) {
+ Class craftItemStack = NMSUtils.getOBCClass("inventory.CraftItemStack");
+ System.out.println("CIS: " + craftItemStack);
+
+ try {
+ // CraftItemStack
+ asNMSCopyMethod = getMethod(craftItemStack, "asNMSCopy", ItemStack.class);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ try {
+ return ReflectionUtils.invokeMethod(asNMSCopyMethod, null, itemStack);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return itemStack;
+ }
+
+ /**
+ * 取对应的 NMS 下的类
+ *
+ * get net.minecraft.server's class object
+ *
+ * @param className a class's name in the package nms
+ * @return {@link Class}
+ */
+ public static Class> getNMSClass(String className) {
+ try {
+ return Class.forName("net.minecraft.server." + version + "." + className);
+ } catch (Exception e) {
+ System.out.println("错误: " + e.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * 给一名玩家发送 NMS 数据包
+ *
+ * send a NMS packet to a player
+ *
+ * @param player player object
+ * @param packet packet object
+ * @see #getNMSPlayer(Player)
+ * @see ReflectionUtils#invokeMethod(Method, Object, Object...)
+ */
+ public static void sendPacket(Player player, Object packet) {
+ Object entityPlayer = getNMSPlayer(player);
+
+ if (playerConnectionField == null) {
+ try {
+ playerConnectionField = getFieldByFieldName(getNMSClass("EntityPlayer"), "playerConnection");
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (sendPacketMethod == null) {
+ try {
+ sendPacketMethod = getMethod(getNMSClass("PlayerConnection"), "sendPacket", getNMSClass("Packet"));
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+
+ try {
+ // get playerConnection instance
+ Object playerConnection = playerConnectionField.get(entityPlayer);
+ // invoke method sendPacket()
+ invokeMethod(sendPacketMethod, playerConnection, packet);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 取玩家的 NMS 对象
+ *
+ * get a player's nms object
+ *
+ * @param player player object
+ * @return {@link Object}
+ * @see ReflectionUtils#invokeMethod(Method, Object, Object...)
+ */
+ public static Object getNMSPlayer(Player player) {
+ try {
+ return invokeMethod(craftBukkitEntityPlayerGetHandleMethod, player);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return player;
+ }
+
+ /**
+ * 将一行文本转换为 IChatBaseComponent 对象
+ *
+ * Convert a text to IChatBaseComponent
+ *
+ * @param text String object
+ * @return {@link Object}
+ * @see ReflectionUtils#getMethod(Class, String, Class[])
+ */
+ public static Object stringToIChatBaseComponent(String text) {
+ if (stringAsIChatBaseComponentMethod == null) {
+ try {
+ // IChatBaseComponent$ChatSerializer
+ stringAsIChatBaseComponentMethod = getMethod(getNMSClass("IChatBaseComponent$ChatSerializer"), "a", String.class);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ try {
+ return invokeMethod(stringAsIChatBaseComponentMethod, Validate.notNull(text));
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/cc/zoyn/core/util/NameTagUtils.java b/common/src/main/java/cc/zoyn/core/util/NameTagUtils.java
similarity index 93%
rename from src/main/java/cc/zoyn/core/util/NameTagUtils.java
rename to common/src/main/java/cc/zoyn/core/util/NameTagUtils.java
index 2693085..1abc50a 100644
--- a/src/main/java/cc/zoyn/core/util/NameTagUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/NameTagUtils.java
@@ -6,7 +6,11 @@
import java.lang.reflect.Field;
-public class NameTagUtils {
+public final class NameTagUtils {
+
+ // Prevent accidental construction
+ private NameTagUtils() {
+ }
public static void changeName(String name, Player player) {
try {
diff --git a/src/main/java/cc/zoyn/core/util/StringUtils.java b/common/src/main/java/cc/zoyn/core/util/StringUtils.java
similarity index 63%
rename from src/main/java/cc/zoyn/core/util/StringUtils.java
rename to common/src/main/java/cc/zoyn/core/util/StringUtils.java
index 323e2fb..50cff03 100644
--- a/src/main/java/cc/zoyn/core/util/StringUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/StringUtils.java
@@ -2,31 +2,37 @@
import java.util.regex.Pattern;
-public class StringUtils {
+public final class StringUtils {
- public static boolean IsChinese(String str) {
+ // Prevent accidental construction
+ private StringUtils() {
+ }
+
+ /**
+ * Determine whether a string is Chinese
+ *
+ * @param str string object
+ * @return true mean yes / false mean no
+ */
+ public static boolean isChinese(String str) {
Pattern pattern = Pattern.compile("[一-龥]*");
return pattern.matcher(str).matches();
}
/**
- * 字符串转16进制
- * PU: --> 50553A
- * 在线工具:http://www.bejson.com/convert/ox2str/
+ * Convert String to Hex String
*/
public static String convertStringToHex(String str) {
char[] chars = str.toCharArray();
- StringBuffer hex = new StringBuffer();
- for (int i = 0; i < chars.length; i++) {
- hex.append(Integer.toHexString((int) chars[i]));
+ StringBuilder hex = new StringBuilder();
+ for (char charObj : chars) {
+ hex.append(Integer.toHexString((int) charObj));
}
return hex.toString().toUpperCase();
}
/**
- * 16进制转换成字符串
- * 50553A --> PU:
- * 在线工具:http://www.bejson.com/convert/ox2str/
+ * Convert Hex String to String
*/
public static String convertHexToString(String hex) {
diff --git a/common/src/main/java/cc/zoyn/core/util/TabUtils.java b/common/src/main/java/cc/zoyn/core/util/TabUtils.java
new file mode 100644
index 0000000..a370db6
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/TabUtils.java
@@ -0,0 +1,55 @@
+package cc.zoyn.core.util;
+
+import com.comphenix.protocol.PacketType;
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.ProtocolManager;
+import com.comphenix.protocol.events.PacketContainer;
+import com.comphenix.protocol.wrappers.WrappedChatComponent;
+import org.apache.commons.lang3.Validate;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+
+import javax.annotation.Nullable;
+import java.lang.reflect.InvocationTargetException;
+
+public final class TabUtils {
+
+ // Prevent accidental construction
+ private TabUtils() {
+
+ }
+
+ /**
+ * 更改一个玩家的Tab列表
+ *
+ * change a player's tab
+ *
+ * @param player player
+ * @param head tab's head
+ * @param foot tab's foot
+ */
+ public static void setTab(@Nullable Player player, @Nullable String head, @Nullable String foot) {
+ Validate.notNull(player);
+
+ String translatedHead = "";
+ String translatedFoot = "";
+ if (head != null) {
+ translatedHead = ChatColor.translateAlternateColorCodes('&', head);
+ }
+ if (foot != null) {
+ translatedFoot = ChatColor.translateAlternateColorCodes('&', foot);
+ }
+
+ // get ProtocolManager instance
+ ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
+ PacketContainer packet = protocolManager.createPacket(PacketType.Play.Server.PLAYER_LIST_HEADER_FOOTER);
+ packet.getChatComponents()
+ .write(0, WrappedChatComponent.fromText(translatedHead))
+ .write(1, WrappedChatComponent.fromText(translatedFoot));
+ try {
+ protocolManager.sendServerPacket(player, packet);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/TimeUtils.java b/common/src/main/java/cc/zoyn/core/util/TimeUtils.java
new file mode 100644
index 0000000..e18644b
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/TimeUtils.java
@@ -0,0 +1,100 @@
+package cc.zoyn.core.util;
+
+import org.apache.commons.lang3.Validate;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public final class TimeUtils {
+
+ private static final int YEAR = 365 * 24 * 60 * 60; // one year's int data
+ private static final int MONTH = 30 * 24 * 60 * 60; // one month's int data
+ private static final int DAY = 24 * 60 * 60; // one day's int data
+ private static final int HOUR = 60 * 60; // one hour int data
+ private static final int MINUTE = 60; // one minute int data
+ private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+ private static final String CHINESE_DATE_FORMAT = "yyyy年MM月dd日 HH:mm:ss";
+
+ // Prevent accidental construction
+ private TimeUtils() {
+ }
+
+ /**
+ * 根据时间戳获取描述性时间,如3分钟前,1天前
+ *
+ * @param timestamp 时间戳 单位为毫秒
+ * @return 时间字符串
+ */
+ public static String getDescriptionTimeFromTimestamp(long timestamp) {
+ long currentTime = System.currentTimeMillis();
+ long timeGap = (currentTime - timestamp) / 1000;// 与现在时间相差秒数
+ String timeStr;
+ if (timeGap > YEAR) {
+ timeStr = timeGap / YEAR + "年前";
+ } else if (timeGap > MONTH) {
+ timeStr = timeGap / MONTH + "个月前";
+ } else if (timeGap > DAY) {// 1天以上
+ timeStr = timeGap / DAY + "天前";
+ } else if (timeGap > HOUR) {// 1小时-24小时
+ timeStr = timeGap / HOUR + "小时前";
+ } else if (timeGap > MINUTE) {// 1分钟-59分钟
+ timeStr = timeGap / MINUTE + "分钟前";
+ } else {// 1秒钟-59秒钟
+ timeStr = "刚刚";
+ }
+ return timeStr;
+ }
+
+ /**
+ * 判断今日是否为休假日
+ *
+ * check today is week
+ *
+ * @return true -> yes / false -> no
+ */
+ public static boolean isWeekDay() {
+ Calendar calendar = Calendar.getInstance();
+ return calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY;
+ }
+
+ /**
+ * 日期格式化
+ *
+ * format a date
+ *
+ * @param date dateObj
+ * @param simpleDataFormat simpleDataFormatObj
+ * @return formattedDateString
+ */
+ public static String getFormattedDate(Date date, SimpleDateFormat simpleDataFormat) {
+ return Validate.notNull(simpleDataFormat).format(date);
+ }
+
+ /**
+ * 日期格式化,默认日期格式 yyyy-MM-dd
+ *
+ * format a date, use yyyy-MM-dd
+ *
+ * @param date dateObj
+ * @return formattedDateString
+ */
+ public static String getDefaultFormatDate(Date date) {
+ return getFormattedDate(date, new SimpleDateFormat(DEFAULT_DATE_FORMAT));
+ }
+
+ /**
+ * 日期格式化,默认日期格式 yyyy年MM月dd日
+ *
+ * format a date, use yyyy年MM月dd日
+ *
+ * @param date dateObj
+ * @return formattedDateString
+ */
+ public static String getChineseDateFormat(Date date) {
+ return getFormattedDate(date, new SimpleDateFormat(CHINESE_DATE_FORMAT));
+ }
+
+
+}
+
diff --git a/src/main/java/cc/zoyn/core/util/TitleUtils.java b/common/src/main/java/cc/zoyn/core/util/TitleUtils.java
similarity index 58%
rename from src/main/java/cc/zoyn/core/util/TitleUtils.java
rename to common/src/main/java/cc/zoyn/core/util/TitleUtils.java
index 341b0e4..61722e9 100644
--- a/src/main/java/cc/zoyn/core/util/TitleUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/TitleUtils.java
@@ -7,7 +7,6 @@
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import org.bukkit.ChatColor;
-import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException;
@@ -15,12 +14,17 @@
/**
* Title工具类
*
- * @author Zoyn
+ * @author Zoyn, D_xiaox
* @since 2016/12/26
- *
+ *
* update 2017/8/05
+ * update 2018/8/02 星空(D_xiaox)
*/
-public class TitleUtils {
+public final class TitleUtils {
+
+ // Prevent accidental construction
+ private TitleUtils() {
+ }
/**
* 给一个玩家发送Title信息 1.8+
@@ -32,28 +36,18 @@ public class TitleUtils {
* @param title 主标题
* @param subTitle 副标题
*/
- public static void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title,
- String subTitle) {
- // 获取PL管理
+ public static void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title, String subTitle) {
+ // get protocol manager instance
ProtocolManager pm = ProtocolLibrary.getProtocolManager();
- PacketContainer packet = null;
+ PacketContainer packet;
if (title != null) {
- title = ChatColor.translateAlternateColorCodes('&', title); // 支持&颜色代码
- title = title.replaceAll("%player%", player.getName());
- // 创建标题数据包
+ String translatedTitle = ChatColor.translateAlternateColorCodes('&', title);
+ translatedTitle = translatedTitle.replaceAll("%player%", player.getName());
+ // create packet
packet = pm.createPacket(PacketType.Play.Server.TITLE);
- // nms内封包结构为
- /*
- * private EnumTitleAction a; private IChatBaseComponent b; private int c;
- * private int d; private int e;
- */
- // 按顺序往里写入数据
+ // write datas
packet.getTitleActions().write(0, EnumWrappers.TitleAction.TITLE); // EnumTitleAction
- packet.getChatComponents().write(0, WrappedChatComponent.fromText(title)); // 标题内容
- packet.getIntegers()
- .write(0, fadeIn) // ---> c
- .write(1, stay) // ---> d
- .write(2, fadeOut); // ---> e
+ packet.getChatComponents().write(0, WrappedChatComponent.fromText(translatedTitle)); // 标题内容
try {
pm.sendServerPacket(player, packet, false); // 发送数据包
} catch (InvocationTargetException e) {
@@ -62,19 +56,31 @@ public static void sendTitle(Player player, Integer fadeIn, Integer stay, Intege
}
if (subTitle != null) {
- subTitle = ChatColor.translateAlternateColorCodes('&', subTitle); // 支持&颜色代码
- subTitle = subTitle.replaceAll("%player%", player.getName());
+ String translatedSubTitle = ChatColor.translateAlternateColorCodes('&', subTitle);
+ translatedSubTitle = translatedSubTitle.replaceAll("%player%", player.getName());
+
packet = pm.createPacket(PacketType.Play.Server.TITLE);
packet.getTitleActions().write(0, EnumWrappers.TitleAction.SUBTITLE);
- packet.getChatComponents().write(0, WrappedChatComponent.fromText(subTitle));
- packet.getIntegers().write(0, fadeIn);
- packet.getIntegers().write(1, stay);
- packet.getIntegers().write(2, fadeOut);
+ packet.getChatComponents().write(0, WrappedChatComponent.fromText(translatedSubTitle));
try {
pm.sendServerPacket(player, packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
+
+ // 以前无法设置时间, 现在可以了
+ packet = pm.createPacket(PacketType.Play.Server.TITLE);
+ packet.getTitleActions().write(0, EnumWrappers.TitleAction.TIMES);
+ packet.getIntegers()
+ .write(0, fadeIn) // ---> c
+ .write(1, stay) // ---> d
+ .write(2, fadeOut); // ---> e
+ try {
+ pm.sendServerPacket(player, packet, false);
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+
}
}
diff --git a/common/src/main/java/cc/zoyn/core/util/nbt/NBTUtils.java b/common/src/main/java/cc/zoyn/core/util/nbt/NBTUtils.java
new file mode 100644
index 0000000..a0920ea
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/nbt/NBTUtils.java
@@ -0,0 +1,380 @@
+package cc.zoyn.core.util.nbt;
+
+import cc.zoyn.core.util.NMSUtils;
+import cc.zoyn.core.util.reflect.ReflectionUtils;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.List;
+
+public class NBTUtils {
+
+ private static Class> NMS_ITEM_STACK;
+ private static Class> NBT_TAG_LIST;
+ public static Class> NBT_TAG_COMPOUND;
+
+ /* The method of NMSItem */
+ private static Method HAS_TAG;
+ private static Method GET_TAG;
+ private static Method SET_TAG;
+
+ /* The method of NBTTagCompound */
+ private static Method SET_DATA;
+ private static Method SET_INT;
+ private static Method SET_STRING;
+ private static Method SET_SHORT;
+ private static Method SET_BYTE;
+ private static Method SET_LONG;
+ private static Method SET_FLOAT;
+ private static Method SET_DOUBLE;
+ private static Method SET_INT_ARRAY;
+ private static Method SET_BYTE_ARRAY;
+ private static Method SET_BOOLEAN;
+
+ /* The method of NBTTagList */
+ private static Method ADD;
+ private static Method GET;
+ private static Method REMOVE;
+
+ // It's public ItemStack(NBTTagCompound nbtTagCompound)
+ private static Constructor> NMS_ITEM_STACK_CONSTRUCTOR_WITH_NBT;
+
+ static {
+ try {
+ NMS_ITEM_STACK = NMSUtils.getNMSClass("ItemStack");
+ NBT_TAG_COMPOUND = NMSUtils.getNMSClass("NBTTagCompound");
+ NBT_TAG_LIST = NMSUtils.getNMSClass("NBTTagList");
+
+ NMS_ITEM_STACK_CONSTRUCTOR_WITH_NBT = NMS_ITEM_STACK.getConstructor(NBT_TAG_COMPOUND);
+
+ HAS_TAG = ReflectionUtils.getMethod(NMS_ITEM_STACK, "hasTag");
+ GET_TAG = ReflectionUtils.getMethod(NMS_ITEM_STACK, "getTag");
+ SET_TAG = ReflectionUtils.getMethod(NMS_ITEM_STACK, "setTag", NBT_TAG_COMPOUND);
+
+ SET_INT = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setInt", String.class, Integer.TYPE);
+ SET_STRING = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setString", String.class, String.class);
+ SET_SHORT = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setShort", String.class, Short.TYPE);
+ SET_BYTE = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setByte", String.class, Byte.TYPE);
+ SET_LONG = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setInt", String.class, Long.TYPE);
+ SET_FLOAT = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setFloat", String.class, Float.TYPE);
+ SET_DOUBLE = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setDouble", String.class, Double.TYPE);
+ SET_INT_ARRAY = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setIntArray", String.class, int[].class);
+ SET_BYTE_ARRAY = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setByteArray", String.class, byte[].class);
+ SET_BOOLEAN = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "setBoolean", String.class, Boolean.TYPE);
+ SET_DATA = ReflectionUtils.getMethod(NBT_TAG_COMPOUND, "set", String.class, NMSUtils.getNMSClass("NBTBase"));
+
+ ADD = ReflectionUtils.getMethod(NBT_TAG_LIST, "add", NMSUtils.getNMSClass("NBTBase"));
+ GET = ReflectionUtils.getMethod(NBT_TAG_LIST, "get", Integer.TYPE);
+ REMOVE = ReflectionUtils.getMethod(NBT_TAG_LIST, "remove", Integer.TYPE);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Prevent accidental construction
+ private NBTUtils() {
+ }
+
+ /**
+ * Get the item nbt
+ *
+ * @param itemStack the ItemStack
+ * @return {@link TagCompound}
+ */
+ public static TagCompound getItemStackNBT(ItemStack itemStack) {
+ return new TagCompound(getOriginalItemStackNBT(itemStack));
+ }
+
+ /**
+ * Get the original item nbt
+ *
+ * @param itemStack the ItemStack
+ * @return {@link Object}
+ */
+ public static Object getOriginalItemStackNBT(ItemStack itemStack) {
+ if (itemStack == null || itemStack.getType().equals(Material.AIR)) {
+ return null;
+ }
+ Object nmsItem = NMSUtils.getNMSItem(itemStack);
+ Object nbtTag = null;
+ try {
+ // check the item has nbttag
+ if (ReflectionUtils.invokeMethod(HAS_TAG, nmsItem).equals(true)) {
+ nbtTag = ReflectionUtils.invokeMethod(GET_TAG, nmsItem);
+ } else {
+ nbtTag = newNBTTagCompound();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return nbtTag;
+ }
+
+ /**
+ * Return an NMSItem with the given nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @return {@link Object}
+ */
+ public static Object newNMSItemStack(Object nbtTagCompound) {
+ try {
+ return ReflectionUtils.instantiateObject(NMS_ITEM_STACK_CONSTRUCTOR_WITH_NBT, nbtTagCompound);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Return a empty NBTTagCompound
+ *
+ * @return {@link Object}
+ */
+ public static Object newNBTTagCompound() {
+ try {
+ return ReflectionUtils.instantiateObject(NBT_TAG_COMPOUND.getDeclaredConstructor());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Return a empty NBTTagList
+ *
+ * @return {@link Object}
+ */
+ public static Object newNBTTagList() {
+ try {
+ return ReflectionUtils.instantiateObject(NBT_TAG_LIST.getDeclaredConstructor());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Set the item nbt, and return the BukkitItem
+ *
+ * @param nbtTagCompound the nbt
+ * @param itemStack the item
+ * @return {@link ItemStack}
+ */
+ public static ItemStack setItemStackNBT(Object nbtTagCompound, ItemStack itemStack) {
+ Object nmsItem = NMSUtils.getNMSItem(itemStack);
+ Object bukkitItem = null;
+ try {
+ ReflectionUtils.invokeMethod(SET_TAG, nmsItem, nbtTagCompound);
+ bukkitItem = NMSUtils.getBukkitItem(nmsItem);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return (ItemStack) bukkitItem;
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setTagCompound(Object nbtTagCompound, String key, Object value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_DATA, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setListTagCompound(Object nbtTagCompound, String key, List value) throws Exception {
+ Object nbtTagList = newNBTTagList();
+ value.forEach(tagCompound -> {
+ try {
+ ReflectionUtils.invokeMethod(ADD, nbtTagList, tagCompound.build());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ });
+ setTagCompound(nbtTagCompound, key, nbtTagList);
+ }
+
+ /**
+ * 利用index来移除一个NBTTagList里的NBTBase数据
+ *
+ * Use index to remove NBTBase data from an NBTTagList
+ *
+ * @param nbtTagList the nbt tag list
+ * @param index the index
+ * @throws Exception When the Remove method is null or the nbtTagList object is not an object of NBTTagList, it will throw an excpetion
+ */
+ public static void removeTagCompound(Object nbtTagList, int index) throws Exception {
+ ReflectionUtils.invokeMethod(REMOVE, nbtTagList, index);
+ }
+
+ /**
+ * 利用index来获取一个NBTTagList里的NBTBase数据
+ *
+ * Use index to get NBTBase data from an NBTTagList
+ *
+ * @param nbtTagList the nbt tag list
+ * @param index the index
+ * @throws Exception When the Get method is null or the nbtTagList object is not an object of NBTTagList, it will throw an excpetion
+ */
+ public static TagCompound getTagCompound(Object nbtTagList, int index) throws Exception {
+ return new TagCompound(ReflectionUtils.invokeMethod(GET, nbtTagList, index));
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setInt(Object nbtTagCompound, String key, int value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_INT, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setString(Object nbtTagCompound, String key, String value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_STRING, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setShort(Object nbtTagCompound, String key, short value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_SHORT, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setByte(Object nbtTagCompound, String key, byte value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_BYTE, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setLong(Object nbtTagCompound, String key, long value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_LONG, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setFloat(Object nbtTagCompound, String key, float value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_FLOAT, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setDouble(Object nbtTagCompound, String key, double value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_DOUBLE, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setIntArray(Object nbtTagCompound, String key, int[] value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_INT_ARRAY, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setByteArray(Object nbtTagCompound, String key, byte[] value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_BYTE_ARRAY, nbtTagCompound, key, value);
+ }
+
+ /**
+ * 利用给定的数据来设置nbt
+ *
+ * Use the given data to set nbt
+ *
+ * @param nbtTagCompound the nbt
+ * @param key the key of json object
+ * @param value the value of json object
+ * @throws Exception When the Set method is null, it will throw an excpetion
+ */
+ public static void setBoolean(Object nbtTagCompound, String key, boolean value) throws Exception {
+ ReflectionUtils.invokeMethod(SET_BOOLEAN, nbtTagCompound, key, value);
+ }
+
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/nbt/TagCompound.java b/common/src/main/java/cc/zoyn/core/util/nbt/TagCompound.java
new file mode 100644
index 0000000..6c2d6dd
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/nbt/TagCompound.java
@@ -0,0 +1,125 @@
+package cc.zoyn.core.util.nbt;
+
+import com.google.common.collect.Maps;
+
+import java.util.List;
+import java.util.Map;
+
+public class TagCompound {
+ private Object nbtTagCompound;
+
+ private Map data = Maps.newHashMap();
+
+ public TagCompound() {
+ this.nbtTagCompound = NBTUtils.newNBTTagCompound();
+ }
+
+ public TagCompound(Object nbtTagCompound) {
+ this.nbtTagCompound = nbtTagCompound;
+ }
+
+ public Object getNBTTagCompound() {
+ return nbtTagCompound;
+ }
+
+ public Map getData() {
+ return data;
+ }
+
+ public TagCompound put(String key, Object value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putListCompound(String key, List value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putCompound(String key, TagCompound value) {
+ data.put(key, value.build());
+ return this;
+ }
+
+ public TagCompound putInt(String key, int value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putString(String key, String value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putShort(String key, short value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putLong(String key, long value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putDouble(String key, double value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putByte(String key, byte value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putBoolean(String key, boolean value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putIntArray(String key, int[] value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public TagCompound putByteArray(String key, byte[] value) {
+ data.put(key, value);
+ return this;
+ }
+
+ public Object build() {
+ data.forEach((key, value) -> {
+ try {
+ if (value.getClass().equals(NBTUtils.NBT_TAG_COMPOUND)) {
+ NBTUtils.setTagCompound(nbtTagCompound, key, value);
+ } else if (value instanceof List) {
+ NBTUtils.setListTagCompound(nbtTagCompound, key, (List) value);
+ } else if (value instanceof Integer) {
+ NBTUtils.setInt(nbtTagCompound, key, (int) value);
+ } else if (value instanceof String) {
+ NBTUtils.setString(nbtTagCompound, key, (String) value);
+ } else if (value instanceof Short) {
+ NBTUtils.setShort(nbtTagCompound, key, (short) value);
+ } else if (value instanceof Long) {
+ NBTUtils.setLong(nbtTagCompound, key, (long) value);
+ } else if (value instanceof Double) {
+ NBTUtils.setDouble(nbtTagCompound, key, (double) value);
+ } else if (value instanceof Float) {
+ NBTUtils.setFloat(nbtTagCompound, key, (float) value);
+ } else if (value instanceof Byte) {
+ NBTUtils.setByte(nbtTagCompound, key, (byte) value);
+ } else if (value instanceof Boolean) {
+ NBTUtils.setBoolean(nbtTagCompound, key, (boolean) value);
+ } else if (value instanceof int[]) {
+ NBTUtils.setIntArray(nbtTagCompound, key, (int[]) value);
+ } else if (value instanceof byte[]) {
+ NBTUtils.setByteArray(nbtTagCompound, key, (byte[]) value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ });
+ return nbtTagCompound;
+ }
+
+
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/package-info.java b/common/src/main/java/cc/zoyn/core/util/package-info.java
new file mode 100644
index 0000000..51cded3
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Some useful util
+ *
+ * @author Zoyn
+ * @since 2017-12-09
+ */
+package cc.zoyn.core.util;
\ No newline at end of file
diff --git a/common/src/main/java/cc/zoyn/core/util/page/ListPager.java b/common/src/main/java/cc/zoyn/core/util/page/ListPager.java
new file mode 100644
index 0000000..50d47a7
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/page/ListPager.java
@@ -0,0 +1,79 @@
+package cc.zoyn.core.util.page;
+
+import java.util.List;
+
+/**
+ * 列表分页工具类
+ *
+ * @author Zoyn
+ * @since 2018/8/27
+ */
+public class ListPager {
+
+ /**
+ * 放入的列表
+ */
+ private List list;
+ /**
+ * 每页显示的个数
+ */
+ private int pageSize;
+ /**
+ * 所有的元素们
+ */
+ private int totalCount;
+
+ /**
+ * 列表分页器
+ *
+ * @param list 列表
+ * @param pageSize 每页显示的个数
+ */
+ public ListPager(List list, int pageSize) {
+ this.list = list;
+ this.pageSize = pageSize;
+ this.totalCount = list.size();
+ }
+
+ /**
+ * 获取分页内容
+ *
+ * @param page 页数
+ * @return {@link List}
+ */
+ public List getPage(int page) {
+ if (page <= 0) {
+ return getPage(1);
+ }
+
+ List subList;
+ if (pageSize >= totalCount) {
+ subList = list;
+ } else {
+ int fromIndex = Math.min(pageSize * (page - 1), totalCount);
+ int endIndex = Math.min(pageSize * page, totalCount);
+
+ subList = list.subList(fromIndex, endIndex);
+ }
+ return subList;
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public int getPageSize() {
+ return pageSize;
+ }
+
+ public ListPager setList(List list) {
+ this.list = list;
+ this.totalCount = list.size();
+ return this;
+ }
+
+ public ListPager setPageSize(int pageSize) {
+ this.pageSize = pageSize;
+ return this;
+ }
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/page/Pagers.java b/common/src/main/java/cc/zoyn/core/util/page/Pagers.java
new file mode 100644
index 0000000..dd7d3e5
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/page/Pagers.java
@@ -0,0 +1,22 @@
+package cc.zoyn.core.util.page;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * 分页工具
+ *
+ * @author Zoyn
+ */
+public class Pagers {
+
+ public static ListPager newListPager(int pageSize, List list) {
+ return new ListPager<>(list, pageSize);
+ }
+
+ public static ListPager newListPager(int pageSize, T... objects) {
+ return newListPager(pageSize, Lists.newArrayList(objects));
+ }
+
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/page/package-info.java b/common/src/main/java/cc/zoyn/core/util/page/package-info.java
new file mode 100644
index 0000000..b6aeef0
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/page/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * The utils for partition
+ *
+ * @author Zoyn
+ * @since 2017-12-09
+ */
+package cc.zoyn.core.util.page;
\ No newline at end of file
diff --git a/common/src/main/java/cc/zoyn/core/util/reflect/ConstructorFilter.java b/common/src/main/java/cc/zoyn/core/util/reflect/ConstructorFilter.java
new file mode 100644
index 0000000..670a5a7
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/reflect/ConstructorFilter.java
@@ -0,0 +1,13 @@
+package cc.zoyn.core.util.reflect;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * @author Zoyn
+ * @since 2017-12-02
+ */
+public interface ConstructorFilter {
+
+ boolean accept(Constructor constructor);
+
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/reflect/FieldFilter.java b/common/src/main/java/cc/zoyn/core/util/reflect/FieldFilter.java
new file mode 100644
index 0000000..f1222e1
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/reflect/FieldFilter.java
@@ -0,0 +1,13 @@
+package cc.zoyn.core.util.reflect;
+
+import java.lang.reflect.Field;
+
+/**
+ * @author Zoyn
+ * @since 2017-12-02
+ */
+public interface FieldFilter {
+
+ boolean accept(Field field);
+
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/reflect/MethodFilter.java b/common/src/main/java/cc/zoyn/core/util/reflect/MethodFilter.java
new file mode 100644
index 0000000..a561e49
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/reflect/MethodFilter.java
@@ -0,0 +1,13 @@
+package cc.zoyn.core.util.reflect;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author Zoyn
+ * @since 2017-12-02
+ */
+public interface MethodFilter {
+
+ boolean accept(Method method);
+
+}
diff --git a/common/src/main/java/cc/zoyn/core/util/reflect/ReflectionUtils.java b/common/src/main/java/cc/zoyn/core/util/reflect/ReflectionUtils.java
new file mode 100644
index 0000000..8a57325
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/reflect/ReflectionUtils.java
@@ -0,0 +1,374 @@
+package cc.zoyn.core.util.reflect;
+
+import org.apache.commons.lang3.Validate;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Easy to reflect
+ *
+ * @author Zoyn
+ * @since 2017-12-02
+ */
+public final class ReflectionUtils {
+
+ // Prevent accidental construction
+ private ReflectionUtils() {
+ }
+
+ /**
+ * get field objects by using field names
+ *
+ * @param clazz class's object
+ * @param fieldName field's name
+ * @return {@link Field}
+ * @throws NoSuchFieldException If the field with the specified name cannot be found
+ * @see #hasField(Class, String)
+ */
+ public static Field getFieldByFieldName(Class> clazz, String fieldName) throws NoSuchFieldException {
+ Field field = null;
+ if (hasField(clazz, fieldName)) {
+ field = clazz.getField(fieldName);
+ }
+ return field;
+ }
+
+ /**
+ * @param classPath class's path
+ * @param fieldName field's name
+ * @return {@link Field}
+ * @throws ClassNotFoundException If the class cannot be found
+ * @throws NoSuchFieldException If the field with the specified name cannot be found
+ * @see #getFieldByFieldName(Class, String)
+ */
+ public static Field getFieldByFieldName(String classPath, String fieldName) throws ClassNotFoundException, NoSuchFieldException {
+ return getFieldByFieldName(Class.forName(classPath), fieldName);
+ }
+
+
+ /**
+ * get a Value field
+ *
+ * @param obj object
+ * @param fieldName field's name
+ * @return {@link Object}
+ * @throws IllegalAccessException If the field is accessible
+ * @see #getFieldByFieldName(Class, String)
+ */
+ public static Object getValueByFieldName(Object obj, String fieldName) throws IllegalAccessException, NoSuchFieldException {
+ Field field = getFieldByFieldName(obj.getClass(), fieldName);
+ Object value = null;
+
+ if (field != null) {
+ if (field.isAccessible()) {
+ value = field.get(obj);
+ } else {
+ field.setAccessible(true);
+ value = field.get(obj);
+ field.setAccessible(false);
+ }
+ }
+ return value;
+ }
+
+ /**
+ * set a object's Value field
+ *
+ * @param obj object
+ * @param fieldName field's name
+ * @param value the value to be set
+ * @throws NoSuchFieldException If the field is missing
+ */
+ public static void setValueByFieldName(Object obj, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {
+ Field field = obj.getClass().getDeclaredField(fieldName);
+ if (field.isAccessible()) {
+ field.set(obj, value);
+ } else {
+ field.setAccessible(true);
+ field.set(obj, value);
+ field.setAccessible(false);
+ }
+ }
+
+ /**
+ * get a class's constructor
+ *
+ * @param clazz class's object
+ * @param parameterTypes parameters
+ * @return {@link Constructor}
+ * @throws NoSuchMethodException If the constructor with the specified parameter types cannot be found
+ * @see #hasConstructor(Class, Class[])
+ */
+ public static Constructor> getConstructor(Class> clazz, Class>... parameterTypes) throws NoSuchMethodException {
+ Constructor constructor = null;
+ if (hasConstructor(clazz, parameterTypes)) {
+ constructor = clazz.getDeclaredConstructor(parameterTypes);
+ }
+ return constructor;
+ }
+
+ /**
+ * get a class's constructor
+ *
+ * @param classPath class's path
+ * @param parameterTypes parameters
+ * @return {@link Constructor}
+ * @throws ClassNotFoundException If the class cannot be found
+ * @throws NoSuchMethodException If the constructor with the specified parameter types cannot be found
+ * @see #getConstructor(Class, Class[])
+ */
+ public static Constructor> getConstructor(String classPath, Class>... parameterTypes) throws ClassNotFoundException, NoSuchMethodException {
+ return getConstructor(Class.forName(classPath), parameterTypes);
+ }
+
+
+ /**
+ * Constructing an object with a constructor
+ *
+ * @param constructor the Constructor
+ * @param arguments the constructor's arguments
+ * @return {@link Object}
+ * @throws IllegalAccessException If the desired constructor cannot be accessed due to certain circumstances
+ * @throws InvocationTargetException If the desired constructor cannot be invoked
+ * @throws InstantiationException If you cannot create an instance of the target class due to certain circumstances
+ */
+ public static Object instantiateObject(Constructor> constructor, Object... arguments) throws IllegalAccessException, InvocationTargetException, InstantiationException {
+ return Validate.notNull(constructor).newInstance(arguments);
+ }
+
+ /**
+ * get a method in a class
+ *
+ * @param clazz class's object
+ * @param methodName method's name
+ * @param parameterTypes the method's arguments
+ * @return {@link Method}
+ * @throws NoSuchMethodException If the method with the specified parameter types cannot be found
+ */
+ public static Method getMethod(Class> clazz, String methodName, Class>... parameterTypes) throws NoSuchMethodException {
+ if (hasMethod(clazz, methodName, parameterTypes)) {
+ return clazz.getDeclaredMethod(methodName, parameterTypes);
+ }
+ return null;
+ }
+
+ /**
+ * get a method in a class
+ *
+ * @param classPath class's path
+ * @param methodName method's name
+ * @param parameterTypes the method's arguments
+ * @return {@link Method}
+ * @throws ClassNotFoundException If the class cannot be found
+ * @throws NoSuchMethodException If the method with the specified parameter types cannot be found
+ * @see #getMethod(Class, String, Class[])
+ */
+ public static Method getMethod(String classPath, String methodName, Class>... parameterTypes) throws ClassNotFoundException, NoSuchMethodException {
+ return getMethod(Class.forName(classPath), methodName, parameterTypes);
+ }
+
+ /**
+ * Invoke a method
+ *
+ * @param method the method object
+ * @param object the object will be invoke
+ * @param arguments the method arguments
+ * @return {@link Object}
+ * @throws InvocationTargetException If the desired method cannot be invoked
+ * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances
+ */
+ public static Object invokeMethod(Method method, Object object, Object... arguments) throws InvocationTargetException, IllegalAccessException {
+ Validate.notNull(method);
+ Object o;
+
+ if (method.isAccessible()) {
+ o = method.invoke(object, arguments);
+ } else {
+ method.setAccessible(true);
+ o = method.invoke(object, arguments);
+ method.setAccessible(false);
+ }
+ return o;
+ }
+
+ /**
+ * Invoke a method
+ *
+ * @param methodName the method name
+ * @param object the object will be invoke
+ * @param arguments the method arguments
+ * @return {@link Object}
+ * @throws InvocationTargetException If the desired method cannot be invoked
+ * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances
+ */
+ public static Object invokeMethod(String methodName, Object object, Object... arguments) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ Method method;
+ Class[] classes = new Class[0];
+ for (int i = 0; i < arguments.length; i++) {
+ classes[i] = arguments[i].getClass();
+ }
+
+ method = getMethod(object.getClass(), methodName, classes);
+ return invokeMethod(method, object, arguments);
+ }
+
+ /**
+ * check a class has a specified field
+ *
+ * @param clazz class's object
+ * @param fieldName field's name
+ * @return return true if the field is exist
+ */
+ public static boolean hasField(Class> clazz, String fieldName) {
+ boolean has;
+
+ try {
+ Validate.notNull(clazz).getDeclaredField(fieldName);
+ has = true;
+ } catch (NoSuchFieldException e) {
+ has = false;
+ }
+ return has;
+ }
+
+ /**
+ * check a class has a specified field
+ *
+ * @param clazz class's object
+ * @param filter filter obj
+ * @return return true if the field is exist
+ */
+ public static boolean hasField(Class> clazz, FieldFilter filter) {
+ Validate.notNull(filter);
+
+ boolean has = false;
+ Field[] fields = clazz.getDeclaredFields();
+ for (Field field : fields) {
+ if (filter.accept(field)) {
+ has = true;
+ break;
+ }
+ }
+ return has;
+ }
+
+ /**
+ * check a class has a specified field
+ *
+ * @param classPath class's path
+ * @param fieldName field's name
+ * @return return true if the field is exist
+ * @see #hasField(Class, String)
+ */
+ public static boolean hasField(String classPath, String fieldName) throws ClassNotFoundException {
+ return hasField(Class.forName(classPath), fieldName);
+ }
+
+ /**
+ * check a class has a specified constructor
+ *
+ * @param clazz class's object
+ * @param parameterTypes the constructor with the specified parameter types
+ * @return return true if the constructor is exist
+ */
+ public static boolean hasConstructor(Class> clazz, Class>... parameterTypes) {
+ boolean has;
+ try {
+ Validate.notNull(clazz).getDeclaredConstructor(parameterTypes);
+ has = true;
+ } catch (NoSuchMethodException e) {
+ has = false;
+ }
+ return has;
+ }
+
+ /**
+ * check a class has a specified constructor
+ *
+ * @param clazz class's object
+ * @param filter filter obj
+ * @return return true if the constructor is exist
+ */
+ public static boolean hasConstructor(Class> clazz, ConstructorFilter filter) {
+ Validate.notNull(filter);
+
+ boolean has = false;
+ Constructor[] constructors = clazz.getDeclaredConstructors();
+ for (Constructor constructor : constructors) {
+ if (filter.accept(constructor)) {
+ has = true;
+ break;
+ }
+ }
+ return has;
+ }
+
+ /**
+ * check a class has a specified constructor
+ *
+ * @param classPath class's path
+ * @param parameterTypes the constructor with the specified parameter types
+ * @return return true if the constructor is exist
+ * @see #hasField(Class, String)
+ */
+ public static boolean hasConstructor(String classPath, Class>... parameterTypes) throws ClassNotFoundException {
+ return hasConstructor(Class.forName(classPath), parameterTypes);
+ }
+
+
+ /**
+ * check a class has a specified method
+ *
+ * @param clazz class's object
+ * @param methodName method's name
+ * @param parameterTypes the method with the specified parameter types
+ * @return return true if the method is exist
+ */
+ public static boolean hasMethod(Class> clazz, String methodName, Class>... parameterTypes) {
+ boolean has;
+ try {
+ Validate.notNull(clazz).getDeclaredMethod(methodName, parameterTypes);
+ has = true;
+ } catch (NoSuchMethodException e) {
+ has = false;
+ }
+ return has;
+ }
+
+ /**
+ * check a class has a specified method
+ *
+ * @param clazz class's object
+ * @param filter filter obj
+ * @return return true if the constructor is exist
+ */
+ public static boolean hasMethod(Class> clazz, MethodFilter filter) {
+ Validate.notNull(filter);
+
+ boolean has = false;
+ Method[] methods = clazz.getDeclaredMethods();
+ for (Method method : methods) {
+ if (filter.accept(method)) {
+ has = true;
+ break;
+ }
+ }
+ return has;
+ }
+
+ /**
+ * check a class has a specified method
+ *
+ * @param classPath class's path
+ * @param methodName method's name
+ * @param parameterTypes the method with the specified parameter types
+ * @return return true if the constructor is exist
+ * @see #hasMethod(Class, String, Class[])
+ */
+ public static boolean hasMethod(String classPath, String methodName, Class>... parameterTypes) throws ClassNotFoundException {
+ return hasMethod(Class.forName(classPath), methodName, parameterTypes);
+ }
+}
\ No newline at end of file
diff --git a/common/src/main/java/cc/zoyn/core/util/reflect/package-info.java b/common/src/main/java/cc/zoyn/core/util/reflect/package-info.java
new file mode 100644
index 0000000..b31ee0c
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/reflect/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * The reflection of utils
+ *
+ * @author Zoyn
+ * @since 2017-12-09
+ */
+package cc.zoyn.core.util.reflect;
\ No newline at end of file
diff --git a/src/main/java/cc/zoyn/core/util/BukkitObjectSerializerUtils.java b/common/src/main/java/cc/zoyn/core/util/serializer/BukkitObjectSerializerUtils.java
similarity index 82%
rename from src/main/java/cc/zoyn/core/util/BukkitObjectSerializerUtils.java
rename to common/src/main/java/cc/zoyn/core/util/serializer/BukkitObjectSerializerUtils.java
index 6b1fe95..db29fcb 100644
--- a/src/main/java/cc/zoyn/core/util/BukkitObjectSerializerUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/serializer/BukkitObjectSerializerUtils.java
@@ -1,4 +1,4 @@
-package cc.zoyn.core.util;
+package cc.zoyn.core.util.serializer;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.util.io.BukkitObjectInputStream;
@@ -13,7 +13,11 @@
import java.util.List;
import java.util.stream.Collectors;
-public class BukkitObjectSerializerUtils {
+public final class BukkitObjectSerializerUtils {
+
+ // Prevent accidental construction
+ private BukkitObjectSerializerUtils() {
+ }
/**
* 单对象序列化为字符串
@@ -22,7 +26,7 @@ public class BukkitObjectSerializerUtils {
* @return 字符串
* @throws IOException
*/
- public String singleObjectToString(Object object) throws IOException {
+ public static String singleObjectToString(Object object) throws IOException {
byte[] raw = singleObjectToByteArray(object);
if (raw != null) {
@@ -39,7 +43,7 @@ public String singleObjectToString(Object object) throws IOException {
* @return 字节数组
* @throws IOException
*/
- public byte[] singleObjectToByteArray(Object object) throws IOException {
+ public static byte[] singleObjectToByteArray(Object object) throws IOException {
if (object instanceof ConfigurationSerializable || object instanceof Serializable) {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
BukkitObjectOutputStream out = new BukkitObjectOutputStream(buf);
@@ -60,7 +64,7 @@ public byte[] singleObjectToByteArray(Object object) throws IOException {
* @return 字符串
* @throws IOException
*/
- public String collectionToString(Collection objects) throws IOException {
+ public static String collectionToString(Collection objects) throws IOException {
byte[] raw = collectionToByteArray(objects);
if (raw != null) {
@@ -77,7 +81,7 @@ public String collectionToString(Collection objects) throws IOException
* @return 字节数组
* @throws IOException
*/
- public byte[] collectionToByteArray(Collection objects) throws IOException {
+ public static byte[] collectionToByteArray(Collection objects) throws IOException {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
BukkitObjectOutputStream out = new BukkitObjectOutputStream(buf);
List compatible = objects.stream()
@@ -102,7 +106,7 @@ public byte[] collectionToByteArray(Collection objects) throws IOExcepti
* @return 实例对象
* @throws IOException
*/
- public T singleObjectFromString(String serialized, Class classOfT) throws IOException {
+ public static T singleObjectFromString(String serialized, Class classOfT) throws IOException {
return singleObjectFromByteArray(Base64Coder.decodeLines(serialized), classOfT);
}
@@ -115,7 +119,7 @@ public T singleObjectFromString(String serialized, Class classOfT) throws
* @throws IOException
*/
@SuppressWarnings("unchecked")
- public T singleObjectFromByteArray(byte[] serialized, Class classOfT) throws IOException {
+ public static T singleObjectFromByteArray(byte[] serialized, Class classOfT) throws IOException {
ByteArrayInputStream buf = new ByteArrayInputStream(serialized);
BukkitObjectInputStream in = new BukkitObjectInputStream(buf);
T object = null;
@@ -140,8 +144,7 @@ public T singleObjectFromByteArray(byte[] serialized, Class classOfT) thr
* @return 实例对象集合
* @throws IOException
*/
- public > C collectionFromString(String serialized, Class classOfC, Class classOfT)
- throws IOException {
+ public static > C collectionFromString(String serialized, Class classOfC, Class classOfT) throws IOException {
return collectionFromByteArray(Base64Coder.decodeLines(serialized), classOfC, classOfT);
}
@@ -155,8 +158,7 @@ public > C collectionFromString(String serialized, Cl
* @throws IOException
*/
@SuppressWarnings("unchecked")
- public > C collectionFromByteArray(byte[] serialized, Class classOfC,
- Class classOfT) throws IOException {
+ public static > C collectionFromByteArray(byte[] serialized, Class classOfC, Class classOfT) throws IOException {
C objects = null;
try {
diff --git a/src/main/java/cc/zoyn/core/util/EffectsSerializerUtils.java b/common/src/main/java/cc/zoyn/core/util/serializer/EffectsSerializerUtils.java
similarity index 86%
rename from src/main/java/cc/zoyn/core/util/EffectsSerializerUtils.java
rename to common/src/main/java/cc/zoyn/core/util/serializer/EffectsSerializerUtils.java
index d6531f1..983e100 100644
--- a/src/main/java/cc/zoyn/core/util/EffectsSerializerUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/serializer/EffectsSerializerUtils.java
@@ -1,4 +1,4 @@
-package cc.zoyn.core.util;
+package cc.zoyn.core.util.serializer;
import com.google.common.collect.Lists;
import org.bukkit.potion.PotionEffect;
@@ -18,7 +18,11 @@
* @author Zoyn
* @since 2017/8/2
*/
-public class EffectsSerializerUtils {
+public final class EffectsSerializerUtils {
+
+ // Prevent accidental construction
+ private EffectsSerializerUtils() {
+ }
/**
* 将药水效果序列化为Base64数据
@@ -26,11 +30,10 @@ public class EffectsSerializerUtils {
* @param paramCollection 药水数据
* @return Base64数据
*/
- public static String potionEffectsToBase64(Collection paramCollection) {
+ public static String toBase64(Collection paramCollection) {
try {
ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream();
- BukkitObjectOutputStream localBukkitObjectOutputStream = new BukkitObjectOutputStream(
- localByteArrayOutputStream);
+ BukkitObjectOutputStream localBukkitObjectOutputStream = new BukkitObjectOutputStream(localByteArrayOutputStream);
localBukkitObjectOutputStream.writeInt(paramCollection.toArray().length);
for (int i = 0; i < paramCollection.toArray().length; i++) {
@@ -49,7 +52,7 @@ public static String potionEffectsToBase64(Collection paramCollect
* @param paramString 药水Base64数据
* @return 药水集合
*/
- public static Collection potionEffectsFromBase64(String paramString) {
+ public static Collection fromBase64(String paramString) {
try {
ByteArrayInputStream localByteArrayInputStream = new ByteArrayInputStream(
Base64Coder.decodeLines(paramString));
diff --git a/src/main/java/cc/zoyn/core/util/ItemSerializerUtils.java b/common/src/main/java/cc/zoyn/core/util/serializer/ItemSerializerUtils.java
similarity index 91%
rename from src/main/java/cc/zoyn/core/util/ItemSerializerUtils.java
rename to common/src/main/java/cc/zoyn/core/util/serializer/ItemSerializerUtils.java
index 25d763a..6a0615d 100644
--- a/src/main/java/cc/zoyn/core/util/ItemSerializerUtils.java
+++ b/common/src/main/java/cc/zoyn/core/util/serializer/ItemSerializerUtils.java
@@ -1,5 +1,6 @@
-package cc.zoyn.core.util;
+package cc.zoyn.core.util.serializer;
+import cc.zoyn.core.util.NMSUtils;
import org.bukkit.inventory.ItemStack;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
@@ -14,11 +15,15 @@
* @version 1.1 更新 2017/8/2 更新内容: 修复兼容1.11与1.12的问题
* @since 2017/?/?
*/
-public class ItemSerializerUtils {
+public final class ItemSerializerUtils {
private static Method WRITE_NBT;
private static Method READ_NBT;
+ // Prevent accidental construction
+ private ItemSerializerUtils() {
+ }
+
/**
* 将物品序列化为Base64数据
*
@@ -61,14 +66,14 @@ public static String toBase64(ItemStack[] items) {
if (WRITE_NBT == null) {
try {
WRITE_NBT = NMSUtils.getNMSClass("NBTCompressedStreamTools").getDeclaredMethod("a",
- new Class[]{NMSUtils.getNMSClass("NBTBase"), DataOutput.class});
+ NMSUtils.getNMSClass("NBTBase"), DataOutput.class);
WRITE_NBT.setAccessible(true);
} catch (Exception localException1) {
throw new IllegalStateException("未找到写入方法", localException1);
}
}
try {
- WRITE_NBT.invoke(null, new Object[]{localNBTTagList, localDataOutputStream});
+ WRITE_NBT.invoke(null, localNBTTagList, localDataOutputStream);
} catch (Exception localException2) {
throw new IllegalArgumentException("无法写入" + localNBTTagList + "至" + localDataOutputStream, localException2);
}
@@ -98,7 +103,7 @@ public static ItemStack[] fromBase64(String paramString) {
int subVersion = Integer.valueOf(version.split("_")[1]);
/*
* 1.11版本及以上删除了createStack方法所以只能使用其构造方法来创建
- */
+ */
if (subVersion >= 11) {
//构造器
Constructor> constructor = NMSUtils.getNMSClass("ItemStack").getConstructor(NMSUtils.getNMSClass("NBTTagCompound"));
@@ -131,7 +136,7 @@ private static Object readNbt(DataInput paramDataInput) {
if (READ_NBT == null) {
try {
READ_NBT = NMSUtils.getNMSClass("NBTCompressedStreamTools").getDeclaredMethod("a",
- new Class[]{DataInput.class, Integer.TYPE, NMSUtils.getNMSClass("NBTReadLimiter")});
+ DataInput.class, Integer.TYPE, NMSUtils.getNMSClass("NBTReadLimiter"));
READ_NBT.setAccessible(true);
} catch (Exception localException1) {
throw new IllegalStateException("未找到方法.", localException1);
@@ -139,8 +144,8 @@ private static Object readNbt(DataInput paramDataInput) {
}
try {
Object limiter = NMSUtils.getNMSClass("NBTReadLimiter").getConstructor(Long.TYPE)
- .newInstance(9223372036854775807L);
- return (Object) READ_NBT.invoke(null, new Object[]{paramDataInput, Integer.valueOf(0), limiter});
+ .newInstance(Long.MAX_VALUE);
+ return READ_NBT.invoke(null, paramDataInput, 0, limiter);
} catch (Exception localException2) {
throw new IllegalArgumentException("无法从该位置读取数据" + paramDataInput, localException2);
}
diff --git a/common/src/main/java/cc/zoyn/core/util/serializer/package-info.java b/common/src/main/java/cc/zoyn/core/util/serializer/package-info.java
new file mode 100644
index 0000000..14478f4
--- /dev/null
+++ b/common/src/main/java/cc/zoyn/core/util/serializer/package-info.java
@@ -0,0 +1,6 @@
+/**
+ * The serialization of utils
+ * @author Zoyn
+ * @since 2017-12-09
+ */
+package cc.zoyn.core.util.serializer;
\ No newline at end of file
diff --git a/common/src/main/resources/plugin.yml b/common/src/main/resources/plugin.yml
new file mode 100644
index 0000000..e38c6e3
--- /dev/null
+++ b/common/src/main/resources/plugin.yml
@@ -0,0 +1,6 @@
+name: May-Common-Library
+main: cc.zoyn.core.Core
+version: 1.0.0
+author: Zoyn
+prefix: Core
+depend: [ProtocolLib]
\ No newline at end of file
diff --git a/plugin-release/pom.xml b/plugin-release/pom.xml
new file mode 100644
index 0000000..385ae29
--- /dev/null
+++ b/plugin-release/pom.xml
@@ -0,0 +1,89 @@
+
+
+
+ May-Common-Library
+ cc.zoyn.core
+ 1.0.0
+
+ 4.0.0
+
+ plugin-release
+
+
+
+ cc.zoyn.core
+ common
+ ${project.parent.version}
+ compile
+
+
+ cc.zoyn.core
+ serverping
+ ${project.parent.version}
+ compile
+
+
+ cc.zoyn.core
+ tellraw
+ ${project.parent.version}
+ compile
+
+
+ cc.zoyn.core
+ book
+ ${project.parent.version}
+ compile
+
+
+ cc.zoyn.core
+ advancement
+ 1.0.0
+ compile
+
+
+
+
+
+
+ ../common/src/main/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.6
+
+ ${project.parent.artifactId}-${project.parent.version}
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.1.0
+
+
+ package
+
+ shade
+
+
+
+
+ cglib
+ org.spigotmc
+ com.comphenix.protocol
+ com.comphenix.executors
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1b09d44..85e7e6b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,11 +5,20 @@
4.0.0
cc.zoyn.core
- MayCore
+ May-Common-Library
1.0.0
- jar
+ pom
- MayCore
+
+ tellraw
+ serverping
+ common
+ plugin-release
+ book
+ advancement
+
+
+ May-Common-Library
Zoyn
@@ -21,34 +30,23 @@
UTF-8
-
-
- spigotmc-repo
- https://hub.spigotmc.org/nexus/content/groups/public/
-
elmakers-repo
http://maven.elmakers.com/repository
- dmulloy2-repo
- http://repo.dmulloy2.net/content/groups/public/
+ lss233-minecraft
+ Lss233's Minecraft Repository
+ https://lss233.com/artifactory/minecraft
-
-
- org.spigotmc
- spigot-api
- 1.12.1-R0.1-SNAPSHOT
- provided
-
org.spigotmc
spigot
- 1.12.1-R0.1-SNAPSHOT
+ 1.12.2-R0.1-SNAPSHOT
@@ -60,14 +58,8 @@
com.comphenix.protocol
- ProtocolLib
- 4.3.0
-
-
-
- org.apache.commons
- commons-lang3
- 3.7
+ ProtocolLib-API
+ 4.3.0-SNAPSHOT
@@ -76,56 +68,19 @@
4.12
test
-
-
- com.zaxxer
- HikariCP
- 2.7.2
- compile
-
- clean install
- ${project.name}-${project.version}
- src/main/java
-
-
org.apache.maven.plugins
maven-compiler-plugin
- 3.1
+ 3.5.1
1.8
1.8
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 3.1.0
-
-
- package
-
- shade
-
-
-
-
- cglib
- org.spigotmc
- com.comphenix.protocol
- com.comphenix.executors
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/serverping/pom.xml b/serverping/pom.xml
new file mode 100644
index 0000000..e196a8e
--- /dev/null
+++ b/serverping/pom.xml
@@ -0,0 +1,23 @@
+
+
+
+ May-Common-Library
+ cc.zoyn.core
+ 1.0.0
+
+ 4.0.0
+
+ serverping
+
+
+
+ cc.zoyn.core
+ common
+ ${project.parent.version}
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/serverping/src/main/java/cc/zoyn/core/serverping/ServerPing.java b/serverping/src/main/java/cc/zoyn/core/serverping/ServerPing.java
new file mode 100644
index 0000000..a658edf
--- /dev/null
+++ b/serverping/src/main/java/cc/zoyn/core/serverping/ServerPing.java
@@ -0,0 +1,104 @@
+package cc.zoyn.core.serverping;
+
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import javax.script.Invocable;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import static cc.zoyn.core.serverping.ServerPingUtils.*;
+
+@Data
+@AllArgsConstructor
+public class ServerPing {
+
+ private String hostName;
+ private int port = 25565;
+ private int timeOut = 2000;
+ private String charSet = "UTF-8";
+ private ServerPingReply reply;
+
+ public ServerPing(String hostName) {
+ this(hostName, 25565);
+ }
+
+ public ServerPing(String hostName, int port) {
+ this(hostName, port, 2000);
+ }
+
+ public ServerPing(String hostName, int port, int timeOut) {
+ this.hostName = hostName;
+ this.port = port;
+ this.timeOut = timeOut;
+ }
+
+ public boolean pingServer() {
+ try (Socket socket = new Socket()) {
+ socket.connect(new InetSocketAddress(hostName, 25565), 8000);
+ final DataInputStream in = new DataInputStream(socket.getInputStream());
+ final DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+
+ //> Handshake
+ ByteArrayOutputStream handshake_bytes = new ByteArrayOutputStream();
+ DataOutputStream handshake = new DataOutputStream(handshake_bytes);
+
+ handshake.writeByte(PACKET_HANDSHAKE);
+ writeVarInt(handshake, PROTOCOL_VERSION);
+ writeVarInt(handshake, this.hostName.length());
+
+ handshake.writeBytes(hostName);
+ handshake.writeShort(getPort());
+ writeVarInt(handshake, STATUS_HANDSHAKE);
+
+ writeVarInt(out, handshake_bytes.size());
+ out.write(handshake_bytes.toByteArray());
+
+ //> Status request
+ out.writeByte(0x01); // Size of packet
+ out.writeByte(PACKET_STATUSREQUEST);
+
+ //< Status response
+ readVarInt(in); // Size
+ int id = readVarInt(in);
+ int length = readVarInt(in);
+ byte[] data = new byte[length];
+ in.readFully(data);
+ String json = new String(data, this.charSet);
+
+ // format data
+ ScriptObjectMirror mirror = (ScriptObjectMirror) ((Invocable) ServerPingUtils.getEngine()).invokeFunction("parse", json);
+ if (mirror == null) {
+ return false;
+ }
+ ServerPingReply reply = new ServerPingReply();
+
+ ServerPingReply.Version version = new ServerPingReply.Version((String) mirror.get("version_name"), (int) mirror.get("version_protocol"));
+ ServerPingReply.Players players = new ServerPingReply.Players((int) mirror.get("players_max"), (int) mirror.get("players_online"));
+ ServerPingReply.Motd motd = new ServerPingReply.Motd((String) mirror.get("motd_text"));
+ ServerPingReply.Favicon favicon = new ServerPingReply.Favicon((String) mirror.get("favicon_data"));
+
+ reply.setVersion(version);
+ reply.setPlayers(players);
+ reply.setMotd(motd);
+ reply.setFavicon(favicon);
+ reply.setOriginalJson(json);
+
+ // Close
+ handshake.close();
+ handshake_bytes.close();
+ out.close();
+ in.close();
+
+ setReply(reply);
+ return true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+}
diff --git a/serverping/src/main/java/cc/zoyn/core/serverping/ServerPingReply.java b/serverping/src/main/java/cc/zoyn/core/serverping/ServerPingReply.java
new file mode 100644
index 0000000..6353882
--- /dev/null
+++ b/serverping/src/main/java/cc/zoyn/core/serverping/ServerPingReply.java
@@ -0,0 +1,52 @@
+package cc.zoyn.core.serverping;
+
+import lombok.*;
+
+/**
+ * @author Zoyn
+ * @since 2017-12-22
+ */
+@Data
+@AllArgsConstructor
+@RequiredArgsConstructor
+public class ServerPingReply {
+
+ private Version version;
+ private Players players;
+ private Motd motd;
+ private Favicon favicon;
+ private String originalJson;
+
+ @ToString
+ @AllArgsConstructor
+ public static class Version {
+ @Getter
+ private String name;
+ @Getter
+ private int protocol;
+ }
+
+ @ToString
+ @AllArgsConstructor
+ public static class Players {
+ @Getter
+ private int maxPlayer;
+ @Getter
+ private int onlinePlayer;
+ }
+
+ @ToString
+ @AllArgsConstructor
+ public static class Motd {
+ @Getter
+ private String text;
+ }
+
+ @ToString
+ @AllArgsConstructor
+ public static class Favicon {
+ @Getter
+ private String data;
+ }
+
+}
diff --git a/serverping/src/main/java/cc/zoyn/core/serverping/ServerPingUtils.java b/serverping/src/main/java/cc/zoyn/core/serverping/ServerPingUtils.java
new file mode 100644
index 0000000..96c51f8
--- /dev/null
+++ b/serverping/src/main/java/cc/zoyn/core/serverping/ServerPingUtils.java
@@ -0,0 +1,136 @@
+package cc.zoyn.core.serverping;
+
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * @since 2017-12-22
+ */
+public final class ServerPingUtils {
+
+ static byte PACKET_HANDSHAKE = 0x00, PACKET_STATUSREQUEST = 0x00;
+ static int PROTOCOL_VERSION = 4;
+ static int STATUS_HANDSHAKE = 1;
+ private static ScriptEngine engine;
+
+ /*
+ * MOTD解析脚本
+ *
+ * @author 喵♂呜
+ * @editor: Zoyn
+ */
+ static {
+ ScriptEngineManager manager = new ScriptEngineManager();
+ engine = manager.getEngineByName("js");
+ try {
+ engine.eval("function parse(json) {\n" +
+ " var color = [];\n" +
+ " color['black'] = '0';\n" +
+ " color['dark_blue'] = '1';\n" +
+ " color['dark_green'] = '2';\n" +
+ " color['dark_aqua'] = '3';\n" +
+ " color['dark_red'] = '4';\n" +
+ " color['dark_purple'] = '5';\n" +
+ " color['gold'] = '6';\n" +
+ " color['gray'] = '7';\n" +
+ " color['dark_gray'] = '8';\n" +
+ " color['blue'] = '9';\n" +
+ " color['green'] = 'a';\n" +
+ " color['aqua'] = 'b';\n" +
+ " color['red'] = 'c';\n" +
+ " color['light_purple'] = 'd';\n" +
+ " color['yellow'] = 'e';\n" +
+ " color['white'] = 'f';\n" +
+ " var obj = JSON.parse(json);\n" +
+ " // noinspection JSUnresolvedVariable\n" +
+ " var motd = obj.description.text;\n" +
+ " // noinspection JSUnresolvedVariable\n" +
+ " if (obj.description.extra) {\n" +
+ " // noinspection JSUnresolvedVariable\n" +
+ " obj.description.extra.forEach(function (part) {\n" +
+ " // noinspection JSUnresolvedVariable\n" +
+ " if (part.obfuscated) {\n" +
+ " motd += \"§k\";\n" +
+ " }\n" +
+ " if (part.bold) {\n" +
+ " motd += \"§l\";\n" +
+ " }\n" +
+ " // noinspection JSUnresolvedVariable\n" +
+ " if (part.strikethrough) {\n" +
+ " motd += \"§m\";\n" +
+ " }\n" +
+ " // noinspection JSUnresolvedVariable\n" +
+ " if (part.underline) {\n" +
+ " motd += \"§n\";\n" +
+ " }\n" +
+ " // noinspection JSUnresolvedVariable\n" +
+ " if (part.italic) {\n" +
+ " motd += \"§o\";\n" +
+ " }\n" +
+ " if (part.reset) {\n" +
+ " motd += \"§r\";\n" +
+ " }\n" +
+ " if (part.color) {\n" +
+ " motd += '§' + color[part.color];\n" +
+ " }\n" +
+ " motd += part.text;\n" +
+ " })\n" +
+ " } else if(obj.description.text) {\n" +
+ " motd = obj.description.text\n" +
+ " }\n" +
+ " obj.version_name = obj.version.name;\n" +
+ " obj.version_protocol = obj.version.protocol;\n" +
+ " obj.players_max = obj.players.max;\n" +
+ " obj.players_online = obj.players.online;\n" +
+ " obj.motd_text = motd;\n" +
+ " obj.favicon_data = obj.favicon;\n" +
+ " return obj;\n" +
+ "}");
+ } catch (ScriptException e) {
+ e.printStackTrace();
+ System.out.println("警告! MOTD 解析脚本初始化失败!");
+ }
+ }
+
+ public static ScriptEngine getEngine() {
+ return engine;
+ }
+
+ /**
+ * @author thinkofdeath
+ * See: https://gist.github.com/thinkofdeath/e975ddee04e9c87faf22
+ */
+ public static int readVarInt(DataInputStream in) throws IOException {
+ int i = 0;
+ int j = 0;
+ while (true) {
+ int k = in.readByte();
+ i |= (k & 0x7F) << j++ * 7;
+ if (j > 5)
+ throw new RuntimeException("VarInt too big");
+ if ((k & 0x80) != 128)
+ break;
+ }
+ return i;
+ }
+
+ /**
+ * @author thinkofdeath
+ * See: https://gist.github.com/thinkofdeath/e975ddee04e9c87faf22
+ */
+ public static void writeVarInt(DataOutputStream out, int paramInt) throws IOException {
+ while (true) {
+ if ((paramInt & 0xFFFFFF80) == 0) {
+ out.writeByte(paramInt);
+ return;
+ }
+ out.writeByte(paramInt & 0x7F | 0x80);
+ paramInt >>>= 7;
+ }
+ }
+
+}
diff --git a/serverping/src/test/java/cc/zoyn/core/ServerPingTest.java b/serverping/src/test/java/cc/zoyn/core/ServerPingTest.java
new file mode 100644
index 0000000..540bbed
--- /dev/null
+++ b/serverping/src/test/java/cc/zoyn/core/ServerPingTest.java
@@ -0,0 +1,21 @@
+package cc.zoyn.core;
+
+import org.junit.Test;
+
+/**
+ * @author Zoyn
+ * @since 2017-12-22
+ */
+public class ServerPingTest {
+
+ @Test
+ public void testServerPing() {
+// ServerPing serverPing = new ServerPing("mc.52ko.com");
+// serverPing.pingServer();
+
+// ServerPingReply reply = serverPing.getReply();
+// System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(reply.getOriginalJson())));
+// Assert.assertTrue(reply.getVersion().getName().contains("1.12"));
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/cc/zoyn/core/Core.java b/src/main/java/cc/zoyn/core/Core.java
deleted file mode 100644
index f1daaa7..0000000
--- a/src/main/java/cc/zoyn/core/Core.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package cc.zoyn.core;
-
-import cc.zoyn.core.command.CommandHandler;
-import cc.zoyn.core.listener.TestListener;
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolLibrary;
-import com.comphenix.protocol.ProtocolManager;
-import com.comphenix.protocol.events.PacketAdapter;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.events.PacketEvent;
-import com.comphenix.protocol.wrappers.BlockPosition;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.bukkit.Bukkit;
-import org.bukkit.World;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.Plugin;
-import org.bukkit.plugin.java.JavaPlugin;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-public class Core extends JavaPlugin {
-
- private static Core instance;
- private ProtocolManager pm;
- public static Map map = Maps.newHashMap();
-
- public void onEnable() {
- instance = this;
-
- Bukkit.getPluginCommand("core").setExecutor(new CommandHandler());
- Bukkit.getPluginManager().registerEvents(new TestListener(), this);
-
- saveDefaultConfig();
- pm = ProtocolLibrary.getProtocolManager();
-
- pm.addPacketListener(
- new PacketAdapter(this, PacketType.Play.Client.UPDATE_SIGN) {
- @Override
- public void onPacketReceiving(PacketEvent event) {
- System.out.println("test");
- PacketContainer packet = event.getPacket();
- Player player = event.getPlayer();
-
- BlockPosition cacheBlockPosition = map.get(player.getName()); //缓存中的牌子位置数据
- BlockPosition packetBlockPosition = packet.getBlockPositionModifier().getValues().get(0); //数据包中的牌子位置数据
-
- System.out.println(packet.getModifier().getValues().toString());
-
- System.out.println(cacheBlockPosition);
- System.out.println(packetBlockPosition);
-
- //NPE检查
- if (cacheBlockPosition == null || packetBlockPosition == null) {
- System.out.println("null?");
- return;
- }
-
- if (cacheBlockPosition.equals(packetBlockPosition)) {
- System.out.println("123");
- }
- }
- }
- );
- }
-
- /**
- * 以List的方式取服务器插件
- *
- * @return 服务器所有插件的集合
- */
- public List getPlugins() {
- return Arrays.asList(Bukkit.getPluginManager().getPlugins());
- }
-
- /**
- * 取全部世界的名字
- *
- * @return 全部世界名
- */
- public List getWorldsName() {
- List names = Lists.newArrayList();
- for (World world : Bukkit.getWorlds()) {
- names.add(world.getName());
- }
- return names;
- }
-
- /**
- * 取Core实例
- *
- * @return Core的实例
- */
- public static Core getInstance() {
- return instance;
- }
-
- public ProtocolManager getProtocolManager() {
- return pm;
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/advancement/FrameEnum.java b/src/main/java/cc/zoyn/core/advancement/FrameEnum.java
deleted file mode 100644
index b8f40cb..0000000
--- a/src/main/java/cc/zoyn/core/advancement/FrameEnum.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package cc.zoyn.core.advancement;
-
-/**
- * 图标边框枚举
- *
- * @author Zoyn
- */
-public enum FrameEnum {
- // TASK(默认)
- // GOAL为更圆的边框标题,其用于完整信标进度
- // CHALLENGE,其用于杀死所有种类生物的进度
- TASK(),
- GOAL(),
- CHALLENGE();
-
- private FrameEnum() {
- }
-}
diff --git a/src/main/java/cc/zoyn/core/api/BungeeCordAPI.java b/src/main/java/cc/zoyn/core/api/BungeeCordAPI.java
deleted file mode 100644
index 04dc3bf..0000000
--- a/src/main/java/cc/zoyn/core/api/BungeeCordAPI.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package cc.zoyn.core.api;
-
-import cc.zoyn.core.util.BungeeCordUtils;
-
-/**
- * 蹦极代理API
- *
- * @author Zoyn
- */
-public class BungeeCordAPI {
-
- /**
- * 踢出一个玩家
- *
- * @param playerName 玩家名
- * @param message 信息
- */
- public static void kickPlayer(String playerName, String message) {
- BungeeCordUtils.kickPlayer(playerName, message);
- }
-
- /**
- * 将玩家传送至某子服
- *
- * @param playerName 玩家名
- * @param serverName 服务器名
- */
- public static void playerConnectServer(String playerName, String serverName) {
- BungeeCordUtils.playerConnectServer(playerName, serverName);
- }
-
- /**
- * 给所有服务器的玩家发送Title
- *
- * @param title 标题
- * @param subtitle 子标题
- */
- public static void sendTitleToAllServer(String title, String subtitle) {
- BungeeCordUtils.sendData("BukkitCoreMessage", title + "%ncyn%" + subtitle);
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/api/CoreAPI.java b/src/main/java/cc/zoyn/core/api/CoreAPI.java
deleted file mode 100644
index 00de213..0000000
--- a/src/main/java/cc/zoyn/core/api/CoreAPI.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package cc.zoyn.core.api;
-
-import cc.zoyn.core.dto.Tellraw;
-import cc.zoyn.core.service.CoreService;
-import cc.zoyn.core.service.CoreServiceImpl;
-import org.bukkit.Location;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-/**
- * 核心API
- *
- * @author Zoyn
- */
-public class CoreAPI {
-
- private static CoreService coreService;
-
- static {
- coreService = new CoreServiceImpl();
- }
-
- /**
- * 给一名玩家发送Tellraw
- *
- * @param tellraw Tellraw的对象
- * @param player 玩家
- */
- public static void sendTellraw(Tellraw tellraw, Player player) {
- coreService.sendTellraw(tellraw, player);
- }
-
- /**
- * 创建一个Tellraw对象
- *
- * @param message 信息
- * @return {@link Tellraw}
- */
- public static Tellraw createTellraw(String message) {
- return coreService.createTellraw(message);
- }
-
- /**
- * 设置一个物品的无法破坏
- *
- * @param is 物品
- * @param unbreakable 无法破坏值[布尔]
- */
- public static void setItemUnbreakable(ItemStack is, boolean unbreakable) {
- coreService.setItemUnbreakable(is, unbreakable);
- }
-
- /**
- * 设置一个物品发光
- *
- * @param is 物品
- * @return {@link ItemStack}
- */
- public static ItemStack setItemGlow(ItemStack is) {
- return coreService.setItemGlow(is);
- }
-
- /**
- * 设置玩家的Tab 可以使用\n换行字符
- *
- * @param player 玩家
- * @param head Tab首
- * @param foot Tab尾
- */
- public static void setPlayerTab(Player player, String head, String foot) {
- coreService.setPlayerTab(player, head, foot);
- }
-
- /**
- * 给玩家发送Title
- *
- * @param player 玩家
- * @param fadeIn 淡入时间
- * @param stay 停留时间
- * @param fadeOut 淡出时间
- * @param title 标题[可用Null]
- * @param subtitle 副标题[可用Null]
- */
- public static void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title, String subtitle) {
- coreService.sendTitle(player, fadeIn, stay, fadeOut, title, subtitle);
- }
-
- /**
- * 给玩家发送一条ActionBar
- *
- * @param player 玩家
- * @param msg 信息
- */
- public static void sendActionBar(Player player, String msg) {
- coreService.sendActionBar(player, msg);
- }
-
- /**
- * 取该坐标附近的所有实体
- *
- * @param loc 坐标
- * @param radius 半径
- * @return {@link Entity}
- */
- public static Entity[] getNearbyEntitiesArrays(Location loc, double radius) {
- return coreService.getNearbyEntitiesArrays(loc, radius);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/cc/zoyn/core/api/events/PlayerReceiveActionbarEvent.java b/src/main/java/cc/zoyn/core/api/events/PlayerReceiveActionbarEvent.java
deleted file mode 100644
index 7fbcda3..0000000
--- a/src/main/java/cc/zoyn/core/api/events/PlayerReceiveActionbarEvent.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package cc.zoyn.core.api.events;
-
-import cc.zoyn.core.dto.Actionbar;
-import org.bukkit.entity.Player;
-import org.bukkit.event.Cancellable;
-import org.bukkit.event.Event;
-import org.bukkit.event.HandlerList;
-
-/**
- * 玩家接收ActionBar事件
- *
- * @author Zoyn
- */
-public class PlayerReceiveActionbarEvent extends Event implements Cancellable {
-
- private Player player;
- private Actionbar actionBar;
- private static final HandlerList handlers = new HandlerList();
-
- public PlayerReceiveActionbarEvent(Player player, Actionbar actionBar) {
- this.player = player;
- this.actionBar = actionBar;
- }
-
- public Player getPlayer() {
- return player;
- }
-
- public void setPlayer(Player player) {
- this.player = player;
- }
-
- public Actionbar getActionbar() {
- return actionBar;
- }
-
- public void setActionbar(Actionbar actionBar) {
- this.actionBar = actionBar;
- }
-
- public HandlerList getHandlers() {
- return handlers;
- }
-
- public static HandlerList getHandlerList() {
- return handlers;
- }
-
- private boolean cancelled = false;
-
- public boolean isCancelled() {
- return this.cancelled;
- }
-
- public void setCancelled(boolean cancel) {
- this.cancelled = cancel;
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/api/events/PlayerReceiveTellrawEvent.java b/src/main/java/cc/zoyn/core/api/events/PlayerReceiveTellrawEvent.java
deleted file mode 100644
index a5cab98..0000000
--- a/src/main/java/cc/zoyn/core/api/events/PlayerReceiveTellrawEvent.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package cc.zoyn.core.api.events;
-
-import cc.zoyn.core.dto.Tellraw;
-import org.bukkit.entity.Player;
-import org.bukkit.event.Cancellable;
-import org.bukkit.event.Event;
-import org.bukkit.event.HandlerList;
-
-/**
- * 玩家接收Tellraw事件
- *
- * @author Zoyn
- */
-public class PlayerReceiveTellrawEvent extends Event implements Cancellable {
-
- private Player player;
- private Tellraw tellraw;
- private static final HandlerList handlers = new HandlerList();
-
- public PlayerReceiveTellrawEvent(Player player, Tellraw tellraw) {
- this.player = player;
- this.tellraw = tellraw;
- }
-
- public Player getPlayer() {
- return player;
- }
-
- public void setPlayer(Player player) {
- this.player = player;
- }
-
- public Tellraw getTellraw() {
- return tellraw;
- }
-
- public void setTellraw(Tellraw tellraw) {
- this.tellraw = tellraw;
- }
-
- public HandlerList getHandlers() {
- return handlers;
- }
-
- public static HandlerList getHandlerList() {
- return handlers;
- }
-
- private boolean cancelled = false;
-
- public boolean isCancelled() {
- return this.cancelled;
- }
-
- public void setCancelled(boolean cancel) {
- this.cancelled = cancel;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/api/events/PlayerReceiveTitleEvent.java b/src/main/java/cc/zoyn/core/api/events/PlayerReceiveTitleEvent.java
deleted file mode 100644
index ed4ee37..0000000
--- a/src/main/java/cc/zoyn/core/api/events/PlayerReceiveTitleEvent.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package cc.zoyn.core.api.events;
-
-import cc.zoyn.core.dto.Title;
-import org.bukkit.entity.Player;
-import org.bukkit.event.Cancellable;
-import org.bukkit.event.Event;
-import org.bukkit.event.HandlerList;
-
-/**
- * 玩家接收Title事件
- *
- * @author Zoyn
- */
-public class PlayerReceiveTitleEvent extends Event implements Cancellable {
-
- private Player player;
- private Title title;
- private static final HandlerList handlers = new HandlerList();
-
- public PlayerReceiveTitleEvent(Player player, Title title) {
- this.player = player;
- this.title = title;
- }
-
- public Player getPlayer() {
- return player;
- }
-
- public void setPlayer(Player player) {
- this.player = player;
- }
-
- public Title getTitle() {
- return title;
- }
-
- public void setTitle(Title title) {
- this.title = title;
- }
-
- public HandlerList getHandlers() {
- return handlers;
- }
-
- public static HandlerList getHandlerList() {
- return handlers;
- }
-
- private boolean cancelled = false;
-
- public boolean isCancelled() {
- return this.cancelled;
- }
-
- public void setCancelled(boolean cancel) {
- this.cancelled = cancel;
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/command/CommandHandler.java b/src/main/java/cc/zoyn/core/command/CommandHandler.java
deleted file mode 100644
index e9b7d64..0000000
--- a/src/main/java/cc/zoyn/core/command/CommandHandler.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package cc.zoyn.core.command;
-
-import cc.zoyn.core.command.subcommand.InfoCommand;
-import cc.zoyn.core.command.subcommand.ListCommand;
-import cc.zoyn.core.util.SubCommand;
-import com.google.common.collect.Maps;
-import org.bukkit.Bukkit;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-
-import java.util.Map;
-
-public class CommandHandler implements CommandExecutor {
-
- private Map subCommandMap = Maps.newHashMap();
-
- public CommandHandler() {
- registerSubCommand("list", new ListCommand());
- registerSubCommand("info", new InfoCommand());
- }
-
- public void registerSubCommand(String commandName, SubCommand subCommand) {
- if (subCommandMap.containsKey(commandName)) {
- Bukkit.getLogger().warning("发现重复注册指令!");
- }
- subCommandMap.put(commandName, subCommand);
- }
-
- @Override
- public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
- if (label.equalsIgnoreCase("core")) {
- if (args.length == 0) {
- sender.sendMessage("§6========== §3[ §eMayCore §l| §e核心 §3] §6==========");
- sender.sendMessage("§b/core list §7查看插件列表");
- sender.sendMessage("§b/core info §7查看服务器信息");
- return true;
- }
- SubCommand subCommand = subCommandMap.get(args[0]);
- if (subCommand == null) {
- sender.sendMessage("§8[§6核心§8] §e>> §c未知指令");
- return true;
- }
- subCommand.execute(sender, args);
- }
- return false;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/command/subcommand/InfoCommand.java b/src/main/java/cc/zoyn/core/command/subcommand/InfoCommand.java
deleted file mode 100644
index 34ceb9b..0000000
--- a/src/main/java/cc/zoyn/core/command/subcommand/InfoCommand.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package cc.zoyn.core.command.subcommand;
-
-import cc.zoyn.core.util.SubCommand;
-import org.bukkit.Bukkit;
-import org.bukkit.command.CommandSender;
-
-public class InfoCommand implements SubCommand {
-
- @Override
- public boolean execute(CommandSender sender, String[] args) {
- if (!sender.isOp()) {
- sender.sendMessage("§b[核心] §e>> §c权限不足");
- return true;
- }
- sender.sendMessage("§6运行版本§c:§r " + Bukkit.getBukkitVersion() + " | " + Bukkit.getVersion());
- sender.sendMessage("§6当前在线§c:§r " + Bukkit.getOnlinePlayers().size());
- sender.sendMessage("§6最大人数§c:§r " + Bukkit.getMaxPlayers());
- sender.sendMessage("§6封禁玩家§c:§r " + Bukkit.getBannedPlayers().size());
- sender.sendMessage("§6封禁IP数§c:§r " + Bukkit.getIPBans().size());
-
- return false;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/command/subcommand/ListCommand.java b/src/main/java/cc/zoyn/core/command/subcommand/ListCommand.java
deleted file mode 100644
index f52e5b5..0000000
--- a/src/main/java/cc/zoyn/core/command/subcommand/ListCommand.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package cc.zoyn.core.command.subcommand;
-
-import cc.zoyn.core.util.SubCommand;
-import cc.zoyn.core.Core;
-import org.bukkit.command.CommandSender;
-import org.bukkit.plugin.Plugin;
-
-import java.util.List;
-
-public class ListCommand implements SubCommand {
-
- private List plugins = null;
-
- @Override
- public boolean execute(CommandSender sender, String[] args) {
- if (plugins == null) {
- plugins = Core.getInstance().getPlugins();
- }
- sender.sendMessage("§6========== §3[ §aPlugins §6◤ §f" + plugins.size() + " §6◢ §3] §6==========");
- for (int i = 0; i < plugins.size(); i++) {
- if (plugins.get(i).isEnabled()) {
- String prefix = plugins.get(i).getDescription().getPrefix();
- if (prefix == null) {
- sender.sendMessage("§6" + plugins.get(i).getName() + " §7- §a✔ 已加载");
- } else {
- sender.sendMessage("§6" + plugins.get(i).getName() + "§7(" + prefix + "§7)" + " §7- §a✔ 已加载");
- }
- } else {
- String prefix = plugins.get(i).getDescription().getPrefix();
- if (prefix == null) {
- sender.sendMessage("§6" + plugins.get(i).getName() + " §7- §c✘ 未加载");
- } else {
- sender.sendMessage("§6" + plugins.get(i).getName() + "§7(" + prefix + "§7)" + " §7- §c✘ 未加载");
- }
- }
- }
- return true;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/dto/Actionbar.java b/src/main/java/cc/zoyn/core/dto/Actionbar.java
deleted file mode 100644
index a67f2dd..0000000
--- a/src/main/java/cc/zoyn/core/dto/Actionbar.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package cc.zoyn.core.dto;
-
-/**
- * Actionbar - 数据模型
- *
- * @author Zoyn
- */
-public class Actionbar {
-
- private String message;
-
- public Actionbar(String message) {
- this.message = message;
- }
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/dto/Book.java b/src/main/java/cc/zoyn/core/dto/Book.java
deleted file mode 100644
index 164c72d..0000000
--- a/src/main/java/cc/zoyn/core/dto/Book.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package cc.zoyn.core.dto;
-
-import cc.zoyn.core.util.BookUtils;
-import org.bukkit.Material;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.BookMeta;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Book - 数据模型
- *
- * @author Zoyn
- */
-public class Book {
-
- private String author = "notch";
- private String title = "SouthOfSouth";
- private List pages = new ArrayList();
-
- @Override
- public String toString() {
- return "Book [author=" + author + ", title=" + title + ", pages=" + pages + "]";
- }
-
- public Book(String author, String title, List pages) {
- super();
- this.author = author;
- this.title = title;
- this.pages = pages;
- }
-
- public String getAuthor() {
- return author;
- }
-
- public void setAuthor(String author) {
- this.author = author;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public List getPages() {
- return pages;
- }
-
- public void setPages(List pages) {
- this.pages = pages;
- }
-
- public ItemStack getItem() {
- ItemStack book = new ItemStack(Material.WRITTEN_BOOK);
- BookMeta meta = (BookMeta) book.getItemMeta();
- meta.setTitle(title);
- meta.setAuthor(author);
- BookUtils.setPagesAsPage(meta, pages);
- book.setItemMeta(meta);
- return book;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/dto/Sign.java b/src/main/java/cc/zoyn/core/dto/Sign.java
deleted file mode 100644
index 9e13c9a..0000000
--- a/src/main/java/cc/zoyn/core/dto/Sign.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package cc.zoyn.core.dto;
-
-import java.util.List;
-
-/**
- * Sign - 数据传输模型
- *
- * @author Zoyn
- */
-public class Sign {
-
- private String[] message = new String[4];
-
- public Sign(List texts) {
- if (texts.size() > 4) {
- for (int i = 0; i < 3; i++) {
- String string = message[i];
- message[i] = string;
- }
- }
- message = texts.toArray(new String[]{});
- }
-
- public Sign(String... texts) {
- if (texts.length > 4) {
- for (int i = 0; i <= 3; i++) {
- String string = texts[i];
- message[i] = string;
- }
- }
- message = texts;
- }
-
- public Sign setTexts(String... texts) {
- if (texts.length > 4) {
- for (int i = 0; i <= 3; i++) {
- String string = texts[i];
- message[i] = string;
- }
- }
- message = texts;
- return this;
- }
-
- public boolean isEmpty() {
- if (message.length == 0) {
- return true;
- }
- return false;
- }
-
- public String[] getTexts() {
- return message;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/dto/SlotTypeEnum.java b/src/main/java/cc/zoyn/core/dto/SlotTypeEnum.java
deleted file mode 100644
index 2edd759..0000000
--- a/src/main/java/cc/zoyn/core/dto/SlotTypeEnum.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package cc.zoyn.core.dto;
-
-/**
- * NBTSlot类型枚举
- *
- * @author Zoyn
- */
-public enum SlotTypeEnum {
- mainhand, offhand, feet, legs, chest, head;
-
- private SlotTypeEnum() {
- }
-}
diff --git a/src/main/java/cc/zoyn/core/dto/Title.java b/src/main/java/cc/zoyn/core/dto/Title.java
deleted file mode 100644
index 118277d..0000000
--- a/src/main/java/cc/zoyn/core/dto/Title.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package cc.zoyn.core.dto;
-
-/**
- * Title - 数据模型
- *
- * @author Zoyn
- */
-public class Title {
-
- private int fadeIn;
- private int stay;
- private int fadeOut;
- private String title;
- private String subtitle;
-
-
- public Title(int fadeIn, int stay, int fadeOut, String title, String subtitle) {
- this.fadeIn = fadeIn;
- this.stay = stay;
- this.fadeOut = fadeOut;
- this.title = title;
- this.subtitle = subtitle;
- }
-
- public int getFadeIn() {
- return fadeIn;
- }
-
- public void setFadeIn(int fadeIn) {
- this.fadeIn = fadeIn;
- }
-
- public int getStay() {
- return stay;
- }
-
- public void setStay(int stay) {
- this.stay = stay;
- }
-
- public int getFadeOut() {
- return fadeOut;
- }
-
- public void setFadeOut(int fadeOut) {
- this.fadeOut = fadeOut;
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- this.title = title;
- }
-
- public String getSubtitle() {
- return subtitle;
- }
-
- public void setSubtitle(String subtitle) {
- this.subtitle = subtitle;
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/listener/TestListener.java b/src/main/java/cc/zoyn/core/listener/TestListener.java
deleted file mode 100644
index 08e4307..0000000
--- a/src/main/java/cc/zoyn/core/listener/TestListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package cc.zoyn.core.listener;
-
-
-import com.comphenix.protocol.wrappers.nbt.NbtBase;
-import com.comphenix.protocol.wrappers.nbt.NbtCompound;
-import com.comphenix.protocol.wrappers.nbt.NbtFactory;
-import com.google.common.collect.Lists;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.player.AsyncPlayerChatEvent;
-
-import java.util.List;
-
-/**
- * 测试用Listener
- *
- * @author Zoyn
- * @since 2017-10-03
- */
-public class TestListener implements Listener {
-
- @EventHandler
- public void onChat(AsyncPlayerChatEvent e) {
- List> list = Lists.newArrayList();
- list.add(NbtFactory.of("name", "null"));
- list.add(NbtFactory.of("Value", "xxx"));
-
- NbtCompound value = NbtFactory.ofCompound("value");
- NbtCompound array = NbtFactory.ofCompound("value");
- array.put("name", "null");
- array.put("Value", "xxx");
- value.put(array);
-
- System.out.println(value.getKeys().toString());
- System.out.println(value.toString());
-
- }
-}
diff --git a/src/main/java/cc/zoyn/core/service/CoreService.java b/src/main/java/cc/zoyn/core/service/CoreService.java
deleted file mode 100644
index 8174a35..0000000
--- a/src/main/java/cc/zoyn/core/service/CoreService.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package cc.zoyn.core.service;
-
-import cc.zoyn.core.dto.Tellraw;
-import cc.zoyn.core.dto.Sign;
-import org.bukkit.Location;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-/**
- * Core - 应用层接口
- *
- * @author Zoyn
- */
-public interface CoreService {
-
- void sendTellraw(Tellraw tellraw, Player player);
-
- Tellraw createTellraw(String message);
-
- void setItemUnbreakable(ItemStack is, boolean unbreakable);
-
- ItemStack setItemGlow(ItemStack is);
-
- void setPlayerTab(Player player, String head, String foot);
-
- void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title, String subtitle);
-
- void sendActionBar(Player player, String msg);
-
- void sendSign(Player player, Sign sign);
-
- Entity[] getNearbyEntitiesArrays(Location loc, double radius);
-}
diff --git a/src/main/java/cc/zoyn/core/service/CoreServiceImpl.java b/src/main/java/cc/zoyn/core/service/CoreServiceImpl.java
deleted file mode 100644
index 6da2ef3..0000000
--- a/src/main/java/cc/zoyn/core/service/CoreServiceImpl.java
+++ /dev/null
@@ -1,191 +0,0 @@
-package cc.zoyn.core.service;
-
-import cc.zoyn.core.Core;
-import cc.zoyn.core.api.events.PlayerReceiveActionbarEvent;
-import cc.zoyn.core.api.events.PlayerReceiveTellrawEvent;
-import cc.zoyn.core.api.events.PlayerReceiveTitleEvent;
-import cc.zoyn.core.dto.Actionbar;
-import cc.zoyn.core.dto.Sign;
-import cc.zoyn.core.dto.Tellraw;
-import cc.zoyn.core.dto.Title;
-import cc.zoyn.core.enchantments.Glow;
-import cc.zoyn.core.util.*;
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolManager;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.wrappers.BlockPosition;
-import com.comphenix.protocol.wrappers.WrappedBlockData;
-import com.comphenix.protocol.wrappers.nbt.NbtCompound;
-import com.comphenix.protocol.wrappers.nbt.NbtFactory;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Core - 接口实现
- *
- * @author Zoyn
- */
-public class CoreServiceImpl implements CoreService {
-
- @Override
- public void sendTellraw(Tellraw tellraw, Player player) {
- if (!player.isOnline()) {
- throw new NullPointerException("错误: 玩家不在线!");
- }
- if (tellraw == null) {
- throw new NullPointerException("错误: Tellraw不能为Null!");
- }
- Tellraw tellRaw = tellraw;
- PlayerReceiveTellrawEvent event = new PlayerReceiveTellrawEvent(player, tellRaw);
- Bukkit.getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
-
- if (Bukkit.getVersion().contains("Paper") && !Bukkit.isPrimaryThread()) {
- Bukkit.getScheduler().runTask(
- Core.getInstance(),
- () -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + tellraw.toJsonString())
- );
-
- } else {
- Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + tellRaw.toJsonString());
- }
- }
-
- @Override
- public Tellraw createTellraw(String message) {
- return new Tellraw(message.replaceAll("&", "§"));
- }
-
- @Override
- public void setItemUnbreakable(ItemStack is, boolean unbreakable) {
- if (is == null) {
- throw new NullPointerException("错误: 物品不能为Null!");
- }
- NBTUtils.setUnbreakable(is, unbreakable);
- }
-
- @Override
- public ItemStack setItemGlow(ItemStack is) {
- if (is == null) {
- throw new NullPointerException("错误: 物品不能为Null!");
- }
- ItemMeta im = is.getItemMeta();
- im.addEnchant(new Glow(255), 1, true);
- is.setItemMeta(im);
- im = null;
- return is;
- }
-
- @Override
- public void setPlayerTab(Player player, String head, String foot) {
- if (!player.isOnline()) {
- throw new NullPointerException("错误: 玩家不在线!");
- }
- TabUtils.setTab(player, head.replaceAll("&", "§"), foot.replaceAll("&", "§"));
- }
-
- @Override
- public void sendTitle(Player player, Integer fadeIn, Integer stay, Integer fadeOut, String title, String subtitle) {
- if (!player.isOnline()) {
- throw new NullPointerException("错误: 玩家不在线!");
- }
- Title t = new Title(fadeIn, stay, fadeOut, title, subtitle);
- PlayerReceiveTitleEvent event = new PlayerReceiveTitleEvent(player, t);
- Bukkit.getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
- TitleUtils.sendTitle(player, t.getFadeIn(), t.getStay(), t.getFadeOut(), t.getTitle(), t.getSubtitle());
- }
-
- @Override
- public void sendActionBar(Player player, String msg) {
- if (!player.isOnline()) {
- throw new NullPointerException("错误: 玩家不在线!");
- }
- Actionbar action = new Actionbar(msg.replaceAll("&", "§"));
- PlayerReceiveActionbarEvent event = new PlayerReceiveActionbarEvent(player, action);
- Bukkit.getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
- ActionBarUtils.sendBar(player, action.getMessage());
- }
-
- @Override
- public Entity[] getNearbyEntitiesArrays(Location loc, double radius) {
- return EntityUtils.getNearbyEntitiesArrays(loc, radius);
- }
-
- @Override
- public void sendSign(Player player, Sign sign) {
- if (!player.isOnline()) {
- throw new NullPointerException("错误: 玩家不在线!");
- }
- if (sign == null) {
- throw new NullPointerException("错误: Sign不能为Null!");
- }
- if (sign.isEmpty()) {
- throw new IllegalArgumentException("错误: Sign不能无内容!");
- }
- String[] lines = sign.getTexts();
- //获取Pl管理
- ProtocolManager pm = Core.getInstance().getProtocolManager();
-
- /*
- * private BlockPosition a; ---> 方块位置
- * public IBlockData block; ---> 方块数据
- */
- BlockPosition blockPosition = new BlockPosition(player.getLocation().toVector());
-
- PacketContainer blockChange = pm.createPacket(PacketType.Play.Server.BLOCK_CHANGE);
- blockChange.getBlockPositionModifier().write(0, blockPosition);
- blockChange.getBlockData().write(0, WrappedBlockData.createData(Material.SIGN_POST));
-
- try {
- pm.sendServerPacket(player, blockChange);
- } catch (InvocationTargetException ex) {
- ex.printStackTrace();
- }
-
- PacketContainer updateSign = pm.createPacket(PacketType.Play.Server.TILE_ENTITY_DATA);
- updateSign.getBlockPositionModifier().write(0, blockPosition);
- updateSign.getIntegers().write(0, 9);
- NbtCompound compound = NbtFactory.ofCompound("Sign");
- for (int i = 0; i < lines.length; i++) {
- compound.put("Text" + (i + 1), "{\"text\":\"" + lines[i] + "\"}");
- }
- updateSign.getNbtModifier().write(0, compound);
-
- try {
- pm.sendServerPacket(player, updateSign);
- } catch (InvocationTargetException ex) {
- ex.printStackTrace();
- }
-
- /*
- * 1.8以下为OPEN_SIGN_ENTITY
- * OpenSignEditor内部字段
- * private BlockPosition a; ---> 方块位置
- */
- PacketContainer open = pm.createPacket(PacketType.Play.Server.OPEN_SIGN_EDITOR);
- open.getBlockPositionModifier().write(0, blockPosition);
-
- try {
- pm.sendServerPacket(player, open);
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- return;
- }
- Core.map.put(player.getName(), blockPosition); //丢入缓冲区
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/BaiduAPIUtils.java b/src/main/java/cc/zoyn/core/util/BaiduAPIUtils.java
deleted file mode 100644
index 4c86fe9..0000000
--- a/src/main/java/cc/zoyn/core/util/BaiduAPIUtils.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package cc.zoyn.core.util;
-
-import java.io.BufferedReader;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-/**
- * Create By IDEA
- *
- * @author Zoyn
- * @since 2017-09-10
- */
-public class BaiduAPIUtils {
-
- /**
- * 获取IP的信息
- *
- * @param ip ip
- * @param apiKey 用户的apiKey
- * @return 一段JSON字符串
- */
- public static String getIPInformation(String ip, String apiKey) {
- BufferedReader reader = null;
- String result = null;
- StringBuffer sbf = new StringBuffer();
- StringBuilder http = new StringBuilder("http://apis.baidu.com/bdyunfenxi/intelligence/ip?ip=");
- http.append(ip);
-
- try {
- URL url = new URL(http.toString());
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- // 设置请求方法
- connection.setRequestMethod("GET");
- // 填入apikey
- connection.setRequestProperty("apikey", apiKey);
- connection.connect();
-
- InputStream is = connection.getInputStream();
- reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
- String strRead = null;
- while ((strRead = reader.readLine()) != null) {
- sbf.append(strRead);
- sbf.append("\r\n");
- }
- reader.close();
- result = sbf.toString();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return result;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/BasicUtils.java b/src/main/java/cc/zoyn/core/util/BasicUtils.java
deleted file mode 100644
index dcdccc3..0000000
--- a/src/main/java/cc/zoyn/core/util/BasicUtils.java
+++ /dev/null
@@ -1,191 +0,0 @@
-package cc.zoyn.core.util;
-
-import com.google.common.collect.Lists;
-import org.bukkit.Bukkit;
-import org.bukkit.World;
-import org.bukkit.entity.Player;
-
-import java.util.List;
-import java.util.UUID;
-
-/**
- * 基础 - 工具类
- *
- * @author Zoyn
- * @since 2016/12/26
- */
-public class BasicUtils {
-
- /**
- * 取服务器版本
- *
- * @return 服务器版本
- */
- public static String getServerVersion() {
- return Bukkit.getServer().getClass().getPackage().getName().substring(23);
- }
-
- /**
- * 给一个玩家发送json数据
- *
- * @param player 玩家
- * @param msg JSON数据
- */
- public static void sendJson(Player player, String msg) {
- String version = getServerVersion();
- try {
- Object icbc = NMSUtils
- .getNMSClass(version.equalsIgnoreCase("v1_8_R1") ? "ChatSerializer"
- : "IChatBaseComponent$ChatSerializer")
- .getMethod("a", new Class[]{String.class}).invoke(null, new Object[]{msg});
- Object ppoc = NMSUtils.getNMSClass("PacketPlayOutChat")
- .getConstructor(new Class[]{NMSUtils.getNMSClass("IChatBaseComponent"), Byte.TYPE})
- .newInstance(icbc, Byte.valueOf("1"));
- NMSUtils.sendPacket(player, ppoc);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- }
-
- /**
- * 转换Unicode
- *
- * @param ori 字符
- * @return 转换后的字符串
- */
- public static String convertUnicode(String ori) {
- int len = ori.length();
- StringBuffer outBuffer = new StringBuffer(len);
- int x = 0;
- while (true) {
- while (true) {
- while (x < len) {
- char aChar = ori.charAt(x++);
- if (aChar == 92) {
- aChar = ori.charAt(x++);
- if (aChar == 117) {
- int value = 0;
- for (int i = 0; i < 4; ++i) {
- aChar = ori.charAt(x++);
- switch (aChar) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- value = (value << 4) + aChar - 48;
- break;
- case ':':
- case ';':
- case '<':
- case '=':
- case '>':
- case '?':
- case '@':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- case '[':
- case '\\':
- case ']':
- case '^':
- case '_':
- case '`':
- default:
- throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- value = (value << 4) + 10 + aChar - 65;
- break;
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- value = (value << 4) + 10 + aChar - 97;
- }
- }
- outBuffer.append((char) value);
- } else {
- if (aChar == 116) {
- aChar = 9;
- } else if (aChar == 114) {
- aChar = 13;
- } else if (aChar == 110) {
- aChar = 10;
- } else if (aChar == 102) {
- aChar = 12;
- }
- outBuffer.append(aChar);
- }
- } else {
- outBuffer.append(aChar);
- }
- }
- return outBuffer.toString();
- }
- }
- }
-
- /**
- * 取服务器在线玩家
- *
- * @return 玩家集合
- */
- public static List getOnlinePlayers() {
- // 实例化两个List用于存放Player和World
- List players = Lists.newArrayList();
- List worlds = Lists.newArrayList();
- worlds.addAll(Bukkit.getWorlds());
- // 遍历所有的世界
- for (int i = 0; i < worlds.size(); i++) {
- // 如果第i个世界的玩家是空的则进行下一次循环
- if (worlds.get(i).getPlayers().isEmpty()) {
- continue;
- } else {
- // 不是空的则添加到players集合中
- players.addAll(worlds.get(i).getPlayers());
- }
- }
- return players;
- }
-
- /**
- * 将名字转换为UUID
- *
- * @param name 名字
- * @return 该名的UUID对象
- */
- public UUID translateNameToUUID(String name) {
- UUID uuid = null;
- uuid = Bukkit.getPlayer(name).getUniqueId();
- return uuid;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/BookUtils.java b/src/main/java/cc/zoyn/core/util/BookUtils.java
deleted file mode 100644
index a2b86a4..0000000
--- a/src/main/java/cc/zoyn/core/util/BookUtils.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package cc.zoyn.core.util;
-
-import cc.zoyn.core.dto.Book;
-import cc.zoyn.core.dto.Page;
-import cc.zoyn.core.util.ReflectionUtils.PackageType;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.BookMeta;
-
-import java.lang.reflect.Method;
-import java.util.List;
-
-/**
- * 书本 - 工具类
- *
- * @author Zoyn
- * @since 2017/?/?
- */
-public class BookUtils {
-
- private static boolean initialised = false;
- private static Method getHandle;
- private static Method openBook;
-
- static {
- try {
- getHandle = ReflectionUtils.getMethod("CraftPlayer", PackageType.CRAFTBUKKIT_ENTITY, "getHandle");
- openBook = ReflectionUtils.getMethod("EntityPlayer", PackageType.MINECRAFT_SERVER, "a",
- PackageType.MINECRAFT_SERVER.getClass("ItemStack"),
- PackageType.MINECRAFT_SERVER.getClass("EnumHand"));
- initialised = true;
- } catch (ReflectiveOperationException e) {
- e.printStackTrace();
- Bukkit.getServer().getLogger().warning("Cannot force open book!");
- initialised = false;
- }
- }
-
- public static boolean isInitialised() {
- return initialised;
- }
-
- /**
- * 打开一个虚拟的书
- *
- * @param item 书
- * @param player 玩家
- * @return 布尔值[true成功/false失败]
- */
- public static boolean openBook(Player player, Book book) {
- if (!initialised)
- return false;
- ItemStack held = player.getInventory().getItemInMainHand();
- ItemStack bookItem = book.getItem();
- try {
- player.getInventory().setItemInMainHand(bookItem);
- sendPacket(bookItem, player);
- } catch (ReflectiveOperationException e) {
- e.printStackTrace();
- initialised = false;
- }
- player.getInventory().setItemInMainHand(held);
- return initialised;
-
- }
-
- /**
- * 打开一个虚拟的书
- *
- * @param item 书
- * @param player 玩家
- * @return 布尔值[true成功/false失败]
- */
- public static boolean openBook(ItemStack item, Player player) {
- if (!initialised)
- return false;
- ItemStack held = player.getInventory().getItemInMainHand();
- try {
- player.getInventory().setItemInMainHand(item);
- sendPacket(item, player);
- } catch (ReflectiveOperationException e) {
- e.printStackTrace();
- initialised = false;
- }
- player.getInventory().setItemInMainHand(held);
- return initialised;
- }
-
- private static void sendPacket(ItemStack i, Player p) throws ReflectiveOperationException {
- Object entityplayer = getHandle.invoke(p);
- Class> enumHand = PackageType.MINECRAFT_SERVER.getClass("EnumHand");
- Object[] enumArray = enumHand.getEnumConstants();
- openBook.invoke(entityplayer, getItemStack(i), enumArray[0]);
- }
-
- public static Object getItemStack(ItemStack item) {
- try {
- Method asNMSCopy = ReflectionUtils.getMethod(PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftItemStack"),
- "asNMSCopy", ItemStack.class);
- return asNMSCopy.invoke(PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftItemStack"), item);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * 以JSON格式来设置书的页面
- *
- * @param metadata 书本的BookMeta
- * @param pages 每页的json集合
- */
- @SuppressWarnings("unchecked")
- public static void setPagesAsJson(BookMeta metadata, List pages) {
- List p;
- Object page;
- try {
- p = (List) ReflectionUtils
- .getField(PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftMetaBook"), true, "pages").get(metadata);
- for (String text : pages) {
- page = ReflectionUtils.invokeMethod(ReflectionUtils.PackageType.MINECRAFT_SERVER
- .getClass("IChatBaseComponent$ChatSerializer").newInstance(), "a", text);
- p.add(page);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- @SuppressWarnings("unchecked")
- public static void setPagesAsPage(BookMeta meta, List pagess) {
- List p;
- Object page;
- try {
- p = (List) ReflectionUtils
- .getField(PackageType.CRAFTBUKKIT_INVENTORY.getClass("CraftMetaBook"), true, "pages").get(meta);
- for (Page onePage : pagess) {
- page = ReflectionUtils.invokeMethod(ReflectionUtils.PackageType.MINECRAFT_SERVER
- .getClass("IChatBaseComponent$ChatSerializer").newInstance(), "a", onePage.toJsonString());
- p.add(page);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/cc/zoyn/core/util/BungeeCordUtils.java b/src/main/java/cc/zoyn/core/util/BungeeCordUtils.java
deleted file mode 100644
index 1f63bb1..0000000
--- a/src/main/java/cc/zoyn/core/util/BungeeCordUtils.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package cc.zoyn.core.util;
-
-import com.google.common.collect.Iterables;
-import cc.zoyn.core.Core;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.messaging.PluginMessageListener;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * BungeeCord - 工具类
- *
- * @author Zoyn
- */
-public class BungeeCordUtils implements PluginMessageListener {
-
- /**
- * 将玩家传送至某子服
- *
- * @param name 名字
- * @param serverName 服务器名
- */
- public static void playerConnectServer(String name, String serverName) {
- ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
- DataOutputStream dataOut = new DataOutputStream(byteOut);
- try {
- dataOut.writeUTF("Connect");
- dataOut.writeUTF(name);
- dataOut.writeUTF(serverName);
- } catch (IOException e) {
- System.out.println("错误: " + e.getMessage());
- }
- if (Bukkit.getOnlinePlayers() != null) {
- Player player = (Player) Iterables.getFirst(Bukkit.getOnlinePlayers(), null);
- player.sendPluginMessage(Core.getInstance(), "BungeeCord", byteOut.toByteArray());
- }
- }
-
- /**
- * 踢出一个玩家
- *
- * @param name 玩家名
- * @param message 信息
- */
- public static void kickPlayer(String name, String message) {
- ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
- DataOutputStream dataOut = new DataOutputStream(byteOut);
- try {
- dataOut.writeUTF("KickPlayer");
- dataOut.writeUTF(name);
- dataOut.writeUTF(message);
- } catch (IOException e) {
- System.out.println("错误: " + e.getMessage());
- }
- if (Bukkit.getOnlinePlayers() != null) {
- Player player = (Player) Iterables.getFirst(Bukkit.getOnlinePlayers(), null);
- player.sendPluginMessage(Core.getInstance(), "BungeeCord", byteOut.toByteArray());
- }
- }
-
- public static void sendData(String tag, String message) {
- ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
- DataOutputStream dataOut = new DataOutputStream(byteOut);
- try {
- dataOut.writeUTF(tag);
- dataOut.writeUTF(message);
- } catch (IOException e) {
- System.out.println("错误: " + e.getMessage());
- }
- if (Bukkit.getOnlinePlayers() != null) {
- Player player = (Player) Iterables.getFirst(Bukkit.getOnlinePlayers(), null);
- player.sendPluginMessage(Core.getInstance(), "BukkitCoreMessage", byteOut.toByteArray());
- }
- }
-
- @Override
- public void onPluginMessageReceived(String channel, Player player, byte[] message) {
- if (!channel.equals("BukkitCoreMessage")) {
- return;
- }
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/util/EffectUtils.java b/src/main/java/cc/zoyn/core/util/EffectUtils.java
deleted file mode 100644
index 4e8f535..0000000
--- a/src/main/java/cc/zoyn/core/util/EffectUtils.java
+++ /dev/null
@@ -1,194 +0,0 @@
-package cc.zoyn.core.util;
-
-import cc.zoyn.core.Core;
-import org.bukkit.Bukkit;
-import org.bukkit.Effect;
-import org.bukkit.Location;
-import org.bukkit.entity.ArmorStand;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.util.EulerAngle;
-import org.bukkit.util.Vector;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-public class EffectUtils {
-
- /**
- * 创建三维旋转特效
- *
- * @param player 玩家
- * @throws Exception
- */
- public void createHelix(Player player) throws Exception {
- Location loc = player.getLocation();
- int radius = 2;
- for (double y = 0; y <= 50; y += 0.05) {
- double x = radius * Math.cos(y);
- double z = radius * Math.sin(y);
- Object packet = NMSUtils.getNMSClass("PacketPlayOutWorldParticles").newInstance();
- packet = packet.getClass()
- .getConstructor(String.class, float.class, float.class, float.class, float.class, float.class,
- float.class, float.class, int.class)
- .newInstance("fireworksSpark", (float) (loc.getX() + x), (float) (loc.getY() + y),
- (float) (loc.getZ() + z), 0, 0, 0, 0, 1);
- for (Player online : Bukkit.getOnlinePlayers()) {
- Object nmsPlayer = online.getClass().getMethod("getHandle").invoke(online);
- Object playerConnection = nmsPlayer.getClass().getDeclaredField("playerConnection").get(nmsPlayer);
- playerConnection.getClass().getMethod("sendPacket", NMSUtils.getNMSClass("Packet"))
- .invoke(playerConnection, packet);
- }
- }
- }
-
- private static HashMap, Location> lastLoc = new HashMap, Location>();
-
- @SuppressWarnings("deprecation")
- public static void callCircle(final Player p, int id, double amount, final int time) {
- // 取玩家的坐标
- Location loc = p.getLocation();
- loc.setDirection(new Vector());
- loc.add(0.0D, -1.0D, 0.0D);
- // 之后将头向下
-
- // 建立一个存放ArmorStand的list
- final List list = new ArrayList();
- // 遍历要生成的个数
- for (int i = 0; i < amount; i++) {
- // 计算第i个ArmorStand的位置 公式为 ---> i除以全部数量乘以π再乘以2
- double rand = i / amount * 3.141592653589793D * 2.0D;
- double dx = Math.cos(rand);
- double dz = Math.sin(rand);
- ArmorStand as = (ArmorStand) loc.getWorld().spawn(loc.clone().add(dx, 0.0D, dz), ArmorStand.class);
- as.setVisible(false);
- as.setGravity(false);
- as.setHelmet(new ItemStack(id));
- as.setHeadPose(EulerAngle.ZERO.setY(rand));
- list.add(as);
- }
-
- // 添加到 第一次开始执行时的Map
- lastLoc.put(list, p.getLocation());
-
- // 异步操作
- Bukkit.getScheduler().runTaskTimer(Core.getInstance(), new Runnable() {
- // 线程死亡开关
- boolean dead;
- // 倒数
- int countDown = 0;
-
- public void run() {
- // 如果线程死亡开启则返回
- if (dead) {
- return;
- }
- // 判断玩家是否在线,并且是活着的
- if ((p.isOnline()) && (!p.isDead()) && (countDown < time)) {
- // 倒数器 自加1
- countDown += 1;
- // 取玩家
- Vector v = p.getLocation().subtract((Location) lastLoc.get(list)).toVector();
- for (ArmorStand as : list) {
- as.teleport(as.getLocation().add(v));
- double rand = 1 / amount * 3.141592653589793D * 2.0D;
- double dx = Math.cos(rand);
- double dz = Math.sin(rand);
- p.playEffect(lastLoc.get(list).clone().add(dx, 0.0D, dz), Effect.HAPPY_VILLAGER, 3);
- }
- lastLoc.put(list, p.getLocation());
- } else {
- for (ArmorStand as : list) {
- as.remove();
- }
- dead = true;
- }
- }
- }, 1L, 1L);
- }
-
- public static List buildCircle(Location center, int radius, float precision) {
- List ret = new ArrayList();
- for (float i = precision; i < 6.283185307179586D; i += precision) {
- ret.add(new Location(center.getWorld(), Math.cos(i) * radius + center.getX(), center.getY(),
- Math.sin(i) * radius + center.getZ()));
- }
- return ret;
- }
-
- public static List buildLine(Location loc1, Location loc2) {
- List line = new ArrayList();
- int dx = Math.max(loc1.getBlockX(), loc2.getBlockX()) - Math.min(loc1.getBlockX(), loc2.getBlockX());
- int dy = Math.max(loc1.getBlockY(), loc2.getBlockY()) - Math.min(loc1.getBlockY(), loc2.getBlockY());
- int dz = Math.max(loc1.getBlockZ(), loc2.getBlockZ()) - Math.min(loc1.getBlockZ(), loc2.getBlockZ());
- int x1 = loc1.getBlockX();
- int x2 = loc2.getBlockX();
- int y1 = loc1.getBlockY();
- int y2 = loc2.getBlockY();
- int z1 = loc1.getBlockZ();
- int z2 = loc2.getBlockZ();
- int x = 0;
- int y = 0;
- int z = 0;
- int i = 0;
- int d = 1;
- switch (findHighest(dx, dy, dz)) {
- case 1:
- i = 0;
- d = 1;
- if (x1 > x2) {
- d = -1;
- }
- x = loc1.getBlockX();
- do {
- i++;
- y = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
- z = z1 + (x - x1) * (z2 - z1) / (x2 - x1);
- line.add(new Location(loc1.getWorld(), x, y, z));
- x += d;
- } while (i <= Math.max(x1, x2) - Math.min(x1, x2));
- break;
- case 2:
- i = 0;
- d = 1;
- if (y1 > y2) {
- d = -1;
- }
- y = loc1.getBlockY();
- do {
- i++;
- x = x1 + (y - y1) * (x2 - x1) / (y2 - y1);
- z = z1 + (y - y1) * (z2 - z1) / (y2 - y1);
- line.add(new Location(loc1.getWorld(), x, y, z));
- y += d;
- } while (i <= Math.max(y1, y2) - Math.min(y1, y2));
- break;
- case 3:
- i = 0;
- d = 1;
- if (z1 > z2) {
- d = -1;
- }
- z = loc1.getBlockZ();
- do {
- i++;
- y = y1 + (z - z1) * (y2 - y1) / (z2 - z1);
- x = x1 + (z - z1) * (x2 - x1) / (z2 - z1);
- line.add(new Location(loc1.getWorld(), x, y, z));
- z += d;
- } while (i <= Math.max(z1, z2) - Math.min(z1, z2));
- }
- return line;
- }
-
- private static int findHighest(int x, int y, int z) {
- if ((x >= y) && (x >= z)) {
- return 1;
- }
- if ((y >= x) && (y >= z)) {
- return 2;
- }
- return 3;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/IsNullUtils.java b/src/main/java/cc/zoyn/core/util/IsNullUtils.java
deleted file mode 100644
index 9ad062a..0000000
--- a/src/main/java/cc/zoyn/core/util/IsNullUtils.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package cc.zoyn.core.util;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 空,非空判断工具
- *
- * @author Zoyn
- */
-public class IsNullUtils {
-
- private static boolean flag; //记录判断结果
-
- /**
- * 判断空
- * 举例
- * null:true
- * new Object():false
- * 0:true
- * List.size() = 0:true
- *
- * @param object 对象
- * @return true[是]/false[不是]
- */
- public static boolean isNull(Object object) {
- if (object == null) {
- return true;
- }
- return detect(object, true);
- }
-
- /**
- * 判断非空
- *
- * 举例
- * null:false
- * new Object():true
- * 0.0001:true
- * List.size() = 0:false
- *
- * @param object 对象
- * @return true[是]/false[不是]
- */
- public static boolean notNull(Object object) {
- if (object == null) {
- return false;
- }
- return detect(object, false);
- }
-
- private static boolean detect(Object object, boolean isDetectNull) {
- if (object instanceof Boolean) {
- return (boolean) object;
- } else if (object instanceof String) {
- if (((String) object).equals("")) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- } else if (object instanceof Integer) {
- if (((Integer) object) == 0) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- } else if (object instanceof Double) {
- if (((Double) object) == 0) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- } else if (object instanceof Float) {
- if (((Float) object) == 0) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- } else if (object instanceof List>) {
- if (((List>) object).size() < 1) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- } else if (object instanceof Map, ?>) {
- if (((Map, ?>) object).isEmpty()) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- } else if (object instanceof File) {
- if (((File) object).exists()) {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- } else {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- }
- } else if (object instanceof Object[]) {
- if (((Object[]) object).length < 1) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- } else {
- if (object == null) {
- if (isDetectNull)
- flag = true;
- else
- flag = false;
- } else {
- if (isDetectNull)
- flag = false;
- else
- flag = true;
- }
- }
- return flag;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/NBTUtils.java b/src/main/java/cc/zoyn/core/util/NBTUtils.java
deleted file mode 100644
index 6eae4ac..0000000
--- a/src/main/java/cc/zoyn/core/util/NBTUtils.java
+++ /dev/null
@@ -1,203 +0,0 @@
-package cc.zoyn.core.util;
-
-import cc.zoyn.core.dto.SlotTypeEnum;
-import org.bukkit.inventory.ItemStack;
-
-import java.lang.reflect.Method;
-
-public class NBTUtils {
-
- private static Method setTag;
- private static Method set;
-
- static {
- try {
- setTag = NMSUtils.getNMSClass("ItemStack").getMethod("setTag", NMSUtils.getNMSClass("NBTTagCompound"));
- set = NMSUtils.getNMSClass("NBTTagCompound").getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")});
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- // /**
- // * 各类属性
- // */
- // private static String attackDamage = "generic.attackDamage";
- // private static String attackSpeed = "generic.attackSpeed";
- // private static String maxHealth = "generic.maxHealth";
- // private static String moveMentSpeed = "generic.movementSpeed";
- // private static String armor = "generic.armor";
- // private static String luck = "generic.luck";
-
- public static Object nbtTagString(String str) {
- try {
- return NMSUtils.getNMSClass("NBTTagString").getConstructor(String.class).newInstance(str);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- public static Object nbtTagInt(int num) {
- try {
- return NMSUtils.getNMSClass("NBTTagInt").getConstructor(Integer.TYPE).newInstance(num);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- public static Object nbtTagDouble(double num) {
- try {
- return NMSUtils.getNMSClass("NBTTagDouble").getConstructor(Double.TYPE).newInstance(num);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- public static Object nbtTagByte(byte num) {
- try {
- return NMSUtils.getNMSClass("NBTTagByte").getConstructor(Byte.TYPE).newInstance(num);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- public static Object nbtTagFloat(float num) {
- try {
- return NMSUtils.getNMSClass("NBTTagFloat").getConstructor(Float.TYPE).newInstance(num);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- public static Object getItemNBT(ItemStack is) {
- Object nmsItem = NMSUtils.getNMSItem(is);
- if (nmsItem == null) {
- return null;
- }
- try {
- return nmsItem.getClass().getMethod("getTag").invoke(nmsItem) != null
- ? nmsItem.getClass().getMethod("getTag").invoke(nmsItem)
- : NMSUtils.getNMSClass("NBTTagCompound").newInstance();
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- public static void setUnbreakable(ItemStack is, boolean unbreak) {
- Object nmsItem = NMSUtils.getNMSItem(is);
- Object itemNbt = getItemNBT(is);
- try {
- //NPE检查
- if (set == null) {
- set = NMSUtils.getNMSClass("NBTTagCompound").getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")});
- }
- set.invoke(itemNbt, new Object[]{"Unbreakable", nbtTagByte((byte) (unbreak ? 1 : 0))});
-
- //NPE检查
- if (setTag == null) {
- setTag = NMSUtils.getNMSClass("ItemStack").getMethod("setTag", NMSUtils.getNMSClass("NBTTagCompound"));
- }
-
- setTag.invoke(nmsItem, itemNbt);
- NMSUtils.getOBCClass("inventory.CraftItemStack").getMethod("asBukkitCopy", NMSUtils.getNMSClass("ItemStack")).invoke(nmsItem, nmsItem);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * 取武器的Attribute数据
- *
- * @param is 物品
- * @return NBTTagCompound的实例
- */
- public static Object getAttribute(ItemStack is) {
- Object nmsItem = NMSUtils.getNMSItem(is);
- // 判断是否有无Tag数据
- try {
- if (nmsItem.getClass().getMethod("getTag").invoke(nmsItem) != null) {
- return nmsItem.getClass().getMethod("getTag").invoke(nmsItem);
- } else {
- // 如果没有Tag数据则实例化个NBTTagCompound的实例
- return NMSUtils.getNMSClass("NBTTagCompound").newInstance();
- }
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
-
- return null;
- }
-
- // public static ItemStack setUnbreakable(ItemStack is, boolean unbreak) {
- // Object nmsItem = NMSUtil.getNMSItem(is);
- // Object itemNbt = getItemNBT(is);
- // return null;
- // }
-
- /**
- * 设置物品伤害
- *
- * @param is 物品
- * @param damage 伤害
- * @param slot 位置
- * @return 物品的ItemStack
- */
- public static ItemStack setItemDamage(ItemStack is, int damage, SlotTypeEnum slot) {
- try {
- // 物品的nms对象
- Object nmsItem = is.getClass().getMethod("asNMSCopy", ItemStack.class).invoke(is, is);
- // 物品的nbt对象
- Object itemNbt = nmsItem.getClass().getMethod("getTag").invoke(nmsItem) != null
- ? nmsItem.getClass().getMethod("getTag").invoke(nmsItem)
- : NMSUtils.getNMSClass("NBTTagCompound").newInstance();
- // NbtTagList对象
- Object modifiers = NMSUtils.getNMSClass("NBTTagList").getConstructor().newInstance();
- Object damageTag = NMSUtils.getNMSClass("NBTTagCompound").getConstructor().newInstance();
- // 模块数据构造
- Object attackDamage = NMSUtils.getNMSClass("NBTTagString").getConstructor(String.class)
- .newInstance("generic.attackDamage");
- Object name = NMSUtils.getNMSClass("NBTTagString").getConstructor(String.class).newInstance("Damage");
- Object amount = NMSUtils.getNMSClass("NBTTagInt").getConstructor(Integer.TYPE).newInstance(damage);
- Object operation = NMSUtils.getNMSClass("NBTTagInt").getConstructor(Integer.TYPE).newInstance(0);
- Object uuidLeast = NMSUtils.getNMSClass("NBTTagInt").getConstructor(Integer.TYPE).newInstance(894654);
- Object uuidMost = NMSUtils.getNMSClass("NBTTagInt").getConstructor(Integer.TYPE).newInstance(2872);
- Object slotTag = NMSUtils.getNMSClass("NBTTagString").getConstructor(String.class)
- .newInstance(slot.toString());
- // 模块数据输入
- damageTag.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(damageTag, new Object[]{"AttributeName", attackDamage});
- damageTag.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(damageTag, new Object[]{"Name", name});
- damageTag.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(damageTag, new Object[]{"Amount", amount});
- damageTag.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(damageTag, new Object[]{"Operation", operation});
- damageTag.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(damageTag, new Object[]{"UUIDLeast", uuidLeast});
- damageTag.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(damageTag, new Object[]{"UUIDMost", uuidMost});
- damageTag.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(damageTag, new Object[]{"Slot", slotTag});
- // NbtTagList数据导入
- modifiers.getClass().getMethod("add", NMSUtils.getNMSClass("NBTBase")).invoke(modifiers, damageTag);
- // 设置该NbtTagList
- itemNbt.getClass().getMethod("set", new Class[]{String.class, NMSUtils.getNMSClass("NBTBase")})
- .invoke(itemNbt, new Object[]{"AttributeModifiers", modifiers});
- // 保存nbt数据
- nmsItem.getClass().getMethod("setTag", NMSUtils.getNMSClass("NBTTagCompound")).invoke(nmsItem, itemNbt);
- ItemStack bukItem = (ItemStack) is.getClass().getMethod("asBukkitCopy", NMSUtils.getNMSClass("ItemStack"))
- .invoke(nmsItem, nmsItem);
- return bukItem;
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return is;
- }
-
-}
diff --git a/src/main/java/cc/zoyn/core/util/NMSUtils.java b/src/main/java/cc/zoyn/core/util/NMSUtils.java
deleted file mode 100644
index a895566..0000000
--- a/src/main/java/cc/zoyn/core/util/NMSUtils.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package cc.zoyn.core.util;
-
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.ItemStack;
-
-/**
- * NMS工具类
- *
- * @author Zoyn
- * @since 2017/4/26
- */
-public class NMSUtils {
-
- private static Class> chatSerializer;
- private static Class> enumTitleAction;
- private static Class> packetPlayOutTitle;
- private static Class> packetPlayOutChat;
- private static String version;
-
- private NMSUtils() {
- }
-
- ;
-
- static {
- //org.bukkit.craftbukkit.vX_XX_RX;
- version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
- chatSerializer = version.contains("v1_8_R1") ? getNMSClass("ChatSerializer") : getNMSClass("IChatBaseComponent$ChatSerializer");
- enumTitleAction = version.contains("v1_8_R1") ? getNMSClass("EnumTitleAction") : getNMSClass("PacketPlayOutTitle$EnumTitleAction");
- packetPlayOutTitle = getNMSClass("PacketPlayOutTitle");
- packetPlayOutChat = getNMSClass("PacketPlayOutChat");
- }
-
- /**
- * 取PacketPlayOutTitle类
- *
- * @return {@link Class}
- */
- public static Class> getPacketPlayOutTitleClass() {
- return packetPlayOutTitle;
- }
-
- /**
- * 取PacketPlayOutChat类
- *
- * @return {@link Class}
- */
- public static Class> getPacketPlayOutChatClass() {
- return packetPlayOutChat;
- }
-
- /**
- * 取EnumTitleAction类
- *
- * @return {@link Class}
- */
- public static Class> getEnumTitleActionClass() {
- return enumTitleAction;
- }
-
- /**
- * 取chatSerializer类
- *
- * @return {@link Class}
- */
- public static Class> getChatSerializerClass() {
- return chatSerializer;
- }
-
- /**
- * 取服务器版本 如v1_10_R1
- *
- * @return 服务器版本
- */
- public static String getVersion() {
- return version;
- }
-
- public static Class> getOBCClass(String className) {
- try {
- return Class.forName("org.bukkit.craftbukkit." + NMSUtils.getVersion() + "." + className);
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- /**
- * 取物品的NMS对象
- *
- * @param is
- * @return {@link Object}
- */
- public static Object getNMSItem(ItemStack is) {
- try {
- return NMSUtils.getOBCClass("inventory.CraftItemStack").getMethod("asNMSCopy", ItemStack.class).invoke(is, is);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- /**
- * 取对应的NMS下的类
- *
- * @param className 类名
- * @return {@link Class}
- */
- public static Class> getNMSClass(String className) {
- try {
- return Class.forName("net.minecraft.server." + version + "." + className);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return null;
- }
-
- /**
- * 给一名玩家发送NMS数据包
- *
- * @param player 玩家
- * @param packet 数据包对象
- */
- public static void sendPacket(Player player, Object packet) {
- //取NMS实例
- Object entityPlayer = getNMSPlayer(player);
- try {
- //取其playerConnection实例
- Object playerConnection = entityPlayer.getClass().getField("playerConnection").get(entityPlayer);
- //调用方法sendPacket()
- playerConnection.getClass().getMethod("sendPacket", new Class[]{getNMSClass("Packet")}).invoke(playerConnection, packet);
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- }
-
- /**
- * 取玩家NMS对象也就是EntityPlayer类的实例
- *
- * @param player 玩家
- * @return 玩家的NMS对象
- */
- public static Object getNMSPlayer(Player player) {
- try {
- //取Player的实现类并调用其方法getHandle
- Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
- return entityPlayer;
- } catch (Exception e) {
- System.out.println("错误: " + e.getMessage());
- }
- return player;
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/NPCUtils.java b/src/main/java/cc/zoyn/core/util/NPCUtils.java
deleted file mode 100644
index 338be86..0000000
--- a/src/main/java/cc/zoyn/core/util/NPCUtils.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package cc.zoyn.core.util;
-
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolLibrary;
-import com.comphenix.protocol.ProtocolManager;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
-import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
-import com.comphenix.protocol.wrappers.PlayerInfoData;
-import com.comphenix.protocol.wrappers.WrappedChatComponent;
-import com.comphenix.protocol.wrappers.WrappedDataWatcher;
-import com.comphenix.protocol.wrappers.WrappedGameProfile;
-import com.google.common.collect.Lists;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
-import com.mojang.authlib.GameProfile;
-import com.mojang.authlib.properties.Property;
-import cc.zoyn.core.Core;
-import net.minecraft.server.v1_12_R1.*;
-import net.minecraft.server.v1_12_R1.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
-import org.bukkit.Bukkit;
-import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
-import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
-import org.bukkit.entity.Player;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.util.List;
-import java.util.UUID;
-
-public class NPCUtils {
-
- public static String[] getFromName(String name) {
- try {
- URL url_0 = new URL("https://api.mojang.com/users/profiles/minecraft/" + name);
- InputStreamReader reader_0 = new InputStreamReader(url_0.openStream());
- String uuid = new JsonParser().parse(reader_0).getAsJsonObject().get("id").getAsString();
-
- URL url_1 = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false");
- InputStreamReader reader_1 = new InputStreamReader(url_1.openStream());
- JsonObject textureProperty = new JsonParser().parse(reader_1).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
- String texture = textureProperty.get("value").getAsString();
- String signature = textureProperty.get("signature").getAsString();
-
- return new String[]{texture, signature};
- } catch (IOException e) {
- System.err.println("无法从服务器读取皮肤信息!");
- e.printStackTrace();
- return null;
- }
- }
-
-
- /**
- * 增加npc
- *
- * @param name NPC显示名
- * @param skinName 皮肤名
- * @param x 坐标X
- * @param y 坐标Y
- * @param z 坐标Z
- */
- public static void addNpc(String name, String skinName, double x, double y, double z) {
- String[] a = getFromName(skinName);
- MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
- GameProfile profile = new GameProfile(UUID.randomUUID(), name);
- profile.getProperties().put("textures", new Property("textures", a[0], a[1]));
- EntityPlayer npc = new EntityPlayer(server, server.getWorldServer(0), profile, new PlayerInteractManager(server.getWorldServer(0)));
- npc.setPosition(x, y, z);
- for (Player player : Bukkit.getOnlinePlayers()) {
- ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc));
- ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc));
- Bukkit.getScheduler().scheduleSyncDelayedTask(Core.getInstance(), new Runnable() {
- @Override
- public void run() {
- ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, npc));
- }
- }, 5);
- }
- }
-
- /**
- * 使用ProtocolLib制造NPC
- *
- * @param name NPC名
- * @param skinName 皮肤名
- * @param x 坐标X
- * @param y 坐标Y
- * @param z 坐标Z
- */
- public static void addNPCUsePL(String name, String skinName, double x, double y, double z) {
- //获取皮肤信息
- String[] skin = getFromName(skinName);
- //获取Server的nms对象
- MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer();
- //新建一个NPC的GameProfile
- GameProfile profile = new GameProfile(UUID.randomUUID(), name);
- //设置皮肤
- profile.getProperties().put("textures", new Property("textures", skin[0], skin[1]));
-
- //实例化NPC对象
- EntityPlayer npc = new EntityPlayer(server, server.getWorldServer(0), profile, new PlayerInteractManager(server.getWorldServer(0)));
- //设置坐标
- npc.setPosition(x, y, z);
-
- //获取PL管理工具
- ProtocolManager pm = ProtocolLibrary.getProtocolManager();
-
- PacketContainer packet = pm.createPacket(PacketType.Play.Server.PLAYER_INFO);
- /*
- * PlayerInfo
- * private EnumPlayerInfoAction a;
- * private final List b = Lists.newArrayList();
- */
- //依次写入相关数据
- packet.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
- List datas = Lists.newArrayList();
- datas.add(new PlayerInfoData(WrappedGameProfile.fromHandle(npc.getProfile()), npc.ping, NativeGameMode.CREATIVE, WrappedChatComponent.fromText(name)));
- packet.getPlayerInfoDataLists().write(0, datas);
-
- //已命名实体生成
- PacketContainer packet2 = pm.createPacket(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
- /*
- * NamedEntitySpawn
- * private int a;
- * private UUID b;
- * private double c;
- * private double d;
- * private double e;
- * private byte f;
- * private byte g;
- * private DataWatcher h;
- * private List> i;
- */
- packet2.getIntegers().write(0, npc.getId());
- packet2.getUUIDs().write(0, profile.getId());
- packet2.getDoubles().write(0, npc.locX);
- packet2.getDoubles().write(1, npc.locY);
- packet2.getDoubles().write(2, npc.locZ);
- packet2.getBytes().write(0, (byte) (int) (npc.yaw * 256.0F / 360.0F));
- packet2.getBytes().write(1, (byte) (int) (npc.pitch * 256.0F / 360.0F));
- packet2.getDataWatcherModifier().write(0, WrappedDataWatcher.getEntityWatcher(npc.getBukkitEntity()));
-
- PacketContainer packet3 = pm.createPacket(PacketType.Play.Server.PLAYER_INFO);
- packet3.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER);
- packet3.getPlayerInfoDataLists().write(0, datas);
-
- for (Player player : Bukkit.getOnlinePlayers()) {
- try {
- pm.sendServerPacket(player, packet);
- pm.sendServerPacket(player, packet2);
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- Bukkit.getScheduler().scheduleSyncDelayedTask(Core.getInstance(), new Runnable() {
- @Override
- public void run() {
- try {
- pm.sendServerPacket(player, packet3);
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
- }, 5);
- }
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/ReflectionUtils.java b/src/main/java/cc/zoyn/core/util/ReflectionUtils.java
deleted file mode 100644
index 58c9e3e..0000000
--- a/src/main/java/cc/zoyn/core/util/ReflectionUtils.java
+++ /dev/null
@@ -1,609 +0,0 @@
-package cc.zoyn.core.util;
-
-import org.bukkit.Bukkit;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * ReflectionUtils
- *
- * This class provides useful methods which makes dealing with reflection much easier, especially when working with Bukkit
- *
- * You are welcome to use it, modify it and redistribute it under the following conditions:
- *
- * Don't claim this class as your own
- * Don't remove this disclaimer
- *
- *
- * It would be nice if you provide credit to me if you use this class in a published project
- *
- * @author DarkBlade12
- * @version 1.1
- */
-public final class ReflectionUtils {
- // Prevent accidental construction
- private ReflectionUtils() {
- }
-
- /**
- * Returns the constructor of a given class with the given parameter types
- *
- * @param clazz Target class
- * @param parameterTypes Parameter types of the desired constructor
- * @return The constructor of the target class with the specified parameter types
- * @throws NoSuchMethodException If the desired constructor with the specified parameter types cannot be found
- * @see DataType
- * @see DataType#getPrimitive(Class[])
- * @see DataType#compare(Class[], Class[])
- */
- public static Constructor> getConstructor(Class> clazz, Class>... parameterTypes) throws NoSuchMethodException {
- Class>[] primitiveTypes = DataType.getPrimitive(parameterTypes);
- for (Constructor> constructor : clazz.getConstructors()) {
- if (!DataType.compare(DataType.getPrimitive(constructor.getParameterTypes()), primitiveTypes)) {
- continue;
- }
- return constructor;
- }
- throw new NoSuchMethodException("There is no such constructor in this class with the specified parameter types");
- }
-
- /**
- * 返回给予的参数的类的构造方法
- *
- * 原文: Returns the constructor of a desired class with the given parameter types
- *
- * @param className Name of the desired target class
- * @param packageType Package where the desired target class is located
- * @param parameterTypes Parameter types of the desired constructor
- * @return The constructor of the desired target class with the specified parameter types
- * @throws NoSuchMethodException If the desired constructor with the specified parameter types cannot be found
- * @throws ClassNotFoundException ClassNotFoundException If the desired target class with the specified name and package cannot be found
- * @see #getClass(String, PackageType)
- * @see #getConstructor(Class, Class...)
- */
- public static Constructor> getConstructor(String className, PackageType packageType, Class>... parameterTypes) throws NoSuchMethodException, ClassNotFoundException {
- return getConstructor(packageType.getClass(className), parameterTypes);
- }
-
- /**
- * Returns an instance of a class with the given arguments
- *
- * @param clazz Target class
- * @param arguments Arguments which are used to construct an object of the target class
- * @return The instance of the target class with the specified arguments
- * @throws InstantiationException If you cannot create an instance of the target class due to certain circumstances
- * @throws IllegalAccessException If the desired constructor cannot be accessed due to certain circumstances
- * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the constructor (this should not occur since it searches for a constructor with the types of the arguments)
- * @throws InvocationTargetException If the desired constructor cannot be invoked
- * @throws NoSuchMethodException If the desired constructor with the specified arguments cannot be found
- */
- public static Object instantiateObject(Class> clazz, Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
- return getConstructor(clazz, DataType.getPrimitive(arguments)).newInstance(arguments);
- }
-
- /**
- * Returns an instance of a desired class with the given arguments
- *
- * @param className Name of the desired target class
- * @param packageType Package where the desired target class is located
- * @param arguments Arguments which are used to construct an object of the desired target class
- * @return The instance of the desired target class with the specified arguments
- * @throws InstantiationException If you cannot create an instance of the desired target class due to certain circumstances
- * @throws IllegalAccessException If the desired constructor cannot be accessed due to certain circumstances
- * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the constructor (this should not occur since it searches for a constructor with the types of the arguments)
- * @throws InvocationTargetException If the desired constructor cannot be invoked
- * @throws NoSuchMethodException If the desired constructor with the specified arguments cannot be found
- * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found
- * @see #getClass(String, PackageType)
- * @see #instantiateObject(Class, Object...)
- */
- public static Object instantiateObject(String className, PackageType packageType, Object... arguments) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
- return instantiateObject(packageType.getClass(className), arguments);
- }
-
- /**
- * Returns a method of a class with the given parameter types
- *
- * @param clazz Target class
- * @param methodName Name of the desired method
- * @param parameterTypes Parameter types of the desired method
- * @return The method of the target class with the specified name and parameter types
- * @throws NoSuchMethodException If the desired method of the target class with the specified name and parameter types cannot be found
- * @see DataType#getPrimitive(Class[])
- * @see DataType#compare(Class[], Class[])
- */
- public static Method getMethod(Class> clazz, String methodName, Class>... parameterTypes) throws NoSuchMethodException {
- Class>[] primitiveTypes = DataType.getPrimitive(parameterTypes);
- for (Method method : clazz.getMethods()) {
- if (!method.getName().equals(methodName) || !DataType.compare(DataType.getPrimitive(method.getParameterTypes()), primitiveTypes)) {
- continue;
- }
- return method;
- }
- throw new NoSuchMethodException("There is no such method in this class with the specified name and parameter types");
- }
-
- /**
- * Returns a method of a desired class with the given parameter types
- *
- * @param className Name of the desired target class
- * @param packageType Package where the desired target class is located
- * @param methodName Name of the desired method
- * @param parameterTypes Parameter types of the desired method
- * @return The method of the desired target class with the specified name and parameter types
- * @throws NoSuchMethodException If the desired method of the desired target class with the specified name and parameter types cannot be found
- * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found
- * @see #getClass(String, PackageType)
- * @see #getMethod(Class, String, Class...)
- */
- public static Method getMethod(String className, PackageType packageType, String methodName, Class>... parameterTypes) throws NoSuchMethodException, ClassNotFoundException {
- return getMethod(packageType.getClass(className), methodName, parameterTypes);
- }
-
- /**
- * Invokes a method on an object with the given arguments
- *
- * @param instance Target object
- * @param methodName Name of the desired method
- * @param arguments Arguments which are used to invoke the desired method
- * @return The result of invoking the desired method on the target object
- * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances
- * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments)
- * @throws InvocationTargetException If the desired method cannot be invoked on the target object
- * @throws NoSuchMethodException If the desired method of the class of the target object with the specified name and arguments cannot be found
- * @see #getMethod(Class, String, Class...)
- * @see DataType#getPrimitive(Object[])
- */
- public static Object invokeMethod(Object instance, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
- return getMethod(instance.getClass(), methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments);
- }
-
- /**
- * Invokes a method of the target class on an object with the given arguments
- *
- * @param instance Target object
- * @param clazz Target class
- * @param methodName Name of the desired method
- * @param arguments Arguments which are used to invoke the desired method
- * @return The result of invoking the desired method on the target object
- * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances
- * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments)
- * @throws InvocationTargetException If the desired method cannot be invoked on the target object
- * @throws NoSuchMethodException If the desired method of the target class with the specified name and arguments cannot be found
- * @see #getMethod(Class, String, Class...)
- * @see DataType#getPrimitive(Object[])
- */
- public static Object invokeMethod(Object instance, Class> clazz, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
- return getMethod(clazz, methodName, DataType.getPrimitive(arguments)).invoke(instance, arguments);
- }
-
- /**
- * Invokes a method of a desired class on an object with the given arguments
- *
- * @param instance Target object
- * @param className Name of the desired target class
- * @param packageType Package where the desired target class is located
- * @param methodName Name of the desired method
- * @param arguments Arguments which are used to invoke the desired method
- * @return The result of invoking the desired method on the target object
- * @throws IllegalAccessException If the desired method cannot be accessed due to certain circumstances
- * @throws IllegalArgumentException If the types of the arguments do not match the parameter types of the method (this should not occur since it searches for a method with the types of the arguments)
- * @throws InvocationTargetException If the desired method cannot be invoked on the target object
- * @throws NoSuchMethodException If the desired method of the desired target class with the specified name and arguments cannot be found
- * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found
- * @see #getClass(String, PackageType)
- * @see #invokeMethod(Object, Class, String, Object...)
- */
- public static Object invokeMethod(Object instance, String className, PackageType packageType, String methodName, Object... arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException {
- return invokeMethod(instance, packageType.getClass(className), methodName, arguments);
- }
-
- /**
- * Returns a field of the target class with the given name
- *
- * @param clazz Target class
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @return The field of the target class with the specified name
- * @throws NoSuchFieldException If the desired field of the given class cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- */
- public static Field getField(Class> clazz, boolean declared, String fieldName) throws NoSuchFieldException, SecurityException {
- Field field = declared ? clazz.getDeclaredField(fieldName) : clazz.getField(fieldName);
- field.setAccessible(true);
- return field;
- }
-
- /**
- * Returns a field of a desired class with the given name
- *
- * @param className Name of the desired target class
- * @param packageType Package where the desired target class is located
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @return The field of the desired target class with the specified name
- * @throws NoSuchFieldException If the desired field of the desired class cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found
- * @see #getField(Class, boolean, String)
- */
- public static Field getField(String className, PackageType packageType, boolean declared, String fieldName) throws NoSuchFieldException, SecurityException, ClassNotFoundException {
- return getField(packageType.getClass(className), declared, fieldName);
- }
-
- /**
- * Returns the value of a field of the given class of an object
- *
- * @param instance Target object
- * @param clazz Target class
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @return The value of field of the target object
- * @throws IllegalArgumentException If the target object does not feature the desired field
- * @throws IllegalAccessException If the desired field cannot be accessed
- * @throws NoSuchFieldException If the desired field of the target class cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- * @see #getField(Class, boolean, String)
- */
- public static Object getValue(Object instance, Class> clazz, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
- return getField(clazz, declared, fieldName).get(instance);
- }
-
- /**
- * Returns the value of a field of a desired class of an object
- *
- * @param instance Target object
- * @param className Name of the desired target class
- * @param packageType Package where the desired target class is located
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @return The value of field of the target object
- * @throws IllegalArgumentException If the target object does not feature the desired field
- * @throws IllegalAccessException If the desired field cannot be accessed
- * @throws NoSuchFieldException If the desired field of the desired class cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found
- * @see #getValue(Object, Class, boolean, String)
- */
- public static Object getValue(Object instance, String className, PackageType packageType, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
- return getValue(instance, packageType.getClass(className), declared, fieldName);
- }
-
- /**
- * Returns the value of a field with the given name of an object
- *
- * @param instance Target object
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @return The value of field of the target object
- * @throws IllegalArgumentException If the target object does not feature the desired field (should not occur since it searches for a field with the given name in the class of the object)
- * @throws IllegalAccessException If the desired field cannot be accessed
- * @throws NoSuchFieldException If the desired field of the target object cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- * @see #getValue(Object, Class, boolean, String)
- */
- public static Object getValue(Object instance, boolean declared, String fieldName) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
- return getValue(instance, instance.getClass(), declared, fieldName);
- }
-
- /**
- * Sets the value of a field of the given class of an object
- *
- * @param instance Target object
- * @param clazz Target class
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @param value New value
- * @throws IllegalArgumentException If the type of the value does not match the type of the desired field
- * @throws IllegalAccessException If the desired field cannot be accessed
- * @throws NoSuchFieldException If the desired field of the target class cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- * @see #getField(Class, boolean, String)
- */
- public static void setValue(Object instance, Class> clazz, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
- getField(clazz, declared, fieldName).set(instance, value);
- }
-
- /**
- * Sets the value of a field of a desired class of an object
- *
- * @param instance Target object
- * @param className Name of the desired target class
- * @param packageType Package where the desired target class is located
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @param value New value
- * @throws IllegalArgumentException If the type of the value does not match the type of the desired field
- * @throws IllegalAccessException If the desired field cannot be accessed
- * @throws NoSuchFieldException If the desired field of the desired class cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- * @throws ClassNotFoundException If the desired target class with the specified name and package cannot be found
- * @see #setValue(Object, Class, boolean, String, Object)
- */
- public static void setValue(Object instance, String className, PackageType packageType, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
- setValue(instance, packageType.getClass(className), declared, fieldName, value);
- }
-
- /**
- * Sets the value of a field with the given name of an object
- *
- * @param instance Target object
- * @param declared Whether the desired field is declared or not
- * @param fieldName Name of the desired field
- * @param value New value
- * @throws IllegalArgumentException If the type of the value does not match the type of the desired field
- * @throws IllegalAccessException If the desired field cannot be accessed
- * @throws NoSuchFieldException If the desired field of the target object cannot be found
- * @throws SecurityException If the desired field cannot be made accessible
- * @see #setValue(Object, Class, boolean, String, Object)
- */
- public static void setValue(Object instance, boolean declared, String fieldName, Object value) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
- setValue(instance, instance.getClass(), declared, fieldName, value);
- }
-
- /**
- * Represents an enumeration of dynamic packages of NMS and CraftBukkit
- *
- * This class is part of the ReflectionUtils and follows the same usage conditions
- *
- * @author DarkBlade12
- * @since 1.0
- */
- public enum PackageType {
- MINECRAFT_SERVER("net.minecraft.server." + getServerVersion()),
- CRAFTBUKKIT("org.bukkit.craftbukkit." + getServerVersion()),
- CRAFTBUKKIT_BLOCK(CRAFTBUKKIT, "block"),
- CRAFTBUKKIT_CHUNKIO(CRAFTBUKKIT, "chunkio"),
- CRAFTBUKKIT_COMMAND(CRAFTBUKKIT, "command"),
- CRAFTBUKKIT_CONVERSATIONS(CRAFTBUKKIT, "conversations"),
- CRAFTBUKKIT_ENCHANTMENS(CRAFTBUKKIT, "enchantments"),
- CRAFTBUKKIT_ENTITY(CRAFTBUKKIT, "entity"),
- CRAFTBUKKIT_EVENT(CRAFTBUKKIT, "event"),
- CRAFTBUKKIT_GENERATOR(CRAFTBUKKIT, "generator"),
- CRAFTBUKKIT_HELP(CRAFTBUKKIT, "help"),
- CRAFTBUKKIT_INVENTORY(CRAFTBUKKIT, "inventory"),
- CRAFTBUKKIT_MAP(CRAFTBUKKIT, "map"),
- CRAFTBUKKIT_METADATA(CRAFTBUKKIT, "metadata"),
- CRAFTBUKKIT_POTION(CRAFTBUKKIT, "potion"),
- CRAFTBUKKIT_PROJECTILES(CRAFTBUKKIT, "projectiles"),
- CRAFTBUKKIT_SCHEDULER(CRAFTBUKKIT, "scheduler"),
- CRAFTBUKKIT_SCOREBOARD(CRAFTBUKKIT, "scoreboard"),
- CRAFTBUKKIT_UPDATER(CRAFTBUKKIT, "updater"),
- CRAFTBUKKIT_UTIL(CRAFTBUKKIT, "util");
-
- private final String path;
-
- /**
- * Construct a new package type
- *
- * @param path Path of the package
- */
- private PackageType(String path) {
- this.path = path;
- }
-
- /**
- * Construct a new package type
- *
- * @param parent Parent package of the package
- * @param path Path of the package
- */
- private PackageType(PackageType parent, String path) {
- this(parent + "." + path);
- }
-
- /**
- * Returns the path of this package type
- *
- * @return The path
- */
- public String getPath() {
- return path;
- }
-
- /**
- * Returns the class with the given name
- *
- * @param className Name of the desired class
- * @return The class with the specified name
- * @throws ClassNotFoundException If the desired class with the specified name and package cannot be found
- */
- public Class> getClass(String className) throws ClassNotFoundException {
- return Class.forName(this + "." + className);
- }
-
- // Override for convenience
- @Override
- public String toString() {
- return path;
- }
-
- /**
- * Returns the version of your server
- *
- * @return The server version
- */
- public static String getServerVersion() {
- return Bukkit.getServer().getClass().getPackage().getName().substring(23);
- }
- }
-
- /**
- * Represents an enumeration of Java data types with corresponding classes
- *
- * This class is part of the ReflectionUtils and follows the same usage conditions
- *
- * @author DarkBlade12
- * @since 1.0
- */
- public enum DataType {
- BYTE(byte.class, Byte.class),
- SHORT(short.class, Short.class),
- INTEGER(int.class, Integer.class),
- LONG(long.class, Long.class),
- CHARACTER(char.class, Character.class),
- FLOAT(float.class, Float.class),
- DOUBLE(double.class, Double.class),
- BOOLEAN(boolean.class, Boolean.class);
-
- private static final Map, DataType> CLASS_MAP = new HashMap, DataType>();
- private final Class> primitive;
- private final Class> reference;
-
- // Initialize map for quick class lookup
- static {
- for (DataType type : values()) {
- CLASS_MAP.put(type.primitive, type);
- CLASS_MAP.put(type.reference, type);
- }
- }
-
- /**
- * Construct a new data type
- *
- * @param primitive Primitive class of this data type
- * @param reference Reference class of this data type
- */
- private DataType(Class> primitive, Class> reference) {
- this.primitive = primitive;
- this.reference = reference;
- }
-
- /**
- * Returns the primitive class of this data type
- *
- * @return The primitive class
- */
- public Class> getPrimitive() {
- return primitive;
- }
-
- /**
- * Returns the reference class of this data type
- *
- * @return The reference class
- */
- public Class> getReference() {
- return reference;
- }
-
- /**
- * Returns the data type with the given primitive/reference class
- *
- * @param clazz Primitive/Reference class of the data type
- * @return The data type
- */
- public static DataType fromClass(Class> clazz) {
- return CLASS_MAP.get(clazz);
- }
-
- /**
- * Returns the primitive class of the data type with the given reference class
- *
- * @param clazz Reference class of the data type
- * @return The primitive class
- */
- public static Class> getPrimitive(Class> clazz) {
- DataType type = fromClass(clazz);
- return type == null ? clazz : type.getPrimitive();
- }
-
- /**
- * Returns the reference class of the data type with the given primitive class
- *
- * @param clazz Primitive class of the data type
- * @return The reference class
- */
- public static Class> getReference(Class> clazz) {
- DataType type = fromClass(clazz);
- return type == null ? clazz : type.getReference();
- }
-
- /**
- * Returns the primitive class array of the given class array
- *
- * @param classes Given class array
- * @return The primitive class array
- */
- public static Class>[] getPrimitive(Class>[] classes) {
- int length = classes == null ? 0 : classes.length;
- Class>[] types = new Class>[length];
- for (int index = 0; index < length; index++) {
- types[index] = getPrimitive(classes[index]);
- }
- return types;
- }
-
- /**
- * Returns the reference class array of the given class array
- *
- * @param classes Given class array
- * @return The reference class array
- */
- public static Class>[] getReference(Class>[] classes) {
- int length = classes == null ? 0 : classes.length;
- Class>[] types = new Class>[length];
- for (int index = 0; index < length; index++) {
- types[index] = getReference(classes[index]);
- }
- return types;
- }
-
- /**
- * Returns the primitive class array of the given object array
- *
- * @param object Given object array
- * @return The primitive class array
- */
- public static Class>[] getPrimitive(Object[] objects) {
- int length = objects == null ? 0 : objects.length;
- Class>[] types = new Class>[length];
- for (int index = 0; index < length; index++) {
- types[index] = getPrimitive(objects[index].getClass());
- }
- return types;
- }
-
- /**
- * Returns the reference class array of the given object array
- *
- * @param object Given object array
- * @return The reference class array
- */
- public static Class>[] getReference(Object[] objects) {
- int length = objects == null ? 0 : objects.length;
- Class>[] types = new Class>[length];
- for (int index = 0; index < length; index++) {
- types[index] = getReference(objects[index].getClass());
- }
- return types;
- }
-
- /**
- * Compares two class arrays on equivalence
- *
- * @param primary Primary class array
- * @param secondary Class array which is compared to the primary array
- * @return Whether these arrays are equal or not
- */
- public static boolean compare(Class>[] primary, Class>[] secondary) {
- if (primary == null || secondary == null || primary.length != secondary.length) {
- return false;
- }
- for (int index = 0; index < primary.length; index++) {
- Class> primaryClass = primary[index];
- Class> secondaryClass = secondary[index];
- if (primaryClass.equals(secondaryClass) || primaryClass.isAssignableFrom(secondaryClass)) {
- continue;
- }
- return false;
- }
- return true;
- }
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/SkinUtils.java b/src/main/java/cc/zoyn/core/util/SkinUtils.java
deleted file mode 100644
index 9f1def7..0000000
--- a/src/main/java/cc/zoyn/core/util/SkinUtils.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package cc.zoyn.core.util;
-
-import net.minecraft.server.v1_12_R1.EntityPlayer;
-import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
-import org.bukkit.entity.Player;
-
-public class SkinUtils {
-
- public static void changeSkin(Player player, String skinName) {
- Object nmsPlayer = NMSUtils.getNMSPlayer(player);
- try {
- Object gameProfile = nmsPlayer.getClass().getMethod("getProfile").invoke(null);
- CraftPlayer cp = (CraftPlayer) player;
- EntityPlayer ep = cp.getHandle();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
-
diff --git a/src/main/java/cc/zoyn/core/util/SubCommand.java b/src/main/java/cc/zoyn/core/util/SubCommand.java
deleted file mode 100644
index a549187..0000000
--- a/src/main/java/cc/zoyn/core/util/SubCommand.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package cc.zoyn.core.util;
-
-import org.bukkit.command.CommandSender;
-
-public interface SubCommand {
-
- boolean execute(CommandSender sender, String[] args);
-
-}
diff --git a/src/main/java/cc/zoyn/core/util/TabUtils.java b/src/main/java/cc/zoyn/core/util/TabUtils.java
deleted file mode 100644
index 290dc83..0000000
--- a/src/main/java/cc/zoyn/core/util/TabUtils.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package cc.zoyn.core.util;
-
-import cc.zoyn.core.Core;
-import com.comphenix.protocol.PacketType;
-import com.comphenix.protocol.ProtocolManager;
-import com.comphenix.protocol.events.PacketContainer;
-import com.comphenix.protocol.wrappers.WrappedChatComponent;
-import org.bukkit.ChatColor;
-import org.bukkit.entity.Player;
-
-import java.lang.reflect.InvocationTargetException;
-
-public class TabUtils {
-
- /**
- * 更改一个玩家的Tab列表
- *
- * @param player 玩家
- * @param head Tab顶部
- * @param foot Tab底部
- */
- public static void setTab(Player player, String head, String foot) {
- if (head == null) {
- head = "";
- }
- head = ChatColor.translateAlternateColorCodes('&', head);
- if (foot == null) {
- foot = "";
- }
- foot = ChatColor.translateAlternateColorCodes('&', foot);
- ProtocolManager pm = Core.getInstance().getProtocolManager();
- PacketContainer packet = pm.createPacket(PacketType.Play.Server.PLAYER_LIST_HEADER_FOOTER);
- packet.getChatComponents()
- .write(0, WrappedChatComponent.fromText(head))
- .write(1, WrappedChatComponent.fromText(foot))
- ;
- try {
- pm.sendServerPacket(player, packet);
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/src/main/java/cc/zoyn/core/util/TimeUtils.java b/src/main/java/cc/zoyn/core/util/TimeUtils.java
deleted file mode 100644
index cb4afa9..0000000
--- a/src/main/java/cc/zoyn/core/util/TimeUtils.java
+++ /dev/null
@@ -1,180 +0,0 @@
-package cc.zoyn.core.util;
-
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-
-public class TimeUtils {
-
- private static final int YEAR = 365 * 24 * 60 * 60;// 年
- private static final int MONTH = 30 * 24 * 60 * 60;// 月
- private static final int DAY = 24 * 60 * 60;// 天
- private static final int HOUR = 60 * 60;// 小时
- private static final int MINUTE = 60;// 分钟
- private static Calendar calendar = Calendar.getInstance();
-
-
- /**
- * 根据时间戳获取描述性时间,如3分钟前,1天前
- *
- * @param timestamp 时间戳 单位为毫秒
- * @return 时间字符串
- */
- public static String getDescriptionTimeFromTimestamp(long timestamp) {
- long currentTime = System.currentTimeMillis();
- long timeGap = (currentTime - timestamp) / 1000;// 与现在时间相差秒数
- String timeStr;
- if (timeGap > YEAR) {
- timeStr = timeGap / YEAR + "年前";
- } else if (timeGap > MONTH) {
- timeStr = timeGap / MONTH + "个月前";
- } else if (timeGap > DAY) {// 1天以上
- timeStr = timeGap / DAY + "天前";
- } else if (timeGap > HOUR) {// 1小时-24小时
- timeStr = timeGap / HOUR + "小时前";
- } else if (timeGap > MINUTE) {// 1分钟-59分钟
- timeStr = timeGap / MINUTE + "分钟前";
- } else {// 1秒钟-59秒钟
- timeStr = "刚刚";
- }
- return timeStr;
- }
-
- /**
- * Long型时间格式化
- *
- * @param time 时间
- * @param dateFormat 日期格式,如yyyy年MM月dd日 HH:mm:ss
- * @return 格式化后的日期字符串
- */
- public static String timeToFormatDate(Long time, String dateFormat) {
- SimpleDateFormat format = new SimpleDateFormat(dateFormat);
- return format.format(time);
- }
-
- /**
- * long型时间转中式日期
- *
- * @param time 时间
- * @return
- */
- public static String timeToDate(Long time) {
- SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
- return format.format(time);
- }
-
- /**
- * 得到当前的时间,时间格式yyyy-MM-dd
- *
- * @return
- */
- public static String getCurrentDate() {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- return sdf.format(new Date());
- }
-
- /**
- * 得到当前的时间,自定义时间格式
- * y 年 M 月 d 日 H 时 m 分 s 秒
- *
- * @param dateFormat 输出显示的时间格式
- * @return
- */
- public static String getCurrentDate(String dateFormat) {
- SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
- return sdf.format(new Date());
- }
-
- /**
- * 日期格式化,默认日期格式yyyy-MM-dd
- *
- * @param date
- * @return
- */
- public static String getFormatDate(Date date) {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- return sdf.format(date);
- }
-
- /**
- * 日期格式化,自定义输出日期格式
- *
- * @param date
- * @return
- */
- public static String getFormatDate(Date date, String dateFormat) {
- SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
- return sdf.format(date);
- }
-
- /**
- * 返回当前日期的前一个时间日期,amount为正数 当前时间后的时间 为负数 当前时间前的时间
- * 默认日期格式yyyy-MM-dd
- *
- * @param field 日历字段
- * y 年 M 月 d 日 H 时 m 分 s 秒
- * @param amount 数量
- * @return 一个日期
- */
- public static String getPreDate(String field, int amount) {
- calendar.setTime(new Date());
- if (field != null && !field.equals("")) {
- if (field.equals("y")) {
- calendar.add(Calendar.YEAR, amount);
- } else if (field.equals("M")) {
- calendar.add(Calendar.MONTH, amount);
- } else if (field.equals("d")) {
- calendar.add(Calendar.DAY_OF_MONTH, amount);
- } else if (field.equals("H")) {
- calendar.add(Calendar.HOUR, amount);
- }
- } else {
- return null;
- }
- return getFormatDate(calendar.getTime());
- }
-
- /**
- * 某一个日期的前一个日期
- *
- * @param date,某一个日期
- * @param field 日历字段
- * y 年 M 月 d 日 H 时 m 分 s 秒
- * @param amount 数量
- * @return 一个日期
- */
- public static String getPreDate(Date date, String field, int amount) {
- calendar.setTime(date);
- if (field != null && !field.equals("")) {
- if (field.equals("y")) {
- calendar.add(Calendar.YEAR, amount);
- } else if (field.equals("M")) {
- calendar.add(Calendar.MONTH, amount);
- } else if (field.equals("d")) {
- calendar.add(Calendar.DAY_OF_MONTH, amount);
- } else if (field.equals("H")) {
- calendar.add(Calendar.HOUR, amount);
- }
- } else {
- return null;
- }
- return getFormatDate(calendar.getTime());
- }
-
- /**
- * 某一个时间的前一个时间
- *
- * @param date
- * @return
- * @throws ParseException
- */
- public static String getPreDate(String date) throws ParseException {
- Date d = new SimpleDateFormat().parse(date);
- String preD = getPreDate(d, "d", 1);
- Date preDate = new SimpleDateFormat().parse(preD);
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- return sdf.format(preDate);
- }
-}
-
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
deleted file mode 100644
index 8636d7f..0000000
--- a/src/main/resources/config.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-Tab:
- Head: "&r &6&l&m一&f&l&m一一一一一一&8 [ &6梦江湖 &8] &f&l&m一一一一一一&6&l&m一\n"
- Foot: "\n&6游戏版本 &a1.12"
-Title:
- FadeIn: 5
- Stay: 20
- FadeOut: 5
- Title: "&a梦江湖"
- SubTitle: null
-BossBar: "&6&o&l90%原创,详情 /Core List"
-ChatRadius: 35.0
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
deleted file mode 100644
index 901c9c5..0000000
--- a/src/main/resources/plugin.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-name: MayCore
-main: Core
-version: 1.0
-author: Zoyn
-prefix: 核心
-depend: [ProtocolLib]
-commands:
- core:
\ No newline at end of file
diff --git a/tellraw/pom.xml b/tellraw/pom.xml
new file mode 100644
index 0000000..1888a81
--- /dev/null
+++ b/tellraw/pom.xml
@@ -0,0 +1,22 @@
+
+
+
+ May-Common-Library
+ cc.zoyn.core
+ 1.0.0
+
+ 4.0.0
+ tellraw
+
+
+
+ cc.zoyn.core
+ common
+ ${project.parent.version}
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/tellraw/src/main/java/cc/zoyn/core/tellraw/ItemSerializer.java b/tellraw/src/main/java/cc/zoyn/core/tellraw/ItemSerializer.java
new file mode 100644
index 0000000..083dbd0
--- /dev/null
+++ b/tellraw/src/main/java/cc/zoyn/core/tellraw/ItemSerializer.java
@@ -0,0 +1,63 @@
+package cc.zoyn.core.tellraw;
+
+import cc.zoyn.core.util.NMSUtils;
+import cc.zoyn.core.util.nbt.NBTUtils;
+import cc.zoyn.core.util.reflect.ReflectionUtils;
+import org.bukkit.inventory.ItemStack;
+
+import java.lang.reflect.Method;
+
+public class ItemSerializer {
+
+ private static Method SAVE_NBT;
+ private static Method MOJANGSON_TO_NBT;
+
+ static {
+ try {
+ SAVE_NBT = ReflectionUtils.getMethod(NMSUtils.getNMSClass("ItemStack"), "save", NMSUtils.getNMSClass("NBTTagCompound"));
+ MOJANGSON_TO_NBT = ReflectionUtils.getMethod(NMSUtils.getNMSClass("MojangsonParser"), "parse", String.class);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Create the item mojangson data
+ *
+ * @param itemStack the item
+ * @return {@link String}
+ */
+ public static String getItemStackJson(ItemStack itemStack) {
+ Object nmsItem = NMSUtils.getNMSItem(itemStack);
+ Object savedTag = null;
+ try {
+ savedTag = ReflectionUtils.invokeMethod(SAVE_NBT, nmsItem, NBTUtils.newNBTTagCompound());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (savedTag != null) {
+ return savedTag.toString();
+ } else {
+ return "null";
+ }
+ }
+
+ /**
+ * Load a item by using mojangson data
+ *
+ * @param mojangson the mojangson data
+ * @return {@link ItemStack}
+ */
+ public static ItemStack loadItemStackJson(String mojangson) {
+ ItemStack itemStack = null;
+ try {
+ Object nbtTag = ReflectionUtils.invokeMethod(MOJANGSON_TO_NBT, null, mojangson);
+ Object nmsItem = NBTUtils.newNMSItemStack(nbtTag);
+ itemStack = (ItemStack) NMSUtils.getBukkitItem(nmsItem);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return itemStack;
+ }
+
+}
diff --git a/tellraw/src/main/java/cc/zoyn/core/tellraw/JsonImpl.java b/tellraw/src/main/java/cc/zoyn/core/tellraw/JsonImpl.java
new file mode 100644
index 0000000..a068db5
--- /dev/null
+++ b/tellraw/src/main/java/cc/zoyn/core/tellraw/JsonImpl.java
@@ -0,0 +1,80 @@
+package cc.zoyn.core.tellraw;
+
+import cc.zoyn.core.util.JsonBuilderUtils;
+
+public class JsonImpl {
+
+ private final static String TEXT_FORMAT = "\"text\":\"%s\"";
+ private final static String CLICK_FORMAT = "\"clickEvent\":{\"action\":\"%s\",\"value\":\"%s\"}";
+ private final static String HOVER_FORMAT = "\"hoverEvent\":{\"action\":\"%s\",\"value\":\"%s\"}";
+ private final static String INSERT_FORMAT = " \"insertion\":\"%s\"";
+ /**
+ * 消息文本
+ */
+ public String text;
+ /**
+ * 点击操作
+ */
+ public String clickActionName;
+ /**
+ * 点击数据
+ */
+ public String clickActionData;
+ /**
+ * 悬浮操作
+ */
+ public String hoverActionName;
+ /**
+ * 悬浮数据
+ */
+ public String hoverActionData;
+ /**
+ * 插入数据
+ */
+ public String insertionData;
+
+ @Override
+ public String toString() {
+ return "JsonImpl [text=" + text + ", clickActionName=" + clickActionName + ", clickActionData="
+ + clickActionData + ", hoverActionName=" + hoverActionName + ", hoverActionData=" + hoverActionData
+ + ", insertionData=" + insertionData + "]";
+ }
+
+ public JsonImpl() {
+ this("");
+ }
+
+ public JsonImpl(String text) {
+ this.text = text;
+ }
+
+ /**
+ * @return 是否有文本
+ */
+ public boolean hasText() {
+ return text != null && !text.isEmpty();
+ }
+
+ /**
+ * 写入Json
+ *
+ * @param str 流对象
+ */
+ public void writeJson(StringBuilder str) {
+ str.append("{");
+ str.append(String.format(TEXT_FORMAT, new JsonBuilderUtils(text)));
+ if (clickActionName != null) {
+ str.append(",");
+ str.append(String.format(CLICK_FORMAT, clickActionName, new JsonBuilderUtils(clickActionData)));
+ }
+ if (hoverActionName != null) {
+ str.append(",");
+ str.append(String.format(HOVER_FORMAT, hoverActionName, new JsonBuilderUtils(hoverActionData)));
+ }
+ if (insertionData != null) {
+ str.append(",");
+ str.append(String.format(INSERT_FORMAT, new JsonBuilderUtils(insertionData)));
+ }
+ str.append("}");
+ }
+}
diff --git a/src/main/java/cc/zoyn/core/dto/Tellraw.java b/tellraw/src/main/java/cc/zoyn/core/tellraw/Tellraw.java
similarity index 64%
rename from src/main/java/cc/zoyn/core/dto/Tellraw.java
rename to tellraw/src/main/java/cc/zoyn/core/tellraw/Tellraw.java
index c976d3c..b170075 100644
--- a/src/main/java/cc/zoyn/core/dto/Tellraw.java
+++ b/tellraw/src/main/java/cc/zoyn/core/tellraw/Tellraw.java
@@ -1,11 +1,13 @@
-package cc.zoyn.core.dto;
+package cc.zoyn.core.tellraw;
import com.google.common.collect.Lists;
-import cc.zoyn.core.minecraft.JsonImpl;
+import com.google.common.collect.Maps;
+import org.bukkit.Bukkit;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -35,6 +37,65 @@ public Tellraw(Map map) {
this.jsonParts = (List) map.get("jsonParts");
}
+ /**
+ * 当玩家光标悬停在tellraw上时,它将向玩家显示成就或统计数据
+ *
+ * When the player cursor hover the tellraw, it will show a achievement or statistic to player
+ *
+ * The key can be found at here
+ * https://minecraft.gamepedia.com/Achievements#List_of_achievements
+ * https://minecraft.gamepedia.com/Statistics#List_of_general_statistics
+ *
+ *
+ * @param value the id of achievement or statistic
+ * @return {@link Tellraw}
+ */
+ public Tellraw showAchievement(String value) {
+ onHover("show_achievement", value);
+ return this;
+ }
+
+ /**
+ * 当玩家光标悬停在tellraw上时,它将向玩家显示实体信息
+ *
+ * When the player cursor hover the tellraw, it will show a entity information to player
+ *
+ * @param name the name
+ * @param entityType the entity type
+ * @param id the id
+ * @return {@link Tellraw}
+ */
+ public Tellraw showEntity(String name, String entityType, String id) {
+ onHover("show_entity", "{\"id\":\"" + id + "\", \"name\":\"" + name + "\", \"type\":\"" + entityType + "\"}");
+ return this;
+ }
+
+ /**
+ * 当玩家光标悬停在tellraw上时,它会向玩家显示一个物品
+ *
+ * When the player cursor hover the tellraw, it will show a item to player
+ *
+ * @param itemStack the item
+ * @return {@link Tellraw}
+ */
+ public Tellraw showItem(ItemStack itemStack) {
+ onHover("show_item", ItemSerializer.getItemStackJson(itemStack));
+ return this;
+ }
+
+ /**
+ * 当玩家点击tellraw时,它会打开一个url并提示玩家
+ *
+ * When the player click the tellraw, it will open a url and tips player
+ *
+ * @param url the url
+ * @return {@link Tellraw}
+ */
+ public Tellraw openUrl(String url) {
+ onClick("open_url", url);
+ return this;
+ }
+
/**
* 补全命令[点击后将会自动出现在聊天栏]
*
@@ -158,15 +219,9 @@ public Tellraw addHover(String... texts) {
* @return {@link Tellraw}
*/
public Tellraw addAnotherTellraw(String text) {
- return addAnotherTellraw(new JsonImpl(String.format(text)));
+ return addAnotherTellraw(new JsonImpl(text));
}
- /**
- * 结束上一串消息 开始下一串数据[使用一个JsonImpl的实例]
- *
- * @param part 下一段内容
- * @return {@link Tellraw}
- */
private Tellraw addAnotherTellraw(JsonImpl part) {
JsonImpl last = latest();
if (!last.hasText()) {
@@ -177,6 +232,15 @@ private Tellraw addAnotherTellraw(JsonImpl part) {
return this;
}
+ /**
+ * 给指定玩家发送Tellraw
+ *
+ * @param player 给定的玩家
+ */
+ public void send(Player player) {
+ Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + toJsonString());
+ }
+
/**
* 转换成Json串
*
@@ -195,7 +259,7 @@ public String toJsonString() {
@Override
public Map serialize() {
- Map map = new HashMap();
+ Map map = Maps.newHashMap();
map.put("jsonParts", this.jsonParts);
return map;
}
diff --git a/tellraw/src/main/java/cc/zoyn/core/tellraw/package-info.java b/tellraw/src/main/java/cc/zoyn/core/tellraw/package-info.java
new file mode 100644
index 0000000..5ea5f2b
--- /dev/null
+++ b/tellraw/src/main/java/cc/zoyn/core/tellraw/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Wrapper tellraw operation
+ *
+ * @author Zoyn
+ * @since 2017-12-09
+ */
+package cc.zoyn.core.tellraw;
\ No newline at end of file