From 732e9c8881b0252b19f899d9a061d0999d8fe699 Mon Sep 17 00:00:00 2001 From: 3AvisD Date: Thu, 22 Oct 2026 15:30:45 -0600 Subject: [PATCH] fix(launcher): handle YAML comments and log failures - strip inline YAML comments from preference values, including quoted values; - keep a successfully unmapped window tracked when the success log raises BrokenPipeError, while still discarding a window whose unmap failed; - cover both cases with tests. --- tests/test_client_in_game_tricks.py | 8 ++++++++ tests/test_hide_league_client_in_game.py | 18 ++++++++++++++++++ tools/client-in-game-tricks.py | 9 ++++++++- tools/hide-league-client-in-game.py | 8 +++++++- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/tests/test_client_in_game_tricks.py b/tests/test_client_in_game_tricks.py index 4b19d28..53a0db3 100644 --- a/tests/test_client_in_game_tricks.py +++ b/tests/test_client_in_game_tricks.py @@ -69,6 +69,14 @@ class ClientInGameTricksTests(unittest.TestCase): ' closeLeagueClientDuringGame: true\n') self.assertEqual(tricks.mode(self.path), 'hide') + def test_inline_yaml_comments_are_ignored(self): + self.path.write_text( + 'lol-user-experience:\n' + ' data:\n' + ' potatoModeEnabled: true # client optimizations\n' + ' closeLeagueClientDuringGame: "true" # close during matches\n') + self.assertEqual(tricks.mode(self.path), 'close') + def test_second_read_failure_fails_closed(self): self.write(True, False) text = self.path.read_text() diff --git a/tests/test_hide_league_client_in_game.py b/tests/test_hide_league_client_in_game.py index 946bbad..f03e8c1 100644 --- a/tests/test_hide_league_client_in_game.py +++ b/tests/test_hide_league_client_in_game.py @@ -199,6 +199,24 @@ class HideClientInGameTests(unittest.TestCase): watcher.restore() self.assertEqual(shown, [0xabc]) + def test_log_failure_does_not_discard_an_unmapped_window(self): + class BrokenOutput: + def write(self, _text): + raise BrokenPipeError + + def flush(self): + pass + + watcher = hide_in_game.Watcher( + self.prefix, FakeX11(), + window_source=lambda _prefix, _cache: [0xabc], + state_source=lambda _prefix: True, + sleep=lambda _seconds: None, + out=BrokenOutput(), + ) + watcher._hide_new() + self.assertEqual(watcher.hidden, {0xabc}) + def test_hides_then_shows_on_match_end(self): states = iter([True, True, False]) x11 = FakeX11() diff --git a/tools/client-in-game-tricks.py b/tools/client-in-game-tricks.py index adf28c6..1b7a314 100755 --- a/tools/client-in-game-tricks.py +++ b/tools/client-in-game-tricks.py @@ -45,7 +45,14 @@ def read_bool(path, key, section=SECTION): continue if not in_section or not stripped.startswith(key + ':'): continue - value = stripped.split(':', 1)[1].strip().strip('"\'').lower() + value = stripped.split(':', 1)[1].strip() + if value[:1] in ('"', "'"): + quote = value[0] + end = value.find(quote, 1) + value = value[1:end] if end != -1 else value[1:] + else: + value = value.split('#', 1)[0].strip() + value = value.lower() if value in TRUE_VALUES: return True if value in FALSE_VALUES: diff --git a/tools/hide-league-client-in-game.py b/tools/hide-league-client-in-game.py index bf6f212..22b9ca2 100755 --- a/tools/hide-league-client-in-game.py +++ b/tools/hide-league-client-in-game.py @@ -299,11 +299,17 @@ class Watcher: self.hidden.add(window) try: self.x11.unmap(window) - print(f'hide-league-client-in-game: hidden 0x{window:x}', file=self.out, flush=True) except Exception as error: self.hidden.discard(window) print(f'hide-league-client-in-game: cannot hide 0x{window:x}: {error}', file=sys.stderr, flush=True) + continue + try: + print(f'hide-league-client-in-game: hidden 0x{window:x}', + file=self.out, flush=True) + except Exception: + # Logging must not lose a successfully unmapped window. + pass def run(self, max_steps=None): steps = 0