diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index 8a5e9056..13d5c71f 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -146,7 +146,8 @@ "advanced": { "sectionTitle": "Advanced", "debugMode": "Debug Mode", - "debugModeMsg": "Restart the app for applying this change" + "debugModeMsg": "Restart the app for applying this change", + "memoryLimit": "Memory Limit" }, "network": { "perAppProxyPageTitle": "Per-app Proxy", diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index cebc0b0a..f0fc4ed0 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -146,7 +146,8 @@ "advanced": { "sectionTitle": "پیشرفته", "debugMode": "دیباگ مود", - "debugModeMsg": "برای اعمال این تغییر اپ را ری‌استارت کنید" + "debugModeMsg": "برای اعمال این تغییر اپ را ری‌استارت کنید", + "memoryLimit": "محدودیت مموری" }, "network": { "perAppProxyPageTitle": "پراکسی برنامه‌ها", diff --git a/assets/translations/strings_ru.i18n.json b/assets/translations/strings_ru.i18n.json index a5c627c7..40cfae55 100644 --- a/assets/translations/strings_ru.i18n.json +++ b/assets/translations/strings_ru.i18n.json @@ -146,7 +146,8 @@ "advanced": { "sectionTitle": "Расширенные", "debugMode": "Режим отладки", - "debugModeMsg": "Для применения перезапустите приложение." + "debugModeMsg": "Для применения перезапустите приложение.", + "memoryLimit": "Ограничение памяти" }, "network": { "perAppProxyPageTitle": "Раздельное проксирование", diff --git a/assets/translations/strings_zh.i18n.json b/assets/translations/strings_zh.i18n.json index a1ec9bd4..52d1d323 100644 --- a/assets/translations/strings_zh.i18n.json +++ b/assets/translations/strings_zh.i18n.json @@ -146,7 +146,8 @@ "advanced": { "sectionTitle": "先进的", "debugMode": "调试模式", - "debugModeMsg": "重新启动应用程序以应用此更改" + "debugModeMsg": "重新启动应用程序以应用此更改", + "memoryLimit": "内存限制" }, "network": { "perAppProxyPageTitle": "每个应用程序代理", diff --git a/lib/core/prefs/general_prefs.dart b/lib/core/prefs/general_prefs.dart index ef787669..0f6d8a92 100644 --- a/lib/core/prefs/general_prefs.dart +++ b/lib/core/prefs/general_prefs.dart @@ -74,6 +74,23 @@ class EnableAnalytics extends _$EnableAnalytics { } } +@Riverpod(keepAlive: true) +class DisableMemoryLimit extends _$DisableMemoryLimit { + late final _pref = Pref( + ref.watch(sharedPreferencesProvider), + "disable_memory_limit", + false, + ); + + @override + bool build() => _pref.getValue(); + + Future update(bool value) { + state = value; + return _pref.update(value); + } +} + @Riverpod(keepAlive: true) class CheckForPreReleaseUpdates extends _$CheckForPreReleaseUpdates { late final _pref = Pref( diff --git a/lib/data/repository/core_facade_impl.dart b/lib/data/repository/core_facade_impl.dart index d8256dd6..3bd9303d 100644 --- a/lib/data/repository/core_facade_impl.dart +++ b/lib/data/repository/core_facade_impl.dart @@ -86,14 +86,19 @@ class CoreFacadeImpl with ExceptionHandler, InfraLogger implements CoreFacade { } @override - TaskEither start(String fileName) { + TaskEither start( + String fileName, + bool disableMemoryLimit, + ) { return exceptionHandler( () { final configPath = filesEditor.configPath(fileName); return setup() .andThen(() => changeConfigOptions(configOptions())) .andThen( - () => singbox.start(configPath).mapLeft(CoreServiceFailure.start), + () => singbox + .start(configPath, disableMemoryLimit) + .mapLeft(CoreServiceFailure.start), ) .run(); }, @@ -110,14 +115,18 @@ class CoreFacadeImpl with ExceptionHandler, InfraLogger implements CoreFacade { } @override - TaskEither restart(String fileName) { + TaskEither restart( + String fileName, + bool disableMemoryLimit, + ) { return exceptionHandler( () { final configPath = filesEditor.configPath(fileName); return changeConfigOptions(configOptions()) .andThen( - () => - singbox.restart(configPath).mapLeft(CoreServiceFailure.start), + () => singbox + .restart(configPath, disableMemoryLimit) + .mapLeft(CoreServiceFailure.start), ) .run(); }, diff --git a/lib/domain/singbox/singbox_facade.dart b/lib/domain/singbox/singbox_facade.dart index 6a8d9541..7b63ee9d 100644 --- a/lib/domain/singbox/singbox_facade.dart +++ b/lib/domain/singbox/singbox_facade.dart @@ -18,11 +18,17 @@ abstract interface class SingboxFacade { ConfigOptions options, ); - TaskEither start(String fileName); + TaskEither start( + String fileName, + bool disableMemoryLimit, + ); TaskEither stop(); - TaskEither restart(String fileName); + TaskEither restart( + String fileName, + bool disableMemoryLimit, + ); Stream>> watchOutbounds(); diff --git a/lib/features/common/connectivity/connectivity_controller.dart b/lib/features/common/connectivity/connectivity_controller.dart index 5f35f98e..936e7aef 100644 --- a/lib/features/common/connectivity/connectivity_controller.dart +++ b/lib/features/common/connectivity/connectivity_controller.dart @@ -1,3 +1,4 @@ +import 'package:hiddify/core/prefs/prefs.dart'; import 'package:hiddify/data/data_providers.dart'; import 'package:hiddify/domain/connectivity/connectivity.dart'; import 'package:hiddify/domain/core_facade.dart'; @@ -50,7 +51,9 @@ class ConnectivityController extends _$ConnectivityController with AppLogger { return _disconnect(); } loggy.debug("reconnecting, profile: [$profileId]"); - await _core.restart(profileId).mapLeft((err) { + await _core + .restart(profileId, ref.read(disableMemoryLimitProvider)) + .mapLeft((err) { loggy.warning("error reconnecting", err); state = AsyncError(err, StackTrace.current); }).run(); @@ -70,8 +73,10 @@ class ConnectivityController extends _$ConnectivityController with AppLogger { Future _connect() async { final activeProfile = await ref.read(activeProfileProvider.future); - await _core.start(activeProfile!.id).mapLeft((err) { - loggy.warning("error connecting", err); + await _core + .start(activeProfile!.id, ref.read(disableMemoryLimitProvider)) + .mapLeft((err) { + loggy.warning("error connecting $err", err); state = AsyncError(err, StackTrace.current); }).run(); } diff --git a/lib/features/settings/widgets/advanced_setting_tiles.dart b/lib/features/settings/widgets/advanced_setting_tiles.dart index 64274c21..c2cd9fdd 100644 --- a/lib/features/settings/widgets/advanced_setting_tiles.dart +++ b/lib/features/settings/widgets/advanced_setting_tiles.dart @@ -18,6 +18,7 @@ class AdvancedSettingTiles extends HookConsumerWidget { final debug = ref.watch(debugModeNotifierProvider); final perAppProxy = ref.watch(perAppProxyModeNotifierProvider).enabled; + final disableMemoryLimit = ref.watch(disableMemoryLimitProvider); return Column( children: [ @@ -83,6 +84,13 @@ class AdvancedSettingTiles extends HookConsumerWidget { await ref.read(debugModeNotifierProvider.notifier).update(value); }, ), + SwitchListTile( + title: Text(t.settings.advanced.memoryLimit), + value: !disableMemoryLimit, + onChanged: (value) async { + await ref.read(disableMemoryLimitProvider.notifier).update(!value); + }, + ), ], ); } diff --git a/lib/gen/singbox_generated_bindings.dart b/lib/gen/singbox_generated_bindings.dart index 8fd548a4..25628fac 100644 --- a/lib/gen/singbox_generated_bindings.dart +++ b/lib/gen/singbox_generated_bindings.dart @@ -930,17 +930,20 @@ class SingboxNativeLibrary { ffi.Pointer start( ffi.Pointer configPath, + int disableMemoryLimit, ) { return _start( configPath, + disableMemoryLimit, ); } late final _startPtr = _lookup< ffi.NativeFunction< - ffi.Pointer Function(ffi.Pointer)>>('start'); + ffi.Pointer Function( + ffi.Pointer, GoUint8)>>('start'); late final _start = _startPtr - .asFunction Function(ffi.Pointer)>(); + .asFunction Function(ffi.Pointer, int)>(); ffi.Pointer stop() { return _stop(); @@ -952,17 +955,20 @@ class SingboxNativeLibrary { ffi.Pointer restart( ffi.Pointer configPath, + int disableMemoryLimit, ) { return _restart( configPath, + disableMemoryLimit, ); } late final _restartPtr = _lookup< ffi.NativeFunction< - ffi.Pointer Function(ffi.Pointer)>>('restart'); + ffi.Pointer Function( + ffi.Pointer, GoUint8)>>('restart'); late final _restart = _restartPtr - .asFunction Function(ffi.Pointer)>(); + .asFunction Function(ffi.Pointer, int)>(); ffi.Pointer startCommandClient( int command, diff --git a/lib/services/singbox/ffi_singbox_service.dart b/lib/services/singbox/ffi_singbox_service.dart index 8b9b3aff..4f9de414 100644 --- a/lib/services/singbox/ffi_singbox_service.dart +++ b/lib/services/singbox/ffi_singbox_service.dart @@ -130,12 +130,16 @@ class FFISingboxService } @override - TaskEither start(String configPath) { + TaskEither start(String configPath, bool disableMemoryLimit) { + loggy.debug("starting, memory limit: [${!disableMemoryLimit}]"); return TaskEither( () => CombineWorker().execute( () { final err = _box - .start(configPath.toNativeUtf8().cast()) + .start( + configPath.toNativeUtf8().cast(), + disableMemoryLimit ? 1 : 0, + ) .cast() .toDartString(); if (err.isNotEmpty) { @@ -163,12 +167,16 @@ class FFISingboxService } @override - TaskEither restart(String configPath) { + TaskEither restart(String configPath, bool disableMemoryLimit) { + loggy.debug("restarting, memory limit: [${!disableMemoryLimit}]"); return TaskEither( () => CombineWorker().execute( () { final err = _box - .restart(configPath.toNativeUtf8().cast()) + .restart( + configPath.toNativeUtf8().cast(), + disableMemoryLimit ? 1 : 0, + ) .cast() .toDartString(); if (err.isNotEmpty) { diff --git a/lib/services/singbox/mobile_singbox_service.dart b/lib/services/singbox/mobile_singbox_service.dart index aaf2b399..95b6bc27 100644 --- a/lib/services/singbox/mobile_singbox_service.dart +++ b/lib/services/singbox/mobile_singbox_service.dart @@ -73,7 +73,7 @@ class MobileSingboxService } @override - TaskEither start(String configPath) { + TaskEither start(String configPath, bool disableMemoryLimit) { return TaskEither( () async { loggy.debug("starting"); @@ -98,7 +98,7 @@ class MobileSingboxService } @override - TaskEither restart(String configPath) { + TaskEither restart(String configPath, bool disableMemoryLimit) { return TaskEither( () async { loggy.debug("restarting"); diff --git a/lib/services/singbox/singbox_service.dart b/lib/services/singbox/singbox_service.dart index 051f66db..8f92afe4 100644 --- a/lib/services/singbox/singbox_service.dart +++ b/lib/services/singbox/singbox_service.dart @@ -32,11 +32,11 @@ abstract interface class SingboxService { TaskEither changeConfigOptions(ConfigOptions options); - TaskEither start(String configPath); + TaskEither start(String configPath, bool disableMemoryLimit); TaskEither stop(); - TaskEither restart(String configPath); + TaskEither restart(String configPath, bool disableMemoryLimit); Stream watchOutbounds(); diff --git a/libcore b/libcore index 7b367fe7..57b239c0 160000 --- a/libcore +++ b/libcore @@ -1 +1 @@ -Subproject commit 7b367fe70c9ecbf0dda2b73289905565e2451745 +Subproject commit 57b239c0f34d2b60a0790c6c3c2cac19922eb4d4