mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-01-28 16:41:52 +08:00
feat!: 移除内置公共服务器
- 移除公共 RustDesk ID 服务器 (用户需自行配置) - 移除公共 TURN 服务器 (仅保留 Google STUN) - 清理废弃代码: PublicServerInfo, is_using_public_server 等 - 更新前端 UI 和国际化文本 - 重新生成 TypeScript 类型 破坏性变更: 不再提供内置公共服务器。用户必须配置自己的 RustDesk 服务器和 TURN 服务器才能在生产环境中使用。
This commit is contained in:
@@ -256,12 +256,6 @@ export const extensionsApi = {
|
||||
|
||||
// ===== RustDesk 配置 API =====
|
||||
|
||||
/** 公共服务器信息 */
|
||||
export interface PublicServerInfo {
|
||||
server: string
|
||||
public_key: string
|
||||
}
|
||||
|
||||
/** RustDesk 配置响应 */
|
||||
export interface RustDeskConfigResponse {
|
||||
enabled: boolean
|
||||
@@ -271,7 +265,6 @@ export interface RustDeskConfigResponse {
|
||||
has_password: boolean
|
||||
has_keypair: boolean
|
||||
has_relay_key: boolean
|
||||
using_public_server: boolean
|
||||
}
|
||||
|
||||
/** RustDesk 状态响应 */
|
||||
@@ -279,7 +272,6 @@ export interface RustDeskStatusResponse {
|
||||
config: RustDeskConfigResponse
|
||||
service_status: string
|
||||
rendezvous_status: string | null
|
||||
public_server: PublicServerInfo | null
|
||||
}
|
||||
|
||||
/** RustDesk 配置更新 */
|
||||
|
||||
@@ -570,18 +570,17 @@ export default {
|
||||
// WebRTC / ICE
|
||||
webrtcSettings: 'WebRTC Settings',
|
||||
webrtcSettingsDesc: 'Configure STUN/TURN servers for NAT traversal',
|
||||
usingPublicIceServers: 'Using public ICE servers',
|
||||
publicIceServersHint: 'Leave empty to use built-in public STUN/TURN servers for NAT traversal',
|
||||
publicIceServersHint: 'Empty uses Google public STUN, configure your own TURN for production',
|
||||
stunServer: 'STUN Server',
|
||||
stunServerPlaceholder: 'stun:stun.l.google.com:19302',
|
||||
stunServerHint: 'Custom STUN server (leave empty to use public server)',
|
||||
stunServerHint: 'Custom STUN server (leave empty to use Google public server)',
|
||||
turnServer: 'TURN Server',
|
||||
turnServerPlaceholder: 'turn:turn.example.com:3478',
|
||||
turnServerHint: 'Custom TURN relay server (leave empty to use public server)',
|
||||
turnServerHint: 'Custom TURN relay server (required for production)',
|
||||
turnUsername: 'TURN Username',
|
||||
turnPassword: 'TURN Password',
|
||||
turnPasswordConfigured: 'Password already configured. Leave empty to keep current password.',
|
||||
turnCredentialsHint: 'Credentials for TURN server authentication (only needed for custom servers)',
|
||||
turnCredentialsHint: 'Credentials for TURN server authentication',
|
||||
iceConfigNote: 'Note: Changes require reconnecting the WebRTC session to take effect.',
|
||||
},
|
||||
virtualKeyboard: {
|
||||
@@ -703,7 +702,7 @@ export default {
|
||||
serverSettings: 'Server Settings',
|
||||
rendezvousServer: 'ID Server',
|
||||
rendezvousServerPlaceholder: 'hbbs.example.com:21116',
|
||||
rendezvousServerHint: 'Leave empty to use public server',
|
||||
rendezvousServerHint: 'Configure your RustDesk server address',
|
||||
relayServer: 'Relay Server',
|
||||
relayServerPlaceholder: 'hbbr.example.com:21117',
|
||||
relayServerHint: 'Relay server address, auto-derived from ID server if empty',
|
||||
@@ -711,10 +710,6 @@ export default {
|
||||
relayKeyPlaceholder: 'Enter relay server key',
|
||||
relayKeySet: '••••••••',
|
||||
relayKeyHint: 'Authentication key for relay server (if server uses -k option)',
|
||||
publicServerInfo: 'Public Server Info',
|
||||
publicServerAddress: 'Server Address',
|
||||
publicServerKey: 'Connection Key',
|
||||
usingPublicServer: 'Using public server',
|
||||
deviceInfo: 'Device Info',
|
||||
deviceId: 'Device ID',
|
||||
deviceIdHint: 'Use this ID in RustDesk client to connect',
|
||||
|
||||
@@ -570,18 +570,17 @@ export default {
|
||||
// WebRTC / ICE
|
||||
webrtcSettings: 'WebRTC 设置',
|
||||
webrtcSettingsDesc: '配置 STUN/TURN 服务器以实现 NAT 穿透',
|
||||
usingPublicIceServers: '正在使用公共 ICE 服务器',
|
||||
publicIceServersHint: '留空以使用内置的公共 STUN/TURN 服务器进行 NAT 穿透',
|
||||
publicIceServersHint: '留空将使用 Google 公共 STUN 服务器,TURN 服务器需自行配置',
|
||||
stunServer: 'STUN 服务器',
|
||||
stunServerPlaceholder: 'stun:stun.l.google.com:19302',
|
||||
stunServerHint: '自定义 STUN 服务器(留空则使用公共服务器)',
|
||||
stunServerHint: '自定义 STUN 服务器(留空则使用 Google 公共服务器)',
|
||||
turnServer: 'TURN 服务器',
|
||||
turnServerPlaceholder: 'turn:turn.example.com:3478',
|
||||
turnServerHint: '自定义 TURN 中继服务器(留空则使用公共服务器)',
|
||||
turnServerHint: '自定义 TURN 中继服务器(生产环境必须配置)',
|
||||
turnUsername: 'TURN 用户名',
|
||||
turnPassword: 'TURN 密码',
|
||||
turnPasswordConfigured: '密码已配置。留空则保持当前密码。',
|
||||
turnCredentialsHint: '用于 TURN 服务器认证的凭据(仅自定义服务器需要)',
|
||||
turnCredentialsHint: '用于 TURN 服务器认证的凭据',
|
||||
iceConfigNote: '注意:更改后需要重新连接 WebRTC 会话才能生效。',
|
||||
},
|
||||
virtualKeyboard: {
|
||||
@@ -703,7 +702,7 @@ export default {
|
||||
serverSettings: '服务器设置',
|
||||
rendezvousServer: 'ID 服务器',
|
||||
rendezvousServerPlaceholder: 'hbbs.example.com:21116',
|
||||
rendezvousServerHint: '留空则使用公共服务器',
|
||||
rendezvousServerHint: '请配置您的 RustDesk 服务器地址',
|
||||
relayServer: '中继服务器',
|
||||
relayServerPlaceholder: 'hbbr.example.com:21117',
|
||||
relayServerHint: '中继服务器地址,留空则自动从 ID 服务器推导',
|
||||
@@ -711,10 +710,6 @@ export default {
|
||||
relayKeyPlaceholder: '输入中继服务器密钥',
|
||||
relayKeySet: '••••••••',
|
||||
relayKeyHint: '中继服务器认证密钥(如果服务器使用 -k 选项)',
|
||||
publicServerInfo: '公共服务器信息',
|
||||
publicServerAddress: '服务器地址',
|
||||
publicServerKey: '连接密钥',
|
||||
usingPublicServer: '正在使用公共服务器',
|
||||
deviceInfo: '设备信息',
|
||||
deviceId: '设备 ID',
|
||||
deviceIdHint: '此 ID 用于 RustDesk 客户端连接',
|
||||
|
||||
@@ -314,9 +314,8 @@ export interface RustDeskConfig {
|
||||
/** Enable RustDesk protocol */
|
||||
enabled: boolean;
|
||||
/**
|
||||
* Rendezvous server address (hbbs), e.g., "rs.example.com" or "192.168.1.100"
|
||||
* Port defaults to 21116 if not specified
|
||||
* If empty, uses the public server from secrets.toml
|
||||
* Rendezvous server address (hbbs), e.g., "rs.example.com" or "192.168.1.100:21116"
|
||||
* Required for RustDesk to function
|
||||
*/
|
||||
rendezvous_server: string;
|
||||
/**
|
||||
@@ -517,14 +516,6 @@ export interface MsdConfigUpdate {
|
||||
virtual_drive_size_mb?: number;
|
||||
}
|
||||
|
||||
/** Public server information for display to users */
|
||||
export interface PublicServerInfo {
|
||||
/** Public server address */
|
||||
server: string;
|
||||
/** Public key for client connection */
|
||||
public_key: string;
|
||||
}
|
||||
|
||||
export interface RustDeskConfigUpdate {
|
||||
enabled?: boolean;
|
||||
rendezvous_server?: string;
|
||||
|
||||
@@ -105,6 +105,12 @@ const mousePosition = ref({ x: 0, y: 0 })
|
||||
const lastMousePosition = ref({ x: 0, y: 0 }) // Track last position for relative mode
|
||||
const isPointerLocked = ref(false) // Track pointer lock state
|
||||
|
||||
// Mouse move throttling (60 Hz = ~16.67ms interval)
|
||||
const MOUSE_SEND_INTERVAL_MS = 16
|
||||
let mouseSendTimer: ReturnType<typeof setInterval> | null = null
|
||||
let pendingMouseMove: { type: 'move' | 'move_abs'; x: number; y: number } | null = null
|
||||
let accumulatedDelta = { x: 0, y: 0 } // For relative mode: accumulate deltas between sends
|
||||
|
||||
// Cursor visibility (from localStorage, updated via storage event)
|
||||
const cursorVisible = ref(localStorage.getItem('hidShowCursor') !== 'false')
|
||||
|
||||
@@ -1479,20 +1485,21 @@ function handleMouseMove(e: MouseEvent) {
|
||||
const y = Math.round((e.clientY - rect.top) / rect.height * 32767)
|
||||
|
||||
mousePosition.value = { x, y }
|
||||
sendMouseEvent({ type: 'move_abs', x, y })
|
||||
// Queue for throttled sending (absolute mode: just update pending position)
|
||||
pendingMouseMove = { type: 'move_abs', x, y }
|
||||
ensureMouseSendTimer()
|
||||
} else {
|
||||
// Relative mode: use movementX/Y when pointer is locked
|
||||
if (isPointerLocked.value) {
|
||||
const dx = e.movementX
|
||||
const dy = e.movementY
|
||||
|
||||
// Only send if there's actual movement
|
||||
// Only accumulate if there's actual movement
|
||||
if (dx !== 0 || dy !== 0) {
|
||||
// Clamp to i8 range (-127 to 127)
|
||||
const clampedDx = Math.max(-127, Math.min(127, dx))
|
||||
const clampedDy = Math.max(-127, Math.min(127, dy))
|
||||
|
||||
sendMouseEvent({ type: 'move', x: clampedDx, y: clampedDy })
|
||||
// Accumulate deltas for throttled sending
|
||||
accumulatedDelta.x += dx
|
||||
accumulatedDelta.y += dy
|
||||
ensureMouseSendTimer()
|
||||
}
|
||||
|
||||
// Update display position (accumulated delta for display only)
|
||||
@@ -1504,6 +1511,50 @@ function handleMouseMove(e: MouseEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
// Start the mouse send timer if not already running
|
||||
function ensureMouseSendTimer() {
|
||||
if (mouseSendTimer !== null) return
|
||||
|
||||
// Send immediately on first event, then throttle
|
||||
flushMouseMove()
|
||||
|
||||
mouseSendTimer = setInterval(() => {
|
||||
if (!flushMouseMove()) {
|
||||
// No pending data, stop the timer
|
||||
if (mouseSendTimer !== null) {
|
||||
clearInterval(mouseSendTimer)
|
||||
mouseSendTimer = null
|
||||
}
|
||||
}
|
||||
}, MOUSE_SEND_INTERVAL_MS)
|
||||
}
|
||||
|
||||
// Flush pending mouse move data, returns true if data was sent
|
||||
function flushMouseMove(): boolean {
|
||||
if (mouseMode.value === 'absolute') {
|
||||
if (pendingMouseMove) {
|
||||
sendMouseEvent(pendingMouseMove)
|
||||
pendingMouseMove = null
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
// Relative mode: send accumulated delta
|
||||
if (accumulatedDelta.x !== 0 || accumulatedDelta.y !== 0) {
|
||||
// Clamp to i8 range (-127 to 127)
|
||||
const clampedDx = Math.max(-127, Math.min(127, accumulatedDelta.x))
|
||||
const clampedDy = Math.max(-127, Math.min(127, accumulatedDelta.y))
|
||||
|
||||
sendMouseEvent({ type: 'move', x: clampedDx, y: clampedDy })
|
||||
|
||||
// Subtract sent amount (keep remainder for next send if clamped)
|
||||
accumulatedDelta.x -= clampedDx
|
||||
accumulatedDelta.y -= clampedDy
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Track pressed mouse button for window-level mouseup handling
|
||||
const pressedMouseButton = ref<'left' | 'right' | 'middle' | null>(null)
|
||||
|
||||
@@ -1746,6 +1797,12 @@ onUnmounted(() => {
|
||||
// Reset initial device info flag
|
||||
initialDeviceInfoReceived = false
|
||||
|
||||
// Clear mouse send timer
|
||||
if (mouseSendTimer !== null) {
|
||||
clearInterval(mouseSendTimer)
|
||||
mouseSendTimer = null
|
||||
}
|
||||
|
||||
// Clear ttyd poll interval
|
||||
if (ttydPollInterval) {
|
||||
clearInterval(ttydPollInterval)
|
||||
|
||||
@@ -47,12 +47,6 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog'
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from '@/components/ui/tooltip'
|
||||
import {
|
||||
Monitor,
|
||||
Keyboard,
|
||||
@@ -82,7 +76,6 @@ import {
|
||||
ExternalLink,
|
||||
Copy,
|
||||
ScreenShare,
|
||||
CircleHelp,
|
||||
} from 'lucide-vue-next'
|
||||
|
||||
const { t, locale } = useI18n()
|
||||
@@ -2094,28 +2087,7 @@ onMounted(async () => {
|
||||
v-model="rustdeskLocalConfig.rendezvous_server"
|
||||
:placeholder="t('extensions.rustdesk.rendezvousServerPlaceholder')"
|
||||
/>
|
||||
<div class="flex items-center gap-1">
|
||||
<p class="text-xs text-muted-foreground">{{ t('extensions.rustdesk.rendezvousServerHint') }}</p>
|
||||
<TooltipProvider v-if="rustdeskStatus?.public_server">
|
||||
<Tooltip>
|
||||
<TooltipTrigger as-child>
|
||||
<CircleHelp class="h-3.5 w-3.5 text-muted-foreground cursor-help" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right" class="max-w-xs">
|
||||
<div class="space-y-1.5 text-xs">
|
||||
<p class="font-medium">{{ t('extensions.rustdesk.publicServerInfo') }}</p>
|
||||
<div class="space-y-1">
|
||||
<p><span class="text-muted-foreground">{{ t('extensions.rustdesk.publicServerAddress') }}:</span> {{ rustdeskStatus.public_server.server }}</p>
|
||||
<p><span class="text-muted-foreground">{{ t('extensions.rustdesk.publicServerKey') }}:</span> <code class="text-[10px] break-all">{{ rustdeskStatus.public_server.public_key }}</code></p>
|
||||
</div>
|
||||
</div>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
<p v-if="rustdeskStatus?.config?.using_public_server" class="text-xs text-blue-500">
|
||||
{{ t('extensions.rustdesk.usingPublicServer') }}
|
||||
</p>
|
||||
<p class="text-xs text-muted-foreground">{{ t('extensions.rustdesk.rendezvousServerHint') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
|
||||
Reference in New Issue
Block a user