mirror of
https://e.coding.net/circlecloud/YumCore.git
synced 2024-11-22 01:48:50 +00:00
feat: 添加TellRaw发包模式 重构C兼容类
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
12b9192aa3
commit
82ea829a73
@ -1,10 +1,5 @@
|
||||
package pw.yumc.YumCore.bukkit.compatible;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import org.bukkit.*;
|
||||
import org.json.simple.JSONObject;
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
@ -12,6 +7,18 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
|
||||
/**
|
||||
* Bukkit兼容类
|
||||
*
|
||||
@ -22,31 +29,34 @@ public class C {
|
||||
private static Class<?> nmsChatSerializer;
|
||||
private static Class<?> nmsIChatBaseComponent;
|
||||
private static Class<?> packetType;
|
||||
private static Class<?> packetActions;
|
||||
private static Class<?> packetTitle;
|
||||
|
||||
private static Method chatSerializer;
|
||||
private static Method getHandle;
|
||||
|
||||
private static String version;
|
||||
private static boolean newversion;
|
||||
|
||||
private static Field playerConnection;
|
||||
private static Method sendPacket;
|
||||
|
||||
public static boolean init;
|
||||
static {
|
||||
try {
|
||||
version = getNMSVersion();
|
||||
boolean newversion = Integer.parseInt(version.split("_")[1]) > 7;
|
||||
newversion = Integer.parseInt(version.split("_")[1]) > 7;
|
||||
nmsChatSerializer = Class.forName(a(newversion ? "IChatBaseComponent$ChatSerializer" : "ChatSerializer"));
|
||||
chatSerializer = nmsChatSerializer.getMethod("a", String.class);
|
||||
nmsIChatBaseComponent = Class.forName(a("IChatBaseComponent"));
|
||||
packetType = Class.forName(a("PacketPlayOutChat"));
|
||||
packetActions = Class.forName(a(newversion ? "PacketPlayOutTitle$EnumTitleAction" : "EnumTitleAction"));
|
||||
packetTitle = Class.forName(a("PacketPlayOutTitle"));
|
||||
Class<?> typeCraftPlayer = Class.forName(b("entity.CraftPlayer"));
|
||||
Class<?> typeNMSPlayer = Class.forName(a("EntityPlayer"));
|
||||
Class<?> typePlayerConnection = Class.forName(a("PlayerConnection"));
|
||||
getHandle = typeCraftPlayer.getMethod("getHandle");
|
||||
playerConnection = typeNMSPlayer.getField("playerConnection");
|
||||
sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(a("Packet")));
|
||||
init = true;
|
||||
} catch (Exception e) {
|
||||
Log.warning(C.class.getSimpleName() + " 兼容性工具初始化失败 可能造成部分功能不可用!");
|
||||
Log.warning("C 兼容性工具初始化失败 可能造成部分功能不可用!");
|
||||
Log.d(e);
|
||||
}
|
||||
}
|
||||
@ -71,6 +81,33 @@ public class C {
|
||||
return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* 给玩家发送Json消息
|
||||
*
|
||||
* @param receivingPacket
|
||||
* 接受信息的玩家
|
||||
* @param json
|
||||
* Json信息
|
||||
* @param type
|
||||
* 类型(0=>消息 2=>ActionBar)
|
||||
*/
|
||||
public static void sendJson(org.bukkit.entity.Player receivingPacket, String json, int type) {
|
||||
Object packet;
|
||||
try {
|
||||
Object serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, json);
|
||||
if (!version.contains("1_7")) {
|
||||
packet = packetType.getConstructor(nmsIChatBaseComponent, byte.class).newInstance(serialized, (byte) type);
|
||||
} else {
|
||||
packet = packetType.getConstructor(nmsIChatBaseComponent, int.class).newInstance(serialized, type);
|
||||
}
|
||||
Object player = getHandle.invoke(receivingPacket);
|
||||
Object connection = playerConnection.get(player);
|
||||
sendPacket.invoke(connection, packet);
|
||||
} catch (Exception ex) {
|
||||
Log.d("Json发包错误 " + version, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ActionBar {
|
||||
private ActionBar() {
|
||||
}
|
||||
@ -96,7 +133,7 @@ public class C {
|
||||
* 需要显示的时间
|
||||
*/
|
||||
public static void broadcast(final String message, final int times) {
|
||||
new Thread(new Runnable() {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(P.instance, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int time = times;
|
||||
@ -106,13 +143,12 @@ public class C {
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
time--;
|
||||
} while (time > 0);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,7 +162,7 @@ public class C {
|
||||
* 需要显示的时间
|
||||
*/
|
||||
public static void broadcast(final World world, final String message, final int times) {
|
||||
new Thread(new Runnable() {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(P.instance, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int time = times;
|
||||
@ -138,14 +174,13 @@ public class C {
|
||||
}
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
time--;
|
||||
} while (time > 0);
|
||||
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,20 +192,7 @@ public class C {
|
||||
* ActionBar信息
|
||||
*/
|
||||
public static void send(org.bukkit.entity.Player receivingPacket, String msg) {
|
||||
Object packet;
|
||||
try {
|
||||
Object serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', JSONObject.escape(msg)) + "\"}");
|
||||
if (!version.contains("1_7")) {
|
||||
packet = packetType.getConstructor(nmsIChatBaseComponent, byte.class).newInstance(serialized, (byte) 2);
|
||||
} else {
|
||||
packet = packetType.getConstructor(nmsIChatBaseComponent, int.class).newInstance(serialized, 2);
|
||||
}
|
||||
Object player = getHandle.invoke(receivingPacket);
|
||||
Object connection = playerConnection.get(player);
|
||||
sendPacket.invoke(connection, packet);
|
||||
} catch (Exception ex) {
|
||||
Log.d("ActionBar发包错误 " + version, ex);
|
||||
}
|
||||
sendJson(receivingPacket, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', JSONObject.escape(msg)) + "\"}", 2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,7 +206,7 @@ public class C {
|
||||
* 需要显示的时间
|
||||
*/
|
||||
public static void send(final org.bukkit.entity.Player receivingPacket, final String msg, final int times) {
|
||||
new Thread(new Runnable() {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(P.instance, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int time = times;
|
||||
@ -192,13 +214,12 @@ public class C {
|
||||
send(receivingPacket, msg);
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
time--;
|
||||
} while (time > 0);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +247,7 @@ public class C {
|
||||
}
|
||||
// getOnlinePlayers end
|
||||
} catch (Exception e) {
|
||||
Log.warning(Player.class.getSimpleName() + "兼容性工具初始化失败 可能造成部分功能不可用!");
|
||||
Log.warning("Player 兼容性工具初始化失败 可能造成部分功能不可用!");
|
||||
}
|
||||
try {
|
||||
// getOfflinePlayer start
|
||||
@ -285,6 +306,21 @@ public class C {
|
||||
}
|
||||
|
||||
public static class Title {
|
||||
private static Class<?> packetActions;
|
||||
private static Class<?> packetTitle;
|
||||
private static Constructor<?> packetTitleSendConstructor;
|
||||
private static Constructor<?> packetTitleSetTimeConstructor;
|
||||
static {
|
||||
try {
|
||||
packetActions = Class.forName(a(newversion ? "PacketPlayOutTitle$EnumTitleAction" : "EnumTitleAction"));
|
||||
packetTitle = Class.forName(a("PacketPlayOutTitle"));
|
||||
packetTitleSendConstructor = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent);
|
||||
packetTitleSetTimeConstructor = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE);
|
||||
} catch (Exception ignore) {
|
||||
Log.warning("Title 兼容性工具初始化失败 可能造成部分功能不可用!");
|
||||
}
|
||||
}
|
||||
|
||||
private Title() {
|
||||
}
|
||||
|
||||
@ -353,7 +389,7 @@ public class C {
|
||||
Object player = getHandle.invoke(recoverPlayer);
|
||||
Object connection = playerConnection.get(player);
|
||||
Object[] actions = packetActions.getEnumConstants();
|
||||
Object packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent).newInstance(actions[4], null);
|
||||
Object packet = packetTitleSendConstructor.newInstance(actions[4], null);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
|
||||
@ -399,21 +435,17 @@ public class C {
|
||||
Object packet;
|
||||
// Send if set
|
||||
if ((fadeInTime != -1) && (fadeOutTime != -1) && (stayTime != -1)) {
|
||||
packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2],
|
||||
null,
|
||||
fadeInTime * 20,
|
||||
stayTime * 20,
|
||||
fadeOutTime * 20);
|
||||
packet = packetTitleSendConstructor.newInstance(actions[2], null, fadeInTime * 20, stayTime * 20, fadeOutTime * 20);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
// Send title
|
||||
Object serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', title) + "\"}");
|
||||
packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent).newInstance(actions[0], serialized);
|
||||
Object serialized = chatSerializer.invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', title) + "\"}");
|
||||
packet = packetTitleSendConstructor.newInstance(actions[0], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
if (!"".equals(subtitle)) {
|
||||
// Send subtitle if present
|
||||
serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\"}");
|
||||
packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent).newInstance(actions[1], serialized);
|
||||
serialized = chatSerializer.invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\"}");
|
||||
packet = packetTitleSendConstructor.newInstance(actions[1], serialized);
|
||||
sendPacket.invoke(connection, packet);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -20,7 +20,7 @@ import pw.yumc.YumCore.bukkit.Log;
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public abstract class ItemSerialize {
|
||||
static ItemSerialize itemSerialize = new Manual();
|
||||
static ItemSerialize itemSerialize;
|
||||
static {
|
||||
try {
|
||||
itemSerialize = new Automatic();
|
||||
|
@ -21,9 +21,11 @@ import pw.yumc.YumCore.bukkit.compatible.C;
|
||||
*/
|
||||
public class Tellraw implements Cloneable {
|
||||
private List<MessagePart> messageParts = new ArrayList<>();
|
||||
private String cache;
|
||||
|
||||
static {
|
||||
if (Bukkit.getVersion().contains("Paper") || Bukkit.getVersion().contains("Torch")) {
|
||||
if (!C.init) {
|
||||
Log.console("§c========== §4警 告 §c==========");
|
||||
Log.console("§a 当前服务器为 §6Paper §a或 §6Torch ");
|
||||
Log.console("§c 异步命令会刷报错 §b不影响使用");
|
||||
@ -32,6 +34,7 @@ public class Tellraw implements Cloneable {
|
||||
Log.console("§c===========================");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Tellraw(String text) {
|
||||
messageParts.add(new MessagePart(text));
|
||||
@ -172,7 +175,11 @@ public class Tellraw implements Cloneable {
|
||||
public void send(final CommandSender sender) {
|
||||
final String json = toJsonString();
|
||||
if (sender instanceof Player && json.getBytes().length < 32000) {
|
||||
if (C.init) {
|
||||
C.sendJson((Player) sender, json, 0);
|
||||
} else {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + json);
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(toOldMessageFormat());
|
||||
}
|
||||
@ -231,7 +238,7 @@ public class Tellraw implements Cloneable {
|
||||
* @param name
|
||||
* 物品名称
|
||||
* @param item
|
||||
* {@link ItemStack}
|
||||
* {@link ItemStack};
|
||||
* @return {@link Tellraw}
|
||||
*/
|
||||
public Tellraw then(String name, ItemStack item) {
|
||||
@ -295,6 +302,7 @@ public class Tellraw implements Cloneable {
|
||||
* @return Json串
|
||||
*/
|
||||
public String toJsonString() {
|
||||
if (cache == null) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("[\"\"");
|
||||
for (MessagePart messagePart : messageParts) {
|
||||
@ -302,8 +310,10 @@ public class Tellraw implements Cloneable {
|
||||
messagePart.writeJson(msg);
|
||||
}
|
||||
msg.append("]");
|
||||
Log.debug(msg.toString());
|
||||
return msg.toString();
|
||||
cache = msg.toString();
|
||||
Log.d(cache);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
public Tellraw setMessageParts(List<MessagePart> messageParts) {
|
||||
@ -395,6 +405,7 @@ public class Tellraw implements Cloneable {
|
||||
} else {
|
||||
messageParts.add(part);
|
||||
}
|
||||
cache = null;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user