From 97620d2a30a3256946e7cabd6ae741e41a1ffa32 Mon Sep 17 00:00:00 2001 From: Battlefield Duck Date: Wed, 24 Jan 2024 00:22:25 +0800 Subject: [PATCH] Update Satisfactory Protocol --- opengsq/protocols/satisfactory.py | 43 ++++++++++++++-------- opengsq/responses/satisfactory/__init__.py | 1 + opengsq/responses/satisfactory/status.py | 17 +++++++++ 3 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 opengsq/responses/satisfactory/__init__.py create mode 100644 opengsq/responses/satisfactory/status.py diff --git a/opengsq/protocols/satisfactory.py b/opengsq/protocols/satisfactory.py index 8f5cc4f..f6d4e7e 100644 --- a/opengsq/protocols/satisfactory.py +++ b/opengsq/protocols/satisfactory.py @@ -1,5 +1,6 @@ import struct +from opengsq.responses.satisfactory import Status from opengsq.binary_reader import BinaryReader from opengsq.exceptions import InvalidPacketException from opengsq.protocol_base import ProtocolBase @@ -7,43 +8,53 @@ class Satisfactory(ProtocolBase): - """Satisfactory Protocol""" - full_name = 'Satisfactory Protocol' + """ + This class represents the Satisfactory Protocol. It provides methods to interact with the Satisfactory API. + """ - async def get_status(self) -> dict: + full_name = "Satisfactory Protocol" + + async def get_status(self) -> Status: """ - Retrieves information about the server including state, version, and beacon port - Server state: 1 - Idle (no game loaded), 2 - currently loading or creating a game, 3 - currently in game + Asynchronously retrieves the status of the game server. The status includes the server state, version, and beacon port. + The server state can be one of the following: + 1 - Idle (no game loaded) + 2 - Currently loading or creating a game + 3 - Currently in game + + :return: A Status object containing the status of the game server. """ # Credit: https://github.com/dopeghoti/SF-Tools/blob/main/Protocol.md # Send message id, protocol version - request = struct.pack('2b', 0, 0) + 'opengsq'.encode() + request = struct.pack("2b", 0, 0) + "opengsq".encode() response = await UdpClient.communicate(self, request) br = BinaryReader(response) header = br.read_byte() if header != 1: - raise InvalidPacketException('Packet header mismatch. Received: {}. Expected: {}.'.format(chr(header), chr(1))) + raise InvalidPacketException( + "Packet header mismatch. Received: {}. Expected: {}.".format( + chr(header), chr(1) + ) + ) br.read_byte() # Protocol version br.read_bytes(8) # Request data - result = {} - result['State'] = br.read_byte() - result['Version'] = br.read_long() - result['BeaconPort'] = br.read_short() - - return result + return Status( + state=br.read_byte(), version=br.read_long(), beacon_port=br.read_short() + ) -if __name__ == '__main__': +if __name__ == "__main__": import asyncio import json + from dataclasses import asdict async def main_async(): - satisfactory = Satisfactory(host='79.136.0.124', port=15777, timeout=5.0) + satisfactory = Satisfactory(host="79.136.0.124", port=15777, timeout=5.0) status = await satisfactory.get_status() - print(json.dumps(status, indent=None) + '\n') + print(json.dumps(asdict(status), indent=None) + "\n") asyncio.run(main_async()) diff --git a/opengsq/responses/satisfactory/__init__.py b/opengsq/responses/satisfactory/__init__.py new file mode 100644 index 0000000..2f91dae --- /dev/null +++ b/opengsq/responses/satisfactory/__init__.py @@ -0,0 +1 @@ +from .status import Status diff --git a/opengsq/responses/satisfactory/status.py b/opengsq/responses/satisfactory/status.py new file mode 100644 index 0000000..9372c9e --- /dev/null +++ b/opengsq/responses/satisfactory/status.py @@ -0,0 +1,17 @@ +from dataclasses import dataclass + + +@dataclass +class Status: + """ + Represents the status response. + """ + + state: int + """The state.""" + + version: int + """The version.""" + + beacon_port: int + """The beacon port."""