import pytest from openttd import OpenTTDClient from openttd.protocol import ( OpenTTDProtocol, GameCommand, ModifyTimetableFlags, ModifyTimetableCtrlFlag, OrderType, OrderNonStopFlags, OrderStopLocation, INVALID_VEH_ORDER_ID, write_varuint, read_varuint, write_varuint_signed, read_varuint_signed ) from openttd_protocol.wire.read import read_uint8, read_uint16 class MockTransport: def is_closing(self): return False def write(self, data): return len(data) class MockProtocol: def __init__(self): self.sent = [] async def send_packet(self, data): self.sent.append(data) return len(data) def decode_sent_command(packet): """Decode a ClientCommand packet by reusing the ServerCommand parser, padding on the frame/my_cmd trailer that only ServerCommand carries on the wire (ClientCommand doesn't).""" padded = bytes(packet)[3:] + b"\x00\x00\x00\x00\x00" return OpenTTDProtocol.receive_ServerCommand(None, memoryview(padded)) def new_client(): client = OpenTTDClient("127.0.0.1") client._protocol = MockProtocol() client._transport = MockTransport() client._target_company = 0 return client # --- Varuint codec --- @pytest.mark.parametrize("value", [ 0, 1, 127, 128, 16383, 16384, 2097151, 2097152, 268435455, 268435456, 34359738367, 34359738368, 4398046511103, 4398046511104, 562949953421311, 562949953421312, 72057594037927935, 72057594037927936, 18446744073709551615, ]) def test_varuint_roundtrip_boundaries(value): buf = bytearray() write_varuint(buf, value) decoded, rest = read_varuint(memoryview(bytes(buf))) assert decoded == value assert bytes(rest) == b"" def test_varuint_rejects_negative(): with pytest.raises(ValueError): write_varuint(bytearray(), -1) @pytest.mark.parametrize("value", [0, 1, -1, 2, -2, 1000000, -1000000, 9223372036854775807, -9223372036854775808]) def test_varuint_signed_roundtrip(value): buf = bytearray() write_varuint_signed(buf, value) decoded, rest = read_varuint_signed(memoryview(bytes(buf))) assert decoded == value assert bytes(rest) == b"" # --- OpenTTDProtocol.receive_ServerCommand --- def build_server_command_bytes(company, cmd, payload, callback=0, callback_param=0, frame=42, my_cmd=True): import struct body = bytearray() body += struct.pack("