add fields to stats.
This commit is contained in:
parent
6d7486ab57
commit
f59128cf72
@ -7,6 +7,7 @@
|
||||
- Ability to set locks from config `NEKO_LOCKS=control login`.
|
||||
- Added control protection - users can gain control only if at least one admin is in the room `NEKO_CONTROL_PROTECTION=true`.
|
||||
- Emotes sending on mouse down holding.
|
||||
- Include `banned`, `locked`, `server_started_at`, `last_admin_left_at`, `last_user_left_at`, `control_protection` data in stats.
|
||||
|
||||
### Misc
|
||||
- ARM-based images not bound to Raspberry Pi only.
|
||||
|
@ -1,11 +1,23 @@
|
||||
package types
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Stats struct {
|
||||
Connections uint32 `json:"connections"`
|
||||
Host string `json:"host"`
|
||||
Members []*Member `json:"members"`
|
||||
|
||||
Banned map[string]string `json:"banned"` // IP -> session ID (that banned it)
|
||||
Locked map[string]string `json:"locked"` // resource name -> session ID (that locked it)
|
||||
|
||||
ServerStartedAt time.Time `json:"server_started_at"`
|
||||
LastAdminLeftAt *time.Time `json:"last_admin_left_at"`
|
||||
LastUserLeftAt *time.Time `json:"last_user_left_at"`
|
||||
|
||||
ControlProtection bool `json:"control_protection"`
|
||||
}
|
||||
|
||||
type WebSocket interface {
|
||||
|
@ -292,8 +292,7 @@ func (h *MessageHandler) adminBan(id string, session types.Session, payload *mes
|
||||
}
|
||||
|
||||
h.logger.Debug().Str("address", remote).Msg("adding address to banned")
|
||||
|
||||
h.banned[address[0]] = true
|
||||
h.banned[address[0]] = id
|
||||
|
||||
if err := target.Kick("banned"); err != nil {
|
||||
return err
|
||||
|
@ -18,8 +18,8 @@ type MessageHandler struct {
|
||||
webrtc types.WebRTCManager
|
||||
remote types.RemoteManager
|
||||
broadcast types.BroadcastManager
|
||||
banned map[string]bool
|
||||
locked map[string]string
|
||||
banned map[string]string // IP -> session ID (that banned it)
|
||||
locked map[string]string // resource name -> session ID (that locked it)
|
||||
}
|
||||
|
||||
func (h *MessageHandler) Connected(admin bool, socket *WebSocket) (bool, string) {
|
||||
@ -27,8 +27,8 @@ func (h *MessageHandler) Connected(admin bool, socket *WebSocket) (bool, string)
|
||||
if address == "" {
|
||||
h.logger.Debug().Msg("no remote address")
|
||||
} else {
|
||||
ok, banned := h.banned[address]
|
||||
if ok && banned {
|
||||
_, ok := h.banned[address]
|
||||
if ok {
|
||||
h.logger.Debug().Str("address", address).Msg("banned")
|
||||
return false, "banned"
|
||||
}
|
||||
|
@ -18,12 +18,20 @@ import (
|
||||
"m1k1o/neko/internal/utils"
|
||||
)
|
||||
|
||||
const CONTROL_PROTECTION_SESSION = "control_protection"
|
||||
const CONTROL_PROTECTION_SESSION = "by_control_protection"
|
||||
|
||||
func New(sessions types.SessionManager, remote types.RemoteManager, broadcast types.BroadcastManager, webrtc types.WebRTCManager, conf *config.WebSocket) *WebSocketHandler {
|
||||
logger := log.With().Str("module", "websocket").Logger()
|
||||
|
||||
locks := make(map[string]string)
|
||||
|
||||
// if control protection is enabled
|
||||
if conf.ControlProtection {
|
||||
locks["control"] = CONTROL_PROTECTION_SESSION
|
||||
logger.Info().Msgf("control locked on behalf of control protection")
|
||||
}
|
||||
|
||||
// apply default locks
|
||||
for _, lock := range conf.Locks {
|
||||
locks[lock] = "" // empty session ID
|
||||
}
|
||||
@ -32,12 +40,6 @@ func New(sessions types.SessionManager, remote types.RemoteManager, broadcast ty
|
||||
logger.Info().Msgf("locked resources: %+v", conf.Locks)
|
||||
}
|
||||
|
||||
// if control protection is enabled
|
||||
if conf.ControlProtection {
|
||||
locks["control"] = CONTROL_PROTECTION_SESSION
|
||||
logger.Info().Msgf("control locked on behalf of control protection")
|
||||
}
|
||||
|
||||
return &WebSocketHandler{
|
||||
logger: logger,
|
||||
shutdown: make(chan interface{}),
|
||||
@ -55,10 +57,10 @@ func New(sessions types.SessionManager, remote types.RemoteManager, broadcast ty
|
||||
broadcast: broadcast,
|
||||
sessions: sessions,
|
||||
webrtc: webrtc,
|
||||
banned: make(map[string]bool),
|
||||
banned: make(map[string]string),
|
||||
locked: locks,
|
||||
},
|
||||
conns: 0,
|
||||
serverStartedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +76,12 @@ type WebSocketHandler struct {
|
||||
remote types.RemoteManager
|
||||
conf *config.WebSocket
|
||||
handler *MessageHandler
|
||||
|
||||
// stats
|
||||
conns uint32
|
||||
serverStartedAt time.Time
|
||||
lastAdminLeftAt *time.Time
|
||||
lastUserLeftAt *time.Time
|
||||
}
|
||||
|
||||
func (ws *WebSocketHandler) Start() {
|
||||
@ -109,6 +116,13 @@ func (ws *WebSocketHandler) Start() {
|
||||
ws.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_UNLOCK)
|
||||
}
|
||||
}
|
||||
|
||||
// remove outdated stats
|
||||
if session.Admin() {
|
||||
ws.lastAdminLeftAt = nil
|
||||
} else {
|
||||
ws.lastUserLeftAt = nil
|
||||
}
|
||||
})
|
||||
|
||||
ws.sessions.OnDestroy(func(id string, session types.Session) {
|
||||
@ -118,8 +132,13 @@ func (ws *WebSocketHandler) Start() {
|
||||
ws.logger.Debug().Str("id", id).Msg("session destroyed")
|
||||
}
|
||||
|
||||
membersCount := len(ws.sessions.Members())
|
||||
adminCount := len(ws.sessions.Admins())
|
||||
|
||||
// if control protection is enabled and no admin
|
||||
if ws.conf.ControlProtection && len(ws.sessions.Admins()) == 0 {
|
||||
// and room is not locked, lock
|
||||
_, ok := ws.handler.locked["control"]
|
||||
if !ok && ws.conf.ControlProtection && adminCount == 0 {
|
||||
ws.handler.locked["control"] = CONTROL_PROTECTION_SESSION
|
||||
ws.logger.Info().Msgf("control locked and released on behalf of control protection")
|
||||
ws.handler.adminRelease(id, session)
|
||||
@ -133,6 +152,18 @@ func (ws *WebSocketHandler) Start() {
|
||||
ws.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_LOCK)
|
||||
}
|
||||
}
|
||||
|
||||
// if this was the last admin
|
||||
if session.Admin() && adminCount == 0 {
|
||||
now := time.Now()
|
||||
ws.lastAdminLeftAt = &now
|
||||
}
|
||||
|
||||
// if this was the last user
|
||||
if !session.Admin() && membersCount-adminCount == 0 {
|
||||
now := time.Now()
|
||||
ws.lastUserLeftAt = &now
|
||||
}
|
||||
})
|
||||
|
||||
ws.wg.Add(1)
|
||||
@ -274,6 +305,15 @@ func (ws *WebSocketHandler) Stats() types.Stats {
|
||||
Connections: atomic.LoadUint32(&ws.conns),
|
||||
Host: host,
|
||||
Members: ws.sessions.Members(),
|
||||
|
||||
Banned: ws.handler.banned,
|
||||
Locked: ws.handler.locked,
|
||||
|
||||
ServerStartedAt: ws.serverStartedAt,
|
||||
LastAdminLeftAt: ws.lastAdminLeftAt,
|
||||
LastUserLeftAt: ws.lastUserLeftAt,
|
||||
|
||||
ControlProtection: ws.conf.ControlProtection,
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user