Skip to content

Commit 41d6c99

Browse files
committed
feat: add lua support with feature flag
- Added a "lua" feature flag to Cargo.toml, making the mlua dependency optional. - Extended keyboard and mouse modules with conditional Lua function registration. - Updated main.rs to execute Lua scripts when the "lua" feature is enabled. - Introduced register_delay and LuaEngine functionality in lua_engine.rs.
1 parent ecb066a commit 41d6c99

File tree

5 files changed

+188
-3
lines changed

5 files changed

+188
-3
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ version = "0.1.0"
88
edition = "2021"
99
authors = ["David Horner"]
1010

11+
[features]
12+
default = ["lua"]
13+
lua = ["mlua"]
1114

1215

1316
[dependencies]
@@ -24,6 +27,7 @@ tracing = "0.1.41"
2427
tracing-subscriber = "0.3.19"
2528
#webrtc = "0.12.0"
2629
webrtc = { git = "https://github.com/davehorner/webrtc.git", branch = "jetkvm_16_bit_patch", version = "0.12.0" }
30+
mlua = { version = "0.10.1", features = ["lua54", "vendored", "async", "send", "serialize"], optional = true }
2731

2832
[dev-dependencies]
2933
regex = "1.11.1"

src/keyboard.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use anyhow::Result as AnyResult;
33
use serde_json::{json, Value};
44
use tokio::time::{sleep, Duration};
55
use tracing::debug;
6+
use std::sync::Arc;
7+
use tokio::sync::Mutex;
68

79
/// Sends a keyboard report with the given modifier and keys.
810
pub async fn rpc_keyboard_report(
@@ -236,3 +238,88 @@ pub async fn send_windows_key(client: &crate::jetkvm_rpc_client::JetKvmRpcClient
236238

237239
Ok(())
238240
}
241+
242+
/// Registers keyboard functions to the provided Lua context.
243+
#[cfg(feature = "lua")]
244+
use mlua::prelude::*;
245+
#[cfg(feature = "lua")]
246+
pub fn register_lua(lua: &Lua, client: Arc<Mutex<JetKvmRpcClient>>) -> LuaResult<()> {
247+
let send_return_fn = {
248+
let client = client.clone();
249+
lua.create_async_function(move |_, ()| {
250+
let client = client.clone();
251+
async move {
252+
send_return(&*client.lock().await).await.map_err(mlua::Error::external)
253+
}
254+
})?
255+
};
256+
lua.globals().set("send_return", send_return_fn)?;
257+
258+
let send_ctrl_a_fn = {
259+
let client = client.clone();
260+
lua.create_async_function(move |_, ()| {
261+
let client = client.clone();
262+
async move {
263+
send_ctrl_a(&*client.lock().await).await.map_err(mlua::Error::external)
264+
}
265+
})?
266+
};
267+
lua.globals().set("send_ctrl_a", send_ctrl_a_fn)?;
268+
269+
let send_ctrl_v_fn = {
270+
let client = client.clone();
271+
lua.create_async_function(move |_, ()| {
272+
let client = client.clone();
273+
async move {
274+
send_ctrl_v(&*client.lock().await).await.map_err(mlua::Error::external)
275+
}
276+
})?
277+
};
278+
lua.globals().set("send_ctrl_v", send_ctrl_v_fn)?;
279+
280+
let send_ctrl_x_fn = {
281+
let client = client.clone();
282+
lua.create_async_function(move |_, ()| {
283+
let client = client.clone();
284+
async move {
285+
send_ctrl_x(&*client.lock().await).await.map_err(mlua::Error::external)
286+
}
287+
})?
288+
};
289+
lua.globals().set("send_ctrl_x", send_ctrl_x_fn)?;
290+
291+
let send_ctrl_c_fn = {
292+
let client = client.clone();
293+
lua.create_async_function(move |_, ()| {
294+
let client = client.clone();
295+
async move {
296+
send_ctrl_c(&*client.lock().await).await.map_err(mlua::Error::external)
297+
}
298+
})?
299+
};
300+
lua.globals().set("send_ctrl_c", send_ctrl_c_fn)?;
301+
302+
let send_windows_key_fn = {
303+
let client = client.clone();
304+
lua.create_async_function(move |_, ()| {
305+
let client = client.clone();
306+
async move {
307+
send_windows_key(&*client.lock().await).await.map_err(mlua::Error::external)
308+
}
309+
})?
310+
};
311+
lua.globals().set("send_windows_key", send_windows_key_fn)?;
312+
313+
let send_text_fn = {
314+
let client = client.clone();
315+
lua.create_async_function(move |_, text: String| {
316+
let client = client.clone();
317+
async move {
318+
rpc_sendtext(&*client.lock().await, &text).await.map_err(mlua::Error::external)
319+
}
320+
})?
321+
};
322+
lua.globals().set("send_text", send_text_fn)?;
323+
324+
Ok(())
325+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ pub mod keyboard;
66
pub mod mouse;
77
pub mod rpc_client;
88
pub mod system;
9+
pub mod lua_engine;
910

1011
pub use jetkvm_rpc_client::JetKvmRpcClient;

src/main.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ use anyhow::Result as AnyResult;
22
use jetkvm_control::device::{rpc_get_device_id, rpc_ping};
33
use jetkvm_control::jetkvm_config::JetKvmConfig;
44
use jetkvm_control::jetkvm_rpc_client::JetKvmRpcClient;
5-
use jetkvm_control::mouse::rpc_abs_mouse_report;
6-
use jetkvm_control::mouse::*;
75
use jetkvm_control::system::rpc_get_edid;
8-
use tokio::time::{sleep, Duration};
6+
97
use tracing::{error, info};
108
use tracing_subscriber;
119

@@ -32,5 +30,35 @@ async fn main() -> AnyResult<()> {
3230
let edid = rpc_get_edid(&client).await;
3331
info!("EDID: {:?}", edid);
3432

33+
#[cfg(feature = "lua")]
34+
{
35+
use std::sync::Arc;
36+
use tokio::sync::Mutex;
37+
use jetkvm_control::lua_engine::LuaEngine;
38+
let client_arc = Arc::new(Mutex::new(client));
39+
40+
// Create and configure the Lua engine.
41+
let lua_engine = LuaEngine::new(client_arc);
42+
lua_engine.register_builtin_functions()?;
43+
44+
// Optionally, execute a Lua script.
45+
let script = r#"
46+
print("Executing Lua script...")
47+
send_windows_key()
48+
delay(250)
49+
send_text("notepad")
50+
send_return()
51+
delay(250)
52+
send_text("Hello World!")
53+
send_ctrl_a()
54+
send_ctrl_c()
55+
right_click(100, 200)
56+
"#;
57+
58+
lua_engine.exec_script(script).await?;
59+
info!("Lua script executed successfully.");
60+
}
61+
62+
3563
Ok(())
3664
}

src/mouse.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use crate::jetkvm_rpc_client::JetKvmRpcClient;
22
use anyhow::Result as AnyResult;
33
use serde_json::{json, Value};
44
use tokio::time::{sleep, Duration};
5+
use std::sync::Arc;
6+
use tokio::sync::Mutex;
57

68
/// Sends an absolute mouse report with x, y coordinates and button state.
79
pub async fn rpc_abs_mouse_report(
@@ -202,3 +204,66 @@ pub async fn rpc_left_click_and_drag_to_center(
202204
.await?;
203205
Ok(())
204206
}
207+
208+
/// Registers mouse functions to the provided Lua context.
209+
#[cfg(feature = "lua")]
210+
use mlua::prelude::*;
211+
#[cfg(feature = "lua")]
212+
pub fn register_lua(lua: &Lua, client: Arc<Mutex<JetKvmRpcClient>>) -> LuaResult<()> {
213+
let left_click_fn = {
214+
let client = client.clone();
215+
lua.create_async_function(move |_, (x, y): (i64, i64)| {
216+
let client = client.clone();
217+
async move {
218+
rpc_left_click(&*client.lock().await, x, y).await.map_err(mlua::Error::external)
219+
}
220+
})?
221+
};
222+
lua.globals().set("left_click", left_click_fn)?;
223+
224+
let right_click_fn = {
225+
let client = client.clone();
226+
lua.create_async_function(move |_, (x, y): (i64, i64)| {
227+
let client = client.clone();
228+
async move {
229+
rpc_right_click(&*client.lock().await, x, y).await.map_err(mlua::Error::external)
230+
}
231+
})?
232+
};
233+
lua.globals().set("right_click", right_click_fn)?;
234+
235+
let middle_click_fn = {
236+
let client = client.clone();
237+
lua.create_async_function(move |_, (x, y): (i64, i64)| {
238+
let client = client.clone();
239+
async move {
240+
rpc_middle_click(&*client.lock().await, x, y).await.map_err(mlua::Error::external)
241+
}
242+
})?
243+
};
244+
lua.globals().set("middle_click", middle_click_fn)?;
245+
246+
let move_mouse_fn = {
247+
let client = client.clone();
248+
lua.create_async_function(move |_, (x, y): (i64, i64)| {
249+
let client = client.clone();
250+
async move {
251+
rpc_move_mouse(&*client.lock().await, x, y).await.map_err(mlua::Error::external)
252+
}
253+
})?
254+
};
255+
lua.globals().set("move_mouse", move_mouse_fn)?;
256+
257+
let double_click_fn = {
258+
let client = client.clone();
259+
lua.create_async_function(move |_, (x, y): (i64, i64)| {
260+
let client = client.clone();
261+
async move {
262+
rpc_double_click(&*client.lock().await, x, y).await.map_err(mlua::Error::external)
263+
}
264+
})?
265+
};
266+
lua.globals().set("double_click", double_click_fn)?;
267+
268+
Ok(())
269+
}

0 commit comments

Comments
 (0)