mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2025-02-10 13:49:07 +03:00
Updated Implementation to use flat api
This commit is contained in:
parent
92b45c7596
commit
d8e5a48f65
Binary file not shown.
80
Facepunch.Steamworks/Callbacks/CallResult.cs
Normal file
80
Facepunch.Steamworks/Callbacks/CallResult.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using Steamworks.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An awaitable version of a SteamAPICall_t
|
||||||
|
/// </summary>
|
||||||
|
internal struct CallResult<T> : INotifyCompletion where T : struct, ICallbackData
|
||||||
|
{
|
||||||
|
SteamAPICall_t call;
|
||||||
|
|
||||||
|
public CallResult( SteamAPICall_t call )
|
||||||
|
{
|
||||||
|
this.call = call;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This gets called if IsComplete returned false on the first call.
|
||||||
|
/// The Action "continues" the async call. We pass it to the Dispatch
|
||||||
|
/// to be called when the callback returns.
|
||||||
|
/// </summary>
|
||||||
|
public void OnCompleted( Action continuation )
|
||||||
|
{
|
||||||
|
Dispatch.OnCallComplete( call, continuation );
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the result. This is called internally by the async shit.
|
||||||
|
/// </summary>
|
||||||
|
public T? GetResult()
|
||||||
|
{
|
||||||
|
if ( !SteamUtils.IsCallComplete( call, out var failed ) || failed )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var t = default( T );
|
||||||
|
var size = t.DataSize;
|
||||||
|
var ptr = Marshal.AllocHGlobal( size );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( !SteamUtils.Internal.GetAPICallResult( call, ptr, size, (int) t.CallbackType, ref failed ) || failed )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return ((T)Marshal.PtrToStructure( ptr, typeof( T ) ));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal( ptr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return true if complete or failed
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCompleted
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if ( SteamUtils.IsCallComplete( call, out var failed ) || failed )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is what makes this struct awaitable
|
||||||
|
/// </summary>
|
||||||
|
internal CallResult<T> GetAwaiter()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,43 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Steamworks.Data;
|
|
||||||
|
|
||||||
namespace Steamworks
|
|
||||||
{
|
|
||||||
[StructLayout( LayoutKind.Sequential )]
|
|
||||||
internal partial class Callback
|
|
||||||
{
|
|
||||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
|
||||||
public delegate void Run( IntPtr thisptr, IntPtr pvParam );
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
|
||||||
public delegate void RunCall( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall );
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
|
||||||
public delegate int GetCallbackSizeBytes( IntPtr thisptr );
|
|
||||||
|
|
||||||
internal enum Flags : byte
|
|
||||||
{
|
|
||||||
Registered = 0x01,
|
|
||||||
GameServer = 0x02
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntPtr vTablePtr;
|
|
||||||
public byte CallbackFlags;
|
|
||||||
public int CallbackId;
|
|
||||||
|
|
||||||
//
|
|
||||||
// These are functions that are on CCallback but are never called
|
|
||||||
// We could just send a IntPtr.Zero but it's probably safer to throw a
|
|
||||||
// big apeshit message if steam changes its behaviour at some point
|
|
||||||
//
|
|
||||||
[MonoPInvokeCallback]
|
|
||||||
internal static void RunStub( IntPtr self, IntPtr param, bool failure, SteamAPICall_t call ) =>
|
|
||||||
throw new System.Exception( "Something changed in the Steam API and now CCallbackBack is calling the CallResult function [Run( void *pvParam, bool bIOFailure, SteamAPICall_t hSteamAPICall )]" );
|
|
||||||
|
|
||||||
[MonoPInvokeCallback]
|
|
||||||
internal static int SizeStub( IntPtr self ) =>
|
|
||||||
throw new System.Exception( "Something changed in the Steam API and now CCallbackBack is calling the GetSize function [GetCallbackSizeBytes()]" );
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
using Steamworks.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Steamworks
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Created on registration of a callback
|
|
||||||
//
|
|
||||||
internal class Event : IDisposable
|
|
||||||
{
|
|
||||||
internal static List<IDisposable> AllClient = new List<IDisposable>();
|
|
||||||
internal static List<IDisposable> AllServer = new List<IDisposable>();
|
|
||||||
|
|
||||||
internal static void DisposeAllClient()
|
|
||||||
{
|
|
||||||
foreach ( var a in AllClient.ToArray() )
|
|
||||||
{
|
|
||||||
a.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
AllClient.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void DisposeAllServer()
|
|
||||||
{
|
|
||||||
foreach ( var a in AllServer.ToArray() )
|
|
||||||
{
|
|
||||||
a.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
AllServer.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Register( Callback.Run func, int size, int callbackId, bool gameserver )
|
|
||||||
{
|
|
||||||
var r = new Event();
|
|
||||||
r.vTablePtr = BuildVTable( func, r.Allocations );
|
|
||||||
|
|
||||||
//
|
|
||||||
// Create the callback object
|
|
||||||
//
|
|
||||||
var cb = new Callback();
|
|
||||||
cb.vTablePtr = r.vTablePtr;
|
|
||||||
cb.CallbackFlags = gameserver ? (byte)0x02 : (byte)0;
|
|
||||||
cb.CallbackId = callbackId;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native
|
|
||||||
//
|
|
||||||
r.PinnedCallback = GCHandle.Alloc( cb, GCHandleType.Pinned );
|
|
||||||
|
|
||||||
//
|
|
||||||
// Register the callback with Steam
|
|
||||||
//
|
|
||||||
SteamClient.RegisterCallback( r.PinnedCallback.AddrOfPinnedObject(), cb.CallbackId );
|
|
||||||
|
|
||||||
r.IsAllocated = true;
|
|
||||||
|
|
||||||
if ( gameserver )
|
|
||||||
Event.AllServer.Add( r );
|
|
||||||
else
|
|
||||||
Event.AllClient.Add( r );
|
|
||||||
}
|
|
||||||
|
|
||||||
static IntPtr BuildVTable( Callback.Run run, List<GCHandle> allocations )
|
|
||||||
{
|
|
||||||
var RunStub = (Callback.RunCall)Callback.RunStub;
|
|
||||||
var SizeStub = (Callback.GetCallbackSizeBytes)Callback.SizeStub;
|
|
||||||
|
|
||||||
allocations.Add( GCHandle.Alloc( run ) );
|
|
||||||
allocations.Add( GCHandle.Alloc( RunStub ) );
|
|
||||||
allocations.Add( GCHandle.Alloc( SizeStub ) );
|
|
||||||
|
|
||||||
var a = Marshal.GetFunctionPointerForDelegate<Callback.Run>( run );
|
|
||||||
var b = Marshal.GetFunctionPointerForDelegate<Callback.RunCall>( RunStub );
|
|
||||||
var c = Marshal.GetFunctionPointerForDelegate<Callback.GetCallbackSizeBytes>( SizeStub );
|
|
||||||
|
|
||||||
var vt = Marshal.AllocHGlobal( IntPtr.Size * 3 );
|
|
||||||
|
|
||||||
// Windows switches the function positions
|
|
||||||
#if PLATFORM_WIN
|
|
||||||
Marshal.WriteIntPtr( vt, IntPtr.Size * 0, b );
|
|
||||||
Marshal.WriteIntPtr( vt, IntPtr.Size * 1, a );
|
|
||||||
Marshal.WriteIntPtr( vt, IntPtr.Size * 2, c );
|
|
||||||
#else
|
|
||||||
Marshal.WriteIntPtr( vt, IntPtr.Size * 0, a );
|
|
||||||
Marshal.WriteIntPtr( vt, IntPtr.Size * 1, b );
|
|
||||||
Marshal.WriteIntPtr( vt, IntPtr.Size * 2, c );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return vt;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsAllocated;
|
|
||||||
List<GCHandle> Allocations = new List<GCHandle>();
|
|
||||||
internal IntPtr vTablePtr;
|
|
||||||
internal GCHandle PinnedCallback;
|
|
||||||
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if ( !IsAllocated ) return;
|
|
||||||
IsAllocated = false;
|
|
||||||
|
|
||||||
if ( !PinnedCallback.IsAllocated )
|
|
||||||
throw new System.Exception( "Callback isn't allocated!?" );
|
|
||||||
|
|
||||||
SteamClient.UnregisterCallback( PinnedCallback.AddrOfPinnedObject() );
|
|
||||||
|
|
||||||
foreach ( var a in Allocations )
|
|
||||||
{
|
|
||||||
if ( a.IsAllocated )
|
|
||||||
a.Free();
|
|
||||||
}
|
|
||||||
|
|
||||||
Allocations = null;
|
|
||||||
|
|
||||||
PinnedCallback.Free();
|
|
||||||
|
|
||||||
if ( vTablePtr != IntPtr.Zero )
|
|
||||||
{
|
|
||||||
Marshal.FreeHGlobal( vTablePtr );
|
|
||||||
vTablePtr = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Event()
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
17
Facepunch.Steamworks/Callbacks/ICallbackData.cs
Normal file
17
Facepunch.Steamworks/Callbacks/ICallbackData.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using Steamworks.Data;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gives us a generic way to get the CallbackId of structs
|
||||||
|
/// </summary>
|
||||||
|
internal interface ICallbackData
|
||||||
|
{
|
||||||
|
CallbackType CallbackType { get; }
|
||||||
|
int DataSize { get; }
|
||||||
|
}
|
||||||
|
}
|
205
Facepunch.Steamworks/Classes/Dispatch.cs
Normal file
205
Facepunch.Steamworks/Classes/Dispatch.cs
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Steamworks.Data;
|
||||||
|
using Steamworks;
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Manually pumps Steam's message queue and dispatches those
|
||||||
|
/// events to any waiting callbacks/callresults.
|
||||||
|
/// </summary>
|
||||||
|
internal static class Dispatch
|
||||||
|
{
|
||||||
|
#region interop
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ManualDispatch_Init", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
internal static extern void SteamAPI_ManualDispatch_Init();
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ManualDispatch_RunFrame", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
internal static extern void SteamAPI_ManualDispatch_RunFrame( HSteamPipe pipe );
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ManualDispatch_GetNextCallback", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
[return: MarshalAs( UnmanagedType.I1 )]
|
||||||
|
internal static extern bool SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe pipe, [In, Out] ref CallbackMsg_t msg );
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ManualDispatch_FreeLastCallback", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
[return: MarshalAs( UnmanagedType.I1 )]
|
||||||
|
internal static extern bool SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe pipe );
|
||||||
|
|
||||||
|
[StructLayout( LayoutKind.Sequential, Pack = Platform.StructPlatformPackSize )]
|
||||||
|
internal struct CallbackMsg_t
|
||||||
|
{
|
||||||
|
public HSteamUser m_hSteamUser; // Specific user to whom this callback applies.
|
||||||
|
public CallbackType Type; // Callback identifier. (Corresponds to the k_iCallback enum in the callback structure.)
|
||||||
|
public IntPtr Data; // Points to the callback structure
|
||||||
|
public int DataSize; // Size of the data pointed to by m_pubParam
|
||||||
|
};
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
internal static HSteamPipe ClientPipe { get; set; }
|
||||||
|
internal static HSteamPipe ServerPipe { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This gets called from Client/Server Init
|
||||||
|
/// It's important to switch to the manual dipatcher
|
||||||
|
/// </summary>
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
SteamAPI_ManualDispatch_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calls RunFrame and processes events from this Steam Pipe
|
||||||
|
/// </summary>
|
||||||
|
public static void Frame( HSteamPipe pipe )
|
||||||
|
{
|
||||||
|
SteamAPI_ManualDispatch_RunFrame( pipe );
|
||||||
|
|
||||||
|
CallbackMsg_t msg = default;
|
||||||
|
|
||||||
|
while ( SteamAPI_ManualDispatch_GetNextCallback( pipe, ref msg ) )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProcessCallback( msg );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SteamAPI_ManualDispatch_FreeLastCallback( pipe );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A callback is a general global message
|
||||||
|
/// </summary>
|
||||||
|
private static void ProcessCallback( CallbackMsg_t msg )
|
||||||
|
{
|
||||||
|
// Is this a special callback telling us that the call result is ready?
|
||||||
|
if ( msg.Type == CallbackType.SteamAPICallCompleted )
|
||||||
|
{
|
||||||
|
ProcessResult( msg );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( Callbacks.TryGetValue( msg.Type, out var list ) )
|
||||||
|
{
|
||||||
|
foreach ( var item in list )
|
||||||
|
{
|
||||||
|
item.action( msg.Data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A result is a reply to a specific command
|
||||||
|
/// </summary>
|
||||||
|
private static void ProcessResult( CallbackMsg_t msg )
|
||||||
|
{
|
||||||
|
var result = msg.Data.ToType<SteamAPICallCompleted_t>();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Do we have an entry added via OnCallComplete
|
||||||
|
//
|
||||||
|
if ( !ResultCallbacks.TryGetValue( result.AsyncCall, out var callbackInfo ) )
|
||||||
|
{
|
||||||
|
// Do we care? Should we throw errors?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove it before we do anything, incase the continuation throws exceptions
|
||||||
|
ResultCallbacks.Remove( result.AsyncCall );
|
||||||
|
|
||||||
|
// At this point whatever async routine called this
|
||||||
|
// continues running.
|
||||||
|
callbackInfo.continuation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pumps the queue in an async loop so we don't
|
||||||
|
/// have to think about it. This has the advantage that
|
||||||
|
/// you can call .Wait() on async shit and it still works.
|
||||||
|
/// </summary>
|
||||||
|
public static async void LoopClientAsync()
|
||||||
|
{
|
||||||
|
while ( ClientPipe != 0 )
|
||||||
|
{
|
||||||
|
Frame( ClientPipe );
|
||||||
|
await Task.Delay( 16 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pumps the queue in an async loop so we don't
|
||||||
|
/// have to think about it. This has the advantage that
|
||||||
|
/// you can call .Wait() on async shit and it still works.
|
||||||
|
/// </summary>
|
||||||
|
public static async void LoopServerAsync()
|
||||||
|
{
|
||||||
|
while ( ServerPipe != 0 )
|
||||||
|
{
|
||||||
|
Frame( ServerPipe );
|
||||||
|
await Task.Delay( 32 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ResultCallback
|
||||||
|
{
|
||||||
|
public Action continuation;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Dictionary<ulong, ResultCallback> ResultCallbacks = new Dictionary<ulong, ResultCallback>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Watch for a steam api call
|
||||||
|
/// </summary>
|
||||||
|
internal static void OnCallComplete( SteamAPICall_t call, Action continuation )
|
||||||
|
{
|
||||||
|
ResultCallbacks[call.Value] = new ResultCallback
|
||||||
|
{
|
||||||
|
continuation = continuation
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Callback
|
||||||
|
{
|
||||||
|
public Action<IntPtr> action;
|
||||||
|
public bool server;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Dictionary<CallbackType, List<Callback>> Callbacks = new Dictionary<CallbackType, List<Callback>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Install a global callback. The passed function will get called if it's all good.
|
||||||
|
/// </summary>
|
||||||
|
internal static void Install<T>( Action<T> p, bool server = false ) where T : ICallbackData
|
||||||
|
{
|
||||||
|
var t = default( T );
|
||||||
|
var type = t.CallbackType;
|
||||||
|
|
||||||
|
if ( !Callbacks.TryGetValue( type, out var list ) )
|
||||||
|
{
|
||||||
|
list = new List<Callback>();
|
||||||
|
Callbacks[type] = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Add( new Callback
|
||||||
|
{
|
||||||
|
action = x => p( x.ToType<T>() ),
|
||||||
|
server = server
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void Wipe()
|
||||||
|
{
|
||||||
|
Callbacks = new Dictionary<CallbackType, List<Callback>>();
|
||||||
|
ResultCallbacks = new Dictionary<ulong, ResultCallback>();
|
||||||
|
ClientPipe = 0;
|
||||||
|
ServerPipe = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,10 +11,28 @@ namespace Steamworks
|
|||||||
public List<Connection> Connected = new List<Connection>();
|
public List<Connection> Connected = new List<Connection>();
|
||||||
public Socket Socket { get; internal set; }
|
public Socket Socket { get; internal set; }
|
||||||
|
|
||||||
public bool Close() => Socket.Close();
|
|
||||||
|
|
||||||
public override string ToString() => Socket.ToString();
|
public override string ToString() => Socket.ToString();
|
||||||
|
|
||||||
|
internal HSteamNetPollGroup pollGroup;
|
||||||
|
|
||||||
|
internal void Initialize()
|
||||||
|
{
|
||||||
|
pollGroup = SteamNetworkingSockets.Internal.CreatePollGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Close()
|
||||||
|
{
|
||||||
|
if ( SteamNetworkingSockets.Internal.IsValid )
|
||||||
|
{
|
||||||
|
SteamNetworkingSockets.Internal.DestroyPollGroup( pollGroup );
|
||||||
|
Socket.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
pollGroup = 0;
|
||||||
|
Socket = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void OnConnectionChanged( Connection connection, ConnectionInfo data )
|
public virtual void OnConnectionChanged( Connection connection, ConnectionInfo data )
|
||||||
{
|
{
|
||||||
switch ( data.State )
|
switch ( data.State )
|
||||||
@ -40,6 +58,8 @@ namespace Steamworks
|
|||||||
{
|
{
|
||||||
connection.Accept();
|
connection.Accept();
|
||||||
Connecting.Add( connection );
|
Connecting.Add( connection );
|
||||||
|
|
||||||
|
SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, pollGroup );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -67,9 +87,10 @@ namespace Steamworks
|
|||||||
int processed = 0;
|
int processed = 0;
|
||||||
IntPtr messageBuffer = Marshal.AllocHGlobal( IntPtr.Size * bufferSize );
|
IntPtr messageBuffer = Marshal.AllocHGlobal( IntPtr.Size * bufferSize );
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
processed = SteamNetworkingSockets.Internal.ReceiveMessagesOnListenSocket( Socket, messageBuffer, bufferSize );
|
processed = SteamNetworkingSockets.Internal.ReceiveMessagesOnPollGroup( pollGroup, messageBuffer, bufferSize );
|
||||||
|
|
||||||
for ( int i = 0; i < processed; i++ )
|
for ( int i = 0; i < processed; i++ )
|
||||||
{
|
{
|
||||||
@ -81,6 +102,7 @@ namespace Steamworks
|
|||||||
Marshal.FreeHGlobal( messageBuffer );
|
Marshal.FreeHGlobal( messageBuffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Overwhelmed our buffer, keep going
|
// Overwhelmed our buffer, keep going
|
||||||
//
|
//
|
||||||
|
50
Facepunch.Steamworks/Classes/SteamApi.cs
Normal file
50
Facepunch.Steamworks/Classes/SteamApi.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Steamworks.Data;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
internal static class SteamAPI
|
||||||
|
{
|
||||||
|
internal static class Native
|
||||||
|
{
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_Init", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
[return: MarshalAs( UnmanagedType.I1 )]
|
||||||
|
public static extern bool SteamAPI_Init();
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_Shutdown", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern void SteamAPI_Shutdown();
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_GetHSteamPipe", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern HSteamPipe SteamAPI_GetHSteamPipe();
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_RestartAppIfNecessary", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
[return: MarshalAs( UnmanagedType.I1 )]
|
||||||
|
public static extern bool SteamAPI_RestartAppIfNecessary( uint unOwnAppID );
|
||||||
|
|
||||||
|
}
|
||||||
|
static internal bool Init()
|
||||||
|
{
|
||||||
|
return Native.SteamAPI_Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal void Shutdown()
|
||||||
|
{
|
||||||
|
Native.SteamAPI_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal HSteamPipe GetHSteamPipe()
|
||||||
|
{
|
||||||
|
return Native.SteamAPI_GetHSteamPipe();
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal bool RestartAppIfNecessary( uint unOwnAppID )
|
||||||
|
{
|
||||||
|
return Native.SteamAPI_RestartAppIfNecessary( unOwnAppID );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
40
Facepunch.Steamworks/Classes/SteamGameServer.cs
Normal file
40
Facepunch.Steamworks/Classes/SteamGameServer.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Steamworks.Data;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
internal static class SteamGameServer
|
||||||
|
{
|
||||||
|
internal static class Native
|
||||||
|
{
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamGameServer_RunCallbacks", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern void SteamGameServer_RunCallbacks();
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamGameServer_Shutdown", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern void SteamGameServer_Shutdown();
|
||||||
|
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamGameServer_GetHSteamPipe", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
public static extern HSteamPipe SteamGameServer_GetHSteamPipe();
|
||||||
|
|
||||||
|
}
|
||||||
|
static internal void RunCallbacks()
|
||||||
|
{
|
||||||
|
Native.SteamGameServer_RunCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal void Shutdown()
|
||||||
|
{
|
||||||
|
Native.SteamGameServer_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal HSteamPipe GetHSteamPipe()
|
||||||
|
{
|
||||||
|
return Native.SteamGameServer_GetHSteamPipe();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
24
Facepunch.Steamworks/Classes/SteamInternal.cs
Normal file
24
Facepunch.Steamworks/Classes/SteamInternal.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Steamworks.Data;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
internal static class SteamInternal
|
||||||
|
{
|
||||||
|
internal static class Native
|
||||||
|
{
|
||||||
|
[DllImport( Platform.LibraryName, EntryPoint = "SteamInternal_GameServer_Init", CallingConvention = CallingConvention.Cdecl )]
|
||||||
|
[return: MarshalAs( UnmanagedType.I1 )]
|
||||||
|
public static extern bool SteamInternal_GameServer_Init( uint unIP, ushort usPort, ushort usGamePort, ushort usQueryPort, int eServerMode, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string pchVersionString );
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal bool GameServer_Init( uint unIP, ushort usPort, ushort usGamePort, ushort usQueryPort, int eServerMode, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string pchVersionString )
|
||||||
|
{
|
||||||
|
return Native.SteamInternal_GameServer_Init( unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,107 +0,0 @@
|
|||||||
namespace Steamworks.Data
|
|
||||||
{
|
|
||||||
/// High level connection status
|
|
||||||
public enum ConnectionState
|
|
||||||
{
|
|
||||||
|
|
||||||
/// Dummy value used to indicate an error condition in the API.
|
|
||||||
/// Specified connection doesn't exist or has already been closed.
|
|
||||||
None = 0,
|
|
||||||
|
|
||||||
/// We are trying to establish whether peers can talk to each other,
|
|
||||||
/// whether they WANT to talk to each other, perform basic auth,
|
|
||||||
/// and exchange crypt keys.
|
|
||||||
///
|
|
||||||
/// - For connections on the "client" side (initiated locally):
|
|
||||||
/// We're in the process of trying to establish a connection.
|
|
||||||
/// Depending on the connection type, we might not know who they are.
|
|
||||||
/// Note that it is not possible to tell if we are waiting on the
|
|
||||||
/// network to complete handshake packets, or for the application layer
|
|
||||||
/// to accept the connection.
|
|
||||||
///
|
|
||||||
/// - For connections on the "server" side (accepted through listen socket):
|
|
||||||
/// We have completed some basic handshake and the client has presented
|
|
||||||
/// some proof of identity. The connection is ready to be accepted
|
|
||||||
/// using AcceptConnection().
|
|
||||||
///
|
|
||||||
/// In either case, any unreliable packets sent now are almost certain
|
|
||||||
/// to be dropped. Attempts to receive packets are guaranteed to fail.
|
|
||||||
/// You may send messages if the send mode allows for them to be queued.
|
|
||||||
/// but if you close the connection before the connection is actually
|
|
||||||
/// established, any queued messages will be discarded immediately.
|
|
||||||
/// (We will not attempt to flush the queue and confirm delivery to the
|
|
||||||
/// remote host, which ordinarily happens when a connection is closed.)
|
|
||||||
Connecting = 1,
|
|
||||||
|
|
||||||
/// Some connection types use a back channel or trusted 3rd party
|
|
||||||
/// for earliest communication. If the server accepts the connection,
|
|
||||||
/// then these connections switch into the rendezvous state. During this
|
|
||||||
/// state, we still have not yet established an end-to-end route (through
|
|
||||||
/// the relay network), and so if you send any messages unreliable, they
|
|
||||||
/// are going to be discarded.
|
|
||||||
FindingRoute = 2,
|
|
||||||
|
|
||||||
/// We've received communications from our peer (and we know
|
|
||||||
/// who they are) and are all good. If you close the connection now,
|
|
||||||
/// we will make our best effort to flush out any reliable sent data that
|
|
||||||
/// has not been acknowledged by the peer. (But note that this happens
|
|
||||||
/// from within the application process, so unlike a TCP connection, you are
|
|
||||||
/// not totally handing it off to the operating system to deal with it.)
|
|
||||||
Connected = 3,
|
|
||||||
|
|
||||||
/// Connection has been closed by our peer, but not closed locally.
|
|
||||||
/// The connection still exists from an API perspective. You must close the
|
|
||||||
/// handle to free up resources. If there are any messages in the inbound queue,
|
|
||||||
/// you may retrieve them. Otherwise, nothing may be done with the connection
|
|
||||||
/// except to close it.
|
|
||||||
///
|
|
||||||
/// This stats is similar to CLOSE_WAIT in the TCP state machine.
|
|
||||||
ClosedByPeer = 4,
|
|
||||||
|
|
||||||
/// A disruption in the connection has been detected locally. (E.g. timeout,
|
|
||||||
/// local internet connection disrupted, etc.)
|
|
||||||
///
|
|
||||||
/// The connection still exists from an API perspective. You must close the
|
|
||||||
/// handle to free up resources.
|
|
||||||
///
|
|
||||||
/// Attempts to send further messages will fail. Any remaining received messages
|
|
||||||
/// in the queue are available.
|
|
||||||
ProblemDetectedLocally = 5,
|
|
||||||
|
|
||||||
//
|
|
||||||
// The following values are used internally and will not be returned by any API.
|
|
||||||
// We document them here to provide a little insight into the state machine that is used
|
|
||||||
// under the hood.
|
|
||||||
//
|
|
||||||
|
|
||||||
/// We've disconnected on our side, and from an API perspective the connection is closed.
|
|
||||||
/// No more data may be sent or received. All reliable data has been flushed, or else
|
|
||||||
/// we've given up and discarded it. We do not yet know for sure that the peer knows
|
|
||||||
/// the connection has been closed, however, so we're just hanging around so that if we do
|
|
||||||
/// get a packet from them, we can send them the appropriate packets so that they can
|
|
||||||
/// know why the connection was closed (and not have to rely on a timeout, which makes
|
|
||||||
/// it appear as if something is wrong).
|
|
||||||
FinWait = -1,
|
|
||||||
|
|
||||||
/// We've disconnected on our side, and from an API perspective the connection is closed.
|
|
||||||
/// No more data may be sent or received. From a network perspective, however, on the wire,
|
|
||||||
/// we have not yet given any indication to the peer that the connection is closed.
|
|
||||||
/// We are in the process of flushing out the last bit of reliable data. Once that is done,
|
|
||||||
/// we will inform the peer that the connection has been closed, and transition to the
|
|
||||||
/// FinWait state.
|
|
||||||
///
|
|
||||||
/// Note that no indication is given to the remote host that we have closed the connection,
|
|
||||||
/// until the data has been flushed. If the remote host attempts to send us data, we will
|
|
||||||
/// do whatever is necessary to keep the connection alive until it can be closed properly.
|
|
||||||
/// But in fact the data will be discarded, since there is no way for the application to
|
|
||||||
/// read it back. Typically this is not a problem, as application protocols that utilize
|
|
||||||
/// the lingering functionality are designed for the remote host to wait for the response
|
|
||||||
/// before sending any more data.
|
|
||||||
Linger = -2,
|
|
||||||
|
|
||||||
/// Connection is completely inactive and ready to be destroyed
|
|
||||||
Dead = -3,
|
|
||||||
|
|
||||||
Force32Bit = 0x7fffffff
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
namespace Steamworks.Data
|
|
||||||
{
|
|
||||||
internal enum NetConfig : int
|
|
||||||
{
|
|
||||||
Invalid = 0,
|
|
||||||
FakePacketLoss_Send = 2,
|
|
||||||
FakePacketLoss_Recv = 3,
|
|
||||||
FakePacketLag_Send = 4,
|
|
||||||
FakePacketLag_Recv = 5,
|
|
||||||
|
|
||||||
FakePacketReorder_Send = 6,
|
|
||||||
FakePacketReorder_Recv = 7,
|
|
||||||
|
|
||||||
FakePacketReorder_Time = 8,
|
|
||||||
|
|
||||||
FakePacketDup_Send = 26,
|
|
||||||
FakePacketDup_Recv = 27,
|
|
||||||
|
|
||||||
FakePacketDup_TimeMax = 28,
|
|
||||||
|
|
||||||
TimeoutInitial = 24,
|
|
||||||
|
|
||||||
TimeoutConnected = 25,
|
|
||||||
|
|
||||||
SendBufferSize = 9,
|
|
||||||
|
|
||||||
SendRateMin = 10,
|
|
||||||
SendRateMax = 11,
|
|
||||||
|
|
||||||
NagleTime = 12,
|
|
||||||
|
|
||||||
IP_AllowWithoutAuth = 23,
|
|
||||||
|
|
||||||
SDRClient_ConsecutitivePingTimeoutsFailInitial = 19,
|
|
||||||
|
|
||||||
SDRClient_ConsecutitivePingTimeoutsFail = 20,
|
|
||||||
|
|
||||||
SDRClient_MinPingsBeforePingAccurate = 21,
|
|
||||||
|
|
||||||
SDRClient_SingleSocket = 22,
|
|
||||||
|
|
||||||
SDRClient_ForceRelayCluster = 29,
|
|
||||||
|
|
||||||
SDRClient_DebugTicketAddress = 30,
|
|
||||||
|
|
||||||
SDRClient_ForceProxyAddr = 31,
|
|
||||||
|
|
||||||
LogLevel_AckRTT = 13,
|
|
||||||
LogLevel_PacketDecode = 14,
|
|
||||||
LogLevel_Message = 15,
|
|
||||||
LogLevel_PacketGaps = 16,
|
|
||||||
LogLevel_P2PRendezvous = 17,
|
|
||||||
LogLevel_SDRRelayPings = 18,
|
|
||||||
|
|
||||||
Force32Bit = 0x7fffffff
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
namespace Steamworks.Data
|
|
||||||
{
|
|
||||||
enum NetConfigResult
|
|
||||||
{
|
|
||||||
BadValue = -1, // No such configuration value
|
|
||||||
BadScopeObj = -2, // Bad connection handle, etc
|
|
||||||
BufferTooSmall = -3, // Couldn't fit the result in your buffer
|
|
||||||
OK = 1,
|
|
||||||
OKInherited = 2, // A value was not set at this level, but the effective (inherited) value was returned.
|
|
||||||
|
|
||||||
Force32Bit = 0x7fffffff
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
namespace Steamworks.Data
|
|
||||||
{
|
|
||||||
enum NetConfigType
|
|
||||||
{
|
|
||||||
Int32 = 1,
|
|
||||||
Int64 = 2,
|
|
||||||
Float = 3,
|
|
||||||
String = 4,
|
|
||||||
FunctionPtr = 5, // NOTE: When setting callbacks, you should put the pointer into a variable and pass a pointer to that variable.
|
|
||||||
|
|
||||||
Force32Bit = 0x7fffffff
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
namespace Steamworks.Data
|
|
||||||
{
|
|
||||||
internal enum NetScope : int
|
|
||||||
{
|
|
||||||
Global = 1,
|
|
||||||
SocketsInterface = 2,
|
|
||||||
ListenSocket = 3,
|
|
||||||
Connection = 4,
|
|
||||||
|
|
||||||
Force32Bit = 0x7fffffff
|
|
||||||
}
|
|
||||||
}
|
|
@ -11,27 +11,7 @@ namespace Steamworks.ServerList
|
|||||||
{
|
{
|
||||||
|
|
||||||
#region ISteamMatchmakingServers
|
#region ISteamMatchmakingServers
|
||||||
|
internal static ISteamMatchmakingServers Internal => SteamMatchmakingServers.Internal;
|
||||||
static ISteamMatchmakingServers _internal;
|
|
||||||
internal static ISteamMatchmakingServers Internal
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamMatchmakingServers();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,32 +11,21 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Exposes a wide range of information and actions for applications and Downloadable Content (DLC).
|
/// Exposes a wide range of information and actions for applications and Downloadable Content (DLC).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamApps
|
public class SteamApps : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamApps _internal;
|
internal static ISteamApps Internal;
|
||||||
internal static ISteamApps Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
|
|
||||||
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
get
|
Internal = new ISteamApps( server );
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamApps();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
DlcInstalled_t.Install( x => OnDlcInstalled?.Invoke( x.AppID ) );
|
Dispatch.Install<DlcInstalled_t>( x => OnDlcInstalled?.Invoke( x.AppID ) );
|
||||||
NewUrlLaunchParameters_t.Install( x => OnNewLaunchParameters?.Invoke() );
|
Dispatch.Install<NewUrlLaunchParameters_t>( x => OnNewLaunchParameters?.Invoke() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -29,76 +29,72 @@ namespace Steamworks
|
|||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
SteamApps.InstallEvents();
|
//
|
||||||
SteamUtils.InstallEvents();
|
// Dispatch is responsible for pumping the
|
||||||
SteamParental.InstallEvents();
|
// event loop.
|
||||||
SteamMusic.InstallEvents();
|
//
|
||||||
SteamVideo.InstallEvents();
|
Dispatch.Init();
|
||||||
SteamUser.InstallEvents();
|
Dispatch.ClientPipe = SteamAPI.GetHSteamPipe();
|
||||||
SteamFriends.InstallEvents();
|
Console.WriteLine( $"Dispatch.ClientPipe = {Dispatch.ClientPipe.Value}" );
|
||||||
SteamScreenshots.InstallEvents();
|
|
||||||
SteamUserStats.InstallEvents();
|
AddInterface<SteamApps>();
|
||||||
SteamInventory.InstallEvents();
|
AddInterface<SteamFriends>();
|
||||||
SteamNetworking.InstallEvents();
|
AddInterface<SteamInput>();
|
||||||
SteamMatchmaking.InstallEvents();
|
AddInterface<SteamInventory>();
|
||||||
SteamParties.InstallEvents();
|
AddInterface<SteamMatchmaking>();
|
||||||
SteamNetworkingSockets.InstallEvents();
|
AddInterface<SteamMatchmakingServers>();
|
||||||
SteamInput.InstallEvents();
|
AddInterface<SteamMusic>();
|
||||||
SteamUGC.InstallEvents();
|
AddInterface<SteamNetworking>();
|
||||||
|
AddInterface<SteamNetworkingSockets>();
|
||||||
|
AddInterface<SteamNetworkingUtils>();
|
||||||
|
AddInterface<SteamParental>();
|
||||||
|
AddInterface<SteamParties>();
|
||||||
|
AddInterface<SteamRemoteStorage>();
|
||||||
|
AddInterface<SteamScreenshots>();
|
||||||
|
AddInterface<SteamUGC>();
|
||||||
|
AddInterface<SteamUser>();
|
||||||
|
AddInterface<SteamUserStats>();
|
||||||
|
AddInterface<SteamUtils>();
|
||||||
|
AddInterface<SteamVideo>();
|
||||||
|
|
||||||
if ( asyncCallbacks )
|
if ( asyncCallbacks )
|
||||||
{
|
{
|
||||||
RunCallbacksAsync();
|
//
|
||||||
|
// This will keep looping in the background every 16 ms
|
||||||
|
// until we shut down.
|
||||||
|
//
|
||||||
|
Dispatch.LoopClientAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<SteamInterface> openIterfaces = new List<SteamInterface>();
|
internal static void AddInterface<T>() where T : SteamClass, new()
|
||||||
|
|
||||||
internal static void WatchInterface( SteamInterface steamInterface )
|
|
||||||
{
|
{
|
||||||
if ( openIterfaces.Contains( steamInterface ) )
|
var t = new T();
|
||||||
throw new System.Exception( "openIterfaces already contains interface!" );
|
t.InitializeInterface( false );
|
||||||
|
openInterfaces.Add( t );
|
||||||
openIterfaces.Add( steamInterface );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<SteamClass> openInterfaces = new List<SteamClass>();
|
||||||
|
|
||||||
internal static void ShutdownInterfaces()
|
internal static void ShutdownInterfaces()
|
||||||
{
|
{
|
||||||
foreach ( var e in openIterfaces )
|
foreach ( var e in openInterfaces )
|
||||||
{
|
{
|
||||||
e.Shutdown();
|
e.DestroyInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
openIterfaces.Clear();
|
openInterfaces.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Action<Exception> OnCallbackException;
|
public static Action<Exception> OnCallbackException;
|
||||||
|
|
||||||
public static bool IsValid => initialized;
|
public static bool IsValid => initialized;
|
||||||
|
|
||||||
internal static async void RunCallbacksAsync()
|
|
||||||
{
|
|
||||||
while ( IsValid )
|
|
||||||
{
|
|
||||||
await Task.Delay( 16 );
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
RunCallbacks();
|
|
||||||
}
|
|
||||||
catch ( System.Exception e )
|
|
||||||
{
|
|
||||||
OnCallbackException?.Invoke( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Shutdown()
|
public static void Shutdown()
|
||||||
{
|
{
|
||||||
if ( !IsValid ) return;
|
if ( !IsValid ) return;
|
||||||
|
|
||||||
SteamInput.Shutdown();
|
|
||||||
|
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
||||||
SteamAPI.Shutdown();
|
SteamAPI.Shutdown();
|
||||||
@ -106,45 +102,17 @@ namespace Steamworks
|
|||||||
|
|
||||||
internal static void Cleanup()
|
internal static void Cleanup()
|
||||||
{
|
{
|
||||||
|
Dispatch.Wipe();
|
||||||
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
|
|
||||||
Event.DisposeAllClient();
|
|
||||||
ShutdownInterfaces();
|
ShutdownInterfaces();
|
||||||
|
|
||||||
SteamInput.Shutdown();
|
|
||||||
SteamApps.Shutdown();
|
|
||||||
SteamUtils.Shutdown();
|
|
||||||
SteamParental.Shutdown();
|
|
||||||
SteamMusic.Shutdown();
|
|
||||||
SteamVideo.Shutdown();
|
|
||||||
SteamUser.Shutdown();
|
|
||||||
SteamFriends.Shutdown();
|
|
||||||
SteamScreenshots.Shutdown();
|
|
||||||
SteamUserStats.Shutdown();
|
|
||||||
SteamInventory.Shutdown();
|
|
||||||
SteamNetworking.Shutdown();
|
|
||||||
SteamMatchmaking.Shutdown();
|
|
||||||
SteamParties.Shutdown();
|
|
||||||
SteamNetworkingUtils.Shutdown();
|
|
||||||
SteamNetworkingSockets.Shutdown();
|
|
||||||
ServerList.Base.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void RegisterCallback( IntPtr intPtr, int callbackId )
|
|
||||||
{
|
|
||||||
SteamAPI.RegisterCallback( intPtr, callbackId );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RunCallbacks()
|
public static void RunCallbacks()
|
||||||
{
|
{
|
||||||
if ( !IsValid ) return;
|
if ( Dispatch.ClientPipe != 0 )
|
||||||
|
Dispatch.Frame( Dispatch.ClientPipe );
|
||||||
SteamAPI.RunCallbacks();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void UnregisterCallback( IntPtr intPtr )
|
|
||||||
{
|
|
||||||
SteamAPI.UnregisterCallback( intPtr );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -10,42 +10,29 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Undocumented Parental Settings
|
/// Undocumented Parental Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamFriends
|
public class SteamFriends : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamFriends _internal;
|
internal static ISteamFriends Internal;
|
||||||
internal static ISteamFriends Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
_internal = new ISteamFriends();
|
Internal = new ISteamFriends( server );
|
||||||
_internal.Init();
|
|
||||||
|
|
||||||
richPresence = new Dictionary<string, string>();
|
richPresence = new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Dictionary<string, string> richPresence;
|
static Dictionary<string, string> richPresence;
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
FriendStateChange_t.Install( x => OnPersonaStateChange?.Invoke( new Friend( x.SteamID ) ) );
|
Dispatch.Install<PersonaStateChange_t>( x => OnPersonaStateChange?.Invoke( new Friend( x.SteamID ) ) );
|
||||||
GameRichPresenceJoinRequested_t.Install( x => OnGameRichPresenceJoinRequested?.Invoke( new Friend( x.SteamIDFriend), x.ConnectUTF8() ) );
|
Dispatch.Install<GameRichPresenceJoinRequested_t>( x => OnGameRichPresenceJoinRequested?.Invoke( new Friend( x.SteamIDFriend), x.ConnectUTF8() ) );
|
||||||
GameConnectedFriendChatMsg_t.Install( OnFriendChatMessage );
|
Dispatch.Install<GameConnectedFriendChatMsg_t>( OnFriendChatMessage );
|
||||||
GameOverlayActivated_t.Install( x => OnGameOverlayActivated?.Invoke() );
|
Dispatch.Install<GameOverlayActivated_t>( x => OnGameOverlayActivated?.Invoke() );
|
||||||
GameServerChangeRequested_t.Install( x => OnGameServerChangeRequested?.Invoke( x.ServerUTF8(), x.PasswordUTF8() ) );
|
Dispatch.Install<GameServerChangeRequested_t>( x => OnGameServerChangeRequested?.Invoke( x.ServerUTF8(), x.PasswordUTF8() ) );
|
||||||
GameLobbyJoinRequested_t.Install( x => OnGameLobbyJoinRequested?.Invoke( new Lobby( x.SteamIDLobby ), x.SteamIDFriend ) );
|
Dispatch.Install<GameLobbyJoinRequested_t>( x => OnGameLobbyJoinRequested?.Invoke( new Lobby( x.SteamIDLobby ), x.SteamIDFriend ) );
|
||||||
FriendRichPresenceUpdate_t.Install( x => OnFriendRichPresenceUpdate?.Invoke( new Friend( x.SteamIDFriend ) ) );
|
Dispatch.Install<FriendRichPresenceUpdate_t>( x => OnFriendRichPresenceUpdate?.Invoke( new Friend( x.SteamIDFriend ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -3,44 +3,18 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Steamworks
|
namespace Steamworks
|
||||||
{
|
{
|
||||||
public static class SteamInput
|
public class SteamInput : SteamClass
|
||||||
{
|
{
|
||||||
|
internal static ISteamInput Internal;
|
||||||
|
internal override SteamInterface Interface => Internal;
|
||||||
|
|
||||||
|
internal override void InitializeInterface( bool server )
|
||||||
|
{
|
||||||
|
Internal = new ISteamInput( server );
|
||||||
|
}
|
||||||
|
|
||||||
internal const int STEAM_CONTROLLER_MAX_COUNT = 16;
|
internal const int STEAM_CONTROLLER_MAX_COUNT = 16;
|
||||||
|
|
||||||
static ISteamInput _internal;
|
|
||||||
internal static ISteamInput Internal
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamInput();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
if ( _internal != null && _internal.IsValid )
|
|
||||||
{
|
|
||||||
_internal.DoShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InstallEvents()
|
|
||||||
{
|
|
||||||
Internal.DoInit();
|
|
||||||
Internal.RunFrame();
|
|
||||||
|
|
||||||
// None?
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// You shouldn't really need to call this because it get called by RunCallbacks on SteamClient
|
/// You shouldn't really need to call this because it get called by RunCallbacks on SteamClient
|
||||||
|
@ -12,32 +12,23 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Undocumented Parental Settings
|
/// Undocumented Parental Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamInventory
|
public class SteamInventory : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamInventory _internal;
|
internal static ISteamInventory Internal;
|
||||||
internal static ISteamInventory Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamInventory();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
{
|
||||||
_internal = null;
|
Internal = new ISteamInventory( server );
|
||||||
|
|
||||||
|
InstallEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
SteamInventoryFullUpdate_t.Install( x => InventoryUpdated( x ) );
|
Dispatch.Install<SteamInventoryFullUpdate_t>( x => InventoryUpdated( x ) );
|
||||||
SteamInventoryDefinitionUpdate_t.Install( x => LoadDefinitions() );
|
Dispatch.Install<SteamInventoryDefinitionUpdate_t>( x => LoadDefinitions() );
|
||||||
SteamInventoryDefinitionUpdate_t.Install( x => LoadDefinitions(), true );
|
Dispatch.Install<SteamInventoryDefinitionUpdate_t>( x => LoadDefinitions(), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InventoryUpdated( SteamInventoryFullUpdate_t x )
|
private static void InventoryUpdated( SteamInventoryFullUpdate_t x )
|
||||||
|
@ -10,48 +10,36 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Functions for clients to access matchmaking services, favorites, and to operate on game lobbies
|
/// Functions for clients to access matchmaking services, favorites, and to operate on game lobbies
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamMatchmaking
|
public class SteamMatchmaking : SteamClass
|
||||||
{
|
{
|
||||||
|
internal static ISteamMatchmaking Internal;
|
||||||
|
internal override SteamInterface Interface => Internal;
|
||||||
|
|
||||||
|
internal override void InitializeInterface( bool server )
|
||||||
|
{
|
||||||
|
Internal = new ISteamMatchmaking( server );
|
||||||
|
|
||||||
|
InstallEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Maximum number of characters a lobby metadata key can be
|
/// Maximum number of characters a lobby metadata key can be
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static int MaxLobbyKeyLength => 255;
|
internal static int MaxLobbyKeyLength => 255;
|
||||||
|
|
||||||
|
|
||||||
static ISteamMatchmaking _internal;
|
|
||||||
|
|
||||||
internal static ISteamMatchmaking Internal
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamMatchmaking();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
LobbyInvite_t.Install( x => OnLobbyInvite?.Invoke( new Friend( x.SteamIDUser ), new Lobby( x.SteamIDLobby ) ) );
|
Dispatch.Install<LobbyInvite_t>( x => OnLobbyInvite?.Invoke( new Friend( x.SteamIDUser ), new Lobby( x.SteamIDLobby ) ) );
|
||||||
|
|
||||||
LobbyEnter_t.Install( x => OnLobbyEntered?.Invoke( new Lobby( x.SteamIDLobby ) ) );
|
Dispatch.Install<LobbyEnter_t>( x => OnLobbyEntered?.Invoke( new Lobby( x.SteamIDLobby ) ) );
|
||||||
|
|
||||||
LobbyCreated_t.Install( x => OnLobbyCreated?.Invoke( x.Result, new Lobby( x.SteamIDLobby ) ) );
|
Dispatch.Install<LobbyCreated_t>( x => OnLobbyCreated?.Invoke( x.Result, new Lobby( x.SteamIDLobby ) ) );
|
||||||
|
|
||||||
LobbyGameCreated_t.Install( x => OnLobbyGameCreated?.Invoke( new Lobby( x.SteamIDLobby ), x.IP, x.Port, x.SteamIDGameServer ) );
|
Dispatch.Install<LobbyGameCreated_t>( x => OnLobbyGameCreated?.Invoke( new Lobby( x.SteamIDLobby ), x.IP, x.Port, x.SteamIDGameServer ) );
|
||||||
|
|
||||||
LobbyDataUpdate_t.Install( x =>
|
Dispatch.Install<LobbyDataUpdate_t>( x =>
|
||||||
{
|
{
|
||||||
if ( x.Success == 0 ) return;
|
if ( x.Success == 0 ) return;
|
||||||
|
|
||||||
@ -61,7 +49,7 @@ namespace Steamworks
|
|||||||
OnLobbyMemberDataChanged?.Invoke( new Lobby( x.SteamIDLobby ), new Friend( x.SteamIDMember ) );
|
OnLobbyMemberDataChanged?.Invoke( new Lobby( x.SteamIDLobby ), new Friend( x.SteamIDMember ) );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
LobbyChatUpdate_t.Install( x =>
|
Dispatch.Install<LobbyChatUpdate_t>( x =>
|
||||||
{
|
{
|
||||||
if ( (x.GfChatMemberStateChange & (int)ChatMemberStateChange.Entered) != 0 )
|
if ( (x.GfChatMemberStateChange & (int)ChatMemberStateChange.Entered) != 0 )
|
||||||
OnLobbyMemberJoined?.Invoke( new Lobby( x.SteamIDLobby ), new Friend( x.SteamIDUserChanged ) );
|
OnLobbyMemberJoined?.Invoke( new Lobby( x.SteamIDLobby ), new Friend( x.SteamIDUserChanged ) );
|
||||||
@ -79,7 +67,7 @@ namespace Steamworks
|
|||||||
OnLobbyMemberBanned?.Invoke( new Lobby( x.SteamIDLobby ), new Friend( x.SteamIDUserChanged ), new Friend( x.SteamIDMakingChange ) );
|
OnLobbyMemberBanned?.Invoke( new Lobby( x.SteamIDLobby ), new Friend( x.SteamIDUserChanged ), new Friend( x.SteamIDMakingChange ) );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
LobbyChatMsg_t.Install( OnLobbyChatMessageRecievedAPI );
|
Dispatch.Install<LobbyChatMsg_t>( OnLobbyChatMessageRecievedAPI );
|
||||||
}
|
}
|
||||||
|
|
||||||
static private unsafe void OnLobbyChatMessageRecievedAPI( LobbyChatMsg_t callback )
|
static private unsafe void OnLobbyChatMessageRecievedAPI( LobbyChatMsg_t callback )
|
||||||
|
23
Facepunch.Steamworks/SteamMatchmakingServers.cs
Normal file
23
Facepunch.Steamworks/SteamMatchmakingServers.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Steamworks.Data;
|
||||||
|
|
||||||
|
namespace Steamworks
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Functions for clients to access matchmaking services, favorites, and to operate on game lobbies
|
||||||
|
/// </summary>
|
||||||
|
public class SteamMatchmakingServers : SteamClass
|
||||||
|
{
|
||||||
|
internal static ISteamMatchmakingServers Internal;
|
||||||
|
internal override SteamInterface Interface => Internal;
|
||||||
|
|
||||||
|
internal override void InitializeInterface( bool server )
|
||||||
|
{
|
||||||
|
Internal = new ISteamMatchmakingServers( server );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,33 +13,22 @@ namespace Steamworks
|
|||||||
/// when an important cut scene is shown, and start playing afterwards.
|
/// when an important cut scene is shown, and start playing afterwards.
|
||||||
/// Nothing uses Steam Music though so this can probably get fucked
|
/// Nothing uses Steam Music though so this can probably get fucked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamMusic
|
public class SteamMusic : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamMusic _internal;
|
internal static ISteamMusic Internal;
|
||||||
internal static ISteamMusic Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
_internal = new ISteamMusic();
|
Internal = new ISteamMusic( server );
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
InstallEvents();
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
PlaybackStatusHasChanged_t.Install( x => OnPlaybackChanged?.Invoke() );
|
Dispatch.Install<PlaybackStatusHasChanged_t>( x => OnPlaybackChanged?.Invoke() );
|
||||||
VolumeHasChanged_t.Install( x => OnVolumeChanged?.Invoke( x.NewVolume ) );
|
Dispatch.Install<VolumeHasChanged_t>( x => OnVolumeChanged?.Invoke( x.NewVolume ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,32 +8,22 @@ using Steamworks.Data;
|
|||||||
|
|
||||||
namespace Steamworks
|
namespace Steamworks
|
||||||
{
|
{
|
||||||
public static class SteamNetworking
|
public class SteamNetworking : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamNetworking _internal;
|
internal static ISteamNetworking Internal;
|
||||||
internal static ISteamNetworking Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamNetworking();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
{
|
||||||
_internal = null;
|
Internal = new ISteamNetworking( server );
|
||||||
|
|
||||||
|
InstallEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
P2PSessionRequest_t.Install( x => OnP2PSessionRequest?.Invoke( x.SteamIDRemote ) );
|
Dispatch.Install<P2PSessionRequest_t>( x => OnP2PSessionRequest?.Invoke( x.SteamIDRemote ) );
|
||||||
P2PSessionConnectFail_t.Install( x => OnP2PConnectionFailed?.Invoke( x.SteamIDRemote, (P2PSessionError) x.P2PSessionError ) );
|
Dispatch.Install<P2PSessionConnectFail_t>( x => OnP2PConnectionFailed?.Invoke( x.SteamIDRemote, (P2PSessionError) x.P2PSessionError ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -8,24 +8,19 @@ using Steamworks.Data;
|
|||||||
|
|
||||||
namespace Steamworks
|
namespace Steamworks
|
||||||
{
|
{
|
||||||
public static class SteamNetworkingSockets
|
public class SteamNetworkingSockets : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamNetworkingSockets _internal;
|
internal static ISteamNetworkingSockets Internal;
|
||||||
internal static ISteamNetworkingSockets Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
|
|
||||||
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
get
|
Internal = new ISteamNetworkingSockets( server );
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamNetworkingSockets();
|
|
||||||
_internal.Init();
|
|
||||||
|
|
||||||
SocketInterfaces = new Dictionary<uint, SocketInterface>();
|
SocketInterfaces = new Dictionary<uint, SocketInterface>();
|
||||||
ConnectionInterfaces = new Dictionary<uint, ConnectionInterface>();
|
ConnectionInterfaces = new Dictionary<uint, ConnectionInterface>();
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
InstallEvents();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region SocketInterface
|
#region SocketInterface
|
||||||
@ -74,18 +69,14 @@ namespace Steamworks
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
SocketInterfaces = null;
|
|
||||||
ConnectionInterfaces = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InstallEvents( bool server = false )
|
internal static void InstallEvents( bool server = false )
|
||||||
{
|
{
|
||||||
SteamNetConnectionStatusChangedCallback_t.Install( x => ConnectionStatusChanged( x ), server );
|
Dispatch.Install<SteamNetConnectionStatusChangedCallback_t>( ConnectionStatusChanged, server );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void ConnectionStatusChanged( SteamNetConnectionStatusChangedCallback_t data )
|
private static void ConnectionStatusChanged( SteamNetConnectionStatusChangedCallback_t data )
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -115,7 +106,10 @@ namespace Steamworks
|
|||||||
public static T CreateNormalSocket<T>( NetAddress address ) where T : SocketInterface, new()
|
public static T CreateNormalSocket<T>( NetAddress address ) where T : SocketInterface, new()
|
||||||
{
|
{
|
||||||
var t = new T();
|
var t = new T();
|
||||||
t.Socket = Internal.CreateListenSocketIP( ref address );
|
var options = new NetKeyValue[0];
|
||||||
|
t.Socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
|
||||||
|
t.Initialize();
|
||||||
|
|
||||||
SetSocketInterface( t.Socket.Id, t );
|
SetSocketInterface( t.Socket.Id, t );
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -126,7 +120,8 @@ namespace Steamworks
|
|||||||
public static T ConnectNormal<T>( NetAddress address ) where T : ConnectionInterface, new()
|
public static T ConnectNormal<T>( NetAddress address ) where T : ConnectionInterface, new()
|
||||||
{
|
{
|
||||||
var t = new T();
|
var t = new T();
|
||||||
t.Connection = Internal.ConnectByIPAddress( ref address );
|
var options = new NetKeyValue[0];
|
||||||
|
t.Connection = Internal.ConnectByIPAddress( ref address, options.Length, options );
|
||||||
SetConnectionInterface( t.Connection.Id, t );
|
SetConnectionInterface( t.Connection.Id, t );
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -137,7 +132,8 @@ namespace Steamworks
|
|||||||
public static T CreateRelaySocket<T>( int virtualport = 0 ) where T : SocketInterface, new()
|
public static T CreateRelaySocket<T>( int virtualport = 0 ) where T : SocketInterface, new()
|
||||||
{
|
{
|
||||||
var t = new T();
|
var t = new T();
|
||||||
t.Socket = Internal.CreateListenSocketP2P( virtualport );
|
var options = new NetKeyValue[0];
|
||||||
|
t.Socket = Internal.CreateListenSocketP2P( virtualport, options.Length, options );
|
||||||
SetSocketInterface( t.Socket.Id, t );
|
SetSocketInterface( t.Socket.Id, t );
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -149,7 +145,8 @@ namespace Steamworks
|
|||||||
{
|
{
|
||||||
var t = new T();
|
var t = new T();
|
||||||
NetIdentity identity = serverId;
|
NetIdentity identity = serverId;
|
||||||
t.Connection = Internal.ConnectP2P( ref identity, virtualport );
|
var options = new NetKeyValue[0];
|
||||||
|
t.Connection = Internal.ConnectP2P( ref identity, virtualport, options.Length, options );
|
||||||
SetConnectionInterface( t.Connection.Id, t );
|
SetConnectionInterface( t.Connection.Id, t );
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -10,26 +10,51 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Undocumented Parental Settings
|
/// Undocumented Parental Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamNetworkingUtils
|
public class SteamNetworkingUtils : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamNetworkingUtils _internal;
|
internal static ISteamNetworkingUtils Internal;
|
||||||
internal static ISteamNetworkingUtils Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
|
|
||||||
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
get
|
Internal = new ISteamNetworkingUtils( server );
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamNetworkingUtils();
|
|
||||||
_internal.InitUserless();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _internal;
|
static void InstallCallbacks()
|
||||||
}
|
{
|
||||||
|
Dispatch.Install<SteamRelayNetworkStatus_t>( x =>
|
||||||
|
{
|
||||||
|
Status = x.Avail;
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Shutdown()
|
public static SteamNetworkingAvailability Status { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If you know that you are going to be using the relay network (for example,
|
||||||
|
/// because you anticipate making P2P connections), call this to initialize the
|
||||||
|
/// relay network. If you do not call this, the initialization will
|
||||||
|
/// be delayed until the first time you use a feature that requires access
|
||||||
|
/// to the relay network, which will delay that first access.
|
||||||
|
///
|
||||||
|
/// You can also call this to force a retry if the previous attempt has failed.
|
||||||
|
/// Performing any action that requires access to the relay network will also
|
||||||
|
/// trigger a retry, and so calling this function is never strictly necessary,
|
||||||
|
/// but it can be useful to call it a program launch time, if access to the
|
||||||
|
/// relay network is anticipated.
|
||||||
|
///
|
||||||
|
/// Use GetRelayNetworkStatus or listen for SteamRelayNetworkStatus_t
|
||||||
|
/// callbacks to know when initialization has completed.
|
||||||
|
/// Typically initialization completes in a few seconds.
|
||||||
|
///
|
||||||
|
/// Note: dedicated servers hosted in known data centers do *not* need
|
||||||
|
/// to call this, since they do not make routing decisions. However, if
|
||||||
|
/// the dedicated server will be using P2P functionality, it will act as
|
||||||
|
/// a "client" and this should be called.
|
||||||
|
/// </summary>
|
||||||
|
public static void InitRelayNetworkAccess()
|
||||||
{
|
{
|
||||||
_internal = null;
|
Internal.InitRelayNetworkAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -70,10 +95,12 @@ namespace Steamworks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static async Task WaitForPingDataAsync( float maxAgeInSeconds = 60 * 5 )
|
public static async Task WaitForPingDataAsync( float maxAgeInSeconds = 60 * 5 )
|
||||||
{
|
{
|
||||||
if ( Internal.CheckPingDataUpToDate( 60.0f ) )
|
if ( Internal.CheckPingDataUpToDate( 120.0f ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while ( Internal.IsPingMeasurementInProgress() )
|
SteamRelayNetworkStatus_t status = default;
|
||||||
|
|
||||||
|
while ( Internal.GetRelayNetworkStatus( ref status ) != SteamNetworkingAvailability.Current )
|
||||||
{
|
{
|
||||||
await Task.Delay( 10 );
|
await Task.Delay( 10 );
|
||||||
}
|
}
|
||||||
@ -123,7 +150,7 @@ namespace Steamworks
|
|||||||
internal unsafe static bool GetConfigInt( NetConfig type, int value )
|
internal unsafe static bool GetConfigInt( NetConfig type, int value )
|
||||||
{
|
{
|
||||||
int* ptr = &value;
|
int* ptr = &value;
|
||||||
return Internal.SetConfigValue( type, NetScope.Global, 0, NetConfigType.Int32, (IntPtr)ptr );
|
return Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.Int32, (IntPtr)ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe static int GetConfigInt( NetConfig type )
|
internal unsafe static int GetConfigInt( NetConfig type )
|
||||||
@ -131,8 +158,8 @@ namespace Steamworks
|
|||||||
int value = 0;
|
int value = 0;
|
||||||
NetConfigType dtype = NetConfigType.Int32;
|
NetConfigType dtype = NetConfigType.Int32;
|
||||||
int* ptr = &value;
|
int* ptr = &value;
|
||||||
ulong size = sizeof( int );
|
UIntPtr size = new UIntPtr( sizeof( int ) );
|
||||||
var result = Internal.GetConfigValue( type, NetScope.Global, 0, ref dtype, (IntPtr) ptr, ref size );
|
var result = Internal.GetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, ref dtype, (IntPtr) ptr, ref size );
|
||||||
if ( result != NetConfigResult.OK )
|
if ( result != NetConfigResult.OK )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -142,7 +169,7 @@ namespace Steamworks
|
|||||||
internal unsafe static bool SetConfigFloat( NetConfig type, float value )
|
internal unsafe static bool SetConfigFloat( NetConfig type, float value )
|
||||||
{
|
{
|
||||||
float* ptr = &value;
|
float* ptr = &value;
|
||||||
return Internal.SetConfigValue( type, NetScope.Global, 0, NetConfigType.Float, (IntPtr)ptr );
|
return Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.Float, (IntPtr)ptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe static float GetConfigFloat( NetConfig type )
|
internal unsafe static float GetConfigFloat( NetConfig type )
|
||||||
@ -150,8 +177,8 @@ namespace Steamworks
|
|||||||
float value = 0;
|
float value = 0;
|
||||||
NetConfigType dtype = NetConfigType.Float;
|
NetConfigType dtype = NetConfigType.Float;
|
||||||
float* ptr = &value;
|
float* ptr = &value;
|
||||||
ulong size = sizeof( float );
|
UIntPtr size = new UIntPtr( sizeof( float ) );
|
||||||
var result = Internal.GetConfigValue( type, NetScope.Global, 0, ref dtype, (IntPtr)ptr, ref size );
|
var result = Internal.GetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, ref dtype, (IntPtr)ptr, ref size );
|
||||||
if ( result != NetConfigResult.OK )
|
if ( result != NetConfigResult.OK )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -164,7 +191,7 @@ namespace Steamworks
|
|||||||
|
|
||||||
fixed ( byte* ptr = bytes )
|
fixed ( byte* ptr = bytes )
|
||||||
{
|
{
|
||||||
return Internal.SetConfigValue( type, NetScope.Global, 0, NetConfigType.String, (IntPtr)ptr );
|
return Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.String, (IntPtr)ptr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,32 +10,21 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Undocumented Parental Settings
|
/// Undocumented Parental Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamParental
|
public class SteamParental : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamParentalSettings _internal;
|
internal static ISteamParentalSettings Internal;
|
||||||
internal static ISteamParentalSettings Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
_internal = new ISteamParentalSettings();
|
Internal = new ISteamParentalSettings( server );
|
||||||
_internal.Init();
|
InstallEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
SteamParentalSettingsChanged_t.Install( x => OnSettingsChanged?.Invoke() );
|
Dispatch.Install<SteamParentalSettingsChanged_t>( x => OnSettingsChanged?.Invoke() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -7,31 +7,21 @@ using Steamworks.Data;
|
|||||||
|
|
||||||
namespace Steamworks
|
namespace Steamworks
|
||||||
{
|
{
|
||||||
public static class SteamParties
|
public class SteamParties : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamParties _internal;
|
internal static ISteamParties Internal;
|
||||||
internal static ISteamParties Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamParties();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
{
|
||||||
_internal = null;
|
Internal = new ISteamParties( server );
|
||||||
|
InstallEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
AvailableBeaconLocationsUpdated_t.Install( x => OnBeaconLocationsUpdated?.Invoke() );
|
Dispatch.Install<AvailableBeaconLocationsUpdated_t>( x => OnBeaconLocationsUpdated?.Invoke() );
|
||||||
ActiveBeaconsUpdated_t.Install( x => OnActiveBeaconsUpdated?.Invoke() );
|
Dispatch.Install<ActiveBeaconsUpdated_t>( x => OnActiveBeaconsUpdated?.Invoke() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -10,26 +10,14 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Undocumented Parental Settings
|
/// Undocumented Parental Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamRemoteStorage
|
public class SteamRemoteStorage : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamRemoteStorage _internal;
|
internal static ISteamRemoteStorage Internal;
|
||||||
internal static ISteamRemoteStorage Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamRemoteStorage();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
{
|
||||||
_internal = null;
|
Internal = new ISteamRemoteStorage( server );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -10,33 +10,21 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Undocumented Parental Settings
|
/// Undocumented Parental Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamScreenshots
|
public class SteamScreenshots : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamScreenshots _internal;
|
internal static ISteamScreenshots Internal;
|
||||||
internal static ISteamScreenshots Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
_internal = new ISteamScreenshots();
|
Internal = new ISteamScreenshots( server );
|
||||||
_internal.Init();
|
InstallEvents();
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
ScreenshotRequested_t.Install( x => OnScreenshotRequested?.Invoke() );
|
Dispatch.Install<ScreenshotRequested_t>( x => OnScreenshotRequested?.Invoke() );
|
||||||
ScreenshotReady_t.Install( x =>
|
Dispatch.Install<ScreenshotReady_t>( x =>
|
||||||
{
|
{
|
||||||
if ( x.Result != Result.OK )
|
if ( x.Result != Result.OK )
|
||||||
OnScreenshotFailed?.Invoke( x.Result );
|
OnScreenshotFailed?.Invoke( x.Result );
|
||||||
|
@ -10,26 +10,18 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the core of the Steam Game Servers API
|
/// Provides the core of the Steam Game Servers API
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static partial class SteamServer
|
public partial class SteamServer : SteamClass
|
||||||
{
|
{
|
||||||
static bool initialized;
|
internal static ISteamGameServer Internal;
|
||||||
|
internal override SteamInterface Interface => Internal;
|
||||||
|
|
||||||
static ISteamGameServer _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
internal static ISteamGameServer Internal
|
|
||||||
{
|
{
|
||||||
get
|
Internal = new ISteamGameServer( server );
|
||||||
{
|
InstallEvents();
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamGameServer( );
|
|
||||||
_internal.InitServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _internal;
|
public static bool IsValid => Internal != null && Internal.IsValid;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsValid => initialized;
|
|
||||||
|
|
||||||
|
|
||||||
public static Action<Exception> OnCallbackException;
|
public static Action<Exception> OnCallbackException;
|
||||||
@ -37,12 +29,12 @@ namespace Steamworks
|
|||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
SteamInventory.InstallEvents();
|
SteamInventory.InstallEvents();
|
||||||
SteamNetworkingSockets.InstallEvents(true);
|
//SteamNetworkingSockets.InstallEvents(true);
|
||||||
|
|
||||||
ValidateAuthTicketResponse_t.Install( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ), true );
|
Dispatch.Install<ValidateAuthTicketResponse_t>( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ), true );
|
||||||
SteamServersConnected_t.Install( x => OnSteamServersConnected?.Invoke(), true );
|
Dispatch.Install<SteamServersConnected_t>( x => OnSteamServersConnected?.Invoke(), true );
|
||||||
SteamServerConnectFailure_t.Install( x => OnSteamServerConnectFailure?.Invoke( x.Result, x.StillRetrying ), true );
|
Dispatch.Install<SteamServerConnectFailure_t>( x => OnSteamServerConnectFailure?.Invoke( x.Result, x.StillRetrying ), true );
|
||||||
SteamServersDisconnected_t.Install( x => OnSteamServersDisconnected?.Invoke( x.Result ), true );
|
Dispatch.Install<SteamServersDisconnected_t>( x => OnSteamServersDisconnected?.Invoke( x.Result ), true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -93,7 +85,17 @@ namespace Steamworks
|
|||||||
throw new System.Exception( $"InitGameServer returned false ({ipaddress},{init.SteamPort},{init.GamePort},{init.QueryPort},{secure},\"{init.VersionString}\")" );
|
throw new System.Exception( $"InitGameServer returned false ({ipaddress},{init.SteamPort},{init.GamePort},{init.QueryPort},{secure},\"{init.VersionString}\")" );
|
||||||
}
|
}
|
||||||
|
|
||||||
initialized = true;
|
//
|
||||||
|
// Dispatch is responsible for pumping the
|
||||||
|
// event loop.
|
||||||
|
//
|
||||||
|
Dispatch.Init();
|
||||||
|
Dispatch.ServerPipe = SteamGameServer.GetHSteamPipe();
|
||||||
|
Console.WriteLine( $"Dispatch.ServerPipe = {Dispatch.ServerPipe.Value}" );
|
||||||
|
|
||||||
|
AddInterface<SteamServer>();
|
||||||
|
AddInterface<SteamNetworkingUtils>();
|
||||||
|
AddInterface<SteamNetworkingSockets>();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initial settings
|
// Initial settings
|
||||||
@ -111,71 +113,50 @@ namespace Steamworks
|
|||||||
|
|
||||||
if ( asyncCallbacks )
|
if ( asyncCallbacks )
|
||||||
{
|
{
|
||||||
RunCallbacksAsync();
|
//
|
||||||
|
// This will keep looping in the background every 16 ms
|
||||||
|
// until we shut down.
|
||||||
|
//
|
||||||
|
Dispatch.LoopServerAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<SteamInterface> openIterfaces = new List<SteamInterface>();
|
internal static void AddInterface<T>() where T : SteamClass, new()
|
||||||
|
|
||||||
internal static void WatchInterface( SteamInterface steamInterface )
|
|
||||||
{
|
{
|
||||||
if ( openIterfaces.Contains( steamInterface ) )
|
var t = new T();
|
||||||
throw new System.Exception( "openIterfaces already contains interface!" );
|
t.InitializeInterface( true );
|
||||||
|
openInterfaces.Add( t );
|
||||||
openIterfaces.Add( steamInterface );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<SteamClass> openInterfaces = new List<SteamClass>();
|
||||||
|
|
||||||
internal static void ShutdownInterfaces()
|
internal static void ShutdownInterfaces()
|
||||||
{
|
{
|
||||||
foreach ( var e in openIterfaces )
|
foreach ( var e in openInterfaces )
|
||||||
{
|
{
|
||||||
e.Shutdown();
|
e.DestroyInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
openIterfaces.Clear();
|
openInterfaces.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Shutdown()
|
public static void Shutdown()
|
||||||
{
|
{
|
||||||
Event.DisposeAllServer();
|
Internal = null;
|
||||||
|
|
||||||
initialized = false;
|
|
||||||
|
|
||||||
_internal = null;
|
|
||||||
|
|
||||||
ShutdownInterfaces();
|
ShutdownInterfaces();
|
||||||
SteamNetworkingUtils.Shutdown();
|
|
||||||
SteamNetworkingSockets.Shutdown();
|
|
||||||
SteamInventory.Shutdown();
|
|
||||||
|
|
||||||
SteamServerStats.Shutdown();
|
|
||||||
|
|
||||||
SteamGameServer.Shutdown();
|
SteamGameServer.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async void RunCallbacksAsync()
|
|
||||||
{
|
|
||||||
while ( IsValid )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
RunCallbacks();
|
|
||||||
}
|
|
||||||
catch ( System.Exception e )
|
|
||||||
{
|
|
||||||
OnCallbackException?.Invoke( e );
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay( 16 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Run the callbacks. This is also called in Async callbacks.
|
/// Run the callbacks. This is also called in Async callbacks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void RunCallbacks()
|
public static void RunCallbacks()
|
||||||
{
|
{
|
||||||
SteamGameServer.RunCallbacks();
|
if ( Dispatch.ServerPipe != 0 )
|
||||||
|
{
|
||||||
|
Dispatch.Frame( Dispatch.ServerPipe );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -315,16 +296,7 @@ namespace Steamworks
|
|||||||
/// current public ip address. Be aware that this is likely to return
|
/// current public ip address. Be aware that this is likely to return
|
||||||
/// null for the first few seconds after initialization.
|
/// null for the first few seconds after initialization.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static System.Net.IPAddress PublicIp
|
public static System.Net.IPAddress PublicIp => Internal.GetPublicIP();
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var ip = Internal.GetPublicIP();
|
|
||||||
if ( ip == 0 ) return null;
|
|
||||||
|
|
||||||
return Utility.Int32ToIp( ip );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enable or disable heartbeats, which are sent regularly to the master server.
|
/// Enable or disable heartbeats, which are sent regularly to the master server.
|
||||||
|
@ -7,26 +7,14 @@ using Steamworks.Data;
|
|||||||
|
|
||||||
namespace Steamworks
|
namespace Steamworks
|
||||||
{
|
{
|
||||||
public static class SteamServerStats
|
public class SteamServerStats : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamGameServerStats _internal;
|
internal static ISteamGameServerStats Internal;
|
||||||
internal static ISteamGameServerStats Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamGameServerStats();
|
|
||||||
_internal.InitServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
{
|
||||||
_internal = null;
|
Internal = new ISteamGameServerStats( server );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -47,7 +35,7 @@ namespace Steamworks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool SetInt( SteamId steamid, string name, int stat )
|
public static bool SetInt( SteamId steamid, string name, int stat )
|
||||||
{
|
{
|
||||||
return Internal.SetUserStat1( steamid, name, stat );
|
return Internal.SetUserStat( steamid, name, stat );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -56,7 +44,7 @@ namespace Steamworks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool SetFloat( SteamId steamid, string name, float stat )
|
public static bool SetFloat( SteamId steamid, string name, float stat )
|
||||||
{
|
{
|
||||||
return Internal.SetUserStat2( steamid, name, stat );
|
return Internal.SetUserStat( steamid, name, stat );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -68,7 +56,7 @@ namespace Steamworks
|
|||||||
{
|
{
|
||||||
int data = defaultValue;
|
int data = defaultValue;
|
||||||
|
|
||||||
if ( !Internal.GetUserStat1( steamid, name, ref data ) )
|
if ( !Internal.GetUserStat( steamid, name, ref data ) )
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -83,7 +71,7 @@ namespace Steamworks
|
|||||||
{
|
{
|
||||||
float data = defaultValue;
|
float data = defaultValue;
|
||||||
|
|
||||||
if ( !Internal.GetUserStat2( steamid, name, ref data ) )
|
if ( !Internal.GetUserStat( steamid, name, ref data ) )
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
@ -12,26 +12,20 @@ namespace Steamworks
|
|||||||
/// Functions for accessing and manipulating Steam user information.
|
/// Functions for accessing and manipulating Steam user information.
|
||||||
/// This is also where the APIs for Steam Voice are exposed.
|
/// This is also where the APIs for Steam Voice are exposed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamUGC
|
public class SteamUGC : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamUGC _internal;
|
internal static ISteamUGC Internal;
|
||||||
internal static ISteamUGC Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamUGC();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
}
|
{
|
||||||
|
Internal = new ISteamUGC( server );
|
||||||
|
InstallEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
DownloadItemResult_t.Install( x => OnDownloadItemResult?.Invoke( x.Result ) );
|
Dispatch.Install<DownloadItemResult_t>( x => OnDownloadItemResult?.Invoke( x.Result ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -39,11 +33,6 @@ namespace Steamworks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static event Action<Result> OnDownloadItemResult;
|
public static event Action<Result> OnDownloadItemResult;
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<bool> DeleteFileAsync( PublishedFileId fileId )
|
public static async Task<bool> DeleteFileAsync( PublishedFileId fileId )
|
||||||
{
|
{
|
||||||
var r = await Internal.DeleteItem( fileId );
|
var r = await Internal.DeleteItem( fileId );
|
||||||
|
@ -13,46 +13,33 @@ namespace Steamworks
|
|||||||
/// Functions for accessing and manipulating Steam user information.
|
/// Functions for accessing and manipulating Steam user information.
|
||||||
/// This is also where the APIs for Steam Voice are exposed.
|
/// This is also where the APIs for Steam Voice are exposed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamUser
|
public class SteamUser : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamUser _internal;
|
internal static ISteamUser Internal;
|
||||||
internal static ISteamUser Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
_internal = new ISteamUser();
|
Internal = new ISteamUser( server );
|
||||||
_internal.Init();
|
InstallEvents();
|
||||||
|
|
||||||
richPresence = new Dictionary<string, string>();
|
richPresence = new Dictionary<string, string>();
|
||||||
|
|
||||||
SampleRate = OptimalSampleRate;
|
SampleRate = OptimalSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Dictionary<string, string> richPresence;
|
static Dictionary<string, string> richPresence;
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
SteamServersConnected_t.Install( x => OnSteamServersConnected?.Invoke() );
|
Dispatch.Install<SteamServersConnected_t>( x => OnSteamServersConnected?.Invoke() );
|
||||||
SteamServerConnectFailure_t.Install( x => OnSteamServerConnectFailure?.Invoke() );
|
Dispatch.Install<SteamServerConnectFailure_t>( x => OnSteamServerConnectFailure?.Invoke() );
|
||||||
SteamServersDisconnected_t.Install( x => OnSteamServersDisconnected?.Invoke() );
|
Dispatch.Install<SteamServersDisconnected_t>( x => OnSteamServersDisconnected?.Invoke() );
|
||||||
ClientGameServerDeny_t.Install( x => OnClientGameServerDeny?.Invoke() );
|
Dispatch.Install<ClientGameServerDeny_t>( x => OnClientGameServerDeny?.Invoke() );
|
||||||
LicensesUpdated_t.Install( x => OnLicensesUpdated?.Invoke() );
|
Dispatch.Install<LicensesUpdated_t>( x => OnLicensesUpdated?.Invoke() );
|
||||||
ValidateAuthTicketResponse_t.Install( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ) );
|
Dispatch.Install<ValidateAuthTicketResponse_t>( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ) );
|
||||||
MicroTxnAuthorizationResponse_t.Install( x => OnMicroTxnAuthorizationResponse?.Invoke( x.AppID, x.OrderID, x.Authorized != 0 ) );
|
Dispatch.Install<MicroTxnAuthorizationResponse_t>( x => OnMicroTxnAuthorizationResponse?.Invoke( x.AppID, x.OrderID, x.Authorized != 0 ) );
|
||||||
GameWebCallback_t.Install( x => OnGameWebCallback?.Invoke( x.URLUTF8() ) );
|
Dispatch.Install<GameWebCallback_t>( x => OnGameWebCallback?.Invoke( x.URLUTF8() ) );
|
||||||
GetAuthSessionTicketResponse_t.Install( x => OnGetAuthSessionTicketResponse?.Invoke( x ) );
|
Dispatch.Install<GetAuthSessionTicketResponse_t>( x => OnGetAuthSessionTicketResponse?.Invoke( x ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -424,6 +411,7 @@ namespace Steamworks
|
|||||||
/// Requests an application ticket encrypted with the secret "encrypted app ticket key".
|
/// Requests an application ticket encrypted with the secret "encrypted app ticket key".
|
||||||
/// The encryption key can be obtained from the Encrypted App Ticket Key page on the App Admin for your app.
|
/// The encryption key can be obtained from the Encrypted App Ticket Key page on the App Admin for your app.
|
||||||
/// There can only be one call pending, and this call is subject to a 60 second rate limit.
|
/// There can only be one call pending, and this call is subject to a 60 second rate limit.
|
||||||
|
/// If you get a null result from this it's probably because you're calling it too often.
|
||||||
/// This can fail if you don't have an encrypted ticket set for your app here https://partner.steamgames.com/apps/sdkauth/
|
/// This can fail if you don't have an encrypted ticket set for your app here https://partner.steamgames.com/apps/sdkauth/
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static async Task<byte[]> RequestEncryptedAppTicketAsync( byte[] dataToInclude )
|
public static async Task<byte[]> RequestEncryptedAppTicketAsync( byte[] dataToInclude )
|
||||||
|
@ -7,36 +7,24 @@ using Steamworks.Data;
|
|||||||
|
|
||||||
namespace Steamworks
|
namespace Steamworks
|
||||||
{
|
{
|
||||||
public static class SteamUserStats
|
public class SteamUserStats : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamUserStats _internal;
|
internal static ISteamUserStats Internal;
|
||||||
internal static ISteamUserStats Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
_internal = new ISteamUserStats();
|
Internal = new ISteamUserStats( server );
|
||||||
_internal.Init();
|
|
||||||
|
|
||||||
|
InstallEvents();
|
||||||
RequestCurrentStats();
|
RequestCurrentStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _internal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool StatsRecieved { get; internal set; }
|
public static bool StatsRecieved { get; internal set; }
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
UserStatsReceived_t.Install( x =>
|
Dispatch.Install<UserStatsReceived_t>( x =>
|
||||||
{
|
{
|
||||||
if ( x.SteamIDUser == SteamClient.SteamId )
|
if ( x.SteamIDUser == SteamClient.SteamId )
|
||||||
StatsRecieved = true;
|
StatsRecieved = true;
|
||||||
@ -44,10 +32,10 @@ namespace Steamworks
|
|||||||
OnUserStatsReceived?.Invoke( x.SteamIDUser, x.Result );
|
OnUserStatsReceived?.Invoke( x.SteamIDUser, x.Result );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
UserStatsStored_t.Install( x => OnUserStatsStored?.Invoke( x.Result ) );
|
Dispatch.Install<UserStatsStored_t>( x => OnUserStatsStored?.Invoke( x.Result ) );
|
||||||
UserAchievementStored_t.Install( x => OnAchievementProgress?.Invoke( new Achievement( x.AchievementNameUTF8() ), (int) x.CurProgress, (int)x.MaxProgress ) );
|
Dispatch.Install<UserAchievementStored_t>( x => OnAchievementProgress?.Invoke( new Achievement( x.AchievementNameUTF8() ), (int) x.CurProgress, (int)x.MaxProgress ) );
|
||||||
UserStatsUnloaded_t.Install( x => OnUserStatsUnloaded?.Invoke( x.SteamIDUser ) );
|
Dispatch.Install<UserStatsUnloaded_t>( x => OnUserStatsUnloaded?.Invoke( x.SteamIDUser ) );
|
||||||
UserAchievementIconFetched_t.Install( x => OnAchievementIconFetched?.Invoke( x.AchievementNameUTF8(), x.IconHandle ) );
|
Dispatch.Install<UserAchievementIconFetched_t>( x => OnAchievementIconFetched?.Invoke( x.AchievementNameUTF8(), x.IconHandle ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -209,7 +197,7 @@ namespace Steamworks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool SetStat( string name, int value )
|
public static bool SetStat( string name, int value )
|
||||||
{
|
{
|
||||||
return Internal.SetStat1( name, value );
|
return Internal.SetStat( name, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -218,7 +206,7 @@ namespace Steamworks
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool SetStat( string name, float value )
|
public static bool SetStat( string name, float value )
|
||||||
{
|
{
|
||||||
return Internal.SetStat2( name, value );
|
return Internal.SetStat( name, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -227,7 +215,7 @@ namespace Steamworks
|
|||||||
public static int GetStatInt( string name )
|
public static int GetStatInt( string name )
|
||||||
{
|
{
|
||||||
int data = 0;
|
int data = 0;
|
||||||
Internal.GetStat1( name, ref data );
|
Internal.GetStat( name, ref data );
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +225,7 @@ namespace Steamworks
|
|||||||
public static float GetStatFloat( string name )
|
public static float GetStatFloat( string name )
|
||||||
{
|
{
|
||||||
float data = 0;
|
float data = 0;
|
||||||
Internal.GetStat2( name, ref data );
|
Internal.GetStat( name, ref data );
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,34 +10,24 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interface which provides access to a range of miscellaneous utility functions
|
/// Interface which provides access to a range of miscellaneous utility functions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamUtils
|
public class SteamUtils : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamUtils _internal;
|
internal static ISteamUtils Internal;
|
||||||
internal static ISteamUtils Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _internal == null )
|
|
||||||
{
|
|
||||||
_internal = new ISteamUtils();
|
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
internal override void InitializeInterface( bool server )
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
{
|
||||||
_internal = null;
|
Internal = new ISteamUtils( server );
|
||||||
|
|
||||||
|
InstallEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
IPCountry_t.Install( x => OnIpCountryChanged?.Invoke() );
|
Dispatch.Install<IPCountry_t>( x => OnIpCountryChanged?.Invoke() );
|
||||||
LowBatteryPower_t.Install( x => OnLowBatteryPower?.Invoke( x.MinutesBatteryLeft ) );
|
Dispatch.Install<LowBatteryPower_t>( x => OnLowBatteryPower?.Invoke( x.MinutesBatteryLeft ) );
|
||||||
SteamShutdown_t.Install( x => SteamClosed() );
|
Dispatch.Install<SteamShutdown_t>( x => SteamClosed() );
|
||||||
GamepadTextInputDismissed_t.Install( x => OnGamepadTextInputDismissed?.Invoke( x.Submitted ) );
|
Dispatch.Install<GamepadTextInputDismissed_t>( x => OnGamepadTextInputDismissed?.Invoke( x.Submitted ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SteamClosed()
|
private static void SteamClosed()
|
||||||
|
@ -10,34 +10,22 @@ namespace Steamworks
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Undocumented Parental Settings
|
/// Undocumented Parental Settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class SteamVideo
|
public class SteamVideo : SteamClass
|
||||||
{
|
{
|
||||||
static ISteamVideo _internal;
|
internal static ISteamVideo Internal;
|
||||||
internal static ISteamVideo Internal
|
internal override SteamInterface Interface => Internal;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
SteamClient.ValidCheck();
|
|
||||||
|
|
||||||
if ( _internal == null )
|
internal override void InitializeInterface( bool server )
|
||||||
{
|
{
|
||||||
_internal = new ISteamVideo();
|
Internal = new ISteamVideo( server );
|
||||||
_internal.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _internal;
|
InstallEvents();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static void Shutdown()
|
|
||||||
{
|
|
||||||
_internal = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InstallEvents()
|
internal static void InstallEvents()
|
||||||
{
|
{
|
||||||
BroadcastUploadStart_t.Install( x => OnBroadcastStarted?.Invoke() );
|
Dispatch.Install<BroadcastUploadStart_t>( x => OnBroadcastStarted?.Invoke() );
|
||||||
BroadcastUploadStop_t.Install( x => OnBroadcastStopped?.Invoke( x.Result ) );
|
Dispatch.Install<BroadcastUploadStop_t>( x => OnBroadcastStopped?.Invoke( x.Result ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static event Action OnBroadcastStarted;
|
public static event Action OnBroadcastStarted;
|
||||||
|
@ -5,9 +5,11 @@ namespace Steamworks.Data
|
|||||||
{
|
{
|
||||||
public struct Connection
|
public struct Connection
|
||||||
{
|
{
|
||||||
public uint Id { get; }
|
public uint Id { get; set; }
|
||||||
|
|
||||||
public override string ToString() => Id.ToString();
|
public override string ToString() => Id.ToString();
|
||||||
|
public static implicit operator Connection( uint value ) => new Connection() { Id = value };
|
||||||
|
public static implicit operator uint( Connection value ) => value.Id;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Accept an incoming connection that has been received on a listen socket.
|
/// Accept an incoming connection that has been received on a listen socket.
|
||||||
@ -54,7 +56,8 @@ namespace Steamworks.Data
|
|||||||
|
|
||||||
public Result SendMessage( IntPtr ptr, int size, SendType sendType = SendType.Reliable )
|
public Result SendMessage( IntPtr ptr, int size, SendType sendType = SendType.Reliable )
|
||||||
{
|
{
|
||||||
return SteamNetworkingSockets.Internal.SendMessageToConnection( this, ptr, (uint) size, (int)sendType );
|
long messageNumber = 0;
|
||||||
|
return SteamNetworkingSockets.Internal.SendMessageToConnection( this, ptr, (uint) size, (int)sendType, ref messageNumber );
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe Result SendMessage( byte[] data, SendType sendType = SendType.Reliable )
|
public unsafe Result SendMessage( byte[] data, SendType sendType = SendType.Reliable )
|
||||||
@ -91,27 +94,5 @@ namespace Steamworks.Data
|
|||||||
|
|
||||||
return strVal;
|
return strVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
[ThreadStatic]
|
|
||||||
private static SteamNetworkingMessage_t[] messageBuffer;
|
|
||||||
|
|
||||||
public IEnumerable<SteamNetworkingMessage_t> Messages
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( messageBuffer == null )
|
|
||||||
messageBuffer = new SteamNetworkingMessage_t[128];
|
|
||||||
|
|
||||||
var num = SteamNetworkingSockets.Internal.ReceiveMessagesOnConnection( this, ref messageBuffer, messageBuffer.Length );
|
|
||||||
|
|
||||||
for ( int i = 0; i < num; i++)
|
|
||||||
{
|
|
||||||
yield return messageBuffer[i];
|
|
||||||
messageBuffer[i].Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -130,8 +130,8 @@ namespace Steamworks
|
|||||||
{
|
{
|
||||||
if ( Properties == null ) return DateTime.UtcNow;
|
if ( Properties == null ) return DateTime.UtcNow;
|
||||||
|
|
||||||
var str = Properties["acquired"];
|
if ( Properties.TryGetValue( "acquired", out var str ) )
|
||||||
|
{
|
||||||
var y = int.Parse( str.Substring( 0, 4 ) );
|
var y = int.Parse( str.Substring( 0, 4 ) );
|
||||||
var m = int.Parse( str.Substring( 4, 2 ) );
|
var m = int.Parse( str.Substring( 4, 2 ) );
|
||||||
var d = int.Parse( str.Substring( 6, 2 ) );
|
var d = int.Parse( str.Substring( 6, 2 ) );
|
||||||
@ -142,6 +142,9 @@ namespace Steamworks
|
|||||||
|
|
||||||
return new DateTime( y, m, d, h, mn, s, DateTimeKind.Utc );
|
return new DateTime( y, m, d, h, mn, s, DateTimeKind.Utc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return DateTime.UtcNow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -153,7 +156,11 @@ namespace Steamworks
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
if ( Properties == null ) return null;
|
if ( Properties == null ) return null;
|
||||||
return Properties["origin"];
|
|
||||||
|
if ( Properties.TryGetValue( "origin", out var str ) )
|
||||||
|
return str;
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,12 @@ namespace Steamworks.Data
|
|||||||
return value.steamID;
|
return value.steamID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => $"{type};{m_cbSize};{steamID}";
|
public override string ToString()
|
||||||
|
{
|
||||||
|
var id = this;
|
||||||
|
SteamNetworkingUtils.Internal.SteamNetworkingIdentity_ToString( ref id, out var str );
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
internal enum IdentityType
|
internal enum IdentityType
|
||||||
{
|
{
|
||||||
|
31
Facepunch.Steamworks/Structs/NetKeyValue.cs
Normal file
31
Facepunch.Steamworks/Structs/NetKeyValue.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Steamworks.Data;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Steamworks.Data
|
||||||
|
{
|
||||||
|
[StructLayout( LayoutKind.Explicit, Pack = Platform.StructPlatformPackSize )]
|
||||||
|
internal struct NetKeyValue
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal NetConfig Value; // m_eValue ESteamNetworkingConfigValue
|
||||||
|
|
||||||
|
[FieldOffset( 4 )]
|
||||||
|
internal NetConfigType DataType; // m_eDataType ESteamNetworkingConfigDataType
|
||||||
|
|
||||||
|
[FieldOffset( 8 )]
|
||||||
|
internal long Int64Value; // m_int64 int64_t
|
||||||
|
|
||||||
|
[FieldOffset( 8 )]
|
||||||
|
internal int Int32Value; // m_val_int32 int32_t
|
||||||
|
|
||||||
|
[FieldOffset( 8 )]
|
||||||
|
internal float FloatValue; // m_val_float float
|
||||||
|
|
||||||
|
[FieldOffset( 8 )]
|
||||||
|
internal IntPtr PointerValue; // m_val_functionPtr void *
|
||||||
|
|
||||||
|
|
||||||
|
// TODO - support strings, maybe
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,15 @@
|
|||||||
namespace Steamworks.Data
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Steamworks.Data
|
||||||
{
|
{
|
||||||
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
public struct Socket
|
public struct Socket
|
||||||
{
|
{
|
||||||
internal uint Id;
|
internal uint Id;
|
||||||
public override string ToString() => Id.ToString();
|
public override string ToString() => Id.ToString();
|
||||||
|
public static implicit operator Socket( uint value ) => new Socket() { Id = value };
|
||||||
|
public static implicit operator uint( Socket value ) => value.Id;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Destroy a listen socket. All the connections that were accepting on the listen
|
/// Destroy a listen socket. All the connections that were accepting on the listen
|
||||||
@ -11,7 +17,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Close()
|
public bool Close()
|
||||||
{
|
{
|
||||||
return SteamNetworkingSockets.Internal.CloseListenSocket( this );
|
return SteamNetworkingSockets.Internal.CloseListenSocket( Id );
|
||||||
}
|
}
|
||||||
|
|
||||||
public SocketInterface Interface
|
public SocketInterface Interface
|
||||||
|
@ -36,7 +36,7 @@ namespace Steamworks.Data
|
|||||||
{
|
{
|
||||||
double val = 0.0;
|
double val = 0.0;
|
||||||
|
|
||||||
if ( SteamUserStats.Internal.GetGlobalStat2( Name, ref val ) )
|
if ( SteamUserStats.Internal.GetGlobalStat( Name, ref val ) )
|
||||||
return val;
|
return val;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -45,7 +45,7 @@ namespace Steamworks.Data
|
|||||||
public long GetGlobalInt()
|
public long GetGlobalInt()
|
||||||
{
|
{
|
||||||
long val = 0;
|
long val = 0;
|
||||||
SteamUserStats.Internal.GetGlobalStat1( Name, ref val );
|
SteamUserStats.Internal.GetGlobalStat( Name, ref val );
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ namespace Steamworks.Data
|
|||||||
|
|
||||||
var r = new long[days];
|
var r = new long[days];
|
||||||
|
|
||||||
var rows = SteamUserStats.Internal.GetGlobalStatHistory1( Name, r, (uint) r.Length * sizeof(long) );
|
var rows = SteamUserStats.Internal.GetGlobalStatHistory( Name, r, (uint) r.Length * sizeof(long) );
|
||||||
|
|
||||||
if ( days != rows )
|
if ( days != rows )
|
||||||
r = r.Take( rows ).ToArray();
|
r = r.Take( rows ).ToArray();
|
||||||
@ -71,7 +71,7 @@ namespace Steamworks.Data
|
|||||||
|
|
||||||
var r = new double[days];
|
var r = new double[days];
|
||||||
|
|
||||||
var rows = SteamUserStats.Internal.GetGlobalStatHistory2( Name, r, (uint)r.Length * sizeof( double ) );
|
var rows = SteamUserStats.Internal.GetGlobalStatHistory( Name, r, (uint)r.Length * sizeof( double ) );
|
||||||
|
|
||||||
if ( days != rows )
|
if ( days != rows )
|
||||||
r = r.Take( rows ).ToArray();
|
r = r.Take( rows ).ToArray();
|
||||||
@ -85,11 +85,11 @@ namespace Steamworks.Data
|
|||||||
|
|
||||||
if ( UserId > 0 )
|
if ( UserId > 0 )
|
||||||
{
|
{
|
||||||
SteamUserStats.Internal.GetUserStat2( UserId, Name, ref val );
|
SteamUserStats.Internal.GetUserStat( UserId, Name, ref val );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SteamUserStats.Internal.GetStat2( Name, ref val );
|
SteamUserStats.Internal.GetStat( Name, ref val );
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -101,11 +101,11 @@ namespace Steamworks.Data
|
|||||||
|
|
||||||
if ( UserId > 0 )
|
if ( UserId > 0 )
|
||||||
{
|
{
|
||||||
SteamUserStats.Internal.GetUserStat1( UserId, Name, ref val );
|
SteamUserStats.Internal.GetUserStat( UserId, Name, ref val );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SteamUserStats.Internal.GetStat1( Name, ref val );
|
SteamUserStats.Internal.GetStat( Name, ref val );
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
@ -114,13 +114,13 @@ namespace Steamworks.Data
|
|||||||
public bool Set( int val )
|
public bool Set( int val )
|
||||||
{
|
{
|
||||||
LocalUserOnly();
|
LocalUserOnly();
|
||||||
return SteamUserStats.Internal.SetStat1( Name, val );
|
return SteamUserStats.Internal.SetStat( Name, val );
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Set( float val )
|
public bool Set( float val )
|
||||||
{
|
{
|
||||||
LocalUserOnly();
|
LocalUserOnly();
|
||||||
return SteamUserStats.Internal.SetStat2( Name, val );
|
return SteamUserStats.Internal.SetStat( Name, val );
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Add( int val )
|
public bool Add( int val )
|
||||||
|
26
Facepunch.Steamworks/Structs/SteamIpAddress.cs
Normal file
26
Facepunch.Steamworks/Structs/SteamIpAddress.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Steamworks.Data
|
||||||
|
{
|
||||||
|
[StructLayout( LayoutKind.Explicit, Pack = Platform.StructPlatformPackSize )]
|
||||||
|
internal struct SteamIPAddress
|
||||||
|
{
|
||||||
|
[FieldOffset( 0 )]
|
||||||
|
public uint Ip4Address; // Host Order
|
||||||
|
|
||||||
|
[FieldOffset( 16 )]
|
||||||
|
internal SteamIPType Type; // m_eType ESteamIPType
|
||||||
|
|
||||||
|
public static implicit operator System.Net.IPAddress( SteamIPAddress value )
|
||||||
|
{
|
||||||
|
if ( value.Type == SteamIPType.Type4 )
|
||||||
|
return Utility.Int32ToIp( value.Ip4Address );
|
||||||
|
|
||||||
|
throw new System.Exception( $"Oops - can't convert SteamIPAddress to System.Net.IPAddress because no-one coded support for {value.Type} yet" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,23 +7,6 @@ namespace Steamworks.Data
|
|||||||
{
|
{
|
||||||
delegate void FSteamNetworkingSocketsDebugOutput (DebugOutputType nType, string pszMsg );
|
delegate void FSteamNetworkingSocketsDebugOutput (DebugOutputType nType, string pszMsg );
|
||||||
|
|
||||||
public struct SteamNetworkingPOPID
|
|
||||||
{
|
|
||||||
public uint Value;
|
|
||||||
|
|
||||||
public static implicit operator SteamNetworkingPOPID( uint value )
|
|
||||||
{
|
|
||||||
return new SteamNetworkingPOPID { Value = value };
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator uint( SteamNetworkingPOPID value )
|
|
||||||
{
|
|
||||||
return value.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString() => Value.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
[StructLayout( LayoutKind.Sequential )]
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
public struct SteamNetworkingQuickConnectionStatus
|
public struct SteamNetworkingQuickConnectionStatus
|
||||||
{
|
{
|
||||||
@ -49,9 +32,4 @@ namespace Steamworks.Data
|
|||||||
{
|
{
|
||||||
// Not implemented
|
// Not implemented
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SteamDatagramHostedAddress
|
|
||||||
{
|
|
||||||
// Not implemented
|
|
||||||
}
|
|
||||||
}
|
}
|
11
Facepunch.Steamworks/Structs/SteamNetworkingErrMsg.cs
Normal file
11
Facepunch.Steamworks/Structs/SteamNetworkingErrMsg.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
using Steamworks.Data;
|
||||||
|
|
||||||
|
namespace Steamworks.Data
|
||||||
|
{
|
||||||
|
|
||||||
|
internal unsafe struct SteamNetworkingErrMsg
|
||||||
|
{
|
||||||
|
public fixed char Value[1024];
|
||||||
|
}
|
||||||
|
}
|
@ -204,7 +204,7 @@ namespace Steamworks.Ugc
|
|||||||
|
|
||||||
progress?.Report( 1 );
|
progress?.Report( 1 );
|
||||||
|
|
||||||
var updated = updating.Result;
|
var updated = updating.GetResult();
|
||||||
|
|
||||||
if ( !updated.HasValue ) return result;
|
if ( !updated.HasValue ) return result;
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ namespace Steamworks.Ugc
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
handle = SteamUGC.Internal.CreateQueryAllUGCRequest1( queryType, matchingType, creatorApp.Value, consumerApp.Value, (uint)page );
|
handle = SteamUGC.Internal.CreateQueryAllUGCRequest( queryType, matchingType, creatorApp.Value, consumerApp.Value, (uint)page );
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyReturns(handle);
|
ApplyReturns(handle);
|
||||||
|
@ -13,32 +13,21 @@ namespace Steamworks
|
|||||||
#if PLATFORM_WIN64
|
#if PLATFORM_WIN64
|
||||||
public const int StructPlatformPackSize = 8;
|
public const int StructPlatformPackSize = 8;
|
||||||
public const string LibraryName = "steam_api64";
|
public const string LibraryName = "steam_api64";
|
||||||
public const CallingConvention MemberConvention = CallingConvention.Cdecl;
|
public const CallingConvention CC = CallingConvention.Cdecl;
|
||||||
#elif PLATFORM_WIN32
|
#elif PLATFORM_WIN32
|
||||||
public const int StructPlatformPackSize = 8;
|
public const int StructPlatformPackSize = 8;
|
||||||
public const string LibraryName = "steam_api";
|
public const string LibraryName = "steam_api";
|
||||||
public const CallingConvention MemberConvention = CallingConvention.ThisCall;
|
public const CallingConvention CC = CallingConvention.Cdecl;
|
||||||
#elif PLATFORM_POSIX32
|
#elif PLATFORM_POSIX32
|
||||||
public const int StructPlatformPackSize = 4;
|
public const int StructPlatformPackSize = 4;
|
||||||
public const string LibraryName = "libsteam_api";
|
public const string LibraryName = "libsteam_api";
|
||||||
public const CallingConvention MemberConvention = CallingConvention.Cdecl;
|
public const CallingConvention CC = CallingConvention.Cdecl;
|
||||||
#elif PLATFORM_POSIX64
|
#elif PLATFORM_POSIX64
|
||||||
public const int StructPlatformPackSize = 4;
|
public const int StructPlatformPackSize = 4;
|
||||||
public const string LibraryName = "libsteam_api";
|
public const string LibraryName = "libsteam_api";
|
||||||
public const CallingConvention MemberConvention = CallingConvention.Cdecl;
|
public const CallingConvention CC = CallingConvention.Cdecl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public const int StructPackSize = 4;
|
public const int StructPackSize = 4;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static int MemoryOffset( int memLocation )
|
|
||||||
{
|
|
||||||
#if PLATFORM_64
|
|
||||||
return memLocation;
|
|
||||||
#else
|
|
||||||
return memLocation / 2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ namespace Steamworks
|
|||||||
return await GetRules(client);
|
return await GetRules(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception)
|
||||||
{
|
{
|
||||||
//Console.Error.WriteLine( e.Message );
|
//Console.Error.WriteLine( e.Message );
|
||||||
return null;
|
return null;
|
||||||
|
@ -11,103 +11,42 @@ namespace Steamworks
|
|||||||
{
|
{
|
||||||
internal abstract class SteamInterface
|
internal abstract class SteamInterface
|
||||||
{
|
{
|
||||||
|
public virtual IntPtr GetUserInterfacePointer() => IntPtr.Zero;
|
||||||
|
public virtual IntPtr GetServerInterfacePointer() => IntPtr.Zero;
|
||||||
|
public virtual IntPtr GetGlobalInterfacePointer() => IntPtr.Zero;
|
||||||
|
|
||||||
public IntPtr Self;
|
public IntPtr Self;
|
||||||
public IntPtr VTable;
|
|
||||||
|
|
||||||
public virtual string InterfaceName => null;
|
public bool IsValid => Self != IntPtr.Zero;
|
||||||
public bool IsValid => Self != IntPtr.Zero && VTable != IntPtr.Zero;
|
|
||||||
|
|
||||||
public void Init()
|
internal void SetupInterface( bool gameServer )
|
||||||
{
|
{
|
||||||
if ( SteamClient.IsValid )
|
Self = GetGlobalInterfacePointer();
|
||||||
{
|
|
||||||
InitClient();
|
if ( Self != IntPtr.Zero )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ( gameServer )
|
||||||
|
Self = GetServerInterfacePointer();
|
||||||
|
else
|
||||||
|
Self = GetUserInterfacePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( SteamServer.IsValid )
|
internal void ShutdownInterface()
|
||||||
{
|
|
||||||
InitServer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new System.Exception( "Trying to initialize Steam Interface but Steam not initialized" );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InitClient()
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
|
||||||
// There's an issue for us using FindOrCreateUserInterface on Rust.
|
|
||||||
// We have a different appid for our staging branch, but we use Rust's
|
|
||||||
// appid so we can still test with the live data/setup. The issue is
|
|
||||||
// if we run the staging branch and get interfaces using FindOrCreate
|
|
||||||
// then some callbacks don't work. I assume this is because these interfaces
|
|
||||||
// have already been initialized using the old appid pipe, but since I
|
|
||||||
// can't see inside Steam this is just a gut feeling. Either way using
|
|
||||||
// CreateInterface doesn't seem to have caused any fires, so we'll just use that.
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// var pipe = SteamAPI.GetHSteamPipe();
|
|
||||||
//
|
|
||||||
|
|
||||||
Self = SteamInternal.CreateInterface( InterfaceName );
|
|
||||||
|
|
||||||
if ( Self == IntPtr.Zero )
|
|
||||||
{
|
|
||||||
var user = SteamAPI.GetHSteamUser();
|
|
||||||
Self = SteamInternal.FindOrCreateUserInterface( user, InterfaceName );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( Self == IntPtr.Zero )
|
|
||||||
throw new System.Exception( $"Couldn't find interface {InterfaceName}" );
|
|
||||||
|
|
||||||
VTable = Marshal.ReadIntPtr( Self, 0 );
|
|
||||||
if ( Self == IntPtr.Zero )
|
|
||||||
throw new System.Exception( $"Invalid VTable for {InterfaceName}" );
|
|
||||||
|
|
||||||
InitInternals();
|
|
||||||
SteamClient.WatchInterface( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InitServer()
|
|
||||||
{
|
|
||||||
var user = SteamGameServer.GetHSteamUser();
|
|
||||||
Self = SteamInternal.FindOrCreateGameServerInterface( user, InterfaceName );
|
|
||||||
|
|
||||||
if ( Self == IntPtr.Zero )
|
|
||||||
throw new System.Exception( $"Couldn't find server interface {InterfaceName}" );
|
|
||||||
|
|
||||||
VTable = Marshal.ReadIntPtr( Self, 0 );
|
|
||||||
if ( Self == IntPtr.Zero )
|
|
||||||
throw new System.Exception( $"Invalid VTable for server {InterfaceName}" );
|
|
||||||
|
|
||||||
InitInternals();
|
|
||||||
SteamServer.WatchInterface( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void InitUserless()
|
|
||||||
{
|
|
||||||
Self = SteamInternal.FindOrCreateUserInterface( 0, InterfaceName );
|
|
||||||
|
|
||||||
if ( Self == IntPtr.Zero )
|
|
||||||
throw new System.Exception( $"Couldn't find interface {InterfaceName}" );
|
|
||||||
|
|
||||||
VTable = Marshal.ReadIntPtr( Self, 0 );
|
|
||||||
if ( Self == IntPtr.Zero )
|
|
||||||
throw new System.Exception( $"Invalid VTable for {InterfaceName}" );
|
|
||||||
|
|
||||||
InitInternals();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal virtual void Shutdown()
|
|
||||||
{
|
{
|
||||||
Self = IntPtr.Zero;
|
Self = IntPtr.Zero;
|
||||||
VTable = IntPtr.Zero;
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void InitInternals();
|
public abstract class SteamClass
|
||||||
|
{
|
||||||
|
internal abstract void InitializeInterface( bool server );
|
||||||
|
internal virtual void DestroyInterface()
|
||||||
|
{
|
||||||
|
Interface.ShutdownInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal abstract SteamInterface Interface { get; }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,12 +3,21 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Steamworks
|
namespace Steamworks
|
||||||
{
|
{
|
||||||
public static partial class Utility
|
public static partial class Utility
|
||||||
{
|
{
|
||||||
|
static internal T ToType<T>( this IntPtr ptr )
|
||||||
|
{
|
||||||
|
if ( ptr == IntPtr.Zero )
|
||||||
|
return default;
|
||||||
|
|
||||||
|
return (T)Marshal.PtrToStructure( ptr, typeof( T ) );
|
||||||
|
}
|
||||||
|
|
||||||
static internal uint Swap( uint x )
|
static internal uint Swap( uint x )
|
||||||
{
|
{
|
||||||
return ((x & 0x000000ff) << 24) +
|
return ((x & 0x000000ff) << 24) +
|
||||||
|
Binary file not shown.
Binary file not shown.
BIN
Facepunch.Steamworks/steam_api.dll
Normal file
BIN
Facepunch.Steamworks/steam_api.dll
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user