diff --git a/lib/data/repository/config_options_store.dart b/lib/data/repository/config_options_store.dart index afc10987..e846d46c 100644 --- a/lib/data/repository/config_options_store.dart +++ b/lib/data/repository/config_options_store.dart @@ -1,6 +1,6 @@ // ignore_for_file: avoid_manual_providers_as_generated_provider_dependency import 'package:hiddify/core/prefs/prefs.dart'; -import 'package:hiddify/domain/singbox/config_options.dart'; +import 'package:hiddify/domain/singbox/singbox.dart'; import 'package:hiddify/utils/pref_notifier.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; @@ -67,6 +67,32 @@ final enableTunStore = PrefNotifier.provider("enable-tun", _default.enableTun); final setSystemProxyStore = PrefNotifier.provider("set-system-proxy", _default.setSystemProxy); +// HACK temporary +@riverpod +List rules(RulesRef ref) => switch (ref.watch(regionNotifierProvider)) { + Region.ir => [ + const Rule( + id: "id", + name: "name", + enabled: true, + domains: "domain:.ir", + ip: "geoip:ir", + outbound: RuleOutbound.bypass, + ), + ], + Region.cn => [ + const Rule( + id: "id", + name: "name", + enabled: true, + domains: "domain:.cn,geosite:cn", + ip: "geoip:cn", + outbound: RuleOutbound.bypass, + ), + ], + _ => [], + }; + @riverpod ConfigOptions configOptions(ConfigOptionsRef ref) => ConfigOptions( executeConfigAsIs: @@ -88,4 +114,5 @@ ConfigOptions configOptions(ConfigOptionsRef ref) => ConfigOptions( clashApiPort: ref.watch(clashApiPortStore), enableTun: ref.watch(enableTunStore), setSystemProxy: ref.watch(setSystemProxyStore), + rules: ref.watch(rulesProvider), ); diff --git a/lib/domain/singbox/config_options.dart b/lib/domain/singbox/config_options.dart index 1890d8a9..bfae62f4 100644 --- a/lib/domain/singbox/config_options.dart +++ b/lib/domain/singbox/config_options.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hiddify/core/prefs/prefs.dart'; +import 'package:hiddify/domain/singbox/rules.dart'; import 'package:hiddify/utils/platform_utils.dart'; part 'config_options.freezed.dart'; @@ -19,13 +20,13 @@ class ConfigOptions with _$ConfigOptions { @Default(IPv6Mode.disable) IPv6Mode ipv6Mode, @Default("tcp://8.8.8.8") String remoteDnsAddress, @Default(DomainStrategy.auto) DomainStrategy remoteDnsDomainStrategy, - @Default("8.8.8.8") String directDnsAddress, + @Default("local") String directDnsAddress, @Default(DomainStrategy.auto) DomainStrategy directDnsDomainStrategy, @Default(2334) int mixedPort, @Default(6450) int localDnsPort, @Default(TunImplementation.mixed) TunImplementation tunImplementation, @Default(9000) int mtu, - @Default("https://www.gstatic.com/generate_204") String connectionTestUrl, + @Default("http://cp.cloudflare.com/") String connectionTestUrl, @IntervalConverter() @Default(Duration(minutes: 10)) Duration urlTestInterval, @@ -33,6 +34,9 @@ class ConfigOptions with _$ConfigOptions { @Default(6756) int clashApiPort, @Default(false) bool enableTun, @Default(true) bool setSystemProxy, + @Default(false) bool bypassLan, + @Default(false) bool enableFakeDns, + List? rules, }) = _ConfigOptions; static ConfigOptions initial = ConfigOptions( diff --git a/lib/domain/singbox/rules.dart b/lib/domain/singbox/rules.dart index f30f024f..80db6ee7 100644 --- a/lib/domain/singbox/rules.dart +++ b/lib/domain/singbox/rules.dart @@ -1,5 +1,40 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hiddify/core/prefs/locale_prefs.dart'; +part 'rules.freezed.dart'; +part 'rules.g.dart'; + +@freezed +class Rule with _$Rule { + @JsonSerializable(fieldRename: FieldRename.kebab) + const factory Rule({ + required String id, + required String name, + @Default(false) bool enabled, + String? domains, + String? ip, + String? port, + String? protocol, + @Default(RuleNetwork.tcpAndUdp) RuleNetwork network, + @Default(RuleOutbound.proxy) RuleOutbound outbound, + }) = _Rule; + + factory Rule.fromJson(Map json) => _$RuleFromJson(json); +} + +enum RuleOutbound { proxy, bypass, block } + +@JsonEnum(valueField: 'key') +enum RuleNetwork { + tcpAndUdp(""), + tcp("tcp"), + udp("udp"); + + const RuleNetwork(this.key); + + final String? key; +} + enum PerAppProxyMode { off, include, diff --git a/lib/features/settings/widgets/advanced_setting_tiles.dart b/lib/features/settings/widgets/advanced_setting_tiles.dart index 82b94bdb..64274c21 100644 --- a/lib/features/settings/widgets/advanced_setting_tiles.dart +++ b/lib/features/settings/widgets/advanced_setting_tiles.dart @@ -6,6 +6,7 @@ import 'package:hiddify/core/core_providers.dart'; import 'package:hiddify/core/prefs/prefs.dart'; import 'package:hiddify/core/router/routes/routes.dart'; import 'package:hiddify/domain/singbox/singbox.dart'; +import 'package:hiddify/features/common/common.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; class AdvancedSettingTiles extends HookConsumerWidget { @@ -20,6 +21,7 @@ class AdvancedSettingTiles extends HookConsumerWidget { return Column( children: [ + const RegionPrefTile(), ListTile( title: Text(t.settings.config.pageTitle), leading: const Icon(Icons.edit_document), diff --git a/lib/services/singbox/ffi_singbox_service.dart b/lib/services/singbox/ffi_singbox_service.dart index e2f75d9c..47dc4e65 100644 --- a/lib/services/singbox/ffi_singbox_service.dart +++ b/lib/services/singbox/ffi_singbox_service.dart @@ -8,7 +8,7 @@ import 'package:combine/combine.dart'; import 'package:ffi/ffi.dart'; import 'package:fpdart/fpdart.dart'; import 'package:hiddify/domain/connectivity/connectivity.dart'; -import 'package:hiddify/domain/singbox/config_options.dart'; +import 'package:hiddify/domain/singbox/singbox.dart'; import 'package:hiddify/gen/singbox_generated_bindings.dart'; import 'package:hiddify/services/singbox/shared.dart'; import 'package:hiddify/services/singbox/singbox_service.dart'; diff --git a/libcore b/libcore index d410fe1c..0480a5d3 160000 --- a/libcore +++ b/libcore @@ -1 +1 @@ -Subproject commit d410fe1c4b0d90f545716737d53e0002be9504cd +Subproject commit 0480a5d3ec0571b7a0662625679a277219c51d0f