Skip to content

Commit

Permalink
2.0.0-beta
Browse files Browse the repository at this point in the history
Full changelist will be in 2.0.0. Essentially a lot of breaking changes, added Userdata support for Vector and Angle, some missing lua c api functions, and a lot of documentation.
  • Loading branch information
Vurv78 committed Dec 31, 2021
1 parent 8fae2a0 commit f51fa1d
Show file tree
Hide file tree
Showing 23 changed files with 1,066 additions and 217 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
# 🌑 ``rglua`` [![cratesio](https://img.shields.io/crates/v/rglua.svg)](https://crates.io/crates/rglua) ![Build Status](https://github.com/Vurv78/rglua/actions/workflows/ci.yml/badge.svg) [![License](https://img.shields.io/github/license/Vurv78/rglua?color=red)](https://opensource.org/licenses/Apache-2.0) [![github/Vurv78](https://img.shields.io/discord/824727565948157963?label=Discord&logo=discord&logoColor=ffffff&labelColor=7289DA&color=2c2f33)](https://discord.gg/epJFC6cNsw)

This is a crate that allows interop with the luajit c api as well as the source sdk through libloading and vtable bindings.
This is a crate that allows interop with the (g)luajit c api as well as the source sdk through libloading and vtable bindings.
You can then use these for binary modules or manually injected code, like with [Autorun-rs](https://github.com/Vurv78/Autorun-rs)

More information on binary modules can be found on the garrysmod wiki: [Creating Binary Modules](https://wiki.facepunch.com/gmod/Creating_Binary_Modules) and examples [can be found here.](https://github.com/Vurv78/rglua/tree/master/examples)
## Usage
If you are targeting 32 bit make sure to install the toolchain and build to it:
```bash
rustup target add i686-pc-windows-msvc
cargo build --release --target=i686-pc-windows-msvc
cargo build --target=i686-pc-windows-msvc
```
## Acknowledgements
### [garrysmod_common](https://github.com/danielga/garrysmod_common)
This is heavily based off of garrysmod_common, in how we export the lua_shared functions and trying to replicate everything from the Lua C Api.

## Comparison
There are actually a decent amount of libraries out there for gmod development.
Expand All @@ -34,6 +31,10 @@ Here's a comparison and why you could use this one.
| Real world examples | ✔️ || ✔️ ||
| Github Stars | 😢 | 👍 | 👑 | 🤷‍♂️ |

__*You can help with that last one 😉*__

\* They technically do, but they depend on autogenerated bindings which is inaccurate for gmod, leading to missing functions. (See lua_resume_real)

__*You can help with that last one 😉*__
## Acknowledgements
### [garrysmod_common](https://github.com/danielga/garrysmod_common)
This is heavily based off of garrysmod_common, in how we export the lua_shared functions and trying to replicate everything from the Lua C Api.
4 changes: 2 additions & 2 deletions examples/is_even/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[package]
name = "gmod_is_even"
description = "Binary module that exposes a function called 'is_even' that does what it says."
version = "0.2.0"
version = "0.3.0"
edition = "2021"
publish = false

[lib]
crate-type = ["cdylib"]

[dependencies]
rglua = { path = "../.." }
rglua = { path = "../../rglua" }
10 changes: 7 additions & 3 deletions examples/is_even/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use rglua::prelude::*;

// The functions we want to provide to lua
extern "C" fn is_even(l: LuaState) -> i32 {
#[lua_function]
fn is_even(l: LuaState) -> i32 {
let num = luaL_checkinteger(l, 1);
// Ask for the first argument of the function.
// If this is the wrong type or missing, an error will be thrown to lua (if you don't want this, use the lua_to* functions)
Expand All @@ -12,13 +13,16 @@ extern "C" fn is_even(l: LuaState) -> i32 {
1
}

extern "C" fn is_odd(l: LuaState) -> i32 {
#[lua_function]
fn is_odd(l: LuaState) -> i32 {
let num = luaL_checkinteger(l, 1);

lua_pushboolean(l, (num % 2 != 0) as i32);
1
}

// Note that since this is #[gmod_open] the name of the function does not matter
// This is the same for #[gmod_close]
#[gmod_open]
fn open(l: LuaState) -> i32 {
// Print to the gmod console
Expand All @@ -31,7 +35,7 @@ fn open(l: LuaState) -> i32 {
];

// Register our functions in ``_G.math``
// This WILL NOT overwrite _G.math if it already exists ()
// This WILL NOT overwrite _G.math if it already exists (which it should..)
luaL_register(l, cstr!("math"), lib.as_ptr());
1
}
Expand Down
12 changes: 12 additions & 0 deletions examples/vector/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "vector"
description = "Binary module that adds some extra functions to the gmod Vector type"
version = "0.1.0"
edition = "2021"
publish = false

[lib]
crate-type = ["cdylib"]

[dependencies]
rglua = { path = "../../rglua" }
8 changes: 8 additions & 0 deletions examples/vector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 🔢 ``vector``
Binary module that adds some extra functions to the ``Vector`` type.

## Vector:IsPositive()
Returns if the vector consists of positive numbers

## Vector:GetPow(n: number)
Returns the vector multiplied by itself n times (exp ^)
44 changes: 44 additions & 0 deletions examples/vector/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use rglua::prelude::*;

#[lua_function]
fn is_positive(l: LuaState) -> i32 {
let vec = luaL_checkvector(l, 1);
lua_pushboolean(l, (vec.x > 0.0 && vec.y > 0.0 && vec.z > 0.0) as i32);
1
}

#[lua_function]
fn get_pow(l: LuaState) -> i32 {
let vec = luaL_checkvector(l, 1);
let by = luaL_checknumber(l, 2) as f32;

lua_pushvector(l, Vector::new(vec.x.powf(by), vec.y.powf(by), vec.z.powf(by)));
1
}

// Note that since this is #[gmod_open] the name of the function does not matter
// This is the same for #[gmod_close]
#[gmod_open]
fn open(l: LuaState) -> i32 {
// Create a library consisting of functions to export to gmod.
let lib = reg! [
"IsPositive" => is_positive,
"GetPow" => get_pow
];

// Get the ``Vector`` metatable from the lua registry and put it onto the stack.
luaL_getmetatable(l, cstr!("Vector"));

// Give a null pointer as the libname so that luaL_register knows we are trying to instead add these functions to the value on top of the stack;
// This being the Vector metatable at (-1).
luaL_register(l, std::ptr::null(), lib.as_ptr());

// Return nothing (0 objects)
0
}

#[gmod_close]
fn close(l: LuaState) -> i32 {
printgm!(l, "Goodbye garrysmod!");
0
}
2 changes: 1 addition & 1 deletion rglua/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "rglua"
description = "Toolkit for garrysmod development with the source sdk and luajit api"
version = "1.0.0"
version = "2.0.0-beta"
authors = ["Vurv <vurvdevelops@gmail.com>"]
keywords = ["glua", "garrysmod", "lua", "gmod"]
categories = ["api-bindings", "external-ffi-bindings", "development-tools::ffi", "game-development", "accessibility"]
Expand Down
26 changes: 26 additions & 0 deletions rglua/src/interface/common.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use super::prelude::*;

#[repr(C)]
#[allow(non_snake_case)]
pub struct PlayerInfo {
Expand All @@ -18,3 +20,27 @@ pub struct PlayerInfo {
filesDownloaded: u8,
pad: [i8; 304],
}

#[repr(C)]
pub struct StudioHdr {
pub id: c_int,
pub version: c_int,
pub checksum: c_int,

pub name: [c_char; 64],
pub length: c_int,

pub eyeposition: Vector,
pub illumposition: Vector,
pub hull_min: Vector,
pub hull_max: Vector,
pub view_bbmin: Vector,
pub view_bbmax: Vector,
pub flags: c_int,
pub numbones: c_int,
pub boneindex: c_int,
pub numbonecontrollers: c_int,
pub bonecontrollerindex: c_int,
pub numhitboxsets: c_int,
pub hitboxsetindex: c_int,
}
4 changes: 2 additions & 2 deletions rglua/src/interface/cvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub struct ConCommandBase {
}

iface! {
/// VEngineCvar007
/// vstdlib.dll
#[version("VEngineCvar007")]
#[file("vstdlib.dll")]
pub abstract struct ICVar {};
}

Expand Down
4 changes: 2 additions & 2 deletions rglua/src/interface/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use super::prelude::*;
use std::os::raw::c_char;

iface! {
/// VEngineClient015
/// Offsets are confirmed correct as of 12/19/2021
#[version("VEngineClient015")]
#[file("engine.dll")]
pub abstract struct EngineClient {};
}

Expand Down
7 changes: 7 additions & 0 deletions rglua/src/interface/lua/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
pub(crate) use super::prelude::{self, iface, VTable};

iface! {
#[version("")]
#[file("")]
/// <https://github.com/danielga/garrysmod_common/blob/9981d4aaee15452a9b0f53436c1aa807f81f3fd6/include/GarrysMod/Lua/LuaObject.h#L24>
/// You do not use this as a typical interface, it is just a type returned by other iface functions.
pub abstract struct ILuaObject {};

#[version("")]
#[file("")]
/// <https://github.com/danielga/garrysmod_common/blob/9981d4aaee15452a9b0f53436c1aa807f81f3fd6/include/GarrysMod/Lua/LuaInterface.h#L25>
/// Basically what is given to ordinary C++ binary modules that do not interface with lua_shared.
/// You can use this but should really just use the lua_shared bindings.
pub abstract struct ILuaInterface {};

#[version("LUASHARED003")]
#[file("")]
/// <https://github.com/danielga/garrysmod_common/blob/9981d4aaee15452a9b0f53436c1aa807f81f3fd6/include/GarrysMod/Lua/LuaShared.h#L57>
pub abstract struct CLuaShared {};
}
Expand Down
6 changes: 6 additions & 0 deletions rglua/src/interface/materials.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
use super::prelude::*;

iface! {
#[version("")]
#[file("")]
/// You do not get this through creating an interface, it is instead exported by other interface functions.
pub abstract struct IMaterial {};

#[version("VMaterialSystem080")]
#[file("materialsystem.dll")]
pub abstract struct IMaterialSystem {};
}

Expand Down
109 changes: 109 additions & 0 deletions rglua/src/interface/mdl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use super::common::StudioHdr;
use super::prelude::*;

iface! {
#[version("MDLCache004")]
#[file("datacache.dll")]
pub abstract struct IMdlCache {};

#[version("")]
#[file("")]
pub abstract struct IMdlCacheNotify {};
}

#[repr(C)]
pub enum MDLCacheDataType {
// Callbacks to get called when data is loaded or unloaded for these:
StudioHDR = 0,
StudioHWData,
VCollide,

// Callbacks NOT called when data is loaded or unloaded for these:
AnimBlock,
VirtualModel,
Vertexes,
DecodedAnimBlock,
}

impl IMdlCacheNotify {
#[virtual_index(0)]
/// Called right after data is loaded
pub fn OnDataLoaded(&self, ty: MDLCacheDataType, handle: MDLHandle) -> () {}

#[virtual_index(1)]
/// Called right before data is unloaded
pub fn OnDataUnloaded(&self, ty: MDLCacheDataType, handle: MDLHandle) -> () {}
}

pub type MDLHandle = c_ushort;
pub type VirtualModel = c_void; // Todo?

const MAX_NUM_LODS: usize = 8;

#[repr(C)]
pub struct VertexFileHeader {
id: c_int,
version: c_int,
checksum: c_int,
numLODs: c_int,
numLODVertexes: [c_int; MAX_NUM_LODS],
numFixups: c_int,
fixupTableStart: c_int,
vertexDataStart: c_int,
tangentDataStart: c_int,
}

impl IMdlCache {
#[virtual_index(0)]
pub fn SetCacheNotify(&self, pNotify: *mut IMdlCacheNotify) -> () {}

#[virtual_index(1)]
pub fn FindMDL(&self, pMDLRelativePath: *const c_char) -> MDLHandle {}

#[virtual_index(2)]
pub fn AddRef(&self, handle: MDLHandle) -> c_int {}

#[virtual_index(3)]
pub fn Release(&self, handle: MDLHandle) -> c_int {}

#[virtual_index(4)]
pub fn GetRef(&self, handle: MDLHandle) -> c_int {}

#[virtual_index(5)]
pub fn GetStudioHdr(&self, handle: MDLHandle) -> *mut StudioHdr {}

#[virtual_index(9)]
pub fn GetVirtualModel(&self, handle: MDLHandle) -> *mut VirtualModel {}

#[virtual_index(11)]
pub fn GetVertexData(&self, handle: MDLHandle) -> *mut VertexFileHeader {}

#[virtual_index(12)]
pub fn TouchAllData(&self, handle: MDLHandle) -> () {}

#[virtual_index(13)]
pub fn SetUserData(&self, handle: MDLHandle, pData: *mut c_void) -> () {}

#[virtual_index(14)]
pub fn GetUserData(&self, handle: MDLHandle) -> *mut c_void {}

#[virtual_index(15)]
pub fn IsErrorModel(&self, handle: MDLHandle) -> bool {}

#[virtual_index(18)]
pub fn GetModelName(&self, handle: MDLHandle) -> *const c_char {}

#[virtual_index(19)]
pub fn GetVirtualModelFast(
&self,
pStudioHdr: *const StudioHdr,
handle: MDLHandle,
) -> *mut VirtualModel {
}

#[virtual_index(20)]
pub fn BeginLock(&self) -> () {}

#[virtual_index(21)]
pub fn EndLock(&self) -> () {}
}
Loading

0 comments on commit f51fa1d

Please sign in to comment.