Steamworks.User functions

This commit is contained in:
Garry Newman 2019-04-15 10:24:44 +01:00
parent e7aa122c1f
commit dcd1ea8503
8 changed files with 721 additions and 3 deletions

View File

@ -53,7 +53,6 @@ public void Dispose()
}
/// <summary>
/// Creates an auth ticket.
/// Which you can send to a server to authenticate that you are who you say you are.
/// </summary>
public unsafe Ticket GetAuthSessionTicket()

View File

@ -0,0 +1,389 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using SteamNative;
namespace Steamworks.Internal
{
public class ISteamUser : BaseSteamInterface
{
public override string InterfaceName => "SteamUser020";
public override void InitInternals()
{
GetHSteamUserDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetHSteamUserDelegate>( Marshal.ReadIntPtr( VTable, 0) );
BLoggedOnDelegatePointer = Marshal.GetDelegateForFunctionPointer<BLoggedOnDelegate>( Marshal.ReadIntPtr( VTable, 8) );
GetSteamIDDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetSteamIDDelegate>( Marshal.ReadIntPtr( VTable, 16) );
InitiateGameConnectionDelegatePointer = Marshal.GetDelegateForFunctionPointer<InitiateGameConnectionDelegate>( Marshal.ReadIntPtr( VTable, 24) );
TerminateGameConnectionDelegatePointer = Marshal.GetDelegateForFunctionPointer<TerminateGameConnectionDelegate>( Marshal.ReadIntPtr( VTable, 32) );
TrackAppUsageEventDelegatePointer = Marshal.GetDelegateForFunctionPointer<TrackAppUsageEventDelegate>( Marshal.ReadIntPtr( VTable, 40) );
GetUserDataFolderDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetUserDataFolderDelegate>( Marshal.ReadIntPtr( VTable, 48) );
StartVoiceRecordingDelegatePointer = Marshal.GetDelegateForFunctionPointer<StartVoiceRecordingDelegate>( Marshal.ReadIntPtr( VTable, 56) );
StopVoiceRecordingDelegatePointer = Marshal.GetDelegateForFunctionPointer<StopVoiceRecordingDelegate>( Marshal.ReadIntPtr( VTable, 64) );
GetAvailableVoiceDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetAvailableVoiceDelegate>( Marshal.ReadIntPtr( VTable, 72) );
GetVoiceDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetVoiceDelegate>( Marshal.ReadIntPtr( VTable, 80) );
DecompressVoiceDelegatePointer = Marshal.GetDelegateForFunctionPointer<DecompressVoiceDelegate>( Marshal.ReadIntPtr( VTable, 88) );
GetVoiceOptimalSampleRateDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetVoiceOptimalSampleRateDelegate>( Marshal.ReadIntPtr( VTable, 96) );
GetAuthSessionTicketDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetAuthSessionTicketDelegate>( Marshal.ReadIntPtr( VTable, 104) );
BeginAuthSessionDelegatePointer = Marshal.GetDelegateForFunctionPointer<BeginAuthSessionDelegate>( Marshal.ReadIntPtr( VTable, 112) );
EndAuthSessionDelegatePointer = Marshal.GetDelegateForFunctionPointer<EndAuthSessionDelegate>( Marshal.ReadIntPtr( VTable, 120) );
CancelAuthTicketDelegatePointer = Marshal.GetDelegateForFunctionPointer<CancelAuthTicketDelegate>( Marshal.ReadIntPtr( VTable, 128) );
UserHasLicenseForAppDelegatePointer = Marshal.GetDelegateForFunctionPointer<UserHasLicenseForAppDelegate>( Marshal.ReadIntPtr( VTable, 136) );
BIsBehindNATDelegatePointer = Marshal.GetDelegateForFunctionPointer<BIsBehindNATDelegate>( Marshal.ReadIntPtr( VTable, 144) );
AdvertiseGameDelegatePointer = Marshal.GetDelegateForFunctionPointer<AdvertiseGameDelegate>( Marshal.ReadIntPtr( VTable, 152) );
RequestEncryptedAppTicketDelegatePointer = Marshal.GetDelegateForFunctionPointer<RequestEncryptedAppTicketDelegate>( Marshal.ReadIntPtr( VTable, 160) );
GetEncryptedAppTicketDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetEncryptedAppTicketDelegate>( Marshal.ReadIntPtr( VTable, 168) );
GetGameBadgeLevelDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetGameBadgeLevelDelegate>( Marshal.ReadIntPtr( VTable, 176) );
GetPlayerSteamLevelDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetPlayerSteamLevelDelegate>( Marshal.ReadIntPtr( VTable, 184) );
RequestStoreAuthURLDelegatePointer = Marshal.GetDelegateForFunctionPointer<RequestStoreAuthURLDelegate>( Marshal.ReadIntPtr( VTable, 192) );
BIsPhoneVerifiedDelegatePointer = Marshal.GetDelegateForFunctionPointer<BIsPhoneVerifiedDelegate>( Marshal.ReadIntPtr( VTable, 200) );
BIsTwoFactorEnabledDelegatePointer = Marshal.GetDelegateForFunctionPointer<BIsTwoFactorEnabledDelegate>( Marshal.ReadIntPtr( VTable, 208) );
BIsPhoneIdentifyingDelegatePointer = Marshal.GetDelegateForFunctionPointer<BIsPhoneIdentifyingDelegate>( Marshal.ReadIntPtr( VTable, 216) );
BIsPhoneRequiringVerificationDelegatePointer = Marshal.GetDelegateForFunctionPointer<BIsPhoneRequiringVerificationDelegate>( Marshal.ReadIntPtr( VTable, 224) );
GetMarketEligibilityDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetMarketEligibilityDelegate>( Marshal.ReadIntPtr( VTable, 232) );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate HSteamUser GetHSteamUserDelegate( IntPtr self );
private GetHSteamUserDelegate GetHSteamUserDelegatePointer;
#endregion
public HSteamUser GetHSteamUser()
{
return GetHSteamUserDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool BLoggedOnDelegate( IntPtr self );
private BLoggedOnDelegate BLoggedOnDelegatePointer;
#endregion
public bool BLoggedOn()
{
return BLoggedOnDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void GetSteamIDDelegate( IntPtr self, ref CSteamID retVal );
private GetSteamIDDelegate GetSteamIDDelegatePointer;
#endregion
public CSteamID GetSteamID()
{
var retVal = default( CSteamID );
GetSteamIDDelegatePointer( Self, ref retVal );
return retVal;
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate int InitiateGameConnectionDelegate( IntPtr self, IntPtr pAuthBlob, int cbMaxAuthBlob, CSteamID steamIDGameServer, uint unIPServer, ushort usPortServer, [MarshalAs( UnmanagedType.U1 )] bool bSecure );
private InitiateGameConnectionDelegate InitiateGameConnectionDelegatePointer;
#endregion
public int InitiateGameConnection( IntPtr pAuthBlob, int cbMaxAuthBlob, CSteamID steamIDGameServer, uint unIPServer, ushort usPortServer, [MarshalAs( UnmanagedType.U1 )] bool bSecure )
{
return InitiateGameConnectionDelegatePointer( Self, pAuthBlob, cbMaxAuthBlob, steamIDGameServer, unIPServer, usPortServer, bSecure );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void TerminateGameConnectionDelegate( IntPtr self, uint unIPServer, ushort usPortServer );
private TerminateGameConnectionDelegate TerminateGameConnectionDelegatePointer;
#endregion
public void TerminateGameConnection( uint unIPServer, ushort usPortServer )
{
TerminateGameConnectionDelegatePointer( Self, unIPServer, usPortServer );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void TrackAppUsageEventDelegate( IntPtr self, CGameID gameID, int eAppUsageEvent, string pchExtraInfo );
private TrackAppUsageEventDelegate TrackAppUsageEventDelegatePointer;
#endregion
public void TrackAppUsageEvent( CGameID gameID, int eAppUsageEvent, string pchExtraInfo )
{
TrackAppUsageEventDelegatePointer( Self, gameID, eAppUsageEvent, pchExtraInfo );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool GetUserDataFolderDelegate( IntPtr self, StringBuilder pchBuffer, int cubBuffer );
private GetUserDataFolderDelegate GetUserDataFolderDelegatePointer;
#endregion
public bool GetUserDataFolder( StringBuilder pchBuffer, int cubBuffer )
{
return GetUserDataFolderDelegatePointer( Self, pchBuffer, cubBuffer );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void StartVoiceRecordingDelegate( IntPtr self );
private StartVoiceRecordingDelegate StartVoiceRecordingDelegatePointer;
#endregion
public void StartVoiceRecording()
{
StartVoiceRecordingDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void StopVoiceRecordingDelegate( IntPtr self );
private StopVoiceRecordingDelegate StopVoiceRecordingDelegatePointer;
#endregion
public void StopVoiceRecording()
{
StopVoiceRecordingDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate VoiceResult GetAvailableVoiceDelegate( IntPtr self, ref uint pcbCompressed, ref uint pcbUncompressed_Deprecated, uint nUncompressedVoiceDesiredSampleRate_Deprecated );
private GetAvailableVoiceDelegate GetAvailableVoiceDelegatePointer;
#endregion
public VoiceResult GetAvailableVoice( ref uint pcbCompressed, ref uint pcbUncompressed_Deprecated, uint nUncompressedVoiceDesiredSampleRate_Deprecated )
{
return GetAvailableVoiceDelegatePointer( Self, ref pcbCompressed, ref pcbUncompressed_Deprecated, nUncompressedVoiceDesiredSampleRate_Deprecated );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate VoiceResult GetVoiceDelegate( IntPtr self, [MarshalAs( UnmanagedType.U1 )] bool bWantCompressed, IntPtr pDestBuffer, uint cbDestBufferSize, ref uint nBytesWritten, [MarshalAs( UnmanagedType.U1 )] bool bWantUncompressed_Deprecated, IntPtr pUncompressedDestBuffer_Deprecated, uint cbUncompressedDestBufferSize_Deprecated, ref uint nUncompressBytesWritten_Deprecated, uint nUncompressedVoiceDesiredSampleRate_Deprecated );
private GetVoiceDelegate GetVoiceDelegatePointer;
#endregion
public VoiceResult GetVoice( [MarshalAs( UnmanagedType.U1 )] bool bWantCompressed, IntPtr pDestBuffer, uint cbDestBufferSize, ref uint nBytesWritten, [MarshalAs( UnmanagedType.U1 )] bool bWantUncompressed_Deprecated, IntPtr pUncompressedDestBuffer_Deprecated, uint cbUncompressedDestBufferSize_Deprecated, ref uint nUncompressBytesWritten_Deprecated, uint nUncompressedVoiceDesiredSampleRate_Deprecated )
{
return GetVoiceDelegatePointer( Self, bWantCompressed, pDestBuffer, cbDestBufferSize, ref nBytesWritten, bWantUncompressed_Deprecated, pUncompressedDestBuffer_Deprecated, cbUncompressedDestBufferSize_Deprecated, ref nUncompressBytesWritten_Deprecated, nUncompressedVoiceDesiredSampleRate_Deprecated );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate VoiceResult DecompressVoiceDelegate( IntPtr self, IntPtr pCompressed, uint cbCompressed, IntPtr pDestBuffer, uint cbDestBufferSize, ref uint nBytesWritten, uint nDesiredSampleRate );
private DecompressVoiceDelegate DecompressVoiceDelegatePointer;
#endregion
public VoiceResult DecompressVoice( IntPtr pCompressed, uint cbCompressed, IntPtr pDestBuffer, uint cbDestBufferSize, ref uint nBytesWritten, uint nDesiredSampleRate )
{
return DecompressVoiceDelegatePointer( Self, pCompressed, cbCompressed, pDestBuffer, cbDestBufferSize, ref nBytesWritten, nDesiredSampleRate );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate uint GetVoiceOptimalSampleRateDelegate( IntPtr self );
private GetVoiceOptimalSampleRateDelegate GetVoiceOptimalSampleRateDelegatePointer;
#endregion
public uint GetVoiceOptimalSampleRate()
{
return GetVoiceOptimalSampleRateDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate HAuthTicket GetAuthSessionTicketDelegate( IntPtr self, IntPtr pTicket, int cbMaxTicket, ref uint pcbTicket );
private GetAuthSessionTicketDelegate GetAuthSessionTicketDelegatePointer;
#endregion
public HAuthTicket GetAuthSessionTicket( IntPtr pTicket, int cbMaxTicket, ref uint pcbTicket )
{
return GetAuthSessionTicketDelegatePointer( Self, pTicket, cbMaxTicket, ref pcbTicket );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate BeginAuthSessionResult BeginAuthSessionDelegate( IntPtr self, IntPtr pAuthTicket, int cbAuthTicket, CSteamID steamID );
private BeginAuthSessionDelegate BeginAuthSessionDelegatePointer;
#endregion
public BeginAuthSessionResult BeginAuthSession( IntPtr pAuthTicket, int cbAuthTicket, CSteamID steamID )
{
return BeginAuthSessionDelegatePointer( Self, pAuthTicket, cbAuthTicket, steamID );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void EndAuthSessionDelegate( IntPtr self, CSteamID steamID );
private EndAuthSessionDelegate EndAuthSessionDelegatePointer;
#endregion
public void EndAuthSession( CSteamID steamID )
{
EndAuthSessionDelegatePointer( Self, steamID );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void CancelAuthTicketDelegate( IntPtr self, HAuthTicket hAuthTicket );
private CancelAuthTicketDelegate CancelAuthTicketDelegatePointer;
#endregion
public void CancelAuthTicket( HAuthTicket hAuthTicket )
{
CancelAuthTicketDelegatePointer( Self, hAuthTicket );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate UserHasLicenseForAppResult UserHasLicenseForAppDelegate( IntPtr self, CSteamID steamID, AppId_t appID );
private UserHasLicenseForAppDelegate UserHasLicenseForAppDelegatePointer;
#endregion
public UserHasLicenseForAppResult UserHasLicenseForApp( CSteamID steamID, AppId_t appID )
{
return UserHasLicenseForAppDelegatePointer( Self, steamID, appID );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool BIsBehindNATDelegate( IntPtr self );
private BIsBehindNATDelegate BIsBehindNATDelegatePointer;
#endregion
public bool BIsBehindNAT()
{
return BIsBehindNATDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate void AdvertiseGameDelegate( IntPtr self, CSteamID steamIDGameServer, uint unIPServer, ushort usPortServer );
private AdvertiseGameDelegate AdvertiseGameDelegatePointer;
#endregion
public void AdvertiseGame( CSteamID steamIDGameServer, uint unIPServer, ushort usPortServer )
{
AdvertiseGameDelegatePointer( Self, steamIDGameServer, unIPServer, usPortServer );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate SteamAPICall_t RequestEncryptedAppTicketDelegate( IntPtr self, IntPtr pDataToInclude, int cbDataToInclude );
private RequestEncryptedAppTicketDelegate RequestEncryptedAppTicketDelegatePointer;
#endregion
public async Task<EncryptedAppTicketResponse_t?> RequestEncryptedAppTicket( IntPtr pDataToInclude, int cbDataToInclude )
{
return await (new Result<EncryptedAppTicketResponse_t>( RequestEncryptedAppTicketDelegatePointer( Self, pDataToInclude, cbDataToInclude ) )).GetResult();
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool GetEncryptedAppTicketDelegate( IntPtr self, IntPtr pTicket, int cbMaxTicket, ref uint pcbTicket );
private GetEncryptedAppTicketDelegate GetEncryptedAppTicketDelegatePointer;
#endregion
public bool GetEncryptedAppTicket( IntPtr pTicket, int cbMaxTicket, ref uint pcbTicket )
{
return GetEncryptedAppTicketDelegatePointer( Self, pTicket, cbMaxTicket, ref pcbTicket );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate int GetGameBadgeLevelDelegate( IntPtr self, int nSeries, [MarshalAs( UnmanagedType.U1 )] bool bFoil );
private GetGameBadgeLevelDelegate GetGameBadgeLevelDelegatePointer;
#endregion
public int GetGameBadgeLevel( int nSeries, [MarshalAs( UnmanagedType.U1 )] bool bFoil )
{
return GetGameBadgeLevelDelegatePointer( Self, nSeries, bFoil );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate int GetPlayerSteamLevelDelegate( IntPtr self );
private GetPlayerSteamLevelDelegate GetPlayerSteamLevelDelegatePointer;
#endregion
public int GetPlayerSteamLevel()
{
return GetPlayerSteamLevelDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate SteamAPICall_t RequestStoreAuthURLDelegate( IntPtr self, string pchRedirectURL );
private RequestStoreAuthURLDelegate RequestStoreAuthURLDelegatePointer;
#endregion
public async Task<StoreAuthURLResponse_t?> RequestStoreAuthURL( string pchRedirectURL )
{
return await (new Result<StoreAuthURLResponse_t>( RequestStoreAuthURLDelegatePointer( Self, pchRedirectURL ) )).GetResult();
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool BIsPhoneVerifiedDelegate( IntPtr self );
private BIsPhoneVerifiedDelegate BIsPhoneVerifiedDelegatePointer;
#endregion
public bool BIsPhoneVerified()
{
return BIsPhoneVerifiedDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool BIsTwoFactorEnabledDelegate( IntPtr self );
private BIsTwoFactorEnabledDelegate BIsTwoFactorEnabledDelegatePointer;
#endregion
public bool BIsTwoFactorEnabled()
{
return BIsTwoFactorEnabledDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool BIsPhoneIdentifyingDelegate( IntPtr self );
private BIsPhoneIdentifyingDelegate BIsPhoneIdentifyingDelegatePointer;
#endregion
public bool BIsPhoneIdentifying()
{
return BIsPhoneIdentifyingDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
public delegate bool BIsPhoneRequiringVerificationDelegate( IntPtr self );
private BIsPhoneRequiringVerificationDelegate BIsPhoneRequiringVerificationDelegatePointer;
#endregion
public bool BIsPhoneRequiringVerification()
{
return BIsPhoneRequiringVerificationDelegatePointer( Self );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
public delegate SteamAPICall_t GetMarketEligibilityDelegate( IntPtr self );
private GetMarketEligibilityDelegate GetMarketEligibilityDelegatePointer;
#endregion
public async Task<MarketEligibilityResponse_t?> GetMarketEligibility()
{
return await (new Result<MarketEligibilityResponse_t>( GetMarketEligibilityDelegatePointer( Self ) )).GetResult();
}
}
}

View File

@ -0,0 +1,30 @@
using System;
namespace Steamworks
{
public class AuthTicket : IDisposable
{
public byte[] Data;
public uint Handle;
/// <summary>
/// Cancels a ticket.
/// You should cancel your ticket when you close the game or leave a server.
/// </summary>
public void Cancel()
{
if ( Handle != 0 )
{
User.Internal.CancelAuthTicket( Handle );
}
Handle = 0;
Data = null;
}
public void Dispose()
{
Cancel();
}
}
}

View File

@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using SteamNative;
namespace Steamworks
{
/// <summary>
/// Undocumented Parental Settings
/// </summary>
public static class User
{
static Internal.ISteamUser _internal;
internal static Internal.ISteamUser Internal
{
get
{
if ( _internal == null )
{
_internal = new Internal.ISteamUser();
richPresence = new Dictionary<string, string>();
SampleRate = OptimalSampleRate;
}
return _internal;
}
}
static Dictionary<string, string> richPresence;
internal static void InstallEvents()
{
// new Event<BroadcastUploadStart_t>( x => OnBroadcastStarted?.Invoke() );
// new Event<BroadcastUploadStop_t>( x => OnBroadcastStopped?.Invoke( x.Result ) );
}
// public static event Action OnBroadcastStarted;
/// <summary>
/// Checks if the current user's Steam client is connected to the Steam servers.
/// If it's not then no real-time services provided by the Steamworks API will be enabled. The Steam
/// client will automatically be trying to recreate the connection as often as possible. When the
/// connection is restored a SteamServersConnected_t callback will be posted.
/// You usually don't need to check for this yourself. All of the API calls that rely on this will
/// check internally. Forcefully disabling stuff when the player loses access is usually not a
/// 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 => Internal.BLoggedOn();
/// <summary>
/// Gets the Steam ID of the account currently logged into the Steam client. This is
/// commonly called the 'current user', or 'local user'.
/// 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 CSteamID SteamID => Internal.GetSteamID();
/// <summary>
/// Starts voice recording.
/// Once started, use GetAvailableVoice and GetVoice to get the data, and then call StopVoiceRecording
/// when the user has released their push-to-talk hotkey or the game session has completed.
/// </summary>
public static void StartVoiceRecording() => Internal.StartVoiceRecording();
/// <summary>
/// Stops voice recording.
/// Because people often release push-to-talk keys early, the system will keep recording for a little bit
/// after this function is called.As such, GetVoice should continue to be called until it returns k_EVoiceResultNotRecording,
/// only then will voice recording be stopped.
/// </summary>
public static void StopVoiceRecording() => Internal.StopVoiceRecording();
/// <summary>
/// Returns true if we have voice data waiting to be read
/// </summary>
public static bool HasVoiceData
{
get
{
uint szCompressed = 0, deprecated = 0;
if ( Internal.GetAvailableVoice( ref szCompressed, ref deprecated, 0 ) != VoiceResult.OK )
return false;
return szCompressed > 0;
}
}
static byte[] readBuffer = new byte[1024*128];
/// <summary>
/// Reads the voice data and returns the number of bytes written.
/// The compressed data can be transmitted by your application and decoded back into raw audio data using
/// DecompressVoice on the other side. The compressed data provided is in an arbitrary format and is not meant to be played directly.
/// This should be called once per frame, and at worst no more than four times a second to keep the microphone input delay as low as
/// possible. Calling this any less may result in gaps in the returned stream.
/// </summary>
public static unsafe int ReadVoiceData( System.IO.Stream stream )
{
if ( !HasVoiceData )
return 0;
uint szWritten = 0;
uint deprecated = 0;
fixed ( byte* b = readBuffer )
{
if ( Internal.GetVoice( true, (IntPtr)b, (uint)readBuffer.Length, ref szWritten, false, IntPtr.Zero, 0, ref deprecated, 0 ) != VoiceResult.OK )
return 0;
}
if ( szWritten == 0 )
return 0;
stream.Write( readBuffer, 0, (int) szWritten );
return (int) szWritten;
}
static uint sampleRate = 48000;
public static uint SampleRate
{
get => sampleRate;
set
{
if ( SampleRate < 11025 ) throw new System.Exception( "Sample Rate must be between 11025 and 48000" );
if ( SampleRate > 48000 ) throw new System.Exception( "Sample Rate must be between 11025 and 48000" );
sampleRate = value;
}
}
public static uint OptimalSampleRate => Internal.GetVoiceOptimalSampleRate();
/// <summary>
/// Decodes the compressed voice data returned by GetVoice.
/// The output data is raw single-channel 16-bit PCM audio.The decoder supports any sample rate from 11025 to 48000.
/// </summary>
public static unsafe int DecompressVoice( System.IO.Stream input, int length, System.IO.Stream output )
{
var from = Helpers.TakeBuffer( length );
var to = Helpers.TakeBuffer( 1024 * 64 );
//
// Copy from input stream to a pinnable buffer
//
using ( var s = new System.IO.MemoryStream( from ) )
{
input.CopyTo( s );
}
uint szWritten = 0;
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 )
return 0;
}
if ( szWritten == 0 )
return 0;
//
// Copy to output buffer
//
output.Write( to, 0, (int)szWritten );
return (int)szWritten;
}
/// <summary>
/// Retrieve a authentication ticket to be sent to the entity who wishes to authenticate you.
/// </summary>
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 );
if ( ticket == 0 )
return null;
return new AuthTicket()
{
Data = data.Take( (int)ticketLength ).ToArray(),
Handle = ticket
};
}
}
public static unsafe BeginAuthSessionResult BeginAuthSession( byte[] ticketData, CSteamID steamid )
{
fixed ( byte* ptr = ticketData )
{
return Internal.BeginAuthSession( (IntPtr) ptr, ticketData.Length, steamid );
}
}
public static void EndAuthSession( CSteamID steamid ) => Internal.EndAuthSession( steamid );
// UserHasLicenseForApp - SERVER VERSION ( DLC CHECKING )
/// <summary>
/// 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();
/// <summary>
/// Gets the Steam level of the user, as shown on their Steam community profile.
/// </summary>
public static int SteamLevel => Internal.GetPlayerSteamLevel();
/// <summary>
/// Requests a URL which authenticates an in-game browser for store check-out, and then redirects to the specified URL.
/// As long as the in-game browser accepts and handles session cookies, Steam microtransaction checkout pages will automatically recognize the user instead of presenting a login page.
/// 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 )
{
var response = await Internal.RequestStoreAuthURL( url );
if ( !response.HasValue )
return null;
return response.Value.URL;
}
/// <summary>
/// Checks whether the current user has verified their phone number.
/// </summary>
public static bool IsPhoneVerified => 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();
/// <summary>
/// Checks whether the user's phone number is used to uniquely identify them.
/// </summary>
public static bool IsPhoneIdentifying => Internal.BIsPhoneIdentifying();
/// <summary>
/// Checks whether the current user's phone number is awaiting (re)verification.
/// </summary>
public static bool IsPhoneRequiringVerification => Internal.BIsPhoneRequiringVerification();
}
}

View File

@ -68,5 +68,6 @@ public void EndSession( ulong steamid )
server.native.gameServer.EndAuthSession( steamid );
}
}
}
}

View File

@ -36,5 +36,37 @@ public static StringBuilder TakeStringBuilder()
return StringBuilderPool[StringBuilderPoolIndex];
}
}
private static byte[][] BufferPool;
private static int BufferPoolIndex;
/// <summary>
/// Returns a StringBuilder. This will get returned and reused later on.
/// </summary>
public static byte[] TakeBuffer( int minSize )
{
if ( BufferPool == null )
{
//
// The pool has 8 items.
//
BufferPool = new byte[8][];
for ( int i = 0; i < BufferPool.Length; i++ )
BufferPool[i] = new byte[ 1024 * 128 ];
}
BufferPoolIndex++;
if ( BufferPoolIndex >= BufferPool.Length )
BufferPoolIndex = 0;
if ( BufferPool[BufferPoolIndex].Length < minSize )
{
BufferPool[BufferPoolIndex] = new byte[minSize + 1024];
}
return BufferPool[BufferPoolIndex];
}
}
}

View File

@ -97,6 +97,7 @@ public void ToFolder( string folder )
GenerateVTableClass( "ISteamParentalSettings", $"{folder}../Generated/Interfaces/ISteamParentalSettings.cs" );
GenerateVTableClass( "ISteamMusic", $"{folder}../Generated/Interfaces/ISteamMusic.cs" );
GenerateVTableClass( "ISteamVideo", $"{folder}../Generated/Interfaces/ISteamVideo.cs" );
GenerateVTableClass( "ISteamUser", $"{folder}../Generated/Interfaces/ISteamUser.cs" );
}
}

View File

@ -24,6 +24,7 @@ public static BaseType Parse( string type, string varname = null )
var basicType = type.Trim( ' ', '*' );
if ( basicType == "void" ) return new PointerType { NativeType = type, VarName = varname };
if ( basicType == "const void" ) return new PointerType { NativeType = type, VarName = varname };
if ( basicType == "int32" || basicType == "int" ) return new IntType { NativeType = type, VarName = varname };
if ( basicType == "uint32" ) return new UIntType { NativeType = type, VarName = varname };
if ( basicType == "uint8" ) return new UInt8Type { NativeType = type, VarName = varname };