From e969c780aa2e96e4744dbb807f92bcfe6d99b985 Mon Sep 17 00:00:00 2001 From: Vurv <56230599+Vurv78@users.noreply.github.com> Date: Fri, 23 Jul 2021 17:45:54 -0700 Subject: [PATCH] Add proper logging Fixes #11 --- Cargo.toml | 9 ++++-- build_win_32.bat | 2 +- build_win_64.bat | 2 +- src/hooks.rs | 12 ++++---- src/input.rs | 42 +++++++++++++++++++++++++ src/lib.rs | 76 ++++++++++++---------------------------------- src/logging.rs | 39 ++++++++++++++++++++++++ src/sys/funcs.rs | 17 +++++------ src/sys/mod.rs | 4 ++- src/sys/runlua.rs | 19 ++++++++++-- src/sys/statics.rs | 2 +- 11 files changed, 144 insertions(+), 80 deletions(-) create mode 100644 src/input.rs create mode 100644 src/logging.rs diff --git a/Cargo.toml b/Cargo.toml index 0a6bb4c..911fff8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "autorun" -version = "0.4.0" +version = "0.4.1" authors = ["Vurv78 "] edition = "2018" @@ -23,4 +23,9 @@ atomic = "0.5.0" # Misc dirs = "3.0.2" # To get your home directory. -anyhow = "1.0.42" \ No newline at end of file +anyhow = "1.0.42" + +# Logging +chrono = "0.4.19" +log = "0.4.14" +simplelog = "0.10.0" \ No newline at end of file diff --git a/build_win_32.bat b/build_win_32.bat index 8e7f0e6..2c276bf 100644 --- a/build_win_32.bat +++ b/build_win_32.bat @@ -1,5 +1,5 @@ @echo off rustup target add i686-pc-windows-msvc cargo build --release --target=i686-pc-windows-msvc -move %cd%\target\i686-pc-windows-msvc\release\Autorun.dll %cd%\Autorun_Win_32.dll +move %cd%\target\i686-pc-windows-msvc\release\Autorun.dll %cd%\gmsv_autorun_win32.dll pause \ No newline at end of file diff --git a/build_win_64.bat b/build_win_64.bat index cdef302..210b389 100644 --- a/build_win_64.bat +++ b/build_win_64.bat @@ -1,4 +1,4 @@ @echo off cargo build --release -move %cd%\target\release\Autorun.dll %cd%\Autorun_Win_64.dll +move %cd%\target\release\Autorun.dll %cd%\gmsv_autorun_win64.dll pause \ No newline at end of file diff --git a/src/hooks.rs b/src/hooks.rs index 6bd1792..8ff7284 100644 --- a/src/hooks.rs +++ b/src/hooks.rs @@ -33,7 +33,7 @@ pub extern fn loadbufferx(state: LuaState, code: CharBuf, size: SizeT, identifie Ok(hook) } Err(why) => { - eprintln!("Couldn't hook JoinServer. {}", why); + error!("Couldn't hook JoinServer. {}", why); return Err(()); } }; @@ -57,11 +57,11 @@ pub extern fn loadbufferx(state: LuaState, code: CharBuf, size: SizeT, identifie if let Ok(script) = fs::read_to_string(&*AUTORUN_SCRIPT_PATH) { // Try to run here if let Err(why) = runLuaEnv(&script, identifier, code, server_ip, true) { - eprintln!("{}", why); + error!("{}", why); } autoran = true; } else { - eprintln!( "Couldn't read your autorun script file at {}/{}", SAUTORUN_DIR.display(), AUTORUN_SCRIPT_PATH.display() ); + error!( "Couldn't read your autorun script file at {}/{}", SAUTORUN_DIR.display(), AUTORUN_SCRIPT_PATH.display() ); } } } @@ -77,7 +77,7 @@ pub extern fn loadbufferx(state: LuaState, code: CharBuf, size: SizeT, identifie } } Err(why) => { - eprintln!("{}", why); + error!("{}", why); } } } @@ -101,7 +101,7 @@ pub extern fn loadbufferx(state: LuaState, code: CharBuf, size: SizeT, identifie // If not, then hook it. pub extern fn joinserver(state: LuaState) -> CInt { let ip = rstring!( lua_tolstring(state, 1, 0) ); - println!("Joining Server with IP {}!", ip); + 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. HAS_AUTORAN.store(false, Ordering::Relaxed); @@ -109,7 +109,7 @@ pub extern fn joinserver(state: LuaState) -> CInt { // We could retrieve the hook from our global variables hook.call(state); } else { - eprintln!("Failed to get JOIN_SERVER hook from global state"); + error!("Failed to get JOIN_SERVER hook from global state"); } 0 } \ No newline at end of file diff --git a/src/input.rs b/src/input.rs new file mode 100644 index 0000000..b3daf71 --- /dev/null +++ b/src/input.rs @@ -0,0 +1,42 @@ +use std::path::Path; +use crate::sys::runLua; + +pub(crate) fn try_process_input() -> anyhow::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(), "") ); + + debug!("Command used: [{}], rest [{}]", word, rest); + + match word { + "lua_run" => { + match runLua(rest) { + Ok(_) => println!("Ran successfully!"), + Err(why) => error!("{}", why) + } + }, + "lua_openscript" => { + let path = rest.trim_end(); + match std::fs::read_to_string( Path::new(path) ) { + Err(why) => error!("Errored on lua_openscript. [{}]", why), + Ok(contents) => { + match runLua( &contents ) { + Ok(_) => info!("Ran file {} successfully!", path), + Err(why) => error!("Errored when running file at path '{}'. [{}]", path, why) + } + } + } + }, + "help" => { + println!("Commands list:"); + println!("lua_run | Runs lua code on the currently loaded lua state. Will print if any errors occur."); + println!("lua_openscript | Runs a lua script located at file_dir, this dir being a full directory, not relative or anything."); + println!("help | Prints this out."); + } + _ => () + } + + Ok(()) +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 9411161..6c6e69e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,63 +1,24 @@ #![allow(non_snake_case)] use std::{ - path::Path, thread, sync::mpsc }; -use once_cell::sync::OnceCell; +#[macro_use] extern crate log; +extern crate simplelog; -pub mod sys; // Sort of configurable files. -pub mod hooks; +use once_cell::sync::OnceCell; -use sys::{ - statics::*, - runlua::runLua -}; +mod input; // Console input +mod sys; // Configs +mod hooks; // Hook functions for detours +mod logging; // You guessed it, logging -fn try_process_input() -> anyhow::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(), "") ); - - match word { - "lua_run" => { - match runLua(rest) { - Ok(_) => { println!("Ran successfully!"); } - Err(why) => { eprintln!("{}", why); } - } - }, - "lua_openscript" => { - let path = rest.trim_end(); - match std::fs::read_to_string( Path::new(path) ) { - Err(why) => { eprintln!("Errored on lua_openscript. [{}]", why); } - Ok(contents) => { - match runLua( &contents ) { - Ok(_) => { println!("Ran file {} successfully!", path) }, - Err(why) => { eprintln!("Errored when running file {}, {}", path, why); } - } - } - } - }, - "help" => { - println!("Commands list:"); - println!("lua_run | Runs lua code on the currently loaded lua state. Will print if any errors occur."); - println!("lua_openscript | Runs a lua script located at file_dir, this dir being a full directory, not relative or anything."); - println!("help | Prints this out."); - }, - "kill" => { - // More debug than anything - if let Some(sender) = SENDER.get() { - sender.send(()).expect("Couldn't send mpsc kill message"); - } - } - _ => () - } +use sys::statics::*; - Ok(()) -} +const SENDER: OnceCell< mpsc::Sender<()> > = OnceCell::new(); +const DLL_PROCESS_ATTACH: u32 = 1; +const DLL_PROCESS_DETACH: u32 = 0; extern "system" { fn AllocConsole() -> i32; @@ -65,15 +26,22 @@ extern "system" { fn init() { assert_eq!( unsafe { AllocConsole() }, 1, "Couldn't allocate console" ); + info!("Initialized."); println!("<---> Autorun-rs <--->"); println!("Type [help] for the list of commands"); + if let Err(why) = logging::init() { + eprintln!("Couldn't start logging module. [{}]", why); + return; + } + &*LUAL_LOADBUFFERX; let (sender, receiver) = mpsc::channel(); thread::spawn(move || loop { - if let Ok(_) = try_process_input() { + if let Ok(_) = input::try_process_input() { + // Got a command continue; } match receiver.try_recv() { @@ -105,11 +73,7 @@ fn cleanup() { } } -const SENDER: OnceCell< mpsc::Sender<()> > = OnceCell::new(); -const DLL_PROCESS_ATTACH: u32 = 1; -const DLL_PROCESS_DETACH: u32 = 0; - -// Windows Only. I'm not going to half-ass cross-operating system support. +// Windows Only. I'm not going to half-ass Linux support (And don't even get me to try and work with OSX..) #[no_mangle] pub extern "stdcall" fn DllMain(_: *const u8, reason: u32, _: *const u8) -> u32 { match reason { diff --git a/src/logging.rs b/src/logging.rs new file mode 100644 index 0000000..138e60c --- /dev/null +++ b/src/logging.rs @@ -0,0 +1,39 @@ +use simplelog::*; + +use chrono::prelude::*; +use std::fs::File; +use crate::sys::statics::SAUTORUN_LOG_DIR; + +pub fn init() -> anyhow::Result<()> { + if !SAUTORUN_LOG_DIR.exists() { + std::fs::create_dir_all(&*SAUTORUN_LOG_DIR)?; + } + + let log_file_handle = File::create( SAUTORUN_LOG_DIR.join( format!("{}.log", Local::now().format("%B %d, %Y %I-%M %P") ) ) )?; + + let configs = ConfigBuilder::new() + .set_level_color( Level::Info, Some( Color::Cyan) ) + .set_level_color( Level::Error, Some( Color::Red) ) + .set_level_color( Level::Warn, Some( Color::Yellow) ) + .build(); + + CombinedLogger::init( +vec![ + TermLogger::new( + // Logs that are level 'info' or above will be sent to the console. + LevelFilter::Info, + configs, + TerminalMode::Mixed, + ColorChoice::Auto + ), + WriteLogger::new( + // Logs that are level 'info' or above will be written to the log. + LevelFilter::Info, + Config::default(), + log_file_handle + ) + ] + )?; + + Ok(()) +} \ No newline at end of file diff --git a/src/sys/funcs.rs b/src/sys/funcs.rs index e03f053..fb24b98 100644 --- a/src/sys/funcs.rs +++ b/src/sys/funcs.rs @@ -33,23 +33,20 @@ pub fn getAutorunHandle(garry_dir: &str, server_ip: &str) -> Option { let file_loc = &*SAUTORUN_DIR .join("lua_dumps") .join(server_ip.replace(":",".")) - .join(&lua_run_path); + .join(&garry_dir.to_owned().replace(":", ".")); match file_loc.parent() { Some(dirs) => { match fs::create_dir_all(dirs) { Err(why) => { - eprintln!("Couldn't create sautorun-rs directories. [{}]", why); - dbg!(dirs); + error!("Couldn't create sautorun-rs dirs with path [{}]. [{}]", dirs.display(), why); None } - Ok(_) => { - match File::create(file_loc) { - Ok(file) => Some(file), - Err(why) => { - eprintln!("Couldn't create sautorun-rs file. [{}]", why); - None - } + Ok(_) => match File::create(file_loc) { + Ok(file) => Some(file), + Err(why) => { + error!("Couldn't create sautorun-rs file with path [{}]. [{}]", why, file_loc.display()); + None } } } diff --git a/src/sys/mod.rs b/src/sys/mod.rs index 8093e27..27e8a6d 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -1,3 +1,5 @@ pub mod statics; // Global variables. pub mod funcs; -pub mod runlua; \ No newline at end of file +pub mod runlua; + +pub use runlua::*; \ No newline at end of file diff --git a/src/sys/runlua.rs b/src/sys/runlua.rs index 402e15b..8f236a3 100644 --- a/src/sys/runlua.rs +++ b/src/sys/runlua.rs @@ -55,8 +55,23 @@ pub fn runLua(code: &str) -> Result<(), String> { } extern fn log(state: LuaState) -> i32 { - let s = lua_tostring(state, 1); - println!( "{}", rstring!(s) ); + let s = luaL_checklstring(state, 1, 0); + let mut level = simplelog::Level::Info as i32; + if lua_type(state, 2) == rglua::globals::Lua::Type::Number as i32 { + level = lua_tointeger(state, 2) as i32; + } + + let str = rstring!(s); + match level { + 1 => error!("{}", str), + 2 => warn!("{}", str), + 3 => info!("{}", str), + 4 => debug!("{}", str), + 5 => trace!("{}", str), + _ => { + luaL_argerror( state, 2, b"Invalid log level (Should be 1-5, 1 being Error, 5 being Trace)\0".as_ptr() as *const i8 ); + } + } 0 } diff --git a/src/sys/statics.rs b/src/sys/statics.rs index 3bde0f9..611621d 100644 --- a/src/sys/statics.rs +++ b/src/sys/statics.rs @@ -27,7 +27,7 @@ use detour::GenericDetour; // detours-rs // ---------------- Configs ---------------- // pub static HOME_DIR: Lazy = Lazy::new(|| dirs::home_dir().expect("Couldn't get your home directory!") ); pub static SAUTORUN_DIR: Lazy = Lazy::new(|| HOME_DIR.join("sautorun-rs") ); - +pub static SAUTORUN_LOG_DIR: Lazy = Lazy::new(|| SAUTORUN_DIR.join("logs") ); // This location is run right before autorun. pub static AUTORUN_SCRIPT_PATH: Lazy = Lazy::new(|| (*SAUTORUN_DIR).join("autorun.lua") );