poe2-bot/docs/input.md
2026-03-07 09:53:57 -05:00

2.5 KiB

Nexus.Input — Input Controllers & Humanization

IInputController Implementations

SendInputController (Default, No Driver)

Uses Win32 SendInput API with KEYEVENTF_SCANCODE flag. Games read hardware scan codes, not virtual key codes.

  • KeyDown/KeyUp: Raw keyboard scan code via SendInput struct
  • KeyPress: Down → Sleep(holdMs) → Up with humanization
  • SmoothMoveTo: Cubic Bézier curve interpolation (10-40 steps) with random perpendicular spread
  • MouseMoveTo: Direct SetCursorPos() (instant teleport)
  • Clicks: Smooth move to target → humanized delay → click

InterceptionInputController (Driver-Based)

Uses Interception keyboard/mouse driver for lower-level control:

  • Delegates to KeyboardHook and MouseHook via InputInterceptor COM library
  • Same smooth movement and humanization as SendInput
  • Returns false from Initialize() if driver not installed (graceful fallback)

SimInputController (Simulator)

Implements IInputController but doesn't make Win32 calls. Instead:

  • WASD → Tracks held state, converts to direction vector with 45° isometric rotation
  • Skills → Queues skill casts to SimWorld via QueueSkill()
  • Mouse → Tracks screen position, converts to world coords via inverse camera matrix
  • Visualization → Maintains flash timers (0.15s) for InputOverlayRenderer

Scan Codes

Movement:  W=0x11  A=0x1E  S=0x1F  D=0x20
Skills:    Q=0x10  E=0x12  R=0x13  T=0x14
Numbers:   1=0x02  2=0x03  3=0x04  4=0x05  5=0x06
Modifiers: LShift=0x2A  LCtrl=0x1D  LAlt=0x38
Other:     Space=0x39  Enter=0x1C  Escape=0x01  Slash=0x35

Humanizer

Anti-detection layer applied to all input operations.

Method Purpose
GaussianDelay(baseMs) Adds gaussian noise (Box-Muller transform), clamped to [50ms, 150ms]
JitterPosition(x, y) Random pixel offset within ClickJitterRadius (3px)
ShouldThrottle() Tracks actions in 60-second rolling window, blocks if APM > MaxApm (250)
RecordAction() Enqueues timestamp for APM tracking
RandomizedInterval(baseMs) Adds ±20% jitter to poll intervals

MovementKeyTracker

Converts normalized direction vectors to WASD key state for isometric camera:

Rotate direction 45°:
  sx = dir.X * cos(45°) - dir.Y * sin(45°)
  sy = dir.X * sin(45°) + dir.Y * cos(45°)

Key mapping:
  W if sy > 0.3,  S if sy < -0.3
  D if sx > 0.3,  A if sx < -0.3

Delta-based: only sends KeyDown/KeyUp when state changes.
Supports holding multiple keys (W+D for diagonal).