diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bffc4b80..944bc00b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,11 +39,11 @@ jobs: targets: exe filename: hiddify-windows-x64 - - platform: linux-appimage - os: ubuntu-20.04 - aarch: amd64 - targets: AppImage - filename: hiddify-linux-x64 + # - platform: linux-appimage + # os: ubuntu-20.04 + # aarch: amd64 + # targets: AppImage + # filename: hiddify-linux-x64 - platform: linux-deb os: ubuntu-20.04 diff --git a/Makefile b/Makefile index e8308cdd..1cf36ddc 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,25 @@ include dependencies.properties +ifeq ($(OS),Windows_NT) + MKDIR := -mkdir + RM := rmdir /s /q + SEP:=\\ + PLATFORM_REQ:= @set /p platform="Run 'make prepare platform=ios' or enter platform name:"; +else + MKDIR := mkdir -p + RM := rm -rf + SEP :=/ + PLATFORM_REQ:= @read -p "Run make prepare platform=ios or enter platform name: " platform; +endif -BINDIR=./libcore/bin -ANDROID_OUT=./android/app/libs -IOS_OUT=./ios/Frameworks -DESKTOP_OUT=./libcore/bin -GEO_ASSETS_DIR=./assets/core +BINDIR=libcore$(SEP)bin +ANDROID_OUT=android$(SEP)app$(SEP)libs +IOS_OUT=ios$(SEP)Frameworks +DESKTOP_OUT=libcore$(SEP)bin +GEO_ASSETS_DIR=assets$(SEP)core CORE_PRODUCT_NAME=hiddify-core CORE_NAME=$(CORE_PRODUCT_NAME) -SRV_NAME=hiddify-service +SRV_NAME=HiddifyService ifeq ($(CHANNEL),prod) CORE_URL=https://github.com/hiddify/hiddify-next-core/releases/download/v$(core.version) else @@ -24,6 +35,10 @@ endif BUILD_ARGS=--dart-define sentry_dsn=$(SENTRY_DSN) DISTRIBUTOR_ARGS=--skip-clean --build-target $(TARGET) --build-dart-define sentry_dsn=$(SENTRY_DSN) + + + + get: flutter pub get @@ -33,19 +48,23 @@ gen: translate: dart run slang -prepare: get-geo-assets get gen translate - @echo "Available platforms:" - @echo "android" - @echo "windows" - @echo "linux" - @echo "macos" - @echo "ios" - if [ -z "$$platform" ]; then \ - read -p "run make prepare platform=ios or Enter platform name: " choice; \ - else \ - choice=$$platform; \ - fi; \ - make $$choice-libs + + +prepare: #get-geo-assets get gen translate + @echo use the following commands to prepare the library for each platform: + @echo make android-prepare + @echo make windows-prepare + @echo make linux-prepare + @echo make macos-prepare + @echo make ios-prepare + +windows-prepare: get-geo-assets get gen translate windows-libs +ios-prepare: get-geo-assets get gen translate ios-libs +macos-prepare: get-geo-assets get gen translate macos-libs +linux-prepare: get-geo-assets get gen translate linux-libs +android-prepare: get-geo-assets get gen translate android-libs + + sync_translate: cd .github && bash sync_translate.sh @@ -81,18 +100,18 @@ ios-release: #not tested flutter_distributor package --platform ios --targets ipa --build-export-options-plist ios/exportOptions.plist $(DISTRIBUTOR_ARGS) android-libs: - mkdir -p $(ANDROID_OUT) + @$(MKDIR) $(ANDROID_OUT) || echo Folder already exists. Skipping... curl -L $(CORE_URL)/$(CORE_NAME)-android.tar.gz | tar xz -C $(ANDROID_OUT)/ android-apk-libs: android-libs android-aab-libs: android-libs windows-libs: - mkdir -p $(DESKTOP_OUT) + @$(MKDIR) $(DESKTOP_OUT) || echo Folder already exists. Skipping... curl -L $(CORE_URL)/$(CORE_NAME)-windows-amd64.tar.gz | tar xz -C $(DESKTOP_OUT)/ linux-libs: - mkdir -p $(DESKTOP_OUT) + @$(MKDIR) $(DESKTOP_OUT) || echo Folder already exists. Skipping... curl -L $(CORE_URL)/$(CORE_NAME)-linux-amd64.tar.gz | tar xz -C $(DESKTOP_OUT)/ @@ -101,13 +120,13 @@ linux-rpm-libs:linux-libs linux-appimage-libs:linux-libs macos-libs: - mkdir -p $(DESKTOP_OUT)/ &&\ - curl -L $(CORE_URL)/$(CORE_NAME)-macos-universal.tar.gz | tar xz -C $(DESKTOP_OUT)/ + @$(MKDIR) $(DESKTOP_OUT) || echo Folder already exists. Skipping... + curl -L $(CORE_URL)/$(CORE_NAME)-macos-universal.tar.gz | tar xz -C $(DESKTOP_OUT) ios-libs: #not tested - mkdir -p $(DESKTOP_OUT)/ && \ - rm -rf $(IOS_OUT)/Libcore.xcframework && \ - curl -L $(CORE_URL)/$(CORE_NAME)-ios.tar.gz | tar xz -C "$(IOS_OUT)" + @$(MKDIR) $(IOS_OUT) || echo Folder already exists. Skipping... + @$(RM) $(IOS_OUT)/Libcore.xcframework + curl -L $(CORE_URL)/$(CORE_NAME)-ios.tar.gz | tar xz -C "$(IOS_OUT)" get-geo-assets: curl -L https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db -o $(GEO_ASSETS_DIR)/geoip.db @@ -136,7 +155,7 @@ build-macos-libs: mv $(BINDIR)/$(SRV_NAME) $(DESKTOP_OUT)/ build-ios-libs: - rm -rf $(IOS_OUT)/Libcore.xcframework && \ + @$(RM) $(IOS_OUT)/Libcore.xcframework && \ make -C libcore -f Makefile ios && \ mv $(BINDIR)/$(CORE_NAME)-ios.xcframework $(IOS_OUT)/Libcore.xcframework diff --git a/assets/translations/strings_en.i18n.json b/assets/translations/strings_en.i18n.json index e4902778..669d4e97 100644 --- a/assets/translations/strings_en.i18n.json +++ b/assets/translations/strings_en.i18n.json @@ -11,7 +11,10 @@ }, "sort": "Sort", "sortBy": "Sort by", - "addToClipboard": "Add to clipboard" + "addToClipboard": "Add to clipboard", + "notSet": "Not Set", + "agree": "Agree", + "decline": "Decline" }, "intro": { "termsAndPolicyCaution(rich)": "by continuing you agree with ${tap(@:about.termsAndConditions)}", @@ -204,8 +207,13 @@ "mux": "Multiplexer", "outbound": "Outbound Options", "tlsTricks": "TLS Tricks", + "warp": "WARP Options", "misc": "Misc Options" }, + "warpConsent": { + "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)}." + }, "pageTitle": "Config Options", "logLevel": "Log Level", "resolveDestination": "Resolve Destination", @@ -243,7 +251,17 @@ "tlsPaddingSize": "TLS Padding", "enableMux": "Enable Mux", "muxProtocol": "Mux Protocol", - "muxMaxStreams": "Max Concurrent Streams" + "muxMaxStreams": "Max Concurrent Streams", + "enableWarp": "Enable WARP", + "warpDetourMode": "Detour Mode", + "warpDetourModes": { + "inbound": "Detour WARP through proxies", + "outbound": "Detour proxies through WARP" + }, + "warpLicenseKey": "License Key", + "warpCleanIp": "Clean IP", + "warpPort": "Port", + "warpNoise": "Noise" }, "geoAssets": { "pageTitle": "Routing Assets", diff --git a/assets/translations/strings_es.i18n.json b/assets/translations/strings_es.i18n.json index 3d00b339..a10c165d 100644 --- a/assets/translations/strings_es.i18n.json +++ b/assets/translations/strings_es.i18n.json @@ -11,7 +11,10 @@ }, "sort": "Clasificar", "sortBy": "Ordenar por", - "addToClipboard": "Añadir al portapapeles" + "addToClipboard": "Añadir al portapapeles", + "notSet": "No establecido", + "agree": "Aceptar", + "decline": "Rechazar" }, "intro": { "termsAndPolicyCaution(rich)": "al continuar, aceptas ${tap(@:about.termsAndConditions)}", @@ -204,6 +207,7 @@ "mux": "Multiplexer", "outbound": "Opciones de salida", "tlsTricks": "Trucos TLS", + "warp": "WARP Options", "misc": "Opciones varias" }, "pageTitle": "Opciones de configuración", @@ -243,7 +247,21 @@ "tlsPaddingSize": "Relleno TLS", "enableMux": "Enable Mux", "muxProtocol": "Mux Protocol", - "muxMaxStreams": "Max Concurrent Streams" + "muxMaxStreams": "Max Concurrent Streams", + "enableWarp": "Enable WARP", + "warpDetourMode": "Detour Mode", + "warpDetourModes": { + "inbound": "Detour WARP through proxies", + "outbound": "Detour proxies through WARP" + }, + "warpLicenseKey": "License Key", + "warpCleanIp": "Clean IP", + "warpPort": "Port", + "warpNoise": "Noise", + "warpConsent": { + "title": "Consentimiento WARP de Cloudflare", + "description(rich)": "Cloudflare WARP es un proveedor de VPN WireGuard gratuito. Al habilitar esta opción, acepta los ${tos(Términos de servicio)} y ${privacy(Política de privacidad)} de Cloudflare WARP." + } }, "geoAssets": { "pageTitle": "Activos de enrutamiento", diff --git a/assets/translations/strings_fa.i18n.json b/assets/translations/strings_fa.i18n.json index dd81bf08..024da3bc 100644 --- a/assets/translations/strings_fa.i18n.json +++ b/assets/translations/strings_fa.i18n.json @@ -11,7 +11,10 @@ }, "sort": "مرتب‌سازی", "sortBy": "مرتب‌سازی براساس", - "addToClipboard": "به کلیپ بورد اضافه کنید" + "addToClipboard": "به کلیپ بورد اضافه کنید", + "notSet": "تنظیم نشده", + "agree": "موافق", + "decline": "کاهش می یابد" }, "intro": { "termsAndPolicyCaution(rich)": "در صورت ادامه با ${tap(@:about.termsAndConditions)} موافقت میکنید", @@ -204,6 +207,7 @@ "mux": "Multiplexer", "outbound": "Outbound Options", "tlsTricks": "TLS Tricks", + "warp": "WARP Options", "misc": "تنظیمات متفرقه" }, "pageTitle": "تنظیمات کانفیگ", @@ -243,7 +247,21 @@ "tlsPaddingSize": "TLS Padding", "enableMux": "Enable Mux", "muxProtocol": "Mux Protocol", - "muxMaxStreams": "Max Concurrent Streams" + "muxMaxStreams": "Max Concurrent Streams", + "enableWarp": "Enable WARP", + "warpDetourMode": "Detour Mode", + "warpDetourModes": { + "inbound": "Detour WARP through proxies", + "outbound": "Detour proxies through WARP" + }, + "warpLicenseKey": "License Key", + "warpCleanIp": "Clean IP", + "warpPort": "Port", + "warpNoise": "Noise", + "warpConsent": { + "title": "رضایت Cloudflare WARP", + "description(rich)": "Cloudflare WARP یک ارائه دهنده رایگان WireGuard VPN است. با فعال کردن این گزینه، با ${tos(شرایط خدمات)} و ${privacy(خط‌مشی رازداری)} Cloudflare WARP موافقت می‌کنید." + } }, "geoAssets": { "pageTitle": "فایل‌های مسیریابی", diff --git a/assets/translations/strings_ru.i18n.json b/assets/translations/strings_ru.i18n.json index 12a4b278..ce4f1eab 100644 --- a/assets/translations/strings_ru.i18n.json +++ b/assets/translations/strings_ru.i18n.json @@ -11,7 +11,10 @@ }, "sort": "Сортировка", "sortBy": "Сортировка", - "addToClipboard": "Копировать в буфер обмена" + "addToClipboard": "Копировать в буфер обмена", + "notSet": "Не задано", + "agree": "Соглашаться", + "decline": "Отклонить" }, "intro": { "termsAndPolicyCaution(rich)": "Продолжая, Вы соглашаетесь с ${tap(@:about.termsAndConditions)}", @@ -204,6 +207,7 @@ "mux": "Multiplexer", "outbound": "Outbound Options", "tlsTricks": "TLS Tricks", + "warp": "WARP Options", "misc": "Разные параметры" }, "pageTitle": "Параметры конфигурации", @@ -243,7 +247,21 @@ "tlsPaddingSize": "TLS Padding", "enableMux": "Enable Mux", "muxProtocol": "Mux Protocol", - "muxMaxStreams": "Max Concurrent Streams" + "muxMaxStreams": "Max Concurrent Streams", + "enableWarp": "Enable WARP", + "warpDetourMode": "Detour Mode", + "warpDetourModes": { + "inbound": "Detour WARP through proxies", + "outbound": "Detour proxies through WARP" + }, + "warpLicenseKey": "License Key", + "warpCleanIp": "Clean IP", + "warpPort": "Port", + "warpNoise": "Noise", + "warpConsent": { + "title": "Согласие Cloudflare WARP", + "description(rich)": "Cloudflare WARP — бесплатный провайдер WireGuard VPN. Включая эту опцию, вы соглашаетесь с ${tos(Условиями обслуживания)} и ${privacy(Политикой конфиденциальности)} Cloudflare WARP." + } }, "geoAssets": { "pageTitle": "Активы маршрутизации", diff --git a/assets/translations/strings_tr.i18n.json b/assets/translations/strings_tr.i18n.json index e1aa5e69..5f4148b9 100644 --- a/assets/translations/strings_tr.i18n.json +++ b/assets/translations/strings_tr.i18n.json @@ -11,7 +11,10 @@ }, "sort": "Sırala", "sortBy": "Sırala", - "addToClipboard": "Panoya ekle" + "addToClipboard": "Panoya ekle", + "notSet": "Ayarlanmadı", + "agree": "Kabul etmek", + "decline": "Reddetmek" }, "intro": { "termsAndPolicyCaution(rich)": "devam ederek ${tap(@:about.termsAndConditions)} kabul etmiş olursunuz", @@ -204,6 +207,7 @@ "mux": "Multiplexer", "outbound": "Outbound Options", "tlsTricks": "TLS Tricks", + "warp": "WARP Options", "misc": "Çeşitli Seçenekler" }, "pageTitle": "Yapılandırma Seçenekleri", @@ -243,7 +247,21 @@ "tlsPaddingSize": "TLS Padding", "enableMux": "Enable Mux", "muxProtocol": "Mux Protocol", - "muxMaxStreams": "Max Concurrent Streams" + "muxMaxStreams": "Max Concurrent Streams", + "enableWarp": "Enable WARP", + "warpDetourMode": "Detour Mode", + "warpDetourModes": { + "inbound": "Detour WARP through proxies", + "outbound": "Detour proxies through WARP" + }, + "warpLicenseKey": "License Key", + "warpCleanIp": "Clean IP", + "warpPort": "Port", + "warpNoise": "Noise", + "warpConsent": { + "title": "Cloudflare WARP Onayı", + "description(rich)": "Cloudflare WARP ücretsiz bir WireGuard VPN sağlayıcısıdır. Bu seçeneği etkinleştirerek Cloudflare WARP'ın ${tos(Hizmet Şartları)} ve ${privacy(Gizlilik Politikası)}'nı kabul etmiş olursunuz." + } }, "geoAssets": { "pageTitle": "Varlıkları Yönlendirme", diff --git a/assets/translations/strings_zh-CN.i18n.json b/assets/translations/strings_zh-CN.i18n.json index 0e4a1988..2802a969 100644 --- a/assets/translations/strings_zh-CN.i18n.json +++ b/assets/translations/strings_zh-CN.i18n.json @@ -11,7 +11,10 @@ }, "sort": "排序", "sortBy": "排序方式", - "addToClipboard": "添加到剪贴板" + "addToClipboard": "添加到剪贴板", + "notSet": "没有设置", + "agree": "同意", + "decline": "衰退" }, "intro": { "termsAndPolicyCaution(rich)": "继续即表示您同意 ${tap(@:about.termsAndConditions)}", @@ -204,7 +207,9 @@ "mux": "复用器", "outbound": "出站选项", "tlsTricks": "TLS Tricks", - "misc": "其他选项" + "misc": "其他选项", + "warp": "WARP 选项", + "misc": "其它选项", }, "pageTitle": "配置选项", "logLevel": "日志级别", @@ -244,6 +249,23 @@ "enableMux": "启用复用器", "muxProtocol": "复用器控制", "muxMaxStreams": "最大并发数" + "enableMux": "启用 Mux", + "muxProtocol": "Mux 控制", + "muxMaxStreams": "最大并发数", + "enableWarp": "启用 WARP", + "warpDetourMode": "迂回模式", + "warpDetourModes": { + "inbound": "通过代理绕过 WARP", + "outbound": "通过 WARP 绕过代理" + }, + "warpLicenseKey": "许可证密钥", + "warpCleanIp": "干净 IP", + "warpPort": "端口", + "warpNoise": "噪音", + "warpConsent": { + "title": "Cloudflare WARP 同意", + "description(rich)": "Cloudflare WARP 是免费的 WireGuard VPN 提供商。启用此选项即表示您同意 Cloudflare WARP 的 ${tos(服务条款)} 和 ${privacy(隐私政策)}" + } }, "geoAssets": { "pageTitle": "路由资源文件", diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index cd4282c9..225a73c1 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -34,7 +34,7 @@ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 54EA599BF9C050F2827533D5 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDA50BDF2E5E5DDA3995F24D /* Pods_RunnerTests.framework */; }; + 59E8864FB99B37076B22F32B /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30560DB3EFDF5E86AAD00AB8 /* Pods_RunnerTests.framework */; }; 6836D3FD2B57FE4300A79D75 /* Libcore in Frameworks */ = {isa = PBXBuildFile; productRef = 6836D3FC2B57FE4300A79D75 /* Libcore */; }; 6836D4022B57FEFF00A79D75 /* Libcore in Frameworks */ = {isa = PBXBuildFile; productRef = 6836D4012B57FEFF00A79D75 /* Libcore */; }; 68885DD72B4EF33400D214BA /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03E392B72ADDA00E000ADF15 /* NetworkExtension.framework */; }; @@ -89,6 +89,7 @@ 032158B72ADDF8BF008D943B /* VPNManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNManager.swift; sourceTree = ""; }; 032158B92ADDFCC9008D943B /* TrafficReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrafficReader.swift; sourceTree = ""; }; 032158BB2ADDFD09008D943B /* SingBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingBox.swift; sourceTree = ""; }; + 0337C822BEDF7A95576475B3 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 03B516662AE6B93A00EA47E2 /* MethodHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MethodHandler.swift; sourceTree = ""; }; 03B516682AE7306B00EA47E2 /* StatusEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEventHandler.swift; sourceTree = ""; }; 03B5166A2AE7315E00EA47E2 /* AlertsEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsEventHandler.swift; sourceTree = ""; }; @@ -109,6 +110,7 @@ 03E392CE2ADDEFC8000ADF15 /* FilePath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePath.swift; sourceTree = ""; }; 03E392D12ADDF1F4000ADF15 /* ExtensionPlatformInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionPlatformInterface.swift; sourceTree = ""; }; 03E392D32ADDF262000ADF15 /* Extension+RunBlocking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extension+RunBlocking.swift"; sourceTree = ""; }; + 040FA3EB0673B72D60CC7145 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 0736954E2B1FEB3E007249BE /* mobile_scanner.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = mobile_scanner.xcframework; path = ../build/ios/framework/Release/mobile_scanner.xcframework; sourceTree = ""; }; 0736958A2B3AC96D007249BE /* Bundle+Properties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+Properties.swift"; sourceTree = ""; }; 0736958C2B3B79E0007249BE /* StatsEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsEventHandler.swift; sourceTree = ""; }; @@ -138,9 +140,9 @@ 07A63A9F2B1E72FC00CAFA4D /* path_provider_foundation.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = path_provider_foundation.xcframework; path = ../build/ios/framework/release/path_provider_foundation.xcframework; sourceTree = ""; }; 07A63AA02B1E72FC00CAFA4D /* shared_preferences_foundation.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = shared_preferences_foundation.xcframework; path = ../build/ios/framework/release/shared_preferences_foundation.xcframework; sourceTree = ""; }; 07A63AA12B1E72FC00CAFA4D /* Sentry.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Sentry.xcframework; path = ../build/ios/framework/release/Sentry.xcframework; sourceTree = ""; }; - 0F7E04B7207513677AF77112 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 30560DB3EFDF5E86AAD00AB8 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; @@ -151,7 +153,7 @@ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7CA62594950187FCFE36B54C /* Pods-Runner-SingBoxPacketTunnel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-SingBoxPacketTunnel.debug.xcconfig"; path = "Target Support Files/Pods-Runner-SingBoxPacketTunnel/Pods-Runner-SingBoxPacketTunnel.debug.xcconfig"; sourceTree = ""; }; - 7E8B7AF73AD416B8FAA5E9B0 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 808A94F72872B54716770416 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 90E93DE403BDFA627F3AA51E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; @@ -160,10 +162,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 9A37A927A1A9458918B3C12A /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 9AC67B4DCF829F5B6F63AA7D /* Pods-Runner-SingBoxPacketTunnel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-SingBoxPacketTunnel.release.xcconfig"; path = "Target Support Files/Pods-Runner-SingBoxPacketTunnel/Pods-Runner-SingBoxPacketTunnel.release.xcconfig"; sourceTree = ""; }; C20A211B58CE31B2738D133C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - DDA50BDF2E5E5DDA3995F24D /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F3FFE1D9C2D5629FACC123EE /* Pods-Runner-SingBoxPacketTunnel.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-SingBoxPacketTunnel.profile.xcconfig"; path = "Target Support Files/Pods-Runner-SingBoxPacketTunnel/Pods-Runner-SingBoxPacketTunnel.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -181,7 +181,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 54EA599BF9C050F2827533D5 /* Pods_RunnerTests.framework in Frameworks */, + 59E8864FB99B37076B22F32B /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -276,12 +276,12 @@ 574F12C7748958784380337F /* Pods-Runner.debug.xcconfig */, 90E93DE403BDFA627F3AA51E /* Pods-Runner.release.xcconfig */, C20A211B58CE31B2738D133C /* Pods-Runner.profile.xcconfig */, - 7E8B7AF73AD416B8FAA5E9B0 /* Pods-RunnerTests.debug.xcconfig */, - 9A37A927A1A9458918B3C12A /* Pods-RunnerTests.release.xcconfig */, - 0F7E04B7207513677AF77112 /* Pods-RunnerTests.profile.xcconfig */, 7CA62594950187FCFE36B54C /* Pods-Runner-SingBoxPacketTunnel.debug.xcconfig */, 9AC67B4DCF829F5B6F63AA7D /* Pods-Runner-SingBoxPacketTunnel.release.xcconfig */, F3FFE1D9C2D5629FACC123EE /* Pods-Runner-SingBoxPacketTunnel.profile.xcconfig */, + 0337C822BEDF7A95576475B3 /* Pods-RunnerTests.debug.xcconfig */, + 808A94F72872B54716770416 /* Pods-RunnerTests.release.xcconfig */, + 040FA3EB0673B72D60CC7145 /* Pods-RunnerTests.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -388,8 +388,8 @@ 07A63A842B1E72AE00CAFA4D /* App.xcframework */, 07A63A832B1E728C00CAFA4D /* Release */, 60F1D4AAC33ACF5C8307310D /* Pods_Runner.framework */, - DDA50BDF2E5E5DDA3995F24D /* Pods_RunnerTests.framework */, 03E392B72ADDA00E000ADF15 /* NetworkExtension.framework */, + 30560DB3EFDF5E86AAD00AB8 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -424,7 +424,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - F63DAC79B8A3B6681959DBC1 /* [CP] Check Pods Manifest.lock */, + 2058E420D1A8B6F0E5E03873 /* [CP] Check Pods Manifest.lock */, 331C807D294A63A400263BE5 /* Sources */, 331C807F294A63A400263BE5 /* Resources */, 531FE8242BCD501C24C8E9FA /* Frameworks */, @@ -546,6 +546,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 2058E420D1A8B6F0E5E03873 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -599,28 +621,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - F63DAC79B8A3B6681959DBC1 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; FBEFD3291AEA65EDE2F5AEF6 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -800,6 +800,8 @@ INFOPLIST_KEY_NSHumanReadableCopyright = ""; IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.5/$(PLATFORM_NAME)", "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", @@ -847,6 +849,8 @@ INFOPLIST_KEY_NSHumanReadableCopyright = ""; IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( + "$(SDKROOT)/usr/lib/swift", + "$(TOOLCHAIN_DIR)/usr/lib/swift-5.5/$(PLATFORM_NAME)", "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", @@ -942,49 +946,18 @@ DEVELOPMENT_TEAM = 3JFTY5BP58; ENABLE_BITCODE = NO; "EXCLUDED_ARCHS[sdk=iphoneos*]" = armv7; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilitiesComponents\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/Sentry\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/SentryPrivate\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cupertino_http\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/device_info_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_native_splash\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/mobile_scanner\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/package_info_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/path_provider_foundation\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/protocol_handler\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sentry_flutter\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/share_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/shared_preferences_foundation\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sqlite3\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sqlite3_flutter_libs\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_ios\"", - "\"${PODS_ROOT}/MLImage/Frameworks\"", - "\"${PODS_ROOT}/MLKitBarcodeScanning/Frameworks\"", - "\"${PODS_ROOT}/MLKitCommon/Frameworks\"", - "\"${PODS_ROOT}/MLKitVision/Frameworks\"", - "$(PROJECT_DIR)/Flutter", - "$(PROJECT_DIR)/Frameworks/**", - "$(PROJECT_DIR)/..", - ); INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", "$(PROJECT_DIR)/build/ios/framework/$(CONFIGURATION)", "$(PROJECT_DIR)/../build/ios/framework/$(CONFIGURATION)", "$(SDKROOT)/usr/lib/swift", "$(TOOLCHAIN_DIR)/usr/lib/swift-5.5/$(PLATFORM_NAME)", + "$(inherited)", "@executable_path/Frameworks", + "@executable_path/../../Frameworks", "@executable_path/../libcore/", - "@executable_path/libcore", + "@executable_path/libcore/", ); ONLY_ACTIVE_ARCH = NO; OTHER_CPLUSPLUSFLAGS = ( @@ -1010,7 +983,7 @@ }; 331C8088294A63A400263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7E8B7AF73AD416B8FAA5E9B0 /* Pods-RunnerTests.debug.xcconfig */; + baseConfigurationReference = 0337C822BEDF7A95576475B3 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -1028,7 +1001,7 @@ }; 331C8089294A63A400263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9A37A927A1A9458918B3C12A /* Pods-RunnerTests.release.xcconfig */; + baseConfigurationReference = 808A94F72872B54716770416 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -1044,7 +1017,7 @@ }; 331C808A294A63A400263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0F7E04B7207513677AF77112 /* Pods-RunnerTests.profile.xcconfig */; + baseConfigurationReference = 040FA3EB0673B72D60CC7145 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -1194,49 +1167,18 @@ ENABLE_BITCODE = NO; "EXCLUDED_ARCHS[sdk=iphoneos*]" = armv7; "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64"; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilitiesComponents\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/Sentry\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/SentryPrivate\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cupertino_http\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/device_info_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_native_splash\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/mobile_scanner\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/package_info_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/path_provider_foundation\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/protocol_handler\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sentry_flutter\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/share_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/shared_preferences_foundation\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sqlite3\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sqlite3_flutter_libs\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_ios\"", - "\"${PODS_ROOT}/MLImage/Frameworks\"", - "\"${PODS_ROOT}/MLKitBarcodeScanning/Frameworks\"", - "\"${PODS_ROOT}/MLKitCommon/Frameworks\"", - "\"${PODS_ROOT}/MLKitVision/Frameworks\"", - "$(PROJECT_DIR)/Flutter", - "$(PROJECT_DIR)/Frameworks/**", - "$(PROJECT_DIR)/..", - ); INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", "$(PROJECT_DIR)/build/ios/framework/$(CONFIGURATION)", "$(PROJECT_DIR)/../build/ios/framework/$(CONFIGURATION)", "$(SDKROOT)/usr/lib/swift", "$(TOOLCHAIN_DIR)/usr/lib/swift-5.5/$(PLATFORM_NAME)", + "$(inherited)", "@executable_path/Frameworks", + "@executable_path/../../Frameworks", "@executable_path/../libcore/", - "@executable_path/libcore", + "@executable_path/libcore/", ); OTHER_CPLUSPLUSFLAGS = ( "-fcxx-modules", @@ -1273,49 +1215,18 @@ DEVELOPMENT_TEAM = 3JFTY5BP58; ENABLE_BITCODE = NO; "EXCLUDED_ARCHS[sdk=iphoneos*]" = armv7; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GTMSessionFetcher\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleToolboxForMac\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilitiesComponents\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/Sentry\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/SentryPrivate\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/cupertino_http\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/device_info_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/flutter_native_splash\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/mobile_scanner\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/package_info_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/path_provider_foundation\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/protocol_handler\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sentry_flutter\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/share_plus\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/shared_preferences_foundation\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sqlite3\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/sqlite3_flutter_libs\"", - "\"${PODS_CONFIGURATION_BUILD_DIR}/url_launcher_ios\"", - "\"${PODS_ROOT}/MLImage/Frameworks\"", - "\"${PODS_ROOT}/MLKitBarcodeScanning/Frameworks\"", - "\"${PODS_ROOT}/MLKitCommon/Frameworks\"", - "\"${PODS_ROOT}/MLKitVision/Frameworks\"", - "$(PROJECT_DIR)/Flutter", - "$(PROJECT_DIR)/Frameworks/**", - "$(PROJECT_DIR)/..", - ); INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", "$(PROJECT_DIR)/build/ios/framework/$(CONFIGURATION)", "$(PROJECT_DIR)/../build/ios/framework/$(CONFIGURATION)", "$(SDKROOT)/usr/lib/swift", "$(TOOLCHAIN_DIR)/usr/lib/swift-5.5/$(PLATFORM_NAME)", + "$(inherited)", "@executable_path/Frameworks", + "@executable_path/../../Frameworks", "@executable_path/../libcore/", - "@executable_path/libcore", + "@executable_path/libcore/", ); ONLY_ACTIVE_ARCH = NO; OTHER_CPLUSPLUSFLAGS = ( diff --git a/ios/Runner/Handlers/LogsEventHandler.swift b/ios/Runner/Handlers/LogsEventHandler.swift index 11ee6396..c1b86208 100644 --- a/ios/Runner/Handlers/LogsEventHandler.swift +++ b/ios/Runner/Handlers/LogsEventHandler.swift @@ -1,31 +1,72 @@ -// -// LogsEventHandler.swift -// Runner -// -// Created by GFWFighter on 10/24/23. -// - import Foundation +import Combine +import Libcore -public class LogsEventHandler: NSObject, FlutterPlugin, FlutterStreamHandler { +class LogsEventHandler: NSObject, FlutterPlugin, FlutterStreamHandler, LibboxCommandClientHandlerProtocol { static let name = "\(Bundle.main.serviceIdentifier)/service.logs" private var channel: FlutterEventChannel? - + + private var commandClient: LibboxCommandClient? + private var events: FlutterEventSink? + private var maxLines: Int + private var logList: [String] = [] + + private var lock: NSLock = NSLock() + public static func register(with registrar: FlutterPluginRegistrar) { - let instance = LogsEventHandler() - instance.channel = FlutterEventChannel(name: Self.name, binaryMessenger: registrar.messenger()) - instance.channel?.setStreamHandler(instance) + let instance = LogsEventHandler() + instance.channel = FlutterEventChannel(name: Self.name, binaryMessenger: registrar.messenger()) + instance.channel?.setStreamHandler(instance) + } + + init(maxLines: Int = 32) { + self.maxLines = maxLines + super.init() + let opts = LibboxCommandClientOptions() + opts.command = LibboxCommandLog + opts.statusInterval = Int64(2 * NSEC_PER_SEC) + commandClient = LibboxCommandClient(self, options: opts) + try? commandClient?.connect() } + deinit { + try? commandClient?.disconnect() + } + public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { - if VPNManager.shared.logCallback { - events(VPNManager.shared.logList) - } + events(logList) + self.events = events return nil } - + public func onCancel(withArguments arguments: Any?) -> FlutterError? { + events = nil return nil } + + func writeLog(_ message: String?) { + guard let message else { + return + } + lock.withLock { [self] in + if logList.count > maxLines { + logList.removeFirst() + } + logList.append(message) + DispatchQueue.main.async { [self] () in + events?(logList) + } + } + } +} + +extension LogsEventHandler { + public func clearLog() {} + public func connected() {} + public func disconnected(_ message: String?) {} + public func initializeClashMode(_ modeList: LibboxStringIteratorProtocol?, currentMode: String?) {} + public func updateClashMode(_ newMode: String?) {} + public func writeGroups(_ message: LibboxOutboundGroupIteratorProtocol?) {} + public func writeStatus(_ message: LibboxStatusMessage?) {} } diff --git a/ios/Runner/VPN/VPNManager.swift b/ios/Runner/VPN/VPNManager.swift index 1ade3291..8bdff45b 100644 --- a/ios/Runner/VPN/VPNManager.swift +++ b/ios/Runner/VPN/VPNManager.swift @@ -39,8 +39,6 @@ class VPNManager: ObservableObject { @Published private(set) var upload: Int64 = 0 @Published private(set) var download: Int64 = 0 @Published private(set) var elapsedTime: TimeInterval = 0 - @Published private(set) var logList: [String] = [] - @Published private(set) var logCallback = false private var _connectTime: Date? private var connectTime: Date? { @@ -88,7 +86,7 @@ class VPNManager: ObservableObject { do { try await loadVPNPreference() } catch { - onServiceWriteLog(message: error.localizedDescription) + LogsEventHandler().writeLog(error.localizedDescription) } } @@ -109,7 +107,7 @@ class VPNManager: ObservableObject { try await newManager.loadFromPreferences() self.manager = newManager } catch { - onServiceWriteLog(message: error.localizedDescription) + LogsEventHandler().writeLog(error.localizedDescription) } } @@ -119,7 +117,7 @@ class VPNManager: ObservableObject { try await manager.saveToPreferences() try await manager.loadFromPreferences() } catch { - onServiceWriteLog(message: error.localizedDescription) + LogsEventHandler().writeLog(error.localizedDescription) } } @@ -159,7 +157,7 @@ class VPNManager: ObservableObject { } try await self?.loadVPNPreference() } catch { - onServiceWriteLog(message: error.localizedDescription) + LogsEventHandler().writeLog(error.localizedDescription) } } }.store(in: &cancelBag) @@ -190,7 +188,7 @@ class VPNManager: ObservableObject { } } } catch { - onServiceWriteLog(message: error.localizedDescription) + LogsEventHandler().writeLog(error.localizedDescription) } } @@ -204,7 +202,7 @@ class VPNManager: ObservableObject { "DisableMemoryLimit": (disableMemoryLimit ? "YES" : "NO") as NSString, ]) } catch { - onServiceWriteLog(message: error.localizedDescription) + LogsEventHandler().writeLog(error.localizedDescription) } connectTime = .now } @@ -213,17 +211,4 @@ class VPNManager: ObservableObject { guard state == .connected else { return } manager.connection.stopVPNTunnel() } - - func onServiceWriteLog(message: String) { - logCallback = true - if logList.count > 300 { - logList.removeFirst() - } - logList.append(message) - } - - func onServiceResetLogs() { - logCallback = false - logList.removeAll() - } } diff --git a/lib/core/model/constants.dart b/lib/core/model/constants.dart index 8882ab83..fcb7bddf 100644 --- a/lib/core/model/constants.dart +++ b/lib/core/model/constants.dart @@ -10,4 +10,8 @@ abstract class Constants { static const telegramChannelUrl = "https://t.me/hiddify"; static const privacyPolicyUrl = "https://hiddify.com/privacy-policy/"; static const termsAndConditionsUrl = "https://hiddify.com/terms/"; + static const cfWarpPrivacyPolicy = + "https://www.cloudflare.com/application/privacypolicy/"; + static const cfWarpTermsOfService = + "https://www.cloudflare.com/application/terms/"; } diff --git a/lib/core/model/range.dart b/lib/core/model/range.dart index fba247b3..d644da6f 100644 --- a/lib/core/model/range.dart +++ b/lib/core/model/range.dart @@ -1,4 +1,6 @@ +import 'package:dartx/dartx.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:hiddify/core/localization/translations.dart'; part 'range.freezed.dart'; @@ -7,14 +9,21 @@ class RangeWithOptionalCeil with _$RangeWithOptionalCeil { const RangeWithOptionalCeil._(); const factory RangeWithOptionalCeil({ - required int min, + int? min, int? max, }) = _RangeWithOptionalCeil; - String format() => "$min${max != null ? "-$max" : ""}"; + String format() => [min, max].whereNotNull().join("-"); + String present(TranslationsEn t) => + format().isEmpty ? t.general.notSet : format(); - factory RangeWithOptionalCeil.fromString(String input) => + factory RangeWithOptionalCeil._fromString( + String input, { + bool allowEmpty = true, + }) => switch (input.split("-")) { + [final String val] when val.isEmpty && allowEmpty => + const RangeWithOptionalCeil(), [final String min] => RangeWithOptionalCeil(min: int.parse(min)), [final String min, final String max] => RangeWithOptionalCeil( min: int.parse(min), @@ -23,9 +32,12 @@ class RangeWithOptionalCeil with _$RangeWithOptionalCeil { _ => throw Exception("Invalid range: $input"), }; - static RangeWithOptionalCeil? tryParse(String input) { + static RangeWithOptionalCeil? tryParse( + String input, { + bool allowEmpty = false, + }) { try { - return RangeWithOptionalCeil.fromString(input); + return RangeWithOptionalCeil._fromString(input); } catch (_) { return null; } @@ -38,7 +50,7 @@ class RangeWithOptionalCeilJsonConverter @override RangeWithOptionalCeil fromJson(String json) => - RangeWithOptionalCeil.fromString(json); + RangeWithOptionalCeil._fromString(json); @override String toJson(RangeWithOptionalCeil object) => object.format(); diff --git a/lib/features/config_option/data/config_option_repository.dart b/lib/features/config_option/data/config_option_repository.dart index 7d8f985d..82faa16f 100644 --- a/lib/features/config_option/data/config_option_repository.dart +++ b/lib/features/config_option/data/config_option_repository.dart @@ -117,6 +117,12 @@ class ConfigOptionRepositoryImpl muxPadding: persisted.muxPadding, muxMaxStreams: persisted.muxMaxStreams, muxProtocol: persisted.muxProtocol, + enableWarp: persisted.enableWarp, + warpDetourMode: persisted.warpDetourMode, + warpLicenseKey: persisted.warpLicenseKey, + warpCleanIp: persisted.warpCleanIp, + warpPort: persisted.warpPort, + warpNoise: persisted.warpNoise, geoipPath: geoAssetPathResolver.relativePath( geoAssets.geoip.providerName, geoAssets.geoip.fileName, diff --git a/lib/features/config_option/model/config_option_entity.dart b/lib/features/config_option/model/config_option_entity.dart index 4412f07e..676f575a 100644 --- a/lib/features/config_option/model/config_option_entity.dart +++ b/lib/features/config_option/model/config_option_entity.dart @@ -57,6 +57,14 @@ class ConfigOptionEntity with _$ConfigOptionEntity { @Default(false) bool muxPadding, @Default(8) int muxMaxStreams, @Default(MuxProtocol.h2mux) MuxProtocol muxProtocol, + @Default(false) bool enableWarp, + @Default(WarpDetourMode.outbound) WarpDetourMode warpDetourMode, + @Default("") String warpLicenseKey, + @Default("auto") String warpCleanIp, + @Default(0) int warpPort, + @RangeWithOptionalCeilJsonConverter() + @Default(RangeWithOptionalCeil()) + RangeWithOptionalCeil warpNoise, }) = _ConfigOptionEntity; static ConfigOptionEntity initial = ConfigOptionEntity( @@ -67,7 +75,11 @@ class ConfigOptionEntity with _$ConfigOptionEntity { if (PlatformUtils.isDesktop && serviceMode == ServiceMode.tun) { return true; } - if (enableTlsFragment || enableTlsMixedSniCase || enableTlsPadding||enableMux) { + if (enableTlsFragment || + enableTlsMixedSniCase || + enableTlsPadding || + enableMux || + enableWarp) { return true; } @@ -117,6 +129,12 @@ class ConfigOptionEntity with _$ConfigOptionEntity { muxPadding: patch.muxPadding ?? muxPadding, muxMaxStreams: patch.muxMaxStreams ?? muxMaxStreams, muxProtocol: patch.muxProtocol ?? muxProtocol, + enableWarp: patch.enableWarp ?? enableWarp, + warpDetourMode: patch.warpDetourMode ?? warpDetourMode, + warpLicenseKey: patch.warpLicenseKey ?? warpLicenseKey, + warpCleanIp: patch.warpCleanIp ?? warpCleanIp, + warpPort: patch.warpPort ?? warpPort, + warpNoise: patch.warpNoise ?? warpNoise, ); } diff --git a/lib/features/config_option/model/config_option_patch.dart b/lib/features/config_option/model/config_option_patch.dart index 501117a4..b9558a3f 100644 --- a/lib/features/config_option/model/config_option_patch.dart +++ b/lib/features/config_option/model/config_option_patch.dart @@ -47,6 +47,12 @@ class ConfigOptionPatch with _$ConfigOptionPatch { bool? muxPadding, int? muxMaxStreams, MuxProtocol? muxProtocol, + bool? enableWarp, + WarpDetourMode? warpDetourMode, + String? warpLicenseKey, + String? warpCleanIp, + int? warpPort, + @RangeWithOptionalCeilJsonConverter() RangeWithOptionalCeil? warpNoise, }) = _ConfigOptionPatch; factory ConfigOptionPatch.fromJson(Map json) => diff --git a/lib/features/config_option/notifier/warp_option_notifier.dart b/lib/features/config_option/notifier/warp_option_notifier.dart new file mode 100644 index 00000000..44e21953 --- /dev/null +++ b/lib/features/config_option/notifier/warp_option_notifier.dart @@ -0,0 +1,26 @@ +import 'package:hiddify/core/preferences/preferences_provider.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'warp_option_notifier.g.dart'; + +@Riverpod(keepAlive: true) +class WarpOptionNotifier extends _$WarpOptionNotifier { + @override + bool build() { + return ref + .read(sharedPreferencesProvider) + .requireValue + .getBool(warpConsentGiven) ?? + false; + } + + Future agree() async { + await ref + .read(sharedPreferencesProvider) + .requireValue + .setBool(warpConsentGiven, true); + state = true; + } + + static const warpConsentGiven = "warp_consent_given"; +} diff --git a/lib/features/config_option/overview/config_options_page.dart b/lib/features/config_option/overview/config_options_page.dart index ad8bb52a..c2df00cd 100644 --- a/lib/features/config_option/overview/config_options_page.dart +++ b/lib/features/config_option/overview/config_options_page.dart @@ -9,6 +9,7 @@ import 'package:hiddify/core/widget/tip_card.dart'; import 'package:hiddify/features/config_option/model/config_option_entity.dart'; import 'package:hiddify/features/config_option/model/config_option_patch.dart'; import 'package:hiddify/features/config_option/notifier/config_option_notifier.dart'; +import 'package:hiddify/features/config_option/overview/warp_options_widgets.dart'; import 'package:hiddify/features/log/model/log_level.dart'; import 'package:hiddify/features/settings/widgets/sections_widgets.dart'; import 'package:hiddify/features/settings/widgets/settings_input_dialog.dart'; @@ -319,7 +320,7 @@ class ConfigOptionsPage extends HookConsumerWidget { ), ListTile( title: Text(t.settings.config.tlsFragmentSize), - subtitle: Text(options.tlsFragmentSize.format()), + subtitle: Text(options.tlsFragmentSize.present(t)), onTap: () async { final range = await SettingsInputDialog( title: t.settings.config.tlsFragmentSize, @@ -336,7 +337,7 @@ class ConfigOptionsPage extends HookConsumerWidget { ), ListTile( title: Text(t.settings.config.tlsFragmentSleep), - subtitle: Text(options.tlsFragmentSleep.format()), + subtitle: Text(options.tlsFragmentSleep.present(t)), onTap: () async { final range = await SettingsInputDialog( title: t.settings.config.tlsFragmentSleep, @@ -368,7 +369,7 @@ class ConfigOptionsPage extends HookConsumerWidget { ), ListTile( title: Text(t.settings.config.tlsPaddingSize), - subtitle: Text(options.tlsPaddingSize.format()), + subtitle: Text(options.tlsPaddingSize.present(t)), onTap: () async { final range = await SettingsInputDialog( title: t.settings.config.tlsPaddingSize, @@ -384,6 +385,13 @@ class ConfigOptionsPage extends HookConsumerWidget { }, ), const SettingsDivider(), + SettingsSection(experimental(t.settings.config.section.warp)), + WarpOptionsTiles( + options: options, + defaultOptions: defaultOptions, + onChange: changeOption, + ), + const SettingsDivider(), SettingsSection(t.settings.config.section.misc), ListTile( title: Text(t.settings.config.connectionTestUrl), diff --git a/lib/features/config_option/overview/warp_options_widgets.dart b/lib/features/config_option/overview/warp_options_widgets.dart new file mode 100644 index 00000000..a5b798a4 --- /dev/null +++ b/lib/features/config_option/overview/warp_options_widgets.dart @@ -0,0 +1,199 @@ +import 'package:dartx/dartx.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:hiddify/core/localization/translations.dart'; +import 'package:hiddify/core/model/constants.dart'; +import 'package:hiddify/core/model/range.dart'; +import 'package:hiddify/features/config_option/model/config_option_entity.dart'; +import 'package:hiddify/features/config_option/model/config_option_patch.dart'; +import 'package:hiddify/features/config_option/notifier/warp_option_notifier.dart'; +import 'package:hiddify/features/settings/widgets/settings_input_dialog.dart'; +import 'package:hiddify/singbox/model/singbox_config_enum.dart'; +import 'package:hiddify/utils/uri_utils.dart'; +import 'package:hiddify/utils/validators.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; + +class WarpOptionsTiles extends HookConsumerWidget { + const WarpOptionsTiles({ + required this.options, + required this.defaultOptions, + required this.onChange, + super.key, + }); + + final ConfigOptionEntity options; + final ConfigOptionEntity defaultOptions; + final Future Function(ConfigOptionPatch patch) onChange; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final t = ref.watch(translationsProvider); + + final warpPrefaceCompleted = ref.watch(warpOptionNotifierProvider); + final canChangeOptions = warpPrefaceCompleted && options.enableWarp; + + return Column( + children: [ + SwitchListTile.adaptive( + title: Text(t.settings.config.enableWarp), + value: options.enableWarp, + onChanged: (value) async { + if (!warpPrefaceCompleted) { + final agreed = await showAdaptiveDialog( + context: context, + builder: (context) => const WarpLicenseAgreementModal(), + ); + if (agreed ?? false) { + await ref.read(warpOptionNotifierProvider.notifier).agree(); + await onChange(ConfigOptionPatch(enableWarp: value)); + } + } else { + await onChange(ConfigOptionPatch(enableWarp: value)); + } + }, + ), + ListTile( + title: Text(t.settings.config.warpDetourMode), + subtitle: Text(options.warpDetourMode.present(t)), + enabled: canChangeOptions, + onTap: () async { + final warpDetourMode = await SettingsPickerDialog( + title: t.settings.config.warpDetourMode, + selected: options.warpDetourMode, + options: WarpDetourMode.values, + getTitle: (e) => e.present(t), + resetValue: defaultOptions.warpDetourMode, + ).show(context); + if (warpDetourMode == null) return; + await onChange( + ConfigOptionPatch(warpDetourMode: warpDetourMode), + ); + }, + ), + ListTile( + title: Text(t.settings.config.warpLicenseKey), + subtitle: Text( + options.warpLicenseKey.isEmpty + ? t.general.notSet + : options.warpLicenseKey, + ), + enabled: canChangeOptions, + onTap: () async { + final licenseKey = await SettingsInputDialog( + title: t.settings.config.warpLicenseKey, + initialValue: options.warpLicenseKey, + resetValue: defaultOptions.warpLicenseKey, + ).show(context); + if (licenseKey == null) return; + await onChange(ConfigOptionPatch(warpLicenseKey: licenseKey)); + }, + ), + ListTile( + title: Text(t.settings.config.warpCleanIp), + subtitle: Text(options.warpCleanIp), + enabled: canChangeOptions, + onTap: () async { + final warpCleanIp = await SettingsInputDialog( + title: t.settings.config.warpCleanIp, + initialValue: options.warpCleanIp, + resetValue: defaultOptions.warpCleanIp, + ).show(context); + if (warpCleanIp == null || warpCleanIp.isBlank) return; + await onChange(ConfigOptionPatch(warpCleanIp: warpCleanIp)); + }, + ), + ListTile( + title: Text(t.settings.config.warpPort), + subtitle: Text(options.warpPort.toString()), + enabled: canChangeOptions, + onTap: () async { + final warpPort = await SettingsInputDialog( + title: t.settings.config.warpPort, + initialValue: options.warpPort, + resetValue: defaultOptions.warpPort, + validator: isPort, + mapTo: int.tryParse, + digitsOnly: true, + ).show(context); + if (warpPort == null) return; + await onChange( + ConfigOptionPatch(warpPort: warpPort), + ); + }, + ), + ListTile( + title: Text(t.settings.config.warpNoise), + subtitle: Text(options.warpNoise.present(t)), + enabled: canChangeOptions, + onTap: () async { + final warpNoise = await SettingsInputDialog( + title: t.settings.config.warpNoise, + initialValue: options.warpNoise.format(), + resetValue: defaultOptions.warpNoise.format(), + ).show(context); + if (warpNoise == null) return; + await onChange( + ConfigOptionPatch( + warpNoise: RangeWithOptionalCeil.tryParse( + warpNoise, + allowEmpty: true, + ), + ), + ); + }, + ), + ], + ); + } +} + +class WarpLicenseAgreementModal extends HookConsumerWidget { + const WarpLicenseAgreementModal({super.key}); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final t = ref.watch(translationsProvider); + + return AlertDialog.adaptive( + title: Text(t.settings.config.warpConsent.title), + content: Text.rich( + t.settings.config.warpConsent.description( + tos: (text) => TextSpan( + text: text, + style: const TextStyle(color: Colors.blue), + recognizer: TapGestureRecognizer() + ..onTap = () async { + await UriUtils.tryLaunch( + Uri.parse(Constants.cfWarpTermsOfService), + ); + }, + ), + privacy: (text) => TextSpan( + text: text, + style: const TextStyle(color: Colors.blue), + recognizer: TapGestureRecognizer() + ..onTap = () async { + await UriUtils.tryLaunch( + Uri.parse(Constants.cfWarpPrivacyPolicy), + ); + }, + ), + ), + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(false); + }, + child: Text(t.general.decline), + ), + TextButton( + onPressed: () { + Navigator.of(context).pop(true); + }, + child: Text(t.general.agree), + ), + ], + ); + } +} diff --git a/lib/features/connection/data/connection_platform_source.dart b/lib/features/connection/data/connection_platform_source.dart index 65e29914..3fc5dd67 100644 --- a/lib/features/connection/data/connection_platform_source.dart +++ b/lib/features/connection/data/connection_platform_source.dart @@ -170,11 +170,11 @@ class ConnectionPlatformSourceImpl fullPath = "libcore"; } if (Platform.isWindows) { - fullPath = p.join(fullPath, "hiddify-service.exe"); + fullPath = p.join(fullPath, "HiddifyService.exe"); } else if (Platform.isMacOS) { - fullPath = p.join(fullPath, "hiddify-service"); + fullPath = p.join(fullPath, "HiddifyService"); } else { - fullPath = p.join(fullPath, "hiddify-service"); + fullPath = p.join(fullPath, "HiddifyService"); } return "$binFolder/$fullPath"; diff --git a/lib/singbox/model/singbox_config_enum.dart b/lib/singbox/model/singbox_config_enum.dart index 5c1a966e..30aaac78 100644 --- a/lib/singbox/model/singbox_config_enum.dart +++ b/lib/singbox/model/singbox_config_enum.dart @@ -78,3 +78,13 @@ enum MuxProtocol { smux, yamux; } + +enum WarpDetourMode { + outbound, + inbound; + + String present(TranslationsEn t) => switch (this) { + outbound => t.settings.config.warpDetourModes.outbound, + inbound => t.settings.config.warpDetourModes.inbound, + }; +} diff --git a/lib/singbox/model/singbox_config_option.dart b/lib/singbox/model/singbox_config_option.dart index 3a0c66fc..5cbf4614 100644 --- a/lib/singbox/model/singbox_config_option.dart +++ b/lib/singbox/model/singbox_config_option.dart @@ -52,6 +52,13 @@ class SingboxConfigOption with _$SingboxConfigOption { required bool muxPadding, required int muxMaxStreams, required MuxProtocol muxProtocol, + required bool enableWarp, + required WarpDetourMode warpDetourMode, + required String warpLicenseKey, + required String warpCleanIp, + required int warpPort, + @RangeWithOptionalCeilJsonConverter() + required RangeWithOptionalCeil warpNoise, required String geoipPath, required String geositePath, required List rules, diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 398f3343..ba38a4ab 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -120,8 +120,11 @@ install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" install(FILES "../libcore/bin/libcore.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) -install(FILES "../libcore/bin/hiddify-service" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) +install( + FILES "../libcore/bin/HiddifyService" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime +) foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 1a1e60df..7bca9452 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -87,9 +87,9 @@ set(HIDDIFY_NEXT_LIB "../libcore/bin/libcore.dll") install(FILES "${HIDDIFY_NEXT_LIB}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime RENAME libcore.dll) -set(HIDDIFY_NEXT_LIB "../libcore/bin/hiddify-service.exe") +set(HIDDIFY_NEXT_LIB "../libcore/bin/HiddifyService.exe") install(FILES "${HIDDIFY_NEXT_LIB}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" -COMPONENT Runtime RENAME hiddify-service.exe) +COMPONENT Runtime RENAME HiddifyService.exe) if(PLUGIN_BUNDLED_LIBRARIES) diff --git a/windows/packaging/exe/make_config.yaml b/windows/packaging/exe/make_config.yaml index 1cb07acb..78f61e98 100644 --- a/windows/packaging/exe/make_config.yaml +++ b/windows/packaging/exe/make_config.yaml @@ -2,9 +2,16 @@ app_id: 6L903538-42B1-4596-G479-BJ779F21A65D publisher: Hiddify publisher_url: https://github.com/hiddify/hiddify-next display_name: Hiddify Next +executable_name: HiddifyNext.exe +output_base_file_name: HiddifyNext.exe create_desktop_icon: true install_dir_name: "{autopf64}\\hiddify" setup_icon_file: ..\..\windows\runner\resources\app_icon.ico locales: - en - - fa \ No newline at end of file + - fa + - zh + - ru + - pt + - tr +#script_template: inno_setup.sas \ No newline at end of file