diff --git a/server/cmd/serve.go b/server/cmd/serve.go index 5b1162de..147e0dda 100644 --- a/server/cmd/serve.go +++ b/server/cmd/serve.go @@ -22,6 +22,7 @@ func init() { neko.Service.Remote, neko.Service.Broadcast, neko.Service.WebSocket, + neko.Service.SessionManager, } cobra.OnInitialize(func() { diff --git a/server/internal/session/manager.go b/server/internal/session/manager.go index b17d5d8e..4ecd8e7a 100644 --- a/server/internal/session/manager.go +++ b/server/internal/session/manager.go @@ -10,6 +10,9 @@ import ( "m1k1o/neko/internal/types" "m1k1o/neko/internal/utils" + + "github.com/spf13/cobra" + "github.com/spf13/viper" ) func New(remote types.RemoteManager) *SessionManager { @@ -31,6 +34,16 @@ type SessionManager struct { emmiter events.EventEmmiter // TODO: Handle locks in sessions as flags. controlLocked bool + implicitControl bool +} + +func (manager *SessionManager) Init(cmd *cobra.Command) error { + cmd.PersistentFlags().Bool("implicit_control", "", "if enabled members can gain control implicitly. Valid values: none, free, on_click") + if err := viper.BindPFlag("implicit_control", cmd.PersistentFlags().Lookup("implicit_control")); err != nil { + return err + } + + manager.implicitControl = viper.GetBool("implicit_control") } func (manager *SessionManager) New(id string, admin bool, socket types.WebSocket) types.Session { @@ -111,8 +124,23 @@ func (manager *SessionManager) SetControlLocked(locked bool) { manager.controlLocked = locked } -func (manager *SessionManager) CanControl(id string) bool { +func (manager *SessionManager) CanControl(id string, isClickEvent bool) bool { session, ok := manager.Get(id) + if !manager.IsHost(id) { + ok = false + } + if !ok { + switch manager.sessions.ImplicitControl { + case types.session.ControlMode.OnMove: + ok = true + case types.session.ControlMode.OnClick: + if isClickEvent: { + // Switch host + manager. + } + } + } + return ok && (!manager.controlLocked || session.Admin()) } @@ -252,3 +280,7 @@ func (manager *SessionManager) OnConnected(listener func(id string, session type listener(payload[0].(string), payload[1].(*Session)) }) } + +func (manager *SessionManager) ImplicitControl() bool { + return manager.implicitControl +} diff --git a/server/internal/types/config/webrtc.go b/server/internal/types/config/webrtc.go index d7dcb1b9..dfdfbfbe 100644 --- a/server/internal/types/config/webrtc.go +++ b/server/internal/types/config/webrtc.go @@ -22,8 +22,6 @@ type WebRTC struct { NAT1To1IPs []string TCPMUX int UDPMUX int - - ImplicitControl bool } func (WebRTC) Init(cmd *cobra.Command) error { @@ -67,12 +65,6 @@ func (WebRTC) Init(cmd *cobra.Command) error { return err } - // TODO: Should be moved to session config. - cmd.PersistentFlags().Bool("implicit_control", false, "if enabled members can gain control implicitly") - if err := viper.BindPFlag("implicit_control", cmd.PersistentFlags().Lookup("implicit_control")); err != nil { - return err - } - return nil } @@ -128,7 +120,4 @@ func (s *WebRTC) Set() { s.EphemeralMin = min s.EphemeralMax = max } - - // TODO: Should be moved to session config. - s.ImplicitControl = viper.GetBool("implicit_control") } diff --git a/server/internal/types/session.go b/server/internal/types/session.go index 04a4626c..0b22330c 100644 --- a/server/internal/types/session.go +++ b/server/internal/types/session.go @@ -1,4 +1,15 @@ package types +import ( + "github.com/spf13/cobra" +) + +type ControlMode string + +const ( + None ControlMode = "" + OnClick = "on_click" + OnMove = "on_click" +) type Member struct { ID string `json:"id"` @@ -30,6 +41,7 @@ type Session interface { } type SessionManager interface { + Init(cmd *cobra.Command) error New(id string, admin bool, socket WebSocket) Session HasHost() bool IsHost(id string) bool @@ -51,4 +63,6 @@ type SessionManager interface { OnDestroy(listener func(id string, session Session)) OnCreated(listener func(id string, session Session)) OnConnected(listener func(id string, session Session)) + ImplicitControl() bool + ImplicitControlMode() ControlMode } diff --git a/server/internal/types/webrtc.go b/server/internal/types/webrtc.go index 26595607..bda3524a 100644 --- a/server/internal/types/webrtc.go +++ b/server/internal/types/webrtc.go @@ -13,7 +13,6 @@ type WebRTCManager interface { CreatePeer(id string, session Session) (Peer, error) ICELite() bool ICEServers() []webrtc.ICEServer - ImplicitControl() bool } type Peer interface { diff --git a/server/internal/types/websocket.go b/server/internal/types/websocket.go index 0ea4ee6b..acdd871c 100644 --- a/server/internal/types/websocket.go +++ b/server/internal/types/websocket.go @@ -18,7 +18,7 @@ type Stats struct { LastUserLeftAt *time.Time `json:"last_user_left_at"` ControlProtection bool `json:"control_protection"` - ImplicitControl bool `json:"implicit_control"` + ImplicitControl string `json:"implicit_control"` } type WebSocket interface { diff --git a/server/internal/webrtc/handle.go b/server/internal/webrtc/handle.go index c75fffb5..01e44602 100644 --- a/server/internal/webrtc/handle.go +++ b/server/internal/webrtc/handle.go @@ -39,10 +39,6 @@ type PayloadKey struct { } func (manager *WebRTCManager) handle(id string, msg webrtc.DataChannelMessage) error { - if (!manager.config.ImplicitControl && !manager.sessions.IsHost(id)) || (manager.config.ImplicitControl && !manager.sessions.CanControl(id)) { - return nil - } - buffer := bytes.NewBuffer(msg.Data) header := &PayloadHeader{} hbytes := make([]byte, 3) @@ -55,6 +51,12 @@ func (manager *WebRTCManager) handle(id string, msg webrtc.DataChannelMessage) e return err } + isClickEvent = header.Event == OP_KEY_CLK + // Confirm we can can continue + if (!manager.sessions.CanControl(id, isClickEvent)) { + return nil + } + buffer = bytes.NewBuffer(msg.Data) switch header.Event {