v1.0.13.1 (first post-1.0 patch)

This commit is contained in:
Regalis11
2023-05-10 15:07:17 +03:00
parent 96fb49ba14
commit ee1db852b1
272 changed files with 5738 additions and 2413 deletions

View File

@@ -14,7 +14,7 @@ namespace Steamworks
internal struct CallResult<T> : INotifyCompletion where T : struct, ICallbackData
{
SteamAPICall_t call;
ISteamUtils utils;
ISteamUtils? utils;
bool server;
public CallResult( SteamAPICall_t call, bool server )
@@ -43,6 +43,8 @@ namespace Steamworks
/// </summary>
public T? GetResult()
{
if (utils is null) { return null; }
bool failed = false;
if ( !utils.IsAPICallCompleted( call, ref failed ) || failed )
return null;
@@ -76,6 +78,8 @@ namespace Steamworks
{
get
{
if (utils is null) { return true; }
bool failed = false;
if ( utils.IsAPICallCompleted( call, ref failed ) || failed )
return true;

View File

@@ -4,7 +4,7 @@ namespace Steamworks
{
public class AuthTicket : IDisposable
{
public byte[] Data;
public byte[]? Data;
public uint Handle;
public bool Canceled { get; private set; }
@@ -17,7 +17,7 @@ namespace Steamworks
{
if (Handle != 0)
{
SteamUser.Internal.CancelAuthTicket(Handle);
SteamUser.Internal?.CancelAuthTicket(Handle);
}
Handle = 0;

View File

@@ -26,7 +26,7 @@ namespace Steamworks
/// Params are : [Callback Type] [Callback Contents] [server]
///
/// </summary>
public static Action<CallbackType, string, bool> OnDebugCallback;
public static Action<CallbackType, string, bool>? OnDebugCallback;
/// <summary>
/// Called if an exception happens during a callback/callresult.
@@ -34,7 +34,7 @@ namespace Steamworks
/// async.. and can fail silently. With this hooked you won't be stuck wondering
/// what happened.
/// </summary>
public static Action<Exception> OnException;
public static Action<Exception>? OnException;
#region interop
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ManualDispatch_Init", CallingConvention = CallingConvention.Cdecl )]
@@ -288,7 +288,7 @@ namespace Steamworks
/// <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
internal static void Install<T>( Action<T> p, bool server = false ) where T : struct, ICallbackData
{
var t = default( T );
var type = t.CallbackType;

View File

@@ -5,10 +5,15 @@
<DefineConstants>$(DefineConstants);PLATFORM_POSIX64;PLATFORM_POSIX;PLATFORM_64</DefineConstants>
<TargetFrameworks>netstandard2.1</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>8.0</LangVersion>
<LangVersion>latest</LangVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<RootNamespace>Steamworks</RootNamespace>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<WarningsAsErrors>;NU1605;CS0114;CS0108;CS8597;CS8600;CS8601;CS8602;CS8603;CS8604;CS8605;CS8606;CS8607;CS8608;CS8609;CS8610;CS8611;CS8612;CS8613;CS8614;CS8615;CS8616;CS8617;CS8618;CS8619;CS8620;CS8621;CS8622;CS8624;CS8625;CS8626;CS8629;CS8631;CS8632;CS8633;CS8634;CS8638;CS8643;CS8644;CS8645;CS8653;CS8654;CS8655;CS8667;CS8669;CS8670;CS8714;CS8717;CS8765</WarningsAsErrors>
</PropertyGroup>
<Import Project="Facepunch.Steamworks.targets" />

View File

@@ -10,6 +10,7 @@
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<RootNamespace>Steamworks</RootNamespace>
<Platforms>AnyCPU;x64</Platforms>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
@@ -48,6 +49,10 @@
<NoWarn>1701;1702;1591;1587</NoWarn>
</PropertyGroup>
<PropertyGroup>
<WarningsAsErrors>;NU1605;CS0114;CS0108;CS8597;CS8600;CS8601;CS8602;CS8603;CS8604;CS8605;CS8606;CS8607;CS8608;CS8609;CS8610;CS8611;CS8612;CS8613;CS8614;CS8615;CS8616;CS8617;CS8618;CS8619;CS8620;CS8621;CS8622;CS8624;CS8625;CS8626;CS8629;CS8631;CS8632;CS8633;CS8634;CS8638;CS8643;CS8644;CS8645;CS8653;CS8654;CS8655;CS8667;CS8669;CS8670;CS8714;CS8717;CS8765</WarningsAsErrors>
</PropertyGroup>
<Import Project="Facepunch.Steamworks.targets" />
<Target Name="PostBuildHome" AfterTargets="PostBuildEvent" Condition="'$(Computername)'=='GarryBasementPc'">

View File

@@ -76,7 +76,7 @@ namespace Steamworks
private static extern Utf8StringPointer _GetCurrentGameLanguage( IntPtr self );
#endregion
internal string GetCurrentGameLanguage()
internal string? GetCurrentGameLanguage()
{
var returnValue = _GetCurrentGameLanguage( Self );
return returnValue;

View File

@@ -40,13 +40,13 @@ namespace Steamworks
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamInventory_GetResultItems", CallingConvention = Platform.CC)]
[return: MarshalAs( UnmanagedType.I1 )]
private static extern bool _GetResultItems( IntPtr self, SteamInventoryResult_t resultHandle, [In,Out] SteamItemDetails_t[] pOutItemsArray, ref uint punOutItemsArraySize );
private static extern bool _GetResultItems( IntPtr self, SteamInventoryResult_t resultHandle, [In,Out] SteamItemDetails_t[]? pOutItemsArray, ref uint punOutItemsArraySize );
#endregion
/// <summary>
/// Copies the contents of a result set into a flat array. The specific contents of the result set depend on which query which was used.
/// </summary>
internal bool GetResultItems( SteamInventoryResult_t resultHandle, [In,Out] SteamItemDetails_t[] pOutItemsArray, ref uint punOutItemsArraySize )
internal bool GetResultItems( SteamInventoryResult_t resultHandle, [In,Out] SteamItemDetails_t[]? pOutItemsArray, ref uint punOutItemsArraySize )
{
var returnValue = _GetResultItems( Self, resultHandle, pOutItemsArray, ref punOutItemsArraySize );
return returnValue;
@@ -55,10 +55,10 @@ namespace Steamworks
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamInventory_GetResultItemProperty", CallingConvention = Platform.CC)]
[return: MarshalAs( UnmanagedType.I1 )]
private static extern bool _GetResultItemProperty( IntPtr self, SteamInventoryResult_t resultHandle, uint unItemIndex, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string pchPropertyName, IntPtr pchValueBuffer, ref uint punValueBufferSizeOut );
private static extern bool _GetResultItemProperty( IntPtr self, SteamInventoryResult_t resultHandle, uint unItemIndex, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string? pchPropertyName, IntPtr pchValueBuffer, ref uint punValueBufferSizeOut );
#endregion
internal bool GetResultItemProperty( SteamInventoryResult_t resultHandle, uint unItemIndex, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string pchPropertyName, out string pchValueBuffer, ref uint punValueBufferSizeOut )
internal bool GetResultItemProperty( SteamInventoryResult_t resultHandle, uint unItemIndex, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string? pchPropertyName, out string pchValueBuffer, ref uint punValueBufferSizeOut )
{
using var memory = Helpers.TakeMemory();
IntPtr mempchValueBuffer = memory;
@@ -311,10 +311,10 @@ namespace Steamworks
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamInventory_GetItemDefinitionIDs", CallingConvention = Platform.CC)]
[return: MarshalAs( UnmanagedType.I1 )]
private static extern bool _GetItemDefinitionIDs( IntPtr self, [In,Out] InventoryDefId[] pItemDefIDs, ref uint punItemDefIDsArraySize );
private static extern bool _GetItemDefinitionIDs( IntPtr self, [In,Out] InventoryDefId[]? pItemDefIDs, ref uint punItemDefIDsArraySize );
#endregion
internal bool GetItemDefinitionIDs( [In,Out] InventoryDefId[] pItemDefIDs, ref uint punItemDefIDsArraySize )
internal bool GetItemDefinitionIDs( [In,Out] InventoryDefId[]? pItemDefIDs, ref uint punItemDefIDsArraySize )
{
var returnValue = _GetItemDefinitionIDs( Self, pItemDefIDs, ref punItemDefIDsArraySize );
return returnValue;
@@ -323,10 +323,10 @@ namespace Steamworks
#region FunctionMeta
[DllImport( Platform.LibraryName, EntryPoint = "SteamAPI_ISteamInventory_GetItemDefinitionProperty", CallingConvention = Platform.CC)]
[return: MarshalAs( UnmanagedType.I1 )]
private static extern bool _GetItemDefinitionProperty( IntPtr self, InventoryDefId iDefinition, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string pchPropertyName, IntPtr pchValueBuffer, ref uint punValueBufferSizeOut );
private static extern bool _GetItemDefinitionProperty( IntPtr self, InventoryDefId iDefinition, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string? pchPropertyName, IntPtr pchValueBuffer, ref uint punValueBufferSizeOut );
#endregion
internal bool GetItemDefinitionProperty( InventoryDefId iDefinition, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string pchPropertyName, out string pchValueBuffer, ref uint punValueBufferSizeOut )
internal bool GetItemDefinitionProperty( InventoryDefId iDefinition, [MarshalAs( UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof( Utf8StringToNative ) )] string? pchPropertyName, out string pchValueBuffer, ref uint punValueBufferSizeOut )
{
using var memory = Helpers.TakeMemory();
IntPtr mempchValueBuffer = memory;

View File

@@ -24,7 +24,7 @@ namespace Steamworks.Data
/// </summary>
public Result Accept()
{
return SteamNetworkingSockets.Internal.AcceptConnection( this );
return SteamNetworkingSockets.Internal?.AcceptConnection( this ) ?? Result.Fail;
}
/// <summary>
@@ -33,7 +33,7 @@ namespace Steamworks.Data
/// </summary>
public bool Close( bool linger = false, int reasonCode = 0, string debugString = "Closing Connection" )
{
return SteamNetworkingSockets.Internal.CloseConnection( this, reasonCode, debugString, linger );
return SteamNetworkingSockets.Internal != null && SteamNetworkingSockets.Internal.CloseConnection( this, reasonCode, debugString, linger );
}
/// <summary>
@@ -41,8 +41,8 @@ namespace Steamworks.Data
/// </summary>
public long UserData
{
get => SteamNetworkingSockets.Internal.GetConnectionUserData( this );
set => SteamNetworkingSockets.Internal.SetConnectionUserData( this, value );
get => SteamNetworkingSockets.Internal?.GetConnectionUserData( this ) ?? 0;
set => SteamNetworkingSockets.Internal?.SetConnectionUserData( this, value );
}
/// <summary>
@@ -52,13 +52,13 @@ namespace Steamworks.Data
{
get
{
if ( !SteamNetworkingSockets.Internal.GetConnectionName( this, out var strVal ) )
if ( SteamNetworkingSockets.Internal is null || !SteamNetworkingSockets.Internal.GetConnectionName( this, out var strVal ) )
return "ERROR";
return strVal;
}
set => SteamNetworkingSockets.Internal.SetConnectionName( this, value );
set => SteamNetworkingSockets.Internal?.SetConnectionName( this, value );
}
/// <summary>
@@ -67,7 +67,7 @@ namespace Steamworks.Data
public Result SendMessage( IntPtr ptr, int size, SendType sendType = SendType.Reliable )
{
long messageNumber = 0;
return SteamNetworkingSockets.Internal.SendMessageToConnection( this, ptr, (uint) size, (int)sendType, ref messageNumber );
return SteamNetworkingSockets.Internal?.SendMessageToConnection( this, ptr, (uint) size, (int)sendType, ref messageNumber ) ?? Result.Fail;
}
/// <summary>
@@ -107,16 +107,16 @@ namespace Steamworks.Data
/// Flush any messages waiting on the Nagle timer and send them at the next transmission
/// opportunity (often that means right now).
/// </summary>
public Result Flush() => SteamNetworkingSockets.Internal.FlushMessagesOnConnection( this );
public Result Flush() => SteamNetworkingSockets.Internal?.FlushMessagesOnConnection( this ) ?? Result.Fail;
/// <summary>
/// Returns detailed connection stats in text format. Useful
/// for dumping to a log, etc.
/// </summary>
/// <returns>Plain text connection info</returns>
public string DetailedStatus()
public string? DetailedStatus()
{
if ( SteamNetworkingSockets.Internal.GetDetailedConnectionStatus( this, out var strVal ) != 0 )
if ( SteamNetworkingSockets.Internal is null || SteamNetworkingSockets.Internal.GetDetailedConnectionStatus( this, out var strVal ) != 0 )
return null;
return strVal;

View File

@@ -9,7 +9,7 @@ namespace Steamworks
/// <summary>
/// An optional interface to use instead of deriving
/// </summary>
public IConnectionManager Interface { get; set; }
public IConnectionManager? Interface { get; set; }
/// <summary>
/// The actual connection we're managing
@@ -94,6 +94,8 @@ namespace Steamworks
public void Receive( int bufferSize = 32 )
{
if (SteamNetworkingSockets.Internal is null) { return; }
int processed = 0;
IntPtr messageBuffer = Marshal.AllocHGlobal( IntPtr.Size * bufferSize );

View File

@@ -107,10 +107,11 @@ namespace Steamworks.Data
/// <summary>
/// We override tostring to provide a sensible representation
/// </summary>
public override string ToString()
public override string? ToString()
{
var id = this;
SteamNetworkingUtils.Internal.SteamNetworkingIdentity_ToString( ref id, out var str );
string? str = null;
SteamNetworkingUtils.Internal?.SteamNetworkingIdentity_ToString( ref id, out str );
return str;
}

View File

@@ -25,15 +25,16 @@ namespace Steamworks.Data
public static NetPingLocation? TryParseFromString( string str )
{
var result = default( NetPingLocation );
if ( !SteamNetworkingUtils.Internal.ParsePingLocationString( str, ref result ) )
if ( SteamNetworkingUtils.Internal is null || !SteamNetworkingUtils.Internal.ParsePingLocationString( str, ref result ) )
return null;
return result;
}
public override string ToString()
public override string? ToString()
{
SteamNetworkingUtils.Internal.ConvertPingLocationToString( ref this, out var strVal );
string? strVal = null;
SteamNetworkingUtils.Internal?.ConvertPingLocationToString( ref this, out strVal );
return strVal;
}
@@ -61,7 +62,7 @@ namespace Steamworks.Data
/// You are looking for the "ticketgen" library.
public int EstimatePingTo( NetPingLocation target )
{
return SteamNetworkingUtils.Internal.EstimatePingTimeBetweenTwoLocations( ref this, ref target );
return SteamNetworkingUtils.Internal?.EstimatePingTimeBetweenTwoLocations( ref this, ref target ) ?? Defines.k_nSteamNetworkingPing_Failed;
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace Steamworks.Data
@@ -17,10 +18,11 @@ namespace Steamworks.Data
/// </summary>
public bool Close()
{
return SteamNetworkingSockets.Internal.CloseListenSocket( Id );
return SteamNetworkingSockets.Internal != null && SteamNetworkingSockets.Internal.CloseListenSocket( Id );
}
public SocketManager Manager
[DisallowNull]
public SocketManager? Manager
{
get => SteamNetworkingSockets.GetSocketManager( Id );
set => SteamNetworkingSockets.SetSocketManager( Id, value );

View File

@@ -14,7 +14,7 @@ namespace Steamworks
/// </summary>
public partial class SocketManager
{
public ISocketManager Interface { get; set; }
public ISocketManager? Interface { get; set; }
public List<Connection> Connecting = new List<Connection>();
public List<Connection> Connected = new List<Connection>();
@@ -26,12 +26,12 @@ namespace Steamworks
internal void Initialize()
{
pollGroup = SteamNetworkingSockets.Internal.CreatePollGroup();
pollGroup = SteamNetworkingSockets.Internal?.CreatePollGroup() ?? default;
}
public bool Close()
{
if ( SteamNetworkingSockets.Internal.IsValid )
if ( SteamNetworkingSockets.Internal is { IsValid: true } )
{
SteamNetworkingSockets.Internal.DestroyPollGroup( pollGroup );
Socket.Close();
@@ -94,7 +94,7 @@ namespace Steamworks
/// </summary>
public virtual void OnConnected( Connection connection, ConnectionInfo info )
{
SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, pollGroup );
SteamNetworkingSockets.Internal?.SetConnectionPollGroup( connection, pollGroup );
Interface?.OnConnected( connection, info );
}
@@ -104,7 +104,7 @@ namespace Steamworks
/// </summary>
public virtual void OnDisconnected( Connection connection, ConnectionInfo info )
{
SteamNetworkingSockets.Internal.SetConnectionPollGroup( connection, 0 );
SteamNetworkingSockets.Internal?.SetConnectionPollGroup( connection, 0 );
connection.Close();
@@ -121,7 +121,7 @@ namespace Steamworks
try
{
processed = SteamNetworkingSockets.Internal.ReceiveMessagesOnPollGroup( pollGroup, messageBuffer, bufferSize );
processed = SteamNetworkingSockets.Internal?.ReceiveMessagesOnPollGroup( pollGroup, messageBuffer, bufferSize ) ?? 0;
for ( int i = 0; i < processed; i++ )
{

View File

@@ -11,7 +11,7 @@ namespace Steamworks.ServerList
{
#region ISteamMatchmakingServers
internal static ISteamMatchmakingServers Internal => SteamMatchmakingServers.Internal;
internal static ISteamMatchmakingServers? Internal => SteamMatchmakingServers.Internal;
#endregion
@@ -23,17 +23,17 @@ namespace Steamworks.ServerList
/// <summary>
/// When a new server is added, this function will get called
/// </summary>
public Action OnChanges;
public Action? OnChanges;
/// <summary>
/// Called for every responsive server
/// </summary>
public Action<ServerInfo> OnResponsiveServer;
public Action<ServerInfo>? OnResponsiveServer;
/// <summary>
/// Called for every unresponsive server
/// </summary>
public Action<ServerInfo> OnUnresponsiveServer;
public Action<ServerInfo>? OnUnresponsiveServer;
/// <summary>
/// A list of servers that responded. If you're only interested in servers that responded since you
@@ -98,7 +98,7 @@ namespace Steamworks.ServerList
return true;
}
public virtual void Cancel() => Internal.CancelQuery( request );
public virtual void Cancel() => Internal?.CancelQuery( request );
// Overrides
internal abstract void LaunchQuery();
@@ -117,8 +117,8 @@ namespace Steamworks.ServerList
#endregion
internal int Count => Internal.GetServerCount( request );
internal bool IsRefreshing => request.Value != IntPtr.Zero && Internal.IsRefreshing( request );
internal int Count => Internal?.GetServerCount( request ) ?? 0;
internal bool IsRefreshing => request.Value != IntPtr.Zero && Internal != null && Internal.IsRefreshing( request );
internal List<int> watchList = new List<int>();
internal int LastCount = 0;
@@ -134,7 +134,7 @@ namespace Steamworks.ServerList
if ( request.Value != IntPtr.Zero )
{
Cancel();
Internal.ReleaseRequest( request );
Internal?.ReleaseRequest( request );
request = IntPtr.Zero;
}
}
@@ -166,6 +166,8 @@ namespace Steamworks.ServerList
{
watchList.RemoveAll( x =>
{
if (Internal is null) { return true; }
var info = Internal.GetServerDetails( request, x );
if ( info.HadSuccessfulResponse )
{
@@ -181,6 +183,8 @@ namespace Steamworks.ServerList
{
watchList.RemoveAll( x =>
{
if (Internal is null) { return true; }
var info = Internal.GetServerDetails( request, x );
OnServer( ServerInfo.From( info ), info.HadSuccessfulResponse );
return true;

View File

@@ -10,6 +10,7 @@ namespace Steamworks.ServerList
{
internal override void LaunchQuery()
{
if (Internal is null) { return; }
var filters = GetFilters();
request = Internal.RequestFavoritesServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero );
}

View File

@@ -10,6 +10,7 @@ namespace Steamworks.ServerList
{
internal override void LaunchQuery()
{
if (Internal is null) { return; }
var filters = GetFilters();
request = Internal.RequestFriendsServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero );
}

View File

@@ -10,6 +10,7 @@ namespace Steamworks.ServerList
{
internal override void LaunchQuery()
{
if (Internal is null) { return; }
var filters = GetFilters();
request = Internal.RequestHistoryServerList( AppId.Value, ref filters, (uint)filters.Length, IntPtr.Zero );
}

View File

@@ -10,8 +10,8 @@ namespace Steamworks.ServerList
{
internal override void LaunchQuery()
{
if (Internal is null) { return; }
var filters = GetFilters();
request = Internal.RequestInternetServerList( AppId.Value, filters, (uint)filters.Length, IntPtr.Zero );
}
}

View File

@@ -10,6 +10,7 @@ namespace Steamworks.ServerList
{
internal override void LaunchQuery()
{
if (Internal is null) { return; }
request = Internal.RequestLANServerList( AppId.Value, IntPtr.Zero );
}
}

View File

@@ -13,7 +13,7 @@ namespace Steamworks
/// </summary>
public class SteamApps : SteamSharedClass<SteamApps>
{
internal static ISteamApps Internal => Interface as ISteamApps;
internal static ISteamApps? Internal => Interface as ISteamApps;
internal override void InitializeInterface( bool server )
{
@@ -29,7 +29,7 @@ namespace Steamworks
/// <summary>
/// posted after the user gains ownership of DLC and that DLC is installed
/// </summary>
public static event Action<AppId> OnDlcInstalled;
public static event Action<AppId>? OnDlcInstalled;
/// <summary>
/// posted after the user gains executes a Steam URL with command line or query parameters
@@ -37,61 +37,63 @@ namespace Steamworks
/// while the game is already running. The new params can be queried
/// with GetLaunchQueryParam and GetLaunchCommandLine
/// </summary>
public static event Action OnNewLaunchParameters;
public static event Action? OnNewLaunchParameters;
/// <summary>
/// Checks if the active user is subscribed to the current App ID
/// </summary>
public static bool IsSubscribed => Internal.BIsSubscribed();
public static bool IsSubscribed => Internal != null && Internal.BIsSubscribed();
/// <summary>
/// Check if user borrowed this game via Family Sharing, If true, call GetAppOwner() to get the lender SteamID
/// </summary>
public static bool IsSubscribedFromFamilySharing => Internal.BIsSubscribedFromFamilySharing();
public static bool IsSubscribedFromFamilySharing => Internal != null && Internal.BIsSubscribedFromFamilySharing();
/// <summary>
/// Checks if the license owned by the user provides low violence depots.
/// Low violence depots are useful for copies sold in countries that have content restrictions
/// </summary>
public static bool IsLowViolence => Internal.BIsLowViolence();
public static bool IsLowViolence => Internal != null && Internal.BIsLowViolence();
/// <summary>
/// Checks whether the current App ID license is for Cyber Cafes.
/// </summary>
public static bool IsCybercafe => Internal.BIsCybercafe();
public static bool IsCybercafe => Internal != null && Internal.BIsCybercafe();
/// <summary>
/// CChecks if the user has a VAC ban on their account
/// </summary>
public static bool IsVACBanned => Internal.BIsVACBanned();
public static bool IsVACBanned => Internal != null && Internal.BIsVACBanned();
/// <summary>
/// Gets the current language that the user has set.
/// This falls back to the Steam UI language if the user hasn't explicitly picked a language for the title.
/// </summary>
public static string GameLanguage => Internal.GetCurrentGameLanguage();
public static string? GameLanguage => Internal?.GetCurrentGameLanguage();
/// <summary>
/// Gets a list of the languages the current app supports.
/// </summary>
public static string[] AvailableLanguages => Internal.GetAvailableGameLanguages().Split( new[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
public static string[]? AvailableLanguages => Internal?.GetAvailableGameLanguages().Split( new[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
/// <summary>
/// Checks if the active user is subscribed to a specified AppId.
/// Only use this if you need to check ownership of another game related to yours, a demo for example.
/// </summary>
public static bool IsSubscribedToApp( AppId appid ) => Internal.BIsSubscribedApp( appid.Value );
public static bool IsSubscribedToApp( AppId appid ) => Internal != null && Internal.BIsSubscribedApp( appid.Value );
/// <summary>
/// Checks if the user owns a specific DLC and if the DLC is installed
/// </summary>
public static bool IsDlcInstalled( AppId appid ) => Internal.BIsDlcInstalled( appid.Value );
public static bool IsDlcInstalled( AppId appid ) => Internal != null && Internal.BIsDlcInstalled( appid.Value );
/// <summary>
/// Returns the time of the purchase of the app
/// </summary>
public static DateTime PurchaseTime( AppId appid = default )
{
if (Internal is null) { return default; }
if ( appid == 0 )
appid = SteamClient.AppId;
@@ -103,7 +105,7 @@ namespace Steamworks
/// This function will return false for users who have a retail or other type of license
/// Before using, please ask your Valve technical contact how to package and secure your free weekened
/// </summary>
public static bool IsSubscribedFromFreeWeekend => Internal.BIsSubscribedFromFreeWeekend();
public static bool IsSubscribedFromFreeWeekend => Internal != null && Internal.BIsSubscribedFromFreeWeekend();
/// <summary>
/// Returns metadata for all available DLC
@@ -113,8 +115,12 @@ namespace Steamworks
var appid = default( AppId );
var available = false;
for ( int i = 0; i < Internal.GetDLCCount(); i++ )
if (Internal is null) { yield break; }
int dlcCount = Internal.GetDLCCount();
for ( int i = 0; i < dlcCount; i++ )
{
if (Internal is null) { yield break; }
if ( !Internal.BGetDLCDataByIndex( i, ref appid, ref available, out var strVal ) )
continue;
@@ -130,21 +136,21 @@ namespace Steamworks
/// <summary>
/// Install/Uninstall control for optional DLC
/// </summary>
public static void InstallDlc( AppId appid ) => Internal.InstallDLC( appid.Value );
public static void InstallDlc( AppId appid ) => Internal?.InstallDLC( appid.Value );
/// <summary>
/// Install/Uninstall control for optional DLC
/// </summary>
public static void UninstallDlc( AppId appid ) => Internal.UninstallDLC( appid.Value );
public static void UninstallDlc( AppId appid ) => Internal?.UninstallDLC( appid.Value );
/// <summary>
/// Returns null if we're not on a beta branch, else the name of the branch
/// </summary>
public static string CurrentBetaName
public static string? CurrentBetaName
{
get
{
if ( !Internal.GetCurrentBetaName( out var strVal ) )
if ( Internal is null || !Internal.GetCurrentBetaName( out var strVal ) )
return null;
return strVal;
@@ -157,13 +163,15 @@ namespace Steamworks
/// If you detect the game is out-of-date(for example, by having the client detect a version mismatch with a server),
/// you can call use MarkContentCorrupt to force a verify, show a message to the user, and then quit.
/// </summary>
public static void MarkContentCorrupt( bool missingFilesOnly ) => Internal.MarkContentCorrupt( missingFilesOnly );
public static void MarkContentCorrupt( bool missingFilesOnly ) => Internal?.MarkContentCorrupt( missingFilesOnly );
/// <summary>
/// Gets a list of all installed depots for a given App ID in mount order
/// </summary>
public static IEnumerable<DepotId> InstalledDepots( AppId appid = default )
{
if (Internal is null) { yield break; }
if ( appid == 0 )
appid = SteamClient.AppId;
@@ -180,12 +188,12 @@ namespace Steamworks
/// Gets the install folder for a specific AppID.
/// This works even if the application is not installed, based on where the game would be installed with the default Steam library location.
/// </summary>
public static string AppInstallDir( AppId appid = default )
public static string? AppInstallDir( AppId appid = default )
{
if ( appid == 0 )
appid = SteamClient.AppId;
if ( Internal.GetAppInstallDir( appid.Value, out var strVal ) == 0 )
if ( Internal is null || Internal.GetAppInstallDir( appid.Value, out var strVal ) == 0 )
return null;
return strVal;
@@ -194,12 +202,12 @@ namespace Steamworks
/// <summary>
/// The app may not actually be owned by the current user, they may have it left over from a free weekend, etc.
/// </summary>
public static bool IsAppInstalled( AppId appid ) => Internal.BIsAppInstalled( appid.Value );
public static bool IsAppInstalled( AppId appid ) => Internal != null && Internal.BIsAppInstalled( appid.Value );
/// <summary>
/// Gets the Steam ID of the original owner of the current app. If it's different from the current user then it is borrowed..
/// </summary>
public static SteamId AppOwner => Internal.GetAppOwner().Value;
public static SteamId AppOwner => Internal?.GetAppOwner().Value ?? default;
/// <summary>
/// Gets the associated launch parameter if the game is run via steam://run/appid/?param1=value1;param2=value2;param3=value3 etc.
@@ -207,7 +215,7 @@ namespace Steamworks
/// Parameter names starting with an underscore '_' are reserved for steam features -- they can be queried by the game,
/// but it is advised that you not param names beginning with an underscore for your own features.
/// </summary>
public static string GetLaunchParam( string param ) => Internal.GetLaunchQueryParam( param );
public static string? GetLaunchParam( string param ) => Internal?.GetLaunchQueryParam( param );
/// <summary>
/// Gets the download progress for optional DLC.
@@ -217,7 +225,7 @@ namespace Steamworks
ulong punBytesDownloaded = 0;
ulong punBytesTotal = 0;
if ( !Internal.GetDlcDownloadProgress( appid.Value, ref punBytesDownloaded, ref punBytesTotal ) )
if ( Internal is null || !Internal.GetDlcDownloadProgress( appid.Value, ref punBytesDownloaded, ref punBytesTotal ) )
return default;
return new DownloadProgress { BytesDownloaded = punBytesDownloaded, BytesTotal = punBytesTotal, Active = true };
@@ -227,7 +235,7 @@ namespace Steamworks
/// Gets the buildid of this app, may change at any time based on backend updates to the game.
/// Defaults to 0 if you're not running a build downloaded from steam.
/// </summary>
public static int BuildId => Internal.GetAppBuildId();
public static int BuildId => Internal?.GetAppBuildId() ?? 0;
/// <summary>
@@ -236,6 +244,7 @@ namespace Steamworks
/// </summary>
public static async Task<FileDetails?> GetFileDetailsAsync( string filename )
{
if (Internal is null) { return null; }
var r = await Internal.GetFileDetails( filename );
if ( !r.HasValue || r.Value.Result != Result.OK )
@@ -257,11 +266,12 @@ namespace Steamworks
/// path and not be placed on the OS command line, you must set a value in your app's
/// configuration on Steam. Ask Valve for help with this.
/// </summary>
public static string CommandLine
public static string? CommandLine
{
get
{
Internal.GetLaunchCommandLine( out var strVal );
string? strVal = null;
Internal?.GetLaunchCommandLine( out strVal );
return strVal;
}
}

View File

@@ -124,7 +124,7 @@ namespace Steamworks
/// very good experience for the player and you could be preventing them from accessing APIs that do not
/// need a live connection to Steam.
/// </summary>
public static bool IsLoggedOn => SteamUser.Internal.BLoggedOn();
public static bool IsLoggedOn => SteamUser.Internal != null && SteamUser.Internal.BLoggedOn();
/// <summary>
/// Gets the Steam ID of the account currently logged into the Steam client. This is
@@ -132,18 +132,18 @@ namespace Steamworks
/// A Steam ID is a unique identifier for a Steam accounts, Steam groups, Lobbies and Chat
/// rooms, and used to differentiate users in all parts of the Steamworks API.
/// </summary>
public static SteamId SteamId => SteamUser.Internal.GetSteamID();
public static SteamId SteamId => SteamUser.Internal?.GetSteamID() ?? default;
/// <summary>
/// returns the local players name - guaranteed to not be NULL.
/// this is the same name as on the users community profile page
/// </summary>
public static string Name => SteamFriends.Internal.GetPersonaName();
public static string? Name => SteamFriends.Internal?.GetPersonaName();
/// <summary>
/// gets the status of the current user
/// </summary>
public static FriendState State => SteamFriends.Internal.GetPersonaState();
public static FriendState State => SteamFriends.Internal?.GetPersonaState() ?? FriendState.Offline;
/// <summary>
/// returns the appID of the current process

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamFriends : SteamClientClass<SteamFriends>
{
internal static ISteamFriends Internal => Interface as ISteamFriends;
internal static ISteamFriends? Internal => Interface as ISteamFriends;
internal override void InitializeInterface( bool server )
{
@@ -23,7 +23,7 @@ namespace Steamworks
InstallEvents();
}
static Dictionary<string, string> richPresence;
static Dictionary<string, string>? richPresence;
internal void InstallEvents()
{
@@ -40,42 +40,42 @@ namespace Steamworks
/// Called when chat message has been received from a friend. You'll need to turn on
/// ListenForFriendsMessages to recieve this. (friend, msgtype, message)
/// </summary>
public static event Action<Friend, string, string> OnChatMessage;
public static event Action<Friend, string, string>? OnChatMessage;
/// <summary>
/// called when a friends' status changes
/// </summary>
public static event Action<Friend> OnPersonaStateChange;
public static event Action<Friend>? OnPersonaStateChange;
/// <summary>
/// Called when the user tries to join a game from their friends list
/// rich presence will have been set with the "connect" key which is set here
/// </summary>
public static event Action<Friend, string> OnGameRichPresenceJoinRequested;
public static event Action<Friend, string>? OnGameRichPresenceJoinRequested;
/// <summary>
/// Posted when game overlay activates or deactivates
/// the game can use this to be pause or resume single player games
/// </summary>
public static event Action<bool> OnGameOverlayActivated;
public static event Action<bool>? OnGameOverlayActivated;
/// <summary>
/// Called when the user tries to join a different game server from their friends list
/// game client should attempt to connect to specified server when this is received
/// </summary>
public static event Action<string, string> OnGameServerChangeRequested;
public static event Action<string, string>? OnGameServerChangeRequested;
/// <summary>
/// Called when the user tries to join a lobby from their friends list
/// game client should attempt to connect to specified lobby when this is received
/// </summary>
public static event Action<Lobby, SteamId> OnGameLobbyJoinRequested;
public static event Action<Lobby, SteamId>? OnGameLobbyJoinRequested;
/// <summary>
/// Callback indicating updated data about friends rich presence information
/// </summary>
public static event Action<Friend> OnFriendRichPresenceUpdate;
public static event Action<Friend>? OnFriendRichPresenceUpdate;
static unsafe void OnFriendChatMessage( GameConnectedFriendChatMsg_t data )
{
@@ -86,7 +86,7 @@ namespace Steamworks
using var buffer = Helpers.TakeMemory();
var type = ChatEntryType.ChatMsg;
var len = Internal.GetFriendMessage( data.SteamIDUser, data.MessageID, buffer, Helpers.MemoryBufferSize, ref type );
var len = Internal?.GetFriendMessage( data.SteamIDUser, data.MessageID, buffer, Helpers.MemoryBufferSize, ref type ) ?? 0;
if ( len == 0 && type == ChatEntryType.Invalid )
return;
@@ -99,15 +99,18 @@ namespace Steamworks
private static IEnumerable<Friend> GetFriendsWithFlag(FriendFlags flag)
{
for ( int i=0; i<Internal.GetFriendCount( (int)flag); i++ )
if (Internal is null) { yield break; }
int friendCount = Internal.GetFriendCount((int)flag);
for ( int i=0; i<friendCount; i++ )
{
if (Internal is null) { yield break; }
yield return new Friend( Internal.GetFriendByIndex( i, (int)flag ) );
}
}
public static string GetFriendPersonaName( SteamId steamId )
public static string? GetFriendPersonaName( SteamId steamId )
{
return Internal.GetFriendPersonaName(steamId);
return Internal?.GetFriendPersonaName(steamId);
}
public static IEnumerable<Friend> GetFriends()
@@ -142,24 +145,33 @@ namespace Steamworks
public static IEnumerable<Friend> GetPlayedWith()
{
for ( int i = 0; i < Internal.GetCoplayFriendCount(); i++ )
if (Internal is null) { yield break; }
int friendCount = Internal.GetCoplayFriendCount();
for ( int i = 0; i < friendCount; i++ )
{
if (Internal is null) { yield break; }
yield return new Friend( Internal.GetCoplayFriend( i ) );
}
}
public static IEnumerable<Friend> GetFromSource( SteamId steamid )
{
for ( int i = 0; i < Internal.GetFriendCountFromSource( steamid ); i++ )
{
if (Internal is null) { yield break; }
int friendCount = Internal.GetFriendCountFromSource( steamid );
for ( int i = 0; i < friendCount; i++ )
{
if (Internal is null) { yield break; }
yield return new Friend( Internal.GetFriendFromSourceByIndex( steamid, i ) );
}
}
public static IEnumerable<Clan> GetClans()
{
for (int i = 0; i < Internal.GetClanCount(); i++)
if (Internal is null) { yield break; }
int friendCount = Internal.GetClanCount();
for ( int i = 0; i < friendCount; i++ )
{
if (Internal is null) { yield break; }
yield return new Clan( Internal.GetClanByIndex( i ) );
}
}
@@ -174,7 +186,7 @@ namespace Steamworks
/// "stats",
/// "achievements".
/// </summary>
public static void OpenOverlay( string type ) => Internal.ActivateGameOverlay( type );
public static void OpenOverlay( string type ) => Internal?.ActivateGameOverlay( type );
/// <summary>
/// "steamid" - Opens the overlay web browser to the specified user or groups profile.
@@ -187,35 +199,35 @@ namespace Steamworks
/// "friendrequestaccept" - Opens the overlay in minimal mode prompting the user to accept an incoming friend invite.
/// "friendrequestignore" - Opens the overlay in minimal mode prompting the user to ignore an incoming friend invite.
/// </summary>
public static void OpenUserOverlay( SteamId id, string type ) => Internal.ActivateGameOverlayToUser( type, id );
public static void OpenUserOverlay( SteamId id, string type ) => Internal?.ActivateGameOverlayToUser( type, id );
/// <summary>
/// Activates the Steam Overlay to the Steam store page for the provided app.
/// </summary>
public static void OpenStoreOverlay( AppId id ) => Internal.ActivateGameOverlayToStore( id.Value, OverlayToStoreFlag.None );
public static void OpenStoreOverlay( AppId id ) => Internal?.ActivateGameOverlayToStore( id.Value, OverlayToStoreFlag.None );
/// <summary>
/// Activates Steam Overlay web browser directly to the specified URL.
/// </summary>
public static void OpenWebOverlay( string url, bool modal = false ) => Internal.ActivateGameOverlayToWebPage( url, modal ? ActivateGameOverlayToWebPageMode.Modal : ActivateGameOverlayToWebPageMode.Default );
public static void OpenWebOverlay( string url, bool modal = false ) => Internal?.ActivateGameOverlayToWebPage( url, modal ? ActivateGameOverlayToWebPageMode.Modal : ActivateGameOverlayToWebPageMode.Default );
/// <summary>
/// Activates the Steam Overlay to open the invite dialog. Invitations sent from this dialog will be for the provided lobby.
/// </summary>
public static void OpenGameInviteOverlay( SteamId lobby ) => Internal.ActivateGameOverlayInviteDialog( lobby );
public static void OpenGameInviteOverlay( SteamId lobby ) => Internal?.ActivateGameOverlayInviteDialog( lobby );
/// <summary>
/// Mark a target user as 'played with'.
/// NOTE: The current user must be in game with the other player for the association to work.
/// </summary>
public static void SetPlayedWith( SteamId steamid ) => Internal.SetPlayedWith( steamid );
public static void SetPlayedWith( SteamId steamid ) => Internal?.SetPlayedWith( steamid );
/// <summary>
/// Requests the persona name and optionally the avatar of a specified user.
/// NOTE: It's a lot slower to download avatars and churns the local cache, so if you don't need avatars, don't request them.
/// returns true if we're fetching the data, false if we already have it
/// </summary>
public static bool RequestUserInformation( SteamId steamid, bool nameonly = true ) => Internal.RequestUserInformation( steamid, nameonly );
public static bool RequestUserInformation( SteamId steamid, bool nameonly = true ) => Internal != null && Internal.RequestUserInformation( steamid, nameonly );
internal static async Task CacheUserInformationAsync( SteamId steamid, bool nameonly )
@@ -239,18 +251,21 @@ namespace Steamworks
public static async Task<Data.Image?> GetSmallAvatarAsync( SteamId steamid )
{
if (Internal is null) { return null; }
await CacheUserInformationAsync( steamid, false );
return SteamUtils.GetImage( Internal.GetSmallFriendAvatar( steamid ) );
}
public static async Task<Data.Image?> GetMediumAvatarAsync( SteamId steamid )
{
if (Internal is null) { return null; }
await CacheUserInformationAsync( steamid, false );
return SteamUtils.GetImage( Internal.GetMediumFriendAvatar( steamid ) );
}
public static async Task<Data.Image?> GetLargeAvatarAsync( SteamId steamid )
{
if (Internal is null) { return null; }
await CacheUserInformationAsync( steamid, false );
var imageid = Internal.GetLargeFriendAvatar( steamid );
@@ -268,8 +283,10 @@ namespace Steamworks
/// <summary>
/// Find a rich presence value by key for current user. Will be null if not found.
/// </summary>
public static string GetRichPresence( string key )
public static string? GetRichPresence( string key )
{
if (richPresence is null) { return null; }
if ( richPresence.TryGetValue( key, out var val ) )
return val;
@@ -281,6 +298,8 @@ namespace Steamworks
/// </summary>
public static bool SetRichPresence( string key, string value )
{
if (richPresence is null || Internal is null) { return false; }
bool success = Internal.SetRichPresence( key, value );
if ( success )
@@ -294,8 +313,8 @@ namespace Steamworks
/// </summary>
public static void ClearRichPresence()
{
richPresence.Clear();
Internal.ClearRichPresence();
richPresence?.Clear();
Internal?.ClearRichPresence();
}
static bool _listenForFriendsMessages;
@@ -312,20 +331,22 @@ namespace Steamworks
set
{
_listenForFriendsMessages = value;
Internal.SetListenForFriendsMessages( value );
Internal?.SetListenForFriendsMessages( value );
}
}
public static async Task<bool> IsFollowing(SteamId steamID)
{
if (Internal is null) { return false; }
var r = await Internal.IsFollowing(steamID);
return r.Value.IsFollowing;
return r?.IsFollowing ?? false;
}
public static async Task<int> GetFollowerCount(SteamId steamID)
{
if (Internal is null) { return 0; }
var r = await Internal.GetFollowerCount(steamID);
return r.Value.Count;
return r?.Count ?? 0;
}
public static async Task<SteamId[]> GetFollowingList()
@@ -337,6 +358,7 @@ namespace Steamworks
do
{
if (Internal is null) { break; }
if ( (result = await Internal.EnumerateFollowingList((uint)resultCount)) != null)
{
resultCount += result.Value.ResultsReturned;

View File

@@ -5,7 +5,7 @@ namespace Steamworks
{
public class SteamInput : SteamClientClass<SteamInput>
{
internal static ISteamInput Internal => Interface as ISteamInput;
internal static ISteamInput? Internal => Interface as ISteamInput;
internal override void InitializeInterface( bool server )
{
@@ -22,7 +22,7 @@ namespace Steamworks
/// </summary>
public static void RunFrame()
{
Internal.RunFrame();
Internal?.RunFrame();
}
static readonly InputHandle_t[] queryArray = new InputHandle_t[STEAM_CONTROLLER_MAX_COUNT];
@@ -34,7 +34,7 @@ namespace Steamworks
{
get
{
var num = Internal.GetConnectedControllers( queryArray );
var num = Internal?.GetConnectedControllers( queryArray ) ?? 0;
for ( int i = 0; i < num; i++ )
{
@@ -52,8 +52,10 @@ namespace Steamworks
/// <param name="controller"></param>
/// <param name="action"></param>
/// <returns></returns>
public static string GetDigitalActionGlyph( Controller controller, string action )
public static string? GetDigitalActionGlyph( Controller controller, string action )
{
if (Internal is null) { return null; }
InputActionOrigin origin = InputActionOrigin.None;
Internal.GetDigitalActionOrigins(
@@ -69,6 +71,8 @@ namespace Steamworks
internal static Dictionary<string, InputDigitalActionHandle_t> DigitalHandles = new Dictionary<string, InputDigitalActionHandle_t>();
internal static InputDigitalActionHandle_t GetDigitalActionHandle( string name )
{
if (Internal is null) { return default; }
if ( DigitalHandles.TryGetValue( name, out var val ) )
return val;
@@ -80,6 +84,8 @@ namespace Steamworks
internal static Dictionary<string, InputAnalogActionHandle_t> AnalogHandles = new Dictionary<string, InputAnalogActionHandle_t>();
internal static InputAnalogActionHandle_t GetAnalogActionHandle( string name )
{
if (Internal is null) { return default; }
if ( AnalogHandles.TryGetValue( name, out var val ) )
return val;
@@ -91,6 +97,8 @@ namespace Steamworks
internal static Dictionary<string, InputActionSetHandle_t> ActionSets = new Dictionary<string, InputActionSetHandle_t>();
internal static InputActionSetHandle_t GetActionSetHandle( string name )
{
if (Internal is null) { return default; }
if ( ActionSets.TryGetValue( name, out var val ) )
return val;

View File

@@ -14,7 +14,7 @@ namespace Steamworks
/// </summary>
public class SteamInventory : SteamSharedClass<SteamInventory>
{
internal static ISteamInventory Internal => Interface as ISteamInventory;
internal static ISteamInventory? Internal => Interface as ISteamInventory;
internal override void InitializeInterface( bool server )
{
@@ -41,8 +41,8 @@ namespace Steamworks
OnInventoryUpdated?.Invoke( r );
}
public static event Action<InventoryResult> OnInventoryUpdated;
public static event Action OnDefinitionsUpdated;
public static event Action<InventoryResult>? OnInventoryUpdated;
public static event Action? OnDefinitionsUpdated;
static void LoadDefinitions()
{
@@ -79,7 +79,7 @@ namespace Steamworks
LoadDefinitions();
}
Internal.LoadItemDefinitions();
Internal?.LoadItemDefinitions();
}
/// <summary>
@@ -113,7 +113,7 @@ namespace Steamworks
/// Try to find the definition that matches this definition ID.
/// Uses a dictionary so should be about as fast as possible.
/// </summary>
public static InventoryDef FindDefinition( InventoryDefId defId )
public static InventoryDef? FindDefinition( InventoryDefId defId )
{
if ( _defMap == null )
return null;
@@ -124,15 +124,17 @@ namespace Steamworks
return null;
}
public static string Currency { get; internal set; }
public static string Currency { get; internal set; } = "";
public static async Task<InventoryDef[]> GetDefinitionsWithPricesAsync()
public static async Task<InventoryDef[]?> GetDefinitionsWithPricesAsync()
{
if (Internal is null) { return null; }
var priceRequest = await Internal.RequestPrices();
if ( !priceRequest.HasValue || priceRequest.Value.Result != Result.OK )
if ( priceRequest?.Result != Result.OK )
return null;
Currency = priceRequest?.CurrencyUTF8();
Currency = priceRequest.Value.CurrencyUTF8();
var num = Internal.GetNumItemsWithPrices();
@@ -153,15 +155,15 @@ namespace Steamworks
/// <summary>
/// We will try to keep this list of your items automatically up to date.
/// </summary>
public static InventoryItem[] Items { get; internal set; }
public static InventoryItem[]? Items { get; internal set; }
public static InventoryDef[] Definitions { get; internal set; }
static Dictionary<int, InventoryDef> _defMap;
public static InventoryDef[]? Definitions { get; internal set; }
static Dictionary<int, InventoryDef>? _defMap;
internal static InventoryDef[] GetDefinitions()
internal static InventoryDef[]? GetDefinitions()
{
uint num = 0;
if ( !Internal.GetItemDefinitionIDs( null, ref num ) )
if ( Internal is null || !Internal.GetItemDefinitionIDs( null, ref num ) )
return null;
var defs = new InventoryDefId[num];
@@ -178,7 +180,7 @@ namespace Steamworks
public static bool GetAllItems()
{
var sresult = Defines.k_SteamInventoryResultInvalid;
return Internal.GetAllItems( ref sresult );
return Internal != null && Internal.GetAllItems( ref sresult );
}
/// <summary>
@@ -188,7 +190,7 @@ namespace Steamworks
{
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !Internal.GetAllItems( ref sresult ) )
if ( Internal is null || !Internal.GetAllItems( ref sresult ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -207,7 +209,7 @@ namespace Steamworks
var defs = new InventoryDefId[] { target.Id };
var cnts = new uint[] { (uint)amount };
if ( !Internal.GenerateItems( ref sresult, defs, cnts, 1 ) )
if ( Internal is null || !Internal.GenerateItems( ref sresult, defs, cnts, 1 ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -228,7 +230,7 @@ namespace Steamworks
var sell = list.Select( x => x.Id ).ToArray();
var sellc = list.Select( x => (uint)1 ).ToArray();
if ( !Internal.ExchangeItems( ref sresult, give, givec, 1, sell, sellc, (uint)sell.Length ) )
if ( Internal is null || !Internal.ExchangeItems( ref sresult, give, givec, 1, sell, sellc, (uint)sell.Length ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -249,7 +251,7 @@ namespace Steamworks
var sell = list.Select( x => x.Item.Id ).ToArray();
var sellc = list.Select( x => (uint) x.Quantity ).ToArray();
if ( !Internal.ExchangeItems( ref sresult, give, givec, 1, sell, sellc, (uint)sell.Length ) )
if ( Internal is null || !Internal.ExchangeItems( ref sresult, give, givec, 1, sell, sellc, (uint)sell.Length ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -285,7 +287,7 @@ namespace Steamworks
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !Internal.DeserializeResult( ref sresult, (IntPtr)ptr, (uint)dataLength, false ) )
if ( Internal is null || !Internal.DeserializeResult( ref sresult, (IntPtr)ptr, (uint)dataLength, false ) )
return null;
@@ -306,7 +308,7 @@ namespace Steamworks
{
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !Internal.GrantPromoItems( ref sresult ) )
if ( Internal is null || !Internal.GrantPromoItems( ref sresult ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -320,7 +322,7 @@ namespace Steamworks
{
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !Internal.TriggerItemDrop( ref sresult, id ) )
if ( Internal is null || !Internal.TriggerItemDrop( ref sresult, id ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -334,7 +336,7 @@ namespace Steamworks
{
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !Internal.AddPromoItem( ref sresult, id ) )
if ( Internal is null || !Internal.AddPromoItem( ref sresult, id ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -347,6 +349,8 @@ namespace Steamworks
/// </summary>
public static async Task<InventoryPurchaseResult?> StartPurchaseAsync( InventoryDef[] items )
{
if (Internal is null) { return null; }
var item_i = items.Select( x => x._id ).ToArray();
var item_q = items.Select( x => (uint)1 ).ToArray();

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamMatchmaking : SteamClientClass<SteamMatchmaking>
{
internal static ISteamMatchmaking Internal => Interface as ISteamMatchmaking;
internal static ISteamMatchmaking? Internal => Interface as ISteamMatchmaking;
internal override void InitializeInterface( bool server )
{
@@ -70,6 +70,8 @@ namespace Steamworks
static private unsafe void OnLobbyChatMessageRecievedAPI( LobbyChatMsg_t callback )
{
if (Internal is null) { return; }
SteamId steamid = default;
ChatEntryType chatEntryType = default;
using var buffer = Helpers.TakeMemory();
@@ -101,62 +103,62 @@ namespace Steamworks
/// <summary>
/// Someone invited you to a lobby
/// </summary>
public static event Action<Friend, Lobby> OnLobbyInvite;
public static event Action<Friend, Lobby>? OnLobbyInvite;
/// <summary>
/// You joined a lobby
/// </summary>
public static event Action<Lobby> OnLobbyEntered;
public static event Action<Lobby>? OnLobbyEntered;
/// <summary>
/// You created a lobby
/// </summary>
public static event Action<Result, Lobby> OnLobbyCreated;
public static event Action<Result, Lobby>? OnLobbyCreated;
/// <summary>
/// A game server has been associated with the lobby
/// </summary>
public static event Action<Lobby, uint, ushort, SteamId> OnLobbyGameCreated;
public static event Action<Lobby, uint, ushort, SteamId>? OnLobbyGameCreated;
/// <summary>
/// The lobby metadata has changed
/// </summary>
public static event Action<Lobby> OnLobbyDataChanged;
public static event Action<Lobby>? OnLobbyDataChanged;
/// <summary>
/// The lobby member metadata has changed
/// </summary>
public static event Action<Lobby, Friend> OnLobbyMemberDataChanged;
public static event Action<Lobby, Friend>? OnLobbyMemberDataChanged;
/// <summary>
/// The lobby member joined
/// </summary>
public static event Action<Lobby, Friend> OnLobbyMemberJoined;
public static event Action<Lobby, Friend>? OnLobbyMemberJoined;
/// <summary>
/// The lobby member left the room
/// </summary>
public static event Action<Lobby, Friend> OnLobbyMemberLeave;
public static event Action<Lobby, Friend>? OnLobbyMemberLeave;
/// <summary>
/// The lobby member left the room
/// </summary>
public static event Action<Lobby, Friend> OnLobbyMemberDisconnected;
public static event Action<Lobby, Friend>? OnLobbyMemberDisconnected;
/// <summary>
/// The lobby member was kicked. The 3rd param is the user that kicked them.
/// </summary>
public static event Action<Lobby, Friend, Friend> OnLobbyMemberKicked;
public static event Action<Lobby, Friend, Friend>? OnLobbyMemberKicked;
/// <summary>
/// The lobby member was banned. The 3rd param is the user that banned them.
/// </summary>
public static event Action<Lobby, Friend, Friend> OnLobbyMemberBanned;
public static event Action<Lobby, Friend, Friend>? OnLobbyMemberBanned;
/// <summary>
/// A chat message was recieved from a member of a lobby
/// </summary>
public static event Action<Lobby, Friend, string> OnChatMessage;
public static event Action<Lobby, Friend, string>? OnChatMessage;
public static LobbyQuery CreateLobbyQuery() { return new LobbyQuery(); }
@@ -165,6 +167,8 @@ namespace Steamworks
/// </summary>
public static async Task<Lobby?> CreateLobbyAsync( int maxMembers = 100 )
{
if (Internal is null) { return null; }
var lobby = await Internal.CreateLobby( LobbyType.Invisible, maxMembers );
if ( !lobby.HasValue ) { return null; }
@@ -176,6 +180,8 @@ namespace Steamworks
/// </summary>
public static async Task<Lobby?> JoinLobbyAsync( SteamId lobbyId )
{
if (Internal is null) { return null; }
var lobby = await Internal.JoinLobby( lobbyId );
if ( !lobby.HasValue ) return null;
@@ -187,6 +193,8 @@ namespace Steamworks
/// </summary>
public static IEnumerable<ServerInfo> GetFavoriteServers()
{
if (Internal is null) { yield break; }
var count = Internal.GetFavoriteGameCount();
for( int i=0; i<count; i++ )
@@ -211,6 +219,8 @@ namespace Steamworks
/// </summary>
public static IEnumerable<ServerInfo> GetHistoryServers()
{
if (Internal is null) { yield break; }
var count = Internal.GetFavoriteGameCount();
for ( int i = 0; i < count; i++ )

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
internal class SteamMatchmakingServers : SteamClientClass<SteamMatchmakingServers>
{
internal static ISteamMatchmakingServers Internal => Interface as ISteamMatchmakingServers;
internal static ISteamMatchmakingServers? Internal => Interface as ISteamMatchmakingServers;
internal override void InitializeInterface( bool server )
{

View File

@@ -15,7 +15,7 @@ namespace Steamworks
/// </summary>
public class SteamMusic : SteamClientClass<SteamMusic>
{
internal static ISteamMusic Internal => Interface as ISteamMusic;
internal static ISteamMusic? Internal => Interface as ISteamMusic;
internal override void InitializeInterface( bool server )
{
@@ -33,50 +33,50 @@ namespace Steamworks
/// <summary>
/// Playback status changed
/// </summary>
public static event Action OnPlaybackChanged;
public static event Action? OnPlaybackChanged;
/// <summary>
/// Volume changed, parameter is new volume
/// </summary>
public static event Action<float> OnVolumeChanged;
public static event Action<float>? OnVolumeChanged;
/// <summary>
/// Checks if Steam Music is enabled
/// </summary>
public static bool IsEnabled => Internal.BIsEnabled();
public static bool IsEnabled => Internal != null && Internal.BIsEnabled();
/// <summary>
/// true if a song is currently playing, paused, or queued up to play; otherwise false.
/// </summary>
public static bool IsPlaying => Internal.BIsPlaying();
public static bool IsPlaying => Internal != null && Internal.BIsPlaying();
/// <summary>
/// Gets the current status of the Steam Music player
/// </summary>
public static MusicStatus Status => Internal.GetPlaybackStatus();
public static MusicStatus Status => Internal?.GetPlaybackStatus() ?? MusicStatus.Undefined;
public static void Play() => Internal.Play();
public static void Play() => Internal?.Play();
public static void Pause() => Internal.Pause();
public static void Pause() => Internal?.Pause();
/// <summary>
/// Have the Steam Music player play the previous song.
/// </summary>
public static void PlayPrevious() => Internal.PlayPrevious();
public static void PlayPrevious() => Internal?.PlayPrevious();
/// <summary>
/// Have the Steam Music player skip to the next song
/// </summary>
public static void PlayNext() => Internal.PlayNext();
public static void PlayNext() => Internal?.PlayNext();
/// <summary>
/// Gets/Sets the current volume of the Steam Music player
/// </summary>
public static float Volume
{
get => Internal.GetVolume();
set => Internal.SetVolume( value );
get => Internal?.GetVolume() ?? 0f;
set => Internal?.SetVolume( value );
}
}
}

View File

@@ -10,7 +10,7 @@ namespace Steamworks
{
public class SteamNetworking : SteamSharedClass<SteamNetworking>
{
internal static ISteamNetworking Internal => Interface as ISteamNetworking;
internal static ISteamNetworking? Internal => Interface as ISteamNetworking;
internal override void InitializeInterface( bool server )
{
@@ -35,26 +35,26 @@ namespace Steamworks
/// This SteamId wants to send you a message. You should respond by calling AcceptP2PSessionWithUser
/// if you want to recieve their messages
/// </summary>
public static Action<SteamId> OnP2PSessionRequest;
public static Action<SteamId>? OnP2PSessionRequest;
/// <summary>
/// Called when packets can't get through to the specified user.
/// All queued packets unsent at this point will be dropped, further attempts
/// to send will retry making the connection (but will be dropped if we fail again).
/// </summary>
public static Action<SteamId, P2PSessionError> OnP2PConnectionFailed;
public static Action<SteamId, P2PSessionError>? OnP2PConnectionFailed;
/// <summary>
/// This should be called in response to a OnP2PSessionRequest
/// </summary>
public static bool AcceptP2PSessionWithUser( SteamId user ) => Internal.AcceptP2PSessionWithUser( user );
public static bool AcceptP2PSessionWithUser( SteamId user ) => Internal != null && Internal.AcceptP2PSessionWithUser( user );
/// <summary>
/// Allow or disallow P2P connects to fall back on Steam server relay if direct
/// connection or NAT traversal can't be established. Applies to connections
/// created after setting or old connections that need to reconnect.
/// </summary>
public static bool AllowP2PPacketRelay( bool allow ) => Internal.AllowP2PPacketRelay( allow );
public static bool AllowP2PPacketRelay( bool allow ) => Internal != null && Internal.AllowP2PPacketRelay( allow );
/// <summary>
/// This should be called when you're done communicating with a user, as this will
@@ -62,7 +62,7 @@ namespace Steamworks
/// If the remote user tries to send data to you again, a new OnP2PSessionRequest
/// callback will be posted
/// </summary>
public static bool CloseP2PSessionWithUser( SteamId user ) => Internal.CloseP2PSessionWithUser( user );
public static bool CloseP2PSessionWithUser( SteamId user ) => Internal != null && Internal.CloseP2PSessionWithUser( user );
/// <summary>
/// Checks if a P2P packet is available to read, and gets the size of the message if there is one.
@@ -70,7 +70,7 @@ namespace Steamworks
public static bool IsP2PPacketAvailable( int channel = 0 )
{
uint _ = 0;
return Internal.IsP2PPacketAvailable( ref _, channel );
return Internal != null && Internal.IsP2PPacketAvailable( ref _, channel );
}
/// <summary>
@@ -80,7 +80,7 @@ namespace Steamworks
{
uint size = 0;
if ( !Internal.IsP2PPacketAvailable( ref size, channel ) )
if ( Internal is null || !Internal.IsP2PPacketAvailable( ref size, channel ) )
return null;
var buffer = Helpers.TakeBuffer( (int) size );
@@ -108,7 +108,7 @@ namespace Steamworks
public unsafe static bool ReadP2PPacket( byte[] buffer, ref uint size, ref SteamId steamid, int channel = 0 )
{
fixed (byte* p = buffer) {
return Internal.ReadP2PPacket( (IntPtr)p, (uint)buffer.Length, ref size, ref steamid, channel );
return Internal != null && Internal.ReadP2PPacket( (IntPtr)p, (uint)buffer.Length, ref size, ref steamid, channel );
}
}
@@ -117,7 +117,7 @@ namespace Steamworks
/// </summary>
public unsafe static bool ReadP2PPacket( byte* buffer, uint cbuf, ref uint size, ref SteamId steamid, int channel = 0 )
{
return Internal.ReadP2PPacket( (IntPtr)buffer, cbuf, ref size, ref steamid, channel );
return Internal != null && Internal.ReadP2PPacket( (IntPtr)buffer, cbuf, ref size, ref steamid, channel );
}
/// <summary>
@@ -132,7 +132,7 @@ namespace Steamworks
fixed ( byte* p = data )
{
return Internal.SendP2PPacket( steamid, (IntPtr)p, (uint)length, (P2PSend)sendType, nChannel );
return Internal != null && Internal.SendP2PPacket( steamid, (IntPtr)p, (uint)length, (P2PSend)sendType, nChannel );
}
}
@@ -143,13 +143,13 @@ namespace Steamworks
/// </summary>
public static unsafe bool SendP2PPacket( SteamId steamid, byte* data, uint length, int nChannel = 1, P2PSend sendType = P2PSend.Reliable )
{
return Internal.SendP2PPacket( steamid, (IntPtr)data, (uint)length, (P2PSend)sendType, nChannel );
return Internal != null && Internal.SendP2PPacket( steamid, (IntPtr)data, (uint)length, (P2PSend)sendType, nChannel );
}
public static P2PSessionState? GetP2PSessionState( SteamId steamid )
{
P2PSessionState_t state = new P2PSessionState_t();
if (Internal.GetP2PSessionState(steamid, ref state))
if (Internal != null && Internal.GetP2PSessionState(steamid, ref state))
{
return new P2PSessionState(state);
}

View File

@@ -10,7 +10,7 @@ namespace Steamworks
{
public class SteamNetworkingSockets : SteamSharedClass<SteamNetworkingSockets>
{
internal static ISteamNetworkingSockets Internal => Interface as ISteamNetworkingSockets;
internal static ISteamNetworkingSockets? Internal => Interface as ISteamNetworkingSockets;
internal override void InitializeInterface( bool server )
{
@@ -22,7 +22,7 @@ namespace Steamworks
static readonly Dictionary<uint, SocketManager> SocketInterfaces = new Dictionary<uint, SocketManager>();
internal static SocketManager GetSocketManager( uint id )
internal static SocketManager? GetSocketManager( uint id )
{
if ( SocketInterfaces == null ) return null;
if ( id == 0 ) throw new System.ArgumentException( "Invalid Socket" );
@@ -43,7 +43,7 @@ namespace Steamworks
#region ConnectionInterface
static readonly Dictionary<uint, ConnectionManager> ConnectionInterfaces = new Dictionary<uint, ConnectionManager>();
internal static ConnectionManager GetConnectionManager( uint id )
internal static ConnectionManager? GetConnectionManager( uint id )
{
if ( ConnectionInterfaces == null ) return null;
if ( id == 0 ) return null;
@@ -88,7 +88,7 @@ namespace Steamworks
OnConnectionStatusChanged?.Invoke( data.Conn, data.Nfo );
}
public static event Action<Connection, ConnectionInfo> OnConnectionStatusChanged;
public static event Action<Connection, ConnectionInfo>? OnConnectionStatusChanged;
/// <summary>
@@ -98,8 +98,10 @@ namespace Steamworks
/// To use this derive a class from SocketManager and override as much as you want.
///
/// </summary>
public static T CreateNormalSocket<T>( NetAddress address ) where T : SocketManager, new()
public static T? CreateNormalSocket<T>( NetAddress address ) where T : SocketManager, new()
{
if (Internal is null) { return null; }
var t = new T();
var options = Array.Empty<NetKeyValue>();
t.Socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
@@ -118,8 +120,10 @@ namespace Steamworks
/// will received all the appropriate callbacks.
///
/// </summary>
public static SocketManager CreateNormalSocket( NetAddress address, ISocketManager intrface )
public static SocketManager? CreateNormalSocket( NetAddress address, ISocketManager intrface )
{
if (Internal is null) { return null; }
var options = Array.Empty<NetKeyValue>();
var socket = Internal.CreateListenSocketIP( ref address, options.Length, options );
@@ -138,8 +142,10 @@ namespace Steamworks
/// <summary>
/// Connect to a socket created via <method>CreateListenSocketIP</method>
/// </summary>
public static T ConnectNormal<T>( NetAddress address ) where T : ConnectionManager, new()
public static T? ConnectNormal<T>( NetAddress address ) where T : ConnectionManager, new()
{
if (Internal is null) { return null; }
var t = new T();
var options = Array.Empty<NetKeyValue>();
t.Connection = Internal.ConnectByIPAddress( ref address, options.Length, options );
@@ -150,8 +156,10 @@ namespace Steamworks
/// <summary>
/// Connect to a socket created via <method>CreateListenSocketIP</method>
/// </summary>
public static ConnectionManager ConnectNormal( NetAddress address, IConnectionManager iface )
public static ConnectionManager? ConnectNormal( NetAddress address, IConnectionManager iface )
{
if (Internal is null) { return null; }
var options = Array.Empty<NetKeyValue>();
var connection = Internal.ConnectByIPAddress( ref address, options.Length, options );
@@ -171,8 +179,10 @@ namespace Steamworks
/// To use this derive a class from SocketManager and override as much as you want.
///
/// </summary>
public static T CreateRelaySocket<T>( int virtualport = 0 ) where T : SocketManager, new()
public static T? CreateRelaySocket<T>( int virtualport = 0 ) where T : SocketManager, new()
{
if (Internal is null) { return null; }
var t = new T();
var options = Array.Empty<NetKeyValue>();
t.Socket = Internal.CreateListenSocketP2P( virtualport, options.Length, options );
@@ -189,8 +199,10 @@ namespace Steamworks
/// will received all the appropriate callbacks.
///
/// </summary>
public static SocketManager CreateRelaySocket( int virtualport, ISocketManager intrface )
public static SocketManager? CreateRelaySocket( int virtualport, ISocketManager intrface )
{
if (Internal is null) { return null; }
var options = Array.Empty<NetKeyValue>();
var socket = Internal.CreateListenSocketP2P( virtualport, options.Length, options );
@@ -209,8 +221,10 @@ namespace Steamworks
/// <summary>
/// Connect to a relay server
/// </summary>
public static T ConnectRelay<T>( SteamId serverId, int virtualport = 0 ) where T : ConnectionManager, new()
public static T? ConnectRelay<T>( SteamId serverId, int virtualport = 0 ) where T : ConnectionManager, new()
{
if (Internal is null) { return null; }
var t = new T();
NetIdentity identity = serverId;
var options = Array.Empty<NetKeyValue>();

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamNetworkingUtils : SteamSharedClass<SteamNetworkingUtils>
{
internal static ISteamNetworkingUtils Internal => Interface as ISteamNetworkingUtils;
internal static ISteamNetworkingUtils? Internal => Interface as ISteamNetworkingUtils;
internal override void InitializeInterface( bool server )
{
@@ -43,7 +43,7 @@ namespace Steamworks
/// and your frame rate will tank and you won't know why.
/// </summary>
public static event Action<NetDebugOutput, string> OnDebugOutput;
public static event Action<NetDebugOutput, string>? OnDebugOutput;
public struct SteamRelayNetworkStatus
{
@@ -82,7 +82,7 @@ namespace Steamworks
/// </summary>
public static void InitRelayNetworkAccess()
{
Internal.InitRelayNetworkAccess();
Internal?.InitRelayNetworkAccess();
}
/// <summary>
@@ -98,6 +98,8 @@ namespace Steamworks
{
get
{
if (Internal is null) { return null; }
NetPingLocation location = default;
var age = Internal.GetLocalPingLocation( ref location );
if ( age < 0 )
@@ -114,7 +116,7 @@ namespace Steamworks
/// </summary>
public static int EstimatePingTo( NetPingLocation target )
{
return Internal.EstimatePingTimeFromLocalHost( ref target );
return Internal?.EstimatePingTimeFromLocalHost( ref target ) ?? 0;
}
/// <summary>
@@ -124,7 +126,7 @@ namespace Steamworks
public static async Task WaitForPingDataAsync( float maxAgeInSeconds = 60 * 5 )
{
await Task.Yield();
if ( Internal.CheckPingDataUpToDate( maxAgeInSeconds ) )
if ( Internal is null || Internal.CheckPingDataUpToDate( maxAgeInSeconds ) )
return;
SteamRelayNetworkStatus_t status = default;
@@ -135,7 +137,7 @@ namespace Steamworks
}
}
public static long LocalTimestamp => Internal.GetLocalTimestamp();
public static long LocalTimestamp => Internal?.GetLocalTimestamp() ?? 0;
/// <summary>
@@ -223,7 +225,7 @@ namespace Steamworks
_debugLevel = value;
_debugFunc = new NetDebugFunc( OnDebugMessage );
Internal.SetDebugOutputFunction( value, _debugFunc );
Internal?.SetDebugOutputFunction( value, _debugFunc );
}
}
@@ -235,7 +237,7 @@ namespace Steamworks
/// <summary>
/// We need to keep the delegate around until it's not used anymore
/// </summary>
static NetDebugFunc _debugFunc;
static NetDebugFunc? _debugFunc;
struct DebugMessage
{
@@ -274,7 +276,7 @@ namespace Steamworks
internal unsafe static bool SetConfigInt( NetConfig type, int value )
{
int* ptr = &value;
return Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.Int32, (IntPtr)ptr );
return Internal != null && Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.Int32, (IntPtr)ptr );
}
internal unsafe static int GetConfigInt( NetConfig type )
@@ -283,7 +285,7 @@ namespace Steamworks
NetConfigType dtype = NetConfigType.Int32;
int* ptr = &value;
UIntPtr size = new UIntPtr( sizeof( int ) );
var result = Internal.GetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, 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 )
return 0;
@@ -293,7 +295,7 @@ namespace Steamworks
internal unsafe static bool SetConfigFloat( NetConfig type, float value )
{
float* ptr = &value;
return Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.Float, (IntPtr)ptr );
return Internal != null && Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.Float, (IntPtr)ptr );
}
internal unsafe static float GetConfigFloat( NetConfig type )
@@ -302,7 +304,7 @@ namespace Steamworks
NetConfigType dtype = NetConfigType.Float;
float* ptr = &value;
UIntPtr size = new UIntPtr( sizeof( float ) );
var result = Internal.GetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, 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 )
return 0;
@@ -315,7 +317,7 @@ namespace Steamworks
fixed ( byte* ptr = bytes )
{
return Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.String, (IntPtr)ptr );
return Internal != null && Internal.SetConfigValue( type, NetConfigScope.Global, IntPtr.Zero, NetConfigType.String, (IntPtr)ptr );
}
}

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamParental : SteamSharedClass<SteamParental>
{
internal static ISteamParentalSettings Internal => Interface as ISteamParentalSettings;
internal static ISteamParentalSettings? Internal => Interface as ISteamParentalSettings;
internal override void InitializeInterface( bool server )
{
@@ -28,37 +28,37 @@ namespace Steamworks
/// <summary>
/// Parental Settings Changed
/// </summary>
public static event Action OnSettingsChanged;
public static event Action? OnSettingsChanged;
/// <summary>
///
/// </summary>
public static bool IsParentalLockEnabled => Internal.BIsParentalLockEnabled();
public static bool IsParentalLockEnabled => Internal != null && Internal.BIsParentalLockEnabled();
/// <summary>
///
/// </summary>
public static bool IsParentalLockLocked => Internal.BIsParentalLockLocked();
public static bool IsParentalLockLocked => Internal != null && Internal.BIsParentalLockLocked();
/// <summary>
///
/// </summary>
public static bool IsAppBlocked( AppId app ) => Internal.BIsAppBlocked( app.Value );
public static bool IsAppBlocked( AppId app ) => Internal != null && Internal.BIsAppBlocked( app.Value );
/// <summary>
///
/// </summary>
public static bool BIsAppInBlockList( AppId app ) => Internal.BIsAppInBlockList( app.Value );
public static bool BIsAppInBlockList( AppId app ) => Internal != null && Internal.BIsAppInBlockList( app.Value );
/// <summary>
///
/// </summary>
public static bool IsFeatureBlocked( ParentalFeature feature ) => Internal.BIsFeatureBlocked( feature );
public static bool IsFeatureBlocked( ParentalFeature feature ) => Internal != null && Internal.BIsFeatureBlocked( feature );
/// <summary>
///
/// </summary>
public static bool BIsFeatureInBlockList( ParentalFeature feature ) => Internal.BIsFeatureInBlockList( feature );
public static bool BIsFeatureInBlockList( ParentalFeature feature ) => Internal != null && Internal.BIsFeatureInBlockList( feature );
}
}

View File

@@ -15,7 +15,7 @@ namespace Steamworks
/// </summary>
public class SteamParties : SteamClientClass<SteamParties>
{
internal static ISteamParties Internal => Interface as ISteamParties;
internal static ISteamParties? Internal => Interface as ISteamParties;
internal override void InitializeInterface( bool server )
{
@@ -32,15 +32,15 @@ namespace Steamworks
/// <summary>
/// The list of possible Party beacon locations has changed
/// </summary>
public static event Action OnBeaconLocationsUpdated;
public static event Action? OnBeaconLocationsUpdated;
/// <summary>
/// The list of active beacons may have changed
/// </summary>
public static event Action OnActiveBeaconsUpdated;
public static event Action? OnActiveBeaconsUpdated;
public static int ActiveBeaconCount => (int) Internal.GetNumActiveBeacons();
public static int ActiveBeaconCount => (int)(Internal?.GetNumActiveBeacons() ?? 0);
public static IEnumerable<PartyBeacon> ActiveBeacons
{
@@ -50,7 +50,7 @@ namespace Steamworks
{
yield return new PartyBeacon
{
Id = Internal.GetBeaconByIndex( i )
Id = Internal?.GetBeaconByIndex( i ) ?? 0
};
}
}

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamRemotePlay : SteamClientClass<SteamRemotePlay>
{
internal static ISteamRemotePlay Internal => Interface as ISteamRemotePlay;
internal static ISteamRemotePlay? Internal => Interface as ISteamRemotePlay;
internal override void InitializeInterface( bool server )
{
@@ -30,29 +30,29 @@ namespace Steamworks
/// <summary>
/// Called when a session is connected
/// </summary>
public static event Action<RemotePlaySession> OnSessionConnected;
public static event Action<RemotePlaySession>? OnSessionConnected;
/// <summary>
/// Called when a session becomes disconnected
/// </summary>
public static event Action<RemotePlaySession> OnSessionDisconnected;
public static event Action<RemotePlaySession>? OnSessionDisconnected;
/// <summary>
/// Get the number of currently connected Steam Remote Play sessions
/// </summary>
public static int SessionCount => (int) Internal.GetSessionCount();
public static int SessionCount => (int)(Internal?.GetSessionCount() ?? 0);
/// <summary>
/// Get the currently connected Steam Remote Play session ID at the specified index.
/// IsValid will return false if it's out of bounds
/// </summary>
public static RemotePlaySession GetSession( int index ) => (RemotePlaySession) Internal.GetSessionID( index ).Value;
public static RemotePlaySession GetSession( int index ) => Internal?.GetSessionID( index ).Value ?? default;
/// <summary>
/// Invite a friend to Remote Play Together
/// This returns false if the invite can't be sent
/// </summary>
public static bool SendInvite( SteamId steamid ) => Internal.BSendRemotePlayTogetherInvite( steamid );
public static bool SendInvite( SteamId steamid ) => Internal != null && Internal.BSendRemotePlayTogetherInvite( steamid );
}
}

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamRemoteStorage : SteamClientClass<SteamRemoteStorage>
{
internal static ISteamRemoteStorage Internal => Interface as ISteamRemoteStorage;
internal static ISteamRemoteStorage? Internal => Interface as ISteamRemoteStorage;
internal override void InitializeInterface( bool server )
{
@@ -28,15 +28,17 @@ namespace Steamworks
{
fixed ( byte* ptr = data )
{
return Internal.FileWrite( filename, (IntPtr) ptr, data.Length );
return Internal != null && Internal.FileWrite( filename, (IntPtr) ptr, data.Length );
}
}
/// <summary>
/// Opens a binary file, reads the contents of the file into a byte array, and then closes the file.
/// </summary>
public unsafe static byte[] FileRead( string filename )
public unsafe static byte[]? FileRead( string filename )
{
if (Internal is null) { return null; }
var size = FileSize( filename );
if ( size <= 0 ) return null;
var buffer = new byte[size];
@@ -51,32 +53,32 @@ namespace Steamworks
/// <summary>
/// Checks whether the specified file exists.
/// </summary>
public static bool FileExists( string filename ) => Internal.FileExists( filename );
public static bool FileExists( string filename ) => Internal != null && Internal.FileExists( filename );
/// <summary>
/// Checks if a specific file is persisted in the steam cloud.
/// </summary>
public static bool FilePersisted( string filename ) => Internal.FilePersisted( filename );
public static bool FilePersisted( string filename ) => Internal != null && Internal.FilePersisted( filename );
/// <summary>
/// Gets the specified file's last modified date/time.
/// </summary>
public static DateTime FileTime( string filename ) => Epoch.ToDateTime( Internal.GetFileTimestamp( filename ) );
public static DateTime FileTime( string filename ) => Internal != null ? Epoch.ToDateTime( Internal.GetFileTimestamp( filename ) ) : default;
/// <summary>
/// Gets the specified files size in bytes. 0 if not exists.
/// </summary>
public static int FileSize( string filename ) => Internal.GetFileSize( filename );
public static int FileSize( string filename ) => Internal?.GetFileSize( filename ) ?? 0;
/// <summary>
/// Deletes the file from remote storage, but leaves it on the local disk and remains accessible from the API.
/// </summary>
public static bool FileForget( string filename ) => Internal.FileForget( filename );
public static bool FileForget( string filename ) => Internal != null && Internal.FileForget( filename );
/// <summary>
/// Deletes a file from the local disk, and propagates that delete to the cloud.
/// </summary>
public static bool FileDelete( string filename ) => Internal.FileDelete( filename );
public static bool FileDelete( string filename ) => Internal != null && Internal.FileDelete( filename );
/// <summary>
@@ -87,7 +89,7 @@ namespace Steamworks
get
{
ulong t = 0, a = 0;
Internal.GetQuota( ref t, ref a );
Internal?.GetQuota( ref t, ref a );
return t;
}
}
@@ -100,7 +102,7 @@ namespace Steamworks
get
{
ulong t = 0, a = 0;
Internal.GetQuota( ref t, ref a );
Internal?.GetQuota( ref t, ref a );
return t - a;
}
}
@@ -113,7 +115,7 @@ namespace Steamworks
get
{
ulong t = 0, a = 0;
Internal.GetQuota( ref t, ref a );
Internal?.GetQuota( ref t, ref a );
return a;
}
}
@@ -127,7 +129,7 @@ namespace Steamworks
/// Checks if the account wide Steam Cloud setting is enabled for this user
/// or if they disabled it in the Settings->Cloud dialog.
/// </summary>
public static bool IsCloudEnabledForAccount => Internal.IsCloudEnabledForAccount();
public static bool IsCloudEnabledForAccount => Internal != null && Internal.IsCloudEnabledForAccount();
/// <summary>
/// Checks if the per game Steam Cloud setting is enabled for this user
@@ -139,14 +141,14 @@ namespace Steamworks
/// </summary>
public static bool IsCloudEnabledForApp
{
get => Internal.IsCloudEnabledForApp();
set => Internal.SetCloudEnabledForApp( value );
get => Internal != null && Internal.IsCloudEnabledForApp();
set => Internal?.SetCloudEnabledForApp( value );
}
/// <summary>
/// Gets the total number of local files synchronized by Steam Cloud.
/// </summary>
public static int FileCount => Internal.GetFileCount();
public static int FileCount => Internal?.GetFileCount() ?? 0;
public struct RemoteFile
{
@@ -155,7 +157,7 @@ namespace Steamworks
public bool Delete()
{
return Internal.FileDelete(Filename);
return Internal != null && Internal.FileDelete(Filename);
}
}
@@ -167,6 +169,8 @@ namespace Steamworks
get
{
var ret = new List<RemoteFile>();
if (Internal is null) { return ret; }
int count = FileCount;
for( int i=0; i<count; i++ )
{

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamScreenshots : SteamClientClass<SteamScreenshots>
{
internal static ISteamScreenshots Internal => Interface as ISteamScreenshots;
internal static ISteamScreenshots? Internal => Interface as ISteamScreenshots;
internal override void InitializeInterface( bool server )
{
@@ -37,17 +37,17 @@ namespace Steamworks
/// This will only be called if Hooked is true, in which case Steam
/// will not take the screenshot itself.
/// </summary>
public static event Action OnScreenshotRequested;
public static event Action? OnScreenshotRequested;
/// <summary>
/// A screenshot successfully written or otherwise added to the library and can now be tagged.
/// </summary>
public static event Action<Screenshot> OnScreenshotReady;
public static event Action<Screenshot>? OnScreenshotReady;
/// <summary>
/// A screenshot attempt failed
/// </summary>
public static event Action<Result> OnScreenshotFailed;
public static event Action<Result>? OnScreenshotFailed;
/// <summary>
/// Writes a screenshot to the user's screenshot library given the raw image data, which must be in RGB format.
@@ -55,6 +55,8 @@ namespace Steamworks
/// </summary>
public unsafe static Screenshot? WriteScreenshot( byte[] data, int width, int height )
{
if (Internal is null) { return null; }
fixed ( byte* ptr = data )
{
var handle = Internal.WriteScreenshot( (IntPtr)ptr, (uint)data.Length, width, height );
@@ -72,6 +74,8 @@ namespace Steamworks
/// </summary>
public unsafe static Screenshot? AddScreenshot( string filename, string thumbnail, int width, int height )
{
if (Internal is null) { return null; }
var handle = Internal.AddScreenshotToLibrary( filename, thumbnail, width, height );
if ( handle.Value == 0 ) return null;
@@ -83,7 +87,7 @@ namespace Steamworks
/// If screenshots are being hooked by the game then a
/// ScreenshotRequested callback is sent back to the game instead.
/// </summary>
public static void TriggerScreenshot() => Internal.TriggerScreenshot();
public static void TriggerScreenshot() => Internal?.TriggerScreenshot();
/// <summary>
/// Toggles whether the overlay handles screenshots when the user presses the screenshot hotkey, or if the game handles them.
@@ -93,8 +97,8 @@ namespace Steamworks
/// </summary>
public static bool Hooked
{
get => Internal.IsScreenshotsHooked();
set => Internal.HookScreenshots( value );
get => Internal != null && Internal.IsScreenshotsHooked();
set => Internal?.HookScreenshots( value );
}
}
}

View File

@@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Steamworks.Data;
using System.Diagnostics.CodeAnalysis;
namespace Steamworks
{
@@ -12,7 +13,7 @@ namespace Steamworks
/// </summary>
public partial class SteamServer : SteamServerClass<SteamServer>
{
internal static ISteamGameServer Internal => Interface as ISteamGameServer;
internal static ISteamGameServer? Internal => Interface as ISteamGameServer;
internal override void InitializeInterface( bool server )
{
@@ -34,28 +35,28 @@ namespace Steamworks
/// <summary>
/// User has been authed or rejected
/// </summary>
public static event Action<SteamId, SteamId, AuthResponse> OnValidateAuthTicketResponse;
public static event Action<SteamId, SteamId, AuthResponse>? OnValidateAuthTicketResponse;
/// <summary>
/// Called when a connections to the Steam back-end has been established.
/// This means the server now is logged on and has a working connection to the Steam master server.
/// </summary>
public static event Action OnSteamServersConnected;
public static event Action? OnSteamServersConnected;
/// <summary>
/// This will occur periodically if the Steam client is not connected, and has failed when retrying to establish a connection (result, stilltrying)
/// </summary>
public static event Action<Result, bool> OnSteamServerConnectFailure;
public static event Action<Result, bool>? OnSteamServerConnectFailure;
/// <summary>
/// Disconnected from Steam
/// </summary>
public static event Action<Result> OnSteamServersDisconnected;
public static event Action<Result>? OnSteamServersDisconnected;
/// <summary>
/// Called when authentication status changes, useful for grabbing SteamId once aavailability is current
/// </summary>
public static event Action<SteamNetworkingAvailability> OnSteamNetAuthenticationStatus;
public static event Action<SteamNetworkingAvailability>? OnSteamNetAuthenticationStatus;
/// <summary>
@@ -172,7 +173,7 @@ namespace Steamworks
public static bool DedicatedServer
{
get => _dedicatedServer;
set { if ( _dedicatedServer == value ) return; Internal.SetDedicatedServer( value ); _dedicatedServer = value; }
set { if ( _dedicatedServer == value ) return; Internal?.SetDedicatedServer( value ); _dedicatedServer = value; }
}
private static bool _dedicatedServer;
@@ -183,7 +184,7 @@ namespace Steamworks
public static int MaxPlayers
{
get => _maxplayers;
set { if ( _maxplayers == value ) return; Internal.SetMaxPlayerCount( value ); _maxplayers = value; }
set { if ( _maxplayers == value ) return; Internal?.SetMaxPlayerCount( value ); _maxplayers = value; }
}
private static int _maxplayers = 0;
@@ -194,7 +195,7 @@ namespace Steamworks
public static int BotCount
{
get => _botcount;
set { if ( _botcount == value ) return; Internal.SetBotPlayerCount( value ); _botcount = value; }
set { if ( _botcount == value ) return; Internal?.SetBotPlayerCount( value ); _botcount = value; }
}
private static int _botcount = 0;
@@ -204,9 +205,9 @@ namespace Steamworks
public static string MapName
{
get => _mapname;
set { if ( _mapname == value ) return; Internal.SetMapName( value ); _mapname = value; }
set { if ( _mapname == value ) return; Internal?.SetMapName( value ); _mapname = value; }
}
private static string _mapname;
private static string _mapname = "";
/// <summary>
/// Gets or sets the current ModDir
@@ -214,7 +215,7 @@ namespace Steamworks
public static string ModDir
{
get => _modDir;
internal set { if ( _modDir == value ) return; Internal.SetModDir( value ); _modDir = value; }
internal set { if ( _modDir == value ) return; Internal?.SetModDir( value ); _modDir = value; }
}
private static string _modDir = "";
@@ -224,7 +225,7 @@ namespace Steamworks
public static string Product
{
get => _product;
internal set { if ( _product == value ) return; Internal.SetProduct( value ); _product = value; }
internal set { if ( _product == value ) return; Internal?.SetProduct( value ); _product = value; }
}
private static string _product = "";
@@ -234,7 +235,7 @@ namespace Steamworks
public static string GameDescription
{
get => _gameDescription;
internal set { if ( _gameDescription == value ) return; Internal.SetGameDescription( value ); _gameDescription = value; }
internal set { if ( _gameDescription == value ) return; Internal?.SetGameDescription( value ); _gameDescription = value; }
}
private static string _gameDescription = "";
@@ -244,7 +245,7 @@ namespace Steamworks
public static string ServerName
{
get => _serverName;
set { if ( _serverName == value ) return; Internal.SetServerName( value ); _serverName = value; }
set { if ( _serverName == value ) return; Internal?.SetServerName( value ); _serverName = value; }
}
private static string _serverName = "";
@@ -254,7 +255,7 @@ namespace Steamworks
public static bool Passworded
{
get => _passworded;
set { if ( _passworded == value ) return; Internal.SetPasswordProtected( value ); _passworded = value; }
set { if ( _passworded == value ) return; Internal?.SetPasswordProtected( value ); _passworded = value; }
}
private static bool _passworded;
@@ -268,20 +269,20 @@ namespace Steamworks
set
{
if ( _gametags == value ) return;
Internal.SetGameTags( value );
Internal?.SetGameTags( value );
_gametags = value;
}
}
private static string _gametags = "";
public static SteamId SteamId => Internal.GetSteamID();
public static SteamId SteamId => Internal?.GetSteamID() ?? default;
/// <summary>
/// Log onto Steam anonymously.
/// </summary>
public static void LogOnAnonymous()
{
Internal.LogOnAnonymous();
Internal?.LogOnAnonymous();
ForceHeartbeat();
}
@@ -290,21 +291,21 @@ namespace Steamworks
/// </summary>
public static void LogOff()
{
Internal.LogOff();
Internal?.LogOff();
}
/// <summary>
/// Returns true if the server is connected and registered with the Steam master server
/// You should have called LogOnAnonymous etc on startup.
/// </summary>
public static bool LoggedOn => Internal.BLoggedOn();
public static bool LoggedOn => Internal != null && Internal.BLoggedOn();
/// <summary>
/// To the best of its ability this tries to get the server's
/// current public ip address. Be aware that this is likely to return
/// null for the first few seconds after initialization.
/// </summary>
public static System.Net.IPAddress PublicIp => Internal.GetPublicIP();
public static System.Net.IPAddress? PublicIp => Internal?.GetPublicIP();
/// <summary>
/// Enable or disable heartbeats, which are sent regularly to the master server.
@@ -312,7 +313,7 @@ namespace Steamworks
/// </summary>
public static bool AutomaticHeartbeats
{
set { Internal.EnableHeartbeats( value ); }
set { Internal?.EnableHeartbeats( value ); }
}
/// <summary>
@@ -321,7 +322,7 @@ namespace Steamworks
/// </summary>
public static int AutomaticHeartbeatRate
{
set { Internal.SetHeartbeatInterval( value ); }
set { Internal?.SetHeartbeatInterval( value ); }
}
/// <summary>
@@ -330,7 +331,7 @@ namespace Steamworks
/// </summary>
public static void ForceHeartbeat()
{
Internal.ForceHeartbeat();
Internal?.ForceHeartbeat();
}
/// <summary>
@@ -340,7 +341,7 @@ namespace Steamworks
/// </summary>
public static void UpdatePlayer( SteamId steamid, string name, int score )
{
Internal.BUpdateUserData( steamid, name, (uint)score );
Internal?.BUpdateUserData( steamid, name, (uint)score );
}
static Dictionary<string, string> KeyValue = new Dictionary<string, string>();
@@ -353,6 +354,8 @@ namespace Steamworks
/// </summary>
public static void SetKey( string Key, string Value )
{
if (Internal is null) { return; }
if ( KeyValue.ContainsKey( Key ) )
{
if ( KeyValue[Key] == Value )
@@ -374,7 +377,7 @@ namespace Steamworks
public static void ClearKeys()
{
KeyValue.Clear();
Internal.ClearAllKeyValues();
Internal?.ClearAllKeyValues();
}
/// <summary>
@@ -382,6 +385,7 @@ namespace Steamworks
/// </summary>
public static unsafe BeginAuthResult BeginAuthSession( byte[] data, SteamId steamid )
{
if (Internal is null) { return BeginAuthResult.ServerNotConnectedToSteam; }
fixed ( byte* p = data )
{
var result = Internal.BeginAuthSession( (IntPtr)p, data.Length, steamid );
@@ -395,7 +399,7 @@ namespace Steamworks
/// </summary>
public static void EndSession( SteamId steamid )
{
Internal.EndAuthSession( steamid );
Internal?.EndAuthSession( steamid );
}
/// <summary>
@@ -406,6 +410,12 @@ namespace Steamworks
/// <returns>True if we want to send a packet</returns>
public static unsafe bool GetOutgoingPacket( out OutgoingPacket packet )
{
if (Internal is null)
{
packet = default;
return false;
}
var buffer = Helpers.TakeBuffer( 1024 * 32 );
packet = new OutgoingPacket();
@@ -442,7 +452,7 @@ namespace Steamworks
/// </summary>
public static unsafe void HandleIncomingPacket( IntPtr ptr, int size, uint address, ushort port )
{
Internal.HandleIncomingPacket( ptr, size, address, port );
Internal?.HandleIncomingPacket( ptr, size, address, port );
}
/// <summary>
@@ -450,7 +460,7 @@ namespace Steamworks
/// </summary>
public static UserHasLicenseForAppResult UserHasLicenseForApp( SteamId steamid, AppId appid )
{
return Internal.UserHasLicenseForApp( steamid, appid );
return Internal?.UserHasLicenseForApp( steamid, appid ) ?? UserHasLicenseForAppResult.NoAuth;
}
}
}

View File

@@ -9,7 +9,7 @@ namespace Steamworks
{
public class SteamServerStats : SteamServerClass<SteamServerStats>
{
internal static ISteamGameServerStats Internal => Interface as ISteamGameServerStats;
internal static ISteamGameServerStats? Internal => Interface as ISteamGameServerStats;
internal override void InitializeInterface( bool server )
{
@@ -24,6 +24,7 @@ namespace Steamworks
/// </summary>
public static async Task<Result> RequestUserStatsAsync( SteamId steamid )
{
if (Internal is null) { return Result.Fail; }
var r = await Internal.RequestUserStats( steamid );
if ( !r.HasValue ) return Result.Fail;
return r.Value.Result;
@@ -35,7 +36,7 @@ namespace Steamworks
/// </summary>
public static bool SetInt( SteamId steamid, string name, int stat )
{
return Internal.SetUserStat( steamid, name, stat );
return Internal != null && Internal.SetUserStat( steamid, name, stat );
}
/// <summary>
@@ -44,7 +45,7 @@ namespace Steamworks
/// </summary>
public static bool SetFloat( SteamId steamid, string name, float stat )
{
return Internal.SetUserStat( steamid, name, stat );
return Internal != null && Internal.SetUserStat( steamid, name, stat );
}
/// <summary>
@@ -56,7 +57,7 @@ namespace Steamworks
{
int data = defaultValue;
if ( !Internal.GetUserStat( steamid, name, ref data ) )
if ( Internal is null || !Internal.GetUserStat( steamid, name, ref data ) )
return defaultValue;
return data;
@@ -71,7 +72,7 @@ namespace Steamworks
{
float data = defaultValue;
if ( !Internal.GetUserStat( steamid, name, ref data ) )
if ( Internal is null || !Internal.GetUserStat( steamid, name, ref data ) )
return defaultValue;
return data;
@@ -83,7 +84,7 @@ namespace Steamworks
/// </summary>
public static bool SetAchievement( SteamId steamid, string name )
{
return Internal.SetUserAchievement( steamid, name );
return Internal != null && Internal.SetUserAchievement( steamid, name );
}
/// <summary>
@@ -92,7 +93,7 @@ namespace Steamworks
/// </summary>
public static bool ClearAchievement( SteamId steamid, string name )
{
return Internal.ClearUserAchievement( steamid, name );
return Internal != null && Internal.ClearUserAchievement( steamid, name );
}
/// <summary>
@@ -102,7 +103,7 @@ namespace Steamworks
{
bool achieved = false;
if ( !Internal.GetUserAchievement( steamid, name, ref achieved ) )
if ( Internal is null || !Internal.GetUserAchievement( steamid, name, ref achieved ) )
return false;
return achieved;
@@ -115,6 +116,7 @@ namespace Steamworks
/// </summary>
public static async Task<Result> StoreUserStats( SteamId steamid )
{
if (Internal is null) { return Result.Fail; }
var r = await Internal.StoreUserStats( steamid );
if ( !r.HasValue ) return Result.Fail;
return r.Value.Result;

View File

@@ -15,7 +15,7 @@ namespace Steamworks
/// </summary>
public class SteamUGC : SteamSharedClass<SteamUGC>
{
internal static ISteamUGC Internal => Interface as ISteamUGC;
internal static ISteamUGC? Internal => Interface as ISteamUGC;
internal override void InitializeInterface( bool server )
{
@@ -44,10 +44,11 @@ namespace Steamworks
/// <summary>
/// Posted after Download call
/// </summary>
public static event Action<Result, ulong> OnDownloadItemResult;
public static event Action<Result, ulong>? OnDownloadItemResult;
public static async Task<bool> DeleteFileAsync( PublishedFileId fileId )
{
if (Internal is null) { return false; }
var r = await Internal.DeleteItem( fileId );
return r?.Result == Result.OK;
}
@@ -60,7 +61,7 @@ namespace Steamworks
/// <returns>true if nothing went wrong and the download is started</returns>
public static bool Download( PublishedFileId fileId, bool highPriority = false )
{
return Internal.DownloadItem( fileId, highPriority );
return Internal != null && Internal.DownloadItem( fileId, highPriority );
}
/// <summary>
@@ -73,7 +74,7 @@ namespace Steamworks
/// <returns>true if downloaded and installed correctly</returns>
public static async Task<bool> DownloadAsync(
PublishedFileId fileId,
Action<float> progress = null,
Action<float>? progress = null,
int millisecondsUpdateDelay = 60,
CancellationToken? ct = null)
{
@@ -163,28 +164,32 @@ namespace Steamworks
public static async Task<bool> StartPlaytimeTracking(PublishedFileId fileId)
{
if (Internal is null) { return false; }
var result = await Internal.StartPlaytimeTracking(new[] {fileId}, 1);
return result.Value.Result == Result.OK;
return result?.Result == Result.OK;
}
public static async Task<bool> StopPlaytimeTracking(PublishedFileId fileId)
{
if (Internal is null) { return false; }
var result = await Internal.StopPlaytimeTracking(new[] {fileId}, 1);
return result.Value.Result == Result.OK;
return result?.Result == Result.OK;
}
public static async Task<bool> StopPlaytimeTrackingForAllItems()
{
if (Internal is null) { return false; }
var result = await Internal.StopPlaytimeTrackingForAllItems();
return result.Value.Result == Result.OK;
return result?.Result == Result.OK;
}
public static Action<ulong> GlobalOnItemInstalled;
public static Action<ulong>? GlobalOnItemInstalled;
public static uint NumSubscribedItems { get { return Internal.GetNumSubscribedItems(); } }
public static uint NumSubscribedItems { get { return Internal?.GetNumSubscribedItems() ?? 0; } }
public static PublishedFileId[] GetSubscribedItems()
{
if (Internal is null) { return Array.Empty<PublishedFileId>(); }
uint numSubscribed = NumSubscribedItems;
PublishedFileId[] ids = new PublishedFileId[numSubscribed];
Internal.GetSubscribedItems(ids, numSubscribed);

View File

@@ -15,7 +15,7 @@ namespace Steamworks
/// </summary>
public class SteamUser : SteamClientClass<SteamUser>
{
internal static ISteamUser Internal => Interface as ISteamUser;
internal static ISteamUser? Internal => Interface as ISteamUser;
internal override void InitializeInterface( bool server )
{
@@ -26,7 +26,7 @@ namespace Steamworks
SampleRate = OptimalSampleRate;
}
static Dictionary<string, string> richPresence;
static Dictionary<string, string>? richPresence;
internal static void InstallEvents()
{
@@ -48,20 +48,20 @@ namespace Steamworks
/// Usually this will have occurred before the game has launched, and should only be seen if the
/// user has dropped connection due to a networking issue or a Steam server update.
/// </summary>
public static event Action OnSteamServersConnected;
public static event Action? OnSteamServersConnected;
/// <summary>
/// Called when a connection attempt has failed.
/// This will occur periodically if the Steam client is not connected,
/// and has failed when retrying to establish a connection.
/// </summary>
public static event Action OnSteamServerConnectFailure;
public static event Action? OnSteamServerConnectFailure;
/// <summary>
/// Called if the client has lost connection to the Steam servers.
/// Real-time services will be disabled until a matching OnSteamServersConnected has been posted.
/// </summary>
public static event Action OnSteamServersDisconnected;
public static event Action? OnSteamServersDisconnected;
/// <summary>
/// Sent by the Steam server to the client telling it to disconnect from the specified game server,
@@ -69,12 +69,12 @@ namespace Steamworks
/// The game client should immediately disconnect upon receiving this message.
/// This can usually occur if the user doesn't have rights to play on the game server.
/// </summary>
public static event Action OnClientGameServerDeny;
public static event Action? OnClientGameServerDeny;
/// <summary>
/// Called whenever the users licenses (owned packages) changes.
/// </summary>
public static event Action OnLicensesUpdated;
public static event Action? OnLicensesUpdated;
/// <summary>
/// Called when an auth ticket has been validated.
@@ -82,18 +82,18 @@ namespace Steamworks
/// The second is the Steam ID that owns the game, this will be different from the first
/// if the game is being borrowed via Steam Family Sharing
/// </summary>
public static event Action<SteamId, SteamId, AuthResponse> OnValidateAuthTicketResponse;
public static event Action<SteamId, SteamId, AuthResponse>? OnValidateAuthTicketResponse;
/// <summary>
/// Used internally for GetAuthSessionTicketAsync
/// </summary>
internal static event Action<GetAuthSessionTicketResponse_t> OnGetAuthSessionTicketResponse;
internal static event Action<GetAuthSessionTicketResponse_t>? OnGetAuthSessionTicketResponse;
/// <summary>
/// Called when a user has responded to a microtransaction authorization request.
/// ( appid, orderid, user authorized )
/// </summary>
public static event Action<AppId, ulong, bool> OnMicroTxnAuthorizationResponse;
public static event Action<AppId, ulong, bool>? OnMicroTxnAuthorizationResponse;
/// <summary>
/// Sent to your game in response to a steam://gamewebcallback/(appid)/command/stuff command from a user clicking a
@@ -101,14 +101,14 @@ namespace Steamworks
/// You can use this to add support for external site signups where you want to pop back into the browser after some web page
/// signup sequence, and optionally get back some detail about that.
/// </summary>
public static event Action<string> OnGameWebCallback;
public static event Action<string>? OnGameWebCallback;
/// <summary>
/// Sent for games with enabled anti indulgence / duration control, for enabled users.
/// Lets the game know whether persistent rewards or XP should be granted at normal rate,
/// half rate, or zero rate.
/// </summary>
public static event Action<DurationControl> OnDurationControl;
public static event Action<DurationControl>? OnDurationControl;
@@ -127,8 +127,8 @@ namespace Steamworks
set
{
_recordingVoice = value;
if ( value ) Internal.StartVoiceRecording();
else Internal.StopVoiceRecording();
if ( value ) Internal?.StartVoiceRecording();
else Internal?.StopVoiceRecording();
}
}
@@ -142,7 +142,7 @@ namespace Steamworks
{
uint szCompressed = 0, deprecated = 0;
if ( Internal.GetAvailableVoice( ref szCompressed, ref deprecated, 0 ) != VoiceResult.OK )
if ( Internal is null || Internal.GetAvailableVoice( ref szCompressed, ref deprecated, 0 ) != VoiceResult.OK )
return false;
return szCompressed > 0;
@@ -168,7 +168,7 @@ namespace Steamworks
fixed ( byte* b = readBuffer )
{
if ( Internal.GetVoice( true, (IntPtr)b, (uint)readBuffer.Length, ref szWritten, false, IntPtr.Zero, 0, ref deprecated, 0 ) != VoiceResult.OK )
if ( Internal is null || Internal.GetVoice( true, (IntPtr)b, (uint)readBuffer.Length, ref szWritten, false, IntPtr.Zero, 0, ref deprecated, 0 ) != VoiceResult.OK )
return 0;
}
@@ -185,7 +185,7 @@ namespace Steamworks
/// ReadVoiceData because it won't be creating a new byte array every call. But this
/// makes it easier to get it working, so let the babies have their bottle.
/// </summary>
public static unsafe byte[] ReadVoiceDataBytes()
public static unsafe byte[]? ReadVoiceDataBytes()
{
if ( !HasVoiceData )
return null;
@@ -195,7 +195,7 @@ namespace Steamworks
fixed ( byte* b = readBuffer )
{
if ( Internal.GetVoice( true, (IntPtr)b, (uint)readBuffer.Length, ref szWritten, false, IntPtr.Zero, 0, ref deprecated, 0 ) != VoiceResult.OK )
if ( Internal is null || Internal.GetVoice( true, (IntPtr)b, (uint)readBuffer.Length, ref szWritten, false, IntPtr.Zero, 0, ref deprecated, 0 ) != VoiceResult.OK )
return null;
}
@@ -222,7 +222,7 @@ namespace Steamworks
}
}
public static uint OptimalSampleRate => Internal.GetVoiceOptimalSampleRate();
public static uint OptimalSampleRate => Internal?.GetVoiceOptimalSampleRate() ?? 0;
/// <summary>
@@ -247,7 +247,7 @@ namespace Steamworks
fixed ( byte* frm = from )
fixed ( byte* dst = to )
{
if ( Internal.DecompressVoice( (IntPtr) frm, (uint) length, (IntPtr)dst, (uint)to.Length, ref szWritten, SampleRate ) != VoiceResult.OK )
if ( Internal is null || Internal.DecompressVoice( (IntPtr) frm, (uint) length, (IntPtr)dst, (uint)to.Length, ref szWritten, SampleRate ) != VoiceResult.OK )
return 0;
}
@@ -273,7 +273,7 @@ namespace Steamworks
fixed ( byte* frm = from )
fixed ( byte* dst = to )
{
if ( Internal.DecompressVoice( (IntPtr)frm, (uint)from.Length, (IntPtr)dst, (uint)to.Length, ref szWritten, SampleRate ) != VoiceResult.OK )
if ( Internal is null || Internal.DecompressVoice( (IntPtr)frm, (uint)from.Length, (IntPtr)dst, (uint)to.Length, ref szWritten, SampleRate ) != VoiceResult.OK )
return 0;
}
@@ -297,7 +297,7 @@ namespace Steamworks
uint szWritten = 0;
if ( Internal.DecompressVoice( from, (uint) length, to, (uint)bufferSize, ref szWritten, SampleRate ) != VoiceResult.OK )
if ( Internal is null || Internal.DecompressVoice( from, (uint) length, to, (uint)bufferSize, ref szWritten, SampleRate ) != VoiceResult.OK )
return 0;
return (int)szWritten;
@@ -306,14 +306,14 @@ namespace Steamworks
/// <summary>
/// Retrieve a authentication ticket to be sent to the entity who wishes to authenticate you.
/// </summary>
public static unsafe AuthTicket GetAuthSessionTicket()
public static unsafe AuthTicket? GetAuthSessionTicket()
{
var data = Helpers.TakeBuffer( 1024 );
fixed ( byte* b = data )
{
uint ticketLength = 0;
uint ticket = Internal.GetAuthSessionTicket( (IntPtr)b, data.Length, ref ticketLength );
uint ticket = Internal?.GetAuthSessionTicket( (IntPtr)b, data.Length, ref ticketLength ) ?? 0;
if ( ticket == 0 )
return null;
@@ -332,15 +332,15 @@ namespace Steamworks
/// the ticket is definitely ready to go as soon as it returns. Will return null if the callback
/// times out or returns negatively.
/// </summary>
public static async Task<AuthTicket> GetAuthSessionTicketAsync( double timeoutSeconds = 10.0f )
public static async Task<AuthTicket?> GetAuthSessionTicketAsync( double timeoutSeconds = 10.0f )
{
var result = Result.Pending;
AuthTicket ticket = null;
AuthTicket? ticket = null;
var stopwatch = Stopwatch.StartNew();
void f( GetAuthSessionTicketResponse_t t )
{
if ( t.AuthTicket != ticket.Handle ) return;
if ( t.AuthTicket != ticket?.Handle ) return;
result = t.Result;
}
@@ -379,11 +379,11 @@ namespace Steamworks
{
fixed ( byte* ptr = ticketData )
{
return Internal.BeginAuthSession( (IntPtr) ptr, ticketData.Length, steamid );
return Internal?.BeginAuthSession( (IntPtr) ptr, ticketData.Length, steamid ) ?? BeginAuthResult.ServerNotConnectedToSteam;
}
}
public static void EndAuthSession( SteamId steamid ) => Internal.EndAuthSession( steamid );
public static void EndAuthSession( SteamId steamid ) => Internal?.EndAuthSession( steamid );
// UserHasLicenseForApp - SERVER VERSION ( DLC CHECKING )
@@ -392,12 +392,12 @@ namespace Steamworks
/// Checks if the current users looks like they are behind a NAT device.
/// This is only valid if the user is connected to the Steam servers and may not catch all forms of NAT.
/// </summary>
public static bool IsBehindNAT => Internal.BIsBehindNAT();
public static bool IsBehindNAT => Internal != null && Internal.BIsBehindNAT();
/// <summary>
/// Gets the Steam level of the user, as shown on their Steam community profile.
/// </summary>
public static int SteamLevel => Internal.GetPlayerSteamLevel();
public static int SteamLevel => Internal?.GetPlayerSteamLevel() ?? 0;
/// <summary>
/// Requests a URL which authenticates an in-game browser for store check-out, and then redirects to the specified URL.
@@ -405,8 +405,10 @@ namespace Steamworks
/// NOTE: The URL has a very short lifetime to prevent history-snooping attacks, so you should only call this API when you are about to launch the browser, or else immediately navigate to the result URL using a hidden browser window.
/// NOTE: The resulting authorization cookie has an expiration time of one day, so it would be a good idea to request and visit a new auth URL every 12 hours.
/// </summary>
public static async Task<string> GetStoreAuthUrlAsync( string url )
public static async Task<string?> GetStoreAuthUrlAsync( string url )
{
if (Internal is null) { return null; }
var response = await Internal.RequestStoreAuthURL( url );
if ( !response.HasValue )
return null;
@@ -417,22 +419,22 @@ namespace Steamworks
/// <summary>
/// Checks whether the current user has verified their phone number.
/// </summary>
public static bool IsPhoneVerified => Internal.BIsPhoneVerified();
public static bool IsPhoneVerified => Internal != null && Internal.BIsPhoneVerified();
/// <summary>
/// Checks whether the current user has Steam Guard two factor authentication enabled on their account.
/// </summary>
public static bool IsTwoFactorEnabled => Internal.BIsTwoFactorEnabled();
public static bool IsTwoFactorEnabled => Internal != null && Internal.BIsTwoFactorEnabled();
/// <summary>
/// Checks whether the user's phone number is used to uniquely identify them.
/// </summary>
public static bool IsPhoneIdentifying => Internal.BIsPhoneIdentifying();
public static bool IsPhoneIdentifying => Internal != null && Internal.BIsPhoneIdentifying();
/// <summary>
/// Checks whether the current user's phone number is awaiting (re)verification.
/// </summary>
public static bool IsPhoneRequiringVerification => Internal.BIsPhoneRequiringVerification();
public static bool IsPhoneRequiringVerification => Internal != null && Internal.BIsPhoneRequiringVerification();
/// <summary>
/// Requests an application ticket encrypted with the secret "encrypted app ticket key".
@@ -441,8 +443,10 @@ namespace Steamworks
/// 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/
/// </summary>
public static async Task<byte[]> RequestEncryptedAppTicketAsync( byte[] dataToInclude )
public static async Task<byte[]?> RequestEncryptedAppTicketAsync( byte[] dataToInclude )
{
if (Internal is null) { return null; }
var dataPtr = Marshal.AllocHGlobal( dataToInclude.Length );
Marshal.Copy( dataToInclude, 0, dataPtr, dataToInclude.Length );
@@ -453,7 +457,7 @@ namespace Steamworks
var ticketData = Marshal.AllocHGlobal( 1024 );
uint outSize = 0;
byte[] data = null;
byte[]? data = null;
if ( Internal.GetEncryptedAppTicket( ticketData, 1024, ref outSize ) )
{
@@ -477,14 +481,16 @@ namespace Steamworks
/// There can only be one call pending, and this call is subject to a 60 second rate limit.
/// This can fail if you don't have an encrypted ticket set for your app here https://partner.steamgames.com/apps/sdkauth/
/// </summary>
public static async Task<byte[]> RequestEncryptedAppTicketAsync()
public static async Task<byte[]?> RequestEncryptedAppTicketAsync()
{
if (Internal is null) { return null; }
var result = await Internal.RequestEncryptedAppTicket( IntPtr.Zero, 0 );
if ( !result.HasValue || result.Value.Result != Result.OK ) return null;
var ticketData = Marshal.AllocHGlobal( 1024 );
uint outSize = 0;
byte[] data = null;
byte[]? data = null;
if ( Internal.GetEncryptedAppTicket( ticketData, 1024, ref outSize ) )
{
@@ -504,6 +510,8 @@ namespace Steamworks
/// </summary>
public static async Task<DurationControl> GetDurationControl()
{
if (Internal is null) { return default; }
var response = await Internal.GetDurationControl();
if ( !response.HasValue ) return default;

View File

@@ -9,7 +9,7 @@ namespace Steamworks
{
public class SteamUserStats : SteamClientClass<SteamUserStats>
{
internal static ISteamUserStats Internal => Interface as ISteamUserStats;
internal static ISteamUserStats? Internal => Interface as ISteamUserStats;
internal override void InitializeInterface( bool server )
{
@@ -40,31 +40,31 @@ namespace Steamworks
/// <summary>
/// called when the achivement icon is loaded
/// </summary>
internal static event Action<string, int> OnAchievementIconFetched;
internal static event Action<string, int>? OnAchievementIconFetched;
/// <summary>
/// called when the latests stats and achievements have been received
/// from the server
/// </summary>
public static event Action<SteamId, Result> OnUserStatsReceived;
public static event Action<SteamId, Result>? OnUserStatsReceived;
/// <summary>
/// result of a request to store the user stats for a game
/// </summary>
public static event Action<Result> OnUserStatsStored;
public static event Action<Result>? OnUserStatsStored;
/// <summary>
/// result of a request to store the achievements for a game, or an
/// "indicate progress" call. If both m_nCurProgress and m_nMaxProgress
/// are zero, that means the achievement has been fully unlocked
/// </summary>
public static event Action<Achievement, int, int> OnAchievementProgress;
public static event Action<Achievement, int, int>? OnAchievementProgress;
/// <summary>
/// Callback indicating that a user's stats have been unloaded
/// </summary>
public static event Action<SteamId> OnUserStatsUnloaded;
public static event Action<SteamId>? OnUserStatsUnloaded;
/// <summary>
/// Get the available achievements
@@ -73,8 +73,11 @@ namespace Steamworks
{
get
{
for( int i=0; i< Internal.GetNumAchievements(); i++ )
if (Internal is null) { yield break; }
uint numAchievements = Internal.GetNumAchievements();
for( int i=0; i < numAchievements; i++ )
{
if (Internal is null) { yield break; }
yield return new Achievement( Internal.GetAchievementName( (uint) i ) );
}
}
@@ -88,6 +91,8 @@ namespace Steamworks
/// </summary>
public static bool IndicateAchievementProgress( string achName, int curProg, int maxProg )
{
if (Internal is null) { return false; }
if ( string.IsNullOrEmpty( achName ) )
throw new ArgumentNullException( "Achievement string is null or empty" );
@@ -103,6 +108,8 @@ namespace Steamworks
/// </summary>
public static async Task<int> PlayerCountAsync()
{
if (Internal is null) { return -1; }
var result = await Internal.GetNumberOfCurrentPlayers();
if ( !result.HasValue || result.Value.Success == 0 )
return -1;
@@ -122,7 +129,7 @@ namespace Steamworks
/// </summary>
public static bool StoreStats()
{
return Internal.StoreStats();
return Internal != null && Internal.StoreStats();
}
/// <summary>
@@ -133,7 +140,7 @@ namespace Steamworks
/// </summary>
public static bool RequestCurrentStats()
{
return Internal.RequestCurrentStats();
return Internal != null && Internal.RequestCurrentStats();
}
/// <summary>
@@ -146,6 +153,7 @@ namespace Steamworks
/// <returns>OK indicates success, InvalidState means you need to call RequestCurrentStats first, Fail means the remote call failed</returns>
public static async Task<Result> RequestGlobalStatsAsync( int days )
{
if (Internal is null) { return Result.Fail; }
var result = await SteamUserStats.Internal.RequestGlobalStats( days );
if ( !result.HasValue ) return Result.Fail;
return result.Value.Result;
@@ -162,6 +170,7 @@ namespace Steamworks
/// </summary>
public static async Task<Leaderboard?> FindOrCreateLeaderboardAsync( string name, LeaderboardSort sort, LeaderboardDisplay display )
{
if (Internal is null) { return null; }
var result = await Internal.FindOrCreateLeaderboard( name, sort, display );
if ( !result.HasValue || result.Value.LeaderboardFound == 0 )
return null;
@@ -172,6 +181,7 @@ namespace Steamworks
public static async Task<Leaderboard?> FindLeaderboardAsync( string name )
{
if (Internal is null) { return null; }
var result = await Internal.FindLeaderboard( name );
if ( !result.HasValue || result.Value.LeaderboardFound == 0 )
return null;
@@ -211,7 +221,7 @@ namespace Steamworks
/// </summary>
public static bool SetStat( string name, int value )
{
return Internal.SetStat( name, value );
return Internal != null && Internal.SetStat( name, value );
}
/// <summary>
@@ -220,7 +230,7 @@ namespace Steamworks
/// </summary>
public static bool SetStat( string name, float value )
{
return Internal.SetStat( name, value );
return Internal != null && Internal.SetStat( name, value );
}
/// <summary>
@@ -229,7 +239,7 @@ namespace Steamworks
public static int GetStatInt( string name )
{
int data = 0;
Internal.GetStat( name, ref data );
Internal?.GetStat( name, ref data );
return data;
}
@@ -239,7 +249,7 @@ namespace Steamworks
public static float GetStatFloat( string name )
{
float data = 0;
Internal.GetStat( name, ref data );
Internal?.GetStat( name, ref data );
return data;
}
@@ -250,7 +260,7 @@ namespace Steamworks
/// <returns></returns>
public static bool ResetAll( bool includeAchievements )
{
return Internal.ResetAllStats( includeAchievements );
return Internal != null && Internal.ResetAllStats( includeAchievements );
}
}
}

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamUtils : SteamSharedClass<SteamUtils>
{
internal static ISteamUtils Internal => Interface as ISteamUtils;
internal static ISteamUtils? Internal => Interface as ISteamUtils;
internal override void InitializeInterface( bool server )
{
@@ -38,47 +38,47 @@ namespace Steamworks
/// <summary>
/// The country of the user changed
/// </summary>
public static event Action OnIpCountryChanged;
public static event Action? OnIpCountryChanged;
/// <summary>
/// Fired when running on a laptop and less than 10 minutes of battery is left, fires then every minute
/// The parameter is the number of minutes left
/// </summary>
public static event Action<int> OnLowBatteryPower;
public static event Action<int>? OnLowBatteryPower;
/// <summary>
/// Called when Steam wants to shutdown
/// </summary>
public static event Action OnSteamShutdown;
public static event Action? OnSteamShutdown;
/// <summary>
/// Big Picture gamepad text input has been closed. Parameter is true if text was submitted, false if cancelled etc.
/// </summary>
public static event Action<bool> OnGamepadTextInputDismissed;
public static event Action<bool>? OnGamepadTextInputDismissed;
/// <summary>
/// Returns the number of seconds since the application was active
/// </summary>
public static uint SecondsSinceAppActive => Internal.GetSecondsSinceAppActive();
public static uint SecondsSinceAppActive => Internal?.GetSecondsSinceAppActive() ?? 0;
/// <summary>
/// Returns the number of seconds since the user last moved the mouse etc
/// </summary>
public static uint SecondsSinceComputerActive => Internal.GetSecondsSinceComputerActive();
public static uint SecondsSinceComputerActive => Internal?.GetSecondsSinceComputerActive() ?? 0;
// the universe this client is connecting to
public static Universe ConnectedUniverse => Internal.GetConnectedUniverse();
public static Universe ConnectedUniverse => Internal?.GetConnectedUniverse() ?? Universe.Invalid;
/// <summary>
/// Steam server time. Number of seconds since January 1, 1970, GMT (i.e unix time)
/// </summary>
public static DateTime SteamServerTime => Epoch.ToDateTime( Internal.GetServerRealTime() );
public static DateTime SteamServerTime => Internal != null ? Epoch.ToDateTime( Internal.GetServerRealTime() ) : default;
/// <summary>
/// returns the 2 digit ISO 3166-1-alpha-2 format country code this client is running in (as looked up via an IP-to-location database)
/// e.g "US" or "UK".
/// </summary>
public static string IpCountry => Internal.GetIPCountry();
public static string? IpCountry => Internal?.GetIPCountry();
/// <summary>
/// returns true if the image exists, and the buffer was successfully filled out
@@ -89,7 +89,7 @@ namespace Steamworks
{
width = 0;
height = 0;
return Internal.GetImageSize( image, ref width, ref height );
return Internal != null && Internal.GetImageSize( image, ref width, ref height );
}
/// <summary>
@@ -109,7 +109,7 @@ namespace Steamworks
var buf = Helpers.TakeBuffer( (int) size );
if ( !Internal.GetImageRGBA( image, buf, (int)size ) )
if ( Internal is null || !Internal.GetImageRGBA( image, buf, (int)size ) )
return null;
i.Data = new byte[size];
@@ -120,12 +120,12 @@ namespace Steamworks
/// <summary>
/// Returns true if we're using a battery (ie, a laptop not plugged in)
/// </summary>
public static bool UsingBatteryPower => Internal.GetCurrentBatteryPower() != 255;
public static bool UsingBatteryPower => Internal != null && Internal.GetCurrentBatteryPower() != 255;
/// <summary>
/// Returns battery power [0-1]
/// </summary>
public static float CurrentBatteryPower => Math.Min( Internal.GetCurrentBatteryPower() / 100, 1.0f );
public static float CurrentBatteryPower => Math.Min( (Internal?.GetCurrentBatteryPower() ?? 0f) / 100, 1.0f );
static NotificationPosition overlayNotificationPosition = NotificationPosition.BottomRight;
@@ -140,7 +140,7 @@ namespace Steamworks
set
{
overlayNotificationPosition = value;
Internal.SetOverlayNotificationPosition( value );
Internal?.SetOverlayNotificationPosition( value );
}
}
@@ -148,7 +148,7 @@ namespace Steamworks
/// Returns true if the overlay is running and the user can access it. The overlay process could take a few seconds to
/// start and hook the game process, so this function will initially return false while the overlay is loading.
/// </summary>
public static bool IsOverlayEnabled => Internal.IsOverlayEnabled();
public static bool IsOverlayEnabled => Internal != null && Internal.IsOverlayEnabled();
/// <summary>
/// Normally this call is unneeded if your game has a constantly running frame loop that calls the
@@ -161,7 +161,7 @@ namespace Steamworks
/// in that case, and then you can check for this periodically (roughly 33hz is desirable) and make sure you
/// refresh the screen with Present or SwapBuffers to allow the overlay to do it's work.
/// </summary>
public static bool DoesOverlayNeedPresent => Internal.BOverlayNeedsPresent();
public static bool DoesOverlayNeedPresent => Internal != null && Internal.BOverlayNeedsPresent();
/// <summary>
/// Asynchronous call to check if an executable file has been signed using the public key set on the signing tab
@@ -169,6 +169,8 @@ namespace Steamworks
/// </summary>
public static async Task<CheckFileSignature> CheckFileSignatureAsync( string filename )
{
if (Internal is null) { throw new System.Exception( "SteamUtils not initialized" ); }
var r = await Internal.CheckFileSignature( filename );
if ( !r.HasValue )
@@ -184,7 +186,7 @@ namespace Steamworks
/// </summary>
public static bool ShowGamepadTextInput( GamepadTextInputMode inputMode, GamepadTextInputLineMode lineInputMode, string description, int maxChars, string existingText = "" )
{
return Internal.ShowGamepadTextInput( inputMode, lineInputMode, description, (uint)maxChars, existingText );
return Internal != null && Internal.ShowGamepadTextInput( inputMode, lineInputMode, description, (uint)maxChars, existingText );
}
/// <summary>
@@ -192,6 +194,8 @@ namespace Steamworks
/// </summary>
public static string GetEnteredGamepadText()
{
if (Internal is null) { return string.Empty; }
var len = Internal.GetEnteredGamepadTextLength();
if ( len == 0 ) return string.Empty;
@@ -205,19 +209,19 @@ namespace Steamworks
/// returns the language the steam client is running in, you probably want
/// Apps.CurrentGameLanguage instead, this is for very special usage cases
/// </summary>
public static string SteamUILanguage => Internal.GetSteamUILanguage();
public static string? SteamUILanguage => Internal?.GetSteamUILanguage();
/// <summary>
/// returns true if Steam itself is running in VR mode
/// </summary>
public static bool IsSteamRunningInVR => Internal.IsSteamRunningInVR();
public static bool IsSteamRunningInVR => Internal != null && Internal.IsSteamRunningInVR();
/// <summary>
/// Sets the inset of the overlay notification from the corner specified by SetOverlayNotificationPosition
/// </summary>
public static void SetOverlayNotificationInset( int x, int y )
{
Internal.SetOverlayNotificationInset( x, y );
Internal?.SetOverlayNotificationInset( x, y );
}
/// <summary>
@@ -225,13 +229,13 @@ namespace Steamworks
/// Games much be launched through the Steam client to enable the Big Picture overlay. During development,
/// a game can be added as a non-steam game to the developers library to test this feature
/// </summary>
public static bool IsSteamInBigPictureMode => Internal.IsSteamInBigPictureMode();
public static bool IsSteamInBigPictureMode => Internal != null && Internal.IsSteamInBigPictureMode();
/// <summary>
/// ask SteamUI to create and render its OpenVR dashboard
/// </summary>
public static void StartVRDashboard() => Internal.StartVRDashboard();
public static void StartVRDashboard() => Internal?.StartVRDashboard();
/// <summary>
/// Set whether the HMD content will be streamed via Steam In-Home Streaming
@@ -242,24 +246,24 @@ namespace Steamworks
/// </summary>
public static bool VrHeadsetStreaming
{
get => Internal.IsVRHeadsetStreamingEnabled();
get => Internal != null && Internal.IsVRHeadsetStreamingEnabled();
set
{
Internal.SetVRHeadsetStreamingEnabled( value );
Internal?.SetVRHeadsetStreamingEnabled( value );
}
}
internal static bool IsCallComplete( SteamAPICall_t call, out bool failed )
{
failed = false;
return Internal.IsAPICallCompleted( call, ref failed );
return Internal != null && Internal.IsAPICallCompleted( call, ref failed );
}
/// <summary>
/// Returns whether this steam client is a Steam China specific client, vs the global client
/// </summary>
public static bool IsSteamChinaLauncher => Internal.IsSteamChinaLauncher();
public static bool IsSteamChinaLauncher => Internal != null && Internal.IsSteamChinaLauncher();
}
}

View File

@@ -12,7 +12,7 @@ namespace Steamworks
/// </summary>
public class SteamVideo : SteamClientClass<SteamVideo>
{
internal static ISteamVideo Internal => Interface as ISteamVideo;
internal static ISteamVideo? Internal => Interface as ISteamVideo;
internal override void InitializeInterface( bool server )
{
@@ -26,8 +26,8 @@ namespace Steamworks
Dispatch.Install<BroadcastUploadStop_t>( x => OnBroadcastStopped?.Invoke( x.Result ) );
}
public static event Action OnBroadcastStarted;
public static event Action<BroadcastUploadResult> OnBroadcastStopped;
public static event Action? OnBroadcastStarted;
public static event Action<BroadcastUploadResult>? OnBroadcastStopped;
/// <summary>
/// Return true if currently using Steam's live broadcasting
@@ -37,7 +37,7 @@ namespace Steamworks
get
{
int viewers = 0;
return Internal.IsBroadcasting( ref viewers );
return Internal != null && Internal.IsBroadcasting( ref viewers );
}
}
@@ -50,7 +50,7 @@ namespace Steamworks
{
int viewers = 0;
if ( !Internal.IsBroadcasting( ref viewers ) )
if ( Internal is null || !Internal.IsBroadcasting( ref viewers ) )
return 0;
return viewers;

View File

@@ -74,12 +74,10 @@ namespace Steamworks
m_RulesFailedToRespond = onRulesFailedToRespond;
m_RulesRefreshComplete = onRulesRefreshComplete;
m_VTable = new VTable()
{
m_VTRulesResponded = InternalOnRulesResponded,
m_VTRulesFailedToRespond = InternalOnRulesFailedToRespond,
m_VTRulesRefreshComplete = InternalOnRulesRefreshComplete
};
m_VTable = new VTable(
mVtRulesResponded: InternalOnRulesResponded,
mVtRulesFailedToRespond: InternalOnRulesFailedToRespond,
mVtRulesRefreshComplete: InternalOnRulesRefreshComplete);
m_pVTable = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(VTable)));
Marshal.StructureToPtr(m_VTable, m_pVTable, false);
@@ -153,13 +151,20 @@ namespace Steamworks
private class VTable
{
[NonSerialized] [MarshalAs(UnmanagedType.FunctionPtr)]
public InternalRulesResponded m_VTRulesResponded;
public readonly InternalRulesResponded m_VTRulesResponded;
[NonSerialized] [MarshalAs(UnmanagedType.FunctionPtr)]
public InternalRulesFailedToRespond m_VTRulesFailedToRespond;
public readonly InternalRulesFailedToRespond m_VTRulesFailedToRespond;
[NonSerialized] [MarshalAs(UnmanagedType.FunctionPtr)]
public InternalRulesRefreshComplete m_VTRulesRefreshComplete;
public readonly InternalRulesRefreshComplete m_VTRulesRefreshComplete;
public VTable(InternalRulesResponded mVtRulesResponded, InternalRulesFailedToRespond mVtRulesFailedToRespond, InternalRulesRefreshComplete mVtRulesRefreshComplete)
{
m_VTRulesResponded = mVtRulesResponded;
m_VTRulesFailedToRespond = mVtRulesFailedToRespond;
m_VTRulesRefreshComplete = mVtRulesRefreshComplete;
}
}
public static explicit operator System.IntPtr(SteamMatchmakingRulesResponse that)

View File

@@ -25,16 +25,16 @@ namespace Steamworks.Data
get
{
var state = false;
SteamUserStats.Internal.GetAchievement( Value, ref state );
SteamUserStats.Internal?.GetAchievement( Value, ref state );
return state;
}
}
public string Identifier => Value;
public string Name => SteamUserStats.Internal.GetAchievementDisplayAttribute( Value, "name" );
public string? Name => SteamUserStats.Internal?.GetAchievementDisplayAttribute( Value, "name" );
public string Description => SteamUserStats.Internal.GetAchievementDisplayAttribute( Value, "desc" );
public string? Description => SteamUserStats.Internal?.GetAchievementDisplayAttribute( Value, "desc" );
/// <summary>
@@ -47,7 +47,7 @@ namespace Steamworks.Data
var state = false;
uint time = 0;
if ( !SteamUserStats.Internal.GetAchievementAndUnlockTime( Value, ref state, ref time ) || !state )
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetAchievementAndUnlockTime( Value, ref state, ref time ) || !state )
return null;
return Epoch.ToDateTime( time );
@@ -60,6 +60,7 @@ namespace Steamworks.Data
/// </summary>
public Image? GetIcon()
{
if (SteamUserStats.Internal is null) { return null; }
return SteamUtils.GetImage( SteamUserStats.Internal.GetAchievementIcon( Value ) );
}
@@ -69,6 +70,7 @@ namespace Steamworks.Data
/// </summary>
public async Task<Image?> GetIconAsync( int timeout = 5000 )
{
if (SteamUserStats.Internal is null) { return null; }
var i = SteamUserStats.Internal.GetAchievementIcon( Value );
if ( i != 0 ) return SteamUtils.GetImage( i );
@@ -115,7 +117,7 @@ namespace Steamworks.Data
{
float pct = 0;
if ( !SteamUserStats.Internal.GetAchievementAchievedPercent( Value, ref pct ) )
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetAchievementAchievedPercent( Value, ref pct ) )
return -1.0f;
return pct / 100.0f;
@@ -127,6 +129,8 @@ namespace Steamworks.Data
/// </summary>
public bool Trigger( bool apply = true )
{
if (SteamUserStats.Internal is null) { return false; }
var r = SteamUserStats.Internal.SetAchievement( Value );
if ( apply && r )
@@ -142,6 +146,7 @@ namespace Steamworks.Data
/// </summary>
public bool Clear()
{
if (SteamUserStats.Internal is null) { return false; }
return SteamUserStats.Internal.ClearAchievement( Value );
}
}

View File

@@ -14,20 +14,20 @@ namespace Steamworks
Id = id;
}
public string Name => SteamFriends.Internal.GetClanName(Id);
public string? Name => SteamFriends.Internal?.GetClanName(Id);
public string Tag => SteamFriends.Internal.GetClanTag(Id);
public string? Tag => SteamFriends.Internal?.GetClanTag(Id);
public int ChatMemberCount => SteamFriends.Internal.GetClanChatMemberCount(Id);
public int ChatMemberCount => SteamFriends.Internal?.GetClanChatMemberCount(Id) ?? 0;
public Friend Owner => new Friend(SteamFriends.Internal.GetClanOwner(Id));
public Friend Owner => new Friend(SteamFriends.Internal?.GetClanOwner(Id) ?? 0);
public bool Public => SteamFriends.Internal.IsClanPublic(Id);
public bool Public => SteamFriends.Internal != null && SteamFriends.Internal.IsClanPublic(Id);
/// <summary>
/// Is the clan an official game group?
/// </summary>
public bool Official => SteamFriends.Internal.IsClanOfficialGameGroup(Id);
public bool Official => SteamFriends.Internal != null && SteamFriends.Internal.IsClanOfficialGameGroup(Id);
/// <summary>
/// Asynchronously fetches the officer list for a given clan
@@ -35,14 +35,18 @@ namespace Steamworks
/// <returns>Whether the request was successful or not</returns>
public async Task<bool> RequestOfficerList()
{
if (SteamFriends.Internal is null) { return false; }
var req = await SteamFriends.Internal.RequestClanOfficerList(Id);
return req.HasValue && req.Value.Success != 0x0;
}
public IEnumerable<Friend> GetOfficers()
{
for (int i = 0; i < SteamFriends.Internal.GetClanOfficerCount(Id); i++)
if (SteamFriends.Internal is null) { yield break; }
var officerCount = SteamFriends.Internal.GetClanOfficerCount(Id);
for (int i = 0; i < officerCount; i++)
{
if (SteamFriends.Internal is null) { yield break; }
yield return new Friend(SteamFriends.Internal.GetClanOfficerByIndex(Id, i));
}
}

View File

@@ -14,7 +14,7 @@ namespace Steamworks
}
public ulong Id => Handle.Value;
public InputType InputType => SteamInput.Internal.GetInputTypeForHandle( Handle );
public InputType InputType => SteamInput.Internal?.GetInputTypeForHandle( Handle ) ?? InputType.Unknown;
/// <summary>
/// Reconfigure the controller to use the specified action set (ie 'Menu', 'Walk' or 'Drive')
@@ -23,12 +23,12 @@ namespace Steamworks
/// </summary>
public string ActionSet
{
set => SteamInput.Internal.ActivateActionSet( Handle, SteamInput.Internal.GetActionSetHandle( value ) );
set => SteamInput.Internal?.ActivateActionSet( Handle, SteamInput.Internal.GetActionSetHandle( value ) );
}
public void DeactivateLayer( string layer ) => SteamInput.Internal.DeactivateActionSetLayer( Handle, SteamInput.Internal.GetActionSetHandle( layer ) );
public void ActivateLayer( string layer ) => SteamInput.Internal.ActivateActionSetLayer( Handle, SteamInput.Internal.GetActionSetHandle( layer ) );
public void ClearLayers() => SteamInput.Internal.DeactivateAllActionSetLayers( Handle );
public void DeactivateLayer( string layer ) => SteamInput.Internal?.DeactivateActionSetLayer( Handle, SteamInput.Internal.GetActionSetHandle( layer ) );
public void ActivateLayer( string layer ) => SteamInput.Internal?.ActivateActionSetLayer( Handle, SteamInput.Internal.GetActionSetHandle( layer ) );
public void ClearLayers() => SteamInput.Internal?.DeactivateAllActionSetLayers( Handle );
/// <summary>
@@ -36,7 +36,7 @@ namespace Steamworks
/// </summary>
public DigitalState GetDigitalState( string actionName )
{
return SteamInput.Internal.GetDigitalActionData( Handle, SteamInput.GetDigitalActionHandle( actionName ) );
return SteamInput.Internal?.GetDigitalActionData( Handle, SteamInput.GetDigitalActionHandle( actionName ) ) ?? default;
}
/// <summary>
@@ -44,7 +44,7 @@ namespace Steamworks
/// </summary>
public AnalogState GetAnalogState( string actionName )
{
return SteamInput.Internal.GetAnalogActionData( Handle, SteamInput.GetAnalogActionHandle( actionName ) );
return SteamInput.Internal?.GetAnalogActionData( Handle, SteamInput.GetAnalogActionHandle( actionName ) ) ?? default;
}

View File

@@ -73,16 +73,16 @@ namespace Steamworks
public Relationship Relationship => SteamFriends.Internal.GetFriendRelationship( Id );
public FriendState State => SteamFriends.Internal.GetFriendPersonaState( Id );
public string Name => SteamFriends.Internal.GetFriendPersonaName( Id );
public Relationship Relationship => SteamFriends.Internal?.GetFriendRelationship( Id ) ?? Relationship.None;
public FriendState State => SteamFriends.Internal?.GetFriendPersonaState( Id ) ?? FriendState.Offline;
public string? Name => SteamFriends.Internal?.GetFriendPersonaName( Id );
public IEnumerable<string> NameHistory
{
get
{
for( int i=0; i<32; i++ )
{
var n = SteamFriends.Internal.GetFriendPersonaNameHistory( Id, i );
var n = SteamFriends.Internal?.GetFriendPersonaNameHistory( Id, i );
if ( string.IsNullOrEmpty( n ) )
break;
@@ -91,7 +91,7 @@ namespace Steamworks
}
}
public int SteamLevel => SteamFriends.Internal.GetFriendSteamLevel( Id );
public int SteamLevel => SteamFriends.Internal?.GetFriendSteamLevel( Id ) ?? 0;
@@ -100,7 +100,7 @@ namespace Steamworks
get
{
FriendGameInfo_t gameInfo = default;
if ( !SteamFriends.Internal.GetFriendGamePlayed( Id, ref gameInfo ) )
if ( SteamFriends.Internal is null || !SteamFriends.Internal.GetFriendGamePlayed( Id, ref gameInfo ) )
return null;
return FriendGameInfo.From( gameInfo );
@@ -109,7 +109,7 @@ namespace Steamworks
public bool IsIn( SteamId group_or_room )
{
return SteamFriends.Internal.IsUserInSource( Id, group_or_room );
return SteamFriends.Internal != null && SteamFriends.Internal.IsUserInSource( Id, group_or_room );
}
public struct FriendGameInfo
@@ -161,9 +161,9 @@ namespace Steamworks
return await SteamFriends.GetLargeAvatarAsync( Id );
}
public string GetRichPresence( string key )
public string? GetRichPresence( string key )
{
var val = SteamFriends.Internal.GetFriendRichPresence( Id, key );
var val = SteamFriends.Internal?.GetFriendRichPresence( Id, key );
if ( string.IsNullOrEmpty( val ) ) return null;
return val;
}
@@ -173,7 +173,7 @@ namespace Steamworks
/// </summary>
public bool InviteToGame( string Text )
{
return SteamFriends.Internal.InviteUserToGame( Id, Text );
return SteamFriends.Internal != null && SteamFriends.Internal.InviteUserToGame( Id, Text );
}
/// <summary>
@@ -181,7 +181,7 @@ namespace Steamworks
/// </summary>
public bool SendMessage( string message )
{
return SteamFriends.Internal.ReplyToFriendMessage( Id, message );
return SteamFriends.Internal != null && SteamFriends.Internal.ReplyToFriendMessage( Id, message );
}
@@ -191,8 +191,9 @@ namespace Steamworks
/// <returns>True if successful, False if failure</returns>
public async Task<bool> RequestUserStatsAsync()
{
if (SteamUserStats.Internal is null) { return false; }
var result = await SteamUserStats.Internal.RequestUserStats( Id );
return result.HasValue && result.Value.Result == Result.OK;
return result?.Result == Result.OK;
}
/// <summary>
@@ -205,7 +206,7 @@ namespace Steamworks
{
var val = defult;
if ( !SteamUserStats.Internal.GetUserStat( Id, statName, ref val ) )
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetUserStat( Id, statName, ref val ) )
return defult;
return val;
@@ -221,7 +222,7 @@ namespace Steamworks
{
var val = defult;
if ( !SteamUserStats.Internal.GetUserStat( Id, statName, ref val ) )
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetUserStat( Id, statName, ref val ) )
return defult;
return val;
@@ -237,7 +238,7 @@ namespace Steamworks
{
var val = defult;
if ( !SteamUserStats.Internal.GetUserAchievement( Id, statName, ref val ) )
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetUserAchievement( Id, statName, ref val ) )
return defult;
return val;
@@ -253,7 +254,7 @@ namespace Steamworks
bool val = false;
uint time = 0;
if ( !SteamUserStats.Internal.GetUserAchievementAndUnlockTime( Id, statName, ref val, ref time ) || !val )
if ( SteamUserStats.Internal is null || !SteamUserStats.Internal.GetUserAchievementAndUnlockTime( Id, statName, ref val, ref time ) || !val )
return DateTime.MinValue;
return Epoch.ToDateTime( time );

View File

@@ -8,7 +8,7 @@ namespace Steamworks
public class InventoryDef : IEquatable<InventoryDef>
{
internal InventoryDefId _id;
internal Dictionary<string, string> _properties;
internal Dictionary<string, string>? _properties;
public InventoryDef( InventoryDefId defId )
{
@@ -20,32 +20,32 @@ namespace Steamworks
/// <summary>
/// Shortcut to call GetProperty( "name" )
/// </summary>
public string Name => GetProperty( "name" );
public string? Name => GetProperty( "name" );
/// <summary>
/// Shortcut to call GetProperty( "description" )
/// </summary>
public string Description => GetProperty( "description" );
public string? Description => GetProperty( "description" );
/// <summary>
/// Shortcut to call GetProperty( "icon_url" )
/// </summary>
public string IconUrl => GetProperty( "icon_url" );
public string? IconUrl => GetProperty( "icon_url" );
/// <summary>
/// Shortcut to call GetProperty( "icon_url_large" )
/// </summary>
public string IconUrlLarge => GetProperty( "icon_url_large" );
public string? IconUrlLarge => GetProperty( "icon_url_large" );
/// <summary>
/// Shortcut to call GetProperty( "price_category" )
/// </summary>
public string PriceCategory => GetProperty( "price_category" );
public string? PriceCategory => GetProperty( "price_category" );
/// <summary>
/// Shortcut to call GetProperty( "type" )
/// </summary>
public string Type => GetProperty( "type" );
public string? Type => GetProperty( "type" );
/// <summary>
/// Returns true if this is an item that generates an item, rather
@@ -56,12 +56,12 @@ namespace Steamworks
/// <summary>
/// Shortcut to call GetProperty( "exchange" )
/// </summary>
public string ExchangeSchema => GetProperty( "exchange" );
public string? ExchangeSchema => GetProperty( "exchange" );
/// <summary>
/// Get a list of exchanges that are available to make this item
/// </summary>
public InventoryRecipe[] GetRecipes()
public InventoryRecipe[]? GetRecipes()
{
if ( string.IsNullOrEmpty( ExchangeSchema ) ) return null;
@@ -93,19 +93,19 @@ namespace Steamworks
/// <summary>
/// Get a specific property by name
/// </summary>
public string GetProperty( string name )
public string? GetProperty( string? name )
{
if ( _properties!= null && _properties.TryGetValue( name, out string val ) )
if ( _properties != null && name != null && _properties.TryGetValue( name, out string val ) )
return val;
uint _ = (uint)Helpers.MemoryBufferSize;
if ( !SteamInventory.Internal.GetItemDefinitionProperty( Id, name, out var vl, ref _ ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.GetItemDefinitionProperty( Id, name, out var vl, ref _ ) )
return null;
if (name == null) //return keys string
return vl;
if ( _properties == null )
_properties = new Dictionary<string, string>();
@@ -119,9 +119,9 @@ namespace Steamworks
/// </summary>
public bool GetBoolProperty( string name )
{
string val = GetProperty( name );
string? val = GetProperty( name );
if ( val.Length == 0 ) return false;
if ( string.IsNullOrEmpty(val) ) return false;
if ( val[0] == '0' || val[0] == 'F' || val[0] == 'f' ) return false;
return true;
@@ -130,9 +130,9 @@ namespace Steamworks
/// <summary>
/// Read a raw property from the definition schema
/// </summary>
public T GetProperty<T>( string name )
public T? GetProperty<T>( string name )
{
string val = GetProperty( name );
string? val = GetProperty( name );
if ( string.IsNullOrEmpty( val ) )
return default;
@@ -150,16 +150,16 @@ namespace Steamworks
/// <summary>
/// Gets a list of all properties on this item
/// </summary>
public IEnumerable<KeyValuePair<string, string>> Properties
public IEnumerable<KeyValuePair<string, string?>> Properties
{
get
{
var list = GetProperty( null );
var list = GetProperty( null ) ?? "";
var keys = list.Split( ',' );
foreach ( var key in keys )
{
yield return new KeyValuePair<string, string>( key, GetProperty( key ) );
yield return new KeyValuePair<string, string?>( key, GetProperty( key ) );
}
}
}
@@ -174,7 +174,7 @@ namespace Steamworks
ulong curprice = 0;
ulong baseprice = 0;
if ( !SteamInventory.Internal.GetItemPrice( Id, ref curprice, ref baseprice ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.GetItemPrice( Id, ref curprice, ref baseprice ) )
return 0;
return (int) curprice;
@@ -194,7 +194,7 @@ namespace Steamworks
ulong curprice = 0;
ulong baseprice = 0;
if ( !SteamInventory.Internal.GetItemPrice( Id, ref curprice, ref baseprice ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.GetItemPrice( Id, ref curprice, ref baseprice ) )
return 0;
return (int)baseprice;
@@ -203,12 +203,12 @@ namespace Steamworks
public string LocalBasePriceFormatted => Utility.FormatPrice( SteamInventory.Currency, LocalPrice / 100.0 );
InventoryRecipe[] _recContaining;
InventoryRecipe[]? _recContaining;
/// <summary>
/// Return a list of recepies that contain this item
/// </summary>
public InventoryRecipe[] GetRecipesContainingThis()
public InventoryRecipe[]? GetRecipesContainingThis()
{
if ( _recContaining != null ) return _recContaining;
@@ -221,17 +221,17 @@ namespace Steamworks
return _recContaining;
}
public static bool operator ==( InventoryDef a, InventoryDef b )
public static bool operator ==( InventoryDef? a, InventoryDef? b )
{
if ( Object.ReferenceEquals( a, null ) )
return Object.ReferenceEquals( b, null );
return a.Equals( b );
}
public static bool operator !=( InventoryDef a, InventoryDef b ) => !(a == b);
public static bool operator !=( InventoryDef? a, InventoryDef? b ) => !(a == b);
public override bool Equals( object p ) => this.Equals( (InventoryDef)p );
public override int GetHashCode() => Id.GetHashCode();
public bool Equals( InventoryDef p )
public bool Equals( InventoryDef? p )
{
if ( p == null ) return false;
return p.Id == Id;

View File

@@ -11,7 +11,7 @@ namespace Steamworks
internal InventoryDefId _def;
internal SteamItemFlags _flags;
internal ushort _quantity;
internal Dictionary<string, string> _properties;
internal Dictionary<string, string>? _properties;
public InventoryItemId Id => _id;
@@ -19,13 +19,13 @@ namespace Steamworks
public int Quantity => _quantity;
public InventoryDef Def => SteamInventory.FindDefinition( DefId );
public InventoryDef? Def => SteamInventory.FindDefinition( DefId );
/// <summary>
/// Only available if the result set was created with the getproperties
/// </summary>
public Dictionary<string, string> Properties => _properties;
public Dictionary<string, string>? Properties => _properties;
/// <summary>
/// This item is account-locked and cannot be traded or given away.
@@ -54,7 +54,7 @@ namespace Steamworks
public async Task<InventoryResult?> ConsumeAsync( int amount = 1 )
{
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !SteamInventory.Internal.ConsumeItem( ref sresult, Id, (uint)amount ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.ConsumeItem( ref sresult, Id, (uint)amount ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -66,7 +66,7 @@ namespace Steamworks
public async Task<InventoryResult?> SplitStackAsync( int quantity = 1 )
{
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !SteamInventory.Internal.TransferItemQuantity( ref sresult, Id, (uint)quantity, ulong.MaxValue ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.TransferItemQuantity( ref sresult, Id, (uint)quantity, ulong.MaxValue ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -78,7 +78,7 @@ namespace Steamworks
public async Task<InventoryResult?> AddAsync( InventoryItem add, int quantity = 1 )
{
var sresult = Defines.k_SteamInventoryResultInvalid;
if ( !SteamInventory.Internal.TransferItemQuantity( ref sresult, add.Id, (uint)quantity, Id ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.TransferItemQuantity( ref sresult, add.Id, (uint)quantity, Id ) )
return null;
return await InventoryResult.GetAsync( sresult );
@@ -98,11 +98,11 @@ namespace Steamworks
return i;
}
internal static Dictionary<string, string> GetProperties( SteamInventoryResult_t result, int index )
internal static Dictionary<string, string>? GetProperties( SteamInventoryResult_t result, int index )
{
var strlen = (uint) Helpers.MemoryBufferSize;
if ( !SteamInventory.Internal.GetResultItemProperty( result, (uint)index, null, out var propNames, ref strlen ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.GetResultItemProperty( result, (uint)index, null, out var propNames, ref strlen ) )
return null;
var props = new Dictionary<string, string>();
@@ -151,7 +151,7 @@ namespace Steamworks
/// Tries to get the origin property. Need properties for this to work.
/// Will return a string like "market"
/// </summary>
public string Origin
public string? Origin
{
get
{

View File

@@ -22,7 +22,7 @@ namespace Steamworks
/// If we don't know about this item definition this might be null.
/// In which case, DefinitionId should still hold the correct id.
/// </summary>
public InventoryDef Definition;
public InventoryDef? Definition;
/// <summary>
/// The amount of this item needed. Generally this will be 1.

View File

@@ -23,7 +23,7 @@ namespace Steamworks
{
uint cnt = 0;
if ( !SteamInventory.Internal.GetResultItems( _id, null, ref cnt ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.GetResultItems( _id, null, ref cnt ) )
return 0;
return (int) cnt;
@@ -36,17 +36,17 @@ namespace Steamworks
/// </summary>
public bool BelongsTo( SteamId steamId )
{
return SteamInventory.Internal.CheckResultSteamID( _id, steamId );
return SteamInventory.Internal != null && SteamInventory.Internal.CheckResultSteamID( _id, steamId );
}
public InventoryItem[] GetItems( bool includeProperties = false )
public InventoryItem[]? GetItems( bool includeProperties = false )
{
uint cnt = (uint) ItemCount;
if ( cnt <= 0 ) return null;
var pOutItemsArray = new SteamItemDetails_t[cnt];
if ( !SteamInventory.Internal.GetResultItems( _id, pOutItemsArray, ref cnt ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.GetResultItems( _id, pOutItemsArray, ref cnt ) )
return null;
var items = new InventoryItem[cnt];
@@ -69,7 +69,7 @@ namespace Steamworks
{
if ( _id.Value == -1 ) return;
SteamInventory.Internal.DestroyResult( _id );
SteamInventory.Internal?.DestroyResult( _id );
}
internal static async Task<InventoryResult?> GetAsync( SteamInventoryResult_t sresult )
@@ -77,7 +77,7 @@ namespace Steamworks
var _result = Result.Pending;
while ( _result == Result.Pending )
{
_result = SteamInventory.Internal.GetResultStatus( sresult );
_result = SteamInventory.Internal?.GetResultStatus( sresult ) ?? Result.Fail;
await Task.Delay( 10 );
}
@@ -97,11 +97,11 @@ namespace Steamworks
/// Results have a built-in timestamp which will be considered "expired" after an hour has elapsed.See DeserializeResult
/// for expiration handling.
/// </summary>
public unsafe byte[] Serialize()
public unsafe byte[]? Serialize()
{
uint size = 0;
if ( !SteamInventory.Internal.SerializeResult( _id, IntPtr.Zero, ref size ) )
if ( SteamInventory.Internal is null || !SteamInventory.Internal.SerializeResult( _id, IntPtr.Zero, ref size ) )
return null;
var data = new byte[size];

View File

@@ -14,10 +14,10 @@ namespace Steamworks.Data
/// <summary>
/// the name of a leaderboard
/// </summary>
public string Name => SteamUserStats.Internal.GetLeaderboardName( Id );
public LeaderboardSort Sort => SteamUserStats.Internal.GetLeaderboardSortMethod( Id );
public LeaderboardDisplay Display => SteamUserStats.Internal.GetLeaderboardDisplayType( Id );
public int EntryCount => SteamUserStats.Internal.GetLeaderboardEntryCount(Id);
public string? Name => SteamUserStats.Internal?.GetLeaderboardName( Id );
public LeaderboardSort Sort => SteamUserStats.Internal?.GetLeaderboardSortMethod( Id ) ?? default;
public LeaderboardDisplay Display => SteamUserStats.Internal?.GetLeaderboardDisplayType( Id ) ?? default;
public int EntryCount => SteamUserStats.Internal?.GetLeaderboardEntryCount(Id) ?? 0;
static int[] detailsBuffer = new int[64];
static int[] noDetails = Array.Empty<int>();
@@ -25,8 +25,9 @@ namespace Steamworks.Data
/// <summary>
/// Submit your score and replace your old score even if it was better
/// </summary>
public async Task<LeaderboardUpdate?> ReplaceScore( int score, int[] details = null )
public async Task<LeaderboardUpdate?> ReplaceScore( int score, int[]? details = null )
{
if (SteamUserStats.Internal is null) { return null; }
if ( details == null ) details = noDetails;
var r = await SteamUserStats.Internal.UploadLeaderboardScore( Id, LeaderboardUploadScoreMethod.ForceUpdate, score, details, details.Length );
@@ -38,8 +39,9 @@ namespace Steamworks.Data
/// <summary>
/// Submit your new score, but won't replace your high score if it's lower
/// </summary>
public async Task<LeaderboardUpdate?> SubmitScoreAsync( int score, int[] details = null )
public async Task<LeaderboardUpdate?> SubmitScoreAsync( int score, int[]? details = null )
{
if (SteamUserStats.Internal is null) { return null; }
if ( details == null ) details = noDetails;
var r = await SteamUserStats.Internal.UploadLeaderboardScore( Id, LeaderboardUploadScoreMethod.KeepBest, score, details, details.Length );
@@ -53,6 +55,7 @@ namespace Steamworks.Data
/// </summary>
public async Task<Result> AttachUgc( Ugc file )
{
if (SteamUserStats.Internal is null) { return Result.Fail; }
var r = await SteamUserStats.Internal.AttachLeaderboardUGC( Id, file.Handle );
if ( !r.HasValue ) return Result.Fail;
@@ -62,8 +65,9 @@ namespace Steamworks.Data
/// <summary>
/// Fetches leaderboard entries for an arbitrary set of users on a specified leaderboard.
/// </summary>
public async Task<LeaderboardEntry[]> GetScoresForUsersAsync( SteamId[] users )
public async Task<LeaderboardEntry[]?> GetScoresForUsersAsync( SteamId[]? users )
{
if (SteamUserStats.Internal is null) { return null; }
if ( users == null || users.Length == 0 )
return null;
@@ -77,8 +81,9 @@ namespace Steamworks.Data
/// <summary>
/// Used to query for a sequential range of leaderboard entries by leaderboard Sort.
/// </summary>
public async Task<LeaderboardEntry[]> GetScoresAsync( int count, int offset = 1 )
public async Task<LeaderboardEntry[]?> GetScoresAsync( int count, int offset = 1 )
{
if (SteamUserStats.Internal is null) { return null; }
if ( offset <= 0 ) throw new System.ArgumentException( "Should be 1+", nameof( offset ) );
var r = await SteamUserStats.Internal.DownloadLeaderboardEntries( Id, LeaderboardDataRequest.Global, offset, offset + count - 1 );
@@ -94,8 +99,9 @@ namespace Steamworks.Data
/// For example, if the user is #1 on the leaderboard and start is set to -2, end is set to 2, Steam will return the first
/// 5 entries in the leaderboard. If The current user has no entry, this will return null.
/// </summary>
public async Task<LeaderboardEntry[]> GetScoresAroundUserAsync( int start = -10, int end = 10 )
public async Task<LeaderboardEntry[]?> GetScoresAroundUserAsync( int start = -10, int end = 10 )
{
if (SteamUserStats.Internal is null) { return null; }
var r = await SteamUserStats.Internal.DownloadLeaderboardEntries( Id, LeaderboardDataRequest.GlobalAroundUser, start, end );
if ( !r.HasValue )
return null;
@@ -106,8 +112,9 @@ namespace Steamworks.Data
/// <summary>
/// Used to retrieve all leaderboard entries for friends of the current user
/// </summary>
public async Task<LeaderboardEntry[]> GetScoresFromFriendsAsync()
public async Task<LeaderboardEntry[]?> GetScoresFromFriendsAsync()
{
if (SteamUserStats.Internal is null) { return null; }
var r = await SteamUserStats.Internal.DownloadLeaderboardEntries( Id, LeaderboardDataRequest.Friends, 0, 0 );
if ( !r.HasValue )
return null;
@@ -116,8 +123,9 @@ namespace Steamworks.Data
}
#region util
internal async Task<LeaderboardEntry[]> LeaderboardResultToEntries( LeaderboardScoresDownloaded_t r )
internal async Task<LeaderboardEntry[]?> LeaderboardResultToEntries( LeaderboardScoresDownloaded_t r )
{
if (SteamUserStats.Internal is null) { return null; }
if ( r.CEntryCount <= 0 )
return null;
@@ -142,6 +150,8 @@ namespace Steamworks.Data
bool gotAll = false;
while ( !gotAll )
{
if (SteamFriends.Internal is null) { return; }
gotAll = true;
foreach ( var entry in entries )

View File

@@ -7,7 +7,7 @@ namespace Steamworks.Data
public Friend User;
public int GlobalRank;
public int Score;
public int[] Details;
public int[]? Details;
// UGCHandle_t m_hUGC
internal static LeaderboardEntry From( LeaderboardEntry_t e, int[] detailsBuffer )

View File

@@ -23,6 +23,8 @@ namespace Steamworks.Data
/// </summary>
public async Task<RoomEnter> Join()
{
if (SteamMatchmaking.Internal is null) { return RoomEnter.Error; }
var result = await SteamMatchmaking.Internal.JoinLobby( Id );
if ( !result.HasValue ) return RoomEnter.Error;
@@ -35,7 +37,7 @@ namespace Steamworks.Data
/// </summary>
public void Leave()
{
SteamMatchmaking.Internal.LeaveLobby( Id );
SteamMatchmaking.Internal?.LeaveLobby( Id );
}
/// <summary>
@@ -45,13 +47,13 @@ namespace Steamworks.Data
/// </summary>
public bool InviteFriend( SteamId steamid )
{
return SteamMatchmaking.Internal.InviteUserToLobby( Id, steamid );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.InviteUserToLobby( Id, steamid );
}
/// <summary>
/// returns the number of users in the specified lobby
/// </summary>
public int MemberCount => SteamMatchmaking.Internal.GetNumLobbyMembers( Id );
public int MemberCount => SteamMatchmaking.Internal?.GetNumLobbyMembers( Id ) ?? 0;
/// <summary>
/// Returns current members. Need to be in the lobby to see the users.
@@ -62,6 +64,7 @@ namespace Steamworks.Data
{
for( int i = 0; i < MemberCount; i++ )
{
if (SteamMatchmaking.Internal is null) { break; }
yield return new Friend( SteamMatchmaking.Internal.GetLobbyMemberByIndex( Id, i ) );
}
}
@@ -71,9 +74,9 @@ namespace Steamworks.Data
/// <summary>
/// Get data associated with this lobby
/// </summary>
public string GetData( string key )
public string? GetData( string key )
{
return SteamMatchmaking.Internal.GetLobbyData( Id, key );
return SteamMatchmaking.Internal?.GetLobbyData( Id, key );
}
/// <summary>
@@ -84,7 +87,7 @@ namespace Steamworks.Data
if ( key.Length > 255 ) throw new System.ArgumentException( "Key should be < 255 chars", nameof( key ) );
if ( value.Length > 8192 ) throw new System.ArgumentException( "Value should be < 8192 chars", nameof( key ) );
return SteamMatchmaking.Internal.SetLobbyData( Id, key, value );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyData( Id, key, value );
}
/// <summary>
@@ -92,7 +95,7 @@ namespace Steamworks.Data
/// </summary>
public bool DeleteData( string key )
{
return SteamMatchmaking.Internal.DeleteLobbyData( Id, key );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.DeleteLobbyData( Id, key );
}
/// <summary>
@@ -102,10 +105,11 @@ namespace Steamworks.Data
{
get
{
var cnt = SteamMatchmaking.Internal.GetLobbyDataCount( Id );
var cnt = SteamMatchmaking.Internal?.GetLobbyDataCount( Id ) ?? 0;
for ( int i =0; i<cnt; i++)
{
if (SteamMatchmaking.Internal is null) { break; }
if ( SteamMatchmaking.Internal.GetLobbyDataByIndex( Id, i, out var a, out var b ) )
{
yield return new KeyValuePair<string, string>( a, b );
@@ -117,9 +121,9 @@ namespace Steamworks.Data
/// <summary>
/// Gets per-user metadata for someone in this lobby
/// </summary>
public string GetMemberData( Friend member, string key )
public string? GetMemberData( Friend member, string key )
{
return SteamMatchmaking.Internal.GetLobbyMemberData( Id, member.Id, key );
return SteamMatchmaking.Internal?.GetLobbyMemberData( Id, member.Id, key );
}
/// <summary>
@@ -127,7 +131,7 @@ namespace Steamworks.Data
/// </summary>
public void SetMemberData( string key, string value )
{
SteamMatchmaking.Internal.SetLobbyMemberData( Id, key, value );
SteamMatchmaking.Internal?.SetLobbyMemberData( Id, key, value );
}
/// <summary>
@@ -148,7 +152,7 @@ namespace Steamworks.Data
{
fixed ( byte* ptr = data )
{
return SteamMatchmaking.Internal.SendLobbyChatMsg( Id, (IntPtr)ptr, data.Length );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SendLobbyChatMsg( Id, (IntPtr)ptr, data.Length );
}
}
@@ -163,7 +167,7 @@ namespace Steamworks.Data
/// </summary>
public bool Refresh()
{
return SteamMatchmaking.Internal.RequestLobbyData( Id );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.RequestLobbyData( Id );
}
/// <summary>
@@ -172,33 +176,33 @@ namespace Steamworks.Data
/// </summary>
public int MaxMembers
{
get => SteamMatchmaking.Internal.GetLobbyMemberLimit( Id );
set => SteamMatchmaking.Internal.SetLobbyMemberLimit( Id, value );
get => SteamMatchmaking.Internal?.GetLobbyMemberLimit( Id ) ?? 0;
set => SteamMatchmaking.Internal?.SetLobbyMemberLimit( Id, value );
}
public bool SetPublic()
{
return SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Public );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Public );
}
public bool SetPrivate()
{
return SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Private );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Private );
}
public bool SetInvisible()
{
return SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Invisible );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.Invisible );
}
public bool SetFriendsOnly()
{
return SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.FriendsOnly );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyType( Id, LobbyType.FriendsOnly );
}
public bool SetJoinable( bool b )
{
return SteamMatchmaking.Internal.SetLobbyJoinable( Id, b );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.SetLobbyJoinable( Id, b );
}
/// <summary>
@@ -211,7 +215,7 @@ namespace Steamworks.Data
if ( !steamServer.IsValid )
throw new ArgumentException( $"SteamId for server is invalid" );
SteamMatchmaking.Internal.SetLobbyGameServer( Id, 0, 0, steamServer );
SteamMatchmaking.Internal?.SetLobbyGameServer( Id, 0, 0, steamServer );
}
/// <summary>
@@ -224,7 +228,7 @@ namespace Steamworks.Data
if ( !IPAddress.TryParse( ip, out IPAddress add ) )
throw new ArgumentException( $"IP address for server is invalid" );
SteamMatchmaking.Internal.SetLobbyGameServer( Id, add.IpToInt32(), port, new SteamId() );
SteamMatchmaking.Internal?.SetLobbyGameServer( Id, add.IpToInt32(), port, new SteamId() );
}
/// <summary>
@@ -233,7 +237,7 @@ namespace Steamworks.Data
/// </summary>
public bool GetGameServer( ref uint ip, ref ushort port, ref SteamId serverId )
{
return SteamMatchmaking.Internal.GetLobbyGameServer( Id, ref ip, ref port, ref serverId );
return SteamMatchmaking.Internal != null && SteamMatchmaking.Internal.GetLobbyGameServer( Id, ref ip, ref port, ref serverId );
}
/// <summary>
@@ -241,8 +245,8 @@ namespace Steamworks.Data
/// </summary>
public Friend Owner
{
get => new Friend( SteamMatchmaking.Internal.GetLobbyOwner( Id ) );
set => SteamMatchmaking.Internal.SetLobbyOwner( Id, value.Id );
get => new Friend( SteamMatchmaking.Internal?.GetLobbyOwner( Id ) ?? 0 );
set => SteamMatchmaking.Internal?.SetLobbyOwner( Id, value.Id );
}
/// <summary>

View File

@@ -197,6 +197,8 @@ namespace Steamworks.Data
void ApplyFilters()
{
if (SteamMatchmaking.Internal is null) { return; }
if ( distance.HasValue )
{
SteamMatchmaking.Internal.AddRequestLobbyListDistanceFilter( distance.Value );
@@ -251,8 +253,10 @@ namespace Steamworks.Data
/// <summary>
/// Run the query, get the matching lobbies
/// </summary>
public async Task<Lobby[]> RequestAsync()
public async Task<Lobby[]?> RequestAsync()
{
if (SteamMatchmaking.Internal is null) { return null; }
await Task.Yield();
ApplyFilters();

View File

@@ -5,7 +5,7 @@ namespace Steamworks
{
public struct PartyBeacon
{
static ISteamParties Internal => SteamParties.Internal;
static ISteamParties? Internal => SteamParties.Internal;
internal PartyBeaconID_t Id;
@@ -18,7 +18,7 @@ namespace Steamworks
{
var owner = default( SteamId );
var location = default( SteamPartyBeaconLocation_t );
Internal.GetBeaconDetails( Id, ref owner, ref location, out _ );
Internal?.GetBeaconDetails( Id, ref owner, ref location, out _ );
return owner;
}
}
@@ -26,13 +26,14 @@ namespace Steamworks
/// <summary>
/// Creator of the beacon
/// </summary>
public string MetaData
public string? MetaData
{
get
{
var owner = default( SteamId );
var location = default( SteamPartyBeaconLocation_t );
_ = Internal.GetBeaconDetails( Id, ref owner, ref location, out var strVal );
string? strVal = null;
_ = Internal?.GetBeaconDetails( Id, ref owner, ref location, out strVal );
return strVal;
}
}
@@ -41,8 +42,10 @@ namespace Steamworks
/// Will attempt to join the party. If successful will return a connection string.
/// If failed, will return null
/// </summary>
public async Task<string> JoinAsync()
public async Task<string?> JoinAsync()
{
if (Internal is null) { return null; }
var result = await Internal.JoinParty( Id );
if ( !result.HasValue || result.Value.Result != Result.OK )
return null;
@@ -56,7 +59,7 @@ namespace Steamworks
/// </summary>
public void OnReservationCompleted( SteamId steamid )
{
Internal.OnReservationCompleted( Id, steamid );
Internal?.OnReservationCompleted( Id, steamid );
}
/// <summary>
@@ -66,7 +69,7 @@ namespace Steamworks
/// </summary>
public void CancelReservation( SteamId steamid )
{
Internal.CancelReservation( Id, steamid );
Internal?.CancelReservation( Id, steamid );
}
/// <summary>
@@ -74,7 +77,7 @@ namespace Steamworks
/// </summary>
public bool Destroy()
{
return Internal.DestroyBeacon( Id );
return Internal != null && Internal.DestroyBeacon( Id );
}
}
}

View File

@@ -23,16 +23,16 @@ namespace Steamworks.Data
/// <summary>
/// Get the SteamID of the connected user
/// </summary>
public SteamId SteamId => SteamRemotePlay.Internal.GetSessionSteamID( Id );
public SteamId SteamId => SteamRemotePlay.Internal?.GetSessionSteamID( Id ) ?? default;
/// <summary>
/// Get the name of the session client device
/// </summary>
public string ClientName => SteamRemotePlay.Internal.GetSessionClientName( Id );
public string? ClientName => SteamRemotePlay.Internal?.GetSessionClientName( Id );
/// <summary>
/// Get the name of the session client device
/// </summary>
public SteamDeviceFormFactor FormFactor => SteamRemotePlay.Internal.GetSessionClientFormFactor( Id );
public SteamDeviceFormFactor FormFactor => SteamRemotePlay.Internal?.GetSessionClientFormFactor( Id ) ?? SteamDeviceFormFactor.Unknown;
}
}

View File

@@ -15,7 +15,7 @@ namespace Steamworks.Data
/// </summary>
public bool TagUser( SteamId user )
{
return SteamScreenshots.Internal.TagUser( Value, user );
return SteamScreenshots.Internal != null && SteamScreenshots.Internal.TagUser( Value, user );
}
/// <summary>
@@ -23,7 +23,7 @@ namespace Steamworks.Data
/// </summary>
public bool SetLocation( string location )
{
return SteamScreenshots.Internal.SetLocation( Value, location );
return SteamScreenshots.Internal != null && SteamScreenshots.Internal.SetLocation( Value, location );
}
/// <summary>
@@ -31,7 +31,7 @@ namespace Steamworks.Data
/// </summary>
public bool TagPublishedFile( PublishedFileId file )
{
return SteamScreenshots.Internal.TagPublishedFile( Value, file );
return SteamScreenshots.Internal != null && SteamScreenshots.Internal.TagPublishedFile( Value, file );
}
}
}

View File

@@ -9,11 +9,11 @@ namespace Steamworks.Data
{
public struct ServerInfo : IEquatable<ServerInfo>
{
public string Name { get; set; }
public string? Name { get; set; }
public int Ping { get; set; }
public string GameDir { get; set; }
public string Map { get; set; }
public string Description { get; set; }
public string? GameDir { get; set; }
public string? Map { get; set; }
public string? Description { get; set; }
public uint AppId { get; set; }
public int Players { get; set; }
public int MaxPlayers { get; set; }
@@ -22,19 +22,19 @@ namespace Steamworks.Data
public bool Secure { get; set; }
public uint LastTimePlayed { get; set; }
public int Version { get; set; }
public string TagString { get; set; }
public string? TagString { get; set; }
public ulong SteamId { get; set; }
public uint AddressRaw { get; set; }
public IPAddress Address { get; set; }
public IPAddress? Address { get; set; }
public int ConnectionPort { get; set; }
public int QueryPort { get; set; }
string[] _tags;
string[]? _tags;
/// <summary>
/// Gets the individual tags for this server
/// </summary>
public string[] Tags
public string[]? Tags
{
get
{
@@ -97,13 +97,13 @@ namespace Steamworks.Data
/// </summary>
public void AddToHistory()
{
SteamMatchmaking.Internal.AddFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory, (uint)Epoch.Current );
SteamMatchmaking.Internal?.AddFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory, (uint)Epoch.Current );
}
/// <summary>
/// If this server responds to source engine style queries, we'll be able to get a list of rules here
/// </summary>
public async Task<Dictionary<string, string>> QueryRulesAsync()
public async Task<Dictionary<string, string>?> QueryRulesAsync()
{
return await SourceServerQuery.GetRules( this );
}
@@ -113,7 +113,7 @@ namespace Steamworks.Data
/// </summary>
public void RemoveFromHistory()
{
SteamMatchmaking.Internal.RemoveFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory );
SteamMatchmaking.Internal?.RemoveFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory );
}
/// <summary>
@@ -121,7 +121,7 @@ namespace Steamworks.Data
/// </summary>
public void AddToFavourites()
{
SteamMatchmaking.Internal.AddFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite, (uint)Epoch.Current );
SteamMatchmaking.Internal?.AddFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite, (uint)Epoch.Current );
}
/// <summary>
@@ -129,7 +129,7 @@ namespace Steamworks.Data
/// </summary>
public void RemoveFromFavourites()
{
SteamMatchmaking.Internal.RemoveFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite );
SteamMatchmaking.Internal?.RemoveFavoriteGame( SteamClient.AppId, AddressRaw, (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite );
}
public bool Equals( ServerInfo other )
@@ -139,7 +139,7 @@ namespace Steamworks.Data
public override int GetHashCode()
{
return Address.GetHashCode() + SteamId.GetHashCode() + ConnectionPort.GetHashCode() + QueryPort.GetHashCode();
return (Address?.GetHashCode() ?? 0) + SteamId.GetHashCode() + ConnectionPort.GetHashCode() + QueryPort.GetHashCode();
}
}
}

View File

@@ -21,7 +21,7 @@ namespace Steamworks
/// </summary>
public struct SteamServerInit
{
public IPAddress IpAddress;
public IPAddress? IpAddress;
public ushort SteamPort;
public ushort GamePort;
public ushort QueryPort;

View File

@@ -26,7 +26,7 @@ namespace Steamworks.Data
UserId = user;
}
internal void LocalUserOnly( [CallerMemberName] string caller = null )
internal void LocalUserOnly( [CallerMemberName] string? caller = null )
{
if ( UserId == 0 ) return;
throw new System.Exception( $"Stat.{caller} can only be called for the local user" );
@@ -36,7 +36,7 @@ namespace Steamworks.Data
{
double val = 0.0;
if ( SteamUserStats.Internal.GetGlobalStat( Name, ref val ) )
if ( SteamUserStats.Internal != null && SteamUserStats.Internal.GetGlobalStat( Name, ref val ) )
return val;
return 0;
@@ -45,12 +45,14 @@ namespace Steamworks.Data
public long GetGlobalInt()
{
long val = 0;
SteamUserStats.Internal.GetGlobalStat( Name, ref val );
SteamUserStats.Internal?.GetGlobalStat( Name, ref val );
return val;
}
public async Task<long[]> GetGlobalIntDaysAsync( int days )
public async Task<long[]?> GetGlobalIntDaysAsync( int days )
{
if (SteamUserStats.Internal is null) { return null; }
var result = await SteamUserStats.Internal.RequestGlobalStats( days );
if ( result?.Result != Result.OK ) return null;
@@ -64,8 +66,10 @@ namespace Steamworks.Data
return r;
}
public async Task<double[]> GetGlobalFloatDays( int days )
public async Task<double[]?> GetGlobalFloatDays( int days )
{
if (SteamUserStats.Internal is null) { return null; }
var result = await SteamUserStats.Internal.RequestGlobalStats( days );
if ( result?.Result != Result.OK ) return null;
@@ -85,14 +89,14 @@ namespace Steamworks.Data
if ( UserId > 0 )
{
SteamUserStats.Internal.GetUserStat( UserId, Name, ref val );
SteamUserStats.Internal?.GetUserStat( UserId, Name, ref val );
}
else
{
SteamUserStats.Internal.GetStat( Name, ref val );
SteamUserStats.Internal?.GetStat( Name, ref val );
}
return 0;
return val;
}
public int GetInt()
@@ -101,11 +105,11 @@ namespace Steamworks.Data
if ( UserId > 0 )
{
SteamUserStats.Internal.GetUserStat( UserId, Name, ref val );
SteamUserStats.Internal?.GetUserStat( UserId, Name, ref val );
}
else
{
SteamUserStats.Internal.GetStat( Name, ref val );
SteamUserStats.Internal?.GetStat( Name, ref val );
}
return val;
@@ -114,13 +118,13 @@ namespace Steamworks.Data
public bool Set( int val )
{
LocalUserOnly();
return SteamUserStats.Internal.SetStat( Name, val );
return SteamUserStats.Internal != null && SteamUserStats.Internal.SetStat( Name, val );
}
public bool Set( float val )
{
LocalUserOnly();
return SteamUserStats.Internal.SetStat( Name, val );
return SteamUserStats.Internal != null && SteamUserStats.Internal.SetStat( Name, val );
}
public bool Add( int val )
@@ -138,13 +142,13 @@ namespace Steamworks.Data
public bool UpdateAverageRate( float count, float sessionlength )
{
LocalUserOnly();
return SteamUserStats.Internal.UpdateAvgRateStat( Name, count, sessionlength );
return SteamUserStats.Internal != null && SteamUserStats.Internal.UpdateAvgRateStat( Name, count, sessionlength );
}
public bool Store()
{
LocalUserOnly();
return SteamUserStats.Internal.StoreStats();
return SteamUserStats.Internal != null && SteamUserStats.Internal.StoreStats();
}
}
}

View File

@@ -47,25 +47,25 @@ namespace Steamworks.Ugc
public Editor ForAppId( AppId id ) { this.consumerAppId = id; return this; }
public string Title { get; private set; }
public string? Title { get; private set; }
public Editor WithTitle( string t ) { this.Title = t; return this; }
public string Description { get; private set; }
public string? Description { get; private set; }
public Editor WithDescription( string t ) { this.Description = t; return this; }
string MetaData;
string? MetaData;
public Editor WithMetaData( string t ) { this.MetaData = t; return this; }
string ChangeLog;
string? ChangeLog;
public Editor WithChangeLog( string t ) { this.ChangeLog = t; return this; }
string Language;
string? Language;
public Editor InLanguage( string t ) { this.Language = t; return this; }
public string PreviewFile { get; private set; }
public Editor WithPreviewFile( string t ) { this.PreviewFile = t; return this; }
public string? PreviewFile { get; private set; }
public Editor WithPreviewFile( string? t ) { this.PreviewFile = t; return this; }
public System.IO.DirectoryInfo ContentFolder { get; private set; }
public System.IO.DirectoryInfo? ContentFolder { get; private set; }
public Editor WithContent( System.IO.DirectoryInfo t ) { this.ContentFolder = t; return this; }
public Editor WithContent( string folderName ) { return WithContent( new System.IO.DirectoryInfo( folderName ) ); }
@@ -73,9 +73,9 @@ namespace Steamworks.Ugc
public Editor WithVisibility(Visibility visibility) { Visibility = visibility; return this; }
public List<string> Tags { get; private set; }
Dictionary<string, List<string>> keyValueTags;
HashSet<string> keyValueTagsToRemove;
public List<string>? Tags { get; private set; }
Dictionary<string, List<string>>? keyValueTags;
HashSet<string>? keyValueTagsToRemove;
public Editor WithTag( string tag )
{
@@ -143,9 +143,10 @@ namespace Steamworks.Ugc
return false;
}
public async Task<PublishResult> SubmitAsync( IProgress<float> progress = null )
public async Task<PublishResult> SubmitAsync( IProgress<float>? progress = null )
{
var result = default( PublishResult );
if (SteamUGC.Internal is null) { return result; }
progress?.Report( 0 );

View File

@@ -35,22 +35,22 @@ namespace Steamworks.Ugc
/// <summary>
/// The given title of this item
/// </summary>
public string Title { get; internal set; }
public string? Title { get; internal set; }
/// <summary>
/// The description of this item, in your local language if available
/// </summary>
public string Description { get; internal set; }
public string? Description { get; internal set; }
/// <summary>
/// A list of tags for this item, all lowercase
/// </summary>
public string[] Tags { get; internal set; }
public string[]? Tags { get; internal set; }
/// <summary>
/// A dictionary of key value tags for this item, only available from queries WithKeyValueTags(true)
/// </summary>
public Dictionary<string,string> KeyValueTags { get; internal set; }
public Dictionary<string,string>? KeyValueTags { get; internal set; }
/// <summary>
/// App Id of the app that created this item
@@ -123,14 +123,14 @@ namespace Steamworks.Ugc
public bool IsSubscribed => (State & ItemState.Subscribed) == ItemState.Subscribed;
public bool NeedsUpdate => (State & ItemState.NeedsUpdate) == ItemState.NeedsUpdate;
public string Directory
public string? Directory
{
get
{
ulong size = 0;
uint ts = 0;
if (SteamUGC.Internal.GetItemInstallInfo(Id, ref size, out var strVal, ref ts)) { return strVal; }
if (SteamUGC.Internal != null && SteamUGC.Internal.GetItemInstallInfo(Id, ref size, out var strVal, ref ts)) { return strVal; }
return null;
}
}
@@ -147,7 +147,7 @@ namespace Steamworks.Ugc
ulong downloaded = 0;
ulong total = 0;
if ( SteamUGC.Internal.GetItemDownloadInfo( Id, ref downloaded, ref total ) )
if ( SteamUGC.Internal != null && SteamUGC.Internal.GetItemDownloadInfo( Id, ref downloaded, ref total ) )
return (long) total;
return -1;
@@ -166,7 +166,7 @@ namespace Steamworks.Ugc
ulong downloaded = 0;
ulong total = 0;
if ( SteamUGC.Internal.GetItemDownloadInfo( Id, ref downloaded, ref total ) )
if ( SteamUGC.Internal != null && SteamUGC.Internal.GetItemDownloadInfo( Id, ref downloaded, ref total ) )
return (long)downloaded;
return -1;
@@ -185,7 +185,7 @@ namespace Steamworks.Ugc
ulong size = 0;
uint ts = 0;
if ( !SteamUGC.Internal.GetItemInstallInfo( Id, ref size, out _, ref ts ) )
if ( SteamUGC.Internal is null || !SteamUGC.Internal.GetItemInstallInfo( Id, ref size, out _, ref ts ) )
return 0;
return (long) size;
@@ -201,7 +201,7 @@ namespace Steamworks.Ugc
{
ulong size = 0;
uint ts = 0;
if ( !SteamUGC.Internal.GetItemInstallInfo( Id, ref size, out _, ref ts ) )
if ( SteamUGC.Internal is null || !SteamUGC.Internal.GetItemInstallInfo( Id, ref size, out _, ref ts ) )
return null;
return Epoch.ToDateTime(ts);
@@ -226,7 +226,7 @@ namespace Steamworks.Ugc
//possibly similar properties should also be changed
ulong downloaded = 0;
ulong total = 0;
if (SteamUGC.Internal.GetItemDownloadInfo(Id, ref downloaded, ref total) && total > 0)
if (SteamUGC.Internal != null && SteamUGC.Internal.GetItemDownloadInfo(Id, ref downloaded, ref total) && total > 0)
{
return (float)((double)downloaded / (double)total);
}
@@ -277,7 +277,7 @@ namespace Steamworks.Ugc
/// </summary>
public bool HasTag( string find )
{
if ( Tags.Length == 0 ) return false;
if ( Tags is null || Tags.Length == 0 ) return false;
return Tags.Contains( find, StringComparer.OrdinalIgnoreCase );
}
@@ -287,6 +287,7 @@ namespace Steamworks.Ugc
/// </summary>
public async Task<bool> Subscribe ()
{
if (SteamUGC.Internal is null) { return false; }
var result = await SteamUGC.Internal.SubscribeItem( _id );
return result?.Result == Result.OK;
}
@@ -296,7 +297,7 @@ namespace Steamworks.Ugc
/// If CancellationToken is default then there is 60 seconds timeout
/// Progress will be set to 0-1
/// </summary>
public async Task<bool> DownloadAsync( Action<float> progress = null, int milisecondsUpdateDelay = 60, CancellationToken ct = default )
public async Task<bool> DownloadAsync( Action<float>? progress = null, int milisecondsUpdateDelay = 60, CancellationToken ct = default )
{
return await SteamUGC.DownloadAsync( Id, progress, milisecondsUpdateDelay, ct );
}
@@ -305,7 +306,8 @@ namespace Steamworks.Ugc
/// Allows the user to unsubscribe from this item
/// </summary>
public async Task<bool> Unsubscribe ()
{
{
if (SteamUGC.Internal is null) { return false; }
var result = await SteamUGC.Internal.UnsubscribeItem( _id );
return result?.Result == Result.OK;
}
@@ -315,6 +317,7 @@ namespace Steamworks.Ugc
/// </summary>
public async Task<bool> AddFavorite()
{
if (SteamUGC.Internal is null) { return false; }
var result = await SteamUGC.Internal.AddItemToFavorites(details.ConsumerAppID, _id);
return result?.Result == Result.OK;
}
@@ -324,6 +327,7 @@ namespace Steamworks.Ugc
/// </summary>
public async Task<bool> RemoveFavorite()
{
if (SteamUGC.Internal is null) { return false; }
var result = await SteamUGC.Internal.RemoveItemFromFavorites(details.ConsumerAppID, _id);
return result?.Result == Result.OK;
}
@@ -333,6 +337,7 @@ namespace Steamworks.Ugc
/// </summary>
public async Task<Result?> Vote( bool up )
{
if (SteamUGC.Internal is null) { return null; }
var r = await SteamUGC.Internal.SetUserItemVote( Id, up );
return r?.Result;
}
@@ -342,6 +347,7 @@ namespace Steamworks.Ugc
/// </summary>
public async Task<UserItemVote?> GetUserVote()
{
if (SteamUGC.Internal is null) { return null; }
var result = await SteamUGC.Internal.GetUserItemVote(_id);
if (!result.HasValue)
return null;
@@ -351,27 +357,27 @@ namespace Steamworks.Ugc
/// <summary>
/// Return a URL to view this item online
/// </summary>
public string Url => $"http://steamcommunity.com/sharedfiles/filedetails/?source=Facepunch.Steamworks&id={Id}";
public string Url => $"https://steamcommunity.com/sharedfiles/filedetails/?source=Facepunch.Steamworks&id={Id}";
/// <summary>
/// The URl to view this item's changelog
/// </summary>
public string ChangelogUrl => $"http://steamcommunity.com/sharedfiles/filedetails/changelog/{Id}";
public string ChangelogUrl => $"https://steamcommunity.com/sharedfiles/filedetails/changelog/{Id}";
/// <summary>
/// The URL to view the comments on this item
/// </summary>
public string CommentsUrl => $"http://steamcommunity.com/sharedfiles/filedetails/comments/{Id}";
public string CommentsUrl => $"https://steamcommunity.com/sharedfiles/filedetails/comments/{Id}";
/// <summary>
/// The URL to discuss this item
/// </summary>
public string DiscussUrl => $"http://steamcommunity.com/sharedfiles/filedetails/discussions/{Id}";
public string DiscussUrl => $"https://steamcommunity.com/sharedfiles/filedetails/discussions/{Id}";
/// <summary>
/// The URL to view this items stats online
/// </summary>
public string StatsUrl => $"http://steamcommunity.com/sharedfiles/filedetails/stats/{Id}";
public string StatsUrl => $"https://steamcommunity.com/sharedfiles/filedetails/stats/{Id}";
public ulong NumSubscriptions { get; internal set; }
public ulong NumFavorites { get; internal set; }
@@ -390,12 +396,12 @@ namespace Steamworks.Ugc
/// <summary>
/// The URL to the preview image for this item
/// </summary>
public string PreviewImageUrl { get; internal set; }
public string? PreviewImageUrl { get; internal set; }
/// <summary>
/// The metadata string for this item, only available from queries WithMetadata(true)
/// </summary>
public string Metadata { get; internal set; }
public string? Metadata { get; internal set; }
/// <summary>
/// Edit this item

View File

@@ -14,7 +14,7 @@ namespace Steamworks.Ugc
UGCQuery queryType;
AppId consumerApp;
AppId creatorApp;
string searchText;
string? searchText;
public Query( UgcType type ) : this()
{
@@ -96,7 +96,7 @@ namespace Steamworks.Ugc
#endregion
#region Files
PublishedFileId[] Files;
PublishedFileId[]? Files;
public Query WithFileId( params PublishedFileId[] files )
{
@@ -109,6 +109,8 @@ namespace Steamworks.Ugc
{
if ( page <= 0 ) throw new System.Exception( "page should be > 0" );
if (SteamUGC.Internal is null) { return null; }
if ( consumerApp == 0 ) consumerApp = SteamClient.AppId;
if ( creatorApp == 0 ) creatorApp = consumerApp;
@@ -159,16 +161,16 @@ namespace Steamworks.Ugc
public QueryType WithType( UgcType type ) { matchingType = type; return this; }
int? maxCacheAge;
public QueryType AllowCachedResponse( int maxSecondsAge ) { maxCacheAge = maxSecondsAge; return this; }
string language;
string? language;
public QueryType InLanguage( string lang ) { language = lang; return this; }
int? trendDays;
public QueryType WithTrendDays( int days ) { trendDays = days; return this; }
List<string> requiredTags;
List<string>? requiredTags;
bool? matchAnyTag;
List<string> excludedTags;
Dictionary<string, string> requiredKv;
List<string>? excludedTags;
Dictionary<string, string>? requiredKv;
/// <summary>
/// Found items must have at least one of the defined tags
@@ -213,34 +215,34 @@ namespace Steamworks.Ugc
if ( requiredTags != null )
{
foreach ( var tag in requiredTags )
SteamUGC.Internal.AddRequiredTag( handle, tag );
SteamUGC.Internal?.AddRequiredTag( handle, tag );
}
if ( excludedTags != null )
{
foreach ( var tag in excludedTags )
SteamUGC.Internal.AddExcludedTag( handle, tag );
SteamUGC.Internal?.AddExcludedTag( handle, tag );
}
if ( requiredKv != null )
{
foreach ( var tag in requiredKv )
SteamUGC.Internal.AddRequiredKeyValueTag( handle, tag.Key, tag.Value );
SteamUGC.Internal?.AddRequiredKeyValueTag( handle, tag.Key, tag.Value );
}
if ( matchAnyTag.HasValue )
{
SteamUGC.Internal.SetMatchAnyTag( handle, matchAnyTag.Value );
SteamUGC.Internal?.SetMatchAnyTag( handle, matchAnyTag.Value );
}
if ( trendDays.HasValue )
{
SteamUGC.Internal.SetRankedByTrendDays( handle, (uint)trendDays.Value );
SteamUGC.Internal?.SetRankedByTrendDays( handle, (uint)trendDays.Value );
}
if ( !string.IsNullOrEmpty( searchText ) )
{
SteamUGC.Internal.SetSearchText( handle, searchText );
SteamUGC.Internal?.SetSearchText( handle, searchText );
}
}
@@ -271,42 +273,42 @@ namespace Steamworks.Ugc
{
if (WantsReturnOnlyIDs.HasValue)
{
SteamUGC.Internal.SetReturnOnlyIDs(handle, WantsReturnOnlyIDs.Value);
SteamUGC.Internal?.SetReturnOnlyIDs(handle, WantsReturnOnlyIDs.Value);
}
if (WantsReturnKeyValueTags.HasValue)
{
SteamUGC.Internal.SetReturnKeyValueTags(handle, WantsReturnKeyValueTags.Value);
SteamUGC.Internal?.SetReturnKeyValueTags(handle, WantsReturnKeyValueTags.Value);
}
if (WantsReturnLongDescription.HasValue)
{
SteamUGC.Internal.SetReturnLongDescription(handle, WantsReturnLongDescription.Value);
SteamUGC.Internal?.SetReturnLongDescription(handle, WantsReturnLongDescription.Value);
}
if (WantsReturnMetadata.HasValue)
{
SteamUGC.Internal.SetReturnMetadata(handle, WantsReturnMetadata.Value);
SteamUGC.Internal?.SetReturnMetadata(handle, WantsReturnMetadata.Value);
}
if (WantsReturnChildren.HasValue)
{
SteamUGC.Internal.SetReturnChildren(handle, WantsReturnChildren.Value);
SteamUGC.Internal?.SetReturnChildren(handle, WantsReturnChildren.Value);
}
if (WantsReturnAdditionalPreviews.HasValue)
{
SteamUGC.Internal.SetReturnAdditionalPreviews(handle, WantsReturnAdditionalPreviews.Value);
SteamUGC.Internal?.SetReturnAdditionalPreviews(handle, WantsReturnAdditionalPreviews.Value);
}
if (WantsReturnTotalOnly.HasValue)
{
SteamUGC.Internal.SetReturnTotalOnly(handle, WantsReturnTotalOnly.Value);
SteamUGC.Internal?.SetReturnTotalOnly(handle, WantsReturnTotalOnly.Value);
}
if (WantsReturnPlaytimeStats.HasValue)
{
SteamUGC.Internal.SetReturnPlaytimeStats(handle, WantsReturnPlaytimeStats.Value);
SteamUGC.Internal?.SetReturnPlaytimeStats(handle, WantsReturnPlaytimeStats.Value);
}
}

View File

@@ -24,6 +24,7 @@ namespace Steamworks.Ugc
var details = default( SteamUGCDetails_t );
for ( uint i=0; i< ResultCount; i++ )
{
if (SteamUGC.Internal is null) { yield break; }
if ( SteamUGC.Internal.GetQueryUGCResult( Handle, i, ref details ) )
{
var item = Item.From( details );
@@ -86,7 +87,7 @@ namespace Steamworks.Ugc
{
ulong val = 0;
if ( !SteamUGC.Internal.GetQueryUGCStatistic( Handle, index, stat, ref val ) )
if ( SteamUGC.Internal is null || !SteamUGC.Internal.GetQueryUGCStatistic( Handle, index, stat, ref val ) )
return 0;
return val;
@@ -96,7 +97,7 @@ namespace Steamworks.Ugc
{
if ( Handle > 0 )
{
SteamUGC.Internal.ReleaseQueryUGCRequest( Handle );
SteamUGC.Internal?.ReleaseQueryUGCRequest( Handle );
Handle = 0;
}
}

View File

@@ -16,13 +16,13 @@ namespace Steamworks
private static readonly HashSet<SteamMatchmakingRulesResponse> ruleResponseHandlers
= new HashSet<SteamMatchmakingRulesResponse>();
internal static async Task<Dictionary<string, string>> GetRules(Steamworks.Data.ServerInfo server)
internal static async Task<Dictionary<string, string>?> GetRules(Steamworks.Data.ServerInfo server)
{
Status status = Status.Pending;
var rules = new Dictionary<string, string>();
SteamMatchmakingRulesResponse responseHandler = null;
SteamMatchmakingRulesResponse? responseHandler = null;
void onRulesResponded(string key, string value)
=> rules.Add(key, value);
@@ -51,6 +51,8 @@ namespace Steamworks
responseHandler = null;
}
if (SteamMatchmakingServers.Internal is null) { return null; }
responseHandler = new SteamMatchmakingRulesResponse(
onRulesResponded,
onRulesFailToRespond,

View File

@@ -61,9 +61,9 @@ namespace Steamworks
public class SteamSharedClass<T> : SteamClass
{
internal static SteamInterface Interface => InterfaceClient ?? InterfaceServer;
internal static SteamInterface InterfaceClient;
internal static SteamInterface InterfaceServer;
internal static SteamInterface? Interface => InterfaceClient ?? InterfaceServer;
internal static SteamInterface? InterfaceClient;
internal static SteamInterface? InterfaceServer;
internal override void InitializeInterface( bool server )
{
@@ -99,7 +99,7 @@ namespace Steamworks
public class SteamClientClass<T> : SteamClass
{
internal static SteamInterface Interface;
internal static SteamInterface? Interface;
internal override void InitializeInterface( bool server )
{
@@ -122,7 +122,7 @@ namespace Steamworks
public class SteamServerClass<T> : SteamClass
{
internal static SteamInterface Interface;
internal static SteamInterface? Interface;
internal override void InitializeInterface( bool server )
{

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
@@ -48,12 +49,13 @@ namespace Steamworks
internal IntPtr ptr;
#pragma warning restore 649
public unsafe static implicit operator string( Utf8StringPointer p )
[return: NotNullIfNotNull("p")]
public unsafe static implicit operator string?( Utf8StringPointer p )
{
return ConvertPtrToString(p.ptr);
return ConvertPtrToString(p.ptr)!;
}
public unsafe static string ConvertPtrToString(IntPtr ptr)
public unsafe static string? ConvertPtrToString(IntPtr ptr)
{
if (ptr == IntPtr.Zero)
return null;

View File

@@ -10,7 +10,7 @@ namespace Steamworks
{
public static partial class Utility
{
static internal T ToType<T>( this IntPtr ptr )
static internal T? ToType<T>( this IntPtr ptr )
{
if ( ptr == IntPtr.Zero )
return default;
@@ -18,7 +18,7 @@ namespace Steamworks
return (T)Marshal.PtrToStructure( ptr, typeof( T ) );
}
static internal object ToType( this IntPtr ptr, System.Type t )
static internal object? ToType( this IntPtr ptr, System.Type t )
{
if ( ptr == IntPtr.Zero )
return default;