rustdesk/src/globals.js

304 lines
9.1 KiB
JavaScript
Raw Normal View History

2022-01-20 12:49:57 +08:00
import Connection from "./connection";
import _sodium from "libsodium-wrappers";
2022-01-26 18:58:55 +08:00
import { CursorData } from "./message";
2022-01-27 18:58:29 +08:00
import { loadOpus, loadVp9 } from "./codec";
2022-01-30 19:48:41 +08:00
import { checkIfRetry, version } from "./gen_js_from_hbb";
2022-01-30 03:39:54 +08:00
import { initZstd, translate } from "./common";
2022-01-26 12:39:44 +08:00
var currentFrame = undefined;
var events = [];
2022-01-20 12:49:57 +08:00
2022-01-26 18:58:55 +08:00
window.curConn = undefined;
2022-01-27 23:32:51 +08:00
window.getRgba = () => {
const tmp = currentFrame;
currentFrame = undefined;
return tmp || null;
}
2022-01-31 13:58:01 +08:00
window.isMobile = () => {
return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4));
}
2022-01-26 12:39:44 +08:00
2022-02-05 01:55:23 +08:00
export function isDesktop() {
2022-02-05 04:28:40 +08:00
return !isMobile();
2022-02-05 01:55:23 +08:00
}
2022-01-26 12:39:44 +08:00
export function msgbox(type, title, text) {
2022-01-27 13:24:40 +08:00
if (!events) return;
2022-01-28 18:20:52 +08:00
if (!type || (type == 'error' && !text)) return;
2022-01-27 01:30:29 +08:00
const text2 = text.toLowerCase();
2022-01-30 03:39:54 +08:00
var hasRetry = checkIfRetry(type, title, text);
2022-01-26 12:39:44 +08:00
events.push({ name: 'msgbox', type, title, text, hasRetry });
}
2022-01-28 18:20:52 +08:00
function jsonfyForDart(payload) {
var tmp = {};
for (const [key, value] of Object.entries(payload)) {
if (!key) continue;
2022-01-30 03:39:54 +08:00
tmp[key] = value instanceof Uint8Array ? '[' + value.toString() + ']' : JSON.stringify(value);
2022-01-28 18:20:52 +08:00
}
return tmp;
}
2022-01-26 12:39:44 +08:00
export function pushEvent(name, payload) {
2022-01-27 13:24:40 +08:00
if (!events) return;
2022-01-29 11:31:05 +08:00
payload = jsonfyForDart(payload);
2022-01-26 12:39:44 +08:00
payload.name = name;
2022-01-29 11:31:05 +08:00
events.push(payload);
2022-01-26 12:39:44 +08:00
}
2022-01-31 13:15:18 +08:00
let yuvWorker;
2022-01-29 23:05:29 +08:00
2022-01-26 12:39:44 +08:00
export function draw(frame) {
2022-01-31 13:16:34 +08:00
if (yuvWorker) yuvWorker.postMessage(frame);
2022-01-26 12:39:44 +08:00
}
2022-01-20 02:27:49 +08:00
export function setConn(conn) {
2022-01-26 18:58:55 +08:00
window.curConn = conn;
2022-01-20 02:27:49 +08:00
}
export function getConn() {
2022-01-26 18:58:55 +08:00
return window.curConn;
2022-01-20 12:49:57 +08:00
}
2022-01-27 01:30:29 +08:00
export async function startConn(id) {
try {
2022-01-29 23:05:29 +08:00
currentFrame = undefined;
events = [];
2022-01-30 19:48:41 +08:00
setByName('remote_id', id);
2022-01-27 01:30:29 +08:00
await curConn.start(id);
} catch (e) {
console.log(e);
msgbox('error', 'Error', String(e));
}
}
2022-01-20 18:02:20 +08:00
export function close() {
getConn()?.close();
setConn(undefined);
2022-01-26 12:39:44 +08:00
currentFrame = undefined;
2022-01-27 13:24:40 +08:00
events = undefined;
2022-01-20 18:02:20 +08:00
}
export function newConn() {
2022-01-26 18:58:55 +08:00
window.curConn?.close();
2022-01-20 12:49:57 +08:00
const conn = new Connection();
setConn(conn);
2022-01-20 18:02:20 +08:00
return conn;
2022-01-20 12:49:57 +08:00
}
let sodium;
export async function verify(signed, pk) {
if (!sodium) {
await _sodium.ready;
sodium = _sodium;
}
2022-01-20 15:41:11 +08:00
if (typeof pk == 'string') {
pk = decodeBase64(pk);
}
2022-01-20 12:49:57 +08:00
return sodium.crypto_sign_open(signed, pk);
}
2022-01-20 15:41:11 +08:00
export function decodeBase64(pk) {
return sodium.from_base64(pk, sodium.base64_variants.ORIGINAL);
}
export function genBoxKeyPair() {
const pair = sodium.crypto_box_keypair();
const sk = pair.privateKey;
const pk = pair.publicKey;
return [sk, pk];
}
export function genSecretKey() {
return sodium.crypto_secretbox_keygen();
}
export function seal(unsigned, theirPk, ourSk) {
const nonce = Uint8Array.from(Array(24).fill(0));
return sodium.crypto_box_easy(unsigned, nonce, theirPk, ourSk);
}
2022-01-20 18:02:20 +08:00
function makeOnce(value) {
var byteArray = Array(24).fill(0);
for (var index = 0; index < byteArray.length && value > 0; index++) {
var byte = value & 0xff;
byteArray[index] = byte;
value = (value - byte) / 256;
}
return Uint8Array.from(byteArray);
};
2022-01-20 15:41:11 +08:00
export function encrypt(unsigned, nonce, key) {
2022-01-20 18:02:20 +08:00
return sodium.crypto_secretbox_easy(unsigned, makeOnce(nonce), key);
2022-01-20 15:41:11 +08:00
}
export function decrypt(signed, nonce, key) {
2022-01-20 18:02:20 +08:00
return sodium.crypto_secretbox_open_easy(signed, makeOnce(nonce), key);
2022-01-26 12:39:44 +08:00
}
window.setByName = (name, value) => {
switch (name) {
2022-01-30 19:48:41 +08:00
case 'remote_id':
localStorage.setItem('remote-id', value);
break;
2022-01-26 18:58:55 +08:00
case 'connect':
2022-01-26 12:39:44 +08:00
newConn();
2022-01-30 19:48:41 +08:00
startConn(value);
2022-01-26 12:39:44 +08:00
break;
case 'login':
2022-01-30 19:48:41 +08:00
value = JSON.parse(value);
curConn.setRemember(value.remember == 'true');
curConn.login(value.password);
2022-01-26 12:39:44 +08:00
break;
case 'close':
close();
break;
case 'refresh':
2022-01-26 18:58:55 +08:00
curConn.refresh();
2022-01-26 12:39:44 +08:00
break;
case 'reconnect':
2022-01-26 18:58:55 +08:00
curConn.reconnect();
break;
case 'toggle_option':
curConn.toggleOption(value);
break;
case 'image_quality':
curConn.setImageQuality(value);
break;
case 'lock_screen':
curConn.lockScreen();
break;
case 'ctrl_alt_del':
2022-01-30 03:39:54 +08:00
curConn.ctrlAltDel();
2022-01-26 18:58:55 +08:00
break;
case 'switch_display':
curConn.switchDisplay(value);
break;
case 'remove':
2022-01-30 19:48:41 +08:00
const peers = getPeers();
2022-01-26 18:58:55 +08:00
delete peers[value];
localStorage.setItem('peers', JSON.stringify(peers));
break;
case 'input_key':
2022-01-30 19:48:41 +08:00
value = JSON.parse(value);
2022-02-05 04:28:40 +08:00
curConn.inputKey(value.name, value.down == 'true', value.press == 'true', value.alt == 'true', value.ctrl == 'true', value.shift == 'true', value.command == 'true');
2022-01-26 18:58:55 +08:00
break;
case 'input_string':
curConn.inputString(value);
break;
case 'send_mouse':
let mask = 0;
2022-01-30 19:48:41 +08:00
value = JSON.parse(value);
2022-01-26 18:58:55 +08:00
switch (value.type) {
case 'down':
mask = 1;
break;
case 'up':
mask = 2;
break;
case 'wheel':
mask = 3;
break;
}
switch (value.buttons) {
case 'left':
mask |= 1 << 3;
break;
case 'right':
mask |= 2 << 3;
break;
case 'wheel':
mask |= 4 << 3;
}
2022-02-05 04:28:40 +08:00
curConn.inputMouse(mask, parseInt(value.x || '0'), parseInt(value.y || '0'), value.alt == 'true', value.ctrl == 'true', value.shift == 'true', value.command == 'true');
2022-01-26 18:58:55 +08:00
break;
case 'option':
2022-01-30 19:48:41 +08:00
value = JSON.parse(value);
2022-01-26 18:58:55 +08:00
localStorage.setItem(value.name, value.value);
break;
case 'peer_option':
2022-01-30 19:48:41 +08:00
value = JSON.parse(value);
2022-01-29 11:31:05 +08:00
curConn.setOption(value.name, value.value);
2022-01-26 18:58:55 +08:00
break;
case 'input_os_password':
2022-01-30 03:39:54 +08:00
curConn.inputOsPassword(value);
2022-01-26 12:39:44 +08:00
break;
default:
break;
}
}
2022-01-26 18:58:55 +08:00
window.getByName = (name, arg) => {
2022-01-31 00:48:04 +08:00
let v = _getByName(name, arg);
if (typeof v == 'string' || v instanceof String) return v;
if (v == undefined || v == null) return '';
return JSON.stringify(v);
}
2022-01-31 02:01:17 +08:00
function getPeersForDart() {
const peers = [];
2022-01-31 13:58:01 +08:00
for (const [id, value] of Object.entries(getPeers())) {
if (!id) continue;
2022-01-31 02:01:17 +08:00
const tm = value['tm'];
2022-01-31 13:15:18 +08:00
const info = value['info'];
2022-01-31 02:01:17 +08:00
if (!tm || !info) continue;
peers.push([tm, id, info]);
}
return peers.sort().reverse().map(x => x.slice(1));
}
2022-01-31 00:48:04 +08:00
function _getByName(name, arg) {
2022-01-26 12:39:44 +08:00
switch (name) {
case 'peers':
2022-01-31 02:01:17 +08:00
return getPeersForDart();
2022-01-26 18:58:55 +08:00
case 'remote_id':
2022-01-31 00:48:04 +08:00
return localStorage.getItem('remote-id');
2022-01-26 18:58:55 +08:00
case 'remember':
return curConn.getRemember();
2022-01-26 12:39:44 +08:00
case 'event':
2022-01-27 13:24:40 +08:00
if (events && events.length) {
2022-01-26 12:39:44 +08:00
const e = events[0];
events.splice(0, 1);
2022-01-26 18:58:55 +08:00
return JSON.stringify(e);
2022-01-26 12:39:44 +08:00
}
break;
2022-01-26 18:58:55 +08:00
case 'toggle_option':
2022-01-31 00:48:04 +08:00
return curConn.getOption(arg) || false;
2022-01-26 18:58:55 +08:00
case 'option':
return localStorage.getItem(arg);
case 'image_quality':
return curConn.getImageQuality();
case 'translate':
2022-01-31 02:17:04 +08:00
arg = JSON.parse(arg);
2022-01-30 03:39:54 +08:00
return translate(arg.locale, arg.text);
2022-01-26 18:58:55 +08:00
case 'peer_option':
return curConn.getOption(arg);
2022-01-27 01:30:29 +08:00
case 'test_if_valid_server':
break;
2022-01-30 19:48:41 +08:00
case 'version':
return version;
2022-01-26 12:39:44 +08:00
}
2022-01-27 01:30:29 +08:00
return '';
2022-01-26 18:58:55 +08:00
}
2022-01-27 18:58:29 +08:00
window.init = async () => {
2022-01-31 13:15:18 +08:00
yuvWorker = new Worker("./yuv.js");
yuvWorker.onmessage = (e) => {
currentFrame = e.data;
}
2022-01-27 18:58:29 +08:00
loadOpus(() => { });
loadVp9(() => { });
2022-01-30 03:39:54 +08:00
await initZstd();
2022-01-30 19:48:41 +08:00
}
export function getPeers() {
try {
return JSON.parse(localStorage.getItem('peers')) || {};
} catch (e) {
return {};
}
2022-02-05 01:55:23 +08:00
}