updayz
This commit is contained in:
94
qlpycon.py
94
qlpycon.py
@ -15,6 +15,10 @@ import logging
|
||||
logger = logging.getLogger('logger')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
# Separate logger for all JSON events when --json flag is used
|
||||
all_json_logger = logging.getLogger('all_json')
|
||||
all_json_logger.setLevel(logging.DEBUG)
|
||||
|
||||
# Separate logger for unknown JSON events
|
||||
unknown_json_logger = logging.getLogger('unknown_json')
|
||||
unknown_json_logger.setLevel(logging.DEBUG)
|
||||
@ -246,12 +250,80 @@ def get_team_color(player_name):
|
||||
'SPECTATOR': '^3(SPEC)^7'
|
||||
}.get(team, '')
|
||||
|
||||
def format_powerup_message(msg_str):
|
||||
"""Format powerup pickup and kill messages with colors"""
|
||||
|
||||
if msg_str.startswith("broadcast:"):
|
||||
msg_str = msg_str[11:].strip()
|
||||
|
||||
# Check for powerup pickup: "PlayerName got the PowerupName!"
|
||||
pickup_match = re.match(r'^(.+?)\s+got the\s+(.+?)!', msg_str)
|
||||
if pickup_match:
|
||||
player_name = pickup_match.group(1).strip()
|
||||
powerup_name = pickup_match.group(2).strip()
|
||||
|
||||
# Get team color for player
|
||||
player_clean = re.sub(r'\^\d', '', player_name)
|
||||
team_prefix = get_team_color(player_clean)
|
||||
|
||||
# Color code powerups
|
||||
powerup_colors = {
|
||||
'Quad Damage': '^5Quad Damage^7',
|
||||
'Battle Suit': '^3Battle Suit^7',
|
||||
'Regeneration': '^1Regeneration^7',
|
||||
'Haste': '^3Haste^7',
|
||||
'Invisibility': '^5Invisibility^7',
|
||||
'Flight': '^5Flight^7',
|
||||
'Medkit': '^1Medkit^7',
|
||||
'MegaHealth': '^4MegaHealth^7'
|
||||
}
|
||||
|
||||
colored_powerup = powerup_colors.get(powerup_name, f'^6{powerup_name}^7')
|
||||
|
||||
return f"{team_prefix}{player_name} ^7got the {colored_powerup}!\n"
|
||||
|
||||
# Check for powerup carrier kill: "PlayerName killed the PowerupName carrier!"
|
||||
carrier_match = re.match(r'^(.+?)\s+killed the\s+(.+?)\s+carrier!', msg_str)
|
||||
if carrier_match:
|
||||
player_name = carrier_match.group(1).strip()
|
||||
powerup_name = carrier_match.group(2).strip()
|
||||
|
||||
# Get team color for player
|
||||
player_clean = re.sub(r'\^\d', '', player_name)
|
||||
team_prefix = get_team_color(player_clean)
|
||||
|
||||
# Color code powerups (same as above)
|
||||
powerup_colors = {
|
||||
'Quad Damage': '^5Quad Damage^7',
|
||||
'Battle Suit': '^3Battle Suit^7',
|
||||
'Regeneration': '^1Regeneration^7',
|
||||
'Haste': '^3Haste^7',
|
||||
'Invisibility': '^5Invisibility^7',
|
||||
'Flight': '^5Flight^7',
|
||||
'Medkit': '^1Medkit^7',
|
||||
'MegaHealth': '^4MegaHealth^7'
|
||||
}
|
||||
|
||||
colored_powerup = powerup_colors.get(powerup_name, f'^6{powerup_name}^7')
|
||||
|
||||
return f"{team_prefix}{player_name} ^7killed the {colored_powerup} ^7carrier!\n"
|
||||
|
||||
# Not a powerup message
|
||||
return None
|
||||
|
||||
def ParseGameEvent(message):
|
||||
"""Parse JSON game events and return formatted message"""
|
||||
global current_gametype, recent_events
|
||||
|
||||
try:
|
||||
jObject = json.loads(message)
|
||||
|
||||
# Log ALL JSON events to file if --json flag was provided
|
||||
if all_json_logger.handlers:
|
||||
all_json_logger.info('JSON Event received:')
|
||||
all_json_logger.info(json.dumps(jObject, indent=2))
|
||||
all_json_logger.info('---')
|
||||
|
||||
if 'TYPE' not in jObject or 'DATA' not in jObject:
|
||||
logger.debug('JSON missing TYPE or DATA fields')
|
||||
return None
|
||||
@ -279,7 +351,7 @@ def ParseGameEvent(message):
|
||||
recent_events.pop(0)
|
||||
|
||||
warmup = data.get('WARMUP', False)
|
||||
warmup_suffix = " ^7(^3warmup^7)" if warmup else ""
|
||||
warmup_suffix = " ^3(warmup)" if warmup else ""
|
||||
|
||||
if event_type == 'PLAYER_SWITCHTEAM':
|
||||
if 'KILLER' not in data:
|
||||
@ -366,7 +438,7 @@ def ParseGameEvent(message):
|
||||
}
|
||||
weapon_name = weapon_names.get(weapon, 'the %s' % weapon)
|
||||
|
||||
return "%s%s ^8fragged^7 %s%s ^7with %s%s\n" % (
|
||||
return "%s%s ^7fragged^7 %s%s ^7with %s%s\n" % (
|
||||
killer_team_prefix, killer_name,
|
||||
victim_team_prefix, victim_name,
|
||||
weapon_name, warmup_suffix
|
||||
@ -459,6 +531,7 @@ def InitWindows(screen, args):
|
||||
curses.initscr()
|
||||
screen.nodelay(1)
|
||||
curses.start_color()
|
||||
curses.use_default_colors()
|
||||
curses.cbreak()
|
||||
curses.setsyx(-1, -1)
|
||||
screen.addstr("Quake Live rcon: %s" % args.host)
|
||||
@ -514,6 +587,7 @@ def main(screen):
|
||||
parser.add_argument( '--identity', default = uuid.uuid1().hex, help = 'Specify the socket identity. Random UUID used by default' )
|
||||
parser.add_argument( '-v', '--verbose', action='count', default=0, help = 'Increase verbosity (use -v for INFO, -vv for DEBUG)' )
|
||||
parser.add_argument( '--unknown-log', default='unknown_events.log', help = 'File to log unknown JSON events. Defaults to unknown_events.log' )
|
||||
parser.add_argument('--json', '-j', dest='json_log', default=None, help='File to log all JSON events. If specified, all JSON messages from server will be captured')
|
||||
args = parser.parse_args()
|
||||
|
||||
# Set logging level based on verbosity
|
||||
@ -689,6 +763,15 @@ def main(screen):
|
||||
|
||||
stats_connected = True
|
||||
PrintMessageFormatted(output_window, "Stats stream connected - ready for game events\n")
|
||||
|
||||
# Set up file handler for all JSON events if --json flag is provided
|
||||
if args.json_log:
|
||||
json_file_handler = logging.FileHandler(args.json_log, mode='a')
|
||||
json_file_formatter = logging.Formatter('%(asctime)s - %(message)s', '%Y-%m-%d %H:%M:%S')
|
||||
json_file_handler.setFormatter(json_file_formatter)
|
||||
all_json_logger.addHandler(json_file_handler)
|
||||
all_json_logger.propagate = False
|
||||
PrintMessageFormatted(output_window, f"*** JSON capture enabled: {args.json_log} ***\n")
|
||||
except Exception as e:
|
||||
timestamp = time.strftime('%H:%M:%S')
|
||||
PrintMessageFormatted(output_window, f"^1[^7{timestamp}^1] Error: Stats connection failed: {e}^7\n", add_timestamp=False)
|
||||
@ -728,6 +811,13 @@ def main(screen):
|
||||
# It's JSON but we didn't parse it - already logged to file
|
||||
logger.debug('Unparsed JSON event')
|
||||
else:
|
||||
# Check for powerup messages
|
||||
formatted_powerup = format_powerup_message(msg_str)
|
||||
if formatted_powerup:
|
||||
PrintMessageFormatted(output_window, formatted_powerup)
|
||||
curses.setsyx(y,x)
|
||||
curses.doupdate()
|
||||
continue
|
||||
# Not JSON - check if it's a bot debug message (filter unless verbose)
|
||||
is_bot_debug = ' entered ' in msg_str and (' seek ' in msg_str or ' battle ' in msg_str or ' chase' in msg_str or ' fight' in msg_str)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user