Общая информация Я работаю над плагином чата для Spigot (сервер Minecraft). Идея состоит в том, чтобы создать систему чата, которая позволяет использовать рабочие вкладки чата:
Чтобы выполнить sh, мне нужно использовать NMS (ProtocolLib), поскольку Minecraft использует 3 типа сообщений в чате:
- Сообщения чата
- Системные сообщения
- Сообщения с информацией об игре
Сообщения чата легко доступны, а остальные 2 - нет. Если я не улавливаю эти сообщения, они выводят sh меню вкладок вместо того, чтобы попасть в их собственный канал чата.
Проблема Код (ниже), который я использую для перехвата этих сообщений, вызывает следующее исключение в подключенных клиентах Minecraft и отключает их при перезагрузке игрового плагина через /reload
:
DecoderException: java. lang.IndexOutOfBoundsException: readerIndex (0) + длина (1) превышает writerIndex (0) UnpooledSlicedByteBuf (ridx: 0, widx: 0, cap: 0/0, развернутый: PooledUnsafeDirectByteBuf (ridx: 2, widx 6: 6): 6) ) @ io.netty.handler.code c .MessageToMessageDecoder: 98
Соответствующий код
private void initPacketListener(){
protocolManager.addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, new PacketType[] { PacketType.Play.Server.CHAT })
{
@SuppressWarnings("unused")
@Override
public void onPacketSending(PacketEvent event) {
if ((event.getPacketType() == PacketType.Play.Server.CHAT)){
PacketContainer packet = event.getPacket();
Player player = event.getPlayer();
String message = "";
try {
String jsonMessage = event.getPacket().getChatComponents().getValues().get(0).getJson();
if (jsonMessage!=null&&!jsonMessage.isEmpty()) {
message = jsonToString(jsonMessage);
if (message.isEmpty()) return;
Subscriber subscriber = UMM.plugin.getSubscribers().get(player.getUniqueId());
String uuid = player.getUniqueId().toString();
Channel messageChannel = UMM.serverChannels.get(uuid);
messageChannel.addMessage(message);
ChatListener cl = new ChatListener(UMM.plugin);
cl.notifyChanges(messageChannel);
event.setCancelled(true);
} else {
System.out.println("Not a system msg");
}
} catch (Throwable e){
System.out.println("UMM Packet Error:" + e.getMessage());
}
}
}
});
}
То, что я попробовал для решения проблемы Я спросил некоторых других разработчиков об этой проблеме, и мне сказали:
Убедитесь, что размер / длина event.getPacket (). GetChatComponents (). GetValues () больше 0, прежде чем сделать # получить вызов.
Итак, я попробовал это:
List<WrappedChatComponent> wrap = event.getPacket().getChatComponents().getValues();
if(wrap.size() > 0) {
if ((event.getPacketType() == PacketType.Play.Server.CHAT)){
...
}
}
Но это никак не повлияло. Они больше не могли мне помочь, поэтому я надеюсь, что кто-то еще может знать, что происходит и как я могу решить эту проблему.
Обновление Даже после сокращения кода до этой, проблема все еще сохраняется:
private void initPacketListener(){
protocolManager.addPacketListener(new PacketAdapter(this, ListenerPriority.NORMAL, new PacketType[] { PacketType.Play.Server.CHAT })
{
@SuppressWarnings("unused")
@Override
public void onPacketSending(PacketEvent event) {
}
});
}
«Временное» решение проблемы использует BukkitRunnable
для вызова галочки метода 1 после перезагрузки сервера. Единственным недостатком этого является то, что любые сообщения, появляющиеся до первого тика, подталкивают меню вкладок вверх. Плагин исправляет это при следующем событии сообщения.