Skip to content
This repository was archived by the owner on Nov 12, 2025. It is now read-only.

Commit 934a049

Browse files
committed
v3.0.0-beta
* Add net channel bindings * Use viable instead of vtables and vtables-derive * Add much more bindings * iface! macro now has a third param for type output and can / should be called with just the interface type. * Update engine example to be more concise with the new iface macro, checking if it is only running on client or menu & using the netchannel bindings. * Add serverside engine bindings
1 parent 90eece1 commit 934a049

30 files changed

Lines changed: 1279 additions & 634 deletions

examples/engine/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "gmod_engine"
33
description = "Binary module that accesses engine.dll"
4-
version = "0.3.0"
4+
version = "0.4.0"
55
edition = "2021"
66
publish = false
77

examples/engine/src/lib.rs

Lines changed: 108 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,145 @@
1-
use rglua::interface::{EngineClient};
1+
use rglua::interface;
22
use rglua::prelude::*;
33

4-
fn get_iface() -> Option<&'static EngineClient> {
5-
let iface: *mut EngineClient = iface!("engine", "VEngineClient015")?;
6-
unsafe { iface.as_ref() }
4+
#[lua_function]
5+
fn concmd(l: LuaState) -> Result<i32, interface::Error> {
6+
let engine = iface!(EngineClient)?;
7+
engine.ExecuteClientCmd( luaL_checkstring(l, 1) );
8+
Ok(0)
79
}
810

911
#[lua_function]
10-
fn concmd(l: LuaState) -> i32 {
11-
if let Some(iface) = get_iface() {
12-
iface.ExecuteClientCmd( luaL_checkstring(l, 1) );
13-
}
14-
0
12+
fn get_resolution(l: LuaState) -> Result<i32, interface::Error> {
13+
let engine = iface!(EngineClient)?;
14+
15+
let (w, h) = (&mut 0, &mut 0);
16+
engine.GetScreenSize(w, h);
17+
18+
lua_pushinteger(l, *w as isize);
19+
lua_pushinteger(l, *h as isize);
20+
21+
Ok(2)
1522
}
1623

1724
#[lua_function]
18-
fn get_resolution(l: LuaState) -> i32 {
19-
if let Some(iface) = get_iface() {
20-
let (w, h): (*mut _, *mut _) = (&mut 0, &mut 0);
21-
iface.GetScreenSize(w, h);
22-
unsafe {
23-
lua_pushinteger(l, *w as isize);
24-
lua_pushinteger(l, *h as isize);
25-
}
26-
return 2;
27-
}
28-
0
25+
fn get_directory(l: LuaState) -> Result<i32, interface::Error> {
26+
let engine = iface!(EngineClient)?;
27+
28+
let dir = engine.GetGameDirectory();
29+
lua_pushstring(l, dir);
30+
31+
Ok(1)
2932
}
3033

3134
#[lua_function]
32-
fn get_directory(l: LuaState) -> i32 {
33-
if let Some(iface) = get_iface() {
34-
let dir = iface.GetGameDirectory();
35-
lua_pushstring(l, dir);
36-
return 1;
37-
}
38-
0
35+
fn get_level(l: LuaState) -> Result<i32, interface::Error> {
36+
let engine = iface!(EngineClient)?;
37+
38+
let level = engine.GetLevelName();
39+
lua_pushstring(l, level);
40+
41+
Ok(1)
3942
}
4043

4144
#[lua_function]
42-
fn get_level(l: LuaState) -> i32 {
43-
if let Some(iface) = get_iface() {
44-
let level = iface.GetLevelName();
45-
lua_pushstring(l, level);
46-
return 1;
47-
}
48-
0
45+
fn is_recording(l: LuaState) -> Result<i32, interface::Error> {
46+
let engine = iface!(EngineClient)?;
47+
48+
let demo = engine.IsRecordingDemo();
49+
lua_pushboolean(l, demo as i32);
50+
51+
Ok(1)
4952
}
5053

5154
#[lua_function]
52-
fn is_recording(l: LuaState) -> i32 {
53-
if let Some(iface) = get_iface() {
54-
let demo = iface.IsRecordingDemo();
55-
lua_pushboolean(l, demo as i32);
56-
return 1;
57-
}
58-
0
55+
fn is_paused(l: LuaState) -> Result<i32, interface::Error> {
56+
let engine = iface!(EngineClient)?;
57+
58+
let paused = engine.IsPaused();
59+
lua_pushboolean(l, paused as i32);
60+
61+
Ok(1)
5962
}
6063

6164
#[lua_function]
62-
fn is_paused(l: LuaState) -> i32 {
63-
if let Some(iface) = get_iface() {
64-
let paused = iface.IsPaused();
65-
lua_pushboolean(l, paused as i32);
66-
return 1;
67-
}
68-
0
65+
fn is_console_visible(l: LuaState) -> Result<i32, interface::Error> {
66+
let engine = iface!(EngineClient)?;
67+
68+
lua_pushboolean(l, engine.IsConsoleVisible() as i32);
69+
70+
Ok(1)
71+
}
72+
73+
#[lua_function]
74+
fn net_infos(l: LuaState) -> Result<i32, interface::Error> {
75+
let flow = luaL_checkinteger(l, 1) as i32;
76+
77+
let engine = iface!(EngineClient)?;
78+
79+
let infos = unsafe { engine.GetNetChannelInfo().as_mut() }
80+
.ok_or(interface::Error::AsMut)?;
81+
82+
lua_newtable(l);
83+
84+
lua_pushstring(l, infos.GetName());
85+
lua_setfield(l, -2, cstr!("name"));
86+
87+
lua_pushstring(l, infos.GetAddress());
88+
lua_setfield(l, -2, cstr!("address"));
89+
90+
lua_pushnumber(l, infos.GetTime() as f64);
91+
lua_setfield(l, -2, cstr!("time"));
92+
93+
lua_pushnumber(l, infos.GetTimeConnected() as f64);
94+
lua_setfield(l, -2, cstr!("time_connected"));
95+
96+
lua_pushnumber(l, infos.GetBufferSize() as f64);
97+
lua_setfield(l, -2, cstr!("buffer_size"));
98+
99+
lua_pushnumber(l, infos.GetDataRate() as f64);
100+
lua_setfield(l, -2, cstr!("data_rate"));
101+
102+
lua_pushnumber(l, infos.GetAvgLoss(flow) as f64);
103+
lua_setfield(l, -2, cstr!("avg_loss"));
104+
105+
lua_pushnumber(l, infos.GetAvgChoke(flow) as f64);
106+
lua_setfield(l, -2, cstr!("avg_choke"));
107+
108+
lua_pushnumber(l, infos.GetAvgData(flow) as f64);
109+
lua_setfield(l, -2, cstr!("avg_data"));
110+
111+
lua_pushnumber(l, infos.GetAvgLatency(flow) as f64);
112+
lua_setfield(l, -2, cstr!("avg_latency"));
113+
114+
Ok(1)
69115
}
70116

71117
#[gmod_open]
72-
fn open(l: LuaState) -> i32 {
118+
fn open(l: LuaState) -> Result<i32, interface::Error> {
73119
printgm!(l, "Loaded engine module!");
74120

121+
let lua = iface!(LuaShared)?;
122+
123+
let client = lua.GetLuaInterface(0);
124+
let menu = lua.GetLuaInterface(2);
125+
if client.is_null() && menu.is_null() {
126+
// TODO: Serverside support & Clientside in one module :)
127+
luaL_error(l, cstr!("This module is only compatible with the CLIENT or MENU states!"));
128+
}
129+
75130
let lib = reg! [
76131
"concmd" => concmd,
77132
"getResolution" => get_resolution,
78133
"getGameDirectory" => get_directory,
79134
"getLevel" => get_level,
80135
"isRecording" => is_recording,
81-
"isPaused" => is_paused
136+
"isPaused" => is_paused,
137+
"isConsoleVisible" => is_console_visible,
138+
"getNetInfo" => net_infos
82139
];
83140

84141
luaL_register(l, cstr!("iengine"), lib.as_ptr());
85-
0
142+
Ok(0)
86143
}
87144

88145
#[gmod_close]

examples/interfaces/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "gmod_interfaces"
3+
description = "Binary module displaying basic functionality from source interfaces"
4+
version = "0.1.0"
5+
edition = "2021"
6+
publish = false
7+
8+
[lib]
9+
crate-type = ["cdylib"]
10+
11+
[dependencies]
12+
rglua = { path = "../../rglua" }
13+
thiserror = "1.0.30"

examples/interfaces/src/lib.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use rglua::prelude::*;
2+
use rglua::interface::{self, LuaShared};
3+
4+
#[derive(Debug, thiserror::Error)]
5+
enum GenericError {
6+
#[error("Couldn't get interface {0}")]
7+
NoInterface(String),
8+
9+
#[error("Couldn't get interface as reference {0}")]
10+
AsMut(String)
11+
}
12+
13+
#[gmod_open]
14+
fn open(l: LuaState) -> Result<i32, GenericError> {
15+
// Access the lua state when you aren't directly given it.
16+
let lua_shared = iface!(LuaShared)?;
17+
let menu = unsafe { lua_shared.GetLuaInterface(2).as_mut() }
18+
.ok_or(interface::Error::AsMut)?;
19+
20+
printgm!(menu.base as _, "Hello from ILuaShared!");
21+
Ok(0)
22+
}
23+
24+
#[gmod_close]
25+
fn close(_l: LuaState) -> i32 {
26+
0
27+
}

rglua/Cargo.toml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "rglua"
33
description = "Toolkit for garrysmod development with the source sdk and luajit api"
4-
version = "2.1.0"
4+
version = "3.0.0-beta"
55
authors = ["Vurv <vurvdevelops@gmail.com>"]
66
keywords = ["glua", "garrysmod", "lua", "gmod"]
77
categories = ["api-bindings", "external-ffi-bindings", "development-tools::ffi", "game-development", "accessibility"]
@@ -20,12 +20,10 @@ thiserror = "1.0.30"
2020
rglua-macros = { version = "0.2.0", path = "../rglua-macros" }
2121
derive_more = { version = "0.99.17", optional = true }
2222

23-
vtables = { version = "0.1.0", optional = true }
24-
vtables_derive = { version = "0.1.0", optional = true }
23+
viable = { version = "0.1", optional = true }
2524

2625
[features]
2726
default = ["interfaces", "userdata"]
2827

29-
interfaces = ["vtables", "vtables_derive"]
30-
28+
interfaces = ["viable"]
3129
userdata = ["derive_more"]

0 commit comments

Comments
 (0)