diff --git a/pom.xml b/pom.xml
index 8402a09..fb69517 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,37 +7,6 @@
1.9.7
${project.artifactId}
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.4
-
-
- package
-
- jar-no-fork
-
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.10.3
-
- false
-
-
-
- attach-javadocs
-
- jar
-
-
-
-
-
Jenkins
diff --git a/src/main/java/pw/yumc/YumCore/bukkit/compatible/C.java b/src/main/java/pw/yumc/YumCore/bukkit/compatible/C.java
index 4b2ca6f..b05426b 100644
--- a/src/main/java/pw/yumc/YumCore/bukkit/compatible/C.java
+++ b/src/main/java/pw/yumc/YumCore/bukkit/compatible/C.java
@@ -23,67 +23,54 @@ import java.util.UUID;
*/
public class C {
public static boolean init;
- private static boolean above_1_16 = false;
private static Class> nmsIChatBaseComponent;
private static Constructor> packetTypeConstructor;
private static Method chatSerializer;
private static Method getHandle;
- private static Method nmsChatMessageTypeClassValueOf;
private static String version;
private static boolean newversion;
private static Field playerConnection;
private static Method sendPacket;
- private static Object[] chatMessageTypes;
static {
try {
- version = getNMSVersion();
- Integer subVersion = Integer.parseInt(version.split("_")[1]);
- newversion = subVersion > 7;
- Class> nmsChatSerializer = subVersion < 17 ?
- Class.forName(a(newversion ? "IChatBaseComponent$ChatSerializer" : "ChatSerializer")) :
- Class.forName("net.minecraft.network.chat.IChatBaseComponent$ChatSerializer");
- chatSerializer = nmsChatSerializer.getMethod("a", String.class);
- nmsIChatBaseComponent = subVersion < 17 ?
- Class.forName(a("IChatBaseComponent")) :
- Class.forName("net.minecraft.network.chat.IChatBaseComponent");
- Class> packetType = subVersion < 17 ?
- Class.forName(a("PacketPlayOutChat")) :
- Class.forName("net.minecraft.network.protocol.game.PacketPlayOutChat");
- Arrays.stream(packetType.getConstructors()).forEach(c -> {
- if (c.getParameterTypes().length == 2) {
- packetTypeConstructor = c;
+ try {
+ version = getNMSVersion();
+ Integer subVersion = Integer.parseInt(version.split("_")[1]);
+ newversion = subVersion > 7;
+ Class> nmsChatSerializer = subVersion < 17 ?
+ Class.forName(a(newversion ? "IChatBaseComponent$ChatSerializer" : "ChatSerializer")) :
+ Class.forName("net.minecraft.network.chat.IChatBaseComponent$ChatSerializer");
+ chatSerializer = nmsChatSerializer.getMethod("a", String.class);
+ nmsIChatBaseComponent = subVersion < 17 ?
+ Class.forName(a("IChatBaseComponent")) :
+ Class.forName("net.minecraft.network.chat.IChatBaseComponent");
+ Class> packetType = subVersion < 17 ?
+ Class.forName(a("PacketPlayOutChat")) :
+ Class.forName("net.minecraft.network.protocol.game.PacketPlayOutChat");
+ Arrays.stream(packetType.getConstructors()).forEach(c -> {
+ if (c.getParameterTypes().length == 2) {
+ packetTypeConstructor = c;
+ }
+ if (c.getParameterTypes().length == 3) {
+ packetTypeConstructor = c;
+ }
+ });
+ Class> typeCraftPlayer = Class.forName(b("entity.CraftPlayer"));
+ Class> typeNMSPlayer = subVersion < 17 ? Class.forName(a("EntityPlayer")) : Class.forName("net.minecraft.server.level.EntityPlayer");
+ Class> typePlayerConnection = subVersion < 17 ? Class.forName(a("PlayerConnection")) : Class.forName("net.minecraft.server.network.PlayerConnection");
+ getHandle = typeCraftPlayer.getMethod("getHandle");
+ playerConnection = subVersion < 17 ? typeNMSPlayer.getField("playerConnection") : typeNMSPlayer.getField("b");
+ if (subVersion < 17) {
+ sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(a("Packet")));
+ } else if (subVersion == 17) {
+ sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName("net.minecraft.network.protocol.Packet"));
+ } else {
+ sendPacket = typePlayerConnection.getMethod("a", Class.forName("net.minecraft.network.protocol.Packet"));
}
- if (c.getParameterTypes().length == 3) {
- packetTypeConstructor = c;
- above_1_16 = true;
- }
- });
- Class> nmsChatMessageTypeClass = packetTypeConstructor.getParameterTypes()[1];
- if (nmsChatMessageTypeClass.isEnum()) {
- chatMessageTypes = nmsChatMessageTypeClass.getEnumConstants();
- } else {
- switch (nmsChatMessageTypeClass.getName()) {
- case "int":
- nmsChatMessageTypeClass = Integer.class;
- break;
- case "byte":
- nmsChatMessageTypeClass = Byte.class;
- break;
- }
- nmsChatMessageTypeClassValueOf = nmsChatMessageTypeClass.getDeclaredMethod("valueOf", String.class);
- }
- Class> typeCraftPlayer = Class.forName(b("entity.CraftPlayer"));
- Class> typeNMSPlayer = subVersion < 17 ? Class.forName(a("EntityPlayer")) : Class.forName("net.minecraft.server.level.EntityPlayer");
- Class> typePlayerConnection = subVersion < 17 ? Class.forName(a("PlayerConnection")) : Class.forName("net.minecraft.server.network.PlayerConnection");
- getHandle = typeCraftPlayer.getMethod("getHandle");
- playerConnection = subVersion < 17 ? typeNMSPlayer.getField("playerConnection") : typeNMSPlayer.getField("b");
- if (subVersion < 17) {
- sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(a("Packet")));
- } else if (subVersion == 17) {
- sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName("net.minecraft.network.protocol.Packet"));
- } else {
- sendPacket = typePlayerConnection.getMethod("a", Class.forName("net.minecraft.network.protocol.Packet"));
+ } catch (Exception ex) {
+ Log.d(ex);
+ Chat.getBukkitChatInvoke();
}
init = true;
} catch (Exception e) {
@@ -122,17 +109,7 @@ public class C {
* 2. ActionBar
*/
public static void sendJson(org.bukkit.entity.Player receivingPacket, String json, int type) {
- try {
- Object serialized = chatSerializer.invoke(null, json);
- Object player = getHandle.invoke(receivingPacket);
- Object connection = playerConnection.get(player);
- Object typeObj = chatMessageTypes == null ? nmsChatMessageTypeClassValueOf.invoke(null, String.valueOf(type)) : chatMessageTypes[type];
- sendPacket.invoke(connection, above_1_16
- ? packetTypeConstructor.newInstance(serialized, typeObj, receivingPacket.getUniqueId())
- : packetTypeConstructor.newInstance(serialized, typeObj));
- } catch (Exception ex) {
- Log.d("Json发包错误 " + version, ex);
- }
+ Chat.getBukkitChatInvoke().send(receivingPacket, json, type);
}
public static class ActionBar {
diff --git a/src/main/java/pw/yumc/YumCore/bukkit/compatible/Chat.java b/src/main/java/pw/yumc/YumCore/bukkit/compatible/Chat.java
new file mode 100644
index 0000000..f818391
--- /dev/null
+++ b/src/main/java/pw/yumc/YumCore/bukkit/compatible/Chat.java
@@ -0,0 +1,272 @@
+package pw.yumc.YumCore.bukkit.compatible;
+
+import lombok.SneakyThrows;
+import net.md_5.bungee.api.chat.BaseComponent;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Player;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class Chat {
+ private static final String version;
+ private static final BukkitChatInvoke bukkitChatInvoke;
+
+ static {
+ version = getNMSVersion();
+ int subVersion = Integer.parseInt(version.split("_")[1]);
+ if (subVersion >= 19) {
+ bukkitChatInvoke = new BukkitChatInvoke_1_19();
+ } else if (subVersion >= 17) {
+ bukkitChatInvoke = new BukkitChatInvoke_1_17_1();
+ } else if (subVersion >= 16) {
+ bukkitChatInvoke = new BukkitChatInvoke_1_16_5();
+ } else if (subVersion >= 8) {
+ bukkitChatInvoke = new BukkitChatInvoke_1_8();
+ } else {
+ bukkitChatInvoke = new BukkitChatInvoke_1_7_10();
+ }
+ bukkitChatInvoke.init();
+ }
+
+ public static BukkitChatInvoke getBukkitChatInvoke() {
+ return bukkitChatInvoke;
+ }
+
+ /**
+ * 获得NMS版本号
+ *
+ * @return NMS版本号
+ */
+ public static String getNMSVersion() {
+ return Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
+ }
+
+ public static Class> nmsCls(String str) throws ClassNotFoundException {
+ return Class.forName("net.minecraft.server." + version + "." + str);
+ }
+
+ public static Class> obcCls(String str) throws ClassNotFoundException {
+ return Class.forName("org.bukkit.craftbukkit." + version + "." + str);
+ }
+
+ public static abstract class BukkitChatInvoke {
+ protected boolean downgrade = false;
+
+ protected Method chatSerializer;
+ protected Constructor> packetTypeConstructor;
+ protected Method getHandle;
+ protected Field playerConnection;
+ protected Method sendPacket;
+ protected Object[] chatMessageTypes;
+
+ protected Method componentSerializer;
+
+ BukkitChatInvoke() {
+ init();
+ }
+
+ public void init() {
+ try {
+ Class> nmsChatSerializerClass = this.getNmsChatSerializerClass();
+ this.chatSerializer = this.getNmsChatSerializerMethod(nmsChatSerializerClass);
+ Constructor>[] constructors = this.getPacketPlayOutChatClass().getConstructors();
+ for (Constructor> constructor : constructors) {
+ if (constructor.getParameterCount() == 2 || constructor.getParameterCount() == 3) {
+ this.packetTypeConstructor = constructor;
+ if (this.isMatchPacketPlayOutChatClassConstructor(constructor)) {
+ break;
+ }
+ }
+ }
+ this.getHandle = this.getGetHandleMethod();
+ this.playerConnection = this.getPlayerConnectionField(this.getHandle.getReturnType());
+ this.sendPacket = this.getSendPacketMethod(this.playerConnection.getType(), this.getPacketClass());
+ } catch (Throwable ex) {
+ this.downgrade = true;
+ try {
+ this.componentSerializer = Class.forName("net.md_5.bungee.chat.ComponentSerializer").getMethod("parse", String.class);
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @SneakyThrows
+ void json(Player receivingPacket, String json) {
+ if (this.downgrade) {
+ receivingPacket.spigot().sendMessage((BaseComponent[]) this.componentSerializer.invoke(null, json));
+ } else {
+ this.send(receivingPacket, json, 0);
+ }
+ }
+
+ @SneakyThrows
+ void send(Player receivingPacket, String json, int type) {
+ this.sendPacket(receivingPacket, this.getPacketPlayOutChat(receivingPacket, json, type));
+ }
+
+ @SneakyThrows
+ void sendPacket(Player receivingPacket, Object packet) {
+ this.sendPacket.invoke(playerConnection.get(getHandle.invoke(receivingPacket)), packet);
+ }
+
+ abstract boolean isMatchPacketPlayOutChatClassConstructor(Constructor> constructor);
+
+ abstract Class> getNmsChatSerializerClass();
+
+ abstract Method getNmsChatSerializerMethod(Class> nmsChatSerializerClass);
+
+ abstract Class> getPacketPlayOutChatClass();
+
+ abstract Field getPlayerConnectionField(Class> nmsEntityPlayerClass);
+
+ abstract Method getGetHandleMethod();
+
+ abstract Class> getPacketClass();
+
+ abstract Method getSendPacketMethod(Class> playerConnectionClass, Class> packetClass);
+
+ abstract Object getPacketPlayOutChat(Player player, String json, int type);
+ }
+
+ public static class BukkitChatInvokeBase extends BukkitChatInvoke {
+ @Override
+ protected boolean isMatchPacketPlayOutChatClassConstructor(Constructor> constructor) {
+ Class>[] types = constructor.getParameterTypes();
+ if (types[1].isEnum()) {
+ this.chatMessageTypes = types[1].getEnumConstants();
+ return true;
+ }
+ return types[1].getName().equals("int");
+ }
+
+ @Override
+ @SneakyThrows
+ Class> getNmsChatSerializerClass() {
+ return nmsCls("ChatSerializer");
+ }
+
+ @Override
+ @SneakyThrows
+ Method getNmsChatSerializerMethod(Class> nmsChatSerializerClass) {
+ return nmsChatSerializerClass.getMethod("a", String.class);
+ }
+
+ @Override
+ @SneakyThrows
+ Class> getPacketPlayOutChatClass() {
+ return nmsCls("PacketPlayOutChat");
+ }
+
+ @Override
+ @SneakyThrows
+ Field getPlayerConnectionField(Class> nmsEntityPlayerClass) {
+ return nmsEntityPlayerClass.getField("playerConnection");
+ }
+
+ @Override
+ @SneakyThrows
+ Method getGetHandleMethod() {
+ return obcCls("entity.CraftPlayer").getMethod("getHandle");
+ }
+
+ @Override
+ @SneakyThrows
+ Class> getPacketClass() {
+ return nmsCls("Packet");
+ }
+
+ @Override
+ @SneakyThrows
+ Method getSendPacketMethod(Class> playerConnectionClass, Class> packetClass) {
+ return playerConnectionClass.getMethod("sendPacket", packetClass);
+ }
+
+ @Override
+ @SneakyThrows
+ Object getPacketPlayOutChat(Player player, String json, int type) {
+ return packetTypeConstructor.newInstance(this.chatSerializer.invoke(null, json), type);
+ }
+ }
+
+ public static class BukkitChatInvoke_1_7_10 extends BukkitChatInvokeBase {
+
+ }
+
+ public static class BukkitChatInvoke_1_8 extends BukkitChatInvoke_1_7_10 {
+ @Override
+ @SneakyThrows
+ Object getPacketPlayOutChat(Player player, String json, int type) {
+ return packetTypeConstructor.newInstance(this.chatSerializer.invoke(null, json), this.chatMessageTypes[type]);
+ }
+
+ @Override
+ @SneakyThrows
+ Class> getNmsChatSerializerClass() {
+ return nmsCls("IChatBaseComponent$ChatSerializer");
+ }
+ }
+
+ public static class BukkitChatInvoke_1_16_5 extends BukkitChatInvoke_1_8 {
+ @Override
+ @SneakyThrows
+ Object getPacketPlayOutChat(Player player, String json, int type) {
+ return packetTypeConstructor.newInstance(this.chatSerializer.invoke(null, json), this.chatMessageTypes[type], player.getUniqueId());
+ }
+ }
+
+ public static class BukkitChatInvoke_1_17_1 extends BukkitChatInvoke_1_16_5 {
+ @Override
+ @SneakyThrows
+ Class> getPacketPlayOutChatClass() {
+ return Class.forName("net.minecraft.network.protocol.game.PacketPlayOutChat");
+ }
+
+ @Override
+ @SneakyThrows
+ Class> getNmsChatSerializerClass() {
+ return Class.forName("net.minecraft.network.chat.IChatBaseComponent$ChatSerializer");
+ }
+
+ @Override
+ @SneakyThrows
+ Field getPlayerConnectionField(Class> nmsEntityPlayerClass) {
+ return nmsEntityPlayerClass.getField("b");
+ }
+
+ @Override
+ @SneakyThrows
+ Class> getPacketClass() {
+ return Class.forName("net.minecraft.network.protocol.Packet");
+ }
+ }
+
+ public static class BukkitChatInvoke_1_19 extends BukkitChatInvoke_1_17_1 {
+ @Override
+ protected boolean isMatchPacketPlayOutChatClassConstructor(Constructor> constructor) {
+ Class>[] types = constructor.getParameterTypes();
+ return types[0] == String.class && types[1] == int.class;
+ }
+
+ @Override
+ @SneakyThrows
+ Method getSendPacketMethod(Class> playerConnectionClass, Class> packetClass) {
+ return playerConnectionClass.getMethod("a", packetClass);
+ }
+
+ @Override
+ @SneakyThrows
+ Class> getPacketPlayOutChatClass() {
+ return Class.forName("net.minecraft.network.protocol.game.ClientboundSystemChatPacket");
+ }
+
+ @Override
+ @SneakyThrows
+ Object getPacketPlayOutChat(Player player, String json, int type) {
+ Object component = this.chatSerializer.invoke(null, json);
+ return this.packetTypeConstructor.newInstance(component, type == 0 ? 1 : type);
+ }
+ }
+}
diff --git a/src/main/java/pw/yumc/YumCore/update/SubscribeTask.java b/src/main/java/pw/yumc/YumCore/update/SubscribeTask.java
index 72138c1..437e0b1 100644
--- a/src/main/java/pw/yumc/YumCore/update/SubscribeTask.java
+++ b/src/main/java/pw/yumc/YumCore/update/SubscribeTask.java
@@ -108,7 +108,7 @@ public class SubscribeTask implements Runnable, Listener {
@EventHandler
public void onJoin(PlayerJoinEvent e) {
final Player player = e.getPlayer();
- if (player.isOp() && updateFile.isUpdated()) {
+ if (player.isOp() && versionInfo.hasNewVersion() && updateFile.isUpdated()) {
Bukkit.getScheduler().runTaskLater(instance, () -> versionInfo.notify(player), 10);
}
}
@@ -255,10 +255,13 @@ public class SubscribeTask implements Runnable, Listener {
*/
private Document document;
+ private boolean hasNewVersion;
+
public VersionInfo(Plugin plugin, String branch, boolean isSecret) {
this.name = plugin.getName();
this.version = plugin.getDescription().getVersion().split("-")[0];
this.info = String.format(isSecret ? pom : url, name, branch);
+ this.hasNewVersion = false;
}
/**
@@ -372,7 +375,10 @@ public class SubscribeTask implements Runnable, Listener {
Log.console("§4注意: §c当前版本为开发版本 且未开启全局调试 已自动下载最新稳定版!");
return result;
}
- if (needUpdate(result, version)) {return result;}
+ if (needUpdate(result, version)) {
+ this.hasNewVersion = true;
+ return result;
+ }
} catch (Exception e) {
Log.d(e);
}
@@ -382,5 +388,9 @@ public class SubscribeTask implements Runnable, Listener {
public void update() throws ParserConfigurationException, IOException, SAXException {
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(info);
}
+
+ public boolean hasNewVersion() {
+ return hasNewVersion;
+ }
}
}