2020-01-13 21:05:38 +13:00
|
|
|
package webrtc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"encoding/json"
|
2020-01-14 21:36:48 +13:00
|
|
|
"time"
|
2020-01-13 21:05:38 +13:00
|
|
|
|
|
|
|
"github.com/go-vgo/robotgo"
|
|
|
|
"github.com/pion/webrtc/v2"
|
|
|
|
|
|
|
|
"n.eko.moe/neko/internal/keys"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (manager *WebRTCManager) createPeer(session *session, raw []byte) error {
|
|
|
|
payload := messageSDP{}
|
|
|
|
if err := json.Unmarshal(raw, &payload); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
peer, err := manager.api.NewPeerConnection(manager.config)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = peer.AddTrack(manager.video)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = peer.AddTrack(manager.audio)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
peer.SetRemoteDescription(webrtc.SessionDescription{
|
|
|
|
SDP: payload.SDP,
|
|
|
|
Type: webrtc.SDPTypeOffer,
|
|
|
|
})
|
|
|
|
|
|
|
|
answer, err := peer.CreateAnswer(nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = peer.SetLocalDescription(answer); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
session.send(messageSDP{
|
|
|
|
message{Event: "sdp/reply"},
|
|
|
|
answer.SDP,
|
|
|
|
})
|
|
|
|
|
|
|
|
session.peer = peer
|
|
|
|
|
|
|
|
peer.OnDataChannel(func(d *webrtc.DataChannel) {
|
|
|
|
d.OnMessage(func(msg webrtc.DataChannelMessage) {
|
|
|
|
if err = manager.onData(session, msg); err != nil {
|
|
|
|
manager.logger.Warn().Err(err).Msg("onData failed")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
peer.OnConnectionStateChange(func(connectionState webrtc.PeerConnectionState) {
|
|
|
|
switch connectionState {
|
|
|
|
case webrtc.PeerConnectionStateDisconnected:
|
|
|
|
case webrtc.PeerConnectionStateFailed:
|
|
|
|
manager.destroy(session)
|
|
|
|
break
|
|
|
|
case webrtc.PeerConnectionStateConnected:
|
|
|
|
manager.logger.Info().Str("ID", session.id).Msg("Peer connected")
|
|
|
|
break
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *WebRTCManager) onData(session *session, msg webrtc.DataChannelMessage) error {
|
|
|
|
if manager.controller != session.id {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
header := &dataHeader{}
|
|
|
|
buffer := bytes.NewBuffer(msg.Data)
|
|
|
|
byt := make([]byte, 3)
|
|
|
|
_, err := buffer.Read(byt)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = binary.Read(bytes.NewBuffer(byt), binary.LittleEndian, header)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
buffer = bytes.NewBuffer(msg.Data)
|
|
|
|
|
|
|
|
switch header.Event {
|
|
|
|
case 0x01: // MOUSE_MOVE
|
|
|
|
payload := &dataMouseMove{}
|
2020-01-14 21:36:48 +13:00
|
|
|
if err := binary.Read(buffer, binary.LittleEndian, payload); err != nil {
|
2020-01-13 21:05:38 +13:00
|
|
|
return err
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
|
2020-01-13 21:05:38 +13:00
|
|
|
robotgo.Move(int(payload.X), int(payload.Y))
|
|
|
|
break
|
|
|
|
case 0x02: // MOUSE_UP
|
|
|
|
payload := &dataMouseKey{}
|
2020-01-14 21:36:48 +13:00
|
|
|
if err := binary.Read(buffer, binary.LittleEndian, payload); err != nil {
|
2020-01-13 21:05:38 +13:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-01-14 21:36:48 +13:00
|
|
|
code := int(payload.Key)
|
|
|
|
if key, ok := keys.Mouse[code]; ok {
|
|
|
|
if _, ok := manager.debounce[code]; !ok {
|
2020-01-13 21:05:38 +13:00
|
|
|
return nil
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
delete(manager.debounce, code)
|
2020-01-13 21:05:38 +13:00
|
|
|
robotgo.MouseToggle("up", key)
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Debug().Msgf("MOUSE_UP key: %v (%v)", code, key)
|
2020-01-13 21:05:38 +13:00
|
|
|
} else {
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Warn().Msgf("Unknown MOUSE_UP key: %v", code)
|
2020-01-13 21:05:38 +13:00
|
|
|
}
|
|
|
|
break
|
|
|
|
case 0x03: // MOUSE_DOWN
|
|
|
|
payload := &dataMouseKey{}
|
|
|
|
err := binary.Read(buffer, binary.LittleEndian, payload)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-01-14 21:36:48 +13:00
|
|
|
code := int(payload.Key)
|
|
|
|
if key, ok := keys.Mouse[code]; ok {
|
|
|
|
if _, ok := manager.debounce[code]; ok {
|
2020-01-13 21:05:38 +13:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.debounce[code] = time.Now()
|
2020-01-13 21:05:38 +13:00
|
|
|
robotgo.MouseToggle("down", key)
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Debug().Msgf("MOUSE_DOWN key: %v (%v)", code, key)
|
2020-01-13 21:05:38 +13:00
|
|
|
} else {
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Warn().Msgf("Unknown MOUSE_DOWN key: %v", code)
|
2020-01-13 21:05:38 +13:00
|
|
|
}
|
|
|
|
break
|
|
|
|
case 0x04: // MOUSE_CLK
|
|
|
|
payload := &dataMouseKey{}
|
|
|
|
err := binary.Read(buffer, binary.LittleEndian, payload)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-01-14 21:36:48 +13:00
|
|
|
code := int(payload.Key)
|
|
|
|
if key, ok := keys.Mouse[code]; ok {
|
|
|
|
switch code {
|
2020-01-13 21:05:38 +13:00
|
|
|
case keys.MOUSE_WHEEL_DOWN:
|
2020-01-14 00:28:14 +13:00
|
|
|
robotgo.Scroll(0, -1)
|
2020-01-13 21:05:38 +13:00
|
|
|
break
|
|
|
|
case keys.MOUSE_WHEEL_UP:
|
2020-01-14 00:28:14 +13:00
|
|
|
robotgo.Scroll(0, 1)
|
2020-01-13 21:05:38 +13:00
|
|
|
break
|
|
|
|
case keys.MOUSE_WHEEL_LEFT:
|
2020-01-14 00:28:14 +13:00
|
|
|
robotgo.Scroll(-1, 0)
|
2020-01-13 21:05:38 +13:00
|
|
|
break
|
|
|
|
case keys.MOUSE_WHEEL_RIGH:
|
2020-01-14 00:28:14 +13:00
|
|
|
robotgo.Scroll(1, 0)
|
2020-01-13 21:05:38 +13:00
|
|
|
break
|
|
|
|
default:
|
|
|
|
robotgo.Click(key, false)
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
|
|
|
|
manager.logger.Debug().Msgf("MOUSE_CLK key: %v (%v)", code, key)
|
2020-01-13 21:05:38 +13:00
|
|
|
} else {
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Warn().Msgf("Unknown MOUSE_CLK key: %v", code)
|
2020-01-13 21:05:38 +13:00
|
|
|
}
|
|
|
|
break
|
|
|
|
case 0x05: // KEY_DOWN
|
|
|
|
payload := &dataKeyboardKey{}
|
|
|
|
err := binary.Read(buffer, binary.LittleEndian, payload)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
|
|
|
|
code := int(payload.Key)
|
|
|
|
if key, ok := keys.Keyboard[code]; ok {
|
|
|
|
if _, ok := manager.debounce[code]; ok {
|
2020-01-13 21:05:38 +13:00
|
|
|
return nil
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.debounce[code] = time.Now()
|
2020-01-13 21:05:38 +13:00
|
|
|
robotgo.KeyToggle(key, "down")
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Debug().Msgf("KEY_DOWN key: %v (%v)", code, key)
|
2020-01-13 21:05:38 +13:00
|
|
|
} else {
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Warn().Msgf("Unknown KEY_DOWN key: %v", code)
|
2020-01-13 21:05:38 +13:00
|
|
|
}
|
|
|
|
break
|
|
|
|
case 0x06: // KEY_UP
|
|
|
|
payload := &dataKeyboardKey{}
|
2020-01-14 21:36:48 +13:00
|
|
|
if err := binary.Read(buffer, binary.LittleEndian, payload); err != nil {
|
2020-01-13 21:05:38 +13:00
|
|
|
return err
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
|
|
|
|
code := int(payload.Key)
|
|
|
|
if key, ok := keys.Keyboard[code]; ok {
|
|
|
|
if _, ok := manager.debounce[code]; !ok {
|
2020-01-13 21:05:38 +13:00
|
|
|
return nil
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
delete(manager.debounce, code)
|
2020-01-13 21:05:38 +13:00
|
|
|
robotgo.KeyToggle(key, "up")
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Debug().Msgf("KEY_UP key: %v (%v)", code, key)
|
2020-01-13 21:05:38 +13:00
|
|
|
} else {
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Warn().Msgf("Unknown KEY_UP key: %v", code)
|
2020-01-13 21:05:38 +13:00
|
|
|
}
|
|
|
|
break
|
|
|
|
case 0x07: // KEY_CLK
|
|
|
|
payload := &dataKeyboardKey{}
|
|
|
|
err := binary.Read(buffer, binary.LittleEndian, payload)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
|
|
|
|
code := int(payload.Key)
|
|
|
|
if key, ok := keys.Keyboard[code]; ok {
|
2020-01-13 21:05:38 +13:00
|
|
|
robotgo.KeyTap(key)
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Debug().Msgf("KEY_CLK key: %v (%v)", code, key)
|
2020-01-13 21:05:38 +13:00
|
|
|
} else {
|
2020-01-14 21:36:48 +13:00
|
|
|
manager.logger.Warn().Msgf("Unknown KEY_CLK key: %v", code)
|
2020-01-13 21:05:38 +13:00
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2020-01-14 21:36:48 +13:00
|
|
|
|
|
|
|
func (manager *WebRTCManager) clearKeys() {
|
|
|
|
for code := range manager.debounce {
|
|
|
|
if key, ok := keys.Keyboard[code]; ok {
|
|
|
|
robotgo.MouseToggle(key, "up")
|
|
|
|
}
|
|
|
|
|
|
|
|
if key, ok := keys.Mouse[code]; ok {
|
|
|
|
robotgo.KeyToggle(key, "up")
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(manager.debounce, code)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (manager *WebRTCManager) checkKeys() {
|
|
|
|
t := time.Now()
|
|
|
|
for code, start := range manager.debounce {
|
|
|
|
if t.Sub(start) < (time.Second * 10) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if key, ok := keys.Keyboard[code]; ok {
|
|
|
|
robotgo.MouseToggle(key, "up")
|
|
|
|
}
|
|
|
|
|
|
|
|
if key, ok := keys.Mouse[code]; ok {
|
|
|
|
robotgo.KeyToggle(key, "up")
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(manager.debounce, code)
|
|
|
|
}
|
|
|
|
}
|