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

Commit 6c44aee

Browse files
committed
0.7.0
* winapi * Fix double loading * awesome proper changelogs maybe later
1 parent 8aef59a commit 6c44aee

File tree

5 files changed

+79
-80
lines changed

5 files changed

+79
-80
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "autorun"
3-
version = "0.6.1"
3+
version = "0.7.0"
44
authors = ["Vurv78 <[email protected]>"]
55
edition = "2021"
66

@@ -28,9 +28,10 @@ log = { version = "0.4.14", optional = true }
2828
simplelog = { version = "0.11.0", optional = true }
2929

3030
regex = "1.5.4"
31+
winapi = { version = "0.3.9", features = ["wincon", "consoleapi"] }
3132

3233
[features]
33-
default = ["runner"]
34+
default = ["runner", "logging"]
3435
runner = []
3536

3637
# Disabled by default for now as this breaks autorun.

src/detours/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ lazy_detour! {
3737

3838
extern "C" fn luaL_newstate() -> LuaState {
3939
let state = LUAL_NEWSTATE_H.call();
40-
debug!("Got client state through luaL_newstate");
4140
setClientState(state);
4241
state
4342
}

src/lib.rs

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ mod input; // Console input
2020
mod sys; // Configs
2121

2222
static SENDER: OnceCell<mpsc::SyncSender<()>> = OnceCell::new();
23-
const DLL_PROCESS_ATTACH: u32 = 1;
24-
const DLL_PROCESS_DETACH: u32 = 0;
2523

26-
extern "system" {
27-
fn AllocConsole() -> bool;
28-
fn FreeConsole() -> bool;
29-
fn GetLastError() -> u32;
30-
}
24+
use winapi::{
25+
shared::minwindef::TRUE,
26+
um::{
27+
consoleapi::AllocConsole,
28+
errhandlingapi::GetLastError,
29+
wincon::{FreeConsole, GetConsoleWindow},
30+
},
31+
};
3132

3233
#[derive(Error, Debug)]
3334
enum InitializeError {
@@ -49,7 +50,6 @@ enum ExitError {
4950

5051
fn init() -> Result<(), InitializeError> {
5152
unsafe {
52-
println!("Init!");
5353
logging::init()?;
5454
detours::init()?;
5555
}
@@ -80,73 +80,85 @@ fn init() -> Result<(), InitializeError> {
8080
Ok(())
8181
}
8282

83-
fn cleanup() -> Result<(), ExitError> {
84-
unsafe { detours::cleanup()? };
83+
// Returns if successfully initialized
84+
fn attach() -> bool {
85+
unsafe {
86+
if GetConsoleWindow().is_null() {
87+
if AllocConsole() != TRUE {
88+
// Console didn't exist and couldn't allocate one now, hard error
89+
error!("Failed to allocate console. {}", GetLastError());
90+
return false;
91+
}
92+
} else {
93+
debug!("Found existing console!");
94+
}
95+
}
8596

86-
if let Some(sender) = SENDER.get() {
87-
sender.send(()).map_err(|_| ExitError::MPSCFailure)?;
97+
if let Err(why) = init() {
98+
match why {
99+
InitializeError::LogInitError(y) => eprintln!("Failed to initialize logging. [{}]", y),
100+
_ => error!("Failed to initialize Autorun. [{}]", why),
101+
}
102+
false
103+
} else {
104+
true
88105
}
106+
}
89107

90-
unsafe {
91-
FreeConsole();
92-
};
108+
fn cleanup() {
109+
fn try_cleanup() -> Result<(), ExitError> {
110+
unsafe { detours::cleanup()? };
93111

94-
Ok(())
112+
if let Some(sender) = SENDER.get() {
113+
sender.send(()).map_err(|_| ExitError::MPSCFailure)?;
114+
}
115+
116+
unsafe {
117+
FreeConsole();
118+
};
119+
120+
Ok(())
121+
}
122+
123+
if let Err(why) = try_cleanup() {
124+
error!("Failed to inject Autorun. [{}]", why);
125+
}
95126
}
96127

97-
// Windows Only. I'm not going to half-ass Linux support (And don't even get me to try and work with OSX..)
98128
#[no_mangle]
99129
extern "system" fn DllMain(_: *const u8, reason: u32, _: *const u8) -> u32 {
130+
use winapi::um::winnt::{DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH};
131+
100132
match reason {
101133
DLL_PROCESS_ATTACH => {
102-
unsafe {
103-
if !AllocConsole() {
104-
// Assume a console already exists and just log an error.
105-
eprintln!("Failed to allocate console. {}", GetLastError());
106-
}
107-
}
108-
109-
if let Err(why) = init() {
110-
error!("Failed to inject Autorun. [{}]", why);
111-
}
134+
attach();
112135
}
113136
DLL_PROCESS_DETACH => {
114-
if let Err(why) = cleanup() {
115-
error!("Failed to inject Autorun. [{}]", why);
116-
}
137+
cleanup();
117138
}
118139
_ => (),
119140
}
141+
120142
1
121143
}
122144

123145
use rglua::types::LuaState;
124146

125147
#[no_mangle]
126148
extern "C" fn gmod13_open(state: LuaState) -> i32 {
149+
// DllMain is called prior to this even if Autorun is used as a binary module.
150+
// So only initialize what we haven't already.
151+
127152
use crate::sys::util::initMenuState;
128-
unsafe {
129-
if !AllocConsole() {
130-
// Assume a console already exists and just log an error.
131-
eprintln!("Failed to allocate console. {}", GetLastError());
132-
}
133-
}
134153

135-
if let Err(why) = init() {
136-
match why {
137-
InitializeError::LogInitError(y) => eprintln!("Failed to initialize logging. [{}]", y),
138-
_ => error!("Failed to initialize Autorun. [{}]", why),
139-
}
140-
} else if let Err(why) = initMenuState(state) {
154+
if let Err(why) = initMenuState(state) {
141155
error!("Failed to initialize menu state. [{}]", why);
142156
}
143157
0
144158
}
145159

146160
#[no_mangle]
147161
extern "C" fn gmod13_close(_state: LuaState) -> i32 {
148-
if let Err(why) = cleanup() {
149-
error!("Failed to close Autorun module. [{}]", why);
150-
}
162+
cleanup();
151163
0
152164
}

src/sys/runlua.rs

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::sys::{
66
use std::ffi::CString;
77

88
use rglua::{
9+
cstr,
910
globals::Lua::{self, GLOBALSINDEX},
1011
lua_shared::*,
1112
rstr,
@@ -14,7 +15,7 @@ use rglua::{
1415

1516
const NO_LUA_STATE: &str = "Didn't run lua code, lua state is not valid/loaded!";
1617
const INVALID_LOG_LEVEL: *const i8 =
17-
"Invalid log level (Should be 1-5, 1 being Error, 5 being Trace)\0".as_ptr() as *const i8;
18+
cstr!("Invalid log level (Should be 1-5, 1 being Error, 5 being Trace)");
1819

1920
pub fn runLua(realm: Realm, code: String) -> Result<(), &'static str> {
2021
// Check if lua state is valid for instant feedback
@@ -69,21 +70,9 @@ extern "C" fn sautorun_require(state: LuaState) -> i32 {
6970

7071
let raw_path = luaL_checklstring(state, 1, 0);
7172

72-
lua_getfield(
73-
state,
74-
rglua::globals::Lua::GLOBALSINDEX,
75-
"sautorun\0".as_ptr() as *const i8,
76-
);
77-
lua_getfield(
78-
state,
79-
rglua::globals::Lua::GLOBALSINDEX,
80-
"package\0".as_ptr() as *const i8,
81-
);
82-
lua_getfield(
83-
state,
84-
rglua::globals::Lua::GLOBALSINDEX,
85-
"loaded\0".as_ptr() as *const i8,
86-
);
73+
lua_getfield(state, rglua::globals::Lua::GLOBALSINDEX, cstr!("sautorun"));
74+
lua_getfield(state, rglua::globals::Lua::GLOBALSINDEX, cstr!("package"));
75+
lua_getfield(state, rglua::globals::Lua::GLOBALSINDEX, cstr!("loaded"));
8776
lua_getfield(state, 2, raw_path);
8877
if lua_toboolean(state, -1) != 0 {
8978
return 1;
@@ -144,39 +133,39 @@ pub fn runLuaEnv(
144133
lua_createtable(state, 0, 0); // local t2 = {}
145134

146135
lua_pushstring(state, identifier);
147-
lua_setfield(state, -2, "NAME\0".as_ptr() as *const i8); // t2.NAME = ...
136+
lua_setfield(state, -2, cstr!("NAME")); // t2.NAME = ...
148137

149138
lua_pushstring(state, dumped_script);
150-
lua_setfield(state, -2, "CODE\0".as_ptr() as *const i8); // t2.CODE = ...
139+
lua_setfield(state, -2, cstr!("CODE")); // t2.CODE = ...
151140

152141
if let Ok(ip) = CString::new(ip) {
153142
lua_pushstring(state, ip.as_ptr());
154143
} else {
155144
lua_pushnil(state);
156145
}
157-
lua_setfield(state, -2, "IP\0".as_ptr() as *const i8);
146+
lua_setfield(state, -2, cstr!("IP"));
158147

159148
// If this is running before autorun, set SAUTORUN.STARTUP to true.
160149
lua_pushboolean(state, startup as i32);
161-
lua_setfield(state, -2, "STARTUP\0".as_ptr() as *const i8);
150+
lua_setfield(state, -2, cstr!("STARTUP"));
162151

163152
lua_pushcfunction(state, log);
164-
lua_setfield(state, -2, "log\0".as_ptr() as *const i8);
153+
lua_setfield(state, -2, cstr!("log"));
165154

166155
/*lua_createtable( state, 0, 0 ); // local t = {}
167156
lua_createtable( state, 0, 0 ); // local t2 = {}
168-
lua_setfield( state, -2, "loaded\0".as_ptr() as *const i8 ); // package.loaded = t2
169-
lua_setfield( state, -2, "package\0".as_ptr() as *const i8 ); // package = t
157+
lua_setfield( state, -2, cstr!("loaded") ); // package.loaded = t2
158+
lua_setfield( state, -2, cstr!("package") ); // package = t
170159
*/
171160

172161
lua_pushcfunction(state, sautorun_require);
173-
lua_setfield(state, -2, "require\0".as_ptr() as *const i8);
162+
lua_setfield(state, -2, cstr!("require"));
174163

175-
lua_setfield(state, -2, "sautorun\0".as_ptr() as *const i8);
164+
lua_setfield(state, -2, cstr!("sautorun"));
176165

177166
lua_createtable(state, 0, 0); // Create a metatable to make the env inherit from _G
178167
lua_pushvalue(state, GLOBALSINDEX);
179-
lua_setfield(state, -2, "__index\0".as_ptr() as *const i8);
168+
lua_setfield(state, -2, cstr!("__index"));
180169
lua_setmetatable(state, -2);
181170

182171
lua_setfenv(state, -2);

src/sys/util.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
sync::atomic::Ordering,
55
};
66

7-
use rglua::{lua_shared::*, rstr, types::LuaState};
7+
use rglua::{cstr, lua_shared::*, rstr, types::LuaState};
88

99
const LUA_OK: i32 = 0;
1010

@@ -72,9 +72,7 @@ pub fn initMenuState(state: LuaState) -> Result<(), detour::Error> {
7272
error!("MENU_STATE was occupied in gmod13_open. Shouldn't happen.");
7373
}
7474

75-
info!("Loaded into menu state.");
76-
77-
lua_getglobal(state, "JoinServer\0".as_ptr() as *const i8);
75+
lua_getglobal(state, cstr!("JoinServer"));
7876
let joinserver_fn = lua_tocfunction(state, -1);
7977
lua_pop(state, 1);
8078

@@ -135,8 +133,8 @@ pub fn lua_compilestring(state: LuaState, code: &str) -> Result<(), &'static str
135133
state,
136134
code.as_ptr() as *const i8,
137135
code.len(),
138-
"@RunString\0".as_ptr() as *const i8,
139-
"bt\0".as_ptr() as *const i8,
136+
cstr!("@RunString"),
137+
cstr!("bt"),
140138
) != LUA_OK
141139
{
142140
let err = lua_tolstring(state, -1, 0);

0 commit comments

Comments
 (0)