Skip to content

Commit

Permalink
Fix for new rglua, remove anyhow
Browse files Browse the repository at this point in the history
Also ran rustfmt and fixed clippy lints
  • Loading branch information
Vurv78 committed Nov 28, 2021
1 parent 940ca63 commit 8aef59a
Show file tree
Hide file tree
Showing 11 changed files with 368 additions and 244 deletions.
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "autorun"
version = "0.6.0"
version = "0.6.1"
authors = ["Vurv78 <[email protected]>"]
edition = "2021"

Expand All @@ -10,7 +10,7 @@ edition = "2021"
crate-type = ["cdylib"]

[dependencies]
rglua = { git = "https://github.com/Vurv78/rglua" }
rglua = "0.5.0"

detour = { version = "0.8.1", default-features = false }

Expand All @@ -20,7 +20,6 @@ atomic = "0.5.0"

# Misc
home = "0.5.3"
anyhow = "1.0.44"
thiserror = "1.0.30"

# Logging
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
hard_tabs = true
2 changes: 1 addition & 1 deletion src/detours/lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ macro_rules! lazy_detour {
lazy_detour!( $($rest)* );
};
() => ();
}
}
99 changes: 63 additions & 36 deletions src/detours/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::{fs, io::prelude::*, sync::atomic::Ordering};

use crate::sys::{
runlua::runLuaEnv,
statics::*,
util::{getAutorunHandle, setClientState},
runlua::runLuaEnv, statics::*
};

use rglua::{
lua_shared::{self, *},
rstr,
types::*,
rstring
};

const LUA_BOOL: i32 = rglua::globals::Lua::Type::Bool as i32;
Expand All @@ -20,16 +21,18 @@ pub mod lazy;
// Make our own static detours because detours.rs is lame and locked theirs behind nightly. :)
lazy_detour! {
pub static LUAL_NEWSTATE_H: extern "C" fn() -> LuaState = (*lua_shared::luaL_newstate, luaL_newstate);
pub static LUAL_LOADBUFFERX_H: extern "C" fn(LuaState, *const i8, SizeT, *const i8, *const i8) -> CInt = (*lua_shared::luaL_loadbufferx, luaL_loadbufferx);
pub static JOINSERVER_H: extern "C" fn(LuaState) -> CInt;
pub static LUAL_LOADBUFFERX_H: extern "C" fn(LuaState, *const i8, SizeT, *const i8, *const i8) -> i32 = (*lua_shared::luaL_loadbufferx, luaL_loadbufferx);
pub static JOINSERVER_H: extern "C" fn(LuaState) -> i32;
}

#[cfg(feature = "runner")]
use rglua::interface::IPanel;

type PaintTraverseFn = extern "fastcall" fn(&'static IPanel, usize, bool, bool);

#[cfg(feature = "runner")]
lazy_detour! {
static PAINT_TRAVERSE_H: extern "fastcall" fn(&'static IPanel, usize, bool, bool);
static PAINT_TRAVERSE_H: PaintTraverseFn;
}

extern "C" fn luaL_newstate() -> LuaState {
Expand All @@ -39,7 +42,13 @@ extern "C" fn luaL_newstate() -> LuaState {
state
}

extern "C" fn luaL_loadbufferx(state: LuaState, mut code: *const i8, mut size: SizeT, identifier: *const i8, mode: *const i8) -> CInt {
extern "C" fn luaL_loadbufferx(
state: LuaState,
mut code: *const i8,
mut size: SizeT,
identifier: *const i8,
mode: *const i8,
) -> i32 {
use crate::sys::util::initMenuState;
if MENU_STATE.get().is_none() {
if let Err(why) = initMenuState(state) {
Expand All @@ -49,11 +58,15 @@ extern "C" fn luaL_loadbufferx(state: LuaState, mut code: *const i8, mut size: S

// Todo: Check if you're in menu state (Not by checking MENU_DLL because that can be modified by lua) and if so, don't dump files.
// Dump the file to sautorun-rs/lua_dumps/IP/...
let raw_path = &rstring!(identifier)[1 ..]; // Remove the @ from the beginning of the path.
let server_ip = CURRENT_SERVER_IP.load( Ordering::Relaxed );
let raw_path = &rstr!(identifier)[1..]; // Remove the @ from the beginning of the path.
let server_ip = CURRENT_SERVER_IP.load(Ordering::Relaxed);

let mut do_run = true;
if raw_path == "lua/includes/init.lua" && HAS_AUTORAN.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed).is_ok() {
if raw_path == "lua/includes/init.lua"
&& HAS_AUTORAN
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_ok()
{
// This will only run once when HAS_AUTORAN is false, setting it to true.
// Will be reset by JoinServer.
if let Ok(script) = fs::read_to_string(&*AUTORUN_SCRIPT_PATH) {
Expand All @@ -62,7 +75,10 @@ extern "C" fn luaL_loadbufferx(state: LuaState, mut code: *const i8, mut size: S
error!("{}", why);
}
} else {
error!( "Couldn't read your autorun script file at [{}]", AUTORUN_SCRIPT_PATH.display() );
error!(
"Couldn't read your autorun script file at [{}]",
AUTORUN_SCRIPT_PATH.display()
);
}
}

Expand All @@ -73,40 +89,43 @@ extern "C" fn luaL_loadbufferx(state: LuaState, mut code: *const i8, mut size: S
match lua_type(state, top + 1) {
LUA_BOOL => {
do_run = lua_toboolean(state, top + 1) == 0;
},
}
LUA_STRING => {
let nul_str = lua_tostring(state, top + 1);
let cstr = unsafe { std::ffi::CStr::from_ptr(nul_str) };
let cutoff = cstr.to_bytes(); // String without the null char at the end (lua strings are always nul terminated)

code = cutoff.as_ptr() as *const i8;
size = cutoff.len();
},
_ => ()
}
_ => (),
}
lua_settop(state, top);
},
Err(_why) => ()
}
Err(_why) => (),
}
}

if let Some(mut file) = getAutorunHandle(raw_path, server_ip) {
if let Err(why) = file.write_all( unsafe { std::ffi::CStr::from_ptr(code) }.to_bytes() ) {
error!("Couldn't write to file made from lua path [{}]. {}", raw_path, why);
if let Err(why) = file.write_all(unsafe { std::ffi::CStr::from_ptr(code) }.to_bytes()) {
error!(
"Couldn't write to file made from lua path [{}]. {}",
raw_path, why
);
}
}

if do_run {
// Call the original function and return the value.
return LUAL_LOADBUFFERX_H.call( state, code, size, identifier, mode );
return LUAL_LOADBUFFERX_H.call(state, code, size, identifier, mode);
}
0
}

// Since the first lua state will always be the menu state, just keep a variable for whether joinserver has been hooked or not,
// If not, then hook it.
pub extern "C" fn joinserver(state: LuaState) -> CInt {
let ip = rstring!(lua_tolstring(state, 1, 0));
pub extern "C" fn joinserver(state: LuaState) -> i32 {
let ip = rstr!(lua_tolstring(state, 1, 0));
info!("Joining Server with IP {}!", ip);

CURRENT_SERVER_IP.store(ip, Ordering::Relaxed); // Set the IP so we know where to write files in loadbufferx.
Expand All @@ -116,29 +135,37 @@ pub extern "C" fn joinserver(state: LuaState) -> CInt {
}

#[cfg(feature = "runner")]
extern "fastcall" fn paint_traverse(this: &'static IPanel, panel_id: usize, force_repaint: bool, force_allow: bool) {
extern "fastcall" fn paint_traverse(
this: &'static IPanel,
panel_id: usize,
force_repaint: bool,
force_allow: bool,
) {
use crate::sys::util::{self, getClientState};

PAINT_TRAVERSE_H.get().unwrap().call(this, panel_id, force_repaint, force_allow);
PAINT_TRAVERSE_H
.get()
.unwrap()
.call(this, panel_id, force_repaint, force_allow);

let script_queue = &mut *LUA_SCRIPTS
.lock()
.unwrap();
let script_queue = &mut *LUA_SCRIPTS.lock().unwrap();

if !script_queue.is_empty() {
let (realm, script) = script_queue.remove(0);

let state = match realm {
REALM_MENU => MENU_STATE.get().unwrap().load(Ordering::Acquire), // Code will never get into the queue without a menu state already existing.
REALM_CLIENT => getClientState()
REALM_CLIENT => getClientState(),
};

if state.is_null() { return; }
if state.is_null() {
return;
}

match util::lua_dostring(state, &script) {
Err(why) => {
error!("{}", why);
},
}
Ok(_) => {
info!("Script of len #{} ran successfully.", script.len())
}
Expand All @@ -150,22 +177,22 @@ extern "fastcall" fn paint_traverse(this: &'static IPanel, panel_id: usize, forc
unsafe fn init_paint_traverse() -> Result<(), detour::Error> {
use rglua::interface::*;

let vgui_interface = get_from_interface( "VGUI_Panel009", get_interface_handle("vgui2.dll").unwrap() )
.unwrap() as *mut IPanel;
let vgui_interface =
get_from_interface("VGUI_Panel009", get_interface_handle("vgui2.dll").unwrap()).unwrap()
as *mut IPanel;

let panel_interface = vgui_interface.as_ref().unwrap();

type PaintTraverseFn = extern "fastcall" fn(&'static IPanel, usize, bool, bool);
// Get painttraverse raw function object to detour.
let painttraverse: PaintTraverseFn = std::mem::transmute(
(panel_interface.vtable as *mut *mut CVoid)
(panel_interface.vtable as *mut *mut c_void)
.offset(41)
.read()
.read(),
);

let detour = detour::GenericDetour::new(painttraverse, paint_traverse)?;

PAINT_TRAVERSE_H.set(detour);
assert!(PAINT_TRAVERSE_H.set(detour).is_ok());
PAINT_TRAVERSE_H.get().unwrap().enable()?;

Ok(())
Expand All @@ -183,7 +210,7 @@ pub unsafe fn init() -> Result<(), detour::Error> {
Ok(())
}

pub unsafe fn cleanup() -> Result<(), detour::Error>{
pub unsafe fn cleanup() -> Result<(), detour::Error> {
LUAL_LOADBUFFERX_H.disable()?;
LUAL_NEWSTATE_H.disable()?;
JOINSERVER_H.get().unwrap().disable()?;
Expand All @@ -192,4 +219,4 @@ pub unsafe fn cleanup() -> Result<(), detour::Error>{
PAINT_TRAVERSE_H.get().unwrap().disable()?;

Ok(())
}
}
44 changes: 26 additions & 18 deletions src/input.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
use std::path::Path;
use crate::sys::{runlua::runLua, statics::*};
use std::path::Path;

pub(crate) fn try_process_input() -> anyhow::Result<()> {
pub(crate) fn try_process_input() -> std::io::Result<()> {
// Loop forever in this thread, since it is separate from Gmod, and take in user input.
let mut buffer = String::new();

std::io::stdin().read_line(&mut buffer)?;
let (word, rest) = buffer.split_once(' ').unwrap_or( (buffer.trim_end(), "") );
let (word, rest) = buffer.split_once(' ').unwrap_or((buffer.trim_end(), ""));
let rest_trim = rest.trim_end();

match word {
"lua_run_cl" => if let Err(why) = runLua(REALM_CLIENT, rest.to_owned()) {
error!("{}", why);
// We don't know if it was successful yet. The code will run later in painttraverse and print there.
},
"lua_openscript_cl" => match std::fs::read_to_string( Path::new(rest_trim) ) {
Err(why) => error!("Errored on lua_openscript. [{}]", why),
Ok(contents) => if let Err(why) = runLua( REALM_CLIENT, contents ) {
"lua_run_cl" => {
if let Err(why) = runLua(REALM_CLIENT, rest.to_owned()) {
error!("{}", why);
// We don't know if it was successful yet. The code will run later in painttraverse and print there.
}
}
"lua_openscript_cl" => match std::fs::read_to_string(Path::new(rest_trim)) {
Err(why) => error!("Errored on lua_openscript. [{}]", why),
Ok(contents) => {
if let Err(why) = runLua(REALM_CLIENT, contents) {
error!("{}", why);
}
}
},

"lua_run_menu" => if let Err(why) = runLua(REALM_MENU, rest.to_owned()) {
error!("{}", why);
},
"lua_run_menu" => {
if let Err(why) = runLua(REALM_MENU, rest.to_owned()) {
error!("{}", why);
}
}

"lua_openscript_menu" => match std::fs::read_to_string( Path::new( rest ) ) {
"lua_openscript_menu" => match std::fs::read_to_string(Path::new(rest)) {
Err(why) => error!("Errored on lua_openscript. [{}]", why),
Ok(contents) => if let Err(why) = runLua( REALM_MENU, contents ) {
error!("Errored on lua_openscript. {}", why);
Ok(contents) => {
if let Err(why) = runLua(REALM_MENU, contents) {
error!("Errored on lua_openscript. {}", why);
}
}
},

Expand All @@ -42,8 +50,8 @@ pub(crate) fn try_process_input() -> anyhow::Result<()> {

println!("help | Prints this out.");
}
_ => ()
_ => (),
}

Ok(())
}
}
Loading

0 comments on commit 8aef59a

Please sign in to comment.