Files
bansonic_beta_main/Assets/scripts/_runtimecache/DlcOwnershipService.cs
T
2026-06-25 11:48:56 +08:00

205 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
#if !UNITY_WEBGL
using Steamworks;
#endif
public enum DlcEntitlementSource
{
None = 0,
BuiltIn = 1,
LocalFlag = 2,
Steam = 3,
RemoteCache = 4
}
public readonly struct DlcEntitlementState
{
public readonly bool owned;
public readonly bool installed;
public readonly DlcEntitlementSource source;
public readonly string dlcKey;
public DlcEntitlementState(string key, bool ownedValue, bool installedValue, DlcEntitlementSource entitlementSource)
{
dlcKey = key ?? string.Empty;
owned = ownedValue;
installed = installedValue;
source = entitlementSource;
}
}
public static class DlcOwnershipService
{
private const string RemoteOwnershipPrefsPrefix = "dlc_remote_owned_";
private const string LocalOverridePrefsPrefix = "dlc_local_override_";
private static readonly Dictionary<string, DlcEntitlementState> Cache =
new Dictionary<string, DlcEntitlementState>(StringComparer.OrdinalIgnoreCase);
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
private static void ResetState()
{
Cache.Clear();
}
public static bool IsDlcOwned(dlcData dlc)
{
return GetEntitlement(dlc).owned;
}
public static bool IsDlcOwned(string dlcKey)
{
dlcData dlc = FindDlcByKey(dlcKey);
if (dlc == null)
{
return true;
}
return IsDlcOwned(dlc);
}
public static DlcEntitlementState GetEntitlement(dlcData dlc)
{
if (dlc == null)
{
return new DlcEntitlementState(string.Empty, true, true, DlcEntitlementSource.BuiltIn);
}
string key = dlc.GetResolvedDlcKey();
if (Cache.TryGetValue(key, out DlcEntitlementState cached))
{
return cached;
}
DlcEntitlementState resolved = ResolveEntitlement(dlc, key);
Cache[key] = resolved;
return resolved;
}
public static void SetRemoteOwned(string dlcKey, bool owned)
{
if (string.IsNullOrWhiteSpace(dlcKey))
{
return;
}
string safeKey = dlcKey.Trim();
PlayerPrefs.SetInt(RemoteOwnershipPrefsPrefix + safeKey, owned ? 1 : 0);
PlayerPrefs.Save();
Cache.Remove(safeKey);
}
public static void SetLocalOwnershipOverride(string dlcKey, bool? owned)
{
if (string.IsNullOrWhiteSpace(dlcKey))
{
return;
}
string safeKey = dlcKey.Trim();
string prefsKey = LocalOverridePrefsPrefix + safeKey;
if (owned.HasValue)
{
PlayerPrefs.SetInt(prefsKey, owned.Value ? 1 : 0);
}
else
{
PlayerPrefs.DeleteKey(prefsKey);
}
PlayerPrefs.Save();
Cache.Remove(safeKey);
}
public static void InvalidateCache()
{
Cache.Clear();
}
private static DlcEntitlementState ResolveEntitlement(dlcData dlc, string key)
{
if (!dlc.ShouldEnforceEntitlement())
{
return new DlcEntitlementState(key, true, dlc.builtInContent, DlcEntitlementSource.BuiltIn);
}
bool? localOverride = ReadOverride(key);
if (localOverride.HasValue)
{
bool overrideValue = localOverride.Value;
return new DlcEntitlementState(key, overrideValue, overrideValue, DlcEntitlementSource.LocalFlag);
}
if (dlc.dlcIsUnlocked)
{
return new DlcEntitlementState(key, true, true, DlcEntitlementSource.LocalFlag);
}
#if !UNITY_WEBGL
if (dlc.steamAppId > 0 && SteamManager.Initialized)
{
try
{
AppId_t appId = new AppId_t((uint)Mathf.Max(0, dlc.steamAppId));
bool installed = SteamApps.BIsDlcInstalled(appId);
if (installed)
{
return new DlcEntitlementState(key, true, true, DlcEntitlementSource.Steam);
}
}
catch (Exception ex)
{
Debug.LogWarning("[DLC] Steam entitlement check failed for '" + key + "': " + ex.Message);
}
}
#endif
bool remoteOwned = PlayerPrefs.GetInt(RemoteOwnershipPrefsPrefix + key, 0) == 1;
if (remoteOwned)
{
return new DlcEntitlementState(key, true, dlc.builtInContent, DlcEntitlementSource.RemoteCache);
}
return new DlcEntitlementState(key, false, false, DlcEntitlementSource.None);
}
private static bool? ReadOverride(string key)
{
string prefsKey = LocalOverridePrefsPrefix + key;
if (!PlayerPrefs.HasKey(prefsKey))
{
return null;
}
return PlayerPrefs.GetInt(prefsKey, 0) == 1;
}
private static dlcData FindDlcByKey(string dlcKey)
{
if (string.IsNullOrWhiteSpace(dlcKey))
{
return null;
}
string safeKey = dlcKey.Trim();
dlcData[] allDlcs = RuntimeResourcesCache.LoadAllDlcs();
for (int i = 0; i < allDlcs.Length; i++)
{
dlcData dlc = allDlcs[i];
if (dlc == null)
{
continue;
}
if (string.Equals(dlc.GetResolvedDlcKey(), safeKey, StringComparison.OrdinalIgnoreCase))
{
return dlc;
}
}
return null;
}
}