Display responses to cvars the user queries from the console
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
This commit is contained in:
@@ -20,6 +20,7 @@ QUIT_CONFIRM_TIMEOUT = 3.0 # Seconds to confirm quit (Ctrl-C twice)
|
|||||||
RESPAWN_DELAY = 3.0 # Seconds before players respawn after death
|
RESPAWN_DELAY = 3.0 # Seconds before players respawn after death
|
||||||
STATUS_OUTPUT_WINDOW = 1.5 # Seconds a 'status' command echo suppresses its chunked table output
|
STATUS_OUTPUT_WINDOW = 1.5 # Seconds a 'status' command echo suppresses its chunked table output
|
||||||
STATUS_SEED_WINDOW = 2.0 # Seconds the roster seeder collects the 'status' dump after connect
|
STATUS_SEED_WINDOW = 2.0 # Seconds the roster seeder collects the 'status' dump after connect
|
||||||
|
CVAR_RESPONSE_TTL = 10.0 # Seconds a user-queried cvar response may arrive after the query
|
||||||
STATS_CONNECTION_DELAY = 0.5 # Initial stats connection delay
|
STATS_CONNECTION_DELAY = 0.5 # Initial stats connection delay
|
||||||
|
|
||||||
# UI dimensions
|
# UI dimensions
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import signal
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from lib.constants import VERSION, DEFAULT_HOST, POLL_TIMEOUT, QUIT_CONFIRM_TIMEOUT, RESPAWN_DELAY, MAX_COMMAND_HISTORY, STATUS_OUTPUT_WINDOW, STATUS_SEED_WINDOW
|
from lib.constants import VERSION, DEFAULT_HOST, POLL_TIMEOUT, QUIT_CONFIRM_TIMEOUT, RESPAWN_DELAY, MAX_COMMAND_HISTORY, STATUS_OUTPUT_WINDOW, STATUS_SEED_WINDOW, CVAR_RESPONSE_TTL
|
||||||
from lib.state import GameState
|
from lib.state import GameState
|
||||||
from lib.network import RconConnection, StatsConnection
|
from lib.network import RconConnection, StatsConnection
|
||||||
from lib.parser import EventParser
|
from lib.parser import EventParser
|
||||||
@@ -43,6 +43,7 @@ STATUS_ROW_PATTERN = re.compile(
|
|||||||
ROSTER_CHAT_GUARD_PATTERN = re.compile(r'^.{1,40}:\s')
|
ROSTER_CHAT_GUARD_PATTERN = re.compile(r'^.{1,40}:\s')
|
||||||
VOTE_CAST_PATTERN = re.compile(r'^(.+?) voted for (.+)\.$')
|
VOTE_CAST_PATTERN = re.compile(r'^(.+?) voted for (.+)\.$')
|
||||||
CHAT_SHAPE_PATTERN = re.compile(r'^[\w(][^:]*:\s')
|
CHAT_SHAPE_PATTERN = re.compile(r'^[\w(][^:]*:\s')
|
||||||
|
CVAR_QUERY_PATTERN = re.compile(r'^[A-Za-z_][A-Za-z0-9_]*$')
|
||||||
GAME_END_PATTERN = re.compile(
|
GAME_END_PATTERN = re.compile(
|
||||||
r'((?:timelimit|fraglimit|capturelimit|roundlimit)\s+hit'
|
r'((?:timelimit|fraglimit|capturelimit|roundlimit)\s+hit'
|
||||||
r'|hit\s+the\s+(?:timelimit|fraglimit|capturelimit|roundlimit)'
|
r'|hit\s+the\s+(?:timelimit|fraglimit|capturelimit|roundlimit)'
|
||||||
@@ -72,6 +73,16 @@ quit_confirm_time = None
|
|||||||
_QUIT_CONFIRM_TIMEOUT = QUIT_CONFIRM_TIMEOUT
|
_QUIT_CONFIRM_TIMEOUT = QUIT_CONFIRM_TIMEOUT
|
||||||
_RESPAWN_DELAY = RESPAWN_DELAY
|
_RESPAWN_DELAY = RESPAWN_DELAY
|
||||||
|
|
||||||
|
# Cvars the user queried from the console (lowercased name -> request time):
|
||||||
|
# their responses display verbatim; everything else stays suppressed
|
||||||
|
expected_cvar_responses = {}
|
||||||
|
|
||||||
|
|
||||||
|
def consume_expected_cvar(cvar_name):
|
||||||
|
"""True when the user queried this cvar from the console recently"""
|
||||||
|
requested_at = expected_cvar_responses.pop(cvar_name.lower(), None)
|
||||||
|
return requested_at is not None and (time.time() - requested_at) < CVAR_RESPONSE_TTL
|
||||||
|
|
||||||
# Global shutdown flag (set by handle_ctrl_c, checked by main_loop)
|
# Global shutdown flag (set by handle_ctrl_c, checked by main_loop)
|
||||||
shutdown_requested = False
|
shutdown_requested = False
|
||||||
|
|
||||||
@@ -102,21 +113,28 @@ def handle_ctrl_c():
|
|||||||
|
|
||||||
def parse_cvar_response(message, game_state, ui):
|
def parse_cvar_response(message, game_state, ui):
|
||||||
"""
|
"""
|
||||||
Parse server cvar responses and update state
|
Parse server cvar responses: update state for known cvars, and display the
|
||||||
Returns True if message should be suppressed from display
|
response when the user queried it from the console. Returns True when the
|
||||||
|
message is consumed (known-cvar update or a displayed query result).
|
||||||
"""
|
"""
|
||||||
# Parse cvar responses (format: "cvar_name" is:"value" default:...)
|
match = CVAR_RESPONSE_PATTERN.search(message)
|
||||||
cvar_match = CVAR_RESPONSE_PATTERN.search(message)
|
if not match:
|
||||||
if cvar_match:
|
|
||||||
cvar_name = cvar_match.group(1)
|
|
||||||
value = cvar_match.group(2)
|
|
||||||
|
|
||||||
if game_state.server_info.update_from_cvar(cvar_name, value):
|
|
||||||
ui.update_server_info(game_state)
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
cvar_name = match.group(1)
|
||||||
|
value = match.group(2)
|
||||||
|
|
||||||
|
state_updated = game_state.server_info.update_from_cvar(cvar_name, value)
|
||||||
|
if state_updated:
|
||||||
|
ui.update_server_info(game_state)
|
||||||
|
|
||||||
|
displayed = consume_expected_cvar(cvar_name)
|
||||||
|
if displayed:
|
||||||
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
|
ui.print_message(f"^3[^7{timestamp}^3]^7 {message.rstrip()}\n")
|
||||||
|
|
||||||
|
return state_updated or displayed
|
||||||
|
|
||||||
|
|
||||||
def is_command_echo(message):
|
def is_command_echo(message):
|
||||||
"""True for the server's echo lines announcing that an RCON client sent a command"""
|
"""True for the server's echo lines announcing that an RCON client sent a command"""
|
||||||
@@ -356,6 +374,11 @@ def handle_user_input(ui, rcon):
|
|||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
ui.print_message(f"^3[^7{timestamp}^3]^7 Server: {stripped[4:]}\n")
|
ui.print_message(f"^3[^7{timestamp}^3]^7 Server: {stripped[4:]}\n")
|
||||||
|
|
||||||
|
# A bare cvar name queries its value; the response displays verbatim
|
||||||
|
# when it arrives (other clients' query output stays suppressed)
|
||||||
|
if CVAR_QUERY_PATTERN.match(stripped):
|
||||||
|
expected_cvar_responses[stripped.lower()] = time.time()
|
||||||
|
|
||||||
|
|
||||||
def handle_stats_stream(stats_conn, stats_check_counter, event_parser, ui, game_state):
|
def handle_stats_stream(stats_conn, stats_check_counter, event_parser, ui, game_state):
|
||||||
"""Poll and process stats stream events"""
|
"""Poll and process stats stream events"""
|
||||||
|
|||||||
Reference in New Issue
Block a user