Feature(Go): Mouse/keyboard input + user management with users.json (Phase 5 + 7)
This commit is contained in:
@@ -48,6 +48,7 @@ type Device struct {
|
||||
Location string // client-reported geo string (reserved field 10)
|
||||
PeerIP string // network-level remote address as seen by the server
|
||||
PublicIP string // client-reported public IP (reserved field 11)
|
||||
Resolution string // client-formatted screen geometry "N:W*H" (reserved field 15)
|
||||
ConnectedAt time.Time
|
||||
|
||||
// Live fields refreshed on every heartbeat. Protected by hub.mu.
|
||||
@@ -115,6 +116,18 @@ func (h *Hub) MainConn(id string) *connection.Context {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Capability returns the device's reported capability hex string
|
||||
// (LOGIN_INFOR.moduleVersion tail). Empty for unknown devices — callers
|
||||
// should treat that as "no caps" (legacy Windows GBK default).
|
||||
func (h *Hub) Capability(id string) string {
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
if d, ok := h.devices[id]; ok {
|
||||
return d.Capability
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// DeviceInfo is the JSON-safe projection of Device for the /api/devices
|
||||
// endpoint and the WS device_list message. Field names match what the
|
||||
// existing browser front-end expects.
|
||||
@@ -131,6 +144,7 @@ type DeviceInfo struct {
|
||||
Location string `json:"location,omitempty"`
|
||||
IP string `json:"ip"` // client-reported public IP (matches C++ key)
|
||||
PeerIP string `json:"peer_ip,omitempty"`
|
||||
Screen string `json:"screen,omitempty"` // "N:W*H" — matches C++ DeviceInfo.screen key
|
||||
RTT int `json:"rtt"`
|
||||
ActiveWindow string `json:"activeWindow,omitempty"`
|
||||
ConnectedAt int64 `json:"connected_at"`
|
||||
@@ -205,6 +219,30 @@ func (h *Hub) SendToDevice(id string, data []byte) error {
|
||||
return h.sender(d.conn, data)
|
||||
}
|
||||
|
||||
// SendToScreen routes a payload to the device's currently-bound screen
|
||||
// sub-connection. Input events (COMMAND_SCREEN_CONTROL) MUST go through the
|
||||
// screen sub-conn rather than the main conn — the C++ client only dispatches
|
||||
// these commands from CScreenManager::OnReceive, which reads exclusively from
|
||||
// the sub-conn (see client/ScreenManager.cpp:1065). Returns ErrDeviceOffline
|
||||
// when the device is unknown OR has no active screen session, so callers can
|
||||
// quietly drop input from browsers that haven't called connect yet.
|
||||
func (h *Hub) SendToScreen(id string, data []byte) error {
|
||||
h.mu.RLock()
|
||||
d, ok := h.devices[id]
|
||||
var sc *connection.Context
|
||||
if ok {
|
||||
sc = d.screenConn
|
||||
}
|
||||
h.mu.RUnlock()
|
||||
if !ok || sc == nil {
|
||||
return ErrDeviceOffline
|
||||
}
|
||||
if h.sender == nil {
|
||||
return ErrNoSender
|
||||
}
|
||||
return h.sender(sc, data)
|
||||
}
|
||||
|
||||
// BindScreenConn associates a freshly-arrived sub-connection (the one that
|
||||
// just sent TOKEN_BITMAPINFO) with the device identified by clientID.
|
||||
// Returns false if the device is not registered — callers should drop the
|
||||
@@ -350,6 +388,7 @@ func deviceToInfo(d *Device) DeviceInfo {
|
||||
Location: d.Location,
|
||||
IP: d.PublicIP,
|
||||
PeerIP: d.PeerIP,
|
||||
Screen: d.Resolution,
|
||||
RTT: d.RTT,
|
||||
ActiveWindow: d.ActiveWindow,
|
||||
ConnectedAt: d.ConnectedAt.Unix(),
|
||||
|
||||
Reference in New Issue
Block a user