233 lines
6.3 KiB
C#
233 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX
|
|
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();
|
|
}
|
|
|
|
public static void ClearLocalPersistence()
|
|
{
|
|
dlcData[] allDlcs = RuntimeResourcesCache.LoadAllDlcs();
|
|
if (allDlcs != null)
|
|
{
|
|
for (int i = 0; i < allDlcs.Length; i++)
|
|
{
|
|
dlcData dlc = allDlcs[i];
|
|
if (dlc == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string key = dlc.GetResolvedDlcKey();
|
|
if (string.IsNullOrWhiteSpace(key))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
PlayerPrefs.DeleteKey(RemoteOwnershipPrefsPrefix + key);
|
|
PlayerPrefs.DeleteKey(LocalOverridePrefsPrefix + key);
|
|
}
|
|
}
|
|
|
|
PlayerPrefs.Save();
|
|
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_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX
|
|
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;
|
|
}
|
|
}
|