From 04c2118ed8ea77a74d3376440e0108df06367107 Mon Sep 17 00:00:00 2001 From: Garry Newman Date: Sun, 30 Oct 2016 20:52:42 +0000 Subject: [PATCH] Generated callback registration --- Facepunch.Steamworks.Test/Client/Workshop.cs | 2 +- Facepunch.Steamworks/BaseSteamworks.cs | 21 +- Facepunch.Steamworks/Callbacks/Workshop.cs | 16 - .../Facepunch.Steamworks.csproj | 5 +- Facepunch.Steamworks/Interfaces/Networking.cs | 6 +- Facepunch.Steamworks/Interfaces/Workshop.cs | 10 +- Facepunch.Steamworks/Interop/Callback.This.cs | 46 - Facepunch.Steamworks/Interop/Callback.cs | 157 - Facepunch.Steamworks/Server/Auth.cs | 2 +- .../SteamNative/SteamNative.Callback.cs | 83 + .../SteamNative/SteamNative.Structs.cs | 7466 ++++++++++++++++- Generator/CodeWriter/CodeWriter.cs | 168 - Generator/CodeWriter/Struct.cs | 84 +- Generator/Program.cs | 191 + Generator/SteamApiDefinition.cs | 2 +- 15 files changed, 7800 insertions(+), 459 deletions(-) delete mode 100644 Facepunch.Steamworks/Interop/Callback.This.cs delete mode 100644 Facepunch.Steamworks/Interop/Callback.cs create mode 100644 Facepunch.Steamworks/SteamNative/SteamNative.Callback.cs diff --git a/Facepunch.Steamworks.Test/Client/Workshop.cs b/Facepunch.Steamworks.Test/Client/Workshop.cs index 2646b41..a55c0c2 100644 --- a/Facepunch.Steamworks.Test/Client/Workshop.cs +++ b/Facepunch.Steamworks.Test/Client/Workshop.cs @@ -320,7 +320,7 @@ public void DownloadFile() { Assert.IsTrue( client.IsValid ); - var item = client.Workshop.GetItem( 661319648); + var item = client.Workshop.GetItem( 787387588 ); if ( !item.Installed ) { diff --git a/Facepunch.Steamworks/BaseSteamworks.cs b/Facepunch.Steamworks/BaseSteamworks.cs index 8e95faf..ab88b9f 100644 --- a/Facepunch.Steamworks/BaseSteamworks.cs +++ b/Facepunch.Steamworks/BaseSteamworks.cs @@ -19,11 +19,11 @@ public class BaseSteamworks : IDisposable public virtual void Dispose() { - foreach ( var d in Disposables ) + foreach ( var h in CallbackHandles ) { - d.Dispose(); + h.Remove( this ); } - Disposables.Clear(); + CallbackHandles.Clear(); if ( Workshop != null ) { @@ -65,8 +65,6 @@ public bool IsValid internal Interop.NativeInterface native; internal virtual bool IsGameServer { get { return false; } } - private List Disposables = new List(); - public enum MessageType : int { Message = 0, @@ -78,18 +76,11 @@ public enum MessageType : int /// public Action OnMessage; - /// - /// Global callback type - /// - internal void AddCallback( Action Callback, int id ) where T : new() - { - var callback = new Callback( native.api, IsGameServer, id, Callback ); - Disposables.Add( callback ); - } - internal void AddCallback( Action Callback, int id ) where T : new() + private List CallbackHandles = new List(); + internal void RegisterCallbackHandle( SteamNative.Callback.Handle handle ) { - AddCallback( Callback, id ); + CallbackHandles.Add( handle ); } public Action OnUpdate; diff --git a/Facepunch.Steamworks/Callbacks/Workshop.cs b/Facepunch.Steamworks/Callbacks/Workshop.cs index 3357ffe..324e714 100644 --- a/Facepunch.Steamworks/Callbacks/Workshop.cs +++ b/Facepunch.Steamworks/Callbacks/Workshop.cs @@ -3,22 +3,6 @@ namespace Facepunch.Steamworks.Callbacks.Workshop { - [StructLayout( LayoutKind.Sequential, Pack = 8 )] - internal struct ItemInstalled - { - public uint AppId; - public ulong FileId; - - public const int CallbackId = SteamNative.CallbackIdentifiers.ClientUGC + 5; - - [StructLayout( LayoutKind.Sequential, Pack = 4 )] - internal struct Small - { - public uint AppId; - public ulong FileId; - }; - }; - internal class QueryCompleted : CallResult { public override int CallbackId { get { return SteamNative.SteamUGCQueryCompleted_t.CallbackId; } } diff --git a/Facepunch.Steamworks/Facepunch.Steamworks.csproj b/Facepunch.Steamworks/Facepunch.Steamworks.csproj index c561a03..711a268 100644 --- a/Facepunch.Steamworks/Facepunch.Steamworks.csproj +++ b/Facepunch.Steamworks/Facepunch.Steamworks.csproj @@ -137,7 +137,6 @@ - @@ -179,12 +178,10 @@ + - - - diff --git a/Facepunch.Steamworks/Interfaces/Networking.cs b/Facepunch.Steamworks/Interfaces/Networking.cs index 11308b7..0fd4e11 100644 --- a/Facepunch.Steamworks/Interfaces/Networking.cs +++ b/Facepunch.Steamworks/Interfaces/Networking.cs @@ -14,12 +14,12 @@ public class Networking : IDisposable internal SteamNative.SteamNetworking networking; - internal Networking( BaseSteamworks sw, SteamNative.SteamNetworking networking ) + internal Networking( BaseSteamworks steamworks, SteamNative.SteamNetworking networking ) { this.networking = networking; - sw.AddCallback( onP2PConnectionRequest, SteamNative.P2PSessionRequest_t.CallbackId ); - sw.AddCallback( onP2PConnectionFailed, SteamNative.P2PSessionConnectFail_t.CallbackId ); + SteamNative.P2PSessionRequest_t.RegisterCallback( steamworks, onP2PConnectionRequest ); + SteamNative.P2PSessionConnectFail_t.RegisterCallback( steamworks, onP2PConnectionFailed ); } public void Dispose() diff --git a/Facepunch.Steamworks/Interfaces/Workshop.cs b/Facepunch.Steamworks/Interfaces/Workshop.cs index 381a7c9..56591f3 100644 --- a/Facepunch.Steamworks/Interfaces/Workshop.cs +++ b/Facepunch.Steamworks/Interfaces/Workshop.cs @@ -22,8 +22,10 @@ internal Workshop( BaseSteamworks steamworks, SteamNative.SteamUGC ugc, SteamNat this.steamworks = steamworks; this.remoteStorage = remoteStorage; - steamworks.AddCallback( onDownloadResult, SteamNative.DownloadItemResult_t.CallbackId ); - steamworks.AddCallback( onItemInstalled, ItemInstalled.CallbackId ); + SteamNative.DownloadItemResult_t.RegisterCallback( steamworks, onDownloadResult ); + SteamNative.ItemInstalled_t.RegisterCallback( steamworks, onItemInstalled ); + + // steamworks.AddCallback( onItemInstalled, ItemInstalled.CallbackId ); } public void Dispose() @@ -37,10 +39,10 @@ public void Dispose() OnItemInstalled = null; } - private void onItemInstalled( ItemInstalled obj, bool failed ) + private void onItemInstalled( SteamNative.ItemInstalled_t obj, bool failed ) { if ( OnItemInstalled != null ) - OnItemInstalled( obj.FileId ); + OnItemInstalled( obj.PublishedFileId ); } private void onDownloadResult( SteamNative.DownloadItemResult_t obj, bool failed ) diff --git a/Facepunch.Steamworks/Interop/Callback.This.cs b/Facepunch.Steamworks/Interop/Callback.This.cs deleted file mode 100644 index 88f6543..0000000 --- a/Facepunch.Steamworks/Interop/Callback.This.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; - -namespace Facepunch.Steamworks.Interop.VTable.This -{ - [StructLayout( LayoutKind.Sequential )] - internal struct Callback - { - [UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void Result( IntPtr thisptr, IntPtr pvParam ); - [UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultBool( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall ); - [UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSize( IntPtr thisptr ); - - [MarshalAs(UnmanagedType.FunctionPtr)] public ResultBool RunCallResult; - [MarshalAs(UnmanagedType.FunctionPtr)] public Result RunCallback; - [MarshalAs(UnmanagedType.FunctionPtr)] public GetSize GetCallbackSizeBytes; - - internal static IntPtr Get( Action onRunCallback, int size, Interop.Callback cb ) - { - var ptr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback ) ) ); - - Callback.Result da = ( _, p ) => { onRunCallback( _, p, false ); }; - Callback.ResultBool db = ( _, p, iofailure, call ) => { onRunCallback( _, p, iofailure ); }; - Callback.GetSize dc = ( _ ) => { return size; }; - - cb.AddHandle( GCHandle.Alloc( da ) ); - cb.AddHandle( GCHandle.Alloc( db ) ); - cb.AddHandle( GCHandle.Alloc( dc ) ); - - var table = new Callback() - { - RunCallback = da, - RunCallResult = db, - GetCallbackSizeBytes = dc - }; - - Marshal.StructureToPtr( table, ptr, false ); - - return ptr; - } - } - - -} diff --git a/Facepunch.Steamworks/Interop/Callback.cs b/Facepunch.Steamworks/Interop/Callback.cs deleted file mode 100644 index 7896681..0000000 --- a/Facepunch.Steamworks/Interop/Callback.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; - - -// -// THANSK AGAIN TO STEAMWORKS.NET -// -// https://github.com/rlabrecque/Steamworks.NET/blob/97935154cf08f60da92c55e2c73ee60a8f456e03/Plugins/Steamworks.NET/CallbackDispatcher.cs -// - -// Calling Conventions: -// Unity x86 Windows - StdCall (No this pointer) -// Unity x86 Linux - Cdecl -// Unity x86 OSX - Cdecl -// Unity x64 Windows - Cdecl -// Unity x64 Linux - Cdecl -// Unity x64 OSX - Cdecl -// Microsoft x86 Windows - ThisCall -// Microsoft x64 Windows - ThisCall -// Mono x86 Linux - Cdecl -// Mono x86 OSX - Cdecl -// Mono x64 Linux - Cdecl -// Mono x64 OSX - Cdecl -// Mono on Windows is probably not supported. - -namespace Facepunch.Steamworks.Interop -{ - internal partial class Callback : IDisposable - { - List Handles = new List(); - - public virtual void Dispose() - { - foreach ( var handle in Handles ) - { - handle.Free(); - } - - Handles = null; - } - - internal void AddHandle( GCHandle gCHandle ) - { - Handles.Add( gCHandle ); - } - } - - internal partial class Callback : Callback where T : new() - { - private SteamNative.SteamApi api; - - public int CallbackId = 0; - public bool GameServer = false; - public Action Function; - - private IntPtr vTablePtr = IntPtr.Zero; - private GCHandle callbackPin; - - private readonly int m_size = Marshal.SizeOf(typeof(T)); - - public Callback( SteamNative.SteamApi api, bool gameserver, int callbackid, Action func ) - { - this.api = api; - GameServer = gameserver; - CallbackId = callbackid; - Function = func; - - BuildVTable(); - - this.api.SteamAPI_RegisterCallback( callbackPin.AddrOfPinnedObject(), CallbackId ); - } - - public override void Dispose() - { - if ( callbackPin.IsAllocated ) - { - api.SteamAPI_UnregisterCallback( callbackPin.AddrOfPinnedObject() ); - callbackPin.Free(); - } - - if ( vTablePtr != IntPtr.Zero ) - { - Marshal.FreeHGlobal( vTablePtr ); - vTablePtr = IntPtr.Zero; - } - - base.Dispose(); - } - - private void OnRunCallback( IntPtr thisObject, IntPtr ptr, bool failure ) - { - if ( callbackPin == null ) throw new System.Exception( "Callback wasn't pinned!" ); - if ( vTablePtr == IntPtr.Zero ) throw new System.Exception( "vTablePtr wasn't pinned!" ); - if ( thisObject != IntPtr.Zero && thisObject != callbackPin.AddrOfPinnedObject() ) throw new System.Exception( "This wasn't valid! ("+ thisObject.ToInt64() + ") ( "+ callbackPin.AddrOfPinnedObject().ToInt64() + " )" ); - - if ( SteamNative.Platform.PackSmall && typeof(T) != typeof( TSmall ) ) throw new System.Exception( "Callback should use PackSmall" ); - - if ( failure ) - { - Function( new T(), failure ); - return; - } - - T data = (T) Marshal.PtrToStructure( ptr, typeof(T) ); - Function( data, failure ); - } - - - private int GetSize() - { - Console.WriteLine( "GET SIZE CALLED" ); - throw new System.NotImplementedException(); - } - - // Steamworks.NET Specific - private void BuildVTable() - { - InitVTable(); - - var callbackBase = new CallbackBase() - { - vTablePtr = vTablePtr, - CallbackFlags = GameServer ? (byte) CallbackBase.Flags.GameServer : (byte) 0, - CallbackId = CallbackId - }; - callbackPin = GCHandle.Alloc( callbackBase, GCHandleType.Pinned ); - } - - void InitVTable() - { - if ( Config.UseThisCall ) - { - vTablePtr = VTable.This.Callback.Get( OnRunCallback, Marshal.SizeOf( typeof( T ) ), this ); - return; - } - - throw new System.NotImplementedException(); - } - } - - [StructLayout( LayoutKind.Sequential )] - internal class CallbackBase - { - internal enum Flags : byte - { - Registered = 0x01, - GameServer = 0x02 - } - - public IntPtr vTablePtr; - public byte CallbackFlags; - public int CallbackId; - }; -} \ No newline at end of file diff --git a/Facepunch.Steamworks/Server/Auth.cs b/Facepunch.Steamworks/Server/Auth.cs index 244e4b7..5d290e1 100644 --- a/Facepunch.Steamworks/Server/Auth.cs +++ b/Facepunch.Steamworks/Server/Auth.cs @@ -51,7 +51,7 @@ internal ServerAuth( Server s ) { server = s; - server.AddCallback( OnAuthTicketValidate, SteamNative.ValidateAuthTicketResponse_t.CallbackId ); + SteamNative.ValidateAuthTicketResponse_t.RegisterCallback( server, OnAuthTicketValidate ); } void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data, bool b ) diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.Callback.cs b/Facepunch.Steamworks/SteamNative/SteamNative.Callback.cs new file mode 100644 index 0000000..99e9b59 --- /dev/null +++ b/Facepunch.Steamworks/SteamNative/SteamNative.Callback.cs @@ -0,0 +1,83 @@ +using System; +using System.Runtime.InteropServices; +using Facepunch.Steamworks; + +namespace SteamNative +{ + [StructLayout( LayoutKind.Sequential )] + internal class Callback + { + internal enum Flags : byte + { + Registered = 0x01, + GameServer = 0x02 + } + + public IntPtr vTablePtr; + public byte CallbackFlags; + public int CallbackId; + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public class VTable + { + public IntPtr ResultA; + public IntPtr ResultB; + public IntPtr GetSize; + } + + // + // All possible functions + // + + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void Result( IntPtr thisptr, IntPtr pvParam ); + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfo( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall ); + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSize( IntPtr thisptr ); + + // + // Created on registration of a callback + // + public class Handle : IDisposable + { + public GCHandle FuncA; + public GCHandle FuncB; + public GCHandle FuncC; + + public IntPtr vTablePtr; + + public GCHandle PinnedCallback; + + public void Dispose() + { + if ( FuncA.IsAllocated ) + FuncA.Free(); + + if ( FuncB.IsAllocated ) + FuncB.Free(); + + if ( FuncC.IsAllocated ) + FuncC.Free(); + + if ( PinnedCallback.IsAllocated ) + PinnedCallback.Free(); + + if ( vTablePtr != IntPtr.Zero ) + { + Marshal.FreeHGlobal( vTablePtr ); + vTablePtr = IntPtr.Zero; + } + } + + internal void Remove( BaseSteamworks baseSteamworks ) + { + if ( PinnedCallback.IsAllocated ) + { + baseSteamworks.native.api.SteamAPI_UnregisterCallback( PinnedCallback.AddrOfPinnedObject() ); + } + + Dispose(); + } + } + }; + + +} diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs b/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs index 591d866..2dd0968 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs @@ -94,6 +94,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamServerConnectFailure_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -134,6 +195,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamServersDisconnected_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -186,6 +308,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( ClientGameServerDeny_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -232,6 +415,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( ValidateAuthTicketResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -278,6 +522,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( MicroTxnAuthorizationResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -318,6 +623,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( EncryptedAppTicketResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -361,6 +727,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GetAuthSessionTicketResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -403,6 +830,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameWebCallback_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -445,6 +933,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( StoreAuthURLResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -581,6 +1130,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( PersonaStateChange_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -621,6 +1231,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameOverlayActivated_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -668,6 +1339,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameServerChangeRequested_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -711,6 +1443,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameLobbyJoinRequested_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -760,6 +1553,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( AvatarImageLoaded_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -806,6 +1660,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( ClanOfficerListResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -849,6 +1764,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( FriendRichPresenceUpdate_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -894,6 +1870,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameRichPresenceJoinRequested_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -940,6 +1977,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameConnectedClanChatMsg_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -983,6 +2081,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameConnectedChatJoin_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -1036,6 +2195,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameConnectedChatLeave_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1078,6 +2298,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( DownloadClanActivityCountsResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -1121,6 +2402,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( JoinClanChatRoomCompletionResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -1164,6 +2506,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GameConnectedFriendChatMsg_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -1210,6 +2613,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( FriendsGetFollowerCount_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -1258,6 +2722,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( FriendsIsFollowing_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -1309,6 +2834,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( FriendsEnumerateFollowingList_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1359,6 +2945,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SetPersonaNameResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1399,6 +3046,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LowBatteryPower_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1445,6 +3153,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamAPICallCompleted_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1485,6 +3254,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( CheckFileSignature_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1530,6 +3360,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GamepadTextInputDismissed_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1789,6 +3680,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( FavoritesListChanged_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1835,6 +3787,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyInvite_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1886,6 +3899,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyEnter_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1932,6 +4006,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyDataUpdate_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -1981,6 +4116,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyChatUpdate_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2030,6 +4226,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyChatMsg_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2079,6 +4336,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyGameCreated_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2119,6 +4437,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyMatchList_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2165,6 +4544,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyKicked_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2208,6 +4648,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LobbyCreated_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -2253,6 +4754,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( PSNGameBootInviteResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2293,6 +4855,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( FavoritesListAccountsUpdated_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2381,6 +5004,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageAppSyncedClient_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2427,6 +5111,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageAppSyncedServer_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2483,6 +5228,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageAppSyncProgress_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2526,6 +5332,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageAppSyncStatusCheck_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2574,6 +5441,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageFileShareResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2622,6 +5550,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStoragePublishFileResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2665,6 +5654,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageDeletePublishedFileResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2716,6 +5766,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageEnumerateUserPublishedFilesResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2759,6 +5870,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageSubscribePublishedFileResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2815,6 +5987,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageEnumerateUserSubscribedFilesResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2858,6 +6091,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageUnsubscribePublishedFileResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2906,6 +6200,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageUpdatePublishedFileResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -2963,6 +6318,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageDownloadUGCResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3079,6 +6495,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageGetPublishedFileDetailsResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3141,6 +6618,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageEnumerateWorkshopFilesResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3196,6 +6734,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageGetPublishedItemVoteDetailsResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3239,6 +6838,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStoragePublishedFileSubscribed_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3282,6 +6942,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStoragePublishedFileUnsubscribed_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3325,6 +7046,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStoragePublishedFileDeleted_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3368,6 +7150,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageUpdateUserPublishedItemVoteResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3414,6 +7257,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageUserVoteDetails_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3465,6 +7369,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageEnumerateUserSharedWorkshopFilesResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3511,6 +7476,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageSetUserPublishedFileActionResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3570,6 +7596,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageEnumeratePublishedFilesByUserActionResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3615,6 +7702,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStoragePublishFileProgress_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3661,6 +7809,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStoragePublishedFileUpdated_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3701,6 +7910,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageFileWriteAsyncComplete_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3750,6 +8020,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RemoteStorageFileReadAsyncComplete_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -3847,6 +8178,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( UserStatsReceived_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3890,6 +8282,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( UserStatsStored_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3946,6 +8399,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( UserAchievementStored_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -3989,6 +8503,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LeaderboardFindResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4035,6 +8610,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LeaderboardScoresDownloaded_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4090,6 +8726,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LeaderboardScoreUploaded_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4133,6 +8830,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( NumberOfCurrentPlayers_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -4173,6 +8931,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( UserStatsUnloaded_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4226,6 +9045,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( UserAchievementIconFetched_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4269,6 +9149,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GlobalAchievementPercentagesReady_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4312,6 +9253,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( LeaderboardUGCSet_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4358,6 +9360,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( PS3TrophiesInstalled_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4401,6 +9464,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GlobalStatsReceived_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4441,6 +9565,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( DlcInstalled_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4484,6 +9669,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( RegisterActivationCodeResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4535,6 +9781,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( AppProofOfPurchaseKeyResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4586,6 +9893,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( FileDetailsResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4686,6 +10054,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( P2PSessionRequest_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -4729,6 +10158,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( P2PSessionConnectFail_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -4778,6 +10268,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SocketStatusCallback_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -4821,6 +10372,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( ScreenshotReady_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5152,6 +10764,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( HTTPRequestCompleted_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5195,6 +10868,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( HTTPRequestHeadersReceived_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5244,6 +10978,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( HTTPRequestDataReceived_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5293,6 +11088,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamUnifiedMessagesSendMethodResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5639,6 +11495,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamUGCQueryCompleted_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5684,6 +11601,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamUGCRequestUGCDetailsResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5732,6 +11710,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( CreateItemResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5777,6 +11816,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SubmitItemUpdateResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5823,6 +11923,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( DownloadItemResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5871,6 +12032,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( UserFavoriteItemsListChanged_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5919,6 +12141,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SetUserItemVoteResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -5977,6 +12260,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GetUserItemVoteResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -6017,6 +12361,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( StartPlaytimeTrackingResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -6057,6 +12462,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( StopPlaytimeTrackingResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7273,6 +13739,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamInventoryResultReady_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7313,6 +13840,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( SteamInventoryFullUpdate_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7401,48 +13989,6 @@ public static PackSmall FromPointer( IntPtr p ) } } - [StructLayout( LayoutKind.Sequential, Pack = 8 )] - public struct CCallbackBase - { - public byte CallbackFlags; // m_nCallbackFlags uint8 - public int Callback; // m_iCallback int - - // - // Read this struct from a pointer, usually from Native - // - public static CCallbackBase FromPointer( IntPtr p ) - { - return (CCallbackBase) Marshal.PtrToStructure( p, typeof(CCallbackBase) ); - } - - [StructLayout( LayoutKind.Sequential, Pack = 4 )] - public struct PackSmall - { - public byte CallbackFlags; // m_nCallbackFlags uint8 - public int Callback; // m_iCallback int - - // - // Easily convert from PackSmall to CCallbackBase - // - public static implicit operator CCallbackBase ( CCallbackBase.PackSmall d ) - { - return new CCallbackBase() - { - CallbackFlags = d.CallbackFlags, - Callback = d.Callback, - }; - } - - // - // Read this struct from a pointer, usually from Native - // - public static PackSmall FromPointer( IntPtr p ) - { - return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); - } - } - } - [StructLayout( LayoutKind.Sequential, Pack = 4 )] public struct GSClientApprove_t { @@ -7484,6 +14030,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSClientApprove_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -7532,6 +14139,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSClientDeny_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -7575,6 +14243,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSClientKick_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7625,6 +14354,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSClientAchievementStatus_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7665,6 +14455,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSPolicyResponse_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7714,6 +14565,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSGameplayStats_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -7767,6 +14679,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSClientGroupStatus_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7827,6 +14800,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSReputation_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 8 )] @@ -7867,6 +14901,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( AssociateWithClanResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -7919,6 +15014,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( ComputeNewPlayerCompatibilityResult_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -8004,6 +15160,67 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSStatsStored_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } [StructLayout( LayoutKind.Sequential, Pack = 4 )] @@ -8044,6 +15261,171 @@ public static PackSmall FromPointer( IntPtr p ) return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); } } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( GSStatsUnloaded_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } + } + + [StructLayout( LayoutKind.Sequential, Pack = 8 )] + public struct ItemInstalled_t + { + public const int CallbackId = CallbackIdentifiers.ClientUGC + 5; + public uint AppID; // m_unAppID AppId_t + public ulong PublishedFileId; // m_nPublishedFileId PublishedFileId_t + + // + // Read this struct from a pointer, usually from Native + // + public static ItemInstalled_t FromPointer( IntPtr p ) + { + return (ItemInstalled_t) Marshal.PtrToStructure( p, typeof(ItemInstalled_t) ); + } + + [StructLayout( LayoutKind.Sequential, Pack = 4 )] + public struct PackSmall + { + public uint AppID; // m_unAppID AppId_t + public ulong PublishedFileId; // m_nPublishedFileId PublishedFileId_t + + // + // Easily convert from PackSmall to ItemInstalled_t + // + public static implicit operator ItemInstalled_t ( ItemInstalled_t.PackSmall d ) + { + return new ItemInstalled_t() + { + AppID = d.AppID, + PublishedFileId = d.PublishedFileId, + }; + } + + // + // Read this struct from a pointer, usually from Native + // + public static PackSmall FromPointer( IntPtr p ) + { + return (PackSmall) Marshal.PtrToStructure( p, typeof(PackSmall) ); + } + } + + public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action CallbackFunction ) + { + var handle = new Callback.Handle(); + + // + // Create the functions we need for the vtable + // + Callback.Result funcA = ( _, p ) => { CallbackFunction( FromPointer( p ), false ); }; + Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => { CallbackFunction( FromPointer( p ), iofailure ); }; + Callback.GetSize funcC = ( _ ) => { return Marshal.SizeOf( typeof( ItemInstalled_t ) ); }; + + // + // If this platform is PackSmall, use PackSmall versions of everything instead + // + if ( Platform.PackSmall ) + { + funcA = ( _, p ) => { CallbackFunction( PackSmall.FromPointer( p ), false ); }; + funcB = ( _, p, iofailure, call ) => { CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }; + funcC = ( _ ) => { return Marshal.SizeOf( typeof( PackSmall ) ); }; + } + + // + // Allocate a handle to each function, so they don't get disposed + // + handle.FuncA = GCHandle.Alloc( funcA ); + handle.FuncB = GCHandle.Alloc( funcB ); + handle.FuncC = GCHandle.Alloc( funcC ); + + // + // Create the VTable by manually allocating the memory and copying across + // + handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) ); + var vTable = new Callback.VTable() + { + ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention + ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first + GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works + }; + Marshal.StructureToPtr( vTable, handle.vTablePtr, false ); + + // + // Create the callback object + // + var cb = new Callback(); + cb.vTablePtr = handle.vTablePtr; + cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0; + cb.CallbackId = CallbackId; + + // + // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native + // + handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned ); + + // + // Register the callback with Steam + // + steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId ); + + steamworks.RegisterCallbackHandle( handle ); + } } } diff --git a/Generator/CodeWriter/CodeWriter.cs b/Generator/CodeWriter/CodeWriter.cs index 0c59f6b..bafc096 100644 --- a/Generator/CodeWriter/CodeWriter.cs +++ b/Generator/CodeWriter/CodeWriter.cs @@ -16,174 +16,6 @@ public CodeWriter( SteamApiDefinition def ) { this.def = def; - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamAPI_Init", - ReturnType = "bool", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamAPI_RunCallbacks", - ReturnType = "void", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamGameServer_RunCallbacks", - ReturnType = "void", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamAPI_RegisterCallback", - ReturnType = "void", - NeedsSelfPointer = false, - Params = new SteamApiDefinition.MethodDef.ParamType[] - { - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "pCallback", - Type = "void *" - }, - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "callback", - Type = "int" - }, - } - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamAPI_UnregisterCallback", - ReturnType = "void", - NeedsSelfPointer = false, - Params = new SteamApiDefinition.MethodDef.ParamType[] - { - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "pCallback", - Type = "void *" - } - } - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamInternal_GameServer_Init", - ReturnType = "bool", - NeedsSelfPointer = false, - Params = new SteamApiDefinition.MethodDef.ParamType[] - { - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "unIP", - Type = "uint32" - }, - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "usPort", - Type = "uint16" - }, - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "usGamePort", - Type = "uint16" - }, - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "usQueryPort", - Type = "uint16" - }, - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "eServerMode", - Type = "int" - }, - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "pchVersionString", - Type = "const char *" - } - }, - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamAPI_Shutdown", - ReturnType = "void", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamGameServer_Shutdown", - ReturnType = "void", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamAPI_GetHSteamUser", - ReturnType = "HSteamUser", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamAPI_GetHSteamPipe", - ReturnType = "HSteamPipe", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamGameServer_GetHSteamUser", - ReturnType = "HSteamUser", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamGameServer_GetHSteamPipe", - ReturnType = "HSteamPipe", - NeedsSelfPointer = false - } ); - - def.methods.Add( new SteamApiDefinition.MethodDef() - { - ClassName = "SteamApi", - Name = "SteamInternal_CreateInterface", - ReturnType = "void *", - Params = new SteamApiDefinition.MethodDef.ParamType[] - { - new SteamApiDefinition.MethodDef.ParamType() - { - Name = "version", - Type = "const char *" - } - }, - NeedsSelfPointer = false - } ); - - - WorkoutTypes(); } diff --git a/Generator/CodeWriter/Struct.cs b/Generator/CodeWriter/Struct.cs index e513591..701b9c0 100644 --- a/Generator/CodeWriter/Struct.cs +++ b/Generator/CodeWriter/Struct.cs @@ -26,7 +26,8 @@ public class TypeDef "CSteamAPIContext", "CCallResult", "CCallback", - "ValvePackingSentinel_t" + "ValvePackingSentinel_t", + "CCallbackBase" }; void Structs() @@ -115,6 +116,11 @@ void Structs() } EndBlock(); + if ( !string.IsNullOrEmpty( c.CallbackId ) ) + { + Callback( c ); + } + } EndBlock(); WriteLine(); @@ -187,5 +193,81 @@ private void StructFields( SteamApiDefinition.StructDef.StructFields[] fields ) WriteLine( $"public {t} {CleanMemberName( m.Name )}; // {m.Name} {m.Type}" ); } } + + private void Callback( SteamApiDefinition.StructDef c ) + { + WriteLine(); + StartBlock( $"public static void RegisterCallback( Facepunch.Steamworks.BaseSteamworks steamworks, Action<{c.Name}, bool> CallbackFunction )" ); + { + WriteLine( $"var handle = new Callback.Handle();" ); + WriteLine( $"" ); + + WriteLine( "//" ); + WriteLine( "// Create the functions we need for the vtable" ); + WriteLine( "//" ); + WriteLine( $"Callback.Result funcA = ( _, p ) => {{ CallbackFunction( FromPointer( p ), false ); }};" ); + WriteLine( $"Callback.ResultWithInfo funcB = ( _, p, iofailure, call ) => {{ CallbackFunction( FromPointer( p ), iofailure ); }};" ); + WriteLine( $"Callback.GetSize funcC = ( _ ) => {{ return Marshal.SizeOf( typeof( {c.Name} ) ); }};" ); + WriteLine(); + WriteLine( "//" ); + WriteLine( "// If this platform is PackSmall, use PackSmall versions of everything instead" ); + WriteLine( "//" ); + StartBlock( "if ( Platform.PackSmall )" ); + { + WriteLine( $"funcA = ( _, p ) => {{ CallbackFunction( PackSmall.FromPointer( p ), false ); }};" ); + WriteLine( $"funcB = ( _, p, iofailure, call ) => {{ CallbackFunction( PackSmall.FromPointer( p ), iofailure ); }};" ); + WriteLine( $"funcC = ( _ ) => {{ return Marshal.SizeOf( typeof( PackSmall ) ); }};" ); + } + EndBlock(); + + WriteLine( "" ); + WriteLine( "//" ); + WriteLine( "// Allocate a handle to each function, so they don't get disposed" ); + WriteLine( "//" ); + WriteLine( "handle.FuncA = GCHandle.Alloc( funcA );" ); + WriteLine( "handle.FuncB = GCHandle.Alloc( funcB );" ); + WriteLine( "handle.FuncC = GCHandle.Alloc( funcC );" ); + WriteLine(); + + WriteLine( "//" ); + WriteLine( "// Create the VTable by manually allocating the memory and copying across" ); + WriteLine( "//" ); + WriteLine( "handle.vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) );" ); + StartBlock( "var vTable = new Callback.VTable()" ); + { + WriteLine( "ResultA = Marshal.GetFunctionPointerForDelegate( funcB ), // The order of these functions is a point of contention" ); + WriteLine( "ResultB = Marshal.GetFunctionPointerForDelegate( funcA ), // Doesn't seem to matter win64, but win32 crashes if WithInfo not first" ); + WriteLine( "GetSize = Marshal.GetFunctionPointerForDelegate( funcC ), // Which is the opposite of how they are in code, but whatever works" ); + } + EndBlock( ";" ); + + WriteLine( "Marshal.StructureToPtr( vTable, handle.vTablePtr, false );" ); + + WriteLine( "" ); + WriteLine( "//" ); + WriteLine( "// Create the callback object" ); + WriteLine( "//" ); + WriteLine( $"var cb = new Callback();" ); + WriteLine( $"cb.vTablePtr = handle.vTablePtr;" ); + WriteLine( $"cb.CallbackFlags = steamworks.IsGameServer ? (byte) SteamNative.Callback.Flags.GameServer : (byte) 0;" ); + WriteLine( $"cb.CallbackId = CallbackId;" ); + + WriteLine( "" ); + WriteLine( "//" ); + WriteLine( "// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native" ); + WriteLine( "//" ); + WriteLine( $"handle.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );" ); + + WriteLine( "" ); + WriteLine( "//" ); + WriteLine( "// Register the callback with Steam" ); + WriteLine( "//" ); + WriteLine( $"steamworks.native.api.SteamAPI_RegisterCallback( handle.PinnedCallback.AddrOfPinnedObject(), CallbackId );" ); + + WriteLine(); + WriteLine( "steamworks.RegisterCallbackHandle( handle );" ); + } + EndBlock(); + } } } diff --git a/Generator/Program.cs b/Generator/Program.cs index 0b9958c..0acbb1a 100644 --- a/Generator/Program.cs +++ b/Generator/Program.cs @@ -14,6 +14,8 @@ static void Main( string[] args ) var content = System.IO.File.ReadAllText( "steam_api.json" ); var def = Newtonsoft.Json.JsonConvert.DeserializeObject( content ); + AddExtras( def ); + var parser = new CodeParser( @"D:\Dropbox (Facepunch Studios)\Software\SteamWorks\steamworks_sdk_138a\public\steam" ); parser.ExtendDefinition( def ); @@ -22,6 +24,195 @@ static void Main( string[] args ) generator.ToFolder( "../Facepunch.Steamworks/SteamNative/" ); } + + private static void AddExtras( SteamApiDefinition def ) + { + def.structs.Add( new SteamApiDefinition.StructDef() + { + Name = "ItemInstalled_t", + Fields = new SteamApiDefinition.StructDef.StructFields[] + { + new SteamApiDefinition.StructDef.StructFields() + { + Name = "m_unAppID", + Type = "AppId_t" + }, + new SteamApiDefinition.StructDef.StructFields() + { + Name = "m_nPublishedFileId", + Type = "PublishedFileId_t" + } + } + + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamAPI_Init", + ReturnType = "bool", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamAPI_RunCallbacks", + ReturnType = "void", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamGameServer_RunCallbacks", + ReturnType = "void", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamAPI_RegisterCallback", + ReturnType = "void", + NeedsSelfPointer = false, + Params = new SteamApiDefinition.MethodDef.ParamType[] + { + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "pCallback", + Type = "void *" + }, + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "callback", + Type = "int" + }, + } + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamAPI_UnregisterCallback", + ReturnType = "void", + NeedsSelfPointer = false, + Params = new SteamApiDefinition.MethodDef.ParamType[] + { + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "pCallback", + Type = "void *" + } + } + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamInternal_GameServer_Init", + ReturnType = "bool", + NeedsSelfPointer = false, + Params = new SteamApiDefinition.MethodDef.ParamType[] + { + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "unIP", + Type = "uint32" + }, + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "usPort", + Type = "uint16" + }, + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "usGamePort", + Type = "uint16" + }, + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "usQueryPort", + Type = "uint16" + }, + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "eServerMode", + Type = "int" + }, + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "pchVersionString", + Type = "const char *" + } + }, + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamAPI_Shutdown", + ReturnType = "void", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamGameServer_Shutdown", + ReturnType = "void", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamAPI_GetHSteamUser", + ReturnType = "HSteamUser", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamAPI_GetHSteamPipe", + ReturnType = "HSteamPipe", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamGameServer_GetHSteamUser", + ReturnType = "HSteamUser", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamGameServer_GetHSteamPipe", + ReturnType = "HSteamPipe", + NeedsSelfPointer = false + } ); + + def.methods.Add( new SteamApiDefinition.MethodDef() + { + ClassName = "SteamApi", + Name = "SteamInternal_CreateInterface", + ReturnType = "void *", + Params = new SteamApiDefinition.MethodDef.ParamType[] + { + new SteamApiDefinition.MethodDef.ParamType() + { + Name = "version", + Type = "const char *" + } + }, + NeedsSelfPointer = false + } ); + + } } } diff --git a/Generator/SteamApiDefinition.cs b/Generator/SteamApiDefinition.cs index 8aeef0e..73a93f5 100644 --- a/Generator/SteamApiDefinition.cs +++ b/Generator/SteamApiDefinition.cs @@ -55,7 +55,7 @@ public class StructFields public string CallbackId { get; set; } } - public StructDef[] structs { get; set; } + public List structs { get; set; } public class MethodDef {