PivityGmodStore

Creating a C/C++/Rust Extension

What is an Extension?

An extension is a simple .dll/.so file that extends the functionality of gluapack with custom code.

One common use case for this is applying Lua obfuscators to your Lua files.

You can do this in any language you like - as long as it can be compiled as a .dll module or .so shared library.

This guide expects you to understand systems programming in your language of choice. I cannot help you learn a language, and I can't provide support for this, obviously. However, if you think something is broken, do let me know of course. If you have any basic questions about the functions or documentation then do not hesitate to contact me.


How it works

Extensions are installed to garrysmod/lua/bin/gluapack/, if that folder doesn't exist, create it.

Your extension will be loaded when gluapack initializes. gluapack will then search your exports for two functions: gluapack_filter and gluapack_mutate. You don't have to define both functions; only one of them. Don't forget to turn off name mangling so gluapack can find your functions in the exports table.


gluapack_filter allows you to specify whether a clientside/shared file should be added to the gluapack pack file or not. If you return false, it'll be networked via vanilla Garry's Mod networking.

It is undefined behaviour to return a different value between auto refreshes. Don't do that.


gluapack_mutate allows you to change the path or contents of a clientside/shared Lua file that is being added to the gluapack pack file.

It is undefined behaviour to change the file path of a Lua file during an auto refresh. Don't do that.


An example in Rust

This example will:

  1. Prevent any Lua file with filter_me in its path from being added to the gluapack pack file; it will be sent through Garry's Mod's vanilla networking instead
  2. Rename any Lua file with rename_me in its path to lua/autorun/client/rename_me_renamed.lua
  3. Override the contents of any Lua file with mutate_me in its path to print('hello world!')


// Equivalent to `char` in C
use std::os::raw::c_char;

#[no_mangle]
/// Called when a Lua file is added to the clientside Lua files list (or auto refreshed)
///
/// Please note, it is **undefined behaviour** to return a different value between auto refreshes for the same file.
unsafe extern "C" fn gluapack_filter(path: *const c_char, _contents: *const c_char) -> bool {
let path = std::ffi::CStr::from_ptr(path).to_string_lossy(); // Convert our `const char*` C pointer to something we can use
if path.contains("filter_me") {
return false;
} else {
return true;
}
}

#[no_mangle]
/// Called when a Lua file is added to the clientside Lua files list (or auto refreshed)
unsafe extern "C" fn gluapack_mutate(
/// Whether this file update was triggered by an autorefresh or not
///
/// Renaming a file during an auto refresh is undefined behaviour.
auto_refresh: bool,

/// A `const char*` pointer to the path of the file potentially being mutated
path: *const c_char,

/// A `const char*` pointer to the contents of the file potentially being mutated
_contents: *const c_char,

/// A pointer to a function that will rename the file
mutate_path: extern "C" fn(path: *const c_char),

/// A pointer to a function that will override the file's contents
mutate_contents: extern "C" fn(contents: *const c_char)
) {
let path_str = std::ffi::CStr::from_ptr(path).to_string_lossy(); // Convert our `const char*` C pointer to something we can use

if !auto_refresh && path_str.contains("rename_me") {
// Renaming a file during an auto refresh is undefined behaviour.
(mutate_path)(b"lua/autorun/client/rename_me_renamed.lua\0".as_ptr() as *const c_char);
} else if path_str.contains("mutate_me") {
(mutate_contents)(b"print('hello world!')\0".as_ptr() as *const c_char);
}
}


Licensing

Your extensions are your own work and may be used privately for commercial or personal use.

Please do not sell gluapack extensions. If you've made something cool, and want to sell it, get in touch and we can work something out.

Can't find what you're looking for?

Contact support