feat(entitlement): pivot to paid app ownership
Check Steam ownership of the paid app with BIsSubscribedApp; keep Debug fake ownership out of Release. Ref: https://partner.steamgames.com/doc/api/ISteamApps#BIsSubscribedApp
This commit is contained in:
@@ -4,44 +4,45 @@ using ytLive.Services.Entitlement;
|
||||
namespace ytLive.ViewModels;
|
||||
|
||||
/// <summary>
|
||||
/// The entitlement surface: whether this session may emit output above the free budget.
|
||||
/// The app-wide Steam ownership flag and its output-profile consumer.
|
||||
///
|
||||
/// <para>Deliberately a separate partial from <c>License.cs</c>: that file owns *how* a
|
||||
/// licence is validated (Polar today), this one owns *what the answer means* for output.
|
||||
/// Steam's DLC check and Polar's lease both collapse into <see cref="IsPremium"/>; nothing
|
||||
/// downstream of <see cref="HasProOutput"/> cares which one proved it.</para>
|
||||
/// <para>Only the entitlement service decides whether the current Steam account owns the paid app.
|
||||
/// Development builds use a fake owned result; Release builds use Steam.</para>
|
||||
/// </summary>
|
||||
public partial class MainViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// The single input to <see cref="Models.OutputProfile.Resolve"/>.
|
||||
///
|
||||
/// <para><b>Fail closed:</b> an unresolved or unreadable licence is simply false, so a
|
||||
/// build with no entitlement emits the free profile. There is no "unknown" branch to get
|
||||
/// wrong.</para>
|
||||
///
|
||||
/// <para><b>Developer mode never ships:</b> <see cref="DeveloperMode"/> is only ever
|
||||
/// settable inside a development build (see <see cref="DevBuild"/>), so this expression
|
||||
/// reduces to <c>IsPremium</c> in a Release binary.</para>
|
||||
/// </summary>
|
||||
public bool HasProOutput => IsPremium || DeveloperMode || _entitlement.IsPro;
|
||||
private IEntitlement _entitlement = CreateEntitlement();
|
||||
private bool _isAppOwned;
|
||||
|
||||
/// <summary>
|
||||
/// The entitlement rail for this session. Lifetime = Steam DLC; until the DLC app id exists it
|
||||
/// is <see cref="SteamEntitlement.NotConfigured"/>, which reads false (fail closed). Tests
|
||||
/// inject a fake through <see cref="EntitlementOverride"/>.
|
||||
/// </summary>
|
||||
private IEntitlement _entitlement = SteamEntitlement.NotConfigured();
|
||||
public bool IsAppOwned
|
||||
{
|
||||
get => _isAppOwned;
|
||||
private set
|
||||
{
|
||||
if (!SetProperty(ref _isAppOwned, value)) return;
|
||||
OnPropertyChanged(nameof(HasProOutput));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Test seam: swap the rail without a Steam client. Internal — the test assembly is
|
||||
/// the only caller, and a public setter here would be a licence bypass surface.</summary>
|
||||
public bool HasProOutput => DeveloperMode || IsAppOwned;
|
||||
|
||||
private static IEntitlement CreateEntitlement()
|
||||
{
|
||||
#if DEBUG
|
||||
return new FakeEntitlement(true);
|
||||
#else
|
||||
return SteamEntitlement.NotConfigured();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>Test seam: swap the ownership source without a Steam client.</summary>
|
||||
internal IEntitlement EntitlementOverride
|
||||
{
|
||||
get => _entitlement;
|
||||
set
|
||||
{
|
||||
_entitlement = value;
|
||||
OnPropertyChanged(nameof(HasProOutput));
|
||||
IsAppOwned = value.IsAppOwned;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ public partial class MainViewModel : ViewModelBase
|
||||
public MainViewModel()
|
||||
{
|
||||
AppLog.Write("MainViewModel ctor begin");
|
||||
IsAppOwned = _entitlement.IsAppOwned;
|
||||
_youtubeAuth = new YouTubeAuthService(OAuthCredentials.ClientId, OAuthCredentials.ClientSecret,
|
||||
sessionChanged: ch => TokenStore.Save(ch));
|
||||
_youtubeStream = new YouTubeStreamService(_youtubeAuth);
|
||||
|
||||
Reference in New Issue
Block a user