1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#![warn(missing_docs)]
mod connection;
mod convert;
mod imports;
use js_sys::Array;
use wasm_bindgen::prelude::*;
use usdpl_core::{socket::Packet, RemoteCall};
static mut CTX: UsdplContext = UsdplContext { port: 31337, id: 1,
#[cfg(feature = "encrypt")] key: Vec::new() };
#[cfg(feature = "encrypt")]
fn encryption_key() -> Vec<u8> {
hex::decode(obfstr::obfstr!(env!("USDPL_ENCRYPTION_KEY"))).unwrap()
}
#[derive(Debug)]
struct UsdplContext {
port: u16,
id: u64,
#[cfg(feature = "encrypt")]
key: Vec<u8>,
}
fn get_port() -> u16 {
unsafe { CTX.port }
}
#[cfg(feature = "encrypt")]
fn get_key() -> Vec<u8> {
unsafe { CTX.key.clone() }
}
fn increment_id() -> u64 {
let current_id = unsafe { CTX.id };
unsafe {
CTX.id += 1;
}
current_id
}
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen]
pub fn init_usdpl(port: u16) {
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
unsafe {
CTX = UsdplContext {
port: port,
id: 1,
#[cfg(feature = "encrypt")]
key: encryption_key(),
};
}
}
#[wasm_bindgen]
pub fn target() -> String {
usdpl_core::api::Platform::current().to_string()
}
#[wasm_bindgen]
pub async fn call_backend(name: String, parameters: Vec<JsValue>) -> JsValue {
#[cfg(feature = "debug")]
imports::console_log(&format!(
"call_backend({}, [params; {}])",
name,
parameters.len()
));
let next_id = increment_id();
let mut params = Vec::with_capacity(parameters.len());
for val in parameters {
params.push(convert::js_to_primitive(val));
}
let port = get_port();
#[cfg(feature = "debug")]
imports::console_log(&format!("USDPL: Got port {}", port));
let results = connection::send_js(
Packet::Call(RemoteCall {
id: next_id,
function: name.clone(),
parameters: params,
}),
port,
#[cfg(feature = "encrypt")]
get_key()
)
.await;
let results = match results {
Ok(x) => x,
#[allow(unused_variables)]
Err(e) => {
#[cfg(feature = "debug")]
imports::console_error(&format!("USDPL: Got error while calling {}: {:?}", name, e));
return JsValue::NULL;
}
};
let results_js = Array::new_with_length(results.len() as _);
let mut i = 0;
for item in results {
results_js.set(i as _, convert::primitive_to_js(item));
i += 1;
}
results_js.into()
}