Use text-adapter-bukkit for sending Components to Bukkit objects

This commit is contained in:
Luck 2018-12-19 10:29:22 +00:00
parent 784161d66d
commit 6d8077ffd0
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
8 changed files with 23 additions and 198 deletions

View File

@ -13,6 +13,7 @@ dependencies {
compile project(':common') compile project(':common')
compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT' compileOnly 'org.spigotmc:spigot-api:1.13.2-R0.1-SNAPSHOT'
compileOnly'net.kyori:text-adapter-bukkit:1.0.0'
compileOnly 'me.lucko:commodore:1.0' compileOnly 'me.lucko:commodore:1.0'
compileOnly('net.milkbowl.vault:VaultAPI:1.6') { compileOnly('net.milkbowl.vault:VaultAPI:1.6') {
exclude(module: 'bukkit') exclude(module: 'bukkit')

View File

@ -26,16 +26,14 @@
package me.lucko.luckperms.bukkit; package me.lucko.luckperms.bukkit;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.bukkit.compat.BukkitJsonMessageHandler;
import me.lucko.luckperms.bukkit.compat.CraftBukkitUtil; import me.lucko.luckperms.bukkit.compat.CraftBukkitUtil;
import me.lucko.luckperms.bukkit.compat.SpigotJsonMessageHandler;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.sender.SenderFactory; import me.lucko.luckperms.common.sender.SenderFactory;
import me.lucko.luckperms.common.util.TextUtils; import me.lucko.luckperms.common.util.TextUtils;
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.serializer.ComponentSerializers; import net.kyori.text.adapter.bukkit.TextAdapter;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
@ -45,13 +43,9 @@ import org.bukkit.entity.Player;
import java.util.UUID; import java.util.UUID;
public class BukkitSenderFactory extends SenderFactory<CommandSender> { public class BukkitSenderFactory extends SenderFactory<CommandSender> {
private final BukkitJsonMessageHandler bukkitHandler;
private final SpigotJsonMessageHandler spigotHandler;
public BukkitSenderFactory(LuckPermsPlugin plugin) { public BukkitSenderFactory(LuckPermsPlugin plugin) {
super(plugin); super(plugin);
this.bukkitHandler = new BukkitJsonMessageHandler();
this.spigotHandler = isSpigot() ? new SpigotJsonMessageHandler() : null;
} }
@Override @Override
@ -85,23 +79,12 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
@Override @Override
protected void sendMessage(CommandSender sender, Component message) { protected void sendMessage(CommandSender sender, Component message) {
if (CraftBukkitUtil.isChatCompatible() && sender instanceof Player) { if (CraftBukkitUtil.isChatCompatible() && sender instanceof Player) {
Player player = (Player) sender; TextAdapter.sendComponent(sender, message);
String json = ComponentSerializers.JSON.serialize(message); } else {
// Try Bukkit.
if (this.bukkitHandler.sendJsonMessage(player, json)) {
return;
}
// Try Spigot.
if (this.spigotHandler != null && this.spigotHandler.sendJsonMessage(player, json)) {
return;
}
}
// Fallback to legacy format // Fallback to legacy format
sendMessage(sender, TextUtils.toLegacy(message)); sendMessage(sender, TextUtils.toLegacy(message));
} }
}
@Override @Override
protected Tristate getPermissionValue(CommandSender sender, String node) { protected Tristate getPermissionValue(CommandSender sender, String node) {
@ -116,15 +99,6 @@ public class BukkitSenderFactory extends SenderFactory<CommandSender> {
return sender.hasPermission(node); return sender.hasPermission(node);
} }
private static boolean isSpigot() {
try {
Class.forName("net.md_5.bungee.chat.ComponentSerializer");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
private static final class SyncMessengerAgent implements Runnable { private static final class SyncMessengerAgent implements Runnable {
private final CommandSender sender; private final CommandSender sender;
private final String message; private final String message;

View File

@ -123,7 +123,7 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
@Override @Override
protected Set<Dependency> getGlobalDependencies() { protected Set<Dependency> getGlobalDependencies() {
EnumSet<Dependency> dependencies = EnumSet.of(Dependency.TEXT, Dependency.CAFFEINE, Dependency.OKIO, Dependency.OKHTTP, Dependency.EVENT); EnumSet<Dependency> dependencies = EnumSet.of(Dependency.TEXT, Dependency.TEXT_ADAPTER_BUKKIT, Dependency.CAFFEINE, Dependency.OKIO, Dependency.OKHTTP, Dependency.EVENT);
if (isBrigadierSupported()) { if (isBrigadierSupported()) {
dependencies.add(Dependency.COMMODORE); dependencies.add(Dependency.COMMODORE);
} }

View File

@ -1,113 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.bukkit.compat;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class BukkitJsonMessageHandler {
private static boolean setup = false;
private static boolean triedAndFailed = false;
private static Method GET_HANDLE_METHOD;
private static Field PLAYER_CONNECTION_FIELD;
private static Method SEND_PACKET_METHOD;
private static Constructor<?> PACKET_CHAT_CONSTRUCTOR;
private static Method SERIALIZE_METHOD;
private static void setup(Object player) throws Exception {
Class<?> craftPlayerClass = player.getClass();
GET_HANDLE_METHOD = craftPlayerClass.getDeclaredMethod("getHandle");
Object handleObject = GET_HANDLE_METHOD.invoke(player);
Class<?> handleClass = handleObject.getClass();
PLAYER_CONNECTION_FIELD = handleClass.getDeclaredField("playerConnection");
Object playerConnectionObject = PLAYER_CONNECTION_FIELD.get(handleObject);
Method[] playerConnectionMethods = playerConnectionObject.getClass().getDeclaredMethods();
for (Method m : playerConnectionMethods) {
if (m.getName().equals("sendPacket")) {
SEND_PACKET_METHOD = m;
break;
}
}
Class<?> packetChatClass = CraftBukkitUtil.nmsClass("PacketPlayOutChat");
Constructor[] packetConstructors = packetChatClass.getDeclaredConstructors();
for (Constructor c : packetConstructors) {
Class<?>[] parameters = c.getParameterTypes();
if (parameters.length == 1 && parameters[0].getName().endsWith("IChatBaseComponent")) {
PACKET_CHAT_CONSTRUCTOR = c;
break;
}
}
Class<?> baseComponentClass = CraftBukkitUtil.nmsClass("IChatBaseComponent");
Class<?> chatSerializerClass;
if (baseComponentClass.getClasses().length > 0) {
chatSerializerClass = baseComponentClass.getClasses()[0];
} else {
// 1.7 class is here instead.
chatSerializerClass = CraftBukkitUtil.nmsClass("ChatSerializer");
}
SERIALIZE_METHOD = chatSerializerClass.getDeclaredMethod("a", String.class);
}
private static synchronized boolean trySetup(Object player) {
if (setup) return true;
if (triedAndFailed) return false;
try {
setup(player);
setup = true;
return true;
} catch (Throwable e) {
triedAndFailed = true;
return false;
}
}
public boolean sendJsonMessage(Player player, String json) {
if (!trySetup(player)) {
return false;
}
try {
Object connection = PLAYER_CONNECTION_FIELD.get(GET_HANDLE_METHOD.invoke(player));
SEND_PACKET_METHOD.invoke(connection, PACKET_CHAT_CONSTRUCTOR.newInstance(SERIALIZE_METHOD.invoke(null, json)));
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@ -28,10 +28,12 @@ package me.lucko.luckperms.bukkit.compat;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
public final class CraftBukkitUtil { public final class CraftBukkitUtil {
private static final String SERVER_VERSION = getServerVersion(); private CraftBukkitUtil() {}
private static final boolean CHAT_COMPATIBLE = !SERVER_VERSION.startsWith(".v1_7_");
private static String getServerVersion() { private static final String SERVER_PACKAGE_VERSION = getServerPackageVersion();
private static final boolean CHAT_COMPATIBLE = !SERVER_PACKAGE_VERSION.startsWith(".v1_7_");
private static String getServerPackageVersion() {
Class<?> server = Bukkit.getServer().getClass(); Class<?> server = Bukkit.getServer().getClass();
if (!server.getSimpleName().equals("CraftServer")) { if (!server.getSimpleName().equals("CraftServer")) {
return "."; return ".";
@ -50,7 +52,7 @@ public final class CraftBukkitUtil {
} }
public static String nms(String className) { public static String nms(String className) {
return "net.minecraft.server" + SERVER_VERSION + className; return "net.minecraft.server" + SERVER_PACKAGE_VERSION + className;
} }
public static Class<?> nmsClass(String className) throws ClassNotFoundException { public static Class<?> nmsClass(String className) throws ClassNotFoundException {
@ -58,13 +60,10 @@ public final class CraftBukkitUtil {
} }
public static String obc(String className) { public static String obc(String className) {
return "org.bukkit.craftbukkit" + SERVER_VERSION + className; return "org.bukkit.craftbukkit" + SERVER_PACKAGE_VERSION + className;
} }
public static Class<?> obcClass(String className) throws ClassNotFoundException { public static Class<?> obcClass(String className) throws ClassNotFoundException {
return Class.forName(obc(className)); return Class.forName(obc(className));
} }
private CraftBukkitUtil() {}
} }

View File

@ -1,43 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.bukkit.compat;
import net.md_5.bungee.chat.ComponentSerializer;
import org.bukkit.entity.Player;
public class SpigotJsonMessageHandler {
public boolean sendJsonMessage(Player player, String json) {
try {
player.spigot().sendMessage(ComponentSerializer.parse(json));
return true;
} catch (Exception e) {
return false;
}
}
}

View File

@ -14,8 +14,8 @@ dependencies {
compile 'com.google.code.gson:gson:2.7' compile 'com.google.code.gson:gson:2.7'
compile 'com.google.guava:guava:19.0' compile 'com.google.guava:guava:19.0'
compile 'com.github.ben-manes.caffeine:caffeine:2.6.2' compile 'com.github.ben-manes.caffeine:caffeine:2.6.2'
compile 'com.squareup.okhttp3:okhttp:3.11.0' compile 'com.squareup.okhttp3:okhttp:3.12.0'
compile 'com.squareup.okio:okio:1.15.0' compile 'com.squareup.okio:okio:1.16.0'
compile('me.lucko.configurate:configurate-core:3.5') { compile('me.lucko.configurate:configurate-core:3.5') {
exclude(module: 'guava') exclude(module: 'guava')
} }

View File

@ -66,6 +66,13 @@ public enum Dependency {
"V821j+n8AWhAvLhHjfXQ+/4284Gn4oXTYYfLkLjvs8o=", "V821j+n8AWhAvLhHjfXQ+/4284Gn4oXTYYfLkLjvs8o=",
Relocation.of("text", "net{}kyori{}text") Relocation.of("text", "net{}kyori{}text")
), ),
TEXT_ADAPTER_BUKKIT(
"net{}kyori",
"text-adapter-bukkit",
"1.0.0",
"V821j+n8AWhAvLhHjfXQ+/4284Gn4oXTYYfLkLjvs8o=",
Relocation.of("text", "net{}kyori{}text")
),
EVENT( EVENT(
"net{}kyori", "net{}kyori",
"event-api", "event-api",