2016-10-25 12:29:35 +03:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Generator
|
|
|
|
|
{
|
2016-10-25 18:11:29 +03:00
|
|
|
|
public partial class CodeWriter
|
2016-10-25 12:29:35 +03:00
|
|
|
|
{
|
2016-10-29 15:02:36 +03:00
|
|
|
|
public class TypeDef
|
|
|
|
|
{
|
|
|
|
|
public string Name;
|
|
|
|
|
public string NativeType;
|
|
|
|
|
public string ManagedType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Dictionary<string, TypeDef> TypeDefs = new Dictionary<string, TypeDef>();
|
|
|
|
|
|
2016-10-29 14:49:36 +03:00
|
|
|
|
//
|
|
|
|
|
// Don't give a fuck about these classes, they just cause us trouble
|
|
|
|
|
//
|
|
|
|
|
public readonly static string[] SkipStructs = new string[]
|
|
|
|
|
{
|
|
|
|
|
"CSteamID",
|
|
|
|
|
"CSteamAPIContext",
|
|
|
|
|
"CCallResult",
|
|
|
|
|
"CCallback",
|
2016-10-30 23:52:42 +03:00
|
|
|
|
"ValvePackingSentinel_t",
|
2019-04-11 18:37:51 +03:00
|
|
|
|
"CCallbackBase",
|
|
|
|
|
"CSteamGameServerAPIContext"
|
|
|
|
|
};
|
2016-10-29 14:49:36 +03:00
|
|
|
|
|
2017-05-16 18:35:37 +03:00
|
|
|
|
public readonly static string[] ForceLargePackStructs = new string[]
|
|
|
|
|
{
|
|
|
|
|
"LeaderboardEntry_t"
|
|
|
|
|
};
|
|
|
|
|
|
2016-10-25 12:29:35 +03:00
|
|
|
|
void Structs()
|
|
|
|
|
{
|
2018-02-14 20:40:16 +03:00
|
|
|
|
var callbackList = new List<SteamApiDefinition.StructDef>();
|
|
|
|
|
|
2016-10-25 12:29:35 +03:00
|
|
|
|
foreach ( var c in def.structs )
|
|
|
|
|
{
|
2019-04-16 13:45:44 +03:00
|
|
|
|
var name = Cleanup.ConvertType( c.Name );
|
|
|
|
|
|
|
|
|
|
if ( SkipStructs.Contains( c.Name ) )
|
2016-10-25 12:29:35 +03:00
|
|
|
|
continue;
|
|
|
|
|
|
2019-04-16 13:45:44 +03:00
|
|
|
|
if ( !Cleanup.ShouldCreate( name ) )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if ( name.Contains( "::" ) )
|
2016-10-25 12:29:35 +03:00
|
|
|
|
continue;
|
|
|
|
|
|
2019-05-08 11:49:32 +03:00
|
|
|
|
int defaultPack = c.IsPack4OnWindows ? 4 : 8;
|
2016-10-25 12:29:35 +03:00
|
|
|
|
|
2019-04-13 20:45:09 +03:00
|
|
|
|
var isCallback = !string.IsNullOrEmpty( c.CallbackId );
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Main struct
|
|
|
|
|
//
|
2019-06-25 13:20:39 +03:00
|
|
|
|
WriteLine( $"[StructLayout( LayoutKind.Sequential, Pack = Platform.{(c.IsPack4OnWindows?"StructPackSize": "StructPlatformPackSize")} )]" );
|
2019-04-30 18:43:27 +03:00
|
|
|
|
StartBlock( $"{Cleanup.Expose( name )} struct {name}" );
|
2016-10-25 12:29:35 +03:00
|
|
|
|
{
|
2019-04-14 00:56:06 +03:00
|
|
|
|
//
|
|
|
|
|
// The fields
|
|
|
|
|
//
|
|
|
|
|
StructFields( c.Fields );
|
|
|
|
|
WriteLine();
|
2019-04-13 20:45:09 +03:00
|
|
|
|
|
2019-04-14 00:56:06 +03:00
|
|
|
|
if ( isCallback )
|
|
|
|
|
{
|
2019-04-30 18:43:27 +03:00
|
|
|
|
WriteLine( "#region SteamCallback" );
|
2019-04-13 20:45:09 +03:00
|
|
|
|
{
|
2019-06-25 13:20:39 +03:00
|
|
|
|
|
|
|
|
|
WriteLine( $"internal static readonly int StructSize = System.Runtime.InteropServices.Marshal.SizeOf( typeof({name}) );" );
|
|
|
|
|
WriteLine( $"internal static {name} Fill( IntPtr p ) => (({name})({name}) Marshal.PtrToStructure( p, typeof({name}) ) );" );
|
2019-04-30 18:43:27 +03:00
|
|
|
|
WriteLine();
|
2019-04-30 17:42:10 +03:00
|
|
|
|
WriteLine( $"static Action<{name}> actionClient;" );
|
2019-04-30 18:43:27 +03:00
|
|
|
|
WriteLine( $"[MonoPInvokeCallback] static void OnClient( IntPtr thisptr, IntPtr pvParam ) => actionClient?.Invoke( Fill( pvParam ) );" );
|
2019-04-30 17:42:10 +03:00
|
|
|
|
|
|
|
|
|
WriteLine( $"static Action<{name}> actionServer;" );
|
2019-04-30 18:43:27 +03:00
|
|
|
|
WriteLine( $"[MonoPInvokeCallback] static void OnServer( IntPtr thisptr, IntPtr pvParam ) => actionServer?.Invoke( Fill( pvParam ) );" );
|
2019-04-30 17:42:10 +03:00
|
|
|
|
|
|
|
|
|
StartBlock( $"public static void Install( Action<{name}> action, bool server = false )" );
|
|
|
|
|
{
|
|
|
|
|
StartBlock( "if ( server )" );
|
|
|
|
|
{
|
2019-04-30 18:43:27 +03:00
|
|
|
|
WriteLine( $"Event.Register( OnServer, StructSize, {c.CallbackId}, true );" );
|
2019-04-30 17:42:10 +03:00
|
|
|
|
WriteLine( $"actionServer = action;" );
|
|
|
|
|
}
|
|
|
|
|
Else();
|
|
|
|
|
{
|
2019-04-30 18:43:27 +03:00
|
|
|
|
WriteLine( $"Event.Register( OnClient, StructSize, {c.CallbackId}, false );" );
|
2019-04-30 17:42:10 +03:00
|
|
|
|
WriteLine( $"actionClient = action;" );
|
|
|
|
|
}
|
|
|
|
|
EndBlock();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
EndBlock();
|
2019-04-30 18:43:27 +03:00
|
|
|
|
|
|
|
|
|
StartBlock( $"public static async Task<{name}?> GetResultAsync( SteamAPICall_t handle )" );
|
|
|
|
|
{
|
|
|
|
|
WriteLine( $"bool failed = false;" );
|
|
|
|
|
WriteLine();
|
|
|
|
|
StartBlock( $"while ( !SteamUtils.IsCallComplete( handle, out failed ) )" );
|
|
|
|
|
{
|
|
|
|
|
WriteLine( $"await Task.Delay( 1 );" );
|
2019-05-13 15:13:12 +03:00
|
|
|
|
WriteLine( $"if ( !SteamClient.IsValid && !SteamServer.IsValid ) return null;" );
|
2019-04-30 18:43:27 +03:00
|
|
|
|
}
|
|
|
|
|
EndBlock();
|
|
|
|
|
|
|
|
|
|
WriteLine( $"if ( failed ) return null;" );
|
|
|
|
|
WriteLine( $"" );
|
|
|
|
|
WriteLine( $"var ptr = Marshal.AllocHGlobal( StructSize );" );
|
|
|
|
|
WriteLine( $"" );
|
|
|
|
|
WriteLine( $"try" );
|
|
|
|
|
WriteLine( $"{{" );
|
|
|
|
|
WriteLine( $" if ( !SteamUtils.Internal.GetAPICallResult( handle, ptr, StructSize, {c.CallbackId}, ref failed ) || failed )" );
|
|
|
|
|
WriteLine( $" return null;" );
|
|
|
|
|
WriteLine( $"" );
|
|
|
|
|
WriteLine( $" return Fill( ptr );" );
|
|
|
|
|
WriteLine( $"}}" );
|
|
|
|
|
WriteLine( $"finally" );
|
|
|
|
|
WriteLine( $"{{" );
|
|
|
|
|
WriteLine( $" Marshal.FreeHGlobal( ptr );" );
|
|
|
|
|
WriteLine( $"}}" );
|
|
|
|
|
}
|
|
|
|
|
EndBlock();
|
2019-04-13 20:45:09 +03:00
|
|
|
|
}
|
2019-04-14 00:56:06 +03:00
|
|
|
|
WriteLine( "#endregion" );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
WriteLine( "#region Marshalling" );
|
|
|
|
|
{
|
2019-06-25 13:20:39 +03:00
|
|
|
|
WriteLine( $"internal static {name} Fill( IntPtr p ) => (({name})({name}) Marshal.PtrToStructure( p, typeof({name}) ) );" );
|
2019-04-13 20:45:09 +03:00
|
|
|
|
}
|
2019-04-30 16:56:59 +03:00
|
|
|
|
WriteLine( "#endregion" );
|
2019-04-13 20:45:09 +03:00
|
|
|
|
}
|
2017-05-08 22:51:57 +03:00
|
|
|
|
|
|
|
|
|
if ( !string.IsNullOrEmpty( c.CallbackId ) )
|
2016-10-30 23:52:42 +03:00
|
|
|
|
{
|
2018-02-14 20:40:16 +03:00
|
|
|
|
callbackList.Add( c );
|
2016-10-30 23:52:42 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-29 14:49:36 +03:00
|
|
|
|
}
|
2016-10-25 12:29:35 +03:00
|
|
|
|
EndBlock();
|
|
|
|
|
WriteLine();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StructFields( SteamApiDefinition.StructDef.StructFields[] fields )
|
|
|
|
|
{
|
|
|
|
|
foreach ( var m in fields )
|
|
|
|
|
{
|
|
|
|
|
var t = ToManagedType( m.Type );
|
|
|
|
|
|
2019-04-16 13:45:44 +03:00
|
|
|
|
t = Cleanup.ConvertType( t );
|
|
|
|
|
|
|
|
|
|
if ( TypeDefs.ContainsKey( t ) )
|
2016-10-25 12:29:35 +03:00
|
|
|
|
{
|
|
|
|
|
t = TypeDefs[t].ManagedType;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-25 13:51:24 +03:00
|
|
|
|
if ( t == "bool" )
|
|
|
|
|
{
|
|
|
|
|
WriteLine( "[MarshalAs(UnmanagedType.I1)]" );
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-25 12:29:35 +03:00
|
|
|
|
if ( t.StartsWith( "char " ) && t.Contains( "[" ) )
|
|
|
|
|
{
|
2019-06-20 15:10:28 +03:00
|
|
|
|
WriteLine( $"internal string {CleanMemberName( m.Name )}UTF8() => System.Text.Encoding.UTF8.GetString( {CleanMemberName( m.Name )}, 0, System.Array.IndexOf<byte>( {CleanMemberName( m.Name )}, 0 ) );" );
|
|
|
|
|
|
2019-04-13 20:45:09 +03:00
|
|
|
|
var num = t.Replace( "char", "" ).Trim( '[', ']', ' ' );
|
2019-06-20 15:10:28 +03:00
|
|
|
|
t = "byte[]";
|
|
|
|
|
WriteLine( $"[MarshalAs(UnmanagedType.ByValArray, SizeConst = {num})] // {t} {m.Name}" );
|
2016-10-25 12:29:35 +03:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-26 18:10:20 +03:00
|
|
|
|
if ( t.StartsWith( "uint8 " ) && t.Contains( "[" ) )
|
|
|
|
|
{
|
|
|
|
|
var num = t.Replace( "uint8", "" ).Trim( '[', ']', ' ' );
|
2019-04-13 20:45:09 +03:00
|
|
|
|
t = "byte[]";
|
|
|
|
|
WriteLine( $"[MarshalAs(UnmanagedType.ByValArray, SizeConst = {num})] // {m.Name}" );
|
2016-10-26 18:10:20 +03:00
|
|
|
|
}
|
|
|
|
|
|
2019-04-16 13:45:44 +03:00
|
|
|
|
if ( t.StartsWith( "SteamId" ) && t.Contains( "[" ) )
|
2016-10-25 12:29:35 +03:00
|
|
|
|
{
|
2019-04-16 13:45:44 +03:00
|
|
|
|
var num = t.Replace( "SteamId", "" ).Trim( '[', ']', ' ' );
|
2016-10-25 12:29:35 +03:00
|
|
|
|
t = $"ulong[]";
|
|
|
|
|
WriteLine( $"[MarshalAs(UnmanagedType.ByValArray, SizeConst = {num}, ArraySubType = UnmanagedType.U8)]" );
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-16 18:37:49 +03:00
|
|
|
|
if ( t.StartsWith( "PublishedFileId " ) && t.Contains( "[" ) )
|
2016-10-25 12:29:35 +03:00
|
|
|
|
{
|
2019-04-16 18:37:49 +03:00
|
|
|
|
var num = t.Replace( "PublishedFileId", "" ).Trim( '[', ']', ' ' );
|
|
|
|
|
t = $"PublishedFileId[]";
|
2016-10-25 12:29:35 +03:00
|
|
|
|
WriteLine( $"[MarshalAs(UnmanagedType.ByValArray, SizeConst = {num}, ArraySubType = UnmanagedType.U8)]" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( t.StartsWith( "uint32 " ) && t.Contains( "[" ) )
|
|
|
|
|
{
|
|
|
|
|
var num = t.Replace( "uint32", "" ).Trim( '[', ']', ' ' );
|
|
|
|
|
t = $"uint[]";
|
2018-01-23 14:02:36 +03:00
|
|
|
|
WriteLine( $"[MarshalAs(UnmanagedType.ByValArray, SizeConst = {num}, ArraySubType = UnmanagedType.U4)]" );
|
2016-10-25 12:29:35 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( t.StartsWith( "float " ) && t.Contains( "[" ) )
|
|
|
|
|
{
|
|
|
|
|
var num = t.Replace( "float", "" ).Trim( '[', ']', ' ' );
|
|
|
|
|
t = $"float[]";
|
|
|
|
|
WriteLine( $"[MarshalAs(UnmanagedType.ByValArray, SizeConst = {num}, ArraySubType = UnmanagedType.R4)]" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( t == "const char **" )
|
|
|
|
|
{
|
|
|
|
|
t = "IntPtr";
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-26 16:29:36 +03:00
|
|
|
|
if (t.StartsWith("AppId ") && t.Contains("["))
|
2018-01-23 14:00:14 +03:00
|
|
|
|
{
|
2019-04-26 16:29:36 +03:00
|
|
|
|
var num = t.Replace("AppId", "").Trim('[', ']', ' ');
|
|
|
|
|
t = $"AppId[]";
|
2018-01-23 14:00:14 +03:00
|
|
|
|
WriteLine($"[MarshalAs(UnmanagedType.ByValArray, SizeConst = {num}, ArraySubType = UnmanagedType.U4)]");
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-14 17:15:02 +03:00
|
|
|
|
WriteLine( $"internal {t} {CleanMemberName( m.Name )}; // {m.Name} {m.Type}" );
|
2016-10-25 12:29:35 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|