diff --git a/Facepunch.Steamworks/Generated/SteamApi.cs b/Facepunch.Steamworks/Generated/SteamApi.cs index 0e81fa3..537409a 100644 --- a/Facepunch.Steamworks/Generated/SteamApi.cs +++ b/Facepunch.Steamworks/Generated/SteamApi.cs @@ -1,42 +1,98 @@ -using System; -using System.Collections.Generic; +using System; using System.Runtime.InteropServices; using System.Text; +using System.Threading.Tasks; +using Steamworks.Data; -public static class SteamApi +namespace Steamworks { - [DllImport( "Steam_api64", EntryPoint = "SteamAPI_Init", CallingConvention = CallingConvention.Cdecl )] - [return: MarshalAs( UnmanagedType.U1 )] - public static extern bool SteamAPI_Init(); - - [DllImport( "Steam_api64", EntryPoint = "SteamAPI_Shutdown", CallingConvention = CallingConvention.Cdecl )] - [return: MarshalAs( UnmanagedType.U1 )] - public static extern bool SteamAPI_Shutdown(); - - [DllImport( "Steam_api64", EntryPoint = "SteamInternal_GameServer_Init", CallingConvention = CallingConvention.Cdecl )] - [return: MarshalAs( UnmanagedType.U1 )] - public static extern bool SteamInternal_GameServer_Init( uint unIP, ushort usSteamPort, ushort usGamePort, ushort usQueryPort, int eServerMode, string pchVersionString); - - [DllImport( "Steam_api64", EntryPoint = "SteamAPI_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )] - public static extern int GetHSteamUser(); - - [DllImport( "Steam_api64", EntryPoint = "SteamGameServer_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )] - public static extern int SteamGameServer_GetHSteamUser(); - - [DllImport( "Steam_api64", EntryPoint = "SteamAPI_RunCallbacks", CallingConvention = CallingConvention.Cdecl )] - public static extern int SteamAPI_RunCallbacks(); - - [DllImport( "Steam_api64", EntryPoint = "SteamGameServer_RunCallbacks", CallingConvention = CallingConvention.Cdecl )] - public static extern int SteamGameServer_RunCallbacks(); - - - [DllImport( "Steam_api64", EntryPoint = "SteamAPI_RegisterCallback", CallingConvention = CallingConvention.Cdecl )] - public static extern int RegisterCallback( IntPtr pCallback, int callback ); - - [DllImport( "Steam_api64", EntryPoint = "SteamAPI_UnregisterCallback", CallingConvention = CallingConvention.Cdecl )] - public static extern int UnregisterCallback( IntPtr pCallback ); - - - + internal static class SteamAPI + { + internal static class Win64 + { + [DllImport( "steam_api64", EntryPoint = "SteamAPI_Init", CallingConvention = CallingConvention.Cdecl )] + [return: MarshalAs( UnmanagedType.I1 )] + public static extern bool SteamAPI_Init(); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_RunCallbacks", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamAPI_RunCallbacks(); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_RegisterCallback", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamAPI_RegisterCallback( IntPtr pCallback, int callback ); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_UnregisterCallback", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamAPI_UnregisterCallback( IntPtr pCallback ); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_RegisterCallResult", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamAPI_RegisterCallResult( IntPtr pCallback, SteamAPICall_t callback ); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_UnregisterCallResult", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamAPI_UnregisterCallResult( IntPtr pCallback, SteamAPICall_t callback ); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_Shutdown", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamAPI_Shutdown(); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )] + public static extern HSteamUser SteamAPI_GetHSteamUser(); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_GetHSteamPipe", CallingConvention = CallingConvention.Cdecl )] + public static extern HSteamPipe SteamAPI_GetHSteamPipe(); + + [DllImport( "steam_api64", EntryPoint = "SteamAPI_RestartAppIfNecessary", CallingConvention = CallingConvention.Cdecl )] + [return: MarshalAs( UnmanagedType.I1 )] + public static extern bool SteamAPI_RestartAppIfNecessary( uint unOwnAppID ); + + } + static internal bool Init() + { + return Win64.SteamAPI_Init(); + } + + static internal void RunCallbacks() + { + Win64.SteamAPI_RunCallbacks(); + } + + static internal void RegisterCallback( IntPtr pCallback, int callback ) + { + Win64.SteamAPI_RegisterCallback( pCallback, callback ); + } + + static internal void UnregisterCallback( IntPtr pCallback ) + { + Win64.SteamAPI_UnregisterCallback( pCallback ); + } + + static internal void RegisterCallResult( IntPtr pCallback, SteamAPICall_t callback ) + { + Win64.SteamAPI_RegisterCallResult( pCallback, callback ); + } + + static internal void UnregisterCallResult( IntPtr pCallback, SteamAPICall_t callback ) + { + Win64.SteamAPI_UnregisterCallResult( pCallback, callback ); + } + + static internal void Shutdown() + { + Win64.SteamAPI_Shutdown(); + } + + static internal HSteamUser GetHSteamUser() + { + return Win64.SteamAPI_GetHSteamUser(); + } + + static internal HSteamPipe GetHSteamPipe() + { + return Win64.SteamAPI_GetHSteamPipe(); + } + + static internal bool RestartAppIfNecessary( uint unOwnAppID ) + { + return Win64.SteamAPI_RestartAppIfNecessary( unOwnAppID ); + } + + } } diff --git a/Facepunch.Steamworks/Generated/SteamGameServer.cs b/Facepunch.Steamworks/Generated/SteamGameServer.cs new file mode 100644 index 0000000..2e45cd8 --- /dev/null +++ b/Facepunch.Steamworks/Generated/SteamGameServer.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using Steamworks.Data; + + +namespace Steamworks +{ + internal static class SteamGameServer + { + internal static class Win64 + { + [DllImport( "steam_api64", EntryPoint = "SteamGameServer_RunCallbacks", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamGameServer_RunCallbacks(); + + [DllImport( "steam_api64", EntryPoint = "SteamGameServer_Shutdown", CallingConvention = CallingConvention.Cdecl )] + public static extern void SteamGameServer_Shutdown(); + + [DllImport( "steam_api64", EntryPoint = "SteamGameServer_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )] + public static extern HSteamUser SteamGameServer_GetHSteamUser(); + + [DllImport( "steam_api64", EntryPoint = "SteamGameServer_GetHSteamPipe", CallingConvention = CallingConvention.Cdecl )] + public static extern HSteamPipe SteamGameServer_GetHSteamPipe(); + + } + static internal void RunCallbacks() + { + Win64.SteamGameServer_RunCallbacks(); + } + + static internal void Shutdown() + { + Win64.SteamGameServer_Shutdown(); + } + + static internal HSteamUser GetHSteamUser() + { + return Win64.SteamGameServer_GetHSteamUser(); + } + + static internal HSteamPipe GetHSteamPipe() + { + return Win64.SteamGameServer_GetHSteamPipe(); + } + + } +} diff --git a/Facepunch.Steamworks/Generated/SteamInternal.cs b/Facepunch.Steamworks/Generated/SteamInternal.cs index e2024aa..459f692 100644 --- a/Facepunch.Steamworks/Generated/SteamInternal.cs +++ b/Facepunch.Steamworks/Generated/SteamInternal.cs @@ -1,15 +1,49 @@ -using System; -using System.Collections.Generic; +using System; using System.Runtime.InteropServices; using System.Text; +using System.Threading.Tasks; +using Steamworks.Data; -public static class SteamInternal +namespace Steamworks { - [DllImport( "Steam_api64", EntryPoint = "SteamInternal_FindOrCreateUserInterface", CallingConvention = CallingConvention.Cdecl )] - public static extern IntPtr FindOrCreateUserInterface( int hSteamUser, [MarshalAs( UnmanagedType.LPStr )] string pszVersion ); - - - [DllImport( "Steam_api64", EntryPoint = "SteamInternal_FindOrCreateGameServerInterface", CallingConvention = CallingConvention.Cdecl )] - public static extern IntPtr FindOrCreateGameServerInterface( int hSteamUser, [MarshalAs( UnmanagedType.LPStr )] string pszVersion ); + internal static class SteamInternal + { + internal static class Win64 + { + [DllImport( "steam_api64", EntryPoint = "SteamInternal_GameServer_Init", CallingConvention = CallingConvention.Cdecl )] + [return: MarshalAs( UnmanagedType.I1 )] + public static extern bool SteamInternal_GameServer_Init( uint unIP, ushort usPort, ushort usGamePort, ushort usQueryPort, int eServerMode, string pchVersionString ); + + [DllImport( "steam_api64", EntryPoint = "SteamInternal_FindOrCreateUserInterface", CallingConvention = CallingConvention.Cdecl )] + public static extern IntPtr SteamInternal_FindOrCreateUserInterface( int steamuser, string versionname ); + + [DllImport( "steam_api64", EntryPoint = "SteamInternal_FindOrCreateGameServerInterface", CallingConvention = CallingConvention.Cdecl )] + public static extern IntPtr SteamInternal_FindOrCreateGameServerInterface( int steamuser, string versionname ); + + [DllImport( "steam_api64", EntryPoint = "SteamInternal_CreateInterface", CallingConvention = CallingConvention.Cdecl )] + public static extern IntPtr SteamInternal_CreateInterface( string version ); + + } + static internal bool GameServer_Init( uint unIP, ushort usPort, ushort usGamePort, ushort usQueryPort, int eServerMode, string pchVersionString ) + { + return Win64.SteamInternal_GameServer_Init( unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString ); + } + + static internal IntPtr FindOrCreateUserInterface( int steamuser, string versionname ) + { + return Win64.SteamInternal_FindOrCreateUserInterface( steamuser, versionname ); + } + + static internal IntPtr FindOrCreateGameServerInterface( int steamuser, string versionname ) + { + return Win64.SteamInternal_FindOrCreateGameServerInterface( steamuser, versionname ); + } + + static internal IntPtr CreateInterface( string version ) + { + return Win64.SteamInternal_CreateInterface( version ); + } + + } } diff --git a/Facepunch.Steamworks/SteamClient.cs b/Facepunch.Steamworks/SteamClient.cs index f49849d..e2eb828 100644 --- a/Facepunch.Steamworks/SteamClient.cs +++ b/Facepunch.Steamworks/SteamClient.cs @@ -20,7 +20,7 @@ public static void Init( uint appid ) System.Environment.SetEnvironmentVariable( "SteamAppId", appid.ToString() ); System.Environment.SetEnvironmentVariable( "SteamGameId", appid.ToString() ); - if ( !SteamApi.SteamAPI_Init() ) + if ( !SteamAPI.Init() ) { throw new System.Exception( "SteamApi_Init returned false. Steam isn't running, couldn't find Steam, AppId is ureleased, Don't own AppId." ); } @@ -52,7 +52,7 @@ internal static async void RunCallbacksAsync() await Task.Delay( 16 ); try { - SteamApi.SteamAPI_RunCallbacks(); + SteamAPI.RunCallbacks(); } catch ( System.Exception ) { @@ -75,21 +75,23 @@ public static void Shutdown() SteamScreenshots.Shutdown(); SteamUserStats.Shutdown(); SteamInventory.Shutdown(); + + SteamAPI.Shutdown(); } internal static void RegisterCallback( IntPtr intPtr, int callbackId ) { - SteamApi.RegisterCallback( intPtr, callbackId ); + SteamAPI.RegisterCallback( intPtr, callbackId ); } public static void Update() { - SteamApi.SteamAPI_RunCallbacks(); + SteamAPI.RunCallbacks(); } internal static void UnregisterCallback( IntPtr intPtr ) { - SteamApi.UnregisterCallback( intPtr ); + SteamAPI.UnregisterCallback( intPtr ); } /// diff --git a/Facepunch.Steamworks/SteamServer.cs b/Facepunch.Steamworks/SteamServer.cs index 53c00b9..c52a6ac 100644 --- a/Facepunch.Steamworks/SteamServer.cs +++ b/Facepunch.Steamworks/SteamServer.cs @@ -53,7 +53,7 @@ public static void Init( AppId appid, SteamServerInit init ) // // Get other interfaces // - if ( !global::SteamApi.SteamInternal_GameServer_Init( ipaddress, init.SteamPort, init.GamePort, init.QueryPort, (int)( init.Secure ? 3 : 2 ), init.VersionString ) ) + if ( !SteamInternal.GameServer_Init( ipaddress, init.SteamPort, init.GamePort, init.QueryPort, (int)( init.Secure ? 3 : 2 ), init.VersionString ) ) { throw new System.Exception( "InitGameServer returned false" ); } @@ -83,6 +83,8 @@ public static void Shutdown() _internal = null; SteamServerInventory.Shutdown(); + + SteamGameServer.Shutdown(); } @@ -99,7 +101,7 @@ public static void Update() { try { - SteamApi.SteamGameServer_RunCallbacks(); + SteamGameServer.RunCallbacks(); } catch ( System.Exception ) { diff --git a/Facepunch.Steamworks/Utility/SteamInterface.cs b/Facepunch.Steamworks/Utility/SteamInterface.cs index 638ba59..8e88760 100644 --- a/Facepunch.Steamworks/Utility/SteamInterface.cs +++ b/Facepunch.Steamworks/Utility/SteamInterface.cs @@ -24,9 +24,9 @@ public SteamInterface( bool server = false ) // if ( !SteamClient.IsValid && SteamServer.IsValid ) server = true; - var hUser = server ? - SteamApi.SteamGameServer_GetHSteamUser() : - SteamApi.GetHSteamUser(); + var hUser = server ? + SteamGameServer.GetHSteamUser() : + SteamAPI.GetHSteamUser(); if ( hUser == 0 ) throw new System.Exception( "Steamworks is uninitialized" ); diff --git a/Generator/CodeWriter/CodeWriter.cs b/Generator/CodeWriter/CodeWriter.cs index 1828b27..40954b2 100644 --- a/Generator/CodeWriter/CodeWriter.cs +++ b/Generator/CodeWriter/CodeWriter.cs @@ -55,6 +55,12 @@ public void ToFolder( string folder ) System.IO.File.WriteAllText( $"{folder}SteamConstants.cs", sb.ToString() ); } + { + GenerateGlobalFunctions( "SteamAPI", $"{folder}../Generated/SteamAPI.cs" ); + GenerateGlobalFunctions( "SteamGameServer", $"{folder}../Generated/SteamGameServer.cs" ); + GenerateGlobalFunctions( "SteamInternal", $"{folder}../Generated/SteamInternal.cs" ); + } + { GenerateVTableClass( "ISteamApps", $"{folder}../Generated/Interfaces/ISteamApps.cs" ); GenerateVTableClass( "ISteamUtils", $"{folder}../Generated/Interfaces/ISteamUtils.cs" ); diff --git a/Generator/CodeWriter/GlobalFunctions.cs b/Generator/CodeWriter/GlobalFunctions.cs new file mode 100644 index 0000000..bd13cd1 --- /dev/null +++ b/Generator/CodeWriter/GlobalFunctions.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Generator +{ + public partial class CodeWriter + { + public void GenerateGlobalFunctions( string startingWith, string filename ) + { + var functions = def.methods.Where( x => x.Name.StartsWith( startingWith ) ); + + sb = new StringBuilder(); + + WriteLine( $"using System;" ); + WriteLine( $"using System.Runtime.InteropServices;" ); + WriteLine( $"using System.Text;" ); + WriteLine( $"using System.Threading.Tasks;" ); + WriteLine( $"using Steamworks.Data;" ); + WriteLine(); + + WriteLine(); + + StartBlock( $"namespace Steamworks" ); + { + StartBlock( $"internal static class {startingWith}" ); + { + StartBlock( $"internal static class Win64" ); + { + foreach ( var func in functions ) + { + WriteMarshalledFunction( func, "steam_api64" ); + } + } + EndBlock(); + + foreach ( var func in functions ) + { + WriteGlobalFunction( startingWith, func ); + WriteLine(); + } + + } + EndBlock(); + } + EndBlock(); + + System.IO.File.WriteAllText( $"{filename}", sb.ToString().Replace( "( )", "()" ) ); + } + + private void WriteGlobalFunction( string cname, SteamApiDefinition.MethodDef func ) + { + var cleanName = func.Name.Substring( cname.Length ).Trim( '_' ); + + var returnType = BaseType.Parse( func.ReturnType ); + returnType.Func = func.Name; + + if ( func.Params == null ) + func.Params = new SteamApiDefinition.MethodDef.ParamType[0]; + + var args = func.Params.Select( x => + { + var bt = BaseType.Parse( x.Type, x.Name ); + bt.Func = func.Name; + return bt; + } ).ToArray(); + var argstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); + var delegateargstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); + + if ( returnType.IsReturnedWeird ) + { + throw new System.Exception( "TODO" ); + } + + StartBlock( $"static internal {returnType.ReturnType} {cleanName}( {argstr} )" ); + { + var callargs = string.Join( ", ", args.Select( x => x.AsCallArgument() ) ); + + if ( returnType.IsReturnedWeird ) + { + WriteLine( $"var retVal = default( {returnType.TypeName} );" ); + WriteLine( $"Win64.{func.Name}( ref retVal, {callargs} );" ); + WriteLine( $"{returnType.Return( "retVal" )}" ); + } + else if ( returnType.IsVoid ) + { + WriteLine( $"Win64.{func.Name}( {callargs} );" ); + } + else + { + var v = $"Win64.{func.Name}( {callargs} )"; + + WriteLine( returnType.Return( v ) ); + } + } + EndBlock(); + + } + + private void WriteMarshalledFunction( SteamApiDefinition.MethodDef func, string dllName ) + { + var returnType = BaseType.Parse( func.ReturnType ); + returnType.Func = func.Name; + + if ( func.Params == null ) + func.Params = new SteamApiDefinition.MethodDef.ParamType[0]; + + var args = func.Params.Select( x => + { + var bt = BaseType.Parse( x.Type, x.Name ); + bt.Func = func.Name; + return bt; + } ).ToArray(); + var argstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); + var delegateargstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); + + WriteLine( $"[DllImport( \"{dllName}\", EntryPoint = \"{func.Name}\", CallingConvention = CallingConvention.Cdecl )]" ); + + if ( returnType.ReturnAttribute != null ) + WriteLine( returnType.ReturnAttribute ); + + WriteLine( $"public static extern {(returnType.IsReturnedWeird ? "void" : returnType.TypeNameFrom)} {func.Name}( {delegateargstr} );" ); + WriteLine(); + } + /* + + */ + + /* + var returnType = BaseType.Parse( func.ReturnType ); + returnType.Func = func.Name; + + var args = func.Arguments.Select( x => + { + var bt = BaseType.Parse( x.Value, x.Key ); + bt.Func = func.Name; + return bt; + } ).ToArray(); + var argstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); + var delegateargstr = string.Join( ", ", args.Select( x => x.AsArgument() ) ); + + if ( returnType.IsReturnedWeird ) + { + delegateargstr = $"ref {returnType.TypeName} retVal, {delegateargstr}"; + delegateargstr = delegateargstr.Trim( ',', ' ' ); + } + + if ( returnType is SteamApiCallType sap ) + { + sap.CallResult = func.CallResult; + } + + WriteLine( $"#region FunctionMeta" ); + + WriteLine( $"[UnmanagedFunctionPointer( CallingConvention.ThisCall )]" ); + + if ( returnType.ReturnAttribute != null) + WriteLine( returnType.ReturnAttribute ); + + WriteLine( $"private delegate {(returnType.IsReturnedWeird?"void":returnType.TypeNameFrom)} F{func.Name}( IntPtr self, {delegateargstr} );".Replace( "( IntPtr self, )", "( IntPtr self )" ) ); + WriteLine( $"private F{func.Name} _{func.Name};" ); + WriteLine(); + WriteLine( $"#endregion" ); + + StartBlock( $"internal {returnType.ReturnType} {func.Name}( {argstr} )".Replace( "( )", "()" ) ); + { + var callargs = string.Join( ", ", args.Select( x => x.AsCallArgument() ) ); + + if ( returnType.IsReturnedWeird ) + { + WriteLine( $"var retVal = default( {returnType.TypeName} );" ); + WriteLine( $"_{func.Name}( Self, ref retVal, {callargs} );".Replace( ", );", " );" ) ); + WriteLine( $"{returnType.Return( "retVal" )}" ); + } + else if ( returnType.IsVoid ) + { + WriteLine( $"_{func.Name}( Self, {callargs} );".Replace( "( Self, )", "( Self )" ) ); + } + else + { + var v = $"_{func.Name}( Self, {callargs} )".Replace( "( Self, )", "( Self )" ); + + WriteLine( returnType.Return( v ) ); + } + } + EndBlock(); + */ + + } +} diff --git a/Generator/Generator.csproj b/Generator/Generator.csproj index e1edf42..009fd46 100644 --- a/Generator/Generator.csproj +++ b/Generator/Generator.csproj @@ -50,6 +50,7 @@ + diff --git a/Generator/steam_api_missing.json b/Generator/steam_api_missing.json index 28ead23..cbb1b1e 100644 --- a/Generator/steam_api_missing.json +++ b/Generator/steam_api_missing.json @@ -305,6 +305,42 @@ } ] }, + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamInternal_FindOrCreateUserInterface", + "returntype": "void *", + "params": + [ + { + "paramname": "steamuser", + "paramtype": "int32" + }, + { + "paramname": "versionname", + "paramtype": "const char *" + } + ] + }, + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamInternal_FindOrCreateGameServerInterface", + "returntype": "void *", + "params": + [ + { + "paramname": "steamuser", + "paramtype": "int32" + }, + { + "paramname": "versionname", + "paramtype": "const char *" + } + ] + }, {