using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Steamworks.Data;
namespace Steamworks
{
public static class SteamClient
{
static bool initialized;
///
/// Initialize the steam client.
/// If is false you need to call 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, App ID is ureleased, Don't own App ID." );
}
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();
initialized = openInterfaces.Count > 0;
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();
bool valid = t.InitializeInterface( false );
if ( valid )
{
openInterfaces.Add( t );
}
else
{
t.DestroyInterface( false );
}
}
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;
///
/// Shuts down the steam client.
///
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, 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 != null && 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() ?? default;
///
/// returns the local players name - guaranteed to not be .
/// This is the same name as on the user's community profile page.
///
public static string? Name => SteamFriends.Internal?.GetPersonaName();
///
/// Gets the status of the current user.
///
public static FriendState State => SteamFriends.Internal?.GetPersonaState() ?? FriendState.Offline;
///
/// Returns the App ID 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" );
}
}
}