IL2CPP works again

This commit is contained in:
Garry Newman 2019-04-30 15:42:10 +01:00
parent ff48493ceb
commit 86e4576baf
18 changed files with 3333 additions and 162 deletions

View File

@ -1,50 +0,0 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using Steamworks.Data;
namespace Steamworks
{
internal partial class Callback
{
internal static class VTable
{
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void Run( IntPtr thisptr, IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void RunCall( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate int GetCallbackSizeBytes( IntPtr thisptr );
internal static IntPtr GetVTable( Run run, RunCall runInfo, GetCallbackSizeBytes size, List<GCHandle> allocations )
{
allocations.Add( GCHandle.Alloc( run ) );
allocations.Add( GCHandle.Alloc( runInfo ) );
allocations.Add( GCHandle.Alloc( size ) );
var a = Marshal.GetFunctionPointerForDelegate<Run>( run );
var b = Marshal.GetFunctionPointerForDelegate<RunCall>( runInfo );
var c = Marshal.GetFunctionPointerForDelegate<GetCallbackSizeBytes>( size );
var vt = Marshal.AllocHGlobal( IntPtr.Size * 3 );
if ( Config.Os == OsType.Windows )
{
Marshal.WriteIntPtr( vt, IntPtr.Size * 0, b );
Marshal.WriteIntPtr( vt, IntPtr.Size * 1, a );
Marshal.WriteIntPtr( vt, IntPtr.Size * 2, c );
}
else
{
Marshal.WriteIntPtr( vt, IntPtr.Size * 0, a );
Marshal.WriteIntPtr( vt, IntPtr.Size * 1, b );
Marshal.WriteIntPtr( vt, IntPtr.Size * 2, c );
}
return vt;
}
}
};
}

View File

@ -1,13 +1,23 @@
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using Steamworks.Data;
namespace Steamworks
{
[StructLayout( LayoutKind.Sequential )]
internal partial class Callback
{
internal enum Flags : byte
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void Run( IntPtr thisptr, IntPtr pvParam );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void RunCall( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall );
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate int GetCallbackSizeBytes( IntPtr thisptr );
internal enum Flags : byte
{
Registered = 0x01,
GameServer = 0x02
@ -16,5 +26,18 @@ namespace Steamworks
public IntPtr vTablePtr;
public byte CallbackFlags;
public int CallbackId;
};
//
// These are functions that are on CCallback but are never called
// We could just send a IntPtr.Zero but it's probably safer to throw a
// big apeshit message if steam changes its behaviour at some point
//
[MonoPInvokeCallback]
internal static void RunStub( IntPtr self, IntPtr param, bool failure, SteamAPICall_t call ) =>
throw new System.Exception( "Something changed in the Steam API and now CCallbackBack is calling the CallResult function [Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall )]" );
[MonoPInvokeCallback]
internal static int SizeStub( IntPtr self ) =>
throw new System.Exception( "Something changed in the Steam API and now CCallbackBack is calling the GetSize function [GetCallbackSizeBytes()]" );
};
}

View File

@ -1,13 +1,14 @@
using System;
using Steamworks.Data;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Steamworks.Data;
namespace Steamworks
{
internal static class Events
//
// Created on registration of a callback
//
internal class Event : IDisposable
{
internal static List<IDisposable> AllClient = new List<IDisposable>();
internal static List<IDisposable> AllServer = new List<IDisposable>();
@ -31,21 +32,75 @@ namespace Steamworks
AllServer.Clear();
}
}
//
// Created on registration of a callback
//
internal class Event : IDisposable
{
Steamworks.ISteamCallback template;
public Action<Steamworks.ISteamCallback> Action;
internal static void Register( Callback.Run func, int size, int callbackId, bool gameserver )
{
var r = new Event();
r.vTablePtr = BuildVTable( func, r.Allocations );
//
// Create the callback object
//
var cb = new Callback();
cb.vTablePtr = r.vTablePtr;
cb.CallbackFlags = gameserver ? (byte)0x02 : (byte)0;
cb.CallbackId = callbackId;
//
// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native
//
r.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );
//
// Register the callback with Steam
//
SteamClient.RegisterCallback( r.PinnedCallback.AddrOfPinnedObject(), cb.CallbackId );
r.IsAllocated = true;
if ( gameserver )
Event.AllServer.Add( r );
else
Event.AllClient.Add( r );
}
static IntPtr BuildVTable( Callback.Run run, List<GCHandle> allocations )
{
var RunStub = (Callback.RunCall)Callback.RunStub;
var SizeStub = (Callback.GetCallbackSizeBytes)Callback.SizeStub;
allocations.Add( GCHandle.Alloc( run ) );
allocations.Add( GCHandle.Alloc( RunStub ) );
allocations.Add( GCHandle.Alloc( SizeStub ) );
var a = Marshal.GetFunctionPointerForDelegate<Callback.Run>( run );
var b = Marshal.GetFunctionPointerForDelegate<Callback.RunCall>( RunStub );
var c = Marshal.GetFunctionPointerForDelegate<Callback.GetCallbackSizeBytes>( SizeStub );
var vt = Marshal.AllocHGlobal( IntPtr.Size * 3 );
if ( Config.Os == OsType.Windows )
{
Marshal.WriteIntPtr( vt, IntPtr.Size * 0, b );
Marshal.WriteIntPtr( vt, IntPtr.Size * 1, a );
Marshal.WriteIntPtr( vt, IntPtr.Size * 2, c );
}
else
{
Marshal.WriteIntPtr( vt, IntPtr.Size * 0, a );
Marshal.WriteIntPtr( vt, IntPtr.Size * 1, b );
Marshal.WriteIntPtr( vt, IntPtr.Size * 2, c );
}
return vt;
}
bool IsAllocated;
List<GCHandle> Allocations = new List<GCHandle>();
internal IntPtr vTablePtr;
internal GCHandle PinnedCallback;
public void Dispose()
{
if ( !IsAllocated ) return;
@ -78,62 +133,5 @@ namespace Steamworks
Dispose();
}
public virtual bool IsValid { get { return true; } }
internal static Event CreateEvent<T>( Action<T> onresult, bool gameserver = false ) where T: struct, Steamworks.ISteamCallback
{
var r = new Event();
r.Action = ( x ) => onresult( (T) x );
r.template = new T();
r.vTablePtr = Callback.VTable.GetVTable( r.OnResult, RunStub, SizeStub, r.Allocations );
//
// Create the callback object
//
var cb = new Callback();
cb.vTablePtr = r.vTablePtr;
cb.CallbackFlags = gameserver ? (byte)0x02 : (byte)0;
cb.CallbackId = r.template.GetCallbackId();
//
// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native
//
r.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );
//
// Register the callback with Steam
//
SteamClient.RegisterCallback( r.PinnedCallback.AddrOfPinnedObject(), cb.CallbackId );
r.IsAllocated = true;
if ( gameserver )
Events.AllServer.Add( r );
else
Events.AllClient.Add( r );
return r;
}
[MonoPInvokeCallback]
internal void OnResult( IntPtr self, IntPtr param )
{
var value = template.Fill( param );
Action( value );
}
[MonoPInvokeCallback]
static void RunStub( IntPtr self, IntPtr param, bool failure, SteamAPICall_t call )
{
throw new System.Exception( "Something changed in the Steam API and now CCallbackBack is calling the CallResult function [Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall )]" );
}
[MonoPInvokeCallback]
static int SizeStub( IntPtr self )
{
throw new System.Exception( "Something changed in the Steam API and now CCallbackBack is calling the GetSize function [GetCallbackSizeBytes()]" );
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -32,8 +32,8 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<DlcInstalled_t>( x => OnDlcInstalled?.Invoke( x.AppID ) );
Event.CreateEvent<NewUrlLaunchParameters_t>( x => OnNewLaunchParameters?.Invoke() );
DlcInstalled_t.Install( x => OnDlcInstalled?.Invoke( x.AppID ) );
NewUrlLaunchParameters_t.Install( x => OnNewLaunchParameters?.Invoke() );
}
/// <summary>

View File

@ -64,7 +64,7 @@ namespace Steamworks
public static void Shutdown()
{
Events.DisposeAllClient();
Event.DisposeAllClient();
initialized = false;

View File

@ -36,13 +36,13 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<FriendStateChange_t>( x => OnPersonaStateChange?.Invoke( new Friend( x.SteamID ) ) );
Event.CreateEvent<GameRichPresenceJoinRequested_t>( x => OnGameRichPresenceJoinRequested?.Invoke( new Friend( x.SteamIDFriend), x.Connect ) );
Event.CreateEvent<GameConnectedFriendChatMsg_t>( OnFriendChatMessage );
Event.CreateEvent<GameOverlayActivated_t>( x => OnGameOverlayActivated?.Invoke() );
Event.CreateEvent<GameServerChangeRequested_t>( x => OnGameServerChangeRequested?.Invoke( x.Server, x.Password ) );
Event.CreateEvent<GameLobbyJoinRequested_t>( x => OnGameLobbyJoinRequested?.Invoke( x.SteamIDLobby, x.SteamIDFriend ) );
Event.CreateEvent<FriendRichPresenceUpdate_t>( x => OnFriendRichPresenceUpdate?.Invoke( new Friend( x.SteamIDFriend ) ) );
FriendStateChange_t.Install( x => OnPersonaStateChange?.Invoke( new Friend( x.SteamID ) ) );
GameRichPresenceJoinRequested_t.Install( x => OnGameRichPresenceJoinRequested?.Invoke( new Friend( x.SteamIDFriend), x.Connect ) );
GameConnectedFriendChatMsg_t.Install( OnFriendChatMessage );
GameOverlayActivated_t.Install( x => OnGameOverlayActivated?.Invoke() );
GameServerChangeRequested_t.Install( x => OnGameServerChangeRequested?.Invoke( x.Server, x.Password ) );
GameLobbyJoinRequested_t.Install( x => OnGameLobbyJoinRequested?.Invoke( x.SteamIDLobby, x.SteamIDFriend ) );
FriendRichPresenceUpdate_t.Install( x => OnFriendRichPresenceUpdate?.Invoke( new Friend( x.SteamIDFriend ) ) );
}
/// <summary>

View File

@ -32,8 +32,8 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<SteamInventoryFullUpdate_t>( x => OnInventoryUpdated?.Invoke( x.Handle ) );
Event.CreateEvent<SteamInventoryDefinitionUpdate_t>( x => DefinitionsUpdated() );
SteamInventoryFullUpdate_t.Install( x => OnInventoryUpdated?.Invoke( x.Handle ) );
SteamInventoryDefinitionUpdate_t.Install( x => DefinitionsUpdated() );
}
public static event Action<int> OnInventoryUpdated;

View File

@ -30,8 +30,8 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<PlaybackStatusHasChanged_t>( x => OnPlaybackChanged?.Invoke() );
Event.CreateEvent<VolumeHasChanged_t>( x => OnVolumeChanged?.Invoke( x.NewVolume ) );
PlaybackStatusHasChanged_t.Install( x => OnPlaybackChanged?.Invoke() );
VolumeHasChanged_t.Install( x => OnVolumeChanged?.Invoke( x.NewVolume ) );
}
/// <summary>

View File

@ -30,7 +30,7 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<SteamParentalSettingsChanged_t>( x => OnSettingsChanged?.Invoke() );
SteamParentalSettingsChanged_t.Install( x => OnSettingsChanged?.Invoke() );
}
/// <summary>

View File

@ -30,8 +30,8 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<ScreenshotRequested_t>( x => OnScreenshotRequested?.Invoke() );
Event.CreateEvent<ScreenshotReady_t>( x =>
ScreenshotRequested_t.Install( x => OnScreenshotRequested?.Invoke() );
ScreenshotReady_t.Install( x =>
{
if ( x.Result != Result.OK )
OnScreenshotFailed?.Invoke( x.Result );

View File

@ -30,7 +30,7 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<ValidateAuthTicketResponse_t>( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ), true );
ValidateAuthTicketResponse_t.Install( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ), true );
SteamServerInventory.InstallEvents();
}
@ -78,7 +78,7 @@ namespace Steamworks
public static void Shutdown()
{
Events.DisposeAllServer();
Event.DisposeAllServer();
initialized = false;

View File

@ -29,7 +29,7 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<SteamInventoryDefinitionUpdate_t>( x => DefinitionsUpdated(), true );
SteamInventoryDefinitionUpdate_t.Install( x => DefinitionsUpdated(), true );
}
public static event Action OnDefinitionsUpdated;

View File

@ -40,14 +40,14 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<SteamServersConnected_t>( x => OnSteamServersConnected?.Invoke() );
Event.CreateEvent<SteamServerConnectFailure_t>( x => OnSteamServerConnectFailure?.Invoke() );
Event.CreateEvent<SteamServersDisconnected_t>( x => OnSteamServersDisconnected?.Invoke() );
Event.CreateEvent<ClientGameServerDeny_t>( x => OnClientGameServerDeny?.Invoke() );
Event.CreateEvent<LicensesUpdated_t>( x => OnLicensesUpdated?.Invoke() );
Event.CreateEvent<ValidateAuthTicketResponse_t>( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ) );
Event.CreateEvent<MicroTxnAuthorizationResponse_t>( x => OnMicroTxnAuthorizationResponse?.Invoke( x.AppID, x.OrderID, x.Authorized != 0 ) );
Event.CreateEvent<GameWebCallback_t>( x => OnGameWebCallback?.Invoke( x.URL ) );
SteamServersConnected_t.Install( x => OnSteamServersConnected?.Invoke() );
SteamServerConnectFailure_t.Install( x => OnSteamServerConnectFailure?.Invoke() );
SteamServersDisconnected_t.Install( x => OnSteamServersDisconnected?.Invoke() );
ClientGameServerDeny_t.Install( x => OnClientGameServerDeny?.Invoke() );
LicensesUpdated_t.Install( x => OnLicensesUpdated?.Invoke() );
ValidateAuthTicketResponse_t.Install( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ) );
MicroTxnAuthorizationResponse_t.Install( x => OnMicroTxnAuthorizationResponse?.Invoke( x.AppID, x.OrderID, x.Authorized != 0 ) );
GameWebCallback_t.Install( x => OnGameWebCallback?.Invoke( x.URL ) );
}
/// <summary>

View File

@ -32,7 +32,7 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<UserStatsReceived_t>( x =>
UserStatsReceived_t.Install( x =>
{
if ( x.SteamIDUser == SteamClient.SteamId )
StatsRecieved = true;
@ -40,9 +40,9 @@ namespace Steamworks
OnUserStatsReceived?.Invoke( x.SteamIDUser, x.Result );
} );
Event.CreateEvent<UserStatsStored_t>( x => OnUserStatsStored?.Invoke( x.Result ) );
Event.CreateEvent<UserAchievementStored_t>( x => OnAchievementProgress?.Invoke( x.AchievementName, (int) x.CurProgress, (int)x.MaxProgress ) );
Event.CreateEvent<UserStatsUnloaded_t>( x => OnUserStatsUnloaded?.Invoke( x.SteamIDUser ) );
UserStatsStored_t.Install( x => OnUserStatsStored?.Invoke( x.Result ) );
UserAchievementStored_t.Install( x => OnAchievementProgress?.Invoke( x.AchievementName, (int) x.CurProgress, (int)x.MaxProgress ) );
UserStatsUnloaded_t.Install( x => OnUserStatsUnloaded?.Invoke( x.SteamIDUser ) );
}
/// <summary>

View File

@ -31,10 +31,10 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<IPCountry_t>( x => OnIpCountryChanged?.Invoke() );
Event.CreateEvent<LowBatteryPower_t>( x => OnLowBatteryPower?.Invoke( x.MinutesBatteryLeft ) );
Event.CreateEvent<SteamShutdown_t>( x => OnSteamShutdown?.Invoke() );
Event.CreateEvent<GamepadTextInputDismissed_t>( x => OnGamepadTextInputDismissed?.Invoke( x.Submitted ) );
IPCountry_t.Install( x => OnIpCountryChanged?.Invoke() );
LowBatteryPower_t.Install( x => OnLowBatteryPower?.Invoke( x.MinutesBatteryLeft ) );
SteamShutdown_t.Install( x => OnSteamShutdown?.Invoke() );
GamepadTextInputDismissed_t.Install( x => OnGamepadTextInputDismissed?.Invoke( x.Submitted ) );
}
/// <summary>

View File

@ -31,8 +31,8 @@ namespace Steamworks
internal static void InstallEvents()
{
Event.CreateEvent<BroadcastUploadStart_t>( x => OnBroadcastStarted?.Invoke() );
Event.CreateEvent<BroadcastUploadStop_t>( x => OnBroadcastStopped?.Invoke( x.Result ) );
BroadcastUploadStart_t.Install( x => OnBroadcastStarted?.Invoke() );
BroadcastUploadStop_t.Install( x => OnBroadcastStopped?.Invoke( x.Result ) );
}
public static event Action OnBroadcastStarted;

View File

@ -53,8 +53,6 @@ namespace Generator
if ( name.Contains( "::" ) )
continue;
int defaultPack = 8;
if ( c.Fields.Any( x => x.Type.Contains( "CSteamID" ) ) && !ForceLargePackStructs.Contains( c.Name ) )
@ -90,6 +88,29 @@ namespace Generator
WriteLine( $"public int GetStructSize() => System.Runtime.InteropServices.Marshal.SizeOf( Config.PackSmall ? typeof({name}) : typeof(Pack8) );" );
WriteLine( $"public Steamworks.ISteamCallback Fill( IntPtr p ) => Config.PackSmall ? (({name})({name}) Marshal.PtrToStructure( p, typeof({name}) )) : (({name})(Pack8) Marshal.PtrToStructure( p, typeof(Pack8) ));" );
}
WriteLine( $"static Action<{name}> actionClient;" );
WriteLine( $"[MonoPInvokeCallback] static void OnClient( IntPtr thisptr, IntPtr pvParam ) => actionClient?.Invoke( ({name})default({name}).Fill( pvParam ) );" );
WriteLine( $"static Action<{name}> actionServer;" );
WriteLine( $"[MonoPInvokeCallback] static void OnServer( IntPtr thisptr, IntPtr pvParam ) => actionServer?.Invoke( ({name})default({name}).Fill( pvParam ) );" );
StartBlock( $"public static void Install( Action<{name}> action, bool server = false )" );
{
StartBlock( "if ( server )" );
{
WriteLine( $"Event.Register( OnServer, default({name}).GetStructSize(), {c.CallbackId}, true );" );
WriteLine( $"actionServer = action;" );
}
Else();
{
WriteLine( $"Event.Register( OnClient, default({name}).GetStructSize(), {c.CallbackId}, false );" );
WriteLine( $"actionClient = action;" );
}
EndBlock();
}
EndBlock();
}
WriteLine( "#endregion" );
}