Войти или зарегистрироваться
  • Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.

Копирование текста в буфер обмена

сделал пока так, надеюсь сработает:
PHP:
            if (isClassPresent("net.kyori.adventure.text.Component") && isClassPresent("net.kyori.adventure.platform.bukkit.BukkitAudiences")) {
                BukkitAudiences adventure = BukkitAudiences.create(plugin);
                Component message = Component.text(TextDecoration.UNDERLINED + "Click to copy")
                        .hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text("Private text")))
                        .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard("Private text"));
                adventure.sender(sender).sendMessage(message);
                return true;
            }else if (isClassPresent("net.md_5.bungee.api.chat.BaseComponent")) {
                TextComponent message = new TextComponent(TextDecoration.UNDERLINED + "Click to copy");
                message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Private text")));
                message.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, "Private text"));
                sender.spigot().sendMessage(message);
                return true;
            }else {
                sender.sendMessage("Private text");
                return true;
            }
 
Что-то мне подсказывает, что такая отправка сообщения возможно не будет работать "sender.sendMessage(message)" здесь "message" должно быть String, а преобразование в строку просто выведет всё как строку без добавленных ивентов
sendMessage() - это метод с кучей перегрузок. Так, например, в Paper класс CommandSender реализует интерфейс Audience. И в этом методе метод sendMessage() прекрасно принимает Component:
upload_2022-12-7_21-8-7.png
Так что всё будет работать.
Да и если бы оно не работало - ты бы узнал об этом от IDE, тебе бы просто не дало скомпилировать код, в котором ты передаёшь параметры неверного типа в метод.

Ты моешь прям в IDE посмотреть, какие есть варианты использования .sendMessage():
upload_2022-12-7_21-9-4.png
 
сделал пока так, надеюсь сработает:
PHP:
            if (isClassPresent("net.kyori.adventure.text.Component") && isClassPresent("net.kyori.adventure.platform.bukkit.BukkitAudiences")) {
                BukkitAudiences adventure = BukkitAudiences.create(plugin);
                Component message = Component.text(TextDecoration.UNDERLINED + "Click to copy")
                        .hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text("Private text")))
                        .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard("Private text"));
                adventure.sender(sender).sendMessage(message);
                return true;
            }else if (isClassPresent("net.md_5.bungee.api.chat.BaseComponent")) {
                TextComponent message = new TextComponent(TextDecoration.UNDERLINED + "Click to copy");
                message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("Private text")));
                message.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, "Private text"));
                sender.spigot().sendMessage(message);
                return true;
            }else {
                sender.sendMessage("Private text");
                return true;
            }
На всякий случай протестируй работу и на Paper, и на Spigot. Убедись, что выполняются корректные ветви условий. Потом можешь сделать отдельный метод для отправки сообщений и использовать его везде в своём плагине. Единственное - я бы рекомендовал закэшировать результат isClassPresent(), чтобы не генерировать новых исключений каждый раз при отправке сообщений
 
на Spigot исключение:
Код:
[16:03:43] [Server thread/ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'anh' in plugin AnhMine v0.0.1
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at org.bukkit.craftbukkit.v1_17_R1.CraftServer.dispatchCommand(CraftServer.java:790) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.network.PlayerConnection.handleCommand(PlayerConnection.java:1931) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1770) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:1751) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:46) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.network.protocol.game.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:30) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.TickTask.run(SourceFile:18) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.util.thread.IAsyncTaskHandler.executeTask(SourceFile:151) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.util.thread.IAsyncTaskHandler.executeNext(SourceFile:125) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.MinecraftServer.bf(MinecraftServer.java:1148) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.MinecraftServer.executeNext(MinecraftServer.java:1141) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.util.thread.IAsyncTaskHandler.awaitTasks(SourceFile:134) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.MinecraftServer.sleepForTick(MinecraftServer.java:1125) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1054) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:305) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at java.lang.Thread.run(Thread.java:833) [?:?]
Caused by: java.lang.NoClassDefFoundError: net/kyori/adventure/text/Component
        at ink.anh.anhmine.cmd.anh.CmdAnhydrite.onCommand(CmdAnhydrite.java:27) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        ... 19 more
Caused by: java.lang.ClassNotFoundException: net.kyori.adventure.text.Component
        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:147) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:99) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
        at ink.anh.anhmine.cmd.anh.CmdAnhydrite.onCommand(CmdAnhydrite.java:27) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        ... 19 more
 
Как это сделать?
Ну вынести в переменную класса это.
Для читабельности по желанию можно вообще инициализировать какой-нибудь MessagesFramework и проверять его при отправке сообщения:
PHP:
enum MessagesFramework {
    PLAIN_TEXT,
    ADVENTURE,
    MD_5
}
 
на Spigot исключение:
Код:
[16:03:43] [Server thread/ERROR]: null
org.bukkit.command.CommandException: Unhandled exception executing command 'anh' in plugin AnhMine v0.0.1
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[middle171.jar:3284a-Spigot-3892929-0ab8487]
.....
Эти исключения возникали ещё на этапе считывания импортов:
Код:
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
Чтобы их избежать вынес все действия в отдельные классы, 1:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

public class MessagePlainText {

    private static boolean allright;
  
    public static boolean message(Player player, String privateMessage) {
        player.sendMessage(privateMessage);
        allright = true;
        return allright;
    }
}
2:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;

public class MessageMD_5 {

    private static boolean allright;
  
    public static boolean message(Player player, String hoverMessage, String privateMessage, String copyText) {
        TextComponent message = new TextComponent(hoverMessage);
        message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(privateMessage)));
        message.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, copyText));
        player.spigot().sendMessage(message);
        allright = true;
        return allright;
    }
}
3:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

import ink.anh.anhmine.AnhMine;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;

public class MessageAdventure {

    private static boolean allright;
  
    public static boolean message(Player player, String hoverMessage, String privateMessage, String copyText) {
        BukkitAudiences adventure = BukkitAudiences.create(AnhMine.getInstance());

        Component message = Component.text(hoverMessage)
                .hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text(privateMessage)))
                .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard(copyText));
        adventure.sender(player).sendMessage(message);
        allright = true;
        return allright;
    }
}
и потому, что в Paper нет класса net.kyori.adventure.platform.bukkit.BukkitAudiences пришлось сделать 4-й:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

import ink.anh.anhmine.AnhMine;
import net.kyori.adventure.text.Component;

public class MessagePaper {

    private static boolean allright;
  
    public static boolean message(Player player, String hoverMessage, String privateMessage, String copyText) {

        Component message = Component.text(hoverMessage)
                .hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text(privateMessage)))
                .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard(copyText));
        player.sendMessage(message);
        allright = true;
        return allright;
    }
}
Соответственно и это:
PHP:
package ink.anh.anhmine.utils.chat;

public enum MessagesFramework {

    PLAIN_TEXT,
    ADVENTURE,
    PAPER,
    MD_5;
  
    public static MessagesFramework getFramework() {
        if (isClassPresent("net.kyori.adventure.text.Component") && isClassPresent("net.kyori.adventure.platform.bukkit.BukkitAudiences")) {
            return MessagesFramework.ADVENTURE;
        }else if (isClassPresent("net.kyori.adventure.text.Component")) {
            return MessagesFramework.PAPER;
        }else if (isClassPresent("net.md_5.bungee.api.chat.BaseComponent")) {
            return MessagesFramework.MD_5;
        }else {
            return MessagesFramework.PLAIN_TEXT;
        }
    }
  
    private static boolean isClassPresent(String className) {
        try {
            Class.forName(className);
            return true;
        } catch (NoClassDefFoundError | ClassNotFoundException e) {
            return false;
        }
    }
}
вызываются классы отсюда:

PHP:
            if (AnhMine.getMessFrame() == MessagesFramework.ADVENTURE) {
                return MessageAdventure.message(player, hoverMessage, privateMessage, copyText);
            }else if (AnhMine.getMessFrame() == MessagesFramework.PAPER) {
                return MessagePaper.message(player, hoverMessage, privateMessage, copyText);
            }else if (AnhMine.getMessFrame() == MessagesFramework.MD_5) {
                return MessageMD_5.message(player, hoverMessage, privateMessage, copyText);
            }else {
                return MessagePlainText.message(player,  privateMessage);
            }

Тестировал на Spigot и Paper. И вот тут мне нужно ещё разобраться как лучше сделать, ведь в Paper вылезло исключение:
Код:
java.lang.Error: Unresolved compilation problem:
        The method sendMessage(String) in the type CommandSender is not applicable for the arguments (Component)

        at ink.anh.anhmine.utils.chat.MessagePaper.message(MessagePaper.java:17) ~[AnhMine.jar:?]
        at ink.anh.anhmine.cmd.anh.CmdNewWallet.execCmdNewWalletRun(CmdNewWallet.java:141) ~[AnhMine.jar:?]
        at ink.anh.anhmine.cmd.anh.CmdNewWallet.lambda$0(CmdNewWallet.java:56) ~[AnhMine.jar:?]
        at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[patched_1.17.1.jar:git-Paper-411]                                                                                                                 
        at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57) ~[patched_1.17.1.jar:git-Paper-411]                                                                                                       
        at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[patched_1.17.1.jar:git-Paper-411]                                                                                       
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
метод sendMessage() прекрасно принимает Component
Нужно узнать способ как отправить sendMessage() игроку с поддержкой Audience?
 
Эти исключения возникали ещё на этапе считывания импортов:
Код:
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
Чтобы их избежать вынес все действия в отдельные классы, 1:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

public class MessagePlainText {

    private static boolean allright;
 
    public static boolean message(Player player, String privateMessage) {
        player.sendMessage(privateMessage);
        allright = true;
        return allright;
    }
}
2:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;

public class MessageMD_5 {

    private static boolean allright;
 
    public static boolean message(Player player, String hoverMessage, String privateMessage, String copyText) {
        TextComponent message = new TextComponent(hoverMessage);
        message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(privateMessage)));
        message.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, copyText));
        player.spigot().sendMessage(message);
        allright = true;
        return allright;
    }
}
3:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

import ink.anh.anhmine.AnhMine;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;

public class MessageAdventure {

    private static boolean allright;
 
    public static boolean message(Player player, String hoverMessage, String privateMessage, String copyText) {
        BukkitAudiences adventure = BukkitAudiences.create(AnhMine.getInstance());

        Component message = Component.text(hoverMessage)
                .hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text(privateMessage)))
                .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard(copyText));
        adventure.sender(player).sendMessage(message);
        allright = true;
        return allright;
    }
}
и потому, что в Paper нет класса net.kyori.adventure.platform.bukkit.BukkitAudiences пришлось сделать 4-й:
PHP:
package ink.anh.anhmine.utils.chat;

import org.bukkit.entity.Player;

import ink.anh.anhmine.AnhMine;
import net.kyori.adventure.text.Component;

public class MessagePaper {

    private static boolean allright;
 
    public static boolean message(Player player, String hoverMessage, String privateMessage, String copyText) {

        Component message = Component.text(hoverMessage)
                .hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text(privateMessage)))
                .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard(copyText));
        player.sendMessage(message);
        allright = true;
        return allright;
    }
}
Соответственно и это:
PHP:
package ink.anh.anhmine.utils.chat;

public enum MessagesFramework {

    PLAIN_TEXT,
    ADVENTURE,
    PAPER,
    MD_5;
 
    public static MessagesFramework getFramework() {
        if (isClassPresent("net.kyori.adventure.text.Component") && isClassPresent("net.kyori.adventure.platform.bukkit.BukkitAudiences")) {
            return MessagesFramework.ADVENTURE;
        }else if (isClassPresent("net.kyori.adventure.text.Component")) {
            return MessagesFramework.PAPER;
        }else if (isClassPresent("net.md_5.bungee.api.chat.BaseComponent")) {
            return MessagesFramework.MD_5;
        }else {
            return MessagesFramework.PLAIN_TEXT;
        }
    }
 
    private static boolean isClassPresent(String className) {
        try {
            Class.forName(className);
            return true;
        } catch (NoClassDefFoundError | ClassNotFoundException e) {
            return false;
        }
    }
}
вызываются классы отсюда:

PHP:
            if (AnhMine.getMessFrame() == MessagesFramework.ADVENTURE) {
                return MessageAdventure.message(player, hoverMessage, privateMessage, copyText);
            }else if (AnhMine.getMessFrame() == MessagesFramework.PAPER) {
                return MessagePaper.message(player, hoverMessage, privateMessage, copyText);
            }else if (AnhMine.getMessFrame() == MessagesFramework.MD_5) {
                return MessageMD_5.message(player, hoverMessage, privateMessage, copyText);
            }else {
                return MessagePlainText.message(player,  privateMessage);
            }

Тестировал на Spigot и Paper. И вот тут мне нужно ещё разобраться как лучше сделать, ведь в Paper вылезло исключение:
Код:
java.lang.Error: Unresolved compilation problem:
        The method sendMessage(String) in the type CommandSender is not applicable for the arguments (Component)

        at ink.anh.anhmine.utils.chat.MessagePaper.message(MessagePaper.java:17) ~[AnhMine.jar:?]
        at ink.anh.anhmine.cmd.anh.CmdNewWallet.execCmdNewWalletRun(CmdNewWallet.java:141) ~[AnhMine.jar:?]
        at ink.anh.anhmine.cmd.anh.CmdNewWallet.lambda$0(CmdNewWallet.java:56) ~[AnhMine.jar:?]
        at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[patched_1.17.1.jar:git-Paper-411]                                                                                                               
        at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:57) ~[patched_1.17.1.jar:git-Paper-411]                                                                                                     
        at com.destroystokyo.paper.ServerSchedulerReportingWrapper.run(ServerSchedulerReportingWrapper.java:22) ~[patched_1.17.1.jar:git-Paper-411]                                                                                     
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]

Нужно узнать способ как отправить sendMessage() игроку с поддержкой Audience?
Очень интересно, причем тут вдруг String. По идее нормально должно работать.
Попробуй явно закастовать CommandSender к Audience и посмотри, какое будет исключение.

А по поводу импортов - достаточно было просто удалить импорты и указать полные пути до классов прям в коде
 
Попробуй явно закастовать CommandSender к Audience
"Закастовал" игрока, заработало на отлично!
PHP:
        Component message = Component.text(hoverMessage)
                .hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text(privateMessage)))
                .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard(copyText));

        Audience audience = (Audience) player;
        audience.sendMessage(message);
Спасибо!
 

Поделиться этой страницей

Назад
Верх