From 453af6b02795e4a10e9eba6640893c8375ab3bde Mon Sep 17 00:00:00 2001 From: eric vz Date: Fri, 30 Jun 2023 22:19:35 -0500 Subject: [PATCH 01/18] Bump version to v1.4.2 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 9bdb566..87ff52e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.4.1 \ No newline at end of file +v1.4.2 \ No newline at end of file From c06ebebfa8efb63efb9b5c7eba806e89ffb83f04 Mon Sep 17 00:00:00 2001 From: eric vz Date: Fri, 30 Jun 2023 22:22:31 -0500 Subject: [PATCH 02/18] use a secret to control image name --- .github/workflows/build-to-dockerhub.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-to-dockerhub.yml b/.github/workflows/build-to-dockerhub.yml index 8aef13b..2920953 100644 --- a/.github/workflows/build-to-dockerhub.yml +++ b/.github/workflows/build-to-dockerhub.yml @@ -21,7 +21,7 @@ jobs: with: # list of Docker images to use as base name for tags images: | - base10/starrypy3k + ${{ secrets.DOCKERHUB_IMAGE }} # generate Docker tags based on the following events/attributes tags: | type=ref,event=branch From 32080a2d4ed7c8d15cc6d0830334c30c2671927b Mon Sep 17 00:00:00 2001 From: eric vz Date: Fri, 30 Jun 2023 22:27:43 -0500 Subject: [PATCH 03/18] Bump version to v1.4.3 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 87ff52e..5beebea 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.4.2 \ No newline at end of file +v1.4.3 \ No newline at end of file From a1b37d7826198756cc37e57aeb8698d47885e362 Mon Sep 17 00:00:00 2001 From: eric vz Date: Fri, 30 Jun 2023 22:28:18 -0500 Subject: [PATCH 04/18] remove testing discord kill command --- plugins/discord_bot.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/discord_bot.py b/plugins/discord_bot.py index 0017ca7..ff1e3e7 100644 --- a/plugins/discord_bot.py +++ b/plugins/discord_bot.py @@ -217,8 +217,6 @@ def on_chat_sent(self, data, connection): msg = data["parsed"]["message"] if self.sc: msg = self.color_strip.sub("", msg) - if msg == "!killdiscord": #FOR TESTING: REMOVE ME - asyncio.ensure_future(self.discord_client.logout()) if data["parsed"]["send_mode"] == ChatSendMode.UNIVERSE: if self.chat_manager: if not self.chat_manager.mute_check(connection.player): From 384c0ee8fdb4d113e1efea13dd9e019cf936294c Mon Sep 17 00:00:00 2001 From: eric vz Date: Sun, 2 Jul 2023 09:05:28 -0500 Subject: [PATCH 05/18] Bump version to 2.0.0 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5beebea..359a5b9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v1.4.3 \ No newline at end of file +2.0.0 \ No newline at end of file From 07cca335cb3b201e630c5d78f3221e4037566022 Mon Sep 17 00:00:00 2001 From: eric vz Date: Sun, 2 Jul 2023 09:13:24 -0500 Subject: [PATCH 06/18] fix version file --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 359a5b9..46b105a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.0 \ No newline at end of file +v2.0.0 From 12c0275cced1f03e31bf2094c30e3703ff76ff5d Mon Sep 17 00:00:00 2001 From: eric vz Date: Sun, 2 Jul 2023 09:13:56 -0500 Subject: [PATCH 07/18] Bump version to v2.0.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 46b105a..81ef58f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.0.0 +v2.0.1 \ No newline at end of file From 025b7fa2e56a40887c1aa48e5dae8edecd6acc58 Mon Sep 17 00:00:00 2001 From: eric vz Date: Sun, 18 Aug 2024 21:27:20 -0500 Subject: [PATCH 08/18] update dependencies --- requirements.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/requirements.txt b/requirements.txt index 33d2cc1..e519783 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,13 @@ -aiohttp==3.8.4 +aiohttp==3.10.4 aiosignal==1.3.1 -async-timeout==4.0.2 -attrs==23.1.0 -charset-normalizer==3.1.0 -discord.py==2.3.1 +async-timeout==4.0.3 +attrs==24.2.0 +charset-normalizer==3.3.2 +discord.py==2.4.0 docopt==0.6.2 -frozenlist==1.3.3 -idna==3.4 +frozenlist==1.4.1 +idna==3.7 irc3==1.1.10 -multidict==6.0.4 -venusian==3.0.0 -yarl==1.9.2 +multidict==6.0.5 +venusian==3.1.0 +yarl==1.9.4 From 74cccddb736dea7e7bbf3edfb6e3cbabfca1b63f Mon Sep 17 00:00:00 2001 From: eric vz Date: Sun, 18 Aug 2024 21:27:42 -0500 Subject: [PATCH 09/18] print traceback of exceptions --- server.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server.py b/server.py index b59312e..1d3d61a 100644 --- a/server.py +++ b/server.py @@ -2,6 +2,7 @@ import logging import sys import signal +import traceback from configuration_manager import ConfigurationManager from data_parser import ChatReceived @@ -74,6 +75,7 @@ async def server_loop(self): except Exception as err: logger.error("Server loop exception occurred:" "{}: {}".format(err.__class__.__name__, err)) + logger.error("Error details and traceback: {}".format(traceback.format_exc())) finally: self.die() From 3d3dffba77b17f8ae1708f6d250925fe0c627090 Mon Sep 17 00:00:00 2001 From: eric vz Date: Mon, 19 Aug 2024 12:41:22 -0500 Subject: [PATCH 10/18] add starjson, add it to protocolresponse --- data_parser.py | 40 ++++++++++++++++++++++++++++++++++++++++ requirements.txt | 2 ++ 2 files changed, 42 insertions(+) diff --git a/data_parser.py b/data_parser.py index 4b8b8ff..72af39b 100644 --- a/data_parser.py +++ b/data_parser.py @@ -336,6 +336,45 @@ def _parse(cls, stream: BytesIO, ctx: OrderedDict): def _build(cls, obj, ctx: OrderedDotDict): return StarByteArray.build(obj.encode("utf-8"), ctx) +class StarJson(Struct): + @classmethod + def _parse(cls, stream: BytesIO, ctx: OrderedDict): + + type_index = Byte.parse(stream, ctx) + if type_index > 0: + type_index -= 1 + + match type_index: + case 1: + return BFloat32.parse(stream, ctx) + case 2: + return Flag.parse(stream, ctx) + case 3: + return SignedVLQ.parse(stream, ctx) + case 4: + return StarString.parse(stream, ctx) + case 5: + l = VLQ.parse(stream, ctx) + c = [] + for _ in range(l): + c.append(StarJson.parse(stream, ctx)) + return c + case 6: + data = {} + l = VLQ.parse(stream, ctx) + for _ in range(l): + key = StarString.parse(stream, ctx) + value = StarJson.parse(stream, ctx) + data[key] = value + return data + case _: + return None # Invalid + + + @classmethod + def _build(cls, obj, ctx: OrderedDotDict): + raise NotImplementedError + class Byte(Struct): @classmethod @@ -748,6 +787,7 @@ class ProtocolRequest(Struct): class ProtocolResponse(Struct): """packet type 1 """ server_response = Byte + info = StarJson class ServerDisconnect(Struct): diff --git a/requirements.txt b/requirements.txt index e519783..1991aad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +aiohappyeyeballs==2.3.7 aiohttp==3.10.4 aiosignal==1.3.1 async-timeout==4.0.3 @@ -11,3 +12,4 @@ irc3==1.1.10 multidict==6.0.5 venusian==3.1.0 yarl==1.9.4 +zstd==1.5.5.1 From 9845d29335541f6317c037e1844c10b1cd5bcf95 Mon Sep 17 00:00:00 2001 From: eric vz Date: Mon, 19 Aug 2024 12:41:34 -0500 Subject: [PATCH 11/18] add opensb detector plugin --- plugins/opensb_detector.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 plugins/opensb_detector.py diff --git a/plugins/opensb_detector.py b/plugins/opensb_detector.py new file mode 100644 index 0000000..10c8d84 --- /dev/null +++ b/plugins/opensb_detector.py @@ -0,0 +1,27 @@ +""" +StarryPy OpenSB Detector Plugin + +Detects zstd compression for the stream and sets server configuration accordingly +""" + +import asyncio + +from base_plugin import SimpleCommandPlugin +from utilities import send_message, Command + + +class OpenSBDetector(SimpleCommandPlugin): + name = "opensb_detector" + + def __init__(self): + super().__init__() + + async def activate(self): + await super().activate() + + async def on_protocol_response(self, data, connection): + self.logger.debug("Received protocol response: {} from connection {}".format(data, connection)) + if data["parsed"]["info"]["compression"] == "Zstd": + self.logger.info("Detected Zstd compression. Setting server configuration.") + connection.start_zstd() + return True From b0e577314177e98ac009152040736d0482aaf0cd Mon Sep 17 00:00:00 2001 From: eric vz Date: Tue, 20 Aug 2024 23:04:30 -0500 Subject: [PATCH 12/18] working (if slow) zstd reader and writer --- requirements.txt | 2 +- server.py | 49 +++++++++++++++++++++++++++++++++++++----------- zstd_reader.py | 46 +++++++++++++++++++++++++++++++++++++++++++++ zstd_writer.py | 25 ++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 zstd_reader.py create mode 100644 zstd_writer.py diff --git a/requirements.txt b/requirements.txt index 1991aad..5a419f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,4 @@ irc3==1.1.10 multidict==6.0.5 venusian==3.1.0 yarl==1.9.4 -zstd==1.5.5.1 +zstandard==0.23.0 diff --git a/server.py b/server.py index 1d3d61a..d9cb884 100644 --- a/server.py +++ b/server.py @@ -10,6 +10,8 @@ from pparser import build_packet from plugin_manager import PluginManager from utilities import path, read_packet, State, Direction, ChatReceiveMode +from zstd_reader import ZstdFrameReader +from zstd_writer import ZstdFrameWriter DEBUG = True @@ -22,18 +24,21 @@ logger = logging.getLogger('starrypy') logger.setLevel(loglevel) +class SwitchToZstdException(Exception): + pass + class StarryPyServer: """ Primary server class. Handles all the things. """ def __init__(self, reader, writer, config, factory): logger.debug("Initializing connection.") - self._reader = reader - self._writer = writer - self._client_reader = None - self._client_writer = None + self._reader = reader # read packets from client + self._writer = writer # writes packets to client + self._client_reader = None # read packets from server (acting as client) + self._client_writer = None # write packets to server self.factory = factory - self._client_loop_future = None + self._client_loop_future = asyncio.create_task(self.client_loop()) self._server_loop_future = asyncio.create_task(self.server_loop()) self.state = None self._alive = True @@ -43,8 +48,20 @@ def __init__(self, reader, writer, config, factory): self._client_read_future = None self._server_write_future = None self._client_write_future = None + self._expect_server_loop_death = False logger.info("Received connection from {}".format(self.client_ip)) + def start_zstd(self): + self._reader = ZstdFrameReader(self._reader) + self._client_reader= ZstdFrameReader(self._client_reader) + self._writer = ZstdFrameWriter(self._writer, skip_packets=1) + self._client_writer = ZstdFrameWriter(self._client_writer) + self._expect_server_loop_death = True + self._server_loop_future.cancel() + self._server_loop_future = asyncio.create_task(self.server_loop()) + logger.info("Switched to zstd") + + async def server_loop(self): """ Main server loop. As clients connect to the proxy, pass the @@ -53,14 +70,15 @@ async def server_loop(self): :return: """ - (self._client_reader, self._client_writer) = \ - await asyncio.open_connection(self.config['upstream_host'], - self.config['upstream_port']) - self._client_loop_future = asyncio.create_task(self.client_loop()) + + # wait until client is available + while self._client_writer is None: + await asyncio.sleep(0.1) + try: while True: packet = await read_packet(self._reader, - Direction.TO_SERVER) + Direction.TO_SERVER) # Break in case of emergencies: # if packet['type'] not in [17, 40, 41, 43, 48, 51]: # logger.debug('c->s {}'.format(packet['type'])) @@ -77,7 +95,12 @@ async def server_loop(self): "{}: {}".format(err.__class__.__name__, err)) logger.error("Error details and traceback: {}".format(traceback.format_exc())) finally: - self.die() + if not self._expect_server_loop_death: + logger.info("Server loop ended.") + self.die() + else: + logger.info("Restarting server loop for switch to zstd.") + self._expect_server_loop_death = False async def client_loop(self): """ @@ -86,6 +109,10 @@ async def client_loop(self): :return: """ + (self._client_reader, self._client_writer) = \ + await asyncio.open_connection(self.config['upstream_host'], + self.config['upstream_port']) + try: while True: packet = await read_packet(self._client_reader, diff --git a/zstd_reader.py b/zstd_reader.py new file mode 100644 index 0000000..8be4b40 --- /dev/null +++ b/zstd_reader.py @@ -0,0 +1,46 @@ +import asyncio +from io import BufferedReader, BytesIO +import zstandard as zstd + +class ZstdFrameReader: + def __init__(self, reader: asyncio.StreamReader): + self.decompressor = zstd.ZstdDecompressor() + self.inputbuffer = bytearray() + self.outputbuffer = BytesIO() + self.remaining = 0 + self.raw_reader = reader + + async def readexactly(self, count): + # print(f"Reading exactly {count} bytes") + + while True: + # if there are enough bytes, return them + if self.remaining >= count: + # print (f"Returning {count} bytes from buffer") + self.remaining -= count; + return self.outputbuffer.read1(count) + + # print(f"Reading from network since there are only {self.remaining} bytes in buffer") + await self.read_from_network() + + async def read_from_network(self): + while True: + chunk = await self.raw_reader.read(1024) # Read in chunks of 1024 bytes + # print(f"Read {len(chunk)} bytes from network") + if not chunk: + raise asyncio.CancelledError("Connection closed") + self.inputbuffer.extend(chunk) + + decompressor = self.decompressor.decompressobj() # single use decompressor + try: + decompressed_data = decompressor.decompress(self.inputbuffer) + if decompressed_data: + # write to the output buffer + self.outputbuffer = BytesIO(decompressed_data)# assume that previous reads emptied the buffer (no packets split across zstd frames) + self.remaining = len(decompressed_data) + # Save leftover bytes + self.inputbuffer = bytearray(decompressor.unused_data) + # print("Decompressed frame of size", len(decompressed_data)) + return + except zstd.ZstdError: + continue # Continue reading if the frame is not complete diff --git a/zstd_writer.py b/zstd_writer.py new file mode 100644 index 0000000..e6c34b5 --- /dev/null +++ b/zstd_writer.py @@ -0,0 +1,25 @@ +import asyncio +from io import BufferedReader, BytesIO +import zstandard as zstd + +class ZstdFrameWriter: + def __init__(self, raw_writer: asyncio.StreamWriter, skip_packets=0): + self.compressor = zstd.ZstdCompressor() + self.raw_writer = raw_writer + self.skip_packets = skip_packets + + async def drain(self): + await self.raw_writer.drain() + + def close(self): + self.raw_writer.close() + self.compressor = None + + def write(self, data): + + if self.skip_packets > 0: + self.skip_packets -= 1 + self.raw_writer.write(data) + return + + self.raw_writer.write(self.compressor.compress(data)) \ No newline at end of file From 98e5937bde21b99d5243d6ce2ca24f15ab52bd0b Mon Sep 17 00:00:00 2001 From: eric vz Date: Tue, 20 Aug 2024 23:20:12 -0500 Subject: [PATCH 13/18] read larger chunks --- zstd_reader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zstd_reader.py b/zstd_reader.py index 8be4b40..45f6f4e 100644 --- a/zstd_reader.py +++ b/zstd_reader.py @@ -25,7 +25,7 @@ async def readexactly(self, count): async def read_from_network(self): while True: - chunk = await self.raw_reader.read(1024) # Read in chunks of 1024 bytes + chunk = await self.raw_reader.read(32768) # Read in chunks; we'll only get what's available # print(f"Read {len(chunk)} bytes from network") if not chunk: raise asyncio.CancelledError("Connection closed") From 2a413d8feb21ee93b4d907e9842d26a0d73f7c58 Mon Sep 17 00:00:00 2001 From: eric vz Date: Wed, 21 Aug 2024 00:12:07 -0500 Subject: [PATCH 14/18] working proxy on vanilla opensb --- server.py | 4 +-- zstd_reader.py | 79 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/server.py b/server.py index d9cb884..8478ef8 100644 --- a/server.py +++ b/server.py @@ -52,8 +52,8 @@ def __init__(self, reader, writer, config, factory): logger.info("Received connection from {}".format(self.client_ip)) def start_zstd(self): - self._reader = ZstdFrameReader(self._reader) - self._client_reader= ZstdFrameReader(self._client_reader) + self._reader = ZstdFrameReader(self._reader, Direction.TO_SERVER) + self._client_reader= ZstdFrameReader(self._client_reader, Direction.TO_CLIENT) self._writer = ZstdFrameWriter(self._writer, skip_packets=1) self._client_writer = ZstdFrameWriter(self._client_writer) self._expect_server_loop_death = True diff --git a/zstd_reader.py b/zstd_reader.py index 45f6f4e..eb2fa71 100644 --- a/zstd_reader.py +++ b/zstd_reader.py @@ -1,46 +1,71 @@ import asyncio -from io import BufferedReader, BytesIO +from io import BufferedReader +import io import zstandard as zstd +from utilities import Direction + class ZstdFrameReader: - def __init__(self, reader: asyncio.StreamReader): - self.decompressor = zstd.ZstdDecompressor() - self.inputbuffer = bytearray() - self.outputbuffer = BytesIO() - self.remaining = 0 + def __init__(self, reader: asyncio.StreamReader, direction: Direction): + self.outputbuffer = NonSeekableMemoryStream() + self.decompressor = zstd.ZstdDecompressor().stream_writer(self.outputbuffer) self.raw_reader = reader + self.direction = direction async def readexactly(self, count): # print(f"Reading exactly {count} bytes") while True: # if there are enough bytes, return them - if self.remaining >= count: - # print (f"Returning {count} bytes from buffer") - self.remaining -= count; - return self.outputbuffer.read1(count) + if self.outputbuffer.remaining() >= count: + # print (f"Returning {count} bytes from buffer {self.direction}") + return self.outputbuffer.read(count) # print(f"Reading from network since there are only {self.remaining} bytes in buffer") - await self.read_from_network() + await self.read_from_network(count) + + async def read_from_network(self, target_count): + while self.outputbuffer.remaining() < target_count: - async def read_from_network(self): - while True: chunk = await self.raw_reader.read(32768) # Read in chunks; we'll only get what's available # print(f"Read {len(chunk)} bytes from network") if not chunk: raise asyncio.CancelledError("Connection closed") - self.inputbuffer.extend(chunk) - - decompressor = self.decompressor.decompressobj() # single use decompressor - try: - decompressed_data = decompressor.decompress(self.inputbuffer) - if decompressed_data: - # write to the output buffer - self.outputbuffer = BytesIO(decompressed_data)# assume that previous reads emptied the buffer (no packets split across zstd frames) - self.remaining = len(decompressed_data) - # Save leftover bytes - self.inputbuffer = bytearray(decompressor.unused_data) - # print("Decompressed frame of size", len(decompressed_data)) - return + try: + self.decompressor.write(chunk) except zstd.ZstdError: - continue # Continue reading if the frame is not complete + print("Zstd error, dropping connection") + raise asyncio.CancelledError("Error in compressed data stream!") + +class NonSeekableMemoryStream(io.RawIOBase): + def __init__(self): + self.buffer = bytearray() + self.read_pos = 0 + self.write_pos = 0 + + def write(self, b): + self.buffer.extend(b) + self.write_pos += len(b) + return len(b) + + def read(self, size=-1): + if size == -1 or size > self.write_pos - self.read_pos: + size = self.write_pos - self.read_pos + if size == 0: + return b'' + data = self.buffer[self.read_pos:self.read_pos + size] + self.read_pos += size + if self.read_pos == self.write_pos: + self.buffer = bytearray() + self.read_pos = 0 + self.write_pos = 0 + return bytes(data) + + def remaining(self): + return self.write_pos - self.read_pos + + def readable(self): + return True + + def writable(self): + return True \ No newline at end of file From c4da682d8b3ff1a09b89cb59aa53a256b128ed4c Mon Sep 17 00:00:00 2001 From: eric vz Date: Wed, 21 Aug 2024 00:33:33 -0500 Subject: [PATCH 15/18] don't debuglog the protocol response packet --- plugins/opensb_detector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/opensb_detector.py b/plugins/opensb_detector.py index 10c8d84..23914c9 100644 --- a/plugins/opensb_detector.py +++ b/plugins/opensb_detector.py @@ -20,7 +20,7 @@ async def activate(self): await super().activate() async def on_protocol_response(self, data, connection): - self.logger.debug("Received protocol response: {} from connection {}".format(data, connection)) + # self.logger.debug("Received protocol response: {} from connection {}".format(data, connection)) if data["parsed"]["info"]["compression"] == "Zstd": self.logger.info("Detected Zstd compression. Setting server configuration.") connection.start_zstd() From 80a7ece578c9e88f1969ae7520c6ec8fc166e431 Mon Sep 17 00:00:00 2001 From: eric vz Date: Sat, 19 Oct 2024 21:34:14 -0500 Subject: [PATCH 16/18] remove starjson as it is redundant with variant --- data_parser.py | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/data_parser.py b/data_parser.py index 72af39b..aa85177 100644 --- a/data_parser.py +++ b/data_parser.py @@ -336,46 +336,6 @@ def _parse(cls, stream: BytesIO, ctx: OrderedDict): def _build(cls, obj, ctx: OrderedDotDict): return StarByteArray.build(obj.encode("utf-8"), ctx) -class StarJson(Struct): - @classmethod - def _parse(cls, stream: BytesIO, ctx: OrderedDict): - - type_index = Byte.parse(stream, ctx) - if type_index > 0: - type_index -= 1 - - match type_index: - case 1: - return BFloat32.parse(stream, ctx) - case 2: - return Flag.parse(stream, ctx) - case 3: - return SignedVLQ.parse(stream, ctx) - case 4: - return StarString.parse(stream, ctx) - case 5: - l = VLQ.parse(stream, ctx) - c = [] - for _ in range(l): - c.append(StarJson.parse(stream, ctx)) - return c - case 6: - data = {} - l = VLQ.parse(stream, ctx) - for _ in range(l): - key = StarString.parse(stream, ctx) - value = StarJson.parse(stream, ctx) - data[key] = value - return data - case _: - return None # Invalid - - - @classmethod - def _build(cls, obj, ctx: OrderedDotDict): - raise NotImplementedError - - class Byte(Struct): @classmethod def _parse(cls, stream: BytesIO, ctx: OrderedDict): @@ -787,7 +747,7 @@ class ProtocolRequest(Struct): class ProtocolResponse(Struct): """packet type 1 """ server_response = Byte - info = StarJson + info = Variant class ServerDisconnect(Struct): From 151265dd97fe06734dba643981b57553f80ad4ad Mon Sep 17 00:00:00 2001 From: eric vz Date: Sat, 19 Oct 2024 21:42:00 -0500 Subject: [PATCH 17/18] eliminate error message in opensb detector --- plugins/opensb_detector.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/opensb_detector.py b/plugins/opensb_detector.py index 23914c9..04ec1a8 100644 --- a/plugins/opensb_detector.py +++ b/plugins/opensb_detector.py @@ -21,7 +21,8 @@ async def activate(self): async def on_protocol_response(self, data, connection): # self.logger.debug("Received protocol response: {} from connection {}".format(data, connection)) - if data["parsed"]["info"]["compression"] == "Zstd": + info = data["parsed"].get("info") + if info != None and info["compression"] == "Zstd": self.logger.info("Detected Zstd compression. Setting server configuration.") connection.start_zstd() return True From eefe6f4a8e37224be72c2c135f43fc6ec247da60 Mon Sep 17 00:00:00 2001 From: eric vz Date: Sat, 19 Oct 2024 21:49:50 -0500 Subject: [PATCH 18/18] add dependabot configuration --- .github/dependabot.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/dependabot.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..715bc4e --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,14 @@ +version: 2 +updates: + - package-ecosystem: "docker" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "monthly" + - package-ecosystem: "pip" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "monthly" + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "monthly" \ No newline at end of file