changey
This commit is contained in:
60
config.py
60
config.py
@ -46,48 +46,48 @@ TEAM_COLORS = {
|
|||||||
|
|
||||||
# Weapon names
|
# Weapon names
|
||||||
WEAPON_NAMES = {
|
WEAPON_NAMES = {
|
||||||
'ROCKET': 'Rocket Launcher',
|
'ROCKET': '^8^1Rocket Launcher^7^0',
|
||||||
'LIGHTNING': 'Lightning Gun',
|
'LIGHTNING': '^8^3Lightning Gun^7^0',
|
||||||
'RAILGUN': 'Railgun',
|
'RAILGUN': '^8^2Railgun^7^0',
|
||||||
'SHOTGUN': 'Shotgun',
|
'SHOTGUN': '^8^3Shotgun^7^0',
|
||||||
'GAUNTLET': 'Gauntlet',
|
'GAUNTLET': '^8^1Gauntlet^7^0',
|
||||||
'GRENADE': 'Grenade Launcher',
|
'GRENADE': '^8^2Grenade Launcher^7^0',
|
||||||
'PLASMA': 'Plasma Gun',
|
'PLASMA': '^8^6Plasma Gun^7^0',
|
||||||
'MACHINEGUN': 'Machine Gun'
|
'MACHINEGUN': '^8^3Machine Gun^7^0'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Weapon names for kill messages
|
# Weapon names for kill messages
|
||||||
WEAPON_KILL_NAMES = {
|
WEAPON_KILL_NAMES = {
|
||||||
'ROCKET': 'the Rocket Launcher',
|
'ROCKET': 'the ^8^1Rocket Launcher',
|
||||||
'LIGHTNING': 'the Lightning Gun',
|
'LIGHTNING': 'the ^8^3Lightning Gun',
|
||||||
'RAILGUN': 'the Railgun',
|
'RAILGUN': 'the ^8^2Railgun',
|
||||||
'SHOTGUN': 'the Shotgun',
|
'SHOTGUN': 'the ^8^3Shotgun',
|
||||||
'GAUNTLET': 'the Gauntlet',
|
'GAUNTLET': 'the ^8^1Gauntlet',
|
||||||
'GRENADE': 'the Grenade Launcher',
|
'GRENADE': 'the ^8^2Grenade Launcher',
|
||||||
'PLASMA': 'the Plasma Gun',
|
'PLASMA': 'the ^8^6Plasma Gun',
|
||||||
'MACHINEGUN': 'the Machine Gun'
|
'MACHINEGUN': 'the ^8^3Machine Gun'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Death messages
|
# Death messages
|
||||||
DEATH_MESSAGES = {
|
DEATH_MESSAGES = {
|
||||||
'FALLING': "%s^0%s^9 ^7cratered.",
|
'FALLING': "%s^8%s^0 ^7cratered.",
|
||||||
'HURT': "%s^0%s^9 ^7was in the wrong place.",
|
'HURT': "%s^8%s^0 ^7was in the wrong place.",
|
||||||
'LAVA': "%s^0%s^9 ^7does a backflip into the lava.",
|
'LAVA': "%s^8%s^0 ^7does a backflip into the lava.",
|
||||||
'WATER': "%s^0%s^9 ^7sank like a rock.",
|
'WATER': "%s^8%s^0 ^7sank like a rock.",
|
||||||
'SLIME': "%s^0%s^9 ^7melted.",
|
'SLIME': "%s^8%s^0 ^7melted.",
|
||||||
'CRUSH': "%s^0%s^9 ^7was crushed."
|
'CRUSH': "%s^8%s^0 ^7was crushed."
|
||||||
}
|
}
|
||||||
|
|
||||||
# Powerup names and colors
|
# Powerup names and colors
|
||||||
POWERUP_COLORS = {
|
POWERUP_COLORS = {
|
||||||
'Quad Damage': '^5Quad Damage^7',
|
'Quad Damage': '^8^5Quad Damage^7^0',
|
||||||
'Battle Suit': '^3Battle Suit^7',
|
'Battle Suit': '^8^3Battle Suit^7^0',
|
||||||
'Regeneration': '^1Regeneration^7',
|
'Regeneration': '^8^1Regeneration^7^0',
|
||||||
'Haste': '^3Haste^7',
|
'Haste': '^8^3Haste^7^0',
|
||||||
'Invisibility': '^5Invisibility^7',
|
'Invisibility': '^8^5Invisibility^7^0',
|
||||||
'Flight': '^5Flight^7',
|
'Flight': '^8^5Flight^7^0',
|
||||||
'Medkit': '^1Medkit^7',
|
'Medkit': '^8^1Medkit^7^0',
|
||||||
'MegaHealth': '^4MegaHealth^7'
|
'MegaHealth': '^8^4MegaHealth^7^0'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Curses color pairs
|
# Curses color pairs
|
||||||
|
|||||||
10
formatter.py
10
formatter.py
@ -137,7 +137,7 @@ def format_chat_message(message, player_tracker):
|
|||||||
player_name = strip_color_codes(name_match.group(1).strip())
|
player_name = strip_color_codes(name_match.group(1).strip())
|
||||||
team_prefix = get_team_prefix(player_name, player_tracker)
|
team_prefix = get_team_prefix(player_name, player_tracker)
|
||||||
location_clean = strip_color_codes(location_part)
|
location_clean = strip_color_codes(location_part)
|
||||||
return f"{team_prefix}^0{player_part}^9 ^3{location_clean}^7:^5{message_part}"
|
return f"{team_prefix}^8{player_part}^0 ^3{location_clean}^7:^5{message_part}"
|
||||||
|
|
||||||
# Team chat without location: (PlayerName): message
|
# Team chat without location: (PlayerName): message
|
||||||
colon_match = re.match(r'^(\([^)]+\)):(\s*.*)', clean_msg)
|
colon_match = re.match(r'^(\([^)]+\)):(\s*.*)', clean_msg)
|
||||||
@ -149,7 +149,7 @@ def format_chat_message(message, player_tracker):
|
|||||||
if name_match:
|
if name_match:
|
||||||
player_name = strip_color_codes(name_match.group(1).strip())
|
player_name = strip_color_codes(name_match.group(1).strip())
|
||||||
team_prefix = get_team_prefix(player_name, player_tracker)
|
team_prefix = get_team_prefix(player_name, player_tracker)
|
||||||
return f"{team_prefix}^0{player_part}^9^5{message_part}\n"
|
return f"{team_prefix}^8{player_part}^0^5{message_part}\n"
|
||||||
|
|
||||||
# Regular chat: PlayerName: message
|
# Regular chat: PlayerName: message
|
||||||
parts = clean_msg.split(':', 1)
|
parts = clean_msg.split(':', 1)
|
||||||
@ -160,7 +160,7 @@ def format_chat_message(message, player_tracker):
|
|||||||
# Preserve original color-coded name
|
# Preserve original color-coded name
|
||||||
original_parts = message.replace(chr(25), '').split(':', 1)
|
original_parts = message.replace(chr(25), '').split(':', 1)
|
||||||
if len(original_parts) == 2:
|
if len(original_parts) == 2:
|
||||||
return f"{team_prefix}^0{original_parts[0]}^9:^2{original_parts[1]}"
|
return f"{team_prefix}^8{original_parts[0]}^0:^2{original_parts[1]}"
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
@ -193,7 +193,7 @@ def format_powerup_message(message, player_tracker):
|
|||||||
|
|
||||||
colored_powerup = POWERUP_COLORS.get(powerup_name, f'^6{powerup_name}^7')
|
colored_powerup = POWERUP_COLORS.get(powerup_name, f'^6{powerup_name}^7')
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
return f"^3[^7{timestamp}^3]^7 {team_prefix}^0{player_name}^9 ^7got the {colored_powerup}!\n"
|
return f"^3[^7{timestamp}^3]^7 {team_prefix}^8{player_name}^0 ^7got the {colored_powerup}!\n"
|
||||||
|
|
||||||
# Powerup carrier kill: "PlayerName killed the PowerupName carrier!"
|
# Powerup carrier kill: "PlayerName killed the PowerupName carrier!"
|
||||||
carrier_match = re.match(r'^(.+?)\s+killed the\s+(.+?)\s+carrier!', message)
|
carrier_match = re.match(r'^(.+?)\s+killed the\s+(.+?)\s+carrier!', message)
|
||||||
@ -206,6 +206,6 @@ def format_powerup_message(message, player_tracker):
|
|||||||
|
|
||||||
colored_powerup = POWERUP_COLORS.get(powerup_name, f'^6{powerup_name}^7')
|
colored_powerup = POWERUP_COLORS.get(powerup_name, f'^6{powerup_name}^7')
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
return f"^3[^7{timestamp}^3]^7 {team_prefix}^0{player_name}^9 ^7killed the {colored_powerup} ^7carrier!\n"
|
return f"^3[^7{timestamp}^3]^7 {team_prefix}^8{player_name}^0 ^7killed the {colored_powerup} ^7carrier!\n"
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|||||||
16
main.py
16
main.py
@ -43,11 +43,11 @@ def signal_handler(sig, frame):
|
|||||||
|
|
||||||
if quit_confirm_time is None or (current_time - quit_confirm_time) > 3:
|
if quit_confirm_time is None or (current_time - quit_confirm_time) > 3:
|
||||||
# First Ctrl-C or timeout expired
|
# First Ctrl-C or timeout expired
|
||||||
logger.warning("^1^0Press Ctrl-C again within 3 seconds to quit^0")
|
logger.warning("^1^8Press Ctrl-C again within 3 seconds to quit^0")
|
||||||
quit_confirm_time = current_time
|
quit_confirm_time = current_time
|
||||||
else:
|
else:
|
||||||
# Second Ctrl-C within 3 seconds
|
# Second Ctrl-C within 3 seconds
|
||||||
logger.warning("^1^0Quittin'^9")
|
logger.warning("^1^8Quittin'^0")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def parse_cvar_response(message, game_state, ui):
|
def parse_cvar_response(message, game_state, ui):
|
||||||
@ -146,7 +146,7 @@ def parse_player_events(message, game_state, ui):
|
|||||||
# Only print if this is NOT the Steam ID line
|
# Only print if this is NOT the Steam ID line
|
||||||
if 'Steam ID' not in message:
|
if 'Steam ID' not in message:
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
ui.print_message(f"^3[^7{timestamp}^3]^7 ^0{player_name}^9 ^2connected^7\n")
|
ui.print_message(f"^3[^7{timestamp}^3]^7 ^8{player_name} ^9^2connected\n")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ def parse_player_events(message, game_state, ui):
|
|||||||
ui.update_server_info(game_state)
|
ui.update_server_info(game_state)
|
||||||
|
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
ui.print_message(f"^3[^7{timestamp}^3]^7 ^0{player_name}^9 ^1disconnected^7\n")
|
ui.print_message(f"^3[^7{timestamp}^3]^7 ^8{player_name} ^9^1disconnected\n")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Kick
|
# Kick
|
||||||
@ -179,7 +179,7 @@ def parse_player_events(message, game_state, ui):
|
|||||||
ui.update_server_info(game_state)
|
ui.update_server_info(game_state)
|
||||||
|
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
ui.print_message(f"^3[^7{timestamp}^3]^7 ^0{player_name}^9 ^1was kicked^7\n")
|
ui.print_message(f"^3[^7{timestamp}^3]^7 ^8{player_name} ^1was kicked\n")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Inactivity
|
# Inactivity
|
||||||
@ -195,7 +195,7 @@ def parse_player_events(message, game_state, ui):
|
|||||||
ui.update_server_info(game_state)
|
ui.update_server_info(game_state)
|
||||||
|
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
ui.print_message(f"^3[^7{timestamp}^3]^7 ^0{player_name}^9 ^3dropped due to inactivity^7\n")
|
ui.print_message(f"^3[^7{timestamp}^3]^7 ^8{player_name}^0 ^3dropped due to inactivity^7\n")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Match renames: "OldName renamed to NewName"
|
# Match renames: "OldName renamed to NewName"
|
||||||
@ -221,7 +221,7 @@ def parse_player_events(message, game_state, ui):
|
|||||||
game_state.player_tracker.rename_player(old_name, new_name)
|
game_state.player_tracker.rename_player(old_name, new_name)
|
||||||
ui.update_server_info(game_state)
|
ui.update_server_info(game_state)
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
ui.print_message(f"^3[^7{timestamp}^3]^7 ^0{old_name}^9 ^6renamed to^7 ^0{new_name}^9\n")
|
ui.print_message(f"^3[^7{timestamp}^3]^7 ^8{old_name} ^6renamed to^7 ^8{new_name}\n")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -374,7 +374,7 @@ def main_loop(screen):
|
|||||||
logger.info('Game initialization detected - refreshing server info')
|
logger.info('Game initialization detected - refreshing server info')
|
||||||
|
|
||||||
timestamp = time.strftime('%H:%M:%S')
|
timestamp = time.strftime('%H:%M:%S')
|
||||||
ui.print_message(f"^3[^7{timestamp}^3] ^0^3Game initialized - Refreshing server info^9^7\n")
|
ui.print_message(f"^3[^7{timestamp}^3] ^8^3Game initialized - Refreshing server info^0^7\n")
|
||||||
|
|
||||||
rcon.send_command(b'qlx_serverBrandName')
|
rcon.send_command(b'qlx_serverBrandName')
|
||||||
rcon.send_command(b'g_factoryTitle')
|
rcon.send_command(b'g_factoryTitle')
|
||||||
|
|||||||
59
parser.py
59
parser.py
@ -104,17 +104,17 @@ class EventParser:
|
|||||||
if team == old_team:
|
if team == old_team:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
warmup = " ^0^3(Warmup)^9" if data.get('WARMUP', False) else ""
|
warmup = " ^8^3(Warmup)^0" if data.get('WARMUP', False) else ""
|
||||||
|
|
||||||
team_messages = {
|
team_messages = {
|
||||||
'FREE': ' ^7joined the ^0fight^9',
|
'FREE': ' ^7joined the ^8fight^0',
|
||||||
'SPECTATOR': ' ^7joined the ^3Spectators^7',
|
'SPECTATOR': ' ^7joined the ^3Spectators^7',
|
||||||
'RED': ' ^7joined the ^1RED Team^7',
|
'RED': ' ^7joined the ^1RED Team^7',
|
||||||
'BLUE': ' ^7joined the ^4BLUE Team^7'
|
'BLUE': ' ^7joined the ^4BLUE Team^7'
|
||||||
}
|
}
|
||||||
|
|
||||||
old_team_messages = {
|
old_team_messages = {
|
||||||
'FREE': 'the ^0fight^9',
|
'FREE': 'the ^8fight^0',
|
||||||
'SPECTATOR': 'the ^3Spectators^7',
|
'SPECTATOR': 'the ^3Spectators^7',
|
||||||
'RED': '^7the ^1RED Team^7',
|
'RED': '^7the ^1RED Team^7',
|
||||||
'BLUE': '^7the ^4BLUE Team^7'
|
'BLUE': '^7the ^4BLUE Team^7'
|
||||||
@ -124,7 +124,7 @@ class EventParser:
|
|||||||
old_team_msg = old_team_messages.get(old_team, f'team {old_team}')
|
old_team_msg = old_team_messages.get(old_team, f'team {old_team}')
|
||||||
|
|
||||||
team_prefix = get_team_prefix(name, self.game_state.player_tracker)
|
team_prefix = get_team_prefix(name, self.game_state.player_tracker)
|
||||||
return f"{team_prefix}^0{name}^9{team_msg} from {old_team_msg}{warmup}\n"
|
return f"{team_prefix}^8{name}^0{team_msg} from {old_team_msg}{warmup}\n"
|
||||||
|
|
||||||
def _handle_death(self, data):
|
def _handle_death(self, data):
|
||||||
"""Handle PLAYER_DEATH and PLAYER_KILL events"""
|
"""Handle PLAYER_DEATH and PLAYER_KILL events"""
|
||||||
@ -147,7 +147,7 @@ class EventParser:
|
|||||||
self.game_state.player_tracker.add_player(victim_name)
|
self.game_state.player_tracker.add_player(victim_name)
|
||||||
|
|
||||||
victim_prefix = get_team_prefix(victim_name, self.game_state.player_tracker)
|
victim_prefix = get_team_prefix(victim_name, self.game_state.player_tracker)
|
||||||
warmup = " ^0^3(Warmup)^9" if data.get('WARMUP', False) else ""
|
warmup = " ^8^3(Warmup)^0" if data.get('WARMUP', False) else ""
|
||||||
score_prefix = ""
|
score_prefix = ""
|
||||||
|
|
||||||
# Environmental death (no killer)
|
# Environmental death (no killer)
|
||||||
@ -155,10 +155,10 @@ class EventParser:
|
|||||||
# -1 for environmental death
|
# -1 for environmental death
|
||||||
if not data.get('WARMUP', False):
|
if not data.get('WARMUP', False):
|
||||||
self.game_state.player_tracker.update_score(victim_name, -1)
|
self.game_state.player_tracker.update_score(victim_name, -1)
|
||||||
score_prefix = "^0^1[-1]^7^9 "
|
score_prefix = "^8^1[-1]^7^0 "
|
||||||
|
|
||||||
mod = data.get('MOD', 'UNKNOWN')
|
mod = data.get('MOD', 'UNKNOWN')
|
||||||
msg_template = DEATH_MESSAGES.get(mod, "%s^0%s^9 ^1DIED FROM %s^7")
|
msg_template = DEATH_MESSAGES.get(mod, "%s^8%s^0 ^1DIED FROM %s^7")
|
||||||
|
|
||||||
if mod in DEATH_MESSAGES:
|
if mod in DEATH_MESSAGES:
|
||||||
msg = msg_template % (victim_prefix, victim_name)
|
msg = msg_template % (victim_prefix, victim_name)
|
||||||
@ -183,18 +183,24 @@ class EventParser:
|
|||||||
# -1 for suicide
|
# -1 for suicide
|
||||||
if not data.get('WARMUP', False):
|
if not data.get('WARMUP', False):
|
||||||
self.game_state.player_tracker.update_score(victim_name, -1)
|
self.game_state.player_tracker.update_score(victim_name, -1)
|
||||||
score_prefix = "^0^1[-1]^7^9 "
|
score_prefix = "^8^1[-1]^7^0 "
|
||||||
|
|
||||||
weapon = killer.get('WEAPON', 'OTHER_WEAPON')
|
weapon = killer.get('WEAPON', 'OTHER_WEAPON')
|
||||||
if weapon != 'OTHER_WEAPON':
|
if weapon == 'ROCKET':
|
||||||
|
return f"{score_prefix}{killer_prefix}^8{killer_name}^0 ^7blew herself up.{warmup}\n"
|
||||||
|
elif weapon == 'GRENADE':
|
||||||
|
return f"{score_prefix}{killer_prefix}^8{killer_name}^0 ^7tripped on her own grenade.{warmup}\n"
|
||||||
|
elif weapon == 'PLASMA':
|
||||||
|
return f"{score_prefix}{killer_prefix}^8{killer_name}^0 ^7melted herself.{warmup}\n"
|
||||||
|
else:
|
||||||
weapon_name = WEAPON_NAMES.get(weapon, weapon)
|
weapon_name = WEAPON_NAMES.get(weapon, weapon)
|
||||||
return f"{score_prefix}{killer_prefix}^0{killer_name}^9 ^7committed suicide with the ^7{weapon_name}{warmup}\n"
|
return f"{score_prefix}{killer_prefix}^8{killer_name}^0 ^7committed suicide with the ^7{weapon_name}{warmup}\n"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Regular kill: +1 for killer
|
# Regular kill: +1 for killer
|
||||||
if not data.get('WARMUP', False):
|
if not data.get('WARMUP', False):
|
||||||
self.game_state.player_tracker.update_score(killer_name, 1)
|
self.game_state.player_tracker.update_score(killer_name, 1)
|
||||||
score_prefix = "^0^2[+1]^7^9 "
|
score_prefix = "^8^2[+1]^7^0 "
|
||||||
|
|
||||||
else:
|
else:
|
||||||
score_prefix = ""
|
score_prefix = ""
|
||||||
@ -202,7 +208,7 @@ class EventParser:
|
|||||||
weapon = killer.get('WEAPON', 'UNKNOWN')
|
weapon = killer.get('WEAPON', 'UNKNOWN')
|
||||||
weapon_name = WEAPON_KILL_NAMES.get(weapon, f'the {weapon}')
|
weapon_name = WEAPON_KILL_NAMES.get(weapon, f'the {weapon}')
|
||||||
|
|
||||||
return f"{score_prefix}{killer_prefix}^0{killer_name}^9 ^7fragged^7 {victim_prefix}^0{victim_name}^9 ^7with {weapon_name}{warmup}\n"
|
return f"{score_prefix}{killer_prefix}^8{killer_name}^0 ^7fragged^7 {victim_prefix}^8{victim_name}^0 ^7with {weapon_name}{warmup}\n"
|
||||||
|
|
||||||
def _handle_round_over(self, data):
|
def _handle_round_over(self, data):
|
||||||
"""Handle ROUND_OVER events for CA"""
|
"""Handle ROUND_OVER events for CA"""
|
||||||
@ -222,10 +228,29 @@ class EventParser:
|
|||||||
"""Handle PLAYER_MEDAL event"""
|
"""Handle PLAYER_MEDAL event"""
|
||||||
name = data.get('NAME', 'Unknown')
|
name = data.get('NAME', 'Unknown')
|
||||||
medal = data.get('MEDAL', 'UNKNOWN')
|
medal = data.get('MEDAL', 'UNKNOWN')
|
||||||
warmup = " ^0^3(Warmup)^7^9" if data.get('WARMUP', False) else ""
|
warmup = " ^8^3(Warmup)^7^0" if data.get('WARMUP', False) else ""
|
||||||
|
|
||||||
team_prefix = get_team_prefix(name, self.game_state.player_tracker)
|
team_prefix = get_team_prefix(name, self.game_state.player_tracker)
|
||||||
return f"{team_prefix}^0{name}^9 ^7got a medal: ^0^6{medal}{warmup}\n"
|
# RED Medals (^1)
|
||||||
|
if medal in ["FIRSTFRAG", "HUMILIATION", "REVENGE"]:
|
||||||
|
return f"{team_prefix}^8{name}^0 ^7got a medal: ^8^9^1{medal}^0{warmup}\n"
|
||||||
|
# GREEN Medals (^2)
|
||||||
|
elif medal in ["MIDAIR", "PERFECT"]:
|
||||||
|
return f"{team_prefix}^8{name}^0 ^7got a medal: ^8^9^2{medal}^0{warmup}\n"
|
||||||
|
# YELLOW Medals (^3)
|
||||||
|
elif medal in ["EXCELLENT", "HEADSHOT", "RAMPAGE"]:
|
||||||
|
return f"{team_prefix}^8{name}^0 ^7got a medal: ^8^9^3{medal}^0{warmup}\n"
|
||||||
|
# BLUE Medals (^4)
|
||||||
|
elif medal in ["ASSIST", "DEFENSE", "QUADGOD"]:
|
||||||
|
return f"{team_prefix}^8{name}^0 ^7got a medal: ^8^9^4{medal}^0{warmup}\n"
|
||||||
|
# CYAN Medals (^5)
|
||||||
|
elif medal in ["CAPTURE", "COMBOKILL", "IMPRESSIVE"]:
|
||||||
|
return f"{team_prefix}^8{name}^0 ^7got a medal: ^8^9^5{medal}^0{warmup}\n"
|
||||||
|
# PINK Medals (^6)
|
||||||
|
elif medal in ["ACCURACY", "PERFORATED"]:
|
||||||
|
return f"{team_prefix}^8{name}^0 ^7got a medal: ^8^9^6{medal}^0{warmup}\n"
|
||||||
|
else:
|
||||||
|
return f"{team_prefix}^8{name}^0 ^7got a medal: ^8^9^7{medal}^0{warmup}\n"
|
||||||
|
|
||||||
def _handle_match_started(self, data):
|
def _handle_match_started(self, data):
|
||||||
"""Handle MATCH_STARTED event"""
|
"""Handle MATCH_STARTED event"""
|
||||||
@ -238,8 +263,8 @@ class EventParser:
|
|||||||
players.append(name)
|
players.append(name)
|
||||||
|
|
||||||
if players:
|
if players:
|
||||||
formatted = "^9 vs. ^0".join(players)
|
formatted = "^0 vs. ^8".join(players)
|
||||||
return f"^0^3Match has started - ^0^7{formatted}\n"
|
return f"^8^3Match has started - ^8^7{formatted}\n"
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -279,4 +304,4 @@ class EventParser:
|
|||||||
|
|
||||||
weapon_name = WEAPON_NAMES.get(best_weapon, best_weapon)
|
weapon_name = WEAPON_NAMES.get(best_weapon, best_weapon)
|
||||||
|
|
||||||
return f"{team_prefix}^0^7{name}^9^7 K/D: {kills}/{deaths} | Best Weapon: {weapon_name} - Acc: {best_accuracy:.2f}% - Kills: {best_weapon_kills}\n"
|
return f"{team_prefix}^8^7{name}^0^7 K/D: {kills}/{deaths} | Best Weapon: {weapon_name} - Acc: {best_accuracy:.2f}% - Kills: {best_weapon_kills}\n"
|
||||||
|
|||||||
50
ui.py
50
ui.py
@ -41,7 +41,7 @@ class CursesHandler(logging.Handler):
|
|||||||
def print_colored(window, message, attributes=0):
|
def print_colored(window, message, attributes=0):
|
||||||
"""
|
"""
|
||||||
Print message with Quake color codes (^N)
|
Print message with Quake color codes (^N)
|
||||||
^0 = bold, ^1 = red, ^2 = green, ^3 = yellow, ^4 = blue, ^5 = cyan, ^6 = magenta, ^7 = white, ^9 = reset
|
^0 = reset, ^1 = red, ^2 = green, ^3 = yellow, ^4 = blue, ^5 = cyan, ^6 = magenta, ^7 = white, ^8 = bold, ^9 = underline
|
||||||
"""
|
"""
|
||||||
if not curses.has_colors:
|
if not curses.has_colors:
|
||||||
window.addstr(message)
|
window.addstr(message)
|
||||||
@ -49,27 +49,31 @@ def print_colored(window, message, attributes=0):
|
|||||||
|
|
||||||
color = 0
|
color = 0
|
||||||
bold = False
|
bold = False
|
||||||
|
underline = False
|
||||||
parse_color = False
|
parse_color = False
|
||||||
|
|
||||||
for ch in message:
|
for ch in message:
|
||||||
val = ord(ch)
|
val = ord(ch)
|
||||||
if parse_color:
|
if parse_color:
|
||||||
if ch == '0':
|
if ch == '8':
|
||||||
bold = True
|
bold = True
|
||||||
elif ch == '9':
|
elif ch == '9':
|
||||||
|
underline = True
|
||||||
|
elif ch == '0':
|
||||||
bold = False
|
bold = False
|
||||||
|
underline = False
|
||||||
elif ch == '7':
|
elif ch == '7':
|
||||||
color = 0
|
color = 0
|
||||||
elif ord('1') <= val <= ord('6'):
|
elif ord('1') <= val <= ord('6'):
|
||||||
color = val - ord('0')
|
color = val - ord('0')
|
||||||
else:
|
else:
|
||||||
window.addch('^', curses.color_pair(color) | (curses.A_BOLD if bold else 0) | attributes)
|
window.addch('^', curses.color_pair(color) | (curses.A_BOLD if bold else 0) | (curses.A_UNDERLINE if underline else 0) | attributes)
|
||||||
window.addch(ch, curses.color_pair(color) | (curses.A_BOLD if bold else 0) | attributes)
|
window.addch(ch, curses.color_pair(color) | (curses.A_BOLD if bold else 0) | (curses.A_UNDERLINE if underline else 0) | attributes)
|
||||||
parse_color = False
|
parse_color = False
|
||||||
elif ch == '^':
|
elif ch == '^':
|
||||||
parse_color = True
|
parse_color = True
|
||||||
else:
|
else:
|
||||||
window.addch(ch, curses.color_pair(color) | (curses.A_BOLD if bold else 0) | attributes)
|
window.addch(ch, curses.color_pair(color) | (curses.A_BOLD if bold else 0) | (curses.A_UNDERLINE if underline else 0) | attributes)
|
||||||
|
|
||||||
class UIManager:
|
class UIManager:
|
||||||
"""Manages curses windows and display"""
|
"""Manages curses windows and display"""
|
||||||
@ -307,8 +311,8 @@ class UIManager:
|
|||||||
|
|
||||||
# Line 1: Hostname
|
# Line 1: Hostname
|
||||||
hostname = server_info.hostname
|
hostname = server_info.hostname
|
||||||
warmup_display = "^3Warmup: ^2YES^9" if server_info.warmup else "^3Warmup: ^1NO^9"
|
warmup_display = "^3Warmup: ^2YES^0" if server_info.warmup else "^3Warmup: ^1NO^0"
|
||||||
print_colored(self.info_window, f"^3Name:^0 {hostname} {warmup_display}\n", 0)
|
print_colored(self.info_window, f"^3Name:^8 {hostname} {warmup_display}\n", 0)
|
||||||
|
|
||||||
# Line 2: Game info
|
# Line 2: Game info
|
||||||
gametype = server_info.gametype
|
gametype = server_info.gametype
|
||||||
@ -317,12 +321,24 @@ class UIManager:
|
|||||||
fraglimit = server_info.fraglimit
|
fraglimit = server_info.fraglimit
|
||||||
roundlimit = server_info.roundlimit
|
roundlimit = server_info.roundlimit
|
||||||
caplimit = server_info.capturelimit
|
caplimit = server_info.capturelimit
|
||||||
curclients = server_info.curclients
|
curclients = len(server_info.players)
|
||||||
maxclients = server_info.maxclients
|
maxclients = server_info.maxclients
|
||||||
|
|
||||||
|
# Context-sensitive limit display based on gametype
|
||||||
|
if gametype == 'Capture the Flag':
|
||||||
|
limit_display = f"^3^0| Capturelimit:^7^8 {caplimit}"
|
||||||
|
elif gametype == 'Clan Arena':
|
||||||
|
limit_display = f"^3^0| Roundlimit:^7^8 {roundlimit}"
|
||||||
|
elif gametype == 'Duel':
|
||||||
|
limit_display = f"^3^0| Timelimit:^7^8 {timelimit}"
|
||||||
|
elif gametype == 'Race':
|
||||||
|
limit_display = f"^3^0| Timelimit:^7^8 {timelimit}"
|
||||||
|
else:
|
||||||
|
limit_display = f"^3^0| Timelimit:^7^8 {timelimit} ^0^3| Fraglimit:^7^8 {fraglimit}"
|
||||||
|
|
||||||
print_colored(self.info_window,
|
print_colored(self.info_window,
|
||||||
f"^3^9Type:^7^0 {gametype} ^9^3| Map:^7^0 {mapname} ^9^3| Players:^7^0 {curclients}/{maxclients} "
|
f"^3^0Type:^7^8 {gametype} ^8^3| Map:^7^8 {mapname} ^0^3| Players:^7^8 {curclients}/{maxclients} "
|
||||||
f"^3^9| Limits (T/F/R/C):^7^0 {timelimit}/{fraglimit}/{roundlimit}/{caplimit}^9\n", 0)
|
f"{limit_display}^0\n", 0)
|
||||||
|
|
||||||
# Blank lines to fill
|
# Blank lines to fill
|
||||||
self.info_window.addstr("\n")
|
self.info_window.addstr("\n")
|
||||||
@ -351,7 +367,7 @@ class UIManager:
|
|||||||
red_score = f"{red_total:>3} "
|
red_score = f"{red_total:>3} "
|
||||||
blue_score = f"{blue_total:>3} "
|
blue_score = f"{blue_total:>3} "
|
||||||
|
|
||||||
print_colored(self.info_window, f"^0^7{red_score}^1RED TEAM ^7{blue_score}^4BLUE TEAM\n", 0)
|
print_colored(self.info_window, f"^8^7{red_score}^9^1RED TEAM^0 ^7^8{blue_score}^9^4BLUE TEAM\n", 0)
|
||||||
|
|
||||||
# Sort players by score within each team
|
# Sort players by score within each team
|
||||||
red_players_with_scores = []
|
red_players_with_scores = []
|
||||||
@ -410,10 +426,10 @@ class UIManager:
|
|||||||
|
|
||||||
red_pad = 24 - len(red_clean)
|
red_pad = 24 - len(red_clean)
|
||||||
|
|
||||||
line = f"^0{red}^9{' ' * red_pad}^0{blue}^9\n"
|
line = f"^8{red}^0{' ' * red_pad}^8{blue}^0\n"
|
||||||
print_colored(self.info_window, line, 0)
|
print_colored(self.info_window, line, 0)
|
||||||
else:
|
else:
|
||||||
print_colored(self.info_window, f"^0 ^5FREE\n", 0)
|
print_colored(self.info_window, f" ^8^9^5FREE\n", 0)
|
||||||
# Sort FREE players by score (highest first)
|
# Sort FREE players by score (highest first)
|
||||||
free_players = teams['FREE']
|
free_players = teams['FREE']
|
||||||
free_players_with_scores = []
|
free_players_with_scores = []
|
||||||
@ -461,7 +477,7 @@ class UIManager:
|
|||||||
|
|
||||||
col1_pad = 24 - len(col1_clean)
|
col1_pad = 24 - len(col1_clean)
|
||||||
|
|
||||||
line = f"^0{col1}^9{' ' * col1_pad}^0{col2}^9\n"
|
line = f"^8{col1}^0{' ' * col1_pad}^8{col2}^0\n"
|
||||||
print_colored(self.info_window, line, 0)
|
print_colored(self.info_window, line, 0)
|
||||||
|
|
||||||
# Blank lines to fill
|
# Blank lines to fill
|
||||||
@ -469,7 +485,7 @@ class UIManager:
|
|||||||
|
|
||||||
# List spectators on one line
|
# List spectators on one line
|
||||||
spec_list = " ".join(spec_players)
|
spec_list = " ".join(spec_players)
|
||||||
line = f"^0 ^3SPEC^7 {spec_list}\n"
|
line = f" ^8^3SPEC^0:^7^8 {spec_list}\n"
|
||||||
print_colored(self.info_window, line, 0)
|
print_colored(self.info_window, line, 0)
|
||||||
|
|
||||||
# Blank lines to fill
|
# Blank lines to fill
|
||||||
@ -480,3 +496,5 @@ class UIManager:
|
|||||||
print_colored(self.info_window, separator, 0)
|
print_colored(self.info_window, separator, 0)
|
||||||
|
|
||||||
self.info_window.noutrefresh()
|
self.info_window.noutrefresh()
|
||||||
|
|
||||||
|
curses.doupdate()
|
||||||
|
|||||||
Reference in New Issue
Block a user