From 33dc21918d43a2df97ed7ac21a49e4d67475aa06 Mon Sep 17 00:00:00 2001 From: problematicconsumer Date: Sun, 18 Feb 2024 12:35:11 +0330 Subject: [PATCH] Add warp config generator --- .../com/hiddify/hiddify/MethodHandler.kt | 36 +- assets/translations/strings_en.i18n.json | 2 + .../data/config_option_data_providers.dart | 2 + .../data/config_option_repository.dart | 37 +- .../model/config_option_entity.dart | 8 + .../model/config_option_failure.dart | 7 + .../notifier/warp_option_notifier.dart | 61 +- .../overview/warp_options_widgets.dart | 23 +- lib/gen/singbox_generated_bindings.dart | 1151 +++-------------- lib/singbox/model/singbox_config_option.dart | 2 + lib/singbox/model/warp_account.dart | 17 + lib/singbox/service/ffi_singbox_service.dart | 41 + .../service/platform_singbox_service.dart | 36 + lib/singbox/service/singbox_service.dart | 7 + libcore | 2 +- 15 files changed, 459 insertions(+), 973 deletions(-) create mode 100644 lib/singbox/model/warp_account.dart 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 6a7f4761..597ea5e7 100644 --- a/android/app/src/main/kotlin/com/hiddify/hiddify/MethodHandler.kt +++ b/android/app/src/main/kotlin/com/hiddify/hiddify/MethodHandler.kt @@ -7,13 +7,14 @@ import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.nekohasekai.libbox.Libbox +import io.nekohasekai.mobile.Mobile import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin, - MethodChannel.MethodCallHandler { + MethodChannel.MethodCallHandler { private var channel: MethodChannel? = null companion object { @@ -30,13 +31,14 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin, SelectOutbound("select_outbound"), UrlTest("url_test"), ClearLogs("clear_logs"), + GenerateWarpConfig("generate_warp_config"), } } override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { channel = MethodChannel( - flutterPluginBinding.binaryMessenger, - channelName, + flutterPluginBinding.binaryMessenger, + channelName, ) channel!!.setMethodCallHandler(this) } @@ -150,10 +152,10 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin, result.runCatching { val args = call.arguments as Map<*, *> Libbox.newStandaloneCommandClient() - .selectOutbound( - args["groupTag"] as String, - args["outboundTag"] as String - ) + .selectOutbound( + args["groupTag"] as String, + args["outboundTag"] as String + ) success(true) } } @@ -164,9 +166,9 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin, result.runCatching { val args = call.arguments as Map<*, *> Libbox.newStandaloneCommandClient() - .urlTest( - args["groupTag"] as String - ) + .urlTest( + args["groupTag"] as String + ) success(true) } } @@ -181,6 +183,20 @@ class MethodHandler(private val scope: CoroutineScope) : FlutterPlugin, } } + Trigger.GenerateWarpConfig.method -> { + scope.launch(Dispatchers.IO) { + result.runCatching { + val args = call.arguments as Map<*, *> + val warpConfig = Mobile.generateWarpConfig( + args["license-key"] as String, + args["previous-account-id"] as String, + args["previous-access-token"] as String, + ) + success(warpConfig) + } + } + } + else -> result.notImplemented() } } diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index d1d4691d..31b62423 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -237,6 +237,8 @@ "title": "Cloudflare WARP Consent", "description(rich)": "Cloudflare WARP is a free WireGuard VPN provider. By enabling this option you are agreeing to the Cloudflare WARP's ${tos(Terms of Service)} and ${privacy(Privacy Policy)}." }, + "generateWarpConfig": "Generate WARP config", + "missingWarpConfig": "Missing WARP config", "pageTitle": "Config Options", "logLevel": "Log Level", "resolveDestination": "Resolve Destination", diff --git a/lib/features/config_option/data/config_option_data_providers.dart b/lib/features/config_option/data/config_option_data_providers.dart index cf8fc061..8176d8d5 100644 --- a/lib/features/config_option/data/config_option_data_providers.dart +++ b/lib/features/config_option/data/config_option_data_providers.dart @@ -1,6 +1,7 @@ import 'package:hiddify/core/preferences/preferences_provider.dart'; import 'package:hiddify/features/config_option/data/config_option_repository.dart'; import 'package:hiddify/features/geo_asset/data/geo_asset_data_providers.dart'; +import 'package:hiddify/singbox/service/singbox_service_provider.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'config_option_data_providers.g.dart'; @@ -11,6 +12,7 @@ ConfigOptionRepository configOptionRepository( ) { return ConfigOptionRepositoryImpl( preferences: ref.watch(sharedPreferencesProvider).requireValue, + singbox: ref.watch(singboxServiceProvider), ); } diff --git a/lib/features/config_option/data/config_option_repository.dart b/lib/features/config_option/data/config_option_repository.dart index 55dde309..c195c495 100644 --- a/lib/features/config_option/data/config_option_repository.dart +++ b/lib/features/config_option/data/config_option_repository.dart @@ -7,6 +7,7 @@ import 'package:hiddify/features/geo_asset/data/geo_asset_path_resolver.dart'; import 'package:hiddify/features/geo_asset/data/geo_asset_repository.dart'; import 'package:hiddify/singbox/model/singbox_config_option.dart'; import 'package:hiddify/singbox/model/singbox_rule.dart'; +import 'package:hiddify/singbox/service/singbox_service.dart'; import 'package:hiddify/utils/utils.dart'; import 'package:meta/meta.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -17,6 +18,7 @@ abstract interface class ConfigOptionRepository { ConfigOptionPatch patch, ); TaskEither resetConfigOption(); + TaskEither generateWarpConfig(); } abstract interface class SingBoxConfigOptionRepository { @@ -27,9 +29,13 @@ abstract interface class SingBoxConfigOptionRepository { class ConfigOptionRepositoryImpl with ExceptionHandler, InfraLogger implements ConfigOptionRepository { - ConfigOptionRepositoryImpl({required this.preferences}); + ConfigOptionRepositoryImpl({ + required this.preferences, + required this.singbox, + }); final SharedPreferences preferences; + final SingboxService singbox; @override Either getConfigOption() { @@ -107,6 +113,35 @@ class ConfigOptionRepositoryImpl } } } + + @override + TaskEither generateWarpConfig() { + return exceptionHandler( + () async { + final options = getConfigOption().getOrElse((l) => throw l); + return await singbox + .generateWarpConfig( + licenseKey: options.warpLicenseKey, + previousAccountId: options.warpAccountId, + previousAccessToken: options.warpAccessToken, + ) + .mapLeft((l) => ConfigOptionFailure.unexpected(l)) + .flatMap( + (warp) => updateConfigOption( + ConfigOptionPatch( + warpAccountId: warp.accountId, + warpAccessToken: warp.accessToken, + ), + ), + ) + .run(); + }, + (error, stackTrace) { + loggy.error(error); + return ConfigOptionUnexpectedFailure(error, stackTrace); + }, + ); + } } class SingBoxConfigOptionRepositoryImpl diff --git a/lib/features/config_option/model/config_option_entity.dart b/lib/features/config_option/model/config_option_entity.dart index 5e8434ab..12076fda 100644 --- a/lib/features/config_option/model/config_option_entity.dart +++ b/lib/features/config_option/model/config_option_entity.dart @@ -61,6 +61,8 @@ class ConfigOptionEntity with _$ConfigOptionEntity { @Default(false) bool enableWarp, @Default(WarpDetourMode.outbound) WarpDetourMode warpDetourMode, @Default("") String warpLicenseKey, + @Default("") String warpAccountId, + @Default("") String warpAccessToken, @Default("auto") String warpCleanIp, @Default(0) int warpPort, @OptionalRangeJsonConverter() @@ -133,6 +135,8 @@ class ConfigOptionEntity with _$ConfigOptionEntity { enableWarp: patch.enableWarp ?? enableWarp, warpDetourMode: patch.warpDetourMode ?? warpDetourMode, warpLicenseKey: patch.warpLicenseKey ?? warpLicenseKey, + warpAccountId: patch.warpAccountId ?? warpAccountId, + warpAccessToken: patch.warpAccessToken ?? warpAccessToken, warpCleanIp: patch.warpCleanIp ?? warpCleanIp, warpPort: patch.warpPort ?? warpPort, warpNoise: patch.warpNoise ?? warpNoise, @@ -183,6 +187,8 @@ class ConfigOptionEntity with _$ConfigOptionEntity { enableWarp: enableWarp, warpDetourMode: warpDetourMode, warpLicenseKey: warpLicenseKey, + warpAccountId: warpAccountId, + warpAccessToken: warpAccessToken, warpCleanIp: warpCleanIp, warpPort: warpPort, warpNoise: warpNoise, @@ -237,6 +243,8 @@ class ConfigOptionPatch with _$ConfigOptionPatch { bool? enableWarp, WarpDetourMode? warpDetourMode, String? warpLicenseKey, + String? warpAccountId, + String? warpAccessToken, String? warpCleanIp, int? warpPort, @OptionalRangeJsonConverter() OptionalRange? warpNoise, diff --git a/lib/features/config_option/model/config_option_failure.dart b/lib/features/config_option/model/config_option_failure.dart index bc5c9ab5..d905ddeb 100644 --- a/lib/features/config_option/model/config_option_failure.dart +++ b/lib/features/config_option/model/config_option_failure.dart @@ -14,6 +14,9 @@ sealed class ConfigOptionFailure with _$ConfigOptionFailure, Failure { StackTrace? stackTrace, ]) = ConfigOptionUnexpectedFailure; + @With() + const factory ConfigOptionFailure.missingWarp() = MissingWarpConfigFailure; + @override ({String type, String? message}) present(TranslationsEn t) { return switch (this) { @@ -21,6 +24,10 @@ sealed class ConfigOptionFailure with _$ConfigOptionFailure, Failure { type: t.failure.unexpected, message: null, ), + MissingWarpConfigFailure() => ( + type: t.settings.config.missingWarpConfig, + message: null, + ), }; } } diff --git a/lib/features/config_option/notifier/warp_option_notifier.dart b/lib/features/config_option/notifier/warp_option_notifier.dart index 44e21953..ef790bb3 100644 --- a/lib/features/config_option/notifier/warp_option_notifier.dart +++ b/lib/features/config_option/notifier/warp_option_notifier.dart @@ -1,26 +1,71 @@ +import 'package:fpdart/fpdart.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hiddify/core/preferences/preferences_provider.dart'; +import 'package:hiddify/features/config_option/data/config_option_data_providers.dart'; +import 'package:hiddify/features/config_option/model/config_option_failure.dart'; +import 'package:hiddify/utils/utils.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +part 'warp_option_notifier.freezed.dart'; part 'warp_option_notifier.g.dart'; @Riverpod(keepAlive: true) -class WarpOptionNotifier extends _$WarpOptionNotifier { +class WarpOptionNotifier extends _$WarpOptionNotifier with AppLogger { @override - bool build() { - return ref - .read(sharedPreferencesProvider) - .requireValue - .getBool(warpConsentGiven) ?? - false; + WarpOptions build() { + final consent = _prefs.getBool(warpConsentGiven) ?? false; + bool hasWarpConfig = false; + try { + final accountId = _prefs.getString("warp-account-id"); + final accessToken = _prefs.getString("warp-access-token"); + hasWarpConfig = accountId != null && accessToken != null; + } catch (e) { + loggy.warning(e); + } + + return WarpOptions( + consentGiven: consent, + configGeneration: hasWarpConfig + ? const AsyncValue.data(unit) + : AsyncError(const MissingWarpConfigFailure(), StackTrace.current), + ); } + SharedPreferences get _prefs => + ref.read(sharedPreferencesProvider).requireValue; + Future agree() async { await ref .read(sharedPreferencesProvider) .requireValue .setBool(warpConsentGiven, true); - state = true; + state = state.copyWith(consentGiven: true); + await generateWarpConfig(); + } + + Future generateWarpConfig() async { + if (state.configGeneration.isLoading) return; + state = state.copyWith(configGeneration: const AsyncLoading()); + final result = await AsyncValue.guard( + () async => await ref + .read(configOptionRepositoryProvider) + .generateWarpConfig() + .getOrElse((l) { + loggy.warning("error generating warp config: $l", l); + throw l; + }).run(), + ); + state = state.copyWith(configGeneration: result); } static const warpConsentGiven = "warp_consent_given"; } + +@freezed +class WarpOptions with _$WarpOptions { + const factory WarpOptions({ + required bool consentGiven, + required AsyncValue configGeneration, + }) = _WarpOptions; +} diff --git a/lib/features/config_option/overview/warp_options_widgets.dart b/lib/features/config_option/overview/warp_options_widgets.dart index f88888a2..dc6855e3 100644 --- a/lib/features/config_option/overview/warp_options_widgets.dart +++ b/lib/features/config_option/overview/warp_options_widgets.dart @@ -28,7 +28,8 @@ class WarpOptionsTiles extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final t = ref.watch(translationsProvider); - final warpPrefaceCompleted = ref.watch(warpOptionNotifierProvider); + final warpOptions = ref.watch(warpOptionNotifierProvider); + final warpPrefaceCompleted = warpOptions.consentGiven; final canChangeOptions = warpPrefaceCompleted && options.enableWarp; return Column( @@ -51,6 +52,26 @@ class WarpOptionsTiles extends HookConsumerWidget { } }, ), + ListTile( + title: Text(t.settings.config.generateWarpConfig), + subtitle: canChangeOptions + ? switch (warpOptions.configGeneration) { + AsyncLoading() => const LinearProgressIndicator(), + AsyncError() => Text( + t.settings.config.missingWarpConfig, + style: + TextStyle(color: Theme.of(context).colorScheme.error), + ), + _ => null, + } + : null, + enabled: canChangeOptions, + onTap: () async { + await ref + .read(warpOptionNotifierProvider.notifier) + .generateWarpConfig(); + }, + ), ListTile( title: Text(t.settings.config.warpDetourMode), subtitle: Text(options.warpDetourMode.present(t)), diff --git a/lib/gen/singbox_generated_bindings.dart b/lib/gen/singbox_generated_bindings.dart index 6bbdb039..0be05855 100644 --- a/lib/gen/singbox_generated_bindings.dart +++ b/lib/gen/singbox_generated_bindings.dart @@ -20,842 +20,20 @@ class SingboxNativeLibrary { lookup) : _lookup = lookup; - void __va_start( - ffi.Pointer arg0, + ffi.Pointer AdminServiceStart( + ffi.Pointer arg, ) { - return ___va_start( - arg0, + return _AdminServiceStart( + arg, ); } - late final ___va_startPtr = - _lookup)>>( - '__va_start'); - late final ___va_start = - ___va_startPtr.asFunction)>(); - - void __security_init_cookie() { - return ___security_init_cookie(); - } - - late final ___security_init_cookiePtr = - _lookup>( - '__security_init_cookie'); - late final ___security_init_cookie = - ___security_init_cookiePtr.asFunction(); - - void __security_check_cookie( - int _StackCookie, - ) { - return ___security_check_cookie( - _StackCookie, - ); - } - - late final ___security_check_cookiePtr = - _lookup>( - '__security_check_cookie'); - late final ___security_check_cookie = - ___security_check_cookiePtr.asFunction(); - - void __report_gsfailure( - int _StackCookie, - ) { - return ___report_gsfailure( - _StackCookie, - ); - } - - late final ___report_gsfailurePtr = - _lookup>( - '__report_gsfailure'); - late final ___report_gsfailure = - ___report_gsfailurePtr.asFunction(); - - late final ffi.Pointer ___security_cookie = - _lookup('__security_cookie'); - - int get __security_cookie => ___security_cookie.value; - - set __security_cookie(int value) => ___security_cookie.value = value; - - void _invalid_parameter_noinfo() { - return __invalid_parameter_noinfo(); - } - - late final __invalid_parameter_noinfoPtr = - _lookup>( - '_invalid_parameter_noinfo'); - late final __invalid_parameter_noinfo = - __invalid_parameter_noinfoPtr.asFunction(); - - void _invalid_parameter_noinfo_noreturn() { - return __invalid_parameter_noinfo_noreturn(); - } - - late final __invalid_parameter_noinfo_noreturnPtr = - _lookup>( - '_invalid_parameter_noinfo_noreturn'); - late final __invalid_parameter_noinfo_noreturn = - __invalid_parameter_noinfo_noreturnPtr.asFunction(); - - void _invoke_watson( - ffi.Pointer _Expression, - ffi.Pointer _FunctionName, - ffi.Pointer _FileName, - int _LineNo, - int _Reserved, - ) { - return __invoke_watson( - _Expression, - _FunctionName, - _FileName, - _LineNo, - _Reserved, - ); - } - - late final __invoke_watsonPtr = _lookup< + late final _AdminServiceStartPtr = _lookup< ffi.NativeFunction< - ffi.Void Function( - ffi.Pointer, - ffi.Pointer, - ffi.Pointer, - ffi.UnsignedInt, - ffi.UintPtr)>>('_invoke_watson'); - late final __invoke_watson = __invoke_watsonPtr.asFunction< - void Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer, int, int)>(); - - ffi.Pointer _errno() { - return __errno(); - } - - late final __errnoPtr = - _lookup Function()>>('_errno'); - late final __errno = __errnoPtr.asFunction Function()>(); - - int _set_errno( - int _Value, - ) { - return __set_errno( - _Value, - ); - } - - late final __set_errnoPtr = - _lookup>('_set_errno'); - late final __set_errno = __set_errnoPtr.asFunction(); - - int _get_errno( - ffi.Pointer _Value, - ) { - return __get_errno( - _Value, - ); - } - - late final __get_errnoPtr = - _lookup)>>( - '_get_errno'); - late final __get_errno = - __get_errnoPtr.asFunction)>(); - - int __threadid() { - return ___threadid(); - } - - late final ___threadidPtr = - _lookup>('__threadid'); - late final ___threadid = ___threadidPtr.asFunction(); - - int __threadhandle() { - return ___threadhandle(); - } - - late final ___threadhandlePtr = - _lookup>('__threadhandle'); - late final ___threadhandle = ___threadhandlePtr.asFunction(); - - double cabs( - _Dcomplex _Z, - ) { - return _cabs( - _Z, - ); - } - - late final _cabsPtr = - _lookup>('cabs'); - late final _cabs = _cabsPtr.asFunction(); - - _Dcomplex cacos( - _Dcomplex _Z, - ) { - return _cacos( - _Z, - ); - } - - late final _cacosPtr = - _lookup>('cacos'); - late final _cacos = _cacosPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex cacosh( - _Dcomplex _Z, - ) { - return _cacosh( - _Z, - ); - } - - late final _cacoshPtr = - _lookup>('cacosh'); - late final _cacosh = _cacoshPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - double carg( - _Dcomplex _Z, - ) { - return _carg( - _Z, - ); - } - - late final _cargPtr = - _lookup>('carg'); - late final _carg = _cargPtr.asFunction(); - - _Dcomplex casin( - _Dcomplex _Z, - ) { - return _casin( - _Z, - ); - } - - late final _casinPtr = - _lookup>('casin'); - late final _casin = _casinPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex casinh( - _Dcomplex _Z, - ) { - return _casinh( - _Z, - ); - } - - late final _casinhPtr = - _lookup>('casinh'); - late final _casinh = _casinhPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex catan( - _Dcomplex _Z, - ) { - return _catan( - _Z, - ); - } - - late final _catanPtr = - _lookup>('catan'); - late final _catan = _catanPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex catanh( - _Dcomplex _Z, - ) { - return _catanh( - _Z, - ); - } - - late final _catanhPtr = - _lookup>('catanh'); - late final _catanh = _catanhPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex ccos( - _Dcomplex _Z, - ) { - return _ccos( - _Z, - ); - } - - late final _ccosPtr = - _lookup>('ccos'); - late final _ccos = _ccosPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex ccosh( - _Dcomplex _Z, - ) { - return _ccosh( - _Z, - ); - } - - late final _ccoshPtr = - _lookup>('ccosh'); - late final _ccosh = _ccoshPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex cexp( - _Dcomplex _Z, - ) { - return _cexp( - _Z, - ); - } - - late final _cexpPtr = - _lookup>('cexp'); - late final _cexp = _cexpPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - double cimag( - _Dcomplex _Z, - ) { - return _cimag( - _Z, - ); - } - - late final _cimagPtr = - _lookup>('cimag'); - late final _cimag = _cimagPtr.asFunction(); - - _Dcomplex clog( - _Dcomplex _Z, - ) { - return _clog( - _Z, - ); - } - - late final _clogPtr = - _lookup>('clog'); - late final _clog = _clogPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex clog10( - _Dcomplex _Z, - ) { - return _clog10( - _Z, - ); - } - - late final _clog10Ptr = - _lookup>('clog10'); - late final _clog10 = _clog10Ptr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex conj( - _Dcomplex _Z, - ) { - return _conj( - _Z, - ); - } - - late final _conjPtr = - _lookup>('conj'); - late final _conj = _conjPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex cpow( - _Dcomplex _X, - _Dcomplex _Y, - ) { - return _cpow( - _X, - _Y, - ); - } - - late final _cpowPtr = - _lookup>( - 'cpow'); - late final _cpow = - _cpowPtr.asFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>(); - - _Dcomplex cproj( - _Dcomplex _Z, - ) { - return _cproj( - _Z, - ); - } - - late final _cprojPtr = - _lookup>('cproj'); - late final _cproj = _cprojPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - double creal( - _Dcomplex _Z, - ) { - return _creal( - _Z, - ); - } - - late final _crealPtr = - _lookup>('creal'); - late final _creal = _crealPtr.asFunction(); - - _Dcomplex csin( - _Dcomplex _Z, - ) { - return _csin( - _Z, - ); - } - - late final _csinPtr = - _lookup>('csin'); - late final _csin = _csinPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex csinh( - _Dcomplex _Z, - ) { - return _csinh( - _Z, - ); - } - - late final _csinhPtr = - _lookup>('csinh'); - late final _csinh = _csinhPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex csqrt( - _Dcomplex _Z, - ) { - return _csqrt( - _Z, - ); - } - - late final _csqrtPtr = - _lookup>('csqrt'); - late final _csqrt = _csqrtPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex ctan( - _Dcomplex _Z, - ) { - return _ctan( - _Z, - ); - } - - late final _ctanPtr = - _lookup>('ctan'); - late final _ctan = _ctanPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - _Dcomplex ctanh( - _Dcomplex _Z, - ) { - return _ctanh( - _Z, - ); - } - - late final _ctanhPtr = - _lookup>('ctanh'); - late final _ctanh = _ctanhPtr.asFunction<_Dcomplex Function(_Dcomplex)>(); - - double norm( - _Dcomplex _Z, - ) { - return _norm( - _Z, - ); - } - - late final _normPtr = - _lookup>('norm'); - late final _norm = _normPtr.asFunction(); - - double cabsf( - _Fcomplex _Z, - ) { - return _cabsf( - _Z, - ); - } - - late final _cabsfPtr = - _lookup>('cabsf'); - late final _cabsf = _cabsfPtr.asFunction(); - - _Fcomplex cacosf( - _Fcomplex _Z, - ) { - return _cacosf( - _Z, - ); - } - - late final _cacosfPtr = - _lookup>('cacosf'); - late final _cacosf = _cacosfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex cacoshf( - _Fcomplex _Z, - ) { - return _cacoshf( - _Z, - ); - } - - late final _cacoshfPtr = - _lookup>('cacoshf'); - late final _cacoshf = _cacoshfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - double cargf( - _Fcomplex _Z, - ) { - return _cargf( - _Z, - ); - } - - late final _cargfPtr = - _lookup>('cargf'); - late final _cargf = _cargfPtr.asFunction(); - - _Fcomplex casinf( - _Fcomplex _Z, - ) { - return _casinf( - _Z, - ); - } - - late final _casinfPtr = - _lookup>('casinf'); - late final _casinf = _casinfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex casinhf( - _Fcomplex _Z, - ) { - return _casinhf( - _Z, - ); - } - - late final _casinhfPtr = - _lookup>('casinhf'); - late final _casinhf = _casinhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex catanf( - _Fcomplex _Z, - ) { - return _catanf( - _Z, - ); - } - - late final _catanfPtr = - _lookup>('catanf'); - late final _catanf = _catanfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex catanhf( - _Fcomplex _Z, - ) { - return _catanhf( - _Z, - ); - } - - late final _catanhfPtr = - _lookup>('catanhf'); - late final _catanhf = _catanhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex ccosf( - _Fcomplex _Z, - ) { - return _ccosf( - _Z, - ); - } - - late final _ccosfPtr = - _lookup>('ccosf'); - late final _ccosf = _ccosfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex ccoshf( - _Fcomplex _Z, - ) { - return _ccoshf( - _Z, - ); - } - - late final _ccoshfPtr = - _lookup>('ccoshf'); - late final _ccoshf = _ccoshfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex cexpf( - _Fcomplex _Z, - ) { - return _cexpf( - _Z, - ); - } - - late final _cexpfPtr = - _lookup>('cexpf'); - late final _cexpf = _cexpfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - double cimagf( - _Fcomplex _Z, - ) { - return _cimagf( - _Z, - ); - } - - late final _cimagfPtr = - _lookup>('cimagf'); - late final _cimagf = _cimagfPtr.asFunction(); - - _Fcomplex clogf( - _Fcomplex _Z, - ) { - return _clogf( - _Z, - ); - } - - late final _clogfPtr = - _lookup>('clogf'); - late final _clogf = _clogfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex clog10f( - _Fcomplex _Z, - ) { - return _clog10f( - _Z, - ); - } - - late final _clog10fPtr = - _lookup>('clog10f'); - late final _clog10f = _clog10fPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex conjf( - _Fcomplex _Z, - ) { - return _conjf( - _Z, - ); - } - - late final _conjfPtr = - _lookup>('conjf'); - late final _conjf = _conjfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex cpowf( - _Fcomplex _X, - _Fcomplex _Y, - ) { - return _cpowf( - _X, - _Y, - ); - } - - late final _cpowfPtr = - _lookup>( - 'cpowf'); - late final _cpowf = - _cpowfPtr.asFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>(); - - _Fcomplex cprojf( - _Fcomplex _Z, - ) { - return _cprojf( - _Z, - ); - } - - late final _cprojfPtr = - _lookup>('cprojf'); - late final _cprojf = _cprojfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - double crealf( - _Fcomplex _Z, - ) { - return _crealf( - _Z, - ); - } - - late final _crealfPtr = - _lookup>('crealf'); - late final _crealf = _crealfPtr.asFunction(); - - _Fcomplex csinf( - _Fcomplex _Z, - ) { - return _csinf( - _Z, - ); - } - - late final _csinfPtr = - _lookup>('csinf'); - late final _csinf = _csinfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex csinhf( - _Fcomplex _Z, - ) { - return _csinhf( - _Z, - ); - } - - late final _csinhfPtr = - _lookup>('csinhf'); - late final _csinhf = _csinhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex csqrtf( - _Fcomplex _Z, - ) { - return _csqrtf( - _Z, - ); - } - - late final _csqrtfPtr = - _lookup>('csqrtf'); - late final _csqrtf = _csqrtfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex ctanf( - _Fcomplex _Z, - ) { - return _ctanf( - _Z, - ); - } - - late final _ctanfPtr = - _lookup>('ctanf'); - late final _ctanf = _ctanfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - _Fcomplex ctanhf( - _Fcomplex _Z, - ) { - return _ctanhf( - _Z, - ); - } - - late final _ctanhfPtr = - _lookup>('ctanhf'); - late final _ctanhf = _ctanhfPtr.asFunction<_Fcomplex Function(_Fcomplex)>(); - - double normf( - _Fcomplex _Z, - ) { - return _normf( - _Z, - ); - } - - late final _normfPtr = - _lookup>('normf'); - late final _normf = _normfPtr.asFunction(); - - _Dcomplex _Cbuild( - double _Re, - double _Im, - ) { - return __Cbuild( - _Re, - _Im, - ); - } - - late final __CbuildPtr = - _lookup>( - '_Cbuild'); - late final __Cbuild = - __CbuildPtr.asFunction<_Dcomplex Function(double, double)>(); - - _Dcomplex _Cmulcc( - _Dcomplex _X, - _Dcomplex _Y, - ) { - return __Cmulcc( - _X, - _Y, - ); - } - - late final __CmulccPtr = - _lookup>( - '_Cmulcc'); - late final __Cmulcc = - __CmulccPtr.asFunction<_Dcomplex Function(_Dcomplex, _Dcomplex)>(); - - _Dcomplex _Cmulcr( - _Dcomplex _X, - double _Y, - ) { - return __Cmulcr( - _X, - _Y, - ); - } - - late final __CmulcrPtr = - _lookup>( - '_Cmulcr'); - late final __Cmulcr = - __CmulcrPtr.asFunction<_Dcomplex Function(_Dcomplex, double)>(); - - _Fcomplex _FCbuild( - double _Re, - double _Im, - ) { - return __FCbuild( - _Re, - _Im, - ); - } - - late final __FCbuildPtr = - _lookup>( - '_FCbuild'); - late final __FCbuild = - __FCbuildPtr.asFunction<_Fcomplex Function(double, double)>(); - - _Fcomplex _FCmulcc( - _Fcomplex _X, - _Fcomplex _Y, - ) { - return __FCmulcc( - _X, - _Y, - ); - } - - late final __FCmulccPtr = - _lookup>( - '_FCmulcc'); - late final __FCmulcc = - __FCmulccPtr.asFunction<_Fcomplex Function(_Fcomplex, _Fcomplex)>(); - - _Fcomplex _FCmulcr( - _Fcomplex _X, - double _Y, - ) { - return __FCmulcr( - _X, - _Y, - ); - } - - late final __FCmulcrPtr = - _lookup>( - '_FCmulcr'); - late final __FCmulcr = - __FCmulcrPtr.asFunction<_Fcomplex Function(_Fcomplex, double)>(); + ffi.Pointer Function( + ffi.Pointer)>>('AdminServiceStart'); + late final _AdminServiceStart = _AdminServiceStartPtr.asFunction< + ffi.Pointer Function(ffi.Pointer)>(); void setupOnce( ffi.Pointer api, @@ -1053,42 +231,121 @@ class SingboxNativeLibrary { ffi.Pointer Function(ffi.Pointer)>>('urlTest'); late final _urlTest = _urlTestPtr .asFunction Function(ffi.Pointer)>(); + + ffi.Pointer generateWarpConfig( + ffi.Pointer licenseKey, + ffi.Pointer accountId, + ffi.Pointer accessToken, + ) { + return _generateWarpConfig( + licenseKey, + accountId, + accessToken, + ); + } + + late final _generateWarpConfigPtr = _lookup< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('generateWarpConfig'); + late final _generateWarpConfig = _generateWarpConfigPtr.asFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(); } -typedef va_list = ffi.Pointer; +final class __mbstate_t extends ffi.Union { + @ffi.Array.multi([128]) + external ffi.Array __mbstate8; -final class __crt_locale_data_public extends ffi.Struct { - external ffi.Pointer _locale_pctype; - - @ffi.Int() - external int _locale_mb_cur_max; - - @ffi.UnsignedInt() - external int _locale_lc_codepage; + @ffi.LongLong() + external int _mbstateL; } -final class __crt_locale_pointers extends ffi.Struct { - external ffi.Pointer<__crt_locale_data> locinfo; +final class __darwin_pthread_handler_rec extends ffi.Struct { + external ffi + .Pointer)>> + __routine; - external ffi.Pointer<__crt_multibyte_data> mbcinfo; + external ffi.Pointer __arg; + + external ffi.Pointer<__darwin_pthread_handler_rec> __next; } -final class __crt_locale_data extends ffi.Opaque {} +final class _opaque_pthread_attr_t extends ffi.Struct { + @ffi.Long() + external int __sig; -final class __crt_multibyte_data extends ffi.Opaque {} - -final class _Mbstatet extends ffi.Struct { - @ffi.UnsignedLong() - external int _Wchar; - - @ffi.UnsignedShort() - external int _Byte; - - @ffi.UnsignedShort() - external int _State; + @ffi.Array.multi([56]) + external ffi.Array __opaque; } -typedef errno_t = ffi.Int; +final class _opaque_pthread_cond_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + @ffi.Array.multi([40]) + external ffi.Array __opaque; +} + +final class _opaque_pthread_condattr_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + @ffi.Array.multi([8]) + external ffi.Array __opaque; +} + +final class _opaque_pthread_mutex_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + @ffi.Array.multi([56]) + external ffi.Array __opaque; +} + +final class _opaque_pthread_mutexattr_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + @ffi.Array.multi([8]) + external ffi.Array __opaque; +} + +final class _opaque_pthread_once_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + @ffi.Array.multi([8]) + external ffi.Array __opaque; +} + +final class _opaque_pthread_rwlock_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + @ffi.Array.multi([192]) + external ffi.Array __opaque; +} + +final class _opaque_pthread_rwlockattr_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + @ffi.Array.multi([16]) + external ffi.Array __opaque; +} + +final class _opaque_pthread_t extends ffi.Struct { + @ffi.Long() + external int __sig; + + external ffi.Pointer<__darwin_pthread_handler_rec> __cleanup_stack; + + @ffi.Array.multi([8176]) + external ffi.Array __opaque; +} final class _GoString_ extends ffi.Struct { external ffi.Pointer p; @@ -1097,22 +354,8 @@ final class _GoString_ extends ffi.Struct { external int n; } -typedef ptrdiff_t = ffi.LongLong; - -final class _C_double_complex extends ffi.Struct { - @ffi.Array.multi([2]) - external ffi.Array _Val; -} - -final class _C_float_complex extends ffi.Struct { - @ffi.Array.multi([2]) - external ffi.Array _Val; -} - -final class _C_ldouble_complex extends ffi.Opaque {} - -typedef _Dcomplex = _C_double_complex; -typedef _Fcomplex = _C_float_complex; +typedef ptrdiff_t = __darwin_ptrdiff_t; +typedef __darwin_ptrdiff_t = ffi.Long; final class GoInterface extends ffi.Struct { external ffi.Pointer t; @@ -1134,83 +377,77 @@ typedef GoInt = GoInt64; typedef GoInt64 = ffi.LongLong; typedef GoUint8 = ffi.UnsignedChar; -const int _VCRT_COMPILER_PREPROCESSOR = 1; +const int __DARWIN_ONLY_64_BIT_INO_T = 1; -const int _SAL_VERSION = 20; +const int __DARWIN_ONLY_UNIX_CONFORMANCE = 1; -const int __SAL_H_VERSION = 180000000; +const int __DARWIN_ONLY_VERS_1050 = 1; -const int _USE_DECLSPECS_FOR_SAL = 0; +const int __DARWIN_UNIX03 = 1; -const int _USE_ATTRIBUTES_FOR_SAL = 0; +const int __DARWIN_64_BIT_INO_T = 1; -const int _CRT_PACKING = 8; +const int __DARWIN_VERS_1050 = 1; -const int _VCRUNTIME_DISABLED_WARNINGS = 4514; +const int __DARWIN_NON_CANCELABLE = 0; -const int _HAS_EXCEPTIONS = 1; +const String __DARWIN_SUF_EXTSN = '\$DARWIN_EXTSN'; -const int _WCHAR_T_DEFINED = 1; +const int __DARWIN_C_ANSI = 4096; + +const int __DARWIN_C_FULL = 900000; + +const int __DARWIN_C_LEVEL = 900000; + +const int __STDC_WANT_LIB_EXT1__ = 1; + +const int __DARWIN_NO_LONG_LONG = 0; + +const int _DARWIN_FEATURE_64_BIT_INODE = 1; + +const int _DARWIN_FEATURE_ONLY_64_BIT_INODE = 1; + +const int _DARWIN_FEATURE_ONLY_VERS_1050 = 1; + +const int _DARWIN_FEATURE_ONLY_UNIX_CONFORMANCE = 1; + +const int _DARWIN_FEATURE_UNIX_CONFORMANCE = 3; + +const int __has_ptrcheck = 0; + +const int __DARWIN_NULL = 0; + +const int __PTHREAD_SIZE__ = 8176; + +const int __PTHREAD_ATTR_SIZE__ = 56; + +const int __PTHREAD_MUTEXATTR_SIZE__ = 8; + +const int __PTHREAD_MUTEX_SIZE__ = 56; + +const int __PTHREAD_CONDATTR_SIZE__ = 8; + +const int __PTHREAD_COND_SIZE__ = 40; + +const int __PTHREAD_ONCE_SIZE__ = 8; + +const int __PTHREAD_RWLOCK_SIZE__ = 192; + +const int __PTHREAD_RWLOCKATTR_SIZE__ = 16; + +const int __DARWIN_WCHAR_MAX = 2147483647; + +const int __DARWIN_WCHAR_MIN = -2147483648; + +const int __DARWIN_WEOF = -1; + +const int _FORTIFY_SOURCE = 2; const int NULL = 0; -const int _HAS_CXX17 = 0; +const int USER_ADDR_NULL = 0; -const int _HAS_CXX20 = 0; - -const int _HAS_CXX23 = 0; - -const int _HAS_NODISCARD = 1; - -const int _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE = 1; - -const int _CRT_BUILD_DESKTOP_APP = 1; - -const int _UCRT_DISABLED_WARNINGS = 4324; - -const int _ARGMAX = 100; - -const int _TRUNCATE = -1; - -const int _CRT_INT_MAX = 2147483647; - -const int _CRT_SIZE_MAX = -1; - -const String __FILEW__ = 'C'; - -const int _CRT_FUNCTIONS_REQUIRED = 1; - -const int _CRT_HAS_CXX17 = 0; - -const int _CRT_HAS_C11 = 0; - -const int _CRT_INTERNAL_NONSTDC_NAMES = 1; - -const int __STDC_SECURE_LIB__ = 200411; - -const int __GOT_SECURE_LIB__ = 200411; - -const int __STDC_WANT_SECURE_LIB__ = 1; - -const int _SECURECRT_FILL_BUFFER_PATTERN = 254; - -const int _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES = 0; - -const int _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT = 0; - -const int _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES = 1; - -const int _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY = 0; - -const int _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY = 0; - -const int INT8_MIN = -128; - -const int INT16_MIN = -32768; - -const int INT32_MIN = -2147483648; - -const int INT64_MIN = -9223372036854775808; +const int __WORDSIZE = 64; const int INT8_MAX = 127; @@ -1220,6 +457,14 @@ const int INT32_MAX = 2147483647; const int INT64_MAX = 9223372036854775807; +const int INT8_MIN = -128; + +const int INT16_MIN = -32768; + +const int INT32_MIN = -2147483648; + +const int INT64_MIN = -9223372036854775808; + const int UINT8_MAX = 255; const int UINT16_MAX = 65535; @@ -1254,7 +499,7 @@ const int UINT_LEAST64_MAX = -1; const int INT_FAST8_MIN = -128; -const int INT_FAST16_MIN = -2147483648; +const int INT_FAST16_MIN = -32768; const int INT_FAST32_MIN = -2147483648; @@ -1262,7 +507,7 @@ const int INT_FAST64_MIN = -9223372036854775808; const int INT_FAST8_MAX = 127; -const int INT_FAST16_MAX = 2147483647; +const int INT_FAST16_MAX = 32767; const int INT_FAST32_MAX = 2147483647; @@ -1270,38 +515,40 @@ const int INT_FAST64_MAX = 9223372036854775807; const int UINT_FAST8_MAX = 255; -const int UINT_FAST16_MAX = 4294967295; +const int UINT_FAST16_MAX = 65535; const int UINT_FAST32_MAX = 4294967295; const int UINT_FAST64_MAX = -1; -const int INTPTR_MIN = -9223372036854775808; - const int INTPTR_MAX = 9223372036854775807; -const int UINTPTR_MAX = -1; +const int INTPTR_MIN = -9223372036854775808; -const int INTMAX_MIN = -9223372036854775808; +const int UINTPTR_MAX = -1; const int INTMAX_MAX = 9223372036854775807; const int UINTMAX_MAX = -1; +const int INTMAX_MIN = -9223372036854775808; + const int PTRDIFF_MIN = -9223372036854775808; const int PTRDIFF_MAX = 9223372036854775807; const int SIZE_MAX = -1; +const int RSIZE_MAX = 9223372036854775807; + +const int WCHAR_MAX = 2147483647; + +const int WCHAR_MIN = -2147483648; + +const int WINT_MIN = -2147483648; + +const int WINT_MAX = 2147483647; + const int SIG_ATOMIC_MIN = -2147483648; const int SIG_ATOMIC_MAX = 2147483647; - -const int WCHAR_MIN = 0; - -const int WCHAR_MAX = 65535; - -const int WINT_MIN = 0; - -const int WINT_MAX = 65535; diff --git a/lib/singbox/model/singbox_config_option.dart b/lib/singbox/model/singbox_config_option.dart index 2bed15c6..5f8229bb 100644 --- a/lib/singbox/model/singbox_config_option.dart +++ b/lib/singbox/model/singbox_config_option.dart @@ -54,6 +54,8 @@ class SingboxConfigOption with _$SingboxConfigOption { required bool enableWarp, required WarpDetourMode warpDetourMode, required String warpLicenseKey, + required String warpAccountId, + required String warpAccessToken, required String warpCleanIp, required int warpPort, @OptionalRangeJsonConverter() required OptionalRange warpNoise, diff --git a/lib/singbox/model/warp_account.dart b/lib/singbox/model/warp_account.dart new file mode 100644 index 00000000..ba010190 --- /dev/null +++ b/lib/singbox/model/warp_account.dart @@ -0,0 +1,17 @@ +import 'package:flutter/foundation.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'warp_account.freezed.dart'; +part 'warp_account.g.dart'; + +@freezed +class WarpAccount with _$WarpAccount { + const factory WarpAccount({ + required String licenseKey, + required String accountId, + required String accessToken, + }) = _WarpAccount; + + factory WarpAccount.fromJson(Map json) => + _$WarpAccountFromJson(json); +} diff --git a/lib/singbox/service/ffi_singbox_service.dart b/lib/singbox/service/ffi_singbox_service.dart index 3626c5b9..35d628be 100644 --- a/lib/singbox/service/ffi_singbox_service.dart +++ b/lib/singbox/service/ffi_singbox_service.dart @@ -13,6 +13,7 @@ import 'package:hiddify/singbox/model/singbox_config_option.dart'; 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/singbox_service.dart'; import 'package:hiddify/utils/utils.dart'; import 'package:loggy/loggy.dart'; @@ -454,4 +455,44 @@ class FFISingboxService with InfraLogger implements SingboxService { } return _logBuffer; } + + @override + TaskEither generateWarpConfig({ + required String licenseKey, + required String previousAccountId, + required String previousAccessToken, + }) { + loggy.debug("generating warp config"); + return TaskEither( + () => CombineWorker().execute( + () { + final response = _box + .generateWarpConfig( + licenseKey.toNativeUtf8().cast(), + previousAccountId.toNativeUtf8().cast(), + previousAccessToken.toNativeUtf8().cast(), + ) + .cast() + .toDartString(); + if (response.startsWith("error:")) { + return left(response.replaceFirst('error:', "")); + } + if (jsonDecode(response) + case { + "account-id": final String newAccountId, + "access-token": final String newAccessToken, + }) { + return right( + WarpAccount( + licenseKey: licenseKey, + accountId: newAccountId, + accessToken: newAccessToken, + ), + ); + } + return left("invalid response"); + }, + ), + ); + } } diff --git a/lib/singbox/service/platform_singbox_service.dart b/lib/singbox/service/platform_singbox_service.dart index 2aadacf5..4c16d00b 100644 --- a/lib/singbox/service/platform_singbox_service.dart +++ b/lib/singbox/service/platform_singbox_service.dart @@ -8,6 +8,7 @@ import 'package:hiddify/singbox/model/singbox_config_option.dart'; 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/singbox_service.dart'; import 'package:hiddify/utils/custom_loggers.dart'; import 'package:rxdart/rxdart.dart'; @@ -263,4 +264,39 @@ class PlatformSingboxService with InfraLogger implements SingboxService { }, ); } + + @override + TaskEither generateWarpConfig({ + required String licenseKey, + required String previousAccountId, + required String previousAccessToken, + }) { + return TaskEither( + () async { + loggy.debug("generating warp config"); + final warpConfig = await methodChannel.invokeMethod( + "generate_warp_config", + { + "license-key": licenseKey, + "previous-account-id": previousAccountId, + "previous-access-token": previousAccessToken, + }, + ); + if (jsonDecode(warpConfig as String) + case { + "account-id": final String newAccountId, + "access-token": final String newAccessToken, + }) { + return right( + WarpAccount( + licenseKey: licenseKey, + accountId: newAccountId, + accessToken: newAccessToken, + ), + ); + } + return left("invalid response"); + }, + ); + } } diff --git a/lib/singbox/service/singbox_service.dart b/lib/singbox/service/singbox_service.dart index 895b74f7..fa181dc6 100644 --- a/lib/singbox/service/singbox_service.dart +++ b/lib/singbox/service/singbox_service.dart @@ -6,6 +6,7 @@ import 'package:hiddify/singbox/model/singbox_config_option.dart'; 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/ffi_singbox_service.dart'; import 'package:hiddify/singbox/service/platform_singbox_service.dart'; @@ -85,4 +86,10 @@ abstract interface class SingboxService { Stream> watchLogs(String path); TaskEither clearLogs(); + + TaskEither generateWarpConfig({ + required String licenseKey, + required String previousAccountId, + required String previousAccessToken, + }); } diff --git a/libcore b/libcore index a006c94c..6672cd81 160000 --- a/libcore +++ b/libcore @@ -1 +1 @@ -Subproject commit a006c94cdf5c6db5a569303357818143671c229c +Subproject commit 6672cd810420cf20a8eae54adf5c64195d152895