py-mine/mcstatus

Problems with ping Bedrock servers on core PMMP

kartashovio opened this issue · 5 comments

Hello! I have problems with pinging Bedrock servers on core https://pmmp.io/ . Mcstatus v9.4.2. Below are some examples of servers on this core:

  1. dragon-empire.ru:19132
    mcstatus: timed out
    Mcsrvstat.us: successfully
    Mcstatus.io: successfully

  2. play.whispmc.ru:19132
    mcstatus: timed out
    Mcsrvstat.us: successfully
    Mcstatus.io: successfully

  3. crystiland.com:19132
    This server is currently inactive, but the owner also uses PMMP, and sent me the following:
    [11:41:22.117]: Bad packet from [MY_IP] 35117: Not enough bytes left in buffer: need 8, have 0
    [11:41:22.117]: Blocked [MY_IP] for 600 seconds

Reproduced with master branch

Python 3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import mcstatus
>>> mcstatus.BedrockServer.lookup("dragon-empire.ru:19132").status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\utils.py", line 66, in sync_wrapper
    raise last_exc  # type: ignore # (This won't actually be unbound)
    ^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\utils.py", line 62, in sync_wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\server.py", line 213, in status
    return BedrockServerStatus(self.address, self.timeout, **kwargs).read_status()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\bedrock_status.py", line 49, in read_status
    data = self._read_status()
           ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\bedrock_status.py", line 58, in _read_status
    data, _ = s.recvfrom(2048)
              ^^^^^^^^^^^^^^^^
TimeoutError: timed out
>>> mcstatus.BedrockServer.lookup("play.whispmc.ru:19132").status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\utils.py", line 66, in sync_wrapper
    raise last_exc  # type: ignore # (This won't actually be unbound)
    ^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\utils.py", line 62, in sync_wrapper
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\server.py", line 213, in status
    return BedrockServerStatus(self.address, self.timeout, **kwargs).read_status()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\bedrock_status.py", line 49, in read_status
    data = self._read_status()
           ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\perch\OneDrive\Рабочий стол\programming\mcstatus\mcstatus\bedrock_status.py", line 58, in _read_status
    data, _ = s.recvfrom(2048)
              ^^^^^^^^^^^^^^^^
TimeoutError: timed out

Galaxite, one of the partnered Minecraft servers, seems to suffer the same issue.

Python 3.10.8 (main, Nov  1 2022, 14:18:21) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from mcstatus import BedrockServer
>>> server = BedrockServer.lookup("play.galaxite.net")
>>> status = server.status()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/michael/.local/lib/python3.10/site-packages/mcstatus/utils.py", line 66, in sync_wrapper
    raise last_exc  # type: ignore # (This won't actually be unbound)
  File "/home/michael/.local/lib/python3.10/site-packages/mcstatus/utils.py", line 62, in sync_wrapper
    return func(*args, **kwargs)
  File "/home/michael/.local/lib/python3.10/site-packages/mcstatus/server.py", line 213, in status
    return BedrockServerStatus(self.address, self.timeout, **kwargs).read_status()
  File "/home/michael/.local/lib/python3.10/site-packages/mcstatus/bedrock_status.py", line 49, in read_status
    data = self._read_status()
  File "/home/michael/.local/lib/python3.10/site-packages/mcstatus/bedrock_status.py", line 58, in _read_status
    data, _ = s.recvfrom(2048)
TimeoutError: timed out

Is the galaxite server down when running this? We expect that users use try-except to catch exceptions on their own when the server is down.

Is the galaxite server down when running this? We expect that users use try-except to catch exceptions on their own when the server is down.

No. The server is online, I can join it in my Minecraft bedrock client and ping it on websites like mcsrvstat.us. mcstatus however is unable to retrieve a response.

PocketMine-MP's ping-server.php script seems to send the following data:

b"\x01\x00\x00\x00\x00\x00\xda\\\xb1\x00\xff\xff\x00\xfe\xfe\xfe\xfe\xfd\xfd\xfd\xfd\x124Vxu4] \xf7B\xb9\xf4"

If I modify mcstatus to send this data (https://github.com/py-mine/mcstatus/blob/master/mcstatus/bedrock_status.py#L14), I am able to get a response back from Galaxite.

I am willing to open a PR but I don't understand RakNet / Minecraft Bedrock's protocol enough to know the difference between the current mcstatus request_status_data bytes and the data PMMP seems to additionally add to their way of pinging servers.