diff --git a/Facepunch.Steamworks.Test/AppTest.cs b/Facepunch.Steamworks.Test/AppTest.cs
index bf216aa..bdfbc88 100644
--- a/Facepunch.Steamworks.Test/AppTest.cs
+++ b/Facepunch.Steamworks.Test/AppTest.cs
@@ -15,6 +15,13 @@ namespace Steamworks
[AssemblyInitialize]
public static void AssemblyInit( TestContext context )
{
+ Steamworks.Dispatch.OnDebugCallback = ( type, str, server ) =>
+ {
+ Console.WriteLine( $"[Callback {type} {(server ? "server" : "client")}]" );
+ Console.WriteLine( str );
+ Console.WriteLine( $"" );
+ };
+
Steamworks.SteamClient.OnCallbackException = ( e ) =>
{
Console.Error.WriteLine( e.Message );
diff --git a/Facepunch.Steamworks/Classes/Dispatch.cs b/Facepunch.Steamworks/Classes/Dispatch.cs
index bfa3675..26b32cd 100644
--- a/Facepunch.Steamworks/Classes/Dispatch.cs
+++ b/Facepunch.Steamworks/Classes/Dispatch.cs
@@ -9,11 +9,24 @@ using System.Linq;
namespace Steamworks
{
///
- /// Manually pumps Steam's message queue and dispatches those
+ /// Responsible for all callback/callresult handling
+ ///
+ /// This manually pumps Steam's message queue and dispatches those
/// events to any waiting callbacks/callresults.
///
- internal static class Dispatch
+ public static class Dispatch
{
+ ///
+ /// If set then we'll call this function every time a callback is generated.
+ ///
+ /// This is SLOW!! - it's for debugging - don't keep it on all the time. If you want to access a specific
+ /// callback then please create an issue on github and I'll add it!
+ ///
+ /// Params are : [Callback Type] [Callback Contents] [server]
+ ///
+ ///
+ public static Action OnDebugCallback;
+
#region interop
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ManualDispatch_Init", CallingConvention = CallingConvention.Cdecl )]
internal static extern void SteamAPI_ManualDispatch_Init();
@@ -45,9 +58,9 @@ namespace Steamworks
///
/// This gets called from Client/Server Init
- /// It's important to switch to the manual dipatcher
+ /// It's important to switch to the manual dispatcher
///
- public static void Init()
+ internal static void Init()
{
SteamAPI_ManualDispatch_Init();
}
@@ -56,7 +69,7 @@ namespace Steamworks
///
/// Calls RunFrame and processes events from this Steam Pipe
///
- public static void Frame( HSteamPipe pipe )
+ internal static void Frame( HSteamPipe pipe )
{
SteamAPI_ManualDispatch_RunFrame( pipe );
SteamNetworkingUtils.OutputDebugMessages();
@@ -88,6 +101,11 @@ namespace Steamworks
return;
}
+ if ( OnDebugCallback != null )
+ {
+ OnDebugCallback( msg.Type, CallbackToString( msg ), isServer );
+ }
+
if ( Callbacks.TryGetValue( msg.Type, out var list ) )
{
foreach ( var item in list )
@@ -100,6 +118,28 @@ namespace Steamworks
}
}
+ ///
+ /// Given a callback, try to turn it into a string
+ ///
+ private static string CallbackToString( CallbackMsg_t msg )
+ {
+ if ( !CallbackTypeFactory.All.TryGetValue( msg.Type, out var t ) )
+ return "[not in sdk]";
+
+ var strct = msg.Data.ToType( t );
+ if ( strct == null )
+ return "[null]";
+
+ var str = "";
+
+ foreach ( var field in t.GetFields( System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic ) )
+ {
+ str += $"{field.Name}: \"{field.GetValue( strct )}\"\n";
+ }
+
+ return str.Trim( '\n' );
+ }
+
///
/// A result is a reply to a specific command
///
@@ -129,7 +169,7 @@ namespace Steamworks
/// have to think about it. This has the advantage that
/// you can call .Wait() on async shit and it still works.
///
- public static async void LoopClientAsync()
+ internal static async void LoopClientAsync()
{
while ( ClientPipe != 0 )
{
@@ -143,7 +183,7 @@ namespace Steamworks
/// have to think about it. This has the advantage that
/// you can call .Wait() on async shit and it still works.
///
- public static async void LoopServerAsync()
+ internal static async void LoopServerAsync()
{
while ( ServerPipe != 0 )
{
diff --git a/Facepunch.Steamworks/Generated/CustomEnums.cs b/Facepunch.Steamworks/Generated/CustomEnums.cs
index 1145b2a..00928cc 100644
--- a/Facepunch.Steamworks/Generated/CustomEnums.cs
+++ b/Facepunch.Steamworks/Generated/CustomEnums.cs
@@ -86,9 +86,9 @@ namespace Steamworks
UserAchievementIconFetched = 1109,
GlobalAchievementPercentagesReady = 1110,
LeaderboardUGCSet = 1111,
- PS3TrophiesInstalled = 1112,
+ // PS3TrophiesInstalled = 1112,
GlobalStatsReceived = 1112,
- SocketStatusCallback = 1201,
+ // SocketStatusCallback = 1201,
P2PSessionRequest = 1202,
P2PSessionConnectFail = 1203,
SteamNetConnectionStatusChangedCallback = 1221,
@@ -292,12 +292,12 @@ namespace Steamworks
{ CallbackType.LeaderboardScoreUploaded, typeof( LeaderboardScoreUploaded_t )},
{ CallbackType.NumberOfCurrentPlayers, typeof( NumberOfCurrentPlayers_t )},
{ CallbackType.UserStatsUnloaded, typeof( UserStatsUnloaded_t )},
- { CallbackType.GSStatsUnloaded, typeof( GSStatsUnloaded_t )},
+ // { CallbackType.GSStatsUnloaded, typeof( GSStatsUnloaded_t )},
{ CallbackType.UserAchievementIconFetched, typeof( UserAchievementIconFetched_t )},
{ CallbackType.GlobalAchievementPercentagesReady, typeof( GlobalAchievementPercentagesReady_t )},
{ CallbackType.LeaderboardUGCSet, typeof( LeaderboardUGCSet_t )},
- { CallbackType.PS3TrophiesInstalled, typeof( PS3TrophiesInstalled_t )},
- { CallbackType.GlobalStatsReceived, typeof( GlobalStatsReceived_t )},
+ // { CallbackType.PS3TrophiesInstalled, typeof( PS3TrophiesInstalled_t )},
+ // { CallbackType.GlobalStatsReceived, typeof( GlobalStatsReceived_t )},
// { CallbackType.SocketStatusCallback, typeof( SocketStatusCallback_t )},
{ CallbackType.P2PSessionRequest, typeof( P2PSessionRequest_t )},
{ CallbackType.P2PSessionConnectFail, typeof( P2PSessionConnectFail_t )},
diff --git a/Facepunch.Steamworks/Utility/Utility.cs b/Facepunch.Steamworks/Utility/Utility.cs
index 645f501..3365d2f 100644
--- a/Facepunch.Steamworks/Utility/Utility.cs
+++ b/Facepunch.Steamworks/Utility/Utility.cs
@@ -18,6 +18,14 @@ namespace Steamworks
return (T)Marshal.PtrToStructure( ptr, typeof( T ) );
}
+ static internal object ToType( this IntPtr ptr, System.Type t )
+ {
+ if ( ptr == IntPtr.Zero )
+ return default;
+
+ return Marshal.PtrToStructure( ptr, t );
+ }
+
static internal uint Swap( uint x )
{
return ((x & 0x000000ff) << 24) +
diff --git a/Generator/CodeWriter/CustomEnums.cs b/Generator/CodeWriter/CustomEnums.cs
index 8dbe0b5..c8c92e4 100644
--- a/Generator/CodeWriter/CustomEnums.cs
+++ b/Generator/CodeWriter/CustomEnums.cs
@@ -13,18 +13,25 @@ namespace Generator
StartBlock( "public enum CallbackType" );
foreach ( var c in def.callback_structs.OrderBy( x => x.CallbackId ) )
{
+ if ( Cleanup.IsDeprecated( c.Name ) )
+ Write( "// " );
+
WriteLine( $"{c.Name.Replace( "_t", "" ) } = {c.CallbackId}," );
}
EndBlock();
+ int last = -1;
+
StartBlock( "internal static partial class CallbackTypeFactory" );
StartBlock( "internal static System.Collections.Generic.Dictionary All = new System.Collections.Generic.Dictionary" );
foreach ( var c in def.callback_structs.OrderBy( x => x.CallbackId ) )
{
- if ( Cleanup.IsDeprecated( c.Name ) )
+ if ( Cleanup.IsDeprecated( c.Name ) || last == c.CallbackId )
Write( "// " );
WriteLine( $"{{ CallbackType.{c.Name.Replace( "_t", "" ) }, typeof( {Cleanup.ConvertType(c.Name)} )}}," );
+
+ last = c.CallbackId;
}
EndBlock( ";" );
EndBlock();