-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathhandler.go
More file actions
60 lines (51 loc) · 1.34 KB
/
handler.go
File metadata and controls
60 lines (51 loc) · 1.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package xbox360
import (
"fmt"
"io"
"log/slog"
"net"
"github.com/Alia5/VIIPER/device"
"github.com/Alia5/VIIPER/internal/server/api"
"github.com/Alia5/VIIPER/usb"
)
func init() {
api.RegisterDevice("xbox360", &handler{})
}
type handler struct{}
func (h *handler) CreateDevice(o *device.CreateOptions) (usb.Device, error) { return New(o) }
func (r *handler) StreamHandler() api.StreamHandlerFunc {
return func(conn net.Conn, devPtr *usb.Device, logger *slog.Logger) error {
if devPtr == nil || *devPtr == nil {
return fmt.Errorf("nil device")
}
xdev, ok := (*devPtr).(*Xbox360)
if !ok {
return fmt.Errorf("device is not xbox360")
}
xdev.SetRumbleCallback(func(rumble XRumbleState) {
data, err := rumble.MarshalBinary()
if err != nil {
logger.Error("failed to marshal rumble", "error", err)
return
}
if _, err := conn.Write(data); err != nil {
logger.Error("failed to send rumble", "error", err)
}
})
buf := make([]byte, 20)
for {
if _, err := io.ReadFull(conn, buf); err != nil {
if err == io.EOF {
logger.Info("client disconnected")
return nil
}
return fmt.Errorf("read input state: %w", err)
}
var state InputState
if err := state.UnmarshalBinary(buf); err != nil {
return fmt.Errorf("unmarshal input state: %w", err)
}
xdev.UpdateInputState(state)
}
}
}