@@ -22,15 +22,15 @@ public static class CallbackDispatcher
2222 /// <summary>
2323 /// Register a callback handler
2424 /// </summary>
25- internal static unsafe void RegisterCallback < T > ( ICallbackHandler < T > handler ) where T : struct
25+ internal static unsafe void RegisterCallback < T > ( ICallbackHandler < T > handler ) where T : struct
2626 {
2727 var callbackId = CallbackIdentities . GetCallbackIdentity ( typeof ( T ) ) ;
2828
2929 // Add handler to dictionary
3030 s_callbackHandlers . AddOrUpdate (
3131 callbackId ,
3232 _ => [ handler ] ,
33- ( _ , list ) => { list . Add ( handler ) ; return list ; }
33+ ( _ , list ) => { list . Add ( handler ) ; return list ; }
3434 ) ;
3535
3636 // Register with Steam if this is the first handler for this callback
@@ -40,8 +40,8 @@ internal static unsafe void RegisterCallback<T>(ICallbackHandler<T> handler) whe
4040 var pCallback = Marshal . AllocHGlobal ( Marshal . SizeOf < CCallbackBase > ( ) ) ;
4141 var callback = ( CCallbackBase * ) pCallback ;
4242
43- callback ->m_vfptr = CCallbackBaseVTable . VTablePtr ;
44- callback ->m_nCallbackFlags = 0 ;
43+ callback ->m_vfptr = CCallbackBaseVTable . CallbackVTablePtr ;
44+ callback ->m_nCallbackFlags = 0x02 ; // k_ECallbackFlagsGameServer
4545 callback ->m_iCallback = callbackId ;
4646
4747 // Register with Steam API
@@ -55,7 +55,7 @@ internal static unsafe void RegisterCallback<T>(ICallbackHandler<T> handler) whe
5555 /// <summary>
5656 /// Unregister a callback handler
5757 /// </summary>
58- internal static unsafe void UnregisterCallback < T > ( ICallbackHandler < T > handler ) where T : struct
58+ internal static unsafe void UnregisterCallback < T > ( ICallbackHandler < T > handler ) where T : struct
5959 {
6060 var callbackId = CallbackIdentities . GetCallbackIdentity ( typeof ( T ) ) ;
6161
@@ -80,7 +80,7 @@ internal static unsafe void UnregisterCallback<T>(ICallbackHandler<T> handler) w
8080 /// <summary>
8181 /// Register a call result handler
8282 /// </summary>
83- internal static unsafe void RegisterCallResult < T > ( ulong hAPICall , ICallResultHandler < T > handler ) where T : struct
83+ internal static unsafe void RegisterCallResult < T > ( ulong hAPICall , ICallResultHandler < T > handler ) where T : struct
8484 {
8585 var callbackId = CallbackIdentities . GetCallbackIdentity ( typeof ( T ) ) ;
8686
@@ -91,8 +91,8 @@ internal static unsafe void RegisterCallResult<T>(ulong hAPICall, ICallResultHan
9191 var pCallback = Marshal . AllocHGlobal ( Marshal . SizeOf < CCallbackBase > ( ) ) ;
9292 var callback = ( CCallbackBase * ) pCallback ;
9393
94- callback ->m_vfptr = CCallbackBaseVTable . VTablePtr ;
95- callback ->m_nCallbackFlags = 1 ; // Flag indicating this is a call result
94+ callback ->m_vfptr = CCallbackBaseVTable . CallResultVTablePtr ;
95+ callback ->m_nCallbackFlags = 0x02 ; // k_ECallbackFlagsGameServer
9696 callback ->m_iCallback = callbackId ;
9797
9898 // Register with Steam API
@@ -105,7 +105,7 @@ internal static unsafe void RegisterCallResult<T>(ulong hAPICall, ICallResultHan
105105 /// <summary>
106106 /// Unregister a call result
107107 /// </summary>
108- internal static unsafe void UnregisterCallResult ( ulong hAPICall , IntPtr pCallback )
108+ internal static unsafe void UnregisterCallResult ( ulong hAPICall , IntPtr pCallback )
109109 {
110110 _ = s_callResultHandlers . TryRemove ( hAPICall , out _ ) ;
111111
@@ -119,7 +119,7 @@ internal static unsafe void UnregisterCallResult(ulong hAPICall, IntPtr pCallbac
119119 /// <summary>
120120 /// Internal method called from VTable Run function
121121 /// </summary>
122- internal static unsafe void DispatchCallback ( int callbackId , void * param )
122+ internal static unsafe void DispatchCallback ( int callbackId , void * param )
123123 {
124124 if ( s_callbackHandlers . TryGetValue ( callbackId , out var handlers ) )
125125 {
@@ -140,7 +140,7 @@ internal static unsafe void DispatchCallback(int callbackId, void* param)
140140 /// <summary>
141141 /// Internal method called from VTable RunCallResult function
142142 /// </summary>
143- internal static unsafe void DispatchCallResult ( void * param , bool ioFailure , ulong hAPICall )
143+ internal static unsafe void DispatchCallResult ( void * param , bool ioFailure , ulong hAPICall )
144144 {
145145 if ( s_callResultHandlers . TryRemove ( hAPICall , out var handler ) )
146146 {
@@ -150,7 +150,7 @@ internal static unsafe void DispatchCallResult(void* param, bool ioFailure, ulon
150150 }
151151 catch ( Exception ex )
152152 {
153- Console . WriteLine ( $ "Error dispatching call result { hAPICall } : { ex } ") ;
153+ Console . WriteLine ( $ "Error dispatching call result: { ex } ") ;
154154 }
155155 }
156156 }
@@ -161,7 +161,7 @@ internal static unsafe void DispatchCallResult(void* param, bool ioFailure, ulon
161161/// </summary>
162162internal interface ICallbackHandler
163163{
164- internal unsafe void Run ( void * param ) ;
164+ internal unsafe void Run ( void * param ) ;
165165}
166166
167167/// <summary>
@@ -176,8 +176,8 @@ internal interface ICallbackHandler<T> : ICallbackHandler where T : struct
176176/// </summary>
177177internal interface ICallResultHandler
178178{
179- internal unsafe void Run ( void * param , bool ioFailure ) ;
180- internal void SetAPICall ( ulong hAPICall , IntPtr pCallback ) ;
179+ internal unsafe void Run ( void * param , bool ioFailure ) ;
180+ internal void SetAPICall ( ulong hAPICall , IntPtr pCallback ) ;
181181}
182182
183183/// <summary>
@@ -196,15 +196,15 @@ public sealed class Callback<T> : ICallbackHandler<T>, IDisposable where T : str
196196 private bool _isRegistered ;
197197 private bool _disposed ;
198198
199- private Callback ( Action < T > callback )
199+ private Callback ( Action < T > callback )
200200 {
201201 _callback = callback ;
202202 }
203203
204204 /// <summary>
205205 /// Create and register a new callback
206206 /// </summary>
207- public static Callback < T > Create ( Action < T > callback )
207+ public static Callback < T > Create ( Action < T > callback )
208208 {
209209 var instance = new Callback < T > ( callback ) ;
210210 instance . Register ( ) ;
@@ -229,7 +229,7 @@ private void Unregister()
229229 }
230230 }
231231
232- unsafe void ICallbackHandler . Run ( void * param )
232+ unsafe void ICallbackHandler . Run ( void * param )
233233 {
234234 if ( _callback != null && ! _disposed )
235235 {
@@ -265,15 +265,15 @@ public sealed class CallResult<T> : ICallResultHandler<T>, IDisposable where T :
265265 private IntPtr _pCallback ;
266266 private bool _disposed ;
267267
268- private CallResult ( Action < T , bool > callback )
268+ private CallResult ( Action < T , bool > callback )
269269 {
270270 _callback = callback ;
271271 }
272272
273273 /// <summary>
274274 /// Create and register a new call result
275275 /// </summary>
276- public static CallResult < T > Create ( ulong hAPICall , Action < T , bool > callback )
276+ public static CallResult < T > Create ( ulong hAPICall , Action < T , bool > callback )
277277 {
278278 var instance = new CallResult < T > ( callback ) ;
279279 instance . Set ( hAPICall ) ;
@@ -283,7 +283,7 @@ public static CallResult<T> Create(ulong hAPICall, Action<T, bool> callback)
283283 /// <summary>
284284 /// Set or change the API call to wait for
285285 /// </summary>
286- public void Set ( ulong hAPICall )
286+ public void Set ( ulong hAPICall )
287287 {
288288 if ( _disposed )
289289 return ;
@@ -302,13 +302,13 @@ public void Set(ulong hAPICall)
302302 }
303303 }
304304
305- void ICallResultHandler . SetAPICall ( ulong hAPICall , IntPtr pCallback )
305+ void ICallResultHandler . SetAPICall ( ulong hAPICall , IntPtr pCallback )
306306 {
307307 _hAPICall = hAPICall ;
308308 _pCallback = pCallback ;
309309 }
310310
311- unsafe void ICallResultHandler . Run ( void * param , bool ioFailure )
311+ unsafe void ICallResultHandler . Run ( void * param , bool ioFailure )
312312 {
313313 if ( _callback != null && ! _disposed )
314314 {
@@ -346,7 +346,7 @@ public void Dispose()
346346/// Native callback structure that matches C++ CCallbackBase layout
347347/// This structure is passed to SteamAPI_RegisterCallback
348348/// </summary>
349- [ StructLayout ( LayoutKind . Sequential ) ]
349+ [ StructLayout ( LayoutKind . Sequential , Pack = 4 ) ]
350350internal unsafe struct CCallbackBase
351351{
352352 public IntPtr m_vfptr ;
@@ -359,24 +359,31 @@ internal unsafe struct CCallbackBase
359359/// </summary>
360360internal static class CCallbackBaseVTable
361361{
362- public static IntPtr VTablePtr { get ; private set ; }
362+ public static IntPtr CallbackVTablePtr { get ; private set ; }
363+ public static IntPtr CallResultVTablePtr { get ; private set ; }
363364
364365 static unsafe CCallbackBaseVTable ( )
365366 {
366367 // Allocate VTable with 3 function pointers
367- VTablePtr = Marshal . AllocHGlobal ( IntPtr . Size * 3 ) ;
368- Span < IntPtr > vtable = new ( ( void * ) VTablePtr , 3 ) ;
369-
370- vtable [ 0 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , void * , void > ) & Run ;
371- vtable [ 1 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , void * , bool , ulong , void > ) & RunCallResult ;
372- vtable [ 2 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , int > ) & GetCallbackSizeBytes ;
368+ CallbackVTablePtr = Marshal . AllocHGlobal ( IntPtr . Size * 3 ) ;
369+ CallResultVTablePtr = Marshal . AllocHGlobal ( IntPtr . Size * 3 ) ;
370+ Span < IntPtr > vtable = new ( ( void * ) CallbackVTablePtr , 3 ) ;
371+ Span < IntPtr > callResultVtable = new ( ( void * ) CallResultVTablePtr , 3 ) ;
372+
373+ vtable [ 0 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , void * , void > ) & RunCallback ;
374+ vtable [ 1 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , void * , byte , ulong , void > ) & RunCallbackOverload ;
375+ vtable [ 2 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , int > ) & GetCallbackSizeBytes ;
376+
377+ callResultVtable [ 0 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , void * , void > ) & RunCallResult ;
378+ callResultVtable [ 1 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , void * , byte , ulong , void > ) & RunCallResultOverload ;
379+ callResultVtable [ 2 ] = ( IntPtr ) ( delegate * unmanaged< CCallbackBase * , int > ) & GetCallbackSizeBytes ;
373380 }
374381
375382 /// <summary>
376383 /// Called by Steam when a callback is triggered
377384 /// </summary>
378385 [ UnmanagedCallersOnly ]
379- private static unsafe void Run ( CCallbackBase * self , void * param )
386+ private static unsafe void RunCallback ( CCallbackBase * self , void * param )
380387 {
381388 try
382389 {
@@ -389,15 +396,40 @@ private static unsafe void Run(CCallbackBase* self, void* param)
389396 }
390397 }
391398
399+
400+ /// <summary>
401+ /// Called by Steam when a callback is triggered, overload version
402+ /// </summary>
403+ [ UnmanagedCallersOnly ]
404+ private static unsafe void RunCallbackOverload ( CCallbackBase * self , void * param , byte ioFailure , ulong hAPICall )
405+ {
406+ try
407+ {
408+ var callbackId = self ->m_iCallback ;
409+ CallbackDispatcher . DispatchCallback ( callbackId , param ) ;
410+ }
411+ catch ( Exception ex )
412+ {
413+ Console . WriteLine ( $ "Exception in CCallbackBase.RunCallResult: { ex } ") ;
414+ }
415+ }
416+
417+ [ UnmanagedCallersOnly ]
418+ private static unsafe void RunCallResult ( CCallbackBase * self , void * param )
419+ {
420+ throw new NotImplementedException ( "Shouldn't be called." ) ;
421+ }
422+
423+
392424 /// <summary>
393425 /// Called by Steam when a call result is ready
394426 /// </summary>
395427 [ UnmanagedCallersOnly ]
396- private static unsafe void RunCallResult ( CCallbackBase * self , void * param , bool ioFailure , ulong hAPICall )
428+ private static unsafe void RunCallResultOverload ( CCallbackBase * self , void * param , byte ioFailure , ulong hAPICall )
397429 {
398430 try
399431 {
400- CallbackDispatcher . DispatchCallResult ( param , ioFailure , hAPICall ) ;
432+ CallbackDispatcher . DispatchCallResult ( param , ioFailure == 1 , hAPICall ) ;
401433 }
402434 catch ( Exception ex )
403435 {
@@ -409,8 +441,9 @@ private static unsafe void RunCallResult(CCallbackBase* self, void* param, bool
409441 /// Returns the size of the callback structure
410442 /// </summary>
411443 [ UnmanagedCallersOnly ]
412- private static unsafe int GetCallbackSizeBytes ( CCallbackBase * self )
444+ private static unsafe int GetCallbackSizeBytes ( CCallbackBase * self )
413445 {
446+ Console . WriteLine ( $ "GetCallbackSizeBytes") ;
414447 try
415448 {
416449 int callbackId = self ->m_iCallback ;
0 commit comments