38f1ddb...178a853: v0.8.9.1, removed content folder
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Facepunch.Steamworks.Interop;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements shared functionality between Steamworks.Client and Steamworks.Server
|
||||
/// </summary>
|
||||
public class BaseSteamworks : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Current running program's AppId
|
||||
/// </summary>
|
||||
public uint AppId { get; internal set; }
|
||||
|
||||
public Networking Networking { get; internal set; }
|
||||
public Inventory Inventory { get; internal set; }
|
||||
public Workshop Workshop { get; internal set; }
|
||||
|
||||
internal event Action OnUpdate;
|
||||
|
||||
internal Interop.NativeInterface native;
|
||||
|
||||
private List<SteamNative.CallbackHandle> CallbackHandles = new List<SteamNative.CallbackHandle>();
|
||||
private List<SteamNative.CallResult> CallResults = new List<SteamNative.CallResult>();
|
||||
protected bool disposed = false;
|
||||
|
||||
|
||||
protected BaseSteamworks( uint appId )
|
||||
{
|
||||
AppId = appId;
|
||||
|
||||
//
|
||||
// No need for the "steam_appid.txt" file any more
|
||||
//
|
||||
System.Environment.SetEnvironmentVariable("SteamAppId", AppId.ToString());
|
||||
System.Environment.SetEnvironmentVariable("SteamGameId", AppId.ToString());
|
||||
}
|
||||
|
||||
~BaseSteamworks()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( disposed ) return;
|
||||
|
||||
Callbacks.Clear();
|
||||
|
||||
foreach ( var h in CallbackHandles )
|
||||
{
|
||||
h.Dispose();
|
||||
}
|
||||
CallbackHandles.Clear();
|
||||
|
||||
foreach ( var h in CallResults )
|
||||
{
|
||||
h.Dispose();
|
||||
}
|
||||
CallResults.Clear();
|
||||
|
||||
if ( Workshop != null )
|
||||
{
|
||||
Workshop.Dispose();
|
||||
Workshop = null;
|
||||
}
|
||||
|
||||
if ( Inventory != null )
|
||||
{
|
||||
Inventory.Dispose();
|
||||
Inventory = null;
|
||||
}
|
||||
|
||||
if ( Networking != null )
|
||||
{
|
||||
Networking.Dispose();
|
||||
Networking = null;
|
||||
}
|
||||
|
||||
if ( native != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
native.Dispose();
|
||||
}
|
||||
catch (DllNotFoundException e)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("Disposing SteamWorks NativeInterface failed (" + e.Message + ")\n" + e.StackTrace);
|
||||
}
|
||||
native = null;
|
||||
}
|
||||
|
||||
System.Environment.SetEnvironmentVariable("SteamAppId", null );
|
||||
System.Environment.SetEnvironmentVariable("SteamGameId", null );
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
protected void SetupCommonInterfaces()
|
||||
{
|
||||
Networking = new Steamworks.Networking( this, native.networking );
|
||||
Inventory = new Steamworks.Inventory( this, native.inventory, IsGameServer );
|
||||
Workshop = new Steamworks.Workshop( this, native.ugc, native.remoteStorage );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this instance has initialized properly.
|
||||
/// If this returns false you should Dispose and throw an error.
|
||||
/// </summary>
|
||||
public bool IsValid
|
||||
{
|
||||
get { return native != null; }
|
||||
}
|
||||
|
||||
|
||||
internal virtual bool IsGameServer { get { return false; } }
|
||||
|
||||
internal void RegisterCallbackHandle( SteamNative.CallbackHandle handle )
|
||||
{
|
||||
CallbackHandles.Add( handle );
|
||||
}
|
||||
|
||||
internal void RegisterCallResult( SteamNative.CallResult handle )
|
||||
{
|
||||
CallResults.Add( handle );
|
||||
}
|
||||
|
||||
internal void UnregisterCallResult( SteamNative.CallResult handle )
|
||||
{
|
||||
CallResults.Remove( handle );
|
||||
}
|
||||
|
||||
public virtual void Update()
|
||||
{
|
||||
Networking.Update();
|
||||
|
||||
RunUpdateCallbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This gets called automatically in Update. Only call it manually if you know why you're doing it.
|
||||
/// </summary>
|
||||
public void RunUpdateCallbacks()
|
||||
{
|
||||
if ( OnUpdate != null )
|
||||
OnUpdate();
|
||||
|
||||
for( int i=0; i < CallResults.Count; i++ )
|
||||
{
|
||||
CallResults[i].Try();
|
||||
}
|
||||
|
||||
//
|
||||
// The SourceServerQuery's happen in another thread, so we
|
||||
// query them to see if they're finished, and if so post a callback
|
||||
// in our main thread. This will all suck less once we have async.
|
||||
//
|
||||
Facepunch.Steamworks.SourceServerQuery.Cycle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run Update until func returns false.
|
||||
/// This will cause your program to lock up until it finishes.
|
||||
/// This is useful for things like tests or command line utilities etc.
|
||||
/// </summary>
|
||||
public void UpdateWhile( Func<bool> func )
|
||||
{
|
||||
const int sleepMs = 1;
|
||||
|
||||
while ( func() )
|
||||
{
|
||||
Update();
|
||||
#if NET_CORE
|
||||
System.Threading.Tasks.Task.Delay( sleepMs ).Wait();
|
||||
#else
|
||||
System.Threading.Thread.Sleep( sleepMs );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debug function, called for every callback. Only really used to confirm that callbacks are working properly.
|
||||
/// </summary>
|
||||
public Action<object> OnAnyCallback;
|
||||
|
||||
Dictionary<Type, List<Action<object>>> Callbacks = new Dictionary<Type, List<Action<object>>>();
|
||||
|
||||
internal List<Action<object>> CallbackList( Type T )
|
||||
{
|
||||
List<Action<object>> list = null;
|
||||
|
||||
if ( !Callbacks.TryGetValue( T, out list ) )
|
||||
{
|
||||
list = new List<Action<object>>();
|
||||
Callbacks[T] = list;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
internal void OnCallback<T>( T data )
|
||||
{
|
||||
var list = CallbackList( typeof( T ) );
|
||||
|
||||
foreach ( var i in list )
|
||||
{
|
||||
i( data );
|
||||
}
|
||||
|
||||
if ( OnAnyCallback != null )
|
||||
{
|
||||
OnAnyCallback.Invoke( data );
|
||||
}
|
||||
}
|
||||
|
||||
internal void RegisterCallback<T>( Action<T> func )
|
||||
{
|
||||
var list = CallbackList( typeof( T ) );
|
||||
list.Add( ( o ) => func( (T) o ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks.Callbacks
|
||||
{
|
||||
public delegate void FailureCallback( Result reason );
|
||||
|
||||
public enum Result : int
|
||||
{
|
||||
OK = 1, // success
|
||||
Fail = 2, // generic failure
|
||||
NoConnection = 3, // no/failed network connection
|
||||
// k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
|
||||
InvalidPassword = 5, // password/ticket is invalid
|
||||
LoggedInElsewhere = 6, // same user logged in elsewhere
|
||||
InvalidProtocolVer = 7, // protocol version is incorrect
|
||||
InvalidParam = 8, // a parameter is incorrect
|
||||
FileNotFound = 9, // file was not found
|
||||
Busy = 10, // called method busy - action not taken
|
||||
InvalidState = 11, // called object was in an invalid state
|
||||
InvalidName = 12, // name is invalid
|
||||
InvalidEmail = 13, // email is invalid
|
||||
DuplicateName = 14, // name is not unique
|
||||
AccessDenied = 15, // access is denied
|
||||
Timeout = 16, // operation timed out
|
||||
Banned = 17, // VAC2 banned
|
||||
AccountNotFound = 18, // account not found
|
||||
InvalidSteamID = 19, // steamID is invalid
|
||||
ServiceUnavailable = 20, // The requested service is currently unavailable
|
||||
NotLoggedOn = 21, // The user is not logged on
|
||||
Pending = 22, // Request is pending (may be in process, or waiting on third party)
|
||||
EncryptionFailure = 23, // Encryption or Decryption failed
|
||||
InsufficientPrivilege = 24, // Insufficient privilege
|
||||
LimitExceeded = 25, // Too much of a good thing
|
||||
Revoked = 26, // Access has been revoked (used for revoked guest passes)
|
||||
Expired = 27, // License/Guest pass the user is trying to access is expired
|
||||
AlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again
|
||||
DuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time
|
||||
AlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user
|
||||
IPNotFound = 31, // IP address not found
|
||||
PersistFailed = 32, // failed to write change to the data store
|
||||
LockingFailed = 33, // failed to acquire access lock for this operation
|
||||
LogonSessionReplaced = 34,
|
||||
ConnectFailed = 35,
|
||||
HandshakeFailed = 36,
|
||||
IOFailure = 37,
|
||||
RemoteDisconnect = 38,
|
||||
ShoppingCartNotFound = 39, // failed to find the shopping cart requested
|
||||
Blocked = 40, // a user didn't allow it
|
||||
Ignored = 41, // target is ignoring sender
|
||||
NoMatch = 42, // nothing matching the request found
|
||||
AccountDisabled = 43,
|
||||
ServiceReadOnly = 44, // this service is not accepting content changes right now
|
||||
AccountNotFeatured = 45, // account doesn't have value, so this feature isn't available
|
||||
AdministratorOK = 46, // allowed to take this action, but only because requester is admin
|
||||
ContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol.
|
||||
TryAnotherCM = 48, // The current CM can't service the user making a request, user should try another.
|
||||
PasswordRequiredToKickSession = 49,// You are already logged in elsewhere, this cached credential login has failed.
|
||||
AlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait
|
||||
Suspended = 51, // Long running operation (content download) suspended/paused
|
||||
Cancelled = 52, // Operation canceled (typically by user: content download)
|
||||
DataCorruption = 53, // Operation canceled because data is ill formed or unrecoverable
|
||||
DiskFull = 54, // Operation canceled - not enough disk space.
|
||||
RemoteCallFailed = 55, // an remote call or IPC call failed
|
||||
PasswordUnset = 56, // Password could not be verified as it's unset server side
|
||||
ExternalAccountUnlinked = 57, // External account (PSN, Facebook...) is not linked to a Steam account
|
||||
PSNTicketInvalid = 58, // PSN ticket was invalid
|
||||
ExternalAccountAlreadyLinked = 59, // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first
|
||||
RemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files
|
||||
IllegalPassword = 61, // The requested new password is not legal
|
||||
SameAsPreviousValue = 62, // new value is the same as the old one ( secret question and answer )
|
||||
AccountLogonDenied = 63, // account login denied due to 2nd factor authentication failure
|
||||
CannotUseOldPassword = 64, // The requested new password is not legal
|
||||
InvalidLoginAuthCode = 65, // account login denied due to auth code invalid
|
||||
AccountLogonDeniedNoMail = 66, // account login denied due to 2nd factor auth failure - and no mail has been sent
|
||||
HardwareNotCapableOfIPT = 67, //
|
||||
IPTInitError = 68, //
|
||||
ParentalControlRestricted = 69, // operation failed due to parental control restrictions for current user
|
||||
FacebookQueryError = 70, // Facebook query returned an error
|
||||
ExpiredLoginAuthCode = 71, // account login denied due to auth code expired
|
||||
IPLoginRestrictionFailed = 72,
|
||||
AccountLockedDown = 73,
|
||||
AccountLogonDeniedVerifiedEmailRequired = 74,
|
||||
NoMatchingURL = 75,
|
||||
BadResponse = 76, // parse failure, missing field, etc.
|
||||
RequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password
|
||||
ValueOutOfRange = 78, // the value entered is outside the acceptable range
|
||||
UnexpectedError = 79, // something happened that we didn't expect to ever happen
|
||||
Disabled = 80, // The requested service has been configured to be unavailable
|
||||
InvalidCEGSubmission = 81, // The set of files submitted to the CEG server are not valid !
|
||||
RestrictedDevice = 82, // The device being used is not allowed to perform this action
|
||||
RegionLocked = 83, // The action could not be complete because it is region restricted
|
||||
RateLimitExceeded = 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent
|
||||
AccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to login
|
||||
ItemDeleted = 86, // The thing we're trying to access has been deleted
|
||||
AccountLoginDeniedThrottle = 87, // login attempt failed, try to throttle response to possible attacker
|
||||
TwoFactorCodeMismatch = 88, // two factor code mismatch
|
||||
TwoFactorActivationCodeMismatch = 89, // activation code for two-factor didn't match
|
||||
AccountAssociatedToMultiplePartners = 90, // account has been associated with multiple partners
|
||||
NotModified = 91, // data not modified
|
||||
NoMobileDevice = 92, // the account does not have a mobile device associated with it
|
||||
TimeNotSynced = 93, // the time presented is out of range or tolerance
|
||||
SmsCodeFailed = 94, // SMS code failure (no match, none pending, etc.)
|
||||
AccountLimitExceeded = 95, // Too many accounts access this resource
|
||||
AccountActivityLimitExceeded = 96, // Too many changes to this account
|
||||
PhoneActivityLimitExceeded = 97, // Too many changes to this phone
|
||||
RefundToWallet = 98, // Cannot refund to payment method, must use wallet
|
||||
EmailSendFailure = 99, // Cannot send an email
|
||||
NotSettled = 100, // Can't perform operation till payment has settled
|
||||
NeedCaptcha = 101, // Needs to provide a valid captcha
|
||||
GSLTDenied = 102, // a game server login token owned by this token's owner has been banned
|
||||
GSOwnerDenied = 103, // game server owner is denied for other reason (account lock, community ban, vac ban, missing phone)
|
||||
InvalidItemType = 104, // the type of thing we were requested to act on is invalid
|
||||
IPBanned = 105, // the ip address has been banned from taking this action
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,307 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Client : BaseSteamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// A singleton accessor to get the current client instance.
|
||||
/// </summary>
|
||||
public static Client Instance { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current user's Username
|
||||
/// </summary>
|
||||
public string Username { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current user's SteamId
|
||||
/// </summary>
|
||||
public ulong SteamId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If we're sharing this game, this is the owner of it.
|
||||
/// </summary>
|
||||
public ulong OwnerSteamId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current Beta name, if we're using a beta branch.
|
||||
/// </summary>
|
||||
public string BetaName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The BuildId of the current build
|
||||
/// </summary>
|
||||
public int BuildId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The folder in which this app is installed
|
||||
/// </summary>
|
||||
public DirectoryInfo InstallFolder { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The currently selected language
|
||||
/// </summary>
|
||||
public string CurrentLanguage { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// List of languages available to the game
|
||||
/// </summary>
|
||||
public string[] AvailableLanguages { get; }
|
||||
|
||||
public Voice Voice { get; private set; }
|
||||
public ServerList ServerList { get; private set; }
|
||||
public LobbyList LobbyList { get; private set; }
|
||||
public App App { get; private set; }
|
||||
public Achievements Achievements { get; private set; }
|
||||
public Stats Stats { get; private set; }
|
||||
public MicroTransactions MicroTransactions { get; private set; }
|
||||
public User User { get; private set; }
|
||||
public RemoteStorage RemoteStorage { get; private set; }
|
||||
public Overlay Overlay { get; private set; }
|
||||
|
||||
public Client( uint appId ) : base( appId )
|
||||
{
|
||||
if ( Instance != null )
|
||||
{
|
||||
throw new System.Exception( "Only one Facepunch.Steamworks.Client can exist - dispose the old one before trying to create a new one." );
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
native = new Interop.NativeInterface();
|
||||
|
||||
//
|
||||
// Get other interfaces
|
||||
//
|
||||
if ( !native.InitClient( this ) )
|
||||
{
|
||||
native.Dispose();
|
||||
native = null;
|
||||
Instance = null;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Register Callbacks
|
||||
//
|
||||
|
||||
SteamNative.Callbacks.RegisterCallbacks( this );
|
||||
|
||||
//
|
||||
// Setup interfaces that client and server both have
|
||||
//
|
||||
SetupCommonInterfaces();
|
||||
|
||||
//
|
||||
// Client only interfaces
|
||||
//
|
||||
Voice = new Voice( this );
|
||||
ServerList = new ServerList( this );
|
||||
LobbyList = new LobbyList(this);
|
||||
App = new App( this );
|
||||
Stats = new Stats( this );
|
||||
Achievements = new Achievements( this );
|
||||
MicroTransactions = new MicroTransactions( this );
|
||||
User = new User( this );
|
||||
RemoteStorage = new RemoteStorage( this );
|
||||
Overlay = new Overlay( this );
|
||||
|
||||
Workshop.friends = Friends;
|
||||
|
||||
Stats.UpdateStats();
|
||||
|
||||
//
|
||||
// Cache common, unchanging info
|
||||
//
|
||||
AppId = appId;
|
||||
Username = native.friends.GetPersonaName();
|
||||
SteamId = native.user.GetSteamID();
|
||||
BetaName = native.apps.GetCurrentBetaName();
|
||||
OwnerSteamId = native.apps.GetAppOwner();
|
||||
var appInstallDir = native.apps.GetAppInstallDir(AppId);
|
||||
|
||||
if (!String.IsNullOrEmpty(appInstallDir) && Directory.Exists(appInstallDir))
|
||||
InstallFolder = new DirectoryInfo(appInstallDir);
|
||||
|
||||
BuildId = native.apps.GetAppBuildId();
|
||||
CurrentLanguage = native.apps.GetCurrentGameLanguage();
|
||||
AvailableLanguages = native.apps.GetAvailableGameLanguages().Split( new[] {';'}, StringSplitOptions.RemoveEmptyEntries ); // TODO: Assumed colon separated
|
||||
|
||||
//
|
||||
// Run update, first call does some initialization
|
||||
//
|
||||
Update();
|
||||
}
|
||||
|
||||
~Client()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be called at least once every frame
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
if ( !IsValid )
|
||||
return;
|
||||
|
||||
RunCallbacks();
|
||||
Voice.Update();
|
||||
Friends.Cycle();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called in Update() - there's no need to call it manually unless you're running your own Update
|
||||
/// </summary>
|
||||
public void RunCallbacks()
|
||||
{
|
||||
native.api.SteamAPI_RunCallbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call when finished to shut down the Steam client.
|
||||
/// </summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
if ( disposed ) return;
|
||||
|
||||
if ( Voice != null )
|
||||
{
|
||||
Voice = null;
|
||||
}
|
||||
|
||||
if ( ServerList != null )
|
||||
{
|
||||
ServerList.Dispose();
|
||||
ServerList = null;
|
||||
}
|
||||
|
||||
if (LobbyList != null)
|
||||
{
|
||||
LobbyList.Dispose();
|
||||
LobbyList = null;
|
||||
}
|
||||
|
||||
if ( App != null )
|
||||
{
|
||||
App.Dispose();
|
||||
App = null;
|
||||
}
|
||||
|
||||
if ( Stats != null )
|
||||
{
|
||||
Stats.Dispose();
|
||||
Stats = null;
|
||||
}
|
||||
|
||||
if ( Achievements != null )
|
||||
{
|
||||
Achievements.Dispose();
|
||||
Achievements = null;
|
||||
}
|
||||
|
||||
if ( MicroTransactions != null )
|
||||
{
|
||||
MicroTransactions.Dispose();
|
||||
MicroTransactions = null;
|
||||
}
|
||||
|
||||
if ( User != null )
|
||||
{
|
||||
User.Dispose();
|
||||
User = null;
|
||||
}
|
||||
|
||||
if ( RemoteStorage != null )
|
||||
{
|
||||
RemoteStorage.Dispose();
|
||||
RemoteStorage = null;
|
||||
}
|
||||
|
||||
if ( Instance == this )
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
public enum LeaderboardSortMethod
|
||||
{
|
||||
None = 0,
|
||||
Ascending = 1, // top-score is lowest number
|
||||
Descending = 2, // top-score is highest number
|
||||
};
|
||||
|
||||
// the display type (used by the Steam Community web site) for a leaderboard
|
||||
public enum LeaderboardDisplayType
|
||||
{
|
||||
None = 0,
|
||||
Numeric = 1, // simple numerical score
|
||||
TimeSeconds = 2, // the score represents a time, in seconds
|
||||
TimeMilliSeconds = 3, // the score represents a time, in milliseconds
|
||||
};
|
||||
|
||||
public Leaderboard GetLeaderboard( string name, LeaderboardSortMethod sortMethod = LeaderboardSortMethod.None, LeaderboardDisplayType displayType = LeaderboardDisplayType.None )
|
||||
{
|
||||
var board = new Leaderboard( this );
|
||||
native.userstats.FindOrCreateLeaderboard( name, (SteamNative.LeaderboardSortMethod)sortMethod, (SteamNative.LeaderboardDisplayType)displayType, board.OnBoardCreated );
|
||||
return board;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current user's Steam client is connected and logged on 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.
|
||||
/// All of the API calls that rely on this will check internally.
|
||||
/// </summary>
|
||||
public bool IsLoggedOn => native.user.BLoggedOn();
|
||||
|
||||
/// <summary>
|
||||
/// True if we're subscribed/authorised to be running this app
|
||||
/// </summary>
|
||||
public bool IsSubscribed => native.apps.BIsSubscribed();
|
||||
|
||||
/// <summary>
|
||||
/// True if we're a cybercafe account
|
||||
/// </summary>
|
||||
public bool IsCybercafe => native.apps.BIsCybercafe();
|
||||
|
||||
/// <summary>
|
||||
/// True if we're subscribed/authorised to be running this app, but only temporarily
|
||||
/// due to a free weekend etc.
|
||||
/// </summary>
|
||||
public bool IsSubscribedFromFreeWeekend => native.apps.BIsSubscribedFromFreeWeekend();
|
||||
|
||||
/// <summary>
|
||||
/// True if we're in low violence mode (germans are only allowed to see the insides of bodies in porn)
|
||||
/// </summary>
|
||||
public bool IsLowViolence => native.apps.BIsLowViolence();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if your executable was launched through Steam and relaunches it through Steam if it wasn't.
|
||||
/// If this returns true then it starts the Steam client if required and launches your game again through it,
|
||||
/// and you should quit your process as soon as possible. This effectively runs steam://run/AppId so it may
|
||||
/// not relaunch the exact executable that called it, as it will always relaunch from the version installed
|
||||
/// in your Steam library folder.
|
||||
/// If it returns false, then your game was launched by the Steam client and no action needs to be taken.
|
||||
/// One exception is if a steam_appid.txt file is present then this will return false regardless. This allows
|
||||
/// you to develop and test without launching your game through the Steam client. Make sure to remove the
|
||||
/// steam_appid.txt file when uploading the game to your Steam depot!
|
||||
/// </summary>
|
||||
public static bool RestartIfNecessary( uint appid )
|
||||
{
|
||||
using ( var api = new SteamNative.SteamApi() )
|
||||
{
|
||||
return api.SteamAPI_RestartAppIfNecessary( appid );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class Achievements : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
public Achievement[] All { get; private set; }
|
||||
|
||||
public event Action OnUpdated;
|
||||
public event Action<Achievement> OnAchievementStateChanged;
|
||||
|
||||
private List<Achievement> unlockedRecently = new List<Achievement>();
|
||||
|
||||
internal Achievements( Client c )
|
||||
{
|
||||
client = c;
|
||||
|
||||
All = new Achievement[0];
|
||||
c.RegisterCallback<UserStatsReceived_t>( UserStatsReceived );
|
||||
c.RegisterCallback<UserStatsStored_t>( UserStatsStored );
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
var old = All;
|
||||
|
||||
All = Enumerable.Range( 0, (int)client.native.userstats.GetNumAchievements() )
|
||||
.Select( x =>
|
||||
{
|
||||
if ( old != null )
|
||||
{
|
||||
var name = client.native.userstats.GetAchievementName( (uint)x );
|
||||
var found = old.FirstOrDefault( y => y.Id == name );
|
||||
if ( found != null )
|
||||
{
|
||||
if ( found.Refresh() )
|
||||
{
|
||||
unlockedRecently.Add( found );
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return new Achievement( client, x );
|
||||
} )
|
||||
.ToArray();
|
||||
|
||||
foreach ( var i in unlockedRecently )
|
||||
{
|
||||
OnUnlocked( i );
|
||||
}
|
||||
|
||||
unlockedRecently.Clear();
|
||||
}
|
||||
|
||||
internal void OnUnlocked( Achievement a )
|
||||
{
|
||||
OnAchievementStateChanged?.Invoke( a );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find an achievement by name. Will be null if not found, or not ready.
|
||||
/// </summary>
|
||||
public Achievement Find( string identifier )
|
||||
{
|
||||
return All.FirstOrDefault( x => x.Id == identifier );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlock an achievement by identifier. If apply is true this will happen as expected
|
||||
/// and the achievement overlay will popup etc. If it's false then you'll have to manually
|
||||
/// call Stats.StoreStats() to actually trigger it.
|
||||
/// </summary>
|
||||
public bool Trigger( string identifier, bool apply = true )
|
||||
{
|
||||
var a = Find( identifier );
|
||||
if ( a == null ) return false;
|
||||
|
||||
return a.Trigger( apply );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset an achievement by identifier
|
||||
/// </summary>
|
||||
public bool Reset( string identifier )
|
||||
{
|
||||
return client.native.userstats.ClearAchievement( identifier );
|
||||
}
|
||||
|
||||
private void UserStatsReceived( UserStatsReceived_t stats )
|
||||
{
|
||||
if ( stats.GameID != client.AppId ) return;
|
||||
|
||||
Refresh();
|
||||
|
||||
OnUpdated?.Invoke();
|
||||
}
|
||||
|
||||
private void UserStatsStored( UserStatsStored_t stats )
|
||||
{
|
||||
if ( stats.GameID != client.AppId ) return;
|
||||
|
||||
Refresh();
|
||||
|
||||
OnUpdated?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public class Achievement
|
||||
{
|
||||
private Client client;
|
||||
|
||||
public string Id { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string Description { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// True if unlocked
|
||||
/// </summary>
|
||||
public bool State { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should hold the unlock time if State is true
|
||||
/// </summary>
|
||||
public DateTime UnlockTime { get; private set; }
|
||||
|
||||
private int iconId { get; set; } = -1;
|
||||
private int refreshCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the percentage of users who have unlocked the specified achievement, or -1 if no data available.
|
||||
/// </summary>
|
||||
public float GlobalUnlockedPercentage
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( State )
|
||||
return 1;
|
||||
|
||||
float pct = 0;
|
||||
|
||||
if ( !client.native.userstats.GetAchievementAchievedPercent( Id, out pct ) )
|
||||
return -1.0f;
|
||||
|
||||
return pct;
|
||||
}
|
||||
}
|
||||
|
||||
private Image _icon;
|
||||
|
||||
public Image Icon
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( iconId <= 0 ) return null;
|
||||
|
||||
if ( _icon == null )
|
||||
{
|
||||
_icon = new Image();
|
||||
_icon.Id = iconId;
|
||||
}
|
||||
|
||||
if ( _icon.IsLoaded )
|
||||
return _icon;
|
||||
|
||||
if ( !_icon.TryLoad( client.native.utils ) )
|
||||
return null;
|
||||
|
||||
return _icon;
|
||||
}
|
||||
}
|
||||
|
||||
public Achievement( Client client, int index )
|
||||
{
|
||||
this.client = client;
|
||||
|
||||
Id = client.native.userstats.GetAchievementName( (uint) index );
|
||||
Name = client.native.userstats.GetAchievementDisplayAttribute( Id, "name" );
|
||||
Description = client.native.userstats.GetAchievementDisplayAttribute( Id, "desc" );
|
||||
|
||||
iconId = client.native.userstats.GetAchievementIcon( Id );
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make this achievement earned
|
||||
/// </summary>
|
||||
public bool Trigger( bool apply = true )
|
||||
{
|
||||
if ( State )
|
||||
return false;
|
||||
|
||||
State = true;
|
||||
UnlockTime = DateTime.Now;
|
||||
|
||||
var r = client.native.userstats.SetAchievement( Id );
|
||||
|
||||
if ( apply )
|
||||
{
|
||||
client.Stats.StoreStats();
|
||||
}
|
||||
|
||||
client.Achievements.OnUnlocked( this );
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset this achievement to not achieved
|
||||
/// </summary>
|
||||
public bool Reset()
|
||||
{
|
||||
State = false;
|
||||
UnlockTime = DateTime.Now;
|
||||
|
||||
return client.native.userstats.ClearAchievement( Id );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh the unlock state. You shouldn't need to call this manually
|
||||
/// but it's here if you have to for some reason. Retuns true if state changed (meaning, probably unlocked)
|
||||
/// </summary>
|
||||
public bool Refresh()
|
||||
{
|
||||
bool previousState = State;
|
||||
|
||||
bool state = false;
|
||||
uint unlockTime;
|
||||
|
||||
State = false;
|
||||
|
||||
if ( client.native.userstats.GetAchievementAndUnlockTime( Id, ref state, out unlockTime ) )
|
||||
{
|
||||
State = state;
|
||||
UnlockTime = Utility.Epoch.ToDateTime( unlockTime );
|
||||
}
|
||||
|
||||
refreshCount++;
|
||||
|
||||
if ( previousState != State && refreshCount > 1 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class App : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
internal App( Client c )
|
||||
{
|
||||
client = c;
|
||||
|
||||
client.RegisterCallback<SteamNative.DlcInstalled_t>( DlcInstalled );
|
||||
}
|
||||
|
||||
public delegate void DlcInstalledDelegate( uint appid );
|
||||
|
||||
/// <summary>
|
||||
/// Triggered after the current user gains ownership of DLC and that DLC is installed.
|
||||
/// </summary>
|
||||
public event DlcInstalledDelegate OnDlcInstalled;
|
||||
|
||||
private void DlcInstalled( DlcInstalled_t data )
|
||||
{
|
||||
if ( OnDlcInstalled != null )
|
||||
{
|
||||
OnDlcInstalled( data.AppID );
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mark the content as corrupt, so it will validate the downloaded files
|
||||
/// once the app is closed. This is good to call when you detect a crash happening
|
||||
/// or a file is missing that is meant to be there.
|
||||
/// </summary>
|
||||
public void MarkContentCorrupt( bool missingFilesOnly = false )
|
||||
{
|
||||
client.native.apps.MarkContentCorrupt( missingFilesOnly );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell steam to install the Dlc specified by the AppId
|
||||
/// </summary>
|
||||
public void InstallDlc( uint appId )
|
||||
{
|
||||
client.native.apps.InstallDLC( appId );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tell steam to uninstall the Dlc specified by the AppId
|
||||
/// </summary>
|
||||
public void UninstallDlc(uint appId)
|
||||
{
|
||||
client.native.apps.UninstallDLC( appId );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the purchase time for this appid. Will return DateTime.MinValue if none.
|
||||
/// </summary>
|
||||
public DateTime PurchaseTime(uint appId)
|
||||
{
|
||||
var time = client.native.apps.GetEarliestPurchaseUnixTime(appId);
|
||||
if ( time == 0 ) return DateTime.MinValue;
|
||||
|
||||
return Utility.Epoch.ToDateTime( time );
|
||||
}
|
||||
|
||||
/// <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 bool IsSubscribed(uint appId)
|
||||
{
|
||||
return client.native.apps.BIsSubscribedApp(appId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if specified app is installed.
|
||||
/// </summary>
|
||||
public bool IsInstalled(uint appId)
|
||||
{
|
||||
return client.native.apps.BIsAppInstalled(appId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if specified app is installed.
|
||||
/// </summary>
|
||||
public bool IsDlcInstalled( uint appId )
|
||||
{
|
||||
return client.native.apps.BIsDlcInstalled( appId );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the appid's name
|
||||
/// Returns error if the current app Id does not have permission to use this interface
|
||||
/// </summary>
|
||||
public string GetName( uint appId )
|
||||
{
|
||||
var str = client.native.applist.GetAppName( appId );
|
||||
if ( str == null ) return "error";
|
||||
return str;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the app's install folder
|
||||
/// Returns error if the current app Id does not have permission to use this interface
|
||||
/// </summary>
|
||||
public string GetInstallFolder( uint appId )
|
||||
{
|
||||
return client.native.applist.GetAppInstallDir( appId );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the app's current build id
|
||||
/// Returns 0 if the current app Id does not have permission to use this interface
|
||||
/// </summary>
|
||||
public int GetBuildId( uint appId )
|
||||
{
|
||||
return client.native.applist.GetAppBuildId( appId );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Client : IDisposable
|
||||
{
|
||||
Auth _auth;
|
||||
|
||||
public Auth Auth
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _auth == null )
|
||||
_auth = new Auth{ client = this };
|
||||
|
||||
return _auth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Auth
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
public class Ticket : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
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 ( client.IsValid && Handle != 0 )
|
||||
{
|
||||
client.native.user.CancelAuthTicket( Handle );
|
||||
Handle = 0;
|
||||
Data = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/// <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()
|
||||
{
|
||||
var data = new byte[1024];
|
||||
|
||||
fixed ( byte* b = data )
|
||||
{
|
||||
uint ticketLength = 0;
|
||||
uint ticket = client.native.user.GetAuthSessionTicket( (IntPtr) b, data.Length, out ticketLength );
|
||||
|
||||
if ( ticket == 0 )
|
||||
return null;
|
||||
|
||||
return new Ticket()
|
||||
{
|
||||
client = client,
|
||||
Data = data.Take( (int)ticketLength ).ToArray(),
|
||||
Handle = ticket
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Client : IDisposable
|
||||
{
|
||||
Friends _friends;
|
||||
|
||||
public Friends Friends
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _friends == null )
|
||||
_friends = new Friends( this );
|
||||
|
||||
return _friends;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles most interactions with people in Steam, not just friends as the name would suggest.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// foreach ( var friend in client.Friends.AllFriends )
|
||||
/// {
|
||||
/// Console.WriteLine( $"{friend.Id}: {friend.Name}" );
|
||||
/// }
|
||||
/// </example>
|
||||
public class Friends
|
||||
{
|
||||
internal Client client;
|
||||
private byte[] buffer = new byte[1024 * 128];
|
||||
|
||||
internal Friends( Client c )
|
||||
{
|
||||
client = c;
|
||||
|
||||
client.RegisterCallback<AvatarImageLoaded_t>( OnAvatarImageLoaded );
|
||||
client.RegisterCallback<PersonaStateChange_t>( OnPersonaStateChange );
|
||||
client.RegisterCallback<GameRichPresenceJoinRequested_t>( OnGameJoinRequested );
|
||||
client.RegisterCallback<GameConnectedFriendChatMsg_t>( OnFriendChatMessage );
|
||||
}
|
||||
|
||||
public delegate void ChatMessageDelegate( SteamFriend friend, string type, string message );
|
||||
|
||||
/// <summary>
|
||||
/// Called when chat message has been received from a friend. You'll need to turn on
|
||||
/// ListenForFriendsMessages to recieve this.
|
||||
/// </summary>
|
||||
public event ChatMessageDelegate OnChatMessage;
|
||||
|
||||
private unsafe void OnFriendChatMessage( GameConnectedFriendChatMsg_t data )
|
||||
{
|
||||
if ( OnChatMessage == null ) return;
|
||||
|
||||
var friend = Get( data.SteamIDUser );
|
||||
var type = ChatEntryType.ChatMsg;
|
||||
fixed ( byte* ptr = buffer )
|
||||
{
|
||||
var len = client.native.friends.GetFriendMessage( data.SteamIDUser, data.MessageID, (IntPtr)ptr, buffer.Length, out type );
|
||||
|
||||
if ( len == 0 && type == ChatEntryType.Invalid )
|
||||
return;
|
||||
|
||||
var typeName = type.ToString();
|
||||
var message = Encoding.UTF8.GetString( buffer, 0, len );
|
||||
|
||||
OnChatMessage( friend, typeName, message );
|
||||
}
|
||||
}
|
||||
|
||||
private bool _listenForFriendsMessages;
|
||||
|
||||
/// <summary>
|
||||
/// Listens for Steam friends chat messages.
|
||||
/// You can then show these chats inline in the game. For example with a Blizzard style chat message system or the chat system in Dota 2.
|
||||
/// After enabling this you will receive callbacks when ever the user receives a chat message.
|
||||
/// </summary>
|
||||
public bool ListenForFriendsMessages
|
||||
{
|
||||
get
|
||||
{
|
||||
return _listenForFriendsMessages;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_listenForFriendsMessages = value;
|
||||
client.native.friends.SetListenForFriendsMessages( value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public delegate void JoinRequestedDelegate( SteamFriend friend, string connect );
|
||||
|
||||
//
|
||||
// Called when a friend has invited you to their game (using InviteToGame)
|
||||
//
|
||||
public event JoinRequestedDelegate OnInvitedToGame;
|
||||
|
||||
|
||||
private void OnGameJoinRequested( GameRichPresenceJoinRequested_t data )
|
||||
{
|
||||
if ( OnInvitedToGame != null )
|
||||
{
|
||||
OnInvitedToGame( Get( data.SteamIDFriend ), data.Connect );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get information about this user - which as name and avatar.
|
||||
/// If returns true, we already have this user's information.
|
||||
/// </summary>
|
||||
public bool UpdateInformation( ulong steamid )
|
||||
{
|
||||
return !client.native.friends.RequestUserInformation( steamid, false );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get this user's name
|
||||
/// </summary>
|
||||
public string GetName( ulong steamid )
|
||||
{
|
||||
client.native.friends.RequestUserInformation( steamid, true );
|
||||
return client.native.friends.GetFriendPersonaName( steamid );
|
||||
}
|
||||
|
||||
private List<SteamFriend> _allFriends;
|
||||
|
||||
/// <summary>
|
||||
/// Returns all friends, even blocked, ignored, friend requests etc
|
||||
/// </summary>
|
||||
public IEnumerable<SteamFriend> All
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _allFriends == null )
|
||||
{
|
||||
_allFriends = new List<SteamFriend>();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
return _allFriends;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only friends
|
||||
/// </summary>
|
||||
public IEnumerable<SteamFriend> AllFriends
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach ( var friend in All )
|
||||
{
|
||||
if ( !friend.IsFriend ) continue;
|
||||
|
||||
yield return friend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all blocked users
|
||||
/// </summary>
|
||||
public IEnumerable<SteamFriend> AllBlocked
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach ( var friend in All )
|
||||
{
|
||||
if ( !friend.IsBlocked ) continue;
|
||||
|
||||
yield return friend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
if ( _allFriends == null )
|
||||
{
|
||||
_allFriends = new List<SteamFriend>();
|
||||
}
|
||||
|
||||
_allFriends.Clear();
|
||||
|
||||
var flags = (int) SteamNative.FriendFlags.All;
|
||||
var count = client.native.friends.GetFriendCount( flags );
|
||||
|
||||
for ( int i=0; i<count; i++ )
|
||||
{
|
||||
var steamid = client.native.friends.GetFriendByIndex( i, flags );
|
||||
_allFriends.Add( Get( steamid ) );
|
||||
}
|
||||
}
|
||||
|
||||
public enum AvatarSize
|
||||
{
|
||||
/// <summary>
|
||||
/// Should be 32x32 - but make sure to check!
|
||||
/// </summary>
|
||||
Small,
|
||||
|
||||
/// <summary>
|
||||
/// Should be 64x64 - but make sure to check!
|
||||
/// </summary>
|
||||
Medium,
|
||||
|
||||
/// <summary>
|
||||
/// Should be 184x184 - but make sure to check!
|
||||
/// </summary>
|
||||
Large
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get the avatar immediately. This should work for people on your friends list.
|
||||
/// </summary>
|
||||
public Image GetCachedAvatar( AvatarSize size, ulong steamid )
|
||||
{
|
||||
var imageid = 0;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case AvatarSize.Small:
|
||||
imageid = client.native.friends.GetSmallFriendAvatar(steamid);
|
||||
break;
|
||||
case AvatarSize.Medium:
|
||||
imageid = client.native.friends.GetMediumFriendAvatar(steamid);
|
||||
break;
|
||||
case AvatarSize.Large:
|
||||
imageid = client.native.friends.GetLargeFriendAvatar(steamid);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( imageid == 1 ) return null; // Placeholder large
|
||||
if ( imageid == 2 ) return null; // Placeholder medium
|
||||
if ( imageid == 3 ) return null; // Placeholder small
|
||||
|
||||
var img = new Image()
|
||||
{
|
||||
Id = imageid
|
||||
};
|
||||
|
||||
if ( !img.TryLoad( client.native.utils ) )
|
||||
return null;
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Callback will be called when the avatar is ready. If we fail to get an
|
||||
/// avatar, might be called with a null Image.
|
||||
/// </summary>
|
||||
public void GetAvatar( AvatarSize size, ulong steamid, Action<Image> callback )
|
||||
{
|
||||
// Maybe we already have it downloaded?
|
||||
var image = GetCachedAvatar(size, steamid);
|
||||
if ( image != null )
|
||||
{
|
||||
callback(image);
|
||||
return;
|
||||
}
|
||||
|
||||
// Lets request it from Steam
|
||||
if (!client.native.friends.RequestUserInformation(steamid, false))
|
||||
{
|
||||
// from docs: false means that we already have all the details about that user, and functions that require this information can be used immediately
|
||||
// but that's probably not true because we just checked the cache
|
||||
|
||||
// check again in case it was just a race
|
||||
image = GetCachedAvatar(size, steamid);
|
||||
if ( image != null )
|
||||
{
|
||||
callback(image);
|
||||
return;
|
||||
}
|
||||
|
||||
// maybe Steam returns false if it was already requested? just add another callback and hope it comes
|
||||
// if not it'll time out anyway
|
||||
}
|
||||
|
||||
PersonaCallbacks.Add( new PersonaCallback
|
||||
{
|
||||
SteamId = steamid,
|
||||
Size = size,
|
||||
Callback = callback,
|
||||
Time = DateTime.Now
|
||||
});
|
||||
}
|
||||
|
||||
private class PersonaCallback
|
||||
{
|
||||
public ulong SteamId;
|
||||
public AvatarSize Size;
|
||||
public Action<Image> Callback;
|
||||
public DateTime Time;
|
||||
}
|
||||
|
||||
List<PersonaCallback> PersonaCallbacks = new List<PersonaCallback>();
|
||||
|
||||
public SteamFriend Get( ulong steamid )
|
||||
{
|
||||
var friend = All.Where( x => x.Id == steamid ).FirstOrDefault();
|
||||
if ( friend != null ) return friend;
|
||||
|
||||
var f = new SteamFriend()
|
||||
{
|
||||
Id = steamid,
|
||||
Client = client
|
||||
};
|
||||
|
||||
f.Refresh();
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
internal void Cycle()
|
||||
{
|
||||
if ( PersonaCallbacks.Count == 0 ) return;
|
||||
|
||||
var timeOut = DateTime.Now.AddSeconds( -10 );
|
||||
|
||||
for ( int i = PersonaCallbacks.Count-1; i >= 0; i-- )
|
||||
{
|
||||
var cb = PersonaCallbacks[i];
|
||||
|
||||
// Timeout
|
||||
if ( cb.Time < timeOut )
|
||||
{
|
||||
if ( cb.Callback != null )
|
||||
{
|
||||
// final attempt, will be null unless the callback was missed somehow
|
||||
var image = GetCachedAvatar( cb.Size, cb.SteamId );
|
||||
|
||||
cb.Callback( image );
|
||||
}
|
||||
|
||||
PersonaCallbacks.Remove( cb );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void OnPersonaStateChange( PersonaStateChange_t data )
|
||||
{
|
||||
// k_EPersonaChangeAvatar
|
||||
if ( (data.ChangeFlags & 0x0040) == 0x0040 )
|
||||
{
|
||||
LoadAvatarForSteamId( data.SteamID );
|
||||
}
|
||||
|
||||
//
|
||||
// Find and refresh this friend's status
|
||||
//
|
||||
foreach ( var friend in All )
|
||||
{
|
||||
if ( friend.Id != data.SteamID ) continue;
|
||||
|
||||
friend.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void LoadAvatarForSteamId( ulong Steamid )
|
||||
{
|
||||
for ( int i = PersonaCallbacks.Count - 1; i >= 0; i-- )
|
||||
{
|
||||
var cb = PersonaCallbacks[i];
|
||||
if ( cb.SteamId != Steamid ) continue;
|
||||
|
||||
var image = GetCachedAvatar( cb.Size, cb.SteamId );
|
||||
if ( image == null ) continue;
|
||||
|
||||
PersonaCallbacks.Remove( cb );
|
||||
|
||||
if ( cb.Callback != null )
|
||||
{
|
||||
cb.Callback( image );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAvatarImageLoaded( AvatarImageLoaded_t data )
|
||||
{
|
||||
LoadAvatarForSteamId( data.SteamID );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class Image
|
||||
{
|
||||
public int Id { get; internal set; }
|
||||
public int Width { get; internal set; }
|
||||
public int Height { get; internal set; }
|
||||
|
||||
public byte[] Data { get; internal set; }
|
||||
|
||||
public bool IsLoaded { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Return true if this image couldn't be loaded for some reason
|
||||
/// </summary>
|
||||
public bool IsError { get; internal set; }
|
||||
|
||||
unsafe internal bool TryLoad( SteamNative.SteamUtils utils )
|
||||
{
|
||||
if ( IsLoaded ) return true;
|
||||
|
||||
uint width = 0, height = 0;
|
||||
|
||||
if ( utils.GetImageSize( Id, out width, out height ) == false )
|
||||
{
|
||||
IsError = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var buffer = new byte[ width * height * 4 ];
|
||||
|
||||
fixed ( byte* ptr = buffer )
|
||||
{
|
||||
if ( utils.GetImageRGBA( Id, (IntPtr) ptr, buffer.Length ) == false )
|
||||
{
|
||||
IsError = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Width = (int) width;
|
||||
Height = (int) height;
|
||||
Data = buffer;
|
||||
IsLoaded = true;
|
||||
IsError = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Color GetPixel( int x, int y )
|
||||
{
|
||||
if ( !IsLoaded ) throw new System.Exception( "Image not loaded" );
|
||||
if ( x < 0 || x >= Width ) throw new System.Exception( "x out of bounds" );
|
||||
if ( y < 0 || y >= Height ) throw new System.Exception( "y out of bounds" );
|
||||
|
||||
Color c = new Color();
|
||||
|
||||
var i = ( y * Width + x ) * 4;
|
||||
|
||||
c.r = Data[i + 0];
|
||||
c.g = Data[i + 1];
|
||||
c.b = Data[i + 2];
|
||||
c.a = Data[i + 3];
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Color
|
||||
{
|
||||
public byte r, g, b, a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Facepunch.Steamworks.Callbacks;
|
||||
using SteamNative;
|
||||
using Result = SteamNative.Result;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class Leaderboard : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of leaderboard request
|
||||
/// </summary>
|
||||
public enum RequestType
|
||||
{
|
||||
/// <summary>
|
||||
/// Query everyone and everything
|
||||
/// </summary>
|
||||
Global = LeaderboardDataRequest.Global,
|
||||
|
||||
/// <summary>
|
||||
/// Query entries near to this user's rank
|
||||
/// </summary>
|
||||
GlobalAroundUser = LeaderboardDataRequest.GlobalAroundUser,
|
||||
|
||||
/// <summary>
|
||||
/// Only show friends of this user
|
||||
/// </summary>
|
||||
Friends = LeaderboardDataRequest.Friends
|
||||
}
|
||||
|
||||
private static readonly int[] subEntriesBuffer = new int[512];
|
||||
|
||||
internal ulong BoardId;
|
||||
public ulong GetBoardId()
|
||||
{
|
||||
return BoardId;
|
||||
}
|
||||
internal Client client;
|
||||
|
||||
private readonly Queue<Action> _onCreated = new Queue<Action>();
|
||||
|
||||
/// <summary>
|
||||
/// The results from the last query. Can be null.
|
||||
/// </summary>
|
||||
public Entry[] Results;
|
||||
|
||||
internal Leaderboard( Client c )
|
||||
{
|
||||
client = c;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of this board, as retrieved from Steam
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The total number of entries on this board
|
||||
/// </summary>
|
||||
public int TotalEntries { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this board is valid, ie, we've received
|
||||
/// a positive response from Steam about it.
|
||||
/// </summary>
|
||||
public bool IsValid => BoardId != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if we asked steam about this board but it returned
|
||||
/// an error.
|
||||
/// </summary>
|
||||
public bool IsError { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if we're querying scores
|
||||
/// </summary>
|
||||
public bool IsQuerying { get; private set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
private void DispatchOnCreatedCallbacks()
|
||||
{
|
||||
while ( _onCreated.Count > 0 )
|
||||
{
|
||||
_onCreated.Dequeue()();
|
||||
}
|
||||
}
|
||||
|
||||
private bool DeferOnCreated( Action onValid, FailureCallback onFailure = null )
|
||||
{
|
||||
if ( IsValid || IsError ) return false;
|
||||
|
||||
_onCreated.Enqueue( () =>
|
||||
{
|
||||
if ( IsValid ) onValid();
|
||||
else onFailure?.Invoke( Callbacks.Result.Fail );
|
||||
} );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the leaderboard information is successfully recieved from Steam
|
||||
/// </summary>
|
||||
public Action OnBoardInformation;
|
||||
|
||||
internal void OnBoardCreated( LeaderboardFindResult_t result, bool error )
|
||||
{
|
||||
Console.WriteLine( $"result.LeaderboardFound: {result.LeaderboardFound}" );
|
||||
Console.WriteLine( $"result.SteamLeaderboard: {result.SteamLeaderboard}" );
|
||||
|
||||
if ( error || ( result.LeaderboardFound == 0 ) )
|
||||
{
|
||||
IsError = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
BoardId = result.SteamLeaderboard;
|
||||
|
||||
if ( IsValid )
|
||||
{
|
||||
Name = client.native.userstats.GetLeaderboardName( BoardId );
|
||||
TotalEntries = client.native.userstats.GetLeaderboardEntryCount( BoardId );
|
||||
|
||||
OnBoardInformation?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
DispatchOnCreatedCallbacks();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a score to this leaderboard.
|
||||
/// Subscores are totally optional, and can be used for other game defined data such as laps etc.. although
|
||||
/// they have no bearing on sorting at all
|
||||
/// If onlyIfBeatsOldScore is true, the score will only be updated if it beats the existing score, else it will always
|
||||
/// be updated. Beating the existing score is subjective - and depends on how your leaderboard was set up as to whether
|
||||
/// that means higher or lower.
|
||||
/// </summary>
|
||||
public bool AddScore( bool onlyIfBeatsOldScore, int score, params int[] subscores )
|
||||
{
|
||||
if ( IsError ) return false;
|
||||
if ( !IsValid ) return DeferOnCreated( () => AddScore( onlyIfBeatsOldScore, score, subscores ) );
|
||||
|
||||
var flags = LeaderboardUploadScoreMethod.ForceUpdate;
|
||||
if ( onlyIfBeatsOldScore ) flags = LeaderboardUploadScoreMethod.KeepBest;
|
||||
|
||||
client.native.userstats.UploadLeaderboardScore( BoardId, flags, score, subscores, subscores.Length );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback invoked by <see cref="AddScore(bool, int, int[], AddScoreCallback, FailureCallback)"/> when score submission
|
||||
/// is complete.
|
||||
/// </summary>
|
||||
/// <param name="result">If successful, information about the new entry</param>
|
||||
public delegate void AddScoreCallback( AddScoreResult result );
|
||||
|
||||
/// <summary>
|
||||
/// Information about a newly submitted score.
|
||||
/// </summary>
|
||||
public struct AddScoreResult
|
||||
{
|
||||
public int Score;
|
||||
public bool ScoreChanged;
|
||||
public int GlobalRankNew;
|
||||
public int GlobalRankPrevious;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a score to this leaderboard.
|
||||
/// Subscores are totally optional, and can be used for other game defined data such as laps etc.. although
|
||||
/// they have no bearing on sorting at all
|
||||
/// If onlyIfBeatsOldScore is true, the score will only be updated if it beats the existing score, else it will always
|
||||
/// be updated.
|
||||
/// Information about the newly submitted score is passed to the optional <paramref name="onSuccess"/>.
|
||||
/// </summary>
|
||||
public bool AddScore( bool onlyIfBeatsOldScore, int score, int[] subscores = null, AddScoreCallback onSuccess = null, FailureCallback onFailure = null )
|
||||
{
|
||||
if ( IsError ) return false;
|
||||
if ( !IsValid ) return DeferOnCreated( () => AddScore( onlyIfBeatsOldScore, score, subscores, onSuccess, onFailure ), onFailure );
|
||||
|
||||
if ( subscores == null ) subscores = new int[0];
|
||||
|
||||
var flags = LeaderboardUploadScoreMethod.ForceUpdate;
|
||||
if ( onlyIfBeatsOldScore ) flags = LeaderboardUploadScoreMethod.KeepBest;
|
||||
|
||||
client.native.userstats.UploadLeaderboardScore( BoardId, flags, score, subscores, subscores.Length, ( result, error ) =>
|
||||
{
|
||||
if ( !error && result.Success != 0 )
|
||||
{
|
||||
onSuccess?.Invoke( new AddScoreResult
|
||||
{
|
||||
Score = result.Score,
|
||||
ScoreChanged = result.ScoreChanged != 0,
|
||||
GlobalRankNew = result.GlobalRankNew,
|
||||
GlobalRankPrevious = result.GlobalRankPrevious
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
onFailure?.Invoke( error ? Callbacks.Result.IOFailure : Callbacks.Result.Fail );
|
||||
}
|
||||
} );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback invoked by <see cref="Leaderboard.AttachRemoteFile"/> when file attachment is complete.
|
||||
/// </summary>
|
||||
public delegate void AttachRemoteFileCallback();
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to attach a <see cref="RemoteStorage"/> file to the current user's leaderboard entry.
|
||||
/// Can be useful for storing replays along with scores.
|
||||
/// </summary>
|
||||
/// <returns>True if the file attachment process has started</returns>
|
||||
public bool AttachRemoteFile( RemoteFile file, AttachRemoteFileCallback onSuccess = null, FailureCallback onFailure = null )
|
||||
{
|
||||
if ( IsError ) return false;
|
||||
if ( !IsValid ) return DeferOnCreated( () => AttachRemoteFile( file, onSuccess, onFailure ), onFailure );
|
||||
|
||||
if ( file.IsShared )
|
||||
{
|
||||
var handle = client.native.userstats.AttachLeaderboardUGC( BoardId, file.UGCHandle, ( result, error ) =>
|
||||
{
|
||||
if ( !error && result.Result == Result.OK )
|
||||
{
|
||||
onSuccess?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
onFailure?.Invoke( result.Result == 0 ? Callbacks.Result.IOFailure : (Callbacks.Result) result.Result );
|
||||
}
|
||||
} );
|
||||
|
||||
return handle.IsValid;
|
||||
}
|
||||
|
||||
file.Share( () =>
|
||||
{
|
||||
if ( !file.IsShared || !AttachRemoteFile( file, onSuccess, onFailure ) )
|
||||
{
|
||||
onFailure?.Invoke( Callbacks.Result.Fail );
|
||||
}
|
||||
}, onFailure );
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetch a subset of scores. The scores end up in Results.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if we have started the query</returns>
|
||||
public bool FetchScores( RequestType RequestType, int start, int end )
|
||||
{
|
||||
if ( !IsValid ) return false;
|
||||
if ( IsQuerying ) return false;
|
||||
|
||||
client.native.userstats.DownloadLeaderboardEntries( BoardId, (LeaderboardDataRequest) RequestType, start, end, OnScores );
|
||||
|
||||
Results = null;
|
||||
IsQuerying = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private unsafe void ReadScores( LeaderboardScoresDownloaded_t result, List<Entry> dest )
|
||||
{
|
||||
for ( var i = 0; i < result.CEntryCount; i++ )
|
||||
fixed ( int* ptr = subEntriesBuffer )
|
||||
{
|
||||
var entry = new LeaderboardEntry_t();
|
||||
if ( client.native.userstats.GetDownloadedLeaderboardEntry( result.SteamLeaderboardEntries, i, ref entry, (IntPtr) ptr, subEntriesBuffer.Length ) )
|
||||
dest.Add( new Entry
|
||||
{
|
||||
GlobalRank = entry.GlobalRank,
|
||||
Score = entry.Score,
|
||||
SteamId = entry.SteamIDUser,
|
||||
SubScores = entry.CDetails == 0 ? null : subEntriesBuffer.Take( entry.CDetails ).ToArray(),
|
||||
Name = client.Friends.GetName( entry.SteamIDUser ),
|
||||
AttachedFile = (entry.UGC >> 32) == 0xffffffff ? null : new RemoteFile( client.RemoteStorage, entry.UGC )
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
[ThreadStatic] private static List<Entry> _sEntryBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Callback invoked by <see cref="FetchScores(RequestType, int, int, FetchScoresCallback, FailureCallback)"/> when
|
||||
/// a query is complete.
|
||||
/// </summary>
|
||||
public delegate void FetchScoresCallback( Entry[] results );
|
||||
|
||||
/// <summary>
|
||||
/// Fetch a subset of scores. The scores are passed to <paramref name="onSuccess"/>.
|
||||
/// </summary>
|
||||
/// <returns>Returns true if we have started the query</returns>
|
||||
public bool FetchScores( RequestType RequestType, int start, int end, FetchScoresCallback onSuccess, FailureCallback onFailure = null )
|
||||
{
|
||||
if ( IsError ) return false;
|
||||
if ( !IsValid ) return DeferOnCreated( () => FetchScores( RequestType, start, end, onSuccess, onFailure ), onFailure );
|
||||
|
||||
client.native.userstats.DownloadLeaderboardEntries( BoardId, (LeaderboardDataRequest) RequestType, start, end, ( result, error ) =>
|
||||
{
|
||||
if ( error )
|
||||
{
|
||||
onFailure?.Invoke( Callbacks.Result.IOFailure );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( _sEntryBuffer == null ) _sEntryBuffer = new List<Entry>();
|
||||
else _sEntryBuffer.Clear();
|
||||
|
||||
ReadScores( result, _sEntryBuffer );
|
||||
onSuccess( _sEntryBuffer.ToArray() );
|
||||
}
|
||||
} );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public unsafe bool FetchUsersScores( RequestType RequestType, UInt64[] steamIds, FetchScoresCallback onSuccess, FailureCallback onFailure = null )
|
||||
{
|
||||
|
||||
if ( IsError ) return false;
|
||||
if ( !IsValid ) return DeferOnCreated( () => FetchUsersScores( RequestType, steamIds, onSuccess, onFailure ), onFailure );
|
||||
|
||||
fixed(ulong* pointer = steamIds){
|
||||
|
||||
client.native.userstats.DownloadLeaderboardEntriesForUsers(BoardId, (IntPtr)pointer, steamIds.Length, (result, error) =>
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
onFailure?.Invoke(Callbacks.Result.IOFailure);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_sEntryBuffer == null) _sEntryBuffer = new List<Entry>();
|
||||
else _sEntryBuffer.Clear();
|
||||
|
||||
ReadScores(result, _sEntryBuffer);
|
||||
onSuccess(_sEntryBuffer.ToArray());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void OnScores( LeaderboardScoresDownloaded_t result, bool error )
|
||||
{
|
||||
IsQuerying = false;
|
||||
|
||||
if ( client == null ) return;
|
||||
if ( error ) return;
|
||||
|
||||
var list = new List<Entry>();
|
||||
ReadScores( result, list );
|
||||
|
||||
Results = list.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A single entry in a leaderboard
|
||||
/// </summary>
|
||||
public struct Entry
|
||||
{
|
||||
public ulong SteamId;
|
||||
public int Score;
|
||||
public int[] SubScores;
|
||||
public int GlobalRank;
|
||||
public RemoteFile AttachedFile;
|
||||
|
||||
/// <summary>
|
||||
/// Note that the player's name might not be immediately available.
|
||||
/// If that's the case you'll have to use Friends.GetName to find the name
|
||||
/// </summary>
|
||||
public string Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Lobby
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to hold global lobby data. This is stuff like maps/modes/etc. Data set here can be filtered by LobbyList.
|
||||
/// </summary>
|
||||
public class LobbyData
|
||||
{
|
||||
internal Client client;
|
||||
internal ulong lobby;
|
||||
internal Dictionary<string, string> data;
|
||||
|
||||
public LobbyData( Client c, ulong l )
|
||||
{
|
||||
client = c;
|
||||
lobby = l;
|
||||
data = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the lobby value for the specific key
|
||||
/// </summary>
|
||||
/// <param name="k">The key to find</param>
|
||||
/// <returns>The value at key</returns>
|
||||
public string GetData( string k )
|
||||
{
|
||||
if ( data.ContainsKey( k ) )
|
||||
{
|
||||
return data[k];
|
||||
}
|
||||
|
||||
return "ERROR: key not found";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all the data in the Lobby
|
||||
/// </summary>
|
||||
/// <returns>Dictionary of all the key/value pairs in the data</returns>
|
||||
public Dictionary<string, string> GetAllData()
|
||||
{
|
||||
Dictionary<string, string> returnData = new Dictionary<string, string>();
|
||||
foreach ( KeyValuePair<string, string> item in data )
|
||||
{
|
||||
returnData.Add( item.Key, item.Value );
|
||||
}
|
||||
return returnData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the value for specified Key. Note that the keys "joinable", "appid", "name", and "lobbytype" are reserved for internal library use.
|
||||
/// </summary>
|
||||
/// <param name="k">The key to set the value for</param>
|
||||
/// <param name="v">The value of the Key</param>
|
||||
/// <returns>True if data successfully set</returns>
|
||||
public bool SetData( string k, string v )
|
||||
{
|
||||
if ( data.ContainsKey( k ) )
|
||||
{
|
||||
if ( data[k] == v ) { return true; }
|
||||
if ( client.native.matchmaking.SetLobbyData( lobby, k, v ) )
|
||||
{
|
||||
data[k] = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( client.native.matchmaking.SetLobbyData( lobby, k, v ) )
|
||||
{
|
||||
data.Add( k, v );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove the key from the LobbyData. Note that the keys "joinable", "appid", "name", and "lobbytype" are reserved for internal library use.
|
||||
/// </summary>
|
||||
/// <param name="k">The key to remove</param>
|
||||
/// <returns>True if Key successfully removed</returns>
|
||||
public bool RemoveData( string k )
|
||||
{
|
||||
if ( data.ContainsKey( k ) )
|
||||
{
|
||||
if ( client.native.matchmaking.DeleteLobbyData( lobby, k ) )
|
||||
{
|
||||
data.Remove( k );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*not implemented
|
||||
|
||||
//set the game server of the lobby
|
||||
client.native.matchmaking.GetLobbyGameServer;
|
||||
client.native.matchmaking.SetLobbyGameServer;
|
||||
|
||||
//used with game server stuff
|
||||
SteamNative.LobbyGameCreated_t
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,599 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Client : IDisposable
|
||||
{
|
||||
Lobby _lobby;
|
||||
|
||||
public Lobby Lobby
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _lobby == null )
|
||||
_lobby = new Steamworks.Lobby( this );
|
||||
return _lobby;
|
||||
}
|
||||
}
|
||||
}
|
||||
public partial class Lobby : IDisposable
|
||||
{
|
||||
//The type of lobby you are creating
|
||||
public enum Type : int
|
||||
{
|
||||
Private = SteamNative.LobbyType.Private,
|
||||
FriendsOnly = SteamNative.LobbyType.FriendsOnly,
|
||||
Public = SteamNative.LobbyType.Public,
|
||||
Invisible = SteamNative.LobbyType.Invisible,
|
||||
Error //happens if you try to get this when you aren't in a valid lobby
|
||||
}
|
||||
|
||||
internal Client client;
|
||||
|
||||
public Lobby( Client c )
|
||||
{
|
||||
client = c;
|
||||
|
||||
// For backwards compatibility
|
||||
OnLobbyJoinRequested = Join;
|
||||
|
||||
client.RegisterCallback<SteamNative.LobbyDataUpdate_t>( OnLobbyDataUpdatedAPI );
|
||||
client.RegisterCallback<SteamNative.LobbyChatMsg_t>( OnLobbyChatMessageRecievedAPI );
|
||||
client.RegisterCallback<SteamNative.LobbyChatUpdate_t>( OnLobbyStateUpdatedAPI );
|
||||
client.RegisterCallback<SteamNative.GameLobbyJoinRequested_t>( OnLobbyJoinRequestedAPI );
|
||||
client.RegisterCallback<SteamNative.LobbyInvite_t>( OnUserInvitedToLobbyAPI );
|
||||
client.RegisterCallback<SteamNative.PersonaStateChange_t>( OnLobbyMemberPersonaChangeAPI );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The CSteamID of the lobby we're currently in.
|
||||
/// </summary>
|
||||
public ulong CurrentLobby { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The LobbyData of the CurrentLobby. Note this is the global data for the lobby. Use SetMemberData to set specific member data.
|
||||
/// </summary>
|
||||
public LobbyData CurrentLobbyData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this lobby is valid, ie, we've succesffuly created and/or joined a lobby.
|
||||
/// </summary>
|
||||
public bool IsValid => CurrentLobby != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Join a Lobby through its LobbyID. OnLobbyJoined is called with the result of the Join attempt.
|
||||
/// </summary>
|
||||
/// <param name="lobbyID">CSteamID of lobby to join</param>
|
||||
public void Join( ulong lobbyID )
|
||||
{
|
||||
Leave();
|
||||
client.native.matchmaking.JoinLobby( lobbyID, OnLobbyJoinedAPI );
|
||||
}
|
||||
|
||||
void OnLobbyJoinedAPI( LobbyEnter_t callback, bool error )
|
||||
{
|
||||
if ( error || (callback.EChatRoomEnterResponse != (uint)(SteamNative.ChatRoomEnterResponse.Success)) )
|
||||
{
|
||||
if ( OnLobbyJoined != null ) { OnLobbyJoined( false ); }
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentLobby = callback.SteamIDLobby;
|
||||
UpdateLobbyData();
|
||||
if ( OnLobbyJoined != null ) { OnLobbyJoined( true ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a lobby has been attempted joined. Returns true if lobby was successfuly joined, false if not.
|
||||
/// </summary>
|
||||
public Action<bool> OnLobbyJoined;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a lobby and returns the created lobby. You auto join the created lobby. The lobby is stored in Client.Lobby.CurrentLobby if successful.
|
||||
/// </summary>
|
||||
/// <param name="lobbyType">The Lobby.Type of Lobby to be created</param>
|
||||
/// <param name="maxMembers">The maximum amount of people you want to be able to be in this lobby, including yourself</param>
|
||||
public void Create( Lobby.Type lobbyType, int maxMembers )
|
||||
{
|
||||
client.native.matchmaking.CreateLobby( (SteamNative.LobbyType)lobbyType, maxMembers, OnLobbyCreatedAPI );
|
||||
createdLobbyType = lobbyType;
|
||||
}
|
||||
|
||||
internal Type createdLobbyType;
|
||||
|
||||
internal void OnLobbyCreatedAPI( LobbyCreated_t callback, bool error )
|
||||
{
|
||||
//from SpaceWarClient.cpp 793
|
||||
if ( error || (callback.Result != Result.OK) )
|
||||
{
|
||||
if ( OnLobbyCreated != null ) { OnLobbyCreated( false ); }
|
||||
return;
|
||||
}
|
||||
|
||||
//set owner specific properties
|
||||
Owner = client.SteamId;
|
||||
CurrentLobby = callback.SteamIDLobby;
|
||||
CurrentLobbyData = new LobbyData( client, CurrentLobby );
|
||||
Name = client.Username + "'s Lobby";
|
||||
CurrentLobbyData.SetData( "appid", client.AppId.ToString() );
|
||||
LobbyType = createdLobbyType;
|
||||
CurrentLobbyData.SetData( "lobbytype", LobbyType.ToString() );
|
||||
Joinable = true;
|
||||
if ( OnLobbyCreated != null ) { OnLobbyCreated( true ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback for when lobby is created. Parameter resolves true when the Lobby was successfully created
|
||||
/// </summary>
|
||||
public Action<bool> OnLobbyCreated;
|
||||
|
||||
/// <summary>
|
||||
/// Sets user data for the Lobby. Things like Character, Skin, Ready, etc. Can only set your own member data
|
||||
/// </summary>
|
||||
public void SetMemberData( string key, string value )
|
||||
{
|
||||
if ( CurrentLobby == 0 ) { return; }
|
||||
client.native.matchmaking.SetLobbyMemberData( CurrentLobby, key, value );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the per-user metadata from this lobby. Can get data from any user
|
||||
/// </summary>
|
||||
/// <param name="steamID">ulong SteamID of the user you want to get data from</param>
|
||||
/// <param name="key">String key of the type of data you want to get</param>
|
||||
/// <returns></returns>
|
||||
public string GetMemberData( ulong steamID, string key )
|
||||
{
|
||||
if ( CurrentLobby == 0 ) { return "ERROR: NOT IN ANY LOBBY"; }
|
||||
return client.native.matchmaking.GetLobbyMemberData( CurrentLobby, steamID, key );
|
||||
}
|
||||
|
||||
internal void OnLobbyDataUpdatedAPI( LobbyDataUpdate_t callback )
|
||||
{
|
||||
if ( callback.SteamIDLobby != CurrentLobby ) return;
|
||||
|
||||
if ( callback.SteamIDLobby == CurrentLobby ) //actual lobby data was updated by owner
|
||||
{
|
||||
UpdateLobbyData();
|
||||
}
|
||||
|
||||
if ( UserIsInCurrentLobby( callback.SteamIDMember ) ) //some member of this lobby updated their information
|
||||
{
|
||||
if ( OnLobbyMemberDataUpdated != null ) { OnLobbyMemberDataUpdated( callback.SteamIDMember ); }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the LobbyData property to have the data for the current lobby, if any
|
||||
/// </summary>
|
||||
internal void UpdateLobbyData()
|
||||
{
|
||||
int dataCount = client.native.matchmaking.GetLobbyDataCount( CurrentLobby );
|
||||
CurrentLobbyData = new LobbyData( client, CurrentLobby );
|
||||
for ( int i = 0; i < dataCount; i++ )
|
||||
{
|
||||
if ( client.native.matchmaking.GetLobbyDataByIndex( CurrentLobby, i, out string key, out string value ) )
|
||||
{
|
||||
CurrentLobbyData.SetData( key, value );
|
||||
}
|
||||
}
|
||||
|
||||
if ( OnLobbyDataUpdated != null ) { OnLobbyDataUpdated(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the lobby data itself has been updated. Called when someone has joined/left, Owner has updated data, etc.
|
||||
/// </summary>
|
||||
public Action OnLobbyDataUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Called when a member of the lobby has updated either their personal Lobby metadata or someone's global steam state has changed (like a display name). Parameter is the user who changed.
|
||||
/// </summary>
|
||||
public Action<ulong> OnLobbyMemberDataUpdated;
|
||||
|
||||
|
||||
public Type LobbyType
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( !IsValid ) { return Type.Error; } //if we're currently in a valid server
|
||||
|
||||
//we know that we've set the lobby type via the lobbydata in the creation function
|
||||
//ps this is important because steam doesn't have an easy way to get lobby type (why idk)
|
||||
string lobbyType = CurrentLobbyData.GetData( "lobbytype" );
|
||||
switch ( lobbyType )
|
||||
{
|
||||
case "Private":
|
||||
return Type.Private;
|
||||
case "FriendsOnly":
|
||||
return Type.FriendsOnly;
|
||||
case "Invisible":
|
||||
return Type.Invisible;
|
||||
case "Public":
|
||||
return Type.Public;
|
||||
default:
|
||||
return Type.Error;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if ( !IsValid ) { return; }
|
||||
if ( client.native.matchmaking.SetLobbyType( CurrentLobby, (SteamNative.LobbyType)value ) )
|
||||
{
|
||||
CurrentLobbyData.SetData( "lobbytype", value.ToString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] chatMessageData = new byte[1024 * 4];
|
||||
|
||||
private unsafe void OnLobbyChatMessageRecievedAPI( LobbyChatMsg_t callback )
|
||||
{
|
||||
//from Client.Networking
|
||||
if ( callback.SteamIDLobby != CurrentLobby )
|
||||
return;
|
||||
|
||||
SteamNative.CSteamID steamid = 1;
|
||||
ChatEntryType chatEntryType; // "If set then this will just always return k_EChatEntryTypeChatMsg. This can usually just be set to NULL."
|
||||
int readData = 0;
|
||||
fixed ( byte* p = chatMessageData )
|
||||
{
|
||||
readData = client.native.matchmaking.GetLobbyChatEntry( CurrentLobby, (int)callback.ChatID, out steamid, (IntPtr)p, chatMessageData.Length, out chatEntryType );
|
||||
}
|
||||
|
||||
|
||||
OnChatMessageRecieved?.Invoke( steamid, chatMessageData, readData );
|
||||
|
||||
if ( readData > 0 )
|
||||
{
|
||||
OnChatStringRecieved?.Invoke( steamid, Encoding.UTF8.GetString( chatMessageData, 0, readData ) );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback to get chat messages. Use Encoding.UTF8.GetString to retrive the message.
|
||||
/// </summary>
|
||||
public Action<ulong, byte[], int> OnChatMessageRecieved;
|
||||
|
||||
/// <summary>
|
||||
/// Like OnChatMessageRecieved but the data is converted to a string
|
||||
/// </summary>
|
||||
public Action<ulong, string> OnChatStringRecieved;
|
||||
|
||||
/// <summary>
|
||||
/// Broadcasts a chat message to the all the users in the lobby users in the lobby (including the local user) will receive a LobbyChatMsg_t callback.
|
||||
/// </summary>
|
||||
/// <returns>True if message successfully sent</returns>
|
||||
public unsafe bool SendChatMessage( string message )
|
||||
{
|
||||
var data = Encoding.UTF8.GetBytes( message );
|
||||
fixed ( byte* p = data )
|
||||
{
|
||||
// pvMsgBody can be binary or text data, up to 4k
|
||||
// if pvMsgBody is text, cubMsgBody should be strlen( text ) + 1, to include the null terminator
|
||||
return client.native.matchmaking.SendLobbyChatMsg( CurrentLobby, (IntPtr)p, data.Length );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enums to catch the state of a user when their state has changed
|
||||
/// </summary>
|
||||
public enum MemberStateChange
|
||||
{
|
||||
Entered = ChatMemberStateChange.Entered,
|
||||
Left = ChatMemberStateChange.Left,
|
||||
Disconnected = ChatMemberStateChange.Disconnected,
|
||||
Kicked = ChatMemberStateChange.Kicked,
|
||||
Banned = ChatMemberStateChange.Banned,
|
||||
}
|
||||
|
||||
internal void OnLobbyStateUpdatedAPI( LobbyChatUpdate_t callback )
|
||||
{
|
||||
if ( callback.SteamIDLobby != CurrentLobby )
|
||||
return;
|
||||
|
||||
MemberStateChange change = (MemberStateChange)callback.GfChatMemberStateChange;
|
||||
ulong initiator = callback.SteamIDMakingChange;
|
||||
ulong affected = callback.SteamIDUserChanged;
|
||||
|
||||
OnLobbyStateChanged?.Invoke( change, initiator, affected );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the state of the Lobby is somehow shifted. Usually when someone joins or leaves the lobby.
|
||||
/// The first ulong is the SteamID of the user that initiated the change.
|
||||
/// The second ulong is the person that was affected
|
||||
/// </summary>
|
||||
public Action<MemberStateChange, ulong, ulong> OnLobbyStateChanged;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the lobby as a property for easy getting/setting. Note that this is setting LobbyData, which you cannot do unless you are the Owner of the lobby
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( !IsValid ) { return ""; }
|
||||
return CurrentLobbyData.GetData( "name" );
|
||||
}
|
||||
set
|
||||
{
|
||||
if ( !IsValid ) { return; }
|
||||
CurrentLobbyData.SetData( "name", value );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns true if we're the current owner
|
||||
/// </summary>
|
||||
public bool IsOwner
|
||||
{
|
||||
get
|
||||
{
|
||||
return Owner == client.SteamId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The Owner of the current lobby. Returns 0 if you are not in a valid lobby.
|
||||
/// </summary>
|
||||
public ulong Owner
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( IsValid )
|
||||
{
|
||||
return client.native.matchmaking.GetLobbyOwner( CurrentLobby );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if ( Owner == value ) return;
|
||||
client.native.matchmaking.SetLobbyOwner( CurrentLobby, value );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the Lobby joinable by other people? Defaults to true;
|
||||
/// </summary>
|
||||
public bool Joinable
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( !IsValid ) { return false; }
|
||||
string joinable = CurrentLobbyData.GetData( "joinable" );
|
||||
switch ( joinable )
|
||||
{
|
||||
case "true":
|
||||
return true;
|
||||
case "false":
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if ( !IsValid ) { return; }
|
||||
if ( client.native.matchmaking.SetLobbyJoinable( CurrentLobby, value ) )
|
||||
{
|
||||
CurrentLobbyData.SetData( "joinable", value.ToString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How many people can be in the Lobby
|
||||
/// </summary>
|
||||
public int MaxMembers
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( !IsValid ) { return 0; } //0 is default, but value is inited when lobby is created.
|
||||
return client.native.matchmaking.GetLobbyMemberLimit( CurrentLobby );
|
||||
}
|
||||
set
|
||||
{
|
||||
if ( !IsValid ) { return; }
|
||||
client.native.matchmaking.SetLobbyMemberLimit( CurrentLobby, value );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How many people are currently in the Lobby
|
||||
/// </summary>
|
||||
public int NumMembers
|
||||
{
|
||||
get { return client.native.matchmaking.GetNumLobbyMembers( CurrentLobby ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Leave the CurrentLobby.
|
||||
/// </summary>
|
||||
public void Leave()
|
||||
{
|
||||
if ( CurrentLobby != 0 )
|
||||
{
|
||||
client.native.matchmaking.LeaveLobby( CurrentLobby );
|
||||
}
|
||||
|
||||
CurrentLobby = 0;
|
||||
CurrentLobbyData = null;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an array of all the CSteamIDs in the CurrentLobby.
|
||||
/// Note that you must be in the Lobby you are trying to request the MemberIDs from.
|
||||
/// Returns an empty array if you aren't in a lobby.
|
||||
/// </summary>
|
||||
/// <returns>Array of member SteamIDs</returns>
|
||||
public ulong[] GetMemberIDs()
|
||||
{
|
||||
ulong[] memIDs = new ulong[NumMembers];
|
||||
for ( int i = 0; i < NumMembers; i++ )
|
||||
{
|
||||
memIDs[i] = client.native.matchmaking.GetLobbyMemberByIndex( CurrentLobby, i );
|
||||
}
|
||||
return memIDs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if a user is in your CurrentLobby
|
||||
/// </summary>
|
||||
/// <param name="steamID">SteamID of the user to check for</param>
|
||||
/// <returns></returns>
|
||||
public bool UserIsInCurrentLobby( ulong steamID )
|
||||
{
|
||||
if ( CurrentLobby == 0 )
|
||||
return false;
|
||||
|
||||
ulong[] mems = GetMemberIDs();
|
||||
|
||||
for ( int i = 0; i < mems.Length; i++ )
|
||||
{
|
||||
if ( mems[i] == steamID )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invites the specified user to the CurrentLobby the user is in.
|
||||
/// </summary>
|
||||
/// <param name="friendID">ulong ID of person to invite</param>
|
||||
public bool InviteUserToLobby( ulong friendID )
|
||||
{
|
||||
return client.native.matchmaking.InviteUserToLobby( CurrentLobby, friendID );
|
||||
}
|
||||
|
||||
internal void OnUserInvitedToLobbyAPI( LobbyInvite_t callback )
|
||||
{
|
||||
if ( callback.GameID != client.AppId ) return;
|
||||
if ( OnUserInvitedToLobby != null ) { OnUserInvitedToLobby( callback.SteamIDLobby, callback.SteamIDUser ); }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activates the steam overlay to invite friends to the CurrentLobby the user is in.
|
||||
/// </summary>
|
||||
public void OpenFriendInviteOverlay()
|
||||
{
|
||||
client.native.friends.ActivateGameOverlayInviteDialog(CurrentLobby);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a user invites the current user to a lobby. The first parameter is the lobby the user was invited to, the second is the CSteamID of the person who invited this user
|
||||
/// </summary>
|
||||
public Action<ulong, ulong> OnUserInvitedToLobby;
|
||||
|
||||
/// <summary>
|
||||
/// Called when a user accepts an invitation to a lobby while the game is running. The parameter is a lobby id.
|
||||
/// </summary>
|
||||
public Action<ulong> OnLobbyJoinRequested;
|
||||
|
||||
/// <summary>
|
||||
/// Joins a lobby if a request was made to join the lobby through the friends list or an invite
|
||||
/// </summary>
|
||||
internal void OnLobbyJoinRequestedAPI( GameLobbyJoinRequested_t callback )
|
||||
{
|
||||
if (OnLobbyJoinRequested != null) { OnLobbyJoinRequested(callback.SteamIDLobby); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes sure we send an update callback if a Lobby user updates their information
|
||||
/// </summary>
|
||||
internal void OnLobbyMemberPersonaChangeAPI( PersonaStateChange_t callback )
|
||||
{
|
||||
if ( !UserIsInCurrentLobby( callback.SteamID ) ) return;
|
||||
if ( OnLobbyMemberDataUpdated != null ) { OnLobbyMemberDataUpdated( callback.SteamID ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the game server associated with the lobby.
|
||||
/// This can only be set by the owner of the lobby.
|
||||
/// Either the IP/Port or the Steam ID of the game server must be valid, depending on how you want the clients to be able to connect.
|
||||
/// </summary>
|
||||
public bool SetGameServer( System.Net.IPAddress ip, int port, ulong serverSteamId = 0 )
|
||||
{
|
||||
if ( !IsValid || !IsOwner ) return false;
|
||||
|
||||
var ipint = System.Net.IPAddress.NetworkToHostOrder( ip.Address );
|
||||
client.native.matchmaking.SetLobbyGameServer( CurrentLobby, (uint)ipint, (ushort)port, serverSteamId );
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the details of a game server set in a lobby.
|
||||
/// </summary>
|
||||
public System.Net.IPAddress GameServerIp
|
||||
{
|
||||
get
|
||||
{
|
||||
uint ip;
|
||||
ushort port;
|
||||
CSteamID steamid;
|
||||
|
||||
if ( !client.native.matchmaking.GetLobbyGameServer( CurrentLobby, out ip, out port, out steamid ) || ip == 0 )
|
||||
return null;
|
||||
|
||||
return new System.Net.IPAddress( System.Net.IPAddress.HostToNetworkOrder( ip ) );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the details of a game server set in a lobby.
|
||||
/// </summary>
|
||||
public int GameServerPort
|
||||
{
|
||||
get
|
||||
{
|
||||
uint ip;
|
||||
ushort port;
|
||||
CSteamID steamid;
|
||||
|
||||
if ( !client.native.matchmaking.GetLobbyGameServer( CurrentLobby, out ip, out port, out steamid ) )
|
||||
return 0;
|
||||
|
||||
return (int)port;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the details of a game server set in a lobby.
|
||||
/// </summary>
|
||||
public ulong GameServerSteamId
|
||||
{
|
||||
get
|
||||
{
|
||||
uint ip;
|
||||
ushort port;
|
||||
CSteamID steamid;
|
||||
|
||||
if ( !client.native.matchmaking.GetLobbyGameServer( CurrentLobby, out ip, out port, out steamid ) )
|
||||
return 0;
|
||||
|
||||
return steamid;
|
||||
}
|
||||
}
|
||||
|
||||
/*not implemented
|
||||
|
||||
//set the game server of the lobby
|
||||
client.native.matchmaking.GetLobbyGameServer;
|
||||
client.native.matchmaking.SetLobbyGameServer;
|
||||
|
||||
//used with game server stuff
|
||||
SteamNative.LobbyGameCreated_t
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class LobbyList
|
||||
{
|
||||
public class Lobby
|
||||
{
|
||||
private Dictionary<string, string> lobbyData;
|
||||
internal Client Client;
|
||||
public string Name { get; private set; }
|
||||
public ulong LobbyID { get; private set; }
|
||||
public ulong Owner { get; private set; }
|
||||
public int MemberLimit{ get; private set; }
|
||||
public int NumMembers{ get; private set; }
|
||||
public string LobbyType { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the lobby value for the specific key
|
||||
/// </summary>
|
||||
/// <param name="k">The key to find</param>
|
||||
/// <returns>The value at key</returns>
|
||||
public string GetData(string k)
|
||||
{
|
||||
if (lobbyData.TryGetValue(k, out var v))
|
||||
return v;
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all the data in the Lobby
|
||||
/// </summary>
|
||||
/// <returns>Dictionary of all the key/value pairs in the data</returns>
|
||||
public Dictionary<string, string> GetAllData()
|
||||
{
|
||||
var returnData = new Dictionary<string, string>();
|
||||
|
||||
foreach ( var item in lobbyData)
|
||||
{
|
||||
returnData.Add(item.Key, item.Value);
|
||||
}
|
||||
|
||||
return returnData;
|
||||
}
|
||||
|
||||
internal static Lobby FromSteam(Client client, ulong lobby)
|
||||
{
|
||||
var lobbyData = new Dictionary<string, string>();
|
||||
int dataCount = client.native.matchmaking.GetLobbyDataCount(lobby);
|
||||
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
{
|
||||
if (client.native.matchmaking.GetLobbyDataByIndex(lobby, i, out var datakey, out var datavalue))
|
||||
{
|
||||
lobbyData.Add(datakey, datavalue);
|
||||
}
|
||||
}
|
||||
|
||||
return new Lobby()
|
||||
{
|
||||
Client = client,
|
||||
LobbyID = lobby,
|
||||
Name = client.native.matchmaking.GetLobbyData(lobby, "name"),
|
||||
LobbyType = client.native.matchmaking.GetLobbyData(lobby, "lobbytype"),
|
||||
MemberLimit = client.native.matchmaking.GetLobbyMemberLimit(lobby),
|
||||
Owner = client.native.matchmaking.GetLobbyOwner(lobby),
|
||||
NumMembers = client.native.matchmaking.GetNumLobbyMembers(lobby),
|
||||
lobbyData = lobbyData
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class LobbyList : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
//The list of retrieved lobbies
|
||||
public List<Lobby> Lobbies { get; private set; }
|
||||
|
||||
//True when all the possible lobbies have had their data updated
|
||||
//if the number of lobbies is now equal to the initial request number, we've found all lobbies
|
||||
public bool Finished { get; private set; }
|
||||
|
||||
//The number of possible lobbies we can get data from
|
||||
internal List<ulong> requests;
|
||||
|
||||
internal LobbyList(Client client)
|
||||
{
|
||||
this.client = client;
|
||||
Lobbies = new List<Lobby>();
|
||||
requests = new List<ulong>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh the List of Lobbies. If no filter is passed in, a default one is created that filters based on AppId ("appid").
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
public void Refresh ( Filter filter = null)
|
||||
{
|
||||
//init out values
|
||||
Lobbies.Clear();
|
||||
requests.Clear();
|
||||
Finished = false;
|
||||
|
||||
if (filter == null)
|
||||
{
|
||||
filter = new Filter();
|
||||
filter.StringFilters.Add("appid", client.AppId.ToString());
|
||||
client.native.matchmaking.RequestLobbyList(OnLobbyList);
|
||||
return;
|
||||
}
|
||||
|
||||
client.native.matchmaking.AddRequestLobbyListDistanceFilter((SteamNative.LobbyDistanceFilter)filter.DistanceFilter);
|
||||
|
||||
if (filter.SlotsAvailable != null)
|
||||
{
|
||||
client.native.matchmaking.AddRequestLobbyListFilterSlotsAvailable((int)filter.SlotsAvailable);
|
||||
}
|
||||
|
||||
if (filter.MaxResults != null)
|
||||
{
|
||||
client.native.matchmaking.AddRequestLobbyListResultCountFilter((int)filter.MaxResults);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> fil in filter.StringFilters)
|
||||
{
|
||||
client.native.matchmaking.AddRequestLobbyListStringFilter(fil.Key, fil.Value, SteamNative.LobbyComparison.Equal);
|
||||
}
|
||||
foreach (KeyValuePair<string, int> fil in filter.NearFilters)
|
||||
{
|
||||
client.native.matchmaking.AddRequestLobbyListNearValueFilter(fil.Key, fil.Value);
|
||||
}
|
||||
//foreach (KeyValuePair<string, KeyValuePair<Filter.Comparison, int>> fil in filter.NumericalFilters)
|
||||
//{
|
||||
// client.native.matchmaking.AddRequestLobbyListNumericalFilter(fil.Key, fil.Value.Value, (SteamNative.LobbyComparison)fil.Value.Key);
|
||||
//}
|
||||
|
||||
|
||||
// this will never return lobbies that are full (via the actual api)
|
||||
client.native.matchmaking.RequestLobbyList(OnLobbyList);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void OnLobbyList(LobbyMatchList_t callback, bool error)
|
||||
{
|
||||
if (error) return;
|
||||
|
||||
//how many lobbies matched
|
||||
uint lobbiesMatching = callback.LobbiesMatching;
|
||||
|
||||
// lobbies are returned in order of closeness to the user, so add them to the list in that order
|
||||
for (int i = 0; i < lobbiesMatching; i++)
|
||||
{
|
||||
//add the lobby to the list of requests
|
||||
ulong lobby = client.native.matchmaking.GetLobbyByIndex(i);
|
||||
requests.Add(lobby);
|
||||
|
||||
//cast to a LobbyList.Lobby
|
||||
Lobby newLobby = Lobby.FromSteam(client, lobby);
|
||||
if (newLobby.Name != "")
|
||||
{
|
||||
//if the lobby is valid add it to the valid return lobbies
|
||||
Lobbies.Add(newLobby);
|
||||
checkFinished();
|
||||
}
|
||||
else
|
||||
{
|
||||
//else we need to get the info for the missing lobby
|
||||
client.native.matchmaking.RequestLobbyData(lobby);
|
||||
client.RegisterCallback<SteamNative.LobbyDataUpdate_t>( OnLobbyDataUpdated );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
checkFinished();
|
||||
|
||||
if (OnLobbiesUpdated != null) { OnLobbiesUpdated(); }
|
||||
}
|
||||
|
||||
void checkFinished()
|
||||
{
|
||||
if (Lobbies.Count == requests.Count)
|
||||
{
|
||||
Finished = true;
|
||||
return;
|
||||
}
|
||||
Finished = false;
|
||||
}
|
||||
|
||||
void OnLobbyDataUpdated(LobbyDataUpdate_t callback)
|
||||
{
|
||||
if (callback.Success == 1) //1 if success, 0 if failure
|
||||
{
|
||||
//find the lobby that has been updated
|
||||
Lobby lobby = Lobbies.Find(x => x.LobbyID == callback.SteamIDLobby);
|
||||
|
||||
//if this lobby isn't yet in the list of lobbies, we know that we should add it
|
||||
if (lobby == null)
|
||||
{
|
||||
Lobbies.Add(lobby);
|
||||
checkFinished();
|
||||
}
|
||||
|
||||
//otherwise lobby data in general was updated and you should listen to see what changed
|
||||
if (OnLobbiesUpdated != null) { OnLobbiesUpdated(); }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Action OnLobbiesUpdated;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
public class Filter
|
||||
{
|
||||
// Filters that match actual metadata keys exactly
|
||||
public Dictionary<string, string> StringFilters = new Dictionary<string, string>();
|
||||
// Filters that are of string key and int value for that key to be close to
|
||||
public Dictionary<string, int> NearFilters = new Dictionary<string, int>();
|
||||
//Filters that are of string key and int value, with a comparison filter to say how we should relate to the value
|
||||
//public Dictionary<string, KeyValuePair<Comparison, int>> NumericalFilters = new Dictionary<string, KeyValuePair<Comparison, int>>();
|
||||
public Distance DistanceFilter = Distance.Worldwide;
|
||||
public int? SlotsAvailable { get; set; }
|
||||
public int? MaxResults { get; set; }
|
||||
|
||||
public enum Distance : int
|
||||
{
|
||||
Close = SteamNative.LobbyDistanceFilter.Close,
|
||||
Default = SteamNative.LobbyDistanceFilter.Default,
|
||||
Far = SteamNative.LobbyDistanceFilter.Far,
|
||||
Worldwide = SteamNative.LobbyDistanceFilter.Worldwide
|
||||
}
|
||||
|
||||
public enum Comparison : int
|
||||
{
|
||||
EqualToOrLessThan = SteamNative.LobbyComparison.EqualToOrLessThan,
|
||||
LessThan = SteamNative.LobbyComparison.LessThan,
|
||||
Equal = SteamNative.LobbyComparison.Equal,
|
||||
GreaterThan = SteamNative.LobbyComparison.GreaterThan,
|
||||
EqualToOrGreaterThan = SteamNative.LobbyComparison.EqualToOrGreaterThan,
|
||||
NotEqual = SteamNative.LobbyComparison.NotEqual
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class MicroTransactions : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
public delegate void AuthorizationResponse( bool authorized, int appId, ulong orderId );
|
||||
|
||||
/// <summary>
|
||||
/// Called on the MicroTxnAuthorizationResponse_t event
|
||||
/// </summary>
|
||||
public event AuthorizationResponse OnAuthorizationResponse;
|
||||
|
||||
internal MicroTransactions( Client c )
|
||||
{
|
||||
client = c;
|
||||
|
||||
client.RegisterCallback<SteamNative.MicroTxnAuthorizationResponse_t>( onMicroTxnAuthorizationResponse );
|
||||
}
|
||||
|
||||
private void onMicroTxnAuthorizationResponse( MicroTxnAuthorizationResponse_t arg1 )
|
||||
{
|
||||
if ( OnAuthorizationResponse != null )
|
||||
{
|
||||
OnAuthorizationResponse( arg1.Authorized == 1, (int) arg1.AppID, arg1.OrderID );
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class Overlay
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
public bool Enabled
|
||||
{
|
||||
get { return client.native.utils.IsOverlayEnabled(); }
|
||||
}
|
||||
|
||||
public bool IsOpen { get; private set; }
|
||||
|
||||
internal Overlay( Client c )
|
||||
{
|
||||
client = c;
|
||||
|
||||
c.RegisterCallback<GameOverlayActivated_t>( OverlayStateChange );
|
||||
}
|
||||
|
||||
private void OverlayStateChange( GameOverlayActivated_t activation )
|
||||
{
|
||||
IsOpen = activation.Active == 1;
|
||||
}
|
||||
|
||||
public void OpenUserPage( string name, ulong steamid ) { client.native.friends.ActivateGameOverlayToUser( name, steamid ); }
|
||||
|
||||
public void OpenProfile( ulong steamid ) { OpenUserPage( "steamid", steamid ); }
|
||||
public void OpenChat( ulong steamid ){ OpenUserPage( "chat", steamid ); }
|
||||
public void OpenTrade( ulong steamid ) { OpenUserPage( "jointrade", steamid ); }
|
||||
public void OpenStats( ulong steamid ) { OpenUserPage( "stats", steamid ); }
|
||||
public void OpenAchievements( ulong steamid ) { OpenUserPage( "achievements", steamid ); }
|
||||
public void AddFriend( ulong steamid ) { OpenUserPage( "friendadd", steamid ); }
|
||||
public void RemoveFriend( ulong steamid ) { OpenUserPage( "friendremove", steamid ); }
|
||||
public void AcceptFriendRequest( ulong steamid ) { OpenUserPage( "friendrequestaccept", steamid ); }
|
||||
public void IgnoreFriendRequest( ulong steamid ) { OpenUserPage( "friendrequestignore", steamid ); }
|
||||
|
||||
public void OpenUrl( string url ) { client.native.friends.ActivateGameOverlayToWebPage( url ); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Facepunch.Steamworks.Callbacks;
|
||||
using SteamNative;
|
||||
using Result = SteamNative.Result;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a file stored in a user's Steam Cloud.
|
||||
/// </summary>
|
||||
public class RemoteFile
|
||||
{
|
||||
internal readonly RemoteStorage remoteStorage;
|
||||
|
||||
private readonly bool _isUgc;
|
||||
private string _fileName;
|
||||
private int _sizeInBytes = -1;
|
||||
private long _timestamp = 0;
|
||||
private UGCHandle_t _handle;
|
||||
private ulong _ownerId;
|
||||
|
||||
private bool _isDownloading;
|
||||
private byte[] _downloadedData;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the file exists.
|
||||
/// </summary>
|
||||
public bool Exists { get; internal set; }
|
||||
|
||||
public bool IsDownloading { get { return _isUgc && _isDownloading && _downloadedData == null; } }
|
||||
|
||||
public bool IsDownloaded { get { return !_isUgc || _downloadedData != null; } }
|
||||
|
||||
/// <summary>
|
||||
/// If true, the file is available for other users to download.
|
||||
/// </summary>
|
||||
public bool IsShared { get { return _handle.Value != 0; } }
|
||||
|
||||
internal UGCHandle_t UGCHandle { get { return _handle; } }
|
||||
|
||||
public ulong SharingId { get { return UGCHandle.Value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Name and path of the file.
|
||||
/// </summary>
|
||||
public string FileName
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _fileName != null ) return _fileName;
|
||||
GetUGCDetails();
|
||||
return _fileName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Steam ID of the file's owner.
|
||||
/// </summary>
|
||||
public ulong OwnerId
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _ownerId != 0 ) return _ownerId;
|
||||
GetUGCDetails();
|
||||
return _ownerId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Total size of the file in bytes.
|
||||
/// </summary>
|
||||
public int SizeInBytes
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _sizeInBytes != -1 ) return _sizeInBytes;
|
||||
if ( _isUgc ) throw new NotImplementedException();
|
||||
_sizeInBytes = remoteStorage.native.GetFileSize( FileName );
|
||||
return _sizeInBytes;
|
||||
}
|
||||
internal set { _sizeInBytes = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Date modified timestamp in epoch format.
|
||||
/// </summary>
|
||||
public long FileTimestamp
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _timestamp != 0 ) return _timestamp;
|
||||
if (_isUgc) throw new NotImplementedException();
|
||||
_timestamp = remoteStorage.native.GetFileTimestamp(FileName);
|
||||
return _timestamp;
|
||||
}
|
||||
internal set { _timestamp = value; }
|
||||
}
|
||||
|
||||
internal RemoteFile( RemoteStorage r, UGCHandle_t handle )
|
||||
{
|
||||
Exists = true;
|
||||
|
||||
remoteStorage = r;
|
||||
|
||||
_isUgc = true;
|
||||
_handle = handle;
|
||||
}
|
||||
|
||||
internal RemoteFile( RemoteStorage r, string name, ulong ownerId, int sizeInBytes = -1, long timestamp = 0 )
|
||||
{
|
||||
remoteStorage = r;
|
||||
|
||||
_isUgc = false;
|
||||
_fileName = name;
|
||||
_ownerId = ownerId;
|
||||
_sizeInBytes = sizeInBytes;
|
||||
_timestamp = timestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="RemoteFileWriteStream"/> used to write to this file.
|
||||
/// </summary>
|
||||
public RemoteFileWriteStream OpenWrite()
|
||||
{
|
||||
if (_isUgc) throw new InvalidOperationException("Cannot write to a shared file.");
|
||||
|
||||
return new RemoteFileWriteStream( remoteStorage, this );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a byte array to this file, replacing any existing contents.
|
||||
/// </summary>
|
||||
public void WriteAllBytes( byte[] buffer )
|
||||
{
|
||||
using ( var stream = OpenWrite() )
|
||||
{
|
||||
stream.Write( buffer, 0, buffer.Length );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write a string to this file, replacing any existing contents.
|
||||
/// </summary>
|
||||
public void WriteAllText( string text, Encoding encoding = null )
|
||||
{
|
||||
if ( encoding == null ) encoding = Encoding.UTF8;
|
||||
WriteAllBytes( encoding.GetBytes( text ) );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback invoked by <see cref="RemoteFile.Download"/> when a file download is complete.
|
||||
/// </summary>
|
||||
public delegate void DownloadCallback();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of bytes downloaded and the total number of bytes expected while
|
||||
/// this file is downloading.
|
||||
/// </summary>
|
||||
/// <returns>True if the file is downloading</returns>
|
||||
public bool GetDownloadProgress( out int bytesDownloaded, out int bytesExpected )
|
||||
{
|
||||
return remoteStorage.native.GetUGCDownloadProgress( _handle, out bytesDownloaded, out bytesExpected );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to start downloading a shared file.
|
||||
/// </summary>
|
||||
/// <returns>True if the download has successfully started</returns>
|
||||
public bool Download( DownloadCallback onSuccess = null, FailureCallback onFailure = null )
|
||||
{
|
||||
if ( !_isUgc ) return false;
|
||||
if ( _isDownloading ) return false;
|
||||
if ( IsDownloaded ) return false;
|
||||
|
||||
_isDownloading = true;
|
||||
|
||||
remoteStorage.native.UGCDownload( _handle, 1000, ( result, error ) =>
|
||||
{
|
||||
_isDownloading = false;
|
||||
|
||||
if ( error || result.Result != Result.OK )
|
||||
{
|
||||
onFailure?.Invoke( result.Result == 0 ? Callbacks.Result.IOFailure : (Callbacks.Result) result.Result );
|
||||
return;
|
||||
}
|
||||
|
||||
_ownerId = result.SteamIDOwner;
|
||||
_sizeInBytes = result.SizeInBytes;
|
||||
_fileName = result.PchFileName;
|
||||
|
||||
unsafe
|
||||
{
|
||||
_downloadedData = new byte[_sizeInBytes];
|
||||
fixed ( byte* bufferPtr = _downloadedData )
|
||||
{
|
||||
remoteStorage.native.UGCRead( _handle, (IntPtr) bufferPtr, _sizeInBytes, 0, UGCReadAction.ontinueReading );
|
||||
}
|
||||
}
|
||||
|
||||
onSuccess?.Invoke();
|
||||
} );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a stream used to read from this file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Stream OpenRead()
|
||||
{
|
||||
return new MemoryStream( ReadAllBytes(), false );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the entire contents of the file as a byte array.
|
||||
/// </summary>
|
||||
public unsafe byte[] ReadAllBytes()
|
||||
{
|
||||
if ( _isUgc )
|
||||
{
|
||||
if ( !IsDownloaded ) throw new Exception( "Cannot read a file that hasn't been downloaded." );
|
||||
return _downloadedData;
|
||||
}
|
||||
|
||||
var size = SizeInBytes;
|
||||
var buffer = new byte[size];
|
||||
|
||||
fixed ( byte* bufferPtr = buffer )
|
||||
{
|
||||
remoteStorage.native.FileRead( FileName, (IntPtr) bufferPtr, size );
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the entire contents of the file as a string.
|
||||
/// </summary>
|
||||
public string ReadAllText( Encoding encoding = null )
|
||||
{
|
||||
if ( encoding == null ) encoding = Encoding.UTF8;
|
||||
return encoding.GetString( ReadAllBytes() );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback invoked by <see cref="RemoteFile.Share"/> when file sharing is complete.
|
||||
/// </summary>
|
||||
public delegate void ShareCallback();
|
||||
|
||||
/// <summary>
|
||||
/// Attempt to publish this file for other users to download.
|
||||
/// </summary>
|
||||
/// <returns>True if we have started attempting to share</returns>
|
||||
public bool Share( ShareCallback onSuccess = null, FailureCallback onFailure = null )
|
||||
{
|
||||
if ( _isUgc ) return false;
|
||||
|
||||
// Already shared
|
||||
if ( _handle.Value != 0 ) return false;
|
||||
|
||||
remoteStorage.native.FileShare( FileName, ( result, error ) =>
|
||||
{
|
||||
if ( !error && result.Result == Result.OK )
|
||||
{
|
||||
_handle.Value = result.File;
|
||||
onSuccess?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
onFailure?.Invoke( result.Result == 0 ? Callbacks.Result.IOFailure : (Callbacks.Result) result.Result );
|
||||
}
|
||||
} );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete this file from remote storage.
|
||||
/// </summary>
|
||||
/// <returns>True if the file could be deleted</returns>
|
||||
public bool Delete()
|
||||
{
|
||||
if ( !Exists ) return false;
|
||||
if ( _isUgc ) return false;
|
||||
if ( !remoteStorage.native.FileDelete( FileName ) ) return false;
|
||||
|
||||
Exists = false;
|
||||
remoteStorage.InvalidateFiles();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove this file from remote storage, while keeping a local copy.
|
||||
/// Writing to this file again will re-add it to the cloud.
|
||||
/// </summary>
|
||||
/// <returns>True if the file was forgotten</returns>
|
||||
public bool Forget()
|
||||
{
|
||||
if ( !Exists ) return false;
|
||||
if ( _isUgc ) return false;
|
||||
|
||||
return remoteStorage.native.FileForget( FileName );
|
||||
}
|
||||
|
||||
private void GetUGCDetails()
|
||||
{
|
||||
if ( !_isUgc ) throw new InvalidOperationException();
|
||||
|
||||
var appId = new AppId_t { Value = remoteStorage.native.steamworks.AppId };
|
||||
|
||||
CSteamID ownerId;
|
||||
remoteStorage.native.GetUGCDetails( _handle, ref appId, out _fileName, out ownerId );
|
||||
|
||||
_ownerId = ownerId.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Stream used to write to a <see cref="RemoteFile"/>.
|
||||
/// </summary>
|
||||
public class RemoteFileWriteStream : Stream
|
||||
{
|
||||
internal readonly RemoteStorage remoteStorage;
|
||||
|
||||
private readonly UGCFileWriteStreamHandle_t _handle;
|
||||
private readonly RemoteFile _file;
|
||||
|
||||
private int _written;
|
||||
private bool _closed;
|
||||
|
||||
internal RemoteFileWriteStream( RemoteStorage r, RemoteFile file )
|
||||
{
|
||||
remoteStorage = r;
|
||||
|
||||
_handle = remoteStorage.native.FileWriteStreamOpen( file.FileName );
|
||||
_file = file;
|
||||
}
|
||||
|
||||
public override void Flush() { }
|
||||
|
||||
public override int Read( byte[] buffer, int offset, int count )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override long Seek( long offset, SeekOrigin origin )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void SetLength( long value )
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override unsafe void Write( byte[] buffer, int offset, int count )
|
||||
{
|
||||
if ( _closed ) throw new ObjectDisposedException( ToString() );
|
||||
|
||||
fixed ( byte* bufferPtr = buffer )
|
||||
{
|
||||
if ( remoteStorage.native.FileWriteStreamWriteChunk( _handle, (IntPtr)(bufferPtr + offset), count ) )
|
||||
{
|
||||
_written += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanRead => false;
|
||||
public override bool CanSeek => false;
|
||||
public override bool CanWrite => true;
|
||||
public override long Length => _written;
|
||||
public override long Position { get { return _written; } set { throw new NotImplementedException(); } }
|
||||
|
||||
/// <summary>
|
||||
/// Close the stream without saving the file to remote storage.
|
||||
/// </summary>
|
||||
public void Cancel()
|
||||
{
|
||||
if ( _closed ) return;
|
||||
|
||||
_closed = true;
|
||||
remoteStorage.native.FileWriteStreamCancel( _handle );
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
if ( _closed ) return;
|
||||
|
||||
_closed = true;
|
||||
remoteStorage.native.FileWriteStreamClose( _handle );
|
||||
|
||||
_file.remoteStorage.OnWrittenNewFile( _file );
|
||||
}
|
||||
|
||||
protected override void Dispose( bool disposing )
|
||||
{
|
||||
if ( disposing ) Close();
|
||||
base.Dispose( disposing );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles Steam Cloud related actions.
|
||||
/// </summary>
|
||||
public class RemoteStorage : IDisposable
|
||||
{
|
||||
private static string NormalizePath( string path )
|
||||
{
|
||||
// TODO: DUMB HACK ALERT
|
||||
|
||||
return SteamNative.Platform.IsWindows
|
||||
? new FileInfo( $"x:/{path}" ).FullName.Substring( 3 )
|
||||
: new FileInfo( $"/x/{path}" ).FullName.Substring( 3 );
|
||||
}
|
||||
|
||||
internal Client client;
|
||||
internal SteamNative.SteamRemoteStorage native;
|
||||
|
||||
private bool _filesInvalid = true;
|
||||
private readonly List<RemoteFile> _files = new List<RemoteFile>();
|
||||
|
||||
internal RemoteStorage( Client c )
|
||||
{
|
||||
client = c;
|
||||
native = client.native.remoteStorage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if Steam Cloud is currently enabled by the current user.
|
||||
/// </summary>
|
||||
public bool IsCloudEnabledForAccount
|
||||
{
|
||||
get { return native.IsCloudEnabledForAccount(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if Steam Cloud is currently enabled for this app by the current user.
|
||||
/// </summary>
|
||||
public bool IsCloudEnabledForApp
|
||||
{
|
||||
get { return native.IsCloudEnabledForApp(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of files in the current user's remote storage for the current game.
|
||||
/// </summary>
|
||||
public int FileCount
|
||||
{
|
||||
get { return native.GetFileCount(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all files in the current user's remote storage for the current game.
|
||||
/// </summary>
|
||||
public IEnumerable<RemoteFile> Files
|
||||
{
|
||||
get
|
||||
{
|
||||
UpdateFiles();
|
||||
return _files;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="RemoteFile"/> with the given <paramref name="path"/>.
|
||||
/// If a file exists at that path it will be overwritten.
|
||||
/// </summary>
|
||||
public RemoteFile CreateFile( string path )
|
||||
{
|
||||
path = NormalizePath( path );
|
||||
|
||||
InvalidateFiles();
|
||||
var existing = Files.FirstOrDefault( x => x.FileName == path );
|
||||
return existing ?? new RemoteFile( this, path, client.SteamId, 0 );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the file if it exists, else returns null;
|
||||
/// </summary>
|
||||
public RemoteFile OpenFile( string path )
|
||||
{
|
||||
path = NormalizePath( path );
|
||||
|
||||
InvalidateFiles();
|
||||
var existing = Files.FirstOrDefault( x => x.FileName == path );
|
||||
return existing;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a previously shared <see cref="RemoteFile"/>
|
||||
/// with the given <paramref name="sharingId"/>.
|
||||
/// </summary>
|
||||
public RemoteFile OpenSharedFile( ulong sharingId )
|
||||
{
|
||||
return new RemoteFile( this, sharingId );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write all text to the file at the specified path. This
|
||||
/// overwrites the contents - it does not append.
|
||||
/// </summary>
|
||||
public bool WriteString( string path, string text, Encoding encoding = null )
|
||||
{
|
||||
var file = CreateFile( path );
|
||||
file.WriteAllText( text, encoding );
|
||||
return file.Exists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write all data to the file at the specified path. This
|
||||
/// overwrites the contents - it does not append.
|
||||
/// </summary>
|
||||
public bool WriteBytes( string path, byte[] data )
|
||||
{
|
||||
var file = CreateFile( path );
|
||||
file.WriteAllBytes( data );
|
||||
return file.Exists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the entire contents of the file as a string.
|
||||
/// Returns null if the file isn't found.
|
||||
/// </summary>
|
||||
public string ReadString( string path, Encoding encoding = null )
|
||||
{
|
||||
var file = OpenFile( path );
|
||||
if ( file == null ) return null;
|
||||
return file.ReadAllText( encoding );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the entire contents of the file as raw data.
|
||||
/// Returns null if the file isn't found.
|
||||
/// </summary>
|
||||
public byte[] ReadBytes( string path )
|
||||
{
|
||||
var file = OpenFile( path );
|
||||
if ( file == null ) return null;
|
||||
return file.ReadAllBytes();
|
||||
}
|
||||
|
||||
internal void OnWrittenNewFile( RemoteFile file )
|
||||
{
|
||||
if ( _files.Any( x => x.FileName == file.FileName ) ) return;
|
||||
|
||||
_files.Add( file );
|
||||
file.Exists = true;
|
||||
|
||||
InvalidateFiles();
|
||||
}
|
||||
|
||||
internal void InvalidateFiles()
|
||||
{
|
||||
_filesInvalid = true;
|
||||
}
|
||||
|
||||
private void UpdateFiles()
|
||||
{
|
||||
if ( !_filesInvalid ) return;
|
||||
_filesInvalid = false;
|
||||
|
||||
foreach ( var file in _files )
|
||||
{
|
||||
file.Exists = false;
|
||||
}
|
||||
|
||||
var count = FileCount;
|
||||
for ( var i = 0; i < count; ++i )
|
||||
{
|
||||
int size;
|
||||
var name = NormalizePath( native.GetFileNameAndSize( i, out size ) );
|
||||
var timestamp = native.GetFileTimestamp(name);
|
||||
|
||||
var existing = _files.FirstOrDefault( x => x.FileName == name );
|
||||
if ( existing == null )
|
||||
{
|
||||
existing = new RemoteFile( this, name, client.SteamId, size, timestamp );
|
||||
_files.Add( existing );
|
||||
}
|
||||
else
|
||||
{
|
||||
existing.SizeInBytes = size;
|
||||
existing.FileTimestamp = timestamp;
|
||||
}
|
||||
|
||||
existing.Exists = true;
|
||||
}
|
||||
|
||||
for ( var i = _files.Count - 1; i >= 0; --i )
|
||||
{
|
||||
if ( !_files[i].Exists ) _files.RemoveAt( i );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether a file exists in remote storage at the given <paramref name="path"/>.
|
||||
/// </summary>
|
||||
public bool FileExists( string path )
|
||||
{
|
||||
return native.FileExists( path );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
native = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Number of bytes used out of the user's total quota
|
||||
/// </summary>
|
||||
public ulong QuotaUsed
|
||||
{
|
||||
get
|
||||
{
|
||||
ulong totalBytes = 0;
|
||||
ulong availableBytes = 0;
|
||||
|
||||
if ( !native.GetQuota( out totalBytes, out availableBytes ) )
|
||||
return 0;
|
||||
|
||||
return totalBytes - availableBytes;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Total quota size in bytes
|
||||
/// </summary>
|
||||
public ulong QuotaTotal
|
||||
{
|
||||
get
|
||||
{
|
||||
ulong totalBytes = 0;
|
||||
ulong availableBytes = 0;
|
||||
|
||||
if ( !native.GetQuota( out totalBytes, out availableBytes ) )
|
||||
return 0;
|
||||
|
||||
return totalBytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Number of bytes remaining out of the user's total quota
|
||||
/// </summary>
|
||||
public ulong QuotaRemaining
|
||||
{
|
||||
get
|
||||
{
|
||||
ulong totalBytes = 0;
|
||||
ulong availableBytes = 0;
|
||||
|
||||
if ( !native.GetQuota( out totalBytes, out availableBytes ) )
|
||||
return 0;
|
||||
|
||||
return availableBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Client : IDisposable
|
||||
{
|
||||
Screenshots _screenshots;
|
||||
|
||||
public Screenshots Screenshots
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _screenshots == null )
|
||||
_screenshots = new Screenshots( this );
|
||||
|
||||
return _screenshots;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Screenshots
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
internal Screenshots( Client c )
|
||||
{
|
||||
client = c;
|
||||
}
|
||||
|
||||
public void Trigger()
|
||||
{
|
||||
client.native.screenshots.TriggerScreenshot();
|
||||
}
|
||||
|
||||
public unsafe void Write( byte[] rgbData, int width, int height )
|
||||
{
|
||||
if ( rgbData == null )
|
||||
{
|
||||
throw new ArgumentNullException( nameof(rgbData) );
|
||||
}
|
||||
|
||||
if ( width < 1 )
|
||||
{
|
||||
throw new ArgumentOutOfRangeException( nameof(width), width,
|
||||
$"Expected {nameof(width)} to be at least 1." );
|
||||
}
|
||||
|
||||
if ( height < 1 )
|
||||
{
|
||||
throw new ArgumentOutOfRangeException( nameof(height), height,
|
||||
$"Expected {nameof(height)} to be at least 1." );
|
||||
}
|
||||
|
||||
var size = width * height * 3;
|
||||
if ( rgbData.Length < size )
|
||||
{
|
||||
throw new ArgumentException( nameof(rgbData),
|
||||
$"Expected {nameof(rgbData)} to contain at least {size} elements (actual size: {rgbData.Length})." );
|
||||
}
|
||||
|
||||
fixed ( byte* ptr = rgbData )
|
||||
{
|
||||
client.native.screenshots.WriteScreenshot( (IntPtr) ptr, (uint) rgbData.Length, width, height );
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe void AddScreenshotToLibrary( string filename, string thumbnailFilename, int width, int height)
|
||||
{
|
||||
client.native.screenshots.AddScreenshotToLibrary(filename, thumbnailFilename, width, height);
|
||||
}
|
||||
|
||||
public unsafe void AddScreenshotToLibrary( string filename, int width, int height)
|
||||
{
|
||||
client.native.screenshots.AddScreenshotToLibrary(filename, null, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class ServerList
|
||||
{
|
||||
public class Request : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
internal List<SubRequest> Requests = new List<SubRequest>();
|
||||
|
||||
internal class SubRequest
|
||||
{
|
||||
internal IntPtr Request;
|
||||
internal int Pointer = 0;
|
||||
internal List<int> WatchList = new List<int>();
|
||||
internal System.Diagnostics.Stopwatch Timer = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
internal bool Update( SteamNative.SteamMatchmakingServers servers, Action<SteamNative.gameserveritem_t> OnServer, Action OnUpdate )
|
||||
{
|
||||
if ( Request == IntPtr.Zero )
|
||||
return true;
|
||||
|
||||
if ( Timer.Elapsed.TotalSeconds < 0.5f )
|
||||
return false;
|
||||
|
||||
Timer.Reset();
|
||||
Timer.Start();
|
||||
|
||||
bool changes = false;
|
||||
|
||||
//
|
||||
// Add any servers we're not watching to our watch list
|
||||
//
|
||||
var count = servers.GetServerCount( Request );
|
||||
if ( count != Pointer )
|
||||
{
|
||||
for ( int i = Pointer; i < count; i++ )
|
||||
{
|
||||
WatchList.Add( i );
|
||||
}
|
||||
}
|
||||
Pointer = count;
|
||||
|
||||
//
|
||||
// Remove any servers that respond successfully
|
||||
//
|
||||
WatchList.RemoveAll( x =>
|
||||
{
|
||||
var info = servers.GetServerDetails( Request, x );
|
||||
if ( info.HadSuccessfulResponse )
|
||||
{
|
||||
OnServer( info );
|
||||
changes = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} );
|
||||
|
||||
//
|
||||
// If we've finished refreshing
|
||||
//
|
||||
if ( servers.IsRefreshing( Request ) == false )
|
||||
{
|
||||
//
|
||||
// Put any other servers on the 'no response' list
|
||||
//
|
||||
WatchList.RemoveAll( x =>
|
||||
{
|
||||
var info = servers.GetServerDetails( Request, x );
|
||||
OnServer( info );
|
||||
return true;
|
||||
} );
|
||||
|
||||
servers.CancelQuery( Request );
|
||||
Request = IntPtr.Zero;
|
||||
changes = true;
|
||||
}
|
||||
|
||||
if ( changes && OnUpdate != null )
|
||||
OnUpdate();
|
||||
|
||||
return Request == IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public Action OnUpdate;
|
||||
public Action<Server> OnServerResponded;
|
||||
public Action OnFinished;
|
||||
|
||||
/// <summary>
|
||||
/// A list of servers that responded. If you're only interested in servers that responded since you
|
||||
/// last updated, then simply clear this list.
|
||||
/// </summary>
|
||||
public List<Server> Responded = new List<Server>();
|
||||
|
||||
/// <summary>
|
||||
/// A list of servers that were in the master list but didn't respond.
|
||||
/// </summary>
|
||||
public List<Server> Unresponsive = new List<Server>();
|
||||
|
||||
/// <summary>
|
||||
/// True when we have finished
|
||||
/// </summary>
|
||||
public bool Finished = false;
|
||||
|
||||
internal Request( Client c )
|
||||
{
|
||||
client = c;
|
||||
|
||||
client.OnUpdate += Update;
|
||||
}
|
||||
|
||||
~Request()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
internal IEnumerable<string> ServerList { get; set; }
|
||||
internal Filter Filter { get; set; }
|
||||
|
||||
internal void StartCustomQuery()
|
||||
{
|
||||
if ( ServerList == null )
|
||||
return;
|
||||
|
||||
int blockSize = 16;
|
||||
int Pointer = 0;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
var sublist = ServerList.Skip( Pointer ).Take( blockSize );
|
||||
|
||||
if ( sublist.Count() == 0 )
|
||||
break;
|
||||
|
||||
Pointer += sublist.Count();
|
||||
|
||||
var filter = new Filter();
|
||||
filter.Add( "or", sublist.Count().ToString() );
|
||||
|
||||
foreach ( var server in sublist )
|
||||
{
|
||||
filter.Add( "gameaddr", server );
|
||||
}
|
||||
|
||||
filter.Start();
|
||||
var id = client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, (uint)filter.Count, IntPtr.Zero );
|
||||
filter.Free();
|
||||
|
||||
AddRequest( id );
|
||||
}
|
||||
|
||||
ServerList = null;
|
||||
}
|
||||
|
||||
internal void AddRequest( IntPtr id )
|
||||
{
|
||||
Requests.Add( new SubRequest() { Request = id } );
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if ( Requests.Count == 0 )
|
||||
return;
|
||||
|
||||
for( int i=0; i< Requests.Count(); i++ )
|
||||
{
|
||||
if ( Requests[i].Update( client.native.servers, OnServer, OnUpdate ) )
|
||||
{
|
||||
Requests.RemoveAt( i );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
if ( Requests.Count == 0 )
|
||||
{
|
||||
Finished = true;
|
||||
client.OnUpdate -= Update;
|
||||
|
||||
OnFinished?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnServer( SteamNative.gameserveritem_t info )
|
||||
{
|
||||
if ( info.HadSuccessfulResponse )
|
||||
{
|
||||
if ( Filter != null && !Filter.Test( info ) )
|
||||
return;
|
||||
|
||||
var s = Server.FromSteam( client, info );
|
||||
Responded.Add( s );
|
||||
|
||||
OnServerResponded?.Invoke( s );
|
||||
}
|
||||
else
|
||||
{
|
||||
Unresponsive.Add( Server.FromSteam( client, info ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposing will end the query
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if ( client.IsValid )
|
||||
client.OnUpdate -= Update;
|
||||
|
||||
//
|
||||
// Cancel the query if it's still running
|
||||
//
|
||||
foreach( var subRequest in Requests )
|
||||
{
|
||||
if ( client.IsValid )
|
||||
client.native.servers.CancelQuery( subRequest.Request );
|
||||
}
|
||||
Requests.Clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class ServerList
|
||||
{
|
||||
public class Server
|
||||
{
|
||||
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 uint AppId { get; set; }
|
||||
public int Players { get; set; }
|
||||
public int MaxPlayers { get; set; }
|
||||
public int BotPlayers { get; set; }
|
||||
public bool Passworded { get; set; }
|
||||
public bool Secure { get; set; }
|
||||
public uint LastTimePlayed { get; set; }
|
||||
public int Version { get; set; }
|
||||
public string[] Tags { get; set; }
|
||||
public ulong SteamId { get; set; }
|
||||
public IPAddress Address { get; set; }
|
||||
public int ConnectionPort { get; set; }
|
||||
public int QueryPort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this server is in the favourites list
|
||||
/// </summary>
|
||||
public bool Favourite
|
||||
{
|
||||
get
|
||||
{
|
||||
return Client.ServerList.IsFavourite( this );
|
||||
}
|
||||
}
|
||||
|
||||
internal Client Client;
|
||||
|
||||
|
||||
internal static Server FromSteam( Client client, SteamNative.gameserveritem_t item )
|
||||
{
|
||||
return new Server()
|
||||
{
|
||||
Client = client,
|
||||
Address = Utility.Int32ToIp( item.NetAdr.IP ),
|
||||
ConnectionPort = item.NetAdr.ConnectionPort,
|
||||
QueryPort = item.NetAdr.QueryPort,
|
||||
Name = item.ServerName,
|
||||
Ping = item.Ping,
|
||||
GameDir = item.GameDir,
|
||||
Map = item.Map,
|
||||
Description = item.GameDescription,
|
||||
AppId = item.AppID,
|
||||
Players = item.Players,
|
||||
MaxPlayers = item.MaxPlayers,
|
||||
BotPlayers = item.BotPlayers,
|
||||
Passworded = item.Password,
|
||||
Secure = item.Secure,
|
||||
LastTimePlayed = item.TimeLastPlayed,
|
||||
Version = item.ServerVersion,
|
||||
Tags = item.GameTags == null ? null : item.GameTags.Split( ',' ),
|
||||
SteamId = item.SteamID
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Callback when rules are receieved.
|
||||
/// The bool is true if server responded properly.
|
||||
/// </summary>
|
||||
public Action<bool> OnReceivedRules;
|
||||
|
||||
/// <summary>
|
||||
/// List of server rules. Use HasRules to see if this is safe to access.
|
||||
/// </summary>
|
||||
public Dictionary<string, string> Rules;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this server has rules
|
||||
/// </summary>
|
||||
public bool HasRules { get { return Rules != null && Rules.Count > 0; } }
|
||||
|
||||
internal SourceServerQuery RulesRequest;
|
||||
|
||||
/// <summary>
|
||||
/// Populates Rules for this server
|
||||
/// </summary>
|
||||
public void FetchRules()
|
||||
{
|
||||
if ( RulesRequest != null )
|
||||
return;
|
||||
|
||||
Rules = null;
|
||||
RulesRequest = new SourceServerQuery( this, Address, QueryPort );
|
||||
}
|
||||
|
||||
internal void OnServerRulesReceiveFinished( Dictionary<string, string> rules, bool Success )
|
||||
{
|
||||
RulesRequest = null;
|
||||
|
||||
if ( Success )
|
||||
{
|
||||
Rules = rules;
|
||||
}
|
||||
|
||||
if ( OnReceivedRules != null )
|
||||
{
|
||||
OnReceivedRules( Success );
|
||||
}
|
||||
}
|
||||
|
||||
internal const uint k_unFavoriteFlagNone = 0x00;
|
||||
internal const uint k_unFavoriteFlagFavorite = 0x01; // this game favorite entry is for the favorites list
|
||||
internal const uint k_unFavoriteFlagHistory = 0x02; // this game favorite entry is for the history list
|
||||
|
||||
/// <summary>
|
||||
/// Add this server to our history list
|
||||
/// If we're already in the history list, weill set the last played time to now
|
||||
/// </summary>
|
||||
public void AddToHistory()
|
||||
{
|
||||
Client.native.matchmaking.AddFavoriteGame( AppId, Utility.IpToInt32( Address ), (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory, (uint)Utility.Epoch.Current );
|
||||
Client.ServerList.UpdateFavouriteList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove this server from our history list
|
||||
/// </summary>
|
||||
public void RemoveFromHistory()
|
||||
{
|
||||
Client.native.matchmaking.RemoveFavoriteGame( AppId, Utility.IpToInt32( Address ), (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagHistory );
|
||||
Client.ServerList.UpdateFavouriteList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add this server to our favourite list
|
||||
/// </summary>
|
||||
public void AddToFavourites()
|
||||
{
|
||||
Client.native.matchmaking.AddFavoriteGame( AppId, Utility.IpToInt32( Address ), (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite, (uint)Utility.Epoch.Current );
|
||||
Client.ServerList.UpdateFavouriteList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove this server from our favourite list
|
||||
/// </summary>
|
||||
public void RemoveFromFavourites()
|
||||
{
|
||||
Client.native.matchmaking.RemoveFavoriteGame( AppId, Utility.IpToInt32( Address ), (ushort)ConnectionPort, (ushort)QueryPort, k_unFavoriteFlagFavorite );
|
||||
Client.ServerList.UpdateFavouriteList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class ServerList : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
internal ServerList( Client client )
|
||||
{
|
||||
this.client = client;
|
||||
|
||||
UpdateFavouriteList();
|
||||
}
|
||||
|
||||
HashSet<ulong> FavouriteHash = new HashSet<ulong>();
|
||||
HashSet<ulong> HistoryHash = new HashSet<ulong>();
|
||||
|
||||
internal void UpdateFavouriteList()
|
||||
{
|
||||
FavouriteHash.Clear();
|
||||
HistoryHash.Clear();
|
||||
|
||||
for ( int i=0; i< client.native.matchmaking.GetFavoriteGameCount(); i++ )
|
||||
{
|
||||
AppId_t appid = 0;
|
||||
uint ip;
|
||||
ushort conPort;
|
||||
ushort queryPort;
|
||||
uint lastplayed;
|
||||
uint flags;
|
||||
|
||||
client.native.matchmaking.GetFavoriteGame( i, ref appid, out ip, out conPort, out queryPort, out flags, out lastplayed );
|
||||
|
||||
ulong encoded = ip;
|
||||
encoded = encoded << 32;
|
||||
encoded = encoded | (uint)conPort;
|
||||
|
||||
if ( ( flags & Server.k_unFavoriteFlagFavorite ) == Server.k_unFavoriteFlagFavorite )
|
||||
FavouriteHash.Add( encoded );
|
||||
|
||||
if ( ( flags & Server.k_unFavoriteFlagFavorite ) == Server.k_unFavoriteFlagFavorite )
|
||||
HistoryHash.Add( encoded );
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
public class Filter : List<KeyValuePair<string, string>>
|
||||
{
|
||||
public void Add( string k, string v )
|
||||
{
|
||||
Add( new KeyValuePair<string, string>( k, v ) );
|
||||
}
|
||||
|
||||
internal IntPtr NativeArray;
|
||||
private IntPtr m_pArrayEntries;
|
||||
|
||||
private int AppId = 0;
|
||||
|
||||
internal void Start()
|
||||
{
|
||||
var filters = this.Select( x =>
|
||||
{
|
||||
if ( x.Key == "appid" ) AppId = int.Parse( x.Value );
|
||||
|
||||
return new SteamNative.MatchMakingKeyValuePair_t()
|
||||
{
|
||||
Key = x.Key,
|
||||
Value = x.Value
|
||||
};
|
||||
} ).ToArray();
|
||||
|
||||
int sizeOfMMKVP = Marshal.SizeOf(typeof(SteamNative.MatchMakingKeyValuePair_t));
|
||||
NativeArray = Marshal.AllocHGlobal( Marshal.SizeOf( typeof( IntPtr ) ) * filters.Length );
|
||||
m_pArrayEntries = Marshal.AllocHGlobal( sizeOfMMKVP * filters.Length );
|
||||
|
||||
for ( int i = 0; i < filters.Length; ++i )
|
||||
{
|
||||
Marshal.StructureToPtr( filters[i], new IntPtr( m_pArrayEntries.ToInt64() + ( i * sizeOfMMKVP ) ), false );
|
||||
}
|
||||
|
||||
Marshal.WriteIntPtr( NativeArray, m_pArrayEntries );
|
||||
}
|
||||
|
||||
internal void Free()
|
||||
{
|
||||
if ( m_pArrayEntries != IntPtr.Zero )
|
||||
{
|
||||
Marshal.FreeHGlobal( m_pArrayEntries );
|
||||
}
|
||||
|
||||
if ( NativeArray != IntPtr.Zero )
|
||||
{
|
||||
Marshal.FreeHGlobal( NativeArray );
|
||||
}
|
||||
}
|
||||
|
||||
internal bool Test( gameserveritem_t info )
|
||||
{
|
||||
if ( AppId != 0 && AppId != info.AppID )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
private struct MatchPair
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string key;
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Request Internet( Filter filter = null )
|
||||
{
|
||||
if ( filter == null )
|
||||
{
|
||||
filter = new Filter();
|
||||
filter.Add( "appid", client.AppId.ToString() );
|
||||
}
|
||||
|
||||
filter.Start();
|
||||
|
||||
var request = new Request( client );
|
||||
request.Filter = filter;
|
||||
request.AddRequest( client.native.servers.RequestInternetServerList( client.AppId, filter.NativeArray, (uint) filter.Count, IntPtr.Zero ) );
|
||||
|
||||
filter.Free();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Query a list of addresses. No filters applied.
|
||||
/// </summary>
|
||||
public Request Custom( IEnumerable<string> serverList )
|
||||
{
|
||||
var request = new Request( client );
|
||||
request.ServerList = serverList;
|
||||
request.StartCustomQuery();
|
||||
return request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a list of servers we've been on. History isn't applied automatically
|
||||
/// You need to call server.AddtoHistoryList() when you join a server etc.
|
||||
/// </summary>
|
||||
public Request History( Filter filter = null )
|
||||
{
|
||||
if ( filter == null )
|
||||
{
|
||||
filter = new Filter();
|
||||
filter.Add( "appid", client.AppId.ToString() );
|
||||
}
|
||||
|
||||
filter.Start();
|
||||
|
||||
var request = new Request( client );
|
||||
request.Filter = filter;
|
||||
request.AddRequest( client.native.servers.RequestHistoryServerList( client.AppId, filter.NativeArray, (uint)filter.Count, IntPtr.Zero ) );
|
||||
|
||||
filter.Free();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a list of servers we've favourited
|
||||
/// </summary>
|
||||
public Request Favourites( Filter filter = null )
|
||||
{
|
||||
if ( filter == null )
|
||||
{
|
||||
filter = new Filter();
|
||||
filter.Add( "appid", client.AppId.ToString() );
|
||||
}
|
||||
|
||||
filter.Start();
|
||||
|
||||
var request = new Request( client );
|
||||
request.Filter = filter;
|
||||
request.AddRequest( client.native.servers.RequestFavoritesServerList( client.AppId, filter.NativeArray, (uint)filter.Count, IntPtr.Zero ) );
|
||||
|
||||
filter.Free();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a list of servers that our friends are on
|
||||
/// </summary>
|
||||
public Request Friends( Filter filter = null )
|
||||
{
|
||||
if ( filter == null )
|
||||
{
|
||||
filter = new Filter();
|
||||
filter.Add( "appid", client.AppId.ToString() );
|
||||
}
|
||||
|
||||
filter.Start();
|
||||
|
||||
var request = new Request( client );
|
||||
request.Filter = filter;
|
||||
request.AddRequest( client.native.servers.RequestFriendsServerList( client.AppId, filter.NativeArray, (uint)filter.Count, IntPtr.Zero ) );
|
||||
|
||||
filter.Free();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request a list of servers that are running on our LAN
|
||||
/// </summary>
|
||||
public Request Local( Filter filter = null )
|
||||
{
|
||||
if ( filter == null )
|
||||
{
|
||||
filter = new Filter();
|
||||
filter.Add( "appid", client.AppId.ToString() );
|
||||
}
|
||||
|
||||
filter.Start();
|
||||
|
||||
var request = new Request( client );
|
||||
request.Filter = filter;
|
||||
request.AddRequest( client.native.servers.RequestLANServerList( client.AppId, IntPtr.Zero ) );
|
||||
|
||||
filter.Free();
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
internal bool IsFavourite( Server server )
|
||||
{
|
||||
ulong encoded = Utility.IpToInt32( server.Address );
|
||||
encoded = encoded << 32;
|
||||
encoded = encoded | (uint)server.ConnectionPort;
|
||||
|
||||
return FavouriteHash.Contains( encoded );
|
||||
}
|
||||
|
||||
internal bool IsHistory( Server server )
|
||||
{
|
||||
ulong encoded = Utility.IpToInt32( server.Address );
|
||||
encoded = encoded << 32;
|
||||
encoded = encoded | (uint)server.ConnectionPort;
|
||||
|
||||
return HistoryHash.Contains( encoded );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class Stats : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
|
||||
internal Stats( Client c )
|
||||
{
|
||||
client = c;
|
||||
}
|
||||
|
||||
public bool StoreStats()
|
||||
{
|
||||
return client.native.userstats.StoreStats();
|
||||
}
|
||||
|
||||
public void UpdateStats()
|
||||
{
|
||||
client.native.userstats.RequestCurrentStats();
|
||||
}
|
||||
|
||||
public void UpdateGlobalStats( int days = 1 )
|
||||
{
|
||||
client.native.userstats.GetNumberOfCurrentPlayers();
|
||||
client.native.userstats.RequestGlobalAchievementPercentages();
|
||||
client.native.userstats.RequestGlobalStats( days );
|
||||
}
|
||||
|
||||
public int GetInt( string name )
|
||||
{
|
||||
int data = 0;
|
||||
client.native.userstats.GetStat( name, out data );
|
||||
return data;
|
||||
}
|
||||
|
||||
public long GetGlobalInt( string name )
|
||||
{
|
||||
long data = 0;
|
||||
client.native.userstats.GetGlobalStat( name, out data );
|
||||
return data;
|
||||
}
|
||||
|
||||
public float GetFloat( string name )
|
||||
{
|
||||
float data = 0;
|
||||
client.native.userstats.GetStat0( name, out data );
|
||||
return data;
|
||||
}
|
||||
|
||||
public double GetGlobalFloat( string name )
|
||||
{
|
||||
double data = 0;
|
||||
client.native.userstats.GetGlobalStat0( name, out data );
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a stat value. This will automatically call StoreStats() after a successful call
|
||||
/// unless you pass false as the last argument.
|
||||
/// </summary>
|
||||
public bool Set( string name, int value, bool store = true )
|
||||
{
|
||||
var r = client.native.userstats.SetStat( name, value );
|
||||
|
||||
if ( store )
|
||||
{
|
||||
return r && client.native.userstats.StoreStats();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a stat value. This will automatically call StoreStats() after a successful call
|
||||
/// unless you pass false as the last argument.
|
||||
/// </summary>
|
||||
public bool Set( string name, float value, bool store = true )
|
||||
{
|
||||
var r = client.native.userstats.SetStat0( name, value );
|
||||
|
||||
if ( store )
|
||||
{
|
||||
return r && client.native.userstats.StoreStats();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds this amount to the named stat. Internally this calls Get() and adds
|
||||
/// to that value. Steam doesn't provide a mechanism for atomically increasing
|
||||
/// stats like this, this functionality is added here as a convenience.
|
||||
/// </summary>
|
||||
public bool Add( string name, int amount = 1, bool store = true )
|
||||
{
|
||||
var val = GetInt( name );
|
||||
val += amount;
|
||||
return Set( name, val, store );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds this amount to the named stat. Internally this calls Get() and adds
|
||||
/// to that value. Steam doesn't provide a mechanism for atomically increasing
|
||||
/// stats like this, this functionality is added here as a convenience.
|
||||
/// </summary>
|
||||
public bool Add(string name, float amount = 1.0f, bool store = true)
|
||||
{
|
||||
var val = GetFloat(name);
|
||||
val += amount;
|
||||
return Set(name, val, store);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Practically wipes the slate clean for this user. If includeAchievements is true, will wipe
|
||||
/// any achievements too.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ResetAll( bool includeAchievements )
|
||||
{
|
||||
return client.native.userstats.ResetAllStats( includeAchievements );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class SteamFriend
|
||||
{
|
||||
/// <summary>
|
||||
/// Steam Id
|
||||
/// </summary>
|
||||
public ulong Id { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return true if blocked
|
||||
/// </summary>
|
||||
public bool IsBlocked => relationship == FriendRelationship.Blocked;
|
||||
|
||||
/// <summary>
|
||||
/// Return true if is a friend. Returns false if blocked, request etc.
|
||||
/// </summary>
|
||||
public bool IsFriend => relationship == FriendRelationship.Friend;
|
||||
|
||||
/// <summary>
|
||||
/// Their current display name
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this friend is online
|
||||
/// </summary>
|
||||
public bool IsOnline => personaState != PersonaState.Offline;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this friend is marked as away
|
||||
/// </summary>
|
||||
public bool IsAway => personaState == PersonaState.Away;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this friend is marked as busy
|
||||
/// </summary>
|
||||
public bool IsBusy => personaState == PersonaState.Busy;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this friend is marked as snoozing
|
||||
/// </summary>
|
||||
public bool IsSnoozing => personaState == PersonaState.Snooze;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this friend is online and playing this game
|
||||
/// </summary>
|
||||
public bool IsPlayingThisGame => CurrentAppId == Client.AppId;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this friend is online and playing this game
|
||||
/// </summary>
|
||||
public bool IsPlaying => CurrentAppId != 0;
|
||||
|
||||
/// <summary>
|
||||
/// The AppId this guy is playing
|
||||
/// </summary>
|
||||
public ulong CurrentAppId { get; internal set; }
|
||||
|
||||
public uint ServerIp { get; internal set; }
|
||||
public int ServerGamePort { get; internal set; }
|
||||
public int ServerQueryPort { get; internal set; }
|
||||
public ulong ServerLobbyId { get; internal set; }
|
||||
|
||||
internal Client Client { get; set; }
|
||||
private PersonaState personaState;
|
||||
private FriendRelationship relationship;
|
||||
|
||||
/// <summary>
|
||||
/// Returns null if the value doesn't exist
|
||||
/// </summary>
|
||||
public string GetRichPresence( string key )
|
||||
{
|
||||
var val = Client.native.friends.GetFriendRichPresence( Id, key );
|
||||
if ( string.IsNullOrEmpty( val ) ) return null;
|
||||
return val;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update this friend, request the latest data from Steam's servers
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
Name = Client.native.friends.GetFriendPersonaName( Id );
|
||||
|
||||
relationship = Client.native.friends.GetFriendRelationship( Id );
|
||||
personaState = Client.native.friends.GetFriendPersonaState( Id );
|
||||
|
||||
CurrentAppId = 0;
|
||||
ServerIp = 0;
|
||||
ServerGamePort = 0;
|
||||
ServerQueryPort = 0;
|
||||
ServerLobbyId = 0;
|
||||
|
||||
var gameInfo = new SteamNative.FriendGameInfo_t();
|
||||
if ( Client.native.friends.GetFriendGamePlayed( Id, ref gameInfo ) && gameInfo.GameID > 0 )
|
||||
{
|
||||
CurrentAppId = gameInfo.GameID;
|
||||
ServerIp = gameInfo.GameIP;
|
||||
ServerGamePort = gameInfo.GamePort;
|
||||
ServerQueryPort = gameInfo.QueryPort;
|
||||
ServerLobbyId = gameInfo.SteamIDLobby;
|
||||
}
|
||||
|
||||
Client.native.friends.RequestFriendRichPresence( Id );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This will return null if you don't have the target user's avatar in your cache.
|
||||
/// Which usually happens for people not on your friends list.
|
||||
/// </summary>
|
||||
public Image GetAvatar( Friends.AvatarSize size )
|
||||
{
|
||||
return Client.Friends.GetCachedAvatar( size, Id );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invite this friend to the game that we are playing
|
||||
/// </summary>
|
||||
public bool InviteToGame(string Text)
|
||||
{
|
||||
return Client.native.friends.InviteUserToGame(Id, Text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a message to a Steam friend. Returns true if success
|
||||
/// </summary>
|
||||
public bool SendMessage( string message )
|
||||
{
|
||||
return Client.native.friends.ReplyToFriendMessage( Id, message );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class User : IDisposable
|
||||
{
|
||||
internal Client client;
|
||||
internal Dictionary<string, string> richPresence = new Dictionary<string, string>();
|
||||
|
||||
internal User( Client c )
|
||||
{
|
||||
client = c;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
client = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a rich presence value by key for current user. Will be null if not found.
|
||||
/// </summary>
|
||||
public string GetRichPresence( string key )
|
||||
{
|
||||
if ( richPresence.TryGetValue( key, out var val ) )
|
||||
return val;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a rich presence value by key for current user.
|
||||
/// </summary>
|
||||
public bool SetRichPresence( string key, string value )
|
||||
{
|
||||
richPresence[key] = value;
|
||||
return client.native.friends.SetRichPresence( key, value );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all of the current user's rich presence data.
|
||||
/// </summary>
|
||||
public void ClearRichPresence()
|
||||
{
|
||||
richPresence.Clear();
|
||||
client.native.friends.ClearRichPresence();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class Voice
|
||||
{
|
||||
const int ReadBufferSize = 1024 * 128;
|
||||
|
||||
internal Client client;
|
||||
|
||||
internal byte[] ReadCompressedBuffer = new byte[ReadBufferSize];
|
||||
internal byte[] ReadUncompressedBuffer = new byte[ReadBufferSize];
|
||||
|
||||
internal byte[] UncompressBuffer = new byte[1024 * 256];
|
||||
|
||||
public Action<byte[], int> OnCompressedData;
|
||||
public Action<byte[], int> OnUncompressedData;
|
||||
|
||||
private System.Diagnostics.Stopwatch UpdateTimer = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the optimal sample rate for voice - according to Steam
|
||||
/// </summary>
|
||||
public uint OptimalSampleRate
|
||||
{
|
||||
get { return client.native.user.GetVoiceOptimalSampleRate(); }
|
||||
}
|
||||
|
||||
private bool _wantsrecording = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If set to true we are listening to the mic.
|
||||
/// You should usually toggle this with the press of a key for push to talk.
|
||||
/// </summary>
|
||||
public bool WantsRecording
|
||||
{
|
||||
get { return _wantsrecording; }
|
||||
set
|
||||
{
|
||||
_wantsrecording = value;
|
||||
|
||||
if ( value )
|
||||
{
|
||||
client.native.user.StartVoiceRecording();
|
||||
}
|
||||
else
|
||||
{
|
||||
client.native.user.StopVoiceRecording();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The last time voice was detected, recorded
|
||||
/// </summary>
|
||||
public DateTime LastVoiceRecordTime { get; private set; }
|
||||
|
||||
public TimeSpan TimeSinceLastVoiceRecord { get { return DateTime.Now.Subtract( LastVoiceRecordTime ); } }
|
||||
|
||||
public bool IsRecording = false;
|
||||
|
||||
/// <summary>
|
||||
/// If set we will capture the audio at this rate. If unset (set to 0) will capture at OptimalSampleRate
|
||||
/// </summary>
|
||||
public uint DesiredSampleRate = 0;
|
||||
|
||||
internal Voice( Client client )
|
||||
{
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This gets called inside Update - so there's no need to call this manually if you're calling update
|
||||
/// </summary>
|
||||
public unsafe void Update()
|
||||
{
|
||||
if ( OnCompressedData == null && OnUncompressedData == null )
|
||||
return;
|
||||
|
||||
if ( UpdateTimer.Elapsed.TotalSeconds < 1.0f / 10.0f )
|
||||
return;
|
||||
|
||||
UpdateTimer.Reset();
|
||||
UpdateTimer.Start();
|
||||
|
||||
uint bufferRegularLastWrite = 0;
|
||||
uint bufferCompressedLastWrite = 0;
|
||||
|
||||
var result = client.native.user.GetAvailableVoice( out bufferCompressedLastWrite, out bufferRegularLastWrite, DesiredSampleRate == 0 ? OptimalSampleRate : DesiredSampleRate );
|
||||
|
||||
if ( result == SteamNative.VoiceResult.NotRecording || result == SteamNative.VoiceResult.NotInitialized )
|
||||
{
|
||||
IsRecording = false;
|
||||
return;
|
||||
}
|
||||
|
||||
fixed (byte* compressedPtr = ReadCompressedBuffer)
|
||||
fixed (byte* uncompressedPtr = ReadUncompressedBuffer)
|
||||
{
|
||||
result = client.native.user.GetVoice( OnCompressedData != null, (IntPtr) compressedPtr, ReadBufferSize, out bufferCompressedLastWrite,
|
||||
OnUncompressedData != null, (IntPtr) uncompressedPtr, ReadBufferSize, out bufferRegularLastWrite,
|
||||
DesiredSampleRate == 0 ? OptimalSampleRate : DesiredSampleRate );
|
||||
}
|
||||
|
||||
IsRecording = true;
|
||||
|
||||
if ( result == SteamNative.VoiceResult.OK )
|
||||
{
|
||||
if ( OnCompressedData != null && bufferCompressedLastWrite > 0 )
|
||||
{
|
||||
OnCompressedData( ReadCompressedBuffer, (int)bufferCompressedLastWrite );
|
||||
}
|
||||
|
||||
if ( OnUncompressedData != null && bufferRegularLastWrite > 0 )
|
||||
{
|
||||
OnUncompressedData( ReadUncompressedBuffer, (int)bufferRegularLastWrite );
|
||||
}
|
||||
|
||||
LastVoiceRecordTime = DateTime.Now;
|
||||
}
|
||||
|
||||
if ( result == SteamNative.VoiceResult.NotRecording ||
|
||||
result == SteamNative.VoiceResult.NotInitialized )
|
||||
IsRecording = false;
|
||||
|
||||
}
|
||||
|
||||
public bool Decompress( byte[] input, MemoryStream output, uint samepleRate = 0 )
|
||||
{
|
||||
return Decompress( input, 0, input.Length, output, samepleRate );
|
||||
}
|
||||
|
||||
public bool Decompress( byte[] input, int inputsize, MemoryStream output, uint samepleRate = 0 )
|
||||
{
|
||||
return Decompress( input, 0, inputsize, output, samepleRate );
|
||||
}
|
||||
|
||||
public unsafe bool Decompress( byte[] input, int inputoffset, int inputsize, MemoryStream output, uint samepleRate = 0 )
|
||||
{
|
||||
if ( inputoffset < 0 || inputoffset >= input.Length )
|
||||
throw new ArgumentOutOfRangeException( "inputoffset" );
|
||||
|
||||
if ( inputsize <= 0 || inputoffset + inputsize > input.Length )
|
||||
throw new ArgumentOutOfRangeException( "inputsize" );
|
||||
|
||||
fixed ( byte* p = input )
|
||||
{
|
||||
return Decompress( (IntPtr)p, inputoffset, inputsize, output, samepleRate );
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe bool Decompress( IntPtr input, int inputoffset, int inputsize, MemoryStream output, uint samepleRate = 0 )
|
||||
{
|
||||
if ( samepleRate == 0 )
|
||||
samepleRate = OptimalSampleRate;
|
||||
|
||||
uint bytesOut = 0;
|
||||
|
||||
SteamNative.VoiceResult result = SteamNative.VoiceResult.NoData;
|
||||
|
||||
fixed ( byte* outBuf = UncompressBuffer )
|
||||
{
|
||||
result = client.native.user.DecompressVoice( (IntPtr)(((byte*)input) + inputoffset), (uint)inputsize, (IntPtr)outBuf, (uint)UncompressBuffer.Length, out bytesOut, samepleRate );
|
||||
}
|
||||
|
||||
if ( result == SteamNative.VoiceResult.OK )
|
||||
{
|
||||
output.Write( (byte[])UncompressBuffer, 0, (int)bytesOut );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public static class Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Should be called before creating any interfaces, to configure Steam for Unity.
|
||||
/// </summary>
|
||||
/// <param name="platform">Please pass in Application.platform.ToString()</param>
|
||||
public static void ForUnity( string platform )
|
||||
{
|
||||
//
|
||||
// Windows Config
|
||||
//
|
||||
if ( platform == "WindowsEditor" || platform == "WindowsPlayer" )
|
||||
{
|
||||
//
|
||||
// 32bit windows unity uses a stdcall
|
||||
//
|
||||
if (IntPtr.Size == 4) UseThisCall = false;
|
||||
|
||||
ForcePlatform( OperatingSystem.Windows, IntPtr.Size == 4 ? Architecture.x86 : Architecture.x64 );
|
||||
}
|
||||
|
||||
if ( platform == "OSXEditor" || platform == "OSXPlayer" || platform == "OSXDashboardPlayer" )
|
||||
{
|
||||
ForcePlatform( OperatingSystem.macOS, IntPtr.Size == 4 ? Architecture.x86 : Architecture.x64 );
|
||||
}
|
||||
|
||||
if ( platform == "LinuxPlayer" || platform == "LinuxEditor" )
|
||||
{
|
||||
ForcePlatform( OperatingSystem.Linux, IntPtr.Size == 4 ? Architecture.x86 : Architecture.x64 );
|
||||
}
|
||||
|
||||
Console.WriteLine( "Facepunch.Steamworks Unity: " + platform );
|
||||
Console.WriteLine( "Facepunch.Steamworks Os: " + SteamNative.Platform.Os );
|
||||
Console.WriteLine( "Facepunch.Steamworks Arch: " + SteamNative.Platform.Arch );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Some platforms allow/need CallingConvention.ThisCall. If you're crashing with argument null
|
||||
/// errors on certain platforms, try flipping this to true.
|
||||
///
|
||||
/// I owe this logic to Riley Labrecque's hard work on Steamworks.net - I don't have the knowledge
|
||||
/// or patience to find this shit on my own, so massive thanks to him. And also massive thanks to him
|
||||
/// for releasing his shit open source under the MIT license so we can all learn and iterate.
|
||||
///
|
||||
/// </summary>
|
||||
public static bool UseThisCall { get; set; } = true;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// You can force the platform to a particular one here.
|
||||
/// This is useful if you're on OSX because some versions of mono don't have a way
|
||||
/// to tell which platform we're running
|
||||
/// </summary>
|
||||
public static void ForcePlatform( Facepunch.Steamworks.OperatingSystem os, Facepunch.Steamworks.Architecture arch )
|
||||
{
|
||||
SteamNative.Platform.Os = os;
|
||||
SteamNative.Platform.Arch = arch;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
<TargetFrameworks>net45;net35;net40</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyName>Facepunch.Steamworks</AssemblyName>
|
||||
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<NoWarn>1701;1702;1705;618;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DefineConstants>TRACE;RELEASE</DefineConstants>
|
||||
<NoWarn>1701;1702;1705;618;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<DefineConstants>$(DefineConstants);NET_CORE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="*AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Server.cs">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="steam_api.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="steam_api64.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<FrameworkPathOverride Condition="'$(TargetFramework)' == 'net35'">C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client</FrameworkPathOverride>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<FrameworkPathOverride Condition="'$(TargetFramework)' == 'net40'">C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client</FrameworkPathOverride>
|
||||
<Authors>Garry Newman</Authors>
|
||||
<PackageId>Facepunch.Steamworks</PackageId>
|
||||
<PackageDescription>Another fucking c# Steamworks implementation</PackageDescription>
|
||||
<PackageProjectUrl>https://github.com/Facepunch/Facepunch.Steamworks</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/Facepunch/Facepunch.Steamworks/blob/master/LICENSE</PackageLicenseUrl>
|
||||
<PackageIconUrl>https://avatars2.githubusercontent.com/u/3371040</PackageIconUrl>
|
||||
<PackageTags>facepunch;steam;unity;steamworks;valve</PackageTags>
|
||||
<PackageVersion>0.7.5</PackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,365 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Inventory
|
||||
{
|
||||
/// <summary>
|
||||
/// An item definition. This describes an item in your Steam inventory, but is
|
||||
/// not unique to that item. For example, this might be a tshirt, but you might be able to own
|
||||
/// multiple tshirts.
|
||||
/// </summary>
|
||||
public class Definition
|
||||
{
|
||||
internal Inventory inventory;
|
||||
|
||||
public int Id { get; private set; }
|
||||
public string Name { get; set; }
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// URL to an image specified by the schema, else empty
|
||||
/// </summary>
|
||||
public string IconUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// URL to an image specified by the schema, else empty
|
||||
/// </summary>
|
||||
public string IconLargeUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Type can be whatever the schema defines.
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If this item can be created using other items this string will contain a comma seperated
|
||||
/// list of definition ids that can be used, ie "100,101;102x5;103x3,104x3"
|
||||
/// </summary>
|
||||
public string ExchangeSchema { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of recepies for creating this item. Can be null if none.
|
||||
/// </summary>
|
||||
public Recipe[] Recipes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of recepies we're included in
|
||||
/// </summary>
|
||||
public Recipe[] IngredientFor { get; set; }
|
||||
|
||||
public DateTime Created { get; set; }
|
||||
public DateTime Modified { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The raw contents of price_category from the schema
|
||||
/// </summary>
|
||||
public string PriceCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The dollar price from PriceRaw
|
||||
/// </summary>
|
||||
public double PriceDollars { get; internal set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The price in the local player's currency. The local player's currency
|
||||
/// is available in Invetory.Currency
|
||||
/// </summary>
|
||||
public double LocalPrice { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Local Price but probably how you want to display it (ie, $3.99, £1.99 etc )
|
||||
/// </summary>
|
||||
public string LocalPriceFormatted { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this item can be sold on the marketplace
|
||||
/// </summary>
|
||||
public bool Marketable { get; set; }
|
||||
|
||||
public bool IsGenerator
|
||||
{
|
||||
get { return Type == "generator"; }
|
||||
}
|
||||
|
||||
private Dictionary<string, string> customProperties;
|
||||
|
||||
internal Definition( Inventory i, int id )
|
||||
{
|
||||
inventory = i;
|
||||
Id = id;
|
||||
|
||||
SetupCommonProperties();
|
||||
UpdatePrice();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If you're manually occupying the Definition (because maybe you're on a server
|
||||
/// and want to hack around the fact that definitions aren't presented to you),
|
||||
/// you can use this to set propertis.
|
||||
/// </summary>
|
||||
public void SetProperty( string name, string value )
|
||||
{
|
||||
if ( customProperties == null )
|
||||
customProperties = new Dictionary<string, string>();
|
||||
|
||||
if ( !customProperties.ContainsKey( name ) )
|
||||
customProperties.Add( name, value );
|
||||
else
|
||||
customProperties[name] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a raw property from the definition schema
|
||||
/// </summary>
|
||||
public T GetProperty<T>( string name )
|
||||
{
|
||||
string val = GetStringProperty( name );
|
||||
|
||||
if ( string.IsNullOrEmpty( val ) )
|
||||
return default( T );
|
||||
|
||||
try
|
||||
{
|
||||
return (T)Convert.ChangeType( val, typeof( T ) );
|
||||
}
|
||||
catch ( System.Exception )
|
||||
{
|
||||
return default( T );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a raw property from the definition schema
|
||||
/// </summary>
|
||||
public string GetStringProperty( string name )
|
||||
{
|
||||
string val = string.Empty;
|
||||
|
||||
if ( customProperties != null && customProperties.ContainsKey( name ) )
|
||||
return customProperties[name];
|
||||
|
||||
if ( !inventory.inventory.GetItemDefinitionProperty( Id, name, out val ) )
|
||||
return string.Empty;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a raw property from the definition schema
|
||||
/// </summary>
|
||||
public bool GetBoolProperty( string name )
|
||||
{
|
||||
string val = GetStringProperty( name );
|
||||
|
||||
if ( val.Length == 0 ) return false;
|
||||
if ( val[0] == '0' || val[0] == 'F'|| val[0] == 'f' ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void SetupCommonProperties()
|
||||
{
|
||||
Name = GetStringProperty( "name" );
|
||||
Description = GetStringProperty( "description" );
|
||||
Created = GetProperty<DateTime>( "timestamp" );
|
||||
Modified = GetProperty<DateTime>( "modified" );
|
||||
ExchangeSchema = GetStringProperty( "exchange" );
|
||||
IconUrl = GetStringProperty( "icon_url" );
|
||||
IconLargeUrl = GetStringProperty( "icon_url_large" );
|
||||
Type = GetStringProperty( "type" );
|
||||
PriceCategory = GetStringProperty( "price_category" );
|
||||
Marketable = GetBoolProperty( "marketable" );
|
||||
|
||||
if ( !string.IsNullOrEmpty( PriceCategory ) )
|
||||
{
|
||||
PriceDollars = PriceCategoryToFloat( PriceCategory );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trigger an item drop. Call this when it's a good time to award
|
||||
/// an item drop to a player. This won't automatically result in giving
|
||||
/// an item to a player. Just call it every minute or so, or on launch.
|
||||
/// ItemDefinition is usually a generator
|
||||
/// </summary>
|
||||
public void TriggerItemDrop()
|
||||
{
|
||||
inventory.TriggerItemDrop( Id );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trigger a promo item drop. You can call this at startup, it won't
|
||||
/// give users multiple promo drops.
|
||||
/// </summary>
|
||||
public void TriggerPromoDrop()
|
||||
{
|
||||
inventory.TriggerPromoDrop( Id );
|
||||
}
|
||||
|
||||
internal void Link( Definition[] definitions )
|
||||
{
|
||||
LinkExchange( definitions );
|
||||
}
|
||||
|
||||
private void LinkExchange( Definition[] definitions )
|
||||
{
|
||||
if ( string.IsNullOrEmpty( ExchangeSchema ) ) return;
|
||||
|
||||
var parts = ExchangeSchema.Split( new[] { ';' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
|
||||
Recipes = parts.Select( x => Recipe.FromString( x, definitions, this ) ).ToArray();
|
||||
}
|
||||
|
||||
internal void InRecipe( Recipe r )
|
||||
{
|
||||
if ( IngredientFor == null )
|
||||
IngredientFor = new Recipe[0];
|
||||
|
||||
var list = new List<Recipe>( IngredientFor );
|
||||
list.Add( r );
|
||||
|
||||
IngredientFor = list.ToArray();
|
||||
}
|
||||
|
||||
internal void UpdatePrice()
|
||||
{
|
||||
if ( inventory.inventory.GetItemPrice( Id, out ulong price) )
|
||||
{
|
||||
LocalPrice = price / 100.0;
|
||||
LocalPriceFormatted = Utility.FormatPrice( inventory.Currency, price );
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalPrice = 0;
|
||||
LocalPriceFormatted = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trigger a promo item drop. You can call this at startup, it won't
|
||||
/// give users multiple promo drops.
|
||||
/// </summary>
|
||||
public void TriggerPromoDrop( int definitionId )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t result = 0;
|
||||
inventory.AddPromoItem( ref result, definitionId );
|
||||
inventory.DestroyResult( result );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trigger an item drop for this user. This is for timed drops. For promo
|
||||
/// drops use TriggerPromoDrop.
|
||||
/// </summary>
|
||||
public void TriggerItemDrop( int definitionId )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t result = 0;
|
||||
inventory.TriggerItemDrop( ref result, definitionId );
|
||||
inventory.DestroyResult( result );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Grant all promotional items the user is eligible for.
|
||||
/// </summary>
|
||||
public void GrantAllPromoItems()
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t result = 0;
|
||||
inventory.GrantPromoItems( ref result );
|
||||
inventory.DestroyResult( result );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a crafting recepie which was defined using the exchange
|
||||
/// section in the item schema.
|
||||
/// </summary>
|
||||
public struct Recipe
|
||||
{
|
||||
public struct Ingredient
|
||||
{
|
||||
/// <summary>
|
||||
/// The definition ID of the ingredient.
|
||||
/// </summary>
|
||||
public int DefinitionId;
|
||||
|
||||
/// <summary>
|
||||
/// 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 Definition Definition;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of this item needed. Generally this will be 1.
|
||||
/// </summary>
|
||||
public int Count;
|
||||
|
||||
internal static Ingredient FromString( string part, Definition[] definitions )
|
||||
{
|
||||
var i = new Ingredient();
|
||||
i.Count = 1;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
if ( part.Contains( 'x' ) )
|
||||
{
|
||||
var idx = part.IndexOf( 'x' );
|
||||
|
||||
int count = 0;
|
||||
if ( int.TryParse( part.Substring( idx + 1 ), out count ) )
|
||||
i.Count = count;
|
||||
|
||||
part = part.Substring( 0, idx );
|
||||
}
|
||||
|
||||
i.DefinitionId = int.Parse( part );
|
||||
i.Definition = definitions.FirstOrDefault( x => x.Id == i.DefinitionId );
|
||||
|
||||
}
|
||||
catch ( System.Exception )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The item that this will create.
|
||||
/// </summary>
|
||||
public Definition Result;
|
||||
|
||||
/// <summary>
|
||||
/// The items, with quantity required to create this item.
|
||||
/// </summary>
|
||||
public Ingredient[] Ingredients;
|
||||
|
||||
internal static Recipe FromString( string part, Definition[] definitions, Definition Result )
|
||||
{
|
||||
var r = new Recipe();
|
||||
r.Result = Result;
|
||||
var parts = part.Split( new[] { ',' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
|
||||
r.Ingredients = parts.Select( x => Ingredient.FromString( x, definitions ) ).Where( x => x.DefinitionId != 0 ).ToArray();
|
||||
|
||||
foreach ( var i in r.Ingredients )
|
||||
{
|
||||
if ( i.Definition == null )
|
||||
continue;
|
||||
|
||||
i.Definition.InRecipe( r );
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Inventory
|
||||
{
|
||||
/// <summary>
|
||||
/// An item in your inventory.
|
||||
/// </summary>
|
||||
public class Item : IEquatable<Item>
|
||||
{
|
||||
internal Item( Inventory Inventory, ulong Id, int Quantity, int DefinitionId )
|
||||
{
|
||||
this.Inventory = Inventory;
|
||||
this.Id = Id;
|
||||
this.Quantity = Quantity;
|
||||
this.DefinitionId = DefinitionId;
|
||||
}
|
||||
|
||||
public struct Amount
|
||||
{
|
||||
public Item Item;
|
||||
public int Quantity;
|
||||
}
|
||||
|
||||
public ulong Id;
|
||||
public int Quantity;
|
||||
|
||||
public int DefinitionId;
|
||||
|
||||
internal Inventory Inventory;
|
||||
|
||||
public Dictionary<string, string> Properties { get; internal set; }
|
||||
|
||||
private Definition _cachedDefinition;
|
||||
|
||||
/// <summary>
|
||||
/// Careful, this might not be available. Especially on a game server.
|
||||
/// </summary>
|
||||
public Definition Definition
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _cachedDefinition != null )
|
||||
return _cachedDefinition;
|
||||
|
||||
_cachedDefinition = Inventory.FindDefinition( DefinitionId );
|
||||
return _cachedDefinition;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TradeLocked;
|
||||
|
||||
public bool Equals(Item other)
|
||||
{
|
||||
if (ReferenceEquals(null, other)) return false;
|
||||
if (ReferenceEquals(this, other)) return true;
|
||||
return Id == other.Id;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((Item)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Id.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(Item left, Item right)
|
||||
{
|
||||
return Equals(left, right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Item left, Item right)
|
||||
{
|
||||
return !Equals(left, right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consumes items from a user's inventory. If the quantity of the given item goes to zero, it is permanently removed.
|
||||
/// Once an item is removed it cannot be recovered.This is not for the faint of heart - if your game implements item removal at all,
|
||||
/// a high-friction UI confirmation process is highly recommended.ConsumeItem can be restricted to certain item definitions or fully
|
||||
/// blocked via the Steamworks website to minimize support/abuse issues such as the classic "my brother borrowed my laptop and deleted all of my rare items".
|
||||
/// </summary>
|
||||
public Result Consume( int amount = 1 )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t resultHandle = -1;
|
||||
if ( !Inventory.inventory.ConsumeItem( ref resultHandle, Id, (uint)amount ) )
|
||||
return null;
|
||||
|
||||
return new Result( Inventory, resultHandle, true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Split stack into two items
|
||||
/// </summary>
|
||||
public Result SplitStack( int quantity = 1 )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t resultHandle = -1;
|
||||
if ( !Inventory.inventory.TransferItemQuantity( ref resultHandle, Id, (uint)quantity, ulong.MaxValue ) )
|
||||
return null;
|
||||
|
||||
return new Result( Inventory, resultHandle, true );
|
||||
}
|
||||
|
||||
SteamNative.SteamInventoryUpdateHandle_t updateHandle;
|
||||
|
||||
private void UpdatingProperties()
|
||||
{
|
||||
if (!Inventory.EnableItemProperties)
|
||||
throw new InvalidOperationException("Item properties are disabled.");
|
||||
|
||||
if (updateHandle != 0) return;
|
||||
|
||||
updateHandle = Inventory.inventory.StartUpdateProperties();
|
||||
}
|
||||
|
||||
public bool SetProperty( string name, string value )
|
||||
{
|
||||
UpdatingProperties();
|
||||
Properties[name] = value.ToString();
|
||||
return Inventory.inventory.SetProperty(updateHandle, Id, name, value);
|
||||
}
|
||||
|
||||
public bool SetProperty(string name, bool value)
|
||||
{
|
||||
UpdatingProperties();
|
||||
Properties[name] = value.ToString();
|
||||
return Inventory.inventory.SetProperty0(updateHandle, Id, name, value);
|
||||
}
|
||||
|
||||
public bool SetProperty(string name, long value)
|
||||
{
|
||||
UpdatingProperties();
|
||||
Properties[name] = value.ToString();
|
||||
return Inventory.inventory.SetProperty1(updateHandle, Id, name, value);
|
||||
}
|
||||
|
||||
public bool SetProperty(string name, float value)
|
||||
{
|
||||
UpdatingProperties();
|
||||
Properties[name] = value.ToString();
|
||||
return Inventory.inventory.SetProperty2(updateHandle, Id, name, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called to finalize any changes made using SetProperty
|
||||
/// </summary>
|
||||
public bool SubmitProperties()
|
||||
{
|
||||
if (updateHandle == 0)
|
||||
throw new Exception("SubmitProperties called without updating properties");
|
||||
|
||||
try
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t result = -1;
|
||||
|
||||
if (!Inventory.inventory.SubmitUpdateProperties(updateHandle, ref result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Inventory.inventory.DestroyResult(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
updateHandle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Inventory
|
||||
{
|
||||
public class Result : IDisposable
|
||||
{
|
||||
internal static Dictionary< int, Result > Pending;
|
||||
internal Inventory inventory;
|
||||
|
||||
private SteamNative.SteamInventoryResult_t Handle { get; set; } = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Called when result is successfully returned
|
||||
/// </summary>
|
||||
public Action<Result> OnResult;
|
||||
|
||||
/// <summary>
|
||||
/// Items that exist, or that have been created, or changed
|
||||
/// </summary>
|
||||
public Item[] Items { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Items that have been removed or somehow destroyed
|
||||
/// </summary>
|
||||
public Item[] Removed { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Items that have been consumed, like in a craft or something
|
||||
/// </summary>
|
||||
public Item[] Consumed { get; internal set; }
|
||||
|
||||
protected bool _gotResult = false;
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this result is still pending
|
||||
/// </summary>
|
||||
public bool IsPending
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _gotResult ) return false;
|
||||
|
||||
if ( Status() == Callbacks.Result.OK )
|
||||
{
|
||||
Fill();
|
||||
return false;
|
||||
}
|
||||
|
||||
return Status() == Callbacks.Result.Pending;
|
||||
}
|
||||
}
|
||||
|
||||
internal uint Timestamp { get; private set; }
|
||||
|
||||
internal bool IsSuccess
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( Items != null ) return true;
|
||||
if ( Handle == -1 ) return false;
|
||||
return Status() == Callbacks.Result.OK;
|
||||
}
|
||||
}
|
||||
|
||||
internal Callbacks.Result Status()
|
||||
{
|
||||
if ( Handle == -1 ) return Callbacks.Result.InvalidParam;
|
||||
return (Callbacks.Result)inventory.inventory.GetResultStatus( Handle );
|
||||
}
|
||||
|
||||
internal Result( Inventory inventory, int Handle, bool pending )
|
||||
{
|
||||
if ( pending )
|
||||
{
|
||||
Pending.Add( Handle, this );
|
||||
}
|
||||
|
||||
this.Handle = Handle;
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
|
||||
internal void Fill()
|
||||
{
|
||||
if ( _gotResult )
|
||||
return;
|
||||
|
||||
if ( Items != null )
|
||||
return;
|
||||
|
||||
if ( Status() != Callbacks.Result.OK )
|
||||
return;
|
||||
|
||||
_gotResult = true;
|
||||
|
||||
Timestamp = inventory.inventory.GetResultTimestamp( Handle );
|
||||
|
||||
SteamNative.SteamItemDetails_t[] steamItems = inventory.inventory.GetResultItems( Handle );
|
||||
|
||||
if ( steamItems == null )
|
||||
return;
|
||||
|
||||
var tempItems = new List<Item>();
|
||||
var tempRemoved = new List<Item>();
|
||||
var tempConsumed = new List<Item>();
|
||||
|
||||
for ( int i=0; i< steamItems.Length; i++ )
|
||||
{
|
||||
var item = inventory.ItemFrom( Handle, steamItems[i], i );
|
||||
if ( item == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ( steamItems[i].Flags & (int)SteamNative.SteamItemFlags.Removed ) != 0 )
|
||||
{
|
||||
tempRemoved.Add(item);
|
||||
}
|
||||
else if ((steamItems[i].Flags & (int)SteamNative.SteamItemFlags.Consumed) != 0)
|
||||
{
|
||||
tempConsumed.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
Items = tempItems.ToArray();
|
||||
Removed = tempRemoved.ToArray();
|
||||
Consumed = tempConsumed.ToArray();
|
||||
|
||||
if ( OnResult != null )
|
||||
{
|
||||
OnResult( this );
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnSteamResult( SteamInventoryResultReady_t data )
|
||||
{
|
||||
var success = data.Result == SteamNative.Result.OK;
|
||||
|
||||
if ( success )
|
||||
{
|
||||
Fill();
|
||||
}
|
||||
}
|
||||
|
||||
internal unsafe byte[] Serialize()
|
||||
{
|
||||
uint size = 0;
|
||||
|
||||
if ( !inventory.inventory.SerializeResult( Handle, IntPtr.Zero, out size ) )
|
||||
return null;
|
||||
|
||||
var data = new byte[size];
|
||||
|
||||
fixed ( byte* ptr = data )
|
||||
{
|
||||
if ( !inventory.inventory.SerializeResult( Handle, (IntPtr)ptr, out size ) )
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if ( Handle != -1 && inventory != null )
|
||||
{
|
||||
inventory.inventory.DestroyResult( Handle );
|
||||
Handle = -1;
|
||||
}
|
||||
|
||||
inventory = null;
|
||||
}
|
||||
}
|
||||
|
||||
internal Item ItemFrom( SteamInventoryResult_t handle, SteamItemDetails_t detail, int index )
|
||||
{
|
||||
Dictionary<string, string> props = null;
|
||||
|
||||
if ( EnableItemProperties && inventory.GetResultItemProperty(handle, (uint) index, null, out string propertyNames) )
|
||||
{
|
||||
props = new Dictionary<string, string>();
|
||||
|
||||
foreach ( var propertyName in propertyNames.Split( ',' ) )
|
||||
{
|
||||
if ( inventory.GetResultItemProperty(handle, (uint)index, propertyName, out string propertyValue ) )
|
||||
{
|
||||
if (propertyName == "error")
|
||||
{
|
||||
Console.Write("Steam item error: ");
|
||||
Console.WriteLine(propertyValue);
|
||||
return null;
|
||||
}
|
||||
|
||||
props.Add(propertyName, propertyValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var item = new Item( this, detail.ItemId, detail.Quantity, detail.Definition );
|
||||
item.Properties = props;
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Inventory : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when the local client's items are first retrieved, and when they change.
|
||||
/// Obviously not called on the server.
|
||||
/// </summary>
|
||||
public event Action OnUpdate;
|
||||
|
||||
/// <summary>
|
||||
/// A list of items owned by this user. You should call Refresh() before trying to access this,
|
||||
/// and then wait until it's non null or listen to OnUpdate to find out immediately when it's populated.
|
||||
/// </summary>
|
||||
public Item[] Items;
|
||||
|
||||
/// <summary>
|
||||
/// You can send this data to a server, or another player who can then deserialize it
|
||||
/// and get a verified list of items.
|
||||
/// </summary>
|
||||
public byte[] SerializedItems;
|
||||
|
||||
/// <summary>
|
||||
/// Serialized data exprires after an hour. This is the time the value in SerializedItems will expire.
|
||||
/// </summary>
|
||||
public DateTime SerializedExpireTime;
|
||||
|
||||
/// <summary>
|
||||
/// Controls whether per-item properties (<see cref="Item.Properties"/>) are available or not. Default true.
|
||||
/// This can improve performance of full inventory updates.
|
||||
/// </summary>
|
||||
public bool EnableItemProperties = true;
|
||||
|
||||
internal uint LastTimestamp = 0;
|
||||
|
||||
internal SteamNative.SteamInventory inventory;
|
||||
|
||||
private bool IsServer { get; set; }
|
||||
|
||||
public event Action OnDefinitionsUpdated;
|
||||
|
||||
public event Action<Result> OnInventoryResultReady;
|
||||
|
||||
internal Inventory( BaseSteamworks steamworks, SteamNative.SteamInventory c, bool server )
|
||||
{
|
||||
IsServer = server;
|
||||
inventory = c;
|
||||
|
||||
steamworks.RegisterCallback<SteamNative.SteamInventoryDefinitionUpdate_t>( onDefinitionsUpdated );
|
||||
|
||||
Result.Pending = new Dictionary<int, Result>();
|
||||
|
||||
FetchItemDefinitions();
|
||||
LoadDefinitions();
|
||||
UpdatePrices();
|
||||
|
||||
if ( !server )
|
||||
{
|
||||
steamworks.RegisterCallback<SteamNative.SteamInventoryResultReady_t>( onResultReady );
|
||||
steamworks.RegisterCallback<SteamNative.SteamInventoryFullUpdate_t>( onFullUpdate );
|
||||
|
||||
|
||||
//
|
||||
// Get a list of our items immediately
|
||||
//
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should get called when the definitions get updated from Steam.
|
||||
/// </summary>
|
||||
private void onDefinitionsUpdated( SteamInventoryDefinitionUpdate_t obj )
|
||||
{
|
||||
LoadDefinitions();
|
||||
UpdatePrices();
|
||||
|
||||
if ( OnDefinitionsUpdated != null )
|
||||
{
|
||||
OnDefinitionsUpdated.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private bool LoadDefinitions()
|
||||
{
|
||||
var ids = inventory.GetItemDefinitionIDs();
|
||||
if ( ids == null )
|
||||
return false;
|
||||
|
||||
Definitions = ids.Select( x => CreateDefinition( x ) ).ToArray();
|
||||
|
||||
foreach ( var def in Definitions )
|
||||
{
|
||||
def.Link( Definitions );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We've received a FULL update
|
||||
/// </summary>
|
||||
private void onFullUpdate( SteamInventoryFullUpdate_t data )
|
||||
{
|
||||
var result = new Result( this, data.Handle, false );
|
||||
result.Fill();
|
||||
|
||||
onResult( result, true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A generic result has returned.
|
||||
/// </summary>
|
||||
private void onResultReady( SteamInventoryResultReady_t data )
|
||||
{
|
||||
Result result;
|
||||
if ( Result.Pending.TryGetValue( data.Handle, out result ) )
|
||||
{
|
||||
result.OnSteamResult( data );
|
||||
|
||||
if ( data.Result == SteamNative.Result.OK )
|
||||
{
|
||||
onResult( result, false );
|
||||
}
|
||||
|
||||
Result.Pending.Remove( data.Handle );
|
||||
result.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = new Result(this, data.Handle, false);
|
||||
result.Fill();
|
||||
}
|
||||
|
||||
OnInventoryResultReady?.Invoke(result);
|
||||
}
|
||||
|
||||
private void onResult( Result r, bool isFullUpdate )
|
||||
{
|
||||
if ( r.IsSuccess )
|
||||
{
|
||||
//
|
||||
// We only serialize FULL updates
|
||||
//
|
||||
if ( isFullUpdate )
|
||||
{
|
||||
//
|
||||
// Only serialize if this result is newer than the last one
|
||||
//
|
||||
if ( r.Timestamp < LastTimestamp )
|
||||
return;
|
||||
|
||||
SerializedItems = r.Serialize();
|
||||
SerializedExpireTime = DateTime.Now.Add( TimeSpan.FromMinutes( 60 ) );
|
||||
}
|
||||
|
||||
LastTimestamp = r.Timestamp;
|
||||
ApplyResult( r, isFullUpdate );
|
||||
}
|
||||
|
||||
r.Dispose();
|
||||
r = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply this result to our current stack of Items
|
||||
/// Here we're trying to keep our stack up to date with whatever happens
|
||||
/// with the crafting, stacking etc
|
||||
/// </summary>
|
||||
internal void ApplyResult( Result r, bool isFullUpdate )
|
||||
{
|
||||
if ( IsServer ) return;
|
||||
|
||||
if ( r.IsSuccess && r.Items != null )
|
||||
{
|
||||
if ( Items == null )
|
||||
Items = new Item[0];
|
||||
|
||||
if (isFullUpdate)
|
||||
{
|
||||
Items = r.Items;
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep the new item instance because it might have a different quantity, properties, etc
|
||||
Items = Items
|
||||
.UnionSelect(r.Items, (oldItem, newItem) => newItem)
|
||||
.Where(x => !r.Removed.Contains(x))
|
||||
.Where(x => !r.Consumed.Contains(x))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
//
|
||||
// Tell everyone we've got new items!
|
||||
//
|
||||
OnUpdate?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
inventory = null;
|
||||
|
||||
Items = null;
|
||||
SerializedItems = null;
|
||||
|
||||
Result.Pending = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this at least every two minutes, every frame doesn't hurt.
|
||||
/// You should call it when you consider it active play time.
|
||||
/// IE - your player is alive, and playing.
|
||||
/// Don't stress on it too much tho cuz it's super hijackable anyway.
|
||||
/// </summary>
|
||||
[Obsolete( "No longer required, will be removed in a later version" )]
|
||||
public void PlaytimeHeartbeat()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this to retrieve the items.
|
||||
/// Note that if this has already been called it won't
|
||||
/// trigger a call to OnUpdate unless the items have changed
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
if ( IsServer ) return;
|
||||
|
||||
SteamNative.SteamInventoryResult_t request = 0;
|
||||
if ( !inventory.GetAllItems( ref request ) || request == -1 )
|
||||
{
|
||||
Console.WriteLine( "GetAllItems failed!?" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Some definitions aren't sent to the client, and all aren't available on the server.
|
||||
/// Manually getting a Definition here lets you call functions on those definitions.
|
||||
/// </summary>
|
||||
public Definition CreateDefinition( int id )
|
||||
{
|
||||
return new Definition( this, id );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fetch item definitions in case new ones have been added since we've initialized
|
||||
/// </summary>
|
||||
public void FetchItemDefinitions()
|
||||
{
|
||||
inventory.LoadItemDefinitions();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No need to call this manually if you're calling Update
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A list of items defined for this app.
|
||||
/// This should be immediately populated and available.
|
||||
/// </summary>
|
||||
public Definition[] Definitions;
|
||||
|
||||
/// <summary>
|
||||
/// A list of item definitions that have prices and so can be bought.
|
||||
/// </summary>
|
||||
public IEnumerable<Definition> DefinitionsWithPrices
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( Definitions == null )
|
||||
yield break;
|
||||
|
||||
for ( int i=0; i< Definitions.Length; i++ )
|
||||
{
|
||||
if (Definitions[i].LocalPrice > 0)
|
||||
yield return Definitions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Utility, given a "1;VLV250" string, convert it to a 2.5
|
||||
/// </summary>
|
||||
public static float PriceCategoryToFloat( string price )
|
||||
{
|
||||
if ( string.IsNullOrEmpty( price ) )
|
||||
return 0.0f;
|
||||
|
||||
price = price.Replace( "1;VLV", "" );
|
||||
|
||||
int iPrice = 0;
|
||||
if ( !int.TryParse( price, out iPrice ) )
|
||||
return 0.0f;
|
||||
|
||||
return int.Parse( price ) / 100.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We might be better off using a dictionary for this, once there's 1000+ definitions
|
||||
/// </summary>
|
||||
public Definition FindDefinition( int DefinitionId )
|
||||
{
|
||||
if ( Definitions == null ) return null;
|
||||
|
||||
for( int i=0; i< Definitions.Length; i++ )
|
||||
{
|
||||
if ( Definitions[i].Id == DefinitionId )
|
||||
return Definitions[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public unsafe Result Deserialize( byte[] data, int dataLength = -1 )
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentException("data should nto be null");
|
||||
|
||||
if ( dataLength == -1 )
|
||||
dataLength = data.Length;
|
||||
|
||||
SteamNative.SteamInventoryResult_t resultHandle = -1;
|
||||
|
||||
fixed ( byte* ptr = data )
|
||||
{
|
||||
var result = inventory.DeserializeResult( ref resultHandle, (IntPtr) ptr, (uint)dataLength, false );
|
||||
if ( !result || resultHandle == -1 )
|
||||
return null;
|
||||
|
||||
var r = new Result( this, resultHandle, false );
|
||||
r.Fill();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Crafting! Uses the passed items to buy the target item.
|
||||
/// You need to have set up the appropriate exchange rules in your item
|
||||
/// definitions. This assumes all the items passed in aren't stacked.
|
||||
/// </summary>
|
||||
public Result CraftItem( Item[] list, Definition target )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t resultHandle = -1;
|
||||
|
||||
var newItems = new SteamNative.SteamItemDef_t[] { new SteamNative.SteamItemDef_t() { Value = target.Id } };
|
||||
var newItemC = new uint[] { 1 };
|
||||
|
||||
var takeItems = list.Select( x => (SteamNative.SteamItemInstanceID_t)x.Id ).ToArray();
|
||||
var takeItemsC = list.Select( x => (uint)1 ).ToArray();
|
||||
|
||||
if ( !inventory.ExchangeItems( ref resultHandle, newItems, newItemC, 1, takeItems, takeItemsC, (uint)takeItems.Length ) )
|
||||
return null;
|
||||
|
||||
return new Result( this, resultHandle, true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Crafting! Uses the passed items to buy the target item.
|
||||
/// You need to have set up the appropriate exchange rules in your item
|
||||
/// definitions.
|
||||
/// </summary>
|
||||
public Result CraftItem( Item.Amount[] list, Definition target )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t resultHandle = -1;
|
||||
|
||||
var newItems = new SteamNative.SteamItemDef_t[] { new SteamNative.SteamItemDef_t() { Value = target.Id } };
|
||||
var newItemC = new uint[] { 1 };
|
||||
|
||||
var takeItems = list.Select( x => (SteamNative.SteamItemInstanceID_t)x.Item.Id ).ToArray();
|
||||
var takeItemsC = list.Select( x => (uint)x.Quantity ).ToArray();
|
||||
|
||||
if ( !inventory.ExchangeItems( ref resultHandle, newItems, newItemC, 1, takeItems, takeItemsC, (uint)takeItems.Length ) )
|
||||
return null;
|
||||
|
||||
return new Result( this, resultHandle, true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Split stack into two items
|
||||
/// </summary>
|
||||
public Result SplitStack( Item item, int quantity = 1 )
|
||||
{
|
||||
return item.SplitStack( quantity );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stack source item onto dest item
|
||||
/// </summary>
|
||||
public Result Stack( Item source, Item dest, int quantity = 1 )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t resultHandle = -1;
|
||||
if ( !inventory.TransferItemQuantity( ref resultHandle, source.Id, (uint)quantity, dest.Id ) )
|
||||
return null;
|
||||
|
||||
return new Result( this, resultHandle, true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used to grant a specific item to the user. This should
|
||||
/// only be used for development prototyping, from a trusted server,
|
||||
/// or if you don't care about hacked clients granting arbitrary items.
|
||||
/// This call can be disabled by a setting on Steamworks.
|
||||
/// </summary>
|
||||
public Result GenerateItem( Definition target, int amount )
|
||||
{
|
||||
SteamNative.SteamInventoryResult_t resultHandle = -1;
|
||||
|
||||
var newItems = new SteamNative.SteamItemDef_t[] { new SteamNative.SteamItemDef_t() { Value = target.Id } };
|
||||
var newItemC = new uint[] { (uint) amount };
|
||||
|
||||
if ( !inventory.GenerateItems( ref resultHandle, newItems, newItemC, 1 ) )
|
||||
return null;
|
||||
|
||||
return new Result( this, resultHandle, true );
|
||||
}
|
||||
|
||||
public delegate void StartPurchaseSuccess( ulong orderId, ulong transactionId );
|
||||
|
||||
/// <summary>
|
||||
/// Starts the purchase process for the user, given a "shopping cart" of item definitions that the user would like to buy.
|
||||
/// The user will be prompted in the Steam Overlay to complete the purchase in their local currency, funding their Steam Wallet if necessary, etc.
|
||||
///
|
||||
/// If was succesful the callback orderId and transactionId will be non 0
|
||||
/// </summary>
|
||||
public bool StartPurchase( Definition[] items, StartPurchaseSuccess callback = null )
|
||||
{
|
||||
var itemGroup = items.GroupBy(x => x.Id);
|
||||
|
||||
var newItems = itemGroup.Select( x => new SteamItemDef_t { Value = x.Key } ).ToArray();
|
||||
var newItemC = itemGroup.Select( x => (uint) x.Count() ).ToArray();
|
||||
|
||||
var h = inventory.StartPurchase( newItems, newItemC, (uint) newItemC.Length, ( result, error ) =>
|
||||
{
|
||||
if ( error )
|
||||
{
|
||||
callback?.Invoke(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback?.Invoke(result.OrderID, result.TransID);
|
||||
}
|
||||
});
|
||||
|
||||
return h != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This might be null until Steam has actually recieved the prices.
|
||||
/// </summary>
|
||||
public string Currency { get; private set; }
|
||||
|
||||
public void UpdatePrices()
|
||||
{
|
||||
if (IsServer)
|
||||
return;
|
||||
|
||||
inventory.RequestPrices((result, b) =>
|
||||
{
|
||||
Currency = result.Currency;
|
||||
|
||||
if ( Definitions == null )
|
||||
return;
|
||||
|
||||
for (int i = 0; i < Definitions.Length; i++)
|
||||
{
|
||||
Definitions[i].UpdatePrice();
|
||||
}
|
||||
|
||||
OnUpdate?.Invoke();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class Networking : IDisposable
|
||||
{
|
||||
private static byte[] ReceiveBuffer = new byte[1024 * 64];
|
||||
|
||||
public delegate void OnRecievedP2PData( ulong steamid, byte[] data, int dataLength, int channel );
|
||||
|
||||
public OnRecievedP2PData OnP2PData;
|
||||
public Func<ulong, bool> OnIncomingConnection;
|
||||
public Action<ulong, SessionError> OnConnectionFailed;
|
||||
|
||||
private List<int> ListenChannels = new List<int>();
|
||||
|
||||
private System.Diagnostics.Stopwatch UpdateTimer = System.Diagnostics.Stopwatch.StartNew();
|
||||
|
||||
internal SteamNative.SteamNetworking networking;
|
||||
|
||||
internal Networking( BaseSteamworks steamworks, SteamNative.SteamNetworking networking )
|
||||
{
|
||||
this.networking = networking;
|
||||
|
||||
steamworks.RegisterCallback<SteamNative.P2PSessionRequest_t>( onP2PConnectionRequest );
|
||||
steamworks.RegisterCallback<SteamNative.P2PSessionConnectFail_t>( onP2PConnectionFailed );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
networking = null;
|
||||
|
||||
OnIncomingConnection = null;
|
||||
OnConnectionFailed = null;
|
||||
OnP2PData = null;
|
||||
ListenChannels.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// No need to call this manually if you're calling Update()
|
||||
/// </summary>
|
||||
public void Update()
|
||||
{
|
||||
if ( OnP2PData == null )
|
||||
return;
|
||||
|
||||
// Update every 60th of a second
|
||||
if ( UpdateTimer.Elapsed.TotalSeconds < 1.0 / 60.0 )
|
||||
return;
|
||||
|
||||
UpdateTimer.Reset();
|
||||
UpdateTimer.Start();
|
||||
|
||||
foreach ( var channel in ListenChannels )
|
||||
{
|
||||
while ( ReadP2PPacket( channel ) )
|
||||
{
|
||||
// Nothing Here.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable listening on a specific channel.
|
||||
/// If you donp't enable the channel we won't listen to it,
|
||||
/// so you won't be able to receive messages on it.
|
||||
/// </summary>
|
||||
public void SetListenChannel( int ChannelId, bool Listen )
|
||||
{
|
||||
ListenChannels.RemoveAll( x => x == ChannelId );
|
||||
|
||||
if ( Listen )
|
||||
{
|
||||
ListenChannels.Add( ChannelId );
|
||||
}
|
||||
}
|
||||
|
||||
private void onP2PConnectionRequest( SteamNative.P2PSessionRequest_t o )
|
||||
{
|
||||
if ( OnIncomingConnection != null )
|
||||
{
|
||||
var accept = OnIncomingConnection( o.SteamIDRemote );
|
||||
|
||||
if ( accept )
|
||||
{
|
||||
networking.AcceptP2PSessionWithUser( o.SteamIDRemote );
|
||||
}
|
||||
else
|
||||
{
|
||||
networking.CloseP2PSessionWithUser( o.SteamIDRemote );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Default is to reject the session
|
||||
//
|
||||
networking.CloseP2PSessionWithUser( o.SteamIDRemote );
|
||||
}
|
||||
|
||||
public enum SessionError : byte
|
||||
{
|
||||
None = 0,
|
||||
NotRunningApp = 1, // target is not running the same game
|
||||
NoRightsToApp = 2, // local user doesn't own the app that is running
|
||||
DestinationNotLoggedIn = 3, // target user isn't connected to Steam
|
||||
Timeout = 4, // target isn't responding, perhaps not calling AcceptP2PSessionWithUser()
|
||||
// corporate firewalls can also block this (NAT traversal is not firewall traversal)
|
||||
// make sure that UDP ports 3478, 4379, and 4380 are open in an outbound direction
|
||||
Max = 5
|
||||
};
|
||||
|
||||
private void onP2PConnectionFailed( SteamNative.P2PSessionConnectFail_t o )
|
||||
{
|
||||
if ( OnConnectionFailed != null )
|
||||
{
|
||||
OnConnectionFailed( o.SteamIDRemote, (SessionError) o.P2PSessionError );
|
||||
}
|
||||
}
|
||||
|
||||
public enum SendType : int
|
||||
{
|
||||
/// <summary>
|
||||
/// Basic UDP send. Packets can't be bigger than 1200 bytes (your typical MTU size). Can be lost, or arrive out of order (rare).
|
||||
/// The sending API does have some knowledge of the underlying connection, so if there is no NAT-traversal accomplished or
|
||||
/// there is a recognized adjustment happening on the connection, the packet will be batched until the connection is open again.
|
||||
/// </summary>
|
||||
|
||||
Unreliable = 0,
|
||||
|
||||
/// <summary>
|
||||
/// As above, but if the underlying p2p connection isn't yet established the packet will just be thrown away. Using this on the first
|
||||
/// packet sent to a remote host almost guarantees the packet will be dropped.
|
||||
/// This is only really useful for kinds of data that should never buffer up, i.e. voice payload packets
|
||||
/// </summary>
|
||||
UnreliableNoDelay = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Reliable message send. Can send up to 1MB of data in a single message.
|
||||
/// Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for efficient sends of large chunks of data.
|
||||
/// </summary>
|
||||
Reliable = 2,
|
||||
|
||||
/// <summary>
|
||||
/// As above, but applies the Nagle algorithm to the send - sends will accumulate
|
||||
/// until the current MTU size (typically ~1200 bytes, but can change) or ~200ms has passed (Nagle algorithm).
|
||||
/// Useful if you want to send a set of smaller messages but have the coalesced into a single packet
|
||||
/// Since the reliable stream is all ordered, you can do several small message sends with k_EP2PSendReliableWithBuffering and then
|
||||
/// do a normal k_EP2PSendReliable to force all the buffered data to be sent.
|
||||
/// </summary>
|
||||
ReliableWithBuffering = 3,
|
||||
|
||||
}
|
||||
|
||||
public unsafe bool SendP2PPacket( ulong steamid, byte[] data, int length, SendType eP2PSendType = SendType.Reliable, int nChannel = 0 )
|
||||
{
|
||||
fixed ( byte* p = data )
|
||||
{
|
||||
return networking.SendP2PPacket( steamid, (IntPtr) p, (uint)length, (SteamNative.P2PSend)(int)eP2PSendType, nChannel );
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe bool ReadP2PPacket( int channel )
|
||||
{
|
||||
uint DataAvailable = 0;
|
||||
|
||||
if ( !networking.IsP2PPacketAvailable( out DataAvailable, channel ) )
|
||||
return false;
|
||||
|
||||
if ( ReceiveBuffer.Length < DataAvailable )
|
||||
ReceiveBuffer = new byte[ DataAvailable + 1024 ];
|
||||
|
||||
fixed ( byte* p = ReceiveBuffer )
|
||||
{
|
||||
SteamNative.CSteamID steamid = 1;
|
||||
if ( !networking.ReadP2PPacket( (IntPtr)p, DataAvailable, out DataAvailable, out steamid, channel ) || DataAvailable == 0 )
|
||||
return false;
|
||||
|
||||
OnP2PData?.Invoke( steamid, ReceiveBuffer, (int) DataAvailable, channel );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This should be called when you're done communicating with a user, as this will free up all of the resources allocated for the connection under-the-hood.
|
||||
/// If the remote user tries to send data to you again, a new onP2PConnectionRequest callback will be posted.
|
||||
/// </summary>
|
||||
public bool CloseSession( ulong steamId )
|
||||
{
|
||||
return networking.CloseP2PSessionWithUser( steamId );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using SteamNative;
|
||||
using Result = Facepunch.Steamworks.Callbacks.Result;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Workshop
|
||||
{
|
||||
public class Editor
|
||||
{
|
||||
internal Workshop workshop;
|
||||
|
||||
internal CallbackHandle CreateItem;
|
||||
internal CallbackHandle SubmitItemUpdate;
|
||||
internal SteamNative.UGCUpdateHandle_t UpdateHandle;
|
||||
|
||||
public ulong Id { get; internal set; }
|
||||
public string Title { get; set; } = null;
|
||||
public string Description { get; set; } = null;
|
||||
public string Folder { get; set; } = null;
|
||||
public string PreviewImage { get; set; } = null;
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
public bool Publishing { get; internal set; }
|
||||
public ItemType? Type { get; set; }
|
||||
public string Error { get; internal set; } = null;
|
||||
public string ChangeNote { get; set; } = "";
|
||||
public uint WorkshopUploadAppId { get; set; }
|
||||
public string MetaData { get; set; } = null;
|
||||
public Dictionary<string, string[]> KeyValues { get; set; } = new Dictionary<string, string[]>();
|
||||
|
||||
public enum VisibilityType : int
|
||||
{
|
||||
Public = 0,
|
||||
FriendsOnly = 1,
|
||||
Private = 2
|
||||
}
|
||||
|
||||
public VisibilityType ? Visibility { get; set; }
|
||||
|
||||
public bool NeedToAgreeToWorkshopLegal { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when published changes have finished being submitted.
|
||||
/// </summary>
|
||||
public event Action<Result> OnChangesSubmitted;
|
||||
|
||||
public double Progress
|
||||
{
|
||||
get
|
||||
{
|
||||
var bt = BytesTotal;
|
||||
if (bt == 0) return 0;
|
||||
|
||||
return (double)BytesUploaded / (double)bt;
|
||||
}
|
||||
}
|
||||
|
||||
private int bytesUploaded = 0;
|
||||
|
||||
public int BytesUploaded
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( !Publishing ) return bytesUploaded;
|
||||
if (UpdateHandle == 0) return bytesUploaded;
|
||||
|
||||
ulong b = 0;
|
||||
ulong t = 0;
|
||||
|
||||
workshop.steamworks.native.ugc.GetItemUpdateProgress( UpdateHandle, out b, out t );
|
||||
bytesUploaded = Math.Max( bytesUploaded, (int) b );
|
||||
return (int)bytesUploaded;
|
||||
}
|
||||
}
|
||||
|
||||
private int bytesTotal = 0;
|
||||
|
||||
public int BytesTotal
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( !Publishing ) return bytesTotal;
|
||||
if (UpdateHandle == 0 ) return bytesTotal;
|
||||
|
||||
ulong b = 0;
|
||||
ulong t = 0;
|
||||
|
||||
workshop.steamworks.native.ugc.GetItemUpdateProgress( UpdateHandle, out b, out t );
|
||||
bytesTotal = Math.Max(bytesTotal, (int)t);
|
||||
return (int)bytesTotal;
|
||||
}
|
||||
}
|
||||
|
||||
public void Publish()
|
||||
{
|
||||
bytesUploaded = 0;
|
||||
bytesTotal = 0;
|
||||
|
||||
Publishing = true;
|
||||
Error = null;
|
||||
|
||||
if ( Id == 0 )
|
||||
{
|
||||
StartCreatingItem();
|
||||
return;
|
||||
}
|
||||
|
||||
PublishChanges();
|
||||
}
|
||||
|
||||
private void StartCreatingItem()
|
||||
{
|
||||
if ( !Type.HasValue )
|
||||
throw new System.Exception( "Editor.Type must be set when creating a new item!" );
|
||||
|
||||
if ( WorkshopUploadAppId == 0 )
|
||||
throw new Exception( "WorkshopUploadAppId should not be 0" );
|
||||
|
||||
CreateItem = workshop.ugc.CreateItem( WorkshopUploadAppId, (SteamNative.WorkshopFileType)(uint)Type, OnItemCreated );
|
||||
}
|
||||
|
||||
private void OnItemCreated( SteamNative.CreateItemResult_t obj, bool Failed )
|
||||
{
|
||||
NeedToAgreeToWorkshopLegal = obj.UserNeedsToAcceptWorkshopLegalAgreement;
|
||||
CreateItem.Dispose();
|
||||
CreateItem = null;
|
||||
|
||||
if ( obj.Result == SteamNative.Result.OK && !Failed )
|
||||
{
|
||||
Error = null;
|
||||
Id = obj.PublishedFileId;
|
||||
PublishChanges();
|
||||
return;
|
||||
}
|
||||
|
||||
Error = $"Error creating new file: {obj.Result} ({obj.PublishedFileId})";
|
||||
Publishing = false;
|
||||
|
||||
OnChangesSubmitted?.Invoke( (Result) obj.Result );
|
||||
}
|
||||
|
||||
private void PublishChanges()
|
||||
{
|
||||
if ( WorkshopUploadAppId == 0 )
|
||||
throw new Exception( "WorkshopUploadAppId should not be 0" );
|
||||
|
||||
UpdateHandle = workshop.ugc.StartItemUpdate(WorkshopUploadAppId, Id );
|
||||
|
||||
if ( Title != null )
|
||||
workshop.ugc.SetItemTitle( UpdateHandle, Title );
|
||||
|
||||
if ( Description != null )
|
||||
workshop.ugc.SetItemDescription( UpdateHandle, Description );
|
||||
|
||||
if ( Folder != null )
|
||||
{
|
||||
var info = new System.IO.DirectoryInfo( Folder );
|
||||
|
||||
if ( !info.Exists )
|
||||
throw new System.Exception( $"Folder doesn't exist ({Folder})" );
|
||||
|
||||
workshop.ugc.SetItemContent( UpdateHandle, Folder );
|
||||
}
|
||||
|
||||
if ( Tags != null && Tags.Count > 0 )
|
||||
workshop.ugc.SetItemTags( UpdateHandle, Tags.ToArray() );
|
||||
|
||||
if ( Visibility.HasValue )
|
||||
workshop.ugc.SetItemVisibility( UpdateHandle, (SteamNative.RemoteStoragePublishedFileVisibility)(uint)Visibility.Value );
|
||||
|
||||
if ( PreviewImage != null )
|
||||
{
|
||||
var info = new System.IO.FileInfo( PreviewImage );
|
||||
|
||||
if ( !info.Exists )
|
||||
throw new System.Exception( $"PreviewImage doesn't exist ({PreviewImage})" );
|
||||
|
||||
if ( info.Length >= 1024 * 1024 )
|
||||
throw new System.Exception( $"PreviewImage should be under 1MB ({info.Length})" );
|
||||
|
||||
workshop.ugc.SetItemPreview( UpdateHandle, PreviewImage );
|
||||
}
|
||||
|
||||
if ( MetaData != null )
|
||||
{
|
||||
workshop.ugc.SetItemMetadata( UpdateHandle, MetaData );
|
||||
}
|
||||
|
||||
if ( KeyValues != null )
|
||||
{
|
||||
foreach ( var key in KeyValues )
|
||||
{
|
||||
foreach ( var value in key.Value )
|
||||
{
|
||||
workshop.ugc.AddItemKeyValueTag( UpdateHandle, key.Key, value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
workshop.ugc.SetItemUpdateLanguage( UpdateId, const char *pchLanguage ) = 0; // specify the language of the title or description that will be set
|
||||
workshop.ugc.RemoveItemKeyValueTags( UpdateId, const char *pchKey ) = 0; // remove any existing key-value tags with the specified key
|
||||
workshop.ugc.AddItemPreviewFile( UpdateId, const char *pszPreviewFile, EItemPreviewType type ) = 0; // add preview file for this item. pszPreviewFile points to local file, which must be under 1MB in size
|
||||
workshop.ugc.AddItemPreviewVideo( UpdateId, const char *pszVideoID ) = 0; // add preview video for this item
|
||||
workshop.ugc.UpdateItemPreviewFile( UpdateId, uint32 index, const char *pszPreviewFile ) = 0; // updates an existing preview file for this item. pszPreviewFile points to local file, which must be under 1MB in size
|
||||
workshop.ugc.UpdateItemPreviewVideo( UpdateId, uint32 index, const char *pszVideoID ) = 0; // updates an existing preview video for this item
|
||||
workshop.ugc.RemoveItemPreview( UpdateId, uint32 index ) = 0; // remove a preview by index starting at 0 (previews are sorted)
|
||||
*/
|
||||
|
||||
SubmitItemUpdate = workshop.ugc.SubmitItemUpdate( UpdateHandle, ChangeNote, OnChangesSubmittedInternal );
|
||||
}
|
||||
|
||||
private void OnChangesSubmittedInternal( SteamNative.SubmitItemUpdateResult_t obj, bool Failed )
|
||||
{
|
||||
if ( Failed )
|
||||
throw new System.Exception( "CreateItemResult_t Failed" );
|
||||
|
||||
UpdateHandle = 0;
|
||||
SubmitItemUpdate = null;
|
||||
NeedToAgreeToWorkshopLegal = obj.UserNeedsToAcceptWorkshopLegalAgreement;
|
||||
Publishing = false;
|
||||
|
||||
Error = obj.Result != SteamNative.Result.OK
|
||||
? $"Error publishing changes: {obj.Result} ({NeedToAgreeToWorkshopLegal})"
|
||||
: null;
|
||||
|
||||
OnChangesSubmitted?.Invoke( (Result) obj.Result );
|
||||
}
|
||||
|
||||
public void Delete()
|
||||
{
|
||||
workshop.ugc.DeleteItem( Id );
|
||||
Id = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Workshop
|
||||
{
|
||||
public class Item
|
||||
{
|
||||
internal Workshop workshop;
|
||||
|
||||
internal Action onInstalled;
|
||||
|
||||
public string Description { get; private set; }
|
||||
public ulong Id { get; private set; }
|
||||
public ulong OwnerId { get; private set; }
|
||||
public float Score { get; private set; }
|
||||
public string[] Tags { get; private set; }
|
||||
public string Title { get; private set; }
|
||||
public uint VotesDown { get; private set; }
|
||||
public uint VotesUp { get; private set; }
|
||||
public DateTime Modified { get; private set; }
|
||||
public DateTime Created { get; private set; }
|
||||
|
||||
public Item( ulong Id, Workshop workshop )
|
||||
{
|
||||
this.Id = Id;
|
||||
this.workshop = workshop;
|
||||
}
|
||||
|
||||
internal static Item From( SteamNative.SteamUGCDetails_t details, Workshop workshop )
|
||||
{
|
||||
var item = new Item( details.PublishedFileId, workshop);
|
||||
|
||||
item.Title = details.Title;
|
||||
item.Description = details.Description;
|
||||
item.OwnerId = details.SteamIDOwner;
|
||||
item.Tags = details.Tags.Split( ',' ).Select( x=> x.ToLower() ).ToArray();
|
||||
item.Score = details.Score;
|
||||
item.VotesUp = details.VotesUp;
|
||||
item.VotesDown = details.VotesDown;
|
||||
item.Modified = Utility.Epoch.ToDateTime( details.TimeUpdated );
|
||||
item.Created = Utility.Epoch.ToDateTime( details.TimeCreated );
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public bool Download( bool highPriority = true, Action onInstalled = null )
|
||||
{
|
||||
if ( Installed ) return true;
|
||||
if ( Downloading ) return true;
|
||||
|
||||
if ( !workshop.ugc.DownloadItem( Id, highPriority ) )
|
||||
{
|
||||
Console.WriteLine( "Download Failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
this.onInstalled = onInstalled;
|
||||
workshop.OnFileDownloaded += OnFileDownloaded;
|
||||
workshop.OnItemInstalled += OnItemInstalled;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Subscribe()
|
||||
{
|
||||
workshop.ugc.SubscribeItem(Id);
|
||||
SubscriptionCount++;
|
||||
}
|
||||
|
||||
public void UnSubscribe()
|
||||
{
|
||||
workshop.ugc.UnsubscribeItem(Id);
|
||||
SubscriptionCount--;
|
||||
}
|
||||
|
||||
|
||||
private void OnFileDownloaded( ulong fileid, Callbacks.Result result )
|
||||
{
|
||||
if ( fileid != Id ) return;
|
||||
|
||||
workshop.OnFileDownloaded -= OnFileDownloaded;
|
||||
}
|
||||
|
||||
private void OnItemInstalled( ulong fileid )
|
||||
{
|
||||
if ( fileid != Id ) return;
|
||||
|
||||
onInstalled?.Invoke();
|
||||
workshop.OnItemInstalled -= OnItemInstalled;
|
||||
}
|
||||
|
||||
public ulong BytesDownloaded { get { UpdateDownloadProgress(); return _BytesDownloaded; } }
|
||||
public ulong BytesTotalDownload { get { UpdateDownloadProgress(); return _BytesTotal; } }
|
||||
|
||||
public double DownloadProgress
|
||||
{
|
||||
get
|
||||
{
|
||||
UpdateDownloadProgress();
|
||||
if ( _BytesTotal == 0 ) return 0;
|
||||
return (double)_BytesDownloaded / (double)_BytesTotal;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Installed { get { return ( State & ItemState.Installed ) != 0; } }
|
||||
public bool Downloading { get { return ( State & ItemState.Downloading ) != 0; } }
|
||||
public bool DownloadPending { get { return ( State & ItemState.DownloadPending ) != 0; } }
|
||||
public bool Subscribed { get { return ( State & ItemState.Subscribed ) != 0; } }
|
||||
public bool NeedsUpdate { get { return ( State & ItemState.NeedsUpdate ) != 0; } }
|
||||
|
||||
private SteamNative.ItemState State { get { return ( SteamNative.ItemState) workshop.ugc.GetItemState( Id ); } }
|
||||
|
||||
|
||||
private DirectoryInfo _directory;
|
||||
|
||||
public DirectoryInfo Directory
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _directory != null )
|
||||
return _directory;
|
||||
|
||||
if ( !Installed )
|
||||
return null;
|
||||
|
||||
ulong sizeOnDisk;
|
||||
string folder;
|
||||
uint timestamp;
|
||||
|
||||
if ( workshop.ugc.GetItemInstallInfo( Id, out sizeOnDisk, out folder, out timestamp ) )
|
||||
{
|
||||
_directory = new DirectoryInfo( folder );
|
||||
Size = sizeOnDisk;
|
||||
|
||||
if ( !_directory.Exists )
|
||||
{
|
||||
// Size = 0;
|
||||
// _directory = null;
|
||||
}
|
||||
}
|
||||
|
||||
return _directory;
|
||||
}
|
||||
}
|
||||
|
||||
public ulong Size { get; private set; }
|
||||
|
||||
private ulong _BytesDownloaded, _BytesTotal;
|
||||
|
||||
internal void UpdateDownloadProgress()
|
||||
{
|
||||
workshop.ugc.GetItemDownloadInfo( Id, out _BytesDownloaded, out _BytesTotal );
|
||||
}
|
||||
|
||||
private int YourVote = 0;
|
||||
|
||||
|
||||
public void VoteUp()
|
||||
{
|
||||
if ( YourVote == 1 ) return;
|
||||
if ( YourVote == -1 ) VotesDown--;
|
||||
|
||||
VotesUp++;
|
||||
workshop.ugc.SetUserItemVote( Id, true );
|
||||
YourVote = 1;
|
||||
}
|
||||
|
||||
public void VoteDown()
|
||||
{
|
||||
if ( YourVote == -1 ) return;
|
||||
if ( YourVote == 1 ) VotesUp--;
|
||||
|
||||
VotesDown++;
|
||||
workshop.ugc.SetUserItemVote( Id, false );
|
||||
YourVote = -1;
|
||||
}
|
||||
|
||||
public Editor Edit()
|
||||
{
|
||||
return workshop.EditItem( Id );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Return a URL to view this item online
|
||||
/// </summary>
|
||||
public string Url { get { return string.Format( "http://steamcommunity.com/sharedfiles/filedetails/?source=Facepunch.Steamworks&id={0}", Id ); } }
|
||||
|
||||
public string ChangelogUrl { get { return string.Format( "http://steamcommunity.com/sharedfiles/filedetails/changelog/{0}", Id ); } }
|
||||
|
||||
public string CommentsUrl { get { return string.Format( "http://steamcommunity.com/sharedfiles/filedetails/comments/{0}", Id ); } }
|
||||
|
||||
public string DiscussUrl { get { return string.Format( "http://steamcommunity.com/sharedfiles/filedetails/discussions/{0}", Id ); } }
|
||||
|
||||
public string StartsUrl { get { return string.Format( "http://steamcommunity.com/sharedfiles/filedetails/stats/{0}", Id ); } }
|
||||
|
||||
public int SubscriptionCount { get; internal set; }
|
||||
public int FavouriteCount { get; internal set; }
|
||||
public int FollowerCount { get; internal set; }
|
||||
public int WebsiteViews { get; internal set; }
|
||||
public int ReportScore { get; internal set; }
|
||||
public string PreviewImageUrl { get; internal set; }
|
||||
|
||||
string _ownerName = null;
|
||||
|
||||
|
||||
|
||||
public string OwnerName
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _ownerName == null && workshop.friends != null )
|
||||
{
|
||||
_ownerName = workshop.friends.GetName( OwnerId );
|
||||
if ( _ownerName == "[unknown]" )
|
||||
{
|
||||
_ownerName = null;
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
if ( _ownerName == null )
|
||||
return string.Empty;
|
||||
|
||||
return _ownerName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public partial class Workshop
|
||||
{
|
||||
public class Query : IDisposable
|
||||
{
|
||||
internal const int SteamResponseSize = 50;
|
||||
|
||||
internal SteamNative.UGCQueryHandle_t Handle;
|
||||
internal SteamNative.CallbackHandle Callback;
|
||||
|
||||
/// <summary>
|
||||
/// The AppId you're querying. This defaults to this appid.
|
||||
/// </summary>
|
||||
public uint AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The AppId of the app used to upload the item. This defaults to 0
|
||||
/// which means all/any.
|
||||
/// </summary>
|
||||
public uint UploaderAppId { get; set; }
|
||||
|
||||
public QueryType QueryType { get; set; } = QueryType.Items;
|
||||
public Order Order { get; set; } = Order.RankedByVote;
|
||||
|
||||
public string SearchText { get; set; }
|
||||
|
||||
public Item[] Items { get; set; }
|
||||
|
||||
public int TotalResults { get; set; }
|
||||
|
||||
public ulong? UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If order is RankedByTrend, this value represents how many days to take
|
||||
/// into account.
|
||||
/// </summary>
|
||||
public int RankedByTrendDays { get; set; }
|
||||
|
||||
public UserQueryType UserQueryType { get; set; } = UserQueryType.Published;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the query finishes
|
||||
/// </summary>
|
||||
public Action<Query> OnResult;
|
||||
|
||||
/// <summary>
|
||||
/// Page starts at 1 !!
|
||||
/// </summary>
|
||||
public int Page { get; set; } = 1;
|
||||
|
||||
public int PerPage { get; set; } = SteamResponseSize;
|
||||
|
||||
internal Workshop workshop;
|
||||
internal Friends friends;
|
||||
|
||||
private int _resultPage = 0;
|
||||
private int _resultsRemain = 0;
|
||||
private int _resultSkip = 0;
|
||||
private List<Item> _results;
|
||||
|
||||
public void Run()
|
||||
{
|
||||
if ( Callback != null )
|
||||
return;
|
||||
|
||||
if ( Page <= 0 )
|
||||
throw new System.Exception( "Page should be 1 or above" );
|
||||
|
||||
var actualOffset = ((Page-1) * PerPage);
|
||||
|
||||
TotalResults = 0;
|
||||
|
||||
_resultSkip = actualOffset % SteamResponseSize;
|
||||
_resultsRemain = PerPage;
|
||||
_resultPage = (int) Math.Floor( (float) actualOffset / (float)SteamResponseSize );
|
||||
_results = new List<Item>();
|
||||
|
||||
RunInternal();
|
||||
}
|
||||
|
||||
unsafe void RunInternal()
|
||||
{
|
||||
if ( FileId.Count != 0 )
|
||||
{
|
||||
var fileArray = FileId.Select( x => (SteamNative.PublishedFileId_t)x ).ToArray();
|
||||
_resultsRemain = fileArray.Length;
|
||||
|
||||
Handle = workshop.ugc.CreateQueryUGCDetailsRequest( fileArray );
|
||||
}
|
||||
else if ( UserId.HasValue )
|
||||
{
|
||||
uint accountId = (uint)( UserId.Value & 0xFFFFFFFFul );
|
||||
Handle = workshop.ugc.CreateQueryUserUGCRequest( accountId, (SteamNative.UserUGCList)( int)UserQueryType, (SteamNative.UGCMatchingUGCType)( int)QueryType, SteamNative.UserUGCListSortOrder.LastUpdatedDesc, UploaderAppId, AppId, (uint)_resultPage + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Handle = workshop.ugc.CreateQueryAllUGCRequest( (SteamNative.UGCQuery)(int)Order, (SteamNative.UGCMatchingUGCType)(int)QueryType, UploaderAppId, AppId, (uint)_resultPage + 1 );
|
||||
}
|
||||
|
||||
if ( !string.IsNullOrEmpty( SearchText ) )
|
||||
workshop.ugc.SetSearchText( Handle, SearchText );
|
||||
|
||||
foreach ( var tag in RequireTags )
|
||||
workshop.ugc.AddRequiredTag( Handle, tag );
|
||||
|
||||
if ( RequireTags.Count > 0 )
|
||||
workshop.ugc.SetMatchAnyTag( Handle, !RequireAllTags );
|
||||
|
||||
if ( RankedByTrendDays > 0 )
|
||||
workshop.ugc.SetRankedByTrendDays( Handle, (uint) RankedByTrendDays );
|
||||
|
||||
foreach ( var tag in ExcludeTags )
|
||||
workshop.ugc.AddExcludedTag( Handle, tag );
|
||||
|
||||
Callback = workshop.ugc.SendQueryUGCRequest( Handle, ResultCallback );
|
||||
}
|
||||
|
||||
void ResultCallback( SteamNative.SteamUGCQueryCompleted_t data, bool bFailed )
|
||||
{
|
||||
if ( bFailed )
|
||||
throw new System.Exception( "bFailed!" );
|
||||
|
||||
var gotFiles = 0;
|
||||
for ( int i = 0; i < data.NumResultsReturned; i++ )
|
||||
{
|
||||
if ( _resultSkip > 0 )
|
||||
{
|
||||
_resultSkip--;
|
||||
continue;
|
||||
}
|
||||
|
||||
SteamNative.SteamUGCDetails_t details = new SteamNative.SteamUGCDetails_t();
|
||||
if ( !workshop.ugc.GetQueryUGCResult( data.Handle, (uint)i, ref details ) )
|
||||
continue;
|
||||
|
||||
// We already have this file, so skip it
|
||||
if ( _results.Any( x => x.Id == details.PublishedFileId ) )
|
||||
continue;
|
||||
|
||||
var item = Item.From( details, workshop );
|
||||
|
||||
item.SubscriptionCount = GetStat( data.Handle, i, ItemStatistic.NumSubscriptions );
|
||||
item.FavouriteCount = GetStat( data.Handle, i, ItemStatistic.NumFavorites );
|
||||
item.FollowerCount = GetStat( data.Handle, i, ItemStatistic.NumFollowers );
|
||||
item.WebsiteViews = GetStat( data.Handle, i, ItemStatistic.NumUniqueWebsiteViews );
|
||||
item.ReportScore = GetStat( data.Handle, i, ItemStatistic.ReportScore );
|
||||
|
||||
string url = null;
|
||||
if ( workshop.ugc.GetQueryUGCPreviewURL( data.Handle, (uint)i, out url ) )
|
||||
item.PreviewImageUrl = url;
|
||||
|
||||
_results.Add( item );
|
||||
|
||||
_resultsRemain--;
|
||||
gotFiles++;
|
||||
|
||||
if ( _resultsRemain <= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
TotalResults = TotalResults > data.TotalMatchingResults ? TotalResults : (int)data.TotalMatchingResults;
|
||||
|
||||
Callback.Dispose();
|
||||
Callback = null;
|
||||
|
||||
_resultPage++;
|
||||
|
||||
if ( _resultsRemain > 0 && gotFiles > 0 )
|
||||
{
|
||||
RunInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
Items = _results.ToArray();
|
||||
|
||||
if ( OnResult != null )
|
||||
{
|
||||
OnResult( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetStat( ulong handle, int index, ItemStatistic stat )
|
||||
{
|
||||
ulong val = 0;
|
||||
if ( !workshop.ugc.GetQueryUGCStatistic( handle, (uint)index, (SteamNative.ItemStatistic)(uint)stat, out val ) )
|
||||
return 0;
|
||||
|
||||
return (int) val;
|
||||
}
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
get { return Callback != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only return items with these tags
|
||||
/// </summary>
|
||||
public List<string> RequireTags { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// If true, return items that have all RequireTags
|
||||
/// If false, return items that have any tags in RequireTags
|
||||
/// </summary>
|
||||
public bool RequireAllTags { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Don't return any items with this tag
|
||||
/// </summary>
|
||||
public List<string> ExcludeTags { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// If you're querying for a particular file or files, add them to this.
|
||||
/// </summary>
|
||||
public List<ulong> FileId { get; set; } = new List<ulong>();
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Don't call this in production!
|
||||
/// </summary>
|
||||
public void Block()
|
||||
{
|
||||
const int sleepMs = 10;
|
||||
|
||||
workshop.steamworks.Update();
|
||||
|
||||
while ( IsRunning )
|
||||
{
|
||||
#if NET_CORE
|
||||
System.Threading.Tasks.Task.Delay( sleepMs ).Wait();
|
||||
#else
|
||||
System.Threading.Thread.Sleep( sleepMs );
|
||||
#endif
|
||||
workshop.steamworks.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// ReleaseQueryUGCRequest
|
||||
}
|
||||
}
|
||||
|
||||
private enum ItemStatistic : uint
|
||||
{
|
||||
NumSubscriptions = 0,
|
||||
NumFavorites = 1,
|
||||
NumFollowers = 2,
|
||||
NumUniqueSubscriptions = 3,
|
||||
NumUniqueFavorites = 4,
|
||||
NumUniqueFollowers = 5,
|
||||
NumUniqueWebsiteViews = 6,
|
||||
ReportScore = 7,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows you to interact with Steam's UGC stuff (User Generated Content).
|
||||
/// To put simply, this allows you to upload a folder of files to Steam.
|
||||
///
|
||||
/// To upload a new file use CreateItem. This returns an Editor object.
|
||||
/// This object is also used to edit existing items.
|
||||
///
|
||||
/// To get a list of items you can call CreateQuery. From there you can download
|
||||
/// an item and retrieve the folder that it's downloaded to.
|
||||
///
|
||||
/// Generally there's no need to compress and decompress your uploads, so you should
|
||||
/// usually be able to use the content straight from the destination folder.
|
||||
///
|
||||
/// </summary>
|
||||
public partial class Workshop : IDisposable
|
||||
{
|
||||
static Workshop()
|
||||
{
|
||||
Debug.Assert( Marshal.SizeOf( typeof(PublishedFileId_t) ) == Marshal.SizeOf( typeof(ulong) ),
|
||||
$"sizeof({nameof(PublishedFileId_t)}) != sizeof({nameof(UInt64)})" );
|
||||
}
|
||||
|
||||
internal const ulong InvalidHandle = 0xffffffffffffffff;
|
||||
|
||||
internal SteamNative.SteamUGC ugc;
|
||||
internal Friends friends;
|
||||
internal BaseSteamworks steamworks;
|
||||
internal SteamNative.SteamRemoteStorage remoteStorage;
|
||||
|
||||
/// <summary>
|
||||
/// Called when an item has been downloaded. This could have been
|
||||
/// because of a call to Download.
|
||||
/// </summary>
|
||||
public event Action<ulong, Callbacks.Result> OnFileDownloaded;
|
||||
|
||||
/// <summary>
|
||||
/// Called when an item has been installed. This could have been
|
||||
/// because of a call to Download or because of a subscription triggered
|
||||
/// via the browser/app.
|
||||
/// </summary>
|
||||
public event Action<ulong> OnItemInstalled;
|
||||
|
||||
internal Workshop( BaseSteamworks steamworks, SteamNative.SteamUGC ugc, SteamNative.SteamRemoteStorage remoteStorage )
|
||||
{
|
||||
this.ugc = ugc;
|
||||
this.steamworks = steamworks;
|
||||
this.remoteStorage = remoteStorage;
|
||||
|
||||
steamworks.RegisterCallback<SteamNative.DownloadItemResult_t>( onDownloadResult );
|
||||
steamworks.RegisterCallback<SteamNative.ItemInstalled_t>( onItemInstalled );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// You should never have to call this manually
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
ugc = null;
|
||||
steamworks = null;
|
||||
remoteStorage = null;
|
||||
friends = null;
|
||||
|
||||
OnFileDownloaded = null;
|
||||
OnItemInstalled = null;
|
||||
}
|
||||
|
||||
private void onItemInstalled( SteamNative.ItemInstalled_t obj )
|
||||
{
|
||||
if ( OnItemInstalled != null && obj.AppID == Client.Instance.AppId )
|
||||
OnItemInstalled( obj.PublishedFileId );
|
||||
}
|
||||
|
||||
private void onDownloadResult( SteamNative.DownloadItemResult_t obj )
|
||||
{
|
||||
if ( OnFileDownloaded != null && obj.AppID == Client.Instance.AppId )
|
||||
OnFileDownloaded( obj.PublishedFileId, (Callbacks.Result) obj.Result );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the IDs of all subscribed workshop items. Not all items may be currently installed.
|
||||
/// </summary>
|
||||
public unsafe ulong[] GetSubscribedItemIds()
|
||||
{
|
||||
var count = ugc.GetNumSubscribedItems();
|
||||
var array = new ulong[count];
|
||||
|
||||
fixed ( ulong* ptr = array )
|
||||
{
|
||||
ugc.GetSubscribedItems( (PublishedFileId_t*) ptr, count );
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
private static ulong[] _sSubscribedItemBuffer;
|
||||
|
||||
/// <summary>
|
||||
/// Get the IDs of all subscribed workshop items, avoiding repeated allocations.
|
||||
/// Not all items may be currently installed.
|
||||
/// </summary>
|
||||
public unsafe int GetSubscribedItemIds( List<ulong> destList )
|
||||
{
|
||||
const int bufferSize = 1024;
|
||||
|
||||
var count = ugc.GetNumSubscribedItems();
|
||||
|
||||
if ( count >= bufferSize )
|
||||
{
|
||||
// Fallback for exceptional cases
|
||||
destList.AddRange( GetSubscribedItemIds() );
|
||||
return (int) count;
|
||||
}
|
||||
|
||||
if ( _sSubscribedItemBuffer == null )
|
||||
{
|
||||
_sSubscribedItemBuffer = new ulong[bufferSize];
|
||||
}
|
||||
|
||||
fixed ( ulong* ptr = _sSubscribedItemBuffer)
|
||||
{
|
||||
count = ugc.GetSubscribedItems( (PublishedFileId_t*) ptr, bufferSize );
|
||||
}
|
||||
|
||||
for ( var i = 0; i < count; ++i )
|
||||
{
|
||||
destList.Add( _sSubscribedItemBuffer[i] );
|
||||
}
|
||||
|
||||
return (int) count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a query object, which is used to get a list of items.
|
||||
///
|
||||
/// This could be a list of the most popular items, or a search,
|
||||
/// or just getting a list of the items you've uploaded.
|
||||
/// </summary>
|
||||
public Query CreateQuery()
|
||||
{
|
||||
return new Query()
|
||||
{
|
||||
AppId = steamworks.AppId,
|
||||
workshop = this,
|
||||
friends = friends
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Editor object with the intention of creating a new item.
|
||||
/// Your item won't actually be created until you call Publish() on the object.
|
||||
/// </summary>
|
||||
public Editor CreateItem( ItemType type = ItemType.Community )
|
||||
{
|
||||
return CreateItem(this.steamworks.AppId, type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Editor object with the intention of creating a new item.
|
||||
/// Your item won't actually be created until you call Publish() on the object.
|
||||
/// Your item will be published to the provided appId.
|
||||
/// </summary>
|
||||
/// <remarks>You need to add app publish permissions for cross app uploading to work.</remarks>
|
||||
public Editor CreateItem( uint workshopUploadAppId, ItemType type = ItemType.Community )
|
||||
{
|
||||
return new Editor() { workshop = this, WorkshopUploadAppId = workshopUploadAppId, Type = type };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a class representing this ItemId. We don't query
|
||||
/// item name, description etc. We don't verify that item exists.
|
||||
/// We don't verify that this item belongs to your app.
|
||||
/// </summary>
|
||||
public Editor EditItem( ulong itemId )
|
||||
{
|
||||
return new Editor() { workshop = this, Id = itemId, WorkshopUploadAppId = steamworks.AppId };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an Item object for a specific item. This doesn't currently
|
||||
/// query the item's name and description. It's only really useful
|
||||
/// if you know an item's ID and want to download it, or check its
|
||||
/// current download status.
|
||||
/// </summary>
|
||||
public Item GetItem( ulong itemid )
|
||||
{
|
||||
return new Item( itemid, this );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How a query should be ordered.
|
||||
/// </summary>
|
||||
public enum Order
|
||||
{
|
||||
RankedByVote = 0,
|
||||
RankedByPublicationDate = 1,
|
||||
AcceptedForGameRankedByAcceptanceDate = 2,
|
||||
RankedByTrend = 3,
|
||||
FavoritedByFriendsRankedByPublicationDate = 4,
|
||||
CreatedByFriendsRankedByPublicationDate = 5,
|
||||
RankedByNumTimesReported = 6,
|
||||
CreatedByFollowedUsersRankedByPublicationDate = 7,
|
||||
NotYetRated = 8,
|
||||
RankedByTotalVotesAsc = 9,
|
||||
RankedByVotesUp = 10,
|
||||
RankedByTextSearch = 11,
|
||||
RankedByTotalUniqueSubscriptions = 12,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The type of item you are querying for
|
||||
/// </summary>
|
||||
public enum QueryType
|
||||
{
|
||||
/// <summary>
|
||||
/// Both MicrotransactionItems and subscriptionItems
|
||||
/// </summary>
|
||||
Items = 0,
|
||||
/// <summary>
|
||||
/// Workshop item that is meant to be voted on for the purpose of selling in-game
|
||||
/// </summary>
|
||||
MicrotransactionItems = 1,
|
||||
/// <summary>
|
||||
/// normal Workshop item that can be subscribed to
|
||||
/// </summary>
|
||||
SubscriptionItems = 2,
|
||||
Collections = 3,
|
||||
Artwork = 4,
|
||||
Videos = 5,
|
||||
Screenshots = 6,
|
||||
AllGuides = 7, // both web guides and integrated guides
|
||||
WebGuides = 8,
|
||||
IntegratedGuides = 9,
|
||||
UsableInGame = 10, // ready-to-use items and integrated guides
|
||||
ControllerBindings = 11,
|
||||
GameManagedItems = 12, // game managed items (not managed by users)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Used to define the item type when creating
|
||||
/// </summary>
|
||||
public enum ItemType
|
||||
{
|
||||
Community = 0, // normal Workshop item that can be subscribed to
|
||||
Microtransaction = 1, // Workshop item that is meant to be voted on for the purpose of selling in-game
|
||||
Collection = 2, // a collection of Workshop or Greenlight items
|
||||
Art = 3, // artwork
|
||||
Video = 4, // external video
|
||||
Screenshot = 5, // screenshot
|
||||
Game = 6, // Greenlight game entry
|
||||
Software = 7, // Greenlight software entry
|
||||
Concept = 8, // Greenlight concept
|
||||
WebGuide = 9, // Steam web guide
|
||||
IntegratedGuide = 10, // application integrated guide
|
||||
Merch = 11, // Workshop merchandise meant to be voted on for the purpose of being sold
|
||||
ControllerBinding = 12, // Steam Controller bindings
|
||||
SteamworksAccessInvite = 13, // internal
|
||||
SteamVideo = 14, // Steam video
|
||||
GameManagedItem = 15, // managed completely by the game, not the user, and not shown on the web
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// When querying a specific user's items this defines what
|
||||
/// type of items you're looking for.
|
||||
/// </summary>
|
||||
public enum UserQueryType : uint
|
||||
{
|
||||
Published = 0,
|
||||
VotedOn,
|
||||
VotedUp,
|
||||
VotedDown,
|
||||
WillVoteLater,
|
||||
Favorited,
|
||||
Subscribed,
|
||||
UsedOrPlayed,
|
||||
Followed,
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using SteamNative;
|
||||
|
||||
namespace Facepunch.Steamworks.Interop
|
||||
{
|
||||
internal class NativeInterface : IDisposable
|
||||
{
|
||||
internal SteamNative.SteamApi api;
|
||||
internal SteamNative.SteamClient client;
|
||||
internal SteamNative.SteamUser user;
|
||||
internal SteamNative.SteamApps apps;
|
||||
internal SteamNative.SteamAppList applist;
|
||||
internal SteamNative.SteamFriends friends;
|
||||
internal SteamNative.SteamMatchmakingServers servers;
|
||||
internal SteamNative.SteamMatchmaking matchmaking;
|
||||
internal SteamNative.SteamInventory inventory;
|
||||
internal SteamNative.SteamNetworking networking;
|
||||
internal SteamNative.SteamUserStats userstats;
|
||||
internal SteamNative.SteamUtils utils;
|
||||
internal SteamNative.SteamScreenshots screenshots;
|
||||
internal SteamNative.SteamHTTP http;
|
||||
internal SteamNative.SteamUGC ugc;
|
||||
internal SteamNative.SteamGameServer gameServer;
|
||||
internal SteamNative.SteamGameServerStats gameServerStats;
|
||||
internal SteamNative.SteamRemoteStorage remoteStorage;
|
||||
|
||||
private bool isServer;
|
||||
|
||||
internal bool InitClient( BaseSteamworks steamworks )
|
||||
{
|
||||
if ( Steamworks.Server.Instance != null )
|
||||
throw new System.Exception("Steam client should be initialized before steam server - or there's big trouble.");
|
||||
|
||||
isServer = false;
|
||||
|
||||
api = new SteamNative.SteamApi();
|
||||
|
||||
if ( !api.SteamAPI_Init() )
|
||||
{
|
||||
Console.Error.WriteLine( "InitClient: SteamAPI_Init returned false" );
|
||||
return false;
|
||||
}
|
||||
|
||||
var hUser = api.SteamAPI_GetHSteamUser();
|
||||
var hPipe = api.SteamAPI_GetHSteamPipe();
|
||||
if ( hPipe == 0 )
|
||||
{
|
||||
Console.Error.WriteLine( "InitClient: hPipe == 0" );
|
||||
return false;
|
||||
}
|
||||
|
||||
FillInterfaces( steamworks, hUser, hPipe );
|
||||
|
||||
if ( !user.IsValid )
|
||||
{
|
||||
Console.Error.WriteLine( "InitClient: ISteamUser is null" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal bool InitServer( BaseSteamworks steamworks, uint IpAddress /*uint32*/, ushort usPort /*uint16*/, ushort GamePort /*uint16*/, ushort QueryPort /*uint16*/, int eServerMode /*int*/, string pchVersionString /*const char **/)
|
||||
{
|
||||
isServer = true;
|
||||
|
||||
api = new SteamNative.SteamApi();
|
||||
|
||||
if ( !api.SteamInternal_GameServer_Init( IpAddress, usPort, GamePort, QueryPort, eServerMode, pchVersionString ) )
|
||||
{
|
||||
Console.Error.WriteLine( "InitServer: GameServer_Init returned false" );
|
||||
return false;
|
||||
}
|
||||
|
||||
var hUser = api.SteamGameServer_GetHSteamUser();
|
||||
var hPipe = api.SteamGameServer_GetHSteamPipe();
|
||||
if ( hPipe == 0 )
|
||||
{
|
||||
Console.Error.WriteLine( "InitServer: hPipe == 0" );
|
||||
return false;
|
||||
}
|
||||
|
||||
FillInterfaces( steamworks, hPipe, hUser );
|
||||
|
||||
if ( !gameServer.IsValid )
|
||||
{
|
||||
gameServer = null;
|
||||
throw new System.Exception( "Steam Server: Couldn't load SteamGameServer012" );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void FillInterfaces( BaseSteamworks steamworks, int hpipe, int huser )
|
||||
{
|
||||
var clientPtr = api.SteamInternal_CreateInterface( "SteamClient017" );
|
||||
if ( clientPtr == IntPtr.Zero )
|
||||
{
|
||||
throw new System.Exception( "Steam Server: Couldn't load SteamClient017" );
|
||||
}
|
||||
|
||||
client = new SteamNative.SteamClient( steamworks, clientPtr );
|
||||
|
||||
user = client.GetISteamUser( huser, hpipe, SteamNative.Defines.STEAMUSER_INTERFACE_VERSION );
|
||||
utils = client.GetISteamUtils( hpipe, SteamNative.Defines.STEAMUTILS_INTERFACE_VERSION );
|
||||
networking = client.GetISteamNetworking( huser, hpipe, SteamNative.Defines.STEAMNETWORKING_INTERFACE_VERSION );
|
||||
gameServerStats = client.GetISteamGameServerStats( huser, hpipe, SteamNative.Defines.STEAMGAMESERVERSTATS_INTERFACE_VERSION );
|
||||
http = client.GetISteamHTTP( huser, hpipe, SteamNative.Defines.STEAMHTTP_INTERFACE_VERSION );
|
||||
inventory = client.GetISteamInventory( huser, hpipe, SteamNative.Defines.STEAMINVENTORY_INTERFACE_VERSION );
|
||||
ugc = client.GetISteamUGC( huser, hpipe, SteamNative.Defines.STEAMUGC_INTERFACE_VERSION );
|
||||
apps = client.GetISteamApps( huser, hpipe, SteamNative.Defines.STEAMAPPS_INTERFACE_VERSION );
|
||||
gameServer = client.GetISteamGameServer( huser, hpipe, SteamNative.Defines.STEAMGAMESERVER_INTERFACE_VERSION );
|
||||
friends = client.GetISteamFriends( huser, hpipe, SteamNative.Defines.STEAMFRIENDS_INTERFACE_VERSION );
|
||||
servers = client.GetISteamMatchmakingServers( huser, hpipe, SteamNative.Defines.STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION );
|
||||
userstats = client.GetISteamUserStats( huser, hpipe, SteamNative.Defines.STEAMUSERSTATS_INTERFACE_VERSION );
|
||||
screenshots = client.GetISteamScreenshots( huser, hpipe, SteamNative.Defines.STEAMSCREENSHOTS_INTERFACE_VERSION );
|
||||
remoteStorage = client.GetISteamRemoteStorage( huser, hpipe, SteamNative.Defines.STEAMREMOTESTORAGE_INTERFACE_VERSION );
|
||||
matchmaking = client.GetISteamMatchmaking( huser, hpipe, SteamNative.Defines.STEAMMATCHMAKING_INTERFACE_VERSION );
|
||||
applist = client.GetISteamAppList( huser, hpipe, SteamNative.Defines.STEAMAPPLIST_INTERFACE_VERSION );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if ( user != null )
|
||||
{
|
||||
user.Dispose();
|
||||
user = null;
|
||||
}
|
||||
|
||||
if ( utils != null )
|
||||
{
|
||||
utils.Dispose();
|
||||
utils = null;
|
||||
}
|
||||
|
||||
if ( networking != null )
|
||||
{
|
||||
networking.Dispose();
|
||||
networking = null;
|
||||
}
|
||||
|
||||
if ( gameServerStats != null )
|
||||
{
|
||||
gameServerStats.Dispose();
|
||||
gameServerStats = null;
|
||||
}
|
||||
|
||||
if ( http != null )
|
||||
{
|
||||
http.Dispose();
|
||||
http = null;
|
||||
}
|
||||
|
||||
if ( inventory != null )
|
||||
{
|
||||
inventory.Dispose();
|
||||
inventory = null;
|
||||
}
|
||||
|
||||
if ( ugc != null )
|
||||
{
|
||||
ugc.Dispose();
|
||||
ugc = null;
|
||||
}
|
||||
|
||||
if ( apps != null )
|
||||
{
|
||||
apps.Dispose();
|
||||
apps = null;
|
||||
}
|
||||
|
||||
if ( gameServer != null )
|
||||
{
|
||||
gameServer.Dispose();
|
||||
gameServer = null;
|
||||
}
|
||||
|
||||
if ( friends != null )
|
||||
{
|
||||
friends.Dispose();
|
||||
friends = null;
|
||||
}
|
||||
|
||||
if ( servers != null )
|
||||
{
|
||||
servers.Dispose();
|
||||
servers = null;
|
||||
}
|
||||
|
||||
if ( userstats != null )
|
||||
{
|
||||
userstats.Dispose();
|
||||
userstats = null;
|
||||
}
|
||||
|
||||
if ( screenshots != null )
|
||||
{
|
||||
screenshots.Dispose();
|
||||
screenshots = null;
|
||||
}
|
||||
|
||||
if ( remoteStorage != null )
|
||||
{
|
||||
remoteStorage.Dispose();
|
||||
remoteStorage = null;
|
||||
}
|
||||
|
||||
if ( matchmaking != null )
|
||||
{
|
||||
matchmaking.Dispose();
|
||||
matchmaking = null;
|
||||
}
|
||||
|
||||
if ( applist != null )
|
||||
{
|
||||
applist.Dispose();
|
||||
applist = null;
|
||||
}
|
||||
|
||||
if ( client != null )
|
||||
{
|
||||
client.Dispose();
|
||||
client = null;
|
||||
}
|
||||
|
||||
if ( api != null )
|
||||
{
|
||||
if ( isServer )
|
||||
api.SteamGameServer_Shutdown();
|
||||
else
|
||||
api.SteamAPI_Shutdown();
|
||||
|
||||
//
|
||||
// The functions above destroy the pipeline handles
|
||||
// and all of the classes. Trying to call a steam function
|
||||
// at this point will result in a crash - because any
|
||||
// pointers we stored are not invalid.
|
||||
//
|
||||
|
||||
api.Dispose();
|
||||
api = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#if !NET_CORE
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Facepunch.Steamworks")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Facepunch Studios Ltd")]
|
||||
[assembly: AssemblyProduct("Facepunch.Steamworks")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("dc2d9fa9-f005-468f-8581-85c79f4e0034")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion( "1.2.0.0" )]
|
||||
[assembly: AssemblyFileVersion("1.2.0.0")]
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,345 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize this class for Game Servers.
|
||||
///
|
||||
/// Game servers offer a limited amount of Steam functionality - and don't require the Steam client.
|
||||
/// </summary>
|
||||
public partial class Server : BaseSteamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// A singleton accessor to get the current client instance.
|
||||
/// </summary>
|
||||
public static Server Instance { get; private set; }
|
||||
|
||||
internal override bool IsGameServer { get { return true; } }
|
||||
|
||||
public ServerQuery Query { get; internal set; }
|
||||
public ServerStats Stats { get; internal set; }
|
||||
public ServerAuth Auth { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a Steam Server instance
|
||||
/// </summary>
|
||||
public Server( uint appId, ServerInit init, bool isPublic) : base( appId )
|
||||
{
|
||||
if ( Instance != null )
|
||||
{
|
||||
throw new System.Exception( "Only one Facepunch.Steamworks.Server can exist - dispose the old one before trying to create a new one." );
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
native = new Interop.NativeInterface();
|
||||
uint ipaddress = 0; // Any Port
|
||||
|
||||
if ( init.SteamPort == 0 ) init.RandomSteamPort();
|
||||
if ( init.IpAddress != null ) ipaddress = Utility.IpToInt32( init.IpAddress );
|
||||
|
||||
//
|
||||
// Get other interfaces
|
||||
//
|
||||
|
||||
//kind of a hack:
|
||||
//use an outdated version number to hide private servers from the server list.
|
||||
//couldn't find a way to do it otherwise - using 1 as the eServerMode doesn't
|
||||
//seem to work, the server info is still returned by the API calls
|
||||
string versionString = isPublic ? init.VersionString : "0.0.0.0";
|
||||
if ( !native.InitServer( this, ipaddress, init.SteamPort, init.GamePort, init.QueryPort, init.Secure ? 3 : 2,
|
||||
isPublic ? init.VersionString : "0.0.0.0" ) )
|
||||
{
|
||||
native.Dispose();
|
||||
native = null;
|
||||
Instance = null;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Register Callbacks
|
||||
//
|
||||
|
||||
SteamNative.Callbacks.RegisterCallbacks( this );
|
||||
|
||||
//
|
||||
// Setup interfaces that client and server both have
|
||||
//
|
||||
SetupCommonInterfaces();
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Initial settings
|
||||
//
|
||||
native.gameServer.EnableHeartbeats( true );
|
||||
MaxPlayers = 32;
|
||||
BotCount = 0;
|
||||
Product = $"{AppId}";
|
||||
ModDir = init.ModDir;
|
||||
GameDescription = init.GameDescription;
|
||||
Passworded = false;
|
||||
DedicatedServer = true;
|
||||
|
||||
//
|
||||
// Child classes
|
||||
//
|
||||
Query = new ServerQuery( this );
|
||||
Stats = new ServerStats( this );
|
||||
Auth = new ServerAuth( this );
|
||||
|
||||
//
|
||||
// Run update, first call does some initialization
|
||||
//
|
||||
Update();
|
||||
}
|
||||
|
||||
~Server()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be called at least once every frame
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
if ( !IsValid )
|
||||
return;
|
||||
|
||||
native.api.SteamGameServer_RunCallbacks();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether this should be marked as a dedicated server.
|
||||
/// If not, it is assumed to be a listen server.
|
||||
/// </summary>
|
||||
public bool DedicatedServer
|
||||
{
|
||||
get { return _dedicatedServer; }
|
||||
set { if ( _dedicatedServer == value ) return; native.gameServer.SetDedicatedServer( value ); _dedicatedServer = value; }
|
||||
}
|
||||
private bool _dedicatedServer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current MaxPlayers.
|
||||
/// This doesn't enforce any kind of limit, it just updates the master server.
|
||||
/// </summary>
|
||||
public int MaxPlayers
|
||||
{
|
||||
get { return _maxplayers; }
|
||||
set { if ( _maxplayers == value ) return; native.gameServer.SetMaxPlayerCount( value ); _maxplayers = value; }
|
||||
}
|
||||
private int _maxplayers = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current BotCount.
|
||||
/// This doesn't enforce any kind of limit, it just updates the master server.
|
||||
/// </summary>
|
||||
public int BotCount
|
||||
{
|
||||
get { return _botcount; }
|
||||
set { if ( _botcount == value ) return; native.gameServer.SetBotPlayerCount( value ); _botcount = value; }
|
||||
}
|
||||
private int _botcount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current Map Name.
|
||||
/// </summary>
|
||||
public string MapName
|
||||
{
|
||||
get { return _mapname; }
|
||||
set { if ( _mapname == value ) return; native.gameServer.SetMapName( value ); _mapname = value; }
|
||||
}
|
||||
private string _mapname;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current ModDir
|
||||
/// </summary>
|
||||
public string ModDir
|
||||
{
|
||||
get { return _modDir; }
|
||||
internal set { if ( _modDir == value ) return; native.gameServer.SetModDir( value ); _modDir = value; }
|
||||
}
|
||||
private string _modDir = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current product
|
||||
/// </summary>
|
||||
public string Product
|
||||
{
|
||||
get { return _product; }
|
||||
internal set { if ( _product == value ) return; native.gameServer.SetProduct( value ); _product = value; }
|
||||
}
|
||||
private string _product = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current Product
|
||||
/// </summary>
|
||||
public string GameDescription
|
||||
{
|
||||
get { return _gameDescription; }
|
||||
internal set { if ( _gameDescription == value ) return; native.gameServer.SetGameDescription( value ); _gameDescription = value; }
|
||||
}
|
||||
private string _gameDescription = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current ServerName
|
||||
/// </summary>
|
||||
public string ServerName
|
||||
{
|
||||
get { return _serverName; }
|
||||
set { if ( _serverName == value ) return; native.gameServer.SetServerName( value ); _serverName = value; }
|
||||
}
|
||||
private string _serverName = "";
|
||||
|
||||
/// <summary>
|
||||
/// Set whether the server should report itself as passworded
|
||||
/// </summary>
|
||||
public bool Passworded
|
||||
{
|
||||
get { return _passworded; }
|
||||
set { if ( _passworded == value ) return; native.gameServer.SetPasswordProtected( value ); _passworded = value; }
|
||||
}
|
||||
private bool _passworded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current GameTags. This is a comma seperated list of tags for this server.
|
||||
/// When querying the server list you can filter by these tags.
|
||||
/// </summary>
|
||||
public string GameTags
|
||||
{
|
||||
get { return _gametags; }
|
||||
set { if ( _gametags == value ) return; native.gameServer.SetGameTags( value ); _gametags = value; }
|
||||
}
|
||||
private string _gametags = "";
|
||||
|
||||
/// <summary>
|
||||
/// Log onto Steam anonymously.
|
||||
/// </summary>
|
||||
public void LogOnAnonymous()
|
||||
{
|
||||
native.gameServer.LogOnAnonymous();
|
||||
ForceHeartbeat();
|
||||
}
|
||||
|
||||
/// <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 bool LoggedOn => native.gameServer.BLoggedOn();
|
||||
|
||||
Dictionary<string, string> KeyValue = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Sets a Key Value. These can be anything you like, and are accessible
|
||||
/// when querying servers from the server list.
|
||||
///
|
||||
/// Information describing gamemodes are common here.
|
||||
/// </summary>
|
||||
public void SetKey( string Key, string Value )
|
||||
{
|
||||
if ( KeyValue.ContainsKey( Key ) )
|
||||
{
|
||||
if ( KeyValue[Key] == Value )
|
||||
return;
|
||||
|
||||
KeyValue[Key] = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyValue.Add( Key, Value );
|
||||
}
|
||||
|
||||
native.gameServer.SetKeyValue( Key, Value );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update this connected player's information. You should really call this
|
||||
/// any time a player's name or score changes. This keeps the information shown
|
||||
/// to server queries up to date.
|
||||
/// </summary>
|
||||
public void UpdatePlayer( ulong steamid, string name, int score )
|
||||
{
|
||||
native.gameServer.BUpdateUserData( steamid, name, (uint) score );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown interface, disconnect from Steam
|
||||
/// </summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
if ( disposed ) return;
|
||||
|
||||
if ( Query != null )
|
||||
{
|
||||
Query = null;
|
||||
}
|
||||
|
||||
if ( Stats != null )
|
||||
{
|
||||
Stats = null;
|
||||
}
|
||||
|
||||
if ( Auth != null )
|
||||
{
|
||||
Auth = null;
|
||||
}
|
||||
|
||||
if ( Instance == this )
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <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 System.Net.IPAddress PublicIp
|
||||
{
|
||||
get
|
||||
{
|
||||
var ip = native.gameServer.GetPublicIP();
|
||||
if ( ip == 0 ) return null;
|
||||
|
||||
return Utility.Int32ToIp( ip );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable heartbeats, which are sent regularly to the master server.
|
||||
/// Enabled by default.
|
||||
/// </summary>
|
||||
public bool AutomaticHeartbeats
|
||||
{
|
||||
set { native.gameServer.EnableHeartbeats( value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set heartbeat interval, if automatic heartbeats are enabled.
|
||||
/// You can leave this at the default.
|
||||
/// </summary>
|
||||
public int AutomaticHeartbeatRate
|
||||
{
|
||||
set { native.gameServer.SetHeartbeatInterval( value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Force send a heartbeat to the master server instead of waiting
|
||||
/// for the next automatic update (if you've left them enabled)
|
||||
/// </summary>
|
||||
public void ForceHeartbeat()
|
||||
{
|
||||
native.gameServer.ForceHeartbeat();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class ServerAuth
|
||||
{
|
||||
internal Server server;
|
||||
|
||||
/// <summary>
|
||||
/// Steamid, Ownerid, Status
|
||||
/// </summary>
|
||||
public Action<ulong, ulong, Status> OnAuthChange;
|
||||
|
||||
/// <summary>
|
||||
/// Steam authetication statuses
|
||||
/// </summary>
|
||||
public enum Status : int
|
||||
{
|
||||
OK = 0,
|
||||
UserNotConnectedToSteam = 1,
|
||||
NoLicenseOrExpired = 2,
|
||||
VACBanned = 3,
|
||||
LoggedInElseWhere = 4,
|
||||
VACCheckTimedOut = 5,
|
||||
AuthTicketCanceled = 6,
|
||||
AuthTicketInvalidAlreadyUsed = 7,
|
||||
AuthTicketInvalid = 8,
|
||||
PublisherIssuedBan = 9,
|
||||
}
|
||||
|
||||
internal ServerAuth( Server s )
|
||||
{
|
||||
server = s;
|
||||
|
||||
server.RegisterCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate );
|
||||
}
|
||||
|
||||
void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data )
|
||||
{
|
||||
if ( OnAuthChange != null )
|
||||
OnAuthChange( data.SteamID, data.OwnerSteamID, (Status) data.AuthSessionResponse );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start authorizing a ticket. This user isn't authorized yet. Wait for a call to OnAuthChange.
|
||||
/// </summary>
|
||||
public unsafe bool StartSession( byte[] data, ulong steamid )
|
||||
{
|
||||
fixed ( byte* p = data )
|
||||
{
|
||||
var result = server.native.gameServer.BeginAuthSession( (IntPtr)p, data.Length, steamid );
|
||||
|
||||
if ( result == SteamNative.BeginAuthSessionResult.OK )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forget this guy. They're no longer in the game.
|
||||
/// </summary>
|
||||
public void EndSession( ulong steamid )
|
||||
{
|
||||
server.native.gameServer.EndAuthSession( steamid );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// If you're manually processing the server queries, you should use this class.
|
||||
/// </summary>
|
||||
public class ServerQuery
|
||||
{
|
||||
internal Server server;
|
||||
internal static byte[] buffer = new byte[64*1024];
|
||||
|
||||
internal ServerQuery( Server s )
|
||||
{
|
||||
server = s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A server query packet.
|
||||
/// </summary>
|
||||
public struct Packet
|
||||
{
|
||||
/// <summary>
|
||||
/// Target IP address
|
||||
/// </summary>
|
||||
public uint Address { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Target port
|
||||
/// </summary>
|
||||
public ushort Port { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// This data is pooled. Make a copy if you don't use it immediately.
|
||||
/// This buffer is also quite large - so pay attention to Size.
|
||||
/// </summary>
|
||||
public byte[] Data { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the data
|
||||
/// </summary>
|
||||
public int Size { get; internal set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, Steam wants to send a packet. You should respond by sending
|
||||
/// this packet in an unconnected way to the returned Address and Port.
|
||||
/// </summary>
|
||||
/// <param name="packet">Packet to send. The Data passed is pooled - so use it immediately.</param>
|
||||
/// <returns>True if we want to send a packet</returns>
|
||||
public unsafe bool GetOutgoingPacket( out Packet packet )
|
||||
{
|
||||
packet = new Packet();
|
||||
|
||||
fixed ( byte* ptr = buffer )
|
||||
{
|
||||
uint addr = 0;
|
||||
ushort port = 0;
|
||||
|
||||
var size = server.native.gameServer.GetNextOutgoingPacket( (IntPtr)ptr, buffer.Length, out addr, out port );
|
||||
if ( size == 0 )
|
||||
return false;
|
||||
|
||||
packet.Size = size;
|
||||
packet.Data = buffer;
|
||||
packet.Address = addr;
|
||||
packet.Port = port;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We have received a server query on our game port. Pass it to Steam to handle.
|
||||
/// </summary>
|
||||
public unsafe void Handle( byte[] data, int size, uint address, ushort port )
|
||||
{
|
||||
fixed ( byte* ptr = data )
|
||||
{
|
||||
server.native.gameServer.HandleIncomingPacket( (IntPtr)ptr, size, address, port );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to set up the server.
|
||||
/// The variables in here are all required to be set, and can't be changed once the server is created.
|
||||
/// </summary>
|
||||
public class ServerInit
|
||||
{
|
||||
public IPAddress IpAddress;
|
||||
public ushort SteamPort;
|
||||
public ushort GamePort = 27015;
|
||||
public ushort QueryPort = 27016;
|
||||
public bool Secure = true;
|
||||
|
||||
/// <summary>
|
||||
/// The version string is usually in the form x.x.x.x, and is used by the master server to detect when the server is out of date.
|
||||
/// If you go into the dedicated server tab on steamworks you'll be able to server the latest version. If this version number is
|
||||
/// less than that latest version then your server won't show.
|
||||
/// </summary>
|
||||
public string VersionString = "1.0.0.0";
|
||||
|
||||
/// <summary>
|
||||
/// This should be the same directory game where gets installed into. Just the folder name, not the whole path. I.e. "Rust", "Garrysmod".
|
||||
/// </summary>
|
||||
public string ModDir = "unset";
|
||||
|
||||
/// <summary>
|
||||
/// The game description. Setting this to the full name of your game is recommended.
|
||||
/// </summary>
|
||||
public string GameDescription = "unset";
|
||||
|
||||
|
||||
public ServerInit( string modDir, string gameDesc )
|
||||
{
|
||||
ModDir = modDir;
|
||||
GameDescription = gameDesc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the Steam quert port
|
||||
/// </summary>
|
||||
public ServerInit RandomSteamPort()
|
||||
{
|
||||
SteamPort = (ushort)new Random().Next( 10000, 60000 );
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If you pass MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE into usQueryPort, then it causes the game server API to use
|
||||
/// "GameSocketShare" mode, which means that the game is responsible for sending and receiving UDP packets for the master
|
||||
/// server updater.
|
||||
///
|
||||
/// More info about this here: https://partner.steamgames.com/doc/api/ISteamGameServer#HandleIncomingPacket
|
||||
/// </summary>
|
||||
public ServerInit QueryShareGamePort()
|
||||
{
|
||||
QueryPort = 0xFFFF;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows getting and setting stats on users from the gameserver. These stats
|
||||
/// should have been set up on the Steamworks website for your app.
|
||||
/// </summary>
|
||||
public class ServerStats
|
||||
{
|
||||
internal Server server;
|
||||
|
||||
internal ServerStats( Server s )
|
||||
{
|
||||
server = s;
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
public struct StatsReceived
|
||||
{
|
||||
public int Result;
|
||||
public ulong SteamId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the stats for this user. If you pass a callback function in
|
||||
/// this will be called when the stats are recieved, the bool will signify whether
|
||||
/// it was successful or not.
|
||||
/// </summary>
|
||||
public void Refresh( ulong steamid, Action<ulong, bool> Callback = null )
|
||||
{
|
||||
if ( Callback == null )
|
||||
{
|
||||
server.native.gameServerStats.RequestUserStats( steamid );
|
||||
return;
|
||||
}
|
||||
|
||||
server.native.gameServerStats.RequestUserStats( steamid, ( o, failed ) =>
|
||||
{
|
||||
Callback( steamid, o.Result == SteamNative.Result.OK && !failed );
|
||||
} );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Once you've set a stat change on a user you need to commit your changes.
|
||||
/// You can do that using this function. The callback will let you know if
|
||||
/// your action succeeded, but most of the time you can fire and forget.
|
||||
/// </summary>
|
||||
public void Commit( ulong steamid, Action<ulong, bool> Callback = null )
|
||||
{
|
||||
if ( Callback == null )
|
||||
{
|
||||
server.native.gameServerStats.StoreUserStats( steamid );
|
||||
return;
|
||||
}
|
||||
|
||||
server.native.gameServerStats.StoreUserStats( steamid, ( o, failed ) =>
|
||||
{
|
||||
Callback( steamid, o.Result == SteamNative.Result.OK && !failed );
|
||||
} );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the named stat for this user. Setting stats should follow the rules
|
||||
/// you defined in Steamworks.
|
||||
/// </summary>
|
||||
public bool SetInt( ulong steamid, string name, int stat )
|
||||
{
|
||||
return server.native.gameServerStats.SetUserStat( steamid, name, stat );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the named stat for this user. Setting stats should follow the rules
|
||||
/// you defined in Steamworks.
|
||||
/// </summary>
|
||||
public bool SetFloat( ulong steamid, string name, float stat )
|
||||
{
|
||||
return server.native.gameServerStats.SetUserStat0( steamid, name, stat );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the named stat for this user. If getting the stat failed, will return
|
||||
/// defaultValue. You should have called Refresh for this userid - which downloads
|
||||
/// the stats from the backend. If you didn't call it this will always return defaultValue.
|
||||
/// </summary>
|
||||
public int GetInt( ulong steamid, string name, int defaultValue = 0 )
|
||||
{
|
||||
int data = defaultValue;
|
||||
|
||||
if ( !server.native.gameServerStats.GetUserStat( steamid, name, out data ) )
|
||||
return defaultValue;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the named stat for this user. If getting the stat failed, will return
|
||||
/// defaultValue. You should have called Refresh for this userid - which downloads
|
||||
/// the stats from the backend. If you didn't call it this will always return defaultValue.
|
||||
/// </summary>
|
||||
public float GetFloat( ulong steamid, string name, float defaultValue = 0 )
|
||||
{
|
||||
float data = defaultValue;
|
||||
|
||||
if ( !server.native.gameServerStats.GetUserStat0( steamid, name, out data ) )
|
||||
return defaultValue;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlocks the specified achievement for the specified user. Must have called Refresh on a steamid first.
|
||||
/// Remember to use Commit after use.
|
||||
/// </summary>
|
||||
public bool SetAchievement( ulong steamid, string name )
|
||||
{
|
||||
return server.native.gameServerStats.SetUserAchievement( steamid, name );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the unlock status of an achievement for the specified user. Must have called Refresh on a steamid first.
|
||||
/// Remember to use Commit after use.
|
||||
/// </summary>
|
||||
public bool ClearAchievement( ulong steamid, string name )
|
||||
{
|
||||
return server.native.gameServerStats.ClearUserAchievement( steamid, name );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if available, exists and unlocked
|
||||
/// </summary>
|
||||
public bool GetAchievement( ulong steamid, string name )
|
||||
{
|
||||
bool achieved = false;
|
||||
|
||||
if ( !server.native.gameServerStats.GetUserAchievement( steamid, name, ref achieved ) )
|
||||
return false;
|
||||
|
||||
return achieved;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Facepunch.Steamworks;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
[StructLayout( LayoutKind.Sequential )]
|
||||
internal class Callback
|
||||
{
|
||||
internal enum Flags : byte
|
||||
{
|
||||
Registered = 0x01,
|
||||
GameServer = 0x02
|
||||
}
|
||||
|
||||
public IntPtr vTablePtr;
|
||||
public byte CallbackFlags;
|
||||
public int CallbackId;
|
||||
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public class VTable
|
||||
{
|
||||
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultD( IntPtr pvParam );
|
||||
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultWithInfoD( IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
|
||||
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate int GetSizeD();
|
||||
|
||||
public ResultD ResultA;
|
||||
public ResultWithInfoD ResultB;
|
||||
public GetSizeD GetSize;
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public class VTableWin
|
||||
{
|
||||
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultD( IntPtr pvParam );
|
||||
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate void ResultWithInfoD( IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
|
||||
[UnmanagedFunctionPointer( CallingConvention.StdCall )] public delegate int GetSizeD();
|
||||
|
||||
public ResultWithInfoD ResultB;
|
||||
public ResultD ResultA;
|
||||
public GetSizeD GetSize;
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public class VTableThis
|
||||
{
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultD( IntPtr thisptr, IntPtr pvParam );
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfoD( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSizeD( IntPtr thisptr );
|
||||
|
||||
public ResultD ResultA;
|
||||
public ResultWithInfoD ResultB;
|
||||
public GetSizeD GetSize;
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||
public class VTableWinThis
|
||||
{
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultD( IntPtr thisptr, IntPtr pvParam );
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate void ResultWithInfoD( IntPtr thisptr, IntPtr pvParam, bool bIOFailure, SteamNative.SteamAPICall_t hSteamAPICall );
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )] public delegate int GetSizeD( IntPtr thisptr );
|
||||
|
||||
public ResultWithInfoD ResultB;
|
||||
public ResultD ResultA;
|
||||
public GetSizeD GetSize;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Created on registration of a callback
|
||||
//
|
||||
internal class CallbackHandle : IDisposable
|
||||
{
|
||||
internal BaseSteamworks Steamworks;
|
||||
|
||||
// Get Rid
|
||||
internal GCHandle FuncA;
|
||||
internal GCHandle FuncB;
|
||||
internal GCHandle FuncC;
|
||||
internal IntPtr vTablePtr;
|
||||
internal GCHandle PinnedCallback;
|
||||
|
||||
internal CallbackHandle( Facepunch.Steamworks.BaseSteamworks steamworks )
|
||||
{
|
||||
Steamworks = steamworks;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
UnregisterCallback();
|
||||
|
||||
if ( FuncA.IsAllocated )
|
||||
FuncA.Free();
|
||||
|
||||
if ( FuncB.IsAllocated )
|
||||
FuncB.Free();
|
||||
|
||||
if ( FuncC.IsAllocated )
|
||||
FuncC.Free();
|
||||
|
||||
if ( PinnedCallback.IsAllocated )
|
||||
PinnedCallback.Free();
|
||||
|
||||
if ( vTablePtr != IntPtr.Zero )
|
||||
{
|
||||
Marshal.FreeHGlobal( vTablePtr );
|
||||
vTablePtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private void UnregisterCallback()
|
||||
{
|
||||
if ( !PinnedCallback.IsAllocated )
|
||||
return;
|
||||
|
||||
Steamworks.native.api.SteamAPI_UnregisterCallback( PinnedCallback.AddrOfPinnedObject() );
|
||||
}
|
||||
|
||||
public virtual bool IsValid { get { return true; } }
|
||||
}
|
||||
|
||||
internal abstract class CallResult : CallbackHandle
|
||||
{
|
||||
internal SteamAPICall_t Call;
|
||||
public override bool IsValid { get { return Call > 0; } }
|
||||
|
||||
|
||||
internal CallResult( Facepunch.Steamworks.BaseSteamworks steamworks, SteamAPICall_t call ) : base( steamworks )
|
||||
{
|
||||
Call = call;
|
||||
}
|
||||
|
||||
internal void Try()
|
||||
{
|
||||
bool failed = false;
|
||||
|
||||
if ( !Steamworks.native.utils.IsAPICallCompleted( Call, ref failed ))
|
||||
return;
|
||||
|
||||
Steamworks.UnregisterCallResult( this );
|
||||
|
||||
RunCallback();
|
||||
}
|
||||
|
||||
internal abstract void RunCallback();
|
||||
}
|
||||
|
||||
|
||||
internal class CallResult<T> : CallResult
|
||||
{
|
||||
private static byte[] resultBuffer = new byte[1024 * 16];
|
||||
|
||||
internal delegate T ConvertFromPointer( IntPtr p );
|
||||
|
||||
Action<T, bool> CallbackFunction;
|
||||
ConvertFromPointer ConvertFromPointerFunction;
|
||||
|
||||
internal int ResultSize = -1;
|
||||
internal int CallbackId = 0;
|
||||
|
||||
internal CallResult( Facepunch.Steamworks.BaseSteamworks steamworks, SteamAPICall_t call, Action<T, bool> callbackFunction, ConvertFromPointer fromPointer, int resultSize, int callbackId ) : base( steamworks, call )
|
||||
{
|
||||
ResultSize = resultSize;
|
||||
CallbackId = callbackId;
|
||||
CallbackFunction = callbackFunction;
|
||||
ConvertFromPointerFunction = fromPointer;
|
||||
|
||||
Steamworks.RegisterCallResult( this );
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"CallResult( {typeof(T).Name}, {CallbackId}, {ResultSize}b )";
|
||||
}
|
||||
|
||||
unsafe internal override void RunCallback()
|
||||
{
|
||||
bool failed = false;
|
||||
|
||||
fixed ( byte* ptr = resultBuffer )
|
||||
{
|
||||
if ( !Steamworks.native.utils.GetAPICallResult( Call, (IntPtr)ptr, resultBuffer.Length, CallbackId, ref failed ) || failed )
|
||||
{
|
||||
CallbackFunction( default(T), true );
|
||||
return;
|
||||
}
|
||||
|
||||
var val = ConvertFromPointerFunction( (IntPtr)ptr );
|
||||
CallbackFunction( val, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class MonoPInvokeCallbackAttribute : Attribute
|
||||
{
|
||||
public MonoPInvokeCallbackAttribute() { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal static class CallbackIdentifiers
|
||||
{
|
||||
public const int SteamUser = 100;
|
||||
public const int SteamGameServer = 200;
|
||||
public const int SteamFriends = 300;
|
||||
public const int SteamBilling = 400;
|
||||
public const int SteamMatchmaking = 500;
|
||||
public const int SteamContentServer = 600;
|
||||
public const int SteamUtils = 700;
|
||||
public const int ClientFriends = 800;
|
||||
public const int ClientUser = 900;
|
||||
public const int SteamApps = 1000;
|
||||
public const int SteamUserStats = 1100;
|
||||
public const int SteamNetworking = 1200;
|
||||
public const int ClientRemoteStorage = 1300;
|
||||
public const int ClientDepotBuilder = 1400;
|
||||
public const int SteamGameServerItems = 1500;
|
||||
public const int ClientUtils = 1600;
|
||||
public const int SteamGameCoordinator = 1700;
|
||||
public const int SteamGameServerStats = 1800;
|
||||
public const int Steam2Async = 1900;
|
||||
public const int SteamGameStats = 2000;
|
||||
public const int ClientHTTP = 2100;
|
||||
public const int ClientScreenshots = 2200;
|
||||
public const int SteamScreenshots = 2300;
|
||||
public const int ClientAudio = 2400;
|
||||
public const int ClientUnifiedMessages = 2500;
|
||||
public const int SteamStreamLauncher = 2600;
|
||||
public const int ClientController = 2700;
|
||||
public const int SteamController = 2800;
|
||||
public const int ClientParentalSettings = 2900;
|
||||
public const int ClientDeviceAuth = 3000;
|
||||
public const int ClientNetworkDeviceManager = 3100;
|
||||
public const int ClientMusic = 3200;
|
||||
public const int ClientRemoteClientManager = 3300;
|
||||
public const int ClientUGC = 3400;
|
||||
public const int SteamStreamClient = 3500;
|
||||
public const int ClientProductBuilder = 3600;
|
||||
public const int ClientShortcuts = 3700;
|
||||
public const int ClientRemoteControlManager = 3800;
|
||||
public const int SteamAppList = 3900;
|
||||
public const int SteamMusic = 4000;
|
||||
public const int SteamMusicRemote = 4100;
|
||||
public const int ClientVR = 4200;
|
||||
public const int ClientGameNotification = 4300;
|
||||
public const int SteamGameNotification = 4400;
|
||||
public const int SteamHTMLSurface = 4500;
|
||||
public const int ClientVideo = 4600;
|
||||
public const int ClientInventory = 4700;
|
||||
public const int ClientBluetoothManager = 4800;
|
||||
public const int ClientSharedConnection = 4900;
|
||||
public const int SteamParentalSettings = 5000;
|
||||
public const int ClientShader = 5100;
|
||||
}
|
||||
internal static class Defines
|
||||
{
|
||||
internal const string STEAMAPPLIST_INTERFACE_VERSION = "STEAMAPPLIST_INTERFACE_VERSION001";
|
||||
internal const string STEAMAPPS_INTERFACE_VERSION = "STEAMAPPS_INTERFACE_VERSION008";
|
||||
internal const string STEAMAPPTICKET_INTERFACE_VERSION = "STEAMAPPTICKET_INTERFACE_VERSION001";
|
||||
internal const string STEAMCONTROLLER_INTERFACE_VERSION = "SteamController006";
|
||||
internal const string STEAMFRIENDS_INTERFACE_VERSION = "SteamFriends015";
|
||||
internal const string STEAMGAMECOORDINATOR_INTERFACE_VERSION = "SteamGameCoordinator001";
|
||||
internal const string STEAMGAMESERVER_INTERFACE_VERSION = "SteamGameServer012";
|
||||
internal const string STEAMGAMESERVERSTATS_INTERFACE_VERSION = "SteamGameServerStats001";
|
||||
internal const string STEAMHTMLSURFACE_INTERFACE_VERSION = "STEAMHTMLSURFACE_INTERFACE_VERSION_004";
|
||||
internal const string STEAMHTTP_INTERFACE_VERSION = "STEAMHTTP_INTERFACE_VERSION002";
|
||||
internal const string STEAMINVENTORY_INTERFACE_VERSION = "STEAMINVENTORY_INTERFACE_V002";
|
||||
internal const string STEAMMATCHMAKING_INTERFACE_VERSION = "SteamMatchMaking009";
|
||||
internal const string STEAMMATCHMAKINGSERVERS_INTERFACE_VERSION = "SteamMatchMakingServers002";
|
||||
internal const string STEAMMUSIC_INTERFACE_VERSION = "STEAMMUSIC_INTERFACE_VERSION001";
|
||||
internal const string STEAMMUSICREMOTE_INTERFACE_VERSION = "STEAMMUSICREMOTE_INTERFACE_VERSION001";
|
||||
internal const string STEAMNETWORKING_INTERFACE_VERSION = "SteamNetworking005";
|
||||
internal const string STEAMPARENTALSETTINGS_INTERFACE_VERSION = "STEAMPARENTALSETTINGS_INTERFACE_VERSION001";
|
||||
internal const string STEAMREMOTESTORAGE_INTERFACE_VERSION = "STEAMREMOTESTORAGE_INTERFACE_VERSION014";
|
||||
internal const string STEAMSCREENSHOTS_INTERFACE_VERSION = "STEAMSCREENSHOTS_INTERFACE_VERSION003";
|
||||
internal const string STEAMUGC_INTERFACE_VERSION = "STEAMUGC_INTERFACE_VERSION010";
|
||||
internal const string STEAMUSER_INTERFACE_VERSION = "SteamUser019";
|
||||
internal const string STEAMUSERSTATS_INTERFACE_VERSION = "STEAMUSERSTATS_INTERFACE_VERSION011";
|
||||
internal const string STEAMUTILS_INTERFACE_VERSION = "SteamUtils009";
|
||||
internal const string STEAMVIDEO_INTERFACE_VERSION = "STEAMVIDEO_INTERFACE_V002";
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal static class Helpers
|
||||
{
|
||||
private static StringBuilder[] StringBuilderPool;
|
||||
private static int StringBuilderPoolIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a StringBuilder. This will get returned and reused later on.
|
||||
/// </summary>
|
||||
public static StringBuilder TakeStringBuilder()
|
||||
{
|
||||
if ( StringBuilderPool == null )
|
||||
{
|
||||
//
|
||||
// The pool has 8 items. This should be safe because we shouldn't really
|
||||
// ever be using more than 2 StringBuilders at the same time.
|
||||
//
|
||||
StringBuilderPool = new StringBuilder[8];
|
||||
|
||||
for ( int i = 0; i < StringBuilderPool.Length; i++ )
|
||||
StringBuilderPool[i] = new StringBuilder( 4096 );
|
||||
}
|
||||
|
||||
StringBuilderPoolIndex++;
|
||||
if ( StringBuilderPoolIndex >= StringBuilderPool.Length )
|
||||
StringBuilderPoolIndex = 0;
|
||||
|
||||
StringBuilderPool[StringBuilderPoolIndex].Capacity = 4096;
|
||||
StringBuilderPool[StringBuilderPoolIndex].Length = 0;
|
||||
|
||||
return StringBuilderPool[StringBuilderPoolIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,717 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal static partial class Platform
|
||||
{
|
||||
internal interface Interface : IDisposable
|
||||
{
|
||||
// Implementation should return true if _ptr is non null
|
||||
bool IsValid { get; }
|
||||
|
||||
uint /*uint32*/ ISteamAppList_GetNumInstalledApps();
|
||||
uint /*uint32*/ ISteamAppList_GetInstalledApps( IntPtr /*AppId_t **/ pvecAppID, uint /*uint32*/ unMaxAppIDs );
|
||||
int /*int*/ ISteamAppList_GetAppName( uint nAppID, System.Text.StringBuilder /*char **/ pchName, int /*int*/ cchNameMax );
|
||||
int /*int*/ ISteamAppList_GetAppInstallDir( uint nAppID, System.Text.StringBuilder /*char **/ pchDirectory, int /*int*/ cchNameMax );
|
||||
int /*int*/ ISteamAppList_GetAppBuildId( uint nAppID );
|
||||
bool /*bool*/ ISteamApps_BIsSubscribed();
|
||||
bool /*bool*/ ISteamApps_BIsLowViolence();
|
||||
bool /*bool*/ ISteamApps_BIsCybercafe();
|
||||
bool /*bool*/ ISteamApps_BIsVACBanned();
|
||||
IntPtr ISteamApps_GetCurrentGameLanguage();
|
||||
IntPtr ISteamApps_GetAvailableGameLanguages();
|
||||
bool /*bool*/ ISteamApps_BIsSubscribedApp( uint appID );
|
||||
bool /*bool*/ ISteamApps_BIsDlcInstalled( uint appID );
|
||||
uint /*uint32*/ ISteamApps_GetEarliestPurchaseUnixTime( uint nAppID );
|
||||
bool /*bool*/ ISteamApps_BIsSubscribedFromFreeWeekend();
|
||||
int /*int*/ ISteamApps_GetDLCCount();
|
||||
bool /*bool*/ ISteamApps_BGetDLCDataByIndex( int /*int*/ iDLC, ref uint pAppID, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAvailable, System.Text.StringBuilder /*char **/ pchName, int /*int*/ cchNameBufferSize );
|
||||
void /*void*/ ISteamApps_InstallDLC( uint nAppID );
|
||||
void /*void*/ ISteamApps_UninstallDLC( uint nAppID );
|
||||
void /*void*/ ISteamApps_RequestAppProofOfPurchaseKey( uint nAppID );
|
||||
bool /*bool*/ ISteamApps_GetCurrentBetaName( System.Text.StringBuilder /*char **/ pchName, int /*int*/ cchNameBufferSize );
|
||||
bool /*bool*/ ISteamApps_MarkContentCorrupt( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bMissingFilesOnly );
|
||||
uint /*uint32*/ ISteamApps_GetInstalledDepots( uint appID, IntPtr /*DepotId_t **/ pvecDepots, uint /*uint32*/ cMaxDepots );
|
||||
uint /*uint32*/ ISteamApps_GetAppInstallDir( uint appID, System.Text.StringBuilder /*char **/ pchFolder, uint /*uint32*/ cchFolderBufferSize );
|
||||
bool /*bool*/ ISteamApps_BIsAppInstalled( uint appID );
|
||||
CSteamID /*(class CSteamID)*/ ISteamApps_GetAppOwner();
|
||||
IntPtr ISteamApps_GetLaunchQueryParam( string /*const char **/ pchKey );
|
||||
bool /*bool*/ ISteamApps_GetDlcDownloadProgress( uint nAppID, out ulong /*uint64 **/ punBytesDownloaded, out ulong /*uint64 **/ punBytesTotal );
|
||||
int /*int*/ ISteamApps_GetAppBuildId();
|
||||
void /*void*/ ISteamApps_RequestAllProofOfPurchaseKeys();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamApps_GetFileDetails( string /*const char **/ pszFileName );
|
||||
HSteamPipe /*(HSteamPipe)*/ ISteamClient_CreateSteamPipe();
|
||||
bool /*bool*/ ISteamClient_BReleaseSteamPipe( int hSteamPipe );
|
||||
HSteamUser /*(HSteamUser)*/ ISteamClient_ConnectToGlobalUser( int hSteamPipe );
|
||||
HSteamUser /*(HSteamUser)*/ ISteamClient_CreateLocalUser( out int phSteamPipe, AccountType /*EAccountType*/ eAccountType );
|
||||
void /*void*/ ISteamClient_ReleaseUser( int hSteamPipe, int hUser );
|
||||
IntPtr /*class ISteamUser **/ ISteamClient_GetISteamUser( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamGameServer **/ ISteamClient_GetISteamGameServer( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
void /*void*/ ISteamClient_SetLocalIPBinding( uint /*uint32*/ unIP, ushort /*uint16*/ usPort );
|
||||
IntPtr /*class ISteamFriends **/ ISteamClient_GetISteamFriends( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamUtils **/ ISteamClient_GetISteamUtils( int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamMatchmaking **/ ISteamClient_GetISteamMatchmaking( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamMatchmakingServers **/ ISteamClient_GetISteamMatchmakingServers( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*void **/ ISteamClient_GetISteamGenericInterface( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamUserStats **/ ISteamClient_GetISteamUserStats( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamGameServerStats **/ ISteamClient_GetISteamGameServerStats( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamApps **/ ISteamClient_GetISteamApps( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamNetworking **/ ISteamClient_GetISteamNetworking( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamRemoteStorage **/ ISteamClient_GetISteamRemoteStorage( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamScreenshots **/ ISteamClient_GetISteamScreenshots( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
uint /*uint32*/ ISteamClient_GetIPCCallCount();
|
||||
void /*void*/ ISteamClient_SetWarningMessageHook( IntPtr /*SteamAPIWarningMessageHook_t*/ pFunction );
|
||||
bool /*bool*/ ISteamClient_BShutdownIfAllPipesClosed();
|
||||
IntPtr /*class ISteamHTTP **/ ISteamClient_GetISteamHTTP( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamController **/ ISteamClient_GetISteamController( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamUGC **/ ISteamClient_GetISteamUGC( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamAppList **/ ISteamClient_GetISteamAppList( int hSteamUser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamMusic **/ ISteamClient_GetISteamMusic( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamMusicRemote **/ ISteamClient_GetISteamMusicRemote( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamHTMLSurface **/ ISteamClient_GetISteamHTMLSurface( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamInventory **/ ISteamClient_GetISteamInventory( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamVideo **/ ISteamClient_GetISteamVideo( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
IntPtr /*class ISteamParentalSettings **/ ISteamClient_GetISteamParentalSettings( int hSteamuser, int hSteamPipe, string /*const char **/ pchVersion );
|
||||
bool /*bool*/ ISteamController_Init();
|
||||
bool /*bool*/ ISteamController_Shutdown();
|
||||
void /*void*/ ISteamController_RunFrame();
|
||||
int /*int*/ ISteamController_GetConnectedControllers( IntPtr /*ControllerHandle_t **/ handlesOut );
|
||||
bool /*bool*/ ISteamController_ShowBindingPanel( ulong controllerHandle );
|
||||
ControllerActionSetHandle_t /*(ControllerActionSetHandle_t)*/ ISteamController_GetActionSetHandle( string /*const char **/ pszActionSetName );
|
||||
void /*void*/ ISteamController_ActivateActionSet( ulong controllerHandle, ulong actionSetHandle );
|
||||
ControllerActionSetHandle_t /*(ControllerActionSetHandle_t)*/ ISteamController_GetCurrentActionSet( ulong controllerHandle );
|
||||
void /*void*/ ISteamController_ActivateActionSetLayer( ulong controllerHandle, ulong actionSetLayerHandle );
|
||||
void /*void*/ ISteamController_DeactivateActionSetLayer( ulong controllerHandle, ulong actionSetLayerHandle );
|
||||
void /*void*/ ISteamController_DeactivateAllActionSetLayers( ulong controllerHandle );
|
||||
int /*int*/ ISteamController_GetActiveActionSetLayers( ulong controllerHandle, IntPtr /*ControllerActionSetHandle_t **/ handlesOut );
|
||||
ControllerDigitalActionHandle_t /*(ControllerDigitalActionHandle_t)*/ ISteamController_GetDigitalActionHandle( string /*const char **/ pszActionName );
|
||||
ControllerDigitalActionData_t /*struct ControllerDigitalActionData_t*/ ISteamController_GetDigitalActionData( ulong controllerHandle, ulong digitalActionHandle );
|
||||
int /*int*/ ISteamController_GetDigitalActionOrigins( ulong controllerHandle, ulong actionSetHandle, ulong digitalActionHandle, out ControllerActionOrigin /*EControllerActionOrigin **/ originsOut );
|
||||
ControllerAnalogActionHandle_t /*(ControllerAnalogActionHandle_t)*/ ISteamController_GetAnalogActionHandle( string /*const char **/ pszActionName );
|
||||
ControllerAnalogActionData_t /*struct ControllerAnalogActionData_t*/ ISteamController_GetAnalogActionData( ulong controllerHandle, ulong analogActionHandle );
|
||||
int /*int*/ ISteamController_GetAnalogActionOrigins( ulong controllerHandle, ulong actionSetHandle, ulong analogActionHandle, out ControllerActionOrigin /*EControllerActionOrigin **/ originsOut );
|
||||
void /*void*/ ISteamController_StopAnalogActionMomentum( ulong controllerHandle, ulong eAction );
|
||||
void /*void*/ ISteamController_TriggerHapticPulse( ulong controllerHandle, SteamControllerPad /*ESteamControllerPad*/ eTargetPad, ushort /*unsigned short*/ usDurationMicroSec );
|
||||
void /*void*/ ISteamController_TriggerRepeatedHapticPulse( ulong controllerHandle, SteamControllerPad /*ESteamControllerPad*/ eTargetPad, ushort /*unsigned short*/ usDurationMicroSec, ushort /*unsigned short*/ usOffMicroSec, ushort /*unsigned short*/ unRepeat, uint /*unsigned int*/ nFlags );
|
||||
void /*void*/ ISteamController_TriggerVibration( ulong controllerHandle, ushort /*unsigned short*/ usLeftSpeed, ushort /*unsigned short*/ usRightSpeed );
|
||||
void /*void*/ ISteamController_SetLEDColor( ulong controllerHandle, byte /*uint8*/ nColorR, byte /*uint8*/ nColorG, byte /*uint8*/ nColorB, uint /*unsigned int*/ nFlags );
|
||||
int /*int*/ ISteamController_GetGamepadIndexForController( ulong ulControllerHandle );
|
||||
ControllerHandle_t /*(ControllerHandle_t)*/ ISteamController_GetControllerForGamepadIndex( int /*int*/ nIndex );
|
||||
ControllerMotionData_t /*struct ControllerMotionData_t*/ ISteamController_GetMotionData( ulong controllerHandle );
|
||||
bool /*bool*/ ISteamController_ShowDigitalActionOrigins( ulong controllerHandle, ulong digitalActionHandle, float /*float*/ flScale, float /*float*/ flXPosition, float /*float*/ flYPosition );
|
||||
bool /*bool*/ ISteamController_ShowAnalogActionOrigins( ulong controllerHandle, ulong analogActionHandle, float /*float*/ flScale, float /*float*/ flXPosition, float /*float*/ flYPosition );
|
||||
IntPtr ISteamController_GetStringForActionOrigin( ControllerActionOrigin /*EControllerActionOrigin*/ eOrigin );
|
||||
IntPtr ISteamController_GetGlyphForActionOrigin( ControllerActionOrigin /*EControllerActionOrigin*/ eOrigin );
|
||||
SteamInputType /*ESteamInputType*/ ISteamController_GetInputTypeForHandle( ulong controllerHandle );
|
||||
IntPtr ISteamFriends_GetPersonaName();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamFriends_SetPersonaName( string /*const char **/ pchPersonaName );
|
||||
PersonaState /*EPersonaState*/ ISteamFriends_GetPersonaState();
|
||||
int /*int*/ ISteamFriends_GetFriendCount( int /*int*/ iFriendFlags );
|
||||
CSteamID /*(class CSteamID)*/ ISteamFriends_GetFriendByIndex( int /*int*/ iFriend, int /*int*/ iFriendFlags );
|
||||
FriendRelationship /*EFriendRelationship*/ ISteamFriends_GetFriendRelationship( ulong steamIDFriend );
|
||||
PersonaState /*EPersonaState*/ ISteamFriends_GetFriendPersonaState( ulong steamIDFriend );
|
||||
IntPtr ISteamFriends_GetFriendPersonaName( ulong steamIDFriend );
|
||||
bool /*bool*/ ISteamFriends_GetFriendGamePlayed( ulong steamIDFriend, ref FriendGameInfo_t /*struct FriendGameInfo_t **/ pFriendGameInfo );
|
||||
IntPtr ISteamFriends_GetFriendPersonaNameHistory( ulong steamIDFriend, int /*int*/ iPersonaName );
|
||||
int /*int*/ ISteamFriends_GetFriendSteamLevel( ulong steamIDFriend );
|
||||
IntPtr ISteamFriends_GetPlayerNickname( ulong steamIDPlayer );
|
||||
int /*int*/ ISteamFriends_GetFriendsGroupCount();
|
||||
FriendsGroupID_t /*(FriendsGroupID_t)*/ ISteamFriends_GetFriendsGroupIDByIndex( int /*int*/ iFG );
|
||||
IntPtr ISteamFriends_GetFriendsGroupName( short friendsGroupID );
|
||||
int /*int*/ ISteamFriends_GetFriendsGroupMembersCount( short friendsGroupID );
|
||||
void /*void*/ ISteamFriends_GetFriendsGroupMembersList( short friendsGroupID, IntPtr /*class CSteamID **/ pOutSteamIDMembers, int /*int*/ nMembersCount );
|
||||
bool /*bool*/ ISteamFriends_HasFriend( ulong steamIDFriend, int /*int*/ iFriendFlags );
|
||||
int /*int*/ ISteamFriends_GetClanCount();
|
||||
CSteamID /*(class CSteamID)*/ ISteamFriends_GetClanByIndex( int /*int*/ iClan );
|
||||
IntPtr ISteamFriends_GetClanName( ulong steamIDClan );
|
||||
IntPtr ISteamFriends_GetClanTag( ulong steamIDClan );
|
||||
bool /*bool*/ ISteamFriends_GetClanActivityCounts( ulong steamIDClan, out int /*int **/ pnOnline, out int /*int **/ pnInGame, out int /*int **/ pnChatting );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamFriends_DownloadClanActivityCounts( IntPtr /*class CSteamID **/ psteamIDClans, int /*int*/ cClansToRequest );
|
||||
int /*int*/ ISteamFriends_GetFriendCountFromSource( ulong steamIDSource );
|
||||
CSteamID /*(class CSteamID)*/ ISteamFriends_GetFriendFromSourceByIndex( ulong steamIDSource, int /*int*/ iFriend );
|
||||
bool /*bool*/ ISteamFriends_IsUserInSource( ulong steamIDUser, ulong steamIDSource );
|
||||
void /*void*/ ISteamFriends_SetInGameVoiceSpeaking( ulong steamIDUser, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bSpeaking );
|
||||
void /*void*/ ISteamFriends_ActivateGameOverlay( string /*const char **/ pchDialog );
|
||||
void /*void*/ ISteamFriends_ActivateGameOverlayToUser( string /*const char **/ pchDialog, ulong steamID );
|
||||
void /*void*/ ISteamFriends_ActivateGameOverlayToWebPage( string /*const char **/ pchURL );
|
||||
void /*void*/ ISteamFriends_ActivateGameOverlayToStore( uint nAppID, OverlayToStoreFlag /*EOverlayToStoreFlag*/ eFlag );
|
||||
void /*void*/ ISteamFriends_SetPlayedWith( ulong steamIDUserPlayedWith );
|
||||
void /*void*/ ISteamFriends_ActivateGameOverlayInviteDialog( ulong steamIDLobby );
|
||||
int /*int*/ ISteamFriends_GetSmallFriendAvatar( ulong steamIDFriend );
|
||||
int /*int*/ ISteamFriends_GetMediumFriendAvatar( ulong steamIDFriend );
|
||||
int /*int*/ ISteamFriends_GetLargeFriendAvatar( ulong steamIDFriend );
|
||||
bool /*bool*/ ISteamFriends_RequestUserInformation( ulong steamIDUser, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bRequireNameOnly );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamFriends_RequestClanOfficerList( ulong steamIDClan );
|
||||
CSteamID /*(class CSteamID)*/ ISteamFriends_GetClanOwner( ulong steamIDClan );
|
||||
int /*int*/ ISteamFriends_GetClanOfficerCount( ulong steamIDClan );
|
||||
CSteamID /*(class CSteamID)*/ ISteamFriends_GetClanOfficerByIndex( ulong steamIDClan, int /*int*/ iOfficer );
|
||||
uint /*uint32*/ ISteamFriends_GetUserRestrictions();
|
||||
bool /*bool*/ ISteamFriends_SetRichPresence( string /*const char **/ pchKey, string /*const char **/ pchValue );
|
||||
void /*void*/ ISteamFriends_ClearRichPresence();
|
||||
IntPtr ISteamFriends_GetFriendRichPresence( ulong steamIDFriend, string /*const char **/ pchKey );
|
||||
int /*int*/ ISteamFriends_GetFriendRichPresenceKeyCount( ulong steamIDFriend );
|
||||
IntPtr ISteamFriends_GetFriendRichPresenceKeyByIndex( ulong steamIDFriend, int /*int*/ iKey );
|
||||
void /*void*/ ISteamFriends_RequestFriendRichPresence( ulong steamIDFriend );
|
||||
bool /*bool*/ ISteamFriends_InviteUserToGame( ulong steamIDFriend, string /*const char **/ pchConnectString );
|
||||
int /*int*/ ISteamFriends_GetCoplayFriendCount();
|
||||
CSteamID /*(class CSteamID)*/ ISteamFriends_GetCoplayFriend( int /*int*/ iCoplayFriend );
|
||||
int /*int*/ ISteamFriends_GetFriendCoplayTime( ulong steamIDFriend );
|
||||
AppId_t /*(AppId_t)*/ ISteamFriends_GetFriendCoplayGame( ulong steamIDFriend );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamFriends_JoinClanChatRoom( ulong steamIDClan );
|
||||
bool /*bool*/ ISteamFriends_LeaveClanChatRoom( ulong steamIDClan );
|
||||
int /*int*/ ISteamFriends_GetClanChatMemberCount( ulong steamIDClan );
|
||||
CSteamID /*(class CSteamID)*/ ISteamFriends_GetChatMemberByIndex( ulong steamIDClan, int /*int*/ iUser );
|
||||
bool /*bool*/ ISteamFriends_SendClanChatMessage( ulong steamIDClanChat, string /*const char **/ pchText );
|
||||
int /*int*/ ISteamFriends_GetClanChatMessage( ulong steamIDClanChat, int /*int*/ iMessage, IntPtr /*void **/ prgchText, int /*int*/ cchTextMax, out ChatEntryType /*EChatEntryType **/ peChatEntryType, out ulong psteamidChatter );
|
||||
bool /*bool*/ ISteamFriends_IsClanChatAdmin( ulong steamIDClanChat, ulong steamIDUser );
|
||||
bool /*bool*/ ISteamFriends_IsClanChatWindowOpenInSteam( ulong steamIDClanChat );
|
||||
bool /*bool*/ ISteamFriends_OpenClanChatWindowInSteam( ulong steamIDClanChat );
|
||||
bool /*bool*/ ISteamFriends_CloseClanChatWindowInSteam( ulong steamIDClanChat );
|
||||
bool /*bool*/ ISteamFriends_SetListenForFriendsMessages( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bInterceptEnabled );
|
||||
bool /*bool*/ ISteamFriends_ReplyToFriendMessage( ulong steamIDFriend, string /*const char **/ pchMsgToSend );
|
||||
int /*int*/ ISteamFriends_GetFriendMessage( ulong steamIDFriend, int /*int*/ iMessageID, IntPtr /*void **/ pvData, int /*int*/ cubData, out ChatEntryType /*EChatEntryType **/ peChatEntryType );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamFriends_GetFollowerCount( ulong steamID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamFriends_IsFollowing( ulong steamID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamFriends_EnumerateFollowingList( uint /*uint32*/ unStartIndex );
|
||||
bool /*bool*/ ISteamFriends_IsClanPublic( ulong steamIDClan );
|
||||
bool /*bool*/ ISteamFriends_IsClanOfficialGameGroup( ulong steamIDClan );
|
||||
bool /*bool*/ ISteamGameServer_InitGameServer( uint /*uint32*/ unIP, ushort /*uint16*/ usGamePort, ushort /*uint16*/ usQueryPort, uint /*uint32*/ unFlags, uint nGameAppId, string /*const char **/ pchVersionString );
|
||||
void /*void*/ ISteamGameServer_SetProduct( string /*const char **/ pszProduct );
|
||||
void /*void*/ ISteamGameServer_SetGameDescription( string /*const char **/ pszGameDescription );
|
||||
void /*void*/ ISteamGameServer_SetModDir( string /*const char **/ pszModDir );
|
||||
void /*void*/ ISteamGameServer_SetDedicatedServer( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bDedicated );
|
||||
void /*void*/ ISteamGameServer_LogOn( string /*const char **/ pszToken );
|
||||
void /*void*/ ISteamGameServer_LogOnAnonymous();
|
||||
void /*void*/ ISteamGameServer_LogOff();
|
||||
bool /*bool*/ ISteamGameServer_BLoggedOn();
|
||||
bool /*bool*/ ISteamGameServer_BSecure();
|
||||
CSteamID /*(class CSteamID)*/ ISteamGameServer_GetSteamID();
|
||||
bool /*bool*/ ISteamGameServer_WasRestartRequested();
|
||||
void /*void*/ ISteamGameServer_SetMaxPlayerCount( int /*int*/ cPlayersMax );
|
||||
void /*void*/ ISteamGameServer_SetBotPlayerCount( int /*int*/ cBotplayers );
|
||||
void /*void*/ ISteamGameServer_SetServerName( string /*const char **/ pszServerName );
|
||||
void /*void*/ ISteamGameServer_SetMapName( string /*const char **/ pszMapName );
|
||||
void /*void*/ ISteamGameServer_SetPasswordProtected( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bPasswordProtected );
|
||||
void /*void*/ ISteamGameServer_SetSpectatorPort( ushort /*uint16*/ unSpectatorPort );
|
||||
void /*void*/ ISteamGameServer_SetSpectatorServerName( string /*const char **/ pszSpectatorServerName );
|
||||
void /*void*/ ISteamGameServer_ClearAllKeyValues();
|
||||
void /*void*/ ISteamGameServer_SetKeyValue( string /*const char **/ pKey, string /*const char **/ pValue );
|
||||
void /*void*/ ISteamGameServer_SetGameTags( string /*const char **/ pchGameTags );
|
||||
void /*void*/ ISteamGameServer_SetGameData( string /*const char **/ pchGameData );
|
||||
void /*void*/ ISteamGameServer_SetRegion( string /*const char **/ pszRegion );
|
||||
bool /*bool*/ ISteamGameServer_SendUserConnectAndAuthenticate( uint /*uint32*/ unIPClient, IntPtr /*const void **/ pvAuthBlob, uint /*uint32*/ cubAuthBlobSize, out ulong pSteamIDUser );
|
||||
CSteamID /*(class CSteamID)*/ ISteamGameServer_CreateUnauthenticatedUserConnection();
|
||||
void /*void*/ ISteamGameServer_SendUserDisconnect( ulong steamIDUser );
|
||||
bool /*bool*/ ISteamGameServer_BUpdateUserData( ulong steamIDUser, string /*const char **/ pchPlayerName, uint /*uint32*/ uScore );
|
||||
HAuthTicket /*(HAuthTicket)*/ ISteamGameServer_GetAuthSessionTicket( IntPtr /*void **/ pTicket, int /*int*/ cbMaxTicket, out uint /*uint32 **/ pcbTicket );
|
||||
BeginAuthSessionResult /*EBeginAuthSessionResult*/ ISteamGameServer_BeginAuthSession( IntPtr /*const void **/ pAuthTicket, int /*int*/ cbAuthTicket, ulong steamID );
|
||||
void /*void*/ ISteamGameServer_EndAuthSession( ulong steamID );
|
||||
void /*void*/ ISteamGameServer_CancelAuthTicket( uint hAuthTicket );
|
||||
UserHasLicenseForAppResult /*EUserHasLicenseForAppResult*/ ISteamGameServer_UserHasLicenseForApp( ulong steamID, uint appID );
|
||||
bool /*bool*/ ISteamGameServer_RequestUserGroupStatus( ulong steamIDUser, ulong steamIDGroup );
|
||||
void /*void*/ ISteamGameServer_GetGameplayStats();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamGameServer_GetServerReputation();
|
||||
uint /*uint32*/ ISteamGameServer_GetPublicIP();
|
||||
bool /*bool*/ ISteamGameServer_HandleIncomingPacket( IntPtr /*const void **/ pData, int /*int*/ cbData, uint /*uint32*/ srcIP, ushort /*uint16*/ srcPort );
|
||||
int /*int*/ ISteamGameServer_GetNextOutgoingPacket( IntPtr /*void **/ pOut, int /*int*/ cbMaxOut, out uint /*uint32 **/ pNetAdr, out ushort /*uint16 **/ pPort );
|
||||
void /*void*/ ISteamGameServer_EnableHeartbeats( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bActive );
|
||||
void /*void*/ ISteamGameServer_SetHeartbeatInterval( int /*int*/ iHeartbeatInterval );
|
||||
void /*void*/ ISteamGameServer_ForceHeartbeat();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamGameServer_AssociateWithClan( ulong steamIDClan );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamGameServer_ComputeNewPlayerCompatibility( ulong steamIDNewPlayer );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamGameServerStats_RequestUserStats( ulong steamIDUser );
|
||||
bool /*bool*/ ISteamGameServerStats_GetUserStat( ulong steamIDUser, string /*const char **/ pchName, out int /*int32 **/ pData );
|
||||
bool /*bool*/ ISteamGameServerStats_GetUserStat0( ulong steamIDUser, string /*const char **/ pchName, out float /*float **/ pData );
|
||||
bool /*bool*/ ISteamGameServerStats_GetUserAchievement( ulong steamIDUser, string /*const char **/ pchName, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAchieved );
|
||||
bool /*bool*/ ISteamGameServerStats_SetUserStat( ulong steamIDUser, string /*const char **/ pchName, int /*int32*/ nData );
|
||||
bool /*bool*/ ISteamGameServerStats_SetUserStat0( ulong steamIDUser, string /*const char **/ pchName, float /*float*/ fData );
|
||||
bool /*bool*/ ISteamGameServerStats_UpdateUserAvgRateStat( ulong steamIDUser, string /*const char **/ pchName, float /*float*/ flCountThisSession, double /*double*/ dSessionLength );
|
||||
bool /*bool*/ ISteamGameServerStats_SetUserAchievement( ulong steamIDUser, string /*const char **/ pchName );
|
||||
bool /*bool*/ ISteamGameServerStats_ClearUserAchievement( ulong steamIDUser, string /*const char **/ pchName );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamGameServerStats_StoreUserStats( ulong steamIDUser );
|
||||
void /*void*/ ISteamHTMLSurface_DestructISteamHTMLSurface();
|
||||
bool /*bool*/ ISteamHTMLSurface_Init();
|
||||
bool /*bool*/ ISteamHTMLSurface_Shutdown();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamHTMLSurface_CreateBrowser( string /*const char **/ pchUserAgent, string /*const char **/ pchUserCSS );
|
||||
void /*void*/ ISteamHTMLSurface_RemoveBrowser( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_LoadURL( uint unBrowserHandle, string /*const char **/ pchURL, string /*const char **/ pchPostData );
|
||||
void /*void*/ ISteamHTMLSurface_SetSize( uint unBrowserHandle, uint /*uint32*/ unWidth, uint /*uint32*/ unHeight );
|
||||
void /*void*/ ISteamHTMLSurface_StopLoad( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_Reload( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_GoBack( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_GoForward( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_AddHeader( uint unBrowserHandle, string /*const char **/ pchKey, string /*const char **/ pchValue );
|
||||
void /*void*/ ISteamHTMLSurface_ExecuteJavascript( uint unBrowserHandle, string /*const char **/ pchScript );
|
||||
void /*void*/ ISteamHTMLSurface_MouseUp( uint unBrowserHandle, HTMLMouseButton /*ISteamHTMLSurface::EHTMLMouseButton*/ eMouseButton );
|
||||
void /*void*/ ISteamHTMLSurface_MouseDown( uint unBrowserHandle, HTMLMouseButton /*ISteamHTMLSurface::EHTMLMouseButton*/ eMouseButton );
|
||||
void /*void*/ ISteamHTMLSurface_MouseDoubleClick( uint unBrowserHandle, HTMLMouseButton /*ISteamHTMLSurface::EHTMLMouseButton*/ eMouseButton );
|
||||
void /*void*/ ISteamHTMLSurface_MouseMove( uint unBrowserHandle, int /*int*/ x, int /*int*/ y );
|
||||
void /*void*/ ISteamHTMLSurface_MouseWheel( uint unBrowserHandle, int /*int32*/ nDelta );
|
||||
void /*void*/ ISteamHTMLSurface_KeyDown( uint unBrowserHandle, uint /*uint32*/ nNativeKeyCode, HTMLKeyModifiers /*ISteamHTMLSurface::EHTMLKeyModifiers*/ eHTMLKeyModifiers );
|
||||
void /*void*/ ISteamHTMLSurface_KeyUp( uint unBrowserHandle, uint /*uint32*/ nNativeKeyCode, HTMLKeyModifiers /*ISteamHTMLSurface::EHTMLKeyModifiers*/ eHTMLKeyModifiers );
|
||||
void /*void*/ ISteamHTMLSurface_KeyChar( uint unBrowserHandle, uint /*uint32*/ cUnicodeChar, HTMLKeyModifiers /*ISteamHTMLSurface::EHTMLKeyModifiers*/ eHTMLKeyModifiers );
|
||||
void /*void*/ ISteamHTMLSurface_SetHorizontalScroll( uint unBrowserHandle, uint /*uint32*/ nAbsolutePixelScroll );
|
||||
void /*void*/ ISteamHTMLSurface_SetVerticalScroll( uint unBrowserHandle, uint /*uint32*/ nAbsolutePixelScroll );
|
||||
void /*void*/ ISteamHTMLSurface_SetKeyFocus( uint unBrowserHandle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bHasKeyFocus );
|
||||
void /*void*/ ISteamHTMLSurface_ViewSource( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_CopyToClipboard( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_PasteFromClipboard( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_Find( uint unBrowserHandle, string /*const char **/ pchSearchStr, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bCurrentlyInFind, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReverse );
|
||||
void /*void*/ ISteamHTMLSurface_StopFind( uint unBrowserHandle );
|
||||
void /*void*/ ISteamHTMLSurface_GetLinkAtPosition( uint unBrowserHandle, int /*int*/ x, int /*int*/ y );
|
||||
void /*void*/ ISteamHTMLSurface_SetCookie( string /*const char **/ pchHostname, string /*const char **/ pchKey, string /*const char **/ pchValue, string /*const char **/ pchPath, uint nExpires, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bSecure, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bHTTPOnly );
|
||||
void /*void*/ ISteamHTMLSurface_SetPageScaleFactor( uint unBrowserHandle, float /*float*/ flZoom, int /*int*/ nPointX, int /*int*/ nPointY );
|
||||
void /*void*/ ISteamHTMLSurface_SetBackgroundMode( uint unBrowserHandle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bBackgroundMode );
|
||||
void /*void*/ ISteamHTMLSurface_SetDPIScalingFactor( uint unBrowserHandle, float /*float*/ flDPIScaling );
|
||||
void /*void*/ ISteamHTMLSurface_AllowStartRequest( uint unBrowserHandle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bAllowed );
|
||||
void /*void*/ ISteamHTMLSurface_JSDialogResponse( uint unBrowserHandle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bResult );
|
||||
HTTPRequestHandle /*(HTTPRequestHandle)*/ ISteamHTTP_CreateHTTPRequest( HTTPMethod /*EHTTPMethod*/ eHTTPRequestMethod, string /*const char **/ pchAbsoluteURL );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestContextValue( uint hRequest, ulong /*uint64*/ ulContextValue );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestNetworkActivityTimeout( uint hRequest, uint /*uint32*/ unTimeoutSeconds );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestHeaderValue( uint hRequest, string /*const char **/ pchHeaderName, string /*const char **/ pchHeaderValue );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestGetOrPostParameter( uint hRequest, string /*const char **/ pchParamName, string /*const char **/ pchParamValue );
|
||||
bool /*bool*/ ISteamHTTP_SendHTTPRequest( uint hRequest, ref ulong pCallHandle );
|
||||
bool /*bool*/ ISteamHTTP_SendHTTPRequestAndStreamResponse( uint hRequest, ref ulong pCallHandle );
|
||||
bool /*bool*/ ISteamHTTP_DeferHTTPRequest( uint hRequest );
|
||||
bool /*bool*/ ISteamHTTP_PrioritizeHTTPRequest( uint hRequest );
|
||||
bool /*bool*/ ISteamHTTP_GetHTTPResponseHeaderSize( uint hRequest, string /*const char **/ pchHeaderName, out uint /*uint32 **/ unResponseHeaderSize );
|
||||
bool /*bool*/ ISteamHTTP_GetHTTPResponseHeaderValue( uint hRequest, string /*const char **/ pchHeaderName, out byte /*uint8 **/ pHeaderValueBuffer, uint /*uint32*/ unBufferSize );
|
||||
bool /*bool*/ ISteamHTTP_GetHTTPResponseBodySize( uint hRequest, out uint /*uint32 **/ unBodySize );
|
||||
bool /*bool*/ ISteamHTTP_GetHTTPResponseBodyData( uint hRequest, out byte /*uint8 **/ pBodyDataBuffer, uint /*uint32*/ unBufferSize );
|
||||
bool /*bool*/ ISteamHTTP_GetHTTPStreamingResponseBodyData( uint hRequest, uint /*uint32*/ cOffset, out byte /*uint8 **/ pBodyDataBuffer, uint /*uint32*/ unBufferSize );
|
||||
bool /*bool*/ ISteamHTTP_ReleaseHTTPRequest( uint hRequest );
|
||||
bool /*bool*/ ISteamHTTP_GetHTTPDownloadProgressPct( uint hRequest, out float /*float **/ pflPercentOut );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestRawPostBody( uint hRequest, string /*const char **/ pchContentType, out byte /*uint8 **/ pubBody, uint /*uint32*/ unBodyLen );
|
||||
HTTPCookieContainerHandle /*(HTTPCookieContainerHandle)*/ ISteamHTTP_CreateCookieContainer( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bAllowResponsesToModify );
|
||||
bool /*bool*/ ISteamHTTP_ReleaseCookieContainer( uint hCookieContainer );
|
||||
bool /*bool*/ ISteamHTTP_SetCookie( uint hCookieContainer, string /*const char **/ pchHost, string /*const char **/ pchUrl, string /*const char **/ pchCookie );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestCookieContainer( uint hRequest, uint hCookieContainer );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestUserAgentInfo( uint hRequest, string /*const char **/ pchUserAgentInfo );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestRequiresVerifiedCertificate( uint hRequest, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bRequireVerifiedCertificate );
|
||||
bool /*bool*/ ISteamHTTP_SetHTTPRequestAbsoluteTimeoutMS( uint hRequest, uint /*uint32*/ unMilliseconds );
|
||||
bool /*bool*/ ISteamHTTP_GetHTTPRequestWasTimedOut( uint hRequest, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbWasTimedOut );
|
||||
Result /*EResult*/ ISteamInventory_GetResultStatus( int resultHandle );
|
||||
bool /*bool*/ ISteamInventory_GetResultItems( int resultHandle, IntPtr /*struct SteamItemDetails_t **/ pOutItemsArray, out uint /*uint32 **/ punOutItemsArraySize );
|
||||
bool /*bool*/ ISteamInventory_GetResultItemProperty( int resultHandle, uint /*uint32*/ unItemIndex, string /*const char **/ pchPropertyName, System.Text.StringBuilder /*char **/ pchValueBuffer, out uint /*uint32 **/ punValueBufferSizeOut );
|
||||
uint /*uint32*/ ISteamInventory_GetResultTimestamp( int resultHandle );
|
||||
bool /*bool*/ ISteamInventory_CheckResultSteamID( int resultHandle, ulong steamIDExpected );
|
||||
void /*void*/ ISteamInventory_DestroyResult( int resultHandle );
|
||||
bool /*bool*/ ISteamInventory_GetAllItems( ref int pResultHandle );
|
||||
bool /*bool*/ ISteamInventory_GetItemsByID( ref int pResultHandle, ulong[] pInstanceIDs, uint /*uint32*/ unCountInstanceIDs );
|
||||
bool /*bool*/ ISteamInventory_SerializeResult( int resultHandle, IntPtr /*void **/ pOutBuffer, out uint /*uint32 **/ punOutBufferSize );
|
||||
bool /*bool*/ ISteamInventory_DeserializeResult( ref int pOutResultHandle, IntPtr /*const void **/ pBuffer, uint /*uint32*/ unBufferSize, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bRESERVED_MUST_BE_FALSE );
|
||||
bool /*bool*/ ISteamInventory_GenerateItems( ref int pResultHandle, int[] pArrayItemDefs, uint[] /*const uint32 **/ punArrayQuantity, uint /*uint32*/ unArrayLength );
|
||||
bool /*bool*/ ISteamInventory_GrantPromoItems( ref int pResultHandle );
|
||||
bool /*bool*/ ISteamInventory_AddPromoItem( ref int pResultHandle, int itemDef );
|
||||
bool /*bool*/ ISteamInventory_AddPromoItems( ref int pResultHandle, int[] pArrayItemDefs, uint /*uint32*/ unArrayLength );
|
||||
bool /*bool*/ ISteamInventory_ConsumeItem( ref int pResultHandle, ulong itemConsume, uint /*uint32*/ unQuantity );
|
||||
bool /*bool*/ ISteamInventory_ExchangeItems( ref int pResultHandle, int[] pArrayGenerate, uint[] /*const uint32 **/ punArrayGenerateQuantity, uint /*uint32*/ unArrayGenerateLength, ulong[] pArrayDestroy, uint[] /*const uint32 **/ punArrayDestroyQuantity, uint /*uint32*/ unArrayDestroyLength );
|
||||
bool /*bool*/ ISteamInventory_TransferItemQuantity( ref int pResultHandle, ulong itemIdSource, uint /*uint32*/ unQuantity, ulong itemIdDest );
|
||||
void /*void*/ ISteamInventory_SendItemDropHeartbeat();
|
||||
bool /*bool*/ ISteamInventory_TriggerItemDrop( ref int pResultHandle, int dropListDefinition );
|
||||
bool /*bool*/ ISteamInventory_TradeItems( ref int pResultHandle, ulong steamIDTradePartner, ulong[] pArrayGive, uint[] /*const uint32 **/ pArrayGiveQuantity, uint /*uint32*/ nArrayGiveLength, ulong[] pArrayGet, uint[] /*const uint32 **/ pArrayGetQuantity, uint /*uint32*/ nArrayGetLength );
|
||||
bool /*bool*/ ISteamInventory_LoadItemDefinitions();
|
||||
bool /*bool*/ ISteamInventory_GetItemDefinitionIDs( IntPtr /*SteamItemDef_t **/ pItemDefIDs, out uint /*uint32 **/ punItemDefIDsArraySize );
|
||||
bool /*bool*/ ISteamInventory_GetItemDefinitionProperty( int iDefinition, string /*const char **/ pchPropertyName, System.Text.StringBuilder /*char **/ pchValueBuffer, out uint /*uint32 **/ punValueBufferSizeOut );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamInventory_RequestEligiblePromoItemDefinitionsIDs( ulong steamID );
|
||||
bool /*bool*/ ISteamInventory_GetEligiblePromoItemDefinitionIDs( ulong steamID, IntPtr /*SteamItemDef_t **/ pItemDefIDs, out uint /*uint32 **/ punItemDefIDsArraySize );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamInventory_StartPurchase( int[] pArrayItemDefs, uint[] /*const uint32 **/ punArrayQuantity, uint /*uint32*/ unArrayLength );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamInventory_RequestPrices();
|
||||
uint /*uint32*/ ISteamInventory_GetNumItemsWithPrices();
|
||||
bool /*bool*/ ISteamInventory_GetItemsWithPrices( IntPtr /*SteamItemDef_t **/ pArrayItemDefs, IntPtr /*uint64 **/ pPrices, uint /*uint32*/ unArrayLength );
|
||||
bool /*bool*/ ISteamInventory_GetItemPrice( int iDefinition, out ulong /*uint64 **/ pPrice );
|
||||
SteamInventoryUpdateHandle_t /*(SteamInventoryUpdateHandle_t)*/ ISteamInventory_StartUpdateProperties();
|
||||
bool /*bool*/ ISteamInventory_RemoveProperty( ulong handle, ulong nItemID, string /*const char **/ pchPropertyName );
|
||||
bool /*bool*/ ISteamInventory_SetProperty( ulong handle, ulong nItemID, string /*const char **/ pchPropertyName, string /*const char **/ pchPropertyValue );
|
||||
bool /*bool*/ ISteamInventory_SetProperty0( ulong handle, ulong nItemID, string /*const char **/ pchPropertyName, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamInventory_SetProperty0( ulong handle, ulong nItemID, string /*const char **/ pchPropertyName, long /*int64*/ nValue );
|
||||
bool /*bool*/ ISteamInventory_SetProperty0( ulong handle, ulong nItemID, string /*const char **/ pchPropertyName, float /*float*/ flValue );
|
||||
bool /*bool*/ ISteamInventory_SubmitUpdateProperties( ulong handle, ref int pResultHandle );
|
||||
int /*int*/ ISteamMatchmaking_GetFavoriteGameCount();
|
||||
bool /*bool*/ ISteamMatchmaking_GetFavoriteGame( int /*int*/ iGame, ref uint pnAppID, out uint /*uint32 **/ pnIP, out ushort /*uint16 **/ pnConnPort, out ushort /*uint16 **/ pnQueryPort, out uint /*uint32 **/ punFlags, out uint /*uint32 **/ pRTime32LastPlayedOnServer );
|
||||
int /*int*/ ISteamMatchmaking_AddFavoriteGame( uint nAppID, uint /*uint32*/ nIP, ushort /*uint16*/ nConnPort, ushort /*uint16*/ nQueryPort, uint /*uint32*/ unFlags, uint /*uint32*/ rTime32LastPlayedOnServer );
|
||||
bool /*bool*/ ISteamMatchmaking_RemoveFavoriteGame( uint nAppID, uint /*uint32*/ nIP, ushort /*uint16*/ nConnPort, ushort /*uint16*/ nQueryPort, uint /*uint32*/ unFlags );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamMatchmaking_RequestLobbyList();
|
||||
void /*void*/ ISteamMatchmaking_AddRequestLobbyListStringFilter( string /*const char **/ pchKeyToMatch, string /*const char **/ pchValueToMatch, LobbyComparison /*ELobbyComparison*/ eComparisonType );
|
||||
void /*void*/ ISteamMatchmaking_AddRequestLobbyListNumericalFilter( string /*const char **/ pchKeyToMatch, int /*int*/ nValueToMatch, LobbyComparison /*ELobbyComparison*/ eComparisonType );
|
||||
void /*void*/ ISteamMatchmaking_AddRequestLobbyListNearValueFilter( string /*const char **/ pchKeyToMatch, int /*int*/ nValueToBeCloseTo );
|
||||
void /*void*/ ISteamMatchmaking_AddRequestLobbyListFilterSlotsAvailable( int /*int*/ nSlotsAvailable );
|
||||
void /*void*/ ISteamMatchmaking_AddRequestLobbyListDistanceFilter( LobbyDistanceFilter /*ELobbyDistanceFilter*/ eLobbyDistanceFilter );
|
||||
void /*void*/ ISteamMatchmaking_AddRequestLobbyListResultCountFilter( int /*int*/ cMaxResults );
|
||||
void /*void*/ ISteamMatchmaking_AddRequestLobbyListCompatibleMembersFilter( ulong steamIDLobby );
|
||||
CSteamID /*(class CSteamID)*/ ISteamMatchmaking_GetLobbyByIndex( int /*int*/ iLobby );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamMatchmaking_CreateLobby( LobbyType /*ELobbyType*/ eLobbyType, int /*int*/ cMaxMembers );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamMatchmaking_JoinLobby( ulong steamIDLobby );
|
||||
void /*void*/ ISteamMatchmaking_LeaveLobby( ulong steamIDLobby );
|
||||
bool /*bool*/ ISteamMatchmaking_InviteUserToLobby( ulong steamIDLobby, ulong steamIDInvitee );
|
||||
int /*int*/ ISteamMatchmaking_GetNumLobbyMembers( ulong steamIDLobby );
|
||||
CSteamID /*(class CSteamID)*/ ISteamMatchmaking_GetLobbyMemberByIndex( ulong steamIDLobby, int /*int*/ iMember );
|
||||
IntPtr ISteamMatchmaking_GetLobbyData( ulong steamIDLobby, string /*const char **/ pchKey );
|
||||
bool /*bool*/ ISteamMatchmaking_SetLobbyData( ulong steamIDLobby, string /*const char **/ pchKey, string /*const char **/ pchValue );
|
||||
int /*int*/ ISteamMatchmaking_GetLobbyDataCount( ulong steamIDLobby );
|
||||
bool /*bool*/ ISteamMatchmaking_GetLobbyDataByIndex( ulong steamIDLobby, int /*int*/ iLobbyData, System.Text.StringBuilder /*char **/ pchKey, int /*int*/ cchKeyBufferSize, System.Text.StringBuilder /*char **/ pchValue, int /*int*/ cchValueBufferSize );
|
||||
bool /*bool*/ ISteamMatchmaking_DeleteLobbyData( ulong steamIDLobby, string /*const char **/ pchKey );
|
||||
IntPtr ISteamMatchmaking_GetLobbyMemberData( ulong steamIDLobby, ulong steamIDUser, string /*const char **/ pchKey );
|
||||
void /*void*/ ISteamMatchmaking_SetLobbyMemberData( ulong steamIDLobby, string /*const char **/ pchKey, string /*const char **/ pchValue );
|
||||
bool /*bool*/ ISteamMatchmaking_SendLobbyChatMsg( ulong steamIDLobby, IntPtr /*const void **/ pvMsgBody, int /*int*/ cubMsgBody );
|
||||
int /*int*/ ISteamMatchmaking_GetLobbyChatEntry( ulong steamIDLobby, int /*int*/ iChatID, out ulong pSteamIDUser, IntPtr /*void **/ pvData, int /*int*/ cubData, out ChatEntryType /*EChatEntryType **/ peChatEntryType );
|
||||
bool /*bool*/ ISteamMatchmaking_RequestLobbyData( ulong steamIDLobby );
|
||||
void /*void*/ ISteamMatchmaking_SetLobbyGameServer( ulong steamIDLobby, uint /*uint32*/ unGameServerIP, ushort /*uint16*/ unGameServerPort, ulong steamIDGameServer );
|
||||
bool /*bool*/ ISteamMatchmaking_GetLobbyGameServer( ulong steamIDLobby, out uint /*uint32 **/ punGameServerIP, out ushort /*uint16 **/ punGameServerPort, out ulong psteamIDGameServer );
|
||||
bool /*bool*/ ISteamMatchmaking_SetLobbyMemberLimit( ulong steamIDLobby, int /*int*/ cMaxMembers );
|
||||
int /*int*/ ISteamMatchmaking_GetLobbyMemberLimit( ulong steamIDLobby );
|
||||
bool /*bool*/ ISteamMatchmaking_SetLobbyType( ulong steamIDLobby, LobbyType /*ELobbyType*/ eLobbyType );
|
||||
bool /*bool*/ ISteamMatchmaking_SetLobbyJoinable( ulong steamIDLobby, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bLobbyJoinable );
|
||||
CSteamID /*(class CSteamID)*/ ISteamMatchmaking_GetLobbyOwner( ulong steamIDLobby );
|
||||
bool /*bool*/ ISteamMatchmaking_SetLobbyOwner( ulong steamIDLobby, ulong steamIDNewOwner );
|
||||
bool /*bool*/ ISteamMatchmaking_SetLinkedLobby( ulong steamIDLobby, ulong steamIDLobbyDependent );
|
||||
HServerListRequest /*(HServerListRequest)*/ ISteamMatchmakingServers_RequestInternetServerList( uint iApp, IntPtr /*struct MatchMakingKeyValuePair_t ***/ ppchFilters, uint /*uint32*/ nFilters, IntPtr /*class ISteamMatchmakingServerListResponse **/ pRequestServersResponse );
|
||||
HServerListRequest /*(HServerListRequest)*/ ISteamMatchmakingServers_RequestLANServerList( uint iApp, IntPtr /*class ISteamMatchmakingServerListResponse **/ pRequestServersResponse );
|
||||
HServerListRequest /*(HServerListRequest)*/ ISteamMatchmakingServers_RequestFriendsServerList( uint iApp, IntPtr /*struct MatchMakingKeyValuePair_t ***/ ppchFilters, uint /*uint32*/ nFilters, IntPtr /*class ISteamMatchmakingServerListResponse **/ pRequestServersResponse );
|
||||
HServerListRequest /*(HServerListRequest)*/ ISteamMatchmakingServers_RequestFavoritesServerList( uint iApp, IntPtr /*struct MatchMakingKeyValuePair_t ***/ ppchFilters, uint /*uint32*/ nFilters, IntPtr /*class ISteamMatchmakingServerListResponse **/ pRequestServersResponse );
|
||||
HServerListRequest /*(HServerListRequest)*/ ISteamMatchmakingServers_RequestHistoryServerList( uint iApp, IntPtr /*struct MatchMakingKeyValuePair_t ***/ ppchFilters, uint /*uint32*/ nFilters, IntPtr /*class ISteamMatchmakingServerListResponse **/ pRequestServersResponse );
|
||||
HServerListRequest /*(HServerListRequest)*/ ISteamMatchmakingServers_RequestSpectatorServerList( uint iApp, IntPtr /*struct MatchMakingKeyValuePair_t ***/ ppchFilters, uint /*uint32*/ nFilters, IntPtr /*class ISteamMatchmakingServerListResponse **/ pRequestServersResponse );
|
||||
void /*void*/ ISteamMatchmakingServers_ReleaseRequest( IntPtr hServerListRequest );
|
||||
IntPtr /*class gameserveritem_t **/ ISteamMatchmakingServers_GetServerDetails( IntPtr hRequest, int /*int*/ iServer );
|
||||
void /*void*/ ISteamMatchmakingServers_CancelQuery( IntPtr hRequest );
|
||||
void /*void*/ ISteamMatchmakingServers_RefreshQuery( IntPtr hRequest );
|
||||
bool /*bool*/ ISteamMatchmakingServers_IsRefreshing( IntPtr hRequest );
|
||||
int /*int*/ ISteamMatchmakingServers_GetServerCount( IntPtr hRequest );
|
||||
void /*void*/ ISteamMatchmakingServers_RefreshServer( IntPtr hRequest, int /*int*/ iServer );
|
||||
HServerQuery /*(HServerQuery)*/ ISteamMatchmakingServers_PingServer( uint /*uint32*/ unIP, ushort /*uint16*/ usPort, IntPtr /*class ISteamMatchmakingPingResponse **/ pRequestServersResponse );
|
||||
HServerQuery /*(HServerQuery)*/ ISteamMatchmakingServers_PlayerDetails( uint /*uint32*/ unIP, ushort /*uint16*/ usPort, IntPtr /*class ISteamMatchmakingPlayersResponse **/ pRequestServersResponse );
|
||||
HServerQuery /*(HServerQuery)*/ ISteamMatchmakingServers_ServerRules( uint /*uint32*/ unIP, ushort /*uint16*/ usPort, IntPtr /*class ISteamMatchmakingRulesResponse **/ pRequestServersResponse );
|
||||
void /*void*/ ISteamMatchmakingServers_CancelServerQuery( int hServerQuery );
|
||||
bool /*bool*/ ISteamMusic_BIsEnabled();
|
||||
bool /*bool*/ ISteamMusic_BIsPlaying();
|
||||
AudioPlayback_Status /*AudioPlayback_Status*/ ISteamMusic_GetPlaybackStatus();
|
||||
void /*void*/ ISteamMusic_Play();
|
||||
void /*void*/ ISteamMusic_Pause();
|
||||
void /*void*/ ISteamMusic_PlayPrevious();
|
||||
void /*void*/ ISteamMusic_PlayNext();
|
||||
void /*void*/ ISteamMusic_SetVolume( float /*float*/ flVolume );
|
||||
float /*float*/ ISteamMusic_GetVolume();
|
||||
bool /*bool*/ ISteamMusicRemote_RegisterSteamMusicRemote( string /*const char **/ pchName );
|
||||
bool /*bool*/ ISteamMusicRemote_DeregisterSteamMusicRemote();
|
||||
bool /*bool*/ ISteamMusicRemote_BIsCurrentMusicRemote();
|
||||
bool /*bool*/ ISteamMusicRemote_BActivationSuccess( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_SetDisplayName( string /*const char **/ pchDisplayName );
|
||||
bool /*bool*/ ISteamMusicRemote_SetPNGIcon_64x64( IntPtr /*void **/ pvBuffer, uint /*uint32*/ cbBufferLength );
|
||||
bool /*bool*/ ISteamMusicRemote_EnablePlayPrevious( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_EnablePlayNext( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_EnableShuffled( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_EnableLooped( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_EnableQueue( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_EnablePlaylists( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_UpdatePlaybackStatus( AudioPlayback_Status /*AudioPlayback_Status*/ nStatus );
|
||||
bool /*bool*/ ISteamMusicRemote_UpdateShuffled( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_UpdateLooped( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bValue );
|
||||
bool /*bool*/ ISteamMusicRemote_UpdateVolume( float /*float*/ flValue );
|
||||
bool /*bool*/ ISteamMusicRemote_CurrentEntryWillChange();
|
||||
bool /*bool*/ ISteamMusicRemote_CurrentEntryIsAvailable( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bAvailable );
|
||||
bool /*bool*/ ISteamMusicRemote_UpdateCurrentEntryText( string /*const char **/ pchText );
|
||||
bool /*bool*/ ISteamMusicRemote_UpdateCurrentEntryElapsedSeconds( int /*int*/ nValue );
|
||||
bool /*bool*/ ISteamMusicRemote_UpdateCurrentEntryCoverArt( IntPtr /*void **/ pvBuffer, uint /*uint32*/ cbBufferLength );
|
||||
bool /*bool*/ ISteamMusicRemote_CurrentEntryDidChange();
|
||||
bool /*bool*/ ISteamMusicRemote_QueueWillChange();
|
||||
bool /*bool*/ ISteamMusicRemote_ResetQueueEntries();
|
||||
bool /*bool*/ ISteamMusicRemote_SetQueueEntry( int /*int*/ nID, int /*int*/ nPosition, string /*const char **/ pchEntryText );
|
||||
bool /*bool*/ ISteamMusicRemote_SetCurrentQueueEntry( int /*int*/ nID );
|
||||
bool /*bool*/ ISteamMusicRemote_QueueDidChange();
|
||||
bool /*bool*/ ISteamMusicRemote_PlaylistWillChange();
|
||||
bool /*bool*/ ISteamMusicRemote_ResetPlaylistEntries();
|
||||
bool /*bool*/ ISteamMusicRemote_SetPlaylistEntry( int /*int*/ nID, int /*int*/ nPosition, string /*const char **/ pchEntryText );
|
||||
bool /*bool*/ ISteamMusicRemote_SetCurrentPlaylistEntry( int /*int*/ nID );
|
||||
bool /*bool*/ ISteamMusicRemote_PlaylistDidChange();
|
||||
bool /*bool*/ ISteamNetworking_SendP2PPacket( ulong steamIDRemote, IntPtr /*const void **/ pubData, uint /*uint32*/ cubData, P2PSend /*EP2PSend*/ eP2PSendType, int /*int*/ nChannel );
|
||||
bool /*bool*/ ISteamNetworking_IsP2PPacketAvailable( out uint /*uint32 **/ pcubMsgSize, int /*int*/ nChannel );
|
||||
bool /*bool*/ ISteamNetworking_ReadP2PPacket( IntPtr /*void **/ pubDest, uint /*uint32*/ cubDest, out uint /*uint32 **/ pcubMsgSize, out ulong psteamIDRemote, int /*int*/ nChannel );
|
||||
bool /*bool*/ ISteamNetworking_AcceptP2PSessionWithUser( ulong steamIDRemote );
|
||||
bool /*bool*/ ISteamNetworking_CloseP2PSessionWithUser( ulong steamIDRemote );
|
||||
bool /*bool*/ ISteamNetworking_CloseP2PChannelWithUser( ulong steamIDRemote, int /*int*/ nChannel );
|
||||
bool /*bool*/ ISteamNetworking_GetP2PSessionState( ulong steamIDRemote, ref P2PSessionState_t /*struct P2PSessionState_t **/ pConnectionState );
|
||||
bool /*bool*/ ISteamNetworking_AllowP2PPacketRelay( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bAllow );
|
||||
SNetListenSocket_t /*(SNetListenSocket_t)*/ ISteamNetworking_CreateListenSocket( int /*int*/ nVirtualP2PPort, uint /*uint32*/ nIP, ushort /*uint16*/ nPort, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bAllowUseOfPacketRelay );
|
||||
SNetSocket_t /*(SNetSocket_t)*/ ISteamNetworking_CreateP2PConnectionSocket( ulong steamIDTarget, int /*int*/ nVirtualPort, int /*int*/ nTimeoutSec, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bAllowUseOfPacketRelay );
|
||||
SNetSocket_t /*(SNetSocket_t)*/ ISteamNetworking_CreateConnectionSocket( uint /*uint32*/ nIP, ushort /*uint16*/ nPort, int /*int*/ nTimeoutSec );
|
||||
bool /*bool*/ ISteamNetworking_DestroySocket( uint hSocket, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bNotifyRemoteEnd );
|
||||
bool /*bool*/ ISteamNetworking_DestroyListenSocket( uint hSocket, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bNotifyRemoteEnd );
|
||||
bool /*bool*/ ISteamNetworking_SendDataOnSocket( uint hSocket, IntPtr /*void **/ pubData, uint /*uint32*/ cubData, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReliable );
|
||||
bool /*bool*/ ISteamNetworking_IsDataAvailableOnSocket( uint hSocket, out uint /*uint32 **/ pcubMsgSize );
|
||||
bool /*bool*/ ISteamNetworking_RetrieveDataFromSocket( uint hSocket, IntPtr /*void **/ pubDest, uint /*uint32*/ cubDest, out uint /*uint32 **/ pcubMsgSize );
|
||||
bool /*bool*/ ISteamNetworking_IsDataAvailable( uint hListenSocket, out uint /*uint32 **/ pcubMsgSize, ref uint phSocket );
|
||||
bool /*bool*/ ISteamNetworking_RetrieveData( uint hListenSocket, IntPtr /*void **/ pubDest, uint /*uint32*/ cubDest, out uint /*uint32 **/ pcubMsgSize, ref uint phSocket );
|
||||
bool /*bool*/ ISteamNetworking_GetSocketInfo( uint hSocket, out ulong pSteamIDRemote, IntPtr /*int **/ peSocketStatus, out uint /*uint32 **/ punIPRemote, out ushort /*uint16 **/ punPortRemote );
|
||||
bool /*bool*/ ISteamNetworking_GetListenSocketInfo( uint hListenSocket, out uint /*uint32 **/ pnIP, out ushort /*uint16 **/ pnPort );
|
||||
SNetSocketConnectionType /*ESNetSocketConnectionType*/ ISteamNetworking_GetSocketConnectionType( uint hSocket );
|
||||
int /*int*/ ISteamNetworking_GetMaxPacketSize( uint hSocket );
|
||||
bool /*bool*/ ISteamParentalSettings_BIsParentalLockEnabled();
|
||||
bool /*bool*/ ISteamParentalSettings_BIsParentalLockLocked();
|
||||
bool /*bool*/ ISteamParentalSettings_BIsAppBlocked( uint nAppID );
|
||||
bool /*bool*/ ISteamParentalSettings_BIsAppInBlockList( uint nAppID );
|
||||
bool /*bool*/ ISteamParentalSettings_BIsFeatureBlocked( ParentalFeature /*EParentalFeature*/ eFeature );
|
||||
bool /*bool*/ ISteamParentalSettings_BIsFeatureInBlockList( ParentalFeature /*EParentalFeature*/ eFeature );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileWrite( string /*const char **/ pchFile, IntPtr /*const void **/ pvData, int /*int32*/ cubData );
|
||||
int /*int32*/ ISteamRemoteStorage_FileRead( string /*const char **/ pchFile, IntPtr /*void **/ pvData, int /*int32*/ cubDataToRead );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_FileWriteAsync( string /*const char **/ pchFile, IntPtr /*const void **/ pvData, uint /*uint32*/ cubData );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_FileReadAsync( string /*const char **/ pchFile, uint /*uint32*/ nOffset, uint /*uint32*/ cubToRead );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileReadAsyncComplete( ulong hReadCall, IntPtr /*void **/ pvBuffer, uint /*uint32*/ cubToRead );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileForget( string /*const char **/ pchFile );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileDelete( string /*const char **/ pchFile );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_FileShare( string /*const char **/ pchFile );
|
||||
bool /*bool*/ ISteamRemoteStorage_SetSyncPlatforms( string /*const char **/ pchFile, RemoteStoragePlatform /*ERemoteStoragePlatform*/ eRemoteStoragePlatform );
|
||||
UGCFileWriteStreamHandle_t /*(UGCFileWriteStreamHandle_t)*/ ISteamRemoteStorage_FileWriteStreamOpen( string /*const char **/ pchFile );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileWriteStreamWriteChunk( ulong writeHandle, IntPtr /*const void **/ pvData, int /*int32*/ cubData );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileWriteStreamClose( ulong writeHandle );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileWriteStreamCancel( ulong writeHandle );
|
||||
bool /*bool*/ ISteamRemoteStorage_FileExists( string /*const char **/ pchFile );
|
||||
bool /*bool*/ ISteamRemoteStorage_FilePersisted( string /*const char **/ pchFile );
|
||||
int /*int32*/ ISteamRemoteStorage_GetFileSize( string /*const char **/ pchFile );
|
||||
long /*int64*/ ISteamRemoteStorage_GetFileTimestamp( string /*const char **/ pchFile );
|
||||
RemoteStoragePlatform /*ERemoteStoragePlatform*/ ISteamRemoteStorage_GetSyncPlatforms( string /*const char **/ pchFile );
|
||||
int /*int32*/ ISteamRemoteStorage_GetFileCount();
|
||||
IntPtr ISteamRemoteStorage_GetFileNameAndSize( int /*int*/ iFile, out int /*int32 **/ pnFileSizeInBytes );
|
||||
bool /*bool*/ ISteamRemoteStorage_GetQuota( out ulong /*uint64 **/ pnTotalBytes, out ulong /*uint64 **/ puAvailableBytes );
|
||||
bool /*bool*/ ISteamRemoteStorage_IsCloudEnabledForAccount();
|
||||
bool /*bool*/ ISteamRemoteStorage_IsCloudEnabledForApp();
|
||||
void /*void*/ ISteamRemoteStorage_SetCloudEnabledForApp( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bEnabled );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_UGCDownload( ulong hContent, uint /*uint32*/ unPriority );
|
||||
bool /*bool*/ ISteamRemoteStorage_GetUGCDownloadProgress( ulong hContent, out int /*int32 **/ pnBytesDownloaded, out int /*int32 **/ pnBytesExpected );
|
||||
bool /*bool*/ ISteamRemoteStorage_GetUGCDetails( ulong hContent, ref uint pnAppID, System.Text.StringBuilder /*char ***/ ppchName, out int /*int32 **/ pnFileSizeInBytes, out ulong pSteamIDOwner );
|
||||
int /*int32*/ ISteamRemoteStorage_UGCRead( ulong hContent, IntPtr /*void **/ pvData, int /*int32*/ cubDataToRead, uint /*uint32*/ cOffset, UGCReadAction /*EUGCReadAction*/ eAction );
|
||||
int /*int32*/ ISteamRemoteStorage_GetCachedUGCCount();
|
||||
UGCHandle_t /*(UGCHandle_t)*/ ISteamRemoteStorage_GetCachedUGCHandle( int /*int32*/ iCachedContent );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_PublishWorkshopFile( string /*const char **/ pchFile, string /*const char **/ pchPreviewFile, uint nConsumerAppId, string /*const char **/ pchTitle, string /*const char **/ pchDescription, RemoteStoragePublishedFileVisibility /*ERemoteStoragePublishedFileVisibility*/ eVisibility, ref SteamParamStringArray_t /*struct SteamParamStringArray_t **/ pTags, WorkshopFileType /*EWorkshopFileType*/ eWorkshopFileType );
|
||||
PublishedFileUpdateHandle_t /*(PublishedFileUpdateHandle_t)*/ ISteamRemoteStorage_CreatePublishedFileUpdateRequest( ulong unPublishedFileId );
|
||||
bool /*bool*/ ISteamRemoteStorage_UpdatePublishedFileFile( ulong updateHandle, string /*const char **/ pchFile );
|
||||
bool /*bool*/ ISteamRemoteStorage_UpdatePublishedFilePreviewFile( ulong updateHandle, string /*const char **/ pchPreviewFile );
|
||||
bool /*bool*/ ISteamRemoteStorage_UpdatePublishedFileTitle( ulong updateHandle, string /*const char **/ pchTitle );
|
||||
bool /*bool*/ ISteamRemoteStorage_UpdatePublishedFileDescription( ulong updateHandle, string /*const char **/ pchDescription );
|
||||
bool /*bool*/ ISteamRemoteStorage_UpdatePublishedFileVisibility( ulong updateHandle, RemoteStoragePublishedFileVisibility /*ERemoteStoragePublishedFileVisibility*/ eVisibility );
|
||||
bool /*bool*/ ISteamRemoteStorage_UpdatePublishedFileTags( ulong updateHandle, ref SteamParamStringArray_t /*struct SteamParamStringArray_t **/ pTags );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_CommitPublishedFileUpdate( ulong updateHandle );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_GetPublishedFileDetails( ulong unPublishedFileId, uint /*uint32*/ unMaxSecondsOld );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_DeletePublishedFile( ulong unPublishedFileId );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_EnumerateUserPublishedFiles( uint /*uint32*/ unStartIndex );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_SubscribePublishedFile( ulong unPublishedFileId );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_EnumerateUserSubscribedFiles( uint /*uint32*/ unStartIndex );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_UnsubscribePublishedFile( ulong unPublishedFileId );
|
||||
bool /*bool*/ ISteamRemoteStorage_UpdatePublishedFileSetChangeDescription( ulong updateHandle, string /*const char **/ pchChangeDescription );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_GetPublishedItemVoteDetails( ulong unPublishedFileId );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_UpdateUserPublishedItemVote( ulong unPublishedFileId, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bVoteUp );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_GetUserPublishedItemVoteDetails( ulong unPublishedFileId );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_EnumerateUserSharedWorkshopFiles( ulong steamId, uint /*uint32*/ unStartIndex, ref SteamParamStringArray_t /*struct SteamParamStringArray_t **/ pRequiredTags, ref SteamParamStringArray_t /*struct SteamParamStringArray_t **/ pExcludedTags );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_PublishVideo( WorkshopVideoProvider /*EWorkshopVideoProvider*/ eVideoProvider, string /*const char **/ pchVideoAccount, string /*const char **/ pchVideoIdentifier, string /*const char **/ pchPreviewFile, uint nConsumerAppId, string /*const char **/ pchTitle, string /*const char **/ pchDescription, RemoteStoragePublishedFileVisibility /*ERemoteStoragePublishedFileVisibility*/ eVisibility, ref SteamParamStringArray_t /*struct SteamParamStringArray_t **/ pTags );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_SetUserPublishedFileAction( ulong unPublishedFileId, WorkshopFileAction /*EWorkshopFileAction*/ eAction );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_EnumeratePublishedFilesByUserAction( WorkshopFileAction /*EWorkshopFileAction*/ eAction, uint /*uint32*/ unStartIndex );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_EnumeratePublishedWorkshopFiles( WorkshopEnumerationType /*EWorkshopEnumerationType*/ eEnumerationType, uint /*uint32*/ unStartIndex, uint /*uint32*/ unCount, uint /*uint32*/ unDays, ref SteamParamStringArray_t /*struct SteamParamStringArray_t **/ pTags, ref SteamParamStringArray_t /*struct SteamParamStringArray_t **/ pUserTags );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamRemoteStorage_UGCDownloadToLocation( ulong hContent, string /*const char **/ pchLocation, uint /*uint32*/ unPriority );
|
||||
ScreenshotHandle /*(ScreenshotHandle)*/ ISteamScreenshots_WriteScreenshot( IntPtr /*void **/ pubRGB, uint /*uint32*/ cubRGB, int /*int*/ nWidth, int /*int*/ nHeight );
|
||||
ScreenshotHandle /*(ScreenshotHandle)*/ ISteamScreenshots_AddScreenshotToLibrary( string /*const char **/ pchFilename, string /*const char **/ pchThumbnailFilename, int /*int*/ nWidth, int /*int*/ nHeight );
|
||||
void /*void*/ ISteamScreenshots_TriggerScreenshot();
|
||||
void /*void*/ ISteamScreenshots_HookScreenshots( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bHook );
|
||||
bool /*bool*/ ISteamScreenshots_SetLocation( uint hScreenshot, string /*const char **/ pchLocation );
|
||||
bool /*bool*/ ISteamScreenshots_TagUser( uint hScreenshot, ulong steamID );
|
||||
bool /*bool*/ ISteamScreenshots_TagPublishedFile( uint hScreenshot, ulong unPublishedFileID );
|
||||
bool /*bool*/ ISteamScreenshots_IsScreenshotsHooked();
|
||||
ScreenshotHandle /*(ScreenshotHandle)*/ ISteamScreenshots_AddVRScreenshotToLibrary( VRScreenshotType /*EVRScreenshotType*/ eType, string /*const char **/ pchFilename, string /*const char **/ pchVRFilename );
|
||||
UGCQueryHandle_t /*(UGCQueryHandle_t)*/ ISteamUGC_CreateQueryUserUGCRequest( uint unAccountID, UserUGCList /*EUserUGCList*/ eListType, UGCMatchingUGCType /*EUGCMatchingUGCType*/ eMatchingUGCType, UserUGCListSortOrder /*EUserUGCListSortOrder*/ eSortOrder, uint nCreatorAppID, uint nConsumerAppID, uint /*uint32*/ unPage );
|
||||
UGCQueryHandle_t /*(UGCQueryHandle_t)*/ ISteamUGC_CreateQueryAllUGCRequest( UGCQuery /*EUGCQuery*/ eQueryType, UGCMatchingUGCType /*EUGCMatchingUGCType*/ eMatchingeMatchingUGCTypeFileType, uint nCreatorAppID, uint nConsumerAppID, uint /*uint32*/ unPage );
|
||||
UGCQueryHandle_t /*(UGCQueryHandle_t)*/ ISteamUGC_CreateQueryUGCDetailsRequest( IntPtr /*PublishedFileId_t **/ pvecPublishedFileID, uint /*uint32*/ unNumPublishedFileIDs );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_SendQueryUGCRequest( ulong handle );
|
||||
bool /*bool*/ ISteamUGC_GetQueryUGCResult( ulong handle, uint /*uint32*/ index, ref SteamUGCDetails_t /*struct SteamUGCDetails_t **/ pDetails );
|
||||
bool /*bool*/ ISteamUGC_GetQueryUGCPreviewURL( ulong handle, uint /*uint32*/ index, System.Text.StringBuilder /*char **/ pchURL, uint /*uint32*/ cchURLSize );
|
||||
bool /*bool*/ ISteamUGC_GetQueryUGCMetadata( ulong handle, uint /*uint32*/ index, System.Text.StringBuilder /*char **/ pchMetadata, uint /*uint32*/ cchMetadatasize );
|
||||
bool /*bool*/ ISteamUGC_GetQueryUGCChildren( ulong handle, uint /*uint32*/ index, IntPtr /*PublishedFileId_t **/ pvecPublishedFileID, uint /*uint32*/ cMaxEntries );
|
||||
bool /*bool*/ ISteamUGC_GetQueryUGCStatistic( ulong handle, uint /*uint32*/ index, ItemStatistic /*EItemStatistic*/ eStatType, out ulong /*uint64 **/ pStatValue );
|
||||
uint /*uint32*/ ISteamUGC_GetQueryUGCNumAdditionalPreviews( ulong handle, uint /*uint32*/ index );
|
||||
bool /*bool*/ ISteamUGC_GetQueryUGCAdditionalPreview( ulong handle, uint /*uint32*/ index, uint /*uint32*/ previewIndex, System.Text.StringBuilder /*char **/ pchURLOrVideoID, uint /*uint32*/ cchURLSize, System.Text.StringBuilder /*char **/ pchOriginalFileName, uint /*uint32*/ cchOriginalFileNameSize, out ItemPreviewType /*EItemPreviewType **/ pPreviewType );
|
||||
uint /*uint32*/ ISteamUGC_GetQueryUGCNumKeyValueTags( ulong handle, uint /*uint32*/ index );
|
||||
bool /*bool*/ ISteamUGC_GetQueryUGCKeyValueTag( ulong handle, uint /*uint32*/ index, uint /*uint32*/ keyValueTagIndex, System.Text.StringBuilder /*char **/ pchKey, uint /*uint32*/ cchKeySize, System.Text.StringBuilder /*char **/ pchValue, uint /*uint32*/ cchValueSize );
|
||||
bool /*bool*/ ISteamUGC_ReleaseQueryUGCRequest( ulong handle );
|
||||
bool /*bool*/ ISteamUGC_AddRequiredTag( ulong handle, string /*const char **/ pTagName );
|
||||
bool /*bool*/ ISteamUGC_AddExcludedTag( ulong handle, string /*const char **/ pTagName );
|
||||
bool /*bool*/ ISteamUGC_SetReturnOnlyIDs( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReturnOnlyIDs );
|
||||
bool /*bool*/ ISteamUGC_SetReturnKeyValueTags( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReturnKeyValueTags );
|
||||
bool /*bool*/ ISteamUGC_SetReturnLongDescription( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReturnLongDescription );
|
||||
bool /*bool*/ ISteamUGC_SetReturnMetadata( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReturnMetadata );
|
||||
bool /*bool*/ ISteamUGC_SetReturnChildren( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReturnChildren );
|
||||
bool /*bool*/ ISteamUGC_SetReturnAdditionalPreviews( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReturnAdditionalPreviews );
|
||||
bool /*bool*/ ISteamUGC_SetReturnTotalOnly( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bReturnTotalOnly );
|
||||
bool /*bool*/ ISteamUGC_SetReturnPlaytimeStats( ulong handle, uint /*uint32*/ unDays );
|
||||
bool /*bool*/ ISteamUGC_SetLanguage( ulong handle, string /*const char **/ pchLanguage );
|
||||
bool /*bool*/ ISteamUGC_SetAllowCachedResponse( ulong handle, uint /*uint32*/ unMaxAgeSeconds );
|
||||
bool /*bool*/ ISteamUGC_SetCloudFileNameFilter( ulong handle, string /*const char **/ pMatchCloudFileName );
|
||||
bool /*bool*/ ISteamUGC_SetMatchAnyTag( ulong handle, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bMatchAnyTag );
|
||||
bool /*bool*/ ISteamUGC_SetSearchText( ulong handle, string /*const char **/ pSearchText );
|
||||
bool /*bool*/ ISteamUGC_SetRankedByTrendDays( ulong handle, uint /*uint32*/ unDays );
|
||||
bool /*bool*/ ISteamUGC_AddRequiredKeyValueTag( ulong handle, string /*const char **/ pKey, string /*const char **/ pValue );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_RequestUGCDetails( ulong nPublishedFileID, uint /*uint32*/ unMaxAgeSeconds );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_CreateItem( uint nConsumerAppId, WorkshopFileType /*EWorkshopFileType*/ eFileType );
|
||||
UGCUpdateHandle_t /*(UGCUpdateHandle_t)*/ ISteamUGC_StartItemUpdate( uint nConsumerAppId, ulong nPublishedFileID );
|
||||
bool /*bool*/ ISteamUGC_SetItemTitle( ulong handle, string /*const char **/ pchTitle );
|
||||
bool /*bool*/ ISteamUGC_SetItemDescription( ulong handle, string /*const char **/ pchDescription );
|
||||
bool /*bool*/ ISteamUGC_SetItemUpdateLanguage( ulong handle, string /*const char **/ pchLanguage );
|
||||
bool /*bool*/ ISteamUGC_SetItemMetadata( ulong handle, string /*const char **/ pchMetaData );
|
||||
bool /*bool*/ ISteamUGC_SetItemVisibility( ulong handle, RemoteStoragePublishedFileVisibility /*ERemoteStoragePublishedFileVisibility*/ eVisibility );
|
||||
bool /*bool*/ ISteamUGC_SetItemTags( ulong updateHandle, ref SteamParamStringArray_t /*const struct SteamParamStringArray_t **/ pTags );
|
||||
bool /*bool*/ ISteamUGC_SetItemContent( ulong handle, string /*const char **/ pszContentFolder );
|
||||
bool /*bool*/ ISteamUGC_SetItemPreview( ulong handle, string /*const char **/ pszPreviewFile );
|
||||
bool /*bool*/ ISteamUGC_RemoveItemKeyValueTags( ulong handle, string /*const char **/ pchKey );
|
||||
bool /*bool*/ ISteamUGC_AddItemKeyValueTag( ulong handle, string /*const char **/ pchKey, string /*const char **/ pchValue );
|
||||
bool /*bool*/ ISteamUGC_AddItemPreviewFile( ulong handle, string /*const char **/ pszPreviewFile, ItemPreviewType /*EItemPreviewType*/ type );
|
||||
bool /*bool*/ ISteamUGC_AddItemPreviewVideo( ulong handle, string /*const char **/ pszVideoID );
|
||||
bool /*bool*/ ISteamUGC_UpdateItemPreviewFile( ulong handle, uint /*uint32*/ index, string /*const char **/ pszPreviewFile );
|
||||
bool /*bool*/ ISteamUGC_UpdateItemPreviewVideo( ulong handle, uint /*uint32*/ index, string /*const char **/ pszVideoID );
|
||||
bool /*bool*/ ISteamUGC_RemoveItemPreview( ulong handle, uint /*uint32*/ index );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_SubmitItemUpdate( ulong handle, string /*const char **/ pchChangeNote );
|
||||
ItemUpdateStatus /*EItemUpdateStatus*/ ISteamUGC_GetItemUpdateProgress( ulong handle, out ulong /*uint64 **/ punBytesProcessed, out ulong /*uint64 **/ punBytesTotal );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_SetUserItemVote( ulong nPublishedFileID, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bVoteUp );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_GetUserItemVote( ulong nPublishedFileID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_AddItemToFavorites( uint nAppId, ulong nPublishedFileID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_RemoveItemFromFavorites( uint nAppId, ulong nPublishedFileID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_SubscribeItem( ulong nPublishedFileID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_UnsubscribeItem( ulong nPublishedFileID );
|
||||
uint /*uint32*/ ISteamUGC_GetNumSubscribedItems();
|
||||
uint /*uint32*/ ISteamUGC_GetSubscribedItems( IntPtr /*PublishedFileId_t **/ pvecPublishedFileID, uint /*uint32*/ cMaxEntries );
|
||||
uint /*uint32*/ ISteamUGC_GetItemState( ulong nPublishedFileID );
|
||||
bool /*bool*/ ISteamUGC_GetItemInstallInfo( ulong nPublishedFileID, out ulong /*uint64 **/ punSizeOnDisk, System.Text.StringBuilder /*char **/ pchFolder, uint /*uint32*/ cchFolderSize, out uint /*uint32 **/ punTimeStamp );
|
||||
bool /*bool*/ ISteamUGC_GetItemDownloadInfo( ulong nPublishedFileID, out ulong /*uint64 **/ punBytesDownloaded, out ulong /*uint64 **/ punBytesTotal );
|
||||
bool /*bool*/ ISteamUGC_DownloadItem( ulong nPublishedFileID, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bHighPriority );
|
||||
bool /*bool*/ ISteamUGC_BInitWorkshopForGameServer( uint unWorkshopDepotID, string /*const char **/ pszFolder );
|
||||
void /*void*/ ISteamUGC_SuspendDownloads( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bSuspend );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_StartPlaytimeTracking( IntPtr /*PublishedFileId_t **/ pvecPublishedFileID, uint /*uint32*/ unNumPublishedFileIDs );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_StopPlaytimeTracking( IntPtr /*PublishedFileId_t **/ pvecPublishedFileID, uint /*uint32*/ unNumPublishedFileIDs );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_StopPlaytimeTrackingForAllItems();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_AddDependency( ulong nParentPublishedFileID, ulong nChildPublishedFileID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_RemoveDependency( ulong nParentPublishedFileID, ulong nChildPublishedFileID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_AddAppDependency( ulong nPublishedFileID, uint nAppID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_RemoveAppDependency( ulong nPublishedFileID, uint nAppID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_GetAppDependencies( ulong nPublishedFileID );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUGC_DeleteItem( ulong nPublishedFileID );
|
||||
HSteamUser /*(HSteamUser)*/ ISteamUser_GetHSteamUser();
|
||||
bool /*bool*/ ISteamUser_BLoggedOn();
|
||||
CSteamID /*(class CSteamID)*/ ISteamUser_GetSteamID();
|
||||
int /*int*/ ISteamUser_InitiateGameConnection( IntPtr /*void **/ pAuthBlob, int /*int*/ cbMaxAuthBlob, ulong steamIDGameServer, uint /*uint32*/ unIPServer, ushort /*uint16*/ usPortServer, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bSecure );
|
||||
void /*void*/ ISteamUser_TerminateGameConnection( uint /*uint32*/ unIPServer, ushort /*uint16*/ usPortServer );
|
||||
void /*void*/ ISteamUser_TrackAppUsageEvent( ulong gameID, int /*int*/ eAppUsageEvent, string /*const char **/ pchExtraInfo );
|
||||
bool /*bool*/ ISteamUser_GetUserDataFolder( System.Text.StringBuilder /*char **/ pchBuffer, int /*int*/ cubBuffer );
|
||||
void /*void*/ ISteamUser_StartVoiceRecording();
|
||||
void /*void*/ ISteamUser_StopVoiceRecording();
|
||||
VoiceResult /*EVoiceResult*/ ISteamUser_GetAvailableVoice( out uint /*uint32 **/ pcbCompressed, out uint /*uint32 **/ pcbUncompressed_Deprecated, uint /*uint32*/ nUncompressedVoiceDesiredSampleRate_Deprecated );
|
||||
VoiceResult /*EVoiceResult*/ ISteamUser_GetVoice( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bWantCompressed, IntPtr /*void **/ pDestBuffer, uint /*uint32*/ cbDestBufferSize, out uint /*uint32 **/ nBytesWritten, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bWantUncompressed_Deprecated, IntPtr /*void **/ pUncompressedDestBuffer_Deprecated, uint /*uint32*/ cbUncompressedDestBufferSize_Deprecated, out uint /*uint32 **/ nUncompressBytesWritten_Deprecated, uint /*uint32*/ nUncompressedVoiceDesiredSampleRate_Deprecated );
|
||||
VoiceResult /*EVoiceResult*/ ISteamUser_DecompressVoice( IntPtr /*const void **/ pCompressed, uint /*uint32*/ cbCompressed, IntPtr /*void **/ pDestBuffer, uint /*uint32*/ cbDestBufferSize, out uint /*uint32 **/ nBytesWritten, uint /*uint32*/ nDesiredSampleRate );
|
||||
uint /*uint32*/ ISteamUser_GetVoiceOptimalSampleRate();
|
||||
HAuthTicket /*(HAuthTicket)*/ ISteamUser_GetAuthSessionTicket( IntPtr /*void **/ pTicket, int /*int*/ cbMaxTicket, out uint /*uint32 **/ pcbTicket );
|
||||
BeginAuthSessionResult /*EBeginAuthSessionResult*/ ISteamUser_BeginAuthSession( IntPtr /*const void **/ pAuthTicket, int /*int*/ cbAuthTicket, ulong steamID );
|
||||
void /*void*/ ISteamUser_EndAuthSession( ulong steamID );
|
||||
void /*void*/ ISteamUser_CancelAuthTicket( uint hAuthTicket );
|
||||
UserHasLicenseForAppResult /*EUserHasLicenseForAppResult*/ ISteamUser_UserHasLicenseForApp( ulong steamID, uint appID );
|
||||
bool /*bool*/ ISteamUser_BIsBehindNAT();
|
||||
void /*void*/ ISteamUser_AdvertiseGame( ulong steamIDGameServer, uint /*uint32*/ unIPServer, ushort /*uint16*/ usPortServer );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUser_RequestEncryptedAppTicket( IntPtr /*void **/ pDataToInclude, int /*int*/ cbDataToInclude );
|
||||
bool /*bool*/ ISteamUser_GetEncryptedAppTicket( IntPtr /*void **/ pTicket, int /*int*/ cbMaxTicket, out uint /*uint32 **/ pcbTicket );
|
||||
int /*int*/ ISteamUser_GetGameBadgeLevel( int /*int*/ nSeries, [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bFoil );
|
||||
int /*int*/ ISteamUser_GetPlayerSteamLevel();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUser_RequestStoreAuthURL( string /*const char **/ pchRedirectURL );
|
||||
bool /*bool*/ ISteamUser_BIsPhoneVerified();
|
||||
bool /*bool*/ ISteamUser_BIsTwoFactorEnabled();
|
||||
bool /*bool*/ ISteamUser_BIsPhoneIdentifying();
|
||||
bool /*bool*/ ISteamUser_BIsPhoneRequiringVerification();
|
||||
bool /*bool*/ ISteamUserStats_RequestCurrentStats();
|
||||
bool /*bool*/ ISteamUserStats_GetStat( string /*const char **/ pchName, out int /*int32 **/ pData );
|
||||
bool /*bool*/ ISteamUserStats_GetStat0( string /*const char **/ pchName, out float /*float **/ pData );
|
||||
bool /*bool*/ ISteamUserStats_SetStat( string /*const char **/ pchName, int /*int32*/ nData );
|
||||
bool /*bool*/ ISteamUserStats_SetStat0( string /*const char **/ pchName, float /*float*/ fData );
|
||||
bool /*bool*/ ISteamUserStats_UpdateAvgRateStat( string /*const char **/ pchName, float /*float*/ flCountThisSession, double /*double*/ dSessionLength );
|
||||
bool /*bool*/ ISteamUserStats_GetAchievement( string /*const char **/ pchName, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAchieved );
|
||||
bool /*bool*/ ISteamUserStats_SetAchievement( string /*const char **/ pchName );
|
||||
bool /*bool*/ ISteamUserStats_ClearAchievement( string /*const char **/ pchName );
|
||||
bool /*bool*/ ISteamUserStats_GetAchievementAndUnlockTime( string /*const char **/ pchName, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAchieved, out uint /*uint32 **/ punUnlockTime );
|
||||
bool /*bool*/ ISteamUserStats_StoreStats();
|
||||
int /*int*/ ISteamUserStats_GetAchievementIcon( string /*const char **/ pchName );
|
||||
IntPtr ISteamUserStats_GetAchievementDisplayAttribute( string /*const char **/ pchName, string /*const char **/ pchKey );
|
||||
bool /*bool*/ ISteamUserStats_IndicateAchievementProgress( string /*const char **/ pchName, uint /*uint32*/ nCurProgress, uint /*uint32*/ nMaxProgress );
|
||||
uint /*uint32*/ ISteamUserStats_GetNumAchievements();
|
||||
IntPtr ISteamUserStats_GetAchievementName( uint /*uint32*/ iAchievement );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_RequestUserStats( ulong steamIDUser );
|
||||
bool /*bool*/ ISteamUserStats_GetUserStat( ulong steamIDUser, string /*const char **/ pchName, out int /*int32 **/ pData );
|
||||
bool /*bool*/ ISteamUserStats_GetUserStat0( ulong steamIDUser, string /*const char **/ pchName, out float /*float **/ pData );
|
||||
bool /*bool*/ ISteamUserStats_GetUserAchievement( ulong steamIDUser, string /*const char **/ pchName, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAchieved );
|
||||
bool /*bool*/ ISteamUserStats_GetUserAchievementAndUnlockTime( ulong steamIDUser, string /*const char **/ pchName, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAchieved, out uint /*uint32 **/ punUnlockTime );
|
||||
bool /*bool*/ ISteamUserStats_ResetAllStats( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bAchievementsToo );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_FindOrCreateLeaderboard( string /*const char **/ pchLeaderboardName, LeaderboardSortMethod /*ELeaderboardSortMethod*/ eLeaderboardSortMethod, LeaderboardDisplayType /*ELeaderboardDisplayType*/ eLeaderboardDisplayType );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_FindLeaderboard( string /*const char **/ pchLeaderboardName );
|
||||
IntPtr ISteamUserStats_GetLeaderboardName( ulong hSteamLeaderboard );
|
||||
int /*int*/ ISteamUserStats_GetLeaderboardEntryCount( ulong hSteamLeaderboard );
|
||||
LeaderboardSortMethod /*ELeaderboardSortMethod*/ ISteamUserStats_GetLeaderboardSortMethod( ulong hSteamLeaderboard );
|
||||
LeaderboardDisplayType /*ELeaderboardDisplayType*/ ISteamUserStats_GetLeaderboardDisplayType( ulong hSteamLeaderboard );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_DownloadLeaderboardEntries( ulong hSteamLeaderboard, LeaderboardDataRequest /*ELeaderboardDataRequest*/ eLeaderboardDataRequest, int /*int*/ nRangeStart, int /*int*/ nRangeEnd );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_DownloadLeaderboardEntriesForUsers( ulong hSteamLeaderboard, IntPtr /*class CSteamID **/ prgUsers, int /*int*/ cUsers );
|
||||
bool /*bool*/ ISteamUserStats_GetDownloadedLeaderboardEntry( ulong hSteamLeaderboardEntries, int /*int*/ index, ref LeaderboardEntry_t /*struct LeaderboardEntry_t **/ pLeaderboardEntry, IntPtr /*int32 **/ pDetails, int /*int*/ cDetailsMax );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_UploadLeaderboardScore( ulong hSteamLeaderboard, LeaderboardUploadScoreMethod /*ELeaderboardUploadScoreMethod*/ eLeaderboardUploadScoreMethod, int /*int32*/ nScore, int[] /*const int32 **/ pScoreDetails, int /*int*/ cScoreDetailsCount );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_AttachLeaderboardUGC( ulong hSteamLeaderboard, ulong hUGC );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_GetNumberOfCurrentPlayers();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_RequestGlobalAchievementPercentages();
|
||||
int /*int*/ ISteamUserStats_GetMostAchievedAchievementInfo( System.Text.StringBuilder /*char **/ pchName, uint /*uint32*/ unNameBufLen, out float /*float **/ pflPercent, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAchieved );
|
||||
int /*int*/ ISteamUserStats_GetNextMostAchievedAchievementInfo( int /*int*/ iIteratorPrevious, System.Text.StringBuilder /*char **/ pchName, uint /*uint32*/ unNameBufLen, out float /*float **/ pflPercent, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbAchieved );
|
||||
bool /*bool*/ ISteamUserStats_GetAchievementAchievedPercent( string /*const char **/ pchName, out float /*float **/ pflPercent );
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUserStats_RequestGlobalStats( int /*int*/ nHistoryDays );
|
||||
bool /*bool*/ ISteamUserStats_GetGlobalStat( string /*const char **/ pchStatName, out long /*int64 **/ pData );
|
||||
bool /*bool*/ ISteamUserStats_GetGlobalStat0( string /*const char **/ pchStatName, out double /*double **/ pData );
|
||||
int /*int32*/ ISteamUserStats_GetGlobalStatHistory( string /*const char **/ pchStatName, out long /*int64 **/ pData, uint /*uint32*/ cubData );
|
||||
int /*int32*/ ISteamUserStats_GetGlobalStatHistory0( string /*const char **/ pchStatName, out double /*double **/ pData, uint /*uint32*/ cubData );
|
||||
uint /*uint32*/ ISteamUtils_GetSecondsSinceAppActive();
|
||||
uint /*uint32*/ ISteamUtils_GetSecondsSinceComputerActive();
|
||||
Universe /*EUniverse*/ ISteamUtils_GetConnectedUniverse();
|
||||
uint /*uint32*/ ISteamUtils_GetServerRealTime();
|
||||
IntPtr ISteamUtils_GetIPCountry();
|
||||
bool /*bool*/ ISteamUtils_GetImageSize( int /*int*/ iImage, out uint /*uint32 **/ pnWidth, out uint /*uint32 **/ pnHeight );
|
||||
bool /*bool*/ ISteamUtils_GetImageRGBA( int /*int*/ iImage, IntPtr /*uint8 **/ pubDest, int /*int*/ nDestBufferSize );
|
||||
bool /*bool*/ ISteamUtils_GetCSERIPPort( out uint /*uint32 **/ unIP, out ushort /*uint16 **/ usPort );
|
||||
byte /*uint8*/ ISteamUtils_GetCurrentBatteryPower();
|
||||
uint /*uint32*/ ISteamUtils_GetAppID();
|
||||
void /*void*/ ISteamUtils_SetOverlayNotificationPosition( NotificationPosition /*ENotificationPosition*/ eNotificationPosition );
|
||||
bool /*bool*/ ISteamUtils_IsAPICallCompleted( ulong hSteamAPICall, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbFailed );
|
||||
SteamAPICallFailure /*ESteamAPICallFailure*/ ISteamUtils_GetAPICallFailureReason( ulong hSteamAPICall );
|
||||
bool /*bool*/ ISteamUtils_GetAPICallResult( ulong hSteamAPICall, IntPtr /*void **/ pCallback, int /*int*/ cubCallback, int /*int*/ iCallbackExpected, [MarshalAs(UnmanagedType.U1)] ref bool /*bool **/ pbFailed );
|
||||
uint /*uint32*/ ISteamUtils_GetIPCCallCount();
|
||||
void /*void*/ ISteamUtils_SetWarningMessageHook( IntPtr /*SteamAPIWarningMessageHook_t*/ pFunction );
|
||||
bool /*bool*/ ISteamUtils_IsOverlayEnabled();
|
||||
bool /*bool*/ ISteamUtils_BOverlayNeedsPresent();
|
||||
SteamAPICall_t /*(SteamAPICall_t)*/ ISteamUtils_CheckFileSignature( string /*const char **/ szFileName );
|
||||
bool /*bool*/ ISteamUtils_ShowGamepadTextInput( GamepadTextInputMode /*EGamepadTextInputMode*/ eInputMode, GamepadTextInputLineMode /*EGamepadTextInputLineMode*/ eLineInputMode, string /*const char **/ pchDescription, uint /*uint32*/ unCharMax, string /*const char **/ pchExistingText );
|
||||
uint /*uint32*/ ISteamUtils_GetEnteredGamepadTextLength();
|
||||
bool /*bool*/ ISteamUtils_GetEnteredGamepadTextInput( System.Text.StringBuilder /*char **/ pchText, uint /*uint32*/ cchText );
|
||||
IntPtr ISteamUtils_GetSteamUILanguage();
|
||||
bool /*bool*/ ISteamUtils_IsSteamRunningInVR();
|
||||
void /*void*/ ISteamUtils_SetOverlayNotificationInset( int /*int*/ nHorizontalInset, int /*int*/ nVerticalInset );
|
||||
bool /*bool*/ ISteamUtils_IsSteamInBigPictureMode();
|
||||
void /*void*/ ISteamUtils_StartVRDashboard();
|
||||
bool /*bool*/ ISteamUtils_IsVRHeadsetStreamingEnabled();
|
||||
void /*void*/ ISteamUtils_SetVRHeadsetStreamingEnabled( [MarshalAs(UnmanagedType.U1)] bool /*bool*/ bEnabled );
|
||||
void /*void*/ ISteamVideo_GetVideoURL( uint unVideoAppID );
|
||||
bool /*bool*/ ISteamVideo_IsBroadcasting( IntPtr /*int **/ pnNumViewers );
|
||||
void /*void*/ ISteamVideo_GetOPFSettings( uint unVideoAppID );
|
||||
bool /*bool*/ ISteamVideo_GetOPFStringForApp( uint unVideoAppID, System.Text.StringBuilder /*char **/ pchBuffer, out int /*int32 **/ pnBufferSize );
|
||||
bool /*bool*/ SteamApi_SteamAPI_Init();
|
||||
void /*void*/ SteamApi_SteamAPI_RunCallbacks();
|
||||
void /*void*/ SteamApi_SteamGameServer_RunCallbacks();
|
||||
void /*void*/ SteamApi_SteamAPI_RegisterCallback( IntPtr /*void **/ pCallback, int /*int*/ callback );
|
||||
void /*void*/ SteamApi_SteamAPI_UnregisterCallback( IntPtr /*void **/ pCallback );
|
||||
void /*void*/ SteamApi_SteamAPI_RegisterCallResult( IntPtr /*void **/ pCallback, ulong callback );
|
||||
void /*void*/ SteamApi_SteamAPI_UnregisterCallResult( IntPtr /*void **/ pCallback, ulong callback );
|
||||
bool /*bool*/ SteamApi_SteamInternal_GameServer_Init( uint /*uint32*/ unIP, ushort /*uint16*/ usPort, ushort /*uint16*/ usGamePort, ushort /*uint16*/ usQueryPort, int /*int*/ eServerMode, string /*const char **/ pchVersionString );
|
||||
void /*void*/ SteamApi_SteamAPI_Shutdown();
|
||||
void /*void*/ SteamApi_SteamGameServer_Shutdown();
|
||||
HSteamUser /*(HSteamUser)*/ SteamApi_SteamAPI_GetHSteamUser();
|
||||
HSteamPipe /*(HSteamPipe)*/ SteamApi_SteamAPI_GetHSteamPipe();
|
||||
HSteamUser /*(HSteamUser)*/ SteamApi_SteamGameServer_GetHSteamUser();
|
||||
HSteamPipe /*(HSteamPipe)*/ SteamApi_SteamGameServer_GetHSteamPipe();
|
||||
IntPtr /*void **/ SteamApi_SteamInternal_CreateInterface( string /*const char **/ version );
|
||||
bool /*bool*/ SteamApi_SteamAPI_RestartAppIfNecessary( uint /*uint32*/ unOwnAppID );
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public enum OperatingSystem
|
||||
{
|
||||
Unset,
|
||||
Windows,
|
||||
Linux,
|
||||
macOS,
|
||||
}
|
||||
|
||||
public enum Architecture
|
||||
{
|
||||
Unset,
|
||||
x86,
|
||||
x64
|
||||
}
|
||||
}
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal static partial class Platform
|
||||
{
|
||||
private static Facepunch.Steamworks.OperatingSystem _os;
|
||||
private static Facepunch.Steamworks.Architecture _arch;
|
||||
|
||||
public static Facepunch.Steamworks.OperatingSystem RunningPlatform()
|
||||
{
|
||||
switch (Environment.OSVersion.Platform)
|
||||
{
|
||||
case PlatformID.Unix:
|
||||
// macOS sometimes reports to .NET as Unix. Fix is to check against macOS root folders
|
||||
if (Directory.Exists("/Applications") && Directory.Exists("/System") && Directory.Exists("/Users") && Directory.Exists("/Volumes"))
|
||||
return Facepunch.Steamworks.OperatingSystem.macOS;
|
||||
else
|
||||
return Facepunch.Steamworks.OperatingSystem.Linux;
|
||||
case PlatformID.MacOSX:
|
||||
return Facepunch.Steamworks.OperatingSystem.macOS;
|
||||
|
||||
default:
|
||||
return Facepunch.Steamworks.OperatingSystem.Windows;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Facepunch.Steamworks.OperatingSystem Os
|
||||
{
|
||||
get
|
||||
{
|
||||
//
|
||||
// Work out our platform
|
||||
//
|
||||
if ( _os == Facepunch.Steamworks.OperatingSystem.Unset )
|
||||
{
|
||||
_os = Facepunch.Steamworks.OperatingSystem.Windows;
|
||||
|
||||
#if !NET_CORE
|
||||
// Fixed Bet
|
||||
_os = RunningPlatform();
|
||||
#endif
|
||||
}
|
||||
|
||||
return _os;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_os = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Facepunch.Steamworks.Architecture Arch
|
||||
{
|
||||
get
|
||||
{
|
||||
//
|
||||
// Work out whether we're 64bit or 32bit
|
||||
//
|
||||
if ( _arch == Facepunch.Steamworks.Architecture.Unset )
|
||||
{
|
||||
if ( IntPtr.Size == 8 )
|
||||
_arch = Facepunch.Steamworks.Architecture.x64;
|
||||
else if ( IntPtr.Size == 4 )
|
||||
_arch = Facepunch.Steamworks.Architecture.x86;
|
||||
else
|
||||
throw new System.Exception( "Unsupported Architecture!" );
|
||||
}
|
||||
|
||||
return _arch;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_arch = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsWindows { get { return Os == Facepunch.Steamworks.OperatingSystem.Windows; } }
|
||||
public static bool IsWindows64 { get { return Arch == Facepunch.Steamworks.Architecture.x64 && IsWindows; } }
|
||||
public static bool IsWindows32 { get { return Arch == Facepunch.Steamworks.Architecture.x86 && IsWindows; } }
|
||||
public static bool IsLinux64 { get { return Arch == Facepunch.Steamworks.Architecture.x64 && Os == Facepunch.Steamworks.OperatingSystem.Linux; } }
|
||||
public static bool IsLinux32 { get { return Arch == Facepunch.Steamworks.Architecture.x86 && Os == Facepunch.Steamworks.OperatingSystem.Linux; } }
|
||||
public static bool IsOsx { get { return Os == Facepunch.Steamworks.OperatingSystem.macOS; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// We're only Pack = 8 on Windows
|
||||
/// </summary>
|
||||
public static bool PackSmall { get { return Os != Facepunch.Steamworks.OperatingSystem.Windows; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamApi : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamApi()
|
||||
{
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( ((IntPtr)1) );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( ((IntPtr)1) );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( ((IntPtr)1) );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( ((IntPtr)1) );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( ((IntPtr)1) );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// HSteamPipe
|
||||
public HSteamPipe SteamAPI_GetHSteamPipe()
|
||||
{
|
||||
return platform.SteamApi_SteamAPI_GetHSteamPipe();
|
||||
}
|
||||
|
||||
// HSteamUser
|
||||
public HSteamUser SteamAPI_GetHSteamUser()
|
||||
{
|
||||
return platform.SteamApi_SteamAPI_GetHSteamUser();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SteamAPI_Init()
|
||||
{
|
||||
return platform.SteamApi_SteamAPI_Init();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamAPI_RegisterCallback( IntPtr pCallback /*void **/, int callback /*int*/ )
|
||||
{
|
||||
platform.SteamApi_SteamAPI_RegisterCallback( (IntPtr) pCallback, callback );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamAPI_RegisterCallResult( IntPtr pCallback /*void **/, SteamAPICall_t callback /*SteamAPICall_t*/ )
|
||||
{
|
||||
platform.SteamApi_SteamAPI_RegisterCallResult( (IntPtr) pCallback, callback.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SteamAPI_RestartAppIfNecessary( uint unOwnAppID /*uint32*/ )
|
||||
{
|
||||
return platform.SteamApi_SteamAPI_RestartAppIfNecessary( unOwnAppID );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamAPI_RunCallbacks()
|
||||
{
|
||||
platform.SteamApi_SteamAPI_RunCallbacks();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamAPI_Shutdown()
|
||||
{
|
||||
platform.SteamApi_SteamAPI_Shutdown();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamAPI_UnregisterCallback( IntPtr pCallback /*void **/ )
|
||||
{
|
||||
platform.SteamApi_SteamAPI_UnregisterCallback( (IntPtr) pCallback );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamAPI_UnregisterCallResult( IntPtr pCallback /*void **/, SteamAPICall_t callback /*SteamAPICall_t*/ )
|
||||
{
|
||||
platform.SteamApi_SteamAPI_UnregisterCallResult( (IntPtr) pCallback, callback.Value );
|
||||
}
|
||||
|
||||
// HSteamPipe
|
||||
public HSteamPipe SteamGameServer_GetHSteamPipe()
|
||||
{
|
||||
return platform.SteamApi_SteamGameServer_GetHSteamPipe();
|
||||
}
|
||||
|
||||
// HSteamUser
|
||||
public HSteamUser SteamGameServer_GetHSteamUser()
|
||||
{
|
||||
return platform.SteamApi_SteamGameServer_GetHSteamUser();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamGameServer_RunCallbacks()
|
||||
{
|
||||
platform.SteamApi_SteamGameServer_RunCallbacks();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SteamGameServer_Shutdown()
|
||||
{
|
||||
platform.SteamApi_SteamGameServer_Shutdown();
|
||||
}
|
||||
|
||||
// IntPtr
|
||||
public IntPtr SteamInternal_CreateInterface( string version /*const char **/ )
|
||||
{
|
||||
return platform.SteamApi_SteamInternal_CreateInterface( version );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SteamInternal_GameServer_Init( uint unIP /*uint32*/, ushort usPort /*uint16*/, ushort usGamePort /*uint16*/, ushort usQueryPort /*uint16*/, int eServerMode /*int*/, string pchVersionString /*const char **/ )
|
||||
{
|
||||
return platform.SteamApi_SteamInternal_GameServer_Init( unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamAppList : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamAppList( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetAppBuildId( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamAppList_GetAppBuildId( nAppID.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
// with: Detect_StringFetch True
|
||||
public string GetAppInstallDir( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
int bSuccess = default( int );
|
||||
System.Text.StringBuilder pchDirectory_sb = Helpers.TakeStringBuilder();
|
||||
int cchNameMax = 4096;
|
||||
bSuccess = platform.ISteamAppList_GetAppInstallDir( nAppID.Value, pchDirectory_sb, cchNameMax );
|
||||
if ( bSuccess <= 0 ) return null;
|
||||
return pchDirectory_sb.ToString();
|
||||
}
|
||||
|
||||
// int
|
||||
// with: Detect_StringFetch True
|
||||
public string GetAppName( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
int bSuccess = default( int );
|
||||
System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder();
|
||||
int cchNameMax = 4096;
|
||||
bSuccess = platform.ISteamAppList_GetAppName( nAppID.Value, pchName_sb, cchNameMax );
|
||||
if ( bSuccess <= 0 ) return null;
|
||||
return pchName_sb.ToString();
|
||||
}
|
||||
|
||||
// with: Detect_VectorReturn
|
||||
// uint
|
||||
public uint GetInstalledApps( AppId_t[] pvecAppID /*AppId_t **/ )
|
||||
{
|
||||
var unMaxAppIDs = (uint) pvecAppID.Length;
|
||||
fixed ( AppId_t* pvecAppID_ptr = pvecAppID )
|
||||
{
|
||||
return platform.ISteamAppList_GetInstalledApps( (IntPtr) pvecAppID_ptr, unMaxAppIDs );
|
||||
}
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetNumInstalledApps()
|
||||
{
|
||||
return platform.ISteamAppList_GetNumInstalledApps();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamApps : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamApps( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
public bool BGetDLCDataByIndex( int iDLC /*int*/, ref AppId_t pAppID /*AppId_t **/, ref bool pbAvailable /*bool **/, out string pchName /*char **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchName = string.Empty;
|
||||
System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder();
|
||||
int cchNameBufferSize = 4096;
|
||||
bSuccess = platform.ISteamApps_BGetDLCDataByIndex( iDLC, ref pAppID.Value, ref pbAvailable, pchName_sb, cchNameBufferSize );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchName = pchName_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsAppInstalled( AppId_t appID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamApps_BIsAppInstalled( appID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsCybercafe()
|
||||
{
|
||||
return platform.ISteamApps_BIsCybercafe();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsDlcInstalled( AppId_t appID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamApps_BIsDlcInstalled( appID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsLowViolence()
|
||||
{
|
||||
return platform.ISteamApps_BIsLowViolence();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsSubscribed()
|
||||
{
|
||||
return platform.ISteamApps_BIsSubscribed();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsSubscribedApp( AppId_t appID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamApps_BIsSubscribedApp( appID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsSubscribedFromFreeWeekend()
|
||||
{
|
||||
return platform.ISteamApps_BIsSubscribedFromFreeWeekend();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsVACBanned()
|
||||
{
|
||||
return platform.ISteamApps_BIsVACBanned();
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetAppBuildId()
|
||||
{
|
||||
return platform.ISteamApps_GetAppBuildId();
|
||||
}
|
||||
|
||||
// uint
|
||||
// with: Detect_StringFetch True
|
||||
public string GetAppInstallDir( AppId_t appID /*AppId_t*/ )
|
||||
{
|
||||
uint bSuccess = default( uint );
|
||||
System.Text.StringBuilder pchFolder_sb = Helpers.TakeStringBuilder();
|
||||
uint cchFolderBufferSize = 4096;
|
||||
bSuccess = platform.ISteamApps_GetAppInstallDir( appID.Value, pchFolder_sb, cchFolderBufferSize );
|
||||
if ( bSuccess <= 0 ) return null;
|
||||
return pchFolder_sb.ToString();
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetAppOwner()
|
||||
{
|
||||
return platform.ISteamApps_GetAppOwner();
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetAvailableGameLanguages()
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamApps_GetAvailableGameLanguages();
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch True
|
||||
public string GetCurrentBetaName()
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder();
|
||||
int cchNameBufferSize = 4096;
|
||||
bSuccess = platform.ISteamApps_GetCurrentBetaName( pchName_sb, cchNameBufferSize );
|
||||
if ( !bSuccess ) return null;
|
||||
return pchName_sb.ToString();
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetCurrentGameLanguage()
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamApps_GetCurrentGameLanguage();
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetDLCCount()
|
||||
{
|
||||
return platform.ISteamApps_GetDLCCount();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetDlcDownloadProgress( AppId_t nAppID /*AppId_t*/, out ulong punBytesDownloaded /*uint64 **/, out ulong punBytesTotal /*uint64 **/ )
|
||||
{
|
||||
return platform.ISteamApps_GetDlcDownloadProgress( nAppID.Value, out punBytesDownloaded, out punBytesTotal );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetEarliestPurchaseUnixTime( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamApps_GetEarliestPurchaseUnixTime( nAppID.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetFileDetails( string pszFileName /*const char **/, Action<FileDetailsResult_t, bool> CallbackFunction = null /*Action<FileDetailsResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamApps_GetFileDetails( pszFileName );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return FileDetailsResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetInstalledDepots( AppId_t appID /*AppId_t*/, IntPtr pvecDepots /*DepotId_t **/, uint cMaxDepots /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamApps_GetInstalledDepots( appID.Value, (IntPtr) pvecDepots, cMaxDepots );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetLaunchQueryParam( string pchKey /*const char **/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamApps_GetLaunchQueryParam( pchKey );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// void
|
||||
public void InstallDLC( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
platform.ISteamApps_InstallDLC( nAppID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool MarkContentCorrupt( bool bMissingFilesOnly /*bool*/ )
|
||||
{
|
||||
return platform.ISteamApps_MarkContentCorrupt( bMissingFilesOnly );
|
||||
}
|
||||
|
||||
// void
|
||||
public void RequestAllProofOfPurchaseKeys()
|
||||
{
|
||||
platform.ISteamApps_RequestAllProofOfPurchaseKeys();
|
||||
}
|
||||
|
||||
// void
|
||||
public void RequestAppProofOfPurchaseKey( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
platform.ISteamApps_RequestAppProofOfPurchaseKey( nAppID.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void UninstallDLC( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
platform.ISteamApps_UninstallDLC( nAppID.Value );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamClient : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamClient( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BReleaseSteamPipe( HSteamPipe hSteamPipe /*HSteamPipe*/ )
|
||||
{
|
||||
return platform.ISteamClient_BReleaseSteamPipe( hSteamPipe.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BShutdownIfAllPipesClosed()
|
||||
{
|
||||
return platform.ISteamClient_BShutdownIfAllPipesClosed();
|
||||
}
|
||||
|
||||
// HSteamUser
|
||||
public HSteamUser ConnectToGlobalUser( HSteamPipe hSteamPipe /*HSteamPipe*/ )
|
||||
{
|
||||
return platform.ISteamClient_ConnectToGlobalUser( hSteamPipe.Value );
|
||||
}
|
||||
|
||||
// HSteamUser
|
||||
public HSteamUser CreateLocalUser( out HSteamPipe phSteamPipe /*HSteamPipe **/, AccountType eAccountType /*EAccountType*/ )
|
||||
{
|
||||
return platform.ISteamClient_CreateLocalUser( out phSteamPipe.Value, eAccountType );
|
||||
}
|
||||
|
||||
// HSteamPipe
|
||||
public HSteamPipe CreateSteamPipe()
|
||||
{
|
||||
return platform.ISteamClient_CreateSteamPipe();
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetIPCCallCount()
|
||||
{
|
||||
return platform.ISteamClient_GetIPCCallCount();
|
||||
}
|
||||
|
||||
// ISteamAppList *
|
||||
public SteamAppList GetISteamAppList( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamAppList( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamAppList( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamApps *
|
||||
public SteamApps GetISteamApps( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamApps( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamApps( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamController *
|
||||
public SteamController GetISteamController( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamController( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamController( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamFriends *
|
||||
public SteamFriends GetISteamFriends( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamFriends( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamFriends( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamGameServer *
|
||||
public SteamGameServer GetISteamGameServer( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamGameServer( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamGameServer( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamGameServerStats *
|
||||
public SteamGameServerStats GetISteamGameServerStats( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamGameServerStats( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamGameServerStats( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// IntPtr
|
||||
public IntPtr GetISteamGenericInterface( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
return platform.ISteamClient_GetISteamGenericInterface( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
}
|
||||
|
||||
// ISteamHTMLSurface *
|
||||
public SteamHTMLSurface GetISteamHTMLSurface( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamHTMLSurface( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamHTMLSurface( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamHTTP *
|
||||
public SteamHTTP GetISteamHTTP( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamHTTP( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamHTTP( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamInventory *
|
||||
public SteamInventory GetISteamInventory( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamInventory( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamInventory( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamMatchmaking *
|
||||
public SteamMatchmaking GetISteamMatchmaking( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamMatchmaking( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamMatchmaking( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamMatchmakingServers *
|
||||
public SteamMatchmakingServers GetISteamMatchmakingServers( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamMatchmakingServers( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamMatchmakingServers( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamMusic *
|
||||
public SteamMusic GetISteamMusic( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamMusic( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamMusic( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamMusicRemote *
|
||||
public SteamMusicRemote GetISteamMusicRemote( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamMusicRemote( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamMusicRemote( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamNetworking *
|
||||
public SteamNetworking GetISteamNetworking( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamNetworking( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamNetworking( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamParentalSettings *
|
||||
public SteamParentalSettings GetISteamParentalSettings( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamParentalSettings( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamParentalSettings( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamRemoteStorage *
|
||||
public SteamRemoteStorage GetISteamRemoteStorage( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamRemoteStorage( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamRemoteStorage( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamScreenshots *
|
||||
public SteamScreenshots GetISteamScreenshots( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamScreenshots( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamScreenshots( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamUGC *
|
||||
public SteamUGC GetISteamUGC( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamUGC( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamUGC( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamUser *
|
||||
public SteamUser GetISteamUser( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamUser( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamUser( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamUserStats *
|
||||
public SteamUserStats GetISteamUserStats( HSteamUser hSteamUser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamUserStats( hSteamUser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamUserStats( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamUtils *
|
||||
public SteamUtils GetISteamUtils( HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamUtils( hSteamPipe.Value, pchVersion );
|
||||
return new SteamUtils( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// ISteamVideo *
|
||||
public SteamVideo GetISteamVideo( HSteamUser hSteamuser /*HSteamUser*/, HSteamPipe hSteamPipe /*HSteamPipe*/, string pchVersion /*const char **/ )
|
||||
{
|
||||
IntPtr interface_pointer;
|
||||
interface_pointer = platform.ISteamClient_GetISteamVideo( hSteamuser.Value, hSteamPipe.Value, pchVersion );
|
||||
return new SteamVideo( steamworks, interface_pointer );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ReleaseUser( HSteamPipe hSteamPipe /*HSteamPipe*/, HSteamUser hUser /*HSteamUser*/ )
|
||||
{
|
||||
platform.ISteamClient_ReleaseUser( hSteamPipe.Value, hUser.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetLocalIPBinding( uint unIP /*uint32*/, ushort usPort /*uint16*/ )
|
||||
{
|
||||
platform.ISteamClient_SetLocalIPBinding( unIP, usPort );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetWarningMessageHook( IntPtr pFunction /*SteamAPIWarningMessageHook_t*/ )
|
||||
{
|
||||
platform.ISteamClient_SetWarningMessageHook( (IntPtr) pFunction );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamController : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamController( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// void
|
||||
public void ActivateActionSet( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerActionSetHandle_t actionSetHandle /*ControllerActionSetHandle_t*/ )
|
||||
{
|
||||
platform.ISteamController_ActivateActionSet( controllerHandle.Value, actionSetHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ActivateActionSetLayer( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerActionSetHandle_t actionSetLayerHandle /*ControllerActionSetHandle_t*/ )
|
||||
{
|
||||
platform.ISteamController_ActivateActionSetLayer( controllerHandle.Value, actionSetLayerHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void DeactivateActionSetLayer( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerActionSetHandle_t actionSetLayerHandle /*ControllerActionSetHandle_t*/ )
|
||||
{
|
||||
platform.ISteamController_DeactivateActionSetLayer( controllerHandle.Value, actionSetLayerHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void DeactivateAllActionSetLayers( ControllerHandle_t controllerHandle /*ControllerHandle_t*/ )
|
||||
{
|
||||
platform.ISteamController_DeactivateAllActionSetLayers( controllerHandle.Value );
|
||||
}
|
||||
|
||||
// ControllerActionSetHandle_t
|
||||
public ControllerActionSetHandle_t GetActionSetHandle( string pszActionSetName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamController_GetActionSetHandle( pszActionSetName );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetActiveActionSetLayers( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, IntPtr handlesOut /*ControllerActionSetHandle_t **/ )
|
||||
{
|
||||
return platform.ISteamController_GetActiveActionSetLayers( controllerHandle.Value, (IntPtr) handlesOut );
|
||||
}
|
||||
|
||||
// ControllerAnalogActionData_t
|
||||
public ControllerAnalogActionData_t GetAnalogActionData( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerAnalogActionHandle_t analogActionHandle /*ControllerAnalogActionHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamController_GetAnalogActionData( controllerHandle.Value, analogActionHandle.Value );
|
||||
}
|
||||
|
||||
// ControllerAnalogActionHandle_t
|
||||
public ControllerAnalogActionHandle_t GetAnalogActionHandle( string pszActionName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamController_GetAnalogActionHandle( pszActionName );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetAnalogActionOrigins( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerActionSetHandle_t actionSetHandle /*ControllerActionSetHandle_t*/, ControllerAnalogActionHandle_t analogActionHandle /*ControllerAnalogActionHandle_t*/, out ControllerActionOrigin originsOut /*EControllerActionOrigin **/ )
|
||||
{
|
||||
return platform.ISteamController_GetAnalogActionOrigins( controllerHandle.Value, actionSetHandle.Value, analogActionHandle.Value, out originsOut );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetConnectedControllers( IntPtr handlesOut /*ControllerHandle_t **/ )
|
||||
{
|
||||
return platform.ISteamController_GetConnectedControllers( (IntPtr) handlesOut );
|
||||
}
|
||||
|
||||
// ControllerHandle_t
|
||||
public ControllerHandle_t GetControllerForGamepadIndex( int nIndex /*int*/ )
|
||||
{
|
||||
return platform.ISteamController_GetControllerForGamepadIndex( nIndex );
|
||||
}
|
||||
|
||||
// ControllerActionSetHandle_t
|
||||
public ControllerActionSetHandle_t GetCurrentActionSet( ControllerHandle_t controllerHandle /*ControllerHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamController_GetCurrentActionSet( controllerHandle.Value );
|
||||
}
|
||||
|
||||
// ControllerDigitalActionData_t
|
||||
public ControllerDigitalActionData_t GetDigitalActionData( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerDigitalActionHandle_t digitalActionHandle /*ControllerDigitalActionHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamController_GetDigitalActionData( controllerHandle.Value, digitalActionHandle.Value );
|
||||
}
|
||||
|
||||
// ControllerDigitalActionHandle_t
|
||||
public ControllerDigitalActionHandle_t GetDigitalActionHandle( string pszActionName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamController_GetDigitalActionHandle( pszActionName );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetDigitalActionOrigins( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerActionSetHandle_t actionSetHandle /*ControllerActionSetHandle_t*/, ControllerDigitalActionHandle_t digitalActionHandle /*ControllerDigitalActionHandle_t*/, out ControllerActionOrigin originsOut /*EControllerActionOrigin **/ )
|
||||
{
|
||||
return platform.ISteamController_GetDigitalActionOrigins( controllerHandle.Value, actionSetHandle.Value, digitalActionHandle.Value, out originsOut );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetGamepadIndexForController( ControllerHandle_t ulControllerHandle /*ControllerHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamController_GetGamepadIndexForController( ulControllerHandle.Value );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetGlyphForActionOrigin( ControllerActionOrigin eOrigin /*EControllerActionOrigin*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamController_GetGlyphForActionOrigin( eOrigin );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// SteamInputType
|
||||
public SteamInputType GetInputTypeForHandle( ControllerHandle_t controllerHandle /*ControllerHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamController_GetInputTypeForHandle( controllerHandle.Value );
|
||||
}
|
||||
|
||||
// ControllerMotionData_t
|
||||
public ControllerMotionData_t GetMotionData( ControllerHandle_t controllerHandle /*ControllerHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamController_GetMotionData( controllerHandle.Value );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetStringForActionOrigin( ControllerActionOrigin eOrigin /*EControllerActionOrigin*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamController_GetStringForActionOrigin( eOrigin );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool Init()
|
||||
{
|
||||
return platform.ISteamController_Init();
|
||||
}
|
||||
|
||||
// void
|
||||
public void RunFrame()
|
||||
{
|
||||
platform.ISteamController_RunFrame();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetLEDColor( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, byte nColorR /*uint8*/, byte nColorG /*uint8*/, byte nColorB /*uint8*/, uint nFlags /*unsigned int*/ )
|
||||
{
|
||||
platform.ISteamController_SetLEDColor( controllerHandle.Value, nColorR, nColorG, nColorB, nFlags );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ShowAnalogActionOrigins( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerAnalogActionHandle_t analogActionHandle /*ControllerAnalogActionHandle_t*/, float flScale /*float*/, float flXPosition /*float*/, float flYPosition /*float*/ )
|
||||
{
|
||||
return platform.ISteamController_ShowAnalogActionOrigins( controllerHandle.Value, analogActionHandle.Value, flScale, flXPosition, flYPosition );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ShowBindingPanel( ControllerHandle_t controllerHandle /*ControllerHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamController_ShowBindingPanel( controllerHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ShowDigitalActionOrigins( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerDigitalActionHandle_t digitalActionHandle /*ControllerDigitalActionHandle_t*/, float flScale /*float*/, float flXPosition /*float*/, float flYPosition /*float*/ )
|
||||
{
|
||||
return platform.ISteamController_ShowDigitalActionOrigins( controllerHandle.Value, digitalActionHandle.Value, flScale, flXPosition, flYPosition );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool Shutdown()
|
||||
{
|
||||
return platform.ISteamController_Shutdown();
|
||||
}
|
||||
|
||||
// void
|
||||
public void StopAnalogActionMomentum( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ControllerAnalogActionHandle_t eAction /*ControllerAnalogActionHandle_t*/ )
|
||||
{
|
||||
platform.ISteamController_StopAnalogActionMomentum( controllerHandle.Value, eAction.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void TriggerHapticPulse( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, SteamControllerPad eTargetPad /*ESteamControllerPad*/, ushort usDurationMicroSec /*unsigned short*/ )
|
||||
{
|
||||
platform.ISteamController_TriggerHapticPulse( controllerHandle.Value, eTargetPad, usDurationMicroSec );
|
||||
}
|
||||
|
||||
// void
|
||||
public void TriggerRepeatedHapticPulse( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, SteamControllerPad eTargetPad /*ESteamControllerPad*/, ushort usDurationMicroSec /*unsigned short*/, ushort usOffMicroSec /*unsigned short*/, ushort unRepeat /*unsigned short*/, uint nFlags /*unsigned int*/ )
|
||||
{
|
||||
platform.ISteamController_TriggerRepeatedHapticPulse( controllerHandle.Value, eTargetPad, usDurationMicroSec, usOffMicroSec, unRepeat, nFlags );
|
||||
}
|
||||
|
||||
// void
|
||||
public void TriggerVibration( ControllerHandle_t controllerHandle /*ControllerHandle_t*/, ushort usLeftSpeed /*unsigned short*/, ushort usRightSpeed /*unsigned short*/ )
|
||||
{
|
||||
platform.ISteamController_TriggerVibration( controllerHandle.Value, usLeftSpeed, usRightSpeed );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,542 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamFriends : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamFriends( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// void
|
||||
public void ActivateGameOverlay( string pchDialog /*const char **/ )
|
||||
{
|
||||
platform.ISteamFriends_ActivateGameOverlay( pchDialog );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ActivateGameOverlayInviteDialog( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamFriends_ActivateGameOverlayInviteDialog( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ActivateGameOverlayToStore( AppId_t nAppID /*AppId_t*/, OverlayToStoreFlag eFlag /*EOverlayToStoreFlag*/ )
|
||||
{
|
||||
platform.ISteamFriends_ActivateGameOverlayToStore( nAppID.Value, eFlag );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ActivateGameOverlayToUser( string pchDialog /*const char **/, CSteamID steamID /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamFriends_ActivateGameOverlayToUser( pchDialog, steamID.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ActivateGameOverlayToWebPage( string pchURL /*const char **/ )
|
||||
{
|
||||
platform.ISteamFriends_ActivateGameOverlayToWebPage( pchURL );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ClearRichPresence()
|
||||
{
|
||||
platform.ISteamFriends_ClearRichPresence();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool CloseClanChatWindowInSteam( CSteamID steamIDClanChat /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_CloseClanChatWindowInSteam( steamIDClanChat.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public SteamAPICall_t DownloadClanActivityCounts( IntPtr psteamIDClans /*class CSteamID **/, int cClansToRequest /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_DownloadClanActivityCounts( (IntPtr) psteamIDClans, cClansToRequest );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle EnumerateFollowingList( uint unStartIndex /*uint32*/, Action<FriendsEnumerateFollowingList_t, bool> CallbackFunction = null /*Action<FriendsEnumerateFollowingList_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamFriends_EnumerateFollowingList( unStartIndex );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return FriendsEnumerateFollowingList_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetChatMemberByIndex( CSteamID steamIDClan /*class CSteamID*/, int iUser /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetChatMemberByIndex( steamIDClan.Value, iUser );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetClanActivityCounts( CSteamID steamIDClan /*class CSteamID*/, out int pnOnline /*int **/, out int pnInGame /*int **/, out int pnChatting /*int **/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetClanActivityCounts( steamIDClan.Value, out pnOnline, out pnInGame, out pnChatting );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetClanByIndex( int iClan /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetClanByIndex( iClan );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetClanChatMemberCount( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetClanChatMemberCount( steamIDClan.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetClanChatMessage( CSteamID steamIDClanChat /*class CSteamID*/, int iMessage /*int*/, IntPtr prgchText /*void **/, int cchTextMax /*int*/, out ChatEntryType peChatEntryType /*EChatEntryType **/, out CSteamID psteamidChatter /*class CSteamID **/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetClanChatMessage( steamIDClanChat.Value, iMessage, (IntPtr) prgchText, cchTextMax, out peChatEntryType, out psteamidChatter.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetClanCount()
|
||||
{
|
||||
return platform.ISteamFriends_GetClanCount();
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetClanName( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetClanName( steamIDClan.Value );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetClanOfficerByIndex( CSteamID steamIDClan /*class CSteamID*/, int iOfficer /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetClanOfficerByIndex( steamIDClan.Value, iOfficer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetClanOfficerCount( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetClanOfficerCount( steamIDClan.Value );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetClanOwner( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetClanOwner( steamIDClan.Value );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetClanTag( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetClanTag( steamIDClan.Value );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetCoplayFriend( int iCoplayFriend /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetCoplayFriend( iCoplayFriend );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetCoplayFriendCount()
|
||||
{
|
||||
return platform.ISteamFriends_GetCoplayFriendCount();
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetFollowerCount( CSteamID steamID /*class CSteamID*/, Action<FriendsGetFollowerCount_t, bool> CallbackFunction = null /*Action<FriendsGetFollowerCount_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamFriends_GetFollowerCount( steamID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return FriendsGetFollowerCount_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetFriendByIndex( int iFriend /*int*/, int iFriendFlags /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendByIndex( iFriend, iFriendFlags );
|
||||
}
|
||||
|
||||
// AppId_t
|
||||
public AppId_t GetFriendCoplayGame( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendCoplayGame( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendCoplayTime( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendCoplayTime( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendCount( int iFriendFlags /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendCount( iFriendFlags );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendCountFromSource( CSteamID steamIDSource /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendCountFromSource( steamIDSource.Value );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetFriendFromSourceByIndex( CSteamID steamIDSource /*class CSteamID*/, int iFriend /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendFromSourceByIndex( steamIDSource.Value, iFriend );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetFriendGamePlayed( CSteamID steamIDFriend /*class CSteamID*/, ref FriendGameInfo_t pFriendGameInfo /*struct FriendGameInfo_t **/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendGamePlayed( steamIDFriend.Value, ref pFriendGameInfo );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendMessage( CSteamID steamIDFriend /*class CSteamID*/, int iMessageID /*int*/, IntPtr pvData /*void **/, int cubData /*int*/, out ChatEntryType peChatEntryType /*EChatEntryType **/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendMessage( steamIDFriend.Value, iMessageID, (IntPtr) pvData, cubData, out peChatEntryType );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetFriendPersonaName( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetFriendPersonaName( steamIDFriend.Value );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetFriendPersonaNameHistory( CSteamID steamIDFriend /*class CSteamID*/, int iPersonaName /*int*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetFriendPersonaNameHistory( steamIDFriend.Value, iPersonaName );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// PersonaState
|
||||
public PersonaState GetFriendPersonaState( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendPersonaState( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// FriendRelationship
|
||||
public FriendRelationship GetFriendRelationship( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendRelationship( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetFriendRichPresence( CSteamID steamIDFriend /*class CSteamID*/, string pchKey /*const char **/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetFriendRichPresence( steamIDFriend.Value, pchKey );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetFriendRichPresenceKeyByIndex( CSteamID steamIDFriend /*class CSteamID*/, int iKey /*int*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetFriendRichPresenceKeyByIndex( steamIDFriend.Value, iKey );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendRichPresenceKeyCount( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendRichPresenceKeyCount( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendsGroupCount()
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendsGroupCount();
|
||||
}
|
||||
|
||||
// FriendsGroupID_t
|
||||
public FriendsGroupID_t GetFriendsGroupIDByIndex( int iFG /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendsGroupIDByIndex( iFG );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendsGroupMembersCount( FriendsGroupID_t friendsGroupID /*FriendsGroupID_t*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendsGroupMembersCount( friendsGroupID.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void GetFriendsGroupMembersList( FriendsGroupID_t friendsGroupID /*FriendsGroupID_t*/, IntPtr pOutSteamIDMembers /*class CSteamID **/, int nMembersCount /*int*/ )
|
||||
{
|
||||
platform.ISteamFriends_GetFriendsGroupMembersList( friendsGroupID.Value, (IntPtr) pOutSteamIDMembers, nMembersCount );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetFriendsGroupName( FriendsGroupID_t friendsGroupID /*FriendsGroupID_t*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetFriendsGroupName( friendsGroupID.Value );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFriendSteamLevel( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetFriendSteamLevel( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetLargeFriendAvatar( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetLargeFriendAvatar( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetMediumFriendAvatar( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetMediumFriendAvatar( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetPersonaName()
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetPersonaName();
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// PersonaState
|
||||
public PersonaState GetPersonaState()
|
||||
{
|
||||
return platform.ISteamFriends_GetPersonaState();
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetPlayerNickname( CSteamID steamIDPlayer /*class CSteamID*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamFriends_GetPlayerNickname( steamIDPlayer.Value );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetSmallFriendAvatar( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_GetSmallFriendAvatar( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetUserRestrictions()
|
||||
{
|
||||
return platform.ISteamFriends_GetUserRestrictions();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool HasFriend( CSteamID steamIDFriend /*class CSteamID*/, int iFriendFlags /*int*/ )
|
||||
{
|
||||
return platform.ISteamFriends_HasFriend( steamIDFriend.Value, iFriendFlags );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool InviteUserToGame( CSteamID steamIDFriend /*class CSteamID*/, string pchConnectString /*const char **/ )
|
||||
{
|
||||
return platform.ISteamFriends_InviteUserToGame( steamIDFriend.Value, pchConnectString );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsClanChatAdmin( CSteamID steamIDClanChat /*class CSteamID*/, CSteamID steamIDUser /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_IsClanChatAdmin( steamIDClanChat.Value, steamIDUser.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsClanChatWindowOpenInSteam( CSteamID steamIDClanChat /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_IsClanChatWindowOpenInSteam( steamIDClanChat.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsClanOfficialGameGroup( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_IsClanOfficialGameGroup( steamIDClan.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsClanPublic( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_IsClanPublic( steamIDClan.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle IsFollowing( CSteamID steamID /*class CSteamID*/, Action<FriendsIsFollowing_t, bool> CallbackFunction = null /*Action<FriendsIsFollowing_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamFriends_IsFollowing( steamID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return FriendsIsFollowing_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsUserInSource( CSteamID steamIDUser /*class CSteamID*/, CSteamID steamIDSource /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_IsUserInSource( steamIDUser.Value, steamIDSource.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle JoinClanChatRoom( CSteamID steamIDClan /*class CSteamID*/, Action<JoinClanChatRoomCompletionResult_t, bool> CallbackFunction = null /*Action<JoinClanChatRoomCompletionResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamFriends_JoinClanChatRoom( steamIDClan.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return JoinClanChatRoomCompletionResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool LeaveClanChatRoom( CSteamID steamIDClan /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_LeaveClanChatRoom( steamIDClan.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool OpenClanChatWindowInSteam( CSteamID steamIDClanChat /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamFriends_OpenClanChatWindowInSteam( steamIDClanChat.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ReplyToFriendMessage( CSteamID steamIDFriend /*class CSteamID*/, string pchMsgToSend /*const char **/ )
|
||||
{
|
||||
return platform.ISteamFriends_ReplyToFriendMessage( steamIDFriend.Value, pchMsgToSend );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestClanOfficerList( CSteamID steamIDClan /*class CSteamID*/, Action<ClanOfficerListResponse_t, bool> CallbackFunction = null /*Action<ClanOfficerListResponse_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamFriends_RequestClanOfficerList( steamIDClan.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return ClanOfficerListResponse_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void RequestFriendRichPresence( CSteamID steamIDFriend /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamFriends_RequestFriendRichPresence( steamIDFriend.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RequestUserInformation( CSteamID steamIDUser /*class CSteamID*/, bool bRequireNameOnly /*bool*/ )
|
||||
{
|
||||
return platform.ISteamFriends_RequestUserInformation( steamIDUser.Value, bRequireNameOnly );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SendClanChatMessage( CSteamID steamIDClanChat /*class CSteamID*/, string pchText /*const char **/ )
|
||||
{
|
||||
return platform.ISteamFriends_SendClanChatMessage( steamIDClanChat.Value, pchText );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetInGameVoiceSpeaking( CSteamID steamIDUser /*class CSteamID*/, bool bSpeaking /*bool*/ )
|
||||
{
|
||||
platform.ISteamFriends_SetInGameVoiceSpeaking( steamIDUser.Value, bSpeaking );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetListenForFriendsMessages( bool bInterceptEnabled /*bool*/ )
|
||||
{
|
||||
return platform.ISteamFriends_SetListenForFriendsMessages( bInterceptEnabled );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle SetPersonaName( string pchPersonaName /*const char **/, Action<SetPersonaNameResponse_t, bool> CallbackFunction = null /*Action<SetPersonaNameResponse_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamFriends_SetPersonaName( pchPersonaName );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return SetPersonaNameResponse_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetPlayedWith( CSteamID steamIDUserPlayedWith /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamFriends_SetPlayedWith( steamIDUserPlayedWith.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetRichPresence( string pchKey /*const char **/, string pchValue /*const char **/ )
|
||||
{
|
||||
return platform.ISteamFriends_SetRichPresence( pchKey, pchValue );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamGameServer : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamGameServer( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle AssociateWithClan( CSteamID steamIDClan /*class CSteamID*/, Action<AssociateWithClanResult_t, bool> CallbackFunction = null /*Action<AssociateWithClanResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamGameServer_AssociateWithClan( steamIDClan.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return AssociateWithClanResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// BeginAuthSessionResult
|
||||
public BeginAuthSessionResult BeginAuthSession( IntPtr pAuthTicket /*const void **/, int cbAuthTicket /*int*/, CSteamID steamID /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamGameServer_BeginAuthSession( (IntPtr) pAuthTicket, cbAuthTicket, steamID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BLoggedOn()
|
||||
{
|
||||
return platform.ISteamGameServer_BLoggedOn();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BSecure()
|
||||
{
|
||||
return platform.ISteamGameServer_BSecure();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BUpdateUserData( CSteamID steamIDUser /*class CSteamID*/, string pchPlayerName /*const char **/, uint uScore /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamGameServer_BUpdateUserData( steamIDUser.Value, pchPlayerName, uScore );
|
||||
}
|
||||
|
||||
// void
|
||||
public void CancelAuthTicket( HAuthTicket hAuthTicket /*HAuthTicket*/ )
|
||||
{
|
||||
platform.ISteamGameServer_CancelAuthTicket( hAuthTicket.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ClearAllKeyValues()
|
||||
{
|
||||
platform.ISteamGameServer_ClearAllKeyValues();
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle ComputeNewPlayerCompatibility( CSteamID steamIDNewPlayer /*class CSteamID*/, Action<ComputeNewPlayerCompatibilityResult_t, bool> CallbackFunction = null /*Action<ComputeNewPlayerCompatibilityResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamGameServer_ComputeNewPlayerCompatibility( steamIDNewPlayer.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return ComputeNewPlayerCompatibilityResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong CreateUnauthenticatedUserConnection()
|
||||
{
|
||||
return platform.ISteamGameServer_CreateUnauthenticatedUserConnection();
|
||||
}
|
||||
|
||||
// void
|
||||
public void EnableHeartbeats( bool bActive /*bool*/ )
|
||||
{
|
||||
platform.ISteamGameServer_EnableHeartbeats( bActive );
|
||||
}
|
||||
|
||||
// void
|
||||
public void EndAuthSession( CSteamID steamID /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamGameServer_EndAuthSession( steamID.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ForceHeartbeat()
|
||||
{
|
||||
platform.ISteamGameServer_ForceHeartbeat();
|
||||
}
|
||||
|
||||
// HAuthTicket
|
||||
public HAuthTicket GetAuthSessionTicket( IntPtr pTicket /*void **/, int cbMaxTicket /*int*/, out uint pcbTicket /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamGameServer_GetAuthSessionTicket( (IntPtr) pTicket, cbMaxTicket, out pcbTicket );
|
||||
}
|
||||
|
||||
// void
|
||||
public void GetGameplayStats()
|
||||
{
|
||||
platform.ISteamGameServer_GetGameplayStats();
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetNextOutgoingPacket( IntPtr pOut /*void **/, int cbMaxOut /*int*/, out uint pNetAdr /*uint32 **/, out ushort pPort /*uint16 **/ )
|
||||
{
|
||||
return platform.ISteamGameServer_GetNextOutgoingPacket( (IntPtr) pOut, cbMaxOut, out pNetAdr, out pPort );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetPublicIP()
|
||||
{
|
||||
return platform.ISteamGameServer_GetPublicIP();
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetServerReputation( Action<GSReputation_t, bool> CallbackFunction = null /*Action<GSReputation_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamGameServer_GetServerReputation();
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return GSReputation_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetSteamID()
|
||||
{
|
||||
return platform.ISteamGameServer_GetSteamID();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool HandleIncomingPacket( IntPtr pData /*const void **/, int cbData /*int*/, uint srcIP /*uint32*/, ushort srcPort /*uint16*/ )
|
||||
{
|
||||
return platform.ISteamGameServer_HandleIncomingPacket( (IntPtr) pData, cbData, srcIP, srcPort );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool InitGameServer( uint unIP /*uint32*/, ushort usGamePort /*uint16*/, ushort usQueryPort /*uint16*/, uint unFlags /*uint32*/, AppId_t nGameAppId /*AppId_t*/, string pchVersionString /*const char **/ )
|
||||
{
|
||||
return platform.ISteamGameServer_InitGameServer( unIP, usGamePort, usQueryPort, unFlags, nGameAppId.Value, pchVersionString );
|
||||
}
|
||||
|
||||
// void
|
||||
public void LogOff()
|
||||
{
|
||||
platform.ISteamGameServer_LogOff();
|
||||
}
|
||||
|
||||
// void
|
||||
public void LogOn( string pszToken /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_LogOn( pszToken );
|
||||
}
|
||||
|
||||
// void
|
||||
public void LogOnAnonymous()
|
||||
{
|
||||
platform.ISteamGameServer_LogOnAnonymous();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RequestUserGroupStatus( CSteamID steamIDUser /*class CSteamID*/, CSteamID steamIDGroup /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamGameServer_RequestUserGroupStatus( steamIDUser.Value, steamIDGroup.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SendUserConnectAndAuthenticate( uint unIPClient /*uint32*/, IntPtr pvAuthBlob /*const void **/, uint cubAuthBlobSize /*uint32*/, out CSteamID pSteamIDUser /*class CSteamID **/ )
|
||||
{
|
||||
return platform.ISteamGameServer_SendUserConnectAndAuthenticate( unIPClient, (IntPtr) pvAuthBlob, cubAuthBlobSize, out pSteamIDUser.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SendUserDisconnect( CSteamID steamIDUser /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamGameServer_SendUserDisconnect( steamIDUser.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetBotPlayerCount( int cBotplayers /*int*/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetBotPlayerCount( cBotplayers );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetDedicatedServer( bool bDedicated /*bool*/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetDedicatedServer( bDedicated );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetGameData( string pchGameData /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetGameData( pchGameData );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetGameDescription( string pszGameDescription /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetGameDescription( pszGameDescription );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetGameTags( string pchGameTags /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetGameTags( pchGameTags );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetHeartbeatInterval( int iHeartbeatInterval /*int*/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetHeartbeatInterval( iHeartbeatInterval );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetKeyValue( string pKey /*const char **/, string pValue /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetKeyValue( pKey, pValue );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetMapName( string pszMapName /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetMapName( pszMapName );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetMaxPlayerCount( int cPlayersMax /*int*/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetMaxPlayerCount( cPlayersMax );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetModDir( string pszModDir /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetModDir( pszModDir );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetPasswordProtected( bool bPasswordProtected /*bool*/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetPasswordProtected( bPasswordProtected );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetProduct( string pszProduct /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetProduct( pszProduct );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetRegion( string pszRegion /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetRegion( pszRegion );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetServerName( string pszServerName /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetServerName( pszServerName );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetSpectatorPort( ushort unSpectatorPort /*uint16*/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetSpectatorPort( unSpectatorPort );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetSpectatorServerName( string pszSpectatorServerName /*const char **/ )
|
||||
{
|
||||
platform.ISteamGameServer_SetSpectatorServerName( pszSpectatorServerName );
|
||||
}
|
||||
|
||||
// UserHasLicenseForAppResult
|
||||
public UserHasLicenseForAppResult UserHasLicenseForApp( CSteamID steamID /*class CSteamID*/, AppId_t appID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamGameServer_UserHasLicenseForApp( steamID.Value, appID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool WasRestartRequested()
|
||||
{
|
||||
return platform.ISteamGameServer_WasRestartRequested();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamGameServerStats : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamGameServerStats( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ClearUserAchievement( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_ClearUserAchievement( steamIDUser.Value, pchName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUserAchievement( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, ref bool pbAchieved /*bool **/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_GetUserAchievement( steamIDUser.Value, pchName, ref pbAchieved );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUserStat( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, out int pData /*int32 **/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_GetUserStat( steamIDUser.Value, pchName, out pData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUserStat0( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, out float pData /*float **/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_GetUserStat0( steamIDUser.Value, pchName, out pData );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestUserStats( CSteamID steamIDUser /*class CSteamID*/, Action<GSStatsReceived_t, bool> CallbackFunction = null /*Action<GSStatsReceived_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamGameServerStats_RequestUserStats( steamIDUser.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return GSStatsReceived_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetUserAchievement( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_SetUserAchievement( steamIDUser.Value, pchName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetUserStat( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, int nData /*int32*/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_SetUserStat( steamIDUser.Value, pchName, nData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetUserStat0( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, float fData /*float*/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_SetUserStat0( steamIDUser.Value, pchName, fData );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle StoreUserStats( CSteamID steamIDUser /*class CSteamID*/, Action<GSStatsStored_t, bool> CallbackFunction = null /*Action<GSStatsStored_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamGameServerStats_StoreUserStats( steamIDUser.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return GSStatsStored_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateUserAvgRateStat( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, float flCountThisSession /*float*/, double dSessionLength /*double*/ )
|
||||
{
|
||||
return platform.ISteamGameServerStats_UpdateUserAvgRateStat( steamIDUser.Value, pchName, flCountThisSession, dSessionLength );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamHTMLSurface : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamHTMLSurface( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddHeader( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, string pchKey /*const char **/, string pchValue /*const char **/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_AddHeader( unBrowserHandle.Value, pchKey, pchValue );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AllowStartRequest( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, bool bAllowed /*bool*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_AllowStartRequest( unBrowserHandle.Value, bAllowed );
|
||||
}
|
||||
|
||||
// void
|
||||
public void CopyToClipboard( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_CopyToClipboard( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle CreateBrowser( string pchUserAgent /*const char **/, string pchUserCSS /*const char **/, Action<HTML_BrowserReady_t, bool> CallbackFunction = null /*Action<HTML_BrowserReady_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamHTMLSurface_CreateBrowser( pchUserAgent, pchUserCSS );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return HTML_BrowserReady_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void DestructISteamHTMLSurface()
|
||||
{
|
||||
platform.ISteamHTMLSurface_DestructISteamHTMLSurface();
|
||||
}
|
||||
|
||||
// void
|
||||
public void ExecuteJavascript( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, string pchScript /*const char **/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_ExecuteJavascript( unBrowserHandle.Value, pchScript );
|
||||
}
|
||||
|
||||
// void
|
||||
public void Find( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, string pchSearchStr /*const char **/, bool bCurrentlyInFind /*bool*/, bool bReverse /*bool*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_Find( unBrowserHandle.Value, pchSearchStr, bCurrentlyInFind, bReverse );
|
||||
}
|
||||
|
||||
// void
|
||||
public void GetLinkAtPosition( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, int x /*int*/, int y /*int*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_GetLinkAtPosition( unBrowserHandle.Value, x, y );
|
||||
}
|
||||
|
||||
// void
|
||||
public void GoBack( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_GoBack( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void GoForward( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_GoForward( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool Init()
|
||||
{
|
||||
return platform.ISteamHTMLSurface_Init();
|
||||
}
|
||||
|
||||
// void
|
||||
public void JSDialogResponse( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, bool bResult /*bool*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_JSDialogResponse( unBrowserHandle.Value, bResult );
|
||||
}
|
||||
|
||||
// void
|
||||
public void KeyChar( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, uint cUnicodeChar /*uint32*/, HTMLKeyModifiers eHTMLKeyModifiers /*ISteamHTMLSurface::EHTMLKeyModifiers*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_KeyChar( unBrowserHandle.Value, cUnicodeChar, eHTMLKeyModifiers );
|
||||
}
|
||||
|
||||
// void
|
||||
public void KeyDown( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, uint nNativeKeyCode /*uint32*/, HTMLKeyModifiers eHTMLKeyModifiers /*ISteamHTMLSurface::EHTMLKeyModifiers*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_KeyDown( unBrowserHandle.Value, nNativeKeyCode, eHTMLKeyModifiers );
|
||||
}
|
||||
|
||||
// void
|
||||
public void KeyUp( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, uint nNativeKeyCode /*uint32*/, HTMLKeyModifiers eHTMLKeyModifiers /*ISteamHTMLSurface::EHTMLKeyModifiers*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_KeyUp( unBrowserHandle.Value, nNativeKeyCode, eHTMLKeyModifiers );
|
||||
}
|
||||
|
||||
// void
|
||||
public void LoadURL( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, string pchURL /*const char **/, string pchPostData /*const char **/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_LoadURL( unBrowserHandle.Value, pchURL, pchPostData );
|
||||
}
|
||||
|
||||
// void
|
||||
public void MouseDoubleClick( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, HTMLMouseButton eMouseButton /*ISteamHTMLSurface::EHTMLMouseButton*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_MouseDoubleClick( unBrowserHandle.Value, eMouseButton );
|
||||
}
|
||||
|
||||
// void
|
||||
public void MouseDown( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, HTMLMouseButton eMouseButton /*ISteamHTMLSurface::EHTMLMouseButton*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_MouseDown( unBrowserHandle.Value, eMouseButton );
|
||||
}
|
||||
|
||||
// void
|
||||
public void MouseMove( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, int x /*int*/, int y /*int*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_MouseMove( unBrowserHandle.Value, x, y );
|
||||
}
|
||||
|
||||
// void
|
||||
public void MouseUp( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, HTMLMouseButton eMouseButton /*ISteamHTMLSurface::EHTMLMouseButton*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_MouseUp( unBrowserHandle.Value, eMouseButton );
|
||||
}
|
||||
|
||||
// void
|
||||
public void MouseWheel( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, int nDelta /*int32*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_MouseWheel( unBrowserHandle.Value, nDelta );
|
||||
}
|
||||
|
||||
// void
|
||||
public void PasteFromClipboard( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_PasteFromClipboard( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void Reload( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_Reload( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void RemoveBrowser( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_RemoveBrowser( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetBackgroundMode( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, bool bBackgroundMode /*bool*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetBackgroundMode( unBrowserHandle.Value, bBackgroundMode );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetCookie( string pchHostname /*const char **/, string pchKey /*const char **/, string pchValue /*const char **/, string pchPath /*const char **/, RTime32 nExpires /*RTime32*/, bool bSecure /*bool*/, bool bHTTPOnly /*bool*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetCookie( pchHostname, pchKey, pchValue, pchPath, nExpires.Value, bSecure, bHTTPOnly );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetDPIScalingFactor( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, float flDPIScaling /*float*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetDPIScalingFactor( unBrowserHandle.Value, flDPIScaling );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetHorizontalScroll( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, uint nAbsolutePixelScroll /*uint32*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetHorizontalScroll( unBrowserHandle.Value, nAbsolutePixelScroll );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetKeyFocus( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, bool bHasKeyFocus /*bool*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetKeyFocus( unBrowserHandle.Value, bHasKeyFocus );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetPageScaleFactor( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, float flZoom /*float*/, int nPointX /*int*/, int nPointY /*int*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetPageScaleFactor( unBrowserHandle.Value, flZoom, nPointX, nPointY );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetSize( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, uint unWidth /*uint32*/, uint unHeight /*uint32*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetSize( unBrowserHandle.Value, unWidth, unHeight );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetVerticalScroll( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/, uint nAbsolutePixelScroll /*uint32*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_SetVerticalScroll( unBrowserHandle.Value, nAbsolutePixelScroll );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool Shutdown()
|
||||
{
|
||||
return platform.ISteamHTMLSurface_Shutdown();
|
||||
}
|
||||
|
||||
// void
|
||||
public void StopFind( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_StopFind( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void StopLoad( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_StopLoad( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ViewSource( HHTMLBrowser unBrowserHandle /*HHTMLBrowser*/ )
|
||||
{
|
||||
platform.ISteamHTMLSurface_ViewSource( unBrowserHandle.Value );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamHTTP : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamHTTP( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// HTTPCookieContainerHandle
|
||||
public HTTPCookieContainerHandle CreateCookieContainer( bool bAllowResponsesToModify /*bool*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_CreateCookieContainer( bAllowResponsesToModify );
|
||||
}
|
||||
|
||||
// HTTPRequestHandle
|
||||
public HTTPRequestHandle CreateHTTPRequest( HTTPMethod eHTTPRequestMethod /*EHTTPMethod*/, string pchAbsoluteURL /*const char **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_CreateHTTPRequest( eHTTPRequestMethod, pchAbsoluteURL );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool DeferHTTPRequest( HTTPRequestHandle hRequest /*HTTPRequestHandle*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_DeferHTTPRequest( hRequest.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetHTTPDownloadProgressPct( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, out float pflPercentOut /*float **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_GetHTTPDownloadProgressPct( hRequest.Value, out pflPercentOut );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetHTTPRequestWasTimedOut( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, ref bool pbWasTimedOut /*bool **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_GetHTTPRequestWasTimedOut( hRequest.Value, ref pbWasTimedOut );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetHTTPResponseBodyData( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, out byte pBodyDataBuffer /*uint8 **/, uint unBufferSize /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_GetHTTPResponseBodyData( hRequest.Value, out pBodyDataBuffer, unBufferSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetHTTPResponseBodySize( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, out uint unBodySize /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_GetHTTPResponseBodySize( hRequest.Value, out unBodySize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetHTTPResponseHeaderSize( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, string pchHeaderName /*const char **/, out uint unResponseHeaderSize /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_GetHTTPResponseHeaderSize( hRequest.Value, pchHeaderName, out unResponseHeaderSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetHTTPResponseHeaderValue( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, string pchHeaderName /*const char **/, out byte pHeaderValueBuffer /*uint8 **/, uint unBufferSize /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_GetHTTPResponseHeaderValue( hRequest.Value, pchHeaderName, out pHeaderValueBuffer, unBufferSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetHTTPStreamingResponseBodyData( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, uint cOffset /*uint32*/, out byte pBodyDataBuffer /*uint8 **/, uint unBufferSize /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_GetHTTPStreamingResponseBodyData( hRequest.Value, cOffset, out pBodyDataBuffer, unBufferSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool PrioritizeHTTPRequest( HTTPRequestHandle hRequest /*HTTPRequestHandle*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_PrioritizeHTTPRequest( hRequest.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ReleaseCookieContainer( HTTPCookieContainerHandle hCookieContainer /*HTTPCookieContainerHandle*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_ReleaseCookieContainer( hCookieContainer.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ReleaseHTTPRequest( HTTPRequestHandle hRequest /*HTTPRequestHandle*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_ReleaseHTTPRequest( hRequest.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SendHTTPRequest( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, ref SteamAPICall_t pCallHandle /*SteamAPICall_t **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SendHTTPRequest( hRequest.Value, ref pCallHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SendHTTPRequestAndStreamResponse( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, ref SteamAPICall_t pCallHandle /*SteamAPICall_t **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SendHTTPRequestAndStreamResponse( hRequest.Value, ref pCallHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetCookie( HTTPCookieContainerHandle hCookieContainer /*HTTPCookieContainerHandle*/, string pchHost /*const char **/, string pchUrl /*const char **/, string pchCookie /*const char **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetCookie( hCookieContainer.Value, pchHost, pchUrl, pchCookie );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestAbsoluteTimeoutMS( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, uint unMilliseconds /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestAbsoluteTimeoutMS( hRequest.Value, unMilliseconds );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestContextValue( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, ulong ulContextValue /*uint64*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestContextValue( hRequest.Value, ulContextValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestCookieContainer( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, HTTPCookieContainerHandle hCookieContainer /*HTTPCookieContainerHandle*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestCookieContainer( hRequest.Value, hCookieContainer.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestGetOrPostParameter( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, string pchParamName /*const char **/, string pchParamValue /*const char **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestGetOrPostParameter( hRequest.Value, pchParamName, pchParamValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestHeaderValue( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, string pchHeaderName /*const char **/, string pchHeaderValue /*const char **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestHeaderValue( hRequest.Value, pchHeaderName, pchHeaderValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestNetworkActivityTimeout( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, uint unTimeoutSeconds /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestNetworkActivityTimeout( hRequest.Value, unTimeoutSeconds );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestRawPostBody( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, string pchContentType /*const char **/, out byte pubBody /*uint8 **/, uint unBodyLen /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestRawPostBody( hRequest.Value, pchContentType, out pubBody, unBodyLen );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestRequiresVerifiedCertificate( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, bool bRequireVerifiedCertificate /*bool*/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestRequiresVerifiedCertificate( hRequest.Value, bRequireVerifiedCertificate );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetHTTPRequestUserAgentInfo( HTTPRequestHandle hRequest /*HTTPRequestHandle*/, string pchUserAgentInfo /*const char **/ )
|
||||
{
|
||||
return platform.ISteamHTTP_SetHTTPRequestUserAgentInfo( hRequest.Value, pchUserAgentInfo );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamInventory : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamInventory( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddPromoItem( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemDef_t itemDef /*SteamItemDef_t*/ )
|
||||
{
|
||||
return platform.ISteamInventory_AddPromoItem( ref pResultHandle.Value, itemDef.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddPromoItems( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemDef_t[] pArrayItemDefs /*const SteamItemDef_t **/, uint unArrayLength /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamInventory_AddPromoItems( ref pResultHandle.Value, pArrayItemDefs.Select( x => x.Value ).ToArray(), unArrayLength );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool CheckResultSteamID( SteamInventoryResult_t resultHandle /*SteamInventoryResult_t*/, CSteamID steamIDExpected /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamInventory_CheckResultSteamID( resultHandle.Value, steamIDExpected.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ConsumeItem( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemInstanceID_t itemConsume /*SteamItemInstanceID_t*/, uint unQuantity /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamInventory_ConsumeItem( ref pResultHandle.Value, itemConsume.Value, unQuantity );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool DeserializeResult( ref SteamInventoryResult_t pOutResultHandle /*SteamInventoryResult_t **/, IntPtr pBuffer /*const void **/, uint unBufferSize /*uint32*/, bool bRESERVED_MUST_BE_FALSE /*bool*/ )
|
||||
{
|
||||
return platform.ISteamInventory_DeserializeResult( ref pOutResultHandle.Value, (IntPtr) pBuffer, unBufferSize, bRESERVED_MUST_BE_FALSE );
|
||||
}
|
||||
|
||||
// void
|
||||
public void DestroyResult( SteamInventoryResult_t resultHandle /*SteamInventoryResult_t*/ )
|
||||
{
|
||||
platform.ISteamInventory_DestroyResult( resultHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ExchangeItems( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemDef_t[] pArrayGenerate /*const SteamItemDef_t **/, uint[] punArrayGenerateQuantity /*const uint32 **/, uint unArrayGenerateLength /*uint32*/, SteamItemInstanceID_t[] pArrayDestroy /*const SteamItemInstanceID_t **/, uint[] punArrayDestroyQuantity /*const uint32 **/, uint unArrayDestroyLength /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamInventory_ExchangeItems( ref pResultHandle.Value, pArrayGenerate.Select( x => x.Value ).ToArray(), punArrayGenerateQuantity, unArrayGenerateLength, pArrayDestroy.Select( x => x.Value ).ToArray(), punArrayDestroyQuantity, unArrayDestroyLength );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GenerateItems( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemDef_t[] pArrayItemDefs /*const SteamItemDef_t **/, uint[] punArrayQuantity /*const uint32 **/, uint unArrayLength /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamInventory_GenerateItems( ref pResultHandle.Value, pArrayItemDefs.Select( x => x.Value ).ToArray(), punArrayQuantity, unArrayLength );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetAllItems( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/ )
|
||||
{
|
||||
return platform.ISteamInventory_GetAllItems( ref pResultHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
// using: Detect_MultiSizeArrayReturn
|
||||
public SteamItemDef_t[] GetEligiblePromoItemDefinitionIDs( CSteamID steamID /*class CSteamID*/ )
|
||||
{
|
||||
uint punItemDefIDsArraySize = 0;
|
||||
|
||||
bool success = false;
|
||||
success = platform.ISteamInventory_GetEligiblePromoItemDefinitionIDs( steamID.Value, IntPtr.Zero, out punItemDefIDsArraySize );
|
||||
if ( !success || punItemDefIDsArraySize == 0) return null;
|
||||
|
||||
var pItemDefIDs = new SteamItemDef_t[punItemDefIDsArraySize];
|
||||
fixed ( void* pItemDefIDs_ptr = pItemDefIDs )
|
||||
{
|
||||
success = platform.ISteamInventory_GetEligiblePromoItemDefinitionIDs( steamID.Value, (IntPtr) pItemDefIDs_ptr, out punItemDefIDsArraySize );
|
||||
if ( !success ) return null;
|
||||
return pItemDefIDs;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
// using: Detect_MultiSizeArrayReturn
|
||||
public SteamItemDef_t[] GetItemDefinitionIDs()
|
||||
{
|
||||
uint punItemDefIDsArraySize = 0;
|
||||
|
||||
bool success = false;
|
||||
success = platform.ISteamInventory_GetItemDefinitionIDs( IntPtr.Zero, out punItemDefIDsArraySize );
|
||||
if ( !success || punItemDefIDsArraySize == 0) return null;
|
||||
|
||||
var pItemDefIDs = new SteamItemDef_t[punItemDefIDsArraySize];
|
||||
fixed ( void* pItemDefIDs_ptr = pItemDefIDs )
|
||||
{
|
||||
success = platform.ISteamInventory_GetItemDefinitionIDs( (IntPtr) pItemDefIDs_ptr, out punItemDefIDsArraySize );
|
||||
if ( !success ) return null;
|
||||
return pItemDefIDs;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetItemDefinitionProperty( SteamItemDef_t iDefinition /*SteamItemDef_t*/, string pchPropertyName /*const char **/, out string pchValueBuffer /*char **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchValueBuffer = string.Empty;
|
||||
System.Text.StringBuilder pchValueBuffer_sb = Helpers.TakeStringBuilder();
|
||||
uint punValueBufferSizeOut = 4096;
|
||||
bSuccess = platform.ISteamInventory_GetItemDefinitionProperty( iDefinition.Value, pchPropertyName, pchValueBuffer_sb, out punValueBufferSizeOut );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchValueBuffer = pchValueBuffer_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetItemPrice( SteamItemDef_t iDefinition /*SteamItemDef_t*/, out ulong pPrice /*uint64 **/ )
|
||||
{
|
||||
return platform.ISteamInventory_GetItemPrice( iDefinition.Value, out pPrice );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetItemsByID( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemInstanceID_t[] pInstanceIDs /*const SteamItemInstanceID_t **/, uint unCountInstanceIDs /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamInventory_GetItemsByID( ref pResultHandle.Value, pInstanceIDs.Select( x => x.Value ).ToArray(), unCountInstanceIDs );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetItemsWithPrices( IntPtr pArrayItemDefs /*SteamItemDef_t **/, IntPtr pPrices /*uint64 **/, uint unArrayLength /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamInventory_GetItemsWithPrices( (IntPtr) pArrayItemDefs, (IntPtr) pPrices, unArrayLength );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetNumItemsWithPrices()
|
||||
{
|
||||
return platform.ISteamInventory_GetNumItemsWithPrices();
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetResultItemProperty( SteamInventoryResult_t resultHandle /*SteamInventoryResult_t*/, uint unItemIndex /*uint32*/, string pchPropertyName /*const char **/, out string pchValueBuffer /*char **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchValueBuffer = string.Empty;
|
||||
System.Text.StringBuilder pchValueBuffer_sb = Helpers.TakeStringBuilder();
|
||||
uint punValueBufferSizeOut = 4096;
|
||||
bSuccess = platform.ISteamInventory_GetResultItemProperty( resultHandle.Value, unItemIndex, pchPropertyName, pchValueBuffer_sb, out punValueBufferSizeOut );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchValueBuffer = pchValueBuffer_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// bool
|
||||
// using: Detect_MultiSizeArrayReturn
|
||||
public SteamItemDetails_t[] GetResultItems( SteamInventoryResult_t resultHandle /*SteamInventoryResult_t*/ )
|
||||
{
|
||||
uint punOutItemsArraySize = 0;
|
||||
|
||||
bool success = false;
|
||||
success = platform.ISteamInventory_GetResultItems( resultHandle.Value, IntPtr.Zero, out punOutItemsArraySize );
|
||||
if ( !success || punOutItemsArraySize == 0) return null;
|
||||
|
||||
var pOutItemsArray = new SteamItemDetails_t[punOutItemsArraySize];
|
||||
fixed ( void* pOutItemsArray_ptr = pOutItemsArray )
|
||||
{
|
||||
success = platform.ISteamInventory_GetResultItems( resultHandle.Value, (IntPtr) pOutItemsArray_ptr, out punOutItemsArraySize );
|
||||
if ( !success ) return null;
|
||||
return pOutItemsArray;
|
||||
}
|
||||
}
|
||||
|
||||
// Result
|
||||
public Result GetResultStatus( SteamInventoryResult_t resultHandle /*SteamInventoryResult_t*/ )
|
||||
{
|
||||
return platform.ISteamInventory_GetResultStatus( resultHandle.Value );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetResultTimestamp( SteamInventoryResult_t resultHandle /*SteamInventoryResult_t*/ )
|
||||
{
|
||||
return platform.ISteamInventory_GetResultTimestamp( resultHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GrantPromoItems( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/ )
|
||||
{
|
||||
return platform.ISteamInventory_GrantPromoItems( ref pResultHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool LoadItemDefinitions()
|
||||
{
|
||||
return platform.ISteamInventory_LoadItemDefinitions();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RemoveProperty( SteamInventoryUpdateHandle_t handle /*SteamInventoryUpdateHandle_t*/, SteamItemInstanceID_t nItemID /*SteamItemInstanceID_t*/, string pchPropertyName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamInventory_RemoveProperty( handle.Value, nItemID.Value, pchPropertyName );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestEligiblePromoItemDefinitionsIDs( CSteamID steamID /*class CSteamID*/, Action<SteamInventoryEligiblePromoItemDefIDs_t, bool> CallbackFunction = null /*Action<SteamInventoryEligiblePromoItemDefIDs_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamInventory_RequestEligiblePromoItemDefinitionsIDs( steamID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return SteamInventoryEligiblePromoItemDefIDs_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestPrices( Action<SteamInventoryRequestPricesResult_t, bool> CallbackFunction = null /*Action<SteamInventoryRequestPricesResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamInventory_RequestPrices();
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return SteamInventoryRequestPricesResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SendItemDropHeartbeat()
|
||||
{
|
||||
platform.ISteamInventory_SendItemDropHeartbeat();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SerializeResult( SteamInventoryResult_t resultHandle /*SteamInventoryResult_t*/, IntPtr pOutBuffer /*void **/, out uint punOutBufferSize /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamInventory_SerializeResult( resultHandle.Value, (IntPtr) pOutBuffer, out punOutBufferSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetProperty( SteamInventoryUpdateHandle_t handle /*SteamInventoryUpdateHandle_t*/, SteamItemInstanceID_t nItemID /*SteamItemInstanceID_t*/, string pchPropertyName /*const char **/, string pchPropertyValue /*const char **/ )
|
||||
{
|
||||
return platform.ISteamInventory_SetProperty( handle.Value, nItemID.Value, pchPropertyName, pchPropertyValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetProperty0( SteamInventoryUpdateHandle_t handle /*SteamInventoryUpdateHandle_t*/, SteamItemInstanceID_t nItemID /*SteamItemInstanceID_t*/, string pchPropertyName /*const char **/, bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamInventory_SetProperty0( handle.Value, nItemID.Value, pchPropertyName, bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetProperty1( SteamInventoryUpdateHandle_t handle /*SteamInventoryUpdateHandle_t*/, SteamItemInstanceID_t nItemID /*SteamItemInstanceID_t*/, string pchPropertyName /*const char **/, long nValue /*int64*/ )
|
||||
{
|
||||
return platform.ISteamInventory_SetProperty0( handle.Value, nItemID.Value, pchPropertyName, nValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetProperty2( SteamInventoryUpdateHandle_t handle /*SteamInventoryUpdateHandle_t*/, SteamItemInstanceID_t nItemID /*SteamItemInstanceID_t*/, string pchPropertyName /*const char **/, float flValue /*float*/ )
|
||||
{
|
||||
return platform.ISteamInventory_SetProperty0( handle.Value, nItemID.Value, pchPropertyName, flValue );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle StartPurchase( SteamItemDef_t[] pArrayItemDefs /*const SteamItemDef_t **/, uint[] punArrayQuantity /*const uint32 **/, uint unArrayLength /*uint32*/, Action<SteamInventoryStartPurchaseResult_t, bool> CallbackFunction = null /*Action<SteamInventoryStartPurchaseResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamInventory_StartPurchase( pArrayItemDefs.Select( x => x.Value ).ToArray(), punArrayQuantity, unArrayLength );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return SteamInventoryStartPurchaseResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamInventoryUpdateHandle_t
|
||||
public SteamInventoryUpdateHandle_t StartUpdateProperties()
|
||||
{
|
||||
return platform.ISteamInventory_StartUpdateProperties();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SubmitUpdateProperties( SteamInventoryUpdateHandle_t handle /*SteamInventoryUpdateHandle_t*/, ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/ )
|
||||
{
|
||||
return platform.ISteamInventory_SubmitUpdateProperties( handle.Value, ref pResultHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool TradeItems( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, CSteamID steamIDTradePartner /*class CSteamID*/, SteamItemInstanceID_t[] pArrayGive /*const SteamItemInstanceID_t **/, uint[] pArrayGiveQuantity /*const uint32 **/, uint nArrayGiveLength /*uint32*/, SteamItemInstanceID_t[] pArrayGet /*const SteamItemInstanceID_t **/, uint[] pArrayGetQuantity /*const uint32 **/, uint nArrayGetLength /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamInventory_TradeItems( ref pResultHandle.Value, steamIDTradePartner.Value, pArrayGive.Select( x => x.Value ).ToArray(), pArrayGiveQuantity, nArrayGiveLength, pArrayGet.Select( x => x.Value ).ToArray(), pArrayGetQuantity, nArrayGetLength );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool TransferItemQuantity( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemInstanceID_t itemIdSource /*SteamItemInstanceID_t*/, uint unQuantity /*uint32*/, SteamItemInstanceID_t itemIdDest /*SteamItemInstanceID_t*/ )
|
||||
{
|
||||
return platform.ISteamInventory_TransferItemQuantity( ref pResultHandle.Value, itemIdSource.Value, unQuantity, itemIdDest.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool TriggerItemDrop( ref SteamInventoryResult_t pResultHandle /*SteamInventoryResult_t **/, SteamItemDef_t dropListDefinition /*SteamItemDef_t*/ )
|
||||
{
|
||||
return platform.ISteamInventory_TriggerItemDrop( ref pResultHandle.Value, dropListDefinition.Value );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,313 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamMatchmaking : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamMatchmaking( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// int
|
||||
public int AddFavoriteGame( AppId_t nAppID /*AppId_t*/, uint nIP /*uint32*/, ushort nConnPort /*uint16*/, ushort nQueryPort /*uint16*/, uint unFlags /*uint32*/, uint rTime32LastPlayedOnServer /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_AddFavoriteGame( nAppID.Value, nIP, nConnPort, nQueryPort, unFlags, rTime32LastPlayedOnServer );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddRequestLobbyListCompatibleMembersFilter( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_AddRequestLobbyListCompatibleMembersFilter( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddRequestLobbyListDistanceFilter( LobbyDistanceFilter eLobbyDistanceFilter /*ELobbyDistanceFilter*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_AddRequestLobbyListDistanceFilter( eLobbyDistanceFilter );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddRequestLobbyListFilterSlotsAvailable( int nSlotsAvailable /*int*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_AddRequestLobbyListFilterSlotsAvailable( nSlotsAvailable );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddRequestLobbyListNearValueFilter( string pchKeyToMatch /*const char **/, int nValueToBeCloseTo /*int*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_AddRequestLobbyListNearValueFilter( pchKeyToMatch, nValueToBeCloseTo );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddRequestLobbyListNumericalFilter( string pchKeyToMatch /*const char **/, int nValueToMatch /*int*/, LobbyComparison eComparisonType /*ELobbyComparison*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_AddRequestLobbyListNumericalFilter( pchKeyToMatch, nValueToMatch, eComparisonType );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddRequestLobbyListResultCountFilter( int cMaxResults /*int*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_AddRequestLobbyListResultCountFilter( cMaxResults );
|
||||
}
|
||||
|
||||
// void
|
||||
public void AddRequestLobbyListStringFilter( string pchKeyToMatch /*const char **/, string pchValueToMatch /*const char **/, LobbyComparison eComparisonType /*ELobbyComparison*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_AddRequestLobbyListStringFilter( pchKeyToMatch, pchValueToMatch, eComparisonType );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle CreateLobby( LobbyType eLobbyType /*ELobbyType*/, int cMaxMembers /*int*/, Action<LobbyCreated_t, bool> CallbackFunction = null /*Action<LobbyCreated_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamMatchmaking_CreateLobby( eLobbyType, cMaxMembers );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LobbyCreated_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool DeleteLobbyData( CSteamID steamIDLobby /*class CSteamID*/, string pchKey /*const char **/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_DeleteLobbyData( steamIDLobby.Value, pchKey );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetFavoriteGame( int iGame /*int*/, ref AppId_t pnAppID /*AppId_t **/, out uint pnIP /*uint32 **/, out ushort pnConnPort /*uint16 **/, out ushort pnQueryPort /*uint16 **/, out uint punFlags /*uint32 **/, out uint pRTime32LastPlayedOnServer /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetFavoriteGame( iGame, ref pnAppID.Value, out pnIP, out pnConnPort, out pnQueryPort, out punFlags, out pRTime32LastPlayedOnServer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFavoriteGameCount()
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetFavoriteGameCount();
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetLobbyByIndex( int iLobby /*int*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetLobbyByIndex( iLobby );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetLobbyChatEntry( CSteamID steamIDLobby /*class CSteamID*/, int iChatID /*int*/, out CSteamID pSteamIDUser /*class CSteamID **/, IntPtr pvData /*void **/, int cubData /*int*/, out ChatEntryType peChatEntryType /*EChatEntryType **/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetLobbyChatEntry( steamIDLobby.Value, iChatID, out pSteamIDUser.Value, (IntPtr) pvData, cubData, out peChatEntryType );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetLobbyData( CSteamID steamIDLobby /*class CSteamID*/, string pchKey /*const char **/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamMatchmaking_GetLobbyData( steamIDLobby.Value, pchKey );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetLobbyDataByIndex( CSteamID steamIDLobby /*class CSteamID*/, int iLobbyData /*int*/, out string pchKey /*char **/, out string pchValue /*char **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchKey = string.Empty;
|
||||
System.Text.StringBuilder pchKey_sb = Helpers.TakeStringBuilder();
|
||||
int cchKeyBufferSize = 4096;
|
||||
pchValue = string.Empty;
|
||||
System.Text.StringBuilder pchValue_sb = Helpers.TakeStringBuilder();
|
||||
int cchValueBufferSize = 4096;
|
||||
bSuccess = platform.ISteamMatchmaking_GetLobbyDataByIndex( steamIDLobby.Value, iLobbyData, pchKey_sb, cchKeyBufferSize, pchValue_sb, cchValueBufferSize );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchValue = pchValue_sb.ToString();
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchKey = pchKey_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetLobbyDataCount( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetLobbyDataCount( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetLobbyGameServer( CSteamID steamIDLobby /*class CSteamID*/, out uint punGameServerIP /*uint32 **/, out ushort punGameServerPort /*uint16 **/, out CSteamID psteamIDGameServer /*class CSteamID **/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetLobbyGameServer( steamIDLobby.Value, out punGameServerIP, out punGameServerPort, out psteamIDGameServer.Value );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetLobbyMemberByIndex( CSteamID steamIDLobby /*class CSteamID*/, int iMember /*int*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetLobbyMemberByIndex( steamIDLobby.Value, iMember );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetLobbyMemberData( CSteamID steamIDLobby /*class CSteamID*/, CSteamID steamIDUser /*class CSteamID*/, string pchKey /*const char **/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamMatchmaking_GetLobbyMemberData( steamIDLobby.Value, steamIDUser.Value, pchKey );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetLobbyMemberLimit( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetLobbyMemberLimit( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetLobbyOwner( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetLobbyOwner( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetNumLobbyMembers( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_GetNumLobbyMembers( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool InviteUserToLobby( CSteamID steamIDLobby /*class CSteamID*/, CSteamID steamIDInvitee /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_InviteUserToLobby( steamIDLobby.Value, steamIDInvitee.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle JoinLobby( CSteamID steamIDLobby /*class CSteamID*/, Action<LobbyEnter_t, bool> CallbackFunction = null /*Action<LobbyEnter_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamMatchmaking_JoinLobby( steamIDLobby.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LobbyEnter_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void LeaveLobby( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_LeaveLobby( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RemoveFavoriteGame( AppId_t nAppID /*AppId_t*/, uint nIP /*uint32*/, ushort nConnPort /*uint16*/, ushort nQueryPort /*uint16*/, uint unFlags /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_RemoveFavoriteGame( nAppID.Value, nIP, nConnPort, nQueryPort, unFlags );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RequestLobbyData( CSteamID steamIDLobby /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_RequestLobbyData( steamIDLobby.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestLobbyList( Action<LobbyMatchList_t, bool> CallbackFunction = null /*Action<LobbyMatchList_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamMatchmaking_RequestLobbyList();
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LobbyMatchList_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SendLobbyChatMsg( CSteamID steamIDLobby /*class CSteamID*/, IntPtr pvMsgBody /*const void **/, int cubMsgBody /*int*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_SendLobbyChatMsg( steamIDLobby.Value, (IntPtr) pvMsgBody, cubMsgBody );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLinkedLobby( CSteamID steamIDLobby /*class CSteamID*/, CSteamID steamIDLobbyDependent /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_SetLinkedLobby( steamIDLobby.Value, steamIDLobbyDependent.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLobbyData( CSteamID steamIDLobby /*class CSteamID*/, string pchKey /*const char **/, string pchValue /*const char **/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_SetLobbyData( steamIDLobby.Value, pchKey, pchValue );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetLobbyGameServer( CSteamID steamIDLobby /*class CSteamID*/, uint unGameServerIP /*uint32*/, ushort unGameServerPort /*uint16*/, CSteamID steamIDGameServer /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_SetLobbyGameServer( steamIDLobby.Value, unGameServerIP, unGameServerPort, steamIDGameServer.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLobbyJoinable( CSteamID steamIDLobby /*class CSteamID*/, bool bLobbyJoinable /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_SetLobbyJoinable( steamIDLobby.Value, bLobbyJoinable );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetLobbyMemberData( CSteamID steamIDLobby /*class CSteamID*/, string pchKey /*const char **/, string pchValue /*const char **/ )
|
||||
{
|
||||
platform.ISteamMatchmaking_SetLobbyMemberData( steamIDLobby.Value, pchKey, pchValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLobbyMemberLimit( CSteamID steamIDLobby /*class CSteamID*/, int cMaxMembers /*int*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_SetLobbyMemberLimit( steamIDLobby.Value, cMaxMembers );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLobbyOwner( CSteamID steamIDLobby /*class CSteamID*/, CSteamID steamIDNewOwner /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_SetLobbyOwner( steamIDLobby.Value, steamIDNewOwner.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLobbyType( CSteamID steamIDLobby /*class CSteamID*/, LobbyType eLobbyType /*ELobbyType*/ )
|
||||
{
|
||||
return platform.ISteamMatchmaking_SetLobbyType( steamIDLobby.Value, eLobbyType );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamMatchmakingServers : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamMatchmakingServers( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// void
|
||||
public void CancelQuery( HServerListRequest hRequest /*HServerListRequest*/ )
|
||||
{
|
||||
platform.ISteamMatchmakingServers_CancelQuery( hRequest.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void CancelServerQuery( HServerQuery hServerQuery /*HServerQuery*/ )
|
||||
{
|
||||
platform.ISteamMatchmakingServers_CancelServerQuery( hServerQuery.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetServerCount( HServerListRequest hRequest /*HServerListRequest*/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_GetServerCount( hRequest.Value );
|
||||
}
|
||||
|
||||
// gameserveritem_t *
|
||||
// with: Detect_ReturningStruct
|
||||
public gameserveritem_t GetServerDetails( HServerListRequest hRequest /*HServerListRequest*/, int iServer /*int*/ )
|
||||
{
|
||||
IntPtr struct_pointer;
|
||||
struct_pointer = platform.ISteamMatchmakingServers_GetServerDetails( hRequest.Value, iServer );
|
||||
if ( struct_pointer == IntPtr.Zero ) return default(gameserveritem_t);
|
||||
return gameserveritem_t.FromPointer( struct_pointer );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsRefreshing( HServerListRequest hRequest /*HServerListRequest*/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_IsRefreshing( hRequest.Value );
|
||||
}
|
||||
|
||||
// HServerQuery
|
||||
public HServerQuery PingServer( uint unIP /*uint32*/, ushort usPort /*uint16*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingPingResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_PingServer( unIP, usPort, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// HServerQuery
|
||||
public HServerQuery PlayerDetails( uint unIP /*uint32*/, ushort usPort /*uint16*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingPlayersResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_PlayerDetails( unIP, usPort, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// void
|
||||
public void RefreshQuery( HServerListRequest hRequest /*HServerListRequest*/ )
|
||||
{
|
||||
platform.ISteamMatchmakingServers_RefreshQuery( hRequest.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void RefreshServer( HServerListRequest hRequest /*HServerListRequest*/, int iServer /*int*/ )
|
||||
{
|
||||
platform.ISteamMatchmakingServers_RefreshServer( hRequest.Value, iServer );
|
||||
}
|
||||
|
||||
// void
|
||||
public void ReleaseRequest( HServerListRequest hServerListRequest /*HServerListRequest*/ )
|
||||
{
|
||||
platform.ISteamMatchmakingServers_ReleaseRequest( hServerListRequest.Value );
|
||||
}
|
||||
|
||||
// HServerListRequest
|
||||
// with: Detect_MatchmakingFilters
|
||||
public HServerListRequest RequestFavoritesServerList( AppId_t iApp /*AppId_t*/, IntPtr ppchFilters /*struct MatchMakingKeyValuePair_t ***/, uint nFilters /*uint32*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingServerListResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_RequestFavoritesServerList( iApp.Value, (IntPtr) ppchFilters, nFilters, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// HServerListRequest
|
||||
// with: Detect_MatchmakingFilters
|
||||
public HServerListRequest RequestFriendsServerList( AppId_t iApp /*AppId_t*/, IntPtr ppchFilters /*struct MatchMakingKeyValuePair_t ***/, uint nFilters /*uint32*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingServerListResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_RequestFriendsServerList( iApp.Value, (IntPtr) ppchFilters, nFilters, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// HServerListRequest
|
||||
// with: Detect_MatchmakingFilters
|
||||
public HServerListRequest RequestHistoryServerList( AppId_t iApp /*AppId_t*/, IntPtr ppchFilters /*struct MatchMakingKeyValuePair_t ***/, uint nFilters /*uint32*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingServerListResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_RequestHistoryServerList( iApp.Value, (IntPtr) ppchFilters, nFilters, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// HServerListRequest
|
||||
// with: Detect_MatchmakingFilters
|
||||
public HServerListRequest RequestInternetServerList( AppId_t iApp /*AppId_t*/, IntPtr ppchFilters /*struct MatchMakingKeyValuePair_t ***/, uint nFilters /*uint32*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingServerListResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_RequestInternetServerList( iApp.Value, (IntPtr) ppchFilters, nFilters, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// HServerListRequest
|
||||
public HServerListRequest RequestLANServerList( AppId_t iApp /*AppId_t*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingServerListResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_RequestLANServerList( iApp.Value, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// HServerListRequest
|
||||
// with: Detect_MatchmakingFilters
|
||||
public HServerListRequest RequestSpectatorServerList( AppId_t iApp /*AppId_t*/, IntPtr ppchFilters /*struct MatchMakingKeyValuePair_t ***/, uint nFilters /*uint32*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingServerListResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_RequestSpectatorServerList( iApp.Value, (IntPtr) ppchFilters, nFilters, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
// HServerQuery
|
||||
public HServerQuery ServerRules( uint unIP /*uint32*/, ushort usPort /*uint16*/, IntPtr pRequestServersResponse /*class ISteamMatchmakingRulesResponse **/ )
|
||||
{
|
||||
return platform.ISteamMatchmakingServers_ServerRules( unIP, usPort, (IntPtr) pRequestServersResponse );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamMusic : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamMusic( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsEnabled()
|
||||
{
|
||||
return platform.ISteamMusic_BIsEnabled();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsPlaying()
|
||||
{
|
||||
return platform.ISteamMusic_BIsPlaying();
|
||||
}
|
||||
|
||||
// AudioPlayback_Status
|
||||
public AudioPlayback_Status GetPlaybackStatus()
|
||||
{
|
||||
return platform.ISteamMusic_GetPlaybackStatus();
|
||||
}
|
||||
|
||||
// float
|
||||
public float GetVolume()
|
||||
{
|
||||
return platform.ISteamMusic_GetVolume();
|
||||
}
|
||||
|
||||
// void
|
||||
public void Pause()
|
||||
{
|
||||
platform.ISteamMusic_Pause();
|
||||
}
|
||||
|
||||
// void
|
||||
public void Play()
|
||||
{
|
||||
platform.ISteamMusic_Play();
|
||||
}
|
||||
|
||||
// void
|
||||
public void PlayNext()
|
||||
{
|
||||
platform.ISteamMusic_PlayNext();
|
||||
}
|
||||
|
||||
// void
|
||||
public void PlayPrevious()
|
||||
{
|
||||
platform.ISteamMusic_PlayPrevious();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetVolume( float flVolume /*float*/ )
|
||||
{
|
||||
platform.ISteamMusic_SetVolume( flVolume );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamMusicRemote : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamMusicRemote( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BActivationSuccess( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_BActivationSuccess( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsCurrentMusicRemote()
|
||||
{
|
||||
return platform.ISteamMusicRemote_BIsCurrentMusicRemote();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool CurrentEntryDidChange()
|
||||
{
|
||||
return platform.ISteamMusicRemote_CurrentEntryDidChange();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool CurrentEntryIsAvailable( bool bAvailable /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_CurrentEntryIsAvailable( bAvailable );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool CurrentEntryWillChange()
|
||||
{
|
||||
return platform.ISteamMusicRemote_CurrentEntryWillChange();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool DeregisterSteamMusicRemote()
|
||||
{
|
||||
return platform.ISteamMusicRemote_DeregisterSteamMusicRemote();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool EnableLooped( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_EnableLooped( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool EnablePlaylists( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_EnablePlaylists( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool EnablePlayNext( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_EnablePlayNext( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool EnablePlayPrevious( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_EnablePlayPrevious( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool EnableQueue( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_EnableQueue( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool EnableShuffled( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_EnableShuffled( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool PlaylistDidChange()
|
||||
{
|
||||
return platform.ISteamMusicRemote_PlaylistDidChange();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool PlaylistWillChange()
|
||||
{
|
||||
return platform.ISteamMusicRemote_PlaylistWillChange();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool QueueDidChange()
|
||||
{
|
||||
return platform.ISteamMusicRemote_QueueDidChange();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool QueueWillChange()
|
||||
{
|
||||
return platform.ISteamMusicRemote_QueueWillChange();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RegisterSteamMusicRemote( string pchName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_RegisterSteamMusicRemote( pchName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ResetPlaylistEntries()
|
||||
{
|
||||
return platform.ISteamMusicRemote_ResetPlaylistEntries();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ResetQueueEntries()
|
||||
{
|
||||
return platform.ISteamMusicRemote_ResetQueueEntries();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetCurrentPlaylistEntry( int nID /*int*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_SetCurrentPlaylistEntry( nID );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetCurrentQueueEntry( int nID /*int*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_SetCurrentQueueEntry( nID );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetDisplayName( string pchDisplayName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_SetDisplayName( pchDisplayName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetPlaylistEntry( int nID /*int*/, int nPosition /*int*/, string pchEntryText /*const char **/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_SetPlaylistEntry( nID, nPosition, pchEntryText );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetPNGIcon_64x64( IntPtr pvBuffer /*void **/, uint cbBufferLength /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_SetPNGIcon_64x64( (IntPtr) pvBuffer, cbBufferLength );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetQueueEntry( int nID /*int*/, int nPosition /*int*/, string pchEntryText /*const char **/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_SetQueueEntry( nID, nPosition, pchEntryText );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateCurrentEntryCoverArt( IntPtr pvBuffer /*void **/, uint cbBufferLength /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_UpdateCurrentEntryCoverArt( (IntPtr) pvBuffer, cbBufferLength );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateCurrentEntryElapsedSeconds( int nValue /*int*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_UpdateCurrentEntryElapsedSeconds( nValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateCurrentEntryText( string pchText /*const char **/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_UpdateCurrentEntryText( pchText );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateLooped( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_UpdateLooped( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdatePlaybackStatus( AudioPlayback_Status nStatus /*AudioPlayback_Status*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_UpdatePlaybackStatus( nStatus );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateShuffled( bool bValue /*bool*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_UpdateShuffled( bValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateVolume( float flValue /*float*/ )
|
||||
{
|
||||
return platform.ISteamMusicRemote_UpdateVolume( flValue );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamNetworking : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamNetworking( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AcceptP2PSessionWithUser( CSteamID steamIDRemote /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_AcceptP2PSessionWithUser( steamIDRemote.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AllowP2PPacketRelay( bool bAllow /*bool*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_AllowP2PPacketRelay( bAllow );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool CloseP2PChannelWithUser( CSteamID steamIDRemote /*class CSteamID*/, int nChannel /*int*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_CloseP2PChannelWithUser( steamIDRemote.Value, nChannel );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool CloseP2PSessionWithUser( CSteamID steamIDRemote /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_CloseP2PSessionWithUser( steamIDRemote.Value );
|
||||
}
|
||||
|
||||
// SNetSocket_t
|
||||
public SNetSocket_t CreateConnectionSocket( uint nIP /*uint32*/, ushort nPort /*uint16*/, int nTimeoutSec /*int*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_CreateConnectionSocket( nIP, nPort, nTimeoutSec );
|
||||
}
|
||||
|
||||
// SNetListenSocket_t
|
||||
public SNetListenSocket_t CreateListenSocket( int nVirtualP2PPort /*int*/, uint nIP /*uint32*/, ushort nPort /*uint16*/, bool bAllowUseOfPacketRelay /*bool*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_CreateListenSocket( nVirtualP2PPort, nIP, nPort, bAllowUseOfPacketRelay );
|
||||
}
|
||||
|
||||
// SNetSocket_t
|
||||
public SNetSocket_t CreateP2PConnectionSocket( CSteamID steamIDTarget /*class CSteamID*/, int nVirtualPort /*int*/, int nTimeoutSec /*int*/, bool bAllowUseOfPacketRelay /*bool*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_CreateP2PConnectionSocket( steamIDTarget.Value, nVirtualPort, nTimeoutSec, bAllowUseOfPacketRelay );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool DestroyListenSocket( SNetListenSocket_t hSocket /*SNetListenSocket_t*/, bool bNotifyRemoteEnd /*bool*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_DestroyListenSocket( hSocket.Value, bNotifyRemoteEnd );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool DestroySocket( SNetSocket_t hSocket /*SNetSocket_t*/, bool bNotifyRemoteEnd /*bool*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_DestroySocket( hSocket.Value, bNotifyRemoteEnd );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetListenSocketInfo( SNetListenSocket_t hListenSocket /*SNetListenSocket_t*/, out uint pnIP /*uint32 **/, out ushort pnPort /*uint16 **/ )
|
||||
{
|
||||
return platform.ISteamNetworking_GetListenSocketInfo( hListenSocket.Value, out pnIP, out pnPort );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetMaxPacketSize( SNetSocket_t hSocket /*SNetSocket_t*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_GetMaxPacketSize( hSocket.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetP2PSessionState( CSteamID steamIDRemote /*class CSteamID*/, ref P2PSessionState_t pConnectionState /*struct P2PSessionState_t **/ )
|
||||
{
|
||||
return platform.ISteamNetworking_GetP2PSessionState( steamIDRemote.Value, ref pConnectionState );
|
||||
}
|
||||
|
||||
// SNetSocketConnectionType
|
||||
public SNetSocketConnectionType GetSocketConnectionType( SNetSocket_t hSocket /*SNetSocket_t*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_GetSocketConnectionType( hSocket.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetSocketInfo( SNetSocket_t hSocket /*SNetSocket_t*/, out CSteamID pSteamIDRemote /*class CSteamID **/, IntPtr peSocketStatus /*int **/, out uint punIPRemote /*uint32 **/, out ushort punPortRemote /*uint16 **/ )
|
||||
{
|
||||
return platform.ISteamNetworking_GetSocketInfo( hSocket.Value, out pSteamIDRemote.Value, (IntPtr) peSocketStatus, out punIPRemote, out punPortRemote );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsDataAvailable( SNetListenSocket_t hListenSocket /*SNetListenSocket_t*/, out uint pcubMsgSize /*uint32 **/, ref SNetSocket_t phSocket /*SNetSocket_t **/ )
|
||||
{
|
||||
return platform.ISteamNetworking_IsDataAvailable( hListenSocket.Value, out pcubMsgSize, ref phSocket.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsDataAvailableOnSocket( SNetSocket_t hSocket /*SNetSocket_t*/, out uint pcubMsgSize /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamNetworking_IsDataAvailableOnSocket( hSocket.Value, out pcubMsgSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsP2PPacketAvailable( out uint pcubMsgSize /*uint32 **/, int nChannel /*int*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_IsP2PPacketAvailable( out pcubMsgSize, nChannel );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ReadP2PPacket( IntPtr pubDest /*void **/, uint cubDest /*uint32*/, out uint pcubMsgSize /*uint32 **/, out CSteamID psteamIDRemote /*class CSteamID **/, int nChannel /*int*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_ReadP2PPacket( (IntPtr) pubDest, cubDest, out pcubMsgSize, out psteamIDRemote.Value, nChannel );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RetrieveData( SNetListenSocket_t hListenSocket /*SNetListenSocket_t*/, IntPtr pubDest /*void **/, uint cubDest /*uint32*/, out uint pcubMsgSize /*uint32 **/, ref SNetSocket_t phSocket /*SNetSocket_t **/ )
|
||||
{
|
||||
return platform.ISteamNetworking_RetrieveData( hListenSocket.Value, (IntPtr) pubDest, cubDest, out pcubMsgSize, ref phSocket.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RetrieveDataFromSocket( SNetSocket_t hSocket /*SNetSocket_t*/, IntPtr pubDest /*void **/, uint cubDest /*uint32*/, out uint pcubMsgSize /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamNetworking_RetrieveDataFromSocket( hSocket.Value, (IntPtr) pubDest, cubDest, out pcubMsgSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SendDataOnSocket( SNetSocket_t hSocket /*SNetSocket_t*/, IntPtr pubData /*void **/, uint cubData /*uint32*/, bool bReliable /*bool*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_SendDataOnSocket( hSocket.Value, (IntPtr) pubData, cubData, bReliable );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SendP2PPacket( CSteamID steamIDRemote /*class CSteamID*/, IntPtr pubData /*const void **/, uint cubData /*uint32*/, P2PSend eP2PSendType /*EP2PSend*/, int nChannel /*int*/ )
|
||||
{
|
||||
return platform.ISteamNetworking_SendP2PPacket( steamIDRemote.Value, (IntPtr) pubData, cubData, eP2PSendType, nChannel );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamParentalSettings : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamParentalSettings( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsAppBlocked( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamParentalSettings_BIsAppBlocked( nAppID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsAppInBlockList( AppId_t nAppID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamParentalSettings_BIsAppInBlockList( nAppID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsFeatureBlocked( ParentalFeature eFeature /*EParentalFeature*/ )
|
||||
{
|
||||
return platform.ISteamParentalSettings_BIsFeatureBlocked( eFeature );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsFeatureInBlockList( ParentalFeature eFeature /*EParentalFeature*/ )
|
||||
{
|
||||
return platform.ISteamParentalSettings_BIsFeatureInBlockList( eFeature );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsParentalLockEnabled()
|
||||
{
|
||||
return platform.ISteamParentalSettings_BIsParentalLockEnabled();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsParentalLockLocked()
|
||||
{
|
||||
return platform.ISteamParentalSettings_BIsParentalLockLocked();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,644 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamRemoteStorage : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamRemoteStorage( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle CommitPublishedFileUpdate( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, Action<RemoteStorageUpdatePublishedFileResult_t, bool> CallbackFunction = null /*Action<RemoteStorageUpdatePublishedFileResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_CommitPublishedFileUpdate( updateHandle.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageUpdatePublishedFileResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// PublishedFileUpdateHandle_t
|
||||
public PublishedFileUpdateHandle_t CreatePublishedFileUpdateRequest( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_CreatePublishedFileUpdateRequest( unPublishedFileId.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle DeletePublishedFile( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, Action<RemoteStorageDeletePublishedFileResult_t, bool> CallbackFunction = null /*Action<RemoteStorageDeletePublishedFileResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_DeletePublishedFile( unPublishedFileId.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageDeletePublishedFileResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle EnumeratePublishedFilesByUserAction( WorkshopFileAction eAction /*EWorkshopFileAction*/, uint unStartIndex /*uint32*/, Action<RemoteStorageEnumeratePublishedFilesByUserActionResult_t, bool> CallbackFunction = null /*Action<RemoteStorageEnumeratePublishedFilesByUserActionResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_EnumeratePublishedFilesByUserAction( eAction, unStartIndex );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageEnumeratePublishedFilesByUserActionResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
// using: Detect_StringArray
|
||||
public CallbackHandle EnumeratePublishedWorkshopFiles( WorkshopEnumerationType eEnumerationType /*EWorkshopEnumerationType*/, uint unStartIndex /*uint32*/, uint unCount /*uint32*/, uint unDays /*uint32*/, string[] pTags /*struct SteamParamStringArray_t **/, ref SteamParamStringArray_t pUserTags /*struct SteamParamStringArray_t **/, Action<RemoteStorageEnumerateWorkshopFilesResult_t, bool> CallbackFunction = null /*Action<RemoteStorageEnumerateWorkshopFilesResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
// Create strings
|
||||
var nativeStrings = new IntPtr[pTags.Length];
|
||||
for ( int i = 0; i < pTags.Length; i++ )
|
||||
{
|
||||
nativeStrings[i] = Marshal.StringToHGlobalAnsi( pTags[i] );
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// Create string array
|
||||
var size = Marshal.SizeOf( typeof( IntPtr ) ) * nativeStrings.Length;
|
||||
var nativeArray = Marshal.AllocHGlobal( size );
|
||||
Marshal.Copy( nativeStrings, 0, nativeArray, nativeStrings.Length );
|
||||
|
||||
// Create SteamParamStringArray_t
|
||||
var tags = new SteamParamStringArray_t();
|
||||
tags.Strings = nativeArray;
|
||||
tags.NumStrings = pTags.Length;
|
||||
callback = platform.ISteamRemoteStorage_EnumeratePublishedWorkshopFiles( eEnumerationType, unStartIndex, unCount, unDays, ref tags, ref pUserTags );
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach ( var x in nativeStrings )
|
||||
Marshal.FreeHGlobal( x );
|
||||
|
||||
}
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageEnumerateWorkshopFilesResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle EnumerateUserPublishedFiles( uint unStartIndex /*uint32*/, Action<RemoteStorageEnumerateUserPublishedFilesResult_t, bool> CallbackFunction = null /*Action<RemoteStorageEnumerateUserPublishedFilesResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_EnumerateUserPublishedFiles( unStartIndex );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageEnumerateUserPublishedFilesResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
// using: Detect_StringArray
|
||||
public CallbackHandle EnumerateUserSharedWorkshopFiles( CSteamID steamId /*class CSteamID*/, uint unStartIndex /*uint32*/, string[] pRequiredTags /*struct SteamParamStringArray_t **/, ref SteamParamStringArray_t pExcludedTags /*struct SteamParamStringArray_t **/, Action<RemoteStorageEnumerateUserPublishedFilesResult_t, bool> CallbackFunction = null /*Action<RemoteStorageEnumerateUserPublishedFilesResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
// Create strings
|
||||
var nativeStrings = new IntPtr[pRequiredTags.Length];
|
||||
for ( int i = 0; i < pRequiredTags.Length; i++ )
|
||||
{
|
||||
nativeStrings[i] = Marshal.StringToHGlobalAnsi( pRequiredTags[i] );
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// Create string array
|
||||
var size = Marshal.SizeOf( typeof( IntPtr ) ) * nativeStrings.Length;
|
||||
var nativeArray = Marshal.AllocHGlobal( size );
|
||||
Marshal.Copy( nativeStrings, 0, nativeArray, nativeStrings.Length );
|
||||
|
||||
// Create SteamParamStringArray_t
|
||||
var tags = new SteamParamStringArray_t();
|
||||
tags.Strings = nativeArray;
|
||||
tags.NumStrings = pRequiredTags.Length;
|
||||
callback = platform.ISteamRemoteStorage_EnumerateUserSharedWorkshopFiles( steamId.Value, unStartIndex, ref tags, ref pExcludedTags );
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach ( var x in nativeStrings )
|
||||
Marshal.FreeHGlobal( x );
|
||||
|
||||
}
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageEnumerateUserPublishedFilesResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle EnumerateUserSubscribedFiles( uint unStartIndex /*uint32*/, Action<RemoteStorageEnumerateUserSubscribedFilesResult_t, bool> CallbackFunction = null /*Action<RemoteStorageEnumerateUserSubscribedFilesResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_EnumerateUserSubscribedFiles( unStartIndex );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageEnumerateUserSubscribedFilesResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileDelete( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileDelete( pchFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileExists( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileExists( pchFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileForget( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileForget( pchFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FilePersisted( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FilePersisted( pchFile );
|
||||
}
|
||||
|
||||
// int
|
||||
public int FileRead( string pchFile /*const char **/, IntPtr pvData /*void **/, int cubDataToRead /*int32*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileRead( pchFile, (IntPtr) pvData, cubDataToRead );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle FileReadAsync( string pchFile /*const char **/, uint nOffset /*uint32*/, uint cubToRead /*uint32*/, Action<RemoteStorageFileReadAsyncComplete_t, bool> CallbackFunction = null /*Action<RemoteStorageFileReadAsyncComplete_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_FileReadAsync( pchFile, nOffset, cubToRead );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageFileReadAsyncComplete_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileReadAsyncComplete( SteamAPICall_t hReadCall /*SteamAPICall_t*/, IntPtr pvBuffer /*void **/, uint cubToRead /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileReadAsyncComplete( hReadCall.Value, (IntPtr) pvBuffer, cubToRead );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle FileShare( string pchFile /*const char **/, Action<RemoteStorageFileShareResult_t, bool> CallbackFunction = null /*Action<RemoteStorageFileShareResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_FileShare( pchFile );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageFileShareResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileWrite( string pchFile /*const char **/, IntPtr pvData /*const void **/, int cubData /*int32*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileWrite( pchFile, (IntPtr) pvData, cubData );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle FileWriteAsync( string pchFile /*const char **/, IntPtr pvData /*const void **/, uint cubData /*uint32*/, Action<RemoteStorageFileWriteAsyncComplete_t, bool> CallbackFunction = null /*Action<RemoteStorageFileWriteAsyncComplete_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_FileWriteAsync( pchFile, (IntPtr) pvData, cubData );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageFileWriteAsyncComplete_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileWriteStreamCancel( UGCFileWriteStreamHandle_t writeHandle /*UGCFileWriteStreamHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileWriteStreamCancel( writeHandle.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileWriteStreamClose( UGCFileWriteStreamHandle_t writeHandle /*UGCFileWriteStreamHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileWriteStreamClose( writeHandle.Value );
|
||||
}
|
||||
|
||||
// UGCFileWriteStreamHandle_t
|
||||
public UGCFileWriteStreamHandle_t FileWriteStreamOpen( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileWriteStreamOpen( pchFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool FileWriteStreamWriteChunk( UGCFileWriteStreamHandle_t writeHandle /*UGCFileWriteStreamHandle_t*/, IntPtr pvData /*const void **/, int cubData /*int32*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_FileWriteStreamWriteChunk( writeHandle.Value, (IntPtr) pvData, cubData );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetCachedUGCCount()
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetCachedUGCCount();
|
||||
}
|
||||
|
||||
// UGCHandle_t
|
||||
public UGCHandle_t GetCachedUGCHandle( int iCachedContent /*int32*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetCachedUGCHandle( iCachedContent );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFileCount()
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetFileCount();
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetFileNameAndSize( int iFile /*int*/, out int pnFileSizeInBytes /*int32 **/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamRemoteStorage_GetFileNameAndSize( iFile, out pnFileSizeInBytes );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetFileSize( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetFileSize( pchFile );
|
||||
}
|
||||
|
||||
// long
|
||||
public long GetFileTimestamp( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetFileTimestamp( pchFile );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetPublishedFileDetails( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, uint unMaxSecondsOld /*uint32*/, Action<RemoteStorageGetPublishedFileDetailsResult_t, bool> CallbackFunction = null /*Action<RemoteStorageGetPublishedFileDetailsResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_GetPublishedFileDetails( unPublishedFileId.Value, unMaxSecondsOld );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageGetPublishedFileDetailsResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, Action<RemoteStorageGetPublishedItemVoteDetailsResult_t, bool> CallbackFunction = null /*Action<RemoteStorageGetPublishedItemVoteDetailsResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_GetPublishedItemVoteDetails( unPublishedFileId.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageGetPublishedItemVoteDetailsResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetQuota( out ulong pnTotalBytes /*uint64 **/, out ulong puAvailableBytes /*uint64 **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetQuota( out pnTotalBytes, out puAvailableBytes );
|
||||
}
|
||||
|
||||
// RemoteStoragePlatform
|
||||
public RemoteStoragePlatform GetSyncPlatforms( string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetSyncPlatforms( pchFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetUGCDetails( UGCHandle_t hContent /*UGCHandle_t*/, ref AppId_t pnAppID /*AppId_t **/, out string ppchName /*char ***/, out CSteamID pSteamIDOwner /*class CSteamID **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
ppchName = string.Empty;
|
||||
System.Text.StringBuilder ppchName_sb = Helpers.TakeStringBuilder();
|
||||
int pnFileSizeInBytes = 4096;
|
||||
bSuccess = platform.ISteamRemoteStorage_GetUGCDetails( hContent.Value, ref pnAppID.Value, ppchName_sb, out pnFileSizeInBytes, out pSteamIDOwner.Value );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
ppchName = ppchName_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUGCDownloadProgress( UGCHandle_t hContent /*UGCHandle_t*/, out int pnBytesDownloaded /*int32 **/, out int pnBytesExpected /*int32 **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_GetUGCDownloadProgress( hContent.Value, out pnBytesDownloaded, out pnBytesExpected );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetUserPublishedItemVoteDetails( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, Action<RemoteStorageGetPublishedItemVoteDetailsResult_t, bool> CallbackFunction = null /*Action<RemoteStorageGetPublishedItemVoteDetailsResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_GetUserPublishedItemVoteDetails( unPublishedFileId.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageGetPublishedItemVoteDetailsResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsCloudEnabledForAccount()
|
||||
{
|
||||
return platform.ISteamRemoteStorage_IsCloudEnabledForAccount();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsCloudEnabledForApp()
|
||||
{
|
||||
return platform.ISteamRemoteStorage_IsCloudEnabledForApp();
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
// using: Detect_StringArray
|
||||
public CallbackHandle PublishVideo( WorkshopVideoProvider eVideoProvider /*EWorkshopVideoProvider*/, string pchVideoAccount /*const char **/, string pchVideoIdentifier /*const char **/, string pchPreviewFile /*const char **/, AppId_t nConsumerAppId /*AppId_t*/, string pchTitle /*const char **/, string pchDescription /*const char **/, RemoteStoragePublishedFileVisibility eVisibility /*ERemoteStoragePublishedFileVisibility*/, string[] pTags /*struct SteamParamStringArray_t **/, Action<RemoteStoragePublishFileProgress_t, bool> CallbackFunction = null /*Action<RemoteStoragePublishFileProgress_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
// Create strings
|
||||
var nativeStrings = new IntPtr[pTags.Length];
|
||||
for ( int i = 0; i < pTags.Length; i++ )
|
||||
{
|
||||
nativeStrings[i] = Marshal.StringToHGlobalAnsi( pTags[i] );
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// Create string array
|
||||
var size = Marshal.SizeOf( typeof( IntPtr ) ) * nativeStrings.Length;
|
||||
var nativeArray = Marshal.AllocHGlobal( size );
|
||||
Marshal.Copy( nativeStrings, 0, nativeArray, nativeStrings.Length );
|
||||
|
||||
// Create SteamParamStringArray_t
|
||||
var tags = new SteamParamStringArray_t();
|
||||
tags.Strings = nativeArray;
|
||||
tags.NumStrings = pTags.Length;
|
||||
callback = platform.ISteamRemoteStorage_PublishVideo( eVideoProvider, pchVideoAccount, pchVideoIdentifier, pchPreviewFile, nConsumerAppId.Value, pchTitle, pchDescription, eVisibility, ref tags );
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach ( var x in nativeStrings )
|
||||
Marshal.FreeHGlobal( x );
|
||||
|
||||
}
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStoragePublishFileProgress_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
// using: Detect_StringArray
|
||||
public CallbackHandle PublishWorkshopFile( string pchFile /*const char **/, string pchPreviewFile /*const char **/, AppId_t nConsumerAppId /*AppId_t*/, string pchTitle /*const char **/, string pchDescription /*const char **/, RemoteStoragePublishedFileVisibility eVisibility /*ERemoteStoragePublishedFileVisibility*/, string[] pTags /*struct SteamParamStringArray_t **/, WorkshopFileType eWorkshopFileType /*EWorkshopFileType*/, Action<RemoteStoragePublishFileProgress_t, bool> CallbackFunction = null /*Action<RemoteStoragePublishFileProgress_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
// Create strings
|
||||
var nativeStrings = new IntPtr[pTags.Length];
|
||||
for ( int i = 0; i < pTags.Length; i++ )
|
||||
{
|
||||
nativeStrings[i] = Marshal.StringToHGlobalAnsi( pTags[i] );
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// Create string array
|
||||
var size = Marshal.SizeOf( typeof( IntPtr ) ) * nativeStrings.Length;
|
||||
var nativeArray = Marshal.AllocHGlobal( size );
|
||||
Marshal.Copy( nativeStrings, 0, nativeArray, nativeStrings.Length );
|
||||
|
||||
// Create SteamParamStringArray_t
|
||||
var tags = new SteamParamStringArray_t();
|
||||
tags.Strings = nativeArray;
|
||||
tags.NumStrings = pTags.Length;
|
||||
callback = platform.ISteamRemoteStorage_PublishWorkshopFile( pchFile, pchPreviewFile, nConsumerAppId.Value, pchTitle, pchDescription, eVisibility, ref tags, eWorkshopFileType );
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach ( var x in nativeStrings )
|
||||
Marshal.FreeHGlobal( x );
|
||||
|
||||
}
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStoragePublishFileProgress_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetCloudEnabledForApp( bool bEnabled /*bool*/ )
|
||||
{
|
||||
platform.ISteamRemoteStorage_SetCloudEnabledForApp( bEnabled );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetSyncPlatforms( string pchFile /*const char **/, RemoteStoragePlatform eRemoteStoragePlatform /*ERemoteStoragePlatform*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_SetSyncPlatforms( pchFile, eRemoteStoragePlatform );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle SetUserPublishedFileAction( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, WorkshopFileAction eAction /*EWorkshopFileAction*/, Action<RemoteStorageSetUserPublishedFileActionResult_t, bool> CallbackFunction = null /*Action<RemoteStorageSetUserPublishedFileActionResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_SetUserPublishedFileAction( unPublishedFileId.Value, eAction );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageSetUserPublishedFileActionResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle SubscribePublishedFile( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, Action<RemoteStorageSubscribePublishedFileResult_t, bool> CallbackFunction = null /*Action<RemoteStorageSubscribePublishedFileResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_SubscribePublishedFile( unPublishedFileId.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageSubscribePublishedFileResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle UGCDownload( UGCHandle_t hContent /*UGCHandle_t*/, uint unPriority /*uint32*/, Action<RemoteStorageDownloadUGCResult_t, bool> CallbackFunction = null /*Action<RemoteStorageDownloadUGCResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_UGCDownload( hContent.Value, unPriority );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageDownloadUGCResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle UGCDownloadToLocation( UGCHandle_t hContent /*UGCHandle_t*/, string pchLocation /*const char **/, uint unPriority /*uint32*/, Action<RemoteStorageDownloadUGCResult_t, bool> CallbackFunction = null /*Action<RemoteStorageDownloadUGCResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_UGCDownloadToLocation( hContent.Value, pchLocation, unPriority );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageDownloadUGCResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// int
|
||||
public int UGCRead( UGCHandle_t hContent /*UGCHandle_t*/, IntPtr pvData /*void **/, int cubDataToRead /*int32*/, uint cOffset /*uint32*/, UGCReadAction eAction /*EUGCReadAction*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_UGCRead( hContent.Value, (IntPtr) pvData, cubDataToRead, cOffset, eAction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle UnsubscribePublishedFile( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, Action<RemoteStorageUnsubscribePublishedFileResult_t, bool> CallbackFunction = null /*Action<RemoteStorageUnsubscribePublishedFileResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_UnsubscribePublishedFile( unPublishedFileId.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageUnsubscribePublishedFileResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdatePublishedFileDescription( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, string pchDescription /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_UpdatePublishedFileDescription( updateHandle.Value, pchDescription );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdatePublishedFileFile( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, string pchFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_UpdatePublishedFileFile( updateHandle.Value, pchFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdatePublishedFilePreviewFile( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, string pchPreviewFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_UpdatePublishedFilePreviewFile( updateHandle.Value, pchPreviewFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdatePublishedFileSetChangeDescription( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, string pchChangeDescription /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_UpdatePublishedFileSetChangeDescription( updateHandle.Value, pchChangeDescription );
|
||||
}
|
||||
|
||||
// bool
|
||||
// using: Detect_StringArray
|
||||
public bool UpdatePublishedFileTags( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, string[] pTags /*struct SteamParamStringArray_t **/ )
|
||||
{
|
||||
// Create strings
|
||||
var nativeStrings = new IntPtr[pTags.Length];
|
||||
for ( int i = 0; i < pTags.Length; i++ )
|
||||
{
|
||||
nativeStrings[i] = Marshal.StringToHGlobalAnsi( pTags[i] );
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// Create string array
|
||||
var size = Marshal.SizeOf( typeof( IntPtr ) ) * nativeStrings.Length;
|
||||
var nativeArray = Marshal.AllocHGlobal( size );
|
||||
Marshal.Copy( nativeStrings, 0, nativeArray, nativeStrings.Length );
|
||||
|
||||
// Create SteamParamStringArray_t
|
||||
var tags = new SteamParamStringArray_t();
|
||||
tags.Strings = nativeArray;
|
||||
tags.NumStrings = pTags.Length;
|
||||
return platform.ISteamRemoteStorage_UpdatePublishedFileTags( updateHandle.Value, ref tags );
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach ( var x in nativeStrings )
|
||||
Marshal.FreeHGlobal( x );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdatePublishedFileTitle( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, string pchTitle /*const char **/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_UpdatePublishedFileTitle( updateHandle.Value, pchTitle );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdatePublishedFileVisibility( PublishedFileUpdateHandle_t updateHandle /*PublishedFileUpdateHandle_t*/, RemoteStoragePublishedFileVisibility eVisibility /*ERemoteStoragePublishedFileVisibility*/ )
|
||||
{
|
||||
return platform.ISteamRemoteStorage_UpdatePublishedFileVisibility( updateHandle.Value, eVisibility );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle UpdateUserPublishedItemVote( PublishedFileId_t unPublishedFileId /*PublishedFileId_t*/, bool bVoteUp /*bool*/, Action<RemoteStorageUpdateUserPublishedItemVoteResult_t, bool> CallbackFunction = null /*Action<RemoteStorageUpdateUserPublishedItemVoteResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamRemoteStorage_UpdateUserPublishedItemVote( unPublishedFileId.Value, bVoteUp );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageUpdateUserPublishedItemVoteResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamScreenshots : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamScreenshots( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ScreenshotHandle
|
||||
public ScreenshotHandle AddScreenshotToLibrary( string pchFilename /*const char **/, string pchThumbnailFilename /*const char **/, int nWidth /*int*/, int nHeight /*int*/ )
|
||||
{
|
||||
return platform.ISteamScreenshots_AddScreenshotToLibrary( pchFilename, pchThumbnailFilename, nWidth, nHeight );
|
||||
}
|
||||
|
||||
// ScreenshotHandle
|
||||
public ScreenshotHandle AddVRScreenshotToLibrary( VRScreenshotType eType /*EVRScreenshotType*/, string pchFilename /*const char **/, string pchVRFilename /*const char **/ )
|
||||
{
|
||||
return platform.ISteamScreenshots_AddVRScreenshotToLibrary( eType, pchFilename, pchVRFilename );
|
||||
}
|
||||
|
||||
// void
|
||||
public void HookScreenshots( bool bHook /*bool*/ )
|
||||
{
|
||||
platform.ISteamScreenshots_HookScreenshots( bHook );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsScreenshotsHooked()
|
||||
{
|
||||
return platform.ISteamScreenshots_IsScreenshotsHooked();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLocation( ScreenshotHandle hScreenshot /*ScreenshotHandle*/, string pchLocation /*const char **/ )
|
||||
{
|
||||
return platform.ISteamScreenshots_SetLocation( hScreenshot.Value, pchLocation );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool TagPublishedFile( ScreenshotHandle hScreenshot /*ScreenshotHandle*/, PublishedFileId_t unPublishedFileID /*PublishedFileId_t*/ )
|
||||
{
|
||||
return platform.ISteamScreenshots_TagPublishedFile( hScreenshot.Value, unPublishedFileID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool TagUser( ScreenshotHandle hScreenshot /*ScreenshotHandle*/, CSteamID steamID /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamScreenshots_TagUser( hScreenshot.Value, steamID.Value );
|
||||
}
|
||||
|
||||
// void
|
||||
public void TriggerScreenshot()
|
||||
{
|
||||
platform.ISteamScreenshots_TriggerScreenshot();
|
||||
}
|
||||
|
||||
// ScreenshotHandle
|
||||
public ScreenshotHandle WriteScreenshot( IntPtr pubRGB /*void **/, uint cubRGB /*uint32*/, int nWidth /*int*/, int nHeight /*int*/ )
|
||||
{
|
||||
return platform.ISteamScreenshots_WriteScreenshot( (IntPtr) pubRGB, cubRGB, nWidth, nHeight );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,692 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamUGC : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamUGC( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle AddAppDependency( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, AppId_t nAppID /*AppId_t*/, Action<AddAppDependencyResult_t, bool> CallbackFunction = null /*Action<AddAppDependencyResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_AddAppDependency( nPublishedFileID.Value, nAppID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return AddAppDependencyResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle AddDependency( PublishedFileId_t nParentPublishedFileID /*PublishedFileId_t*/, PublishedFileId_t nChildPublishedFileID /*PublishedFileId_t*/, Action<AddUGCDependencyResult_t, bool> CallbackFunction = null /*Action<AddUGCDependencyResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_AddDependency( nParentPublishedFileID.Value, nChildPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return AddUGCDependencyResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddExcludedTag( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, string pTagName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_AddExcludedTag( handle.Value, pTagName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddItemKeyValueTag( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pchKey /*const char **/, string pchValue /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_AddItemKeyValueTag( handle.Value, pchKey, pchValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddItemPreviewFile( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pszPreviewFile /*const char **/, ItemPreviewType type /*EItemPreviewType*/ )
|
||||
{
|
||||
return platform.ISteamUGC_AddItemPreviewFile( handle.Value, pszPreviewFile, type );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddItemPreviewVideo( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pszVideoID /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_AddItemPreviewVideo( handle.Value, pszVideoID );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle AddItemToFavorites( AppId_t nAppId /*AppId_t*/, PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, Action<UserFavoriteItemsListChanged_t, bool> CallbackFunction = null /*Action<UserFavoriteItemsListChanged_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_AddItemToFavorites( nAppId.Value, nPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return UserFavoriteItemsListChanged_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddRequiredKeyValueTag( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, string pKey /*const char **/, string pValue /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_AddRequiredKeyValueTag( handle.Value, pKey, pValue );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool AddRequiredTag( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, string pTagName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_AddRequiredTag( handle.Value, pTagName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BInitWorkshopForGameServer( DepotId_t unWorkshopDepotID /*DepotId_t*/, string pszFolder /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_BInitWorkshopForGameServer( unWorkshopDepotID.Value, pszFolder );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle CreateItem( AppId_t nConsumerAppId /*AppId_t*/, WorkshopFileType eFileType /*EWorkshopFileType*/, Action<CreateItemResult_t, bool> CallbackFunction = null /*Action<CreateItemResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_CreateItem( nConsumerAppId.Value, eFileType );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return CreateItemResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// UGCQueryHandle_t
|
||||
public UGCQueryHandle_t CreateQueryAllUGCRequest( UGCQuery eQueryType /*EUGCQuery*/, UGCMatchingUGCType eMatchingeMatchingUGCTypeFileType /*EUGCMatchingUGCType*/, AppId_t nCreatorAppID /*AppId_t*/, AppId_t nConsumerAppID /*AppId_t*/, uint unPage /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_CreateQueryAllUGCRequest( eQueryType, eMatchingeMatchingUGCTypeFileType, nCreatorAppID.Value, nConsumerAppID.Value, unPage );
|
||||
}
|
||||
|
||||
// with: Detect_VectorReturn
|
||||
// UGCQueryHandle_t
|
||||
public UGCQueryHandle_t CreateQueryUGCDetailsRequest( PublishedFileId_t[] pvecPublishedFileID /*PublishedFileId_t **/ )
|
||||
{
|
||||
var unNumPublishedFileIDs = (uint) pvecPublishedFileID.Length;
|
||||
fixed ( PublishedFileId_t* pvecPublishedFileID_ptr = pvecPublishedFileID )
|
||||
{
|
||||
return platform.ISteamUGC_CreateQueryUGCDetailsRequest( (IntPtr) pvecPublishedFileID_ptr, unNumPublishedFileIDs );
|
||||
}
|
||||
}
|
||||
|
||||
// UGCQueryHandle_t
|
||||
public UGCQueryHandle_t CreateQueryUserUGCRequest( AccountID_t unAccountID /*AccountID_t*/, UserUGCList eListType /*EUserUGCList*/, UGCMatchingUGCType eMatchingUGCType /*EUGCMatchingUGCType*/, UserUGCListSortOrder eSortOrder /*EUserUGCListSortOrder*/, AppId_t nCreatorAppID /*AppId_t*/, AppId_t nConsumerAppID /*AppId_t*/, uint unPage /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_CreateQueryUserUGCRequest( unAccountID.Value, eListType, eMatchingUGCType, eSortOrder, nCreatorAppID.Value, nConsumerAppID.Value, unPage );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle DeleteItem( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, Action<DeleteItemResult_t, bool> CallbackFunction = null /*Action<DeleteItemResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_DeleteItem( nPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return DeleteItemResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool DownloadItem( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, bool bHighPriority /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_DownloadItem( nPublishedFileID.Value, bHighPriority );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetAppDependencies( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, Action<GetAppDependenciesResult_t, bool> CallbackFunction = null /*Action<GetAppDependenciesResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_GetAppDependencies( nPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return GetAppDependenciesResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetItemDownloadInfo( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, out ulong punBytesDownloaded /*uint64 **/, out ulong punBytesTotal /*uint64 **/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetItemDownloadInfo( nPublishedFileID.Value, out punBytesDownloaded, out punBytesTotal );
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetItemInstallInfo( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, out ulong punSizeOnDisk /*uint64 **/, out string pchFolder /*char **/, out uint punTimeStamp /*uint32 **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchFolder = string.Empty;
|
||||
System.Text.StringBuilder pchFolder_sb = Helpers.TakeStringBuilder();
|
||||
uint cchFolderSize = 4096;
|
||||
bSuccess = platform.ISteamUGC_GetItemInstallInfo( nPublishedFileID.Value, out punSizeOnDisk, pchFolder_sb, cchFolderSize, out punTimeStamp );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchFolder = pchFolder_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetItemState( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetItemState( nPublishedFileID.Value );
|
||||
}
|
||||
|
||||
// ItemUpdateStatus
|
||||
public ItemUpdateStatus GetItemUpdateProgress( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, out ulong punBytesProcessed /*uint64 **/, out ulong punBytesTotal /*uint64 **/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetItemUpdateProgress( handle.Value, out punBytesProcessed, out punBytesTotal );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetNumSubscribedItems()
|
||||
{
|
||||
return platform.ISteamUGC_GetNumSubscribedItems();
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetQueryUGCAdditionalPreview( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/, uint previewIndex /*uint32*/, out string pchURLOrVideoID /*char **/, out string pchOriginalFileName /*char **/, out ItemPreviewType pPreviewType /*EItemPreviewType **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchURLOrVideoID = string.Empty;
|
||||
System.Text.StringBuilder pchURLOrVideoID_sb = Helpers.TakeStringBuilder();
|
||||
uint cchURLSize = 4096;
|
||||
pchOriginalFileName = string.Empty;
|
||||
System.Text.StringBuilder pchOriginalFileName_sb = Helpers.TakeStringBuilder();
|
||||
uint cchOriginalFileNameSize = 4096;
|
||||
bSuccess = platform.ISteamUGC_GetQueryUGCAdditionalPreview( handle.Value, index, previewIndex, pchURLOrVideoID_sb, cchURLSize, pchOriginalFileName_sb, cchOriginalFileNameSize, out pPreviewType );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchOriginalFileName = pchOriginalFileName_sb.ToString();
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchURLOrVideoID = pchURLOrVideoID_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetQueryUGCChildren( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/, PublishedFileId_t* pvecPublishedFileID /*PublishedFileId_t **/, uint cMaxEntries /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetQueryUGCChildren( handle.Value, index, (IntPtr) pvecPublishedFileID, cMaxEntries );
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/, uint keyValueTagIndex /*uint32*/, out string pchKey /*char **/, out string pchValue /*char **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchKey = string.Empty;
|
||||
System.Text.StringBuilder pchKey_sb = Helpers.TakeStringBuilder();
|
||||
uint cchKeySize = 4096;
|
||||
pchValue = string.Empty;
|
||||
System.Text.StringBuilder pchValue_sb = Helpers.TakeStringBuilder();
|
||||
uint cchValueSize = 4096;
|
||||
bSuccess = platform.ISteamUGC_GetQueryUGCKeyValueTag( handle.Value, index, keyValueTagIndex, pchKey_sb, cchKeySize, pchValue_sb, cchValueSize );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchValue = pchValue_sb.ToString();
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchKey = pchKey_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetQueryUGCMetadata( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/, out string pchMetadata /*char **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchMetadata = string.Empty;
|
||||
System.Text.StringBuilder pchMetadata_sb = Helpers.TakeStringBuilder();
|
||||
uint cchMetadatasize = 4096;
|
||||
bSuccess = platform.ISteamUGC_GetQueryUGCMetadata( handle.Value, index, pchMetadata_sb, cchMetadatasize );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchMetadata = pchMetadata_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetQueryUGCNumAdditionalPreviews( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetQueryUGCNumAdditionalPreviews( handle.Value, index );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetQueryUGCNumKeyValueTags( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetQueryUGCNumKeyValueTags( handle.Value, index );
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch False
|
||||
public bool GetQueryUGCPreviewURL( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/, out string pchURL /*char **/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
pchURL = string.Empty;
|
||||
System.Text.StringBuilder pchURL_sb = Helpers.TakeStringBuilder();
|
||||
uint cchURLSize = 4096;
|
||||
bSuccess = platform.ISteamUGC_GetQueryUGCPreviewURL( handle.Value, index, pchURL_sb, cchURLSize );
|
||||
if ( !bSuccess ) return bSuccess;
|
||||
pchURL = pchURL_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetQueryUGCResult( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/, ref SteamUGCDetails_t pDetails /*struct SteamUGCDetails_t **/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetQueryUGCResult( handle.Value, index, ref pDetails );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetQueryUGCStatistic( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint index /*uint32*/, ItemStatistic eStatType /*EItemStatistic*/, out ulong pStatValue /*uint64 **/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetQueryUGCStatistic( handle.Value, index, eStatType, out pStatValue );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetSubscribedItems( PublishedFileId_t* pvecPublishedFileID /*PublishedFileId_t **/, uint cMaxEntries /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_GetSubscribedItems( (IntPtr) pvecPublishedFileID, cMaxEntries );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetUserItemVote( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, Action<GetUserItemVoteResult_t, bool> CallbackFunction = null /*Action<GetUserItemVoteResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_GetUserItemVote( nPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return GetUserItemVoteResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ReleaseQueryUGCRequest( UGCQueryHandle_t handle /*UGCQueryHandle_t*/ )
|
||||
{
|
||||
return platform.ISteamUGC_ReleaseQueryUGCRequest( handle.Value );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RemoveAppDependency( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, AppId_t nAppID /*AppId_t*/, Action<RemoveAppDependencyResult_t, bool> CallbackFunction = null /*Action<RemoveAppDependencyResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_RemoveAppDependency( nPublishedFileID.Value, nAppID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoveAppDependencyResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RemoveDependency( PublishedFileId_t nParentPublishedFileID /*PublishedFileId_t*/, PublishedFileId_t nChildPublishedFileID /*PublishedFileId_t*/, Action<RemoveUGCDependencyResult_t, bool> CallbackFunction = null /*Action<RemoveUGCDependencyResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_RemoveDependency( nParentPublishedFileID.Value, nChildPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoveUGCDependencyResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RemoveItemFromFavorites( AppId_t nAppId /*AppId_t*/, PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, Action<UserFavoriteItemsListChanged_t, bool> CallbackFunction = null /*Action<UserFavoriteItemsListChanged_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_RemoveItemFromFavorites( nAppId.Value, nPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return UserFavoriteItemsListChanged_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RemoveItemKeyValueTags( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pchKey /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_RemoveItemKeyValueTags( handle.Value, pchKey );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RemoveItemPreview( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, uint index /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_RemoveItemPreview( handle.Value, index );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public SteamAPICall_t RequestUGCDetails( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, uint unMaxAgeSeconds /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_RequestUGCDetails( nPublishedFileID.Value, unMaxAgeSeconds );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle SendQueryUGCRequest( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, Action<SteamUGCQueryCompleted_t, bool> CallbackFunction = null /*Action<SteamUGCQueryCompleted_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_SendQueryUGCRequest( handle.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return SteamUGCQueryCompleted_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetAllowCachedResponse( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint unMaxAgeSeconds /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetAllowCachedResponse( handle.Value, unMaxAgeSeconds );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetCloudFileNameFilter( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, string pMatchCloudFileName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetCloudFileNameFilter( handle.Value, pMatchCloudFileName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetItemContent( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pszContentFolder /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetItemContent( handle.Value, pszContentFolder );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetItemDescription( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pchDescription /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetItemDescription( handle.Value, pchDescription );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetItemMetadata( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pchMetaData /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetItemMetadata( handle.Value, pchMetaData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetItemPreview( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pszPreviewFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetItemPreview( handle.Value, pszPreviewFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
// using: Detect_StringArray
|
||||
public bool SetItemTags( UGCUpdateHandle_t updateHandle /*UGCUpdateHandle_t*/, string[] pTags /*const struct SteamParamStringArray_t **/ )
|
||||
{
|
||||
// Create strings
|
||||
var nativeStrings = new IntPtr[pTags.Length];
|
||||
for ( int i = 0; i < pTags.Length; i++ )
|
||||
{
|
||||
nativeStrings[i] = Marshal.StringToHGlobalAnsi( pTags[i] );
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// Create string array
|
||||
var size = Marshal.SizeOf( typeof( IntPtr ) ) * nativeStrings.Length;
|
||||
var nativeArray = Marshal.AllocHGlobal( size );
|
||||
Marshal.Copy( nativeStrings, 0, nativeArray, nativeStrings.Length );
|
||||
|
||||
// Create SteamParamStringArray_t
|
||||
var tags = new SteamParamStringArray_t();
|
||||
tags.Strings = nativeArray;
|
||||
tags.NumStrings = pTags.Length;
|
||||
return platform.ISteamUGC_SetItemTags( updateHandle.Value, ref tags );
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach ( var x in nativeStrings )
|
||||
Marshal.FreeHGlobal( x );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetItemTitle( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pchTitle /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetItemTitle( handle.Value, pchTitle );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetItemUpdateLanguage( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pchLanguage /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetItemUpdateLanguage( handle.Value, pchLanguage );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetItemVisibility( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, RemoteStoragePublishedFileVisibility eVisibility /*ERemoteStoragePublishedFileVisibility*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetItemVisibility( handle.Value, eVisibility );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetLanguage( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, string pchLanguage /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetLanguage( handle.Value, pchLanguage );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetMatchAnyTag( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bMatchAnyTag /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetMatchAnyTag( handle.Value, bMatchAnyTag );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetRankedByTrendDays( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint unDays /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetRankedByTrendDays( handle.Value, unDays );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnAdditionalPreviews( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bReturnAdditionalPreviews /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnAdditionalPreviews( handle.Value, bReturnAdditionalPreviews );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnChildren( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bReturnChildren /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnChildren( handle.Value, bReturnChildren );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnKeyValueTags( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bReturnKeyValueTags /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnKeyValueTags( handle.Value, bReturnKeyValueTags );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnLongDescription( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bReturnLongDescription /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnLongDescription( handle.Value, bReturnLongDescription );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnMetadata( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bReturnMetadata /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnMetadata( handle.Value, bReturnMetadata );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnOnlyIDs( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bReturnOnlyIDs /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnOnlyIDs( handle.Value, bReturnOnlyIDs );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnPlaytimeStats( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, uint unDays /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnPlaytimeStats( handle.Value, unDays );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetReturnTotalOnly( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, bool bReturnTotalOnly /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetReturnTotalOnly( handle.Value, bReturnTotalOnly );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetSearchText( UGCQueryHandle_t handle /*UGCQueryHandle_t*/, string pSearchText /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_SetSearchText( handle.Value, pSearchText );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle SetUserItemVote( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, bool bVoteUp /*bool*/, Action<SetUserItemVoteResult_t, bool> CallbackFunction = null /*Action<SetUserItemVoteResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_SetUserItemVote( nPublishedFileID.Value, bVoteUp );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return SetUserItemVoteResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// UGCUpdateHandle_t
|
||||
public UGCUpdateHandle_t StartItemUpdate( AppId_t nConsumerAppId /*AppId_t*/, PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/ )
|
||||
{
|
||||
return platform.ISteamUGC_StartItemUpdate( nConsumerAppId.Value, nPublishedFileID.Value );
|
||||
}
|
||||
|
||||
// with: Detect_VectorReturn
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle StartPlaytimeTracking( PublishedFileId_t[] pvecPublishedFileID /*PublishedFileId_t **/, Action<StartPlaytimeTrackingResult_t, bool> CallbackFunction = null /*Action<StartPlaytimeTrackingResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
var unNumPublishedFileIDs = (uint) pvecPublishedFileID.Length;
|
||||
fixed ( PublishedFileId_t* pvecPublishedFileID_ptr = pvecPublishedFileID )
|
||||
{
|
||||
callback = platform.ISteamUGC_StartPlaytimeTracking( (IntPtr) pvecPublishedFileID_ptr, unNumPublishedFileIDs );
|
||||
}
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return StartPlaytimeTrackingResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// with: Detect_VectorReturn
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle StopPlaytimeTracking( PublishedFileId_t[] pvecPublishedFileID /*PublishedFileId_t **/, Action<StopPlaytimeTrackingResult_t, bool> CallbackFunction = null /*Action<StopPlaytimeTrackingResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
var unNumPublishedFileIDs = (uint) pvecPublishedFileID.Length;
|
||||
fixed ( PublishedFileId_t* pvecPublishedFileID_ptr = pvecPublishedFileID )
|
||||
{
|
||||
callback = platform.ISteamUGC_StopPlaytimeTracking( (IntPtr) pvecPublishedFileID_ptr, unNumPublishedFileIDs );
|
||||
}
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return StopPlaytimeTrackingResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle StopPlaytimeTrackingForAllItems( Action<StopPlaytimeTrackingResult_t, bool> CallbackFunction = null /*Action<StopPlaytimeTrackingResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_StopPlaytimeTrackingForAllItems();
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return StopPlaytimeTrackingResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle SubmitItemUpdate( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, string pchChangeNote /*const char **/, Action<SubmitItemUpdateResult_t, bool> CallbackFunction = null /*Action<SubmitItemUpdateResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_SubmitItemUpdate( handle.Value, pchChangeNote );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return SubmitItemUpdateResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle SubscribeItem( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, Action<RemoteStorageSubscribePublishedFileResult_t, bool> CallbackFunction = null /*Action<RemoteStorageSubscribePublishedFileResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_SubscribeItem( nPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageSubscribePublishedFileResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SuspendDownloads( bool bSuspend /*bool*/ )
|
||||
{
|
||||
platform.ISteamUGC_SuspendDownloads( bSuspend );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle UnsubscribeItem( PublishedFileId_t nPublishedFileID /*PublishedFileId_t*/, Action<RemoteStorageUnsubscribePublishedFileResult_t, bool> CallbackFunction = null /*Action<RemoteStorageUnsubscribePublishedFileResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUGC_UnsubscribeItem( nPublishedFileID.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return RemoteStorageUnsubscribePublishedFileResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateItemPreviewFile( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, uint index /*uint32*/, string pszPreviewFile /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_UpdateItemPreviewFile( handle.Value, index, pszPreviewFile );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateItemPreviewVideo( UGCUpdateHandle_t handle /*UGCUpdateHandle_t*/, uint index /*uint32*/, string pszVideoID /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUGC_UpdateItemPreviewVideo( handle.Value, index, pszVideoID );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamUser : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamUser( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// void
|
||||
public void AdvertiseGame( CSteamID steamIDGameServer /*class CSteamID*/, uint unIPServer /*uint32*/, ushort usPortServer /*uint16*/ )
|
||||
{
|
||||
platform.ISteamUser_AdvertiseGame( steamIDGameServer.Value, unIPServer, usPortServer );
|
||||
}
|
||||
|
||||
// BeginAuthSessionResult
|
||||
public BeginAuthSessionResult BeginAuthSession( IntPtr pAuthTicket /*const void **/, int cbAuthTicket /*int*/, CSteamID steamID /*class CSteamID*/ )
|
||||
{
|
||||
return platform.ISteamUser_BeginAuthSession( (IntPtr) pAuthTicket, cbAuthTicket, steamID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsBehindNAT()
|
||||
{
|
||||
return platform.ISteamUser_BIsBehindNAT();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsPhoneIdentifying()
|
||||
{
|
||||
return platform.ISteamUser_BIsPhoneIdentifying();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsPhoneRequiringVerification()
|
||||
{
|
||||
return platform.ISteamUser_BIsPhoneRequiringVerification();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsPhoneVerified()
|
||||
{
|
||||
return platform.ISteamUser_BIsPhoneVerified();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BIsTwoFactorEnabled()
|
||||
{
|
||||
return platform.ISteamUser_BIsTwoFactorEnabled();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BLoggedOn()
|
||||
{
|
||||
return platform.ISteamUser_BLoggedOn();
|
||||
}
|
||||
|
||||
// void
|
||||
public void CancelAuthTicket( HAuthTicket hAuthTicket /*HAuthTicket*/ )
|
||||
{
|
||||
platform.ISteamUser_CancelAuthTicket( hAuthTicket.Value );
|
||||
}
|
||||
|
||||
// VoiceResult
|
||||
public VoiceResult DecompressVoice( IntPtr pCompressed /*const void **/, uint cbCompressed /*uint32*/, IntPtr pDestBuffer /*void **/, uint cbDestBufferSize /*uint32*/, out uint nBytesWritten /*uint32 **/, uint nDesiredSampleRate /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUser_DecompressVoice( (IntPtr) pCompressed, cbCompressed, (IntPtr) pDestBuffer, cbDestBufferSize, out nBytesWritten, nDesiredSampleRate );
|
||||
}
|
||||
|
||||
// void
|
||||
public void EndAuthSession( CSteamID steamID /*class CSteamID*/ )
|
||||
{
|
||||
platform.ISteamUser_EndAuthSession( steamID.Value );
|
||||
}
|
||||
|
||||
// HAuthTicket
|
||||
public HAuthTicket GetAuthSessionTicket( IntPtr pTicket /*void **/, int cbMaxTicket /*int*/, out uint pcbTicket /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamUser_GetAuthSessionTicket( (IntPtr) pTicket, cbMaxTicket, out pcbTicket );
|
||||
}
|
||||
|
||||
// VoiceResult
|
||||
public VoiceResult GetAvailableVoice( out uint pcbCompressed /*uint32 **/, out uint pcbUncompressed_Deprecated /*uint32 **/, uint nUncompressedVoiceDesiredSampleRate_Deprecated /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUser_GetAvailableVoice( out pcbCompressed, out pcbUncompressed_Deprecated, nUncompressedVoiceDesiredSampleRate_Deprecated );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetEncryptedAppTicket( IntPtr pTicket /*void **/, int cbMaxTicket /*int*/, out uint pcbTicket /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamUser_GetEncryptedAppTicket( (IntPtr) pTicket, cbMaxTicket, out pcbTicket );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetGameBadgeLevel( int nSeries /*int*/, bool bFoil /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUser_GetGameBadgeLevel( nSeries, bFoil );
|
||||
}
|
||||
|
||||
// HSteamUser
|
||||
public HSteamUser GetHSteamUser()
|
||||
{
|
||||
return platform.ISteamUser_GetHSteamUser();
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetPlayerSteamLevel()
|
||||
{
|
||||
return platform.ISteamUser_GetPlayerSteamLevel();
|
||||
}
|
||||
|
||||
// ulong
|
||||
public ulong GetSteamID()
|
||||
{
|
||||
return platform.ISteamUser_GetSteamID();
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch True
|
||||
public string GetUserDataFolder()
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
System.Text.StringBuilder pchBuffer_sb = Helpers.TakeStringBuilder();
|
||||
int cubBuffer = 4096;
|
||||
bSuccess = platform.ISteamUser_GetUserDataFolder( pchBuffer_sb, cubBuffer );
|
||||
if ( !bSuccess ) return null;
|
||||
return pchBuffer_sb.ToString();
|
||||
}
|
||||
|
||||
// VoiceResult
|
||||
public VoiceResult GetVoice( bool bWantCompressed /*bool*/, IntPtr pDestBuffer /*void **/, uint cbDestBufferSize /*uint32*/, out uint nBytesWritten /*uint32 **/, bool bWantUncompressed_Deprecated /*bool*/, IntPtr pUncompressedDestBuffer_Deprecated /*void **/, uint cbUncompressedDestBufferSize_Deprecated /*uint32*/, out uint nUncompressBytesWritten_Deprecated /*uint32 **/, uint nUncompressedVoiceDesiredSampleRate_Deprecated /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUser_GetVoice( bWantCompressed, (IntPtr) pDestBuffer, cbDestBufferSize, out nBytesWritten, bWantUncompressed_Deprecated, (IntPtr) pUncompressedDestBuffer_Deprecated, cbUncompressedDestBufferSize_Deprecated, out nUncompressBytesWritten_Deprecated, nUncompressedVoiceDesiredSampleRate_Deprecated );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetVoiceOptimalSampleRate()
|
||||
{
|
||||
return platform.ISteamUser_GetVoiceOptimalSampleRate();
|
||||
}
|
||||
|
||||
// int
|
||||
public int InitiateGameConnection( IntPtr pAuthBlob /*void **/, int cbMaxAuthBlob /*int*/, CSteamID steamIDGameServer /*class CSteamID*/, uint unIPServer /*uint32*/, ushort usPortServer /*uint16*/, bool bSecure /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUser_InitiateGameConnection( (IntPtr) pAuthBlob, cbMaxAuthBlob, steamIDGameServer.Value, unIPServer, usPortServer, bSecure );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestEncryptedAppTicket( IntPtr pDataToInclude /*void **/, int cbDataToInclude /*int*/, Action<EncryptedAppTicketResponse_t, bool> CallbackFunction = null /*Action<EncryptedAppTicketResponse_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUser_RequestEncryptedAppTicket( (IntPtr) pDataToInclude, cbDataToInclude );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return EncryptedAppTicketResponse_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestStoreAuthURL( string pchRedirectURL /*const char **/, Action<StoreAuthURLResponse_t, bool> CallbackFunction = null /*Action<StoreAuthURLResponse_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUser_RequestStoreAuthURL( pchRedirectURL );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return StoreAuthURLResponse_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// void
|
||||
public void StartVoiceRecording()
|
||||
{
|
||||
platform.ISteamUser_StartVoiceRecording();
|
||||
}
|
||||
|
||||
// void
|
||||
public void StopVoiceRecording()
|
||||
{
|
||||
platform.ISteamUser_StopVoiceRecording();
|
||||
}
|
||||
|
||||
// void
|
||||
public void TerminateGameConnection( uint unIPServer /*uint32*/, ushort usPortServer /*uint16*/ )
|
||||
{
|
||||
platform.ISteamUser_TerminateGameConnection( unIPServer, usPortServer );
|
||||
}
|
||||
|
||||
// void
|
||||
public void TrackAppUsageEvent( CGameID gameID /*class CGameID*/, int eAppUsageEvent /*int*/, string pchExtraInfo /*const char **/ )
|
||||
{
|
||||
platform.ISteamUser_TrackAppUsageEvent( gameID.Value, eAppUsageEvent, pchExtraInfo );
|
||||
}
|
||||
|
||||
// UserHasLicenseForAppResult
|
||||
public UserHasLicenseForAppResult UserHasLicenseForApp( CSteamID steamID /*class CSteamID*/, AppId_t appID /*AppId_t*/ )
|
||||
{
|
||||
return platform.ISteamUser_UserHasLicenseForApp( steamID.Value, appID.Value );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamUserStats : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamUserStats( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle AttachLeaderboardUGC( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/, UGCHandle_t hUGC /*UGCHandle_t*/, Action<LeaderboardUGCSet_t, bool> CallbackFunction = null /*Action<LeaderboardUGCSet_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_AttachLeaderboardUGC( hSteamLeaderboard.Value, hUGC.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LeaderboardUGCSet_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ClearAchievement( string pchName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_ClearAchievement( pchName );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle DownloadLeaderboardEntries( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/, LeaderboardDataRequest eLeaderboardDataRequest /*ELeaderboardDataRequest*/, int nRangeStart /*int*/, int nRangeEnd /*int*/, Action<LeaderboardScoresDownloaded_t, bool> CallbackFunction = null /*Action<LeaderboardScoresDownloaded_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_DownloadLeaderboardEntries( hSteamLeaderboard.Value, eLeaderboardDataRequest, nRangeStart, nRangeEnd );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LeaderboardScoresDownloaded_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle DownloadLeaderboardEntriesForUsers( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/, IntPtr prgUsers /*class CSteamID **/, int cUsers /*int*/, Action<LeaderboardScoresDownloaded_t, bool> CallbackFunction = null /*Action<LeaderboardScoresDownloaded_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_DownloadLeaderboardEntriesForUsers( hSteamLeaderboard.Value, (IntPtr) prgUsers, cUsers );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LeaderboardScoresDownloaded_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle FindLeaderboard( string pchLeaderboardName /*const char **/, Action<LeaderboardFindResult_t, bool> CallbackFunction = null /*Action<LeaderboardFindResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_FindLeaderboard( pchLeaderboardName );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LeaderboardFindResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle FindOrCreateLeaderboard( string pchLeaderboardName /*const char **/, LeaderboardSortMethod eLeaderboardSortMethod /*ELeaderboardSortMethod*/, LeaderboardDisplayType eLeaderboardDisplayType /*ELeaderboardDisplayType*/, Action<LeaderboardFindResult_t, bool> CallbackFunction = null /*Action<LeaderboardFindResult_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_FindOrCreateLeaderboard( pchLeaderboardName, eLeaderboardSortMethod, eLeaderboardDisplayType );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LeaderboardFindResult_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetAchievement( string pchName /*const char **/, ref bool pbAchieved /*bool **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetAchievement( pchName, ref pbAchieved );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetAchievementAchievedPercent( string pchName /*const char **/, out float pflPercent /*float **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetAchievementAchievedPercent( pchName, out pflPercent );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetAchievementAndUnlockTime( string pchName /*const char **/, ref bool pbAchieved /*bool **/, out uint punUnlockTime /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetAchievementAndUnlockTime( pchName, ref pbAchieved, out punUnlockTime );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetAchievementDisplayAttribute( string pchName /*const char **/, string pchKey /*const char **/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamUserStats_GetAchievementDisplayAttribute( pchName, pchKey );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetAchievementIcon( string pchName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetAchievementIcon( pchName );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetAchievementName( uint iAchievement /*uint32*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamUserStats_GetAchievementName( iAchievement );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetDownloadedLeaderboardEntry( SteamLeaderboardEntries_t hSteamLeaderboardEntries /*SteamLeaderboardEntries_t*/, int index /*int*/, ref LeaderboardEntry_t pLeaderboardEntry /*struct LeaderboardEntry_t **/, IntPtr pDetails /*int32 **/, int cDetailsMax /*int*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetDownloadedLeaderboardEntry( hSteamLeaderboardEntries.Value, index, ref pLeaderboardEntry, (IntPtr) pDetails, cDetailsMax );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetGlobalStat( string pchStatName /*const char **/, out long pData /*int64 **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetGlobalStat( pchStatName, out pData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetGlobalStat0( string pchStatName /*const char **/, out double pData /*double **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetGlobalStat0( pchStatName, out pData );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetGlobalStatHistory( string pchStatName /*const char **/, out long pData /*int64 **/, uint cubData /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetGlobalStatHistory( pchStatName, out pData, cubData );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetGlobalStatHistory0( string pchStatName /*const char **/, out double pData /*double **/, uint cubData /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetGlobalStatHistory0( pchStatName, out pData, cubData );
|
||||
}
|
||||
|
||||
// LeaderboardDisplayType
|
||||
public LeaderboardDisplayType GetLeaderboardDisplayType( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetLeaderboardDisplayType( hSteamLeaderboard.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
public int GetLeaderboardEntryCount( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetLeaderboardEntryCount( hSteamLeaderboard.Value );
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetLeaderboardName( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/ )
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamUserStats_GetLeaderboardName( hSteamLeaderboard.Value );
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// LeaderboardSortMethod
|
||||
public LeaderboardSortMethod GetLeaderboardSortMethod( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetLeaderboardSortMethod( hSteamLeaderboard.Value );
|
||||
}
|
||||
|
||||
// int
|
||||
// with: Detect_StringFetch False
|
||||
public int GetMostAchievedAchievementInfo( out string pchName /*char **/, out float pflPercent /*float **/, ref bool pbAchieved /*bool **/ )
|
||||
{
|
||||
int bSuccess = default( int );
|
||||
pchName = string.Empty;
|
||||
System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder();
|
||||
uint unNameBufLen = 4096;
|
||||
bSuccess = platform.ISteamUserStats_GetMostAchievedAchievementInfo( pchName_sb, unNameBufLen, out pflPercent, ref pbAchieved );
|
||||
if ( bSuccess <= 0 ) return bSuccess;
|
||||
pchName = pchName_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// int
|
||||
// with: Detect_StringFetch False
|
||||
public int GetNextMostAchievedAchievementInfo( int iIteratorPrevious /*int*/, out string pchName /*char **/, out float pflPercent /*float **/, ref bool pbAchieved /*bool **/ )
|
||||
{
|
||||
int bSuccess = default( int );
|
||||
pchName = string.Empty;
|
||||
System.Text.StringBuilder pchName_sb = Helpers.TakeStringBuilder();
|
||||
uint unNameBufLen = 4096;
|
||||
bSuccess = platform.ISteamUserStats_GetNextMostAchievedAchievementInfo( iIteratorPrevious, pchName_sb, unNameBufLen, out pflPercent, ref pbAchieved );
|
||||
if ( bSuccess <= 0 ) return bSuccess;
|
||||
pchName = pchName_sb.ToString();
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetNumAchievements()
|
||||
{
|
||||
return platform.ISteamUserStats_GetNumAchievements();
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle GetNumberOfCurrentPlayers( Action<NumberOfCurrentPlayers_t, bool> CallbackFunction = null /*Action<NumberOfCurrentPlayers_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_GetNumberOfCurrentPlayers();
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return NumberOfCurrentPlayers_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetStat( string pchName /*const char **/, out int pData /*int32 **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetStat( pchName, out pData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetStat0( string pchName /*const char **/, out float pData /*float **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetStat0( pchName, out pData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUserAchievement( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, ref bool pbAchieved /*bool **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetUserAchievement( steamIDUser.Value, pchName, ref pbAchieved );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUserAchievementAndUnlockTime( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, ref bool pbAchieved /*bool **/, out uint punUnlockTime /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetUserAchievementAndUnlockTime( steamIDUser.Value, pchName, ref pbAchieved, out punUnlockTime );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUserStat( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, out int pData /*int32 **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetUserStat( steamIDUser.Value, pchName, out pData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetUserStat0( CSteamID steamIDUser /*class CSteamID*/, string pchName /*const char **/, out float pData /*float **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_GetUserStat0( steamIDUser.Value, pchName, out pData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IndicateAchievementProgress( string pchName /*const char **/, uint nCurProgress /*uint32*/, uint nMaxProgress /*uint32*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_IndicateAchievementProgress( pchName, nCurProgress, nMaxProgress );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool RequestCurrentStats()
|
||||
{
|
||||
return platform.ISteamUserStats_RequestCurrentStats();
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestGlobalAchievementPercentages( Action<GlobalAchievementPercentagesReady_t, bool> CallbackFunction = null /*Action<GlobalAchievementPercentagesReady_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_RequestGlobalAchievementPercentages();
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return GlobalAchievementPercentagesReady_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestGlobalStats( int nHistoryDays /*int*/, Action<GlobalStatsReceived_t, bool> CallbackFunction = null /*Action<GlobalStatsReceived_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_RequestGlobalStats( nHistoryDays );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return GlobalStatsReceived_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle RequestUserStats( CSteamID steamIDUser /*class CSteamID*/, Action<UserStatsReceived_t, bool> CallbackFunction = null /*Action<UserStatsReceived_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_RequestUserStats( steamIDUser.Value );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return UserStatsReceived_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ResetAllStats( bool bAchievementsToo /*bool*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_ResetAllStats( bAchievementsToo );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetAchievement( string pchName /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUserStats_SetAchievement( pchName );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetStat( string pchName /*const char **/, int nData /*int32*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_SetStat( pchName, nData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool SetStat0( string pchName /*const char **/, float fData /*float*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_SetStat0( pchName, fData );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool StoreStats()
|
||||
{
|
||||
return platform.ISteamUserStats_StoreStats();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool UpdateAvgRateStat( string pchName /*const char **/, float flCountThisSession /*float*/, double dSessionLength /*double*/ )
|
||||
{
|
||||
return platform.ISteamUserStats_UpdateAvgRateStat( pchName, flCountThisSession, dSessionLength );
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle UploadLeaderboardScore( SteamLeaderboard_t hSteamLeaderboard /*SteamLeaderboard_t*/, LeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod /*ELeaderboardUploadScoreMethod*/, int nScore /*int32*/, int[] pScoreDetails /*const int32 **/, int cScoreDetailsCount /*int*/, Action<LeaderboardScoreUploaded_t, bool> CallbackFunction = null /*Action<LeaderboardScoreUploaded_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUserStats_UploadLeaderboardScore( hSteamLeaderboard.Value, eLeaderboardUploadScoreMethod, nScore, pScoreDetails, cScoreDetailsCount );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return LeaderboardScoreUploaded_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamUtils : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamUtils( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool BOverlayNeedsPresent()
|
||||
{
|
||||
return platform.ISteamUtils_BOverlayNeedsPresent();
|
||||
}
|
||||
|
||||
// SteamAPICall_t
|
||||
public CallbackHandle CheckFileSignature( string szFileName /*const char **/, Action<CheckFileSignature_t, bool> CallbackFunction = null /*Action<CheckFileSignature_t, bool>*/ )
|
||||
{
|
||||
SteamAPICall_t callback = 0;
|
||||
callback = platform.ISteamUtils_CheckFileSignature( szFileName );
|
||||
|
||||
if ( CallbackFunction == null ) return null;
|
||||
if ( callback == 0 ) return null;
|
||||
|
||||
return CheckFileSignature_t.CallResult( steamworks, callback, CallbackFunction );
|
||||
}
|
||||
|
||||
// SteamAPICallFailure
|
||||
public SteamAPICallFailure GetAPICallFailureReason( SteamAPICall_t hSteamAPICall /*SteamAPICall_t*/ )
|
||||
{
|
||||
return platform.ISteamUtils_GetAPICallFailureReason( hSteamAPICall.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetAPICallResult( SteamAPICall_t hSteamAPICall /*SteamAPICall_t*/, IntPtr pCallback /*void **/, int cubCallback /*int*/, int iCallbackExpected /*int*/, ref bool pbFailed /*bool **/ )
|
||||
{
|
||||
return platform.ISteamUtils_GetAPICallResult( hSteamAPICall.Value, (IntPtr) pCallback, cubCallback, iCallbackExpected, ref pbFailed );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetAppID()
|
||||
{
|
||||
return platform.ISteamUtils_GetAppID();
|
||||
}
|
||||
|
||||
// Universe
|
||||
public Universe GetConnectedUniverse()
|
||||
{
|
||||
return platform.ISteamUtils_GetConnectedUniverse();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetCSERIPPort( out uint unIP /*uint32 **/, out ushort usPort /*uint16 **/ )
|
||||
{
|
||||
return platform.ISteamUtils_GetCSERIPPort( out unIP, out usPort );
|
||||
}
|
||||
|
||||
// byte
|
||||
public byte GetCurrentBatteryPower()
|
||||
{
|
||||
return platform.ISteamUtils_GetCurrentBatteryPower();
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch True
|
||||
public string GetEnteredGamepadTextInput()
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
System.Text.StringBuilder pchText_sb = Helpers.TakeStringBuilder();
|
||||
uint cchText = 4096;
|
||||
bSuccess = platform.ISteamUtils_GetEnteredGamepadTextInput( pchText_sb, cchText );
|
||||
if ( !bSuccess ) return null;
|
||||
return pchText_sb.ToString();
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetEnteredGamepadTextLength()
|
||||
{
|
||||
return platform.ISteamUtils_GetEnteredGamepadTextLength();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetImageRGBA( int iImage /*int*/, IntPtr pubDest /*uint8 **/, int nDestBufferSize /*int*/ )
|
||||
{
|
||||
return platform.ISteamUtils_GetImageRGBA( iImage, (IntPtr) pubDest, nDestBufferSize );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool GetImageSize( int iImage /*int*/, out uint pnWidth /*uint32 **/, out uint pnHeight /*uint32 **/ )
|
||||
{
|
||||
return platform.ISteamUtils_GetImageSize( iImage, out pnWidth, out pnHeight );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetIPCCallCount()
|
||||
{
|
||||
return platform.ISteamUtils_GetIPCCallCount();
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetIPCountry()
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamUtils_GetIPCountry();
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetSecondsSinceAppActive()
|
||||
{
|
||||
return platform.ISteamUtils_GetSecondsSinceAppActive();
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetSecondsSinceComputerActive()
|
||||
{
|
||||
return platform.ISteamUtils_GetSecondsSinceComputerActive();
|
||||
}
|
||||
|
||||
// uint
|
||||
public uint GetServerRealTime()
|
||||
{
|
||||
return platform.ISteamUtils_GetServerRealTime();
|
||||
}
|
||||
|
||||
// string
|
||||
// with: Detect_StringReturn
|
||||
public string GetSteamUILanguage()
|
||||
{
|
||||
IntPtr string_pointer;
|
||||
string_pointer = platform.ISteamUtils_GetSteamUILanguage();
|
||||
return Marshal.PtrToStringAnsi( string_pointer );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsAPICallCompleted( SteamAPICall_t hSteamAPICall /*SteamAPICall_t*/, ref bool pbFailed /*bool **/ )
|
||||
{
|
||||
return platform.ISteamUtils_IsAPICallCompleted( hSteamAPICall.Value, ref pbFailed );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsOverlayEnabled()
|
||||
{
|
||||
return platform.ISteamUtils_IsOverlayEnabled();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsSteamInBigPictureMode()
|
||||
{
|
||||
return platform.ISteamUtils_IsSteamInBigPictureMode();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsSteamRunningInVR()
|
||||
{
|
||||
return platform.ISteamUtils_IsSteamRunningInVR();
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsVRHeadsetStreamingEnabled()
|
||||
{
|
||||
return platform.ISteamUtils_IsVRHeadsetStreamingEnabled();
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetOverlayNotificationInset( int nHorizontalInset /*int*/, int nVerticalInset /*int*/ )
|
||||
{
|
||||
platform.ISteamUtils_SetOverlayNotificationInset( nHorizontalInset, nVerticalInset );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetOverlayNotificationPosition( NotificationPosition eNotificationPosition /*ENotificationPosition*/ )
|
||||
{
|
||||
platform.ISteamUtils_SetOverlayNotificationPosition( eNotificationPosition );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetVRHeadsetStreamingEnabled( bool bEnabled /*bool*/ )
|
||||
{
|
||||
platform.ISteamUtils_SetVRHeadsetStreamingEnabled( bEnabled );
|
||||
}
|
||||
|
||||
// void
|
||||
public void SetWarningMessageHook( IntPtr pFunction /*SteamAPIWarningMessageHook_t*/ )
|
||||
{
|
||||
platform.ISteamUtils_SetWarningMessageHook( (IntPtr) pFunction );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool ShowGamepadTextInput( GamepadTextInputMode eInputMode /*EGamepadTextInputMode*/, GamepadTextInputLineMode eLineInputMode /*EGamepadTextInputLineMode*/, string pchDescription /*const char **/, uint unCharMax /*uint32*/, string pchExistingText /*const char **/ )
|
||||
{
|
||||
return platform.ISteamUtils_ShowGamepadTextInput( eInputMode, eLineInputMode, pchDescription, unCharMax, pchExistingText );
|
||||
}
|
||||
|
||||
// void
|
||||
public void StartVRDashboard()
|
||||
{
|
||||
platform.ISteamUtils_StartVRDashboard();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal unsafe class SteamVideo : IDisposable
|
||||
{
|
||||
//
|
||||
// Holds a platform specific implentation
|
||||
//
|
||||
internal Platform.Interface platform;
|
||||
internal Facepunch.Steamworks.BaseSteamworks steamworks;
|
||||
|
||||
//
|
||||
// Constructor decides which implementation to use based on current platform
|
||||
//
|
||||
internal SteamVideo( Facepunch.Steamworks.BaseSteamworks steamworks, IntPtr pointer )
|
||||
{
|
||||
this.steamworks = steamworks;
|
||||
|
||||
if ( Platform.IsWindows64 ) platform = new Platform.Win64( pointer );
|
||||
else if ( Platform.IsWindows32 ) platform = new Platform.Win32( pointer );
|
||||
else if ( Platform.IsLinux32 ) platform = new Platform.Linux32( pointer );
|
||||
else if ( Platform.IsLinux64 ) platform = new Platform.Linux64( pointer );
|
||||
else if ( Platform.IsOsx ) platform = new Platform.Mac( pointer );
|
||||
}
|
||||
|
||||
//
|
||||
// Class is invalid if we don't have a valid implementation
|
||||
//
|
||||
public bool IsValid{ get{ return platform != null && platform.IsValid; } }
|
||||
|
||||
//
|
||||
// When shutting down clear all the internals to avoid accidental use
|
||||
//
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if ( platform != null )
|
||||
{
|
||||
platform.Dispose();
|
||||
platform = null;
|
||||
}
|
||||
}
|
||||
|
||||
// void
|
||||
public void GetOPFSettings( AppId_t unVideoAppID /*AppId_t*/ )
|
||||
{
|
||||
platform.ISteamVideo_GetOPFSettings( unVideoAppID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
// with: Detect_StringFetch True
|
||||
public string GetOPFStringForApp( AppId_t unVideoAppID /*AppId_t*/ )
|
||||
{
|
||||
bool bSuccess = default( bool );
|
||||
System.Text.StringBuilder pchBuffer_sb = Helpers.TakeStringBuilder();
|
||||
int pnBufferSize = 4096;
|
||||
bSuccess = platform.ISteamVideo_GetOPFStringForApp( unVideoAppID.Value, pchBuffer_sb, out pnBufferSize );
|
||||
if ( !bSuccess ) return null;
|
||||
return pchBuffer_sb.ToString();
|
||||
}
|
||||
|
||||
// void
|
||||
public void GetVideoURL( AppId_t unVideoAppID /*AppId_t*/ )
|
||||
{
|
||||
platform.ISteamVideo_GetVideoURL( unVideoAppID.Value );
|
||||
}
|
||||
|
||||
// bool
|
||||
public bool IsBroadcasting( IntPtr pnNumViewers /*int **/ )
|
||||
{
|
||||
return platform.ISteamVideo_IsBroadcasting( (IntPtr) pnNumViewers );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,712 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace SteamNative
|
||||
{
|
||||
internal struct GID_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator GID_t( ulong value )
|
||||
{
|
||||
return new GID_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( GID_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct JobID_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator JobID_t( ulong value )
|
||||
{
|
||||
return new JobID_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( JobID_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct TxnID_t
|
||||
{
|
||||
public GID_t Value;
|
||||
|
||||
public static implicit operator TxnID_t( GID_t value )
|
||||
{
|
||||
return new TxnID_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator GID_t( TxnID_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct PackageId_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator PackageId_t( uint value )
|
||||
{
|
||||
return new PackageId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( PackageId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct BundleId_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator BundleId_t( uint value )
|
||||
{
|
||||
return new BundleId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( BundleId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct AppId_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator AppId_t( uint value )
|
||||
{
|
||||
return new AppId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( AppId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct AssetClassId_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator AssetClassId_t( ulong value )
|
||||
{
|
||||
return new AssetClassId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( AssetClassId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct PhysicalItemId_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator PhysicalItemId_t( uint value )
|
||||
{
|
||||
return new PhysicalItemId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( PhysicalItemId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct DepotId_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator DepotId_t( uint value )
|
||||
{
|
||||
return new DepotId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( DepotId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct RTime32
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator RTime32( uint value )
|
||||
{
|
||||
return new RTime32(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( RTime32 value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct CellID_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator CellID_t( uint value )
|
||||
{
|
||||
return new CellID_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( CellID_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SteamAPICall_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator SteamAPICall_t( ulong value )
|
||||
{
|
||||
return new SteamAPICall_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( SteamAPICall_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct AccountID_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator AccountID_t( uint value )
|
||||
{
|
||||
return new AccountID_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( AccountID_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct PartnerId_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator PartnerId_t( uint value )
|
||||
{
|
||||
return new PartnerId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( PartnerId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ManifestId_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator ManifestId_t( ulong value )
|
||||
{
|
||||
return new ManifestId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( ManifestId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SiteId_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator SiteId_t( ulong value )
|
||||
{
|
||||
return new SiteId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( SiteId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HAuthTicket
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator HAuthTicket( uint value )
|
||||
{
|
||||
return new HAuthTicket(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( HAuthTicket value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct BREAKPAD_HANDLE
|
||||
{
|
||||
public IntPtr Value;
|
||||
|
||||
public static implicit operator BREAKPAD_HANDLE( IntPtr value )
|
||||
{
|
||||
return new BREAKPAD_HANDLE(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr( BREAKPAD_HANDLE value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HSteamPipe
|
||||
{
|
||||
public int Value;
|
||||
|
||||
public static implicit operator HSteamPipe( int value )
|
||||
{
|
||||
return new HSteamPipe(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator int( HSteamPipe value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HSteamUser
|
||||
{
|
||||
public int Value;
|
||||
|
||||
public static implicit operator HSteamUser( int value )
|
||||
{
|
||||
return new HSteamUser(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator int( HSteamUser value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct FriendsGroupID_t
|
||||
{
|
||||
public short Value;
|
||||
|
||||
public static implicit operator FriendsGroupID_t( short value )
|
||||
{
|
||||
return new FriendsGroupID_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator short( FriendsGroupID_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HServerListRequest
|
||||
{
|
||||
public IntPtr Value;
|
||||
|
||||
public static implicit operator HServerListRequest( IntPtr value )
|
||||
{
|
||||
return new HServerListRequest(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr( HServerListRequest value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HServerQuery
|
||||
{
|
||||
public int Value;
|
||||
|
||||
public static implicit operator HServerQuery( int value )
|
||||
{
|
||||
return new HServerQuery(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator int( HServerQuery value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct UGCHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator UGCHandle_t( ulong value )
|
||||
{
|
||||
return new UGCHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( UGCHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct PublishedFileUpdateHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator PublishedFileUpdateHandle_t( ulong value )
|
||||
{
|
||||
return new PublishedFileUpdateHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( PublishedFileUpdateHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct PublishedFileId_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator PublishedFileId_t( ulong value )
|
||||
{
|
||||
return new PublishedFileId_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( PublishedFileId_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct UGCFileWriteStreamHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator UGCFileWriteStreamHandle_t( ulong value )
|
||||
{
|
||||
return new UGCFileWriteStreamHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( UGCFileWriteStreamHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SteamLeaderboard_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator SteamLeaderboard_t( ulong value )
|
||||
{
|
||||
return new SteamLeaderboard_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( SteamLeaderboard_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SteamLeaderboardEntries_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator SteamLeaderboardEntries_t( ulong value )
|
||||
{
|
||||
return new SteamLeaderboardEntries_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( SteamLeaderboardEntries_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SNetSocket_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator SNetSocket_t( uint value )
|
||||
{
|
||||
return new SNetSocket_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( SNetSocket_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SNetListenSocket_t
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator SNetListenSocket_t( uint value )
|
||||
{
|
||||
return new SNetListenSocket_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( SNetListenSocket_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ScreenshotHandle
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator ScreenshotHandle( uint value )
|
||||
{
|
||||
return new ScreenshotHandle(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( ScreenshotHandle value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HTTPRequestHandle
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator HTTPRequestHandle( uint value )
|
||||
{
|
||||
return new HTTPRequestHandle(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( HTTPRequestHandle value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HTTPCookieContainerHandle
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator HTTPCookieContainerHandle( uint value )
|
||||
{
|
||||
return new HTTPCookieContainerHandle(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( HTTPCookieContainerHandle value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ControllerHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator ControllerHandle_t( ulong value )
|
||||
{
|
||||
return new ControllerHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( ControllerHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ControllerActionSetHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator ControllerActionSetHandle_t( ulong value )
|
||||
{
|
||||
return new ControllerActionSetHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( ControllerActionSetHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ControllerDigitalActionHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator ControllerDigitalActionHandle_t( ulong value )
|
||||
{
|
||||
return new ControllerDigitalActionHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( ControllerDigitalActionHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct ControllerAnalogActionHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator ControllerAnalogActionHandle_t( ulong value )
|
||||
{
|
||||
return new ControllerAnalogActionHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( ControllerAnalogActionHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct UGCQueryHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator UGCQueryHandle_t( ulong value )
|
||||
{
|
||||
return new UGCQueryHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( UGCQueryHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct UGCUpdateHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator UGCUpdateHandle_t( ulong value )
|
||||
{
|
||||
return new UGCUpdateHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( UGCUpdateHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct HHTMLBrowser
|
||||
{
|
||||
public uint Value;
|
||||
|
||||
public static implicit operator HHTMLBrowser( uint value )
|
||||
{
|
||||
return new HHTMLBrowser(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator uint( HHTMLBrowser value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SteamItemInstanceID_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator SteamItemInstanceID_t( ulong value )
|
||||
{
|
||||
return new SteamItemInstanceID_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( SteamItemInstanceID_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SteamItemDef_t
|
||||
{
|
||||
public int Value;
|
||||
|
||||
public static implicit operator SteamItemDef_t( int value )
|
||||
{
|
||||
return new SteamItemDef_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator int( SteamItemDef_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SteamInventoryResult_t
|
||||
{
|
||||
public int Value;
|
||||
|
||||
public static implicit operator SteamInventoryResult_t( int value )
|
||||
{
|
||||
return new SteamInventoryResult_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator int( SteamInventoryResult_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct SteamInventoryUpdateHandle_t
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator SteamInventoryUpdateHandle_t( ulong value )
|
||||
{
|
||||
return new SteamInventoryUpdateHandle_t(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( SteamInventoryUpdateHandle_t value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct CGameID
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator CGameID( ulong value )
|
||||
{
|
||||
return new CGameID(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( CGameID value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
internal struct CSteamID
|
||||
{
|
||||
public ulong Value;
|
||||
|
||||
public static implicit operator CSteamID( ulong value )
|
||||
{
|
||||
return new CSteamID(){ Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator ulong( CSteamID value )
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public static partial class Utility
|
||||
{
|
||||
static internal uint Swap( uint x )
|
||||
{
|
||||
return ((x & 0x000000ff) << 24) +
|
||||
((x & 0x0000ff00) << 8) +
|
||||
((x & 0x00ff0000) >> 8) +
|
||||
((x & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
static public uint IpToInt32( this IPAddress ipAddress )
|
||||
{
|
||||
return Swap( (uint) ipAddress.Address );
|
||||
}
|
||||
|
||||
static public IPAddress Int32ToIp( uint ipAddress )
|
||||
{
|
||||
return new IPAddress( Swap( ipAddress ) );
|
||||
}
|
||||
|
||||
static internal class Epoch
|
||||
{
|
||||
private static readonly DateTime epoch = new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc );
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current Unix Epoch
|
||||
/// </summary>
|
||||
public static int Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)( DateTime.UtcNow.Subtract( epoch ).TotalSeconds );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an epoch to a datetime
|
||||
/// </summary>
|
||||
public static DateTime ToDateTime( decimal unixTime )
|
||||
{
|
||||
return epoch.AddSeconds( (long)unixTime );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a DateTime to a unix time
|
||||
/// </summary>
|
||||
public static uint FromDateTime( DateTime dt )
|
||||
{
|
||||
return (uint)( dt.Subtract( epoch ).TotalSeconds );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal static string FormatPrice(string currency, ulong price)
|
||||
{
|
||||
return FormatPrice(currency, price / 100.0);
|
||||
}
|
||||
|
||||
public static string FormatPrice(string currency, double price)
|
||||
{
|
||||
var decimaled = price.ToString("0.00");
|
||||
|
||||
switch (currency)
|
||||
{
|
||||
case "AED": return $"{decimaled}د.إ";
|
||||
case "ARS": return $"${decimaled} ARS";
|
||||
case "AUD": return $"${decimaled} AUD";
|
||||
case "BRL": return $"R$ {decimaled}";
|
||||
case "CAD": return $"${decimaled} CAD";
|
||||
case "CHF": return $"Fr. {decimaled}";
|
||||
case "CLP": return $"${decimaled} CLP";
|
||||
case "CNY": return $"{decimaled}元";
|
||||
case "COP": return $"COL$ {decimaled}";
|
||||
case "CRC": return $"₡{decimaled}";
|
||||
case "EUR": return $"€{decimaled}";
|
||||
case "GBP": return $"£{decimaled}";
|
||||
case "HKD": return $"HK$ {decimaled}";
|
||||
case "ILS": return $"₪{decimaled}";
|
||||
case "IDR": return $"Rp{decimaled}";
|
||||
case "INR": return $"₹{decimaled}";
|
||||
case "JPY": return $"¥{decimaled}";
|
||||
case "KRW": return $"₩{decimaled}";
|
||||
case "KWD": return $"KD {decimaled}";
|
||||
case "KZT": return $"{decimaled}₸";
|
||||
case "MXN": return $"Mex$ {decimaled}";
|
||||
case "MYR": return $"RM {decimaled}";
|
||||
case "NOK": return $"{decimaled} kr";
|
||||
case "NZD": return $"${decimaled} NZD";
|
||||
case "PEN": return $"S/. {decimaled}";
|
||||
case "PHP": return $"₱{decimaled}";
|
||||
case "PLN": return $"zł {decimaled}";
|
||||
case "QAR": return $"QR {decimaled}";
|
||||
case "RUB": return $"₽{decimaled}";
|
||||
case "SAR": return $"SR {decimaled}";
|
||||
case "SGD": return $"S$ {decimaled}";
|
||||
case "THB": return $"฿{decimaled}";
|
||||
case "TRY": return $"₺{decimaled}";
|
||||
case "TWD": return $"NT$ {decimaled}";
|
||||
case "UAH": return $"₴{decimaled}";
|
||||
case "USD": return $"${decimaled}";
|
||||
case "UYU": return $"$U {decimaled}"; // yes the U goes after $
|
||||
case "VND": return $"₫{decimaled}";
|
||||
case "ZAR": return $"R {decimaled}";
|
||||
|
||||
// TODO - check all of them https://partner.steamgames.com/doc/store/pricing/currencies
|
||||
|
||||
default: return $"{decimaled} {currency}";
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadNullTerminatedUTF8String( this BinaryReader br, byte[] buffer = null )
|
||||
{
|
||||
if ( buffer == null )
|
||||
buffer = new byte[1024];
|
||||
|
||||
byte chr;
|
||||
int i = 0;
|
||||
while ( (chr = br.ReadByte()) != 0 && i < buffer.Length )
|
||||
{
|
||||
buffer[i] = chr;
|
||||
i++;
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString( buffer, 0, i );
|
||||
}
|
||||
|
||||
public static IEnumerable<T> UnionSelect<T>(
|
||||
this IEnumerable<T> first,
|
||||
IEnumerable<T> second,
|
||||
Func<T, T, T> selector) where T : IEquatable<T>
|
||||
{
|
||||
var items = new Dictionary<T, T>();
|
||||
|
||||
foreach (var i in first)
|
||||
{
|
||||
items[i] = i;
|
||||
}
|
||||
|
||||
foreach (var i in second)
|
||||
{
|
||||
T firstValue;
|
||||
if (items.TryGetValue(i, out firstValue))
|
||||
{
|
||||
items.Remove(i);
|
||||
yield return selector(firstValue, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
|
||||
internal class SourceServerQuery : IDisposable
|
||||
{
|
||||
public static List<SourceServerQuery> Current = new List<SourceServerQuery>();
|
||||
|
||||
public static void Cycle()
|
||||
{
|
||||
if ( Current.Count == 0 )
|
||||
return;
|
||||
|
||||
for( int i = Current.Count; i>0; i-- )
|
||||
{
|
||||
Current[i-1].Update();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly byte[] A2S_SERVERQUERY_GETCHALLENGE = { 0x55, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
// private static readonly byte A2S_PLAYER = 0x55;
|
||||
private static readonly byte A2S_RULES = 0x56;
|
||||
|
||||
public volatile bool IsRunning;
|
||||
public volatile bool IsSuccessful;
|
||||
|
||||
private ServerList.Server Server;
|
||||
private UdpClient udpClient;
|
||||
private IPEndPoint endPoint;
|
||||
private System.Threading.Thread thread;
|
||||
private byte[] _challengeBytes;
|
||||
|
||||
private Dictionary<string, string> rules = new Dictionary<string, string>();
|
||||
|
||||
public SourceServerQuery( ServerList.Server server, IPAddress address, int queryPort )
|
||||
{
|
||||
Server = server;
|
||||
endPoint = new IPEndPoint( address, queryPort );
|
||||
|
||||
Current.Add( this );
|
||||
|
||||
IsRunning = true;
|
||||
IsSuccessful = false;
|
||||
thread = new System.Threading.Thread( ThreadedStart );
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if ( !IsRunning )
|
||||
{
|
||||
Current.Remove( this );
|
||||
Server.OnServerRulesReceiveFinished( rules, IsSuccessful );
|
||||
}
|
||||
}
|
||||
|
||||
private void ThreadedStart( object obj )
|
||||
{
|
||||
try
|
||||
{
|
||||
using ( udpClient = new UdpClient() )
|
||||
{
|
||||
udpClient.Client.SendTimeout = 3000;
|
||||
udpClient.Client.ReceiveTimeout = 3000;
|
||||
udpClient.Connect( endPoint );
|
||||
|
||||
GetRules();
|
||||
|
||||
IsSuccessful = true;
|
||||
}
|
||||
}
|
||||
catch ( System.Exception )
|
||||
{
|
||||
IsSuccessful = false;
|
||||
}
|
||||
|
||||
udpClient = null;
|
||||
IsRunning = false;
|
||||
}
|
||||
|
||||
void GetRules()
|
||||
{
|
||||
GetChallengeData();
|
||||
|
||||
_challengeBytes[0] = A2S_RULES;
|
||||
Send( _challengeBytes );
|
||||
var ruleData = Receive();
|
||||
|
||||
using ( var br = new BinaryReader( new MemoryStream( ruleData ) ) )
|
||||
{
|
||||
if ( br.ReadByte() != 0x45 )
|
||||
throw new Exception( "Invalid data received in response to A2S_RULES request" );
|
||||
|
||||
var numRules = br.ReadUInt16();
|
||||
for ( int index = 0; index < numRules; index++ )
|
||||
{
|
||||
rules.Add( br.ReadNullTerminatedUTF8String( readBuffer ), br.ReadNullTerminatedUTF8String( readBuffer ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte[] readBuffer = new byte[1024 * 4];
|
||||
|
||||
private byte[] Receive()
|
||||
{
|
||||
byte[][] packets = null;
|
||||
byte packetNumber = 0, packetCount = 1;
|
||||
|
||||
do
|
||||
{
|
||||
var result = udpClient.Receive( ref endPoint );
|
||||
|
||||
using ( var br = new BinaryReader( new MemoryStream( result ) ) )
|
||||
{
|
||||
var header = br.ReadInt32();
|
||||
|
||||
if ( header == -1 )
|
||||
{
|
||||
var unsplitdata = new byte[result.Length - br.BaseStream.Position];
|
||||
Buffer.BlockCopy( result, (int)br.BaseStream.Position, unsplitdata, 0, unsplitdata.Length );
|
||||
return unsplitdata;
|
||||
}
|
||||
else if ( header == -2 )
|
||||
{
|
||||
int requestId = br.ReadInt32();
|
||||
packetNumber = br.ReadByte();
|
||||
packetCount = br.ReadByte();
|
||||
int splitSize = br.ReadInt32();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.Exception( "Invalid Header" );
|
||||
}
|
||||
|
||||
if ( packets == null ) packets = new byte[packetCount][];
|
||||
|
||||
var data = new byte[result.Length - br.BaseStream.Position];
|
||||
Buffer.BlockCopy( result, (int)br.BaseStream.Position, data, 0, data.Length );
|
||||
packets[packetNumber] = data;
|
||||
}
|
||||
}
|
||||
while ( packets.Any( p => p == null ) );
|
||||
|
||||
var combinedData = Combine( packets );
|
||||
return combinedData;
|
||||
}
|
||||
|
||||
private void GetChallengeData()
|
||||
{
|
||||
if ( _challengeBytes != null ) return;
|
||||
|
||||
Send( A2S_SERVERQUERY_GETCHALLENGE );
|
||||
|
||||
var challengeData = Receive();
|
||||
|
||||
if ( challengeData[0] != 0x41 )
|
||||
throw new Exception( "Invalid Challenge" );
|
||||
|
||||
_challengeBytes = challengeData;
|
||||
}
|
||||
|
||||
byte[] sendBuffer = new byte[1024];
|
||||
|
||||
private void Send( byte[] message )
|
||||
{
|
||||
sendBuffer[0] = 0xFF;
|
||||
sendBuffer[1] = 0xFF;
|
||||
sendBuffer[2] = 0xFF;
|
||||
sendBuffer[3] = 0xFF;
|
||||
|
||||
Buffer.BlockCopy( message, 0, sendBuffer, 4, message.Length );
|
||||
|
||||
udpClient.Send( sendBuffer, message.Length + 4 );
|
||||
}
|
||||
|
||||
private byte[] Combine( byte[][] arrays )
|
||||
{
|
||||
var rv = new byte[arrays.Sum( a => a.Length )];
|
||||
int offset = 0;
|
||||
foreach ( byte[] array in arrays )
|
||||
{
|
||||
Buffer.BlockCopy( array, 0, rv, offset, array.Length );
|
||||
offset += array.Length;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if ( thread != null && thread.IsAlive )
|
||||
{
|
||||
thread.Abort();
|
||||
}
|
||||
|
||||
thread = null;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@ namespace FarseerPhysics.Dynamics
|
||||
/// </summary>
|
||||
public CollisionFilterDelegate ContactFilter;
|
||||
|
||||
public List<Contact> ContactList = new List<Contact>(128);
|
||||
public List<Contact> ContactList = new List<Contact>(256);
|
||||
|
||||
#if USE_ACTIVE_CONTACT_SET
|
||||
/// <summary>
|
||||
|
||||
@@ -68,6 +68,11 @@ namespace FarseerPhysics.Dynamics.Joints
|
||||
private float _invIB;
|
||||
private Mat33 _mass;
|
||||
|
||||
/// <summary>
|
||||
/// If true, body B is treated as if it was kinematic (i.e. as if it had infinite mass)
|
||||
/// </summary>
|
||||
public bool KinematicBodyB;
|
||||
|
||||
internal WeldJoint()
|
||||
{
|
||||
JointType = JointType.Weld;
|
||||
@@ -158,9 +163,9 @@ namespace FarseerPhysics.Dynamics.Joints
|
||||
_localCenterA = BodyA._sweep.LocalCenter;
|
||||
_localCenterB = BodyB._sweep.LocalCenter;
|
||||
_invMassA = BodyA._invMass;
|
||||
_invMassB = BodyB._invMass;
|
||||
_invMassB = KinematicBodyB ? 0.0f : BodyB._invMass;
|
||||
_invIA = BodyA._invI;
|
||||
_invIB = BodyB._invI;
|
||||
_invIB = KinematicBodyB ? 0.0f : BodyB._invI;
|
||||
|
||||
float aA = data.positions[_indexA].a;
|
||||
Vector2 vA = data.velocities[_indexA].v;
|
||||
|
||||
@@ -339,7 +339,6 @@ namespace FarseerPhysics.Dynamics
|
||||
|
||||
// You tried to remove a body that is not contained in the BodyList.
|
||||
// Are you removing the body more than once?
|
||||
System.Diagnostics.Debug.WriteLine(body.UserData);
|
||||
Debug.Assert(BodyList.Contains(body));
|
||||
|
||||
#if USE_AWAKE_BODY_SET
|
||||
|
||||
@@ -39,6 +39,14 @@ namespace FarseerPhysics.Factories
|
||||
return body.CreateFixture(rectangleShape, userData);
|
||||
}
|
||||
|
||||
public static Fixture AttachRectangle(float width, float height, float density, float angle, Vector2 offset, Body body, object userData = null)
|
||||
{
|
||||
Vertices rectangleVertices = PolygonTools.CreateRectangle(width / 2, height / 2, Vector2.Zero, angle);
|
||||
rectangleVertices.Translate(ref offset);
|
||||
PolygonShape rectangleShape = new PolygonShape(rectangleVertices, density);
|
||||
return body.CreateFixture(rectangleShape, userData);
|
||||
}
|
||||
|
||||
public static Fixture AttachCircle(float radius, float density, Body body, object userData = null)
|
||||
{
|
||||
if (radius <= 0)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user