using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using Facepunch.Steamworks.Data; namespace Facepunch.Steamworks { public static class SteamClient { static bool initialized; /// /// Initialize the steam client. /// If asyncCallbacks is false you need to call RunCallbacks manually every frame. /// public static void Init( uint appid, bool asyncCallbacks = true ) { if ( initialized ) throw new System.Exception( "Calling SteamClient.Init but is already initialized" ); System.Environment.SetEnvironmentVariable( "SteamAppId", appid.ToString() ); System.Environment.SetEnvironmentVariable( "SteamGameId", appid.ToString() ); if ( !SteamAPI.Init() ) { throw new System.Exception( "SteamApi_Init returned false. Steam isn't running, couldn't find Steam, AppId is ureleased, Don't own AppId." ); } AppId = appid; initialized = true; // // Dispatch is responsible for pumping the // event loop. // Dispatch.Init(); Dispatch.ClientPipe = SteamAPI.GetHSteamPipe(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); AddInterface(); if ( asyncCallbacks ) { // // This will keep looping in the background every 16 ms // until we shut down. // Dispatch.LoopClientAsync(); } } internal static void AddInterface() where T : SteamClass, new() { var t = new T(); t.InitializeInterface( false ); openInterfaces.Add( t ); } static readonly List openInterfaces = new List(); internal static void ShutdownInterfaces() { foreach ( var e in openInterfaces ) { e.DestroyInterface( false ); } openInterfaces.Clear(); } public static bool IsValid => initialized; public static void Shutdown() { if ( !IsValid ) return; Cleanup(); SteamAPI.Shutdown(); } internal static void Cleanup() { Dispatch.ShutdownClient(); initialized = false; ShutdownInterfaces(); } public static void RunCallbacks() { if ( Dispatch.ClientPipe != 0 ) Dispatch.Frame( Dispatch.ClientPipe ); } /// /// Checks if the current user's Steam client is connected to the Steam servers. /// If it's not then no real-time services provided by the Steamworks API will be enabled. The Steam /// client will automatically be trying to recreate the connection as often as possible. When the /// connection is restored a SteamServersConnected_t callback will be posted. /// You usually don't need to check for this yourself. All of the API calls that rely on this will /// check internally. Forcefully disabling stuff when the player loses access is usually not a /// very good experience for the player and you could be preventing them from accessing APIs that do not /// need a live connection to Steam. /// public static bool IsLoggedOn => SteamUser.Internal.BLoggedOn(); /// /// Gets the Steam ID of the account currently logged into the Steam client. This is /// commonly called the 'current user', or 'local user'. /// A Steam ID is a unique identifier for a Steam accounts, Steam groups, Lobbies and Chat /// rooms, and used to differentiate users in all parts of the Steamworks API. /// public static SteamId SteamId => SteamUser.Internal.GetSteamID(); /// /// returns the local players name - guaranteed to not be NULL. /// this is the same name as on the users community profile page /// public static string Name => SteamFriends.Internal.GetPersonaName(); /// /// gets the status of the current user /// public static FriendState State => SteamFriends.Internal.GetPersonaState(); /// /// returns the appID of the current process /// public static AppId AppId { get; internal set; } /// /// Checks if your executable was launched through Steam and relaunches it through Steam if it wasn't /// 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/ /// Note that during development, when not launching via Steam, this might always return true. /// public static bool RestartAppIfNecessary( uint appid ) { // Having these here would probably mean it always returns false? //System.Environment.SetEnvironmentVariable( "SteamAppId", appid.ToString() ); //System.Environment.SetEnvironmentVariable( "SteamGameId", appid.ToString() ); return SteamAPI.RestartAppIfNecessary( appid ); } /// /// Called in interfaces that rely on this being initialized /// internal static void ValidCheck() { if ( !IsValid ) throw new System.Exception( "SteamClient isn't initialized" ); } } }