using System; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading.Tasks; namespace KSTools.Licensing { /// /// KSTools 授權 API 客戶端 /// 負責與授權管理系統的 API 通信 /// public class ApiClient { private static readonly string DEFAULT_API_BASE = "https://your-space.hf.space/api"; private static readonly HttpClient httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(30) }; private readonly string _apiBase; /// /// 初始化 API 客戶端 /// /// API 基礎 URL,如果為空則使用預設值 public ApiClient(string apiBase = null) { _apiBase = string.IsNullOrEmpty(apiBase) ? DEFAULT_API_BASE : apiBase.TrimEnd('/'); // 設定 HTTP 客戶端標頭 httpClient.DefaultRequestHeaders.Clear(); httpClient.DefaultRequestHeaders.Add("User-Agent", "KSTools-Revit-Plugin/1.0"); } /// /// 啟用授權 /// /// 授權碼 /// 硬體指紋ID,如果為空則自動生成 /// 啟用結果 public async Task ActivateLicenseAsync(string licenseCode, string hardwareId = null) { try { if (string.IsNullOrEmpty(licenseCode)) { return new ActivationResult { Success = false, Message = "授權碼不能為空" }; } // 如果沒有提供硬體ID,自動生成 if (string.IsNullOrEmpty(hardwareId)) { hardwareId = HardwareFingerprint.GetHardwareId(); } var request = new { license_code = licenseCode, hardware_id = hardwareId, machine_name = Environment.MachineName }; var json = JsonSerializer.Serialize(request, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync($"{_apiBase}/license/activate", content); var resultJson = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { var apiResponse = JsonSerializer.Deserialize(resultJson, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); return new ActivationResult { Success = apiResponse.Success, Message = apiResponse.Message, ExpiresAt = apiResponse.ExpiresAt, UserName = apiResponse.UserName, HardwareId = apiResponse.HardwareId }; } else { return new ActivationResult { Success = false, Message = $"HTTP 錯誤 {response.StatusCode}: {resultJson}" }; } } catch (HttpRequestException ex) { return new ActivationResult { Success = false, Message = $"網路連接錯誤: {ex.Message}" }; } catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) { return new ActivationResult { Success = false, Message = "請求超時,請檢查網路連接" }; } catch (Exception ex) { return new ActivationResult { Success = false, Message = $"未知錯誤: {ex.Message}" }; } } /// /// 驗證授權 /// /// 授權碼 /// 硬體指紋ID,如果為空則自動生成 /// 驗證結果 public async Task ValidateLicenseAsync(string licenseCode, string hardwareId = null) { try { if (string.IsNullOrEmpty(licenseCode)) { return new ValidationResult { Valid = false, Message = "授權碼不能為空" }; } // 如果沒有提供硬體ID,自動生成 if (string.IsNullOrEmpty(hardwareId)) { hardwareId = HardwareFingerprint.GetHardwareId(); } var request = new { license_code = licenseCode, hardware_id = hardwareId, machine_name = Environment.MachineName }; var json = JsonSerializer.Serialize(request, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync($"{_apiBase}/license/validate", content); var resultJson = await response.Content.ReadAsStringAsync(); if (response.IsSuccessStatusCode) { var apiResponse = JsonSerializer.Deserialize(resultJson, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); return new ValidationResult { Valid = apiResponse.Valid, Message = apiResponse.Message, ExpiresAt = apiResponse.ExpiresAt, UserName = apiResponse.UserName, HardwareId = apiResponse.HardwareId }; } else { return new ValidationResult { Valid = false, Message = $"HTTP 錯誤 {response.StatusCode}: {resultJson}" }; } } catch (HttpRequestException ex) { return new ValidationResult { Valid = false, Message = $"網路連接錯誤: {ex.Message}" }; } catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) { return new ValidationResult { Valid = false, Message = "請求超時,請檢查網路連接" }; } catch (Exception ex) { return new ValidationResult { Valid = false, Message = $"未知錯誤: {ex.Message}" }; } } /// /// 測試 API 連接 /// /// 是否連接成功 public async Task TestConnectionAsync() { try { var response = await httpClient.GetAsync($"{_apiBase.Replace("/api", "")}/health"); return response.IsSuccessStatusCode; } catch { return false; } } } #region API 回應模型 /// /// API 啟用回應模型 /// internal class ApiActivationResponse { public bool Success { get; set; } public string Message { get; set; } public DateTime? ExpiresAt { get; set; } public string UserName { get; set; } public string HardwareId { get; set; } } /// /// API 驗證回應模型 /// internal class ApiValidationResponse { public bool Valid { get; set; } public string Message { get; set; } public DateTime? ExpiresAt { get; set; } public string UserName { get; set; } public string HardwareId { get; set; } } #endregion #region 公開結果模型 /// /// 授權啟用結果 /// public class ActivationResult { /// /// 啟用是否成功 /// public bool Success { get; set; } /// /// 狀態訊息 /// public string Message { get; set; } /// /// 授權到期時間 /// public DateTime? ExpiresAt { get; set; } /// /// 授權用戶名稱 /// public string UserName { get; set; } /// /// 硬體指紋ID /// public string HardwareId { get; set; } } /// /// 授權驗證結果 /// public class ValidationResult { /// /// 授權是否有效 /// public bool Valid { get; set; } /// /// 狀態訊息 /// public string Message { get; set; } /// /// 授權到期時間 /// public DateTime? ExpiresAt { get; set; } /// /// 授權用戶名稱 /// public string UserName { get; set; } /// /// 硬體指紋ID /// public string HardwareId { get; set; } } #endregion }