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

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

Метки:
Теги Теги
java консоль ошибка
Статус
Закрыто для дальнейших ответов.

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:
 
Нельзя модифицировать коллекцию, если итерируешь её через for-each. Впрочем, кажется, здесь это и не нужно.
Код:
for (Player pl : e.getRecipients())
    if (pl.getLocation().distance(pLocation) <= msgRadius)
        pl.sendMessage(message);
e.getRecipients().clear();
Мне кажется, рано взялся за плагины.
 
А как сделать, что-бы то работало только в одном мире? (Overworld и т.д.) То есть если я пишу в чате в Аду, то пишется в стандартный майнкрафтовский чат. А в другом мире не писалось.
 
А как сделать, что-бы то работало только в одном мире? (Overworld и т.д.) То есть если я пишу в чате в Аду, то пишется в стандартный майнкрафтовский чат. А в другом мире не писалось.
Наверное по аналогии, нет?
Java:
@EventHandler
public void onChat(AsyncPlayerChatEvent event)
{
    event.getRecipients().clear();

    Player sender = event.getPlayer();

    ... // bla-bla-bla

    event.getRecipients().addAll(player.getWorld().getPlayers());
}
 
Наверное по аналогии, нет?
Java:
@EventHandler
public void onChat(AsyncPlayerChatEvent event)
{
    event.getRecipients().clear();

    Player sender = event.getPlayer();

    ... // bla-bla-bla

    event.getRecipients().addAll(player.getWorld().getPlayers());
}
Простите пожалуйста, я тупой) Можно вариант с фором, то-есть полный код функции :3
 
Простите пожалуйста, я тупой) Можно вариант с фором, то-есть полный код функции :3
А зачем тебе там цикл?
У тебя есть список получателей сообщения [event.getRecipients()].
Всё, что от тебя необходимо - установить формат сообщения, очистить список получателей и добавить в этот список тех, кого нужно. Собственно, код, что я скинул, это и делает.
 
А зачем тебе там цикл?
У тебя есть список получателей сообщения [event.getRecipients()].
Всё, что от тебя необходимо - установить формат сообщения, очистить список получателей и добавить в этот список тех, кого нужно. Собственно, код, что я скинул, это и делает.
Мне нужно разделение на глобальный и локальный чат, и кастомное сообщение, что выводиться в чат. Я это сам реализую. Но просто я не смог совместить ваш вариант с моим)
 
Мне нужно разделение на глобальный и локальный чат, и кастомное сообщение, что выводиться в чат. Я это сам реализую. Но просто я не смог совместить ваш вариант с моим)
Ну значит твой вариант не очень. Вот как я реализовал такое в своём чатике:
Listener:
Java:
@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:
Java:
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);
    }
}
 
Последнее редактирование:
Ну значит твой вариант не очень. Вот как я реализовал такое в своём чатике:
Listener:
Java:
@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:
Java:
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);
    }
}
Хорошо, спасибо, но я думаю ваш вариант не особо мне подходит) Простите(
 
А хоттттттяяяяяяяяяяяяя! Всё получилось! Всем огромное спасибо! Тема закрыта. :3
 
Статус
Закрыто для дальнейших ответов.

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

Назад
Верх