1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
  2. Вы находитесь в сообществе Rubukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на различные языки плагины наших коллег из других стран.
    Скрыть объявление
Скрыть объявление
В преддверии глобального обновления, мы проводим исследования, которые помогут нам сделать опыт пользования форумом ещё удобнее. Помогите нам, примите участие!

Помогите Ошибка, хотя всё работает (AsyncPlayerChatEvent)

Тема в разделе "Разработка плагинов для новичков", создана пользователем AlexP_, 24 сен 2019.

Статус темы:
Закрыта.
  1. Автор темы
    AlexP_

    AlexP_ Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    AlexP_
    Разрабатываю я плагин и он мне выдаёт ошибку. Плагин должен отправлять сообщения только в радиусе 30 блоков. Так-же пользователю должна выводиться этот текст хотя никого нет рядом.
    Помогите пожалуйста!
    Вот мой код:
    Код:
    package catlandrp.main;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.entity.Entity;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.player.PlayerJoinEvent;
    import org.bukkit.event.player.AsyncPlayerChatEvent;
    
    public class Handler implements Listener {
    
        @EventHandler
        public void Join (PlayerJoinEvent e) {
            e.getPlayer().sendMessage("Привет, " + e.getPlayer().getName() + "!");
        }
    
        @EventHandler
        public void Message (AsyncPlayerChatEvent e) {
            String message = e.getPlayer().getName() + ": " + e.getMessage();
            int msgRadius = 30;
            Location pLocation = e.getPlayer().getLocation();
    
            for (Player pl : e.getRecipients()) {
                if (pl.getLocation().distance(pLocation) <= msgRadius) {
                    pl.sendMessage(message);
                    e.getRecipients().clear();
                }
                else {
                    e.getPlayer().sendMessage(message);
                    e.getRecipients().clear();
                }
            }
        }
    }
    
    А вот ошибка:

    Код:
    [23:14:27] [Async Chat Thread - #0/ERROR]: Could not pass event AsyncPlayerChatEvent to CatLand_RP v1.0
    org.bukkit.event.EventException: null
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:320) ~[spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:529) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:508) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            at net.minecraft.server.v1_14_R1.PlayerConnection.chat(PlayerConnection.java:1563) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            at net.minecraft.server.v1_14_R1.PlayerConnection.a(PlayerConnection.java:1501) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            at net.minecraft.server.v1_14_R1.PacketPlayInChat$1.run(PacketPlayInChat.java:41) [spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_212]
            at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_212]
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_212]
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_212]
            at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
    Caused by: java.util.ConcurrentModificationException
            at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445) ~[?:1.8.0_212]
            at java.util.HashMap$KeyIterator.next(HashMap.java:1469) ~[?:1.8.0_212]
            at catlandrp.main.Handler.Message(Handler.java:32) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_212]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_212]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_212]
            at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_212]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:316) ~[spigot-1.14.4.jar:git-Spigot-9de398a-9c887d4]
            ... 11 more
    [23:14:27] [Async Chat Thread - #0/INFO]: <AlexP_> ╩юЄ
    Помогите пожалуйста! :cry:
     
  2. imDaniX

    imDaniX Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    imDaniX
    Нельзя модифицировать коллекцию, если итерируешь её через for-each. Впрочем, кажется, здесь это и не нужно.
    Код:
    for (Player pl : e.getRecipients())
        if (pl.getLocation().distance(pLocation) <= msgRadius)
            pl.sendMessage(message);
    e.getRecipients().clear();
    
    Мне кажется, рано взялся за плагины.
     
  3. Автор темы
    AlexP_

    AlexP_ Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    AlexP_
    Да, может быть, но никогда не поздно учится). Но всё равно спасибо! Всё работает. Тема закрыта.
     
  4. Автор темы
    AlexP_

    AlexP_ Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    AlexP_
    А как сделать, что-бы то работало только в одном мире? (Overworld и т.д.) То есть если я пишу в чате в Аду, то пишется в стандартный майнкрафтовский чат. А в другом мире не писалось.
     
  5. CoolBoy

    CoolBoy Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Наверное по аналогии, нет?
    Код:
    @EventHandler
    public void onChat(AsyncPlayerChatEvent event)
    {
        event.getRecipients().clear();
    
        Player sender = event.getPlayer();
    
        ... // bla-bla-bla
    
        event.getRecipients().addAll(player.getWorld().getPlayers());
    }
    
     
  6. Автор темы
    AlexP_

    AlexP_ Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    AlexP_
    Простите пожалуйста, я тупой) Можно вариант с фором, то-есть полный код функции :3
     
  7. CoolBoy

    CoolBoy Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    А зачем тебе там цикл?
    У тебя есть список получателей сообщения [event.getRecipients()].
    Всё, что от тебя необходимо - установить формат сообщения, очистить список получателей и добавить в этот список тех, кого нужно. Собственно, код, что я скинул, это и делает.
     
  8. Автор темы
    AlexP_

    AlexP_ Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    AlexP_
    Мне нужно разделение на глобальный и локальный чат, и кастомное сообщение, что выводиться в чат. Я это сам реализую. Но просто я не смог совместить ваш вариант с моим)
     
  9. CoolBoy

    CoolBoy Активный участник Пользователь

    Баллы:
    96
    Имя в Minecraft:
    Xezard
    Ну значит твой вариант не очень. Вот как я реализовал такое в своём чатике:
    Listener:
    Код:
    @EventHandler
    public void onChat(AsyncPlayerChatEvent event)
    {
        String message = event.getMessage();
    
        event.getRecipients().clear();
    
        this.channelsManager.getByMessage(message).ifPresent((channel) ->
        {
            // тут может быть огромная куча логики, от форматирования до фильтрации
    
            event.setFormat(channel.getFormat());
            event.setMessage(message);
    
            event.getRecipients().addAll(channel.getRecipients(player));
        }
    }
    
    ChatChannel:
    Код:
    public class Channel
    {
        public List<Player> getRecipients(Player sender)
        {
            /*
              * В зависимости от кучи разных параметров канала
              * собираем тех, кто должен увидеть сообщение сендера.
              * На этом этапе, у меня, например, уже имеется список всех
              * потенциальных наблюдателей этого сообщения.
              * В более простом случае их можно листом закинуть прямо
              * в аргументы этого метода из листенера, например.
              *
              * (ниже просто псевдокод)
              */
    
            return this.viewingPlayers.stream()
                                      .filter((viewer) -> this.checkRequirements(sender, viewer))
                                      .collect(Collectors.toList());
        }
    
        private boolean checkRequirements(Player sender, Player viewer)
        {
            /*
             * Случай с локальным чатом, допустим:
             */
    
            return sender.getLocation().getNearbyPlayers(this.radius).contains(viewer);
        }
    }
    
     
    Последнее редактирование: 28 сен 2019
  10. Автор темы
    AlexP_

    AlexP_ Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    AlexP_
    Хорошо, спасибо, но я думаю ваш вариант не особо мне подходит) Простите(
     
  11. Автор темы
    AlexP_

    AlexP_ Активный участник Пользователь

    Баллы:
    66
    Имя в Minecraft:
    AlexP_
    А хоттттттяяяяяяяяяяяяя! Всё получилось! Всем огромное спасибо! Тема закрыта. :3
     
Статус темы:
Закрыта.

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