/** * RustDesk Standalone Web Client - Protobuf Message Definitions * * This module defines all protobuf messages used in the RustDesk protocol * using protobuf.js programmatic definitions (parsed from .proto text format). */ const RDProto = (() => { // Embedded proto definition - complete RustDesk protocol const PROTO_TEXT = ` syntax = "proto3"; package hbb; // ===== Enums ===== enum NatType { UNKNOWN_NAT = 0; ASYMMETRIC = 1; SYMMETRIC = 2; } enum ConnType { DEFAULT_CONN = 0; FILE_TRANSFER = 1; PORT_FORWARD = 2; RDP = 3; VIEW_CAMERA = 4; TERMINAL = 5; } enum ImageQuality { NotSet = 0; Low = 2; Balanced = 3; Best = 4; } enum BoolOption { NotSet = 0; Yes = 1; No = 2; } enum PreferCodec { Auto = 0; VP9 = 1; H264 = 2; H265 = 3; VP8 = 4; AV1 = 5; } enum Chroma { I420 = 0; I444 = 1; } enum KeyboardMode { Legacy = 0; Map = 1; Translate = 2; Auto = 3; } enum ControlKey { Unknown = 0; Alt = 1; Backspace = 2; CapsLock = 3; Control = 4; Delete = 5; DownArrow = 6; End = 7; Escape = 8; F1 = 9; F10 = 10; F11 = 11; F12 = 12; F2 = 13; F3 = 14; F4 = 15; F5 = 16; F6 = 17; F7 = 18; F8 = 19; F9 = 20; Home = 21; LeftArrow = 22; Meta = 23; PageDown = 24; PageUp = 25; Return = 26; RightArrow = 27; Shift = 28; Space = 29; Tab = 30; UpArrow = 31; Numpad0 = 32; Numpad1 = 33; Numpad2 = 34; Numpad3 = 35; Numpad4 = 36; Numpad5 = 37; Numpad6 = 38; Numpad7 = 39; Numpad8 = 40; Numpad9 = 41; NumpadAdd = 42; NumpadDecimal = 43; NumpadDelete = 44; NumpadDivide = 45; NumpadEnter = 46; NumpadMultiply = 47; NumpadSubtract = 48; Insert = 49; LeftControl = 50; LeftShift = 51; LeftAlt = 52; LeftMeta = 53; RightControl = 54; RightShift = 55; RightAlt = 56; RightMeta = 57; VolumeDown = 58; VolumeMute = 59; VolumeUp = 60; Win = 61; WakeUp = 62; NumLock = 63; ScrollLock = 64; Print = 65; PrintScreen = 66; CtrlAltDel = 100; LockScreen = 101; } // ===== Rendezvous Protocol ===== message RendezvousMessage { oneof union { RegisterPeer register_peer = 6; RegisterPeerResponse register_peer_response = 7; PunchHoleRequest punch_hole_request = 8; PunchHole punch_hole = 9; PunchHoleSent punch_hole_sent = 10; PunchHoleResponse punch_hole_response = 11; FetchLocalAddr fetch_local_addr = 12; LocalAddr local_addr = 13; ConfigUpdate configure_update = 14; RegisterPk register_pk = 15; RegisterPkResponse register_pk_response = 16; SoftwareUpdate software_update = 17; RequestRelay request_relay = 18; RelayResponse relay_response = 19; TestNatRequest test_nat_request = 20; TestNatResponse test_nat_response = 21; PeerDiscovery peer_discovery = 22; OnlineRequest online_request = 23; OnlineResponse online_response = 24; KeyExchange key_exchange = 25; HealthCheck hc = 26; HttpProxyRequest http_proxy_request = 27; HttpProxyResponse http_proxy_response = 28; } } message RegisterPeer { string id = 1; uint32 serial = 2; } message RegisterPeerResponse { bool request_pk = 1; } message RegisterPk { string id = 1; string uuid = 2; bytes pk = 3; string old_id = 4; bool no_register_device = 5; } message RegisterPkResponse { enum Result { OK = 0; UUID_MISMATCH = 2; ID_EXISTS = 3; TOO_FREQUENT = 4; INVALID_ID_FORMAT = 5; NOT_SUPPORT = 6; SERVER_ERROR = 7; } Result result = 1; } message PunchHoleRequest { string id = 1; NatType nat_type = 2; string licence_key = 3; ConnType conn_type = 4; string token = 5; string version = 6; uint32 udp_port = 7; bool force_relay = 8; string socket_addr_v6 = 9; } message PunchHole { string socket_addr = 1; string relay_server = 2; NatType nat_type = 3; uint32 udp_port = 4; bool force_relay = 5; string socket_addr_v6 = 6; } message PunchHoleSent { string socket_addr = 1; string id = 2; string relay_server = 3; NatType nat_type = 4; string version = 5; uint32 udp_port = 6; string socket_addr_v6 = 7; } message PunchHoleResponse { string socket_addr = 1; bytes pk = 2; enum Failure { ID_NOT_EXIST = 0; OFFLINE = 2; LICENSE_MISMATCH = 3; LICENSE_OVERUSE = 4; } Failure failure = 3; string relay_server = 4; oneof union { NatType nat_type = 5; bool is_local = 6; } string other_failure = 7; string feedback = 8; bool is_udp = 9; uint32 udp_port = 10; string socket_addr_v6 = 11; } message RequestRelay { string id = 1; string uuid = 2; string socket_addr = 3; string relay_server = 4; bool secure = 5; string licence_key = 6; ConnType conn_type = 7; string token = 8; } message RelayResponse { string socket_addr = 1; string uuid = 2; string relay_server = 3; oneof union { string id = 4; bytes pk = 5; } string refuse_reason = 6; string version = 7; string feedback = 8; string socket_addr_v6 = 9; uint32 udp_port = 10; } message OnlineRequest { string id = 1; repeated string peers = 2; } message OnlineResponse { bytes states = 1; } message KeyExchange { repeated bytes keys = 1; } message FetchLocalAddr { string socket_addr = 1; string relay_server = 2; string socket_addr_v6 = 3; } message LocalAddr { string socket_addr = 1; string local_addr = 2; string relay_server = 3; string id = 4; string version = 5; string socket_addr_v6 = 6; } message ConfigUpdate { uint32 serial = 1; repeated string rendezvous_servers = 2; } message SoftwareUpdate { string url = 1; } message TestNatRequest { uint32 serial = 1; } message TestNatResponse { uint32 port = 1; ConfigUpdate cu = 2; } message PeerDiscovery { string cmd = 1; string mac = 2; string id = 3; string username = 4; string hostname = 5; string platform = 6; string misc = 7; } message HealthCheck { string token = 1; } message HttpProxyRequest { string method = 1; string path = 2; repeated HeaderEntry headers = 3; bytes body = 4; } message HttpProxyResponse { int32 status = 1; repeated HeaderEntry headers = 2; bytes body = 3; string error = 4; } message HeaderEntry { string name = 1; string value = 2; } // ===== Session Protocol ===== message Message { oneof union { SignedId signed_id = 3; PublicKey public_key = 4; TestDelay test_delay = 5; VideoFrame video_frame = 6; LoginRequest login_request = 7; LoginResponse login_response = 8; Hash hash = 9; MouseEvent mouse_event = 10; AudioFrame audio_frame = 11; CursorData cursor_data = 12; CursorPosition cursor_position = 13; uint64 cursor_id = 14; KeyEvent key_event = 15; Clipboard clipboard = 16; FileAction file_action = 17; FileResponse file_response = 18; Misc misc = 19; Cliprdr cliprdr = 20; MessageBox message_box = 21; SwitchSidesResponse switch_sides_response = 22; VoiceCallRequest voice_call_request = 23; VoiceCallResponse voice_call_response = 24; PeerInfo peer_info = 25; PointerDeviceEvent pointer_device_event = 26; Auth2FA auth_2fa = 27; MultiClipboards multi_clipboards = 28; ScreenshotRequest screenshot_request = 29; ScreenshotResponse screenshot_response = 30; TerminalAction terminal_action = 31; TerminalResponse terminal_response = 32; } } message SignedId { bytes id = 1; } message IdPk { string id = 1; bytes pk = 2; } message PublicKey { bytes asymmetric_value = 1; bytes symmetric_value = 2; } message Hash { string salt = 1; string challenge = 2; } message LoginRequest { string username = 1; bytes password = 2; string my_id = 4; string my_name = 5; OptionMessage option = 6; oneof union { FileTransfer file_transfer = 7; PortForward port_forward = 8; ViewCamera view_camera = 15; Terminal terminal = 16; } bool video_ack_required = 9; uint64 session_id = 10; string version = 11; OSLogin os_login = 12; string my_platform = 13; bytes hwid = 14; string avatar = 17; } message LoginResponse { oneof union { string error = 1; PeerInfo peer_info = 2; } bool enable_trusted_devices = 3; } message PeerInfo { string username = 1; string hostname = 2; string platform = 3; repeated DisplayInfo displays = 4; int32 current_display = 5; bool sas_enabled = 6; string version = 7; Features features = 8; SupportedEncoding encoding = 9; SupportedResolutions resolutions = 10; string platform_additions = 11; WindowsSessions windows_sessions = 12; } message DisplayInfo { sint32 x = 1; sint32 y = 2; int32 width = 3; int32 height = 4; string name = 5; bool online = 6; bool cursor_embedded = 7; Resolution original_resolution = 8; double scale = 9; } message Resolution { int32 width = 1; int32 height = 2; } message Features { bool privacy_mode = 1; bool terminal = 2; } message SupportedEncoding { bool h264 = 1; bool h265 = 2; bool vp8 = 3; bool av1 = 4; CodecAbility i444 = 5; } message CodecAbility { bool vp8 = 1; bool vp9 = 2; bool av1 = 3; bool h264 = 4; bool h265 = 5; } message SupportedResolutions { repeated Resolution resolutions = 1; } message WindowsSessions { repeated WindowsSession sessions = 1; uint32 current_sid = 2; } message WindowsSession { uint32 sid = 1; string name = 2; } message OptionMessage { ImageQuality image_quality = 1; BoolOption lock_after_session_end = 2; BoolOption show_remote_cursor = 3; BoolOption privacy_mode = 4; int32 custom_image_quality = 5; BoolOption disable_audio = 6; BoolOption enable_file_transfer = 7; BoolOption clipboard = 8; SupportedDecoding supported_decoding = 9; int32 custom_fps = 10; BoolOption follow_remote_cursor = 11; BoolOption follow_remote_window = 12; BoolOption disable_camera = 13; BoolOption block_input = 14; BoolOption keyboard = 15; BoolOption terminal_persistent = 16; BoolOption show_my_cursor = 17; } message SupportedDecoding { bool ability_vp9 = 1; bool ability_h264 = 2; bool ability_h265 = 3; bool ability_vp8 = 4; bool ability_av1 = 5; PreferCodec prefer = 6; CodecAbility i444 = 7; Chroma prefer_chroma = 8; } message FileTransfer { string dir = 1; bool show_hidden = 2; } message PortForward { string host = 1; int32 port = 2; } message ViewCamera {} message Terminal { string service_id = 1; } message OSLogin { string username = 1; string password = 2; } // ===== Video ===== message VideoFrame { oneof union { EncodedVideoFrames vp9s = 6; RGB rgb = 7; YUV yuv = 8; EncodedVideoFrames h264s = 10; EncodedVideoFrames h265s = 11; EncodedVideoFrames vp8s = 12; EncodedVideoFrames av1s = 13; } int32 display = 14; } message EncodedVideoFrames { repeated EncodedVideoFrame frames = 1; } message EncodedVideoFrame { bytes data = 1; bool key = 2; int64 pts = 3; } message RGB { bool compress = 1; } message YUV { bool compress = 1; int32 stride = 2; } // ===== Audio ===== message AudioFrame { bytes data = 1; } // ===== Input ===== message MouseEvent { int32 mask = 1; sint32 x = 2; sint32 y = 3; repeated ControlKey modifiers = 4; } message KeyEvent { bool down = 1; bool press = 2; oneof union { ControlKey control_key = 3; uint32 chr = 4; uint32 unicode = 5; string seq = 6; uint32 win2win_hotkey = 7; } repeated ControlKey modifiers = 8; KeyboardMode mode = 9; } // ===== Cursor ===== message CursorData { uint64 id = 1; sint32 hotx = 2; sint32 hoty = 3; int32 width = 4; int32 height = 5; bytes colors = 6; } message CursorPosition { sint32 x = 1; sint32 y = 2; } // ===== Misc ===== message Misc { oneof union { ChatMessage chat_message = 1; SwitchDisplay switch_display = 2; PermissionInfo permission_info = 3; Option option = 4; AudioFormat audio_format = 5; string close_reason = 6; bool refresh_video = 7; bool video_received = 8; BackNotification back_notification = 9; bool restart_remote_device = 10; bool uac = 11; bool foreground_window_elevated = 12; bool stop_service = 13; ElevationRequest elevation_request = 14; bool elevation_response = 15; bool portable_service_running = 16; SwitchSidesRequest switch_sides_request = 17; SwitchBack switch_back = 18; ChangeResolution change_resolution = 19; PluginRequest plugin_request = 20; PluginFailure plugin_failure = 21; bool full_speed_fps = 22; bool auto_adjust_fps = 23; bool client_record_status = 24; CaptureDisplays capture_displays = 25; int32 refresh_video_display = 26; ToggleVirtualDisplay toggle_virtual_display = 27; TogglePrivacyMode toggle_privacy_mode = 28; SupportedEncoding supported_encoding = 29; string selected_sid = 30; DisplayResolution change_display_resolution = 31; MessageQuery message_query = 32; bool follow_current_display = 33; } } message ChatMessage { string text = 1; } message SwitchDisplay { int32 display = 1; sint32 x = 2; sint32 y = 3; int32 width = 4; int32 height = 5; bool cursor_embedded = 6; SupportedResolutions resolutions = 7; Resolution original_resolution = 8; } message PermissionInfo { enum Permission { Keyboard = 0; Clipboard = 2; Audio = 3; File = 4; Restart = 5; Recording = 6; BlockInput = 7; } Permission permission = 1; bool enabled = 2; } message Option { string name = 1; string value = 2; } message AudioFormat { uint32 sample_rate = 1; uint32 channels = 2; } message BackNotification { oneof union { PrivacyModeState privacy_mode_state = 1; BlockInputState block_input_state = 2; } string details = 3; string impl_key = 4; enum PrivacyModeState { OFF = 0; ON = 1; BLANK_SCREEN = 2; } enum BlockInputState { RUNNING = 0; ON = 1; OFF = 2; } } message ElevationRequest { oneof union { bool direct = 1; ElevationRequestWithLogon logon = 2; } } message ElevationRequestWithLogon { string username = 1; string password = 2; } message SwitchSidesRequest { bytes uuid = 1; } message SwitchBack {} message ChangeResolution { Resolution resolution = 1; } message PluginRequest { string id = 1; bytes content = 2; } message PluginFailure { string id = 1; string name = 2; string msg = 3; } message CaptureDisplays { repeated int32 set = 1; repeated int32 add = 2; repeated int32 sub = 3; } message ToggleVirtualDisplay { int32 display = 1; bool on = 2; } message TogglePrivacyMode { string impl_key = 1; bool on = 2; } message DisplayResolution { int32 display = 1; Resolution resolution = 2; } message MessageQuery { int32 switch_display = 1; } // ===== Clipboard ===== message Clipboard { enum ClipboardFormat { Text = 0; Rtf = 1; Html = 2; ImageRgba = 21; ImagePng = 22; ImageSvg = 23; Special = 31; } bool compress = 1; repeated ClipboardContent contents = 2; } message ClipboardContent { Clipboard.ClipboardFormat format = 1; bytes data = 2; } // ===== File Transfer ===== message FileAction { oneof union { ReadDir read_dir = 1; FileTransferSendRequest send = 2; FileTransferReceiveRequest receive = 3; FileDirCreate create = 4; FileRemoveDir remove_dir = 5; FileRemoveFile remove_file = 6; ReadAllFiles all_files = 7; FileTransferCancel cancel = 8; FileTransferSendConfirmRequest send_confirm = 9; FileRename rename = 10; ReadEmptyDirs read_empty_dirs = 11; } } message ReadDir { string path = 1; bool include_hidden = 2; } message ReadAllFiles { string id = 1; string path = 2; bool include_hidden = 3; } message ReadEmptyDirs { string id = 1; string path = 2; bool include_hidden = 3; } message FileDirCreate { string id = 1; string path = 2; } message FileRemoveDir { string id = 1; string path = 2; bool recursive = 3; } message FileRemoveFile { string id = 1; string path = 2; sint32 file_num = 3; } message FileRename { string id = 1; string path = 2; string new_name = 3; } message FileTransferSendRequest { string id = 1; string path = 2; bool include_hidden = 3; sint32 file_num = 4; enum FileType { Generic = 0; Printer = 1; } FileType file_type = 5; } message FileTransferReceiveRequest { string id = 1; string path = 2; repeated FileEntry files = 3; sint32 file_num = 4; uint64 total_size = 5; } message FileTransferSendConfirmRequest { string id = 1; sint32 file_num = 2; oneof union { bool skip = 3; uint32 offset_blk = 4; } } message FileTransferCancel { string id = 1; } message FileResponse { oneof union { FileDirectory dir = 1; FileTransferBlock block = 2; FileTransferError error = 3; FileTransferDone done = 4; FileTransferDigest digest = 5; ReadEmptyDirsResponse empty_dirs = 6; } } message FileDirectory { string id = 1; string path = 2; repeated FileEntry entries = 3; } message FileEntry { enum FileType { Dir = 0; DirLink = 2; DirDrive = 3; File = 4; FileLink = 5; } FileType entry_type = 1; string name = 2; bool is_hidden = 3; uint64 size = 4; uint64 modified_time = 5; } message FileTransferBlock { string id = 1; sint32 file_num = 2; bytes data = 3; bool compressed = 4; uint32 blk_id = 5; } message FileTransferError { string id = 1; string error = 2; sint32 file_num = 3; } message FileTransferDone { string id = 1; sint32 file_num = 2; } message FileTransferDigest { string id = 1; sint32 file_num = 2; uint64 last_modified = 3; uint64 file_size = 4; bool is_upload = 5; bool is_identical = 6; uint64 transferred_size = 7; bool is_resume = 8; } message ReadEmptyDirsResponse { string path = 1; repeated FileDirectory empty_dirs = 2; } // ===== Test Delay ===== message TestDelay { int64 time = 1; bool from_client = 2; int32 last_delay = 3; int32 target_bitrate = 4; } // ===== Auth ===== message Auth2FA { string code = 1; bytes hwid = 2; } // ===== Terminal ===== message TerminalAction { oneof union { OpenTerminal open = 1; TerminalData data = 2; ResizeTerminal resize = 3; CloseTerminal close = 4; } } message TerminalResponse { oneof union { TerminalOpened opened = 1; TerminalData data = 2; TerminalClosed closed = 3; TerminalError error = 4; } } message OpenTerminal { int32 terminal_id = 1; uint32 rows = 2; uint32 cols = 3; } message TerminalData { int32 terminal_id = 1; bytes data = 2; bool compressed = 3; } message ResizeTerminal { int32 terminal_id = 1; uint32 rows = 2; uint32 cols = 3; } message CloseTerminal { int32 terminal_id = 1; } message TerminalOpened { int32 terminal_id = 1; bool success = 2; string message = 3; } message TerminalClosed { int32 terminal_id = 1; int32 exit_code = 2; } message TerminalError { int32 terminal_id = 1; string message = 2; } // ===== Others ===== message MessageBox { string msgtype = 1; string title = 2; string text = 3; string link = 4; } message PointerDeviceEvent { TouchEvent touch = 1; repeated ControlKey modifiers = 2; } message TouchEvent { oneof union { TouchScaleUpdate scale_update = 1; TouchPanStart pan_start = 2; TouchPanUpdate pan_update = 3; TouchPanEnd pan_end = 4; TouchEnd end = 5; } } message TouchScaleUpdate { int32 scale = 1; } message TouchPanStart { sint32 x = 1; sint32 y = 2; } message TouchPanUpdate { sint32 x = 1; sint32 y = 2; } message TouchPanEnd { sint32 x = 1; sint32 y = 2; } message TouchEnd { sint32 x = 1; sint32 y = 2; } message ScreenshotRequest { int32 display = 1; uint64 sid = 2; } message ScreenshotResponse { uint64 sid = 1; string msg = 2; bytes data = 3; } message SwitchSidesResponse { bytes uuid = 1; LoginRequest lr = 2; } message VoiceCallRequest { int64 req_timestamp = 1; bool is_connect = 2; } message VoiceCallResponse { bool accepted = 1; int64 req_timestamp = 2; int64 ack_timestamp = 3; } message MultiClipboards { repeated Clipboard clipboards = 1; } message Cliprdr { oneof union { CliprdrMonitorReady ready = 1; CliprdrServerFormatList format_list = 2; CliprdrServerFormatListResponse format_list_response = 3; CliprdrServerFormatDataRequest format_data_request = 4; CliprdrServerFormatDataResponse format_data_response = 5; CliprdrFileContentsRequest file_contents_request = 6; CliprdrFileContentsResponse file_contents_response = 7; CliprdrTryEmpty try_empty = 8; CliprdrFiles files = 9; } } message CliprdrMonitorReady {} message CliprdrServerFormatList { repeated CliprdrFormat formats = 1; } message CliprdrFormat { int32 id = 1; string format = 2; } message CliprdrServerFormatListResponse { int32 msg_flags = 1; } message CliprdrServerFormatDataRequest { int32 requested_format_id = 1; } message CliprdrServerFormatDataResponse { int32 msg_flags = 1; bytes format_data = 2; } message CliprdrTryEmpty {} message CliprdrFiles { repeated CliprdrFile files = 1; } message CliprdrFile { string name = 1; uint64 size = 2; } message CliprdrFileContentsRequest { uint32 stream_id = 1; uint32 list_index = 2; uint32 dw_flags = 3; uint64 n_position_low = 4; uint64 n_position_high = 5; uint32 cb_requested = 6; bool have_clip_data_id = 7; uint32 clip_data_id = 8; } message CliprdrFileContentsResponse { int32 msg_flags = 1; uint32 stream_id = 2; bytes requested_data = 3; } `; let root = null; let RendezvousMessage = null; let Message = null; /** * Initialize protobuf definitions. Must be called after protobuf.js is loaded. */ function init() { try { root = protobuf.Root.fromJSON(protobuf.parse(PROTO_TEXT).toJSON()); RendezvousMessage = root.lookupType('hbb.RendezvousMessage'); Message = root.lookupType('hbb.Message'); console.log('[RDProto] Protocol definitions loaded successfully'); return true; } catch (e) { console.error('[RDProto] Failed to load protocol definitions:', e); return false; } } /** * Lookup a message type by name */ function lookup(name) { return root.lookupType(`hbb.${name}`); } /** * Encode a RendezvousMessage to bytes */ function encodeRendezvousMsg(data) { const errMsg = RendezvousMessage.verify(data); if (errMsg) throw new Error(`RendezvousMessage verify error: ${errMsg}`); const msg = RendezvousMessage.create(data); return RendezvousMessage.encode(msg).finish(); } /** * Decode a RendezvousMessage from bytes */ function decodeRendezvousMsg(bytes) { return RendezvousMessage.decode(new Uint8Array(bytes)); } /** * Encode a Message to bytes */ function encodeMsg(data) { const errMsg = Message.verify(data); if (errMsg) throw new Error(`Message verify error: ${errMsg}`); const msg = Message.create(data); return Message.encode(msg).finish(); } /** * Decode a Message from bytes */ function decodeMsg(bytes) { return Message.decode(new Uint8Array(bytes)); } /** * Get the active union field name from a message */ function getActiveField(msg) { if (msg.union === null || msg.union === undefined) return null; // protobuf.js oneof: check which field is set const oneofFields = msg.$type.oneofs; if (oneofFields && oneofFields.union) { return oneofFields.union.oneof.find(f => msg[f] != null); } return null; } /** * Helper: Create a TestDelay message for latency measurement */ function createTestDelay(fromClient = true, lastDelay = 0) { return { test_delay: { time: BigInt(Date.now()), from_client: fromClient, last_delay: lastDelay } }; } /** * Helper: Create a MouseEvent */ function createMouseEvent(mask, x, y, modifiers = []) { return { mouse_event: { mask: mask, x: x, y: y, modifiers: modifiers } }; } /** * Helper: Create a KeyEvent (legacy mode) */ function createKeyEvent(controlKey, down, press = false, modifiers = []) { return { key_event: { control_key: controlKey, down: down, press: press, modifiers: modifiers, mode: 0 // Legacy } }; } /** * Helper: Create a KeyEvent with character */ function createCharKeyEvent(chr, down, press = false, modifiers = []) { return { key_event: { chr: chr, down: down, press: press, modifiers: modifiers, mode: 0 // Legacy } }; } /** * Helper: Create a LoginRequest */ function createLoginRequest(myId, myName, password, peerPlatform, version) { return { login_request: { my_id: myId, my_name: myName, password: password, my_platform: peerPlatform || 'Web', version: version || '1.3.6', option: { image_quality: 0, // NotSet show_remote_cursor: 1, // Yes privacy_mode: 0, disable_audio: 0, enable_file_transfer: 1, clipboard: 1, supported_decoding: { ability_vp9: true, ability_h264: false, ability_h265: false, ability_vp8: true, ability_av1: true, prefer: 0, // Auto } } } }; } /** * Helper: Create a LoginRequest for password auth */ function createPasswordLogin(myId, myName, hashedPassword, peerPlatform, version) { return createLoginRequest(myId, myName, hashedPassword, peerPlatform, version); } /** * Helper: Create a Clipboard message */ function createClipboard(text) { const encoder = new TextEncoder(); return { clipboard: { contents: [{ format: 0, // Text data: encoder.encode(text) }] } }; } return { init, lookup, encodeRendezvousMsg, decodeRendezvousMsg, encodeMsg, decodeMsg, getActiveField, createTestDelay, createMouseEvent, createKeyEvent, createCharKeyEvent, createLoginRequest, createPasswordLogin, createClipboard, // Expose type references get Message() { return Message; }, get RendezvousMessage() { return RendezvousMessage; }, get root() { return root; } }; })();