using System; using System.IO; using System.Threading.Tasks; using Microsoft.Win32; namespace KSTools.Licensing { /// /// KSTools 授權管理器 /// 提供完整的授權管理功能,包括授權儲存、驗證、快取等 /// public class LicenseManager { private const string REGISTRY_KEY_PATH = @"HKEY_CURRENT_USER\Software\KSTools\RevitPlugin"; private const string LICENSE_CODE_KEY = "LicenseCode"; private const string LICENSE_CACHE_KEY = "LicenseCache"; private const string LAST_VALIDATION_KEY = "LastValidation"; private const int VALIDATION_CACHE_HOURS = 1; // 快取驗證結果1小時 private readonly ApiClient _apiClient; private readonly string _hardwareId; /// /// 初始化授權管理器 /// /// API 基礎 URL public LicenseManager(string apiBaseUrl = null) { _apiClient = new ApiClient(apiBaseUrl); _hardwareId = HardwareFingerprint.GetHardwareId(); } /// /// 取得當前硬體指紋ID /// /// 硬體指紋ID public string GetHardwareId() { return _hardwareId; } /// /// 取得硬體資訊摘要 /// /// 硬體資訊 public string GetHardwareInfo() { return HardwareFingerprint.GetHardwareInfo(); } /// /// 啟用授權並儲存到本地 /// /// 授權碼 /// 啟用結果 public async Task ActivateLicenseAsync(string licenseCode) { try { var result = await _apiClient.ActivateLicenseAsync(licenseCode, _hardwareId); if (result.Success) { // 儲存授權碼到註冊表 StoreLicenseCode(licenseCode); // 儲存快取資訊 StoreLicenseCache(result); // 記錄最後驗證時間 StoreLastValidation(); } return result; } catch (Exception ex) { return new ActivationResult { Success = false, Message = $"啟用過程發生錯誤: {ex.Message}" }; } } /// /// 驗證授權 (使用快取機制) /// /// 是否強制進行線上檢查 /// 驗證結果 public async Task ValidateLicenseAsync(bool forceOnlineCheck = false) { try { string licenseCode = GetStoredLicenseCode(); if (string.IsNullOrEmpty(licenseCode)) { return new ValidationResult { Valid = false, Message = "尚未啟用授權,請先輸入授權碼" }; } // 如果不強制線上檢查,先嘗試使用快取 if (!forceOnlineCheck) { var cachedResult = GetCachedValidation(); if (cachedResult != null) { return cachedResult; } } // 進行線上驗證 var result = await _apiClient.ValidateLicenseAsync(licenseCode, _hardwareId); if (result.Valid) { // 更新快取 StoreLicenseCache(new ActivationResult { Success = true, Message = result.Message, ExpiresAt = result.ExpiresAt, UserName = result.UserName, HardwareId = result.HardwareId }); StoreLastValidation(); } else { // 驗證失敗,清除快取 ClearLicenseCache(); } return result; } catch (Exception ex) { // 網路錯誤時,嘗試使用快取的驗證結果 var cachedResult = GetCachedValidation(); if (cachedResult != null) { cachedResult.Message += " (離線模式)"; return cachedResult; } return new ValidationResult { Valid = false, Message = $"驗證過程發生錯誤: {ex.Message}" }; } } /// /// 檢查是否已有有效授權 (快速檢查) /// /// 是否有有效授權 public bool HasValidLicense() { try { string licenseCode = GetStoredLicenseCode(); if (string.IsNullOrEmpty(licenseCode)) return false; var cachedResult = GetCachedValidation(); return cachedResult?.Valid == true; } catch { return false; } } /// /// 取得授權資訊 /// /// 授權資訊,如果沒有授權則返回 null public LicenseInfo GetLicenseInfo() { try { string licenseCode = GetStoredLicenseCode(); if (string.IsNullOrEmpty(licenseCode)) return null; var cachedData = GetRegistryValue(LICENSE_CACHE_KEY); if (!string.IsNullOrEmpty(cachedData)) { var parts = cachedData.Split('|'); if (parts.Length >= 4) { return new LicenseInfo { LicenseCode = licenseCode, UserName = parts[0], ExpiresAt = DateTime.TryParse(parts[1], out var expires) ? expires : (DateTime?)null, HardwareId = parts[2], LastValidation = DateTime.TryParse(parts[3], out var lastVal) ? lastVal : (DateTime?)null }; } } return new LicenseInfo { LicenseCode = licenseCode, HardwareId = _hardwareId }; } catch { return null; } } /// /// 清除儲存的授權資訊 /// public void ClearLicense() { try { Registry.SetValue(REGISTRY_KEY_PATH, LICENSE_CODE_KEY, ""); ClearLicenseCache(); } catch { // 忽略錯誤 } } /// /// 測試 API 連接 /// /// 是否連接成功 public async Task TestApiConnectionAsync() { return await _apiClient.TestConnectionAsync(); } #region 私有方法 /// /// 儲存授權碼到註冊表 /// /// 授權碼 private void StoreLicenseCode(string licenseCode) { Registry.SetValue(REGISTRY_KEY_PATH, LICENSE_CODE_KEY, licenseCode); } /// /// 從註冊表取得授權碼 /// /// 授權碼 private string GetStoredLicenseCode() { return GetRegistryValue(LICENSE_CODE_KEY); } /// /// 儲存授權快取資訊 /// /// 啟用或驗證結果 private void StoreLicenseCache(ActivationResult result) { string cacheData = $"{result.UserName}|{result.ExpiresAt}|{result.HardwareId}|{DateTime.Now}"; Registry.SetValue(REGISTRY_KEY_PATH, LICENSE_CACHE_KEY, cacheData); } /// /// 記錄最後驗證時間 /// private void StoreLastValidation() { Registry.SetValue(REGISTRY_KEY_PATH, LAST_VALIDATION_KEY, DateTime.Now.ToString()); } /// /// 取得快取的驗證結果 /// /// 驗證結果,如果快取無效則返回 null private ValidationResult GetCachedValidation() { try { string lastValidationStr = GetRegistryValue(LAST_VALIDATION_KEY); if (string.IsNullOrEmpty(lastValidationStr)) return null; if (!DateTime.TryParse(lastValidationStr, out var lastValidation)) return null; // 檢查快取是否過期 if (DateTime.Now - lastValidation > TimeSpan.FromHours(VALIDATION_CACHE_HOURS)) return null; string cacheData = GetRegistryValue(LICENSE_CACHE_KEY); if (string.IsNullOrEmpty(cacheData)) return null; var parts = cacheData.Split('|'); if (parts.Length < 4) return null; DateTime.TryParse(parts[1], out var expiresAt); // 檢查是否已過期 if (expiresAt > DateTime.MinValue && expiresAt < DateTime.Now) { return new ValidationResult { Valid = false, Message = "授權已過期" }; } return new ValidationResult { Valid = true, Message = "授權有效 (快取)", ExpiresAt = expiresAt > DateTime.MinValue ? expiresAt : (DateTime?)null, UserName = parts[0], HardwareId = parts[2] }; } catch { return null; } } /// /// 清除授權快取 /// private void ClearLicenseCache() { try { Registry.SetValue(REGISTRY_KEY_PATH, LICENSE_CACHE_KEY, ""); Registry.SetValue(REGISTRY_KEY_PATH, LAST_VALIDATION_KEY, ""); } catch { // 忽略錯誤 } } /// /// 從註冊表取得值 /// /// 鍵名 /// private string GetRegistryValue(string keyName) { try { return Registry.GetValue(REGISTRY_KEY_PATH, keyName, "")?.ToString() ?? ""; } catch { return ""; } } #endregion } /// /// 授權資訊 /// public class LicenseInfo { /// /// 授權碼 /// public string LicenseCode { get; set; } /// /// 用戶名稱 /// public string UserName { get; set; } /// /// 到期時間 /// public DateTime? ExpiresAt { get; set; } /// /// 硬體指紋ID /// public string HardwareId { get; set; } /// /// 最後驗證時間 /// public DateTime? LastValidation { get; set; } /// /// 是否即將到期 (7天內) /// public bool IsExpiringSoon => ExpiresAt.HasValue && ExpiresAt.Value.Subtract(DateTime.Now).TotalDays <= 7; /// /// 剩餘天數 /// public int DaysRemaining => ExpiresAt.HasValue ? Math.Max(0, (int)ExpiresAt.Value.Subtract(DateTime.Now).TotalDays) : 0; } }