Iapetus-11 / aio-mc-rcon

An asynchronous RCON client/wrapper for Minecraft Java Edition
MIT License
38 stars 4 forks source link

Error: unpack requires a buffer of 4 bytes #8

Open FroostySnoowman opened 7 months ago

FroostySnoowman commented 7 months ago

Hello, I'm not entirely sure what to do about this error here.

async def execute_command(self, command: str, server_address: str = None, timeout=20):
    success = ""
    failed = ""

    async with self.bot.pool.acquire() as conn:
        async with conn.cursor(aiomysql.DictCursor) as cursor:
            await conn.commit()
            if server_address is None:
                sql = "SELECT * FROM modpacks"
                await cursor.execute(sql)
                modpacks = await cursor.fetchall()
                for modpack in modpacks:
                    try:
                        async with Client(modpack['ip_address'], modpack['rcon_port'], rcon_password) as client:
                            await asyncio.wait_for(client.send_cmd(command), timeout=timeout)
                            success += f"{modpack['server_address']}\n"
                            await asyncio.sleep(1)
                    except Exception as e:
                        print(e)
                        failed += f"{modpack['server_address']}\n"
            else:
                sql = "SELECT * FROM modpacks WHERE server_address = %s"
                await cursor.execute(sql, (server_address, ))
                modpack = await cursor.fetchone()
                try:
                    async with Client(modpack['ip_address'], modpack['rcon_port'], rcon_password) as client:
                        await asyncio.wait_for(client.send_cmd(command), timeout=timeout)
                        success += f"{server_address}\n"
                except Exception as e:
                    print(e)
                    failed += f"{server_address}\n"
            if failed == "":
                failed = "N/A"
            if success == "":
                success = "N/A"
            return success, failed

Command used: tellraw @a ["",{"text":"⭐","color":"yellow"},{"text":"==","bold":true,"color":"white"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"==","bold":true,"color":"white"},{"text":"⭐","color":"yellow"},"\n","To our cherished modded Minecraft family,","\n","May your holidays be as unique and creative as our world.","\n","Together, we've built more than just blocks – we've built a community.","\n","Merry Christmas and a Happy New Year, from Craft Down Under!","\n",{"text":"⭐","color":"yellow"},{"text":"==","bold":true,"color":"white"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"=","bold":true,"underlined":true,"color":"dark_red"},{"text":"=","bold":true,"underlined":true,"color":"dark_green"},{"text":"==","bold":true,"color":"white"},{"text":"⭐","color":"yellow"}]

Any help is appreciated!

Iapetus-11 commented 7 months ago

What error? Could you include the traceback?

FroostySnoowman commented 7 months ago

What error? Could you include the traceback?

Apologies, I'm getting this error: unpack requires a buffer of 4 bytes

If needed, I can provide a full traceback shortly.

Iapetus-11 commented 7 months ago

The full traceback would be very helpful

FroostySnoowman commented 7 months ago

The full traceback would be very helpful

Here you are:

Traceback (most recent call last):
  File "/Users//Desktop/Code/Mr. Roboto/cogs/commands/dispatch.py", line 114, in execute_command
    await asyncio.wait_for(client.send_cmd(command), timeout=timeout)
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/tasks.py", line 479, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/aiomcrcon/client.py", line 118, in send_cmd
    return await asyncio.wait_for(self._send_msg(MessageType.COMMAND, cmd), timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/tasks.py", line 479, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/aiomcrcon/client.py", line 93, in _send_msg
    in_len = struct.unpack("<i", await self._read(4))[0]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct.error: unpack requires a buffer of 4 bytes
Iapetus-11 commented 7 months ago

Are you on the latest version (3.2.1) I believe that fixes this issue, could you ensure you're on the latest? (if not, I am confusing it with a similar issue, and I will investigate further)

FroostySnoowman commented 7 months ago

Yes, I am indeed using 3.2.1. (Installed by pip install aio-mc-rcon)

FroostySnoowman commented 7 months ago

Just following up, do you by chance have any ideas?

Iapetus-11 commented 7 months ago

I have two guesses:

  1. The server is taking so long to respond that the _read() call doesn't receive any data and exits early causing the struct unpack to blowup
  2. The command doesn't have a response for some reason so there's nothing to _read() so it blows up

I unfortunately don't have a Minecraft server running anymore so to debug this I will have to set one up -- I just haven't had the time.

FroostySnoowman commented 7 months ago

I don't think either of those would work as smaller commands work fine. I can setup a server for you and give you the rcon credentials in a few hours. I'll send another message here with those!

Iapetus-11 commented 7 months ago

I setup a vanilla java server and was able to reproduce the problem -- commands greater than 1446 characters are not recognized by the server through RCON and cause the error you've been encountering.

I'm going to read up on the RCON protocol (probably just here lol: https://wiki.vg/RCON) and see if I can fix the issue. For now, I recommend making an alias to this command so you can just send the shorter alias instead.

Iapetus-11 commented 7 months ago

Looking at these docs it looks like there's no way to bypass the maximum length. I will push an update to enforce this with an explicitly raised ValueError.