Skip to content

Commit

Permalink
feat: Autowho
Browse files Browse the repository at this point in the history
Automatically type /who when the game starts
- Can be toggled on/off
- Uses settings for chat hotkey and how long after game start to type
  • Loading branch information
Amund211 committed Sep 14, 2024
1 parent 3b13abf commit a7d4e61
Showing 1 changed file with 62 additions and 1 deletion.
63 changes: 62 additions & 1 deletion src/prism/overlay/real_controller.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import sys
import threading
import time
from collections.abc import Mapping
Expand All @@ -16,7 +17,12 @@
get_estimated_winstreaks,
get_playerdata,
)
from prism.overlay.controller import ERROR_DURING_PROCESSING, ProcessingError
from prism.overlay.controller import (
ERROR_DURING_PROCESSING,
OverlayController,
ProcessingError,
)
from prism.overlay.keybinds import AlphanumericKey
from prism.overlay.player import MISSING_WINSTREAKS
from prism.ratelimiting import RateLimiter
from prism.ssl_errors import MissingLocalIssuerSSLError
Expand Down Expand Up @@ -65,6 +71,8 @@ def __init__(
else None
)

AutoWhoThread(self).start()

def get_uuid(self, username: str) -> str | None | ProcessingError:
try:
uuid = get_uuid(username)
Expand Down Expand Up @@ -133,3 +141,56 @@ def get_estimated_winstreaks(

def store_settings(self) -> None:
self.settings.flush_to_disk()


class AutoWhoThread(threading.Thread): # pragma: nocover
"""Thread that types /who on request, unless cancelled"""

def __init__(self, controller: OverlayController) -> None:
super().__init__(daemon=True) # Don't block the process from exiting
self.controller = controller

def run(self) -> None:
"""Wait for requests, check if not cancelled, then type /who"""
if sys.platform == "darwin": # Not supported on macOS
return

try:
from pynput.keyboard import Controller, Key, KeyCode

keyboard = Controller()

while True:
# Wait until autowho is requested
self.controller.autowho_event.wait()

# NOTE: The delay must not be zero!
# The bedwars game start event is parsed also at the end of a game.
# We cancel this by parsing a bedwars game end event right after, but
# need to give a bit of time for the state updater thread to process
# this event so we don't send /who at the end of a game as well.
time.sleep(self.controller.settings.autowho_delay)

if not self.controller.autowho_event.is_set():
# Autowho was cancelled
continue

self.controller.autowho_event.clear()

chat_hotkey = self.controller.settings.chat_hotkey
chat_keycode: KeyCode
if isinstance(chat_hotkey, AlphanumericKey):
chat_keycode = KeyCode.from_char(chat_hotkey.char)
elif chat_hotkey.vk is not None:
chat_keycode = KeyCode.from_vk(chat_hotkey.vk)
else:
logger.error(f"Invalid chat hotkey {chat_hotkey}")
continue

keyboard.tap(chat_keycode)
time.sleep(0.1)
keyboard.type("/who")
keyboard.tap(Key.enter)
except Exception:
logger.exception("Exception caught in autowho thread. Exiting.")
# We let the overlay keep working if the autowho thread dies

0 comments on commit a7d4e61

Please sign in to comment.