diff --git a/Makefile b/Makefile index ccef937c..d25c1ca1 100644 --- a/Makefile +++ b/Makefile @@ -70,7 +70,11 @@ android-prepare: get-geo-assets get gen translate android-libs android-apk-prepare:android-prepare android-aab-prepare:android-prepare - + +.PHONY: protos +protos: + make -C libcore -f Makefile protos + protoc --dart_out=grpc:lib/singbox/generated --proto_path=libcore/protos libcore/protos/*.proto macos-install-dependencies: brew install create-dmg tree diff --git a/android/app/src/main/kotlin/com/hiddify/hiddify/MethodHandler.kt b/android/app/src/main/kotlin/com/hiddify/hiddify/MethodHandler.kt index 597ea5e7..0608b012 100644 --- a/android/app/src/main/kotlin/com/hiddify/hiddify/MethodHandler.kt +++ b/android/app/src/main/kotlin/com/hiddify/hiddify/MethodHandler.kt @@ -10,6 +10,7 @@ import io.nekohasekai.libbox.Libbox import io.nekohasekai.mobile.Mobile import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -22,6 +23,7 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin, const val channelName = "com.hiddify.app/method" enum class Trigger(val method: String) { + Setup("setup"), ParseConfig("parse_config"), ChangeConfigOptions("change_config_options"), GenerateConfig("generate_config"), @@ -49,6 +51,15 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin, override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { + Trigger.Setup.method -> { + GlobalScope.launch { + result.runCatching { + Mobile.setup() + success("") + } + } + } + Trigger.ParseConfig.method -> { scope.launch(Dispatchers.IO) { result.runCatching { diff --git a/lib/singbox/generated/core.pb.dart b/lib/singbox/generated/core.pb.dart new file mode 100644 index 00000000..733bb0b8 --- /dev/null +++ b/lib/singbox/generated/core.pb.dart @@ -0,0 +1,274 @@ +// +// Generated code. Do not modify. +// source: core.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class ParseConfigRequest extends $pb.GeneratedMessage { + factory ParseConfigRequest({ + $core.String? tempPath, + $core.String? path, + $core.bool? debug, + }) { + final $result = create(); + if (tempPath != null) { + $result.tempPath = tempPath; + } + if (path != null) { + $result.path = path; + } + if (debug != null) { + $result.debug = debug; + } + return $result; + } + ParseConfigRequest._() : super(); + factory ParseConfigRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ParseConfigRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ParseConfigRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'ConfigOptions'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'tempPath', protoName: 'tempPath') + ..aOS(2, _omitFieldNames ? '' : 'path') + ..aOB(3, _omitFieldNames ? '' : 'debug') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ParseConfigRequest clone() => ParseConfigRequest()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ParseConfigRequest copyWith(void Function(ParseConfigRequest) updates) => super.copyWith((message) => updates(message as ParseConfigRequest)) as ParseConfigRequest; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static ParseConfigRequest create() => ParseConfigRequest._(); + ParseConfigRequest createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ParseConfigRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ParseConfigRequest? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get tempPath => $_getSZ(0); + @$pb.TagNumber(1) + set tempPath($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasTempPath() => $_has(0); + @$pb.TagNumber(1) + void clearTempPath() => clearField(1); + + @$pb.TagNumber(2) + $core.String get path => $_getSZ(1); + @$pb.TagNumber(2) + set path($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasPath() => $_has(1); + @$pb.TagNumber(2) + void clearPath() => clearField(2); + + @$pb.TagNumber(3) + $core.bool get debug => $_getBF(2); + @$pb.TagNumber(3) + set debug($core.bool v) { $_setBool(2, v); } + @$pb.TagNumber(3) + $core.bool hasDebug() => $_has(2); + @$pb.TagNumber(3) + void clearDebug() => clearField(3); +} + +class ParseConfigResponse extends $pb.GeneratedMessage { + factory ParseConfigResponse({ + $core.String? error, + }) { + final $result = create(); + if (error != null) { + $result.error = error; + } + return $result; + } + ParseConfigResponse._() : super(); + factory ParseConfigResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ParseConfigResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ParseConfigResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'ConfigOptions'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'error') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + ParseConfigResponse clone() => ParseConfigResponse()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + ParseConfigResponse copyWith(void Function(ParseConfigResponse) updates) => super.copyWith((message) => updates(message as ParseConfigResponse)) as ParseConfigResponse; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static ParseConfigResponse create() => ParseConfigResponse._(); + ParseConfigResponse createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ParseConfigResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ParseConfigResponse? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get error => $_getSZ(0); + @$pb.TagNumber(1) + set error($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasError() => $_has(0); + @$pb.TagNumber(1) + void clearError() => clearField(1); +} + +class GenerateConfigRequest extends $pb.GeneratedMessage { + factory GenerateConfigRequest({ + $core.String? path, + $core.bool? debug, + }) { + final $result = create(); + if (path != null) { + $result.path = path; + } + if (debug != null) { + $result.debug = debug; + } + return $result; + } + GenerateConfigRequest._() : super(); + factory GenerateConfigRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GenerateConfigRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'GenerateConfigRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'ConfigOptions'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'path') + ..aOB(2, _omitFieldNames ? '' : 'debug') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GenerateConfigRequest clone() => GenerateConfigRequest()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GenerateConfigRequest copyWith(void Function(GenerateConfigRequest) updates) => super.copyWith((message) => updates(message as GenerateConfigRequest)) as GenerateConfigRequest; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static GenerateConfigRequest create() => GenerateConfigRequest._(); + GenerateConfigRequest createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GenerateConfigRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GenerateConfigRequest? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get path => $_getSZ(0); + @$pb.TagNumber(1) + set path($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasPath() => $_has(0); + @$pb.TagNumber(1) + void clearPath() => clearField(1); + + @$pb.TagNumber(2) + $core.bool get debug => $_getBF(1); + @$pb.TagNumber(2) + set debug($core.bool v) { $_setBool(1, v); } + @$pb.TagNumber(2) + $core.bool hasDebug() => $_has(1); + @$pb.TagNumber(2) + void clearDebug() => clearField(2); +} + +class GenerateConfigResponse extends $pb.GeneratedMessage { + factory GenerateConfigResponse({ + $core.String? config, + $core.String? error, + }) { + final $result = create(); + if (config != null) { + $result.config = config; + } + if (error != null) { + $result.error = error; + } + return $result; + } + GenerateConfigResponse._() : super(); + factory GenerateConfigResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory GenerateConfigResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'GenerateConfigResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'ConfigOptions'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'config') + ..aOS(2, _omitFieldNames ? '' : 'error') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + GenerateConfigResponse clone() => GenerateConfigResponse()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + GenerateConfigResponse copyWith(void Function(GenerateConfigResponse) updates) => super.copyWith((message) => updates(message as GenerateConfigResponse)) as GenerateConfigResponse; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static GenerateConfigResponse create() => GenerateConfigResponse._(); + GenerateConfigResponse createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static GenerateConfigResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static GenerateConfigResponse? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get config => $_getSZ(0); + @$pb.TagNumber(1) + set config($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasConfig() => $_has(0); + @$pb.TagNumber(1) + void clearConfig() => clearField(1); + + @$pb.TagNumber(2) + $core.String get error => $_getSZ(1); + @$pb.TagNumber(2) + set error($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasError() => $_has(1); + @$pb.TagNumber(2) + void clearError() => clearField(2); +} + + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/lib/singbox/generated/core.pbenum.dart b/lib/singbox/generated/core.pbenum.dart new file mode 100644 index 00000000..04442479 --- /dev/null +++ b/lib/singbox/generated/core.pbenum.dart @@ -0,0 +1,11 @@ +// +// Generated code. Do not modify. +// source: core.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + diff --git a/lib/singbox/generated/core.pbgrpc.dart b/lib/singbox/generated/core.pbgrpc.dart new file mode 100644 index 00000000..ea886f1f --- /dev/null +++ b/lib/singbox/generated/core.pbgrpc.dart @@ -0,0 +1,79 @@ +// +// Generated code. Do not modify. +// source: core.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:async' as $async; +import 'dart:core' as $core; + +import 'package:grpc/service_api.dart' as $grpc; +import 'package:protobuf/protobuf.dart' as $pb; + +import 'core.pb.dart' as $0; + +export 'core.pb.dart'; + +@$pb.GrpcServiceName('ConfigOptions.CoreService') +class CoreServiceClient extends $grpc.Client { + static final _$parseConfig = $grpc.ClientMethod<$0.ParseConfigRequest, $0.ParseConfigResponse>( + '/ConfigOptions.CoreService/ParseConfig', + ($0.ParseConfigRequest value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.ParseConfigResponse.fromBuffer(value)); + static final _$generateFullConfig = $grpc.ClientMethod<$0.GenerateConfigRequest, $0.GenerateConfigResponse>( + '/ConfigOptions.CoreService/GenerateFullConfig', + ($0.GenerateConfigRequest value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.GenerateConfigResponse.fromBuffer(value)); + + CoreServiceClient($grpc.ClientChannel channel, + {$grpc.CallOptions? options, + $core.Iterable<$grpc.ClientInterceptor>? interceptors}) + : super(channel, options: options, + interceptors: interceptors); + + $grpc.ResponseFuture<$0.ParseConfigResponse> parseConfig($0.ParseConfigRequest request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$parseConfig, request, options: options); + } + + $grpc.ResponseFuture<$0.GenerateConfigResponse> generateFullConfig($0.GenerateConfigRequest request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$generateFullConfig, request, options: options); + } +} + +@$pb.GrpcServiceName('ConfigOptions.CoreService') +abstract class CoreServiceBase extends $grpc.Service { + $core.String get $name => 'ConfigOptions.CoreService'; + + CoreServiceBase() { + $addMethod($grpc.ServiceMethod<$0.ParseConfigRequest, $0.ParseConfigResponse>( + 'ParseConfig', + parseConfig_Pre, + false, + false, + ($core.List<$core.int> value) => $0.ParseConfigRequest.fromBuffer(value), + ($0.ParseConfigResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$0.GenerateConfigRequest, $0.GenerateConfigResponse>( + 'GenerateFullConfig', + generateFullConfig_Pre, + false, + false, + ($core.List<$core.int> value) => $0.GenerateConfigRequest.fromBuffer(value), + ($0.GenerateConfigResponse value) => value.writeToBuffer())); + } + + $async.Future<$0.ParseConfigResponse> parseConfig_Pre($grpc.ServiceCall call, $async.Future<$0.ParseConfigRequest> request) async { + return parseConfig(call, await request); + } + + $async.Future<$0.GenerateConfigResponse> generateFullConfig_Pre($grpc.ServiceCall call, $async.Future<$0.GenerateConfigRequest> request) async { + return generateFullConfig(call, await request); + } + + $async.Future<$0.ParseConfigResponse> parseConfig($grpc.ServiceCall call, $0.ParseConfigRequest request); + $async.Future<$0.GenerateConfigResponse> generateFullConfig($grpc.ServiceCall call, $0.GenerateConfigRequest request); +} diff --git a/lib/singbox/generated/core.pbjson.dart b/lib/singbox/generated/core.pbjson.dart new file mode 100644 index 00000000..bc3dee43 --- /dev/null +++ b/lib/singbox/generated/core.pbjson.dart @@ -0,0 +1,77 @@ +// +// Generated code. Do not modify. +// source: core.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use parseConfigRequestDescriptor instead') +const ParseConfigRequest$json = { + '1': 'ParseConfigRequest', + '2': [ + {'1': 'tempPath', '3': 1, '4': 1, '5': 9, '10': 'tempPath'}, + {'1': 'path', '3': 2, '4': 1, '5': 9, '10': 'path'}, + {'1': 'debug', '3': 3, '4': 1, '5': 8, '10': 'debug'}, + ], +}; + +/// Descriptor for `ParseConfigRequest`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List parseConfigRequestDescriptor = $convert.base64Decode( + 'ChJQYXJzZUNvbmZpZ1JlcXVlc3QSGgoIdGVtcFBhdGgYASABKAlSCHRlbXBQYXRoEhIKBHBhdG' + 'gYAiABKAlSBHBhdGgSFAoFZGVidWcYAyABKAhSBWRlYnVn'); + +@$core.Deprecated('Use parseConfigResponseDescriptor instead') +const ParseConfigResponse$json = { + '1': 'ParseConfigResponse', + '2': [ + {'1': 'error', '3': 1, '4': 1, '5': 9, '9': 0, '10': 'error', '17': true}, + ], + '8': [ + {'1': '_error'}, + ], +}; + +/// Descriptor for `ParseConfigResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List parseConfigResponseDescriptor = $convert.base64Decode( + 'ChNQYXJzZUNvbmZpZ1Jlc3BvbnNlEhkKBWVycm9yGAEgASgJSABSBWVycm9yiAEBQggKBl9lcn' + 'Jvcg=='); + +@$core.Deprecated('Use generateConfigRequestDescriptor instead') +const GenerateConfigRequest$json = { + '1': 'GenerateConfigRequest', + '2': [ + {'1': 'path', '3': 1, '4': 1, '5': 9, '10': 'path'}, + {'1': 'debug', '3': 2, '4': 1, '5': 8, '10': 'debug'}, + ], +}; + +/// Descriptor for `GenerateConfigRequest`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List generateConfigRequestDescriptor = $convert.base64Decode( + 'ChVHZW5lcmF0ZUNvbmZpZ1JlcXVlc3QSEgoEcGF0aBgBIAEoCVIEcGF0aBIUCgVkZWJ1ZxgCIA' + 'EoCFIFZGVidWc='); + +@$core.Deprecated('Use generateConfigResponseDescriptor instead') +const GenerateConfigResponse$json = { + '1': 'GenerateConfigResponse', + '2': [ + {'1': 'config', '3': 1, '4': 1, '5': 9, '10': 'config'}, + {'1': 'error', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'error', '17': true}, + ], + '8': [ + {'1': '_error'}, + ], +}; + +/// Descriptor for `GenerateConfigResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List generateConfigResponseDescriptor = $convert.base64Decode( + 'ChZHZW5lcmF0ZUNvbmZpZ1Jlc3BvbnNlEhYKBmNvbmZpZxgBIAEoCVIGY29uZmlnEhkKBWVycm' + '9yGAIgASgJSABSBWVycm9yiAEBQggKBl9lcnJvcg=='); + diff --git a/lib/singbox/service/core_singbox_service.dart b/lib/singbox/service/core_singbox_service.dart new file mode 100644 index 00000000..7c3fa9cc --- /dev/null +++ b/lib/singbox/service/core_singbox_service.dart @@ -0,0 +1,48 @@ +import 'package:fpdart/fpdart.dart'; +import 'package:grpc/grpc.dart'; +import 'package:hiddify/singbox/generated/core.pbgrpc.dart'; +import 'package:hiddify/singbox/service/singbox_service.dart'; + +abstract class CoreSingboxService extends CoreServiceClient + implements SingboxService { + CoreSingboxService() + : super( + ClientChannel( + 'localhost', + port: 7078, + options: const ChannelOptions( + credentials: ChannelCredentials.insecure(), + ), + ), + ); + + @override + TaskEither validateConfigByPath( + String path, + String tempPath, + bool debug, + ) { + return TaskEither( + () async { + final response = await parseConfig( + ParseConfigRequest(tempPath: tempPath, path: path, debug: false), + ); + if (response.error != "") return left(response.error); + return right(unit); + }, + ); + } + + @override + TaskEither generateFullConfigByPath(String path) { + return TaskEither( + () async { + final response = await generateFullConfig( + GenerateConfigRequest(path: path, debug: false), + ); + if (response.error != "") return left(response.error); + return right(response.config); + }, + ); + } +} diff --git a/lib/singbox/service/platform_singbox_service.dart b/lib/singbox/service/platform_singbox_service.dart index e8376584..e7707efa 100644 --- a/lib/singbox/service/platform_singbox_service.dart +++ b/lib/singbox/service/platform_singbox_service.dart @@ -9,11 +9,14 @@ import 'package:hiddify/singbox/model/singbox_outbound.dart'; import 'package:hiddify/singbox/model/singbox_stats.dart'; import 'package:hiddify/singbox/model/singbox_status.dart'; import 'package:hiddify/singbox/model/warp_account.dart'; +import 'package:hiddify/singbox/service/core_singbox_service.dart'; import 'package:hiddify/singbox/service/singbox_service.dart'; import 'package:hiddify/utils/custom_loggers.dart'; import 'package:rxdart/rxdart.dart'; -class PlatformSingboxService with InfraLogger implements SingboxService { +class PlatformSingboxService extends CoreSingboxService + with InfraLogger + implements SingboxService { static const channelPrefix = "com.hiddify.app"; static const methodChannel = MethodChannel("$channelPrefix/method"); @@ -46,30 +49,9 @@ class PlatformSingboxService with InfraLogger implements SingboxService { TaskEither setup(Directories directories, bool debug) { return TaskEither( () async { - if (!Platform.isIOS) { - return right(unit); - } - await methodChannel.invokeMethod("setup"); - return right(unit); - }, - ); - } - @override - TaskEither validateConfigByPath( - String path, - String tempPath, - bool debug, - ) { - return TaskEither( - () async { - final message = await methodChannel.invokeMethod( - "parse_config", - {"path": path, "tempPath": tempPath, "debug": debug}, - ); - if (message == null || message.isEmpty) return right(unit); - return left(message); + return right(unit); }, ); } @@ -88,23 +70,6 @@ class PlatformSingboxService with InfraLogger implements SingboxService { ); } - @override - TaskEither generateFullConfigByPath(String path) { - return TaskEither( - () async { - loggy.debug("generating full config by path"); - final configJson = await methodChannel.invokeMethod( - "generate_config", - {"path": path}, - ); - if (configJson == null || configJson.isEmpty) { - return left("null response"); - } - return right(configJson); - }, - ); - } - @override TaskEither start( String path, diff --git a/libcore b/libcore index ec9efac5..85cc81a4 160000 --- a/libcore +++ b/libcore @@ -1 +1 @@ -Subproject commit ec9efac57c6638dfa8311ddde3c1e28b4b1bd9b2 +Subproject commit 85cc81a46ad041a5c6f4ebb22df3af2ce9c3206a diff --git a/pubspec.lock b/pubspec.lock index b0c925fb..fe3121a1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -718,6 +718,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.1" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "9482364c9f8b7bd36902572ebc3a7c2b5c8ee57a9c93e6eb5099c1a9ec5265d8" + url: "https://pub.dev" + source: hosted + version: "0.3.1+1" + googleapis_auth: + dependency: transitive + description: + name: googleapis_auth + sha256: cafc46446574fd42826aa4cd4d623c94482598fda0a5a5649bf2781bcbc09258 + url: "https://pub.dev" + source: hosted + version: "1.5.0" graphs: dependency: transitive description: @@ -726,6 +742,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" + grpc: + dependency: "direct main" + description: + name: grpc + sha256: e93ee3bce45c134bf44e9728119102358c7cd69de7832d9a874e2e74eb8cab40 + url: "https://pub.dev" + source: hosted + version: "3.2.4" hooks_riverpod: dependency: "direct main" description: @@ -750,6 +774,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + http2: + dependency: transitive + description: + name: http2 + sha256: "9ced024a160b77aba8fb8674e38f70875e321d319e6f303ec18e87bd5a4b0c1d" + url: "https://pub.dev" + source: hosted + version: "2.3.0" http_multi_server: dependency: transitive description: @@ -1214,6 +1246,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + protobuf: + dependency: "direct main" + description: + name: protobuf + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" + source: hosted + version: "3.1.0" protocol_handler: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 4220fb6a..bba7cd48 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -80,6 +80,8 @@ dependencies: # circle_flags: ^4.0.2 circle_flags: git: https://github.com/hiddify-com/flutter_circle_flags.git + protobuf: ^3.1.0 + grpc: ^3.2.4 dev_dependencies: flutter_test: