38f1ddb...178a853: v0.8.9.1, removed content folder

This commit is contained in:
Joonas Rikkonen
2019-03-18 19:46:58 +02:00
parent 38f1ddb6fe
commit 6c0679c297
1054 changed files with 151673 additions and 144931 deletions
@@ -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
};
}
+307
View File
@@ -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;
}
}
}
+65
View File
@@ -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
+345
View File
@@ -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;
}
}
}
+159
View File
@@ -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;
}
};
}
File diff suppressed because it is too large Load Diff
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