import 'dart:async'; import 'print/backend.dart'; import 'print/mock_backend.dart'; import 'server/http_server.dart'; import 'server/print_queue.dart'; import 'utils/file_log.dart'; /// 启动参数:--mock 模拟打印;--port=NNN / --port NNN 指定监听端口(默认 38200-38202 顺延)。 class AgentOptions { AgentOptions({this.mock = false, this.port}); final bool mock; final int? port; factory AgentOptions.parse(List args) { var mock = false; int? port; for (var i = 0; i < args.length; i++) { final arg = args[i]; if (arg == '--mock') { mock = true; } else if (arg.startsWith('--port=')) { port = int.tryParse(arg.substring('--port='.length)); } else if ((arg == '--port' || arg == '-p') && i + 1 < args.length) { port = int.tryParse(args[++i]); } } return AgentOptions(mock: mock, port: port); } } /// 运行日志环形缓冲(GUI 展示用),同时打到 stdout。 class AgentLog { final lines = []; final _controller = StreamController.broadcast(); Stream get stream => _controller.stream; void write(String line) { final stamped = '${DateTime.now().toIso8601String().substring(11, 19)} $line'; lines.add(stamped); if (lines.length > 500) { lines.removeRange(0, lines.length - 500); } // ignore: avoid_print print(stamped); FileLog.write(line); // 文件持久化(供现场排查,用户可取回分析) _controller.add(stamped); } void dispose() => _controller.close(); } /// 助手核心:组合打印后端、任务队列与 HTTP 服务(Flutter 窗口与 headless 入口共用)。 class Agent { Agent(this.options) : log = AgentLog(); final AgentOptions options; final AgentLog log; late final PrintQueue queue; late final PrintBackend backend; late final AgentHttpServer server; int? port; Future start() async { final backendName = osBackendName(); backend = options.mock ? MockBackend(onLog: log.write) : createOsBackend(onLog: log.write); queue = PrintQueue(backend, onLog: log.write); server = AgentHttpServer( queue: queue, backend: backend, mock: options.mock, manifestBackendName: backendName, ); final ports = options.port == null ? const [38200, 38201, 38202] : [options.port!]; port = await server.start(candidatePorts: ports); log.write('资安信插件助手已启动 http://127.0.0.1:$port' '(后端=$backendName,mock=${options.mock},agent=desktop-plugin)'); return port!; } bool _stopped = false; /// 幂等停止:托盘退出与窗口销毁可能先后各调一次。 Future stop() async { if (_stopped) return; _stopped = true; await server.stop(); queue.dispose(); log.dispose(); } }