diff --git a/main.py b/main.py index 6f4c364..9ce7d1b 100644 --- a/main.py +++ b/main.py @@ -34,9 +34,9 @@ DISCONNECT_PATTERN = re.compile(r'^(.+?)\s+disconnected') KICK_PATTERN = re.compile(r'^(.+?)\s+was kicked') INACTIVITY_PATTERN = re.compile(r'^(.+?)\s+Dropped due to inactivity') RENAME_PATTERN = re.compile(r'^(.+?)\s+renamed to\s+(.+?)$') -STATUS_ROW_PATTERN = re.compile(r'^\s*\d+\s+\S.*\s\d{15,}\s*$', re.MULTILINE) -STATUS_SEP_PATTERN = re.compile(r'^--- -----', re.MULTILINE) +STATUS_HEAD_PATTERN = re.compile(r'^\s*\d+\s+-?\d+\s+(bot|\d+)\s+\S', re.MULTILINE) STATUS_MAP_PATTERN = re.compile(r'^map:\s+\S+\s*$', re.MULTILINE) +STEAMID_PATTERN = re.compile(r'\b\d{16,}\b') # Configure logging logger = logging.getLogger('main') @@ -113,15 +113,23 @@ def is_command_output(message): Detect console output produced by RCON commands: cvar dumps and status tables. These are hidden; the 'zmq RCON command' echo lines still show which client ran what. Shape checks run on color-stripped text because - the server sprinkles Quake color codes into status rows. + the server sprinkles Quake color codes into status rows. Rows also arrive + broadcast-wrapped or split across several messages, so the checks are + containment-based and a row fragment (head without steamid, tail without + row prefix) is caught too. JSON stats events are exempt: they contain + 16+ digit STEAM_IDs and are handled by the event parser. """ clean = strip_color_codes(message) + stripped = clean.lstrip() + if stripped[:1] in ('{', '['): + return False if CVAR_RESPONSE_PATTERN.search(clean): return True - if 'num score ping' in clean: + if 'num score ping' in clean or '--- -----' in clean: return True - if (STATUS_ROW_PATTERN.search(clean) or STATUS_SEP_PATTERN.search(clean) - or STATUS_MAP_PATTERN.search(clean)): + if STEAMID_PATTERN.search(clean) or STATUS_HEAD_PATTERN.search(clean): + return True + if STATUS_MAP_PATTERN.search(clean): return True return False