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;
|
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.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -12,6 +7,18 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.UUID;
|
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兼容类
|
* Bukkit兼容类
|
||||||
*
|
*
|
||||||
@ -22,31 +29,34 @@ public class C {
|
|||||||
private static Class<?> nmsChatSerializer;
|
private static Class<?> nmsChatSerializer;
|
||||||
private static Class<?> nmsIChatBaseComponent;
|
private static Class<?> nmsIChatBaseComponent;
|
||||||
private static Class<?> packetType;
|
private static Class<?> packetType;
|
||||||
private static Class<?> packetActions;
|
|
||||||
private static Class<?> packetTitle;
|
|
||||||
|
|
||||||
|
private static Method chatSerializer;
|
||||||
private static Method getHandle;
|
private static Method getHandle;
|
||||||
|
|
||||||
private static String version;
|
private static String version;
|
||||||
|
private static boolean newversion;
|
||||||
|
|
||||||
private static Field playerConnection;
|
private static Field playerConnection;
|
||||||
private static Method sendPacket;
|
private static Method sendPacket;
|
||||||
|
|
||||||
|
public static boolean init;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
version = getNMSVersion();
|
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"));
|
nmsChatSerializer = Class.forName(a(newversion ? "IChatBaseComponent$ChatSerializer" : "ChatSerializer"));
|
||||||
|
chatSerializer = nmsChatSerializer.getMethod("a", String.class);
|
||||||
nmsIChatBaseComponent = Class.forName(a("IChatBaseComponent"));
|
nmsIChatBaseComponent = Class.forName(a("IChatBaseComponent"));
|
||||||
packetType = Class.forName(a("PacketPlayOutChat"));
|
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<?> typeCraftPlayer = Class.forName(b("entity.CraftPlayer"));
|
||||||
Class<?> typeNMSPlayer = Class.forName(a("EntityPlayer"));
|
Class<?> typeNMSPlayer = Class.forName(a("EntityPlayer"));
|
||||||
Class<?> typePlayerConnection = Class.forName(a("PlayerConnection"));
|
Class<?> typePlayerConnection = Class.forName(a("PlayerConnection"));
|
||||||
getHandle = typeCraftPlayer.getMethod("getHandle");
|
getHandle = typeCraftPlayer.getMethod("getHandle");
|
||||||
playerConnection = typeNMSPlayer.getField("playerConnection");
|
playerConnection = typeNMSPlayer.getField("playerConnection");
|
||||||
sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(a("Packet")));
|
sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(a("Packet")));
|
||||||
|
init = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.warning(C.class.getSimpleName() + " 兼容性工具初始化失败 可能造成部分功能不可用!");
|
Log.warning("C 兼容性工具初始化失败 可能造成部分功能不可用!");
|
||||||
Log.d(e);
|
Log.d(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,6 +81,33 @@ public class C {
|
|||||||
return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
|
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 {
|
public static class ActionBar {
|
||||||
private ActionBar() {
|
private ActionBar() {
|
||||||
}
|
}
|
||||||
@ -96,7 +133,7 @@ public class C {
|
|||||||
* 需要显示的时间
|
* 需要显示的时间
|
||||||
*/
|
*/
|
||||||
public static void broadcast(final String message, final int times) {
|
public static void broadcast(final String message, final int times) {
|
||||||
new Thread(new Runnable() {
|
Bukkit.getScheduler().runTaskAsynchronously(P.instance, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int time = times;
|
int time = times;
|
||||||
@ -106,13 +143,12 @@ public class C {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException ignored) {
|
||||||
// Ignore
|
|
||||||
}
|
}
|
||||||
time--;
|
time--;
|
||||||
} while (time > 0);
|
} while (time > 0);
|
||||||
}
|
}
|
||||||
}).start();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -126,7 +162,7 @@ public class C {
|
|||||||
* 需要显示的时间
|
* 需要显示的时间
|
||||||
*/
|
*/
|
||||||
public static void broadcast(final World world, final String message, final int times) {
|
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
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int time = times;
|
int time = times;
|
||||||
@ -138,14 +174,13 @@ public class C {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException ignored) {
|
||||||
// Ignore
|
|
||||||
}
|
}
|
||||||
time--;
|
time--;
|
||||||
} while (time > 0);
|
} while (time > 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
}).start();
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,20 +192,7 @@ public class C {
|
|||||||
* ActionBar信息
|
* ActionBar信息
|
||||||
*/
|
*/
|
||||||
public static void send(org.bukkit.entity.Player receivingPacket, String msg) {
|
public static void send(org.bukkit.entity.Player receivingPacket, String msg) {
|
||||||
Object packet;
|
sendJson(receivingPacket, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', JSONObject.escape(msg)) + "\"}", 2);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,7 +206,7 @@ public class C {
|
|||||||
* 需要显示的时间
|
* 需要显示的时间
|
||||||
*/
|
*/
|
||||||
public static void send(final org.bukkit.entity.Player receivingPacket, final String msg, final int times) {
|
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
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int time = times;
|
int time = times;
|
||||||
@ -192,13 +214,12 @@ public class C {
|
|||||||
send(receivingPacket, msg);
|
send(receivingPacket, msg);
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException ignored) {
|
||||||
// Ignore
|
|
||||||
}
|
}
|
||||||
time--;
|
time--;
|
||||||
} while (time > 0);
|
} while (time > 0);
|
||||||
}
|
}
|
||||||
}).start();
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +247,7 @@ public class C {
|
|||||||
}
|
}
|
||||||
// getOnlinePlayers end
|
// getOnlinePlayers end
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.warning(Player.class.getSimpleName() + "兼容性工具初始化失败 可能造成部分功能不可用!");
|
Log.warning("Player 兼容性工具初始化失败 可能造成部分功能不可用!");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// getOfflinePlayer start
|
// getOfflinePlayer start
|
||||||
@ -285,6 +306,21 @@ public class C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Title {
|
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() {
|
private Title() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +389,7 @@ public class C {
|
|||||||
Object player = getHandle.invoke(recoverPlayer);
|
Object player = getHandle.invoke(recoverPlayer);
|
||||||
Object connection = playerConnection.get(player);
|
Object connection = playerConnection.get(player);
|
||||||
Object[] actions = packetActions.getEnumConstants();
|
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);
|
sendPacket.invoke(connection, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,21 +435,17 @@ public class C {
|
|||||||
Object packet;
|
Object packet;
|
||||||
// Send if set
|
// Send if set
|
||||||
if ((fadeInTime != -1) && (fadeOutTime != -1) && (stayTime != -1)) {
|
if ((fadeInTime != -1) && (fadeOutTime != -1) && (stayTime != -1)) {
|
||||||
packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent, Integer.TYPE, Integer.TYPE, Integer.TYPE).newInstance(actions[2],
|
packet = packetTitleSendConstructor.newInstance(actions[2], null, fadeInTime * 20, stayTime * 20, fadeOutTime * 20);
|
||||||
null,
|
|
||||||
fadeInTime * 20,
|
|
||||||
stayTime * 20,
|
|
||||||
fadeOutTime * 20);
|
|
||||||
sendPacket.invoke(connection, packet);
|
sendPacket.invoke(connection, packet);
|
||||||
}
|
}
|
||||||
// Send title
|
// Send title
|
||||||
Object serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', title) + "\"}");
|
Object serialized = chatSerializer.invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', title) + "\"}");
|
||||||
packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent).newInstance(actions[0], serialized);
|
packet = packetTitleSendConstructor.newInstance(actions[0], serialized);
|
||||||
sendPacket.invoke(connection, packet);
|
sendPacket.invoke(connection, packet);
|
||||||
if (!"".equals(subtitle)) {
|
if (!"".equals(subtitle)) {
|
||||||
// Send subtitle if present
|
// Send subtitle if present
|
||||||
serialized = nmsChatSerializer.getMethod("a", String.class).invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\"}");
|
serialized = chatSerializer.invoke(null, "{\"text\":\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\"}");
|
||||||
packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent).newInstance(actions[1], serialized);
|
packet = packetTitleSendConstructor.newInstance(actions[1], serialized);
|
||||||
sendPacket.invoke(connection, packet);
|
sendPacket.invoke(connection, packet);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -20,7 +20,7 @@ import pw.yumc.YumCore.bukkit.Log;
|
|||||||
* @author 喵♂呜
|
* @author 喵♂呜
|
||||||
*/
|
*/
|
||||||
public abstract class ItemSerialize {
|
public abstract class ItemSerialize {
|
||||||
static ItemSerialize itemSerialize = new Manual();
|
static ItemSerialize itemSerialize;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
itemSerialize = new Automatic();
|
itemSerialize = new Automatic();
|
||||||
|
@ -21,15 +21,18 @@ import pw.yumc.YumCore.bukkit.compatible.C;
|
|||||||
*/
|
*/
|
||||||
public class Tellraw implements Cloneable {
|
public class Tellraw implements Cloneable {
|
||||||
private List<MessagePart> messageParts = new ArrayList<>();
|
private List<MessagePart> messageParts = new ArrayList<>();
|
||||||
|
private String cache;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (Bukkit.getVersion().contains("Paper") || Bukkit.getVersion().contains("Torch")) {
|
if (Bukkit.getVersion().contains("Paper") || Bukkit.getVersion().contains("Torch")) {
|
||||||
Log.console("§c========== §4警 告 §c==========");
|
if (!C.init) {
|
||||||
Log.console("§a 当前服务器为 §6Paper §a或 §6Torch ");
|
Log.console("§c========== §4警 告 §c==========");
|
||||||
Log.console("§c 异步命令会刷报错 §b不影响使用");
|
Log.console("§a 当前服务器为 §6Paper §a或 §6Torch ");
|
||||||
Log.console("§d 如果介意请使用原版 Spigot");
|
Log.console("§c 异步命令会刷报错 §b不影响使用");
|
||||||
Log.console("§e YUMC构建站: http://ci.yumc.pw/job/Spigot/");
|
Log.console("§d 如果介意请使用原版 Spigot");
|
||||||
Log.console("§c===========================");
|
Log.console("§e YUMC构建站: http://ci.yumc.pw/job/Spigot/");
|
||||||
|
Log.console("§c===========================");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +175,11 @@ public class Tellraw implements Cloneable {
|
|||||||
public void send(final CommandSender sender) {
|
public void send(final CommandSender sender) {
|
||||||
final String json = toJsonString();
|
final String json = toJsonString();
|
||||||
if (sender instanceof Player && json.getBytes().length < 32000) {
|
if (sender instanceof Player && json.getBytes().length < 32000) {
|
||||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + json);
|
if (C.init) {
|
||||||
|
C.sendJson((Player) sender, json, 0);
|
||||||
|
} else {
|
||||||
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender.getName() + " " + json);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sender.sendMessage(toOldMessageFormat());
|
sender.sendMessage(toOldMessageFormat());
|
||||||
}
|
}
|
||||||
@ -231,7 +238,7 @@ public class Tellraw implements Cloneable {
|
|||||||
* @param name
|
* @param name
|
||||||
* 物品名称
|
* 物品名称
|
||||||
* @param item
|
* @param item
|
||||||
* {@link ItemStack}
|
* {@link ItemStack};
|
||||||
* @return {@link Tellraw}
|
* @return {@link Tellraw}
|
||||||
*/
|
*/
|
||||||
public Tellraw then(String name, ItemStack item) {
|
public Tellraw then(String name, ItemStack item) {
|
||||||
@ -295,15 +302,18 @@ public class Tellraw implements Cloneable {
|
|||||||
* @return Json串
|
* @return Json串
|
||||||
*/
|
*/
|
||||||
public String toJsonString() {
|
public String toJsonString() {
|
||||||
StringBuilder msg = new StringBuilder();
|
if (cache == null) {
|
||||||
msg.append("[\"\"");
|
StringBuilder msg = new StringBuilder();
|
||||||
for (MessagePart messagePart : messageParts) {
|
msg.append("[\"\"");
|
||||||
msg.append(",");
|
for (MessagePart messagePart : messageParts) {
|
||||||
messagePart.writeJson(msg);
|
msg.append(",");
|
||||||
|
messagePart.writeJson(msg);
|
||||||
|
}
|
||||||
|
msg.append("]");
|
||||||
|
cache = msg.toString();
|
||||||
|
Log.d(cache);
|
||||||
}
|
}
|
||||||
msg.append("]");
|
return cache;
|
||||||
Log.debug(msg.toString());
|
|
||||||
return msg.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tellraw setMessageParts(List<MessagePart> messageParts) {
|
public Tellraw setMessageParts(List<MessagePart> messageParts) {
|
||||||
@ -395,6 +405,7 @@ public class Tellraw implements Cloneable {
|
|||||||
} else {
|
} else {
|
||||||
messageParts.add(part);
|
messageParts.add(part);
|
||||||
}
|
}
|
||||||
|
cache = null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user