1+ using GmodNET . API ;
12using System ;
23using System . IO ;
34using System . Runtime . InteropServices ;
@@ -13,9 +14,103 @@ internal class GameConsoleWriter : TextWriter
1314 public override string NewLine => "\n " ;
1415 public override Encoding Encoding => Encoding . UTF8 ;
1516
16- #pragma warning disable CA2101
17- [ DllImport ( "tier0" , CallingConvention = CallingConvention . Cdecl ) ]
18- private static extern void Msg ( [ MarshalAs ( UnmanagedType . LPUTF8Str ) ] string msg ) ;
17+ public GameConsoleWriter ( ILua lua )
18+ {
19+ if ( OperatingSystem . IsWindows ( ) )
20+ {
21+ Msg = Msg_Tier0 ;
22+ }
23+ else if ( OperatingSystem . IsLinux ( ) )
24+ {
25+ lua . PushSpecial ( SPECIAL_TABLES . SPECIAL_GLOB ) ;
26+ lua . GetField ( - 1 , "game" ) ;
27+ lua . GetField ( - 1 , "IsDedicated" ) ;
28+ lua . MCall ( 0 , 1 ) ;
29+ bool is_dedicated = lua . GetBool ( - 1 ) ;
30+ lua . Pop ( 3 ) ;
31+
32+ if ( is_dedicated )
33+ {
34+ Msg = Msg_Tier0 ;
35+ }
36+ else
37+ {
38+ Msg = Msg_Tier0_Client ;
39+ }
40+ }
41+ else if ( OperatingSystem . IsMacOS ( ) )
42+ {
43+ unsafe
44+ {
45+ IntPtr lib_handle = NativeLibrary . Load ( Directory . GetCurrentDirectory ( ) + "/GarrysMod_Signed.app/Contents/MacOS/libtier0.dylib" ) ;
46+ delegate * unmanaged[ Cdecl] < byte * , void > msg_func = ( delegate * unmanaged[ Cdecl] < byte * , void > ) NativeLibrary . GetExport ( lib_handle , "Msg" ) ;
47+
48+ Msg = ( message ) =>
49+ {
50+ byte * __message_gen_native = default ;
51+ //
52+ // Setup
53+ //
54+ bool message__allocated = false ;
55+ try
56+ {
57+ //
58+ // Marshal
59+ //
60+ if ( message != null )
61+ {
62+ int message__bytelen = ( message . Length + 1 ) * 3 + 1 ;
63+ if ( message__bytelen > 260 )
64+ {
65+ __message_gen_native = ( byte * ) System . Runtime . InteropServices . Marshal . StringToCoTaskMemUTF8 ( message ) ;
66+ message__allocated = true ;
67+ }
68+ else
69+ {
70+ byte * path__stackptr = stackalloc byte [ message__bytelen ] ;
71+ {
72+ message__bytelen = System . Text . Encoding . UTF8 . GetBytes ( message , new System . Span < byte > ( path__stackptr , message__bytelen ) ) ;
73+ path__stackptr [ message__bytelen ] = 0 ;
74+ }
75+
76+ __message_gen_native = ( byte * ) path__stackptr ;
77+ }
78+ }
79+
80+ //
81+ // Invoke
82+ //
83+ msg_func ( __message_gen_native ) ;
84+ }
85+ finally
86+ {
87+ //
88+ // Cleanup
89+ //
90+ if ( message__allocated )
91+ {
92+ System . Runtime . InteropServices . Marshal . FreeCoTaskMem ( ( System . IntPtr ) __message_gen_native ) ;
93+ }
94+ }
95+ } ;
96+ }
97+ }
98+ else Msg = ( string msg ) => throw new PlatformNotSupportedException ( ) ;
99+ }
100+
101+ #pragma warning disable CA2101 // workaround for https://github.com/dotnet/roslyn-analyzers/issues/5009
102+
103+ [ DllImport ( "tier0" , EntryPoint = "Msg" , CallingConvention = CallingConvention . Cdecl ) ]
104+ private static extern void Msg_Tier0 ( [ MarshalAs ( UnmanagedType . LPUTF8Str ) ] string msg ) ;
105+
106+ [ DllImport ( "tier0_client" , EntryPoint = "Msg" , CallingConvention = CallingConvention . Cdecl ) ]
107+ private static extern void Msg_Tier0_Client ( [ MarshalAs ( UnmanagedType . LPUTF8Str ) ] string msg ) ;
108+
109+ #pragma warning restore CA2101
110+
111+ private delegate void MsgFunc ( string str ) ;
112+
113+ private static MsgFunc Msg ;
19114
20115 public override void Write ( string value )
21116 {
0 commit comments