fix(input): an unbound skill key is a no-op, not a thread-killing ValueError

Regression from the previous commit. Blanking vigor/holy_shield/cleansing
stopped the stray F4 presses, but exposed that paladin.cast_buffs sends the
holy_shield key with no check:

    keyboard.send(self._skill_hotkeys["holy_shield"])   # -> ValueError: Unknown key:

which killed the bot thread mid-run:

    Uncaught exception in thread Thread-8 (start)
    ...
    File "src/char/paladin/paladin.py", line 33, in cast_buffs
    ValueError: Unknown key:

There are 90+ `keyboard.send(self._skill_hotkeys[x])` call sites across the
paladin classes and almost none check first, so the guard belongs at the
boundary: an empty or None key logs at debug and returns. A genuinely unknown
key still raises — the guard is for unbound optional skills, not for typos.

cast_buffs additionally returns early when holy_shield is unbound: send() now
tolerates the empty key, but the right-click after it would still fire and cast
whatever sits on the right slot instead.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
alexpolo1
2026-08-28 00:18:39 +02:00
co-authored by Claude Opus 5
parent 5211564df4
commit 4bdc5b90db
3 changed files with 53 additions and 0 deletions
+5
View File
@@ -30,6 +30,11 @@ class Paladin(IChar):
self._action_frame = 6
def cast_buffs(self, casting_delay: float):
# Skip entirely when Holy Shield is unbound. keyboard.send() tolerates
# the empty key now, but the right-click after it would still fire and
# cast whatever happens to be on the right slot instead.
if not self._skill_hotkeys.get("holy_shield"):
return
keyboard.send(self._skill_hotkeys["holy_shield"])
wait(0.04, 0.1)
mouse.click(button="right")
+11
View File
@@ -12,6 +12,7 @@ On non-Windows (Docker/Linux), uses bridge_input to talk to a Windows host
via TCP. Set BOTTY_BRIDGE_HOST / BOTTY_BRIDGE_PORT env vars.
"""
import re as _re
from logger import Logger
import os as _os
import threading as _threading
@@ -192,9 +193,19 @@ class _Keyboard:
"""
Send a key press event with stealth timing.
An EMPTY key is a no-op, not an error. An unbound optional skill is a
legitimate configuration — a FoHdin with no Holy Shield, no Vigor, no
Cleansing — and there are 90+ `keyboard.send(self._skill_hotkeys[x])`
call sites across the paladin classes alone, almost none of which check
first. Raising here kills the whole bot thread for a skill the
character was never meant to cast. Guard once, at the boundary.
Supports combo keys like 'shift + a', 'ctrl + alt + del'.
Supports do_release=False (hold key) and do_press=False (release-only).
"""
if key is None or str(key).strip() == "":
Logger.debug("keyboard.send: empty key (unbound skill) — skipping")
return
self._stealth_before()
# Handle combo keys (e.g. 'shift + a', 'ctrl + alt + del')