From f1ed9c3d2cb8c25d7c8b6398d145c7e62089c148 Mon Sep 17 00:00:00 2001 From: pfl Date: Fri, 9 Jan 2026 15:02:03 +0100 Subject: [PATCH] Add UI test mode script --- test_ui.py | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100755 test_ui.py diff --git a/test_ui.py b/test_ui.py new file mode 100755 index 0000000..f86fac3 --- /dev/null +++ b/test_ui.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +""" +Test mode for QLPyCon - Simulates game events to test UI +Run with: python3 test_ui.py +""" + +import curses +import time +import json +import logging +import queue +import threading +import sys + +from config import VERSION +from state import GameState +from parser import EventParser +from ui import UIManager + +logger = logging.getLogger('test_ui') + +def simulate_game_events(game_state, parser, ui): + """Simulate game events for testing""" + + # Wait for UI to initialize + time.sleep(1) + + ui.print_message("=== TEST MODE - SIMULATING GAME EVENTS ===\n") + ui.print_message(f"QLPyCon {VERSION} Test Mode\n\n") + + # Event 1: Match start + time.sleep(2) + event = { + "TYPE": "MATCH_STARTED", + "DATA": { + "TIME": 0, + "PLAYERS": [ + {"NAME": "^1RedWarrior"}, + {"NAME": "^4BlueSniper"} + ] + } + } + result = parser.parse_event(json.dumps(event)) + if result: + ui.print_message(result) + ui.update_server_info(game_state) + + # Event 2: Players join teams + time.sleep(2) + event = { + "TYPE": "PLAYER_SWITCHTEAM", + "DATA": { + "TIME": 5, + "KILLER": { + "NAME": "^1RedWarrior", + "TEAM": "RED", + "OLD_TEAM": "SPECTATOR" + } + } + } + result = parser.parse_event(json.dumps(event)) + if result: + ui.print_message(result) + ui.update_server_info(game_state) + + time.sleep(1) + event = { + "TYPE": "PLAYER_SWITCHTEAM", + "DATA": { + "TIME": 6, + "KILLER": { + "NAME": "^4BlueSniper", + "TEAM": "BLUE", + "OLD_TEAM": "SPECTATOR" + } + } + } + result = parser.parse_event(json.dumps(event)) + if result: + ui.print_message(result) + ui.update_server_info(game_state) + + # Event 3: Some kills + for i in range(10): + time.sleep(3) + match_time = 10 + (i * 5) + + event = { + "TYPE": "PLAYER_DEATH", + "DATA": { + "TIME": match_time, + "KILLER": { + "NAME": "^1RedWarrior", + "TEAM": "RED", + "WEAPON": ["ROCKET", "RAILGUN", "LIGHTNING"][i % 3], + "HEALTH": 100 - (i * 10) + }, + "VICTIM": { + "NAME": "^4BlueSniper", + "TEAM": "BLUE" + } + } + } + result = parser.parse_event(json.dumps(event)) + if result: + ui.print_message(result) + ui.update_server_info(game_state) + + # Counter-kill + time.sleep(2) + event = { + "TYPE": "PLAYER_DEATH", + "DATA": { + "TIME": match_time + 2, + "KILLER": { + "NAME": "^4BlueSniper", + "TEAM": "BLUE", + "WEAPON": ["PLASMA", "GRENADE", "SHOTGUN"][i % 3], + "HEALTH": 50 + }, + "VICTIM": { + "NAME": "^1RedWarrior", + "TEAM": "RED" + } + } + } + result = parser.parse_event(json.dumps(event)) + if result: + ui.print_message(result) + ui.update_server_info(game_state) + + # Event 4: Chat messages + time.sleep(2) + ui.print_message("^1RedWarrior^7: ^2gg!\n") + time.sleep(1) + ui.print_message("^4BlueSniper^7: ^2nice shots\n") + + # Event 5: Medal + time.sleep(2) + event = { + "TYPE": "PLAYER_MEDAL", + "DATA": { + "TIME": 120, + "NAME": "^1RedWarrior", + "MEDAL": "EXCELLENT" + } + } + result = parser.parse_event(json.dumps(event)) + if result: + ui.print_message(result) + + # Event 6: Match end + time.sleep(3) + event = { + "TYPE": "MATCH_REPORT", + "DATA": { + "TIME": 180, + "TSCORE0": "12", + "TSCORE1": "8" + } + } + result = parser.parse_event(json.dumps(event)) + if result: + ui.print_message(result) + ui.update_server_info(game_state) + + ui.print_message("\n=== TEST COMPLETE ===\n") + ui.print_message("Press Ctrl-C twice to quit\n") + +def test_main(screen): + """Main test loop""" + + # Initialize UI + ui = UIManager(screen, "tcp://127.0.0.1:27961 [TEST MODE]") + + # Setup logging + log_handler = ui.setup_logging() + logger.addHandler(log_handler) + logger.setLevel(logging.INFO) + + # Initialize game state + game_state = GameState() + + # Set some initial server info + game_state.server_info.hostname = "^3Test Server [Demo Mode]" + game_state.server_info.map = "bloodrun" + game_state.server_info.gametype = "Team Deathmatch" + game_state.server_info.timelimit = "10" + game_state.server_info.fraglimit = "50" + game_state.server_info.maxclients = "16" + + ui.update_server_info(game_state) + + # Create parser + parser = EventParser(game_state) + + # Display startup message + ui.print_message(f"*** QL pyCon Version {VERSION} - TEST MODE ***\n") + ui.print_message("This mode simulates game events to test the UI\n") + ui.print_message("Watch the timer tick in real-time!\n\n") + + # Start event simulation in background thread + sim_thread = threading.Thread( + target=simulate_game_events, + args=(game_state, parser, ui), + daemon=True + ) + sim_thread.start() + + # Setup input queue (even though we won't use it much) + input_queue = ui.setup_input_queue() + + # Main loop - just keep updating UI + try: + while True: + # Update server info display (this will show live timer) + ui.update_server_info(game_state) + + # Process any user input + while not input_queue.empty(): + command = input_queue.get() + ui.print_message(f">>> {command}\n") + ui.print_message("[Test mode: commands not sent to server]\n") + + time.sleep(0.1) # Update 10 times per second + + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + try: + curses.wrapper(test_main) + except KeyboardInterrupt: + print("\nTest mode exited.")