Клиент может принимать пакеты от сервера когда Minecraft#player==null

7,099
324
1,510
Рефакторил код одного мода, переписал пакеты на ElegantNetworking. Заметил, что в каждом пакете, отправляемым с сервера на клиент и работающем с игроком, есть проверка что игрок не отсутствует. Я пошел посмотреть код. При приеме на сервере игрок берется из NetHandlerPlayServer, а в нем он никогда не null. При приеме на клиенте было не очень прозрачно в коде, так что я сделал следующий тест:
Java:
@ElegantPacket
public class TestPacket implements ServerToClientPacket {
    final String payload;

    public TestPacket(String payload) {
        this.payload = payload;
    }

    @SideOnly(Side.CLIENT)
    @Override
    public void onReceive(Minecraft minecraft) {
        if(minecraft.player==null)
            System.out.println("TestPacket#onReceive minecraft.player==null");
    }
}
Java:
public static final String payload = "Просто 300 рандомных символов";

@SideOnly(Side.SERVER)
@SubscribeEvent
public static void onPlayerTick(TickEvent.PlayerTickEvent event){
    for (int i = 0; i < 10; i++)
        new TestPacket(payload).sendToPlayer((EntityPlayerMP) event.player);
}
Рассчет на то, что когда клиент ливает, из-за задержек сети на клиенте поле player обнулится раньше чем сервер перестанет отправлять пакеты вдогонку.
Запустил это на отдельном хосте.
Попробовал заходить и выходить на этот сервер - в логе клиента не было строк "TestPacket#onReceive minecraft.player==null".
Добавил в клиентскую сборку мод Proxy Server.
Попробовал заходить и выходить на сервер через прокси с 100 пингом - в логе клиента появились строки "TestPacket#onReceive minecraft.player==null".

Результаты этого эксперимента могут означать две вещи:
  • Клиент реально может принять пакет от сервера после отключения
  • Мод Proxy Server нарушает чистоту эксперимента и кейс возникает только с ним
В любом случае я могу убрать этот кейс, если добавлю проверку mc.player!=null прямо во фреймворк перед вызовом пользовательского обработчика.
Вопрос лишь в том, могут ли существовать разумные кейсы логики модов, когда нужно обработать входящий пакет при отсутствующем игроке?
 
Последнее редактирование:
1,369
112
241
могут ли существовать разумные кейсы логики модов, когда нужно обработать входящий пакет при отсутствующем игроке?
Чистка каких-то данных сервера на клиенте (типа рецептов, каких-то рендеров, специфичных для каждого отдельного мира и всё в таком духе), наверное. Хотя нормальный разраб такое хранить на клиенте не будет.
 
7,099
324
1,510
Делать такое по приему пакета означает что иногда пакет не отправляется, иначе клиент может просто всегда очищать данные при отключении от сервера.
Допустим, есть какой-то рендер, зависящий от мира. Тогда серверу имеет смысл иногда указывать клиенту очищать данные только если сервер знает, в какой следующий мир войдет игрок. Такое может быть например при юзе bungeecord: сервер перекиддывает игрока на другую ноду и если на этой ноде тот же самый контент, то отправлять пакет не надо. Но в этом кейсе можно сначала отправлять пакет о очистке, а после перекидывать игрока, так что это не требует обработки пакета при нулябельном игроке
 
1,074
72
372
Вопрос лишь в том, могут ли существовать разумные кейсы логики модов, когда нужно обработать входящий пакет при отсутствующем игроке?
В майнкрафте возможно всё. Не факт что каждому обработчику пакетов на клиенте нужен игрок. Если пакет пришёл - значить его нужно в любом случае обработать. Это задача разработчика учитывать факт что поле player является nullable. Добавление искусственного игнорирования пакетов на стороне клиента породит вопросы по её обходу, чем принесёт пользу.

Обработка пакетов должна работать как должна. Дополнительные проверки имеют смысл, если дело касается вопросов безопасности.
 
Сверху