package plus.crates.Utils; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; import plus.crates.CratesPlus; import plus.crates.Events.PlayerInputEvent; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class SignInputHandler { private static Field channelField; static { try { channelField = ReflectionUtil.getNMSClass("NetworkManager").getDeclaredField("channel"); } catch (NoSuchFieldException e) { e.printStackTrace(); } } public static void injectNetty(final Player player) { try { Object handle = player.getClass().getMethod("getHandle").invoke(player); Object playerConnection = handle.getClass().getField("playerConnection").get(handle); final Channel channel = (Channel) channelField.get(playerConnection.getClass().getField("networkManager").get(playerConnection)); if (channel != null) { channel.pipeline().addAfter("decoder", "update_sign", new MessageToMessageDecoder<Object>() { @Override protected void decode(ChannelHandlerContext channelHandlerContext, Object object, List list) throws Exception { try { if (object.toString().contains("PacketPlayInUpdateSign")) { Class iChatBaseComponentClass = ReflectionUtil.getNMSClass("IChatBaseComponent"); Object packet = ReflectionUtil.getNMSClass("PacketPlayInUpdateSign").cast(object); Method method = null; try { method = packet.getClass().getMethod("c"); } catch (Exception e) { // Ignore it, this is mostly for 1.13+ support } if (method == null) { method = packet.getClass().getMethod("b"); } ArrayList<String> lines = new ArrayList<>(); Object response = method.invoke(packet); Object[] signLines = (Object[]) response; for (Object line : signLines) { if (line instanceof String) { lines.add((String) line); } else if (iChatBaseComponentClass != null && iChatBaseComponentClass.isAssignableFrom(line.getClass())) { lines.add((String) iChatBaseComponentClass.getMethod("getText").invoke(iChatBaseComponentClass.cast(line))); } } if (lines.isEmpty()) { player.sendMessage(ChatColor.RED + "Unable to handle input"); } else { Bukkit.getScheduler().runTask(JavaPlugin.getPlugin(CratesPlus.class), () -> Bukkit.getPluginManager().callEvent(new PlayerInputEvent(player, lines))); } } list.add(object); } catch (Exception e) { e.printStackTrace(); } } }); } } catch (Exception e) { e.printStackTrace(); } } public static void ejectNetty(Player player) { try { Object handle = player.getClass().getMethod("getHandle").invoke(player); Object playerConnection = handle.getClass().getField("playerConnection").get(handle); Channel channel = (Channel) channelField.get(playerConnection.getClass().getField("networkManager").get(playerConnection)); if (channel != null) { if (channel.pipeline().get("update_sign") != null) { channel.pipeline().remove("update_sign"); } } } catch (Exception e) { e.printStackTrace(); } } }