1
0
mirror of https://e.coding.net/circlecloud/YumCore.git synced 2024-12-25 07:08:52 +00:00

feat: 添加ActionBar和Title管理

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
502647092 2016-08-08 20:39:35 +08:00
parent f29ccdf4a7
commit a55c89c231

View File

@ -1,14 +1,19 @@
package pw.yumc.YumCore.bukkit.compatible;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;
import java.util.logging.Level;
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;
@ -21,6 +26,167 @@ import pw.yumc.YumCore.bukkit.Log;
* @author
*/
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 getHandle;
private static String version;
private static Field playerConnection;
private static Method sendPacket;
static {
try {
version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
final boolean newversion = Integer.parseInt(version.split("_")[1]) > 7;
nmsChatSerializer = Class.forName(a(newversion ? "ChatSerializer" : "IChatBaseComponent$ChatSerializer"));
nmsIChatBaseComponent = Class.forName(a("IChatBaseComponent"));
packetType = Class.forName(a("PacketPlayOutChat"));
packetActions = Class.forName(a(newversion ? "EnumTitleAction" : "PacketPlayOutTitle$EnumTitleAction"));
packetTitle = Class.forName(a("PacketPlayOutTitle"));
final Class<?> typeCraftPlayer = Class.forName(a("CraftPlayer"));
final Class<?> typeNMSPlayer = Class.forName(a("EntityPlayer"));
final Class<?> typePlayerConnection = Class.forName(a("PlayerConnection"));
getHandle = typeCraftPlayer.getMethod("getHandle");
playerConnection = typeNMSPlayer.getField("playerConnection");
sendPacket = typePlayerConnection.getMethod("sendPacket", Class.forName(a("Packet")));
} catch (final Exception e) {
Log.warning(Player.class.getSimpleName() + "兼容性工具初始化失败 可能造成部分功能不可用!");
}
}
public static String a(final String str) {
return "net.minecraft.server." + version + "." + str;
}
public static class ActionBar {
/**
* 公告发送ActionBar
*
* @param message
* 需要发送的消息
*/
public static void broadcast(final String message) {
for (final org.bukkit.entity.Player player : C.Player.getOnlinePlayers()) {
send(player, message);
}
}
/**
* 公告发送ActionBar
*
* @param message
* 需要发送的消息
* @param times
* 需要显示的时间
*/
public static void broadcast(final String message, final int times) {
new Thread(new Runnable() {
@Override
public void run() {
int time = times;
do {
for (final org.bukkit.entity.Player player : C.Player.getOnlinePlayers()) {
send(player, message);
}
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
}
time--;
} while (time > 0);
}
}).start();
}
/**
* 公告发送ActionBar(分世界)
*
* @param world
* 需要发送的世界
* @param message
* 需要发送的消息
* @param times
* 需要显示的时间
*/
public static void broadcast(final World world, final String message, final int times) {
new Thread(new Runnable() {
@Override
public void run() {
int time = times;
do {
for (final org.bukkit.entity.Player player : C.Player.getOnlinePlayers()) {
if (player.getWorld().getName().equalsIgnoreCase(world.getName())) {
send(player, message);
}
}
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
}
time--;
} while (time > 0);
}
}).start();;
}
/**
* 给玩家发送ActionBar消息
*
* @param receivingPacket
* 接受信息的玩家
* @param msg
* ActionBar信息
*/
public static void send(final org.bukkit.entity.Player receivingPacket, final String msg) {
Object packet = null;
try {
final 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);
}
final Object player = getHandle.invoke(receivingPacket);
final Object connection = playerConnection.get(player);
sendPacket.invoke(connection, packet);
} catch (final Exception ex) {
Log.log(Level.SEVERE, "ActionBar发包错误 %s " + version, ex);
}
}
/**
* 给玩家发送ActionBar消息
*
* @param receivingPacket
* 接受信息的玩家
* @param msg
* 需要发送的消息
* @param times
* 需要显示的时间
*/
public static void send(final org.bukkit.entity.Player receivingPacket, final String msg, final int times) {
new Thread(new Runnable() {
@Override
public void run() {
int time = times;
do {
send(receivingPacket, msg);
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {
}
time--;
} while (time > 0);
}
}).start();
}
}
/**
* Bukkit Player兼容类
*
@ -97,4 +263,84 @@ public class C {
}
}
}
public static class Title {
/**
* 重置玩家的Title
*
* @param recoverPlayer
* 接受的玩家
* @throws Exception
* 异常
*/
public static void reset(final Player recoverPlayer) throws Exception {
// Send timings first
final Object player = getHandle.invoke(recoverPlayer);
final Object connection = playerConnection.get(player);
final Object[] actions = packetActions.getEnumConstants();
final Object packet = packetTitle.getConstructor(packetActions, nmsIChatBaseComponent).newInstance(actions[4], null);
sendPacket.invoke(connection, packet);
}
/**
* 发送Titile(默认时间 1 2 1)
*
* @param receivingPacket
* 接受信息的玩家
* @param title
* 标题
* @param subtitle
* 子标题
*/
public static void send(final Player receivingPacket, final String title, final String subtitle) {
send(receivingPacket, title, subtitle, 1, 2, 1);
}
/**
* 发送Titile
*
* @param receivingPacket
* 接受信息的玩家
* @param title
* 标题
* @param subtitle
* 子标题
* @param fadeInTime
* 淡入时间
* @param stayTime
* 持续时间
* @param fadeOutTime
* 淡出时间
*/
public static void send(final Player receivingPacket, final String title, final String subtitle, final int fadeInTime, final int stayTime, final int fadeOutTime) {
if (packetTitle != null) {
try {
// First reset previous settings
reset(receivingPacket);
// Send timings first
final Object player = getHandle.invoke(receivingPacket);
final Object connection = playerConnection.get(player);
final Object[] actions = packetActions.getEnumConstants();
Object packet = null;
// 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);
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);
sendPacket.invoke(connection, packet);
if (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);
sendPacket.invoke(connection, packet);
}
} catch (final Throwable e) {
e.printStackTrace();
}
}
}
}
}