class ProxyConfig { final String name; final String type; final String server; final int port; final bool? udp; // vless final String? flow; final String? servername; final bool? tls; final Reality? realityOpts; // V2Ray/VLESS特定属性 final String? uuid; final int? alterId; // Shadowsocks特定属性 final String? cipher; final String? password; final String? clientFingerprint; final String? network; final GrpcOpts? grpcOpts; final WsOpts? wsOpts; ProxyConfig({ required this.name, required this.type, required this.server, required this.port, this.password, this.udp, this.flow, this.servername, this.tls, this.realityOpts, // 新增字段 this.grpcOpts, this.wsOpts, this.uuid, this.alterId, this.cipher, this.clientFingerprint, this.network }); // 更新解析方法 factory ProxyConfig.fromMap(Map map) { return ProxyConfig( name: map['name'], type: map['type'], server: map['server'], port: map['port'], password: map['password'], udp: map['udp'], flow: map['flow'], servername: map['servername'], tls: map['tls'], realityOpts: map['reality-opts'] != null ? Reality.fromMap(map['reality-opts']) : null, grpcOpts: map['grpc-opts'] != null ? GrpcOpts.fromMap(map['grpc-opts']) : null, wsOpts: map['ws-opts'] != null ? WsOpts.fromMap(map['ws-opts']) : null, uuid: map['uuid'], alterId: map['alterId'], cipher:map['cipher'], clientFingerprint:map['client-fingerprint'], network:map['network'] ); } // 更新 JSON 序列化方法 Map toJson() { return { 'name': name, 'type': type, 'server': server, 'port': port, 'password': password, 'udp': udp, 'flow': flow, 'servername': servername, 'tls': tls, 'reality-opts': realityOpts?.toJson(), 'uuid': uuid, 'alterId': alterId, 'cipher' : cipher, 'client-fingerprint': clientFingerprint, 'grpc-opts': grpcOpts, 'ws-opts': wsOpts, 'network' : network, }; } String toYaml() { var yaml = ''' - name: $name type: $type server: $server port: $port'''; if (password != null) yaml += '\n password: $password'; if (flow != null) yaml += '\n flow: $flow'; if (servername != null) yaml += '\n servername: $servername'; if (tls != null) yaml += '\n tls: $tls'; final realityOpts = this.realityOpts; if (realityOpts != null) { yaml += '\n reality-opts:'; if (realityOpts.publicKey != null) { yaml += '\n public-key: ${realityOpts.publicKey}'; } if (realityOpts.shortID != null) { yaml += '\n short-id: ${realityOpts.shortID}'; } } if (uuid != null) { yaml += '\n uuid: $uuid'; } if (alterId != null) yaml += '\n alterId: $alterId'; if (cipher != null) yaml += '\n cipher: $cipher'; if (clientFingerprint != null) '\n client-fingerprint: $clientFingerprint'; if(network != null) yaml += '\n network: $network'; if(udp != null) yaml += '\n udp: $udp'; if (grpcOpts != null) { yaml += '\n ${grpcOpts!.toYaml()}'; } if (wsOpts != null) { yaml += '\n ${wsOpts!.toYaml()}'; } return yaml; } } class Reality { final String? publicKey; final String? shortID; Reality({this.publicKey,this.shortID}); factory Reality.fromMap(Map map) { return Reality( publicKey: map['public-key'] as String?, shortID: map['short-id'] as String?, ); } Map toJson() { return { 'public-key': publicKey, 'short-id' : shortID }; } String toYaml() { var yaml = ''; if (publicKey != null) { yaml += ' reality-opts:\n public-key: $publicKey\n'; } if (shortID != null) { yaml += ' short-id: $shortID\n'; } return yaml; } } class GrpcOpts { final String? grpcServiceName; GrpcOpts({this.grpcServiceName}); factory GrpcOpts.fromMap(Map map) { return GrpcOpts( grpcServiceName: map['grpc-service-name'] as String?, ); } Map toJson() { return { if (grpcServiceName != null) 'grpc-service-name': grpcServiceName, }; } String toYaml() { if (grpcServiceName == null) { return ''; } return ' grpc-opts:\n grpc-service-name: "$grpcServiceName"'; } } class WsOpts { final String? path; final Map? headers; WsOpts({this.path, this.headers}); factory WsOpts.fromMap(Map map) { return WsOpts( path: map['path'] as String?, headers: (map['headers'] as Map?)?.cast(), ); } Map toJson() { return { if (path != null) 'path': path, if (headers != null) 'headers': headers, }; } String toYaml() { var yaml = 'ws-opts:'; if (path != null) { yaml += '\n path: $path'; } if (headers != null && headers!.isNotEmpty) { yaml += '\n headers:'; headers!.forEach((key, value) { yaml += '\n $key: $value'; }); } return yaml; } }