babalae/better-genshin-impact · error · ArgumentOutOfRangeException

不支持的原琴按键

Error message

不支持的原琴按键

What it means

Thrown by KeyInputTransportBase.ToVirtualKey when the character passed to KeyDown or KeyUp is not one of the 26 uppercase letters A-Z. The switch expression only maps A-Z to virtual key codes; any other character (digit, symbol, lowercase letter that somehow bypassed ToUpper, or non-ASCII) hits the default arm and throws ArgumentOutOfRangeException.

Source

Thrown at BetterGenshinImpact/GameTask/Music/Service/KeyInputTransports.cs:93

            'I' => User32.VK.VK_I,
            'J' => User32.VK.VK_J,
            'K' => User32.VK.VK_K,
            'L' => User32.VK.VK_L,
            'M' => User32.VK.VK_M,
            'N' => User32.VK.VK_N,
            'O' => User32.VK.VK_O,
            'P' => User32.VK.VK_P,
            'Q' => User32.VK.VK_Q,
            'R' => User32.VK.VK_R,
            'S' => User32.VK.VK_S,
            'T' => User32.VK.VK_T,
            'U' => User32.VK.VK_U,
            'V' => User32.VK.VK_V,
            'W' => User32.VK.VK_W,
            'X' => User32.VK.VK_X,
            'Y' => User32.VK.VK_Y,
            'Z' => User32.VK.VK_Z,
            _ => throw new ArgumentOutOfRangeException(nameof(key), key, "不支持的原琴按键")
        };
    }
}

public sealed class PostMessageKeyInputTransport : KeyInputTransportBase
{
    public override MusicInputMode Mode => MusicInputMode.BackgroundPostMessage;

    protected override void SendKeyDown(User32.VK key)
    {
        TaskContext.Instance().PostMessageSimulator.KeyDownBackground(key);
    }

    protected override void SendKeyUp(User32.VK key)
    {
        TaskContext.Instance().PostMessageSimulator.KeyUpBackground(key);
    }
}

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Filter notes to only SupportedKeys ('QWERTYUASDFGHJZXCVBNM' as defined in MusicScoreParser) before sending them to the transport.
  2. Validate the key character against 'A'-'Z' before calling KeyDown/KeyUp and skip invalid keys with a warning.
  3. Extend ToVirtualKey to support additional virtual key codes if the score format legitimately uses them.
  4. Inspect the score file for unexpected note characters.

Example fix

// before
public void KeyDown(char key)
{
    key = char.ToUpperInvariant(key);
    lock (_syncRoot)
    {
        if (!_pressedKeys.Add(key)) return;
        SendKeyDown(ToVirtualKey(key));
    }
}

// after — guard against unsupported keys
public void KeyDown(char key)
{
    key = char.ToUpperInvariant(key);
    if (key < 'A' || key > 'Z') return; // silently skip unsupported
    lock (_syncRoot)
    {
        if (!_pressedKeys.Add(key)) return;
        SendKeyDown(ToVirtualKey(key));
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Before sending key
key = char.ToUpperInvariant(key);
if (key < 'A' || key > 'Z')
{
    logger.LogWarning("不支持的音乐按键:{Key}", key);
    return;
}

Type guard

static bool IsSupportedKey(char key) => key >= 'A' && key <= 'Z';

Try / catch

try { transport.KeyDown(c); }
catch (ArgumentOutOfRangeException ex) { logger.LogWarning(ex, "跳过不支持的按键"); }

Prevention

When it happens

Trigger: Calling KeyDown(c) or KeyUp(c) where c (after ToUpperInvariant) is outside 'A'-'Z'. This happens if the music score contains notes mapped to characters outside the 26-letter range, or the score parser produces an unexpected character.

Common situations: A music score file references keys like digits (1-9) or symbols that are not in the A-Z mapping; a MIDI-to-key mapping produces a character outside the supported set; the score format is keyboard-type but uses non-letter note names.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/9ebd9356a6f30f41. Report an issue: GitHub.