1#![allow(clippy::missing_safety_doc)]
4#![allow(clippy::result_unit_err)]
5
6#![feature(c_unwind)]
7#![feature(thread_id_value)]
8
9#![cfg_attr(feature = "gmcl", feature(internal_output_capture))]
10
11#[cfg(not(all(any(target_os = "windows", target_os = "linux", target_os = "macos"), any(target_pointer_width = "32", target_pointer_width = "64"))))]
12compile_error!("Unsupported platform");
13
14pub use cstr;
15pub use libloading;
16pub use gmod_macros::*;
17
18#[cfg(feature = "hax")]
19mod haxports {
20 #[cfg(not(target_os = "macos"))]
21 pub use skidscan as sigscan;
22
23 #[cfg(target_os = "macos")]
24 compile_error!("Sigscanning is currently not supported on MacOS, please disable the `hax` feature on gmod-rs using `default-features = false` to make a normal module");
25
26 pub use retour as detour;
27 pub use ctor::{ctor as dllopen, dtor as dllclose};
28
29 pub use fn_type_alias::*;
30 pub use fn_abi::*;
31 pub use cfg_table::*;
32 pub use null_fn::*;
33 pub use fn_has_this::*;
34}
35#[cfg(feature = "hax")]
36pub use haxports::*;
37
38pub mod lua;
40
41pub mod msgc;
43
44pub mod hax;
46
47pub mod userdata;
49
50pub mod net;
52
53#[cfg(feature = "gmcl")]
55pub mod gmcl;
56
57pub fn is_x86_64() -> bool {
59 #[cfg(target_pointer_width = "64")] {
60 true
62 }
63 #[cfg(target_pointer_width = "32")] {
64 lazy_static::lazy_static! {
65 static ref IS_X86_64: bool = {
66 use std::path::PathBuf;
67
68 #[cfg(target_os = "macos")] {
69 PathBuf::from("garrysmod/bin/lua_shared.dylib").is_file()
70 }
71 #[cfg(target_os = "windows")] {
72 PathBuf::from("srcds_win64.exe").is_file()
73 }
74 #[cfg(target_os = "linux")] {
75 match std::env::current_exe().expect("Failed to get executable path").file_name().expect("Failed to get executable file name").to_string_lossy().as_ref() {
77 #[cfg(target_os = "windows")]
78 "srcds.exe" => false,
79
80 #[cfg(target_os = "linux")]
81 "srcds_linux" => false,
82
83 #[cfg(target_os = "linux")]
84 "srcds" => true,
85
86 _ => {
87 #[cfg(target_os = "linux")] {
89 PathBuf::from("bin/linux64").is_dir()
90 }
91 #[cfg(target_os = "windows")] {
92 PathBuf::from("bin/win64").is_dir()
93 }
94 }
95 }
96 }
97 };
98 }
99 *IS_X86_64
100 }
101}
102
103#[macro_export]
112macro_rules! open_library_raw {
113 ($($path:literal),+) => {
114 match $crate::libloading::Library::new(concat!($($path),+)) {
115 Ok(lib) => Ok((lib, concat!($($path),+))),
116 Err(err) => Err((err, concat!($($path),+)))
117 }
118 }
119}
120
121#[macro_export]
131macro_rules! open_library_srv {
132 ($name:literal) => {{
133 #[cfg(all(target_os = "windows", target_pointer_width = "64"))] {
134 $crate::__private__gmod_rs__try_chained_open! {
135 $crate::open_library_raw!("bin/win64/", $name, ".dll"),
136 $crate::open_library_raw!($name)
137 }
138 }
139 #[cfg(all(target_os = "windows", target_pointer_width = "32"))] {
140 $crate::__private__gmod_rs__try_chained_open! {
141 $crate::open_library_raw!("bin/", $name, ".dll"),
142 $crate::open_library_raw!("garrysmod/bin/", $name, ".dll"),
143 $crate::open_library_raw!($name)
144 }
145 }
146
147 #[cfg(all(target_os = "linux", target_pointer_width = "64"))] {
148 $crate::__private__gmod_rs__try_chained_open! {
149 $crate::open_library_raw!("bin/linux64/", $name, ".so"),
150 $crate::open_library_raw!("bin/linux64/lib", $name, ".so"),
151 $crate::open_library_raw!($name)
152 }
153 }
154 #[cfg(all(target_os = "linux", target_pointer_width = "32"))] {
155 $crate::__private__gmod_rs__try_chained_open! {
156 $crate::open_library_raw!("bin/linux32/", $name, ".so"),
157 $crate::open_library_raw!("bin/linux32/lib", $name, ".so"),
158 $crate::open_library_raw!("bin/", $name, "_srv.so"),
159 $crate::open_library_raw!("bin/lib", $name, "_srv.so"),
160 $crate::open_library_raw!("garrysmod/bin/", $name, "_srv.so"),
161 $crate::open_library_raw!("garrysmod/bin/lib", $name, "_srv.so"),
162 $crate::open_library_raw!("bin/", $name, ".so"),
163 $crate::open_library_raw!("bin/lib", $name, ".so"),
164 $crate::open_library_raw!("garrysmod/bin/", $name, ".so"),
165 $crate::open_library_raw!("garrysmod/bin/lib", $name, ".so"),
166 $crate::open_library_raw!($name)
167 }
168 }
169
170 #[cfg(target_os = "macos")] {
171 $crate::__private__gmod_rs__try_chained_open! {
172 $crate::open_library_raw!("GarrysMod_Signed.app/Contents/MacOS/", $name, ".dylib"),
173 $crate::open_library_raw!("GarrysMod_Signed.app/Contents/MacOS/lib", $name, ".dylib"),
174 $crate::open_library_raw!("bin/", $name, "_srv.dylib"),
175 $crate::open_library_raw!("bin/lib", $name, "_srv.dylib"),
176 $crate::open_library_raw!("garrysmod/bin/", $name, "_srv.dylib"),
177 $crate::open_library_raw!("garrysmod/bin/lib", $name, "_srv.dylib"),
178 $crate::open_library_raw!("bin/", $name, ".dylib"),
179 $crate::open_library_raw!("bin/lib", $name, ".dylib"),
180 $crate::open_library_raw!("garrysmod/bin/", $name, ".dylib"),
181 $crate::open_library_raw!("garrysmod/bin/lib", $name, ".dylib"),
182 $crate::open_library_raw!($name)
183 }
184 }
185 }};
186}
187
188#[macro_export]
198macro_rules! open_library {
199 ($name:literal) => {{
200 #[cfg(all(target_os = "windows", target_pointer_width = "64"))] {
201 $crate::__private__gmod_rs__try_chained_open! {
202 $crate::open_library_raw!("bin/win64/", $name, ".dll"),
203 $crate::open_library_raw!($name)
204 }
205 }
206 #[cfg(all(target_os = "windows", target_pointer_width = "32"))] {
207 $crate::__private__gmod_rs__try_chained_open! {
208 $crate::open_library_raw!("bin/", $name, ".dll"),
209 $crate::open_library_raw!("garrysmod/bin/", $name, ".dll"),
210 $crate::open_library_raw!($name)
211 }
212 }
213
214 #[cfg(all(target_os = "linux", target_pointer_width = "64"))] {
215 $crate::__private__gmod_rs__try_chained_open! {
216 $crate::open_library_raw!("bin/linux64/", $name, ".so"),
217 $crate::open_library_raw!("bin/linux64/lib", $name, ".so"),
218 $crate::open_library_raw!($name)
219 }
220 }
221 #[cfg(all(target_os = "linux", target_pointer_width = "32"))] {
222 $crate::__private__gmod_rs__try_chained_open! {
223 $crate::open_library_raw!("bin/linux32/", $name, ".so"),
224 $crate::open_library_raw!("bin/linux32/lib", $name, ".so"),
225 $crate::open_library_raw!("bin/", $name, ".so"),
226 $crate::open_library_raw!("bin/lib", $name, ".so"),
227 $crate::open_library_raw!("garrysmod/bin/", $name, ".so"),
228 $crate::open_library_raw!("garrysmod/bin/lib", $name, ".so"),
229 $crate::open_library_raw!("bin/", $name, "_srv.so"),
230 $crate::open_library_raw!("bin/lib", $name, "_srv.so"),
231 $crate::open_library_raw!("garrysmod/bin/", $name, "_srv.so"),
232 $crate::open_library_raw!("garrysmod/bin/lib", $name, "_srv.so"),
233 $crate::open_library_raw!($name)
234 }
235 }
236
237 #[cfg(target_os = "macos")] {
238 $crate::__private__gmod_rs__try_chained_open! {
239 $crate::open_library_raw!("GarrysMod_Signed.app/Contents/MacOS/", $name, ".dylib"),
240 $crate::open_library_raw!("GarrysMod_Signed.app/Contents/MacOS/lib", $name, ".dylib"),
241 $crate::open_library_raw!("bin/", $name, ".dylib"),
242 $crate::open_library_raw!("bin/lib", $name, ".dylib"),
243 $crate::open_library_raw!("garrysmod/bin/", $name, ".dylib"),
244 $crate::open_library_raw!("garrysmod/bin/lib", $name, ".dylib"),
245 $crate::open_library_raw!("bin/", $name, "_srv.dylib"),
246 $crate::open_library_raw!("bin/lib", $name, "_srv.dylib"),
247 $crate::open_library_raw!("garrysmod/bin/", $name, "_srv.dylib"),
248 $crate::open_library_raw!("garrysmod/bin/lib", $name, "_srv.dylib"),
249 $crate::open_library_raw!($name)
250 }
251 }
252 }};
253}
254
255#[derive(Default)]
256#[doc(hidden)]
257pub struct OpenGmodLibraryErrs(pub std::collections::HashMap<&'static str, libloading::Error>);
258impl std::error::Error for OpenGmodLibraryErrs {}
259impl std::fmt::Display for OpenGmodLibraryErrs {
260 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
261 writeln!(f)?;
262 for (path, err) in &self.0 {
263 writeln!(f, "{} = {}", path, err)?;
264 }
265 writeln!(f)?;
266 Ok(())
267 }
268}
269impl std::fmt::Debug for OpenGmodLibraryErrs {
270 #[inline]
271 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272 std::fmt::Display::fmt(self, f)
273 }
274}
275
276#[doc(hidden)]
277#[macro_export]
278macro_rules! __private__gmod_rs__try_chained_open {
279 {$($expr:expr),+} => {
280 loop {
281 let mut errors = $crate::OpenGmodLibraryErrs::default();
282 $(
283 match $expr {
284 Ok(val) => break Ok(val),
285 Err((err, path)) => { errors.0.insert(path, err); }
286 }
287 )+
288 break Err(errors);
289 }
290 };
291}
292
293pub unsafe fn set_lua_state(state: *mut std::ffi::c_void) {
295 lua::__set_state__internal(lua::State(state));
296 lua::load();
297}