版本更新至 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:
parent
8a20fb7edb
commit
5843e0be04
9
pom.xml
9
pom.xml
@ -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>
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 *");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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,8 +34,10 @@ 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
|
||||||
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
|
@ -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
|
||||||
|
133
src/main/java/me/skymc/taboolib/json/tellraw/TellrawJson.java
Normal file
133
src/main/java/me/skymc/taboolib/json/tellraw/TellrawJson.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
|
@ -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;
|
||||||
@ -27,14 +28,20 @@ public class ShowItemEvent extends HoverEvent{
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public ShowItemEvent(ItemStack is) {
|
public ShowItemEvent(ItemStack is) {
|
||||||
|
if (TabooLib.getVerint() > 10700) {
|
||||||
|
try {
|
||||||
|
object.put("action", "show_item");
|
||||||
|
object.put("value", TellrawJson.create().getItemComponent(is));
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
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();
|
||||||
@ -61,10 +68,8 @@ 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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Unknown
|
||||||
|
*/
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
@Deprecated
|
|
||||||
public class NMSUtil19 {
|
public class NMSUtil19 {
|
||||||
|
|
||||||
protected static boolean failed = false;
|
protected static boolean failed = false;
|
||||||
@ -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();
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
@ -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,13 +1913,11 @@ 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) {
|
||||||
|
@ -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");
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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,12 +17,61 @@ 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;
|
||||||
@ -29,6 +83,7 @@ public class ArrayUtils {
|
|||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
113
src/main/java/me/skymc/taboolib/string/VariableFormatter.java
Normal file
113
src/main/java/me/skymc/taboolib/string/VariableFormatter.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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() + ">]");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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} 对象失败'
|
||||||
|
@ -25,4 +25,4 @@ commands:
|
|||||||
aliases: [tlm]
|
aliases: [tlm]
|
||||||
|
|
||||||
depend: [Vault]
|
depend: [Vault]
|
||||||
softdepend: [PlaceholderAPI, Skript, TabooCode, MassiveLag]
|
softdepend: [PlaceholderAPI, Skript, MassiveLag]
|
Loading…
Reference in New Issue
Block a user