Files
2025-11-30 08:35:03 +02:00

142 lines
4.6 KiB
C#

using System;
using System.Threading;
using System.Threading.Tasks;
using UnityEditor;
namespace Needle.Engine
{
internal abstract class LicenseCheck
{
// ReSharper disable once EventNeverSubscribedTo.Local
#pragma warning disable CS0067
private static event Action<bool> ReceivedLicenseReply;
#pragma warning restore CS0067
internal static bool LastLicenseCheckReturnedNull { get; private set; } = false;
private static readonly WebClientHelper client =
new WebClientHelper("https://urls.needle.tools/license-endpoint-cloud");
public static Task<bool> QueryLicense(bool invalidateCurrentLicense)
{
#if UNITY_EDITOR
var currentLicenseType = LastLicenseTypeResult;
if (invalidateCurrentLicense)
{
_licenseCheckCancellationTokenSource.Cancel();
if (_currentQueryLicenseTask != null)
{
NeedleDebug.Log(TracingScenario.AuthenticationState, "Cancelling previous license check since an invalidation was requested.");
}
_currentQueryLicenseTask = null;
LastLicenseTypeResult = null;
}
if (_currentQueryLicenseTask == null)
{
_licenseCheckCancellationTokenSource = new CancellationTokenSource();
_currentQueryLicenseTask = _QueryLicense(_licenseCheckCancellationTokenSource.Token);
}
if (invalidateCurrentLicense && LastLicenseTypeResult != currentLicenseType)
Authentication.LicenseChanged?.Invoke();
return _currentQueryLicenseTask;
#else
return Task.FromResult(false);
#endif
}
#if UNITY_EDITOR
private static CancellationTokenSource _licenseCheckCancellationTokenSource = new CancellationTokenSource();
private static async Task<bool> _QueryLicense(CancellationToken token)
{
NeedleDebug.Log(TracingScenario.AuthenticationState, "Checking license...");
var currentLicenseType = LastLicenseTypeResult;
try
{
var license = await Authentication.GetLicenseInformation(token);
LastLicenseCheckReturnedNull = license == null;
LicenseIsActive = license?.needle_engine_license_is_active ?? false;
LastLicenseResult = license != null;
_currentQueryLicenseTask = null;
TryParseLicenseType(license);
ReceivedLicenseReply?.Invoke(true);
return LastLicenseResult ?? false;
}
finally
{
_currentQueryLicenseTask = null;
if (LastLicenseTypeResult != currentLicenseType || !_gotLicenseTypeResultDuringCurrentDomainReload)
{
_gotLicenseTypeResultDuringCurrentDomainReload = true;
Authentication.LicenseChanged?.Invoke();
}
}
}
private static void TryParseLicenseType(LicenseInformation license)
{
var licenseTypeResult = license?.needle_engine_license;
if (OptionOverrides.OverrideLicenseType)
licenseTypeResult = OptionOverrides.LicenseType;
switch (license?.needle_engine_license)
{
case "enterprise":
LastLicenseResult = true;
RequireLicenseAttribute.CurrentLicenseType = LicenseType.Enterprise;
break;
case "pro":
LastLicenseResult = true;
RequireLicenseAttribute.CurrentLicenseType = LicenseType.Pro;
break;
case "indie":
LastLicenseResult = true;
RequireLicenseAttribute.CurrentLicenseType = LicenseType.Indie;
break;
case "edu":
LastLicenseResult = true;
RequireLicenseAttribute.CurrentLicenseType = LicenseType.Edu;
break;
case "basic":
LastLicenseResult = false;
RequireLicenseAttribute.CurrentLicenseType = LicenseType.Basic;
break;
default:
LastLicenseResult = false;
licenseTypeResult = "basic"; // force override this
RequireLicenseAttribute.CurrentLicenseType = LicenseType.Basic;
break;
}
LastLicenseTypeResult = licenseTypeResult;
}
#endif
private static Task<bool> _currentQueryLicenseTask;
internal static bool LicenseCheckInProcess => _currentQueryLicenseTask != null;
internal static bool HasLicense => LastLicenseResult == true;
internal static bool? LastLicenseResult { get; private set; } = null;
internal static bool LicenseIsActive { get; private set; } = false;
internal static string LicenseStatus = "active";
#if UNITY_EDITOR
private static bool _gotLicenseTypeResultDuringCurrentDomainReload = false;
#endif
internal static string LastLicenseTypeResult
{
#if UNITY_EDITOR
get => SessionState.GetString("NEEDLE_ENGINE_last_license_type", null);
private set => SessionState.SetString("NEEDLE_ENGINE_last_license_type", value);
#else
get => null;
private set {}
#endif
}
internal static bool HasCommercialLicense => LastLicenseTypeResult != null && LastLicenseTypeResult != "basic";
internal static bool HasProOrEnterpriseLicense => LastLicenseTypeResult == "pro" || LastLicenseTypeResult == "enterprise";
}
}