using Steamworks; namespace ytLive.Services.Entitlement; /// /// Reads ownership of the paid app from Steam. In the free Demo, this checks the associated paid /// app ID; no key, server, or LlamaCasty account is involved. A missing ID, Steam client, or native /// library fails closed so the app can continue with the free output profile. /// public sealed class SteamEntitlement : IEntitlement { private readonly uint _paidAppId; private readonly Func _initializeSteam; private readonly Func _isAppSubscribed; private readonly Action _shutdownSteam; private bool _initAttempted; private bool _available; private bool? _cached; private string? _errorMessage; public SteamEntitlement(uint paidAppId) : this( paidAppId, SteamAPI.Init, appId => SteamApps.BIsSubscribedApp(new AppId_t(appId)), SteamAPI.Shutdown) { } internal SteamEntitlement( uint paidAppId, Func initializeSteam, Func isAppSubscribed, Action shutdownSteam) { _paidAppId = paidAppId; _initializeSteam = initializeSteam; _isAppSubscribed = isAppSubscribed; _shutdownSteam = shutdownSteam; } /// Configured with no paid app ID; ownership fails closed without touching Steam. public static SteamEntitlement NotConfigured() => new(0); public string? ErrorMessage => _errorMessage; public bool IsAppOwned { get { if (_paidAppId == 0) { _cached = false; _errorMessage = "Steam licensing is not configured in this build."; return false; } if (_cached is { } known) return known; if (!_initAttempted) { _initAttempted = true; try { _available = _initializeSteam(); } catch (Exception ex) { _available = false; _errorMessage = $"Steam could not start ({ex.Message}). Open Steam, sign in, then restart LlamaCasty."; } } if (!_available) { _cached = false; _errorMessage ??= "Steam could not verify ownership. Open Steam, sign in, then restart LlamaCasty."; return false; } try { var owned = _isAppSubscribed(_paidAppId); _cached = owned; _errorMessage = null; return owned; } catch (Exception ex) { _cached = false; _errorMessage = $"Steam could not check ownership ({ex.Message}). Open Steam, sign in, then restart LlamaCasty."; return false; } } } public void Shutdown() { if (_available) _shutdownSteam(); _available = false; _cached = null; _initAttempted = false; _errorMessage = null; } }