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 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 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 _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 _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"; } }