mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2024-12-24 05:35:35 +03:00
Generated callback registration
This commit is contained in:
parent
17b84c4f58
commit
04c2118ed8
@ -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 )
|
||||
{
|
||||
|
@ -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<IDisposable> Disposables = new List<IDisposable>();
|
||||
|
||||
public enum MessageType : int
|
||||
{
|
||||
Message = 0,
|
||||
@ -78,18 +76,11 @@ public enum MessageType : int
|
||||
/// </summary>
|
||||
public Action<MessageType, string> OnMessage;
|
||||
|
||||
/// <summary>
|
||||
/// Global callback type
|
||||
/// </summary>
|
||||
internal void AddCallback<T, TSmall>( Action<T, bool> Callback, int id ) where T : new()
|
||||
{
|
||||
var callback = new Callback<T, TSmall>( native.api, IsGameServer, id, Callback );
|
||||
Disposables.Add( callback );
|
||||
}
|
||||
|
||||
internal void AddCallback<T>( Action<T, bool> Callback, int id ) where T : new()
|
||||
private List<SteamNative.Callback.Handle> CallbackHandles = new List<SteamNative.Callback.Handle>();
|
||||
internal void RegisterCallbackHandle( SteamNative.Callback.Handle handle )
|
||||
{
|
||||
AddCallback<T, T>( Callback, id );
|
||||
CallbackHandles.Add( handle );
|
||||
}
|
||||
|
||||
public Action OnUpdate;
|
||||
|
@ -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<SteamNative.SteamUGCQueryCompleted_t, SteamNative.SteamUGCQueryCompleted_t.PackSmall>
|
||||
{
|
||||
public override int CallbackId { get { return SteamNative.SteamUGCQueryCompleted_t.CallbackId; } }
|
||||
|
@ -137,7 +137,6 @@
|
||||
<Compile Include="Interfaces\Workshop.Editor.cs" />
|
||||
<Compile Include="Interfaces\Workshop.Item.cs" />
|
||||
<Compile Include="Interfaces\Workshop.Query.cs" />
|
||||
<Compile Include="Interop\Callback.cs" />
|
||||
<Compile Include="Interop\CallResult.cs" />
|
||||
<Compile Include="Interop\Native.cs" />
|
||||
<Compile Include="Interop\ServerRules.cs" />
|
||||
@ -179,12 +178,10 @@
|
||||
<Compile Include="SteamNative\SteamNative.SteamUserStats.cs" />
|
||||
<Compile Include="SteamNative\SteamNative.SteamUtils.cs" />
|
||||
<Compile Include="SteamNative\SteamNative.SteamVideo.cs" />
|
||||
<Compile Include="SteamNative\SteamNative.Callback.cs" />
|
||||
<Compile Include="SteamNative\SteamNative.Structs.cs" />
|
||||
<Compile Include="SteamNative\SteamNative.Types.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Interop\Callback.This.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>
|
||||
|
@ -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<SteamNative.P2PSessionRequest_t>( onP2PConnectionRequest, SteamNative.P2PSessionRequest_t.CallbackId );
|
||||
sw.AddCallback<SteamNative.P2PSessionConnectFail_t>( onP2PConnectionFailed, SteamNative.P2PSessionConnectFail_t.CallbackId );
|
||||
SteamNative.P2PSessionRequest_t.RegisterCallback( steamworks, onP2PConnectionRequest );
|
||||
SteamNative.P2PSessionConnectFail_t.RegisterCallback( steamworks, onP2PConnectionFailed );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -22,8 +22,10 @@ internal Workshop( BaseSteamworks steamworks, SteamNative.SteamUGC ugc, SteamNat
|
||||
this.steamworks = steamworks;
|
||||
this.remoteStorage = remoteStorage;
|
||||
|
||||
steamworks.AddCallback<SteamNative.DownloadItemResult_t, SteamNative.DownloadItemResult_t.PackSmall>( onDownloadResult, SteamNative.DownloadItemResult_t.CallbackId );
|
||||
steamworks.AddCallback<ItemInstalled, ItemInstalled.Small>( onItemInstalled, ItemInstalled.CallbackId );
|
||||
SteamNative.DownloadItemResult_t.RegisterCallback( steamworks, onDownloadResult );
|
||||
SteamNative.ItemInstalled_t.RegisterCallback( steamworks, onItemInstalled );
|
||||
|
||||
// steamworks.AddCallback<ItemInstalled, ItemInstalled.Small>( 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 )
|
||||
|
@ -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<IntPtr, IntPtr, bool> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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<GCHandle> Handles = new List<GCHandle>();
|
||||
|
||||
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<T, TSmall> : Callback where T : new()
|
||||
{
|
||||
private SteamNative.SteamApi api;
|
||||
|
||||
public int CallbackId = 0;
|
||||
public bool GameServer = false;
|
||||
public Action<T, bool> 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<T, bool> 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;
|
||||
};
|
||||
}
|
@ -51,7 +51,7 @@ internal ServerAuth( Server s )
|
||||
{
|
||||
server = s;
|
||||
|
||||
server.AddCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate, SteamNative.ValidateAuthTicketResponse_t.CallbackId );
|
||||
SteamNative.ValidateAuthTicketResponse_t.RegisterCallback( server, OnAuthTicketValidate );
|
||||
}
|
||||
|
||||
void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data, bool b )
|
||||
|
83
Facepunch.Steamworks/SteamNative/SteamNative.Callback.cs
Normal file
83
Facepunch.Steamworks/SteamNative/SteamNative.Callback.cs
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ static void Main( string[] args )
|
||||
var content = System.IO.File.ReadAllText( "steam_api.json" );
|
||||
var def = Newtonsoft.Json.JsonConvert.DeserializeObject<SteamApiDefinition>( 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
|
||||
} );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class StructFields
|
||||
public string CallbackId { get; set; }
|
||||
}
|
||||
|
||||
public StructDef[] structs { get; set; }
|
||||
public List<StructDef> structs { get; set; }
|
||||
|
||||
public class MethodDef
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user