版本更新至:3.76

调整:开发框架改为 Gradle
新增:Language2 工具新增 [book] 类型
This commit is contained in:
坏黑
2018-03-10 21:13:05 +08:00
parent 6439e4b780
commit ad1a21196f
238 changed files with 1686 additions and 1132 deletions

View File

@@ -0,0 +1,325 @@
package me.skymc.taboolib;
import java.io.File;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import lombok.Getter;
import lombok.Setter;
import me.skymc.taboolib.anvil.AnvilContainerAPI;
import me.skymc.taboolib.bstats.Metrics;
import me.skymc.taboolib.client.LogClient;
import me.skymc.taboolib.commands.MainCommands;
import me.skymc.taboolib.commands.language.Language2Command;
import me.skymc.taboolib.commands.sub.itemlist.listener.ItemLibraryPatch;
import me.skymc.taboolib.database.PlayerDataManager;
import me.skymc.taboolib.database.GlobalDataManager;
import me.skymc.taboolib.economy.EcoUtils;
import me.skymc.taboolib.entity.EntityUtils;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.inventory.speciaitem.SpecialItem;
import me.skymc.taboolib.javashell.JavaShell;
import me.skymc.taboolib.listener.ListenerNetWork;
import me.skymc.taboolib.listener.ListenerPlayerCommand;
import me.skymc.taboolib.listener.ListenerPlayerQuit;
import me.skymc.taboolib.listener.ListenerPlayerJump;
import me.skymc.taboolib.listener.ListenerPluginDisable;
import me.skymc.taboolib.message.ChatCatcher;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.mysql.protect.MySQLConnection;
import me.skymc.taboolib.sign.SignUtils;
import me.skymc.taboolib.skript.SkriptHandler;
import me.skymc.taboolib.string.StringUtils;
import me.skymc.taboolib.string.language2.Language2;
import me.skymc.taboolib.support.SupportPlaceholder;
import me.skymc.taboolib.team.TagUtils;
import me.skymc.taboolib.timecycle.TimeCycleManager;
import me.skymc.taboolib.update.UpdateTask;
import me.skymc.tlm.TLM;
import me.skymc.tlm.command.TLMCommands;
import me.skymc.tlm.module.TabooLibraryModule;
import me.skymc.taboolib.nms.item.DabItemUtils;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.permission.PermissionUtils;
import me.skymc.taboolib.playerdata.DataUtils;
import net.milkbowl.vault.economy.Economy;
@SuppressWarnings("deprecation")
public class Main extends JavaPlugin implements Listener {
@Getter
private static Plugin inst;
@Getter
private static String prefix = "§8[§3§lTabooLib§8] §7";
@Getter
@Setter
private static Economy Economy;
@Getter
private static File playerDataFolder;
@Getter
private static File serverDataFolder;
@Getter
private static File docsFolder;
@Getter
private static StorageType storageType;
@Getter
private static boolean disable = false;
@Getter
private static MySQLConnection connection = null;
@Getter
private FileConfiguration config = null;
@Getter
private static LogClient client;
@Getter
private static Language2 exampleLangauge2;
@Getter
private static boolean started;
public static Random getRandom() {
return NumberUtils.getRand();
}
public static String getTablePrefix() {
return inst.getConfig().getString("MYSQL.PREFIX");
}
@Override
public void saveDefaultConfig() {
reloadConfig();
}
@Override
public void reloadConfig() {
File file = new File(getDataFolder(), "config.yml");
if (!file.exists()) {
saveResource("config.yml", true);
}
config = ConfigUtils.load(this, file);
}
@Override
public void onLoad() {
inst = this; disable = false;
// 启动监控
new Metrics(this);
// 载入配置
saveDefaultConfig();
// 载入目录
setupDataFolder();
// 注册配置
DataUtils.addPluginData("TabooLibrary", null);
// 启用数据库
if (getConfig().getBoolean("MYSQL.ENABLE")) {
// 连接数据库
connection = new MySQLConnection(getConfig().getString("MYSQL.HOST"), getConfig().getString("MYSQL.USER"), getConfig().getString("MYSQL.POST"), getConfig().getString("MYSQL.PASSWORD"), getConfig().getString("MYSQL.DATABASE"), 30, this);
// 连接成功
if (connection.isConnection()) {
// 创建表
connection.createTable(getTablePrefix() + "_playerdata", "username", "configuration");
connection.createTable(getTablePrefix() + "_plugindata", "name", "variable", "upgrade");
connection.createTable(getTablePrefix() + "_serveruuid", "uuid", "hash");
// 如果没有数据
if (!connection.isExists(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID())) {
connection.intoValue(getTablePrefix() + "_serveruuid", TabooLib.getServerUID(), StringUtils.hashKeyForDisk(getDataFolder().getPath()));
}
else {
String hash = connection.getValue(getTablePrefix() + "_serveruuid", "uuid", TabooLib.getServerUID(), "hash").toString();
// 如果这个值和我的值不同
if (!hash.equals(StringUtils.hashKeyForDisk(getDataFolder().getPath()))) {
MsgUtils.warn("检测到本服序列号与其他服务器相同, 已重新生成!");
// 重新生成序列号
TabooLib.resetServerUID();
// 关服
Bukkit.shutdown();
}
}
}
else {
// 提示
MsgUtils.warn("数据库连接失败, 请检查配置是否正确!");
// 关服
Bukkit.shutdown();
}
// 储存方式
storageType = StorageType.SQL;
}
else {
// 储存方式
storageType = StorageType.LOCAL;
}
}
@Override
public void onEnable() {
// 注册指令
getCommand("taboolib").setExecutor(new MainCommands());
getCommand("language2").setExecutor(new Language2Command());
getCommand("taboolibrarymodule").setExecutor(new TLMCommands());
// 注册监听
registerListener();
// 载入经济
EcoUtils.setupEconomy();
// 载入权限
PermissionUtils.loadRegisteredServiceProvider();
// 物品名称
ItemUtils.LoadLib();
// 低层工具
DabItemUtils.getInstance();
// 载入周期管理器
TimeCycleManager.load();
// 启动脚本
JavaShell.javaShellSetup();
// 载入语言文件
exampleLangauge2 = new Language2("Language2", this);
// 注册脚本
SkriptHandler.getInst();
// 启动数据库储存方法
if (getStorageType() == StorageType.SQL) {
GlobalDataManager.SQLMethod.startSQLMethod();
}
// 载入完成
MsgUtils.send("§7插件载入完成!");
MsgUtils.send("§7插件版本: §f" + getDescription().getVersion());
MsgUtils.send("§7插件作者: §f" + getDescription().getAuthors());
MsgUtils.send("§7游戏版本: §f" + TabooLib.getVerint());
// 文件保存
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> DataUtils.saveAllCaches(), 20, 20 * 120);
Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> PlayerDataManager.saveAllCaches(true, false), 20, 20 * 60);
// 插件联动
new BukkitRunnable() {
@Override
public void run() {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new SupportPlaceholder(getInst(), "taboolib").hook();
}
// 载入 SpecialItem 接口
SpecialItem.getInst().loadItems();
// 载入 TLM 接口
TLM.getInst();
}
}.runTask(this);
// 更新检测
new UpdateTask();
// 启动
started = true;
}
@Override
public void onDisable() {
disable = true;
// 如果插件尚未启动完成
if (!started) {
MsgUtils.send("&c插件尚未启动完成, 已跳过卸载代码");
MsgUtils.send("&c插件作者: &4坏黑");
return;
}
// 保存数据
Bukkit.getOnlinePlayers().forEach(x -> DataUtils.saveOnline(x.getName()));
// 结束线程
Bukkit.getScheduler().cancelTasks(this);
// 保存插件数据
DataUtils.saveAllCaches();
// 保存玩家数据
PlayerDataManager.saveAllPlayers(false, true);
// 结束脚本
JavaShell.javaShellCancel();
// 注销 SpecialItem 接口
SpecialItem.getInst().unloadItems();
// 注销 TLM 接口
TabooLibraryModule.getInst().unloadModules();
// 结束数据库储存方法
if (getStorageType() == StorageType.SQL) {
GlobalDataManager.SQLMethod.cancelSQLMethod();
}
// 清理数据
if (getStorageType() == StorageType.LOCAL && getConfig().getBoolean("DELETE-DATA")) {
getPlayerDataFolder().delete();
}
// 清理数据
if (getStorageType() == StorageType.SQL && getConfig().getBoolean("DELETE-VARIABLE")) {
GlobalDataManager.clearInvalidVariables();
}
// 提示信息
MsgUtils.send("&c插件已卸载, 感谢您使用&4禁忌书库");
MsgUtils.send("&c插件作者: &4坏黑");
// 清理头衔
TagUtils.delete();
// 结束连接
if (connection != null && connection.isConnection()) {
connection.closeConnection();
}
// 关闭服务器
Bukkit.shutdown();
}
private void setupDataFolder() {
playerDataFolder = new File(getConfig().getString("DATAURL.PLAYER-DATA"));
if (!playerDataFolder.exists()) {
playerDataFolder.mkdirs();
}
serverDataFolder = new File(getConfig().getString("DATAURL.SERVER-DATA"));
if (!serverDataFolder.exists()) {
serverDataFolder.mkdirs();
}
docsFolder = new File(getDataFolder(), "Document");
if (!docsFolder.exists()) {
docsFolder.mkdirs();
}
}
private void registerListener() {
getServer().getPluginManager().registerEvents(this, this);
getServer().getPluginManager().registerEvents(new ListenerPlayerCommand(), this);
getServer().getPluginManager().registerEvents(new ListenerPlayerJump(), this);
getServer().getPluginManager().registerEvents(new ListenerPlayerQuit(), this);
getServer().getPluginManager().registerEvents(new ChatCatcher(), this);
getServer().getPluginManager().registerEvents(new DataUtils(), this);
getServer().getPluginManager().registerEvents(new AnvilContainerAPI(), this);
getServer().getPluginManager().registerEvents(new ListenerPluginDisable(), this);
getServer().getPluginManager().registerEvents(new PlayerDataManager(), this);
getServer().getPluginManager().registerEvents(new ItemLibraryPatch(), this);
if (TabooLib.getVerint() > 10700) {
getServer().getPluginManager().registerEvents(new EntityUtils(), this);
getServer().getPluginManager().registerEvents(new SignUtils(), this);
}
// 如果 YUM 插件存在
if (Bukkit.getPluginManager().getPlugin("YUM") != null) {
getServer().getPluginManager().registerEvents(new ListenerNetWork(), this);
}
}
public static enum StorageType {
LOCAL, SQL;
}
}

View File

@@ -0,0 +1,100 @@
package me.skymc.taboolib;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import me.skymc.taboolib.playerdata.DataUtils;
import net.md_5.bungee.api.ChatColor;
public class TabooLib {
/**
* 获取插件版本
*
* @return
*/
public static double getPluginVersion() {
try {
return Double.valueOf(Main.getInst().getDescription().getVersion());
}
catch (Exception e) {
return 0D;
}
}
/**
* 获取 NMS 版本
*
* @return
*/
public static String getVersion() {
return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
}
/**
* 获取服务器 UID
*
* @return
*/
public static String getServerUID() {
if (!DataUtils.getPluginData("TabooLibrary", null).contains("serverUID")) {
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
}
return DataUtils.getPluginData("TabooLibrary", null).getString("serverUID");
}
/**
* 重置服务器 UID
*/
public static void resetServerUID() {
DataUtils.getPluginData("TabooLibrary", null).set("serverUID", UUID.randomUUID().toString());
}
/**
* 向后台发送 DEBUG 信息
*
* @param plugin
* @param ss
*/
public static void debug(Plugin plugin, String... ss) {
if (Main.getInst().getConfig().getBoolean("DEBUG")) {
for (String s : ss) {
// [00:42:41 INFO]: [TabooLib - DEBUG][TabooPlugin] Example bug message
Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[TabooLib - DEBUG][" + plugin.getName() + "] " + ChatColor.RED + s);
}
}
}
/**
* 获取 NMS 版本(数字)
*
* @return
*/
public static int getVerint() {
if (getVersion().startsWith("v1_7")) {
return 10700;
}
else if (getVersion().startsWith("v1_8")) {
return 10800;
}
else if (getVersion().startsWith("v1_9")) {
return 10900;
}
else if (getVersion().startsWith("v1_10")) {
return 11000;
}
else if (getVersion().startsWith("v1_11")) {
return 11100;
}
else if (getVersion().startsWith("v1_12")) {
return 11200;
}
else if (getVersion().startsWith("v1_13")) {
return 11300;
}
return 0;
}
}

View File

@@ -0,0 +1,125 @@
package me.skymc.taboolib.anvil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import me.skymc.taboolib.anvil.versions.AnvilContainer_V1_9_4;
import me.skymc.taboolib.methods.MethodsUtils;
public class AnvilContainerAPI implements Listener{
public static List<String> list = new ArrayList<>();
public static ItemStack item = new ItemStack(Material.NAME_TAG);
public static HashMap<String, String> isOpen = new HashMap<>();
public static AnvilContainerAPIEvent event;
public static void send(Player p, String type, String str, List<String> lorelist)
{
isOpen.put(p.getName(), type);
AnvilContainer_V1_9_4.openAnvil(p);
ItemMeta meta = item.getItemMeta();
list.clear();
if (lorelist == null)
{
list.add("");
list.add("§7在上方文本框内输入信息");
list.add("§7随后点击右侧输出物品");
}
else
{
list = lorelist;
}
meta.setLore(list);
meta.setDisplayName(str);
item.setItemMeta(meta);
p.getOpenInventory().setItem(0, item);
p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1, 1);
}
@EventHandler
public void close(InventoryCloseEvent e)
{
if (isOpen.containsKey(e.getPlayer().getName()))
{
isOpen.remove(e.getPlayer().getName());
if (e.getInventory().getType() == InventoryType.ANVIL)
{
e.getInventory().clear();
}
}
}
@EventHandler
public void click(InventoryClickEvent e)
{
if (!isOpen.containsKey(e.getWhoClicked().getName()))
{
return;
}
if (e.getInventory().getType() != InventoryType.ANVIL)
{
return;
}
e.setCancelled(true);
int slot = e.getRawSlot();
if (slot != 2)
{
return;
}
Inventory inv = e.getInventory();
if (inv.getItem(2) == null)
{
return;
}
if (inv.getItem(2).getItemMeta().hasDisplayName())
{
event = new AnvilContainerAPIEvent(e, isOpen.get(e.getWhoClicked().getName()), inv.getItem(2).getItemMeta().getDisplayName());
e.getWhoClicked().closeInventory();
Bukkit.getPluginManager().callEvent(event);
}
}
@EventHandler
public void example(PlayerCommandPreprocessEvent e)
{
if (e.getMessage().equals("/anvilexample"))
{
if (e.getPlayer().hasPermission("taboolib.admin"))
{
e.setCancelled(true);
AnvilContainerAPI.send(e.getPlayer(), "EXAMPLE", "在这里输入文本", null);
}
}
}
@EventHandler
public void example2(AnvilContainerAPIEvent e)
{
if (e.type.equals("EXAMPLE"))
{
e.event.getWhoClicked().sendMessage(e.string);
}
}
}

View File

@@ -0,0 +1,31 @@
package me.skymc.taboolib.anvil;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.inventory.InventoryClickEvent;
public class AnvilContainerAPIEvent extends Event{
public static final HandlerList handlers = new HandlerList();
public InventoryClickEvent event;
public String string;
public String type;
public AnvilContainerAPIEvent(InventoryClickEvent e, String t, String s)
{
event = e;
string = s;
type = t;
}
@Override
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@@ -0,0 +1,40 @@
package me.skymc.taboolib.anvil.versions;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import me.skymc.taboolib.methods.MethodsUtils;
import net.minecraft.server.v1_11_R1.BlockPosition;
import net.minecraft.server.v1_11_R1.ChatMessage;
import net.minecraft.server.v1_11_R1.ContainerAnvil;
import net.minecraft.server.v1_11_R1.EntityHuman;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.PacketPlayOutOpenWindow;
public class AnvilContainer_V1_11_R1 extends ContainerAnvil {
public AnvilContainer_V1_11_R1(EntityHuman player)
{
super(player.inventory, player.world, new BlockPosition(0, 0, 0), player);
}
public boolean a(EntityHuman player)
{
return true;
}
/**
* @deprecated 方法已过期,已有新的方法
*/
public static void openAnvil(Player p)
{
EntityPlayer player = ((CraftPlayer)p).getHandle();
AnvilContainer_V1_11_R1 container = new AnvilContainer_V1_11_R1(player);
int c = player.nextContainerCounter();
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(c, "minecraft:anvil", new ChatMessage("Repairing", new Object[0]), 0));
player.activeContainer = container;
player.activeContainer.windowId = c;
player.activeContainer.addSlotListener(player);
}
}

View File

@@ -0,0 +1,40 @@
package me.skymc.taboolib.anvil.versions;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import me.skymc.taboolib.methods.MethodsUtils;
import net.minecraft.server.v1_8_R3.BlockPosition;
import net.minecraft.server.v1_8_R3.ChatMessage;
import net.minecraft.server.v1_8_R3.ContainerAnvil;
import net.minecraft.server.v1_8_R3.EntityHuman;
import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.PacketPlayOutOpenWindow;
public class AnvilContainer_V1_8_R3 extends ContainerAnvil {
public AnvilContainer_V1_8_R3(EntityHuman player)
{
super(player.inventory, player.world, new BlockPosition(0, 0, 0), player);
}
public boolean a(EntityHuman player)
{
return true;
}
/**
* @deprecated 方法已过期,已有新的方法
*/
public static void openAnvil(Player p)
{
EntityPlayer player = ((CraftPlayer)p).getHandle();
AnvilContainer_V1_8_R3 container = new AnvilContainer_V1_8_R3(player);
int c = player.nextContainerCounter();
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(c, "minecraft:anvil", new ChatMessage("Repairing", new Object[0]), 0));
player.activeContainer = container;
player.activeContainer.windowId = c;
player.activeContainer.addSlotListener(player);
}
}

View File

@@ -0,0 +1,40 @@
package me.skymc.taboolib.anvil.versions;
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
import me.skymc.taboolib.methods.MethodsUtils;
import net.minecraft.server.v1_9_R2.BlockPosition;
import net.minecraft.server.v1_9_R2.ChatMessage;
import net.minecraft.server.v1_9_R2.ContainerAnvil;
import net.minecraft.server.v1_9_R2.EntityHuman;
import net.minecraft.server.v1_9_R2.EntityPlayer;
import net.minecraft.server.v1_9_R2.PacketPlayOutOpenWindow;
public class AnvilContainer_V1_9_4 extends ContainerAnvil {
public AnvilContainer_V1_9_4(EntityHuman player)
{
super(player.inventory, player.world, new BlockPosition(0, 0, 0), player);
}
public boolean a(EntityHuman player)
{
return true;
}
/**
* @deprecated 方法已过期,已有新的方法
*/
public static void openAnvil(Player p)
{
EntityPlayer player = ((CraftPlayer)p).getHandle();
AnvilContainer_V1_9_4 container = new AnvilContainer_V1_9_4(player);
int c = player.nextContainerCounter();
player.playerConnection.sendPacket(new PacketPlayOutOpenWindow(c, "minecraft:anvil", new ChatMessage("Repairing", new Object[0]), 0));
player.activeContainer = container;
player.activeContainer.windowId = c;
player.activeContainer.addSlotListener(player);
}
}

View File

@@ -0,0 +1,62 @@
package me.skymc.taboolib.bookformatter;
import org.bukkit.Achievement;
import java.util.HashMap;
import static org.bukkit.Achievement.*;
public final class BookAchievement {
private static final HashMap<Achievement, String> achievements = new HashMap<>();
static {
achievements.put(OPEN_INVENTORY, "openInventory");
achievements.put(MINE_WOOD, "mineWood");
achievements.put(BUILD_WORKBENCH, "buildWorkBench");
achievements.put(BUILD_PICKAXE, "buildPickaxe");
achievements.put(BUILD_FURNACE, "buildFurnace");
achievements.put(ACQUIRE_IRON, "aquireIron");
achievements.put(BUILD_HOE, "buildHoe");
achievements.put(MAKE_BREAD, "makeBread");
achievements.put(BAKE_CAKE,"bakeCake");
achievements.put(BUILD_BETTER_PICKAXE,"buildBetterPickaxe");
achievements.put(COOK_FISH,"cookFish");
achievements.put(ON_A_RAIL,"onARail");
achievements.put(BUILD_SWORD,"buildSword");
achievements.put(KILL_ENEMY,"killEnemy");
achievements.put(KILL_COW,"killCow");
achievements.put(FLY_PIG,"flyPig");
achievements.put(SNIPE_SKELETON,"snipeSkeleton");
achievements.put(GET_DIAMONDS,"diamonds");
achievements.put(NETHER_PORTAL,"portal");
achievements.put(GHAST_RETURN,"ghast");
achievements.put(GET_BLAZE_ROD,"blazerod");
achievements.put(BREW_POTION,"potion");
achievements.put(END_PORTAL,"thEnd");
achievements.put(THE_END,"theEnd2");
achievements.put(ENCHANTMENTS,"enchantments");
achievements.put(OVERKILL,"overkill");
achievements.put(BOOKCASE,"bookacase");
achievements.put(EXPLORE_ALL_BIOMES,"exploreAllBiomes");
achievements.put(SPAWN_WITHER,"spawnWither");
achievements.put(KILL_WITHER,"killWither");
achievements.put(FULL_BEACON,"fullBeacon");
achievements.put(BREED_COW,"breedCow");
achievements.put(DIAMONDS_TO_YOU,"diamondsToYou");
achievements.put(OVERPOWERED, "overpowered");
}
/**
* Gets the json id from the bukkit achievement passed as argument
* @param achievement the achievement
* @return the achievement's id or null if not found
*/
public static String toId(Achievement achievement) {
return achievements.get(achievement);
}
private BookAchievement(){
}
}

View File

@@ -0,0 +1,75 @@
package me.skymc.taboolib.bookformatter;
import me.skymc.taboolib.bookformatter.builder.BookBuilder;
import me.skymc.taboolib.events.CustomBookOpenEvent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@SuppressWarnings("deprecation")
public final class BookFormatter {
/**
* Opens a book GUI to the player
* @param p the player
* @param book the book to be opened
*/
public static void openPlayer(Player p, ItemStack book) {
CustomBookOpenEvent event = new CustomBookOpenEvent(p, book, false);
//Call the CustomBookOpenEvent
Bukkit.getPluginManager().callEvent(event);
//Check if it's cancelled
if(event.isCancelled()) {
return;
}
//Close inventory currently
p.closeInventory();
//Store the previous item
ItemStack hand = p.getItemInHand();
p.setItemInHand(event.getBook());
//Opening the GUI
BookReflection.openBook(p, event.getBook(), event.getHand() == CustomBookOpenEvent.Hand.OFF_HAND);
//Returning whatever was on hand.
p.setItemInHand(hand);
}
/**
* Opens a book GUI to the player, Bypass the {@link CustomBookOpenEvent}
* @param p the player
* @param book the book to be opened
*/
public static void forceOpen(Player p, ItemStack book) {
//Close inventory currently
p.closeInventory();
//Store the previous item
ItemStack hand = p.getItemInHand();
p.setItemInHand(book);
//Opening the GUI
BookReflection.openBook(p, book, false);
//Returning whatever was on hand.
p.setItemInHand(hand);
}
/**
* Creates a BookBuilder instance with a written book as the Itemstack's type
* @return
*/
public static BookBuilder writtenBook() {
return new BookBuilder(new ItemStack(Material.WRITTEN_BOOK));
}
/**
* Creates a BookBuilder instance with a written book as the Itemstack's type
* @return
*/
public static BookBuilder writtenBook(String title, String author) {
return new BookBuilder(new ItemStack(Material.WRITTEN_BOOK), title, author);
}
}

View File

@@ -0,0 +1,297 @@
package me.skymc.taboolib.bookformatter;
import lombok.Getter;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* The NMS helper for all the Book-API
*/
public final class BookReflection {
private static final String version;
private static final boolean doubleHands;
private static final Class<?> craftMetaBookClass;
private static final Field craftMetaBookField;
private static final Method chatSerializerA;
private static final Method craftPlayerGetHandle;
//This method takes an enum that represents the player's hand only in versions >= 1.9
//In the other versions it only takes the nms item
private static final Method entityPlayerOpenBook;
//only version >= 1.9
private static final Object[] hands;
//Older versions
/*private static final Field entityHumanPlayerConnection;
private static final Method playerConnectionSendPacket;
private static final Constructor<?> packetPlayOutCustomPayloadConstructor;
private static final Constructor<?> packetDataSerializerConstructor;*/
private static final Method nmsItemStackSave;
private static final Constructor<?> nbtTagCompoundConstructor;
private static final Method craftItemStackAsNMSCopy;
static {
version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
final int major, minor;
Pattern pattern = Pattern.compile("v([0-9]+)_([0-9]+)");
Matcher m = pattern.matcher(version);
if(m.find()) {
major = Integer.parseInt(m.group(1));
minor = Integer.parseInt(m.group(2));
} else {
throw new IllegalStateException("Cannot parse version \"" + version + "\", make sure it follows \"v<major>_<minor>...\"");
}
doubleHands = major <= 1 && minor >= 9;
try {
craftMetaBookClass = getCraftClass("inventory.CraftMetaBook");
craftMetaBookField = craftMetaBookClass.getDeclaredField("pages");
craftMetaBookField.setAccessible(true);
Class<?> chatSerializer = getNmsClass("IChatBaseComponent$ChatSerializer", false);
if(chatSerializer == null)
chatSerializer = getNmsClass("ChatSerializer");
chatSerializerA = chatSerializer.getDeclaredMethod("a", String.class);
final Class<?> craftPlayerClass = getCraftClass("entity.CraftPlayer");
craftPlayerGetHandle = craftPlayerClass.getMethod("getHandle");
final Class<?> entityPlayerClass = getNmsClass("EntityPlayer");
final Class<?> itemStackClass = getNmsClass("ItemStack");
if(doubleHands) {
final Class<?> enumHandClass = getNmsClass("EnumHand");
entityPlayerOpenBook = entityPlayerClass.getMethod("a", itemStackClass, enumHandClass);
hands = enumHandClass.getEnumConstants();
} else {
entityPlayerOpenBook = entityPlayerClass.getMethod("openBook", itemStackClass);
hands = null;
}
//Older versions
/*entityHumanPlayerConnection = entityPlayerClass.getField("playerConnection");
final Class<?> playerConnectionClass = getNmsClass("PlayerConnection");
playerConnectionSendPacket = playerConnectionClass.getMethod("sendPacket", getNmsClass("Packet"));
final Class<?> packetDataSerializerClasss = getNmsClass("PacketDataSerializer");
packetPlayOutCustomPayloadConstructor = getNmsClass("PacketPlayOutCustomPayload").getConstructor(String.class, packetDataSerializerClasss);
packetDataSerializerConstructor = packetDataSerializerClasss.getConstructor(ByteBuf.class);*/
final Class<?> craftItemStackClass = getCraftClass("inventory.CraftItemStack");
craftItemStackAsNMSCopy = craftItemStackClass.getMethod("asNMSCopy", ItemStack.class);
Class<?> nmsItemStackClazz = getNmsClass("ItemStack");
Class<?> nbtTagCompoundClazz = getNmsClass("NBTTagCompound");
nmsItemStackSave = nmsItemStackClazz.getMethod("save", nbtTagCompoundClazz);
nbtTagCompoundConstructor = nbtTagCompoundClazz.getConstructor();
} catch (Exception e) {
throw new IllegalStateException("Cannot initiate reflections for " + version, e);
}
}
/**
* Sets the pages of the book to the components json equivalent
* @param meta the book meta to change
* @param components the pages of the book
*/
@SuppressWarnings("unchecked")//reflections = unchecked warnings
public static void setPages(BookMeta meta, BaseComponent[][] components) {
try {
List<Object> pages = (List<Object>) craftMetaBookField.get(meta);
pages.clear();
for(BaseComponent[] c : components) {
final String json = ComponentSerializer.toString(c);
//System.out.println("page:" + json); //Debug
pages.add(chatSerializerA.invoke(null, json));
}
} catch (Exception e) {
throw new UnsupportedVersionException(e);
}
}
/**
* Append the pages of the book to the components json equivalent
* @param meta the book meta to change
* @param components the pages of the book
*/
@SuppressWarnings("unchecked")//reflections = unchecked warnings
public static void addPages(BookMeta meta, BaseComponent[][] components) {
try {
List<Object> pages = (List<Object>) craftMetaBookField.get(meta);
for(BaseComponent[] c : components) {
final String json = ComponentSerializer.toString(c);
//System.out.println("page:" + json); //Debug
pages.add(chatSerializerA.invoke(null, json));
}
} catch (Exception e) {
throw new UnsupportedVersionException(e);
}
}
/**
* Opens the book to a player (the player needs to have the book in one of his hands)
* @param player the player
* @param book the book to open
* @param offHand false if the book is in the right hand, true otherwise
*/
public static void openBook(Player player, ItemStack book, boolean offHand) {
//nms(player).openBook(nms(player), nms(book), hand);
try {
//Older versions:
/*playerConnectionSendPacket.invoke(
entityHumanPlayerConnection.get(toNms(player)),
createBookOpenPacket()
);*/
if(doubleHands) {
entityPlayerOpenBook.invoke(
toNms(player),
nmsCopy(book),
hands[offHand ? 1 : 0]
);
} else {
entityPlayerOpenBook.invoke(
toNms(player),
nmsCopy(book)
);
}
} catch (Exception e) {
throw new UnsupportedVersionException(e);
}
}
//Older versions
/*public static Object createBookOpenPacket() {
//new PacketPlayOutCustomPayload("MC|BOpen", new PacketDataSerializer(Unpooled.buffer())));
try {
return packetPlayOutCustomPayloadConstructor.newInstance(
"MC|BOpen",
packetDataSerializerConstructor.newInstance(Unpooled.buffer())
);
} catch (Exception e) {
throw new UnsupportedVersionException(e);
}
}*/
/**
* Translates an ItemStack to his Chat-Component equivalent
* @param item the item to be converted
* @return a Chat-Component equivalent of the parameter
*/
public static BaseComponent[] itemToComponents(ItemStack item) {
return jsonToComponents(itemToJson(item));
}
/**
* Translates a json string to his Chat-Component equivalent
* @param json the json string to be converted
* @return a Chat-Component equivalent of the parameter
*/
public static BaseComponent[] jsonToComponents(String json) {
return new BaseComponent[] { new TextComponent(json) };
}
/**
* Translates an ItemStack to his json equivalent
* @param item the item to be converted
* @return a json equivalent of the parameter
*/
private static String itemToJson(ItemStack item) {
try {
//net.minecraft.server.ItemStack nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
Object nmsItemStack = nmsCopy(item);
//net.minecraft.server.NBTTagCompound compound = new NBTTagCompound();
//compound = nmsItemStack.save(compound);
Object emptyTag = nbtTagCompoundConstructor.newInstance();
Object json = nmsItemStackSave.invoke(nmsItemStack, emptyTag);
return json.toString();
} catch (Exception e) {
throw new UnsupportedVersionException(e);
}
}
/**
* An error thrown when this NMS-helper class doesn't support the running MC version
*/
public static class UnsupportedVersionException extends RuntimeException {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 6835583513394319946L;
/**
* The current running version
*/
@Getter
private final String version = BookReflection.version;
public UnsupportedVersionException(Exception e) {
super("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")", e);
}
}
/**
* Gets the EntityPlayer handled by the argument
* @param player the Player handler
* @return the handled class
* @throws InvocationTargetException when some problems are found with the reflection
* @throws IllegalAccessException when some problems are found with the reflection
*/
public static Object toNms(Player player) throws InvocationTargetException, IllegalAccessException {
return craftPlayerGetHandle.invoke(player);
}
/**
* Creates a NMS copy of the parameter
* @param item the ItemStack to be nms-copied
* @return a NMS-ItemStack that is the equivalent of the one passed as argument
* @throws InvocationTargetException when some problems are found with the reflection
* @throws IllegalAccessException when some problems are found with the reflection
*/
public static Object nmsCopy(ItemStack item) throws InvocationTargetException, IllegalAccessException {
return craftItemStackAsNMSCopy.invoke(null, item);
}
public static Class<?> getNmsClass(String className, boolean log) {
try {
return Class.forName("net.minecraft.server." + version + "." + className);
} catch(ClassNotFoundException e) {
if(log)
e.printStackTrace();
return null;
}
}
public static Class<?> getNmsClass(String className) {
return getNmsClass(className, true);
}
private static Class<?> getCraftClass(String path) {
try {
return Class.forName("org.bukkit.craftbukkit." + version + "." + path);
} catch(ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -0,0 +1,73 @@
package me.skymc.taboolib.bookformatter.action;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Accessors;
import net.md_5.bungee.api.chat.ClickEvent;
/**
* @author sky
* @since 2018-03-08 22:38:04
*/
public interface ClickAction {
/**
* Get the Chat-Component action
* @return the Chat-Component action
*/
ClickEvent.Action action();
/**
* The value paired to the action
* @return the value paired tot the action
*/
String value();
/**
* Creates a command action: when the player clicks, the command passed as parameter gets executed with the clicker as sender
* @param command the command to be executed
* @return a new ClickAction
*/
static ClickAction runCommand(String command) {
return new SimpleClickAction(ClickEvent.Action.RUN_COMMAND, command);
}
/**
* Creates a suggest_command action: when the player clicks, the book closes and the chat opens with the parameter written into it
* @param command the command to be suggested
* @return a new ClickAction
*/
static ClickAction suggestCommand(String command) {
return new SimpleClickAction(ClickEvent.Action.SUGGEST_COMMAND, command);
}
/**
* Creates a open_utl action: when the player clicks the url passed as argument will open in the browser
* @param url the url to be opened
* @return a new ClickAction
*/
static ClickAction openUrl(String url) {
if(url.startsWith("http://") || url.startsWith("https://"))
return new SimpleClickAction(ClickEvent.Action.OPEN_URL, url);
else
throw new IllegalArgumentException("Invalid url: \"" + url + "\", it should start with http:// or https://");
}
/**
* Creates a change_page action: when the player clicks the book page will be set at the value passed as argument
* @param page the new page
* @return a new ClickAction
*/
static ClickAction changePage(int page) {
return new SimpleClickAction(ClickEvent.Action.CHANGE_PAGE, Integer.toString(page));
}
@Getter
@Accessors(fluent = true)
@RequiredArgsConstructor
class SimpleClickAction implements ClickAction {
private final ClickEvent.Action action;
private final String value;
}
}

View File

@@ -0,0 +1,143 @@
package me.skymc.taboolib.bookformatter.action;
import java.util.UUID;
import org.bukkit.Achievement;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import lombok.Getter;
import lombok.experimental.Accessors;
import me.skymc.taboolib.bookformatter.BookAchievement;
import me.skymc.taboolib.bookformatter.BookReflection;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
/**
* @author sky
* @since 2018-03-08 22:38:51
*/
@SuppressWarnings("deprecation")
public interface HoverAction {
/**
* Get the Chat-Component action
* @return the Chat-Component action
*/
HoverEvent.Action action();
/**
* The value paired to the action
* @return the value paired tot the action
*/
BaseComponent[] value();
/**
* Creates a show_text action: when the component is hovered the text used as parameter will be displayed
* @param text the text to display
* @return a new HoverAction instance
*/
static HoverAction showText(BaseComponent... text) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_TEXT, text);
}
/**
* Creates a show_text action: when the component is hovered the text used as parameter will be displayed
* @param text the text to display
* @return a new HoverAction instance
*/
static HoverAction showText(String text) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_TEXT, new TextComponent(text));
}
/**
* Creates a show_item action: when the component is hovered some item information will be displayed
* @param item a component array representing item to display
* @return a new HoverAction instance
*/
static HoverAction showItem(BaseComponent... item) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_ITEM, item);
}
/**
* Creates a show_item action: when the component is hovered some item information will be displayed
* @param item the item to display
* @return a new HoverAction instance
*/
static HoverAction showItem(ItemStack item) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_ITEM, BookReflection.itemToComponents(item));
}
/**
* Creates a show_entity action: when the component is hovered some entity information will be displayed
* @param entity a component array representing the item to display
* @return a new HoverAction instance
*/
static HoverAction showEntity(BaseComponent... entity) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_ENTITY, entity);
}
/**
* Creates a show_entity action: when the component is hovered some entity information will be displayed
* @param uuid the entity's UniqueId
* @param type the entity's type
* @param name the entity's name
* @return a new HoverAction instance
*/
static HoverAction showEntity(UUID uuid, String type, String name) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_ENTITY,
BookReflection.jsonToComponents(
"{id:\"" + uuid + "\",type:\"" + type + "\"name:\"" + name + "\"}"
)
);
}
/**
* Creates a show_entity action: when the component is hovered some entity information will be displayed
* @param entity the item to display
* @return a new HoverAction instance
*/
static HoverAction showEntity(Entity entity) {
return showEntity(entity.getUniqueId(), entity.getType().getName(), entity.getName());
}
/**
* Creates a show_achievement action: when the component is hovered the achievement information will be displayed
* @param achievementId the id of the achievement to display
* @return a new HoverAction instance
*/
static HoverAction showAchievement(String achievementId) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_ACHIEVEMENT, new TextComponent("achievement." + achievementId));
}
/**
* Creates a show_achievement action: when the component is hovered the achievement information will be displayed
* @param achievement the achievement to display
* @return a new HoverAction instance
*/
static HoverAction showAchievement(Achievement achievement) {
return showAchievement(BookAchievement.toId(achievement));
}
/**
* Creates a show_achievement action: when the component is hovered the statistic information will be displayed
* @param statisticId the id of the statistic to display
* @return a new HoverAction instance
*/
static HoverAction showStatistic(String statisticId) {
return new SimpleHoverAction(HoverEvent.Action.SHOW_ACHIEVEMENT, new TextComponent("statistic." + statisticId));
}
@Getter
@Accessors(fluent = true)
class SimpleHoverAction implements HoverAction {
private final HoverEvent.Action action;
private final BaseComponent[] value;
public SimpleHoverAction(HoverEvent.Action action, BaseComponent... value) {
this.action = action;
this.value = value;
}
}
}

View File

@@ -0,0 +1,129 @@
package me.skymc.taboolib.bookformatter.builder;
import java.util.List;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import me.skymc.taboolib.bookformatter.BookReflection;
import net.md_5.bungee.api.chat.BaseComponent;
/**
* @author sky
* @since 2018-03-08 22:36:14
*/
public class BookBuilder {
private final BookMeta meta;
private final ItemStack book;
/**
* Creates a new instance of the BookBuilder from an ItemStack representing the book item
* @param book the book's ItemStack
*/
public BookBuilder(ItemStack book) {
this.book = book;
this.meta = (BookMeta)book.getItemMeta();
}
/**
* Creates a new instance of the BookBuilder from an ItemStack representing the book item
* @param book the book's ItemStack
*/
public BookBuilder(ItemStack book, String title, String author) {
this.book = book;
this.meta = (BookMeta)book.getItemMeta();
this.meta.setTitle(title);
this.meta.setAuthor(author);
}
/**
* Sets the title of the book
* @param title the title of the book
* @return the BookBuilder's calling instance
*/
public BookBuilder title(String title) {
meta.setTitle(title);
return this;
}
/**
* Sets the author of the book
* @param author the author of the book
* @return the BookBuilder's calling instance
*/
public BookBuilder author(String author) {
meta.setAuthor(author);
return this;
}
/**
* Sets the generation of the book
* Only works from MC 1.10
* @param generation the Book generation
* @return the BookBuilder calling instance
*/
public BookBuilder generation(BookMeta.Generation generation) {
meta.setGeneration(generation);
return this;
}
/**
* Sets the pages of the book without worrying about json or interactivity
* @param pages text-based pages
* @return the BookBuilder's calling instance
*/
public BookBuilder pagesRaw(String... pages) {
meta.setPages(pages);
return this;
}
/**
* Sets the pages of the book without worrying about json or interactivity
* @param pages text-based pages
* @return the BookBuilder's calling instance
*/
public BookBuilder pagesRaw(List<String> pages) {
meta.setPages(pages);
return this;
}
/**
* Sets the pages of the book
* @param pages the pages of the book
* @return the BookBuilder's calling instance
*/
public BookBuilder pages(BaseComponent[]... pages) {
BookReflection.setPages(meta, pages);
return this;
}
/**
* Sets the pages of the book
* @param pages the pages of the book
* @return the BookBuilder's calling instance
*/
public BookBuilder pages(List<BaseComponent[]> pages) {
BookReflection.setPages(meta, pages.toArray(new BaseComponent[0][]));
return this;
}
/**
* Append the pages of the book
* @param pages the pages of the book
* @return the BookBuilder's calling instance
*/
public BookBuilder addPages(BaseComponent[]... pages) {
BookReflection.addPages(meta, pages);
return this;
}
/**
* Creates the book
* @return the built book
*/
public ItemStack build() {
book.setItemMeta(meta);
return book;
}
}

View File

@@ -0,0 +1,114 @@
package me.skymc.taboolib.bookformatter.builder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
/**
* @author sky
* @since 2018-03-08 22:36:58
*/
public class PageBuilder {
private List<BaseComponent> text = new ArrayList<>();
/**
* Adds a simple black-colored text to the page
* @param text the text to add
* @return the PageBuilder's calling instance
*/
public PageBuilder add(String text) {
this.text.add(TextBuilder.of(text).build());
return this;
}
/**
* Adds a component to the page
* @param component the component to add
* @return the PageBuilder's calling instance
*/
public PageBuilder add(BaseComponent component) {
this.text.add(component);
return this;
}
/**
* Adds one or more components to the page
* @param components the components to add
* @return the PageBuilder's calling instance
*/
public PageBuilder add(BaseComponent... components) {
this.text.addAll(Arrays.asList(components));
return this;
}
/**
* Adds one or more components to the page
* @param components the components to add
* @return the PageBuilder's calling instance
*/
public PageBuilder add(Collection<BaseComponent> components) {
this.text.addAll(components);
return this;
}
/**
* Adds a newline to the page (equivalent of adding \n to the previous component)
* @return the PageBuilder's calling instance
*/
public PageBuilder newLine() {
this.text.add(new TextComponent("\n"));
return this;
}
/**
* Another way of newLine(), better resolution (equivalent of adding \n to the previous component)
* @return the PageBuilder's calling instance
*/
public PageBuilder endLine() {
return newLine();
}
/**
* Builds the page
* @return an array of BaseComponents representing the page
*/
public BaseComponent[] build() {
return text.toArray(new BaseComponent[0]);
}
/**
* Creates a new PageBuilder instance wih the parameter as the initial text
* @param text the initial text of the page
* @return a new PageBuilder with the parameter as the initial text
*/
public static PageBuilder of(String text) {
return new PageBuilder().add(text);
}
/**
* Creates a new PageBuilder instance wih the parameter as the initial component
* @param text the initial component of the page
* @return a new PageBuilder with the parameter as the initial component
*/
public static PageBuilder of(BaseComponent text) {
return new PageBuilder().add(text);
}
/**
* Creates a new PageBuilder instance wih the parameter as the initial components
* @param text the initial components of the page
* @return a new PageBuilder with the parameter as the initial components
*/
public static PageBuilder of(BaseComponent... text) {
PageBuilder res = new PageBuilder();
for(BaseComponent b : text)
res.add(b);
return res;
}
}

View File

@@ -0,0 +1,55 @@
package me.skymc.taboolib.bookformatter.builder;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import me.skymc.taboolib.bookformatter.action.ClickAction;
import me.skymc.taboolib.bookformatter.action.HoverAction;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
/**
* @author sky
* @since 2018-03-08 22:37:27
*/
@Setter
@Getter
@Accessors(fluent = true, chain = true)
public class TextBuilder {
private String text = "";
private ClickAction onClick = null;
private HoverAction onHover = null;
public TextBuilder() {}
public TextBuilder(String text) {
this.text = text;
}
/**
* Creates the component representing the built text
* @return the component representing the built text
*/
public BaseComponent build() {
TextComponent res = new TextComponent(text);
if(onClick != null) {
res.setClickEvent(new ClickEvent(onClick.action(), onClick.value()));
}
if(onHover != null) {
res.setHoverEvent(new HoverEvent(onHover.action(), onHover.value()));
}
return res;
}
/**
* Creates a new TextBuilder with the parameter as his initial text
* @param text initial text
* @return a new TextBuilder with the parameter as his initial text
*/
public static TextBuilder of(String text) {
return new TextBuilder().text(text);
}
}

View File

@@ -0,0 +1,667 @@
package me.skymc.taboolib.bstats;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import org.bukkit.plugin.java.JavaPlugin;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import javax.net.ssl.HttpsURLConnection;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
/**
* bStats collects some data for plugin authors.
*
* Check out https://bStats.org/ to learn more about bStats!
*/
public class Metrics {
static {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
final String defaultPackage = new String(
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure nobody just copy & pastes the example and use the wrong package names
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
// The version of this bStats class
public static final int B_STATS_VERSION = 1;
// The url to which the data is sent
private static final String URL = "https://bStats.org/submitData/bukkit";
// Should failed requests be logged?
private static boolean logFailedRequests;
// The uuid of the server
private static String serverUUID;
// The plugin
private final JavaPlugin plugin;
// A list with all custom charts
private final List<CustomChart> charts = new ArrayList<>();
/**
* Class constructor.
*
* @param plugin The plugin which stats should be submitted.
*/
public Metrics(JavaPlugin plugin) {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null!");
}
this.plugin = plugin;
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
// Check if the config file exists
if (!config.isSet("serverUuid")) {
// Add default values
config.addDefault("enabled", true);
// Every server gets it's unique random id.
config.addDefault("serverUuid", UUID.randomUUID().toString());
// Should failed request be logged?
config.addDefault("logFailedRequests", false);
// Inform the server owners about bStats
config.options().header(
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
"To honor their work, you should not disable it.\n" +
"This has nearly no effect on the server performance!\n" +
"Check out https://bStats.org/ to learn more :)"
).copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) { }
}
// Load the data
serverUUID = config.getString("serverUuid");
logFailedRequests = config.getBoolean("logFailedRequests", false);
if (config.getBoolean("enabled", true)) {
boolean found = false;
// Search for all other bStats Metrics classes to see if we are the first one
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
found = true; // We aren't the first
break;
} catch (NoSuchFieldException ignored) { }
}
// Register our service
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
if (!found) {
// We are the first!
startSubmitting();
}
}
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
if (chart == null) {
throw new IllegalArgumentException("Chart cannot be null!");
}
charts.add(chart);
}
/**
* Starts the Scheduler which submits our data every 30 minutes.
*/
private void startSubmitting() {
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (!plugin.isEnabled()) { // Plugin was disabled
timer.cancel();
return;
}
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
Bukkit.getScheduler().runTask(plugin, new Runnable() {
@Override
public void run() {
submitData();
}
});
}
}, 1000*60*5, 1000*60*30);
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
// WARNING: Just don't do it!
}
/**
* Gets the plugin specific data.
* This method is called using Reflection.
*
* @return The plugin specific data.
*/
public JSONObject getPluginData() {
JSONObject data = new JSONObject();
String pluginName = plugin.getDescription().getName();
String pluginVersion = plugin.getDescription().getVersion();
data.put("pluginName", pluginName); // Append the name of the plugin
data.put("pluginVersion", pluginVersion); // Append the version of the plugin
JSONArray customCharts = new JSONArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
JSONObject chart = customChart.getRequestJsonObject();
if (chart == null) { // If the chart is null, we skip it
continue;
}
customCharts.add(chart);
}
data.put("customCharts", customCharts);
return data;
}
/**
* Gets the server specific data.
*
* @return The server specific data.
*/
private JSONObject getServerData() {
// Minecraft specific data
int playerAmount;
try {
// Around MC 1.8 the return type was changed to a collection from an array,
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
} catch (Exception e) {
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
}
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
String bukkitVersion = org.bukkit.Bukkit.getVersion();
bukkitVersion = bukkitVersion.substring(bukkitVersion.indexOf("MC: ") + 4, bukkitVersion.length() - 1);
// OS/Java specific data
String javaVersion = System.getProperty("java.version");
String osName = System.getProperty("os.name");
String osArch = System.getProperty("os.arch");
String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors();
JSONObject data = new JSONObject();
data.put("serverUUID", serverUUID);
data.put("playerAmount", playerAmount);
data.put("onlineMode", onlineMode);
data.put("bukkitVersion", bukkitVersion);
data.put("javaVersion", javaVersion);
data.put("osName", osName);
data.put("osArch", osArch);
data.put("osVersion", osVersion);
data.put("coreCount", coreCount);
return data;
}
/**
* Collects the data and sends it afterwards.
*/
private void submitData() {
final JSONObject data = getServerData();
JSONArray pluginData = new JSONArray();
// Search for all other bStats Metrics classes to get their plugin data
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
pluginData.add(provider.getService().getMethod("getPluginData").invoke(provider.getProvider()));
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
}
} catch (NoSuchFieldException ignored) { }
}
data.put("plugins", pluginData);
// Create a new thread for the connection to the bStats server
new Thread(new Runnable() {
@Override
public void run() {
try {
// Send the data
sendData(data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
}
}
}
}).start();
}
/**
* Sends the data to the bStats server.
*
* @param data The data to send.
* @throws Exception If the request failed.
*/
private static void sendData(JSONObject data) throws Exception {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null!");
}
if (Bukkit.isPrimaryThread()) {
throw new IllegalAccessException("This method must not be called from the main thread!");
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
// Add headers
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
// Send data
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.write(compressedData);
outputStream.flush();
outputStream.close();
connection.getInputStream().close(); // We don't care about the response - Just send our data :)
}
/**
* Gzips the given String.
*
* @param str The string to gzip.
* @return The gzipped String.
* @throws IOException If the compression failed.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
gzip.write(str.getBytes("UTF-8"));
gzip.close();
return outputStream.toByteArray();
}
/**
* Represents a custom chart.
*/
public static abstract class CustomChart {
// The id of the chart
final String chartId;
/**
* Class constructor.
*
* @param chartId The id of the chart.
*/
CustomChart(String chartId) {
if (chartId == null || chartId.isEmpty()) {
throw new IllegalArgumentException("ChartId cannot be null or empty!");
}
this.chartId = chartId;
}
private JSONObject getRequestJsonObject() {
JSONObject chart = new JSONObject();
chart.put("chartId", chartId);
try {
JSONObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
chart.put("data", data);
} catch (Throwable t) {
if (logFailedRequests) {
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return chart;
}
protected abstract JSONObject getChartData() throws Exception;
}
/**
* Represents a custom simple pie.
*/
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
data.put("value", value);
return data;
}
}
/**
* Represents a custom advanced pie.
*/
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom drilldown pie.
*/
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JSONObject value = new JSONObject();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.put(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.put(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom single line chart.
*/
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
data.put("value", value);
return data;
}
}
/**
* Represents a custom multi line chart.
*/
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.put(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom simple bar chart.
*/
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
JSONArray categoryValues = new JSONArray();
categoryValues.add(entry.getValue());
values.put(entry.getKey(), categoryValues);
}
data.put("values", values);
return data;
}
}
/**
* Represents a custom advanced bar chart.
*/
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JSONObject getChartData() throws Exception {
JSONObject data = new JSONObject();
JSONObject values = new JSONObject();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
continue; // Skip this invalid
}
allSkipped = false;
JSONArray categoryValues = new JSONArray();
for (int categoryValue : entry.getValue()) {
categoryValues.add(categoryValue);
}
values.put(entry.getKey(), categoryValues);
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.put("values", values);
return data;
}
}
}

View File

@@ -0,0 +1,72 @@
package me.skymc.taboolib.client;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.text.SimpleDateFormat;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.BevelBorder;
@Deprecated
public class LogClient extends JFrame {
/**
* DEFAULT VERSION UID
*/
private static final long serialVersionUID = 1L;
private JTextArea textArea = new JTextArea();
private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
public LogClient(String title) {
super(title);
// DEFAULT CLOSE OPERATION
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// SETTINGS
final JScrollPane scrollPane = new JScrollPane();
scrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
scrollPane.setViewportView(textArea);
getContentPane().add(scrollPane, BorderLayout.CENTER);
setSize(700, 500);
setVisible(true);
// CON'T EDIT
textArea.setEditable(false);
textArea.setFont(new Font("黑体", 0, 18));
textArea.setBackground(Color.black);
textArea.setForeground(Color.LIGHT_GRAY);
addstr(title);
addstr("");
}
public void addString(String a) {
textArea.append("[" + sdf.format(System.currentTimeMillis()) + " NONE]: " + a + '\n');
textArea.setSelectionStart(textArea.getText().length());
}
public void addstr(String a) {
textArea.append(a + '\n');
textArea.setSelectionStart(textArea.getText().length());
}
public void info(String a) {
textArea.append("[" + sdf.format(System.currentTimeMillis()) + " INFO]: " + a + '\n');
textArea.setSelectionStart(textArea.getText().length());
}
public void warn(String a) {
textArea.append("[" + sdf.format(System.currentTimeMillis()) + " WARN]: " + a + '\n');
textArea.setSelectionStart(textArea.getText().length());
}
}

View File

@@ -0,0 +1,92 @@
package me.skymc.taboolib.commands;
import java.util.HashMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.commands.sub.AttributesCommand;
import me.skymc.taboolib.commands.sub.EnchantCommand;
import me.skymc.taboolib.commands.sub.FlagCommand;
import me.skymc.taboolib.commands.sub.HelpCommand;
import me.skymc.taboolib.commands.sub.ImportCommand;
import me.skymc.taboolib.commands.sub.InfoCommand;
import me.skymc.taboolib.commands.sub.ItemCommand;
import me.skymc.taboolib.commands.sub.PotionCommand;
import me.skymc.taboolib.commands.sub.SaveCommand;
import me.skymc.taboolib.commands.sub.SlotCommand;
import me.skymc.taboolib.commands.sub.VariableGetCommand;
import me.skymc.taboolib.commands.sub.VariableSetCommand;
import me.skymc.taboolib.commands.sub.cycle.CycleCommand;
import me.skymc.taboolib.commands.sub.itemlist.ItemListCommand;
import me.skymc.taboolib.commands.sub.shell.ShellCommand;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.message.MsgUtils;
public class MainCommands implements CommandExecutor{
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 0 || args[0].equalsIgnoreCase("help")) {
new HelpCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("itemreload") || args[0].equalsIgnoreCase("ireload")) {
ItemUtils.reloadItemCache();
ItemUtils.reloadItemName();
MsgUtils.send(sender, "重载成功");
}
else if (args[0].equalsIgnoreCase("save")) {
new SaveCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("enchants")) {
new EnchantCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("potions")) {
new PotionCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("flags")) {
new FlagCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("attributes")) {
new AttributesCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("slots")) {
new SlotCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("importdata")) {
new ImportCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("iteminfo")) {
new InfoCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("itemlist")) {
new ItemListCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("item") || args[0].equalsIgnoreCase("i")) {
new ItemCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("setvariable")) {
new VariableSetCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("getvariable")) {
new VariableGetCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("shell") || args[0].equalsIgnoreCase("s")) {
new ShellCommand(sender, args);
}
else if (args[0].equalsIgnoreCase("cycle") || args[0].equalsIgnoreCase("c")) {
new CycleCommand(sender, args);
}
else {
MsgUtils.send(sender, "&4指令错误");
}
return true;
}
}

View File

@@ -0,0 +1,38 @@
package me.skymc.taboolib.commands;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public abstract class SubCommand {
public CommandSender sender;
public String[] args;
public boolean returnValue = false;
public SubCommand(CommandSender sender, String[] args) {
this.sender = sender;
this.args = args;
}
public boolean setReturn(boolean returnValue) {
return this.returnValue = returnValue;
}
public boolean isPlayer() {
return sender instanceof Player;
}
public boolean command() {
return returnValue;
}
public String getArgs(int size) {
StringBuffer sb = new StringBuffer();
for (int i = size ; i < args.length ; i++) {
sb.append(args[i]);
sb.append(" ");
}
return sb.toString().substring(0, sb.length() - 1);
}
}

View File

@@ -0,0 +1,10 @@
package me.skymc.taboolib.commands;
import org.bukkit.command.CommandSender;
@Deprecated
public abstract interface SubCommandExecutor {
public abstract boolean command(CommandSender sender, String[] args);
}

View File

@@ -0,0 +1,80 @@
package me.skymc.taboolib.commands.language;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.string.language2.Language2Value;
/**
* @author sky
* @since 2018年2月13日 下午5:11:01
*/
public class Language2Command implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 0) {
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lLanguage2 Commands §b§l-----");
sender.sendMessage("§f");
sender.sendMessage("§f /language2 send §8[§7玩家/ALL§8] §8[§7语言§8] §8<§7变量§8> §6- §e发送语言提示");
sender.sendMessage("§f /language2 reload §6- §e重载语言库");
sender.sendMessage("§f");
}
else if (args[0].equalsIgnoreCase("reload")) {
MsgUtils.send(sender, "§7重载中..");
long time = System.currentTimeMillis();
Main.getExampleLangauge2().reload();
MsgUtils.send(sender, "§7重载完成! 耗时: &f" + (System.currentTimeMillis() - time) + "ms");
}
else if (args[0].equalsIgnoreCase("send")) {
if (args.length < 3) {
MsgUtils.send(sender, "§4参数错误");
}
else {
// 时间
long time = System.currentTimeMillis();
// 获取语言文件
Language2Value value = Main.getExampleLangauge2().get(args[2]);
// 如果有变量参数
if (args.length > 3) {
int i = 0;
for (String variable : args[3].split("\\|")) {
value.addPlaceholder("$" + i, variable);
i++;
}
}
// 如果是公告
if (args[1].equals("ALL")) {
// 发送信息
value.broadcast();
}
else {
// 获取玩家
Player player = Bukkit.getPlayerExact(args[1]);
if (player == null) {
MsgUtils.send(sender, "§4玩家不在线");
}
else {
// 发送信息
value.send(player);
}
}
// 如果发送者是玩家
if (sender instanceof Player && ((Player) sender).getItemInHand().getType().equals(Material.COMMAND)) {
MsgUtils.send(sender, "§7信息已发送, 本次计算耗时: &f" + (System.currentTimeMillis() - time) + "ms");
}
}
}
return true;
}
}

View File

@@ -0,0 +1,36 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
public class AttributesCommand extends SubCommand {
public AttributesCommand(CommandSender sender, String[] args) {
super(sender, args);
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lItemStack Attributes §b§l-----");
sender.sendMessage("§f");
String[] attributes = new String[] { "damage", "speed", "attackspeed", "health", "knockback", "armor", "luck" };
for (String name : attributes) {
if (isPlayer()) {
JSONFormatter json = new JSONFormatter();
json.append(" §7- §f" + name);
json.appendHoverClick(" §8(点击复制)", new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(name));
json.send((Player) sender);
}
else {
sender.sendMessage(" §7- §f" + name);
}
}
sender.sendMessage("§f");
}
}

View File

@@ -0,0 +1,35 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
public class EnchantCommand extends SubCommand {
@SuppressWarnings("deprecation")
public EnchantCommand(CommandSender sender, String[] args) {
super(sender, args);
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lItemStack Enchantments §b§l-----");
sender.sendMessage("§f");
for (Enchantment enchant : Enchantment.values()) {
if (isPlayer()) {
JSONFormatter json = new JSONFormatter();
json.append(" §7- §f" + enchant.getId() + ". " + enchant.getName());
json.appendHoverClick(" §8(点击复制)", new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(enchant.getName()));
json.send((Player) sender);
}
else {
sender.sendMessage(" §7- §f" + enchant.getId() + ". " + enchant.getName());
}
}
sender.sendMessage("§f");
}
}

View File

@@ -0,0 +1,34 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
public class FlagCommand extends SubCommand {
public FlagCommand(CommandSender sender, String[] args) {
super(sender, args);
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lItemStack Flags §b§l-----");
sender.sendMessage("§f");
for (ItemFlag flag : ItemFlag.values()) {
if (isPlayer()) {
JSONFormatter json = new JSONFormatter();
json.append(" §7- §f" + flag.name());
json.appendHoverClick(" §8(点击复制)", new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(flag.name()));
json.send((Player) sender);
}
else {
sender.sendMessage(" §7- §f" + flag.name());
}
}
sender.sendMessage("§f");
}
}

View File

@@ -0,0 +1,80 @@
package me.skymc.taboolib.commands.sub;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
public class HelpCommand extends SubCommand {
public HelpCommand(CommandSender sender, String[] args) {
super(sender, args);
HashMap<String, String> helps = new LinkedHashMap<>();
helps.put("/taboolib save §8[§7名称§8]", "§e保存手中物品");
helps.put("/taboolib item §8[§7名称§8] §8<§7玩家§8> §8<§7数量§8>", "§e给予玩家物品");
helps.put("/taboolib iteminfo", "§e查看物品信息");
helps.put("/taboolib itemlist", "§e查看所有物品");
helps.put("/taboolib itemreload", "§e重载物品缓存");
helps.put("§a", null);
helps.put("/taboolib attributes", "§e查看所有属性");
helps.put("/taboolib enchants", "§e查看所有附魔");
helps.put("/taboolib potions", "§e查看所有药水");
helps.put("/taboolib flags", "§e查看所有标签");
helps.put("/taboolib slots", "§e查看所有部位");
helps.put("§b", null);
helps.put("/taboolib getvariable §8[§7-s|a§8] §8[§7键§8]", "§e查看变量");
helps.put("/taboolib setvariable §8[§7-s|a§8] §8[§7键§8] §8[§7值§8]", "§e更改变量");
helps.put("§c", null);
helps.put("/taboolib cycle list", "§e列出所有时间检查器");
helps.put("/taboolib cycle info §8[§7名称§8]", "§e查询检查器信息");
helps.put("/taboolib cycle reset §8[§7名称§8]", "§e初始化时间检查器");
helps.put("/taboolib cycle update §8[§7名称§8]", "§e更新时间检查器");
helps.put("§f", null);
helps.put("/taboolib shell load §8[§7名称§8]", "§e载入某个脚本");
helps.put("/taboolib shell unload §8[§7名称§8]", "§e卸载某个脚本");
helps.put("§e", null);
helps.put("/taboolib importdata", "§4向数据库导入本地数据 §8(该操作将会清空数据库)");
if (sender instanceof ConsoleCommandSender || TabooLib.getVerint() < 10900) {
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lTaooLib Commands §b§l-----");
sender.sendMessage("§f");
// 遍历命令
for (Entry<String, String> entry : helps.entrySet()) {
if (entry.getValue() == null) {
sender.sendMessage("§f");
} else {
sender.sendMessage("§f " + entry.getKey() + " §6- " + entry.getValue());
}
}
sender.sendMessage("§f");
}
else if (sender instanceof Player) {
JSONFormatter json = new JSONFormatter();
json.append("§f"); json.newLine();
json.append("§b§l----- §3§lTaooLib Commands §b§l-----"); json.newLine();
json.append("§f"); json.newLine();
// 遍历命令
for (Entry<String, String> entry : helps.entrySet()) {
if (entry.getValue() == null) {
json.append("§f"); json.newLine();
} else {
json.appendHoverClick("§f " + entry.getKey() + " §6- " + entry.getValue(), new ShowTextEvent("§f点击复制指令"), new SuggestCommandEvent(entry.getKey().split("§")[0])); json.newLine();
}
}
json.append("§f");
json.send((Player) sender);
}
}
}

View File

@@ -0,0 +1,45 @@
package me.skymc.taboolib.commands.sub;
import java.io.File;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.Main.StorageType;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.message.MsgUtils;
public class ImportCommand extends SubCommand {
public ImportCommand(CommandSender sender, String[] args) {
super(sender, args);
if (isPlayer()) {
MsgUtils.warn("改命令只能由控制台输入");
}
else if (Main.getStorageType() == StorageType.LOCAL) {
MsgUtils.warn("只有启用数据库储存时才能这么做");
}
else {
MsgUtils.send("正在清空数据库...");
Main.getConnection().truncateTable(Main.getTablePrefix() + "_playerdata");
MsgUtils.send("开始导入玩家数据...");
int size = Main.getPlayerDataFolder().listFiles().length;
int loop = 1;
for (File file : Main.getPlayerDataFolder().listFiles()) {
FileConfiguration conf = YamlConfiguration.loadConfiguration(file);
Main.getConnection().intoValue(Main.getTablePrefix() + "_playerdata", file.getName().replace(".yml", ""), ConfigUtils.encodeYAML(conf));
MsgUtils.send("导入玩家: &f" + file.getName().replace(".yml", "") + " &7进度: &f" + loop + "/" + size);
loop++;
}
MsgUtils.send("导入完成!");
}
}
}

View File

@@ -0,0 +1,53 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.itemnbtapi.NBTItem;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowItemEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
import me.skymc.taboolib.message.MsgUtils;
public class InfoCommand extends SubCommand {
@SuppressWarnings("deprecation")
public InfoCommand(CommandSender sender, String[] args) {
super(sender, args);
if (isPlayer()) {
Player player = (Player) sender;
if (player.getItemInHand().getType().equals(Material.AIR)) {
MsgUtils.send(player, "&7请手持正确物品");
}
else {
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lItemStack Info §b§l-----");
sender.sendMessage("§f");
JSONFormatter json = new JSONFormatter();
json.append("§7 - 物品材质: §f"); json.appendHoverClick("§f" + player.getItemInHand().getType().name(), new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(player.getItemInHand().getType().name()));
json.newLine();
json.append("§7 - 物品名称: §f"); json.appendHoverClick("§f" + ItemUtils.getCustomName(player.getItemInHand()), new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(ItemUtils.getCustomName(player.getItemInHand()).replace("§", "&")));
json.newLine();
json.append("§7 - 物品序号: §f" + player.getItemInHand().getTypeId() + ":" + player.getItemInHand().getDurability());
json.newLine();
json.append("§7 - 物品展示: §f"); json.appendHover(ItemUtils.getCustomName(player.getItemInHand()), new ShowItemEvent(player.getItemInHand()));
json.send(player);
NBTItem nbt = new NBTItem(((Player) sender).getItemInHand());
sender.sendMessage("§7 - 物品 NBT: §f");
sender.sendMessage("§f");
sender.sendMessage(nbt.toString());
sender.sendMessage("§f");
}
}
}
}

View File

@@ -0,0 +1,77 @@
package me.skymc.taboolib.commands.sub;
import java.util.HashMap;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.other.NumberUtils;
public class ItemCommand extends SubCommand {
/**
* /TabooLib item 物品 玩家 数量
*
* @param sender
* @param args
*/
public ItemCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 2) {
MsgUtils.send(sender, "请输入正确的物品名称");
setReturn(false);
}
else {
if (ItemUtils.getCacheItem(args[1]) == null) {
MsgUtils.send(sender, "物品 &f" + args[1] + "&7 不存在");
setReturn(false);
return;
}
Player player;
Integer amount = 1;
ItemStack item = ItemUtils.getCacheItem(args[1]).clone();
if (args.length > 2) {
player = Bukkit.getPlayerExact(args[2]);
if (player == null) {
MsgUtils.send(sender, "玩家 &f" + args[2] + "&7 不在线");
setReturn(false);
return;
}
}
else if (sender instanceof Player) {
player = (Player) sender;
}
else {
MsgUtils.send(sender, "后台不允许这么做");
setReturn(false);
return;
}
if (args.length > 3) {
amount = NumberUtils.getInteger(args[3]);
if (amount < 1) {
MsgUtils.send(sender, "数量必须大于0");
setReturn(false);
return;
}
}
item.setAmount(amount);
HashMap<Integer, ItemStack> map = player.getInventory().addItem(item);
if (map.size() > 0) {
player.getWorld().dropItem(player.getLocation(), item);
}
MsgUtils.send(sender, "物品已发送至玩家 &f" + player.getName() + " &7的背包中");
setReturn(true);
}
}
}

View File

@@ -0,0 +1,37 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
public class PotionCommand extends SubCommand {
@SuppressWarnings("deprecation")
public PotionCommand(CommandSender sender, String[] args) {
super(sender, args);
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lPotionEffect Types §b§l-----");
sender.sendMessage("§f");
for (PotionEffectType type : PotionEffectType.values()) {
if (type != null) {
if (isPlayer()) {
JSONFormatter json = new JSONFormatter();
json.append(" §7- §f" + type.getId() + ". " + type.getName());
json.appendHoverClick(" §8(点击复制)", new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(type.getName()));
json.send((Player) sender);
}
else {
sender.sendMessage(" §7- §f" + type.getId() + ". " + type.getName() + "");
}
}
}
sender.sendMessage("§f");
}
}

View File

@@ -0,0 +1,89 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.message.ChatCatcher;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.message.ChatCatcher.Catcher;
import me.skymc.taboolib.playerdata.DataUtils;
public class SaveCommand extends SubCommand {
public SaveCommand(CommandSender sender, String[] args) {
super(sender, args);
if (!(sender instanceof Player)) {
MsgUtils.send(sender, "&4后台无法这么做");
return;
}
if (args.length < 2) {
MsgUtils.send(sender, "&4请输入正确的名称");
return;
}
if (((Player) sender).getItemInHand().getType().equals(Material.AIR)) {
MsgUtils.send(sender, "&4你不能保存空气");
return;
}
if (ItemUtils.getItemCachesFinal().containsKey(args[1])) {
MsgUtils.send(sender, "&4该名称所对应的物品保存于固定物品库中, 无法覆盖");
return;
}
if (ItemUtils.getItemCaches().containsKey(args[1])) {
// 检查聊天引导
if (ChatCatcher.contains((Player) sender)) {
MsgUtils.send(sender, "&4你有一个正在进行的聊天引导, 请完成后在这么做");
return;
}
ChatCatcher.call((Player) sender, new ChatCatcher.Catcher() {
@Override
public void cancel() {
MsgUtils.send(sender, "&7退出引导");
}
@Override
public Catcher before() {
MsgUtils.send(sender, "物品 &f" + args[1] + "&7 已存在, 如果你想要覆盖它, 请在聊天框中输入 \"&f是&7\"");
return this;
}
@SuppressWarnings("deprecation")
@Override
public boolean after(String message) {
if (message.equals("")) {
saveItem(args[1], ((Player) sender).getItemInHand());
MsgUtils.send(sender, "物品 &f" + args[1] + " &7已替换");
}
else {
MsgUtils.send(sender, "&7退出引导");
}
return false;
}
});
}
else {
saveItem(args[1], ((Player) sender).getItemInHand());
MsgUtils.send(sender, "物品 &f" + args[1] + " &7已保存");
}
}
private void saveItem(String name, ItemStack item) {
FileConfiguration conf = ConfigUtils.load(Main.getInst(), ItemUtils.getItemCacheFile());
conf.set(name + ".bukkit", item);
DataUtils.saveConfiguration(conf, ItemUtils.getItemCacheFile());
ItemUtils.reloadItemCache();
}
}

View File

@@ -0,0 +1,36 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
public class SlotCommand extends SubCommand {
public SlotCommand(CommandSender sender, String[] args) {
super(sender, args);
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lAttribute Slots §b§l-----");
sender.sendMessage("§f");
String[] attributes = new String[] { "mainhand", "offhand", "feet", "legs", "chest", "head", "all" };
for (String name : attributes) {
if (isPlayer()) {
JSONFormatter json = new JSONFormatter();
json.append(" §7- §f" + name);
json.appendHoverClick(" §8(点击复制)", new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(name));
json.send((Player) sender);
}
else {
sender.sendMessage(" §7- §f" + name);
}
}
sender.sendMessage("§f");
}
}

View File

@@ -0,0 +1,40 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.command.CommandSender;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.database.GlobalDataManager;
import me.skymc.taboolib.message.MsgUtils;
public class VariableGetCommand extends SubCommand {
public VariableGetCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 3) {
MsgUtils.send(sender, "&4请输入正确的指令 ");
}
else if (!(args[1].equals("-a") || args[1].equals("-s"))) {
MsgUtils.send(sender, "&4请输入正确的读取方式");
}
Long time = System.currentTimeMillis();
String value = null;
if (args[1].equals("-s")) {
value = GlobalDataManager.getVariable(args[2], null);
}
else if (args[1].equals("-a")) {
value = GlobalDataManager.getVariableAsynchronous(args[2], null);
}
if (value == null) {
MsgUtils.send(sender, "读取完成, 耗时: &f" + (System.currentTimeMillis() - time) + " &7(ms)");
MsgUtils.send(sender, "变量 &f" + args[2] + " &7不存在");
}
else {
MsgUtils.send(sender, "读取完成, 耗时: &f" + (System.currentTimeMillis() - time) + " &7(ms)");
MsgUtils.send(sender, "变量 &f" + args[2] + " &7的值为 &f" + value);
}
}
}

View File

@@ -0,0 +1,34 @@
package me.skymc.taboolib.commands.sub;
import org.bukkit.command.CommandSender;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.database.GlobalDataManager;
import me.skymc.taboolib.message.MsgUtils;
public class VariableSetCommand extends SubCommand {
public VariableSetCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 4) {
MsgUtils.send(sender, "&4请输入正确的指令 ");
}
else if (!(args[1].equals("-a") || args[1].equals("-s"))) {
MsgUtils.send(sender, "&4请输入正确的写入方式");
}
Long time = System.currentTimeMillis();
String value = getArgs(3);
if (args[1].equals("-s")) {
GlobalDataManager.setVariable(args[2], value);
}
else if (args[1].equals("-a")) {
GlobalDataManager.setVariableAsynchronous(args[2], value);
}
MsgUtils.send(sender, "写入完成, 耗时: &f" + (System.currentTimeMillis() - time) + " &7(ms)");
setReturn(true);
}
}

View File

@@ -0,0 +1,39 @@
package me.skymc.taboolib.commands.sub.cycle;
import java.io.File;
import org.bukkit.command.CommandSender;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.javashell.JavaShell;
import me.skymc.taboolib.message.MsgUtils;
public class CycleCommand extends SubCommand {
public CycleCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length > 1) {
if (args[1].equalsIgnoreCase("list")) {
new CycleListCommand(sender, args);
}
else if (args[1].equalsIgnoreCase("info")) {
new CycleInfoCommand(sender, args);
}
else if (args[1].equalsIgnoreCase("reset")) {
new CycleResetCommand(sender, args);
}
else if (args[1].equalsIgnoreCase("update")) {
new CycleUpdateCommand(sender, args);
}
}
else {
MsgUtils.send(sender, "&4指令错误");
}
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,58 @@
package me.skymc.taboolib.commands.sub.cycle;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.database.GlobalDataManager;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.other.DateUtils;
import me.skymc.taboolib.timecycle.TimeCycle;
import me.skymc.taboolib.timecycle.TimeCycleEvent;
import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent;
import me.skymc.taboolib.timecycle.TimeCycleManager;
public class CycleInfoCommand extends SubCommand {
public CycleInfoCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 3) {
MsgUtils.send(sender, "&c请输入正确的检查器名称");
return;
}
TimeCycle cycle = TimeCycleManager.getTimeCycle(args[2]);
if (cycle == null) {
MsgUtils.send(sender, "&c检查器 &4" + args[2] + " &c不存在");
return;
}
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lTimeCycle Info §b§l-----");
sender.sendMessage("§f");
sender.sendMessage(" §f- §7注册周期: §f" + asString(cycle.getCycle() / 1000L));
sender.sendMessage(" §f- §7注册插件: §f" + cycle.getPlugin().getName());
sender.sendMessage("§f");
sender.sendMessage(" §f- §7上次刷新时间: §f" + DateUtils.CH_ALL.format(TimeCycleManager.getBeforeTimeline(cycle.getName())));
sender.sendMessage(" §f- §7下次刷新时间: §f" + DateUtils.CH_ALL.format(TimeCycleManager.getAfterTimeline(cycle.getName())));
sender.sendMessage("§f");
}
public String asString(long seconds) {
long day = TimeUnit.SECONDS.toDays(seconds);
long hours = TimeUnit.SECONDS.toHours(seconds) - day * 24;
long minute = TimeUnit.SECONDS.toMinutes(seconds) - TimeUnit.SECONDS.toHours(seconds) * 60L;
long second = TimeUnit.SECONDS.toSeconds(seconds) - TimeUnit.SECONDS.toMinutes(seconds) * 60L;
return "§f" + day + "§7 天, §f" + hours + "§7 小时, §f" + minute + "§7 分钟, §f" + second + "§7 秒";
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,47 @@
package me.skymc.taboolib.commands.sub.cycle;
import java.io.File;
import java.util.concurrent.TimeUnit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.javashell.JavaShell;
import me.skymc.taboolib.jsonformatter.JSONFormatter;
import me.skymc.taboolib.jsonformatter.click.SuggestCommandEvent;
import me.skymc.taboolib.jsonformatter.hover.ShowTextEvent;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.timecycle.TimeCycle;
import me.skymc.taboolib.timecycle.TimeCycleManager;
public class CycleListCommand extends SubCommand {
public CycleListCommand(CommandSender sender, String[] args) {
super(sender, args);
sender.sendMessage("§f");
sender.sendMessage("§b§l----- §3§lTimeCycle List §b§l-----");
sender.sendMessage("§f");
for (TimeCycle cycle : TimeCycleManager.getTimeCycles()) {
if (isPlayer()) {
JSONFormatter json = new JSONFormatter();
json.append(" §7- §f" + cycle.getName());
json.appendHoverClick(" §8(点击复制)", new ShowTextEvent("§f点击复制"), new SuggestCommandEvent(cycle.getName()));
json.send((Player) sender);
}
else {
sender.sendMessage(" §7- §f" + cycle.getName());
}
}
sender.sendMessage("§f");
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,51 @@
package me.skymc.taboolib.commands.sub.cycle;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.database.GlobalDataManager;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.timecycle.TimeCycle;
import me.skymc.taboolib.timecycle.TimeCycleEvent;
import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent;
import me.skymc.taboolib.timecycle.TimeCycleManager;
public class CycleResetCommand extends SubCommand {
public CycleResetCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 3) {
MsgUtils.send(sender, "&c请输入正确的检查器名称");
return;
}
TimeCycle cycle = TimeCycleManager.getTimeCycle(args[2]);
if (cycle == null) {
MsgUtils.send(sender, "&c检查器 &4" + args[2] + " &c不存在");
return;
}
new BukkitRunnable() {
@Override
public void run() {
long time = new TimeCycleInitializeEvent(cycle, System.currentTimeMillis()).call().getTimeline();
// 初始化
GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(time));
// 触发器
Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle));
// 提示
MsgUtils.send(sender, "检查器 &f" + args[2] + " &7初始化完成");
}
}.runTaskAsynchronously(Main.getInst());
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,50 @@
package me.skymc.taboolib.commands.sub.cycle;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.database.GlobalDataManager;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.timecycle.TimeCycle;
import me.skymc.taboolib.timecycle.TimeCycleEvent;
import me.skymc.taboolib.timecycle.TimeCycleInitializeEvent;
import me.skymc.taboolib.timecycle.TimeCycleManager;
public class CycleUpdateCommand extends SubCommand {
public CycleUpdateCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 3) {
MsgUtils.send(sender, "&c请输入正确的检查器名称");
return;
}
TimeCycle cycle = TimeCycleManager.getTimeCycle(args[2]);
if (cycle == null) {
MsgUtils.send(sender, "&c检查器 &4" + args[2] + " &c不存在");
return;
}
new BukkitRunnable() {
@Override
public void run() {
// 重置
GlobalDataManager.setVariable("timecycle:" + cycle.getName(), String.valueOf(System.currentTimeMillis()));
// 触发器
Bukkit.getPluginManager().callEvent(new TimeCycleEvent(cycle));
// 提示
MsgUtils.send(sender, "检查器 &f" + args[2] + " &7已更新");
}
}.runTaskAsynchronously(Main.getInst());
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,31 @@
package me.skymc.taboolib.commands.sub.itemlist;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.commands.sub.itemlist.listener.ItemLibraryPatch;
import me.skymc.taboolib.other.NumberUtils;
/**
* @author sky
* @since 2018年2月4日 下午8:08:22
*/
public class ItemListCommand extends SubCommand {
/**
* @param sender
* @param args
*/
public ItemListCommand(CommandSender sender, String[] args) {
super(sender, args);
if (isPlayer()) {
if (args.length == 1) {
ItemLibraryPatch.openInventory((Player) sender, 1);
}
else {
ItemLibraryPatch.openInventory((Player) sender, NumberUtils.getInteger(args[1]));
}
}
}
}

View File

@@ -0,0 +1,113 @@
package me.skymc.taboolib.commands.sub.itemlist.listener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import me.skymc.taboolib.inventory.InventoryUtil;
import me.skymc.taboolib.inventory.ItemUtils;
/**
* @author sky
* @since 2018年2月4日 下午4:35:00
*/
public class ItemLibraryPatch implements Listener {
@EventHandler
public void inventoryClick(InventoryClickEvent e) {
if (e.getInventory().getHolder() instanceof ItemLibraryHolder) {
e.setCancelled(true);
if (e.getCurrentItem() == null || e.getCurrentItem().getType().equals(Material.AIR) || e.getRawSlot() >= e.getInventory().getSize()) {
return;
}
if (e.getRawSlot() == 47) {
openInventory((Player) e.getWhoClicked(), ((ItemLibraryHolder) e.getInventory().getHolder()).PAGE - 1);
}
else if (e.getRawSlot() == 51) {
openInventory((Player) e.getWhoClicked(), ((ItemLibraryHolder) e.getInventory().getHolder()).PAGE + 1);
}
else {
e.getWhoClicked().getInventory().addItem(ItemUtils.getCacheItem(((ItemLibraryHolder) e.getInventory().getHolder()).ITEMS_DATA.get(e.getRawSlot())));
}
}
}
/**
* 打开物品库界面
*
* @param player
* @param page
*/
public static void openInventory(Player player, int page) {
ItemLibraryHolder holder = new ItemLibraryHolder(page);
Inventory inventory = Bukkit.createInventory(holder, 54, "物品库");
LinkedHashMap<String, ItemStack> map = new LinkedHashMap<>();
map.putAll(ItemUtils.getItemCachesFinal());
map.putAll(ItemUtils.getItemCaches());
int loop = 0;
Iterator<String> iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String name = iterator.next();
if (loop >= (page - 1) * 28) {
if (loop < page * 28) {
int slot = InventoryUtil.SLOT_OF_CENTENTS.get(loop - ((page - 1) * 28));
ItemStack item = map.get(name).clone(); {
ItemMeta meta = item.getItemMeta();
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
lore.add("§f");
lore.add("§f§m ");
lore.add("§f序列号: §8" + name);
meta.setLore(lore);
item.setItemMeta(meta);
inventory.setItem(slot, item);
}
holder.ITEMS_DATA.put(slot, name);
}
else {
break;
}
}
loop++;
}
if (page > 1) {
inventory.setItem(47, ItemUtils.setName(new ItemStack(Material.ARROW), "§f上一页"));
}
if (((int) Math.ceil(ItemUtils.getItemCaches().size() / 28D)) > page) {
inventory.setItem(51, ItemUtils.setName(new ItemStack(Material.ARROW), "§f下一页"));
}
player.openInventory(inventory);
}
public static class ItemLibraryHolder implements InventoryHolder {
public final int PAGE;
public final HashMap<Integer, String> ITEMS_DATA = new HashMap<>();
public ItemLibraryHolder(int page) {
this.PAGE = page;
}
@Override
public Inventory getInventory() {
return null;
}
}
}

View File

@@ -0,0 +1,33 @@
package me.skymc.taboolib.commands.sub.shell;
import java.io.File;
import org.bukkit.command.CommandSender;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.javashell.JavaShell;
import me.skymc.taboolib.message.MsgUtils;
public class ShellCommand extends SubCommand {
public ShellCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length > 1) {
if (args[1].equalsIgnoreCase("load")) {
new ShellLoadCommand(sender, args);
}
else if (args[1].equalsIgnoreCase("unload")) {
new ShellUnloadCommand(sender, args);
}
}
else {
MsgUtils.send(sender, "&4指令错误");
}
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,36 @@
package me.skymc.taboolib.commands.sub.shell;
import java.io.File;
import org.bukkit.command.CommandSender;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.javashell.JavaShell;
import me.skymc.taboolib.message.MsgUtils;
public class ShellLoadCommand extends SubCommand {
public ShellLoadCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 3) {
MsgUtils.send(sender, "&c请输入正确的脚本名称");
return;
}
File file = new File(JavaShell.getScriptFolder(), args[2].contains(".java") ? args[2] : args[2] + ".java");
if (!file.exists()) {
MsgUtils.send(sender, "&c脚本 &4" + args[2] + "&c 不存在");
return;
}
if (JavaShell.reloadShell(args[2])) {
MsgUtils.send(sender, "脚本 " + args[2] + " 已载入");
}
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,35 @@
package me.skymc.taboolib.commands.sub.shell;
import java.io.File;
import org.bukkit.command.CommandSender;
import me.skymc.taboolib.commands.SubCommand;
import me.skymc.taboolib.javashell.JavaShell;
import me.skymc.taboolib.message.MsgUtils;
public class ShellUnloadCommand extends SubCommand {
public ShellUnloadCommand(CommandSender sender, String[] args) {
super(sender, args);
if (args.length < 3) {
MsgUtils.send(sender, "&c请输入正确的脚本名称");
return;
}
File file = new File(JavaShell.getScriptFolder(), args[2].contains(".java") ? args[2] : args[2] + ".java");
if (!file.exists()) {
MsgUtils.send(sender, "&c脚本 &4" + args[2] + "&c 不存在");
return;
}
JavaShell.unloadShell(args[2]);
MsgUtils.send(sender, "脚本 " + args[2] + " 已卸载");
}
@Override
public boolean command() {
return true;
}
}

View File

@@ -0,0 +1,62 @@
package me.skymc.taboolib.cooldown;
import java.util.HashMap;
import org.bukkit.plugin.Plugin;
@Deprecated
public class CooldownPack {
private String plugin;
private String name;
private int seconds;
private HashMap<String, Long> data = new HashMap<>();
public CooldownPack(String n, int s) {
this.name = n;
this.seconds = s;
this.plugin = "null";
}
public String getPackName() {
return name;
}
public int getPackSeconds() {
return seconds;
}
public String getPlugin() {
return plugin;
}
public void setPlugin(String p) {
this.plugin = p;
}
public void unRegister(String player) {
data.remove(player);
}
public int getCooldown(String player) {
if (!data.containsKey(player)) {
return 0;
}
int difference = (int) ((System.currentTimeMillis() - data.get(player)) / 1000);
return difference >= seconds ? 0 : seconds - difference;
}
public boolean isCooldown(String player, int cutseconds) {
if (!data.containsKey(player)) {
data.put(player, System.currentTimeMillis());
return false;
}
if ((getCooldown(player) - (cutseconds*1000)) <= 0) {
data.put(player, System.currentTimeMillis());
return false;
}
return true;
}
}

View File

@@ -0,0 +1,60 @@
package me.skymc.taboolib.cooldown;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin;
import me.skymc.taboolib.message.MsgUtils;
@Deprecated
public class CooldownUtils implements Listener {
private static ConcurrentHashMap<String, CooldownPack> packlist = new ConcurrentHashMap<>();
public static void register(CooldownPack pack) {
packlist.put(pack.getPackName(), pack);
MsgUtils.send("注册冷却包: " + pack.getPackName() + ", 时间: " + pack.getPackSeconds() + " 秒 (匿名注册)");
}
public static void register(CooldownPack pack, Plugin plugin) {
pack.setPlugin(plugin.getName());
packlist.put(pack.getPackName(), pack);
MsgUtils.send("注册冷却包: " + pack.getPackName() + ", 时间: " + pack.getPackSeconds() + " 秒 (" + plugin.getName() + ")");
}
public static void unregister(String name) {
packlist.remove(name);
MsgUtils.send("注销冷却包: " + name + " (主动注销)");
}
@EventHandler
public void quit(PlayerQuitEvent e) {
for (CooldownPack pack : packlist.values()) {
if (!pack.isCooldown(e.getPlayer().getName(), 0)) {
pack.unRegister(e.getPlayer().getName());
}
}
}
@EventHandler
public void disable(PluginDisableEvent e) {
for (CooldownPack pack : packlist.values()) {
if (pack.getPlugin().equals(e.getPlugin().getName())) {
packlist.remove(pack.getPackName());
MsgUtils.send("注销冷却包: " + pack.getPackName() + " (自动注销)");
}
}
}
}

View File

@@ -0,0 +1,61 @@
package me.skymc.taboolib.cooldown.seconds;
import java.util.HashMap;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
public class CooldownPack2 {
private String plugin;
private String name;
private int seconds;
private HashMap<String, Long> data = new HashMap<>();
public CooldownPack2(String n, int s) {
this.name = n;
this.seconds = s;
this.plugin = "null";
}
public String getPackName() {
return name;
}
public int getPackSeconds() {
return seconds;
}
public String getPlugin() {
return plugin;
}
public void setPlugin(String p) {
this.plugin = p;
}
public void unRegister(String player) {
data.remove(player);
}
public int getCooldown(String player, int cutseconds) {
if (!data.containsKey(player)) {
return 0;
}
int difference = (int) ((System.currentTimeMillis() + cutseconds) - data.get(player));
return difference >= seconds ? 0 : seconds - difference;
}
public boolean isCooldown(String player, int cutseconds) {
if (!data.containsKey(player)) {
data.put(player, System.currentTimeMillis());
return false;
}
if (getCooldown(player, cutseconds) <= 0) {
data.put(player, System.currentTimeMillis());
return false;
}
return true;
}
}

View File

@@ -0,0 +1,63 @@
package me.skymc.taboolib.cooldown.seconds;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin;
import me.skymc.taboolib.message.MsgUtils;
public class CooldownUtils2 implements Listener {
private static ConcurrentHashMap<String, CooldownPack2> packlist = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, CooldownPack2> getCooldownPacks() {
return packlist;
}
public static void register(CooldownPack2 pack) {
packlist.put(pack.getPackName(), pack);
// MsgUtils.send("注册冷却包: " + pack.getPackName() + ", 时间: " + pack.getPackSeconds() + " 秒 (匿名注册)");
}
public static void register(CooldownPack2 pack, Plugin plugin) {
pack.setPlugin(plugin.getName());
packlist.put(pack.getPackName(), pack);
// MsgUtils.send("注册冷却包: " + pack.getPackName() + ", 时间: " + pack.getPackSeconds() + " 秒 (" + plugin.getName() + ")");
}
public static void unregister(String name) {
packlist.remove(name);
// MsgUtils.send("注销冷却包: " + name + " (主动注销)");
}
@EventHandler
public void quit(PlayerQuitEvent e) {
for (CooldownPack2 pack : packlist.values()) {
if (!pack.isCooldown(e.getPlayer().getName(), 0)) {
pack.unRegister(e.getPlayer().getName());
}
}
}
@EventHandler
public void disable(PluginDisableEvent e) {
for (CooldownPack2 pack : packlist.values()) {
if (pack.getPlugin().equals(e.getPlugin().getName())) {
packlist.remove(pack.getPackName());
// MsgUtils.send("注销冷却包: " + pack.getPackName() + " (自动注销)");
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,327 @@
package me.skymc.taboolib.csvutils;
import java.nio.charset.*;
import java.io.*;
public class CsvWriter
{
private Writer outputStream;
private String fileName;
private boolean firstColumn;
private boolean useCustomRecordDelimiter;
private Charset charset;
private UserSettings userSettings;
private boolean initialized;
private boolean closed;
private String systemRecordDelimiter;
public static final int ESCAPE_MODE_DOUBLED = 1;
public static final int ESCAPE_MODE_BACKSLASH = 2;
public CsvWriter(final String fileName, final char delimiter, final Charset charset) {
this.outputStream = null;
this.fileName = null;
this.firstColumn = true;
this.useCustomRecordDelimiter = false;
this.charset = null;
this.userSettings = new UserSettings();
this.initialized = false;
this.closed = false;
this.systemRecordDelimiter = System.getProperty("line.separator");
if (fileName == null) {
throw new IllegalArgumentException("Parameter fileName can not be null.");
}
if (charset == null) {
throw new IllegalArgumentException("Parameter charset can not be null.");
}
this.fileName = fileName;
this.userSettings.Delimiter = delimiter;
this.charset = charset;
}
public CsvWriter(final String s) {
this(s, ',', Charset.forName("ISO-8859-1"));
}
public CsvWriter(final Writer outputStream, final char delimiter) {
this.outputStream = null;
this.fileName = null;
this.firstColumn = true;
this.useCustomRecordDelimiter = false;
this.charset = null;
this.userSettings = new UserSettings();
this.initialized = false;
this.closed = false;
this.systemRecordDelimiter = System.getProperty("line.separator");
if (outputStream == null) {
throw new IllegalArgumentException("Parameter outputStream can not be null.");
}
this.outputStream = outputStream;
this.userSettings.Delimiter = delimiter;
this.initialized = true;
}
public CsvWriter(final OutputStream outputStream, final char c, final Charset charset) {
this(new OutputStreamWriter(outputStream, charset), c);
}
public char getDelimiter() {
return this.userSettings.Delimiter;
}
public void setDelimiter(final char delimiter) {
this.userSettings.Delimiter = delimiter;
}
public char getRecordDelimiter() {
return this.userSettings.RecordDelimiter;
}
public void setRecordDelimiter(final char recordDelimiter) {
this.useCustomRecordDelimiter = true;
this.userSettings.RecordDelimiter = recordDelimiter;
}
public char getTextQualifier() {
return this.userSettings.TextQualifier;
}
public void setTextQualifier(final char textQualifier) {
this.userSettings.TextQualifier = textQualifier;
}
public boolean getUseTextQualifier() {
return this.userSettings.UseTextQualifier;
}
public void setUseTextQualifier(final boolean useTextQualifier) {
this.userSettings.UseTextQualifier = useTextQualifier;
}
public int getEscapeMode() {
return this.userSettings.EscapeMode;
}
public void setEscapeMode(final int escapeMode) {
this.userSettings.EscapeMode = escapeMode;
}
public void setComment(final char comment) {
this.userSettings.Comment = comment;
}
public char getComment() {
return this.userSettings.Comment;
}
public boolean getForceQualifier() {
return this.userSettings.ForceQualifier;
}
public void setForceQualifier(final boolean forceQualifier) {
this.userSettings.ForceQualifier = forceQualifier;
}
public void write(String s, final boolean b) throws IOException {
this.checkClosed();
this.checkInit();
if (s == null) {
s = "";
}
if (!this.firstColumn) {
this.outputStream.write(this.userSettings.Delimiter);
}
int forceQualifier = this.userSettings.ForceQualifier ? 1 : 0;
if (!b && s.length() > 0) {
s = s.trim();
}
if (forceQualifier == 0 && this.userSettings.UseTextQualifier && (s.indexOf(this.userSettings.TextQualifier) > -1 || s.indexOf(this.userSettings.Delimiter) > -1 || (!this.useCustomRecordDelimiter && (s.indexOf(10) > -1 || s.indexOf(13) > -1)) || (this.useCustomRecordDelimiter && s.indexOf(this.userSettings.RecordDelimiter) > -1) || (this.firstColumn && s.length() > 0 && s.charAt(0) == this.userSettings.Comment) || (this.firstColumn && s.length() == 0))) {
forceQualifier = 1;
}
if (this.userSettings.UseTextQualifier && forceQualifier == 0 && s.length() > 0 && b) {
final char char1 = s.charAt(0);
if (char1 == ' ' || char1 == '\t') {
forceQualifier = 1;
}
if (forceQualifier == 0 && s.length() > 1) {
final char char2 = s.charAt(s.length() - 1);
if (char2 == ' ' || char2 == '\t') {
forceQualifier = 1;
}
}
}
if (forceQualifier != 0) {
this.outputStream.write(this.userSettings.TextQualifier);
if (this.userSettings.EscapeMode == 2) {
s = replace(s, "\\", "\\\\");
s = replace(s, "" + this.userSettings.TextQualifier, "\\" + this.userSettings.TextQualifier);
}
else {
s = replace(s, "" + this.userSettings.TextQualifier, "" + this.userSettings.TextQualifier + this.userSettings.TextQualifier);
}
}
else if (this.userSettings.EscapeMode == 2) {
s = replace(s, "\\", "\\\\");
s = replace(s, "" + this.userSettings.Delimiter, "\\" + this.userSettings.Delimiter);
if (this.useCustomRecordDelimiter) {
s = replace(s, "" + this.userSettings.RecordDelimiter, "\\" + this.userSettings.RecordDelimiter);
}
else {
s = replace(s, "\r", "\\\r");
s = replace(s, "\n", "\\\n");
}
if (this.firstColumn && s.length() > 0 && s.charAt(0) == this.userSettings.Comment) {
if (s.length() > 1) {
s = "\\" + this.userSettings.Comment + s.substring(1);
}
else {
s = "\\" + this.userSettings.Comment;
}
}
}
this.outputStream.write(s);
if (forceQualifier != 0) {
this.outputStream.write(this.userSettings.TextQualifier);
}
this.firstColumn = false;
}
public void write(final String s) throws IOException {
this.write(s, false);
}
public void writeComment(final String s) throws IOException {
this.checkClosed();
this.checkInit();
this.outputStream.write(this.userSettings.Comment);
this.outputStream.write(s);
if (this.useCustomRecordDelimiter) {
this.outputStream.write(this.userSettings.RecordDelimiter);
}
else {
this.outputStream.write(this.systemRecordDelimiter);
}
this.firstColumn = true;
}
public void writeRecord(final String[] array, final boolean b) throws IOException {
if (array != null && array.length > 0) {
for (int i = 0; i < array.length; ++i) {
this.write(array[i], b);
}
this.endRecord();
}
}
public void writeRecord(final String[] array) throws IOException {
this.writeRecord(array, false);
}
public void endRecord() throws IOException {
this.checkClosed();
this.checkInit();
if (this.useCustomRecordDelimiter) {
this.outputStream.write(this.userSettings.RecordDelimiter);
}
else {
this.outputStream.write(this.systemRecordDelimiter);
}
this.firstColumn = true;
}
private void checkInit() throws IOException {
if (!this.initialized) {
if (this.fileName != null) {
this.outputStream = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.fileName), this.charset));
}
this.initialized = true;
}
}
public void flush() throws IOException {
this.outputStream.flush();
}
public void close() {
if (!this.closed) {
this.close(true);
this.closed = true;
}
}
private void close(final boolean b) {
if (!this.closed) {
if (b) {
this.charset = null;
}
try {
if (this.initialized) {
this.outputStream.close();
}
}
catch (Exception ex) {}
this.outputStream = null;
this.closed = true;
}
}
private void checkClosed() throws IOException {
if (this.closed) {
throw new IOException("This instance of the CsvWriter class has already been closed.");
}
}
protected void finalize() {
this.close(false);
}
public static String replace(final String s, final String s2, final String s3) {
final int length = s2.length();
int i = s.indexOf(s2);
if (i > -1) {
final StringBuffer sb = new StringBuffer();
int n;
for (n = 0; i != -1; i = s.indexOf(s2, n)) {
sb.append(s.substring(n, i));
sb.append(s3);
n = i + length;
}
sb.append(s.substring(n));
return sb.toString();
}
return s;
}
private class UserSettings
{
public char TextQualifier;
public boolean UseTextQualifier;
public char Delimiter;
public char RecordDelimiter;
public char Comment;
public int EscapeMode;
public boolean ForceQualifier;
public UserSettings() {
this.TextQualifier = '\"';
this.UseTextQualifier = true;
this.Delimiter = ',';
this.RecordDelimiter = '\0';
this.Comment = '#';
this.EscapeMode = 1;
this.ForceQualifier = false;
}
}
private class Letters
{
public static final char LF = '\n';
public static final char CR = '\r';
public static final char QUOTE = '\"';
public static final char COMMA = ',';
public static final char SPACE = ' ';
public static final char TAB = '\t';
public static final char POUND = '#';
public static final char BACKSLASH = '\\';
public static final char NULL = '\0';
}
}

View File

@@ -0,0 +1,73 @@
package me.skymc.taboolib.damage;
import java.lang.reflect.InvocationTargetException;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import me.skymc.taboolib.TabooLib;
public class DamageUtils {
public static void damage(Player damager, LivingEntity victim, double damage)
{
dmg(damager, victim, damage);
}
public static void damage(Player damager, Entity victim, double damage)
{
if (victim instanceof LivingEntity) {
dmg(damager, (LivingEntity) victim, damage);
}
}
public static void dmg(LivingEntity paramLivingEntity1, LivingEntity paramLivingEntity2, double paramDouble)
{
if ((paramLivingEntity2.hasMetadata("NPC")) || (paramLivingEntity1.hasMetadata("NPC"))) {
return;
}
Object localObject1 = null;
try
{
localObject1 = paramLivingEntity1.getClass().getDeclaredMethod("getHandle", new Class[0]).invoke(paramLivingEntity1, new Object[0]);
}
catch (IllegalAccessException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException localIllegalAccessException1)
{
return;
}
Object localObject2 = null;
try
{
localObject2 = paramLivingEntity2.getClass().getDeclaredMethod("getHandle", new Class[0]).invoke(paramLivingEntity2, new Object[0]);
}
catch (IllegalAccessException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException localIllegalAccessException2)
{
return;
}
try
{
Class<?> DamageSource = nmsClass("DamageSource");
Object localObject3 = DamageSource.getDeclaredMethod("playerAttack", new Class[] { nmsClass("EntityHuman") }).invoke(DamageSource, new Object[] { localObject1 });
localObject2.getClass().getDeclaredMethod("damageEntity", new Class[] { DamageSource, Float.TYPE }).invoke(localObject2, new Object[] { localObject3, Float.valueOf((float) paramDouble) });
}
catch (IllegalAccessException|IllegalArgumentException|InvocationTargetException|NoSuchMethodException|SecurityException localIllegalAccessException3)
{
return;
}
}
private static Class<?> nmsClass(String paramString)
{
String str = "net.minecraft.server." + TabooLib.getVersion() + "." + paramString;
try {
return Class.forName(str);
} catch (ClassNotFoundException e) {
return null;
}
}
}

View File

@@ -0,0 +1,23 @@
package me.skymc.taboolib.damage;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
public class GetDamager {
public static Player get(EntityDamageByEntityEvent e) {
Player p = null;
if (e.getDamager() instanceof Projectile) {
Projectile arrow = (Projectile) e.getDamager();
if (arrow.getShooter() instanceof Player) {
p = (Player) arrow.getShooter();
}
}
else if (e.getDamager() instanceof Player) {
p = (Player) e.getDamager();
}
return p;
}
}

View File

@@ -0,0 +1,26 @@
package me.skymc.taboolib.damage;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.entity.EntityDeathEvent;
import me.skymc.taboolib.methods.MethodsUtils;
public class GetKiller {
public static Player get(EntityDeathEvent e) {
Player p = null;
if (e.getEntity().getKiller() instanceof Projectile) {
Projectile arrow = (Projectile) e.getEntity().getKiller();
if (arrow.getShooter() instanceof Player) {
p = (Player) arrow.getShooter();
}
}
else if (e.getEntity().getKiller() instanceof Player) {
p = e.getEntity().getKiller();
}
return p;
}
}

View File

@@ -0,0 +1,439 @@
package me.skymc.taboolib.database;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.scheduler.BukkitRunnable;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.Main.StorageType;
import me.skymc.taboolib.playerdata.DataUtils;
public class GlobalDataManager {
public static FileConfiguration data = DataUtils.addPluginData("TabooLibrary-Variable.yml", null);
/**
* 获取变量
*
* @param name 名称
* @param defaultVariable 默认值
* @return
*/
public static String getVariable(String name, String defaultVariable) {
if (Main.getStorageType() == StorageType.SQL) {
Object obj = Main.getConnection().getValueLast(Main.getTablePrefix() + "_plugindata", "name", name, "variable");
return obj != null ? obj.toString().equals("null") ? defaultVariable : obj.toString() : defaultVariable;
}
else {
return data.contains(name.replace(":", "-")) ? data.getString(name.replace(":", "-")) : defaultVariable;
}
}
/**
* 获取缓存变量(该方法仅限数据库储存方式)
*
* @param name 名称
* @param defaultVariable 默认值
* @return
*/
public static String getVariableAsynchronous(String name, String defaultVariable) {
if (Main.getStorageType() == StorageType.SQL) {
SQLVariable variable = SQLMethod.getSQLVariable(name);
return variable == null ? defaultVariable : variable.getVariable().equals("null") ? defaultVariable : variable.getVariable();
}
else {
return getVariable(name, defaultVariable);
}
}
/**
* 设置变量
*
* @param name 名称
* @param variable 变量
*/
public static void setVariable(String name, String variable) {
if (Main.getStorageType() == StorageType.SQL) {
Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, variable == null ? "null" : variable, TabooLib.getServerUID());
}
else {
data.set(name.replace(":", "-"), variable);
}
}
/**
* 设置缓存变量(该方法仅限数据库储存方式)
*
* @param name
* @param variable
*/
public static void setVariableAsynchronous(String name, String variable) {
if (Main.getStorageType() == StorageType.SQL) {
SQLVariable _variable = SQLMethod.contains(name) ? SQLMethod.getSQLVariable(name).setVariable(variable == null ? "null" : variable) : SQLMethod.addSQLVariable(name, variable == null ? "null" : variable);
// 更新数据
SQLMethod.uploadVariable(_variable, true);
}
else {
setVariable(name, variable);
}
}
/**
* 检查变量是否存在
*
* @param name 名称
*/
public static boolean contains(String name) {
if (Main.getStorageType() == StorageType.SQL) {
return getVariable(name, null) == null ? false : true;
}
else {
return data.contains(name.replace(":", "-"));
}
}
/**
* 检查变量是否被缓存(该方法仅限数据库储存方式)
*
* @param name 名称
* @return
*/
public static boolean containsAsynchronous(String name) {
if (Main.getStorageType() == StorageType.SQL) {
return getVariableAsynchronous(name, null) == null ? false : true;
}
else {
return contains(name);
}
}
/**
* 清理所有失效的变量
* 该方法仅限数据库储存时有效
*/
public static void clearInvalidVariables() {
if (Main.getStorageType() == StorageType.SQL) {
HashMap<String, String> map = getVariables();
Main.getConnection().truncateTable(Main.getTablePrefix() + "_plugindata");
for (String name : map.keySet()) {
Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", name, map.get(name), TabooLib.getServerUID());
}
}
}
/**
* 获取所有有效变量
*
* @return
*/
public static HashMap<String, String> getVariables() {
HashMap<String, String> map = new HashMap<>();
if (Main.getStorageType() == StorageType.SQL) {
LinkedList<HashMap<String, Object>> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable");
for (HashMap<String, Object> _map : list) {
if (!_map.get("variable").toString().equals("null")) {
map.put(_map.get("name").toString(), _map.get("variable").toString());
}
}
}
else {
for (String name : data.getConfigurationSection("").getKeys(false)) {
map.put(name, data.getString(name));
}
}
return map;
}
/**
* 获取缓存变量(该方法仅限数据库储存方式)
*
* @return
*/
public static HashMap<String, String> getVariablesAsynchronous() {
if (Main.getStorageType() == StorageType.SQL) {
HashMap<String, String> map = new HashMap<>();
for (SQLVariable variable : SQLMethod.getSQLVariables()) {
if (!variable.getVariable().equals("null")) {
map.put(variable.getName(), variable.getVariable());
}
}
return map;
}
else {
return getVariables();
}
}
/**
* 数据库变量
*
* @author sky
*
*/
public static class SQLVariable {
public String name = "";
public String variable = "";
public String upgradeUID = "";
public SQLVariable(String name, String variable, String upgradeUID) {
this.name = name;
this.variable = variable;
this.upgradeUID = upgradeUID;
}
public String getName() {
return name;
}
public String getVariable() {
return variable;
}
public SQLVariable setVariable(String args) {
this.variable = args;
return this;
}
public String getUpgradeUID() {
return upgradeUID;
}
}
/**
* 数据库方法
*
* @author sky
*
*/
public static class SQLMethod {
private static ConcurrentHashMap<String, SQLVariable> variables = new ConcurrentHashMap<>();
/**
* 获取数据
*
* @param name 名字
*/
public static SQLVariable getSQLVariable(String name) {
return variables.get(name);
}
/**
* 获取所有变量
*
* @return
*/
public static Collection<SQLVariable> getSQLVariables() {
return variables.values();
}
/**
* 添加一个变量
*
* @param name 名字
* @param value 值
* @return
*/
public static SQLVariable addSQLVariable(String name, String value) {
SQLVariable variable = new SQLVariable(name, value, TabooLib.getServerUID());
variables.put(name, variable);
return variable;
}
/**
* 移除一个变量
*
* @param name 名字
* @return
*/
public static SQLVariable removeSQLVariable(String name) {
if (variables.contains(name)) {
variables.get(name).setVariable("null");
}
return variables.get(name);
}
/**
* 是否包含变量
*
* @param name 名字
* @return
*/
public static boolean contains(String name) {
return variables.containsKey(name);
}
/**
* 载入数据库中的所有变量缓存
*
* @param sync 是否异步
*/
public static void loadVariables(boolean sync) {
if (Main.getStorageType() == StorageType.LOCAL) {
return;
}
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
LinkedList<HashMap<String, Object>> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade");
for (HashMap<String, Object> _map : list) {
if (!_map.get("variable").toString().equals("null")) {
variables.put(_map.get("name").toString(), new SQLVariable(_map.get("name").toString(), _map.get("variable").toString(), _map.get("upgrade").toString()));
}
}
}
};
if (sync) {
runnable.runTaskAsynchronously(Main.getInst());
}
else {
runnable.run();
}
}
/**
* 检查当前变量是否被其他服务器更新
*
* @param sync 是否异步
*/
public static void checkVariable(boolean sync) {
if (Main.getStorageType() == StorageType.LOCAL) {
return;
}
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
/**
* 根据正序排列获取所有变量
* 新的变量会覆盖旧的变量
*/
LinkedList<HashMap<String, Object>> list = Main.getConnection().getValues(Main.getTablePrefix() + "_plugindata", "id", -1, false, "name", "variable", "upgrade");
// 循环变量
for (HashMap<String, Object> value : list) {
Object name = value.get("name");
try {
// 如果变量存在
if (variables.containsKey(name)) {
// 如果变量不是由本服更新
if (!value.get("upgrade").equals(variables.get(name).getUpgradeUID())) {
// 如果变量是空
if (value.get("variable").equals("null")) {
// 删除变量
variables.remove(name);
}
else {
// 更新变量
variables.get(name).setVariable(value.get("variable").toString());
}
}
}
// 如果变量存在则下载到本地
else if (!value.get("variable").equals("null")) {
variables.put(value.get("name").toString(), new SQLVariable(value.get("name").toString(), value.get("variable").toString(), value.get("upgrade").toString()));
}
}
catch (Exception e) {
// 移除
variables.remove(name);
// 提示
MsgUtils.warn("变量出现异常: &4" + name);
MsgUtils.warn("原因: &4" + e.getMessage());
}
}
}
};
if (sync) {
runnable.runTaskAsynchronously(Main.getInst());
}
else {
runnable.run();
}
}
/**
* 向数据库上传所有数据
*
* @param sync 是否异步
*/
public static void uploadVariables(boolean sync) {
if (Main.getStorageType() == StorageType.LOCAL) {
return;
}
for (SQLVariable variable : variables.values()) {
uploadVariable(variable, sync);
}
}
/**
* 向数据库上传当前数据
*
* @param variable 数据
* @param sync 是否异步
*/
public static void uploadVariable(SQLVariable variable, boolean sync) {
if (Main.getStorageType() == StorageType.LOCAL) {
return;
}
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
Main.getConnection().intoValue(Main.getTablePrefix() + "_plugindata", variable.getName(), variable.getVariable() == null ? "null" : variable.getVariable(), TabooLib.getServerUID());
}
};
if (sync) {
runnable.runTaskAsynchronously(Main.getInst());
}
else {
runnable.run();
}
}
/**
* 启动数据库储存方法
*
*/
public static void startSQLMethod() {
long time = System.currentTimeMillis();
// 载入数据
loadVariables(false);
// 提示信息
MsgUtils.send("从数据库中获取 &f" + variables.size() + " &7个变量, 耗时: &f" + (System.currentTimeMillis() - time) + " &7(ms)");
// 检查更新
new BukkitRunnable() {
@Override
public void run() {
checkVariable(true);
}
}.runTaskTimerAsynchronously(Main.getInst(), Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20, Main.getInst().getConfig().getInt("PluginData.CHECK-DELAY") * 20);
}
/**
* 结束数据库储存方法
*
*/
public static void cancelSQLMethod() {
// 上传数据
uploadVariables(false);
}
}
}

View File

@@ -0,0 +1,270 @@
package me.skymc.taboolib.database;
import java.io.File;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.Main.StorageType;
import me.skymc.taboolib.events.PlayerLoadedEvent;
import me.skymc.taboolib.exception.PlayerOfflineException;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.fileutils.FileUtils;
import me.skymc.taboolib.message.MsgUtils;
public class PlayerDataManager implements Listener {
private static final ConcurrentHashMap<String, FileConfiguration> PLAYER_DATA = new ConcurrentHashMap<>();
public static enum UsernameType {
UUID, USERNAME;
}
/**
* 获取用户储存方式
*
* @return
*/
public static UsernameType getUsernameType() {
return Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? UsernameType.UUID : UsernameType.USERNAME;
}
/**
* 获取玩家数据
*
* @param player 玩家
* @return
* @throws PlayerOfflineException
*/
public static FileConfiguration getPlayerData(Player player) {
if (getUsernameType() == UsernameType.UUID) {
return getPlayerData(player.getUniqueId().toString(), false);
}
else {
return getPlayerData(player.getName(), false);
}
}
/**
* 获取玩家数据
*
* @param player
* @return
*/
public static FileConfiguration getPlayerData(OfflinePlayer player) {
if (!player.isOnline()) {
return null;
}
if (getUsernameType() == UsernameType.UUID) {
return getPlayerData(player.getUniqueId().toString(), false);
}
else {
return getPlayerData(player.getName(), false);
}
}
/**
* 读取玩家数据
*
* @param username 玩家
* @return
* @throws PlayerOfflineException
*/
public static FileConfiguration getPlayerData(String username, boolean offline) {
if (PLAYER_DATA.containsKey(username)) {
return PLAYER_DATA.get(username);
}
else if (offline) {
if (Main.getStorageType() == StorageType.SQL) {
throw new PlayerOfflineException("不允许在储存模式为数据库的情况下获取离线玩家数据");
}
return loadPlayerData(username);
}
return null;
}
/**
* 载入玩家数据
*
* @param username 玩家
* @return
*/
public static FileConfiguration loadPlayerData(String username) {
// 本地储存
if (Main.getStorageType() == StorageType.LOCAL) {
// 读取文件
File file = FileUtils.file(Main.getPlayerDataFolder(), username + ".yml");
// 载入配置
PLAYER_DATA.put(username, YamlConfiguration.loadConfiguration(file));
}
else {
// 数据是否存在
if (Main.getConnection().isExists(Main.getTablePrefix() + "_playerdata", "username", username)) {
// 获取数据
String code = Main.getConnection().getValue(Main.getTablePrefix() + "_playerdata", "username", username, "configuration").toString();
try {
// 载入配置
PLAYER_DATA.put(username, ConfigUtils.decodeYAML(code));
}
catch (Exception e) {
// 创建空数据
PLAYER_DATA.put(username, new YamlConfiguration());
// 反馈信息
MsgUtils.warn("玩家 &4" + username + " &c的数据载入出现异常: &4" + e.getMessage());
}
}
else {
// 创建空数据
PLAYER_DATA.put(username, new YamlConfiguration());
}
}
return PLAYER_DATA.get(username);
}
/**
* 保存玩家数据
*
* @param username 玩家
* @param remove 是否移除缓存
*/
public static void savePlayerData(String username, boolean remove) {
// 没有数据
if (!PLAYER_DATA.containsKey(username)) {
return;
}
// 本地储存
if (Main.getStorageType() == StorageType.LOCAL) {
// 读取文件
File file = FileUtils.file(Main.getPlayerDataFolder(), username + ".yml");
// 保存配置
try {
PLAYER_DATA.get(username).save(file);
}
catch (Exception e) {
// TODO: handle exception
}
}
// 如果是数据库储存且有数据
else if (PLAYER_DATA.get(username).getConfigurationSection("").getKeys(false).size() > 0) {
// 数据是否存在
if (Main.getConnection().isExists(Main.getTablePrefix() + "_playerdata", "username", username)) {
// 写入数据
Main.getConnection().setValue(Main.getTablePrefix() + "_playerdata", "username", username, "configuration", ConfigUtils.encodeYAML(PLAYER_DATA.get(username)));
}
else {
// 插入数据
Main.getConnection().intoValue(Main.getTablePrefix() + "_playerdata", username, ConfigUtils.encodeYAML(PLAYER_DATA.get(username)));
}
}
// 获取这个属性对应的玩家
Player player;
if (getUsernameType() == UsernameType.UUID) {
player = Bukkit.getPlayer(UUID.fromString(username));
}
else {
player = Bukkit.getPlayerExact(username);
}
// 如果移除数据 或 玩家不在线
if (remove || player == null) {
PLAYER_DATA.remove(username);
}
}
/**
* 保存所有玩家的缓存
*
* @param sync 是否异步进行
* @param remove 是否移除数据
*/
public static void saveAllCaches(boolean sync, boolean remove) {
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
long time = System.currentTimeMillis();
// 保存
for (String name : PLAYER_DATA.keySet()) {
savePlayerData(name, false);
}
// 提示
if (!Main.getInst().getConfig().getBoolean("HIDE-NOTIFY")) {
MsgUtils.send("保存 &f" + PLAYER_DATA.size() + " &7条玩家数据, 耗时: &f" + (System.currentTimeMillis() - time) + " &7(ms)");
}
}
};
// 如果异步
if (sync) {
runnable.runTaskAsynchronously(Main.getInst());
}
// 如果同步
else {
runnable.run();
}
}
/**
* 保存所有玩家的数据
*
* @param sync 是否异步进行
* @param remove 是否移除数据
*/
public static void saveAllPlayers(boolean sync, boolean remove) {
// 创建任务
BukkitRunnable runnable = new BukkitRunnable() {
@Override
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) {
savePlayerData(Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? player.getUniqueId().toString() : player.getName(), remove);
}
}
};
// 如果异步
if (sync) {
runnable.runTaskAsynchronously(Main.getInst());
}
// 如果同步
else {
runnable.run();
}
}
@EventHandler
public void join(PlayerJoinEvent e) {
new BukkitRunnable() {
@Override
public void run() {
// 载入数据
loadPlayerData(Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? e.getPlayer().getUniqueId().toString() : e.getPlayer().getName());
// 载入完成
Bukkit.getPluginManager().callEvent(new PlayerLoadedEvent(e.getPlayer()));
}
}.runTaskAsynchronously(Main.getInst());
}
@EventHandler
public void quit(PlayerQuitEvent e) {
if (!Main.isDisable()) {
new BukkitRunnable() {
@Override
public void run() {
// 保存数据
savePlayerData(Main.getInst().getConfig().getBoolean("ENABLE-UUID") ? e.getPlayer().getUniqueId().toString() : e.getPlayer().getName(), true);
}
}.runTaskAsynchronously(Main.getInst());
}
}
}

View File

@@ -0,0 +1,66 @@
package me.skymc.taboolib.display;
import java.lang.reflect.Constructor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import me.skymc.taboolib.TabooLib;
public class ActionUtils {
private static void sendPacket(Player player, Object packet)
{
try
{
Object handle = player.getClass().getMethod("getHandle", new Class[0]).invoke(player, new Object[0]);
Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
playerConnection.getClass().getMethod("sendPacket", new Class[] { getNMSClass("Packet") }).invoke(playerConnection, new Object[] { packet });
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
private static Class<?> getNMSClass(String class_name)
{
String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
try
{
return Class.forName("net.minecraft.server." + version + "." + class_name);
}
catch (ClassNotFoundException ex)
{
ex.printStackTrace();
}
return null;
}
public static void send(Player p, String msg)
{
if (msg == null) {
msg = "";
}
try
{
Object ab = getNMSClass("ChatComponentText").getConstructor(new Class[] { String.class }).newInstance(new Object[] { msg });
Constructor<?> ac = null;
Object abPacket = null;
// 如果版本大于 1.11.0
if (TabooLib.getVerint() > 11100) {
Class<?> chatMessageType = getNMSClass("ChatMessageType");
ac = getNMSClass("PacketPlayOutChat").getConstructor(getNMSClass("IChatBaseComponent"), chatMessageType);
abPacket = ac.newInstance(ab, chatMessageType.getMethod("a", Byte.TYPE).invoke(null, (byte) 2));
} else {
ac = getNMSClass("PacketPlayOutChat").getConstructor(getNMSClass("IChatBaseComponent"), Byte.TYPE);
abPacket = ac.newInstance(ab, Byte.valueOf((byte) 2));
}
sendPacket(p, abPacket);
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}

View File

@@ -0,0 +1,87 @@
package me.skymc.taboolib.display;
import java.lang.reflect.Constructor;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import me.skymc.taboolib.methods.MethodsUtils;
public class TitleUtils {
private static void sendPacket(Player player, Object packet)
{
try
{
Object handle = player.getClass().getMethod("getHandle", new Class[0]).invoke(player, new Object[0]);
Object playerConnection = handle.getClass().getField("playerConnection").get(handle);
playerConnection.getClass().getMethod("sendPacket", new Class[] { getNMSClass("Packet") }).invoke(playerConnection, new Object[] { packet });
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
private static Class<?> getNMSClass(String class_name)
{
String version = org.bukkit.Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
try
{
return Class.forName("net.minecraft.server." + version + "." + class_name);
}
catch (ClassNotFoundException ex)
{
ex.printStackTrace();
}
return null;
}
public static void sendTitle(Player p, String title, String subtitle, int fadein, int stay, int fadeout) {
sendTitle(p, title, fadein, stay, fadeout, subtitle, fadein, stay, fadeout);
}
public static void sendTitle(Player p, String title, int fadeint, int stayt, int fadeoutt, String subtitle, int fadeinst, int stayst, int fadeoutst)
{
if (title == null) {
title = "";
}
if (subtitle == null) {
subtitle = "";
}
try
{
if (title != null)
{
Object e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TIMES").get(null);
Object chatTitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[] { String.class }).invoke(null, new Object[] { "{\"text\":\"" + title + "\"}" });
Constructor<?> subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(new Class[] { getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE });
Object titlePacket = subtitleConstructor.newInstance(new Object[] { e, chatTitle, Integer.valueOf(fadeint), Integer.valueOf(stayt), Integer.valueOf(fadeoutt) });
sendPacket(p, titlePacket);
e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TITLE").get(null);
chatTitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[] { String.class }).invoke(null, new Object[] { "{\"text\":\"" + title + "\"}" });
subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(new Class[] { getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent") });
titlePacket = subtitleConstructor.newInstance(new Object[] { e, chatTitle });
sendPacket(p, titlePacket);
}
if (subtitle != null)
{
Object e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("TIMES").get(null);
Object chatSubtitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[] { String.class }).invoke(null, new Object[] { "{\"text\":\"" + title + "\"}" });
Constructor<?> subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(new Class[] { getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE });
Object subtitlePacket = subtitleConstructor.newInstance(new Object[] { e, chatSubtitle, Integer.valueOf(fadeinst), Integer.valueOf(stayst), Integer.valueOf(fadeoutst) });
sendPacket(p, subtitlePacket);
e = getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0].getField("SUBTITLE").get(null);
chatSubtitle = getNMSClass("IChatBaseComponent").getDeclaredClasses()[0].getMethod("a", new Class[] { String.class }).invoke(null, new Object[] { "{\"text\":\"" + subtitle + "\"}" });
subtitleConstructor = getNMSClass("PacketPlayOutTitle").getConstructor(new Class[] { getNMSClass("PacketPlayOutTitle").getDeclaredClasses()[0], getNMSClass("IChatBaseComponent"), Integer.TYPE, Integer.TYPE, Integer.TYPE });
subtitlePacket = subtitleConstructor.newInstance(new Object[] { e, chatSubtitle, Integer.valueOf(fadeinst), Integer.valueOf(stayst), Integer.valueOf(fadeoutst) });
sendPacket(p, subtitlePacket);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}

View File

@@ -0,0 +1,34 @@
package me.skymc.taboolib.economy;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.RegisteredServiceProvider;
import me.skymc.taboolib.Main;
import net.milkbowl.vault.economy.Economy;
public class EcoUtils {
public static void setupEconomy() {
RegisteredServiceProvider<Economy> l = Bukkit.getServer().getServicesManager().getRegistration(Economy.class);
if (l != null) {
Main.setEconomy(l.getProvider());
}
}
public static void remove(OfflinePlayer p, double d) {
Main.getEconomy().withdrawPlayer(p, d);
}
public static void add(OfflinePlayer p, double d) {
Main.getEconomy().depositPlayer(p, d);
}
public static double get(OfflinePlayer p) {
return Main.getEconomy().getBalance(p);
}
public static void create(OfflinePlayer p) {
Main.getEconomy().createPlayerAccount(p);
}
}

View File

@@ -0,0 +1,19 @@
package me.skymc.taboolib.enchantment;
import java.lang.reflect.Field;
import org.bukkit.enchantments.Enchantment;
public class EnchantmentUtils {
public static void setAcceptingNew(boolean value) {
try {
Field f = Enchantment.class.getDeclaredField("acceptingNew");
f.setAccessible(true);
f.set(null, value);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,92 @@
package me.skymc.taboolib.entity;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntitySpawnEvent;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import me.skymc.taboolib.methods.MethodsUtils;
public class EntityUtils implements Listener{
public static Entity lastSpawned = null;
@EventHandler
public void spawn(EntitySpawnEvent e) {
lastSpawned = e.getEntity();
}
public static Entity getEntityWithUUID(UUID u) {
for (World w : Bukkit.getWorlds()) {
for (Entity e : w.getLivingEntities()) {
if (e.getUniqueId().equals(u)) {
return e;
}
}
}
return null;
}
public static Entity getEntityWithUUID_World(UUID u, World world) {
for (Entity e : world.getLivingEntities()) {
if (e.getUniqueId().equals(u)) {
return e;
}
}
return null;
}
/**
* 设置生物发光ProcotolLib
*
* @param player
* @param entity
*/
public static void addGlow(Player player,Entity entity) {
PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
packet.getIntegers().write(0, entity.getEntityId());
WrappedDataWatcher watcher = new WrappedDataWatcher();
WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class);
watcher.setEntity(player);
watcher.setObject(0, serializer, (byte) (0x40));
packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects());
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* 取消生物发光ProcotolLib
*
* @param player
* @param entity
*/
public static void delGlow(Player player,Entity entity) {
PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
packet.getIntegers().write(0, entity.getEntityId());
WrappedDataWatcher watcher = new WrappedDataWatcher();
WrappedDataWatcher.Serializer serializer = WrappedDataWatcher.Registry.get(Byte.class);
watcher.setEntity(player);
watcher.setObject(0, serializer, (byte) (0x0));
packet.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects());
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,60 @@
package me.skymc.taboolib.events;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.inventory.ItemStack;
/**
* The event called when a book is opened trough this Util
*/
public class CustomBookOpenEvent extends Event implements Cancellable {
private static final HandlerList handlers = new HandlerList();
@Getter
@Setter
private boolean cancelled;
/**
* The player
*/
@Getter
private final Player player;
/**
* The hand used to open the book (the previous item will be restored after the opening)
*/
@Getter
@Setter
private Hand hand;
/**
* The actual book to be opened
*/
@Getter
@Setter
private ItemStack book;
public CustomBookOpenEvent(Player player, ItemStack book, boolean offHand) {
this.player = player;
this.book = book;
this.hand = offHand ? Hand.OFF_HAND : Hand.MAIN_HAND;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public enum Hand {
MAIN_HAND, OFF_HAND
}
}

View File

@@ -0,0 +1,28 @@
package me.skymc.taboolib.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class DefaultEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Player player;
public DefaultEvent(Player player) {
this.player = player;
}
public Player getPlayer() {
return this.player;
}
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,51 @@
package me.skymc.taboolib.events;
import org.bukkit.event.player.*;
import org.bukkit.entity.*;
import org.bukkit.event.*;
public class DefaultEvent2 extends PlayerEvent
{
private static final HandlerList handlers;
static {
handlers = new HandlerList();
}
private DefaultEvent2(final Player who) {
super(who);
}
public static HandlerList getHandlerList() {
return DefaultEvent2.handlers;
}
public HandlerList getHandlers() {
return DefaultEvent2.handlers;
}
public static class Pre extends DefaultEvent2 implements Cancellable
{
private boolean cancelled;
public Pre(Player who) {
super(who);
this.cancelled = false;
}
public boolean isCancelled() {
return this.cancelled;
}
public void setCancelled(final boolean cancelled) {
this.cancelled = cancelled;
}
}
public static class Post extends DefaultEvent2
{
public Post(Player who) {
super(who);
}
}
}

View File

@@ -0,0 +1,46 @@
package me.skymc.taboolib.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerJumpEvent
extends Event
implements Cancellable
{
private static final HandlerList handlers = new HandlerList();
private boolean isCancelled;
private Player player;
public PlayerJumpEvent(boolean b, Player player)
{
this.isCancelled = false;
this.player = player;
}
public Player getPlayer()
{
return this.player;
}
public boolean isCancelled()
{
return this.isCancelled;
}
public void setCancelled(boolean e)
{
this.isCancelled = e;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
}

View File

@@ -0,0 +1,29 @@
package me.skymc.taboolib.events;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class PlayerLoadedEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Player player;
public PlayerLoadedEvent(Player player) {
super(true);
this.player = player;
}
public Player getPlayer() {
return this.player;
}
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@@ -0,0 +1,10 @@
package me.skymc.taboolib.exception;
public class PlayerOfflineException extends Error {
private static final long serialVersionUID = 4129402767538548807L;
public PlayerOfflineException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,70 @@
package me.skymc.taboolib.fileutils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.HashMap;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import com.google.common.base.Charsets;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.message.MsgUtils;
public class ConfigUtils {
public static FileConfiguration decodeYAML(String args) {
return YamlConfiguration.loadConfiguration(new StringReader(Base64Coder.decodeString(args)));
}
public static String encodeYAML(FileConfiguration file) {
return Base64Coder.encodeLines(file.saveToString().getBytes()).replaceAll("\\s+", "");
}
/**
* 以 UTF-8 的格式释放配置文件并载入
*
* 录入时间2018年2月10日21:28:30
* 录入版本3.49
*
* @param plugin
* @return
*/
public static FileConfiguration saveDefaultConfig(Plugin plugin, String name) {
File file = new File(plugin.getDataFolder(), name);
if (!file.exists()) {
plugin.saveResource(name, true);
}
return load(plugin, file);
}
/**
* 以 UTF-8 的格式载入配置文件
*
* @param main
* @param filename
* @return
*/
public static FileConfiguration load(Plugin plugin, File file) {
YamlConfiguration yaml = new YamlConfiguration();
try {
yaml = YamlConfiguration.loadConfiguration(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8));
} catch (FileNotFoundException e) {
MsgUtils.warn("配置文件载入失败!");
MsgUtils.warn("插件: &4" + plugin.getName());
MsgUtils.warn("文件: &4" + file.getName());
}
return yaml;
}
@Deprecated
public static FileConfiguration load(Plugin plugin, String file) {
return load(plugin, FileUtils.file(file));
}
}

View File

@@ -0,0 +1,98 @@
package me.skymc.taboolib.fileutils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import me.skymc.taboolib.methods.MethodsUtils;
public class CopyUtils {
public static long Copy(File file1, File file2) throws IOException {
// CHECK THE FILE
if (!file1.exists()) {
file1.createNewFile();
}
if (!file2.exists()) {
file2.createNewFile();
}
// RESET TIME
long time = System.currentTimeMillis();
// I/O SETTING
FileInputStream in = new FileInputStream(file1);
FileOutputStream out = new FileOutputStream(file2);
FileChannel inC = in.getChannel();
FileChannel outC = out.getChannel();
ByteBuffer b = null;
// CAPACITY [2GB]
Integer length = 2097152;
// WORKSPACE
while (true) {
if (inC.position() == inC.size()) {
inC.close();
outC.close();
return System.currentTimeMillis() - time;
}
if ((inC.size() - inC.position()) < length) {
length = (int) (inC.size()-inC.position());
}
else {
length = 2097152;
}
b = ByteBuffer.allocateDirect(length);
inC.read(b);
b.flip();
outC.write(b);
outC.force(false);
}
}
public static long Copy(FileInputStream in, File file2) throws IOException {
// CHECK THE FILE
if (!file2.exists()) {
file2.createNewFile();
}
// RESET TIME
long time = System.currentTimeMillis();
// I/O SETTING
FileOutputStream out = new FileOutputStream(file2);
FileChannel inC = in.getChannel();
FileChannel outC = out.getChannel();
ByteBuffer b = null;
// CAPACITY [2GB]
Integer length = 2097152;
// WORKSPACE
while (true) {
if (inC.position() == inC.size()) {
inC.close();
outC.close();
return System.currentTimeMillis() - time;
}
if ((inC.size() - inC.position()) < length) {
length = (int) (inC.size()-inC.position());
}
else {
length = 2097152;
}
b = ByteBuffer.allocateDirect(length);
inC.read(b);
b.flip();
outC.write(b);
outC.force(false);
}
}
}

View File

@@ -0,0 +1,124 @@
package me.skymc.taboolib.fileutils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
public class EncodeUtils {
/**
* 把指定文件或目录转换成指定的编码
*
* @param fileName 要转换的文件
* @param fromCharsetName 源文件的编码
* @param toCharsetName 要转换的编码
* @throws Exception
*/
public static void convert(String fileName, String fromCharsetName, String toCharsetName) throws Exception {
convert(new File(fileName), fromCharsetName, toCharsetName, null);
}
/**
* 把指定文件或目录转换成指定的编码
*
* @param file 要转换的文件或目录
* @param fromCharsetName 源文件的编码
* @param toCharsetName 要转换的编码
* @throws Exception
*/
public static void convert(File file, String fromCharsetName, String toCharsetName) throws Exception {
convert(file, fromCharsetName, toCharsetName, null);
}
/**
* 把指定文件或目录转换成指定的编码
*
* @param file 要转换的文件或目录
* @param fromCharsetName 源文件的编码
* @param toCharsetName 转换的编码
* @param filter 文件名过滤器
* @throws Exception
*/
public static void convert(String fileName, String fromCharsetName, String toCharsetName, FilenameFilter filter) throws Exception {
convert(new File(fileName), fromCharsetName, toCharsetName, filter);
}
/**
* 把指定文件或目录转换成指定的编码
*
* @param file 要转换的文件或目录
* @param fromCharsetName 源文件的编码
* @param toCharsetName 要转换的编码
* @param filter 文件名过滤器
* @throws Exception
*/
public static void convert(File file, String fromCharsetName, String toCharsetName, FilenameFilter filter) throws Exception {
if (file.isDirectory()) {
File[] fileList = null;
if (filter == null) {
fileList = file.listFiles();
} else {
fileList = file.listFiles(filter);
}
for (File f : fileList) {
convert(f, fromCharsetName, toCharsetName, filter);
}
} else {
if (filter == null
|| filter.accept(file.getParentFile(), file.getName())) {
String fileContent = getFileContentFromCharset(file,
fromCharsetName);
saveFile2Charset(file, toCharsetName, fileContent);
}
}
}
/**
* 以指定编码方式读取文件,返回文件内容
*
* @param file 要转换的文件
* @param fromCharsetName 源文件的编码
* @return
* @throws Exception
*/
public static String getFileContentFromCharset(File file, String fromCharsetName) throws Exception {
if (!Charset.isSupported(fromCharsetName)) {
throw new UnsupportedCharsetException(fromCharsetName);
}
InputStream inputStream = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(inputStream,
fromCharsetName);
char[] chs = new char[(int) file.length()];
reader.read(chs);
String str = new String(chs).trim();
reader.close();
return str;
}
/**
* 以指定编码方式写文本文件,存在会覆盖
*
* @param file 要写入的文件
* @param toCharsetName 要转换的编码
* @param content 文件内容
* @throws Exception
*/
public static void saveFile2Charset(File file, String toCharsetName, String content) throws Exception {
if (!Charset.isSupported(toCharsetName)) {
throw new UnsupportedCharsetException(toCharsetName);
}
OutputStream outputStream = new FileOutputStream(file);
OutputStreamWriter outWrite = new OutputStreamWriter(outputStream, toCharsetName);
outWrite.write(content);
outWrite.close();
System.out.println("[Encodeing...] 更改文件: " + file.getPath());
}
}

View File

@@ -0,0 +1,203 @@
package me.skymc.taboolib.fileutils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import me.skymc.taboolib.message.MsgUtils;
public class FileUtils {
public static String ip() {
try {
InputStream ins = null;
URL url = new URL("http://1212.ip138.com/ic.asp");
URLConnection con = url.openConnection();
ins = con.getInputStream();
InputStreamReader isReader = new InputStreamReader(ins, "GB2312");
BufferedReader bReader = new BufferedReader(isReader);
StringBuffer webContent = new StringBuffer();
String str = null;
while ((str = bReader.readLine()) != null) {
webContent.append(str);
}
int start = webContent.indexOf("[") + 1;
int end = webContent.indexOf("]");
ins.close();
return webContent.substring(start, end);
}
catch (Exception e) {
// TODO: handle exception
}
return "[IP ERROR]";
}
public static File file(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
return file;
}
public static File file(File Path, String filePath) {
File file = new File(Path, filePath);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
return file;
}
public static String getStringFromInputStream(InputStream in, int size, String encode) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[size];
int i = 0;
while ((i = in.read(b)) > 0) {
bos.write(b, 0, i);
}
bos.close();
return new String(bos.toByteArray(), encode);
} catch (IOException e) {
MsgUtils.warn("输入流读取出错: &4" + e.getMessage());
}
return null;
}
public static String getStringFromFile(File file, int size, String encode) {
try {
FileInputStream fin = new FileInputStream(file);
BufferedInputStream bin = new BufferedInputStream(fin);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[size];
int i = 0;
while ((i = bin.read(b)) > 0) {
bos.write(b, 0, i);
}
bos.close();
bin.close();
fin.close();
return new String(bos.toByteArray(), encode);
} catch (IOException e) {
MsgUtils.warn("文件读取出错: &4" + e.getMessage());
}
return null;
}
public static String getStringFromURL(String url, int size) {
try {
URLConnection conn = new URL(url).openConnection();
BufferedInputStream bin = new BufferedInputStream(conn.getInputStream());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[size];
int i = 0;
while ((i = bin.read(b)) > 0) {
bos.write(b, 0, i);
}
bos.close();
bin.close();
return new String(bos.toByteArray(), conn.getContentEncoding() == null ? "UTF-8" : conn.getContentEncoding());
} catch (IOException e) {
MsgUtils.warn("网络访问出错: &4" + e.getMessage());
}
return null;
}
/**
* Write a UTF8 file
*
* @param strs list of lines
* @param f file to write
*
*/
public FileUtils(List<String> strs, File f) throws IOException
{
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(f), "UTF8"));
for(String s : strs) {
out.write(s+"\n");
}
out.flush();
out.close();
}
public FileUtils(String str, File f) throws IOException
{
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(f), "UTF8"));
out.write(str);
out.flush();
out.close();
}
public static void download(String urlStr, String filename, File saveDir) {
try {
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 超时时间
conn.setConnectTimeout(5 * 1000);
// 防止屏蔽程序抓取而返回 403 错误
conn.setRequestProperty("User-Agent", "Mozilla/31.0 (compatible; MSIE 10.0; Windows NT; DigExt)");
// 得到输入流
InputStream inputStream = conn.getInputStream();
// 获取数组
byte[] data = read(inputStream);
// 创建文件夹
if (!saveDir.exists()) {
saveDir.mkdirs();
}
// 保存文件
File file = new File(saveDir, filename);
FileOutputStream fos = new FileOutputStream(file);
// 写入文件
fos.write(data);
// 结束
fos.close();
inputStream.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] read(InputStream in) {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
while((len = in.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
}
catch (Exception e) {
e.printStackTrace();
}
return bos.toByteArray();
}
}

View File

@@ -0,0 +1,60 @@
package me.skymc.taboolib.fileutils;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import org.bukkit.plugin.Plugin;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.methods.MethodsUtils;
import me.skymc.taboolib.other.DateUtils;
@Deprecated
public class LogUtils {
public static void Log(String s, String s2)
{
try
{
File file = new File(Main.getInst().getDataFolder(), s2+".txt");
if(!file.exists())
{
file.createNewFile();
}
FileWriter fileWritter = new FileWriter(file, true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
bufferWritter.write(s);
bufferWritter.newLine();
bufferWritter.close();
}
catch (Exception e)
{
Main.getInst().getLogger().warning(s2+":"+s);
}
}
public static void newLog(Plugin main, String s, String s2)
{
try
{
File file = new File(main.getDataFolder(), s2+".txt");
if(!file.exists())
{
file.createNewFile();
}
FileWriter fileWritter = new FileWriter(file, true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
bufferWritter.write("["+DateUtils.CH_ALL.format(System.currentTimeMillis())+"]"+s);
bufferWritter.newLine();
bufferWritter.close();
}
catch (Exception e)
{
Main.getInst().getLogger().warning(s2+":"+s);
}
}
}

View File

@@ -0,0 +1,51 @@
package me.skymc.taboolib.inventory;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import me.skymc.taboolib.other.NumberUtils;
public class DropUtils {
public static Item drop(Player player, ItemStack itemStack, double bulletSpread, double radius) {
Location location = player.getLocation();
location.setY(location.getY() + 1.5);
Item item = player.getWorld().dropItem(location, itemStack);
double yaw = Math.toRadians(-player.getLocation().getYaw() - 90.0F);
double pitch = Math.toRadians(-player.getLocation().getPitch());
double x = 0;
double y = 0;
double z = 0;
if (bulletSpread > 0) {
double[] spread = { 1.0D, 1.0D, 1.0D };
for (int t = 0; t < 3; t++) {
spread[t] = ((NumberUtils.getRand().nextDouble() - NumberUtils.getRand().nextDouble()) * bulletSpread * 0.1D);
}
x = Math.cos(pitch) * Math.cos(yaw) + spread[0];
y = Math.sin(pitch) + spread[1];
z = -Math.sin(yaw) * Math.cos(pitch) + spread[2];
}
else {
x = Math.cos(pitch) * Math.cos(yaw);
y = Math.sin(pitch);
z = -Math.sin(yaw) * Math.cos(pitch);
}
Vector dirVel = new Vector(x, y, z);
dirVel.normalize().multiply(radius);
item.setVelocity(dirVel);
return item;
}
}

View File

@@ -0,0 +1,140 @@
package me.skymc.taboolib.inventory;
import java.util.Arrays;
import java.util.LinkedList;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import me.skymc.taboolib.methods.MethodsUtils;
public class InventoryUtil {
public final static LinkedList<Integer> SLOT_OF_CENTENTS = new LinkedList<>(Arrays.asList(
10, 11, 12, 13, 14, 15, 16,
19, 20, 21, 22, 23, 24, 25,
28, 29, 30, 31, 32, 33, 34,
37, 38, 39, 40, 41, 42, 43));
@Deprecated
public static boolean isEmpey(Player p) {
return isEmpty(p, 0);
}
/**
* 检查背包是否有空位
*
* @param p 玩家
* @param i 起始位置
*/
public static boolean isEmpty(Player p, int i) {
while (i < 35) {
if (p.getInventory().getItem(i) == null) {
return true;
}
i++;
}
return false;
}
/**
* 检测玩家是否有指定物品
*
* @param player 玩家
* @param item 物品
* @param amount 数量
* @param remove 是否删除
*/
public static boolean hasItem(Player player, ItemStack item, int amount, boolean remove) {
int hasAmount = 0;
for (ItemStack _item : player.getInventory()) {
if (item.isSimilar(_item)) {
hasAmount += _item.getAmount();
}
}
if (hasAmount < amount) {
return false;
}
int requireAmount = amount;
for (int i = 0; i < player.getInventory().getSize() && remove; i++) {
ItemStack _item = player.getInventory().getItem(i);
if (_item != null && _item.isSimilar(item)) {
/**
* 如果循环到的物品数量 小于 需要的数量
* 则 删除物品,减少需要的数量
*/
if (_item.getAmount() < requireAmount) {
player.getInventory().setItem(i, null);
requireAmount -= _item.getAmount();
}
/**
* 如果循环到的物品数量 等于 需要的数量
* 则 删除物品,直接结束
*/
else if (_item.getAmount() == requireAmount) {
player.getInventory().setItem(i, null);
return true;
}
/**
* 如果循环到的物品数量 大于 需要的数量
* 则扣除 需要的数量
*/
else {
_item.setAmount(_item.getAmount() - requireAmount);
return true;
}
}
}
return true;
}
@Deprecated
public static boolean hasItem(Inventory targetInventory, ItemStack targetItem, Integer amount) {
int inventoryAmount = 0;
for (ItemStack item : targetInventory) {
if (item != null) {
if (item.isSimilar(targetItem)) {
inventoryAmount += item.getAmount();
}
}
}
if (inventoryAmount >= amount) {
return true;
}
return false;
}
@Deprecated
public static boolean takeItem2(Inventory inv, ItemStack takeitem, Integer amount) {
for (int i = 0; i < inv.getSize(); ++i) {
if (amount <= 0) {
return true;
}
ItemStack item = inv.getItem(i);
if (item == null) {
continue;
}
if (!item.isSimilar(takeitem)) {
continue;
}
if (item.getAmount() >= amount) {
if (item.getAmount() - amount == 0) {
inv.setItem(i, null);
}
else {
item.setAmount(item.getAmount() - amount);
}
return true;
}
else {
amount -= item.getAmount();
inv.setItem(i, null);
}
}
return false;
}
}

View File

@@ -0,0 +1,608 @@
package me.skymc.taboolib.inventory;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import lombok.Getter;
import me.clip.placeholderapi.PlaceholderAPI;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.fileutils.ConfigUtils;
import me.skymc.taboolib.itemnbtapi.NBTItem;
import me.skymc.taboolib.itemnbtapi.NBTList;
import me.skymc.taboolib.itemnbtapi.NBTListCompound;
import me.skymc.taboolib.itemnbtapi.NBTType;
import me.skymc.taboolib.message.MsgUtils;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.Language;
public class ItemUtils {
@Getter
private static FileConfiguration itemdir = null;
@Getter
private static FileConfiguration itemCache = null;
@Getter
private static File finalItemsFolder;
@Getter
private static LinkedHashMap<String, String> itemlib = new LinkedHashMap<>();
@Getter
private static LinkedHashMap<String, ItemStack> itemCaches = new LinkedHashMap<>();
@Getter
private static LinkedHashMap<String, ItemStack> itemCachesFinal = new LinkedHashMap<>();
/**
* 获取物品缓存
* 检测顺序:
* 1. 固定物品库
* 2. 动态物品库
*
* @param name 物品名称
* @return
*/
public static ItemStack getCacheItem(String name) {
// 检测固定物品库是否存在该物品
if (itemCachesFinal.containsKey(name)) {
return itemCachesFinal.get(name);
}
// 返回动态物品库
return itemCaches.get(name);
}
public static boolean isExists(String name) {
return itemCachesFinal.containsKey(name) || itemCaches.containsKey(name);
}
public static void LoadLib() {
itemdir = YamlConfiguration.loadConfiguration(new File(Main.getInst().getConfig().getString("DATAURL.ITEMDIR")));
reloadItemName();
reloadItemCache();
}
public static void loadItemsFile(File file, boolean finalFile) {
FileConfiguration conf = ConfigUtils.load(Main.getInst(), file);
for (String name : conf.getConfigurationSection("").getKeys(false)) {
if (isExists(name)) {
MsgUtils.warn("无法载入载入物品 &4" + name + "&c, 因为它已经存在了");
} else if (finalFile) {
itemCachesFinal.put(name, loadItem(conf, name));
} else {
itemCaches.put(name, loadItem(conf, name));
}
}
}
public static void reloadItemCache() {
itemCaches.clear();
itemCachesFinal.clear();
loadItemsFile(getItemCacheFile(), false);
// 创建固定物品库
finalItemsFolder = new File(Main.getInst().getDataFolder(), "FinalItems");
if (!finalItemsFolder.exists()) {
finalItemsFolder.mkdir();
}
// 检查固定物品库中的物品
for (File file : finalItemsFolder.listFiles()) {
loadItemsFile(file, true);
}
MsgUtils.send("载入 " + (itemCaches.size() + itemCachesFinal.size()) + " 项缓存物品");
}
public static void reloadItemName() {
FileConfiguration conf = new Language("ITEM_NAME", Main.getInst(), true).getConfiguration();
itemlib.clear();
for (String a : conf.getConfigurationSection("").getKeys(false)) {
itemlib.put(a, conf.getString(a));
}
MsgUtils.send("载入 " + itemlib.size() + " 项物品名称");
}
public static File getItemCacheFile() {
File itemCacheFile = new File(Main.getInst().getDataFolder(), "items.yml");
if (!itemCacheFile.exists()) {
Main.getInst().saveResource("items.yml", true);
}
return itemCacheFile;
}
public static String getCustomName(ItemStack item) {
if (item == null || item.getType().equals(Material.AIR)) {
return "";
}
int data = item.getType().getMaxDurability() == 0 ? item.getDurability() : 0;
return item.getItemMeta().hasDisplayName() ? item.getItemMeta().getDisplayName() : itemlib.get(item.getType() + ":" + data) == null ? item.getType().toString() : itemlib.get(item.getType() + ":" + data);
}
@SuppressWarnings("deprecation")
public static ItemStack getItemFromDir(String name) {
if (itemdir != null) {
return itemdir.getItemStack("item." + name);
}
return null;
}
@SuppressWarnings("deprecation")
public static ItemStack item(int n, int a, int d) {
ItemStack item = new ItemStack(n, a, (short)d);
return item;
}
public static ItemStack setName(ItemStack i, String n) {
ItemMeta meta = i.getItemMeta();
meta.setDisplayName(n);
i.setItemMeta(meta);
return i;
}
public static ItemStack Enchant(ItemStack i, Enchantment e, int l) {
ItemMeta meta = i.getItemMeta();
meta.addEnchant(e, l, false);
i.setItemMeta(meta);
return i;
}
public static ItemStack addFlag(ItemStack i, ItemFlag f) {
ItemMeta meta = i.getItemMeta();
meta.addItemFlags(f);
i.setItemMeta(meta);
return i;
}
public static boolean isNull(ItemStack item) {
return item == null || item.getType().equals(Material.AIR);
}
public static boolean isName(ItemStack i, String a) {
if (!isNamed(i) || i.getItemMeta() == null || i.getItemMeta().getDisplayName() == null || !i.getItemMeta().getDisplayName().equals(a)) {
return false;
}
return true;
}
public static boolean isNameAs(ItemStack i, String a) {
if (!isNamed(i) || !i.getItemMeta().getDisplayName().contains(a)) {
return false;
}
return true;
}
public static String asString(String args, Player placeholderPlayer) {
if (placeholderPlayer == null) {
return args.replace("&", "§");
}
return PlaceholderAPI.setPlaceholders(placeholderPlayer, args.replace("&", "§"));
}
public static List<String> asString(List<String> args, Player placeholderPlayer) {
for (int i = 0 ; i < args.size() ; i ++) {
args.set(i, asString(args.get(i), placeholderPlayer));
}
return args;
}
public static ItemFlag asItemFlag(String flag) {
try {
return ItemFlag.valueOf(flag);
}
catch (Exception e) {
return null;
}
}
@SuppressWarnings("deprecation")
public static Material asMaterial(String args) {
try {
Material material = Material.getMaterial(args);
return material != null ? material : Material.getMaterial(Integer.valueOf(args));
}
catch (Exception e) {
return Material.STONE;
}
}
@SuppressWarnings({ "deprecation" })
public static Enchantment asEnchantment(String enchant) {
try {
Enchantment enchantment = Enchantment.getByName(enchant);
return enchantment != null ? enchantment : Enchantment.getById(Integer.valueOf(enchant));
}
catch (Exception e) {
return null;
}
}
@SuppressWarnings("deprecation")
public static PotionEffectType asPotionEffectType(String potion) {
try {
PotionEffectType type = PotionEffectType.getByName(potion);
return type != null ? type : PotionEffectType.getById(Integer.valueOf(potion));
}
catch (Exception e) {
return null;
}
}
public static Color asColor(String color) {
try {
return Color.fromBGR(Integer.valueOf(color.split("-")[0]), Integer.valueOf(color.split("-")[1]), Integer.valueOf(color.split("-")[2]));
}
catch (Exception e) {
return Color.fromBGR(0, 0, 0);
}
}
public static String asAttribute(String name) {
if (name.toLowerCase().equals("damage")) {
return "generic.attackDamage";
}
else if (name.toLowerCase().equals("attackspeed")) {
return "generic.attackSpeed";
}
else if (name.toLowerCase().equals("health")) {
return "generic.maxHealth";
}
else if (name.toLowerCase().equals("speed")) {
return "generic.movementSpeed";
}
else if (name.toLowerCase().equals("knockback")) {
return "generic.knockbackResistance";
}
else if (name.toLowerCase().equals("armor")) {
return "generic.armor";
}
else if (name.toLowerCase().equals("luck")) {
return "generic.luck";
}
return null;
}
/**
* 包含介绍
*
* @param i 物品
* @param a 关键字
*/
public static boolean hasLore(ItemStack i, String a) {
if (!isLored(i) || !i.getItemMeta().getLore().toString().contains(a)) {
return false;
}
return true;
}
/**
* 如果已描述
*
* @param i
* @return
*/
public static boolean isLored(ItemStack i) {
if (i == null || i.getItemMeta() == null || i.getItemMeta().getLore() == null) {
return false;
}
return true;
}
/**
* 如果已命名
*
* @param i
* @return
*/
public static boolean isNamed(ItemStack i) {
if (i == null || i.getItemMeta() == null || i.getItemMeta().getDisplayName() == null) {
return false;
}
return true;
}
/**
* 添加描述
*
* @param is 物品
* @param lore 描述
*/
public static ItemStack addLore(ItemStack is, String lore) {
ItemMeta meta = is.getItemMeta();
List<String> _lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
_lore.add(lore.replaceAll("&", "§"));
is.setItemMeta(meta);
return is;
}
/**
* 移除描述
*
* @param is 物品
* @param line 行数
*/
public static ItemStack delLore(ItemStack is, int line) {
ItemMeta meta = is.getItemMeta();
if (meta.hasLore()) {
List<String> l = meta.getLore();
if (l.size() >= line) {
l.remove(line);
meta.setLore(l);
is.setItemMeta(meta);
}
}
return is;
}
/**
* 获取介绍所在行数
*
* @param i 物品
* @param a 关键字
*/
public static int getLore(ItemStack i, String a) {
if (isLored(i)) {
for (int j = 0; j < i.getItemMeta().getLore().size() ; j++) {
if (i.getItemMeta().getLore().get(j).contains(a)) {
return j;
}
}
}
return 0;
}
/**
* 添加耐久
*
* @param i 物品
* @param d 耐久
*/
public static ItemStack addDurability(ItemStack i, int d) {
i.setDurability((short) (i.getDurability() + d));
int min = i.getDurability();
int max = i.getType().getMaxDurability();
if (min >= max) {
i.setType(Material.AIR);
}
return i;
}
/**
* 替换描述
*
* @param i 物品
* @param l1 关键字1
* @param l2 关键字2
*/
public static ItemStack repalceLore(ItemStack i, String l1, String l2) {
if (!isLored(i)) {
return i;
}
else {
ItemMeta meta = i.getItemMeta();
List<String> lore = meta.getLore();
for (int j = 0 ; j < lore.size() ; j++) {
lore.set(j, lore.get(j).replace(l1, l2));
}
meta.setLore(lore);
i.setItemMeta(meta);
}
return i;
}
public static ItemStack loadItem(FileConfiguration f, String s) {
return loadItem(f, s, null);
}
public static ItemStack loadItem(FileConfiguration f, String s, Player papiPlayer) {
return loadItem(f.getConfigurationSection(s), papiPlayer);
}
public static ItemStack loadItem(ConfigurationSection section, Player papiPlayer) {
if (section.get("bukkit") instanceof ItemStack) {
return section.getItemStack("bukkit");
}
// 材质
ItemStack item = new ItemStack(asMaterial(section.get("material").toString()));
// 数量
item.setAmount(section.contains("amount") ? section.getInt("amount") : 1);
// 耐久
item.setDurability((short) section.getInt("data"));
// 元数据
ItemMeta meta = item.getItemMeta();
// 展示名
if (section.contains("name")) {
meta.setDisplayName(asString(section.getString("name"), papiPlayer));
}
// 描述
if (section.contains("lore")) {
meta.setLore(asString(section.getStringList("lore"), papiPlayer));
}
// 附魔
if (section.contains("enchants")) {
for (String preEnchant : section.getConfigurationSection("enchants").getKeys(false)) {
Enchantment enchant = asEnchantment(preEnchant);
if (enchant != null) {
meta.addEnchant(enchant, section.getInt("enchants." + preEnchant), true);
}
else {
MsgUtils.warn("&8" + preEnchant + " &c不是一个有效的附魔名称");
MsgUtils.warn("&c输入 &4/taboolib enchants&c 查看所有附魔");
}
}
}
// 标签
if (section.contains("flags") && TabooLib.getVerint() > 10700) {
for (String preFlag : section.getStringList("flags")) {
ItemFlag flag = asItemFlag(preFlag);
if (flag != null) {
meta.addItemFlags(flag);
}
else {
MsgUtils.warn("&8" + preFlag + " &c不是一个有效的标签名称");
MsgUtils.warn("&c输入 &4/taboolib flags&c 查看所有标签");
}
}
}
// 皮革
if (meta instanceof LeatherArmorMeta && section.contains("color")) {
((LeatherArmorMeta) meta).setColor(asColor(section.getString("color")));
}
// 药水
if (meta instanceof PotionMeta && section.contains("potions")) {
PotionMeta potionMeta = (PotionMeta) meta;
for (String prePotionName : section.getConfigurationSection("potions").getKeys(false)) {
PotionEffectType potionEffectType = asPotionEffectType(prePotionName);
if (potionEffectType != null) {
potionMeta.addCustomEffect(new PotionEffect(
potionEffectType,
NumberUtils.getInteger(section.getString("potions." + prePotionName).split("-")[0]),
NumberUtils.getInteger(section.getString("potions." + prePotionName).split("-")[1]) - 1), true);
}
else {
MsgUtils.warn("&8" + potionEffectType + " &c不是一个有效的药水名称");
MsgUtils.warn("&c输入 &4/taboolib potions&c 查看所有药水");
}
}
}
// 元数据
item.setItemMeta(meta);
// 数据
NBTItem nbt = new NBTItem(item);
// 物品标签
if (section.contains("nbt")) {
for (String name : section.getConfigurationSection("nbt").getKeys(false)) {
Object obj = section.get("nbt." + name);
if (obj instanceof String) {
nbt.setString(name, obj.toString());
}
else if (obj instanceof Double) {
nbt.setDouble(name, Double.valueOf(obj.toString()));
}
else if (obj instanceof Integer) {
nbt.setInteger(name, Integer.valueOf(obj.toString()));
}
else if (obj instanceof Long) {
nbt.setLong(name, Long.valueOf(obj.toString()));
}
else {
nbt.setObject(name, obj);
}
}
}
// 物品属性
if (section.contains("attributes")) {
NBTList attr = nbt.getList("AttributeModifiers", NBTType.NBTTagCompound);
for (String hand : section.getConfigurationSection("attributes").getKeys(false)) {
for (String name : section.getConfigurationSection("attributes." + hand).getKeys(false)) {
if (asAttribute(name) != null) {
try {
NBTListCompound _attr = attr.addCompound();
Object num = section.get("attributes." + hand + "." + name);
if (num.toString().contains("%")) {
_attr.setDouble("Amount", Double.valueOf(num.toString().replace("%", "")) / 100D);
_attr.setInteger("Operation", 1);
}
else {
_attr.setDouble("Amount", Double.valueOf(num.toString()));
_attr.setInteger("Operation", 0);
}
_attr.setString("AttributeName", asAttribute(name));
_attr.setInteger("UUIDMost", NumberUtils.getRand().nextInt(Integer.MAX_VALUE));
_attr.setInteger("UUIDLeast", NumberUtils.getRand().nextInt(Integer.MAX_VALUE));
_attr.setString("Name", asAttribute(name));
if (!hand.equals("all")) {
_attr.setString("Slot", hand);
}
}
catch (Exception e) {
MsgUtils.warn("&8" + name + " &c属性载入失败: &8" + e.getMessage());
}
}
else {
MsgUtils.warn("&8" + name + " &c不是一个有效的属性名称");
MsgUtils.warn("&c输入 &4/taboolib attributes&c 查看所有属性");
}
}
}
}
return nbt.getItem();
}
public static NBTItem setAttribute(NBTItem nbt, String name, Object num, String hand) {
NBTList attr = nbt.getList("AttributeModifiers", NBTType.NBTTagCompound);
if (asAttribute(name) != null) {
try {
NBTListCompound _attr = null;
for (int i = 0 ; i < attr.size() ; i++) {
NBTListCompound nlc = attr.getCompound(i);
if (nlc.getString("AttributeName").equals(asAttribute(name))) {
_attr = nlc;
}
}
if (_attr == null) {
_attr = attr.addCompound();
}
if (num.toString().contains("%")) {
_attr.setDouble("Amount", Double.valueOf(num.toString().replace("%", "")) / 100D);
_attr.setInteger("Operation", 1);
}
else {
_attr.setDouble("Amount", Double.valueOf(num.toString()));
_attr.setInteger("Operation", 0);
}
_attr.setString("AttributeName", asAttribute(name));
_attr.setInteger("UUIDMost", NumberUtils.getRand().nextInt(Integer.MAX_VALUE));
_attr.setInteger("UUIDLeast", NumberUtils.getRand().nextInt(Integer.MAX_VALUE));
_attr.setString("Name", asAttribute(name));
if (!hand.equals("all")) {
_attr.setString("Slot", hand);
}
}
catch (Exception e) {
MsgUtils.warn("&8" + name + " &c属性载入失败: &8" + e.getMessage());
}
}
else {
MsgUtils.warn("&8" + name + " &c不是一个有效的属性名称");
MsgUtils.warn("&c输入 &4/taboolib attributes&c 查看所有属性");
}
return nbt;
}
@Deprecated
public static void putO(ItemStack item, Inventory inv, int i) {
inv.setItem(i, item);
inv.setItem(i+1, item);
inv.setItem(i+2, item);
inv.setItem(i+9, item);
inv.setItem(i+10, null);
inv.setItem(i+11, item);
inv.setItem(i+18, item);
inv.setItem(i+19, item);
inv.setItem(i+20, item);
}
}

View File

@@ -0,0 +1,46 @@
package me.skymc.taboolib.inventory.speciaitem;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
/**
* @author sky
* @since 2018年2月17日 下午8:35:42
*/
public abstract interface AbstractSpecialItem {
/**
* 当接口被载入
*/
default void onEnable() {}
/**
* 当接口被卸载
*/
default void onDisable() {}
/**
* 获取识别名称
*
* @return String
*/
abstract String getName();
/**
* 获取载入插件
*
* @return {@link Plugin}
*/
abstract Plugin getPlugin();
/**
* 是否进行点击事件
*
* @param player 玩家
* @param currentItem 点击物品
* @param cursorItem 持有物品
* @return {@link SpecialItemResult[]}
*/
abstract SpecialItemResult[] isCorrectClick(Player player, ItemStack currentItem, ItemStack cursorItem);
}

View File

@@ -0,0 +1,181 @@
package me.skymc.taboolib.inventory.speciaitem;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin;
import lombok.Getter;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.message.MsgUtils;
/**
* @author sky
* @since 2018年2月17日 下午8:34:12
*/
public class SpecialItem implements Listener {
private static SpecialItem specialItem = null;
private final List<AbstractSpecialItem> ITEM_DATA = new CopyOnWriteArrayList<>();
@Getter
private boolean isLoaded;
/**
* 构造方法
*/
private SpecialItem() {
}
/**
* 获取工具对象
*
* @return {@link SpecialItem}
*/
public static SpecialItem getInst() {
if (specialItem == null) {
synchronized (SpecialItem.class) {
if (specialItem == null) {
specialItem = new SpecialItem();
// 注册监听器
Bukkit.getPluginManager().registerEvents(specialItem, Main.getInst());
}
}
}
return specialItem;
}
/**
* 注册接口
*
* @param item 接口对象
*/
public void register(AbstractSpecialItem item) {
if (contains(item.getName())) {
MsgUtils.warn("特殊物品接口已存在, 检查名称 &4" + item.getName() + " &c是否重复");
}
else {
ITEM_DATA.add(item);
if (isLoaded) {
item.onEnable();
}
}
}
/**
* 注销接口
*
* @param name 注册名称
*/
public void cancel(String name) {
for (AbstractSpecialItem specialitem : ITEM_DATA) {
if (specialitem.getName() != null && specialitem.getName().equals(specialitem)) {
specialitem.onDisable();
ITEM_DATA.remove(specialitem);
}
}
}
/**
* 注销接口
*
* @param plugin 注册插件
*/
public void cancel(Plugin plugin) {
for (AbstractSpecialItem specialitem : ITEM_DATA) {
if (specialitem.getPlugin() != null && specialitem.getPlugin().equals(plugin)) {
specialitem.onDisable();
ITEM_DATA.remove(specialitem);
}
}
}
/**
* 判断名称是否存在
*
* @param name 注册名称
* @return boolean
*/
public boolean contains(String name) {
for (AbstractSpecialItem specialitem : ITEM_DATA) {
if (specialitem.getName().equals(name)) {
return true;
}
}
return false;
}
/**
* 载入所有已注册接口
*/
public void loadItems() {
ITEM_DATA.forEach(x -> x.onEnable());
isLoaded = true;
}
/**
* 注销所有已注册接口
*/
public void unloadItems() {
ITEM_DATA.forEach(x -> x.onDisable());
ITEM_DATA.clear();
}
@EventHandler
public void onDisable(PluginDisableEvent e) {
cancel(e.getPlugin());
}
@EventHandler (priority = EventPriority.MONITOR)
public void click(InventoryClickEvent e) {
if (e.isCancelled()) {
return;
}
if (ItemUtils.isNull(e.getCurrentItem()) || ItemUtils.isNull(e.getCursor())) {
return;
}
Player player = (Player) e.getWhoClicked();
for (AbstractSpecialItem specialitem : ITEM_DATA) {
for (SpecialItemResult result : specialitem.isCorrectClick(player, e.getCurrentItem(), e.getCursor())) {
if (result == SpecialItemResult.CANCEL) {
e.setCancelled(true);
}
else if (result == SpecialItemResult.BREAK) {
return;
}
else if (result == SpecialItemResult.REMOVE_ITEM_CURRENT) {
e.setCurrentItem(null);
}
else if (result == SpecialItemResult.REMOVE_ITEM_CURSOR) {
e.getWhoClicked().setItemOnCursor(null);
}
else if (result == SpecialItemResult.REMOVE_ITEM_CURRENT_AMOUNT_1) {
if (e.getCurrentItem().getAmount() > 1) {
e.getCurrentItem().setAmount(e.getCurrentItem().getAmount() - 1);
}
else {
e.setCurrentItem(null);
}
}
else if (result == SpecialItemResult.REMOVE_ITEM_CURSOR_AMOUNT_1) {
if (e.getCursor().getAmount() > 1) {
e.getCursor().setAmount(e.getCursor().getAmount() - 1);
}
else {
e.getWhoClicked().setItemOnCursor(null);
}
}
}
}
}
}

View File

@@ -0,0 +1,39 @@
package me.skymc.taboolib.inventory.speciaitem;
/**
* @author sky
* @since 2018年2月17日 下午8:55:36
*/
public enum SpecialItemResult {
/**
* 停止接口检测
*/
BREAK,
/**
* 取消点击事件
*/
CANCEL,
/**
* 移除点击物品
*/
REMOVE_ITEM_CURRENT,
/**
* 移除鼠标物品
*/
REMOVE_ITEM_CURSOR,
/**
* 移除一个点击物品
*/
REMOVE_ITEM_CURRENT_AMOUNT_1,
/**
* 移除一个鼠标物品
*/
REMOVE_ITEM_CURSOR_AMOUNT_1;
}

View File

@@ -0,0 +1,192 @@
package me.skymc.taboolib.itemnbtapi;
import java.util.Set;
import me.skymc.taboolib.TabooLib;
public class NBTCompound {
private String compundName;
private NBTCompound parent;
protected NBTCompound(NBTCompound owner, String name) {
this.compundName = name;
this.parent = owner;
}
public String getName() {
return compundName;
}
protected Object getCompound() {
return parent.getCompound();
}
protected void setCompound(Object compound) {
parent.setCompound(compound);
}
public NBTCompound getParent() {
return parent;
}
public void mergeCompound(NBTCompound comp){
NBTReflectionUtil.addOtherNBTCompound(this, comp);
}
public void setString(String key, String value) {
NBTReflectionUtil.setString(this, key, value);
}
public String getString(String key) {
return NBTReflectionUtil.getString(this, key);
}
protected String getContent(String key) {
return NBTReflectionUtil.getContent(this, key);
}
public void setInteger(String key, Integer value) {
NBTReflectionUtil.setInt(this, key, value);
}
public Integer getInteger(String key) {
return NBTReflectionUtil.getInt(this, key);
}
public void setDouble(String key, Double value) {
NBTReflectionUtil.setDouble(this, key, value);
}
public Double getDouble(String key) {
return NBTReflectionUtil.getDouble(this, key);
}
public void setByte(String key, Byte value) {
NBTReflectionUtil.setByte(this, key, value);
}
public Byte getByte(String key) {
return NBTReflectionUtil.getByte(this, key);
}
public void setShort(String key, Short value) {
NBTReflectionUtil.setShort(this, key, value);
}
public Short getShort(String key) {
return NBTReflectionUtil.getShort(this, key);
}
public void setLong(String key, Long value) {
NBTReflectionUtil.setLong(this, key, value);
}
public Long getLong(String key) {
return NBTReflectionUtil.getLong(this, key);
}
public void setFloat(String key, Float value) {
NBTReflectionUtil.setFloat(this, key, value);
}
public Float getFloat(String key) {
return NBTReflectionUtil.getFloat(this, key);
}
public void setByteArray(String key, byte[] value) {
NBTReflectionUtil.setByteArray(this, key, value);
}
public byte[] getByteArray(String key) {
return NBTReflectionUtil.getByteArray(this, key);
}
public void setIntArray(String key, int[] value) {
NBTReflectionUtil.setIntArray(this, key, value);
}
public int[] getIntArray(String key) {
return NBTReflectionUtil.getIntArray(this, key);
}
public void setBoolean(String key, Boolean value) {
NBTReflectionUtil.setBoolean(this, key, value);
}
protected void set(String key, Object val) {
NBTReflectionUtil.set(this, key, val);
}
public Boolean getBoolean(String key) {
return NBTReflectionUtil.getBoolean(this, key);
}
public void setObject(String key, Object value) {
NBTReflectionUtil.setObject(this, key, value);
}
public <T> T getObject(String key, Class<T> type) {
return NBTReflectionUtil.getObject(this, key, type);
}
public Boolean hasKey(String key) {
return NBTReflectionUtil.hasKey(this, key);
}
public void removeKey(String key) {
NBTReflectionUtil.remove(this, key);
}
public Set<String> getKeys() {
return NBTReflectionUtil.getKeys(this);
}
public NBTCompound addCompound(String name) {
NBTReflectionUtil.addNBTTagCompound(this, name);
return getCompound(name);
}
public NBTCompound getCompound(String name) {
NBTCompound next = new NBTCompound(this, name);
if (NBTReflectionUtil.valideCompound(next)) return next;
return null;
}
public NBTList getList(String name, NBTType type) {
return NBTReflectionUtil.getList(this, name, type);
}
public NBTType getType(String name) {
if (TabooLib.getVerint() == 10700) return NBTType.NBTTagEnd;
return NBTType.valueOf(NBTReflectionUtil.getType(this, name));
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (String key : getKeys()) {
result.append(toString(key));
}
return result.toString();
}
public String toString(String key) {
StringBuilder result = new StringBuilder();
NBTCompound compound = this;
while (compound.getParent() != null) {
result.append(" ");
compound = compound.getParent();
}
if (this.getType(key) == NBTType.NBTTagCompound) {
return this.getCompound(key).toString();
} else {
return result + "-" + key + ": " + getContent(key) + System.lineSeparator();
}
}
public String asNBTString(){
return getCompound().toString();
}
}

View File

@@ -0,0 +1,35 @@
package me.skymc.taboolib.itemnbtapi;
public class NBTContainer extends NBTCompound{
private Object nbt;
public NBTContainer() {
super(null, null);
nbt = NBTReflectionUtil.getNewNBTTag();
}
protected NBTContainer(Object nbt){
super(null, null);
this.nbt = nbt;
}
public NBTContainer(String nbtString) throws IllegalArgumentException {
super(null, null);
try{
nbt = NBTReflectionUtil.parseNBT(nbtString);
}catch(Exception ex){
ex.printStackTrace();
throw new IllegalArgumentException("Malformed Json: " + ex.getMessage());
}
}
protected Object getCompound() {
return nbt;
}
protected void setCompound(Object tag) {
nbt = tag;
}
}

View File

@@ -0,0 +1,22 @@
package me.skymc.taboolib.itemnbtapi;
import org.bukkit.entity.Entity;
public class NBTEntity extends NBTCompound {
private final Entity ent;
public NBTEntity(Entity entity) {
super(null, null);
ent = entity;
}
protected Object getCompound() {
return NBTReflectionUtil.getEntityNBTTagCompound(NBTReflectionUtil.getNMSEntity(ent));
}
protected void setCompound(Object compound) {
NBTReflectionUtil.setEntityNBTTag(compound, NBTReflectionUtil.getNMSEntity(ent));
}
}

View File

@@ -0,0 +1,46 @@
package me.skymc.taboolib.itemnbtapi;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class NBTFile extends NBTCompound {
private final File file;
private Object nbt;
public NBTFile(File file) throws IOException {
super(null, null);
this.file = file;
if (file.exists()) {
FileInputStream inputsteam = new FileInputStream(file);
nbt = NBTReflectionUtil.readNBTFile(inputsteam);
} else {
nbt = NBTReflectionUtil.getNewNBTTag();
save();
}
}
public void save() throws IOException {
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
FileOutputStream outStream = new FileOutputStream(file);
NBTReflectionUtil.saveNBTFile(nbt, outStream);
}
public File getFile() {
return file;
}
protected Object getCompound() {
return nbt;
}
protected void setCompound(Object compound) {
nbt = compound;
}
}

View File

@@ -0,0 +1,38 @@
package me.skymc.taboolib.itemnbtapi;
import org.bukkit.inventory.ItemStack;
public class NBTItem extends NBTCompound {
private ItemStack bukkitItem;
public NBTItem(ItemStack item) {
super(null, null);
bukkitItem = item.clone();
}
protected Object getCompound() {
return NBTReflectionUtil.getItemRootNBTTagCompound(NBTReflectionUtil.getNMSItemStack(bukkitItem));
}
protected void setCompound(Object compound) {
bukkitItem = NBTReflectionUtil.getBukkitItemStack(NBTReflectionUtil.setNBTTag(compound, NBTReflectionUtil.getNMSItemStack(bukkitItem)));
}
public ItemStack getItem() {
return bukkitItem;
}
protected void setItem(ItemStack item) {
bukkitItem = item;
}
public static NBTContainer convertItemtoNBT(ItemStack item){
return NBTReflectionUtil.convertNMSItemtoNBTCompound(NBTReflectionUtil.getNMSItemStack(item));
}
public static ItemStack convertNBTtoItem(NBTCompound comp){
return NBTReflectionUtil.getBukkitItemStack(NBTReflectionUtil.convertNBTCompoundtoNMSItem(comp));
}
}

View File

@@ -0,0 +1,128 @@
package me.skymc.taboolib.itemnbtapi;
import java.lang.reflect.Method;
import me.skymc.taboolib.itemnbtapi.utils.MethodNames;
import me.skymc.taboolib.message.MsgUtils;
public class NBTList {
private String listName;
private NBTCompound parent;
private NBTType type;
private Object listObject;
protected NBTList(NBTCompound owner, String name, NBTType type, Object list) {
parent = owner;
listName = name;
this.type = type;
this.listObject = list;
if (!(type == NBTType.NBTTagString || type == NBTType.NBTTagCompound)) {
System.err.println("List types != String/Compound are currently not implemented!");
}
}
protected void save() {
parent.set(listName, listObject);
}
public NBTListCompound addCompound() {
if (type != NBTType.NBTTagCompound) {
new Throwable("Using Compound method on a non Compound list!").printStackTrace();
return null;
}
try {
Method method = listObject.getClass().getMethod("add", NBTReflectionUtil.getNBTBase());
Object compound = NBTReflectionUtil.getNBTTagCompound().newInstance();
method.invoke(listObject, compound);
return new NBTListCompound(this, compound);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public NBTListCompound getCompound(int id) {
if (type != NBTType.NBTTagCompound) {
new Throwable("Using Compound method on a non Compound list!").printStackTrace();
return null;
}
try {
Method method = listObject.getClass().getMethod("get", int.class);
Object compound = method.invoke(listObject, id);
return new NBTListCompound(this, compound);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public String getString(int i) {
if (type != NBTType.NBTTagString) {
new Throwable("Using String method on a non String list!").printStackTrace();
return null;
}
try {
Method method = listObject.getClass().getMethod("getString", int.class);
return (String) method.invoke(listObject, i);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
@SuppressWarnings("unchecked")
public void addString(String s) {
if (type != NBTType.NBTTagString) {
new Throwable("Using String method on a non String list!").printStackTrace();
return;
}
try {
Method method = listObject.getClass().getMethod("add", NBTReflectionUtil.getNBTBase());
method.invoke(listObject, NBTReflectionUtil.getNBTTagString().getConstructor(String.class).newInstance(s));
save();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
@SuppressWarnings("unchecked")
public void setString(int i, String s) {
if (type != NBTType.NBTTagString) {
new Throwable("Using String method on a non String list!").printStackTrace();
return;
}
try {
Method method = listObject.getClass().getMethod("a", int.class, NBTReflectionUtil.getNBTBase());
method.invoke(listObject, i, NBTReflectionUtil.getNBTTagString().getConstructor(String.class).newInstance(s));
save();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public void remove(int i) {
try {
Method method = listObject.getClass().getMethod(MethodNames.getRemoveMethodName(), int.class);
method.invoke(listObject, i);
save();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public int size() {
try {
Method method = listObject.getClass().getMethod("size");
return (int) method.invoke(listObject);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return -1;
}
public NBTType getType() {
return type;
}
}

View File

@@ -0,0 +1,104 @@
package me.skymc.taboolib.itemnbtapi;
import java.util.HashSet;
import java.util.Set;
import me.skymc.taboolib.message.MsgUtils;
public class NBTListCompound {
private NBTList owner;
private Object compound;
protected NBTListCompound(NBTList parent, Object obj) {
owner = parent;
compound = obj;
}
public void setString(String key, String value) {
if (value == null) {
remove(key);
return;
}
try {
compound.getClass().getMethod("setString", String.class, String.class).invoke(compound, key, value);
owner.save();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public void setInteger(String key, int value) {
try {
compound.getClass().getMethod("setInt", String.class, int.class).invoke(compound, key, value);
owner.save();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public int getInteger(String value) {
try {
return (int) compound.getClass().getMethod("getInt", String.class).invoke(compound, value);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return 0;
}
public void setDouble(String key, double value) {
try {
compound.getClass().getMethod("setDouble", String.class, double.class).invoke(compound, key, value);
owner.save();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public double getDouble(String key) {
try {
return (double) compound.getClass().getMethod("getDouble", String.class).invoke(compound, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return 0;
}
public String getString(String key) {
try {
return (String) compound.getClass().getMethod("getString", String.class).invoke(compound, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return "";
}
public boolean hasKey(String key) {
try {
return (boolean) compound.getClass().getMethod("hasKey", String.class).invoke(compound, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return false;
}
@SuppressWarnings("unchecked")
public Set<String> getKeys() {
try {
return (Set<String>) compound.getClass().getMethod("c").invoke(compound);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return new HashSet<>();
}
public void remove(String key) {
try {
compound.getClass().getMethod("remove", String.class).invoke(compound, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
}

View File

@@ -0,0 +1,978 @@
package me.skymc.taboolib.itemnbtapi;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.Stack;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.itemnbtapi.utils.GsonWrapper;
import me.skymc.taboolib.itemnbtapi.utils.MethodNames;
import me.skymc.taboolib.message.MsgUtils;
// TODO: finish codestyle cleanup -sgdc3
public class NBTReflectionUtil {
private static final String version = TabooLib.getVersion();
@SuppressWarnings("rawtypes")
private static Class getCraftItemStack() {
try {
Class clazz = Class.forName("org.bukkit.craftbukkit." + version + ".inventory.CraftItemStack");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
private static Class getCraftEntity() {
try {
Class clazz = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftEntity");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getNBTBase() {
try {
Class clazz = Class.forName("net.minecraft.server." + version + ".NBTBase");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getNBTTagString() {
try {
Class clazz = Class.forName("net.minecraft.server." + version + ".NBTTagString");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getNMSItemStack() {
try {
Class clazz = Class.forName("net.minecraft.server." + version + ".ItemStack");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getNBTTagCompound() {
try {
Class clazz = Class.forName("net.minecraft.server." + version + ".NBTTagCompound");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getNBTCompressedStreamTools() {
try {
Class clazz = Class.forName("net.minecraft.server." + version + ".NBTCompressedStreamTools");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getMojangsonParser() {
try {
Class c = Class.forName("net.minecraft.server." + version + ".MojangsonParser");
return c;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getTileEntity() {
try {
Class clazz = Class.forName("net.minecraft.server." + version + ".TileEntity");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
@SuppressWarnings("rawtypes")
protected static Class getCraftWorld() {
try {
Class clazz = Class.forName("org.bukkit.craftbukkit." + version + ".CraftWorld");
return clazz;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
public static Object getNewNBTTag() {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
try {
@SuppressWarnings("rawtypes")
Class c = Class.forName("net.minecraft.server." + version + ".NBTTagCompound");
return c.newInstance();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
private static Object getNewBlockPosition(int x, int y, int z) {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
try {
@SuppressWarnings("rawtypes")
Class clazz = Class.forName("net.minecraft.server." + version + ".BlockPosition");
return clazz.getConstructor(int.class, int.class, int.class).newInstance(x, y, z);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
public static Object setNBTTag(Object NBTTag, Object NMSItem) {
try {
Method method;
method = NMSItem.getClass().getMethod("setTag", NBTTag.getClass());
method.invoke(NMSItem, NBTTag);
return NMSItem;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
@SuppressWarnings("unchecked")
public static Object getNMSItemStack(ItemStack item) {
@SuppressWarnings("rawtypes")
Class clazz = getCraftItemStack();
Method method;
try {
method = clazz.getMethod("asNMSCopy", ItemStack.class);
Object answer = method.invoke(clazz, item);
return answer;
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings("unchecked")
public static Object getNMSEntity(Entity entity) {
@SuppressWarnings("rawtypes")
Class clazz = getCraftEntity();
Method method;
try {
method = clazz.getMethod("getHandle");
return method.invoke(getCraftEntity().cast(entity));
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static Object parseNBT(String json) {
@SuppressWarnings("rawtypes")
Class cis = getMojangsonParser();
java.lang.reflect.Method method;
try {
method = cis.getMethod("parse", String.class);
return method.invoke(null, json);
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static Object readNBTFile(FileInputStream stream) {
@SuppressWarnings("rawtypes")
Class clazz = getNBTCompressedStreamTools();
Method method;
try {
method = clazz.getMethod("a", InputStream.class);
return method.invoke(clazz, stream);
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static Object saveNBTFile(Object nbt, FileOutputStream stream) {
@SuppressWarnings("rawtypes")
Class clazz = getNBTCompressedStreamTools();
Method method;
try {
method = clazz.getMethod("a", getNBTTagCompound(), OutputStream.class);
return method.invoke(clazz, nbt, stream);
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static ItemStack getBukkitItemStack(Object item) {
@SuppressWarnings("rawtypes")
Class clazz = getCraftItemStack();
Method method;
try {
method = clazz.getMethod("asCraftMirror", item.getClass());
Object answer = method.invoke(clazz, item);
return (ItemStack) answer;
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static Object getItemRootNBTTagCompound(Object nmsitem) {
@SuppressWarnings("rawtypes")
Class clazz = nmsitem.getClass();
Method method;
try {
method = clazz.getMethod("getTag");
Object answer = method.invoke(nmsitem);
return answer;
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static Object convertNBTCompoundtoNMSItem(NBTCompound nbtcompound) {
@SuppressWarnings("rawtypes")
Class clazz = getNMSItemStack();
try {
Object nmsstack = clazz.getConstructor(getNBTTagCompound()).newInstance(nbtcompound.getCompound());
return nmsstack;
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static NBTContainer convertNMSItemtoNBTCompound(Object nmsitem) {
@SuppressWarnings("rawtypes")
Class clazz = nmsitem.getClass();
Method method;
try {
method = clazz.getMethod("save", getNBTTagCompound());
Object answer = method.invoke(nmsitem, getNewNBTTag());
return new NBTContainer(answer);
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
@SuppressWarnings({"unchecked"})
public static Object getEntityNBTTagCompound(Object nmsitem) {
@SuppressWarnings("rawtypes")
Class c = nmsitem.getClass();
Method method;
try {
method = c.getMethod(MethodNames.getEntityNbtGetterMethodName(), getNBTTagCompound());
Object nbt = getNBTTagCompound().newInstance();
Object answer = method.invoke(nmsitem, nbt);
if (answer == null)
answer = nbt;
return answer;
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
public static Object setEntityNBTTag(Object NBTTag, Object NMSItem) {
try {
Method method;
method = NMSItem.getClass().getMethod(MethodNames.getEntityNbtSetterMethodName(), getNBTTagCompound());
method.invoke(NMSItem, NBTTag);
return NMSItem;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static Object getTileEntityNBTTagCompound(BlockState tile) {
Method method;
try {
Object pos = getNewBlockPosition(tile.getX(), tile.getY(), tile.getZ());
Object cworld = getCraftWorld().cast(tile.getWorld());
Object nmsworld = cworld.getClass().getMethod("getHandle").invoke(cworld);
Object o = nmsworld.getClass().getMethod("getTileEntity", pos.getClass()).invoke(nmsworld, pos);
method = getTileEntity().getMethod(MethodNames.getTileDataMethodName(), getNBTTagCompound());
Object tag = getNBTTagCompound().newInstance();
Object answer = method.invoke(o, tag);
if (answer == null)
answer = tag;
return answer;
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
public static void setTileEntityNBTTagCompound(BlockState tile, Object comp) {
Method method;
try {
Object pos = getNewBlockPosition(tile.getX(), tile.getY(), tile.getZ());
Object cworld = getCraftWorld().cast(tile.getWorld());
Object nmsworld = cworld.getClass().getMethod("getHandle").invoke(cworld);
Object o = nmsworld.getClass().getMethod("getTileEntity", pos.getClass()).invoke(nmsworld, pos);
method = getTileEntity().getMethod("a", getNBTTagCompound());
method.invoke(o, comp);
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
}
@SuppressWarnings("unchecked")
public static Object getSubNBTTagCompound(Object compound, String name) {
@SuppressWarnings("rawtypes")
Class c = compound.getClass();
Method method;
try {
method = c.getMethod("getCompound", String.class);
Object answer = method.invoke(compound, name);
return answer;
} catch (Exception e) {
MsgUtils.warn("NBT 操作出现异常: §7" + e.getMessage());
}
return null;
}
public static void addNBTTagCompound(NBTCompound comp, String name) {
if (name == null) {
remove(comp, name);
return;
}
Object nbttag = comp.getCompound();
if (nbttag == null) {
nbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(nbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("set", String.class, getNBTBase());
method.invoke(workingtag, name, getNBTTagCompound().newInstance());
comp.setCompound(nbttag);
return;
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return;
}
public static Boolean valideCompound(NBTCompound comp) {
Object root = comp.getCompound();
if (root == null) {
root = getNewNBTTag();
}
return (gettoCompount(root, comp)) != null;
}
private static Object gettoCompount(Object nbttag, NBTCompound comp) {
Stack<String> structure = new Stack<>();
while (comp.getParent() != null) {
structure.add(comp.getName());
comp = comp.getParent();
}
while (!structure.isEmpty()) {
nbttag = getSubNBTTagCompound(nbttag, structure.pop());
if (nbttag == null) {
return null;
}
}
return nbttag;
}
public static void addOtherNBTCompound(NBTCompound comp, NBTCompound nbtcompound) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("a", getNBTTagCompound());
method.invoke(workingtag, nbtcompound.getCompound());
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static void setString(NBTCompound comp, String key, String text) {
if (text == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setString", String.class, String.class);
method.invoke(workingtag, key, text);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static String getString(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getString", String.class);
return (String) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static String getContent(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("get", String.class);
return method.invoke(workingtag, key).toString();
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setInt(NBTCompound comp, String key, Integer i) {
if (i == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setInt", String.class, int.class);
method.invoke(workingtag, key, i);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Integer getInt(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getInt", String.class);
return (Integer) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setByteArray(NBTCompound comp, String key, byte[] b) {
if (b == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setByteArray", String.class, byte[].class);
method.invoke(workingtag, key, b);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return;
}
public static byte[] getByteArray(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getByteArray", String.class);
return (byte[]) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setIntArray(NBTCompound comp, String key, int[] i) {
if (i == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setIntArray", String.class, int[].class);
method.invoke(workingtag, key, i);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static int[] getIntArray(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getIntArray", String.class);
return (int[]) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setFloat(NBTCompound comp, String key, Float f) {
if (f == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setFloat", String.class, float.class);
method.invoke(workingtag, key, (float) f);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Float getFloat(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getFloat", String.class);
return (Float) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setLong(NBTCompound comp, String key, Long f) {
if (f == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setLong", String.class, long.class);
method.invoke(workingtag, key, (long) f);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Long getLong(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getLong", String.class);
return (Long) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setShort(NBTCompound comp, String key, Short f) {
if (f == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setShort", String.class, short.class);
method.invoke(workingtag, key, (short) f);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Short getShort(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getShort", String.class);
return (Short) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setByte(NBTCompound comp, String key, Byte f) {
if (f == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setByte", String.class, byte.class);
method.invoke(workingtag, key, (byte) f);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Byte getByte(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getByte", String.class);
return (Byte) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setDouble(NBTCompound comp, String key, Double d) {
if (d == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setDouble", String.class, double.class);
method.invoke(workingtag, key, d);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Double getDouble(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getDouble", String.class);
return (Double) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static byte getType(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return 0;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod(MethodNames.getTypeMethodName(), String.class);
return (byte) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return 0;
}
public static void setBoolean(NBTCompound comp, String key, Boolean d) {
if (d == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("setBoolean", String.class, boolean.class);
method.invoke(workingtag, key, d);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Boolean getBoolean(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getBoolean", String.class);
return (Boolean) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void set(NBTCompound comp, String key, Object val) {
if (val == null) {
remove(comp, key);
return;
}
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) {
new Throwable("InvalideCompound").printStackTrace();
return;
}
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("set", String.class, getNBTBase());
method.invoke(workingtag, key, val);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static NBTList getList(NBTCompound comp, String key, NBTType type) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("getList", String.class, int.class);
return new NBTList(comp, key, type, method.invoke(workingtag, key, type.getId()));
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
public static void setObject(NBTCompound comp, String key, Object value) {
try {
String json = GsonWrapper.getString(value);
setString(comp, key, json);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static <T> T getObject(NBTCompound comp, String key, Class<T> type) {
String json = getString(comp, key);
if (json == null) {
return null;
}
return GsonWrapper.deserializeJson(json, type);
}
public static void remove(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("remove", String.class);
method.invoke(workingtag, key);
comp.setCompound(rootnbttag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
}
public static Boolean hasKey(NBTCompound comp, String key) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("hasKey", String.class);
return (Boolean) method.invoke(workingtag, key);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
@SuppressWarnings("unchecked")
public static Set<String> getKeys(NBTCompound comp) {
Object rootnbttag = comp.getCompound();
if (rootnbttag == null) {
rootnbttag = getNewNBTTag();
}
if (!valideCompound(comp)) return null;
Object workingtag = gettoCompount(rootnbttag, comp);
Method method;
try {
method = workingtag.getClass().getMethod("c");
return (Set<String>) method.invoke(workingtag);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
}
return null;
}
}

View File

@@ -0,0 +1,22 @@
package me.skymc.taboolib.itemnbtapi;
import org.bukkit.block.BlockState;
public class NBTTileEntity extends NBTCompound {
private final BlockState tile;
public NBTTileEntity(BlockState tile) {
super(null, null);
this.tile = tile;
}
protected Object getCompound() {
return NBTReflectionUtil.getTileEntityNBTTagCompound(tile);
}
protected void setCompound(Object compound) {
NBTReflectionUtil.setTileEntityNBTTagCompound(tile, compound);
}
}

View File

@@ -0,0 +1,34 @@
package me.skymc.taboolib.itemnbtapi;
public enum NBTType {
NBTTagEnd(0),
NBTTagByte(1),
NBTTagShort(2),
NBTTagInt(3),
NBTTagLong(4),
NBTTagFloat(5),
NBTTagDouble(6),
NBTTagByteArray(7),
NBTTagIntArray(11),
NBTTagString(8),
NBTTagList(9),
NBTTagCompound(10);
NBTType(int i) {
id = i;
}
private final int id;
public int getId() {
return id;
}
public static NBTType valueOf(int id) {
for (NBTType t : values())
if (t.getId() == id)
return t;
return NBTType.NBTTagEnd;
}
}

View File

@@ -0,0 +1,29 @@
package me.skymc.taboolib.itemnbtapi.utils;
import com.google.gson.Gson;
import me.skymc.taboolib.message.MsgUtils;
public class GsonWrapper {
private static final Gson gson = new Gson();
public static String getString(Object obj) {
return gson.toJson(obj);
}
public static <T> T deserializeJson(String json, Class<T> type) {
try {
if (json == null) {
return null;
}
T obj = gson.fromJson(json, type);
return type.cast(obj);
} catch (Exception ex) {
MsgUtils.warn("NBT 操作出现异常: §7" + ex.getMessage());
return null;
}
}
}

View File

@@ -0,0 +1,35 @@
package me.skymc.taboolib.itemnbtapi.utils;
import me.skymc.taboolib.TabooLib;
public class MethodNames {
public static String getEntityNbtGetterMethodName() {
return "b";
}
public static String getEntityNbtSetterMethodName() {
return "a";
}
public static String getTileDataMethodName() {
if (TabooLib.getVerint() <= 10800) {
return "b";
}
return "save";
}
public static String getTypeMethodName() {
if (TabooLib.getVerint() <= 10800) {
return "b";
}
return "d";
}
public static String getRemoveMethodName() {
if (TabooLib.getVerint() <= 10800) {
return "a";
}
return "remove";
}
}

View File

@@ -0,0 +1,90 @@
package me.skymc.taboolib.javascript;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import me.skymc.taboolib.Main;
public class JavaScriptUtils {
private static ScriptEngineManager manager = new ScriptEngineManager();
public static ScriptEngineManager getScriptManager() {
return manager;
}
public static void invokeJavaScript(File jsFile, String method, Object... o) {
ScriptEngine engine = manager.getEngineByName("javascript");
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(Main.class.getClassLoader());
FileReader reader = new FileReader(jsFile);
engine.eval(reader);
// TODO run
Thread.currentThread().setContextClassLoader(classLoader);
}
catch (Exception e) {
// TODO: handle exception
}
}
@Deprecated
public static Object JavaScriptInterface(String jsFile, Object... o) {
ScriptEngine engine = manager.getEngineByName("javascript");
try {
FileReader reader = new FileReader(jsFile);
engine.eval(reader);
if (engine instanceof Invocable) {
return ((Invocable) engine).invokeFunction("main", o);
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ScriptException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
@Deprecated
public static void JavaScriptExecute(String jsFile, Object... o) {
ScriptEngine engine = manager.getEngineByName("javascript");
try {
FileReader reader = new FileReader(jsFile);
engine.eval(reader);
if (engine instanceof Invocable) {
((Invocable) engine).invokeFunction("main", o);
}
reader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ScriptException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,216 @@
package me.skymc.taboolib.javashell;
import java.io.File;
import java.io.FilenameFilter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.plugin.RegisteredListener;
import org.bukkit.scheduler.BukkitRunnable;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.javashell.utils.JarUtils;
import me.skymc.taboolib.message.MsgUtils;
import lombok.Getter;
import lombok.Setter;
public class JavaShell {
@Getter
@Setter
private static String paths = "";
@Getter
@Setter
private static File javaShellFolder;
@Getter
@Setter
private static File scriptFolder;
@Getter
@Setter
private static File cacheFolder;
@Getter
@Setter
private static File libFolder;
@Getter
@Setter
private static HashMap<String, Class<?>> shells = new HashMap<>();
public static void javaShellSetup() {
File dataFolder = Main.getInst().getDataFolder();
File pluginsFolder = dataFolder.getParentFile();
File serverRoot = Bukkit.getWorldContainer();
File[] rootJars = serverRoot.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith("jar");
}
});
File[] pluginJars = pluginsFolder.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith("jar");
}
});
for (File file : (File[]) ArrayUtils.addAll(rootJars, pluginJars)) {
String path = file.getAbsolutePath();
paths += File.pathSeparator + path;
}
javaShellFolder = new File(Main.getInst().getDataFolder(), "JavaShells");
if (!javaShellFolder.exists()) {
Main.getInst().saveResource("JavaShells/scripts/-testshell.java", true);
}
scriptFolder = new File(javaShellFolder, "scripts");
if (!scriptFolder.exists()) {
scriptFolder.mkdir();
}
cacheFolder = new File(javaShellFolder, "cache");
if (!cacheFolder.exists()) {
cacheFolder.mkdir();
}
libFolder = new File(javaShellFolder, "lib");
if (!libFolder.exists()) {
libFolder.mkdir();
}
File tools = new File(Main.getInst().getDataFolder(), "JavaShells/lib/com.sun.tools.jar");
if (!tools.exists()) {
MsgUtils.warn("&4JavaShell &c工具的必要依赖 &4com.sun.tools.jar &c不存在, 功能关闭!");
return;
}
loadLibrary();
new BukkitRunnable() {
@Override
public void run() {
long time = System.currentTimeMillis();
for (File file : scriptFolder.listFiles()) {
if (!file.getName().startsWith("-")) {
reloadShell(file.getName());
}
}
MsgUtils.send("载入 " + shells.size() + " 个脚本, 耗时 &f" + (System.currentTimeMillis() - time) + "ms");
}
}.runTask(Main.getInst());
}
public static void javaShellCancel() {
for (File cacheFile : cacheFolder.listFiles()) {
cacheFile.delete();
}
for (String name : shells.keySet()) {
invokeMethod(name, "onDisable");
}
}
public static void invokeMethod(String name, String method) {
if (shells.containsKey(name)) {
Class<?> clazz = shells.get(name);
try {
Method disableMethod = clazz.getMethod(method, new Class[0]);
if (disableMethod != null) {
disableMethod.invoke(clazz.newInstance());
}
}
catch (Exception e) {
//
}
}
}
public static void unloadShell(String shell) {
invokeMethod(shell, "onDisable");
Class<?> clazz = shells.remove(shell);
try {
if (clazz.newInstance() instanceof Listener) {
for (RegisteredListener listener : HandlerList.getRegisteredListeners(Main.getInst())) {
if (listener.getListener().getClass().getName().equals(clazz.getName())) {
HandlerList.unregisterAll(listener.getListener());
}
}
MsgUtils.send("已为脚本 &f" + shell + " &7注销监听器");
}
}
catch (Exception e) {
//
}
}
public static boolean reloadShell(String shell) {
unloadShell(shell = shell.replace(".java", ""));
try {
Class.forName("com.sun.tools.javac.main.Main");
}
catch (Exception e) {
MsgUtils.warn("&4JavaShell &c工具的必要依赖 &4com.sun.tools.jar &c丢失, 无法载入!");
return false;
}
File javaFile = new File(scriptFolder, shell + ".java");
if (!javaFile.exists()) {
MsgUtils.send("&c脚本 &4" + shell + "&c 不存在");
return false;
}
String[] args = {
"-nowarn",
"-classpath", "." + File.pathSeparator + JavaShell.getPaths(),
"-d", cacheFolder.getAbsolutePath() + File.separator,
javaFile.getAbsolutePath()
};
int code = new com.sun.tools.javac.main.Main("javac").compile(args).exitCode;
if (code == 0) {
MsgUtils.send("&f" + shell + "&7 载入成功");
try {
URL[] urls = { cacheFolder.toURI().toURL() };
URLClassLoader sysloader = new URLClassLoader(urls, Main.class.getClassLoader());
Class<?> clazz = sysloader.loadClass(shell);
shells.put(shell, clazz);
sysloader.close();
invokeMethod(shell, "onEnable");
if (clazz.newInstance() instanceof Listener) {
Bukkit.getPluginManager().registerEvents((Listener) clazz.newInstance(), Main.getInst());
MsgUtils.send("已为脚本 &f" + shell + " &7注册监听器");
}
}
catch (Exception e) {
//
}
return true;
}
else {
MsgUtils.send("&4" + shell + "&c 载入失败");
return false;
}
}
private static void loadLibrary() {
for (File jar : libFolder.listFiles()) {
try {
JarUtils.addClassPath(JarUtils.getJarUrl(jar));
MsgUtils.send("成功载入 &f" + jar.getName() + " &7到运行库");
} catch (Exception e) {
//
}
}
}
}

View File

@@ -0,0 +1,104 @@
package me.skymc.taboolib.javashell.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.bukkit.Bukkit;
import me.skymc.taboolib.message.MsgUtils;
public class JarUtils {
public static boolean extractFromJar(final String fileName, final String dest) throws IOException {
if (getRunningJar() == null) {
return false;
}
final File file = new File(dest);
if (file.isDirectory()) {
file.mkdir();
return false;
}
if (!file.exists()) {
file.getParentFile().mkdirs();
}
final JarFile jar = getRunningJar();
final Enumeration<JarEntry> e = jar.entries();
while (e.hasMoreElements()) {
final JarEntry je = e.nextElement();
if (!je.getName().contains(fileName)) {
continue;
}
final InputStream in = new BufferedInputStream(jar.getInputStream(je));
final OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
copyInputStream(in, out);
jar.close();
return true;
}
jar.close();
return false;
}
private final static void copyInputStream(final InputStream in, final OutputStream out) throws IOException {
try {
final byte[] buff = new byte[4096];
int n;
while ((n = in.read(buff)) > 0) {
out.write(buff, 0, n);
}
} finally {
out.flush();
out.close();
in.close();
}
}
public static URL getJarUrl(final File file) throws IOException {
return new URL("jar:" + file.toURI().toURL().toExternalForm() + "!/");
}
public static JarFile getRunningJar() throws IOException {
if (!RUNNING_FROM_JAR) {
return null; // null if not running from jar
}
String path = new File(JarUtils.class.getProtectionDomain().getCodeSource().getLocation().getPath())
.getAbsolutePath();
path = URLDecoder.decode(path, "UTF-8");
return new JarFile(path);
}
private static boolean RUNNING_FROM_JAR = false;
static {
final URL resource = JarUtils.class.getClassLoader().getResource("plugin.yml");
if (resource != null) {
RUNNING_FROM_JAR = true;
}
}
public static void addClassPath(final URL url) throws IOException {
final URLClassLoader sysloader = (URLClassLoader) Bukkit.class.getClassLoader();
final Class<URLClassLoader> sysclass = URLClassLoader.class;
try {
final Method method = sysclass.getDeclaredMethod("addURL", new Class[] { URL.class });
method.setAccessible(true);
method.invoke(sysloader, new Object[] { url });
} catch (Throwable t) {
MsgUtils.warn("无法添加添加 &4" + url + "&c 到运行库");
MsgUtils.warn(t.getMessage());
}
}
}

View File

@@ -0,0 +1,158 @@
package me.skymc.taboolib.json;
public class CDL {
private static String getValue(JSONTokener x) throws JSONException {
char c;
char q;
StringBuffer sb;
do {
c = x.next();
} while (c == ' ' || c == '\t');
switch (c) {
case 0:
return null;
case '"':
case '\'':
q = c;
sb = new StringBuffer();
for (;;) {
c = x.next();
if (c == q) {
break;
}
if (c == 0 || c == '\n' || c == '\r') {
throw x.syntaxError("Missing close quote '" + q + "'.");
}
sb.append(c);
}
return sb.toString();
case ',':
x.back();
return "";
default:
x.back();
return x.nextTo(',');
}
}
public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
JSONArray ja = new JSONArray();
for (;;) {
String value = getValue(x);
char c = x.next();
if (value == null ||
(ja.length() == 0 && value.length() == 0 && c != ',')) {
return null;
}
ja.put(value);
for (;;) {
if (c == ',') {
break;
}
if (c != ' ') {
if (c == '\n' || c == '\r' || c == 0) {
return ja;
}
throw x.syntaxError("Bad character '" + c + "' (" +
(int)c + ").");
}
c = x.next();
}
}
}
public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
throws JSONException {
JSONArray ja = rowToJSONArray(x);
return ja != null ? ja.toJSONObject(names) : null;
}
public static String rowToString(JSONArray ja) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < ja.length(); i += 1) {
if (i > 0) {
sb.append(',');
}
Object object = ja.opt(i);
if (object != null) {
String string = object.toString();
if (string.length() > 0 && (string.indexOf(',') >= 0 ||
string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 ||
string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
sb.append('"');
int length = string.length();
for (int j = 0; j < length; j += 1) {
char c = string.charAt(j);
if (c >= ' ' && c != '"') {
sb.append(c);
}
}
sb.append('"');
} else {
sb.append(string);
}
}
}
sb.append('\n');
return sb.toString();
}
public static JSONArray toJSONArray(String string) throws JSONException {
return toJSONArray(new JSONTokener(string));
}
public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
return toJSONArray(rowToJSONArray(x), x);
}
public static JSONArray toJSONArray(JSONArray names, String string)
throws JSONException {
return toJSONArray(names, new JSONTokener(string));
}
public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
throws JSONException {
if (names == null || names.length() == 0) {
return null;
}
JSONArray ja = new JSONArray();
for (;;) {
JSONObject jo = rowToJSONObject(names, x);
if (jo == null) {
break;
}
ja.put(jo);
}
if (ja.length() == 0) {
return null;
}
return ja;
}
public static String toString(JSONArray ja) throws JSONException {
JSONObject jo = ja.optJSONObject(0);
if (jo != null) {
JSONArray names = jo.names();
if (names != null) {
return rowToString(names) + toString(names, ja);
}
}
return null;
}
public static String toString(JSONArray names, JSONArray ja)
throws JSONException {
if (names == null || names.length() == 0) {
return null;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < ja.length(); i += 1) {
JSONObject jo = ja.optJSONObject(i);
if (jo != null) {
sb.append(rowToString(jo.toJSONArray(names)));
}
}
return sb.toString();
}
}

View File

@@ -0,0 +1,92 @@
package me.skymc.taboolib.json;
public class Cookie {
public static String escape(String string) {
char c;
String s = string.trim();
StringBuffer sb = new StringBuffer();
int length = s.length();
for (int i = 0; i < length; i += 1) {
c = s.charAt(i);
if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
sb.append('%');
sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
sb.append(Character.forDigit((char)(c & 0x0f), 16));
} else {
sb.append(c);
}
}
return sb.toString();
}
public static JSONObject toJSONObject(String string) throws JSONException {
String name;
JSONObject jo = new JSONObject();
Object value;
JSONTokener x = new JSONTokener(string);
jo.put("name", x.nextTo('='));
x.next('=');
jo.put("value", x.nextTo(';'));
x.next();
while (x.more()) {
name = unescape(x.nextTo("=;"));
if (x.next() != '=') {
if (name.equals("secure")) {
value = Boolean.TRUE;
} else {
throw x.syntaxError("Missing '=' in cookie parameter.");
}
} else {
value = unescape(x.nextTo(';'));
x.next();
}
jo.put(name, value);
}
return jo;
}
public static String toString(JSONObject jo) throws JSONException {
StringBuffer sb = new StringBuffer();
sb.append(escape(jo.getString("name")));
sb.append("=");
sb.append(escape(jo.getString("value")));
if (jo.has("expires")) {
sb.append(";expires=");
sb.append(jo.getString("expires"));
}
if (jo.has("domain")) {
sb.append(";domain=");
sb.append(escape(jo.getString("domain")));
}
if (jo.has("path")) {
sb.append(";path=");
sb.append(escape(jo.getString("path")));
}
if (jo.optBoolean("secure")) {
sb.append(";secure");
}
return sb.toString();
}
public static String unescape(String string) {
int length = string.length();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; ++i) {
char c = string.charAt(i);
if (c == '+') {
c = ' ';
} else if (c == '%' && i + 2 < length) {
int d = JSONTokener.dehexchar(string.charAt(i + 1));
int e = JSONTokener.dehexchar(string.charAt(i + 2));
if (d >= 0 && e >= 0) {
c = (char)(d * 16 + e);
i += 2;
}
}
sb.append(c);
}
return sb.toString();
}
}

View File

@@ -0,0 +1,39 @@
package me.skymc.taboolib.json;
import java.util.Iterator;
public class CookieList {
public static JSONObject toJSONObject(String string) throws JSONException {
JSONObject jo = new JSONObject();
JSONTokener x = new JSONTokener(string);
while (x.more()) {
String name = Cookie.unescape(x.nextTo('='));
x.next('=');
jo.put(name, Cookie.unescape(x.nextTo(';')));
x.next();
}
return jo;
}
@SuppressWarnings("rawtypes")
public static String toString(JSONObject jo) throws JSONException {
boolean b = false;
Iterator keys = jo.keys();
String string;
StringBuffer sb = new StringBuffer();
while (keys.hasNext()) {
string = keys.next().toString();
if (!jo.isNull(string)) {
if (b) {
sb.append(';');
}
sb.append(Cookie.escape(string));
sb.append("=");
sb.append(Cookie.escape(jo.getString(string)));
b = true;
}
}
return sb.toString();
}
}

View File

@@ -0,0 +1,71 @@
package me.skymc.taboolib.json;
import java.util.Iterator;
public class HTTP {
public static final String CRLF = "\r\n";
public static JSONObject toJSONObject(String string) throws JSONException {
JSONObject jo = new JSONObject();
HTTPTokener x = new HTTPTokener(string);
String token;
token = x.nextToken();
if (token.toUpperCase().startsWith("HTTP")) {
jo.put("HTTP-Version", token);
jo.put("Status-Code", x.nextToken());
jo.put("Reason-Phrase", x.nextTo('\0'));
x.next();
} else {
jo.put("Method", token);
jo.put("Request-URI", x.nextToken());
jo.put("HTTP-Version", x.nextToken());
}
while (x.more()) {
String name = x.nextTo(':');
x.next(':');
jo.put(name, x.nextTo('\0'));
x.next();
}
return jo;
}
@SuppressWarnings("rawtypes")
public static String toString(JSONObject jo) throws JSONException {
Iterator keys = jo.keys();
String string;
StringBuffer sb = new StringBuffer();
if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
sb.append(jo.getString("HTTP-Version"));
sb.append(' ');
sb.append(jo.getString("Status-Code"));
sb.append(' ');
sb.append(jo.getString("Reason-Phrase"));
} else if (jo.has("Method") && jo.has("Request-URI")) {
sb.append(jo.getString("Method"));
sb.append(' ');
sb.append('"');
sb.append(jo.getString("Request-URI"));
sb.append('"');
sb.append(' ');
sb.append(jo.getString("HTTP-Version"));
} else {
throw new JSONException("Not enough material for an HTTP header.");
}
sb.append(CRLF);
while (keys.hasNext()) {
string = keys.next().toString();
if (!"HTTP-Version".equals(string) && !"Status-Code".equals(string) &&
!"Reason-Phrase".equals(string) && !"Method".equals(string) &&
!"Request-URI".equals(string) && !jo.isNull(string)) {
sb.append(string);
sb.append(": ");
sb.append(jo.getString(string));
sb.append(CRLF);
}
}
sb.append(CRLF);
return sb.toString();
}
}

View File

@@ -0,0 +1,37 @@
package me.skymc.taboolib.json;
public class HTTPTokener extends JSONTokener {
public HTTPTokener(String string) {
super(string);
}
public String nextToken() throws JSONException {
char c;
char q;
StringBuffer sb = new StringBuffer();
do {
c = next();
} while (Character.isWhitespace(c));
if (c == '"' || c == '\'') {
q = c;
for (;;) {
c = next();
if (c < ' ') {
throw syntaxError("Unterminated string.");
}
if (c == q) {
return sb.toString();
}
sb.append(c);
}
}
for (;;) {
if (c == 0 || Character.isWhitespace(c)) {
return sb.toString();
}
sb.append(c);
c = next();
}
}
}

View File

@@ -0,0 +1,414 @@
package me.skymc.taboolib.json;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
@SuppressWarnings({"rawtypes", "unchecked"})
public class JSONArray {
private final ArrayList myArrayList;
public JSONArray() {
this.myArrayList = new ArrayList();
}
public JSONArray(JSONTokener x) throws JSONException {
this();
if (x.nextClean() != '[') {
throw x.syntaxError("A JSONArray text must start with '['");
}
if (x.nextClean() != ']') {
x.back();
for (;;) {
if (x.nextClean() == ',') {
x.back();
this.myArrayList.add(JSONObject.NULL);
} else {
x.back();
this.myArrayList.add(x.nextValue());
}
switch (x.nextClean()) {
case ';':
case ',':
if (x.nextClean() == ']') {
return;
}
x.back();
break;
case ']':
return;
default:
throw x.syntaxError("Expected a ',' or ']'");
}
}
}
}
public JSONArray(String source) throws JSONException {
this(new JSONTokener(source));
}
public JSONArray(Collection collection) {
this.myArrayList = new ArrayList();
if (collection != null) {
Iterator iter = collection.iterator();
while (iter.hasNext()) {
this.myArrayList.add(JSONObject.wrap(iter.next()));
}
}
}
public JSONArray(Object array) throws JSONException {
this();
if (array.getClass().isArray()) {
int length = Array.getLength(array);
for (int i = 0; i < length; i += 1) {
this.put(JSONObject.wrap(Array.get(array, i)));
}
} else {
throw new JSONException("JSONArray initial value should be a string or collection or array.");
}
}
public Object get(int index) throws JSONException {
Object object = this.opt(index);
if (object == null) {
throw new JSONException("JSONArray[" + index + "] not found.");
}
return object;
}
public boolean getBoolean(int index) throws JSONException {
Object object = this.get(index);
if (object.equals(Boolean.FALSE) ||
(object instanceof String &&
((String)object).equalsIgnoreCase("false"))) {
return false;
} else if (object.equals(Boolean.TRUE) ||
(object instanceof String &&
((String)object).equalsIgnoreCase("true"))) {
return true;
}
throw new JSONException("JSONArray[" + index + "] is not a boolean.");
}
public double getDouble(int index) throws JSONException {
Object object = this.get(index);
try {
return object instanceof Number
? ((Number)object).doubleValue()
: Double.parseDouble((String)object);
} catch (Exception e) {
throw new JSONException("JSONArray[" + index +
"] is not a number.");
}
}
public int getInt(int index) throws JSONException {
Object object = this.get(index);
try {
return object instanceof Number
? ((Number)object).intValue()
: Integer.parseInt((String)object);
} catch (Exception e) {
throw new JSONException("JSONArray[" + index +
"] is not a number.");
}
}
public JSONArray getJSONArray(int index) throws JSONException {
Object object = this.get(index);
if (object instanceof JSONArray) {
return (JSONArray)object;
}
throw new JSONException("JSONArray[" + index +
"] is not a JSONArray.");
}
public JSONObject getJSONObject(int index) throws JSONException {
Object object = this.get(index);
if (object instanceof JSONObject) {
return (JSONObject)object;
}
throw new JSONException("JSONArray[" + index +
"] is not a JSONObject.");
}
public long getLong(int index) throws JSONException {
Object object = this.get(index);
try {
return object instanceof Number
? ((Number)object).longValue()
: Long.parseLong((String)object);
} catch (Exception e) {
throw new JSONException("JSONArray[" + index +
"] is not a number.");
}
}
public String getString(int index) throws JSONException {
Object object = this.get(index);
if (object instanceof String) {
return (String)object;
}
throw new JSONException("JSONArray[" + index + "] not a string.");
}
public boolean isNull(int index) {
return JSONObject.NULL.equals(this.opt(index));
}
public String join(String separator) throws JSONException {
int len = this.length();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < len; i += 1) {
if (i > 0) {
sb.append(separator);
}
sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
}
return sb.toString();
}
public int length() {
return this.myArrayList.size();
}
public Object opt(int index) {
return (index < 0 || index >= this.length())
? null
: this.myArrayList.get(index);
}
public boolean optBoolean(int index) {
return this.optBoolean(index, false);
}
public boolean optBoolean(int index, boolean defaultValue) {
try {
return this.getBoolean(index);
} catch (Exception e) {
return defaultValue;
}
}
public double optDouble(int index) {
return this.optDouble(index, Double.NaN);
}
public double optDouble(int index, double defaultValue) {
try {
return this.getDouble(index);
} catch (Exception e) {
return defaultValue;
}
}
public int optInt(int index) {
return this.optInt(index, 0);
}
public int optInt(int index, int defaultValue) {
try {
return this.getInt(index);
} catch (Exception e) {
return defaultValue;
}
}
public JSONArray optJSONArray(int index) {
Object o = this.opt(index);
return o instanceof JSONArray ? (JSONArray)o : null;
}
public JSONObject optJSONObject(int index) {
Object o = this.opt(index);
return o instanceof JSONObject ? (JSONObject)o : null;
}
public long optLong(int index) {
return this.optLong(index, 0);
}
public long optLong(int index, long defaultValue) {
try {
return this.getLong(index);
} catch (Exception e) {
return defaultValue;
}
}
public String optString(int index) {
return this.optString(index, "");
}
public String optString(int index, String defaultValue) {
Object object = this.opt(index);
return JSONObject.NULL.equals(object)
? defaultValue : object
.toString();
}
public JSONArray put(boolean value) {
this.put(value ? Boolean.TRUE : Boolean.FALSE);
return this;
}
public JSONArray put(Collection value) {
this.put(new JSONArray(value));
return this;
}
public JSONArray put(double value) throws JSONException {
Double d = new Double(value);
JSONObject.testValidity(d);
this.put(d);
return this;
}
public JSONArray put(int value) {
this.put(new Integer(value));
return this;
}
public JSONArray put(long value) {
this.put(new Long(value));
return this;
}
public JSONArray put(Map value) {
this.put(new JSONObject(value));
return this;
}
public JSONArray put(Object value) {
this.myArrayList.add(value);
return this;
}
public JSONArray put(int index, boolean value) throws JSONException {
this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
return this;
}
public JSONArray put(int index, Collection value) throws JSONException {
this.put(index, new JSONArray(value));
return this;
}
public JSONArray put(int index, double value) throws JSONException {
this.put(index, new Double(value));
return this;
}
public JSONArray put(int index, int value) throws JSONException {
this.put(index, new Integer(value));
return this;
}
public JSONArray put(int index, long value) throws JSONException {
this.put(index, new Long(value));
return this;
}
public JSONArray put(int index, Map value) throws JSONException {
this.put(index, new JSONObject(value));
return this;
}
public JSONArray put(int index, Object value) throws JSONException {
JSONObject.testValidity(value);
if (index < 0) {
throw new JSONException("JSONArray[" + index + "] not found.");
}
if (index < this.length()) {
this.myArrayList.set(index, value);
} else {
while (index != this.length()) {
this.put(JSONObject.NULL);
}
this.put(value);
}
return this;
}
public Object remove(int index) {
Object o = this.opt(index);
this.myArrayList.remove(index);
return o;
}
public JSONObject toJSONObject(JSONArray names) throws JSONException {
if (names == null || names.length() == 0 || this.length() == 0) {
return null;
}
JSONObject jo = new JSONObject();
for (int i = 0; i < names.length(); i += 1) {
jo.put(names.getString(i), this.opt(i));
}
return jo;
}
public String toString() {
try {
return '[' + this.join(",") + ']';
} catch (Exception e) {
return null;
}
}
public String toString(int indentFactor) throws JSONException {
StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) {
return this.write(sw, indentFactor, 0).toString();
}
}
public Writer write(Writer writer) throws JSONException {
return this.write(writer, 0, 0);
}
Writer write(Writer writer, int indentFactor, int indent)
throws JSONException {
try {
boolean commanate = false;
int length = this.length();
writer.write('[');
if (length == 1) {
JSONObject.writeValue(writer, this.myArrayList.get(0),
indentFactor, indent);
} else if (length != 0) {
final int newindent = indent + indentFactor;
for (int i = 0; i < length; i += 1) {
if (commanate) {
writer.write(',');
}
if (indentFactor > 0) {
writer.write('\n');
}
JSONObject.indent(writer, newindent);
JSONObject.writeValue(writer, this.myArrayList.get(i),
indentFactor, newindent);
commanate = true;
}
if (indentFactor > 0) {
writer.write('\n');
}
JSONObject.indent(writer, indent);
}
writer.write(']');
return writer;
} catch (IOException e) {
throw new JSONException(e);
}
}
}

View File

@@ -0,0 +1,21 @@
package me.skymc.taboolib.json;
public class JSONException extends Exception {
private static final long serialVersionUID = 0;
private Throwable cause;
public JSONException(String message) {
super(message);
}
public JSONException(Throwable cause) {
super(cause.getMessage());
this.cause = cause;
}
public Throwable getCause() {
return this.cause;
}
}

View File

@@ -0,0 +1,311 @@
package me.skymc.taboolib.json;
import java.util.Iterator;
@SuppressWarnings({"rawtypes"})
public class JSONML {
private static Object parse(
XMLTokener x,
boolean arrayForm,
JSONArray ja
) throws JSONException {
String attribute;
char c;
String closeTag = null;
int i;
JSONArray newja = null;
JSONObject newjo = null;
Object token;
String tagName = null;
while (true) {
if (!x.more()) {
throw x.syntaxError("Bad XML");
}
token = x.nextContent();
if (token == XML.LT) {
token = x.nextToken();
if (token instanceof Character) {
if (token == XML.SLASH) {
token = x.nextToken();
if (!(token instanceof String)) {
throw new JSONException(
"Expected a closing name instead of '" +
token + "'.");
}
if (x.nextToken() != XML.GT) {
throw x.syntaxError("Misshaped close tag");
}
return token;
} else if (token == XML.BANG) {
c = x.next();
if (c == '-') {
if (x.next() == '-') {
x.skipPast("-->");
} else {
x.back();
}
} else if (c == '[') {
token = x.nextToken();
if (token.equals("CDATA") && x.next() == '[') {
if (ja != null) {
ja.put(x.nextCDATA());
}
} else {
throw x.syntaxError("Expected 'CDATA['");
}
} else {
i = 1;
do {
token = x.nextMeta();
if (token == null) {
throw x.syntaxError("Missing '>' after '<!'.");
} else if (token == XML.LT) {
i += 1;
} else if (token == XML.GT) {
i -= 1;
}
} while (i > 0);
}
} else if (token == XML.QUEST) {
x.skipPast("?>");
} else {
throw x.syntaxError("Misshaped tag");
}
} else {
if (!(token instanceof String)) {
throw x.syntaxError("Bad tagName '" + token + "'.");
}
tagName = (String)token;
newja = new JSONArray();
newjo = new JSONObject();
if (arrayForm) {
newja.put(tagName);
if (ja != null) {
ja.put(newja);
}
} else {
newjo.put("tagName", tagName);
if (ja != null) {
ja.put(newjo);
}
}
token = null;
for (;;) {
if (token == null) {
token = x.nextToken();
}
if (token == null) {
throw x.syntaxError("Misshaped tag");
}
if (!(token instanceof String)) {
break;
}
attribute = (String)token;
if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) {
throw x.syntaxError("Reserved attribute.");
}
token = x.nextToken();
if (token == XML.EQ) {
token = x.nextToken();
if (!(token instanceof String)) {
throw x.syntaxError("Missing value");
}
newjo.accumulate(attribute, XML.stringToValue((String)token));
token = null;
} else {
newjo.accumulate(attribute, "");
}
}
if (arrayForm && newjo.length() > 0) {
newja.put(newjo);
}
if (token == XML.SLASH) {
if (x.nextToken() != XML.GT) {
throw x.syntaxError("Misshaped tag");
}
if (ja == null) {
if (arrayForm) {
return newja;
} else {
return newjo;
}
}
} else {
if (token != XML.GT) {
throw x.syntaxError("Misshaped tag");
}
closeTag = (String)parse(x, arrayForm, newja);
if (closeTag != null) {
if (!closeTag.equals(tagName)) {
throw x.syntaxError("Mismatched '" + tagName +
"' and '" + closeTag + "'");
}
tagName = null;
if (!arrayForm && newja.length() > 0) {
newjo.put("childNodes", newja);
}
if (ja == null) {
if (arrayForm) {
return newja;
} else {
return newjo;
}
}
}
}
}
} else {
if (ja != null) {
ja.put(token instanceof String
? XML.stringToValue((String)token)
: token);
}
}
}
}
public static JSONArray toJSONArray(String string) throws JSONException {
return toJSONArray(new XMLTokener(string));
}
public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
return (JSONArray)parse(x, true, null);
}
public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
return (JSONObject)parse(x, false, null);
}
public static JSONObject toJSONObject(String string) throws JSONException {
return toJSONObject(new XMLTokener(string));
}
public static String toString(JSONArray ja) throws JSONException {
int i;
JSONObject jo;
String key;
Iterator keys;
int length;
Object object;
StringBuffer sb = new StringBuffer();
String tagName;
String value;
tagName = ja.getString(0);
XML.noSpace(tagName);
tagName = XML.escape(tagName);
sb.append('<');
sb.append(tagName);
object = ja.opt(1);
if (object instanceof JSONObject) {
i = 2;
jo = (JSONObject)object;
keys = jo.keys();
while (keys.hasNext()) {
key = keys.next().toString();
XML.noSpace(key);
value = jo.optString(key);
if (value != null) {
sb.append(' ');
sb.append(XML.escape(key));
sb.append('=');
sb.append('"');
sb.append(XML.escape(value));
sb.append('"');
}
}
} else {
i = 1;
}
length = ja.length();
if (i >= length) {
sb.append('/');
sb.append('>');
} else {
sb.append('>');
do {
object = ja.get(i);
i += 1;
if (object != null) {
if (object instanceof String) {
sb.append(XML.escape(object.toString()));
} else if (object instanceof JSONObject) {
sb.append(toString((JSONObject)object));
} else if (object instanceof JSONArray) {
sb.append(toString((JSONArray)object));
}
}
} while (i < length);
sb.append('<');
sb.append('/');
sb.append(tagName);
sb.append('>');
}
return sb.toString();
}
public static String toString(JSONObject jo) throws JSONException {
StringBuffer sb = new StringBuffer();
int i;
JSONArray ja;
String key;
Iterator keys;
int length;
Object object;
String tagName;
String value;
tagName = jo.optString("tagName");
if (tagName == null) {
return XML.escape(jo.toString());
}
XML.noSpace(tagName);
tagName = XML.escape(tagName);
sb.append('<');
sb.append(tagName);
keys = jo.keys();
while (keys.hasNext()) {
key = keys.next().toString();
if (!"tagName".equals(key) && !"childNodes".equals(key)) {
XML.noSpace(key);
value = jo.optString(key);
if (value != null) {
sb.append(' ');
sb.append(XML.escape(key));
sb.append('=');
sb.append('"');
sb.append(XML.escape(value));
sb.append('"');
}
}
}
ja = jo.optJSONArray("childNodes");
if (ja == null) {
sb.append('/');
sb.append('>');
} else {
sb.append('>');
length = ja.length();
for (i = 0; i < length; i += 1) {
object = ja.get(i);
if (object != null) {
if (object instanceof String) {
sb.append(XML.escape(object.toString()));
} else if (object instanceof JSONObject) {
sb.append(toString((JSONObject)object));
} else if (object instanceof JSONArray) {
sb.append(toString((JSONArray)object));
} else {
sb.append(object.toString());
}
}
}
sb.append('<');
sb.append('/');
sb.append(tagName);
sb.append('>');
}
return sb.toString();
}
}

View File

@@ -0,0 +1,884 @@
package me.skymc.taboolib.json;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
@SuppressWarnings({"rawtypes", "unchecked"})
public class JSONObject {
private static final class Null {
protected final Object clone() {
return this;
}
public boolean equals(Object object) {
return object == null || object == this;
}
public String toString() {
return "null";
}
}
private final Map map;
public static final Object NULL = new Null();
public JSONObject() {
this.map = new HashMap();
}
public JSONObject(JSONObject jo, String[] names) {
this();
for (int i = 0; i < names.length; i += 1) {
try {
this.putOnce(names[i], jo.opt(names[i]));
} catch (Exception ignore) {
}
}
}
public JSONObject(JSONTokener x) throws JSONException {
this();
char c;
String key;
if (x.nextClean() != '{') {
throw x.syntaxError("A JSONObject text must begin with '{'");
}
for (;;) {
c = x.nextClean();
switch (c) {
case 0:
throw x.syntaxError("A JSONObject text must end with '}'");
case '}':
return;
default:
x.back();
key = x.nextValue().toString();
}
c = x.nextClean();
if (c == '=') {
if (x.next() != '>') {
x.back();
}
} else if (c != ':') {
throw x.syntaxError("Expected a ':' after a key");
}
this.putOnce(key, x.nextValue());
switch (x.nextClean()) {
case ';':
case ',':
if (x.nextClean() == '}') {
return;
}
x.back();
break;
case '}':
return;
default:
throw x.syntaxError("Expected a ',' or '}'");
}
}
}
public JSONObject(Map map) {
this.map = new HashMap();
if (map != null) {
Iterator i = map.entrySet().iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry)i.next();
Object value = e.getValue();
if (value != null) {
this.map.put(e.getKey(), wrap(value));
}
}
}
}
public JSONObject(Object bean) {
this();
this.populateMap(bean);
}
public JSONObject(Object object, String names[]) {
this();
Class c = object.getClass();
for (int i = 0; i < names.length; i += 1) {
String name = names[i];
try {
this.putOpt(name, c.getField(name).get(object));
} catch (Exception ignore) {
}
}
}
public JSONObject(String source) throws JSONException {
this(new JSONTokener(source));
}
public JSONObject(String baseName, Locale locale) throws JSONException {
this();
ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale,
Thread.currentThread().getContextClassLoader());
Enumeration keys = bundle.getKeys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
if (key instanceof String) {
String[] path = ((String)key).split("\\.");
int last = path.length - 1;
JSONObject target = this;
for (int i = 0; i < last; i += 1) {
String segment = path[i];
JSONObject nextTarget = target.optJSONObject(segment);
if (nextTarget == null) {
nextTarget = new JSONObject();
target.put(segment, nextTarget);
}
target = nextTarget;
}
target.put(path[last], bundle.getString((String)key));
}
}
}
public JSONObject accumulate(
String key,
Object value
) throws JSONException {
testValidity(value);
Object object = this.opt(key);
if (object == null) {
this.put(key, value instanceof JSONArray
? new JSONArray().put(value)
: value);
} else if (object instanceof JSONArray) {
((JSONArray)object).put(value);
} else {
this.put(key, new JSONArray().put(object).put(value));
}
return this;
}
public JSONObject append(String key, Object value) throws JSONException {
testValidity(value);
Object object = this.opt(key);
if (object == null) {
this.put(key, new JSONArray().put(value));
} else if (object instanceof JSONArray) {
this.put(key, ((JSONArray)object).put(value));
} else {
throw new JSONException("JSONObject[" + key +
"] is not a JSONArray.");
}
return this;
}
public static String doubleToString(double d) {
if (Double.isInfinite(d) || Double.isNaN(d)) {
return "null";
}
String string = Double.toString(d);
if (string.indexOf('.') > 0 && string.indexOf('e') < 0 &&
string.indexOf('E') < 0) {
while (string.endsWith("0")) {
string = string.substring(0, string.length() - 1);
}
if (string.endsWith(".")) {
string = string.substring(0, string.length() - 1);
}
}
return string;
}
public Object get(String key) throws JSONException {
if (key == null) {
throw new JSONException("Null key.");
}
Object object = this.opt(key);
if (object == null) {
throw new JSONException("JSONObject[" + quote(key) +
"] not found.");
}
return object;
}
public boolean getBoolean(String key) throws JSONException {
Object object = this.get(key);
if (object.equals(Boolean.FALSE) ||
(object instanceof String &&
((String)object).equalsIgnoreCase("false"))) {
return false;
} else if (object.equals(Boolean.TRUE) ||
(object instanceof String &&
((String)object).equalsIgnoreCase("true"))) {
return true;
}
throw new JSONException("JSONObject[" + quote(key) +
"] is not a Boolean.");
}
public double getDouble(String key) throws JSONException {
Object object = this.get(key);
try {
return object instanceof Number
? ((Number)object).doubleValue()
: Double.parseDouble((String)object);
} catch (Exception e) {
throw new JSONException("JSONObject[" + quote(key) +
"] is not a number.");
}
}
public int getInt(String key) throws JSONException {
Object object = this.get(key);
try {
return object instanceof Number
? ((Number)object).intValue()
: Integer.parseInt((String)object);
} catch (Exception e) {
throw new JSONException("JSONObject[" + quote(key) +
"] is not an int.");
}
}
public JSONArray getJSONArray(String key) throws JSONException {
Object object = this.get(key);
if (object instanceof JSONArray) {
return (JSONArray)object;
}
throw new JSONException("JSONObject[" + quote(key) +
"] is not a JSONArray.");
}
public JSONObject getJSONObject(String key) throws JSONException {
Object object = this.get(key);
if (object instanceof JSONObject) {
return (JSONObject)object;
}
throw new JSONException("JSONObject[" + quote(key) +
"] is not a JSONObject.");
}
public long getLong(String key) throws JSONException {
Object object = this.get(key);
try {
return object instanceof Number
? ((Number)object).longValue()
: Long.parseLong((String)object);
} catch (Exception e) {
throw new JSONException("JSONObject[" + quote(key) +
"] is not a long.");
}
}
public static String[] getNames(JSONObject jo) {
int length = jo.length();
if (length == 0) {
return null;
}
Iterator iterator = jo.keys();
String[] names = new String[length];
int i = 0;
while (iterator.hasNext()) {
names[i] = (String)iterator.next();
i += 1;
}
return names;
}
public static String[] getNames(Object object) {
if (object == null) {
return null;
}
Class klass = object.getClass();
Field[] fields = klass.getFields();
int length = fields.length;
if (length == 0) {
return null;
}
String[] names = new String[length];
for (int i = 0; i < length; i += 1) {
names[i] = fields[i].getName();
}
return names;
}
public String getString(String key) throws JSONException {
Object object = this.get(key);
if (object instanceof String) {
return (String)object;
}
throw new JSONException("JSONObject[" + quote(key) +
"] not a string.");
}
public boolean has(String key) {
return this.map.containsKey(key);
}
public JSONObject increment(String key) throws JSONException {
Object value = this.opt(key);
if (value == null) {
this.put(key, 1);
} else if (value instanceof Integer) {
this.put(key, ((Integer)value).intValue() + 1);
} else if (value instanceof Long) {
this.put(key, ((Long)value).longValue() + 1);
} else if (value instanceof Double) {
this.put(key, ((Double)value).doubleValue() + 1);
} else if (value instanceof Float) {
this.put(key, ((Float)value).floatValue() + 1);
} else {
throw new JSONException("Unable to increment [" + quote(key) + "].");
}
return this;
}
public boolean isNull(String key) {
return JSONObject.NULL.equals(this.opt(key));
}
public Iterator keys() {
return this.map.keySet().iterator();
}
public int length() {
return this.map.size();
}
public JSONArray names() {
JSONArray ja = new JSONArray();
Iterator keys = this.keys();
while (keys.hasNext()) {
ja.put(keys.next());
}
return ja.length() == 0 ? null : ja;
}
public static String numberToString(Number number)
throws JSONException {
if (number == null) {
throw new JSONException("Null pointer");
}
testValidity(number);
String string = number.toString();
if (string.indexOf('.') > 0 && string.indexOf('e') < 0 &&
string.indexOf('E') < 0) {
while (string.endsWith("0")) {
string = string.substring(0, string.length() - 1);
}
if (string.endsWith(".")) {
string = string.substring(0, string.length() - 1);
}
}
return string;
}
public Object opt(String key) {
return key == null ? null : this.map.get(key);
}
public boolean optBoolean(String key) {
return this.optBoolean(key, false);
}
public boolean optBoolean(String key, boolean defaultValue) {
try {
return this.getBoolean(key);
} catch (Exception e) {
return defaultValue;
}
}
public double optDouble(String key) {
return this.optDouble(key, Double.NaN);
}
public double optDouble(String key, double defaultValue) {
try {
return this.getDouble(key);
} catch (Exception e) {
return defaultValue;
}
}
public int optInt(String key) {
return this.optInt(key, 0);
}
public int optInt(String key, int defaultValue) {
try {
return this.getInt(key);
} catch (Exception e) {
return defaultValue;
}
}
public JSONArray optJSONArray(String key) {
Object o = this.opt(key);
return o instanceof JSONArray ? (JSONArray)o : null;
}
public JSONObject optJSONObject(String key) {
Object object = this.opt(key);
return object instanceof JSONObject ? (JSONObject)object : null;
}
public long optLong(String key) {
return this.optLong(key, 0);
}
public long optLong(String key, long defaultValue) {
try {
return this.getLong(key);
} catch (Exception e) {
return defaultValue;
}
}
public String optString(String key) {
return this.optString(key, "");
}
public String optString(String key, String defaultValue) {
Object object = this.opt(key);
return NULL.equals(object) ? defaultValue : object.toString();
}
private void populateMap(Object bean) {
Class klass = bean.getClass();
boolean includeSuperClass = klass.getClassLoader() != null;
Method[] methods = includeSuperClass
? klass.getMethods()
: klass.getDeclaredMethods();
for (int i = 0; i < methods.length; i += 1) {
try {
Method method = methods[i];
if (Modifier.isPublic(method.getModifiers())) {
String name = method.getName();
String key = "";
if (name.startsWith("get")) {
if ("getClass".equals(name) ||
"getDeclaringClass".equals(name)) {
key = "";
} else {
key = name.substring(3);
}
} else if (name.startsWith("is")) {
key = name.substring(2);
}
if (key.length() > 0 &&
Character.isUpperCase(key.charAt(0)) &&
method.getParameterTypes().length == 0) {
if (key.length() == 1) {
key = key.toLowerCase();
} else if (!Character.isUpperCase(key.charAt(1))) {
key = key.substring(0, 1).toLowerCase() +
key.substring(1);
}
Object result = method.invoke(bean, (Object[])null);
if (result != null) {
this.map.put(key, wrap(result));
}
}
}
} catch (Exception ignore) {
}
}
}
public JSONObject put(String key, boolean value) throws JSONException {
this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
return this;
}
public JSONObject put(String key, Collection value) throws JSONException {
this.put(key, new JSONArray(value));
return this;
}
public JSONObject put(String key, double value) throws JSONException {
this.put(key, new Double(value));
return this;
}
public JSONObject put(String key, int value) throws JSONException {
this.put(key, new Integer(value));
return this;
}
public JSONObject put(String key, long value) throws JSONException {
this.put(key, new Long(value));
return this;
}
public JSONObject put(String key, Map value) throws JSONException {
this.put(key, new JSONObject(value));
return this;
}
public JSONObject put(String key, Object value) throws JSONException {
if (key == null) {
throw new JSONException("Null key.");
}
if (value != null) {
testValidity(value);
this.map.put(key, value);
} else {
this.remove(key);
}
return this;
}
public JSONObject putOnce(String key, Object value) throws JSONException {
if (key != null && value != null) {
if (this.opt(key) != null) {
throw new JSONException("Duplicate key \"" + key + "\"");
}
this.put(key, value);
}
return this;
}
public JSONObject putOpt(String key, Object value) throws JSONException {
if (key != null && value != null) {
this.put(key, value);
}
return this;
}
public static String quote(String string) {
StringWriter sw = new StringWriter();
synchronized (sw.getBuffer()) {
try {
return quote(string, sw).toString();
} catch (IOException ignored) {
return "";
}
}
}
public static Writer quote(String string, Writer w) throws IOException {
if (string == null || string.length() == 0) {
w.write("\"\"");
return w;
}
char b;
char c = 0;
String hhhh;
int i;
int len = string.length();
w.write('"');
for (i = 0; i < len; i += 1) {
b = c;
c = string.charAt(i);
switch (c) {
case '\\':
case '"':
w.write('\\');
w.write(c);
break;
case '/':
if (b == '<') {
w.write('\\');
}
w.write(c);
break;
case '\b':
w.write("\\b");
break;
case '\t':
w.write("\\t");
break;
case '\n':
w.write("\\n");
break;
case '\f':
w.write("\\f");
break;
case '\r':
w.write("\\r");
break;
default:
if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
|| (c >= '\u2000' && c < '\u2100')) {
hhhh = "000" + Integer.toHexString(c);
w.write("\\u" + hhhh.substring(hhhh.length() - 4));
} else {
w.write(c);
}
}
}
w.write('"');
return w;
}
public Object remove(String key) {
return this.map.remove(key);
}
public static Object stringToValue(String string) {
Double d;
if (string.equals("")) {
return string;
}
if (string.equalsIgnoreCase("true")) {
return Boolean.TRUE;
}
if (string.equalsIgnoreCase("false")) {
return Boolean.FALSE;
}
if (string.equalsIgnoreCase("null")) {
return JSONObject.NULL;
}
char b = string.charAt(0);
if ((b >= '0' && b <= '9') || b == '.' || b == '-' || b == '+') {
try {
if (string.indexOf('.') > -1 ||
string.indexOf('e') > -1 || string.indexOf('E') > -1) {
d = Double.valueOf(string);
if (!d.isInfinite() && !d.isNaN()) {
return d;
}
} else {
Long myLong = new Long(string);
if (myLong.longValue() == myLong.intValue()) {
return new Integer(myLong.intValue());
} else {
return myLong;
}
}
} catch (Exception ignore) {
}
}
return string;
}
public static void testValidity(Object o) throws JSONException {
if (o != null) {
if (o instanceof Double) {
if (((Double)o).isInfinite() || ((Double)o).isNaN()) {
throw new JSONException(
"JSON does not allow non-finite numbers.");
}
} else if (o instanceof Float) {
if (((Float)o).isInfinite() || ((Float)o).isNaN()) {
throw new JSONException(
"JSON does not allow non-finite numbers.");
}
}
}
}
public JSONArray toJSONArray(JSONArray names) throws JSONException {
if (names == null || names.length() == 0) {
return null;
}
JSONArray ja = new JSONArray();
for (int i = 0; i < names.length(); i += 1) {
ja.put(this.opt(names.getString(i)));
}
return ja;
}
public String toString() {
try {
return this.toString(0);
} catch (Exception e) {
return null;
}
}
public String toString(int indentFactor) throws JSONException {
StringWriter w = new StringWriter();
synchronized (w.getBuffer()) {
return this.write(w, indentFactor, 0).toString();
}
}
public static String valueToString(Object value) throws JSONException {
if (value == null || value.equals(null)) {
return "null";
}
if (value instanceof JSONString) {
Object object;
try {
object = ((JSONString)value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
if (object instanceof String) {
return (String)object;
}
throw new JSONException("Bad value from toJSONString: " + object);
}
if (value instanceof Number) {
return numberToString((Number) value);
}
if (value instanceof Boolean || value instanceof JSONObject ||
value instanceof JSONArray) {
return value.toString();
}
if (value instanceof Map) {
return new JSONObject((Map)value).toString();
}
if (value instanceof Collection) {
return new JSONArray((Collection)value).toString();
}
if (value.getClass().isArray()) {
return new JSONArray(value).toString();
}
return quote(value.toString());
}
public static Object wrap(Object object) {
try {
if (object == null) {
return NULL;
}
if (object instanceof JSONObject || object instanceof JSONArray ||
NULL.equals(object) || object instanceof JSONString ||
object instanceof Byte || object instanceof Character ||
object instanceof Short || object instanceof Integer ||
object instanceof Long || object instanceof Boolean ||
object instanceof Float || object instanceof Double ||
object instanceof String || object instanceof Enum) {
return object;
}
if (object instanceof Collection) {
return new JSONArray((Collection)object);
}
if (object.getClass().isArray()) {
return new JSONArray(object);
}
if (object instanceof Map) {
return new JSONObject((Map)object);
}
Package objectPackage = object.getClass().getPackage();
String objectPackageName = objectPackage != null
? objectPackage.getName()
: "";
if (
objectPackageName.startsWith("java.") ||
objectPackageName.startsWith("javax.") ||
object.getClass().getClassLoader() == null
) {
return object.toString();
}
return new JSONObject(object);
} catch(Exception exception) {
return null;
}
}
public Writer write(Writer writer) throws JSONException {
return this.write(writer, 0, 0);
}
static final Writer writeValue(Writer writer, Object value,
int indentFactor, int indent) throws JSONException, IOException {
if (value == null || value.equals(null)) {
writer.write("null");
} else if (value instanceof JSONObject) {
((JSONObject) value).write(writer, indentFactor, indent);
} else if (value instanceof JSONArray) {
((JSONArray) value).write(writer, indentFactor, indent);
} else if (value instanceof Map) {
new JSONObject((Map) value).write(writer, indentFactor, indent);
} else if (value instanceof Collection) {
new JSONArray((Collection) value).write(writer, indentFactor,
indent);
} else if (value.getClass().isArray()) {
new JSONArray(value).write(writer, indentFactor, indent);
} else if (value instanceof Number) {
writer.write(numberToString((Number) value));
} else if (value instanceof Boolean) {
writer.write(value.toString());
} else if (value instanceof JSONString) {
Object o;
try {
o = ((JSONString) value).toJSONString();
} catch (Exception e) {
throw new JSONException(e);
}
writer.write(o != null ? o.toString() : quote(value.toString()));
} else {
quote(value.toString(), writer);
}
return writer;
}
static final void indent(Writer writer, int indent) throws IOException {
for (int i = 0; i < indent; i += 1) {
writer.write(' ');
}
}
Writer write(Writer writer, int indentFactor, int indent)
throws JSONException {
try {
boolean commanate = false;
final int length = this.length();
Iterator keys = this.keys();
writer.write('{');
if (length == 1) {
Object key = keys.next();
writer.write(quote(key.toString()));
writer.write(':');
if (indentFactor > 0) {
writer.write(' ');
}
writeValue(writer, this.map.get(key), indentFactor, indent);
} else if (length != 0) {
final int newindent = indent + indentFactor;
while (keys.hasNext()) {
Object key = keys.next();
if (commanate) {
writer.write(',');
}
if (indentFactor > 0) {
writer.write('\n');
}
indent(writer, newindent);
writer.write(quote(key.toString()));
writer.write(':');
if (indentFactor > 0) {
writer.write(' ');
}
writeValue(writer, this.map.get(key), indentFactor,
newindent);
commanate = true;
}
if (indentFactor > 0) {
writer.write('\n');
}
indent(writer, indent);
}
writer.write('}');
return writer;
} catch (IOException exception) {
throw new JSONException(exception);
}
}
}

Some files were not shown because too many files have changed in this diff Show More