PocketMine-MP Plugin to Log Every Server List Ping in Console

Answered using AI by Vibe Coding

Code Question:

Напиши плагин для PocketMine-MP 5.37.3, чтобы если игрок находится в меню игры и видит MOTD сервера, в консоли в это время спамились каждую секунду сообщения о пинге сервера, вроде это пинг RakNet насколько я помню.

Code Solution:

В PocketMine-MP нет встроенного события «игрок видит MOTD» (то есть он ещё не вошёл, а просто обновляет список серверов в клиенте).
Но RakLib (точнее — класс SessionManager в папке src/raklib/server) уже пишет в лог каждый Unconnected Ping («Raw packet 0x01»).
По умолчанию это происходит только при старте сервера или если уровень логирования поставить DEBUG.
Поэтому задача сводится к двум шагам:

  1. Перехватить (или «прослушать») входящий пакет UNCONNECTED_PING (ID 0x01).
  2. Выводить в консоль собственное короткое сообщение каждый раз, когда к нам прилетает такой «холостой» пинг.

PM-5.37.3 предоставляет для этого интерфейс RakLibPacketReceiveEvent, который бросается до того, как RakLib ответит клиенту.
В событии есть сырой буфер пакета – первый байт и есть его ID.

Создаём простой плагин PingSpam:

plugins/PingSpam/
 ├── plugin.yml
 └── src/
     └── falk/
         └── PingSpam.php

plugin.yml

name: PingSpam
main: falk\PingSpam
version: 1.0.0
api: 5.0.0
description: "Каждый UNCONNECTED_PING пишет в консоль"
author: falk

src/falk/PingSpam.php

<?php
declare(strict_types=1);

namespace falk;

use pocketmine\event\Listener;
use pocketmine\event\server\RakLibPacketReceiveEvent;
use pocketmine\network\mcpe\raklib\RakLibInterface;
use pocketmine\plugin\PluginBase;
use raklib\protocol\UnconnectedPing;

final class PingSpam extends PluginBase implements Listener{

    protected function onEnable() : void{
        $this->getServer()->getPluginManager()->registerEvents($this, $this);
    }

    /**
     * @priority MONITOR
     * @ignoreCancelled false   // пакет не cancell'ится, но на всякий
     */
    public function onRakLibPacket(RakLibPacketReceiveEvent $ev) : void{
        // 0x01 – это UnconnectedPing (Open-Connection вики RakNet)
        if($ev->getPacket()[0] === "\x01"){
            // можно распарсить и время, но для спама это не обязательно
            $time = UnconnectedPing::create($ev->getPacket())->sendPingTime; // опционально
            $this->getLogger()->info("Ping from {$ev->getAddress()}:{$ev->getPort()}  (sendTime={$time})");
        }
    }
}

Что делает код:

  • Ловит любой сырой RakNet-пакет, прилетающий на UDP-порт сервера.
  • Если первый байт 0x01 (UnconnectedPing), выводит в консоль строку вида:
    [PingSpam] Ping from 192.168.1.25:52134 (sendTime=123456789)

Теперь, если кто-то обновляет список серверов в клиенте (или сторонний мониторинг держит открытым Query/Ping), каждый «холостой» пинг будет сразу виден в консоли – ровно то, что вы просили.