Skip to content

Commit 2b92d88

Browse files
authored
Merge pull request #54 from thevurv/none-lua-tables
Add an mlua like tables api
2 parents f103016 + 9ac43b8 commit 2b92d88

File tree

23 files changed

+364
-340
lines changed

23 files changed

+364
-340
lines changed

Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,17 @@ serde = { version = "1.0.219", features = ["derive"] }
2121
interprocess = "2.2.3"
2222
nanoserde = { version = "0.2.1", default-features = false, features = ["binary"] }
2323
retour = { git = "https://github.com/thevurv/retour-rs" }
24+
25+
autorun-lua = { path = "packages/autorun-lua" }
26+
autorun-ipc = { path = "packages/autorun-ipc" }
27+
autorun-types = { path = "packages/autorun-types" }
28+
autorun-log = { path = "packages/autorun-log" }
29+
autorun-interfaces = { path = "packages/autorun-interfaces" }
30+
autorun-scan = { path = "packages/autorun-scan" }
31+
autorun-core = { path = "packages/autorun-core" }
32+
autorun-env = { path = "packages/autorun-env" }
33+
autorun-fs = { path = "packages/autorun-fs" }
34+
autorun-steam = { path = "packages/autorun-steam" }
35+
autorun-jit = { path = "packages/autorun-jit" }
36+
autorun-luajit = { path = "packages/autorun-luajit" }
37+
autorun-plugin-api = { path = "packages/autorun-plugin-api" }

apps/autorun-egui/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ egui_extras = { version = "0.28.0", default-features = false, features = ["synte
1212
shh = { version = "1.0.1" }
1313
image = { version = "0.24", default-features = false, features = ["png"] }
1414

15-
autorun-ipc = { path = "../../packages/autorun-ipc" }
16-
autorun-steam = { path = "../../packages/autorun-steam" }
17-
autorun-types = { path = "../../packages/autorun-types" }
18-
autorun-log = { path = "../../packages/autorun-log" }
19-
autorun-core = { path = "../../packages/autorun-core" }
15+
autorun-ipc = { workspace = true }
16+
autorun-steam = { workspace = true }
17+
autorun-types = { workspace = true }
18+
autorun-log = { workspace = true }
19+
autorun-core = { workspace = true }
2020

2121
[target.'cfg(windows)'.dependencies]
2222
eframe = { version = "0.28.0" }

packages/autorun-core/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,7 @@ description.workspace = true
99
serde = { workspace = true }
1010
cap-std = { workspace = true }
1111
anyhow = { workspace = true }
12+
autorun-lua = { workspace = true }
13+
1214
nestify = "0.3.3"
1315
toml = "0.9.5"

packages/autorun-core/src/plugins.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use autorun_lua::LuaUserdata;
12
use cap_std::fs::Dir;
23
use serde::{Deserialize, Serialize};
34

@@ -11,6 +12,8 @@ pub struct Plugin {
1112
config: Config,
1213
}
1314

15+
impl LuaUserdata for Plugin {}
16+
1417
impl core::fmt::Display for Plugin {
1518
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1619
let cfg = &self.config;

packages/autorun-env/Cargo.toml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ retour = { workspace = true }
1313
cap-std = { workspace = true }
1414
rand = "0.8.5"
1515

16-
autorun-core = { path = "../autorun-core" }
17-
autorun-types = { path = "../autorun-types" }
18-
autorun-lua = { path = "../autorun-lua" }
19-
autorun-log = { path = "../autorun-log" }
20-
autorun-jit = { path = "../autorun-jit" }
21-
autorun-luajit = { path = "../autorun-luajit" }
22-
autorun-interfaces = { path = "../autorun-interfaces" }
16+
autorun-core = { workspace = true }
17+
autorun-types = { workspace = true }
18+
autorun-lua = { workspace = true }
19+
autorun-log = { workspace = true }
20+
autorun-jit = { workspace = true }
21+
autorun-luajit = { workspace = true }
22+
autorun-interfaces = { workspace = true }

packages/autorun-env/src/env.rs

Lines changed: 49 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,23 @@ pub mod global;
33
use anyhow::Context;
44
use autorun_core::plugins::Plugin;
55
use autorun_log::*;
6-
use autorun_lua::{LuaApi, RawHandle};
6+
use autorun_lua::{Globals, LuaApi, LuaTable};
77
use autorun_luajit::{GCRef, LJState, index2adr};
88
use autorun_types::{LuaState, Realm};
99
use std::ffi::{CStr, CString, c_int};
1010

11+
use crate::functions;
12+
1113
#[derive(Debug, Clone, Copy)]
1214
pub struct EnvHandle {
1315
realm: Realm,
1416
env_gcr: GCRef,
1517
chunk_nonce: u64,
16-
handle: RawHandle,
17-
}
18-
19-
impl core::ops::Deref for EnvHandle {
20-
type Target = RawHandle;
21-
22-
fn deref(&self) -> &Self::Target {
23-
&self.handle
24-
}
18+
env: LuaTable,
19+
autorun: LuaTable,
2520
}
2621

27-
macro_rules! as_env_lua_function {
22+
macro_rules! wrap {
2823
($func:expr) => {
2924
autorun_lua::as_lua_function!(|lua: &LuaApi, state: *mut LuaState| {
3025
let realm = crate::global::get_realm(state);
@@ -48,6 +43,10 @@ macro_rules! as_env_lua_function {
4843
}
4944

5045
impl EnvHandle {
46+
pub fn push(&self, lua: &LuaApi, state: *mut LuaState) {
47+
self.env.push(lua, state);
48+
}
49+
5150
pub fn realm(&self) -> Realm {
5251
self.realm
5352
}
@@ -86,93 +85,34 @@ impl EnvHandle {
8685
return None;
8786
}
8887

89-
self.push_autorun_table(lua, state);
90-
lua.get_field(state, -1, c"PLUGIN".as_ptr());
91-
92-
let dir = lua.to_userdata(state, -1) as *mut Plugin;
93-
if dir.is_null() {
94-
lua.pop(state, 2);
95-
return None;
96-
}
97-
lua.pop(state, 2);
88+
let dir: *mut Plugin = lua.get(state, &self.autorun, "PLUGIN");
89+
let dir = unsafe { dir.as_ref() }?;
9890

99-
unsafe { dir.as_ref() }
91+
Some(dir)
10092
}
10193

102-
fn create_autorun_table(lua: &LuaApi, state: *mut LuaState) {
103-
lua.create_table(state, 0, 6);
104-
105-
lua.push(state, c"print");
106-
lua.push(state, as_env_lua_function!(crate::functions::print));
107-
lua.set_table(state, -3);
108-
109-
lua.push(state, c"read");
110-
lua.push(state, as_env_lua_function!(crate::functions::read));
111-
lua.set_table(state, -3);
112-
113-
lua.push(state, c"write");
114-
lua.push(state, as_env_lua_function!(crate::functions::write));
115-
lua.set_table(state, -3);
116-
117-
lua.push(state, c"writeAsync");
118-
lua.push(state, as_env_lua_function!(crate::functions::write_async));
119-
lua.set_table(state, -3);
120-
121-
lua.push(state, c"mkdir");
122-
lua.push(state, as_env_lua_function!(crate::functions::mkdir));
123-
lua.set_table(state, -3);
124-
125-
lua.push(state, c"append");
126-
lua.push(state, as_env_lua_function!(crate::functions::append));
127-
lua.set_table(state, -3);
128-
129-
lua.push(state, c"exists");
130-
lua.push(state, as_env_lua_function!(crate::functions::exists));
131-
lua.set_table(state, -3);
132-
133-
lua.push(state, c"detour");
134-
lua.push(state, as_env_lua_function!(crate::functions::detour));
135-
lua.set_table(state, -3);
136-
137-
lua.push(state, c"enableDetour");
138-
lua.push(state, as_env_lua_function!(crate::functions::detour_enable));
139-
lua.set_table(state, -3);
140-
141-
lua.push(state, c"disableDetour");
142-
lua.push(state, as_env_lua_function!(crate::functions::detour_disable));
143-
lua.set_table(state, -3);
144-
145-
lua.push(state, c"removeDetour");
146-
lua.push(state, as_env_lua_function!(crate::functions::detour_remove));
147-
lua.set_table(state, -3);
148-
149-
lua.push(state, c"getOriginalFunction");
150-
lua.push(state, as_env_lua_function!(crate::functions::detour_get_original));
151-
lua.set_table(state, -3);
152-
153-
lua.push(state, c"copyFastFunction");
154-
lua.push(state, as_env_lua_function!(crate::functions::copy_fast_function));
155-
lua.set_table(state, -3);
156-
157-
lua.push(state, c"load");
158-
lua.push(state, as_env_lua_function!(crate::functions::load));
159-
lua.set_table(state, -3);
160-
161-
lua.push(state, c"triggerRemote");
162-
lua.push(state, as_env_lua_function!(crate::functions::trigger_remote));
163-
lua.set_table(state, -3);
164-
165-
lua.push(state, c"isFunctionAuthorized");
166-
lua.push(state, as_env_lua_function!(crate::functions::is_function_authorized));
167-
lua.set_table(state, -3);
168-
169-
lua.push(state, c"isProtoAuthorized");
170-
lua.push(state, as_env_lua_function!(crate::functions::is_proto_authorized));
171-
lua.set_table(state, -3);
172-
173-
lua.push(state, c"VERSION");
174-
lua.push(state, env!("CARGO_PKG_VERSION").to_string());
175-
lua.set_table(state, -3);
94+
fn create_autorun_table(lua: &LuaApi, state: *mut LuaState) -> LuaTable {
95+
let t = lua.table(state);
96+
lua.set(state, &t, "print", wrap!(functions::print));
97+
lua.set(state, &t, "read", wrap!(functions::read));
98+
lua.set(state, &t, "write", wrap!(functions::write));
99+
lua.set(state, &t, "writeAsync", wrap!(functions::write_async));
100+
lua.set(state, &t, "mkdir", wrap!(functions::mkdir));
101+
lua.set(state, &t, "append", wrap!(functions::append));
102+
lua.set(state, &t, "exists", wrap!(functions::exists));
103+
lua.set(state, &t, "detour", wrap!(functions::detour));
104+
lua.set(state, &t, "enableDetour", wrap!(functions::detour_enable));
105+
lua.set(state, &t, "disableDetour", wrap!(functions::detour_disable));
106+
lua.set(state, &t, "removeDetour", wrap!(functions::detour_remove));
107+
lua.set(state, &t, "getOriginalFunction", wrap!(functions::detour_get_original));
108+
lua.set(state, &t, "copyFastFunction", wrap!(functions::copy_fast_function));
109+
lua.set(state, &t, "load", wrap!(functions::load));
110+
lua.set(state, &t, "triggerRemote", wrap!(functions::trigger_remote));
111+
lua.set(state, &t, "isFunctionAuthorized", wrap!(functions::is_function_authorized));
112+
lua.set(state, &t, "isProtoAuthorized", wrap!(functions::is_proto_authorized));
113+
lua.set(state, &t, "VERSION", env!("CARGO_PKG_VERSION"));
114+
115+
return t;
176116
}
177117

178118
pub fn execute(&self, lua: &LuaApi, state: *mut LuaState, name: &CStr, src: &[u8]) -> anyhow::Result<()> {
@@ -194,30 +134,31 @@ impl EnvHandle {
194134
}
195135

196136
pub fn create(lua: &LuaApi, state: *mut LuaState, realm: Realm) -> anyhow::Result<Self> {
197-
// Create autorun environment
198-
lua.create_table(state, 0, 2);
137+
let autorun = Self::create_autorun_table(lua, state);
199138

200-
lua.push(state, "Autorun");
201-
Self::create_autorun_table(lua, state);
202-
lua.set_table(state, -3);
139+
let env = lua.table(state);
140+
lua.set(state, &env, "Autorun", &autorun);
141+
lua.set(state, &env, "_G", Globals);
203142

204-
lua.push(state, "_G");
205-
lua.push_globals(state);
206-
lua.set_table(state, -3);
143+
// todo: refactor luajit code to not depend on the stack
144+
env.push(lua, state);
207145

208146
// Can unwrap since we are sure there is something on the stack
209147
let lj_state = state as *mut LJState;
210148
let lj_state = unsafe { lj_state.as_ref().context("Failed to dereference LJState")? };
211149
let env_tvalue = index2adr(lj_state, -1).context("Failed to get TValue for environment")?;
212150
let env_gcr = unsafe { (*env_tvalue).gcr };
213151

214-
let handle = RawHandle::from_stack(lua, state).unwrap();
152+
// todo: refactor luajit code to not depend on the stack
153+
lua.pop(state, 1);
154+
215155
let chunk_nonce = rand::random::<u64>();
216156
Ok(Self {
217157
realm,
218158
env_gcr,
219159
chunk_nonce,
220-
handle,
160+
env,
161+
autorun,
221162
})
222163
}
223164

@@ -233,28 +174,16 @@ impl EnvHandle {
233174
}
234175
}
235176

236-
fn push_autorun_table(&self, lua: &LuaApi, state: *mut LuaState) {
237-
self.push(lua, state);
238-
lua.get_field(state, -1, c"Autorun".as_ptr());
239-
lua.remove(state, -2);
240-
}
241-
242177
pub fn set_plugin(&self, lua: &LuaApi, state: *mut LuaState, plugin: &Plugin) -> anyhow::Result<()> {
243-
self.push_autorun_table(lua, state);
244-
245-
lua.push(state, c"PLUGIN");
246-
lua.new_userdata(state, plugin.try_clone()?);
247-
lua.set_table(state, -3);
248-
249-
lua.pop(state, 1);
178+
lua.set(state, &self.autorun, "PLUGIN", plugin.try_clone()?);
250179
Ok(())
251180
}
252181

253182
pub fn trigger(&self, lua: &LuaApi, state: *mut LuaState, event_name: &CStr, n_args: c_int) -> anyhow::Result<()> {
254183
lua.push(state, event_name);
255184
lua.insert(state, -(n_args + 1));
256185

257-
self.push_autorun_table(lua, state);
186+
self.autorun.push(lua, state);
258187
lua.get_field(state, -1, c"trigger".as_ptr());
259188
lua.remove(state, -2); // remove Autorun table
260189

@@ -279,7 +208,7 @@ impl EnvHandle {
279208
lua.push(state, event_name);
280209
lua.insert(state, -(n_args + 1));
281210

282-
self.push_autorun_table(lua, state);
211+
self.autorun.push(lua, state);
283212
lua.get_field(state, -1, c"runRemoteCallbacks".as_ptr());
284213
lua.remove(state, -2); // remove Autorun table
285214

packages/autorun-env/src/functions/detour/userdata.rs

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
use anyhow::anyhow;
12
use autorun_jit::Function;
2-
use autorun_lua::{IntoLua, LuaApi, LuaFunction, RawHandle};
3+
use autorun_lua::{LuaApi, LuaFunction, LuaUserdata, RawHandle};
34
use autorun_types::LuaState;
45

56
pub struct Detour {
@@ -10,19 +11,12 @@ pub struct Detour {
1011
pub original_function_ptr: Box<usize>,
1112
}
1213

13-
impl IntoLua for Detour {
14-
fn into_lua(self, lua: &LuaApi, state: *mut LuaState) {
15-
lua.new_userdata(state, self);
16-
}
17-
}
14+
impl LuaUserdata for Detour {}
1815

1916
pub fn detour_enable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<()> {
20-
let detour_userdata = lua.to_userdata(state, 1) as *mut Detour;
21-
if detour_userdata.is_null() {
22-
anyhow::bail!("First argument must be a detour userdata.");
23-
}
17+
let detour = lua.to::<*mut Detour>(state, 1);
18+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
2419

25-
let detour = unsafe { &mut *detour_userdata };
2620
unsafe {
2721
detour.detour.enable()?;
2822
}
@@ -31,12 +25,9 @@ pub fn detour_enable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle)
3125
}
3226

3327
pub fn detour_disable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<()> {
34-
let detour_userdata = lua.to_userdata(state, 1) as *mut Detour;
35-
if detour_userdata.is_null() {
36-
anyhow::bail!("First argument must be a detour userdata.");
37-
}
28+
let detour = lua.to::<*mut Detour>(state, 1);
29+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
3830

39-
let detour = unsafe { &mut *detour_userdata };
4031
unsafe {
4132
detour.detour.disable()?;
4233
}
@@ -45,26 +36,19 @@ pub fn detour_disable(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle
4536
}
4637

4738
pub fn detour_get_original(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<LuaFunction> {
48-
let detour_userdata = lua.to_userdata(state, 1) as *mut Detour;
49-
if detour_userdata.is_null() {
50-
anyhow::bail!("First argument must be a detour userdata.");
51-
}
52-
53-
let detour = unsafe { &mut *detour_userdata };
39+
let detour = lua.to::<*mut Detour>(state, 1);
40+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
5441

5542
Ok(unsafe { std::mem::transmute::<usize, LuaFunction>(*detour.original_function_ptr) })
5643
}
5744

5845
pub fn detour_remove(lua: &LuaApi, state: *mut LuaState, _env: crate::EnvHandle) -> anyhow::Result<()> {
59-
let detour_userdata = lua.to_userdata(state, 1) as *mut Detour;
60-
if detour_userdata.is_null() {
61-
anyhow::bail!("First argument must be a detour userdata.");
62-
}
46+
let detour = lua.to::<*mut Detour>(state, 1);
47+
let detour = unsafe { detour.as_mut() }.ok_or(anyhow!("First argument must be a detour userdata"))?;
6348

64-
let detour = unsafe { &mut *detour_userdata };
6549
unsafe {
6650
detour.detour.disable()?;
67-
std::ptr::drop_in_place(detour_userdata);
51+
std::ptr::drop_in_place(detour);
6852
}
6953

7054
Ok(())

0 commit comments

Comments
 (0)