Failed reading ош

uter81

Знающий
Участник
Сообщения
226
Розыгрыши
0
Репутация
1
Реакции
11
Баллы
430
Хроники
  1. Master Class
Исходники
Присутствуют
Сборка
L2jmobius
подскажите как поправить ошибку сервера

Код:
2024.09.26 09:32:34,org.l2jmobius.gameserver.network.PacketLogger    Client: [IP: 100.71.129.85] - Failed reading: AuthLogin ; null
2024.09.26 09:32:34,org.l2jmobius.gameserver.network.PacketLogger    java.nio.BufferUnderflowException
    at java.base/java.nio.Buffer.nextGetIndex(Buffer.java:721)
    at java.base/java.nio.DirectByteBuffer.getInt(DirectByteBuffer.java:753)
    at org.l2jmobius.commons.network.internal.SinglePacketBuffer.readInt(SinglePacketBuffer.java:92)
    at org.l2jmobius.commons.network.ReadablePacket.readInt(ReadablePacket.java:132)
    at org.l2jmobius.gameserver.network.clientpackets.AuthLogin.readImpl(AuthLogin.java:40)
    at org.l2jmobius.gameserver.network.clientpackets.ClientPacket.read(ClientPacket.java:35)
    at org.l2jmobius.commons.network.ReadHandler.execute(ReadHandler.java:127)
    at org.l2jmobius.commons.network.ReadHandler.parseAndExecutePacket(ReadHandler.java:115)
    at org.l2jmobius.commons.network.ReadHandler.handlePayload(ReadHandler.java:93)
    at org.l2jmobius.commons.network.ReadHandler.completed(ReadHandler.java:66)
    at org.l2jmobius.commons.network.ReadHandler.completed(ReadHandler.java:30)
    at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:129)
    at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:284)
    at java.base/sun.nio.ch.WindowsAsynchronousSocketChannelImpl$ReadTask.completed(WindowsAsynchronousSocketChannelImpl.java:586)
    at java.base/sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:387)
    at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:113)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)
 
просто раньше не было такой ош. и все работало.
на сервер был прислан пакет AuthLogin, в котором происходит чтение данных (_loginName, _playKey1, _playKey2, _loginKey1, _loginKey2)
Java:
    @Override
    protected void readImpl()
    {
        _loginName = readString().toLowerCase();
        _playKey2 = readInt();
        _playKey1 = readInt();
        _loginKey1 = readInt();
        _loginKey2 = readInt();
    }
Так вот, ошибка судя по всему была вызвана тем, что в пакете не оказалось данных для чтения (_playKey1, _playKey2, _loginKey1, _loginKey2), или же данные были не корректны.

делаем проверку от тут
if (getAvailableBytes() == 0)
{
return;
}
Речь наверное о методе remaining, поскольку getAvailableBytes отсутствует. Не суть.
Но ты же понимаешь, что делая подобное ты пропустишь выполнения метода readImpl, спровоцировав тем самым последующее выполнение метода runImpl?

Ибо непонятно накуя, мобиус переписал реализацию, сделав метод readImpl возвращающим void. Ну то есть если метод readImpl не выбросив какое либо исключение, вернет true, продолжит выполнять следующий метод runImpl пакета.
Java:
    @Override
    public boolean read()
    {
        try
        {
            readImpl();
            return true;
        }
        catch (Exception e)
        {
            PacketLogger.warning("Client: " + getClient() + " - Failed reading: " + getClass().getSimpleName() + " ; " + e.getMessage());
            PacketLogger.warning(CommonUtil.getStackTrace(e));
        }
        return false;
    }
Java:
private void execute(ReadablePacket<T> packet)
    {
        if (packet.read())
        {
            // LOGGER.info("packet " + packet + " was read from client " + packet.client);
            _executor.execute(packet);
        }
    }
Тут мы видим, что выполнив readImpl без исключений, метод read вернет true, что спровацирует выполнение runImpl, что в данном случае будет не к чему.

По логике вещей, это должно было выглядеть примерно так
Java:
public abstract class ClientPacket extends ReadablePacket<GameClient>
{
    @Override
    public boolean read()
    {
        try
        {
            return readImpl();
        }
        catch (Exception e)
        {
            PacketLogger.warning("Client: " + getClient() + " - Failed reading: " + getClass().getSimpleName() + " ; " + e.getMessage());
            PacketLogger.warning(CommonUtil.getStackTrace(e));
        }
        return false;
    }
 
    protected abstract boolean readImpl();
 
    ...
}
Java:
public class AuthLogin extends ClientPacket
{
    // loginName + keys must match what the loginserver used.
    private String _loginName;
    private int _playKey1;
    private int _playKey2;
    private int _loginKey1;
    private int _loginKey2;
 
    @Override
    protected boolean readImpl()
    {
        _loginName = readString().toLowerCase();
        if (remaining() == 0)
        {
            return false;
        }

        _playKey2 = readInt();
        _playKey1 = readInt();
        _loginKey1 = readInt();
        _loginKey2 = readInt();

        return true;
    }

А ведь в теории подобное поможет избавиться от засора тредпула выполнением ненужных задач, не выполняя подобные задачи:
Java:
    private void execute(ReadablePacket<T> packet)
    {
        if (packet.read())
        {
            // LOGGER.info("packet " + packet + " was read from client " + packet.client);
            _executor.execute(packet);
        }
    }
 
Последнее редактирование:
Речь наверное о методе remaining, поскольку getAvailableBytes отсутствует. Но не суть.
ну около того В любом случае нужно сделать проверку на колличество доступных байт для чтения.
хм... интересный прикол конечно. Я думал то, что там какая-то защита использована (условно AA использует как раз таки AuthLogin для это уже и использует его для отправки HWID) и человек пытается зайти, без неё на сервер.

Java:
        readableBytes = packet.getReadableBytes();
        if (AA_HWID_ENABLED && readableBytes >= 32)
        {
            int length = readableBytes - 32;
            if (length != 0) {
                packet.readB(length);
            }
            _data = packet.readB(32);
            hwidPersists = true;
        }

но у мобиуса, оно выглядит... Странно? Никогда не видел, чтоб только login_name только приходил...

Java:
36|    @Override
37|    protected void readImpl()
38|    {
39|        _loginName = readString().toLowerCase();
40|        _playKey2 = readInt();
41|        _playKey1 = readInt();
42|        _loginKey1 = readInt();
43|        _loginKey2 = readInt();
44|    }
 
Да там суть то не совсем в том, чем "условно защищена" пакетка (клиент или какой-то стороннее по шлет пакет), а в том, что по серверу можно флудить "кривыми" пакетами заставляя тредпул выполнять просто немереное кол-во бесполезных задач, которые можно было дропнуть на этапе чтения.