diff --git a/Cargo.toml b/Cargo.toml index 2a22da7..02e14c6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ description = "wrappers and functions for R2Northstar plugins" repository = "https://github.com/catornot/rrplug" license = "Apache-2.0 OR MIT" keywords = ["plugin", "northstar", "titanfall"] -exclude = ["/rrplug_template", ".gitignore"] +exclude = [".gitignore"] edition = "2021" rust-version = "1.77" diff --git a/src/errors.rs b/src/errors.rs index 1505369..5263bf3 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -155,7 +155,6 @@ pub enum InterfaceGetterError<'a> { InterfaceNotFound(&'a str), } -// TODO: make a macro for this impl InterfaceGetterError<'_> { /// logs the error with the builtin logger pub fn log(&self) { diff --git a/src/high/engine/convars.rs b/src/high/engine/convars.rs index 8c5db88..44e8b8c 100644 --- a/src/high/engine/convars.rs +++ b/src/high/engine/convars.rs @@ -168,7 +168,6 @@ impl ConVarRegister { } } -// TODO: rewrite convars with thread_local! // so the convars have to init at mod scope with a macro // sync and send must be removed from ConVarStruct to forbid unsafe access with race condition // altought a unsafe way of initing the ConVarStruct should be given @@ -406,6 +405,8 @@ impl ConVarStruct { } // TODO: add exclusive access set_value s aka &mut self + // this might not be needed acutally since this acts like a Cell where you can't get a reference to internal parts + // well the string can be referenced but eh ub is fine ig XD // this really should not be a &self /// set the int value of the convar diff --git a/src/high/engine_sync.rs b/src/high/engine_sync.rs index 5f83be5..2d938fc 100644 --- a/src/high/engine_sync.rs +++ b/src/high/engine_sync.rs @@ -121,7 +121,7 @@ pub unsafe fn run_async_routine() { let result = unsafe { (sqfunctions.sq_getfunction)( sqvm.as_ptr(), - to_cstring(&function_name).as_ptr(), // TODO: safe or not? + to_cstring(&function_name).as_ptr(), function_obj.as_mut_ptr(), std::ptr::null(), ) diff --git a/src/high/squirrel_traits.rs b/src/high/squirrel_traits.rs index 7eb3c1c..cee784a 100644 --- a/src/high/squirrel_traits.rs +++ b/src/high/squirrel_traits.rs @@ -171,7 +171,6 @@ impl IntoSquirrelArgs for T { } } -// TODO: format this // TODO: check for correctness macro_rules! into_squirrel_args_impl{ ( $( ($($ty_name: ident : $tuple_index:tt),*) );*; ) => { $( diff --git a/src/interfaces/mod.rs b/src/interfaces/mod.rs index 707e02b..d9cd411 100644 --- a/src/interfaces/mod.rs +++ b/src/interfaces/mod.rs @@ -9,7 +9,7 @@ mod test { use crate::rrplug; use rrplug_proc::as_interface; - #[allow(dead_code)] // TODO: fix later + #[allow(dead_code)] #[repr(C)] struct TestInterface { the_line: &'static str, diff --git a/src/macros/entry.rs b/src/macros/entry.rs index b60dd26..3ab53cd 100644 --- a/src/macros/entry.rs +++ b/src/macros/entry.rs @@ -37,15 +37,17 @@ macro_rules! entry { use high::engine::EngineData; use mid::squirrel::SQFUNCTIONS; + use std::ffi::{CStr, CString}; use $crate::bindings::{plugin_abi, squirrelclasstypes, squirreldatatypes}; use $crate::exports::log; + use $crate::exports::windows::{ + core::PCSTR, Win32::System::LibraryLoader::GetModuleHandleA, + }; use $crate::interfaces::external::SourceInterface; use $crate::plugin::Plugin; use $crate::rrplug; use $crate::{high, mid}; - use std::ffi::CString; - pub static PLUGIN: $crate::exports::OnceCell<$plugin> = $crate::exports::OnceCell::new(); @@ -111,6 +113,27 @@ macro_rules! entry { if PLUGIN.set(plugin).is_err() { panic!("PLUGIN failed initialization") } + + if reloaded { + const ENGINE: &CStr = c"engine.dll"; + const SERVER: &CStr = c"server.dll"; + const CLIENT: &CStr = c"client.dll"; + unsafe { + _ = self.OnLibraryLoaded( + GetModuleHandleA(PCSTR(ENGINE.as_ptr().cast())) + .expect("engine.dll should exists if called for reload"), + ENGINE.as_ptr(), + ); + if let Ok(handle) = GetModuleHandleA(PCSTR(CLIENT.as_ptr().cast())) { + self.OnLibraryLoaded(handle, CLIENT.as_ptr()); + } // client gets loaded before server + self.OnLibraryLoaded( + GetModuleHandleA(PCSTR(SERVER.as_ptr().cast())) + .expect("server.dll should exists if called for reload"), + SERVER.as_ptr(), + ); + } + } } fn Finalize(&self) { PLUGIN diff --git a/src/macros/sq_utils.rs b/src/macros/sq_utils.rs index 70d991d..6714dd2 100644 --- a/src/macros/sq_utils.rs +++ b/src/macros/sq_utils.rs @@ -122,38 +122,6 @@ macro_rules! call_sq_object_function { ) } -// TODO: remove this -/* -/// calls any function defined on the sqvm -/// the call will happen on the next engine frame -/// -/// macro version of [`crate::high::squirrel::async_call_sq_function`], used to call a function with args -/// -/// ## example -/// ```no_run -/// # use rrplug::prelude::*; -/// -/// rrplug::async_call_sq_function!(ScriptVmType::Client, "SomeSQFunc", 9347, "Test".to_string()); -/// ``` -#[macro_export] -macro_rules! async_call_sq_function { - ($context:expr, $function_name:expr, $( $arg:expr ),* ) => ( - $crate::high::squirrel::async_call_sq_function( - $context, - $function_name, - Some( Box::new( move |sqvm,sqfunctions| { - use $crate::high::squirrel_traits::PushToSquirrelVm; - $( - $arg.push_to_sqvm(sqvm, sqfunctions); - )* - - $crate::macros::sq_utils::__arg_count_helper([$($crate::__replace_expr!($arg)),*]) as i32 - } )), - ) - ); -} -*/ - /// internal macro used in counting args in some macros #[doc(hidden)] #[macro_export] diff --git a/src/mid/engine/concommands.rs b/src/mid/engine/concommands.rs index acbf10d..3bb3d3a 100644 --- a/src/mid/engine/concommands.rs +++ b/src/mid/engine/concommands.rs @@ -33,7 +33,6 @@ impl RegisterConCommands { help_string: &str, flags: i32, ) -> Result<*mut ConCommand, RegisterError> { - // TODO: use IMemAlloc here let name = try_cstring(name)?.into_bytes_with_nul(); let name_ptr = unsafe { diff --git a/src/mid/reloading.rs b/src/mid/reloading.rs index c42ee68..cfe1eff 100644 --- a/src/mid/reloading.rs +++ b/src/mid/reloading.rs @@ -1,6 +1,13 @@ //! rrplug's prototype of a plugin reloading system /// the reponse to a unload event +/// +/// # Difficulties +/// the main issue arises from dangling pointers since the moment a plugin is reloaded callbacks, sqfunctions, etc will start calling into uninit memory. +/// which may be hard to handle at times. +/// +/// the other issue is reinstating the plugin. rrplug will get back up by getting handles to engine, client and server in order +/// but squirrel cannot be fully restorted so it's best to reset all vms. pub struct ReloadResponse { should_reload: bool, } @@ -22,9 +29,9 @@ impl ReloadResponse { /// /// # Safety /// - /// this will create ub! + /// **this will create ub!** /// - /// **unless** before calling this everything will cleaned up! + /// **unless** before calling this everything will be cleaned up! /// /// ex: convars, concommands, sqfunctions (sqvm reload), hooks, etc pub const unsafe fn allow_reload() -> Self {