using System; using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Net.Http.Json; using System.Text.Json; using System.Threading.Tasks; using EveryPublish.Client.Models; namespace EveryPublish.Client.Services; /// agent-core 本机控制客户端(读 local.json → 127.0.0.1 + token 鉴权) public class CoreClient : IDisposable { private readonly HttpClient _http; private readonly string _dataDir; private string _base = ""; private string _token = ""; public CoreClient(string dataDir) { _dataDir = dataDir; _http = new HttpClient { Timeout = TimeSpan.FromSeconds(5) }; ReloadLocalJson(); } /// 重新读取 data/local.json(端口/token,core 每次启动随机) public void ReloadLocalJson() { try { var path = Path.Combine(_dataDir, "local.json"); if (!File.Exists(path)) return; var info = JsonSerializer.Deserialize(File.ReadAllText(path)); if (info == null || info.Port <= 0 || string.IsNullOrEmpty(info.Token)) return; _base = "http://127.0.0.1:" + info.Port; _token = info.Token; } catch { // core 尚未写入 local.json,稍后重试 } } private HttpRequestMessage NewRequest(HttpMethod method, string path) { var req = new HttpRequestMessage(method, _base + path); req.Headers.Add("X-Agent-Token", _token); return req; } public async Task GetStatusAsync() { try { using var resp = await _http.SendAsync(NewRequest(HttpMethod.Get, "/status")); if (!resp.IsSuccessStatusCode) return null; return await resp.Content.ReadFromJsonAsync(); } catch { return null; } } public async Task> GetChallengesAsync() { try { using var resp = await _http.SendAsync(NewRequest(HttpMethod.Get, "/challenges")); if (!resp.IsSuccessStatusCode) return new List(); var doc = await resp.Content.ReadFromJsonAsync(); if (doc.TryGetProperty("list", out var list)) { return list.Deserialize>() ?? new List(); } return new List(); } catch { return new List(); } } public Task<(bool Ok, string Message)> PairAsync(string code, string name) { return PostAsync("/pair", new { code, name }); } public Task<(bool Ok, string Message)> SolveAsync(string challengeId, string value) { return PostAsync("/challenges/" + challengeId, new { value }); } private async Task<(bool Ok, string Message)> PostAsync(string path, object body) { try { using var req = NewRequest(HttpMethod.Post, path); req.Content = JsonContent.Create(body); using var resp = await _http.SendAsync(req); var doc = await resp.Content.ReadFromJsonAsync(); var ok = doc.TryGetProperty("code", out var c) && c.GetInt32() == 0; var msg = doc.TryGetProperty("message", out var m) ? m.GetString() ?? "" : ""; return (ok, msg); } catch (Exception ex) { return (false, "无法连接客户端核心:" + ex.Message); } } public void Dispose() { _http.Dispose(); } }