mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2025-01-26 05:28:07 +03:00
SteamApps events
This commit is contained in:
parent
027a110c61
commit
cd30b85444
129
Facepunch.Steamworks/Callbacks/Events.cs
Normal file
129
Facepunch.Steamworks/Callbacks/Events.cs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using SteamNative;
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Created on registration of a callback
|
||||||
|
//
|
||||||
|
internal class Event<T> : IDisposable where T : struct, Steamworks.ISteamCallback
|
||||||
|
{
|
||||||
|
public Action<T> Action;
|
||||||
|
|
||||||
|
List<GCHandle> Allocations = new List<GCHandle>();
|
||||||
|
internal IntPtr vTablePtr;
|
||||||
|
internal GCHandle PinnedCallback;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
UnregisterCallback();
|
||||||
|
|
||||||
|
foreach ( var a in Allocations )
|
||||||
|
{
|
||||||
|
if ( a.IsAllocated )
|
||||||
|
a.Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
Allocations.Clear();
|
||||||
|
|
||||||
|
if ( PinnedCallback.IsAllocated )
|
||||||
|
PinnedCallback.Free();
|
||||||
|
|
||||||
|
if ( vTablePtr != IntPtr.Zero )
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal( vTablePtr );
|
||||||
|
vTablePtr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UnregisterCallback()
|
||||||
|
{
|
||||||
|
if ( !PinnedCallback.IsAllocated )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Steam.UnregisterCallback( PinnedCallback.AddrOfPinnedObject() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool IsValid { get { return true; } }
|
||||||
|
|
||||||
|
T template;
|
||||||
|
|
||||||
|
internal Event( Action<T> onresult, bool gameserver = false )
|
||||||
|
{
|
||||||
|
Action = onresult;
|
||||||
|
|
||||||
|
template = new T();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the functions we need for the vtable
|
||||||
|
//
|
||||||
|
if ( Facepunch.Steamworks.Config.UseThisCall )
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Create the VTable by manually allocating the memory and copying across
|
||||||
|
//
|
||||||
|
if ( Platform.IsWindows )
|
||||||
|
{
|
||||||
|
vTablePtr = Callback.VTableWinThis.GetVTable( OnResultThis, OnResultWithInfoThis, OnGetSizeThis, Allocations );
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vTablePtr = Callback.VTableThis.GetVTable( OnResultThis, OnResultWithInfoThis, OnGetSizeThis, Allocations );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Create the VTable by manually allocating the memory and copying across
|
||||||
|
//
|
||||||
|
if ( Platform.IsWindows )
|
||||||
|
{
|
||||||
|
vTablePtr = Callback.VTableWin.GetVTable( OnResult, OnResultWithInfo, OnGetSize, Allocations );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vTablePtr = Callback.VTable.GetVTable( OnResult, OnResultWithInfo, OnGetSize, Allocations );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the callback object
|
||||||
|
//
|
||||||
|
var cb = new Callback();
|
||||||
|
cb.vTablePtr = vTablePtr;
|
||||||
|
cb.CallbackFlags = gameserver ? (byte)0x02 : (byte)0;
|
||||||
|
cb.CallbackId = template.GetCallbackId();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native
|
||||||
|
//
|
||||||
|
PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );
|
||||||
|
|
||||||
|
//
|
||||||
|
// Register the callback with Steam
|
||||||
|
//
|
||||||
|
Steam.RegisterCallback( PinnedCallback.AddrOfPinnedObject(), cb.CallbackId );
|
||||||
|
}
|
||||||
|
|
||||||
|
[MonoPInvokeCallback] internal void OnResultThis( IntPtr self, IntPtr param ) => OnResult( param );
|
||||||
|
[MonoPInvokeCallback] internal void OnResultWithInfoThis( IntPtr self, IntPtr param, bool failure, SteamNative.SteamAPICall_t call ) => OnResultWithInfo( param, failure, call );
|
||||||
|
[MonoPInvokeCallback] internal int OnGetSizeThis( IntPtr self ) => OnGetSize();
|
||||||
|
[MonoPInvokeCallback] internal int OnGetSize() => template.GetStructSize();
|
||||||
|
[MonoPInvokeCallback] internal void OnResult( IntPtr param ) => OnResultWithInfo( param, false, 0 );
|
||||||
|
|
||||||
|
[MonoPInvokeCallback]
|
||||||
|
internal void OnResultWithInfo( IntPtr param, bool failure, SteamNative.SteamAPICall_t call )
|
||||||
|
{
|
||||||
|
if ( failure ) return;
|
||||||
|
|
||||||
|
var value = (T)template.Fill( param );
|
||||||
|
|
||||||
|
Action( value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,4 +13,13 @@ public static class SteamApi
|
|||||||
[DllImport( "Steam_api64", EntryPoint = "SteamAPI_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )]
|
[DllImport( "Steam_api64", EntryPoint = "SteamAPI_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )]
|
||||||
public static extern int GetHSteamUser();
|
public static extern int GetHSteamUser();
|
||||||
|
|
||||||
|
[DllImport( "Steam_api64", EntryPoint = "SteamAPI_RunCallbacks", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern int RunCallbacks();
|
||||||
|
|
||||||
|
[DllImport( "Steam_api64", EntryPoint = "SteamAPI_RegisterCallback", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern int RegisterCallback( IntPtr pCallback, int callback );
|
||||||
|
|
||||||
|
[DllImport( "Steam_api64", EntryPoint = "SteamAPI_UnregisterCallback", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern int UnregisterCallback( IntPtr pCallback );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using SteamNative;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@ -24,6 +25,24 @@ namespace Steamworks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void InstallEvents()
|
||||||
|
{
|
||||||
|
new Event<DlcInstalled_t>( x => OnDlcInstalled( x.AppID ) );
|
||||||
|
new Event<NewUrlLaunchParameters_t>( x => OnNewLaunchParameters() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// posted after the user gains ownership of DLC & that DLC is installed
|
||||||
|
/// </summary>
|
||||||
|
public static event Action< AppId > OnDlcInstalled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// posted after the user gains executes a Steam URL with command line or query parameters
|
||||||
|
/// such as steam://run/appid//-commandline/?param1=value1¶m2=value2¶m3=value3 etc
|
||||||
|
/// while the game is already running. The new params can be queried
|
||||||
|
/// with GetLaunchQueryParam and GetLaunchCommandLine
|
||||||
|
/// </summary>
|
||||||
|
public static event Action OnNewLaunchParameters;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the active user is subscribed to the current App ID
|
/// Checks if the active user is subscribed to the current App ID
|
||||||
|
@ -31,5 +31,15 @@ namespace Steamworks
|
|||||||
throw new System.Exception( "GetHSteamUser returned 0" );
|
throw new System.Exception( "GetHSteamUser returned 0" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static void RegisterCallback( IntPtr intPtr, int callbackId )
|
||||||
|
{
|
||||||
|
SteamApi.RegisterCallback( intPtr, callbackId );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void UnregisterCallback( IntPtr intPtr )
|
||||||
|
{
|
||||||
|
SteamApi.UnregisterCallback( intPtr );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Facepunch.Steamworks;
|
using Facepunch.Steamworks;
|
||||||
|
|
||||||
namespace SteamNative
|
namespace SteamNative
|
||||||
@ -27,6 +28,26 @@ namespace SteamNative
|
|||||||
public ResultD ResultA;
|
public ResultD ResultA;
|
||||||
public ResultWithInfoD ResultB;
|
public ResultWithInfoD ResultB;
|
||||||
public GetSizeD GetSize;
|
public GetSizeD GetSize;
|
||||||
|
|
||||||
|
internal static IntPtr GetVTable( ResultD onResultThis, ResultWithInfoD onResultWithInfoThis, GetSizeD onGetSizeThis, List<GCHandle> allocations )
|
||||||
|
{
|
||||||
|
var vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTable ) ) );
|
||||||
|
|
||||||
|
var vTable = new Callback.VTable
|
||||||
|
{
|
||||||
|
ResultA = onResultThis,
|
||||||
|
ResultB = onResultWithInfoThis,
|
||||||
|
GetSize = onGetSizeThis,
|
||||||
|
};
|
||||||
|
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultA ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultB ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.GetSize ) );
|
||||||
|
|
||||||
|
Marshal.StructureToPtr( vTable, vTablePtr, false );
|
||||||
|
|
||||||
|
return vTablePtr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||||
@ -39,6 +60,26 @@ namespace SteamNative
|
|||||||
public ResultWithInfoD ResultB;
|
public ResultWithInfoD ResultB;
|
||||||
public ResultD ResultA;
|
public ResultD ResultA;
|
||||||
public GetSizeD GetSize;
|
public GetSizeD GetSize;
|
||||||
|
|
||||||
|
internal static IntPtr GetVTable( ResultD onResultThis, ResultWithInfoD onResultWithInfoThis, GetSizeD onGetSizeThis, List<GCHandle> allocations )
|
||||||
|
{
|
||||||
|
var vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTableWin ) ) );
|
||||||
|
|
||||||
|
var vTable = new Callback.VTableWin
|
||||||
|
{
|
||||||
|
ResultA = onResultThis,
|
||||||
|
ResultB = onResultWithInfoThis,
|
||||||
|
GetSize = onGetSizeThis,
|
||||||
|
};
|
||||||
|
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultA ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultB ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.GetSize ) );
|
||||||
|
|
||||||
|
Marshal.StructureToPtr( vTable, vTablePtr, false );
|
||||||
|
|
||||||
|
return vTablePtr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||||
@ -46,6 +87,27 @@ namespace SteamNative
|
|||||||
{
|
{
|
||||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultD( IntPtr thisptr, IntPtr pvParam );
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultD( IntPtr thisptr, IntPtr pvParam );
|
||||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfoD( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfoD( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
|
||||||
|
|
||||||
|
internal static IntPtr GetVTable( ResultD onResultThis, ResultWithInfoD onResultWithInfoThis, GetSizeD onGetSizeThis, List<GCHandle> allocations )
|
||||||
|
{
|
||||||
|
var vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTableThis ) ) );
|
||||||
|
|
||||||
|
var vTable = new Callback.VTableThis
|
||||||
|
{
|
||||||
|
ResultA = onResultThis,
|
||||||
|
ResultB = onResultWithInfoThis,
|
||||||
|
GetSize = onGetSizeThis,
|
||||||
|
};
|
||||||
|
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultA ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultB ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.GetSize ) );
|
||||||
|
|
||||||
|
Marshal.StructureToPtr( vTable, vTablePtr, false );
|
||||||
|
|
||||||
|
return vTablePtr;
|
||||||
|
}
|
||||||
|
|
||||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSizeD( IntPtr thisptr );
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSizeD( IntPtr thisptr );
|
||||||
|
|
||||||
public ResultD ResultA;
|
public ResultD ResultA;
|
||||||
@ -63,6 +125,26 @@ namespace SteamNative
|
|||||||
public ResultWithInfoD ResultB;
|
public ResultWithInfoD ResultB;
|
||||||
public ResultD ResultA;
|
public ResultD ResultA;
|
||||||
public GetSizeD GetSize;
|
public GetSizeD GetSize;
|
||||||
|
|
||||||
|
internal static IntPtr GetVTable( ResultD onResultThis, ResultWithInfoD onResultWithInfoThis, GetSizeD onGetSizeThis, List<GCHandle> allocations )
|
||||||
|
{
|
||||||
|
var vTablePtr = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( Callback.VTableWinThis ) ) );
|
||||||
|
|
||||||
|
var vTable = new Callback.VTableWinThis
|
||||||
|
{
|
||||||
|
ResultA = onResultThis,
|
||||||
|
ResultB = onResultWithInfoThis,
|
||||||
|
GetSize = onGetSizeThis,
|
||||||
|
};
|
||||||
|
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultA ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.ResultB ) );
|
||||||
|
allocations.Add( GCHandle.Alloc( vTable.GetSize ) );
|
||||||
|
|
||||||
|
Marshal.StructureToPtr( vTable, vTablePtr, false );
|
||||||
|
|
||||||
|
return vTablePtr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user