版本更新至 4.06

新增:TLocale 新增 BOOK 类型,用于发送书本界面(代替 Language2)
新增:TLocale 新增 BAR 类型,用于发送 Bossbar(需要 BossBarAPI)
新增:TLocale#Tellraw 工具用于发送原始 json 信息
新增:TellrawJson 工具用于创建原始 json 信息
新增:VariableFormatter 工具用于变量识别
新增:ArrayUtils 新增数组修改方法
修复:Language2Book 工具失效问题
调整:JsonFormatter 工具已过时,不再维护

从该版本起不再对 1.7.10 版本进行支持与维护,任何在 1.7.10 版本内出现的问题不再修复。
1.7.10 稳定版:v3.832
This commit is contained in:
坏黑 2018-05-27 21:15:29 +08:00
parent 8a20fb7edb
commit 5843e0be04
27 changed files with 1095 additions and 464 deletions

View File

@ -6,7 +6,7 @@
<groupId>me.skymc</groupId> <groupId>me.skymc</groupId>
<artifactId>TabooLib</artifactId> <artifactId>TabooLib</artifactId>
<version>4.05</version> <version>4.06</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -176,6 +176,13 @@
<scope>system</scope> <scope>system</scope>
<systemPath>${basedir}/libs/Vault.jar</systemPath> <systemPath>${basedir}/libs/Vault.jar</systemPath>
</dependency> </dependency>
<dependency>
<groupId>bossbar</groupId>
<artifactId>bossbar</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${basedir}/libs/BossBarAPI.jar</systemPath>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -6,6 +6,7 @@ import com.ilummc.tlib.bungee.api.chat.TextComponent;
import com.ilummc.tlib.bungee.api.chat.TranslatableComponent; import com.ilummc.tlib.bungee.api.chat.TranslatableComponent;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
/** /**

View File

@ -2,20 +2,30 @@ package com.ilummc.tlib.resources;
import com.ilummc.tlib.TLib; import com.ilummc.tlib.TLib;
import com.ilummc.tlib.bungee.api.ChatColor; import com.ilummc.tlib.bungee.api.ChatColor;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import com.ilummc.tlib.bungee.api.chat.TextComponent;
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.inject.TLoggerManager; import com.ilummc.tlib.inject.TLoggerManager;
import com.ilummc.tlib.util.Ref; import com.ilummc.tlib.util.Ref;
import com.ilummc.tlib.util.Strings; import com.ilummc.tlib.util.Strings;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import me.skymc.taboolib.Main; import me.skymc.taboolib.Main;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.nms.NMSUtil19;
import me.skymc.taboolib.nms.NMSUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* @author IzzelAliz
*/
public class TLocale { public class TLocale {
private TLocale() { private TLocale() {
@ -128,4 +138,22 @@ public class TLocale {
} }
} }
public static class Tellraw extends TLocale {
private static final Field playerConnection = NMSUtils.getFieldSilent(NMSUtil19.class_EntityPlayer, "playerConnection");
private static final Method sendPacket = NMSUtils.getMethodSilent(NMSUtil19.class_PlayerConnection, "sendPacket", NMSUtil19.class_Packet);
private static final Constructor<?> PacketPlayOutChat = NMSUtils.getConstructorSilent(NMSUtil19.class_PacketPlayOutChat, NMSUtil19.class_IChatBaseComponent);
public static void send(CommandSender sender, String rawMessage) {
if (sender instanceof Player) {
try {
sendPacket.invoke(playerConnection.get(NMSUtils.getHandle(sender)), PacketPlayOutChat.newInstance(rawMessage));
} catch (Exception e) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + rawMessage);
}
} else {
sender.sendMessage(TextComponent.toLegacyText(ComponentSerializer.parse(rawMessage)));
}
}
}
} }

View File

@ -30,8 +30,10 @@ public class TLocaleLoader {
public static void init() { public static void init() {
ConfigurationSerialization.registerClass(TLocaleText.class, "TEXT"); ConfigurationSerialization.registerClass(TLocaleText.class, "TEXT");
ConfigurationSerialization.registerClass(TLocaleJson.class, "JSON"); ConfigurationSerialization.registerClass(TLocaleJson.class, "JSON");
ConfigurationSerialization.registerClass(TLocaleBook.class, "BOOK");
ConfigurationSerialization.registerClass(TLocaleSound.class, "SOUND"); ConfigurationSerialization.registerClass(TLocaleSound.class, "SOUND");
ConfigurationSerialization.registerClass(TLocaleTitle.class, "TITLE"); ConfigurationSerialization.registerClass(TLocaleTitle.class, "TITLE");
ConfigurationSerialization.registerClass(TLocaleBossBar.class, "BAR");
ConfigurationSerialization.registerClass(TLocaleActionBar.class, "ACTION"); ConfigurationSerialization.registerClass(TLocaleActionBar.class, "ACTION");
} }

View File

@ -0,0 +1,91 @@
package com.ilummc.tlib.resources.type;
import com.google.common.collect.Maps;
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.resources.TLocaleSerialize;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.Main;
import me.skymc.taboolib.bookformatter.BookFormatter;
import me.skymc.taboolib.bookformatter.builder.BookBuilder;
import me.skymc.taboolib.json.tellraw.TellrawJson;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import javax.annotation.concurrent.ThreadSafe;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author sky
* @Since 2018-05-27 0:05
*/
@ThreadSafe
@SerializableAs("BOOK")
public class TLocaleBook extends TLocaleSerialize {
/*
BookTest:
- ==: BOOK
pages:
0:
- '第一页内容'
- '[ <变量1@page-1> ]'
1:
- '第二页内容'
- '[ <变量2@page-2> ]'
args:
page-1:
hover: '展示内容1'
command: '/say %player_name% NB1'
page-2:
hover: '展示内容2'
suggest: '/say %player_name% NB2'
*/
private final List<TellrawJson> pages;
private final Map<String, Object> map;
private final boolean papi;
public TLocaleBook(List<TellrawJson> pages, Map<String, Object> map, boolean papi) {
this.pages = pages;
this.map = map;
this.papi = papi;
}
@Override
public Map<String, Object> serialize() {
return Maps.newHashMap(map);
}
@Override
public void sendTo(CommandSender sender, String... args) {
if (!(sender instanceof Player)) {
return;
}
new BukkitRunnable() {
@Override
public void run() {
BookBuilder bookBuilder = BookFormatter.writtenBook();
pages.stream().map(jsonPage -> papi ? TLocale.Translate.setPlaceholders(sender, Strings.replaceWithOrder(jsonPage.toRawMessage(), args)) : TLocale.Translate.setColored(Strings.replaceWithOrder(jsonPage.toRawMessage(), args))).map(ComponentSerializer::parse).forEach(bookBuilder::addPages);
new BukkitRunnable() {
@Override
public void run() {
BookFormatter.forceOpen((Player) sender, bookBuilder.build());
}
}.runTask(Main.getInst());
}
}.runTaskAsynchronously(Main.getInst());
}
public static TLocaleBook valueOf(Map<String, Object> map) {
Map<String, Object> pages = map.containsKey("pages") ? (Map<String, Object>) map.get("pages") : new HashMap<>();
Map<String, Object> section = map.containsKey("args") ? (Map<String, Object>) map.get("args") : new HashMap<>();
List<TellrawJson> pageJsonList = pages.values().stream().map(page -> TLocaleJson.formatJson(section, page, TellrawJson.create())).collect(Collectors.toList());
return new TLocaleBook(pageJsonList, map, isPlaceholderEnabled(map));
}
}

View File

@ -0,0 +1,95 @@
package com.ilummc.tlib.resources.type;
import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.resources.TLocaleSerialize;
import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.other.NumberUtils;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player;
import org.inventivetalent.bossbar.BossBar;
import org.inventivetalent.bossbar.BossBarAPI;
import javax.annotation.concurrent.ThreadSafe;
import java.util.Map;
/**
* @Author sky
* @Since 2018-05-27 18:52
*/
@ThreadSafe
@SerializableAs("BAR")
public class TLocaleBossBar extends TLocaleSerialize {
/*
BossBar:
- ==: BAR
text: 'BossBar 血条公告'
color: BLUE
style: NOTCHED_20
progress: 1.0
timeout: 20
timeout-interval: 2
*/
private final String text;
private final BossBarAPI.Color color;
private final BossBarAPI.Style style;
private final float progress;
private final int timeout;
private final int timeoutInterval;
private final boolean papi;
public TLocaleBossBar(String text, BossBarAPI.Color color, BossBarAPI.Style style, float progress, int timeout, int timeoutInterval, boolean papi) {
this.text = text;
this.color = color;
this.style = style;
this.progress = progress;
this.timeout = timeout;
this.timeoutInterval = timeoutInterval;
this.papi = papi;
}
@Override
public void sendTo(CommandSender sender, String... args) {
if (Bukkit.getPluginManager().getPlugin("BossBarAPI") == null) {
TLocale.Logger.error("LOCALE.BAR-PLUGIN-NOT-FOUND");
return;
}
if (sender instanceof Player) {
TextComponent textComponent = new TextComponent(papi ? TLocale.Translate.setPlaceholders(sender, Strings.replaceWithOrder(text, args)) : TLocale.Translate.setColored(Strings.replaceWithOrder(text, args)));
BossBar bossBar = BossBarAPI.addBar((Player) sender, textComponent, color, style, progress, timeout, timeoutInterval);
} else {
sender.sendMessage(text);
}
}
@Override
public Map<String, Object> serialize() {
return null;
}
public static TLocaleBossBar valueOf(Map<String, Object> map) {
return new TLocaleBossBar(map.getOrDefault("text", "§4* Invalid Text*").toString(), getColor(String.valueOf(map.get("color"))), getStyle(String.valueOf(map.get("style"))), (float) NumberUtils.getDouble(String.valueOf(map.getOrDefault("progress", 1))), NumberUtils.getInteger(String.valueOf(map.getOrDefault("timeout", 20))), NumberUtils.getInteger(String.valueOf(map.getOrDefault("timeout-interval", 2))), isPlaceholderEnabled(map));
}
private static BossBarAPI.Color getColor(String color) {
try {
return BossBarAPI.Color.valueOf(color);
} catch (Exception e) {
TLocale.Logger.error("LOCALE.BAR-STYLE-IDENTIFICATION-FAILED", e.toString());
return BossBarAPI.Color.WHITE;
}
}
private static BossBarAPI.Style getStyle(String style) {
try {
return BossBarAPI.Style.valueOf(style);
} catch (Exception e) {
TLocale.Logger.error("LOCALE.BAR-COLOR-IDENTIFICATION-FAILED", e.toString());
return BossBarAPI.Style.NOTCHED_20;
}
}
}

View File

@ -10,10 +10,12 @@ import com.ilummc.tlib.compat.PlaceholderHook;
import com.ilummc.tlib.resources.TLocale; import com.ilummc.tlib.resources.TLocale;
import com.ilummc.tlib.resources.TLocaleSerialize; import com.ilummc.tlib.resources.TLocaleSerialize;
import com.ilummc.tlib.util.Strings; import com.ilummc.tlib.util.Strings;
import me.skymc.taboolib.jsonformatter.JSONFormatter; import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.json.tellraw.TellrawJson;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.VariableFormatter;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.SerializableAs; import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player;
import javax.annotation.concurrent.ThreadSafe; import javax.annotation.concurrent.ThreadSafe;
import java.util.*; import java.util.*;
@ -21,6 +23,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ThreadSafe @ThreadSafe
@SerializableAs("JSON") @SerializableAs("JSON")
public class TLocaleJson extends TLocaleSerialize { public class TLocaleJson extends TLocaleSerialize {
@ -72,11 +75,11 @@ public class TLocaleJson extends TLocaleSerialize {
// 可能有很多个 BaseComponent于是为每个 component 单独设置各种事件 // 可能有很多个 BaseComponent于是为每个 component 单独设置各种事件
BaseComponent[] component = TextComponent.fromLegacyText(text); BaseComponent[] component = TextComponent.fromLegacyText(text);
arg.forEach((key, value) -> { arg.forEach((key, value) -> {
if ("suggest".equalsIgnoreCase(key)) { if (key.equalsIgnoreCase("suggest")) {
Arrays.stream(component).forEach(baseComponent -> baseComponent.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.valueOf(value)))); Arrays.stream(component).forEach(baseComponent -> baseComponent.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, String.valueOf(value))));
} else if ("command".equalsIgnoreCase(key) || "commands".equalsIgnoreCase(key)) { } else if (key.equalsIgnoreCase("command") || "commands".equalsIgnoreCase(key)) {
Arrays.stream(component).forEach(baseComponent -> baseComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.valueOf(value)))); Arrays.stream(component).forEach(baseComponent -> baseComponent.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, String.valueOf(value))));
} else if ("hover".equalsIgnoreCase(key)) { } else if (key.equalsIgnoreCase("hover")) {
Arrays.stream(component).forEach(baseComponent -> baseComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(TLocale.Translate.setColored(String.valueOf(value))).create()))); Arrays.stream(component).forEach(baseComponent -> baseComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(TLocale.Translate.setColored(String.valueOf(value))).create())));
} }
}); });
@ -101,7 +104,7 @@ public class TLocaleJson extends TLocaleSerialize {
private static List<String> getTextList(Object textObj) { private static List<String> getTextList(Object textObj) {
if (textObj instanceof List) { if (textObj instanceof List) {
return ((List<?>) textObj).stream().map(Object::toString).map(s -> TLocale.Translate.setColored(s)).collect(Collectors.toList()); return ((List<?>) textObj).stream().map(Object::toString).map(TLocale.Translate::setColored).collect(Collectors.toList());
} else if (textObj instanceof String) { } else if (textObj instanceof String) {
return Lists.newArrayList(TLocale.Translate.setColored((String) textObj)); return Lists.newArrayList(TLocale.Translate.setColored((String) textObj));
} else { } else {
@ -125,11 +128,11 @@ public class TLocaleJson extends TLocaleSerialize {
} }
private void sendRawMessage(CommandSender sender, BaseComponent[] components) { private void sendRawMessage(CommandSender sender, BaseComponent[] components) {
if (sender instanceof Player) { TLocale.Tellraw.send(sender, ComponentSerializer.toString(components));
JSONFormatter.sendRawMessage((Player) sender, ComponentSerializer.toString(components));
} else {
sender.sendMessage(TextComponent.toLegacyText(components));
} }
private List<BaseComponent> replace(List<BaseComponent> component, CommandSender sender, String... args) {
return component.stream().map(c -> replace(c, sender, args)).collect(Collectors.toList());
} }
private BaseComponent[] replace(BaseComponent[] component, CommandSender sender, String... args) { private BaseComponent[] replace(BaseComponent[] component, CommandSender sender, String... args) {
@ -140,10 +143,6 @@ public class TLocaleJson extends TLocaleSerialize {
return components; return components;
} }
private List<BaseComponent> replace(List<BaseComponent> component, CommandSender sender, String... args) {
return component.stream().map(c -> replace(c, sender, args)).collect(Collectors.toList());
}
private BaseComponent replace(BaseComponent component, CommandSender sender, String... args) { private BaseComponent replace(BaseComponent component, CommandSender sender, String... args) {
if (component.getClickEvent() != null) { if (component.getClickEvent() != null) {
ClickEvent clickEvent = new ClickEvent(component.getClickEvent().getAction(), replace(sender, component.getClickEvent().getValue(), args)); ClickEvent clickEvent = new ClickEvent(component.getClickEvent().getAction(), replace(sender, component.getClickEvent().getValue(), args));
@ -166,4 +165,63 @@ public class TLocaleJson extends TLocaleSerialize {
String s = Strings.replaceWithOrder(text, args); String s = Strings.replaceWithOrder(text, args);
return papi ? PlaceholderHook.replace(sender, s) : s; return papi ? PlaceholderHook.replace(sender, s) : s;
} }
public static TellrawJson formatJson(Map<String, Object> section, Object textObject, TellrawJson pageJson) {
List<String> textList = textObject instanceof List ? (List<String>) textObject : Collections.singletonList(String.valueOf(textObject));
// 遍历本页文本
for (int i = 0; i < textList.size(); i++) {
// 捕捉变量
for (VariableFormatter.Variable variable : new VariableFormatter(textList.get(i), pattern).find().getVariableList()) {
// 如果是变量
if (variable.isVariable()) {
String[] split = variable.getText().split("@");
// @ 前面的字符串
String text = split.length > 1 ? split[0] : "§4* Invalid Text *";
// @ 后面的节点名
String node = split.length > 1 ? split[1] : null;
// 处理变量
formatNode(section, pageJson, text, node);
} else {
pageJson.append(variable.getText());
}
}
if (i + 1 < textList.size()) {
pageJson.newLine();
}
}
return pageJson;
}
private static void formatNode(Map<String, Object> section, TellrawJson pageJson, String text, String node) {
if (section.containsKey(node)) {
try {
Map<String, Object> args = (Map<String, Object>) section.get(node);
// 文本
pageJson.append(args.getOrDefault("text", text).toString());
// 功能
if (args.containsKey("item")) {
pageJson.hoverItem(ItemUtils.getCacheItem(args.get("item").toString()));
}
if (args.containsKey("hover")) {
pageJson.hoverText(args.get("hover").toString());
}
if (args.containsKey("suggest")) {
pageJson.clickSuggest(args.get("suggest").toString());
}
if (args.containsKey("command")) {
pageJson.clickCommand(args.get("command").toString());
}
if (args.containsKey("page")) {
pageJson.clickChangePage(NumberUtils.getInteger(args.get("page").toString()));
}
if (args.containsKey("url")) {
pageJson.clickOpenURL(args.get("url").toString());
}
} catch (Exception e) {
TLocale.Logger.error("LOCALE.BOOK-ARGUMENTS-IDENTIFICATION-FAILED", e.toString());
}
} else {
pageJson.append("§4* Invalid Argument *");
}
}
} }

View File

@ -2,6 +2,14 @@ package com.ilummc.tlib.util;
public class Strings { public class Strings {
public static boolean isBlank(String var) {
return var == null || var.trim().isEmpty();
}
public static boolean isEmpty(CharSequence var) {
return var == null || var.length() == 0;
}
/** /**
* 优化过的 String#replace比默认快了大概 5 * 优化过的 String#replace比默认快了大概 5
* *
@ -28,15 +36,13 @@ public class Strings {
return stringBuilder.toString(); return stringBuilder.toString();
} }
// *********************************
//
// Deprecated
//
// *********************************
public static String replaceWithOrder(String template, String... args) { public static String replaceWithOrder(String template, String... args) {
return replaceWithOrder(template, (Object[]) args); return replaceWithOrder(template, (Object[]) args);
} }
public static boolean isBlank(String var) {
return var == null || var.trim().isEmpty();
}
public static boolean isEmpty(CharSequence var) {
return var == null || var.length() == 0;
}
} }

View File

@ -1,8 +1,10 @@
package me.skymc.taboolib.bookformatter; package me.skymc.taboolib.bookformatter;
import net.md_5.bungee.api.chat.BaseComponent; import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent; import com.ilummc.tlib.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer; import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.logger.TLogger;
import com.ilummc.tlib.resources.TLocale;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -12,6 +14,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -31,11 +34,13 @@ public final class BookReflection {
private static final Method craftPlayerGetHandle; 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 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; private static final Method entityPlayerOpenBook;
//only version >= 1.9 // only version >= 1.9
private static final Object[] hands; private static final Object[] hands;
//Older versions //Older versions
@ -115,18 +120,22 @@ public final class BookReflection {
* @param meta the book meta to change * @param meta the book meta to change
* @param components the pages of the book * @param components the pages of the book
*/ */
@SuppressWarnings("unchecked")//reflections = unchecked warnings public static void setPages(BookMeta meta, BaseComponent[]... components) {
public static void setPages(BookMeta meta, BaseComponent[][] components) { List<Object> pages = null;
try { try {
List<Object> pages = (List<Object>) craftMetaBookField.get(meta); pages = (List<Object>) craftMetaBookField.get(meta);
} catch (Exception e) {
TLogger.getGlobalLogger().error("Error while executing reflections, failed to get bookmeta (version: " + BookReflection.version + ")");
return;
}
pages.clear(); pages.clear();
for (BaseComponent[] c : components) { for (BaseComponent[] c : components) {
final String json = ComponentSerializer.toString(c); try {
//System.out.println("page:" + json); //Debug pages.add(chatSerializerA.invoke(null, ComponentSerializer.toString(c)));
pages.add(chatSerializerA.invoke(null, json));
}
} catch (Exception e) { } catch (Exception e) {
throw new UnsupportedVersionException(e); TLogger.getGlobalLogger().error("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")");
e.printStackTrace();
}
} }
} }
@ -136,17 +145,21 @@ public final class BookReflection {
* @param meta the book meta to change * @param meta the book meta to change
* @param components the pages of the book * @param components the pages of the book
*/ */
@SuppressWarnings("unchecked")//reflections = unchecked warnings public static void addPages(BookMeta meta, BaseComponent[]... components) {
public static void addPages(BookMeta meta, BaseComponent[][] components) { List<Object> pages = null;
try { try {
List<Object> pages = (List<Object>) craftMetaBookField.get(meta); 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) { } catch (Exception e) {
throw new UnsupportedVersionException(e); TLogger.getGlobalLogger().error("Error while executing reflections, failed to get bookmeta (version: " + BookReflection.version + ")");
return;
}
for (BaseComponent[] c : components) {
try {
pages.add(chatSerializerA.invoke(null, ComponentSerializer.toString(c)));
} catch (Exception e) {
TLogger.getGlobalLogger().error("Error while executing reflections, submit to developers the following log (version: " + BookReflection.version + ")");
e.printStackTrace();
}
} }
} }

View File

@ -1,6 +1,6 @@
package me.skymc.taboolib.bookformatter.action; package me.skymc.taboolib.bookformatter.action;
import net.md_5.bungee.api.chat.ClickEvent; import com.ilummc.tlib.bungee.api.chat.ClickEvent;
/** /**
* @author sky * @author sky
@ -86,12 +86,12 @@ public interface ClickAction {
@Override @Override
public ClickEvent.Action action() { public ClickEvent.Action action() {
return null; return action;
} }
@Override @Override
public String value() { public String value() {
return null; return value;
} }
} }
} }

View File

@ -1,10 +1,10 @@
package me.skymc.taboolib.bookformatter.action; package me.skymc.taboolib.bookformatter.action;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import com.ilummc.tlib.bungee.api.chat.HoverEvent;
import com.ilummc.tlib.bungee.api.chat.TextComponent;
import me.skymc.taboolib.bookformatter.BookAchievement; import me.skymc.taboolib.bookformatter.BookAchievement;
import me.skymc.taboolib.bookformatter.BookReflection; 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;
import org.bukkit.Achievement; import org.bukkit.Achievement;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -157,12 +157,12 @@ public interface HoverAction {
@Override @Override
public HoverEvent.Action action() { public HoverEvent.Action action() {
return null; return action;
} }
@Override @Override
public BaseComponent[] value() { public BaseComponent[] value() {
return new BaseComponent[0]; return value;
} }
} }
} }

View File

@ -1,7 +1,7 @@
package me.skymc.taboolib.bookformatter.builder; package me.skymc.taboolib.bookformatter.builder;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import me.skymc.taboolib.bookformatter.BookReflection; import me.skymc.taboolib.bookformatter.BookReflection;
import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta; import org.bukkit.inventory.meta.BookMeta;
@ -125,4 +125,19 @@ public class BookBuilder {
book.setItemMeta(meta); book.setItemMeta(meta);
return book; return book;
} }
// *********************************
//
// Getter and Setter
//
// *********************************
public BookMeta getMeta() {
return meta;
}
public ItemStack getBook() {
return book;
}
} }

View File

@ -1,7 +1,7 @@
package me.skymc.taboolib.bookformatter.builder; package me.skymc.taboolib.bookformatter.builder;
import net.md_5.bungee.api.chat.BaseComponent; import com.ilummc.tlib.bungee.api.chat.*;
import net.md_5.bungee.api.chat.TextComponent; import me.skymc.taboolib.string.ArrayUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -14,7 +14,7 @@ import java.util.List;
*/ */
public class PageBuilder { public class PageBuilder {
private List<BaseComponent> text = new ArrayList<>(); private BaseComponent[] text = TextComponent.fromLegacyText("");
/** /**
* Adds a simple black-colored text to the page * Adds a simple black-colored text to the page
@ -22,7 +22,7 @@ public class PageBuilder {
* @return the PageBuilder's calling instance * @return the PageBuilder's calling instance
*/ */
public PageBuilder add(String text) { public PageBuilder add(String text) {
this.text.add(TextBuilder.of(text).build()); Arrays.stream(TextComponent.fromLegacyText(text)).forEach(component -> this.text = ArrayUtils.arrayAppend(this.text, component));
return this; return this;
} }
@ -32,7 +32,7 @@ public class PageBuilder {
* @return the PageBuilder's calling instance * @return the PageBuilder's calling instance
*/ */
public PageBuilder add(BaseComponent component) { public PageBuilder add(BaseComponent component) {
this.text.add(component); this.text = ArrayUtils.arrayAppend(this.text, component);
return this; return this;
} }
@ -42,17 +42,7 @@ public class PageBuilder {
* @return the PageBuilder's calling instance * @return the PageBuilder's calling instance
*/ */
public PageBuilder add(BaseComponent... components) { public PageBuilder add(BaseComponent... components) {
this.text.addAll(Arrays.asList(components)); Arrays.stream(components).forEach(component -> this.text = ArrayUtils.arrayAppend(this.text, 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(Collection<BaseComponent> components) {
this.text.addAll(components);
return this; return this;
} }
@ -61,8 +51,7 @@ public class PageBuilder {
* @return the PageBuilder's calling instance * @return the PageBuilder's calling instance
*/ */
public PageBuilder newLine() { public PageBuilder newLine() {
this.text.add(new TextComponent("\n")); return add("\n");
return this;
} }
/** /**
@ -78,10 +67,9 @@ public class PageBuilder {
* @return an array of BaseComponents representing the page * @return an array of BaseComponents representing the page
*/ */
public BaseComponent[] build() { public BaseComponent[] build() {
return text.toArray(new BaseComponent[0]); return text;
} }
/** /**
* Creates a new PageBuilder instance wih the parameter as the initial text * Creates a new PageBuilder instance wih the parameter as the initial text
* @param text the initial text of the page * @param text the initial text of the page

View File

@ -1,11 +1,8 @@
package me.skymc.taboolib.bookformatter.builder; package me.skymc.taboolib.bookformatter.builder;
import com.ilummc.tlib.bungee.api.chat.*;
import me.skymc.taboolib.bookformatter.action.ClickAction; import me.skymc.taboolib.bookformatter.action.ClickAction;
import me.skymc.taboolib.bookformatter.action.HoverAction; 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 * @author sky

View File

@ -0,0 +1,133 @@
package me.skymc.taboolib.json.tellraw;
import com.ilummc.tlib.bungee.api.chat.*;
import com.ilummc.tlib.bungee.chat.ComponentSerializer;
import com.ilummc.tlib.logger.TLogger;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.methods.ReflectionUtils;
import me.skymc.taboolib.nms.NMSUtils;
import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.ArrayUtils;
import me.skymc.taboolib.string.VariableFormatter;
import org.bukkit.command.CommandSender;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* @Author sky
* @Since 2018-05-26 14:42json
*/
public class TellrawJson {
private BaseComponent[] components = TextComponent.fromLegacyText("");
private final Class<?> craftItemStackClazz = NMSUtils.getOBCClass("inventory.CraftItemStack");
private final Class<?> nmsItemStackClazz = NMSUtils.getNMSClass("ItemStack");
private final Class<?> nbtTagCompoundClazz = NMSUtils.getNMSClass("NBTTagCompound");
private final String INVALID_ITEM = "{id:stone,tag:{display:{Name:§c* Invalid ItemStack *}}}";
TellrawJson() {
}
public static TellrawJson create() {
return new TellrawJson();
}
public String toRawMessage() {
return ComponentSerializer.toString(components);
}
public String toLegacyText() {
return TextComponent.toLegacyText(components);
}
public TellrawJson newLine() {
return append("\n");
}
public TellrawJson append(String text) {
Arrays.stream(TextComponent.fromLegacyText(text)).forEach(component -> this.components = ArrayUtils.arrayAppend(this.components, component));
return this;
}
public TellrawJson hoverText(String text) {
getLatestComponent().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(text).create()));
return this;
}
public TellrawJson hoverItem(ItemStack itemStack) {
getLatestComponent().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_ITEM, new ComponentBuilder(getItemComponent(itemStack)).create()));
return this;
}
public TellrawJson clickCommand(String command) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
return this;
}
public TellrawJson clickSuggest(String command) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command));
return this;
}
public TellrawJson clickOpenURL(String url) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
return this;
}
public TellrawJson clickChangePage(int page) {
getLatestComponent().setClickEvent(new ClickEvent(ClickEvent.Action.CHANGE_PAGE, String.valueOf(page)));
return this;
}
public void send(CommandSender sender) {
TLocale.Tellraw.send(sender, toRawMessage());
}
public String getItemComponent(ItemStack itemStack) {
try {
Method asNMSCopyMethod = ReflectionUtils.getMethod(craftItemStackClazz, "asNMSCopy", ItemStack.class);
Method saveNmsItemStackMethod = ReflectionUtils.getMethod(nmsItemStackClazz, "save", nbtTagCompoundClazz);
Object nmsNbtTagCompoundObj = nbtTagCompoundClazz.newInstance();
Object nmsItemStackObj = asNMSCopyMethod.invoke(null, itemStack);
return saveNmsItemStackMethod.invoke(nmsItemStackObj, nmsNbtTagCompoundObj).toString();
} catch (Throwable t) {
TLogger.getGlobalLogger().error("failed to serialize itemstack to nms item: " + t.toString());
return INVALID_ITEM;
}
}
// *********************************
//
// Private Methods
//
// *********************************
private BaseComponent getLatestComponent() {
return components[components.length - 1];
}
private void setLatestComponent(BaseComponent component) {
components[components.length - 1] = component;
}
// *********************************
//
// Getter and Setter
//
// *********************************
public BaseComponent[] getComponents() {
return components;
}
public void setComponents(BaseComponent[] components) {
this.components = components;
}
}

View File

@ -1,5 +1,6 @@
package me.skymc.taboolib.jsonformatter; package me.skymc.taboolib.jsonformatter;
import com.ilummc.tlib.resources.TLocale;
import me.skymc.taboolib.json.JSONArray; import me.skymc.taboolib.json.JSONArray;
import me.skymc.taboolib.json.JSONObject; import me.skymc.taboolib.json.JSONObject;
import me.skymc.taboolib.jsonformatter.click.ClickEvent; import me.skymc.taboolib.jsonformatter.click.ClickEvent;
@ -15,17 +16,14 @@ import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* @author Unknown
*/
@Deprecated
public class JSONFormatter { public class JSONFormatter {
public static void sendRawMessage(Player player, String message) { public static void sendRawMessage(Player player, String message) {
try { TLocale.Tellraw.send(player, message);
Object entityplayer = NMSUtils.getHandle(player);
Object ppco = ppc.get(entityplayer);
Object packet = ppocc.newInstance(message);
sp.invoke(ppco, packet);
} catch (Exception e) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + player.getName() + " " + message);
}
} }
private JSONArray ja = new JSONArray(); private JSONArray ja = new JSONArray();

View File

@ -3,6 +3,7 @@ package me.skymc.taboolib.jsonformatter.hover;
import me.skymc.taboolib.TabooLib; import me.skymc.taboolib.TabooLib;
import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.json.JSONObject; import me.skymc.taboolib.json.JSONObject;
import me.skymc.taboolib.json.tellraw.TellrawJson;
import me.skymc.taboolib.nms.item.DabItemUtils; import me.skymc.taboolib.nms.item.DabItemUtils;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -13,7 +14,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
public class ShowItemEvent extends HoverEvent{ public class ShowItemEvent extends HoverEvent {
private JSONObject object = new JSONObject(); private JSONObject object = new JSONObject();
@ -26,22 +27,28 @@ public class ShowItemEvent extends HoverEvent{
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public ShowItemEvent(ItemStack is){ public ShowItemEvent(ItemStack is) {
try{ if (TabooLib.getVerint() > 10700) {
try {
object.put("action", "show_item");
object.put("value", TellrawJson.create().getItemComponent(is));
} catch (Exception ignored) {
}
}
try {
object.put("action", "show_item"); object.put("action", "show_item");
StringBuilder tag = new StringBuilder(); StringBuilder tag = new StringBuilder();
Object itemTag = getItemTag(is); Object itemTag = getItemTag(is);
if (itemTag != null) { if (itemTag != null) {
tag.append(",tag:").append(itemTag); tag.append(",tag:").append(itemTag);
} } else {
else {
ItemMeta im = is.getItemMeta(); ItemMeta im = is.getItemMeta();
List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<>(); List<String> lore = im.hasLore() ? im.getLore() : new ArrayList<>();
Map<Enchantment, Integer> enchants = is.getItemMeta().getEnchants(); Map<Enchantment, Integer> enchants = is.getItemMeta().getEnchants();
tag.append(",tag:{display:{Name:").append(enchants.size() > 0 ? "§b§o" : "§f").append(ItemUtils.getCustomName(is)); tag.append(",tag:{display:{Name:").append(enchants.size() > 0 ? "§b§o" : "§f").append(ItemUtils.getCustomName(is));
if (lore.size() > 0) { if (lore.size() > 0) {
tag.append(",Lore:["); tag.append(",Lore:[");
for (String s : lore){ for (String s : lore) {
tag.append("\"").append(s).append("\","); tag.append("\"").append(s).append("\",");
} }
tag.delete(tag.length() - 1, tag.length()); tag.delete(tag.length() - 1, tag.length());
@ -49,7 +56,7 @@ public class ShowItemEvent extends HoverEvent{
} }
tag.append("}"); tag.append("}");
if (enchants.size() > 0) { if (enchants.size() > 0) {
if(tag.length() > 6) { if (tag.length() > 6) {
tag.append(","); tag.append(",");
} }
tag.append("ench:["); tag.append("ench:[");
@ -61,15 +68,13 @@ public class ShowItemEvent extends HoverEvent{
} }
tag.append("}"); tag.append("}");
} }
object.put("value", "{id:" + (TabooLib.getVerint() > 10700 ? DabItemUtils.getMinecraftName(is) : is.getTypeId()) + ",Count:" + is.getAmount() + tag.toString() + "}"); object.put("value", "{id:" + (TabooLib.getVerint() > 10700 ? DabItemUtils.getMinecraftName(is) : is.getTypeId()) + ",Count:" + is.getAmount() + tag.toString() + "}");
} catch(Exception e) { } catch (Exception ignored) {
e.printStackTrace();
} }
} }
@Override @Override
public JSONObject getEvent(){ public JSONObject getEvent() {
return object; return object;
} }

View File

@ -20,8 +20,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
/**
* @author Unknown
*/
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@Deprecated
public class NMSUtil18 { public class NMSUtil18 {
protected static boolean failed = false; protected static boolean failed = false;

View File

@ -22,8 +22,10 @@ import java.lang.reflect.Method;
import java.util.*; import java.util.*;
import java.util.logging.Level; import java.util.logging.Level;
@SuppressWarnings({ "rawtypes", "unchecked" }) /**
@Deprecated * @author Unknown
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public class NMSUtil19 { public class NMSUtil19 {
protected static boolean failed = false; protected static boolean failed = false;
@ -32,7 +34,7 @@ public class NMSUtil19 {
protected static String versionPrefix = ""; protected static String versionPrefix = "";
protected final static int NBT_TYPE_COMPOUND = 10; protected final static int NBT_TYPE_COMPOUND = 10;
protected final static int NBT_TYPE_INT_ARRAY= 11; protected final static int NBT_TYPE_INT_ARRAY = 11;
protected final static int NBT_TYPE_DOUBLE = 6; protected final static int NBT_TYPE_DOUBLE = 6;
protected final static int NBT_TYPE_FLOAT = 5; protected final static int NBT_TYPE_FLOAT = 5;
protected final static int NBT_TYPE_STRING = 8; protected final static int NBT_TYPE_STRING = 8;
@ -40,91 +42,91 @@ public class NMSUtil19 {
protected static int WITHER_SKULL_TYPE = 66; protected static int WITHER_SKULL_TYPE = 66;
protected static int FIREWORK_TYPE = 76; protected static int FIREWORK_TYPE = 76;
protected static Class<?> class_Block; public static Class<?> class_Block;
protected static Class<?> class_ItemStack; public static Class<?> class_ItemStack;
protected static Class<?> class_NBTBase; public static Class<?> class_NBTBase;
protected static Class<?> class_NBTTagCompound; public static Class<?> class_NBTTagCompound;
protected static Class<?> class_NBTTagList; public static Class<?> class_NBTTagList;
protected static Class<?> class_NBTTagByte; public static Class<?> class_NBTTagByte;
protected static Class<?> class_NBTTagDouble; public static Class<?> class_NBTTagDouble;
protected static Class<?> class_NBTTagFloat; public static Class<?> class_NBTTagFloat;
protected static Class<?> class_NBTTagInt; public static Class<?> class_NBTTagInt;
protected static Class<?> class_NBTTagLong; public static Class<?> class_NBTTagLong;
protected static Class<?> class_NBTTagShort; public static Class<?> class_NBTTagShort;
protected static Class<?> class_NBTTagString; public static Class<?> class_NBTTagString;
protected static Class<?> class_CraftTask; public static Class<?> class_CraftTask;
protected static Class<?> class_CraftInventoryCustom; public static Class<?> class_CraftInventoryCustom;
protected static Class<?> class_CraftItemStack; public static Class<?> class_CraftItemStack;
protected static Class<?> class_CraftBlockState; public static Class<?> class_CraftBlockState;
protected static Class<?> class_CraftLivingEntity; public static Class<?> class_CraftLivingEntity;
protected static Class<?> class_CraftWorld; public static Class<?> class_CraftWorld;
protected static Class<?> class_Consumer; public static Class<?> class_Consumer;
protected static Class<?> class_Entity; public static Class<?> class_Entity;
protected static Class<?> class_EntityCreature; public static Class<?> class_EntityCreature;
protected static Class<?> class_EntityLiving; public static Class<?> class_EntityLiving;
protected static Class<?> class_EntityHuman; public static Class<?> class_EntityHuman;
protected static Class<?> class_DataWatcher; public static Class<?> class_DataWatcher;
protected static Class<?> class_DamageSource; public static Class<?> class_DamageSource;
protected static Class<?> class_EntityDamageSource; public static Class<?> class_EntityDamageSource;
protected static Class<?> class_World; public static Class<?> class_World;
protected static Class<?> class_WorldServer; public static Class<?> class_WorldServer;
protected static Class<?> class_Packet; public static Class<?> class_Packet;
protected static Class<Enum> class_EnumSkyBlock; protected static Class<Enum> class_EnumSkyBlock;
protected static Class<?> class_EntityPainting; public static Class<?> class_EntityPainting;
protected static Class<?> class_EntityItemFrame; public static Class<?> class_EntityItemFrame;
protected static Class<?> class_EntityMinecartRideable; public static Class<?> class_EntityMinecartRideable;
protected static Class<?> class_EntityTNTPrimed; public static Class<?> class_EntityTNTPrimed;
protected static Class<?> class_AxisAlignedBB; public static Class<?> class_AxisAlignedBB;
protected static Class<?> class_PathPoint; public static Class<?> class_PathPoint;
protected static Class<?> class_PathEntity; public static Class<?> class_PathEntity;
protected static Class<?> class_EntityFirework; public static Class<?> class_EntityFirework;
protected static Class<?> class_CraftSkull; public static Class<?> class_CraftSkull;
protected static Class<?> class_CraftBanner; public static Class<?> class_CraftBanner;
protected static Class<?> class_CraftMetaSkull; public static Class<?> class_CraftMetaSkull;
protected static Class<?> class_CraftMetaBanner; public static Class<?> class_CraftMetaBanner;
protected static Class<?> class_GameProfile; public static Class<?> class_GameProfile;
protected static Class<?> class_GameProfileProperty; public static Class<?> class_GameProfileProperty;
protected static Class<?> class_BlockPosition; public static Class<?> class_BlockPosition;
protected static Class<?> class_NBTCompressedStreamTools; public static Class<?> class_NBTCompressedStreamTools;
protected static Class<?> class_TileEntity; public static Class<?> class_TileEntity;
protected static Class<?> class_TileEntitySign; public static Class<?> class_TileEntitySign;
protected static Class<?> class_TileEntityContainer; public static Class<?> class_TileEntityContainer;
protected static Class<?> class_ChestLock; public static Class<?> class_ChestLock;
protected static Class<Enum> class_EnumDirection; protected static Class<Enum> class_EnumDirection;
protected static Class<?> class_EntityHorse; public static Class<?> class_EntityHorse;
protected static Class<?> class_EntityWitherSkull; public static Class<?> class_EntityWitherSkull;
protected static Class<?> class_PacketPlayOutAttachEntity; public static Class<?> class_PacketPlayOutAttachEntity;
protected static Class<?> class_PacketPlayOutEntityDestroy; public static Class<?> class_PacketPlayOutEntityDestroy;
protected static Class<?> class_PacketPlayOutSpawnEntity; public static Class<?> class_PacketPlayOutSpawnEntity;
protected static Class<?> class_PacketPlayOutSpawnEntityLiving; public static Class<?> class_PacketPlayOutSpawnEntityLiving;
protected static Class<?> class_PacketPlayOutEntityMetadata; public static Class<?> class_PacketPlayOutEntityMetadata;
protected static Class<?> class_PacketPlayOutEntityStatus; public static Class<?> class_PacketPlayOutEntityStatus;
protected static Class<?> class_PacketPlayOutCustomSoundEffect; public static Class<?> class_PacketPlayOutCustomSoundEffect;
protected static Class<?> class_PacketPlayOutExperience; public static Class<?> class_PacketPlayOutExperience;
protected static Class<?> class_PacketPlayOutAnimation; public static Class<?> class_PacketPlayOutAnimation;
protected static Class<?> class_PacketPlayOutBlockBreakAnimation; public static Class<?> class_PacketPlayOutBlockBreakAnimation;
protected static Enum<?> enum_SoundCategory_PLAYERS; protected static Enum<?> enum_SoundCategory_PLAYERS;
protected static Class<Enum> class_EnumSoundCategory; protected static Class<Enum> class_EnumSoundCategory;
protected static Class<?> class_EntityFallingBlock; public static Class<?> class_EntityFallingBlock;
protected static Class<?> class_EntityArmorStand; public static Class<?> class_EntityArmorStand;
protected static Class<?> class_EntityPlayer; public static Class<?> class_EntityPlayer;
protected static Class<?> class_PlayerConnection; public static Class<?> class_PlayerConnection;
protected static Class<?> class_Chunk; public static Class<?> class_Chunk;
protected static Class<?> class_CraftPlayer; public static Class<?> class_CraftPlayer;
protected static Class<?> class_CraftChunk; public static Class<?> class_CraftChunk;
protected static Class<?> class_CraftEntity; public static Class<?> class_CraftEntity;
protected static Class<?> class_EntityProjectile; public static Class<?> class_EntityProjectile;
protected static Class<?> class_EntityFireball; public static Class<?> class_EntityFireball;
protected static Class<?> class_EntityArrow; public static Class<?> class_EntityArrow;
protected static Class<?> class_CraftArrow; public static Class<?> class_CraftArrow;
protected static Class<?> class_MinecraftServer; public static Class<?> class_MinecraftServer;
protected static Class<?> class_CraftServer; public static Class<?> class_CraftServer;
protected static Class<?> class_DataWatcherObject; public static Class<?> class_DataWatcherObject;
protected static Class<?> class_PacketPlayOutChat; public static Class<?> class_PacketPlayOutChat;
protected static Class<Enum> class_ChatMessageType; protected static Class<Enum> class_ChatMessageType;
protected static Enum<?> enum_ChatMessageType_GAME_INFO; protected static Enum<?> enum_ChatMessageType_GAME_INFO;
protected static Class<?> class_ChatComponentText; public static Class<?> class_ChatComponentText;
protected static Class<?> class_IChatBaseComponent; public static Class<?> class_IChatBaseComponent;
protected static Method class_NBTTagList_addMethod; protected static Method class_NBTTagList_addMethod;
protected static Method class_NBTTagList_getMethod; protected static Method class_NBTTagList_getMethod;
@ -275,8 +277,7 @@ public class NMSUtil19 {
protected static Field class_Entity_moveStrafingField; protected static Field class_Entity_moveStrafingField;
protected static Field class_Entity_moveForwardField; protected static Field class_Entity_moveForwardField;
static static {
{
// Find classes Bukkit hides from us. :-D // Find classes Bukkit hides from us. :-D
// Much thanks to @DPOHVAR for sharing the PowerNBT code that powers the reflection approach. // Much thanks to @DPOHVAR for sharing the PowerNBT code that powers the reflection approach.
String className = Bukkit.getServer().getClass().getName(); String className = Bukkit.getServer().getClass().getName();
@ -312,8 +313,8 @@ public class NMSUtil19 {
class_Packet = fixBukkitClass("net.minecraft.server.Packet"); class_Packet = fixBukkitClass("net.minecraft.server.Packet");
class_World = fixBukkitClass("net.minecraft.server.World"); class_World = fixBukkitClass("net.minecraft.server.World");
class_WorldServer = fixBukkitClass("net.minecraft.server.WorldServer"); class_WorldServer = fixBukkitClass("net.minecraft.server.WorldServer");
class_EnumSkyBlock = (Class<Enum>)fixBukkitClass("net.minecraft.server.EnumSkyBlock"); class_EnumSkyBlock = (Class<Enum>) fixBukkitClass("net.minecraft.server.EnumSkyBlock");
class_EnumSoundCategory = (Class<Enum>)fixBukkitClass("net.minecraft.server.SoundCategory"); class_EnumSoundCategory = (Class<Enum>) fixBukkitClass("net.minecraft.server.SoundCategory");
enum_SoundCategory_PLAYERS = Enum.valueOf(class_EnumSoundCategory, "PLAYERS"); enum_SoundCategory_PLAYERS = Enum.valueOf(class_EnumSoundCategory, "PLAYERS");
class_EntityPainting = fixBukkitClass("net.minecraft.server.EntityPainting"); class_EntityPainting = fixBukkitClass("net.minecraft.server.EntityPainting");
class_EntityCreature = fixBukkitClass("net.minecraft.server.EntityCreature"); class_EntityCreature = fixBukkitClass("net.minecraft.server.EntityCreature");
@ -508,7 +509,7 @@ public class NMSUtil19 {
class_CraftBanner_setPatternsMethod = class_CraftBanner.getMethod("setPatterns", List.class); class_CraftBanner_setPatternsMethod = class_CraftBanner.getMethod("setPatterns", List.class);
class_CraftBanner_setBaseColorMethod = class_CraftBanner.getMethod("setBaseColor", DyeColor.class); class_CraftBanner_setBaseColorMethod = class_CraftBanner.getMethod("setBaseColor", DyeColor.class);
class_EnumDirection = (Class<Enum>)fixBukkitClass("net.minecraft.server.EnumDirection"); class_EnumDirection = (Class<Enum>) fixBukkitClass("net.minecraft.server.EnumDirection");
class_BlockPosition_Constructor = class_BlockPosition.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE); class_BlockPosition_Constructor = class_BlockPosition.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE);
class_EntityPaintingConstructor = class_EntityPainting.getConstructor(class_World, class_BlockPosition, class_EnumDirection); class_EntityPaintingConstructor = class_EntityPainting.getConstructor(class_World, class_BlockPosition, class_EnumDirection);
class_EntityItemFrameConstructor = class_EntityItemFrame.getConstructor(class_World, class_BlockPosition, class_EnumDirection); class_EntityItemFrameConstructor = class_EntityItemFrame.getConstructor(class_World, class_BlockPosition, class_EnumDirection);
@ -603,7 +604,7 @@ public class NMSUtil19 {
class_ChatComponentText_constructor = class_ChatComponentText.getConstructor(String.class); class_ChatComponentText_constructor = class_ChatComponentText.getConstructor(String.class);
// 1.12 specific // 1.12 specific
class_ChatMessageType = (Class<Enum>)fixBukkitClass("net.minecraft.server.ChatMessageType"); class_ChatMessageType = (Class<Enum>) fixBukkitClass("net.minecraft.server.ChatMessageType");
enum_ChatMessageType_GAME_INFO = Enum.valueOf(class_ChatMessageType, "GAME_INFO"); enum_ChatMessageType_GAME_INFO = Enum.valueOf(class_ChatMessageType, "GAME_INFO");
class_PacketPlayOutChat_constructor = class_PacketPlayOutChat.getConstructor(class_IChatBaseComponent, class_ChatMessageType); class_PacketPlayOutChat_constructor = class_PacketPlayOutChat.getConstructor(class_IChatBaseComponent, class_ChatMessageType);
@ -771,8 +772,7 @@ public class NMSUtil19 {
Bukkit.getLogger().log(Level.WARNING, "An error occurred, setting arrow lifespan will not work", ex); Bukkit.getLogger().log(Level.WARNING, "An error occurred, setting arrow lifespan will not work", ex);
class_EntityArrow_lifeField = null; class_EntityArrow_lifeField = null;
} }
if (class_EntityArrow_lifeField != null) if (class_EntityArrow_lifeField != null) {
{
class_EntityArrow_lifeField.setAccessible(true); class_EntityArrow_lifeField.setAccessible(true);
} }
@ -874,8 +874,7 @@ public class NMSUtil19 {
// 1.10 and earlier // 1.10 and earlier
legacy = true; legacy = true;
} }
} } catch (Throwable ex) {
catch (Throwable ex) {
failed = true; failed = true;
Bukkit.getLogger().log(Level.SEVERE, "An unexpected error occurred initializing Magic", ex); Bukkit.getLogger().log(Level.SEVERE, "An unexpected error occurred initializing Magic", ex);
} }
@ -994,7 +993,7 @@ public class NMSUtil19 {
Object chunkHandle = getHandle(chunk); Object chunkHandle = getHandle(chunk);
boolean done = false; boolean done = false;
try { try {
done = (Boolean)class_Chunk_doneField.get(chunkHandle); done = (Boolean) class_Chunk_doneField.get(chunkHandle);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1046,8 +1045,7 @@ public class NMSUtil19 {
sendPacketMethod.invoke(connection, packet); sendPacketMethod.invoke(connection, packet);
} }
public static int getFacing(BlockFace direction) public static int getFacing(BlockFace direction) {
{
int dir; int dir;
switch (direction) { switch (direction) {
case SOUTH: case SOUTH:
@ -1068,8 +1066,7 @@ public class NMSUtil19 {
return dir; return dir;
} }
public static Entity getBukkitEntity(Object entity) public static Entity getBukkitEntity(Object entity) {
{
if (entity == null) { if (entity == null) {
return null; return null;
} }
@ -1079,7 +1076,7 @@ public class NMSUtil19 {
if (!(bukkitEntity instanceof Entity)) { if (!(bukkitEntity instanceof Entity)) {
return null; return null;
} }
return (Entity)bukkitEntity; return (Entity) bukkitEntity;
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1197,7 +1194,7 @@ public class NMSUtil19 {
} }
Boolean result = false; Boolean result = false;
try { try {
result = (Boolean)class_NBTTagCompound_hasKeyMethod.invoke(nbtBase, tag); result = (Boolean) class_NBTTagCompound_hasKeyMethod.invoke(nbtBase, tag);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1267,7 +1264,7 @@ public class NMSUtil19 {
} }
String meta = null; String meta = null;
try { try {
meta = (String)class_NBTTagCompound_getStringMethod.invoke(node, tag); meta = (String) class_NBTTagCompound_getStringMethod.invoke(node, tag);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1280,7 +1277,7 @@ public class NMSUtil19 {
} }
String meta = null; String meta = null;
try { try {
meta = (String)class_NBTTagCompound_getStringMethod.invoke(node, tag); meta = (String) class_NBTTagCompound_getStringMethod.invoke(node, tag);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1293,7 +1290,7 @@ public class NMSUtil19 {
} }
Byte meta = null; Byte meta = null;
try { try {
meta = (Byte)class_NBTTagCompound_getByteMethod.invoke(node, tag); meta = (Byte) class_NBTTagCompound_getByteMethod.invoke(node, tag);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1306,7 +1303,7 @@ public class NMSUtil19 {
} }
Integer meta = null; Integer meta = null;
try { try {
meta = (Integer)class_NBTTagCompound_getIntMethod.invoke(node, tag); meta = (Integer) class_NBTTagCompound_getIntMethod.invoke(node, tag);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1319,7 +1316,7 @@ public class NMSUtil19 {
} }
Boolean meta = null; Boolean meta = null;
try { try {
meta = (Boolean)class_NBTTagCompound_getBooleanMethod.invoke(node, tag); meta = (Boolean) class_NBTTagCompound_getBooleanMethod.invoke(node, tag);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1327,7 +1324,7 @@ public class NMSUtil19 {
} }
public static void setMeta(Object node, String tag, String value) { public static void setMeta(Object node, String tag, String value) {
if (node == null|| !class_NBTTagCompound.isInstance(node)) { if (node == null || !class_NBTTagCompound.isInstance(node)) {
return; return;
} }
try { try {
@ -1342,7 +1339,7 @@ public class NMSUtil19 {
} }
public static void setMetaLong(Object node, String tag, long value) { public static void setMetaLong(Object node, String tag, long value) {
if (node == null|| !class_NBTTagCompound.isInstance(node)) { if (node == null || !class_NBTTagCompound.isInstance(node)) {
return; return;
} }
try { try {
@ -1353,7 +1350,7 @@ public class NMSUtil19 {
} }
public static void setMetaBoolean(Object node, String tag, boolean value) { public static void setMetaBoolean(Object node, String tag, boolean value) {
if (node == null|| !class_NBTTagCompound.isInstance(node)) { if (node == null || !class_NBTTagCompound.isInstance(node)) {
return; return;
} }
try { try {
@ -1364,7 +1361,7 @@ public class NMSUtil19 {
} }
public static void setMetaDouble(Object node, String tag, double value) { public static void setMetaDouble(Object node, String tag, double value) {
if (node == null|| !class_NBTTagCompound.isInstance(node)) { if (node == null || !class_NBTTagCompound.isInstance(node)) {
return; return;
} }
try { try {
@ -1375,7 +1372,7 @@ public class NMSUtil19 {
} }
public static void setMetaInt(Object node, String tag, int value) { public static void setMetaInt(Object node, String tag, int value) {
if (node == null|| !class_NBTTagCompound.isInstance(node)) { if (node == null || !class_NBTTagCompound.isInstance(node)) {
return; return;
} }
try { try {
@ -1386,7 +1383,7 @@ public class NMSUtil19 {
} }
public static void removeMeta(Object node, String tag) { public static void removeMeta(Object node, String tag) {
if (node == null|| !class_NBTTagCompound.isInstance(node)) { if (node == null || !class_NBTTagCompound.isInstance(node)) {
return; return;
} }
try { try {
@ -1471,7 +1468,7 @@ public class NMSUtil19 {
if (tagObject == null) { if (tagObject == null) {
return null; return null;
} }
meta = (String)class_NBTTagCompound_getStringMethod.invoke(tagObject, tag); meta = (String) class_NBTTagCompound_getStringMethod.invoke(tagObject, tag);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1646,7 +1643,7 @@ public class NMSUtil19 {
Object explosion = class_World_explodeMethod.invoke(worldHandle, entityHandle, x, y, z, power, setFire, breakBlocks); Object explosion = class_World_explodeMethod.invoke(worldHandle, entityHandle, x, y, z, power, setFire, breakBlocks);
Field cancelledField = explosion.getClass().getDeclaredField("wasCanceled"); Field cancelledField = explosion.getClass().getDeclaredField("wasCanceled");
result = (Boolean)cancelledField.get(explosion); result = (Boolean) cancelledField.get(explosion);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
result = false; result = false;
@ -1743,7 +1740,7 @@ public class NMSUtil19 {
} else { } else {
nmsStack = class_ItemStack_createStackMethod.invoke(null, itemTag); nmsStack = class_ItemStack_createStackMethod.invoke(null, itemTag);
} }
item = (ItemStack)class_CraftItemStack_mirrorMethod.invoke(null, nmsStack); item = (ItemStack) class_CraftItemStack_mirrorMethod.invoke(null, nmsStack);
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
@ -1753,7 +1750,7 @@ public class NMSUtil19 {
public static ItemStack[] getItems(Object rootTag, String tagName) { public static ItemStack[] getItems(Object rootTag, String tagName) {
try { try {
Object itemList = class_NBTTagCompound_getListMethod.invoke(rootTag, tagName, NBT_TYPE_COMPOUND); Object itemList = class_NBTTagCompound_getListMethod.invoke(rootTag, tagName, NBT_TYPE_COMPOUND);
Integer size = (Integer)class_NBTTagList_sizeMethod.invoke(itemList); Integer size = (Integer) class_NBTTagList_sizeMethod.invoke(itemList);
ItemStack[] items = new ItemStack[size]; ItemStack[] items = new ItemStack[size];
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
try { try {
@ -1823,10 +1820,10 @@ public class NMSUtil19 {
class_TileEntity_saveMethod.invoke(tileEntity, entityData); class_TileEntity_saveMethod.invoke(tileEntity, entityData);
Object itemList = class_NBTTagCompound_getListMethod.invoke(entityData, "Items", NBT_TYPE_COMPOUND); Object itemList = class_NBTTagCompound_getListMethod.invoke(entityData, "Items", NBT_TYPE_COMPOUND);
if (itemList != null) { if (itemList != null) {
List items = (List)class_NBTTagList_list.get(itemList); List items = (List) class_NBTTagList_list.get(itemList);
items.clear(); items.clear();
} }
class_NBTTagCompound_removeMethod.invoke(entityData,"Item"); class_NBTTagCompound_removeMethod.invoke(entityData, "Item");
class_TileEntity_loadMethod.invoke(tileEntity, entityData); class_TileEntity_loadMethod.invoke(tileEntity, entityData);
class_TileEntity_updateMethod.invoke(tileEntity); class_TileEntity_updateMethod.invoke(tileEntity);
} }
@ -1871,9 +1868,9 @@ public class NMSUtil19 {
} }
try { try {
Object posList = class_NBTTagCompound_getListMethod.invoke(entityData, tag, NBT_TYPE_DOUBLE); Object posList = class_NBTTagCompound_getListMethod.invoke(entityData, tag, NBT_TYPE_DOUBLE);
Double x = (Double)class_NBTTagList_getDoubleMethod.invoke(posList, 0); Double x = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 0);
Double y = (Double)class_NBTTagList_getDoubleMethod.invoke(posList, 1); Double y = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 1);
Double z = (Double)class_NBTTagList_getDoubleMethod.invoke(posList, 2); Double z = (Double) class_NBTTagList_getDoubleMethod.invoke(posList, 2);
if (x != null && y != null && z != null) { if (x != null && y != null && z != null) {
return new Vector(x, y, z); return new Vector(x, y, z);
} }
@ -1886,7 +1883,7 @@ public class NMSUtil19 {
public static Entity getEntity(World world, UUID uuid) { public static Entity getEntity(World world, UUID uuid) {
try { try {
Object worldHandle = getHandle(world); Object worldHandle = getHandle(world);
final Map<UUID, Entity> entityMap = (Map<UUID, Entity>)class_WorldServer_entitiesByUUIDField.get(worldHandle); final Map<UUID, Entity> entityMap = (Map<UUID, Entity>) class_WorldServer_entitiesByUUIDField.get(worldHandle);
if (entityMap != null) { if (entityMap != null) {
Object nmsEntity = entityMap.get(uuid); Object nmsEntity = entityMap.get(uuid);
if (nmsEntity != null) { if (nmsEntity != null) {
@ -1907,8 +1904,7 @@ public class NMSUtil19 {
} }
} }
public static void playCustomSound(Player player, Location location, String sound, float volume, float pitch) public static void playCustomSound(Player player, Location location, String sound, float volume, float pitch) {
{
try { try {
Object packet = class_PacketPlayOutCustomSoundEffect_Constructor.newInstance(sound, enum_SoundCategory_PLAYERS, location.getX(), location.getY(), location.getZ(), volume, pitch); Object packet = class_PacketPlayOutCustomSoundEffect_Constructor.newInstance(sound, enum_SoundCategory_PLAYERS, location.getX(), location.getY(), location.getZ(), volume, pitch);
sendPacket(player, packet); sendPacket(player, packet);
@ -1917,17 +1913,15 @@ public class NMSUtil19 {
} }
} }
public static Map<String, Object> getMap(ConfigurationSection section) public static Map<String, Object> getMap(ConfigurationSection section) {
{
if (section == null) { if (section == null) {
return null; return null;
} }
if (section instanceof MemorySection) if (section instanceof MemorySection) {
{
try { try {
Object mapObject = class_MemorySection_mapField.get(section); Object mapObject = class_MemorySection_mapField.get(section);
if (mapObject instanceof Map) { if (mapObject instanceof Map) {
return (Map<String, Object>)mapObject; return (Map<String, Object>) mapObject;
} }
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
@ -1956,7 +1950,7 @@ public class NMSUtil19 {
if (handle == null) { if (handle == null) {
return false; return false;
} }
return (Boolean)class_ItemStack_isEmptyMethod.invoke(handle); return (Boolean) class_ItemStack_isEmptyMethod.invoke(handle);
} catch (Throwable ex) { } catch (Throwable ex) {
ex.printStackTrace(); ex.printStackTrace();
} }

View File

@ -7,6 +7,9 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
/**
* @author Unknown
*/
public class NMSUtils { public class NMSUtils {
public static Class<?> c = getOBCClass("block.CraftBlock"); public static Class<?> c = getOBCClass("block.CraftBlock");

View File

@ -8,7 +8,9 @@ import org.bukkit.inventory.ItemStack;
import java.util.HashSet; import java.util.HashSet;
@SuppressWarnings("deprecation") /**
* @author sky
*/
public class PlayerUtils { public class PlayerUtils {
/** /**
@ -19,9 +21,9 @@ public class PlayerUtils {
* @return * @return
*/ */
public static Block getTargetBlock(Player player, int max) { public static Block getTargetBlock(Player player, int max) {
HashSet<Byte> Byte = new HashSet<>(); HashSet<Byte> bytes = new HashSet<>();
Byte.add((byte) 0); bytes.add((byte) 0);
return player.getTargetBlock(Byte, max); return player.getTargetBlock(bytes, max);
} }
/** /**

View File

@ -1,5 +1,10 @@
package me.skymc.taboolib.string; package me.skymc.taboolib.string;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -12,23 +17,73 @@ import java.util.stream.IntStream;
*/ */
public class ArrayUtils { public class ArrayUtils {
public static String arrayJoin(String[] args, int start) {
return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
}
@SafeVarargs
public static <T> List<T> asList(T... args) { public static <T> List<T> asList(T... args) {
List<T> list = new ArrayList<>(); List<T> list = new ArrayList<>();
Collections.addAll(list, args); Collections.addAll(list, args);
return list; return list;
} }
public static <T> T[] arrayAppend(T[] array, T obj) {
T[] arrayNew = arrayExpand(array, 1);
arrayNew[array.length] = obj;
return arrayNew;
}
public static <T> T[] arrayAddFirst(T[] array, T obj) {
T[] arrayNew = arrayExpandAtFirst(array, 1);
arrayNew[0] = obj;
return arrayNew;
}
@SuppressWarnings("SuspiciousSystemArraycopy")
public static <T> T arrayExpand(T oldArray, int expand) {
int length = Array.getLength(oldArray);
Object newArray = Array.newInstance(oldArray.getClass().getComponentType(), length + expand);
System.arraycopy(oldArray, 0, newArray, 0, length);
return (T) newArray;
}
@SuppressWarnings("SuspiciousSystemArraycopy")
public static <T> T arrayExpandAtFirst(T oldArray, int expand) {
int length = Array.getLength(oldArray);
Object newArray = Array.newInstance(oldArray.getClass().getComponentType(), length + expand);
System.arraycopy(oldArray, 0, newArray, expand, length);
return (T) newArray;
}
public static <T> T cloneAsByte(T obj) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(obj);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (T) objectInputStream.readObject();
}
// *********************************
//
// Deprecated
//
// *********************************
@Deprecated
public static String[] addFirst(String[] args, String... value) { public static String[] addFirst(String[] args, String... value) {
if (args.length < 1) { if (args.length < 1) {
return value; return value;
} }
List<String> list = asList(args); List<String> list = asList(args);
for (int i = value.length - 1 ; i >= 0 ; i--) { for (int i = value.length - 1; i >= 0; i--) {
list.add(0, value[i]); list.add(0, value[i]);
} }
return list.toArray(new String[0]); return list.toArray(new String[0]);
} }
@Deprecated
public static String[] removeFirst(String[] args) { public static String[] removeFirst(String[] args) {
if (args.length <= 1) { if (args.length <= 1) {
return new String[0]; return new String[0];
@ -37,8 +92,4 @@ public class ArrayUtils {
list.remove(0); list.remove(0);
return list.toArray(new String[0]); return list.toArray(new String[0]);
} }
public static String arrayJoin(String[] args, int start) {
return IntStream.range(start, args.length).mapToObj(i -> args[i] + " ").collect(Collectors.joining()).trim();
}
} }

View File

@ -0,0 +1,113 @@
package me.skymc.taboolib.string;
import com.ilummc.tlib.util.Strings;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Author sky
* @Since 2018-05-27 11:33
*/
public class VariableFormatter {
private Pattern pattern;
private String text;
private String textOrigin;
private List<Variable> variableList = new ArrayList<>();
public VariableFormatter(String text) {
this(text, "<([^<>]+)>");
}
public VariableFormatter(String text, String regex) {
this(text, Pattern.compile(regex));
}
public VariableFormatter(String text, Pattern pattern) {
this.text = text;
this.textOrigin = text;
this.pattern = pattern;
}
public VariableFormatter reset() {
text = textOrigin;
variableList.clear();
return this;
}
public VariableFormatter find() {
reset();
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String group = matcher.group();
String[] textOther = text.split(group);
String textLeft = text.indexOf(group) > 0 ? textOther[0] : null;
String textRight = textOther.length >= 2 ? text.substring(text.indexOf(group) + group.length()) : null;
if (textLeft != null) {
variableList.add(new Variable(textLeft, false));
}
variableList.add(new Variable(group.substring(1, group.length() - 1), true));
if (textRight != null && !pattern.matcher(textRight).find()) {
variableList.add(new Variable(textRight, false));
} else {
text = String.valueOf(textRight);
}
}
if (variableList.size() == 0) {
variableList.add(new Variable(text, false));
}
return this;
}
@Override
public String toString() {
return Strings.replaceWithOrder("VariableFormatter'{'pattern={0}, text=''{1}'', textOrigin=''{2}'', variableList={3}'}'", pattern, text, textOrigin, variableList);
}
// *********************************
//
// Getter and Setter
//
// *********************************
public String getText() {
return text;
}
public List<Variable> getVariableList() {
return variableList;
}
// *********************************
//
// Public classes
//
// *********************************
public static class Variable {
private final String text;
private final boolean variable;
public Variable(String text, boolean variable) {
this.text = text;
this.variable = variable;
}
public String getText() {
return text;
}
public boolean isVariable() {
return variable;
}
@Override
public String toString() {
return Strings.replaceWithOrder("Variable'{'text=''{0}'', variable={1}'}'", text, variable);
}
}
}

View File

@ -1,5 +1,9 @@
package me.skymc.taboolib.string.language2.value; package me.skymc.taboolib.string.language2.value;
import com.ilummc.tlib.bungee.api.chat.BaseComponent;
import com.ilummc.tlib.bungee.api.chat.ClickEvent;
import com.ilummc.tlib.bungee.api.chat.HoverEvent;
import com.ilummc.tlib.bungee.api.chat.TextComponent;
import me.skymc.taboolib.bookformatter.BookFormatter; import me.skymc.taboolib.bookformatter.BookFormatter;
import me.skymc.taboolib.bookformatter.action.ClickAction; import me.skymc.taboolib.bookformatter.action.ClickAction;
import me.skymc.taboolib.bookformatter.action.HoverAction; import me.skymc.taboolib.bookformatter.action.HoverAction;
@ -8,6 +12,7 @@ import me.skymc.taboolib.bookformatter.builder.PageBuilder;
import me.skymc.taboolib.bookformatter.builder.TextBuilder; import me.skymc.taboolib.bookformatter.builder.TextBuilder;
import me.skymc.taboolib.inventory.ItemUtils; import me.skymc.taboolib.inventory.ItemUtils;
import me.skymc.taboolib.other.NumberUtils; import me.skymc.taboolib.other.NumberUtils;
import me.skymc.taboolib.string.VariableFormatter;
import me.skymc.taboolib.string.language2.Language2Format; import me.skymc.taboolib.string.language2.Language2Format;
import me.skymc.taboolib.string.language2.Language2Line; import me.skymc.taboolib.string.language2.Language2Line;
import me.skymc.taboolib.string.language2.Language2Value; import me.skymc.taboolib.string.language2.Language2Value;
@ -21,7 +26,6 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
@ -52,17 +56,15 @@ public class Language2Book implements Language2Line {
// 变量 // 变量
this.player = player; this.player = player;
this.value = format.getLanguage2Value(); this.value = format.getLanguage2Value();
this.book = BookFormatter.writtenBook();
// 获取书本设置 // 设置
formatOptions(list); formatOptions(list);
// 书本
book = BookFormatter.writtenBook();
// 内容 // 内容
PageBuilder page = new PageBuilder(); PageBuilder page = new PageBuilder();
// 遍历内容 // 遍历内容
for (String line : list) { for (String line : list) {
// 翻页 // 翻页
if ("[page]".equals(line)) { if (line.equals("[page]")) {
book.addPages(page.build()); book.addPages(page.build());
page = new PageBuilder(); page = new PageBuilder();
} }
@ -70,57 +72,50 @@ public class Language2Book implements Language2Line {
else if (line.startsWith("@option")) { else if (line.startsWith("@option")) {
break; break;
} else { } else {
Matcher matcher = pattern.matcher(line); for (VariableFormatter.Variable variable : new VariableFormatter(line, pattern).find().getVariableList()) {
boolean find = false; if (variable.isVariable()) {
while (matcher.find()) { String node = variable.getText().substring(1);
find = true; if (!options.containsKey(node)) {
String optionName = matcher.group(1);
String optionFullName = "<@" + matcher.group(1) + ">";
// 判断设置是否存在
if (!options.containsKey(optionName)) {
page.add("§4[<ERROR-50: " + format.getLanguage2Value().getLanguageKey() + ">]"); page.add("§4[<ERROR-50: " + format.getLanguage2Value().getLanguageKey() + ">]");
} else { } else {
String[] line_split = line.split(optionFullName); TextBuilder builder = options.get(node);
try { BaseComponent component = new TextComponent(builder.getText());
// 单独一行 if (builder.getHover() != null) {
if (line_split.length == 0) { component.setHoverEvent(new HoverEvent(builder.getHover().action(), builder.getHover().value()));
page.add(options.get(optionName).build()).endLine();
} else {
// 前段
page.add(line_split[0]);
// 变量
page.add(options.get(optionName).build());
// 后段
if (line_split.length >= 2) {
// 获取文本
StringBuilder sb = new StringBuilder();
for (int i = 1; i < line_split.length; i++) {
sb.append(line_split[i]).append(optionFullName);
} }
// 更改文本 if (builder.getClick() != null) {
line = sb.substring(0, sb.length() - optionFullName.length()); component.setClickEvent(new ClickEvent(builder.getClick().action(), builder.getClick().value()));
// 如果后段还有变量 }
if (!pattern.matcher(line).find()) { page.add(component);
page.add(line_split[1]).endLine();
} }
} else { } else {
page.endLine(); page.add(variable.getText());
} }
} }
} catch (Exception e) { page.newLine();
page.add("§4[<ERROR-51: " + format.getLanguage2Value().getLanguageKey() + ">]");
}
}
}
if (!find) {
page.add(line).endLine();
}
} }
} }
// 结尾 // 结尾
book.addPages(page.build()); book.addPages(page.build());
} }
@Override
public void send(Player player) {
BookFormatter.forceOpen(player, book.build());
}
@Override
public void console() {
Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[<ERROR-40: " + value.getLanguageKey() + ">]");
}
// *********************************
//
// Getter and Setter
//
// *********************************
public static Pattern getPattern() { public static Pattern getPattern() {
return pattern; return pattern;
} }
@ -141,6 +136,46 @@ public class Language2Book implements Language2Line {
return book; return book;
} }
// *********************************
//
// Private Methods
//
// *********************************
private List<List<String>> getBookPages(List<String> source) {
List<List<String>> list = new ArrayList<>();
for (String line : removeOption(source)) {
if (line.equalsIgnoreCase("[page]")) {
list.add(new ArrayList<>());
} else {
getLatestList(list).add(line);
}
}
return list;
}
public List<String> getLatestList(List<List<String>> list) {
if (list.size() == 0) {
List<String> newList = new ArrayList<>();
list.add(newList);
return newList;
} else {
return list.get(list.size() - 1);
}
}
public List<String> removeOption(List<String> source) {
List<String> list = new ArrayList<>();
for (String line : source) {
if (!line.contains("@option")) {
list.add(line);
} else {
return list;
}
}
return list;
}
private void formatOptions(List<String> list) { private void formatOptions(List<String> list) {
// 获取书本设置 // 获取书本设置
HashMap<String, List<String>> _options = getOptions(list); HashMap<String, List<String>> _options = getOptions(list);
@ -204,14 +239,4 @@ public class Language2Book implements Language2Line {
options_source.put(optionName, option); options_source.put(optionName, option);
return options_source; return options_source;
} }
@Override
public void send(Player player) {
BookFormatter.forceOpen(player, book.build());
}
@Override
public void console() {
Bukkit.getConsoleSender().sendMessage(ChatColor.DARK_RED + "[<ERROR-40: " + value.getLanguageKey() + ">]");
}
} }

View File

@ -57,6 +57,10 @@ NOTIFY:
LOCALE: LOCALE:
TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}' TITLE-SEND-TO-NON-PLAYER: '该语言类型只能发送给玩家:{0}'
PLUGIN-NOT-FOUND: '无效的语言文件发送形式: &4{0}' PLUGIN-NOT-FOUND: '无效的语言文件发送形式: &4{0}'
BOOK-ARGUMENTS-IDENTIFICATION-FAILED: 'TlocaleBook 的变量识别失败: {0}'
BAR-COLOR-IDENTIFICATION-FAILED: 'TLocaleBossBar 的颜色识别失败: {0}'
BAR-STYLE-IDENTIFICATION-FAILED: 'TLocaleBossBar 的类型识别失败: {0}'
BAR-PLUGIN-NOT-FOUND: 'TLocaleBossBar 的依赖插件 BossBarAPI 不存在'
MISC: MISC:
FIELD-COPY-FAILED: '拷贝 {0} 对象失败' FIELD-COPY-FAILED: '拷贝 {0} 对象失败'

View File

@ -25,4 +25,4 @@ commands:
aliases: [tlm] aliases: [tlm]
depend: [Vault] depend: [Vault]
softdepend: [PlaceholderAPI, Skript, TabooCode, MassiveLag] softdepend: [PlaceholderAPI, Skript, MassiveLag]