├── .github ├── ISSUE_TEMPLATE │ ├── 01_bug_report.yml │ └── 02_feature_request.yml └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── LICENSE ├── README.md └── v2rayN ├── .gitattributes ├── .gitignore ├── HiddifyRestartN ├── HiddifyRestartN.csproj ├── Program.cs └── Properties │ └── launchSettings.json ├── HiddifyUpgradeN ├── HiddifyUpgradeN.csproj ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Program.cs ├── Properties │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings └── app.manifest ├── PacLib ├── PacHandler.cs ├── PacLib.csproj ├── Resources.Designer.cs ├── Resources.resx └── Resources │ └── pac.txt ├── ProtosLib ├── ProtosLib.csproj ├── Statistics.proto └── Tests.cs ├── v2rayN.ico ├── v2rayN.sln └── v2rayN ├── App.xaml ├── App.xaml.cs ├── AssemblyInfo.cs ├── Base ├── DownloaderHelper.cs ├── HttpClientHelper.cs ├── MyDGTextColumn.cs ├── SqliteHelper.cs └── StringEx.cs ├── Converters ├── DelayColorConverter.cs ├── LocalizeConverter.cs ├── MaterialDesignFonts.cs └── SizeConverter.cs ├── FodyWeavers.xml ├── Global.cs ├── Handler ├── ConfigHandler.cs ├── CoreConfigHandler.cs ├── CoreConfigSingbox.cs ├── CoreConfigV2ray.cs ├── CoreHandler.cs ├── DownloadHandle.cs ├── HotkeyHandler.cs ├── LazyConfig.cs ├── MainFormHandler.cs ├── NoticeHandler.cs ├── ProfileExHandler.cs ├── ProxySetting.cs ├── QRCodeHelper.cs ├── ShareHandler.cs ├── SpeedtestHandler.cs ├── StatisticsHandler.cs ├── SysProxyHandle.cs ├── TunHandler.cs └── UpdateHandle.cs ├── Mode ├── BalancerItem.cs ├── ComboItem.cs ├── Config.cs ├── ConfigItems.cs ├── ConfigOld.cs ├── CoreInfo.cs ├── DNSItem.cs ├── EConfigType.cs ├── ECoreType.cs ├── EGlobalHotkey.cs ├── EMove.cs ├── EServerColName.cs ├── ESpeedActionType.cs ├── ESysProxyType.cs ├── EViewAction.cs ├── GitHubRelease.cs ├── HiddifyEnums.cs ├── ProfileExItem.cs ├── ProfileItem.cs ├── ProfileItemModel.cs ├── ProxyMode.cs ├── RoutingItem.cs ├── RoutingItemModel.cs ├── RulesItem.cs ├── RulesItemModel.cs ├── ServerSpeedItem.cs ├── ServerStatItem.cs ├── ServerTestItem.cs ├── SingboxConfig.cs ├── SsSIP008.cs ├── SubItem.cs ├── SubscriptionInfo.cs ├── SysproxyConfig.cs ├── V2rayConfig.cs ├── V2rayTcpRequest.cs └── VmessQRCode.cs ├── Properties ├── Resources.Designer.cs └── Resources.resx ├── Resources ├── NotifyIcon1.ico ├── NotifyIcon2.ico ├── NotifyIcon3.ico ├── RestartProgram.ico ├── sysproxy.exe.gz └── sysproxy64.exe.gz ├── Resx ├── Hiddify.Designer.cs ├── Hiddify.resx ├── ResUI.Designer.cs ├── ResUI.fa-Ir.resx ├── ResUI.resx ├── ResUI.ru.resx └── ResUI.zh-Hans.resx ├── Sample ├── SampleClientConfig ├── SampleHttprequest ├── SampleHttpresponse ├── SampleInbound ├── SingboxSampleClientConfig ├── custom_routing_black ├── custom_routing_global ├── custom_routing_locked ├── custom_routing_rules ├── custom_routing_white ├── dns_singbox_normal ├── dns_v2ray_normal ├── tun_singbox ├── tun_singbox_dns ├── tun_singbox_inbound └── tun_singbox_rules ├── Tool ├── DeepLinking.cs ├── FileManager.cs ├── Job.cs ├── Logging.cs ├── QueryableExtension.cs ├── TestSpeed.cs ├── UI.cs └── Utils.cs ├── ViewModels ├── AddServer2ViewModel.cs ├── AddServerViewModel.cs ├── AnotherCommandImplementation.cs ├── DNSSettingViewModel.cs ├── DemoItem.cs ├── HomeWindowViewModel.cs ├── MainWindowViewModel.cs ├── OptionSettingViewModel.cs ├── RoutingRuleDetailsViewModel.cs ├── RoutingRuleSettingViewModel.cs ├── RoutingSettingViewModel.cs ├── SubEditViewModel.cs ├── SubSettingViewModel.cs └── ViewModelBase.cs ├── Views ├── AddServer2Window.xaml ├── AddServer2Window.xaml.cs ├── AddServerWindow.xaml ├── AddServerWindow.xaml.cs ├── DNSSettingWindow.xaml ├── DNSSettingWindow.xaml.cs ├── GlobalHotkeySettingWindow.xaml ├── GlobalHotkeySettingWindow.xaml.cs ├── HiddifyUI.xaml ├── HiddifyUI.xaml.cs ├── MainSubInfoView.xaml ├── MainSubInfoView.xaml.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── MsgView.xaml ├── MsgView.xaml.cs ├── OptionSettingWindow.xaml ├── OptionSettingWindow.xaml.cs ├── QrcodeView.xaml ├── QrcodeView.xaml.cs ├── RoutingRuleDetailsWindow.xaml ├── RoutingRuleDetailsWindow.xaml.cs ├── RoutingRuleSettingWindow.xaml ├── RoutingRuleSettingWindow.xaml.cs ├── RoutingSettingWindow.xaml ├── RoutingSettingWindow.xaml.cs ├── SubEditWindow.xaml ├── SubEditWindow.xaml.cs ├── SubInfoView.xaml ├── SubInfoView.xaml.cs ├── SubSettingWindow.xaml ├── SubSettingWindow.xaml.cs └── v2rayN.ico ├── app.manifest ├── v2rayN.csproj └── v2rayN.ico /.github/ISSUE_TEMPLATE/01_bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug 报告 2 | description: 在提出问题前请先自行排除服务器端问题和升级到最新客户端,同时也请通过搜索确认是否有人提出过相同问题。 3 | title: "[Bug]: " 4 | labels: ["bug"] 5 | body: 6 | - type: input 7 | id: "expectation" 8 | attributes: 9 | label: "预期情况" 10 | description: "描述你认为应该发生什么" 11 | validations: 12 | required: true 13 | - type: textarea 14 | id: "describe-the-bug" 15 | attributes: 16 | label: "实际情况" 17 | description: "描述实际发生了什么" 18 | validations: 19 | required: true 20 | - type: textarea 21 | id: "reproduction-method" 22 | attributes: 23 | label: "复现方法" 24 | description: "在BUG出现前执行了哪些操作" 25 | placeholder: 标序号 26 | validations: 27 | required: true 28 | - type: textarea 29 | id: "log" 30 | attributes: 31 | label: "日志信息" 32 | description: "位置在软件当前目录下的guiLogs" 33 | placeholder: 在日志开始和结束位置粘贴冒号后的内容:``` 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: "more" 38 | attributes: 39 | label: "额外信息" 40 | description: "可选" 41 | validations: 42 | required: false 43 | - type: checkboxes 44 | id: "latest-version" 45 | attributes: 46 | label: "我确认已更新至最新版本" 47 | description: "否则请更新后尝试" 48 | options: 49 | - label: 是 50 | required: true 51 | - type: checkboxes 52 | id: "issues" 53 | attributes: 54 | label: "我确认已查询历史issues" 55 | description: "否则请查询后提出" 56 | options: 57 | - label: 是 58 | required: true 59 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/02_feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature 请求 2 | description: "为这个项目提出一个建议" 3 | title: "[Feature request]: " 4 | labels: ['enhancement'] 5 | body: 6 | - type: input 7 | id: problem 8 | attributes: 9 | label: 相关问题 10 | description: "清楚而简洁地描述问题是什么。" 11 | placeholder: "当我想要……时,软件不能……" 12 | validations: 13 | required: true 14 | - type: input 15 | id: way-to-solve 16 | attributes: 17 | label: 描述你希望的解决方案 18 | description: "你希望发生什么" 19 | validations: 20 | required: true 21 | - type: input 22 | id: instead 23 | attributes: 24 | label: 描述你所考虑的替代方案 25 | validations: 26 | required: false 27 | - type: checkboxes 28 | id: "issues" 29 | attributes: 30 | label: "我确认已查询历史issues" 31 | description: "否则请查询后提出" 32 | options: 33 | - label: 是 34 | required: true 35 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # This workflow will build, test, sign and package a WPF or Windows Forms desktop application 7 | # built on .NET Core. 8 | # To learn how to migrate your existing application to .NET Core, 9 | # refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework 10 | # 11 | # To configure this workflow: 12 | # 13 | # 1. Configure environment variables 14 | # GitHub sets default environment variables for every workflow run. 15 | # Replace the variables relative to your project in the "env" section below. 16 | # 17 | # 2. Signing 18 | # Generate a signing certificate in the Windows Application 19 | # Packaging Project or add an existing signing certificate to the project. 20 | # Next, use PowerShell to encode the .pfx file using Base64 encoding 21 | # by running the following Powershell script to generate the output string: 22 | # 23 | # $pfx_cert = Get-Content '.\SigningCertificate.pfx' -Encoding Byte 24 | # [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt' 25 | # 26 | # Open the output file, SigningCertificate_Encoded.txt, and copy the 27 | # string inside. Then, add the string to the repo as a GitHub secret 28 | # and name it "Base64_Encoded_Pfx." 29 | # For more information on how to configure your signing certificate for 30 | # this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing 31 | # 32 | # Finally, add the signing certificate password to the repo as a secret and name it "Pfx_Key". 33 | # See "Build the Windows Application Packaging project" below to see how the secret is used. 34 | # 35 | # For more information on GitHub Actions, refer to https://github.com/features/actions 36 | # For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications, 37 | # refer to https://github.com/microsoft/github-actions-for-desktop-apps 38 | 39 | name: .NET Core Desktop 40 | 41 | on: 42 | push: 43 | branches: [ "master" ] 44 | pull_request: 45 | branches: [ "master" ] 46 | 47 | jobs: 48 | 49 | build: 50 | 51 | strategy: 52 | matrix: 53 | include: 54 | - configuration: x64 55 | xray: Xray-windows-64.zip 56 | - configuration: x86 57 | xray: Xray-windows-32.zip 58 | 59 | 60 | runs-on: windows-latest # For a list of available runner types, refer to 61 | # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on 62 | 63 | steps: 64 | - name: Checkout 65 | uses: actions/checkout@v3 66 | with: 67 | fetch-depth: 0 68 | - name: Download xray 69 | run: | 70 | curl -L -o ${{ matrix.xray }} https://github.com/hiddify/Hiddify-Xray-core/releases/latest/download/${{ matrix.xray }} 71 | dir 72 | 73 | 74 | 75 | # Install the .NET Core workload 76 | - name: Install .NET Core 77 | uses: actions/setup-dotnet@v3 78 | with: 79 | dotnet-version: 6.0.x 80 | - name: Restore 81 | run: | 82 | dotnet restore 83 | working-directory: v2rayN 84 | 85 | 86 | - name: Build 87 | working-directory: v2rayN 88 | run: | 89 | dotnet build --configuration Release --no-restore 90 | 91 | - name: Publish win ${{ matrix.configuration }} 92 | working-directory: v2rayN 93 | run: | 94 | dotnet publish v2rayN\v2rayN.csproj --property WarningLevel=0 -c Release -o ../release/win-${{ matrix.configuration }} -r win-${{ matrix.configuration }} -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true /p:PublishSingleFileExecutable=HiddifyN.exe 95 | # dotnet publish --property WarningLevel=0 -c Release -o ../release/win-x64 -r win-x64 -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true 96 | - name: add xray 97 | run: | 98 | mkdir release\win-${{ matrix.configuration }}\bin\Xray 99 | dir 100 | 7z x "${{ matrix.xray }}" -i!"*.exe" 101 | move *xray.exe release\win-${{ matrix.configuration }}\bin\Xray\ 102 | 103 | # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact 104 | - name: Upload build win-${{ matrix.configuration }} 105 | uses: actions/upload-artifact@v3 106 | with: 107 | name: win-${{ matrix.configuration }} 108 | path: release/win-${{ matrix.configuration }} 109 | retention-days: 5 110 | 111 | 112 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | # Sequence of patterns matched against refs/tags 5 | tags: 6 | - "v*" 7 | 8 | jobs: 9 | 10 | build: 11 | 12 | strategy: 13 | matrix: 14 | include: 15 | - configuration: x64 16 | xray: Xray-windows-64.zip 17 | - configuration: x86 18 | xray: Xray-windows-32.zip 19 | 20 | 21 | runs-on: windows-latest # For a list of available runner types, refer to 22 | # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on 23 | 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v3 27 | with: 28 | fetch-depth: 0 29 | - name: Download xray 30 | run: | 31 | curl -L -o ${{ matrix.xray }} https://github.com/hiddify/Hiddify-Xray-core/releases/latest/download/${{ matrix.xray }} 32 | dir 33 | 34 | 35 | 36 | # Install the .NET Core workload 37 | - name: Install .NET Core 38 | uses: actions/setup-dotnet@v3 39 | with: 40 | dotnet-version: 6.0.x 41 | - name: Restore 42 | run: | 43 | dotnet restore 44 | working-directory: v2rayN 45 | 46 | 47 | - name: Build 48 | working-directory: v2rayN 49 | run: | 50 | dotnet build --configuration Release --no-restore 51 | 52 | - name: Publish win ${{ matrix.configuration }} 53 | working-directory: v2rayN 54 | run: | 55 | dotnet publish v2rayN\v2rayN.csproj --property WarningLevel=0 -c Release -o ../release/win-${{ matrix.configuration }} -r win-${{ matrix.configuration }} -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true /p:PublishSingleFileExecutable=HiddifyN.exe 56 | # dotnet publish --property WarningLevel=0 -c Release -o ../release/win-x64 -r win-x64 -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true 57 | - name: add xray 58 | run: | 59 | mkdir release\win-${{ matrix.configuration }}\bin\Xray 60 | dir 61 | 7z x "${{ matrix.xray }}" -i!"*.exe" 62 | move *xray.exe release\win-${{ matrix.configuration }}\bin\Xray\ 63 | 64 | # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact 65 | - name: Upload build win-${{ matrix.configuration }} 66 | uses: actions/upload-artifact@v3 67 | with: 68 | name: win-${{ matrix.configuration }} 69 | path: release/win-${{ matrix.configuration }} 70 | retention-days: 5 71 | publish: 72 | runs-on: ubuntu-latest 73 | steps: 74 | - uses: actions/checkout@v1 75 | - name: Load Release URL File from release job 76 | uses: actions/download-artifact@v1 77 | with: 78 | name: win-x64.zip 79 | - name: Load Release URL File from release job 80 | uses: actions/download-artifact@v1 81 | with: 82 | name: win-x86.zip 83 | - name: Upload Release 84 | uses: softprops/action-gh-release@v1 85 | with: 86 | # tag: ${{ github.ref_name }} 87 | tag_name: ${{ github.ref }} 88 | release_name: ${{ github.ref }} 89 | files: "*.zip" 90 | prerelease: false 91 | generate_release_notes: true 92 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 3 | ################################################################################ 4 | 5 | /vs 6 | /v2rayN/.vs/ 7 | /v2rayN/v2rayN/bin/Debug/app.publish 8 | /v2rayN/v2rayN/bin/Debug 9 | /v2rayN/v2rayN/bin/Release 10 | /v2rayN/v2rayN/obj/ 11 | /v2rayN/.vs/v2rayN/DesignTimeBuild 12 | /v2rayN/packages 13 | .vs/ProjectSettings.json 14 | .vs/slnx.sqlite 15 | .vs/VSWorkspaceState.json 16 | /v2rayN/v2rayUpgrade/bin/Debug 17 | /v2rayN/v2rayUpgrade/bin/Release 18 | /v2rayN/v2rayUpgrade/obj/ 19 | *.user 20 | /v2rayN/v2rayN/Properties/* 21 | /v2rayN/v2rayN/Properties/ 22 | /.vs/v2rayN -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HiddifyN 2 | A GUI client for Windows, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores) 3 | ![image](https://user-images.githubusercontent.com/114227601/236046684-35a41cbc-9b4f-4dbf-8592-ef0436fbb5b0.png) 4 | 5 | 6 | [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/v2rayN)](https://github.com/2dust/v2rayN/commits/master) 7 | [![CodeFactor](https://www.codefactor.io/repository/github/2dust/v2rayn/badge)](https://www.codefactor.io/repository/github/2dust/v2rayn) 8 | [![GitHub Releases](https://img.shields.io/github/downloads/2dust/v2rayN/latest/total?logo=github)](https://github.com/2dust/v2rayN/releases) 9 | [![Chat on Telegram](https://img.shields.io/badge/Chat%20on-Telegram-brightgreen.svg)](https://t.me/v2rayn) 10 | 11 | ### How to use 12 | - If you are new to this, please download v2rayN-Core.zip from [releases](https://github.com/2dust/v2rayN/releases) 13 | - Otherwise please download v2rayN.zip (you will also need to download v2ray core into the same folder with HiddifyN.exe) 14 | - Run HiddifyN.exe 15 | 16 | ## Requirements 17 | - [Microsoft .NET 6.0 Desktop Runtime ](https://download.visualstudio.microsoft.com/download/pr/513d13b7-b456-45af-828b-b7b7981ff462/edf44a743b78f8b54a2cec97ce888346/windowsdesktop-runtime-6.0.15-win-x64.exe) 18 | - [Supported cores](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores) 19 | 20 | ### Telegram 21 | - Channel: [Hiddify](https://t.me/hiddify) 22 | - Group: [Hiddify Discussion](https://t.me/hiddify_board) 23 | -------------------------------------------------------------------------------- /v2rayN/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /v2rayN/HiddifyRestartN/HiddifyRestartN.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /v2rayN/HiddifyRestartN/Program.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | 3 | // This program is jsut for restarting main program 4 | try 5 | { 6 | // Killing 7 | 8 | // Get running main program process id 9 | int mainProgramProcessID = int.Parse(Environment.GetCommandLineArgs()[1]); 10 | // Get process 11 | //var mainProcess = Process.GetProcessById(mainProgramProcessID); 12 | // Kill process 13 | //mainProcess.Kill(); 14 | 15 | // Running 16 | 17 | // Main program exe path 18 | string mainProgramPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "HiddifyN.exe")); 19 | // Command to run program 20 | string cmd = $"{mainProgramPath}"; 21 | 22 | // Run again 23 | Process.Start(cmd); 24 | } 25 | catch (Exception err) 26 | { 27 | Console.Error.WriteLine(err); 28 | } -------------------------------------------------------------------------------- /v2rayN/HiddifyRestartN/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "HiddifyRestartN": { 4 | "commandName": "Project", 5 | "commandLineArgs": "2342 --admin", 6 | "workingDirectory": "C:\\Users\\me\\Desktop\\HiddifyDesktopN\\v2rayN\\v2rayN\\bin\\Debug\\net6.0-windows" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/HiddifyUpgradeN.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0-windows 4 | WinExe 5 | true 6 | Copyright © 2019-2023 (GPLv3) 7 | 1.1.0.0 8 | app.manifest 9 | enable 10 | HiddifyUpgradeN 11 | 12 | -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayUpgrade 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// 必需的设计器变量。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 清理所有正在使用的资源。 12 | /// 13 | /// 如果应释放托管资源,为 true;否则为 false。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows 窗体设计器生成的代码 24 | 25 | /// 26 | /// 设计器支持所需的方法 - 不要修改 27 | /// 使用代码编辑器修改此方法的内容。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.btnClose = new System.Windows.Forms.Button(); 32 | this.btnOK = new System.Windows.Forms.Button(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.SuspendLayout(); 36 | // 37 | // btnClose 38 | // 39 | this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; 40 | this.btnClose.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); 41 | this.btnClose.ImeMode = System.Windows.Forms.ImeMode.NoControl; 42 | this.btnClose.Location = new System.Drawing.Point(367, 118); 43 | this.btnClose.Name = "btnClose"; 44 | this.btnClose.Size = new System.Drawing.Size(184, 89); 45 | this.btnClose.TabIndex = 1; 46 | this.btnClose.Text = "&Exit(退出)"; 47 | this.btnClose.UseVisualStyleBackColor = true; 48 | this.btnClose.Click += new System.EventHandler(this.btnClose_Click); 49 | // 50 | // btnOK 51 | // 52 | this.btnOK.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); 53 | this.btnOK.ImeMode = System.Windows.Forms.ImeMode.NoControl; 54 | this.btnOK.Location = new System.Drawing.Point(81, 118); 55 | this.btnOK.Name = "btnOK"; 56 | this.btnOK.Size = new System.Drawing.Size(184, 89); 57 | this.btnOK.TabIndex = 0; 58 | this.btnOK.Text = "&Upgrade(升级)"; 59 | this.btnOK.UseVisualStyleBackColor = true; 60 | this.btnOK.Click += new System.EventHandler(this.btnOK_Click); 61 | // 62 | // label1 63 | // 64 | this.label1.AutoSize = true; 65 | this.label1.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); 66 | this.label1.Location = new System.Drawing.Point(79, 64); 67 | this.label1.Name = "label1"; 68 | this.label1.Size = new System.Drawing.Size(205, 15); 69 | this.label1.TabIndex = 8; 70 | this.label1.Text = "升级成功后将自动重启v2rayN"; 71 | // 72 | // label2 73 | // 74 | this.label2.AutoSize = true; 75 | this.label2.Font = new System.Drawing.Font("微软雅黑", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134))); 76 | this.label2.Location = new System.Drawing.Point(79, 37); 77 | this.label2.Name = "label2"; 78 | this.label2.Size = new System.Drawing.Size(471, 15); 79 | this.label2.TabIndex = 9; 80 | this.label2.Text = "v2rayN will restart automatically after successful upgrade"; 81 | // 82 | // MainForm 83 | // 84 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 85 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 86 | this.ClientSize = new System.Drawing.Size(616, 284); 87 | this.Controls.Add(this.label2); 88 | this.Controls.Add(this.label1); 89 | this.Controls.Add(this.btnClose); 90 | this.Controls.Add(this.btnOK); 91 | this.Name = "MainForm"; 92 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 93 | this.Text = "v2rayUpgrade"; 94 | this.ResumeLayout(false); 95 | this.PerformLayout(); 96 | 97 | } 98 | 99 | #endregion 100 | 101 | private System.Windows.Forms.Button btnClose; 102 | private System.Windows.Forms.Button btnOK; 103 | private System.Windows.Forms.Label label1; 104 | private System.Windows.Forms.Label label2; 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.IO.Compression; 5 | using System.Text; 6 | using System.Web; 7 | using System.Windows.Forms; 8 | 9 | namespace v2rayUpgrade 10 | { 11 | public partial class MainForm : Form 12 | { 13 | private readonly string defaultFilename = "v2ray-windows.zip"; 14 | private string? fileName; 15 | 16 | public MainForm(string[] args) 17 | { 18 | InitializeComponent(); 19 | if (args.Length > 0) 20 | { 21 | fileName = HttpUtility.UrlDecode(string.Join(" ", args)); 22 | } 23 | else 24 | { 25 | fileName = defaultFilename; 26 | } 27 | } 28 | 29 | private void ShowWarn(string message) 30 | { 31 | MessageBox.Show(message, "", MessageBoxButtons.OK, MessageBoxIcon.Warning); 32 | } 33 | 34 | private void btnOK_Click(object sender, EventArgs e) 35 | { 36 | try 37 | { 38 | Process[] existing = Process.GetProcessesByName("HiddifyN"); 39 | foreach (Process p in existing) 40 | { 41 | string? path = p.MainModule?.FileName; 42 | if (path == GetPath("HiddifyN.exe")) 43 | { 44 | p.Kill(); 45 | p.WaitForExit(100); 46 | } 47 | } 48 | } 49 | catch (Exception ex) 50 | { 51 | // Access may be denied without admin right. The user may not be an administrator. 52 | ShowWarn("Failed to close v2rayN(关闭v2rayN失败).\n" + 53 | "Close it manually, or the upgrade may fail.(请手动关闭正在运行的v2rayN,否则可能升级失败。\n\n" + ex.StackTrace); 54 | } 55 | 56 | if (!File.Exists(fileName)) 57 | { 58 | if (File.Exists(defaultFilename)) 59 | { 60 | fileName = defaultFilename; 61 | } 62 | else 63 | { 64 | ShowWarn("Upgrade Failed, File Not Exist(升级失败,文件不存在)."); 65 | return; 66 | } 67 | } 68 | 69 | StringBuilder sb = new(); 70 | try 71 | { 72 | string thisAppOldFile = $"{Application.ExecutablePath}.tmp"; 73 | File.Delete(thisAppOldFile); 74 | string startKey = "v2rayN/"; 75 | 76 | using ZipArchive archive = ZipFile.OpenRead(fileName); 77 | foreach (ZipArchiveEntry entry in archive.Entries) 78 | { 79 | try 80 | { 81 | if (entry.Length == 0) 82 | { 83 | continue; 84 | } 85 | string fullName = entry.FullName; 86 | if (fullName.StartsWith(startKey)) 87 | { 88 | fullName = fullName[startKey.Length..]; 89 | } 90 | if (string.Equals(Application.ExecutablePath, GetPath(fullName), StringComparison.OrdinalIgnoreCase)) 91 | { 92 | File.Move(Application.ExecutablePath, thisAppOldFile); 93 | } 94 | 95 | string entryOuputPath = GetPath(fullName); 96 | Directory.CreateDirectory(Path.GetDirectoryName(entryOuputPath)!); 97 | entry.ExtractToFile(entryOuputPath, true); 98 | } 99 | catch (Exception ex) 100 | { 101 | sb.Append(ex.StackTrace); 102 | } 103 | } 104 | } 105 | catch (Exception ex) 106 | { 107 | ShowWarn("Upgrade Failed(升级失败)." + ex.StackTrace); 108 | return; 109 | } 110 | if (sb.Length > 0) 111 | { 112 | ShowWarn("Upgrade Failed,Hold ctrl + c to copy to clipboard.\n" + 113 | "(升级失败,按住ctrl+c可以复制到剪贴板)." + sb.ToString()); 114 | return; 115 | } 116 | 117 | Process.Start("HiddifyN.exe"); 118 | MessageBox.Show("Upgrade successed(升级成功)", "", MessageBoxButtons.OK, MessageBoxIcon.Information); 119 | 120 | Close(); 121 | } 122 | 123 | private void btnClose_Click(object sender, EventArgs e) 124 | { 125 | Close(); 126 | } 127 | 128 | public static string GetExePath() 129 | { 130 | return Application.ExecutablePath; 131 | } 132 | 133 | public static string StartupPath() 134 | { 135 | return Application.StartupPath; 136 | } 137 | 138 | public static string GetPath(string fileName) 139 | { 140 | string startupPath = StartupPath(); 141 | if (string.IsNullOrEmpty(fileName)) 142 | { 143 | return startupPath; 144 | } 145 | return Path.Combine(startupPath, fileName); 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace v2rayUpgrade 5 | { 6 | internal static class Program 7 | { 8 | /// 9 | /// 应用程序的主入口点。 10 | /// 11 | [STAThread] 12 | private static void Main(string[] args) 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetHighDpiMode(HighDpiMode.SystemAware); 16 | Application.SetCompatibleTextRenderingDefault(false); 17 | Application.Run(new MainForm(args)); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace v2rayUpgrade.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("v2rayUpgrade.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性 51 | /// 重写当前线程的 CurrentUICulture 属性。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace v2rayUpgrade.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.3.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /v2rayN/HiddifyUpgradeN/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | true 6 | PerMonitorV2 7 | 8 | 9 | -------------------------------------------------------------------------------- /v2rayN/PacLib/PacHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Net.Sockets; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace PacLib; 9 | 10 | public class PacHandler 11 | { 12 | private static string _configPath; 13 | private static int _httpPort; 14 | private static int _pacPort; 15 | private static TcpListener? _tcpListener; 16 | private static string _pacText; 17 | private static bool _isRunning; 18 | private static bool _needRestart = true; 19 | 20 | public static void Start(string configPath, int httpPort, int pacPort) 21 | { 22 | _needRestart = (configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning); 23 | 24 | _configPath = configPath; 25 | _httpPort = httpPort; 26 | _pacPort = pacPort; 27 | 28 | InitText(); 29 | 30 | if (_needRestart) 31 | { 32 | Stop(); 33 | RunListener(); 34 | } 35 | } 36 | 37 | private static void InitText() 38 | { 39 | var path = Path.Combine(_configPath, "pac.txt"); 40 | if (!File.Exists(path)) 41 | { 42 | File.AppendAllText(path, Resources.ResourceManager.GetString("pac")); 43 | } 44 | 45 | _pacText = File.ReadAllText(path).Replace("__PROXY__", $"PROXY 127.0.0.1:{_httpPort};DIRECT;"); 46 | } 47 | 48 | private static void RunListener() 49 | { 50 | _tcpListener = TcpListener.Create(_pacPort); 51 | _isRunning = true; 52 | _tcpListener.Start(); 53 | Task.Factory.StartNew(() => 54 | { 55 | while (_isRunning) 56 | { 57 | try 58 | { 59 | if (!_tcpListener.Pending()) 60 | { 61 | Thread.Sleep(10); 62 | continue; 63 | } 64 | 65 | var client = _tcpListener.AcceptTcpClient(); 66 | Task.Run(() => 67 | { 68 | var stream = client.GetStream(); 69 | var sb = new StringBuilder(); 70 | sb.AppendLine("HTTP/1.0 200 OK"); 71 | sb.AppendLine("Content-type:application/x-ns-proxy-autoconfig"); 72 | sb.AppendLine("Connection:close"); 73 | sb.AppendLine("Content-Length:" + Encoding.UTF8.GetByteCount(_pacText)); 74 | sb.AppendLine(); 75 | sb.Append(_pacText); 76 | var content = Encoding.UTF8.GetBytes(sb.ToString()); 77 | stream.Write(content, 0, content.Length); 78 | stream.Flush(); 79 | }); 80 | } 81 | catch (Exception e) 82 | { 83 | } 84 | } 85 | }, TaskCreationOptions.LongRunning); 86 | } 87 | 88 | public static void Stop() 89 | { 90 | if (_tcpListener != null) 91 | { 92 | try 93 | { 94 | _isRunning = false; 95 | _tcpListener.Stop(); 96 | _tcpListener = null; 97 | } 98 | catch (Exception e) 99 | { 100 | } 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /v2rayN/PacLib/PacLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net6.0-windows 5 | enable 6 | 7 | 8 | 9 | 10 | True 11 | True 12 | Resources.resx 13 | 14 | 15 | ResXFileCodeGenerator 16 | Resources.Designer.cs 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /v2rayN/PacLib/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // 此代码由工具生成。 4 | // 运行时版本:4.0.30319.42000 5 | // 6 | // 对此文件的更改可能会导致不正确的行为,并且如果 7 | // 重新生成代码,这些更改将会丢失。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace PacLib { 12 | using System; 13 | 14 | 15 | /// 16 | /// 一个强类型的资源类,用于查找本地化的字符串等。 17 | /// 18 | // 此类是由 StronglyTypedResourceBuilder 19 | // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 20 | // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen 21 | // (以 /str 作为命令选项),或重新生成 VS 项目。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// 返回此类使用的缓存的 ResourceManager 实例。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PacLib.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 重写当前线程的 CurrentUICulture 属性,对 51 | /// 使用此强类型资源类的所有资源查找执行重写。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// 查找类似 var proxy = '__PROXY__'; 65 | ///var rules = [ 66 | /// [ 67 | /// [], 68 | /// [] 69 | /// ], 70 | /// [ 71 | /// [ 72 | /// "aftygh.gov.tw", 73 | /// "aide.gov.tw", 74 | /// "aliyun.com", 75 | /// "arte.gov.tw", 76 | /// "baidu.com", 77 | /// "chinaso.com", 78 | /// "chinaz.com", 79 | /// "chukuang.gov.tw", 80 | /// "cycab.gov.tw", 81 | /// "dbnsa.gov.tw", 82 | /// "df.gov.tw", 83 | /// "eastcoast-nsa.gov.tw", 84 | /// "erv-nsa.gov.tw", 85 | /// "grb.gov.tw", 86 | /// "haosou.com", 87 | /// [字符串的其余部分被截断]"; 的本地化字符串。 88 | /// 89 | internal static string pac { 90 | get { 91 | return ResourceManager.GetString("pac", resourceCulture); 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /v2rayN/ProtosLib/ProtosLib.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0-windows 4 | enable 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /v2rayN/ProtosLib/Statistics.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package v2ray.core.app.stats.command; 4 | option csharp_namespace = "ProtosLib.Statistics"; 5 | 6 | message GetStatsRequest { 7 | // Name of the stat counter. 8 | string name = 1; 9 | // Whether or not to reset the counter to fetching its value. 10 | bool reset = 2; 11 | } 12 | 13 | message Stat { 14 | string name = 1; 15 | int64 value = 2; 16 | } 17 | 18 | message GetStatsResponse { 19 | Stat stat = 1; 20 | } 21 | 22 | message QueryStatsRequest { 23 | string pattern = 1; 24 | bool reset = 2; 25 | } 26 | 27 | message QueryStatsResponse { 28 | repeated Stat stat = 1; 29 | } 30 | 31 | message SysStatsRequest { 32 | } 33 | 34 | message SysStatsResponse { 35 | uint32 NumGoroutine = 1; 36 | uint32 NumGC = 2; 37 | uint64 Alloc = 3; 38 | uint64 TotalAlloc = 4; 39 | uint64 Sys = 5; 40 | uint64 Mallocs = 6; 41 | uint64 Frees = 7; 42 | uint64 LiveObjects = 8; 43 | uint64 PauseTotalNs = 9; 44 | uint32 Uptime = 10; 45 | } 46 | 47 | service StatsService { 48 | rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {} 49 | rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {} 50 | rpc GetSysStats(SysStatsRequest) returns (SysStatsResponse) {} 51 | } 52 | 53 | message Config {} 54 | -------------------------------------------------------------------------------- /v2rayN/ProtosLib/Tests.cs: -------------------------------------------------------------------------------- 1 | using ProtosLib.Statistics; 2 | 3 | namespace ProtosLib 4 | { 5 | public class Tests 6 | { 7 | private StatsService.StatsServiceClient client_; 8 | 9 | public Tests() 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN.ico -------------------------------------------------------------------------------- /v2rayN/v2rayN.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32811.315 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "v2rayN", "v2rayN\v2rayN.csproj", "{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProtosLib", "ProtosLib\ProtosLib.csproj", "{C5F24BB0-9CC1-44DD-82FF-D545F081819B}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PacLib", "PacLib\PacLib.csproj", "{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HiddifyUpgradeN", "HiddifyUpgradeN\HiddifyUpgradeN.csproj", "{3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HiddifyRestartN", "HiddifyRestartN\HiddifyRestartN.csproj", "{89185DF9-A4F2-4A1E-A290-EA02959C37DA}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {43E06CBD-3DA9-40A3-8E4D-F0943CB0DD32} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Threading; 3 | using v2rayN.Handler; 4 | using v2rayN.Mode; 5 | using v2rayN.Tool; 6 | using v2rayN.ViewModels; 7 | using v2rayN.Tool; 8 | using System.Net; 9 | using HiddifyN.Tool; 10 | using v2rayN.Views; 11 | using System.IO.Pipes; 12 | using System.IO; 13 | 14 | namespace v2rayN 15 | { 16 | /// 17 | /// Interaction logic for App.xaml 18 | /// 19 | public partial class App : Application 20 | { 21 | public static EventWaitHandle ProgramStarted; 22 | public static bool IsNewInstance = false; 23 | private static Config _config; 24 | 25 | 26 | public App() 27 | { 28 | // Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly()); 29 | this.DispatcherUnhandledException += App_DispatcherUnhandledException; 30 | AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; 31 | TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; 32 | } 33 | 34 | /// 35 | /// 只打开一个进程 36 | /// 37 | /// 38 | protected override void OnStartup(StartupEventArgs e) 39 | { 40 | 41 | DeepLinking.RegisterSchemes(); 42 | 43 | Global.ExePathKey = Utils.GetMD5(Utils.GetExePath()); 44 | 45 | var rebootas = (e.Args ?? new string[] { }).Any(t => t == Global.RebootAs); 46 | ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, Global.ExePathKey, out bool bCreatedNew); 47 | if (!rebootas && !bCreatedNew) 48 | { 49 | ProgramStarted.Set(); 50 | IsNewInstance = true; 51 | sendLinkToUi(); 52 | } 53 | 54 | 55 | Global.processJob = new Job(); 56 | 57 | Logging.Setup(); 58 | Init(); 59 | Logging.LoggingEnabled(_config.guiItem.enableLog); 60 | Utils.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}"); 61 | Logging.ClearLogs(); 62 | 63 | Thread.CurrentThread.CurrentUICulture = new(_config.uiItem.currentLanguage); 64 | 65 | base.OnStartup(e); 66 | 67 | } 68 | 69 | private void sendLinkToUi() 70 | { 71 | try 72 | { 73 | using (var pipeClient = new NamedPipeClientStream("HiddifyPipe")) 74 | { 75 | pipeClient.Connect(); 76 | 77 | using (var writer = new StreamWriter(pipeClient)) 78 | { 79 | var args = Environment.GetCommandLineArgs(); 80 | // Write the message to the named pipe 81 | string message = args.Length>1? args[1]:""; 82 | writer.WriteLine(message); 83 | writer.Flush(); 84 | Thread.Sleep(10000); 85 | } 86 | 87 | pipeClient.Close(); 88 | } 89 | } 90 | catch (Exception ex) 91 | { 92 | // Handle any exceptions that occur while sending the message 93 | // ... 94 | } 95 | 96 | 97 | // Exit the new instance of the application 98 | Application.Current.Shutdown(); 99 | } 100 | private void Init() 101 | { 102 | if (ConfigHandler.LoadConfig(ref _config) != 0) 103 | { 104 | UI.ShowWarning($"Loading GUI configuration file is abnormal,please restart the application{Environment.NewLine}加载GUI配置文件异常,请重启应用"); 105 | Current.Shutdown(); 106 | Environment.Exit(0); 107 | return; 108 | } 109 | //if (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.X64) 110 | //{ 111 | // _config.guiItem.enableStatistics = false; 112 | //} 113 | } 114 | 115 | private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 116 | { 117 | Utils.SaveLog("App_DispatcherUnhandledException", e.Exception); 118 | e.Handled = true; 119 | } 120 | 121 | private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 122 | { 123 | if (e.ExceptionObject != null) 124 | { 125 | Utils.SaveLog("CurrentDomain_UnhandledException", (Exception)e.ExceptionObject!); 126 | } 127 | } 128 | 129 | private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e) 130 | { 131 | Utils.SaveLog("TaskScheduler_UnobservedTaskException", e.Exception); 132 | } 133 | 134 | 135 | 136 | } 137 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | [assembly: ThemeInfo( 4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 5 | //(used if a resource is not found in the page, 6 | // or application resource dictionaries) 7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 8 | //(used if a resource is not found in the page, 9 | // app, or any theme specific resource dictionaries) 10 | )] -------------------------------------------------------------------------------- /v2rayN/v2rayN/Base/MyDGTextColumn.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Controls; 2 | 3 | namespace v2rayN.Base 4 | { 5 | internal class MyDGTextColumn : DataGridTextColumn 6 | { 7 | public string ExName { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Base/SqliteHelper.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | using System.Collections; 3 | 4 | namespace v2rayN.Base 5 | { 6 | public sealed class SqliteHelper 7 | { 8 | private static readonly Lazy _instance = new(() => new()); 9 | public static SqliteHelper Instance => _instance.Value; 10 | private string _connstr; 11 | private SQLiteConnection _db; 12 | private SQLiteAsyncConnection _dbAsync; 13 | private static readonly object objLock = new(); 14 | 15 | public SqliteHelper() 16 | { 17 | _connstr = Utils.GetConfigPath(Global.ConfigDB); 18 | _db = new SQLiteConnection(_connstr, false); 19 | _dbAsync = new SQLiteAsyncConnection(_connstr, false); 20 | } 21 | 22 | public CreateTableResult CreateTable() 23 | { 24 | return _db.CreateTable(); 25 | } 26 | 27 | public int Insert(object model) 28 | { 29 | return _db.Insert(model); 30 | } 31 | 32 | public int InsertAll(IEnumerable models) 33 | { 34 | lock (objLock) 35 | { 36 | return _db.InsertAll(models); 37 | } 38 | } 39 | 40 | public async Task InsertAsync(object model) 41 | { 42 | return await _dbAsync.InsertAsync(model); 43 | } 44 | 45 | public int Replace(object model) 46 | { 47 | lock (objLock) 48 | { 49 | return _db.InsertOrReplace(model); 50 | } 51 | } 52 | 53 | public async Task Replacesync(object model) 54 | { 55 | return await _dbAsync.InsertOrReplaceAsync(model); 56 | } 57 | 58 | public int Update(object model) 59 | { 60 | lock (objLock) 61 | { 62 | return _db.Update(model); 63 | } 64 | } 65 | 66 | public async Task UpdateAsync(object model) 67 | { 68 | return await _dbAsync.UpdateAsync(model); 69 | } 70 | 71 | public int UpdateAll(IEnumerable models) 72 | { 73 | lock (objLock) 74 | { 75 | return _db.UpdateAll(models); 76 | } 77 | } 78 | 79 | public int Delete(object model) 80 | { 81 | lock (objLock) 82 | { 83 | return _db.Delete(model); 84 | } 85 | } 86 | 87 | public async Task DeleteAsync(object model) 88 | { 89 | return await _dbAsync.DeleteAsync(model); 90 | } 91 | 92 | public List Query(string sql) where T : new() 93 | { 94 | return _db.Query(sql); 95 | } 96 | 97 | public async Task> QueryAsync(string sql) where T : new() 98 | { 99 | return await _dbAsync.QueryAsync(sql); 100 | } 101 | 102 | public int Execute(string sql) 103 | { 104 | return _db.Execute(sql); 105 | } 106 | 107 | public async Task ExecuteAsync(string sql) 108 | { 109 | return await _dbAsync.ExecuteAsync(sql); 110 | } 111 | 112 | public TableQuery Table() where T : new() 113 | { 114 | return _db.Table(); 115 | } 116 | 117 | public AsyncTableQuery TableAsync() where T : new() 118 | { 119 | return _dbAsync.Table(); 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Base/StringEx.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics.CodeAnalysis; 2 | using System.IO; 3 | 4 | namespace v2rayN.Base 5 | { 6 | internal static class StringEx 7 | { 8 | public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value) 9 | { 10 | return string.IsNullOrEmpty(value); 11 | } 12 | 13 | public static bool IsNullOrWhiteSpace([NotNullWhen(false)] this string? value) 14 | { 15 | return string.IsNullOrWhiteSpace(value); 16 | } 17 | 18 | public static bool BeginWithAny(this string s, IEnumerable chars) 19 | { 20 | if (s.IsNullOrEmpty()) return false; 21 | return chars.Contains(s[0]); 22 | } 23 | 24 | public static bool IsWhiteSpace(this string value) 25 | { 26 | foreach (char c in value) 27 | { 28 | if (char.IsWhiteSpace(c)) continue; 29 | 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | public static IEnumerable NonWhiteSpaceLines(this TextReader reader) 36 | { 37 | string? line; 38 | while ((line = reader.ReadLine()) != null) 39 | { 40 | if (line.IsWhiteSpace()) continue; 41 | yield return line; 42 | } 43 | } 44 | 45 | public static string TrimEx(this string? value) 46 | { 47 | return value == null ? string.Empty : value.Trim(); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Converters/DelayColorConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Data; 2 | using System.Windows.Media; 3 | 4 | namespace v2rayN.Converters 5 | { 6 | public class DelayColorConverter : IValueConverter 7 | { 8 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 9 | { 10 | int.TryParse(value.ToString(), out var delay); 11 | 12 | if (delay <= 0) 13 | return new SolidColorBrush(Colors.Red); 14 | if (delay <= 200) 15 | return new SolidColorBrush(Colors.Green); 16 | else 17 | return new SolidColorBrush(Colors.IndianRed); 18 | } 19 | 20 | public object? ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 21 | { 22 | return null; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Converters/LocalizeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | using System.Windows; 9 | using v2rayN.Mode; 10 | 11 | namespace v2rayN.Converters 12 | { 13 | public class LocalizeConverter : IValueConverter 14 | { 15 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 16 | { 17 | if (value is ProxyModeEnum) 18 | return ((ProxyModeEnum)value).ToLocalizedDescriptionString(); 19 | string resourceName = value.ToString(); 20 | return Application.Current.FindResource(resourceName); 21 | } 22 | 23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 24 | { 25 | throw new NotImplementedException(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Converters/MaterialDesignFonts.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Media; 2 | using v2rayN.Handler; 3 | 4 | namespace v2rayN.Converters 5 | { 6 | public class MaterialDesignFonts 7 | { 8 | public static FontFamily MyFont { get; } 9 | 10 | static MaterialDesignFonts() 11 | { 12 | try 13 | { 14 | var fontFamily = LazyConfig.Instance.GetConfig().uiItem.currentFontFamily; 15 | if (!string.IsNullOrEmpty(fontFamily)) 16 | { 17 | var fontPath = Utils.GetFontsPath(); 18 | MyFont = new FontFamily(new Uri(@$"file:///{fontPath}\"), $"./#{fontFamily}"); 19 | } 20 | } 21 | catch 22 | { 23 | } 24 | MyFont ??= new FontFamily("Microsoft YaHei"); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Converters/SizeConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Globalization; 2 | using System.Windows.Data; 3 | using System.Windows.Media; 4 | 5 | namespace v2rayN.Converters 6 | { 7 | public class SizeConverter : IValueConverter 8 | { 9 | private static readonly string[] SizeSuffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; 10 | 11 | 12 | private static bool IsNumber(object value) 13 | { 14 | return value is sbyte || value is byte || 15 | value is short || value is ushort || 16 | value is int || value is uint || 17 | value is long || value is ulong || 18 | value is float || value is double || 19 | value is decimal; 20 | } 21 | 22 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 23 | { 24 | if (value == null || !IsNumber(value)) 25 | { 26 | return null; 27 | } 28 | 29 | long fileSizeInBytes = System.Convert.ToInt64(value); 30 | if (fileSizeInBytes == 0) 31 | { 32 | return "0 B"; 33 | } 34 | 35 | var sizeIndex = (int)Math.Floor(Math.Log(fileSizeInBytes, 1024)); 36 | var size = fileSizeInBytes / Math.Pow(1024, sizeIndex); 37 | var sizeSuffix = SizeSuffixes[sizeIndex]; 38 | var formattedSize = string.Format("{0:n1}", size); 39 | 40 | return $"{formattedSize} {sizeSuffix}"; 41 | } 42 | 43 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 44 | { 45 | throw new NotImplementedException(); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Handler/NoticeHandler.cs: -------------------------------------------------------------------------------- 1 | using MaterialDesignThemes.Wpf; 2 | using ReactiveUI; 3 | 4 | namespace v2rayN.Handler 5 | { 6 | public class NoticeHandler 7 | { 8 | private readonly ISnackbarMessageQueue _snackbarMessageQueue; 9 | 10 | public NoticeHandler(ISnackbarMessageQueue snackbarMessageQueue) 11 | { 12 | _snackbarMessageQueue = snackbarMessageQueue ?? throw new ArgumentNullException(nameof(snackbarMessageQueue)); 13 | 14 | //_snackbarMessageQueue = snackbarMessageQueue; 15 | } 16 | 17 | public void Enqueue(object content) 18 | { 19 | _snackbarMessageQueue?.Enqueue(content); 20 | } 21 | 22 | public void SendMessage(string msg) 23 | { 24 | MessageBus.Current.SendMessage(msg, "MsgView"); 25 | } 26 | 27 | public void SendMessage(string msg, bool time) 28 | { 29 | msg = $"{DateTime.Now} {msg}"; 30 | MessageBus.Current.SendMessage(msg, "MsgView"); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Handler/ProfileExHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Reactive.Linq; 3 | using v2rayN.Base; 4 | using v2rayN.Mode; 5 | 6 | namespace v2rayN.Handler 7 | { 8 | internal class ProfileExHandler 9 | { 10 | private static readonly Lazy _instance = new(() => new()); 11 | private ConcurrentBag _lstProfileEx; 12 | private Queue _queIndexIds = new(); 13 | public ConcurrentBag ProfileExs => _lstProfileEx; 14 | public static ProfileExHandler Instance => _instance.Value; 15 | 16 | public ProfileExHandler() 17 | { 18 | Init(); 19 | } 20 | 21 | private void Init() 22 | { 23 | SqliteHelper.Instance.Execute($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )"); 24 | 25 | _lstProfileEx = new(SqliteHelper.Instance.Table()); 26 | 27 | Task.Run(() => 28 | { 29 | while (true) 30 | { 31 | var cnt = _queIndexIds.Count; 32 | for (int i = 0; i < cnt; i++) 33 | { 34 | var id = _queIndexIds.Dequeue(); 35 | var item = _lstProfileEx.FirstOrDefault(t => t.indexId == id); 36 | if (item is not null) 37 | { 38 | SqliteHelper.Instance.Replace(item); 39 | } 40 | } 41 | Thread.Sleep(1000 * 60); 42 | } 43 | }); 44 | } 45 | 46 | private void IndexIdEnqueue(string indexId) 47 | { 48 | if (!Utils.IsNullOrEmpty(indexId) && !_queIndexIds.Contains(indexId)) 49 | { 50 | _queIndexIds.Enqueue(indexId); 51 | } 52 | } 53 | 54 | private void AddProfileEx(string indexId, ref ProfileExItem profileEx) 55 | { 56 | profileEx = new() 57 | { 58 | indexId = indexId, 59 | delay = 0, 60 | speed = 0, 61 | sort = 0 62 | }; 63 | _lstProfileEx.Add(profileEx); 64 | IndexIdEnqueue(indexId); 65 | } 66 | 67 | public void ClearAll() 68 | { 69 | SqliteHelper.Instance.Execute($"delete from ProfileExItem "); 70 | _lstProfileEx = new(); 71 | } 72 | 73 | public void SaveTo() 74 | { 75 | try 76 | { 77 | //foreach (var item in _lstProfileEx) 78 | //{ 79 | // SqliteHelper.Instance.Replace(item); 80 | //} 81 | SqliteHelper.Instance.UpdateAll(_lstProfileEx); 82 | } 83 | catch (Exception ex) 84 | { 85 | Utils.SaveLog(ex.Message, ex); 86 | } 87 | } 88 | 89 | public void SetTestDelay(string indexId, string delayVal) 90 | { 91 | var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); 92 | if (profileEx == null) 93 | { 94 | AddProfileEx(indexId, ref profileEx); 95 | } 96 | 97 | int.TryParse(delayVal, out int delay); 98 | profileEx.delay = delay; 99 | IndexIdEnqueue(indexId); 100 | } 101 | 102 | public void SetTestSpeed(string indexId, string speedVal) 103 | { 104 | var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); 105 | if (profileEx == null) 106 | { 107 | AddProfileEx(indexId, ref profileEx); 108 | } 109 | 110 | decimal.TryParse(speedVal, out decimal speed); 111 | profileEx.speed = speed; 112 | IndexIdEnqueue(indexId); 113 | } 114 | 115 | public void SetSort(string indexId, int sort) 116 | { 117 | var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); 118 | if (profileEx == null) 119 | { 120 | AddProfileEx(indexId, ref profileEx); 121 | } 122 | profileEx.sort = sort; 123 | IndexIdEnqueue(indexId); 124 | } 125 | 126 | public int GetSort(string indexId) 127 | { 128 | var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId); 129 | if (profileEx == null) 130 | { 131 | return 0; 132 | } 133 | return profileEx.sort; 134 | } 135 | 136 | public int GetMaxSort() 137 | { 138 | if (_lstProfileEx.Count <= 0) 139 | { 140 | return 0; 141 | } 142 | return _lstProfileEx.Max(t => t == null ? 0 : t.sort); 143 | } 144 | } 145 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Handler/QRCodeHelper.cs: -------------------------------------------------------------------------------- 1 | using QRCoder; 2 | using QRCoder.Xaml; 3 | using System.Windows.Media; 4 | 5 | namespace v2rayN.Handler 6 | { 7 | /// 8 | /// 含有QR码的描述类和包装编码和渲染 9 | /// 10 | public class QRCodeHelper 11 | { 12 | public static DrawingImage? GetQRCode(string strContent) 13 | { 14 | try 15 | { 16 | QRCodeGenerator qrGenerator = new(); 17 | QRCodeData qrCodeData = qrGenerator.CreateQrCode(strContent, QRCodeGenerator.ECCLevel.H); 18 | XamlQRCode qrCode = new(qrCodeData); 19 | DrawingImage qrCodeAsXaml = qrCode.GetGraphic(40); 20 | return qrCodeAsXaml; 21 | } 22 | catch 23 | { 24 | return null; 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/BalancerItem.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | public class BalancerItem 5 | { 6 | public string tag { get; set; } 7 | public string[] selector { get; set; } 8 | 9 | public BalancerStrategyItem strategy { get; set; } 10 | public BalancerStrategySettings optimalSettings { get; set; } 11 | 12 | } 13 | [Serializable] 14 | public class BalancerStrategyItem 15 | { 16 | public string type { get; set; } 17 | public BalancerStrategySettings settings { get; set; } 18 | } 19 | 20 | 21 | public interface BalancerStrategySettings{} 22 | 23 | [Serializable] 24 | public class OptimalBalancerStrategySetting: BalancerStrategySettings 25 | { 26 | public int timeout { get; set; } = 10000; 27 | public int interval { get; set; } = 30000; 28 | public string url { get; set; } = "https://about.google"; 29 | public int count { get; set; } = 3; 30 | public bool accept_little_diff { get; set; } = true; 31 | public bool load_balancing { get; set; } = false; 32 | public double diff_percent { get; set; } = 0.5; 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ComboItem.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public class ComboItem 4 | { 5 | public string ID 6 | { 7 | get; set; 8 | } 9 | 10 | public string Text 11 | { 12 | get; set; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/Config.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | /// 4 | /// 本软件配置文件实体类 5 | /// 6 | [Serializable] 7 | public class Config 8 | { 9 | #region property 10 | 11 | public string indexId { get; set; } 12 | public string subIndexId { get; set; } 13 | public ESysProxyType sysProxyType { get; set; } 14 | public string systemProxyExceptions { get; set; } 15 | public string systemProxyAdvancedProtocol { get; set; } 16 | 17 | #endregion property 18 | 19 | #region other entities 20 | 21 | public CoreBasicItem coreBasicItem { get; set; } 22 | public TunModeItem tunModeItem { get; set; } 23 | public KcpItem kcpItem { get; set; } 24 | public GrpcItem grpcItem { get; set; } 25 | public RoutingBasicItem routingBasicItem { get; set; } 26 | public GUIItem guiItem { get; set; } 27 | public UIItem uiItem { get; set; } 28 | public ConstItem constItem { get; set; } 29 | public SpeedTestItem speedTestItem { get; set; } 30 | public List inbound { get; set; } 31 | public List globalHotkeys { get; set; } 32 | public List coreTypeItem { get; set; } 33 | 34 | #endregion other entities 35 | } 36 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/CoreInfo.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | public class CoreInfo 5 | { 6 | public ECoreType coreType { get; set; } 7 | 8 | public List coreExes { get; set; } 9 | 10 | public string arguments { get; set; } 11 | 12 | public string coreUrl { get; set; } 13 | 14 | public string coreReleaseApiUrl { get; set; } 15 | 16 | public string coreDownloadUrl32 { get; set; } 17 | 18 | public string coreDownloadUrl64 { get; set; } 19 | 20 | public string coreDownloadUrlArm64 { get; set; } 21 | 22 | public string match { get; set; } 23 | public string versionArg { get; set; } 24 | 25 | public bool redirectInfo { get; set; } 26 | } 27 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/DNSItem.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | 3 | namespace v2rayN.Mode 4 | { 5 | [Serializable] 6 | public class DNSItem 7 | { 8 | [PrimaryKey] 9 | public string id { get; set; } 10 | 11 | public string remarks { get; set; } 12 | public bool enabled { get; set; } = true; 13 | public ECoreType coreType { get; set; } 14 | public string? normalDNS { get; set; } 15 | public string? directDNS { get; set; } 16 | public string? proxyDNS { get; set; } 17 | public string? domainStrategy4Freedom { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/EConfigType.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum EConfigType 4 | { 5 | VMess = 1, 6 | Custom = 2, 7 | Shadowsocks = 3, 8 | Socks = 4, 9 | VLESS = 5, 10 | Trojan = 6, 11 | LowestPing = 101, 12 | LoadBalance=102, 13 | Usage = 103, 14 | } 15 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ECoreType.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum ECoreType 4 | { 5 | v2fly = 1, 6 | Xray = 2, 7 | SagerNet = 3, 8 | v2fly_v5 = 4, 9 | clash = 11, 10 | clash_meta = 12, 11 | hysteria = 21, 12 | naiveproxy = 22, 13 | tuic = 23, 14 | sing_box = 24, 15 | v2rayN = 99 16 | } 17 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/EGlobalHotkey.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum EGlobalHotkey 4 | { 5 | ShowForm = 0, 6 | SystemProxyClear = 1, 7 | SystemProxySet = 2, 8 | SystemProxyUnchanged = 3, 9 | SystemProxyPac = 4, 10 | } 11 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/EMove.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum EMove 4 | { 5 | Top = 1, 6 | Up = 2, 7 | Down = 3, 8 | Bottom = 4, 9 | Position = 5 10 | } 11 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/EServerColName.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum EServerColName 4 | { 5 | def = 0, 6 | configType, 7 | remarks, 8 | address, 9 | port, 10 | security, 11 | network, 12 | streamSecurity, 13 | subRemarks, 14 | delayVal, 15 | speedVal, 16 | 17 | todayDown, 18 | todayUp, 19 | totalDown, 20 | totalUp 21 | } 22 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ESpeedActionType.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum ESpeedActionType 4 | { 5 | Ping, 6 | Tcping, 7 | Realping, 8 | Speedtest, 9 | Mixedtest 10 | } 11 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ESysProxyType.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum ESysProxyType 4 | { 5 | ForcedClear = 0, 6 | ForcedChange = 1, 7 | Unchanged = 2, 8 | Pac = 3 9 | } 10 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/EViewAction.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public enum EViewAction 4 | { 5 | AdjustMainLvColWidth, 6 | ProfilesFocus 7 | } 8 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/GitHubRelease.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace v2rayN.Mode 4 | { 5 | public class GitHubReleaseAsset 6 | { 7 | [JsonProperty("url")] public string Url { get; set; } 8 | 9 | [JsonProperty("id")] public int Id { get; set; } 10 | 11 | [JsonProperty("node_id")] public string NodeId { get; set; } 12 | 13 | [JsonProperty("name")] public string Name { get; set; } 14 | 15 | [JsonProperty("label")] public object Label { get; set; } 16 | 17 | [JsonProperty("content_type")] public string ContentType { get; set; } 18 | 19 | [JsonProperty("state")] public string State { get; set; } 20 | 21 | [JsonProperty("size")] public int Size { get; set; } 22 | 23 | [JsonProperty("download_count")] public int DownloadCount { get; set; } 24 | 25 | [JsonProperty("created_at")] public DateTime CreatedAt { get; set; } 26 | 27 | [JsonProperty("updated_at")] public DateTime UpdatedAt { get; set; } 28 | 29 | [JsonProperty("browser_download_url")] public string BrowserDownloadUrl { get; set; } 30 | } 31 | 32 | public class GitHubRelease 33 | { 34 | [JsonProperty("url")] public string Url { get; set; } 35 | 36 | [JsonProperty("assets_url")] public string AssetsUrl { get; set; } 37 | 38 | [JsonProperty("upload_url")] public string UploadUrl { get; set; } 39 | 40 | [JsonProperty("html_url")] public string HtmlUrl { get; set; } 41 | 42 | [JsonProperty("id")] public int Id { get; set; } 43 | 44 | [JsonProperty("node_id")] public string NodeId { get; set; } 45 | 46 | [JsonProperty("tag_name")] public string TagName { get; set; } 47 | 48 | [JsonProperty("target_commitish")] public string TargetCommitish { get; set; } 49 | 50 | [JsonProperty("name")] public string Name { get; set; } 51 | 52 | [JsonProperty("draft")] public bool Draft { get; set; } 53 | 54 | [JsonProperty("prerelease")] public bool Prerelease { get; set; } 55 | 56 | [JsonProperty("created_at")] public DateTime CreatedAt { get; set; } 57 | 58 | [JsonProperty("published_at")] public DateTime PublishedAt { get; set; } 59 | 60 | [JsonProperty("assets")] public List Assets { get; set; } 61 | 62 | [JsonProperty("tarball_url")] public string TarballUrl { get; set; } 63 | 64 | [JsonProperty("zipball_url")] public string ZipballUrl { get; set; } 65 | 66 | [JsonProperty("body")] public string Body { get; set; } 67 | } 68 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/HiddifyEnums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using v2rayN.Resx; 8 | using System.Resources; 9 | using v2rayN.Mode; 10 | 11 | namespace v2rayN.Mode 12 | { 13 | internal class HiddifyEnums 14 | { 15 | } 16 | public enum RoutingEnum 17 | { 18 | All, 19 | Blocked, 20 | BypassNotblocked 21 | } 22 | public enum ProxyModeEnum : int 23 | { 24 | [LocalizedDescription("HomeProxyAuto", typeof(ResUI))] 25 | Smart, 26 | [LocalizedDescription("HomeProxyLoadBalance", typeof(ResUI))] 27 | Loadbalance, 28 | [LocalizedDescription("HomeProxyManual", typeof(ResUI))] 29 | Manual 30 | 31 | 32 | } 33 | } 34 | 35 | public class LocalizedDescriptionAttribute : DescriptionAttribute 36 | { 37 | private readonly string _resourceName; 38 | private readonly Type _resourceType; 39 | 40 | public LocalizedDescriptionAttribute(string resourceName, Type resourceType) 41 | { 42 | _resourceName = resourceName; 43 | _resourceType = resourceType; 44 | } 45 | 46 | public override string Description 47 | { 48 | get 49 | { 50 | ResourceManager rm = new ResourceManager(_resourceType); 51 | return rm.GetString(_resourceName); 52 | } 53 | } 54 | 55 | 56 | } 57 | 58 | 59 | public static class ProxyModeEnumExtensions 60 | { 61 | public static string ToLocalizedDescriptionString(this ProxyModeEnum value) 62 | { 63 | var fieldInfo = value.GetType().GetField(value.ToString()); 64 | var attributes = fieldInfo.GetCustomAttributes(typeof(LocalizedDescriptionAttribute), false) as LocalizedDescriptionAttribute[]; 65 | return attributes?.Length > 0 ? attributes[0].Description : value.ToString(); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ProfileExItem.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | 3 | namespace v2rayN.Mode 4 | { 5 | [Serializable] 6 | public class ProfileExItem 7 | { 8 | [PrimaryKey] 9 | public string indexId { get; set; } 10 | 11 | public int delay { get; set; } 12 | public decimal speed { get; set; } 13 | public int sort { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ProfileItem.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | using v2rayN.Base; 3 | 4 | namespace v2rayN.Mode 5 | { 6 | [Serializable] 7 | public class ProfileItem 8 | { 9 | public ProfileItem() 10 | { 11 | indexId = string.Empty; 12 | configType = EConfigType.VMess; 13 | configVersion = 2; 14 | address = string.Empty; 15 | port = 0; 16 | id = string.Empty; 17 | alterId = 0; 18 | security = string.Empty; 19 | network = string.Empty; 20 | remarks = string.Empty; 21 | headerType = string.Empty; 22 | requestHost = string.Empty; 23 | path = string.Empty; 24 | streamSecurity = string.Empty; 25 | allowInsecure = string.Empty; 26 | subid = string.Empty; 27 | flow = string.Empty; 28 | } 29 | 30 | #region function 31 | 32 | public string GetSummary() 33 | { 34 | string summary = string.Format("[{0}] ", (configType).ToString()); 35 | string[] arrAddr = address.Split('.'); 36 | string addr; 37 | if (arrAddr.Length > 2) 38 | { 39 | addr = $"{arrAddr[0]}***{arrAddr[arrAddr.Length - 1]}"; 40 | } 41 | else if (arrAddr.Length > 1) 42 | { 43 | addr = $"***{arrAddr[arrAddr.Length - 1]}"; 44 | } 45 | else 46 | { 47 | addr = address; 48 | } 49 | switch (configType) 50 | { 51 | case EConfigType.VMess: 52 | case EConfigType.Shadowsocks: 53 | case EConfigType.Socks: 54 | case EConfigType.VLESS: 55 | case EConfigType.Trojan: 56 | summary += string.Format("{0}({1}:{2})", remarks, addr, port); 57 | break; 58 | 59 | default: 60 | summary += string.Format("{0}", remarks); 61 | break; 62 | } 63 | return summary; 64 | } 65 | 66 | public List GetAlpn() 67 | { 68 | if (Utils.IsNullOrEmpty(alpn)) 69 | { 70 | return null; 71 | } 72 | else 73 | { 74 | return Utils.String2List(alpn); 75 | } 76 | } 77 | 78 | public string GetNetwork() 79 | { 80 | if (Utils.IsNullOrEmpty(network) || !Global.networks.Contains(network)) 81 | { 82 | return Global.DefaultNetwork; 83 | } 84 | return network.TrimEx(); 85 | } 86 | 87 | #endregion function 88 | 89 | [PrimaryKey] 90 | public string indexId { get; set; } 91 | 92 | /// 93 | /// config type(1=normal,2=custom) 94 | /// 95 | public EConfigType configType { get; set; } 96 | 97 | /// 98 | /// 版本(现在=2) 99 | /// 100 | public int configVersion { get; set; } 101 | 102 | /// 103 | /// 远程服务器地址 104 | /// 105 | public string address { get; set; } 106 | 107 | /// 108 | /// 远程服务器端口 109 | /// 110 | public int port { get; set; } 111 | 112 | /// 113 | /// 远程服务器ID 114 | /// 115 | public string id { get; set; } 116 | 117 | /// 118 | /// 远程服务器额外ID 119 | /// 120 | public int alterId { get; set; } 121 | 122 | /// 123 | /// 本地安全策略 124 | /// 125 | public string security { get; set; } 126 | 127 | /// 128 | /// tcp,kcp,ws,h2,quic 129 | /// 130 | public string network { get; set; } 131 | 132 | /// 133 | /// 134 | /// 135 | public string remarks { get; set; } 136 | 137 | /// 138 | /// 伪装类型 139 | /// 140 | public string headerType { get; set; } 141 | 142 | /// 143 | /// 伪装的域名 144 | /// 145 | public string requestHost { get; set; } 146 | 147 | /// 148 | /// ws h2 path 149 | /// 150 | public string path { get; set; } 151 | public string fragment { get; set; }//hiddify 152 | 153 | /// 154 | /// 传输层安全 155 | /// 156 | public string streamSecurity { get; set; } 157 | 158 | /// 159 | /// 是否允许不安全连接(用于客户端) 160 | /// 161 | public string allowInsecure { get; set; } 162 | 163 | /// 164 | /// SubItem id 165 | /// 166 | public string subid { get; set; } 167 | 168 | public bool isSub { get; set; } = true; 169 | 170 | /// 171 | /// VLESS flow 172 | /// 173 | public string flow { get; set; } 174 | 175 | /// 176 | /// tls sni 177 | /// 178 | public string sni { get; set; } 179 | 180 | /// 181 | /// tls alpn 182 | /// 183 | public string alpn { get; set; } = string.Empty; 184 | 185 | public ECoreType? coreType { get; set; } 186 | 187 | public int preSocksPort { get; set; } 188 | 189 | public string fingerprint { get; set; } 190 | 191 | public bool displayLog { get; set; } = true; 192 | public string publicKey { get; set; } 193 | public string shortId { get; set; } 194 | public string spiderX { get; set; } 195 | } 196 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ProfileItemModel.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | public class ProfileItemModel : ProfileItem 5 | { 6 | public bool isActive { get; set; } 7 | public string subRemarks { get; set; } 8 | public int delay { get; set; } 9 | public decimal speed { get; set; } 10 | public int sort { get; set; } 11 | public string delayVal { get; set; } 12 | public string speedVal { get; set; } 13 | public string todayUp { get; set; } 14 | public string todayDown { get; set; } 15 | public string totalUp { get; set; } 16 | public string totalDown { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ProxyMode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace v2rayN.Mode 8 | { 9 | public class ProxyMode 10 | { 11 | public int id { get; set; } 12 | public string remark { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/RoutingItem.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | 3 | namespace v2rayN.Mode 4 | { 5 | [Serializable] 6 | public class RoutingItem 7 | { 8 | [PrimaryKey] 9 | public string id { get; set; } 10 | 11 | public string remarks { get; set; } 12 | public string url { get; set; } 13 | public string ruleSet { get; set; } 14 | public int ruleNum { get; set; } 15 | public bool enabled { get; set; } = true; 16 | public bool locked { get; set; } 17 | public string customIcon { get; set; } 18 | public string domainStrategy { get; set; } 19 | public string domainStrategy4Singbox { get; set; } 20 | public int sort { get; set; } 21 | } 22 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/RoutingItemModel.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | public class RoutingItemModel : RoutingItem 5 | { 6 | public bool isActive { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/RulesItem.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | public class RulesItem 5 | { 6 | public string id { get; set; } 7 | public string type { get; set; } 8 | 9 | public string port { get; set; } 10 | 11 | public List inboundTag { get; set; } 12 | 13 | public string outboundTag { get; set; } 14 | public string balancerTag { get; set; } 15 | 16 | public List ip { get; set; } 17 | 18 | public List domain { get; set; } 19 | 20 | public List protocol { get; set; } 21 | 22 | public bool enabled { get; set; } = true; 23 | } 24 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/RulesItemModel.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | public class RulesItemModel : RulesItem 5 | { 6 | public string inboundTags { get; set; } 7 | 8 | public string ips { get; set; } 9 | 10 | public string domains { get; set; } 11 | 12 | public string protocols { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ServerSpeedItem.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | internal class ServerSpeedItem : ServerStatItem 5 | { 6 | public long proxyUp 7 | { 8 | get; set; 9 | } 10 | 11 | public long proxyDown 12 | { 13 | get; set; 14 | } 15 | 16 | public long directUp 17 | { 18 | get; set; 19 | } 20 | 21 | public long directDown 22 | { 23 | get; set; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ServerStatItem.cs: -------------------------------------------------------------------------------- 1 | using SQLite; 2 | 3 | namespace v2rayN.Mode 4 | { 5 | [Serializable] 6 | public class ServerStatItem 7 | { 8 | [PrimaryKey] 9 | public string indexId 10 | { 11 | get; set; 12 | } 13 | 14 | public long totalUp 15 | { 16 | get; set; 17 | } 18 | 19 | public long totalDown 20 | { 21 | get; set; 22 | } 23 | 24 | public long todayUp 25 | { 26 | get; set; 27 | } 28 | 29 | public long todayDown 30 | { 31 | get; set; 32 | } 33 | 34 | public long dateNow 35 | { 36 | get; set; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/ServerTestItem.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | [Serializable] 4 | internal class ServerTestItem 5 | { 6 | public string indexId { get; set; } 7 | public string address { get; set; } 8 | public int port { get; set; } 9 | public EConfigType configType { get; set; } 10 | public bool allowTest { get; set; } 11 | public int delay { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/SsSIP008.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | public class SsSIP008 4 | { 5 | public List servers { get; set; } 6 | } 7 | 8 | [Serializable] 9 | public class SsServer 10 | { 11 | public string remarks { get; set; } 12 | public string server { get; set; } 13 | public string server_port { get; set; } 14 | public string method { get; set; } 15 | public string password { get; set; } 16 | public string plugin { get; set; } 17 | } 18 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/SubItem.cs: -------------------------------------------------------------------------------- 1 |  2 | using SQLite; 3 | using System.Windows; 4 | namespace v2rayN.Mode 5 | { 6 | [Serializable] 7 | public class SubItem 8 | { 9 | [PrimaryKey] 10 | public string id { get; set; } 11 | 12 | public string remarks { get; set; } 13 | 14 | public string url { get; set; } 15 | 16 | public string moreUrl { get; set; } 17 | 18 | public bool enabled { get; set; } = true; 19 | 20 | public string userAgent { get; set; } = string.Empty; 21 | 22 | public int sort { get; set; } 23 | 24 | public string? filter { get; set; } 25 | public long upload { get; set; } 26 | public long download { get; set; } 27 | public long total { get; set; } 28 | public long usage { get { return (download + upload); } set { } } 29 | 30 | public long expireDate { get; set; } 31 | public int remaningExpireDays { get; set; } 32 | public int UsedDataGB { get; set; } 33 | public int TotalDataGB { get; set; } 34 | public string? profileWebPageUrl { get; set; } 35 | 36 | public int profileUpdateInterval { get; set; } 37 | 38 | public long updateTime { get; set; } 39 | 40 | public string? convertTarget { get; set; } 41 | public Visibility sub_info_visible { get { return TotalDataGB>0?Visibility.Visible:Visibility.Collapsed;} } 42 | //public Visibility sub_info_visible { get { return Visibility.Collapsed; } } 43 | public double UploadMegaBytes() 44 | { 45 | return GetJustThreeDigitOfaNumber(this.upload/1024/1024); 46 | } 47 | public double DownloadMegaBytes() 48 | { 49 | return GetJustThreeDigitOfaNumber(this.download/1024 / 1024); 50 | } 51 | public double TotalMegaBytes() 52 | { 53 | return GetJustThreeDigitOfaNumber(this.total/1024 / 1024); 54 | } 55 | 56 | public double UploadGigaBytes() 57 | { 58 | return GetJustThreeDigitOfaNumber(this.upload / 1024 / 1024/1024); 59 | } 60 | public double DownloadGigaBytes() 61 | { 62 | return GetJustThreeDigitOfaNumber(this.download / 1024 / 1024 / 1024); 63 | } 64 | public int TotalDataGigaBytes() 65 | { 66 | return (int)((this.total / 1024 / 1024 / 1024)); 67 | } 68 | public int UsedDataGigaBytes() 69 | { 70 | return (int)(this.download + this.upload) / 1024 / 1024 / 1024; 71 | } 72 | public double DownloadAndUploadTotalGigaBytes() 73 | { 74 | return GetJustThreeDigitOfaNumber((this.download + this.upload) / 1024 / 1024 / 1024); 75 | } 76 | public DateTime ExpireToDate() 77 | { 78 | return Utils.EpochToDate(this.expireDate); 79 | } 80 | 81 | public int DaysLeftToExpire() 82 | { 83 | return this.ExpireToDate().Subtract(DateTime.Now).Days; 84 | } 85 | 86 | private double GetJustThreeDigitOfaNumber(double num) 87 | { 88 | string strNum = ""; 89 | int counter = 0; 90 | foreach (var n in num.ToString().ToCharArray()) 91 | { 92 | if (counter == 3) 93 | { 94 | break; 95 | } 96 | strNum += n; 97 | counter++; 98 | } 99 | 100 | return double.Parse(strNum); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/SubscriptionInfo.cs: -------------------------------------------------------------------------------- 1 |  2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace v2rayN.Mode 9 | { 10 | public class SubscriptionInfo 11 | { 12 | public long Upload { get; set; } 13 | public long Download { get; set; } 14 | public long Total { get; set; } 15 | public long ExpireDate { get; set; } 16 | public string? ProfileWebPageUrl { get; set; } 17 | public string? ProfileTitle { get; set; } 18 | public int ProfileUpdateInterval { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/SysproxyConfig.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | internal class SysproxyConfig 4 | { 5 | public bool UserSettingsRecorded; 6 | public string Flags; 7 | public string ProxyServer; 8 | public string BypassList; 9 | public string PacUrl; 10 | 11 | public SysproxyConfig() 12 | { 13 | UserSettingsRecorded = false; 14 | Flags = "1"; 15 | ProxyServer = ""; 16 | BypassList = ""; 17 | PacUrl = ""; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/V2rayTcpRequest.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | /// 4 | /// Tcp伪装http的Request,只要Host 5 | /// 6 | public class V2rayTcpRequest 7 | { 8 | /// 9 | /// 10 | /// 11 | public RequestHeaders headers { get; set; } 12 | } 13 | 14 | public class RequestHeaders 15 | { 16 | /// 17 | /// 18 | /// 19 | public List Host { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Mode/VmessQRCode.cs: -------------------------------------------------------------------------------- 1 | namespace v2rayN.Mode 2 | { 3 | /// 4 | /// https://github.com/2dust/v2rayN/wiki/ 5 | /// 6 | [Serializable] 7 | internal class VmessQRCode 8 | { 9 | /// 10 | /// 11 | /// 12 | public string v { get; set; } = string.Empty; 13 | 14 | /// 15 | /// 16 | /// 17 | public string ps { get; set; } = string.Empty; 18 | 19 | /// 20 | /// 21 | /// 22 | public string add { get; set; } = string.Empty; 23 | 24 | /// 25 | /// 26 | /// 27 | public string port { get; set; } = string.Empty; 28 | 29 | /// 30 | /// 31 | /// 32 | public string id { get; set; } = string.Empty; 33 | 34 | /// 35 | /// 36 | /// 37 | public string aid { get; set; } = string.Empty; 38 | 39 | /// 40 | /// 41 | /// 42 | public string scy { get; set; } = string.Empty; 43 | 44 | /// 45 | /// 46 | /// 47 | public string net { get; set; } = string.Empty; 48 | 49 | /// 50 | /// 51 | /// 52 | public string type { get; set; } = string.Empty; 53 | 54 | /// 55 | /// 56 | /// 57 | public string host { get; set; } = string.Empty; 58 | 59 | /// 60 | /// 61 | /// 62 | public string path { get; set; } = string.Empty; 63 | 64 | /// 65 | /// TLS 66 | /// 67 | public string tls { get; set; } = string.Empty; 68 | 69 | /// 70 | /// TLS SNI 71 | /// 72 | public string sni { get; set; } = string.Empty; 73 | 74 | /// 75 | /// TLS alpn 76 | /// 77 | public string alpn { get; set; } = string.Empty; 78 | 79 | /// 80 | /// TLS fingerprint 81 | /// 82 | public string fp { get; set; } = string.Empty; 83 | public string allowInsecure { get; set; } = string.Empty; 84 | 85 | } 86 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Resources/NotifyIcon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN/Resources/NotifyIcon1.ico -------------------------------------------------------------------------------- /v2rayN/v2rayN/Resources/NotifyIcon2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN/Resources/NotifyIcon2.ico -------------------------------------------------------------------------------- /v2rayN/v2rayN/Resources/NotifyIcon3.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN/Resources/NotifyIcon3.ico -------------------------------------------------------------------------------- /v2rayN/v2rayN/Resources/RestartProgram.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN/Resources/RestartProgram.ico -------------------------------------------------------------------------------- /v2rayN/v2rayN/Resources/sysproxy.exe.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN/Resources/sysproxy.exe.gz -------------------------------------------------------------------------------- /v2rayN/v2rayN/Resources/sysproxy64.exe.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN/Resources/sysproxy64.exe.gz -------------------------------------------------------------------------------- /v2rayN/v2rayN/Resx/Hiddify.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace v2rayN.Resx { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | public class Hiddify { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Hiddify() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | public static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("v2rayN.Resx.Hiddify", typeof(Hiddify).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | public static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Fragment. 65 | /// 66 | public static string Fragment { 67 | get { 68 | return ResourceManager.GetString("Fragment", resourceCulture); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/SampleClientConfig: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "access": "Vaccess.log", 4 | "error": "Verror.log", 5 | "loglevel": "warning" 6 | }, 7 | "inbounds": [ 8 | { 9 | "tag": "tag1", 10 | "port": 10808, 11 | "protocol": "socks", 12 | "listen": "127.0.0.1", 13 | "settings": { 14 | "auth": "noauth", 15 | "udp": true 16 | }, 17 | "sniffing": { 18 | "enabled": true, 19 | "destOverride": [ 20 | "http", 21 | "tls" 22 | ] 23 | } 24 | }, 25 | { 26 | "tag": "tag2", 27 | "port": 10809, 28 | "protocol": "http", 29 | "listen": "127.0.0.1", 30 | "settings": { 31 | "allowTransparent": false 32 | }, 33 | "sniffing": { 34 | "enabled": true, 35 | "destOverride": [ 36 | "http", 37 | "tls" 38 | ] 39 | } 40 | }, 41 | { 42 | "tag": "tag3", 43 | "port": 10809, 44 | "protocol": "http", 45 | "listen": "127.0.0.1", 46 | "settings": { 47 | "allowTransparent": false 48 | }, 49 | "sniffing": { 50 | "enabled": true, 51 | "destOverride": [ 52 | "http", 53 | "tls" 54 | ] 55 | } 56 | } 57 | ], 58 | "outbounds": [ 59 | { 60 | "tag": "proxy", 61 | "protocol": "vmess", 62 | "settings": { 63 | "vnext": [ 64 | { 65 | "address": "v2ray.cool", 66 | "port": 10086, 67 | "users": [ 68 | { 69 | "id": "a3482e88-686a-4a58-8126-99c9df64b7bf", 70 | "security": "auto" 71 | } 72 | ] 73 | } 74 | ], 75 | "servers": [ 76 | { 77 | "address": "v2ray.cool", 78 | "method": "chacha20", 79 | "ota": false, 80 | "password": "123456", 81 | "port": 10086, 82 | "level": 1 83 | } 84 | ] 85 | }, 86 | "streamSettings": { 87 | "network": "tcp" 88 | }, 89 | "mux": { 90 | "enabled": false 91 | } 92 | }, 93 | { 94 | "protocol": "freedom", 95 | "settings": {}, 96 | "tag": "direct" 97 | }, 98 | { 99 | "protocol": "blackhole", 100 | "tag": "block", 101 | "settings": { 102 | "response": { 103 | "type": "http" 104 | } 105 | } 106 | } 107 | ], 108 | "routing": { 109 | "domainStrategy": "IPIfNonMatch", 110 | "rules": [ 111 | { 112 | "inboundTag": [ "api" ], 113 | "outboundTag": "api", 114 | "type": "field" 115 | } 116 | ], 117 | "balancers": [] 118 | } 119 | //, 120 | //"observatory": { 121 | //"subjectSelector": ["balancer"], 122 | //"probeURL": "http://www.google.com/generate_204", 123 | //"probeInterval": "1m" 124 | //} 125 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/SampleHttprequest: -------------------------------------------------------------------------------- 1 | {"version":"1.1","method":"GET","path":[$requestPath$],"headers":{"Host":[$requestHost$],"User-Agent":[$requestUserAgent$],"Accept-Encoding":["gzip, deflate"],"Connection":["keep-alive"],"Pragma":"no-cache"}} -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/SampleHttpresponse: -------------------------------------------------------------------------------- 1 | {"version":"1.1","status":"200","reason":"OK","headers":{"Content-Type":["application/octet-stream","video/mpeg"],"Transfer-Encoding":["chunked"],"Connection":["keep-alive"],"Pragma":"no-cache"}} -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/SampleInbound: -------------------------------------------------------------------------------- 1 | { 2 | "tag": "tag1", 3 | "port": 10808, 4 | "protocol": "socks", 5 | "listen": "127.0.0.1", 6 | "settings": { 7 | "auth": "noauth", 8 | "udp": true, 9 | "allowTransparent": false 10 | }, 11 | "sniffing": { 12 | "enabled": true, 13 | "destOverride": [ 14 | "http", 15 | "tls" 16 | ] 17 | } 18 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/SingboxSampleClientConfig: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "level": "debug", 4 | "timestamp": true 5 | }, 6 | "inbounds": [ 7 | { 8 | "type": "socks", 9 | "tag": "socks", 10 | "listen": "127.0.0.1", 11 | "listen_port": 10000 12 | } 13 | ], 14 | "outbounds": [ 15 | { 16 | "type": "vless", 17 | "tag": "proxy", 18 | "server": "", 19 | "server_port": 443 20 | }, 21 | { 22 | "type": "direct", 23 | "tag": "direct" 24 | }, 25 | { 26 | "type": "block", 27 | "tag": "block" 28 | } 29 | ], 30 | "route": { 31 | "rules": [] 32 | } 33 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/custom_routing_black: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "outboundTag": "proxy", 4 | "domain": [ 5 | "domain:example.com", 6 | "domain:example2.com" 7 | ] 8 | }, 9 | { 10 | "type": "field", 11 | "port": "", 12 | "outboundTag": "block", 13 | "domain": [ 14 | "geosite:category-ads-all" 15 | ] 16 | }, 17 | { 18 | "type": "field", 19 | "port": "", 20 | "outboundTag": "proxy", 21 | "domain": [ 22 | "tld-!ir" 23 | ] 24 | }, 25 | { 26 | "type": "field", 27 | "port": "", 28 | "outboundTag": "proxy", 29 | "ip": [ 30 | "109.239.140.0/24", 31 | "149.154.160.0/22", 32 | "149.154.164.0/22", 33 | "149.154.168.0/22", 34 | "149.154.172.0/22", 35 | "67.198.55.0/24", 36 | "91.108.12.0/22", 37 | "91.108.16.0/22", 38 | "91.108.20.0/22", 39 | "91.108.20.0/23", 40 | "91.108.4.0/22", 41 | "91.108.56.0/22", 42 | "91.108.56.0/23", 43 | "91.108.8.0/22", 44 | "95.161.64.0/20", 45 | "95.161.84.0/23", 46 | "2001:67c:4e8::/48", 47 | "2001:b28:f23c::/48", 48 | "2001:b28:f23d::/48", 49 | "2001:b28:f23f::/48", 50 | "2001:b28:f242::/48" 51 | ] 52 | }, 53 | { 54 | "type": "field", 55 | "port": "", 56 | "outboundTag": "proxy", 57 | "ip": [ 58 | "geoip:facebook", 59 | "geoip:fastly", 60 | "geoip:netflix", 61 | "geoip:telegram", 62 | "geoip:twitter", 63 | "geoip:ae", 64 | "geoip:au", 65 | "geoip:br", 66 | "geoip:ca", 67 | "geoip:de", 68 | "geoip:dk", 69 | "geoip:es", 70 | "geoip:fi", 71 | "geoip:fr", 72 | "geoip:gb", 73 | "geoip:gr", 74 | "geoip:hk", 75 | "geoip:id", 76 | "geoip:il", 77 | "geoip:in", 78 | "geoip:iq", 79 | "geoip:it", 80 | "geoip:jp", 81 | "geoip:kr", 82 | "geoip:mo", 83 | "geoip:my", 84 | "geoip:nl", 85 | "geoip:no", 86 | "geoip:nz", 87 | "geoip:ph", 88 | "geoip:ru", 89 | "geoip:sa", 90 | "geoip:sg", 91 | "geoip:th", 92 | "geoip:tr", 93 | "geoip:tw", 94 | "geoip:us", 95 | "geoip:vn" 96 | ] 97 | }, 98 | { 99 | "type": "field", 100 | "port": "0-65535", 101 | "outboundTag": "direct" 102 | } 103 | ] 104 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/custom_routing_global: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "port": "0-65535", 4 | "outboundTag": "proxy" 5 | } 6 | ] -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/custom_routing_locked: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "domain": [ 4 | "geosite:google" 5 | ], 6 | "outboundTag": "proxy" 7 | }, 8 | { 9 | "outboundTag": "direct", 10 | "domain": [ 11 | "domain:example-example.com", 12 | "domain:example-example2.com" 13 | ] 14 | }, 15 | { 16 | "outboundTag": "block", 17 | "domain": [ 18 | "geosite:category-ads-all" 19 | ] 20 | } 21 | ] -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/custom_routing_rules: -------------------------------------------------------------------------------- 1 | [{ 2 | "remarks": "block", 3 | "outboundTag": "block", 4 | "domain": [ 5 | "geosite:category-ads-all" 6 | ] 7 | }, 8 | { 9 | "remarks": "direct", 10 | "outboundTag": "direct", 11 | "domain": [ 12 | "geosite:ir" 13 | ] 14 | }, 15 | { 16 | "remarks": "direct", 17 | "outboundTag": "direct", 18 | "ip": [ 19 | "geoip:private", 20 | "geoip:ir" 21 | ] 22 | }, 23 | { 24 | "remarks": "proxy", 25 | "port": "0-65535", 26 | "outboundTag": "proxy" 27 | } 28 | ] -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/custom_routing_white: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "outboundTag": "direct", 4 | "domain": [ 5 | "domain:example.com", 6 | "domain:example2.com" 7 | ] 8 | }, 9 | { 10 | "type": "field", 11 | "outboundTag": "block", 12 | "domain": [ 13 | "geosite:category-ads-all" 14 | ] 15 | }, 16 | { 17 | "type": "field", 18 | "outboundTag": "direct", 19 | "domain": [ 20 | "geosite:private", 21 | "geosite:apple@cn", 22 | "geosite:google@cn", 23 | "geosite:tld-cn", 24 | "tld-ir" 25 | ] 26 | }, 27 | { 28 | "type": "field", 29 | "outboundTag": "proxy", 30 | "domain": [ 31 | "geoip:!ir" 32 | ] 33 | }, 34 | { 35 | "type": "field", 36 | "outboundTag": "direct", 37 | "ip": [ 38 | "geoip:private", 39 | "geoip:cn", 40 | "geoip:ir" 41 | ], 42 | "domain": [] 43 | }, 44 | { 45 | "type": "field", 46 | "port": "0-65535", 47 | "outboundTag": "proxy" 48 | } 49 | ] 50 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/dns_singbox_normal: -------------------------------------------------------------------------------- 1 | { 2 | "servers": [ 3 | { 4 | "tag": "remote", 5 | "address": "tcp://8.8.8.8", 6 | "detour": "proxy" 7 | }, 8 | { 9 | "tag": "local", 10 | "address": "223.5.5.5", 11 | "detour": "direct" 12 | }, 13 | { 14 | "tag": "block", 15 | "address": "rcode://success" 16 | } 17 | ], 18 | "rules": [ 19 | { 20 | "geosite": [ 21 | "cn" 22 | ], 23 | "server": "local" 24 | }, 25 | { 26 | "geosite": [ 27 | "category-ads-all" 28 | ], 29 | "server": "block" 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/dns_v2ray_normal: -------------------------------------------------------------------------------- 1 | { 2 | "hosts": { 3 | "dns.google": "8.8.8.8", 4 | "proxy.example.com": "127.0.0.1" 5 | }, 6 | "servers": [ 7 | { 8 | "address": "223.5.5.5", 9 | "domains": [ 10 | "geosite:cn" 11 | ], 12 | "expectIPs": [ 13 | "geoip:cn" 14 | ] 15 | }, 16 | "1.1.1.1", 17 | "8.8.8.8", 18 | "https://dns.google/dns-query" 19 | ] 20 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/tun_singbox: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "disabled": $log_disabled$, 4 | "level": "debug", 5 | $log_output$ 6 | "timestamp": true 7 | }, 8 | "dns": $dns_object$ , 9 | "inbounds": [ 10 | { 11 | "type": "tun", 12 | "tag": "tun-in", 13 | "interface_name": "singbox_tun", 14 | "inet4_address": "172.19.0.1/30", 15 | 16 | "mtu": $mtu$, 17 | "auto_route": true, 18 | "strict_route": $strict_route$, 19 | "stack": "$stack$", 20 | "sniff": true 21 | } 22 | ], 23 | "outbounds": [ 24 | { 25 | "type": "socks", 26 | "tag": "proxy", 27 | "udp_fragment": true, 28 | "server": "127.0.0.1", 29 | "server_port": $socksPort$ 30 | }, 31 | { 32 | "type": "block", 33 | "tag": "block" 34 | }, 35 | { 36 | "type": "direct", 37 | "tag": "direct" 38 | }, 39 | { 40 | "type": "dns", 41 | "tag": "dns_out" 42 | } 43 | ], 44 | "route": { 45 | "auto_detect_interface": true, 46 | "rules": [ 47 | { 48 | "inbound": "dns_in", 49 | "outbound": "dns_out" 50 | }, 51 | { 52 | "protocol": "dns", 53 | "outbound": "dns_out" 54 | }, 55 | { 56 | "network": "udp", 57 | "port": [ 58 | 135, 59 | 137, 60 | 138, 61 | 139, 62 | 5353 63 | ], 64 | "outbound": "block" 65 | }, 66 | { 67 | "ip_cidr": [ 68 | "224.0.0.0/3", 69 | "ff00::/8" 70 | ], 71 | "outbound": "block" 72 | }, 73 | { 74 | "source_ip_cidr": [ 75 | "224.0.0.0/3", 76 | "ff00::/8" 77 | ], 78 | "outbound": "block" 79 | }, 80 | { 81 | "port": 53, 82 | "process_name": [ $dnsProcessName$], 83 | "outbound": "dns_out" 84 | }, 85 | { 86 | "process_name": [ $directProcessName$], 87 | "outbound": "direct" 88 | } 89 | $ruleDirectIPs$ 90 | $ruleDirectProcess$ 91 | $ruleProxyIPs$ 92 | $ruleProxyProcess$ 93 | $ruleFinally$ 94 | ] 95 | } 96 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/tun_singbox_dns: -------------------------------------------------------------------------------- 1 | { 2 | "servers": [ 3 | { 4 | "tag": "remote", 5 | "address": "tcp://8.8.8.8", 6 | "detour": "proxy" 7 | }, 8 | { 9 | "tag": "local", 10 | "address": "223.5.5.5", 11 | "detour": "direct" 12 | }, 13 | { 14 | "tag": "block", 15 | "address": "rcode://success" 16 | } 17 | ], 18 | "rules": [ 19 | { 20 | "geosite": [ 21 | "cn" 22 | ], 23 | "server": "local", 24 | "disable_cache": true 25 | }, 26 | { 27 | "geosite": [ 28 | "category-ads-all" 29 | ], 30 | "server": "block", 31 | "disable_cache": true 32 | } 33 | ], 34 | "strategy": "ipv4_only" 35 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/tun_singbox_inbound: -------------------------------------------------------------------------------- 1 | { 2 | "type":"tun", 3 | "tag":"tun-in", 4 | "interface_name":"singbox_tun", 5 | "inet4_address":"172.19.0.1/30", 6 | "mtu":9000, 7 | "auto_route":true, 8 | "strict_route":false, 9 | "stack":"system", 10 | "sniff":true 11 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Sample/tun_singbox_rules: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inbound": [ "dns_in" ], 4 | "outbound": "dns_out" 5 | }, 6 | { 7 | "protocol": [ "dns" ], 8 | "outbound": "dns_out" 9 | }, 10 | { 11 | "network": "udp", 12 | "port": [ 13 | 135, 14 | 137, 15 | 138, 16 | 139, 17 | 5353 18 | ], 19 | "outbound": "block" 20 | }, 21 | { 22 | "ip_cidr": [ 23 | "224.0.0.0/3", 24 | "ff00::/8" 25 | ], 26 | "outbound": "block" 27 | }, 28 | { 29 | "source_ip_cidr": [ 30 | "224.0.0.0/3", 31 | "ff00::/8" 32 | ], 33 | "outbound": "block" 34 | } 35 | ] -------------------------------------------------------------------------------- /v2rayN/v2rayN/Tool/FileManager.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.IO.Compression; 3 | using System.Text; 4 | 5 | namespace v2rayN.Tool 6 | { 7 | public static class FileManager 8 | { 9 | public static bool ByteArrayToFile(string fileName, byte[] content) 10 | { 11 | try 12 | { 13 | File.WriteAllBytes(fileName, content); 14 | return true; 15 | } 16 | catch (Exception ex) 17 | { 18 | Utils.SaveLog(ex.Message, ex); 19 | } 20 | return false; 21 | } 22 | 23 | public static void UncompressFile(string fileName, byte[] content) 24 | { 25 | try 26 | { 27 | using FileStream fs = File.Create(fileName); 28 | using GZipStream input = new(new MemoryStream(content), CompressionMode.Decompress, false); 29 | input.CopyTo(fs); 30 | } 31 | catch (Exception ex) 32 | { 33 | Utils.SaveLog(ex.Message, ex); 34 | } 35 | } 36 | 37 | public static string NonExclusiveReadAllText(string path) 38 | { 39 | return NonExclusiveReadAllText(path, Encoding.Default); 40 | } 41 | 42 | public static string NonExclusiveReadAllText(string path, Encoding encoding) 43 | { 44 | try 45 | { 46 | using FileStream fs = new(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 47 | using StreamReader sr = new(fs, encoding); 48 | return sr.ReadToEnd(); 49 | } 50 | catch (Exception ex) 51 | { 52 | Utils.SaveLog(ex.Message, ex); 53 | throw; 54 | } 55 | } 56 | 57 | public static bool ZipExtractToFile(string fileName, string toPath, string ignoredName) 58 | { 59 | try 60 | { 61 | using ZipArchive archive = ZipFile.OpenRead(fileName); 62 | foreach (ZipArchiveEntry entry in archive.Entries) 63 | { 64 | if (entry.Length == 0) 65 | { 66 | continue; 67 | } 68 | try 69 | { 70 | if (!Utils.IsNullOrEmpty(ignoredName) && entry.Name.Contains(ignoredName)) 71 | { 72 | continue; 73 | } 74 | entry.ExtractToFile(Path.Combine(toPath, entry.Name), true); 75 | } 76 | catch (IOException ex) 77 | { 78 | Utils.SaveLog(ex.Message, ex); 79 | } 80 | } 81 | } 82 | catch (Exception ex) 83 | { 84 | Utils.SaveLog(ex.Message, ex); 85 | return false; 86 | } 87 | return true; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Tool/Job.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace v2rayN 5 | { 6 | /* 7 | * See: 8 | * http://stackoverflow.com/questions/6266820/working-example-of-createjobobject-setinformationjobobject-pinvoke-in-net 9 | */ 10 | 11 | public class Job : IDisposable 12 | { 13 | private IntPtr handle = IntPtr.Zero; 14 | 15 | public Job() 16 | { 17 | handle = CreateJobObject(IntPtr.Zero, null); 18 | IntPtr extendedInfoPtr = IntPtr.Zero; 19 | JOBOBJECT_BASIC_LIMIT_INFORMATION info = new() 20 | { 21 | LimitFlags = 0x2000 22 | }; 23 | 24 | JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new() 25 | { 26 | BasicLimitInformation = info 27 | }; 28 | 29 | try 30 | { 31 | int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); 32 | extendedInfoPtr = Marshal.AllocHGlobal(length); 33 | Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false); 34 | 35 | if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, 36 | (uint)length)) 37 | throw new Exception(string.Format("Unable to set information. Error: {0}", 38 | Marshal.GetLastWin32Error())); 39 | } 40 | finally 41 | { 42 | if (extendedInfoPtr != IntPtr.Zero) 43 | { 44 | Marshal.FreeHGlobal(extendedInfoPtr); 45 | } 46 | } 47 | } 48 | 49 | public bool AddProcess(IntPtr processHandle) 50 | { 51 | bool succ = AssignProcessToJobObject(handle, processHandle); 52 | 53 | if (!succ) 54 | { 55 | Utils.SaveLog("Failed to call AssignProcessToJobObject! GetLastError=" + Marshal.GetLastWin32Error()); 56 | } 57 | 58 | return succ; 59 | } 60 | 61 | public bool AddProcess(int processId) 62 | { 63 | return AddProcess(Process.GetProcessById(processId).Handle); 64 | } 65 | 66 | #region IDisposable 67 | 68 | private bool disposed; 69 | 70 | public void Dispose() 71 | { 72 | Dispose(true); 73 | GC.SuppressFinalize(this); 74 | } 75 | 76 | protected virtual void Dispose(bool disposing) 77 | { 78 | if (disposed) return; 79 | disposed = true; 80 | 81 | if (disposing) 82 | { 83 | // no managed objects to free 84 | } 85 | 86 | if (handle != IntPtr.Zero) 87 | { 88 | CloseHandle(handle); 89 | handle = IntPtr.Zero; 90 | } 91 | } 92 | 93 | ~Job() 94 | { 95 | Dispose(false); 96 | } 97 | 98 | #endregion IDisposable 99 | 100 | #region Interop 101 | 102 | [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] 103 | private static extern IntPtr CreateJobObject(IntPtr a, string? lpName); 104 | 105 | [DllImport("kernel32.dll", SetLastError = true)] 106 | private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength); 107 | 108 | [DllImport("kernel32.dll", SetLastError = true)] 109 | private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process); 110 | 111 | [DllImport("kernel32.dll", SetLastError = true)] 112 | [return: MarshalAs(UnmanagedType.Bool)] 113 | private static extern bool CloseHandle(IntPtr hObject); 114 | 115 | #endregion Interop 116 | } 117 | 118 | #region Helper classes 119 | 120 | [StructLayout(LayoutKind.Sequential)] 121 | internal struct IO_COUNTERS 122 | { 123 | public UInt64 ReadOperationCount; 124 | public UInt64 WriteOperationCount; 125 | public UInt64 OtherOperationCount; 126 | public UInt64 ReadTransferCount; 127 | public UInt64 WriteTransferCount; 128 | public UInt64 OtherTransferCount; 129 | } 130 | 131 | [StructLayout(LayoutKind.Sequential)] 132 | internal struct JOBOBJECT_BASIC_LIMIT_INFORMATION 133 | { 134 | public Int64 PerProcessUserTimeLimit; 135 | public Int64 PerJobUserTimeLimit; 136 | public UInt32 LimitFlags; 137 | public UIntPtr MinimumWorkingSetSize; 138 | public UIntPtr MaximumWorkingSetSize; 139 | public UInt32 ActiveProcessLimit; 140 | public UIntPtr Affinity; 141 | public UInt32 PriorityClass; 142 | public UInt32 SchedulingClass; 143 | } 144 | 145 | [StructLayout(LayoutKind.Sequential)] 146 | public struct SECURITY_ATTRIBUTES 147 | { 148 | public UInt32 nLength; 149 | public IntPtr lpSecurityDescriptor; 150 | public Int32 bInheritHandle; 151 | } 152 | 153 | [StructLayout(LayoutKind.Sequential)] 154 | internal struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION 155 | { 156 | public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation; 157 | public IO_COUNTERS IoInfo; 158 | public UIntPtr ProcessMemoryLimit; 159 | public UIntPtr JobMemoryLimit; 160 | public UIntPtr PeakProcessMemoryUsed; 161 | public UIntPtr PeakJobMemoryUsed; 162 | } 163 | 164 | public enum JobObjectInfoType 165 | { 166 | AssociateCompletionPortInformation = 7, 167 | BasicLimitInformation = 2, 168 | BasicUIRestrictions = 4, 169 | EndOfJobTimeInformation = 6, 170 | ExtendedLimitInformation = 9, 171 | SecurityLimitInformation = 5, 172 | GroupInformation = 11 173 | } 174 | 175 | #endregion Helper classes 176 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Tool/Logging.cs: -------------------------------------------------------------------------------- 1 | using NLog; 2 | using NLog.Config; 3 | using NLog.Targets; 4 | using System.IO; 5 | 6 | namespace v2rayN.Tool 7 | { 8 | public class Logging 9 | { 10 | public static void Setup() 11 | { 12 | LoggingConfiguration config = new(); 13 | FileTarget fileTarget = new(); 14 | config.AddTarget("file", fileTarget); 15 | fileTarget.Layout = "${longdate}-${level:uppercase=true} ${message}"; 16 | fileTarget.FileName = Utils.GetLogPath("${shortdate}.txt"); 17 | config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget)); 18 | LogManager.Configuration = config; 19 | } 20 | 21 | public static void LoggingEnabled(bool enable) 22 | { 23 | if (!enable) 24 | { 25 | LogManager.SuspendLogging(); 26 | } 27 | } 28 | 29 | public static void ClearLogs() 30 | { 31 | Task.Run(() => 32 | { 33 | try 34 | { 35 | var now = DateTime.Now.AddMonths(-1); 36 | var dir = Utils.GetLogPath(); 37 | var files = Directory.GetFiles(dir, "*.txt"); 38 | foreach (var filePath in files) 39 | { 40 | var file = new FileInfo(filePath); 41 | if (file.CreationTime < now) 42 | { 43 | try 44 | { 45 | file.Delete(); 46 | } 47 | catch { } 48 | } 49 | } 50 | } 51 | catch { } 52 | }); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Tool/QueryableExtension.cs: -------------------------------------------------------------------------------- 1 | using System.Linq.Expressions; 2 | using System.Reflection; 3 | 4 | namespace v2rayN.Tool 5 | { 6 | public static class QueryableExtension 7 | { 8 | public static IOrderedQueryable OrderBy(this IQueryable query, string propertyName) 9 | { 10 | return _OrderBy(query, propertyName, false); 11 | } 12 | 13 | public static IOrderedQueryable OrderByDescending(this IQueryable query, string propertyName) 14 | { 15 | return _OrderBy(query, propertyName, true); 16 | } 17 | 18 | private static IOrderedQueryable _OrderBy(IQueryable query, string propertyName, bool isDesc) 19 | { 20 | string methodname = (isDesc) ? "OrderByDescendingInternal" : "OrderByInternal"; 21 | 22 | var memberProp = typeof(T).GetProperty(propertyName); 23 | 24 | var method = typeof(QueryableExtension).GetMethod(methodname) 25 | .MakeGenericMethod(typeof(T), memberProp.PropertyType); 26 | 27 | return (IOrderedQueryable)method.Invoke(null, new object[] { query, memberProp }); 28 | } 29 | 30 | public static IOrderedQueryable OrderByInternal(IQueryable query, PropertyInfo memberProperty) 31 | {//public 32 | return query.OrderBy(_GetLamba(memberProperty)); 33 | } 34 | 35 | public static IOrderedQueryable OrderByDescendingInternal(IQueryable query, PropertyInfo memberProperty) 36 | {//public 37 | return query.OrderByDescending(_GetLamba(memberProperty)); 38 | } 39 | 40 | private static Expression> _GetLamba(PropertyInfo memberProperty) 41 | { 42 | if (memberProperty.PropertyType != typeof(TProp)) throw new Exception(); 43 | 44 | var thisArg = Expression.Parameter(typeof(T)); 45 | var lamba = Expression.Lambda>(Expression.Property(thisArg, memberProperty), thisArg); 46 | 47 | return lamba; 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Tool/TestSpeed.cs: -------------------------------------------------------------------------------- 1 | using v2rayN; 2 | using Newtonsoft; 3 | using System.Diagnostics; 4 | using Newtonsoft.Json.Linq; 5 | using System.Net; 6 | using Newtonsoft.Json; 7 | using System.Windows.Navigation; 8 | 9 | namespace HiddifyN.Tool 10 | { 11 | public class TestSpeed 12 | { 13 | private string _appHttpProxy; 14 | public TestSpeed() 15 | { 16 | WebProxy p = (WebProxy)Utils.GetAppProxyAddress(); 17 | _appHttpProxy = p.Address.OriginalString; 18 | } 19 | 20 | public double? UploadSpeed(bool withProxy = true) 21 | { 22 | var sInfo = new ProcessStartInfo(); 23 | var extra = withProxy ? $"--http-proxy={_appHttpProxy}" : ""; 24 | sInfo = new ProcessStartInfo() 25 | { 26 | FileName = Global.SpeedTestProgramExePath, 27 | Arguments = $"--no-download --no-icmp --json {extra}", 28 | UseShellExecute = false, 29 | RedirectStandardOutput = true, 30 | RedirectStandardError = true, 31 | CreateNoWindow = true, 32 | }; 33 | 34 | 35 | // Start speed tester program and get its output or error and handle it 36 | var (stdout, stderr) = Utils.StartProcess(sInfo); 37 | if (stdout == null) 38 | { 39 | return null; 40 | } 41 | // Parse json result 42 | dynamic testerResult = JObject.Parse(ConvertJsonListToObject(stdout.Trim())); 43 | 44 | // Get download speed as Mbps 45 | double uploadSpeed = testerResult.upload; 46 | 47 | return uploadSpeed; 48 | 49 | } 50 | public double? DownloadSpeed(bool withProxy = true) 51 | { 52 | var sInfo = new ProcessStartInfo(); 53 | var extra = withProxy ? $"--http-proxy={_appHttpProxy}" : ""; 54 | sInfo = new ProcessStartInfo() 55 | { 56 | FileName = Global.SpeedTestProgramExePath, 57 | Arguments = $"--no-upload --no-icmp --json {extra}", 58 | UseShellExecute = false, 59 | RedirectStandardOutput = true, 60 | RedirectStandardError = true, 61 | CreateNoWindow = true, 62 | }; 63 | 64 | 65 | // Start speed tester program and get its output or error and handle it 66 | var (stdout, stderr) = Utils.StartProcess(sInfo); 67 | if (stdout == null) 68 | { 69 | return null; 70 | } 71 | // Parse json result 72 | dynamic testerResult = JObject.Parse(ConvertJsonListToObject(stdout.Trim())); 73 | 74 | // Get download speed as Mbps 75 | double downloadSpeed = testerResult.download; 76 | 77 | return downloadSpeed; 78 | } 79 | 80 | private string ConvertJsonListToObject(string j) 81 | { 82 | return j.Remove(j.Length- 1,1).Remove(0,1).Trim(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Tool/UI.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace v2rayN 4 | { 5 | internal class UI 6 | { 7 | private static readonly string caption = "HiddifyN"; 8 | 9 | public static void Show(string msg) 10 | { 11 | MessageBox.Show(msg, caption, MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK); 12 | } 13 | 14 | public static void ShowWarning(string msg) 15 | { 16 | MessageBox.Show(msg, caption, MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); 17 | } 18 | public static void ShowError(string msg) 19 | { 20 | MessageBox.Show(msg, caption, MessageBoxButton.OK, MessageBoxImage.Error); 21 | } 22 | 23 | public static MessageBoxResult ShowYesNo(string msg) 24 | { 25 | return MessageBox.Show(msg, caption, MessageBoxButton.YesNo, MessageBoxImage.Question); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/AddServer2ViewModel.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using ReactiveUI; 3 | using ReactiveUI.Fody.Helpers; 4 | using ReactiveUI.Validation.Helpers; 5 | using Splat; 6 | using System.IO; 7 | using System.Reactive; 8 | using System.Windows; 9 | using v2rayN.Base; 10 | using v2rayN.Handler; 11 | using v2rayN.Mode; 12 | using v2rayN.Resx; 13 | 14 | namespace v2rayN.ViewModels 15 | { 16 | public class AddServer2ViewModel : ReactiveValidationObject 17 | { 18 | private static Config _config; 19 | private NoticeHandler? _noticeHandler; 20 | private Window _view; 21 | 22 | [Reactive] 23 | public ProfileItem SelectedSource { get; set; } 24 | 25 | public ReactiveCommand BrowseServerCmd { get; } 26 | public ReactiveCommand EditServerCmd { get; } 27 | public ReactiveCommand SaveServerCmd { get; } 28 | public bool IsModified { get; set; } 29 | 30 | public AddServer2ViewModel(ProfileItem profileItem, Window view) 31 | { 32 | _noticeHandler = Locator.Current.GetService(); 33 | _config = LazyConfig.Instance.GetConfig(); 34 | 35 | if (profileItem.indexId.IsNullOrEmpty()) 36 | { 37 | SelectedSource = profileItem; 38 | } 39 | else 40 | { 41 | SelectedSource = Utils.DeepCopy(profileItem); 42 | } 43 | 44 | _view = view; 45 | 46 | BrowseServerCmd = ReactiveCommand.Create(() => 47 | { 48 | BrowseServer(); 49 | }); 50 | 51 | EditServerCmd = ReactiveCommand.Create(() => 52 | { 53 | EditServer(); 54 | }); 55 | 56 | SaveServerCmd = ReactiveCommand.Create(() => 57 | { 58 | SaveServer(); 59 | }); 60 | 61 | Utils.SetDarkBorder(view, _config.uiItem.colorModeDark); 62 | } 63 | 64 | private void SaveServer() 65 | { 66 | string remarks = SelectedSource.remarks; 67 | if (Utils.IsNullOrEmpty(remarks)) 68 | { 69 | UI.Show(ResUI.PleaseFillRemarks); 70 | return; 71 | } 72 | 73 | if (Utils.IsNullOrEmpty(SelectedSource.address)) 74 | { 75 | UI.Show(ResUI.FillServerAddressCustom); 76 | return; 77 | } 78 | 79 | var item = LazyConfig.Instance.GetProfileItem(SelectedSource.indexId); 80 | if (item is null) 81 | { 82 | item = SelectedSource; 83 | } 84 | else 85 | { 86 | item.remarks = SelectedSource.remarks; 87 | item.address = SelectedSource.address; 88 | item.coreType = SelectedSource.coreType; 89 | item.displayLog = SelectedSource.displayLog; 90 | item.preSocksPort = SelectedSource.preSocksPort; 91 | } 92 | 93 | if (ConfigHandler.EditCustomServer(ref _config, item) == 0) 94 | { 95 | _noticeHandler?.Enqueue(ResUI.OperationSuccess); 96 | _view.DialogResult = true; 97 | } 98 | else 99 | { 100 | UI.Show(ResUI.OperationFailed); 101 | } 102 | } 103 | 104 | private void BrowseServer() 105 | { 106 | UI.Show(ResUI.CustomServerTips); 107 | 108 | OpenFileDialog fileDialog = new() 109 | { 110 | Multiselect = false, 111 | Filter = "Config|*.json|YAML|*.yaml;*.yml|All|*.*" 112 | }; 113 | if (fileDialog.ShowDialog() != true) 114 | { 115 | return; 116 | } 117 | string fileName = fileDialog.FileName; 118 | if (Utils.IsNullOrEmpty(fileName)) 119 | { 120 | return; 121 | } 122 | var item = LazyConfig.Instance.GetProfileItem(SelectedSource.indexId); 123 | item ??= SelectedSource; 124 | item.address = fileName; 125 | if (ConfigHandler.AddCustomServer(ref _config, item, false) == 0) 126 | { 127 | _noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomServer); 128 | if (!Utils.IsNullOrEmpty(item.indexId)) 129 | { 130 | SelectedSource = Utils.DeepCopy(item); 131 | } 132 | IsModified = true; 133 | } 134 | else 135 | { 136 | UI.ShowWarning(ResUI.FailedImportedCustomServer); 137 | } 138 | } 139 | 140 | private void EditServer() 141 | { 142 | var address = SelectedSource.address; 143 | if (Utils.IsNullOrEmpty(address)) 144 | { 145 | UI.Show(ResUI.FillServerAddressCustom); 146 | return; 147 | } 148 | 149 | address = Utils.GetConfigPath(address); 150 | if (File.Exists(address)) 151 | { 152 | Utils.ProcessStart(address); 153 | } 154 | else 155 | { 156 | _noticeHandler?.Enqueue(ResUI.FailedReadConfiguration); 157 | } 158 | } 159 | } 160 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/AddServerViewModel.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using ReactiveUI.Fody.Helpers; 3 | using Splat; 4 | using System.Reactive; 5 | using System.Windows; 6 | using v2rayN.Base; 7 | using v2rayN.Handler; 8 | using v2rayN.Mode; 9 | using v2rayN.Resx; 10 | 11 | namespace v2rayN.ViewModels 12 | { 13 | public class AddServerViewModel : ReactiveObject 14 | { 15 | private static Config _config; 16 | private NoticeHandler? _noticeHandler; 17 | private Window _view; 18 | 19 | [Reactive] 20 | public ProfileItem SelectedSource { get; set; } 21 | 22 | public ReactiveCommand SaveCmd { get; } 23 | 24 | public AddServerViewModel(ProfileItem profileItem, Window view) 25 | { 26 | _config = LazyConfig.Instance.GetConfig(); 27 | _noticeHandler = Locator.Current.GetService(); 28 | _view = view; 29 | 30 | if (profileItem.id.IsNullOrEmpty()) 31 | { 32 | profileItem.network = Global.DefaultNetwork; 33 | profileItem.headerType = Global.None; 34 | profileItem.requestHost = ""; 35 | profileItem.streamSecurity = ""; 36 | SelectedSource = profileItem; 37 | } 38 | else 39 | { 40 | SelectedSource = Utils.DeepCopy(profileItem); 41 | } 42 | 43 | SaveCmd = ReactiveCommand.Create(() => 44 | { 45 | SaveServer(); 46 | }); 47 | 48 | Utils.SetDarkBorder(view, _config.uiItem.colorModeDark); 49 | } 50 | 51 | private void SaveServer() 52 | { 53 | if (Utils.IsNullOrEmpty(SelectedSource.remarks)) 54 | { 55 | UI.Show(ResUI.PleaseFillRemarks); 56 | return; 57 | } 58 | 59 | if (Utils.IsNullOrEmpty(SelectedSource.address)) 60 | { 61 | UI.Show(ResUI.FillServerAddress); 62 | return; 63 | } 64 | var port = SelectedSource.port.ToString(); 65 | if (Utils.IsNullOrEmpty(port) || !Utils.IsNumberic(port) 66 | || SelectedSource.port <= 0 || SelectedSource.port >= Global.MaxPort) 67 | { 68 | UI.Show(ResUI.FillCorrectServerPort); 69 | return; 70 | } 71 | if (SelectedSource.configType == EConfigType.Shadowsocks) 72 | { 73 | if (Utils.IsNullOrEmpty(SelectedSource.id)) 74 | { 75 | UI.Show(ResUI.FillPassword); 76 | return; 77 | } 78 | if (Utils.IsNullOrEmpty(SelectedSource.security)) 79 | { 80 | UI.Show(ResUI.PleaseSelectEncryption); 81 | return; 82 | } 83 | } 84 | if (SelectedSource.configType != EConfigType.Socks) 85 | { 86 | if (Utils.IsNullOrEmpty(SelectedSource.id)) 87 | { 88 | UI.Show(ResUI.FillUUID); 89 | return; 90 | } 91 | } 92 | 93 | var item = LazyConfig.Instance.GetProfileItem(SelectedSource.indexId); 94 | if (item is null) 95 | { 96 | item = SelectedSource; 97 | } 98 | else 99 | { 100 | item.coreType = SelectedSource.coreType; 101 | item.remarks = SelectedSource.remarks; 102 | item.address = SelectedSource.address; 103 | item.port = SelectedSource.port; 104 | 105 | item.id = SelectedSource.id; 106 | item.alterId = SelectedSource.alterId; 107 | item.security = SelectedSource.security; 108 | item.flow = SelectedSource.flow; 109 | 110 | item.network = SelectedSource.network; 111 | item.headerType = SelectedSource.headerType; 112 | item.requestHost = SelectedSource.requestHost; 113 | item.path = SelectedSource.path; 114 | item.fragment = SelectedSource.fragment; 115 | 116 | item.streamSecurity = SelectedSource.streamSecurity; 117 | item.sni = SelectedSource.sni; 118 | item.allowInsecure = SelectedSource.allowInsecure; 119 | item.fingerprint = SelectedSource.fingerprint; 120 | item.alpn = SelectedSource.alpn; 121 | 122 | item.publicKey = SelectedSource.publicKey; 123 | item.shortId = SelectedSource.shortId; 124 | item.spiderX = SelectedSource.spiderX; 125 | } 126 | 127 | int ret = -1; 128 | switch (item.configType) 129 | { 130 | case EConfigType.VMess: 131 | ret = ConfigHandler.AddServer(ref _config, item); 132 | break; 133 | 134 | case EConfigType.Shadowsocks: 135 | ret = ConfigHandler.AddShadowsocksServer(ref _config, item); 136 | break; 137 | 138 | case EConfigType.Socks: 139 | ret = ConfigHandler.AddSocksServer(ref _config, item); 140 | break; 141 | 142 | case EConfigType.VLESS: 143 | ret = ConfigHandler.AddVlessServer(ref _config, item); 144 | break; 145 | 146 | case EConfigType.Trojan: 147 | ret = ConfigHandler.AddTrojanServer(ref _config, item); 148 | break; 149 | } 150 | 151 | if (ret == 0) 152 | { 153 | _noticeHandler?.Enqueue(ResUI.OperationSuccess); 154 | _view.DialogResult = true; 155 | //_view?.Close(); 156 | } 157 | else 158 | { 159 | UI.Show(ResUI.OperationFailed); 160 | } 161 | } 162 | } 163 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/AnotherCommandImplementation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Input; 7 | 8 | namespace v2rayN.ViewModels 9 | { 10 | public class AnotherCommandImplementation : ICommand 11 | { 12 | private readonly Action _execute; 13 | private readonly Func _canExecute; 14 | 15 | public AnotherCommandImplementation(Action execute) 16 | : this(execute, null) 17 | { } 18 | 19 | public AnotherCommandImplementation(Action execute, Func? canExecute) 20 | { 21 | if (execute is null) throw new ArgumentNullException(nameof(execute)); 22 | 23 | _execute = execute; 24 | _canExecute = canExecute ?? (x => true); 25 | } 26 | 27 | public bool CanExecute(object? parameter) => _canExecute(parameter); 28 | 29 | public void Execute(object? parameter) => _execute(parameter); 30 | 31 | public event EventHandler? CanExecuteChanged 32 | { 33 | add 34 | { 35 | CommandManager.RequerySuggested += value; 36 | } 37 | remove 38 | { 39 | CommandManager.RequerySuggested -= value; 40 | } 41 | } 42 | 43 | public void Refresh() => CommandManager.InvalidateRequerySuggested(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using ReactiveUI.Fody.Helpers; 3 | using Splat; 4 | using System.Reactive; 5 | using System.Windows; 6 | using v2rayN.Handler; 7 | using v2rayN.Mode; 8 | using v2rayN.Resx; 9 | 10 | namespace v2rayN.ViewModels 11 | { 12 | public class DNSSettingViewModel : ReactiveObject 13 | { 14 | private static Config _config; 15 | private NoticeHandler? _noticeHandler; 16 | private Window _view; 17 | 18 | [Reactive] public string domainStrategy4Freedom { get; set; } 19 | [Reactive] public string normalDNS { get; set; } 20 | [Reactive] public string normalDNS2 { get; set; } 21 | 22 | public ReactiveCommand SaveCmd { get; } 23 | public ReactiveCommand ImportDefConfig4V2rayCmd { get; } 24 | public ReactiveCommand ImportDefConfig4SingboxCmd { get; } 25 | 26 | public DNSSettingViewModel(Window view) 27 | { 28 | _config = LazyConfig.Instance.GetConfig(); 29 | _noticeHandler = Locator.Current.GetService(); 30 | _view = view; 31 | 32 | var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray); 33 | domainStrategy4Freedom = item?.domainStrategy4Freedom!; 34 | normalDNS = item?.normalDNS!; 35 | 36 | var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); 37 | normalDNS2 = item2?.normalDNS!; 38 | 39 | SaveCmd = ReactiveCommand.Create(() => 40 | { 41 | SaveSetting(); 42 | }); 43 | 44 | ImportDefConfig4V2rayCmd = ReactiveCommand.Create(() => 45 | { 46 | normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName); 47 | }); 48 | 49 | ImportDefConfig4SingboxCmd = ReactiveCommand.Create(() => 50 | { 51 | normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName); 52 | }); 53 | 54 | Utils.SetDarkBorder(view, _config.uiItem.colorModeDark); 55 | } 56 | 57 | private void SaveSetting() 58 | { 59 | if (!Utils.IsNullOrEmpty(normalDNS)) 60 | { 61 | var obj = Utils.ParseJson(normalDNS); 62 | if (obj != null && obj.ContainsKey("servers") == true) 63 | { 64 | } 65 | else 66 | { 67 | if (normalDNS.Contains("{") || normalDNS.Contains("}")) 68 | { 69 | UI.Show(ResUI.FillCorrectDNSText); 70 | return; 71 | } 72 | } 73 | } 74 | if (!Utils.IsNullOrEmpty(normalDNS2)) 75 | { 76 | var obj2 = Utils.FromJson(normalDNS2); 77 | if (obj2 == null) 78 | { 79 | UI.Show(ResUI.FillCorrectDNSText); 80 | return; 81 | } 82 | } 83 | 84 | var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray); 85 | item.domainStrategy4Freedom = domainStrategy4Freedom; 86 | item.normalDNS = normalDNS; 87 | ConfigHandler.SaveDNSItems(_config, item); 88 | 89 | var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box); 90 | item2.normalDNS = Utils.ToJson(Utils.ParseJson(normalDNS2)); 91 | ConfigHandler.SaveDNSItems(_config, item2); 92 | 93 | _noticeHandler?.Enqueue(ResUI.OperationSuccess); 94 | _view.DialogResult = true; 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/DemoItem.cs: -------------------------------------------------------------------------------- 1 | using MaterialDesignThemes.Wpf; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Controls; 8 | using System.Windows; 9 | 10 | namespace v2rayN.ViewModels 11 | { 12 | public class DemoItem : ViewModelBase 13 | { 14 | private readonly Type _contentType; 15 | private readonly object? _dataContext; 16 | 17 | private object? _content; 18 | private ScrollBarVisibility _horizontalScrollBarVisibilityRequirement; 19 | private ScrollBarVisibility _verticalScrollBarVisibilityRequirement = ScrollBarVisibility.Auto; 20 | private Thickness _marginRequirement = new(16); 21 | 22 | private int _notificationNumber = 0; 23 | 24 | public DemoItem(string name, Type contentType, 25 | PackIconKind selectedIcon, PackIconKind unselectedIcon, object? dataContext = null) 26 | { 27 | Name = name; 28 | _contentType = contentType; 29 | _dataContext = dataContext; 30 | 31 | SelectedIcon = selectedIcon; 32 | UnselectedIcon = unselectedIcon; 33 | } 34 | 35 | public string Name { get; } 36 | 37 | 38 | public object? Content => _content ??= CreateContent(); 39 | 40 | public PackIconKind SelectedIcon { get; set; } 41 | public PackIconKind UnselectedIcon { get; set; } 42 | 43 | public object? Notifications 44 | { 45 | get 46 | { 47 | if (_notificationNumber == 0) return null; 48 | else return _notificationNumber < 100 ? _notificationNumber : "99+"; 49 | } 50 | } 51 | 52 | public ScrollBarVisibility HorizontalScrollBarVisibilityRequirement 53 | { 54 | get => _horizontalScrollBarVisibilityRequirement; 55 | set => SetProperty(ref _horizontalScrollBarVisibilityRequirement, value); 56 | } 57 | 58 | public ScrollBarVisibility VerticalScrollBarVisibilityRequirement 59 | { 60 | get => _verticalScrollBarVisibilityRequirement; 61 | set => SetProperty(ref _verticalScrollBarVisibilityRequirement, value); 62 | } 63 | 64 | public Thickness MarginRequirement 65 | { 66 | get => _marginRequirement; 67 | set => SetProperty(ref _marginRequirement, value); 68 | } 69 | 70 | private object? CreateContent() 71 | { 72 | var content = Activator.CreateInstance(_contentType); 73 | if (_dataContext != null && content is FrameworkElement element) 74 | { 75 | element.DataContext = _dataContext; 76 | } 77 | 78 | return content; 79 | } 80 | 81 | public void AddNewNotification() 82 | { 83 | _notificationNumber++; 84 | OnPropertyChanged(nameof(Notifications)); 85 | } 86 | 87 | public void DismissAllNotifications() 88 | { 89 | _notificationNumber = 0; 90 | OnPropertyChanged(nameof(Notifications)); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/HomeWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using Google.Protobuf.Collections; 2 | using Google.Protobuf.WellKnownTypes; 3 | using MaterialDesignThemes.Wpf; 4 | using MaterialDesignThemes.Wpf.Transitions; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Collections.ObjectModel; 8 | using System.ComponentModel; 9 | using System.Configuration; 10 | using System.Diagnostics; 11 | using System.Linq; 12 | using System.Text; 13 | using System.Threading.Tasks; 14 | using System.Windows.Controls; 15 | using System.Windows.Data; 16 | using System.Windows.Documents; 17 | using v2rayN.Views; 18 | 19 | using v2rayN.ViewModels; 20 | using v2rayN.Converters; 21 | using v2rayN.Mode; 22 | 23 | namespace v2rayN.ViewModels 24 | { 25 | public class HomeWindowViewModel : ViewModelBase 26 | { 27 | 28 | public HomeWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue) 29 | { 30 | _snackbarMessageQueue = snackbarMessageQueue; 31 | DemoItems = new ObservableCollection 32 | { 33 | new DemoItem( 34 | "Home", 35 | typeof(MainWindow), 36 | selectedIcon: PackIconKind.Home, 37 | unselectedIcon: PackIconKind.HomeOutline) 38 | }; 39 | 40 | 41 | MainDemoItems = new ObservableCollection 42 | { 43 | }; 44 | 45 | _demoItemsView = CollectionViewSource.GetDefaultView(DemoItems); 46 | 47 | 48 | 49 | DismissAllNotificationsCommand = new AnotherCommandImplementation( 50 | _ => DemoItems[0].DismissAllNotifications(), 51 | _ => DemoItems[0].Notifications != null); 52 | 53 | AddNewNotificationCommand = new AnotherCommandImplementation( 54 | _ => DemoItems[0].AddNewNotification()); 55 | 56 | AddNewNotificationCommand.Execute(new object()); 57 | 58 | NewProfileCommand = new AnotherCommandImplementation(ExecuteNewProfileDialog); 59 | Items1 = new ObservableCollection() 60 | { 61 | _selectedProfile, 62 | new SubItem 63 | { 64 | id = "A", 65 | remarks = "Profile2", 66 | url= "XAML Toolkit" 67 | }, 68 | new SubItem 69 | { 70 | id = "B", 71 | remarks = "Profile3", 72 | url= "Material Design in XAML Toolkit" 73 | }, 74 | new SubItem 75 | { 76 | id = "C", 77 | remarks = "Profile4", 78 | url= "Material " 79 | }, 80 | }; 81 | 82 | } 83 | private async void ExecuteNewProfileDialog(object? _) 84 | { 85 | //let's set up a little MVVM, cos that's what the cool kids are doing: 86 | 87 | 88 | //show the dialog 89 | _snackbarMessageQueue.Enqueue("Nothing find in the Clipboard"); 90 | 91 | //check the result... 92 | 93 | } 94 | private SubItem _selectedProfile = new SubItem 95 | { 96 | id = "A", 97 | remarks = "Profile 1", 98 | url = "XAML Toolkit" 99 | }; 100 | public SubItem SelectedProfile { get => _selectedProfile; set => SetProperty(ref _selectedProfile, value); } 101 | public ObservableCollection Items1 { get; } 102 | 103 | private readonly ICollectionView _demoItemsView; 104 | private DemoItem? _selectedItem; 105 | private int _selectedIndex; 106 | private string? _searchKeyword; 107 | private bool _controlsEnabled = true; 108 | private ISnackbarMessageQueue _snackbarMessageQueue; 109 | 110 | public ObservableCollection DemoItems { get; } 111 | public ObservableCollection MainDemoItems { get; } 112 | 113 | public DemoItem? SelectedItem 114 | { 115 | get => _selectedItem; 116 | set => SetProperty(ref _selectedItem, value); 117 | } 118 | 119 | public int SelectedIndex 120 | { 121 | get => _selectedIndex; 122 | set => SetProperty(ref _selectedIndex, value); 123 | } 124 | private bool _connectProgress = false; 125 | public bool ConnectProgress { 126 | get =>_connectProgress; 127 | set => SetProperty(ref _connectProgress, value); 128 | } 129 | public bool ControlsEnabled 130 | { 131 | get => _controlsEnabled; 132 | set => SetProperty(ref _controlsEnabled, value); 133 | } 134 | 135 | 136 | public AnotherCommandImplementation DismissAllNotificationsCommand { get; } 137 | public AnotherCommandImplementation AddNewNotificationCommand { get; } 138 | public AnotherCommandImplementation NewProfileCommand { get; } 139 | 140 | private static IEnumerable GenerateDemoItems(ISnackbarMessageQueue snackbarMessageQueue) 141 | { 142 | if (snackbarMessageQueue is null) 143 | throw new ArgumentNullException(nameof(snackbarMessageQueue)); 144 | 145 | yield return null; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using ReactiveUI.Fody.Helpers; 3 | using Splat; 4 | using System.Reactive; 5 | using System.Windows; 6 | using v2rayN.Base; 7 | using v2rayN.Handler; 8 | using v2rayN.Mode; 9 | using v2rayN.Resx; 10 | 11 | namespace v2rayN.ViewModels 12 | { 13 | public class RoutingRuleDetailsViewModel : ReactiveObject 14 | { 15 | private static Config _config; 16 | private NoticeHandler? _noticeHandler; 17 | private Window _view; 18 | 19 | public IList ProtocolItems { get; set; } 20 | public IList InboundTagItems { get; set; } 21 | 22 | [Reactive] 23 | public RulesItem SelectedSource { get; set; } 24 | 25 | [Reactive] 26 | public string Domain { get; set; } 27 | 28 | [Reactive] 29 | public string IP { get; set; } 30 | 31 | [Reactive] 32 | public bool AutoSort { get; set; } 33 | 34 | public ReactiveCommand SaveCmd { get; } 35 | 36 | public RoutingRuleDetailsViewModel(RulesItem rulesItem, Window view) 37 | { 38 | _config = LazyConfig.Instance.GetConfig(); 39 | _noticeHandler = Locator.Current.GetService(); 40 | _view = view; 41 | 42 | if (rulesItem.id.IsNullOrEmpty()) 43 | { 44 | rulesItem.id = Utils.GetGUID(false); 45 | rulesItem.outboundTag = Global.agentTag; 46 | rulesItem.enabled = true; 47 | SelectedSource = rulesItem; 48 | } 49 | else 50 | { 51 | SelectedSource = rulesItem; 52 | } 53 | 54 | Domain = Utils.List2String(SelectedSource.domain, true); 55 | IP = Utils.List2String(SelectedSource.ip, true); 56 | 57 | SaveCmd = ReactiveCommand.Create(() => 58 | { 59 | SaveRules(); 60 | }); 61 | 62 | Utils.SetDarkBorder(view, _config.uiItem.colorModeDark); 63 | } 64 | 65 | private void SaveRules() 66 | { 67 | Domain = Utils.Convert2Comma(Domain); 68 | IP = Utils.Convert2Comma(IP); 69 | 70 | if (AutoSort) 71 | { 72 | SelectedSource.domain = Utils.String2ListSorted(Domain); 73 | SelectedSource.ip = Utils.String2ListSorted(IP); 74 | } 75 | else 76 | { 77 | SelectedSource.domain = Utils.String2List(Domain); 78 | SelectedSource.ip = Utils.String2List(IP); 79 | } 80 | SelectedSource.protocol = ProtocolItems?.ToList(); 81 | SelectedSource.inboundTag = InboundTagItems?.ToList(); 82 | 83 | bool hasRule = 84 | SelectedSource.domain != null 85 | && SelectedSource.domain.Count > 0 86 | || SelectedSource.ip != null 87 | && SelectedSource.ip.Count > 0 88 | || SelectedSource.protocol != null 89 | && SelectedSource.protocol.Count > 0 90 | || !Utils.IsNullOrEmpty(SelectedSource.port); 91 | 92 | if (!hasRule) 93 | { 94 | UI.ShowWarning(string.Format(ResUI.RoutingRuleDetailRequiredTips, "Port/Protocol/Domain/IP")); 95 | return; 96 | } 97 | //_noticeHandler?.Enqueue(ResUI.OperationSuccess); 98 | _view.DialogResult = true; 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/SubEditViewModel.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using ReactiveUI.Fody.Helpers; 3 | using Splat; 4 | using System.Reactive; 5 | using System.Windows; 6 | using v2rayN.Base; 7 | using v2rayN.Handler; 8 | using v2rayN.Mode; 9 | using v2rayN.Resx; 10 | 11 | namespace v2rayN.ViewModels 12 | { 13 | public class SubEditViewModel : ReactiveObject 14 | { 15 | private static Config _config; 16 | private NoticeHandler? _noticeHandler; 17 | private Window _view; 18 | 19 | [Reactive] 20 | public SubItem SelectedSource { get; set; } 21 | 22 | public ReactiveCommand SaveCmd { get; } 23 | 24 | public SubEditViewModel(SubItem subItem, Window view) 25 | { 26 | _config = LazyConfig.Instance.GetConfig(); 27 | _noticeHandler = Locator.Current.GetService(); 28 | _view = view; 29 | 30 | if (subItem.id.IsNullOrEmpty()) 31 | { 32 | SelectedSource = subItem; 33 | } 34 | else 35 | { 36 | SelectedSource = Utils.DeepCopy(subItem); 37 | } 38 | 39 | SaveCmd = ReactiveCommand.Create(() => 40 | { 41 | SaveSub(); 42 | }); 43 | 44 | Utils.SetDarkBorder(view, _config.uiItem.colorModeDark); 45 | } 46 | 47 | private void SaveSub() 48 | { 49 | string remarks = SelectedSource.remarks; 50 | if (Utils.IsNullOrEmpty(remarks)) 51 | { 52 | UI.Show(ResUI.PleaseFillRemarks); 53 | return; 54 | } 55 | 56 | var item = LazyConfig.Instance.GetSubItem(SelectedSource.id); 57 | if (item is null) 58 | { 59 | item = SelectedSource; 60 | } 61 | else 62 | { 63 | item.remarks = SelectedSource.remarks; 64 | item.url = SelectedSource.url; 65 | item.moreUrl = SelectedSource.moreUrl; 66 | item.enabled = SelectedSource.enabled; 67 | item.profileUpdateInterval = SelectedSource.profileUpdateInterval; 68 | item.userAgent = SelectedSource.userAgent; 69 | item.sort = SelectedSource.sort; 70 | item.filter = SelectedSource.filter; 71 | item.convertTarget = SelectedSource.convertTarget; 72 | } 73 | 74 | if (ConfigHandler.AddSubItem(ref _config, item) == 0) 75 | { 76 | _noticeHandler?.Enqueue(ResUI.OperationSuccess); 77 | if (_view.IsActive) 78 | { 79 | _view.DialogResult = true; 80 | } 81 | //_view?.Close(); 82 | } 83 | else 84 | { 85 | _noticeHandler?.Enqueue(ResUI.OperationFailed); 86 | } 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/SubSettingViewModel.cs: -------------------------------------------------------------------------------- 1 | using DynamicData; 2 | using DynamicData.Binding; 3 | using MaterialDesignThemes.Wpf; 4 | using ReactiveUI; 5 | using ReactiveUI.Fody.Helpers; 6 | using Splat; 7 | using System.Reactive; 8 | using System.Windows; 9 | using v2rayN.Base; 10 | using v2rayN.Handler; 11 | using v2rayN.Mode; 12 | using v2rayN.Resx; 13 | using v2rayN.Views; 14 | 15 | namespace v2rayN.ViewModels 16 | { 17 | public class SubSettingViewModel : ReactiveObject 18 | { 19 | private static Config _config; 20 | private NoticeHandler? _noticeHandler; 21 | 22 | private IObservableCollection _subItems = new ObservableCollectionExtended(); 23 | public IObservableCollection SubItems => _subItems; 24 | 25 | [Reactive] 26 | public SubItem SelectedSource { get; set; } 27 | 28 | public IList SelectedSources { get; set; } 29 | 30 | public ReactiveCommand SubAddCmd { get; } 31 | public ReactiveCommand SubDeleteCmd { get; } 32 | public ReactiveCommand SubEditCmd { get; } 33 | public ReactiveCommand SubShareCmd { get; } 34 | public bool IsModified { get; set; } 35 | 36 | public SubSettingViewModel(Window view) 37 | { 38 | _config = LazyConfig.Instance.GetConfig(); 39 | _noticeHandler = Locator.Current.GetService(); 40 | 41 | SelectedSource = new(); 42 | 43 | RefreshSubItems(); 44 | 45 | var canEditRemove = this.WhenAnyValue( 46 | x => x.SelectedSource, 47 | selectedSource => selectedSource != null && !selectedSource.id.IsNullOrEmpty()); 48 | 49 | SubAddCmd = ReactiveCommand.Create(() => 50 | { 51 | EditSub(true); 52 | }); 53 | SubDeleteCmd = ReactiveCommand.Create(() => 54 | { 55 | DeleteSub(); 56 | }, canEditRemove); 57 | SubEditCmd = ReactiveCommand.Create(() => 58 | { 59 | EditSub(false); 60 | }, canEditRemove); 61 | SubShareCmd = ReactiveCommand.Create(() => 62 | { 63 | SubShare(); 64 | }, canEditRemove); 65 | 66 | Utils.SetDarkBorder(view, _config.uiItem.colorModeDark); 67 | } 68 | 69 | public void RefreshSubItems() 70 | { 71 | _subItems.Clear(); 72 | _subItems.AddRange(LazyConfig.Instance.SubItems().OrderByDescending(t => t.sort)); 73 | } 74 | 75 | public void EditSub(bool blNew) 76 | { 77 | SubItem item; 78 | if (blNew) 79 | { 80 | item = new(); 81 | } 82 | else 83 | { 84 | item = LazyConfig.Instance.GetSubItem(SelectedSource?.id); 85 | if (item is null) 86 | { 87 | return; 88 | } 89 | } 90 | var ret = (new SubEditWindow(item)).ShowDialog(); 91 | if (ret == true) 92 | { 93 | RefreshSubItems(); 94 | IsModified = true; 95 | } 96 | } 97 | 98 | private void DeleteSub() 99 | { 100 | if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No) 101 | { 102 | return; 103 | } 104 | 105 | foreach (var it in SelectedSources) 106 | { 107 | ConfigHandler.DeleteSubItem(ref _config, it?.id); 108 | } 109 | RefreshSubItems(); 110 | _noticeHandler?.Enqueue(ResUI.OperationSuccess); 111 | IsModified = true; 112 | } 113 | 114 | private async void SubShare() 115 | { 116 | if (Utils.IsNullOrEmpty(SelectedSource?.url)) 117 | { 118 | return; 119 | } 120 | var img = QRCodeHelper.GetQRCode(SelectedSource?.url); 121 | var dialog = new QrcodeView() 122 | { 123 | imgQrcode = { Source = img }, 124 | txtContent = { Text = SelectedSource?.url }, 125 | }; 126 | 127 | await DialogHost.Show(dialog, "SubDialog"); 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/ViewModels/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Runtime.CompilerServices; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace v2rayN.ViewModels 11 | { 12 | public abstract class ViewModelBase : ReactiveObject, INotifyPropertyChanged 13 | { 14 | public event PropertyChangedEventHandler? PropertyChanged; 15 | 16 | /// 17 | /// Sets property if it does not equal existing value. Notifies listeners if change occurs. 18 | /// 19 | /// Type of property. 20 | /// The property's backing field. 21 | /// The new value. 22 | /// Name of the property used to notify listeners. This 23 | /// value is optional and can be provided automatically when invoked from compilers 24 | /// that support . 25 | protected virtual bool SetProperty(ref T member, T value, [CallerMemberName] string? propertyName = null) 26 | { 27 | if (EqualityComparer.Default.Equals(member, value)) 28 | { 29 | return false; 30 | } 31 | 32 | member = value; 33 | OnPropertyChanged(propertyName); 34 | return true; 35 | } 36 | 37 | /// 38 | /// Notifies listeners that a property value has changed. 39 | /// 40 | /// Name of the property, used to notify listeners. 41 | protected void OnPropertyChanged([CallerMemberName] string? propertyName = null) 42 | => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/AddServer2Window.xaml.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using System.Reactive.Disposables; 3 | using System.Windows; 4 | using v2rayN.Mode; 5 | using v2rayN.ViewModels; 6 | 7 | namespace v2rayN.Views 8 | { 9 | public partial class AddServer2Window 10 | { 11 | public AddServer2Window(ProfileItem profileItem) 12 | { 13 | InitializeComponent(); 14 | this.Owner = Application.Current.MainWindow; 15 | this.Loaded += Window_Loaded; 16 | ViewModel = new AddServer2ViewModel(profileItem, this); 17 | 18 | foreach (ECoreType it in Enum.GetValues(typeof(ECoreType))) 19 | { 20 | if (it == ECoreType.v2rayN) 21 | continue; 22 | cmbCoreType.Items.Add(it.ToString()); 23 | } 24 | cmbCoreType.Items.Add(string.Empty); 25 | 26 | this.WhenActivated(disposables => 27 | { 28 | this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables); 29 | this.Bind(ViewModel, vm => vm.SelectedSource.address, v => v.txtAddress.Text).DisposeWith(disposables); 30 | this.Bind(ViewModel, vm => vm.SelectedSource.coreType, v => v.cmbCoreType.Text).DisposeWith(disposables); 31 | this.Bind(ViewModel, vm => vm.SelectedSource.displayLog, v => v.togDisplayLog.IsChecked).DisposeWith(disposables); 32 | this.Bind(ViewModel, vm => vm.SelectedSource.preSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables); 33 | 34 | this.BindCommand(ViewModel, vm => vm.BrowseServerCmd, v => v.btnBrowse).DisposeWith(disposables); 35 | this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables); 36 | this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables); 37 | }); 38 | } 39 | 40 | private void Window_Loaded(object sender, RoutedEventArgs e) 41 | { 42 | txtRemarks.Focus(); 43 | } 44 | 45 | private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e) 46 | { 47 | if (ViewModel?.IsModified == true) 48 | { 49 | this.DialogResult = true; 50 | } 51 | else 52 | { 53 | this.Close(); 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using ReactiveUI; 2 | using System.Reactive.Disposables; 3 | using System.Windows; 4 | using v2rayN.Handler; 5 | using v2rayN.Mode; 6 | using v2rayN.ViewModels; 7 | 8 | namespace v2rayN.Views 9 | { 10 | public partial class DNSSettingWindow 11 | { 12 | private static Config _config; 13 | 14 | public DNSSettingWindow() 15 | { 16 | InitializeComponent(); 17 | this.Owner = Application.Current.MainWindow; 18 | _config = LazyConfig.Instance.GetConfig(); 19 | 20 | ViewModel = new DNSSettingViewModel(this); 21 | 22 | Global.domainStrategy4Freedoms.ForEach(it => 23 | { 24 | cmbdomainStrategy4Freedom.Items.Add(it); 25 | }); 26 | 27 | this.WhenActivated(disposables => 28 | { 29 | this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables); 30 | this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables); 31 | this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables); 32 | 33 | this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables); 34 | this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables); 35 | this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables); 36 | }); 37 | } 38 | 39 | private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e) 40 | { 41 | Utils.ProcessStart("https://www.v2fly.org/config/dns.html#dnsobject"); 42 | } 43 | 44 | private void linkDnsSingboxObjectDoc_Click(object sender, RoutedEventArgs e) 45 | { 46 | Utils.ProcessStart("http://sing-box.sagernet.org/zh/configuration/dns/"); 47 | } 48 | 49 | private void btnCancel_Click(object sender, RoutedEventArgs e) 50 | { 51 | this.Close(); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Windows; 3 | using System.Windows.Controls; 4 | using System.Windows.Input; 5 | using v2rayN.Handler; 6 | using v2rayN.Mode; 7 | using v2rayN.Resx; 8 | 9 | namespace v2rayN.Views 10 | { 11 | public partial class GlobalHotkeySettingWindow 12 | { 13 | private static Config _config = default!; 14 | private Dictionary _TextBoxKeyEventItem = default!; 15 | 16 | public GlobalHotkeySettingWindow() 17 | { 18 | InitializeComponent(); 19 | this.Owner = Application.Current.MainWindow; 20 | _config = LazyConfig.Instance.GetConfig(); 21 | _config.globalHotkeys ??= new List(); 22 | 23 | txtGlobalHotkey0.KeyDown += TxtGlobalHotkey_KeyDown; 24 | txtGlobalHotkey1.KeyDown += TxtGlobalHotkey_KeyDown; 25 | txtGlobalHotkey2.KeyDown += TxtGlobalHotkey_KeyDown; 26 | txtGlobalHotkey3.KeyDown += TxtGlobalHotkey_KeyDown; 27 | txtGlobalHotkey4.KeyDown += TxtGlobalHotkey_KeyDown; 28 | 29 | HotkeyHandler.Instance.IsPause = true; 30 | this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false; 31 | Utils.SetDarkBorder(this, _config.uiItem.colorModeDark); 32 | InitData(); 33 | } 34 | 35 | private void InitData() 36 | { 37 | _TextBoxKeyEventItem = new() 38 | { 39 | { txtGlobalHotkey0,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.ShowForm) }, 40 | { txtGlobalHotkey1,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyClear) }, 41 | { txtGlobalHotkey2,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxySet) }, 42 | { txtGlobalHotkey3,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyUnchanged)}, 43 | { txtGlobalHotkey4,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyPac)} 44 | }; 45 | BindingData(); 46 | } 47 | 48 | private void TxtGlobalHotkey_KeyDown(object sender, KeyEventArgs e) 49 | { 50 | e.Handled = true; 51 | var _ModifierKeys = new Key[] { Key.LeftCtrl, Key.RightCtrl, Key.LeftShift, 52 | Key.RightShift, Key.LeftAlt, Key.RightAlt, Key.LWin, Key.RWin}; 53 | _TextBoxKeyEventItem[sender].KeyCode = e.Key == Key.System ? (_ModifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (_ModifierKeys.Contains(e.Key) ? Key.None : e.Key); 54 | _TextBoxKeyEventItem[sender].Alt = (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt; 55 | _TextBoxKeyEventItem[sender].Control = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control; 56 | _TextBoxKeyEventItem[sender].Shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift; 57 | (sender as TextBox)!.Text = KeyEventItemToString(_TextBoxKeyEventItem[sender]); 58 | } 59 | 60 | private KeyEventItem GetKeyEventItemByEGlobalHotkey(List KELsit, EGlobalHotkey eg) 61 | { 62 | return Utils.DeepCopy(KELsit.Find((it) => it.eGlobalHotkey == eg) ?? new() 63 | { 64 | eGlobalHotkey = eg, 65 | Control = false, 66 | Alt = false, 67 | Shift = false, 68 | KeyCode = null 69 | }); 70 | } 71 | 72 | private string KeyEventItemToString(KeyEventItem item) 73 | { 74 | var res = new StringBuilder(); 75 | 76 | if (item.Control) res.Append($"{ModifierKeys.Control}+"); 77 | if (item.Shift) res.Append($"{ModifierKeys.Shift}+"); 78 | if (item.Alt) res.Append($"{ModifierKeys.Alt}+"); 79 | if (item.KeyCode != null && item.KeyCode != Key.None) 80 | res.Append($"{item.KeyCode}"); 81 | 82 | return res.ToString(); 83 | } 84 | 85 | private void BindingData() 86 | { 87 | foreach (var item in _TextBoxKeyEventItem) 88 | { 89 | if (item.Value.KeyCode != null && item.Value.KeyCode != Key.None) 90 | { 91 | (item.Key as TextBox)!.Text = KeyEventItemToString(item.Value); 92 | } 93 | else 94 | { 95 | (item.Key as TextBox)!.Text = string.Empty; 96 | } 97 | } 98 | } 99 | 100 | private void btnSave_Click(object sender, RoutedEventArgs e) 101 | { 102 | _config.globalHotkeys = _TextBoxKeyEventItem.Values.ToList(); 103 | 104 | if (ConfigHandler.SaveConfig(ref _config, false) == 0) 105 | { 106 | HotkeyHandler.Instance.ReLoad(); 107 | this.DialogResult = true; 108 | } 109 | else 110 | { 111 | UI.ShowWarning(ResUI.OperationFailed); 112 | } 113 | } 114 | 115 | private void btnCancel_Click(object sender, RoutedEventArgs e) 116 | { 117 | this.Close(); 118 | } 119 | 120 | private void btnReset_Click(object sender, RoutedEventArgs e) 121 | { 122 | foreach (var k in _TextBoxKeyEventItem.Keys) 123 | { 124 | _TextBoxKeyEventItem[k].Alt = false; 125 | _TextBoxKeyEventItem[k].Control = false; 126 | _TextBoxKeyEventItem[k].Shift = false; 127 | _TextBoxKeyEventItem[k].KeyCode = Key.None; 128 | } 129 | BindingData(); 130 | } 131 | 132 | private void GlobalHotkeySettingWindow_KeyDown(object sender, KeyEventArgs e) 133 | { 134 | if (e.Key == Key.Escape) 135 | { 136 | this.Close(); 137 | } 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/HiddifyUI.xaml.cs: -------------------------------------------------------------------------------- 1 | using MaterialDesignThemes.Wpf; 2 | using ReactiveUI; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | using System.Windows.Data; 12 | using System.Windows.Documents; 13 | using System.Windows.Input; 14 | using System.Windows.Media; 15 | using System.Windows.Media.Imaging; 16 | using System.Windows.Navigation; 17 | using System.Windows.Shapes; 18 | using v2rayN.Resx; 19 | using v2rayN.ViewModels; 20 | 21 | namespace v2rayN.Views 22 | { 23 | /// 24 | /// Interaction logic for HiddifyUI.xaml 25 | /// 26 | public partial class HiddifyUI : UserControl 27 | { 28 | public static Snackbar Snackbar = new(); 29 | public bool ShowTitleBar { 30 | get => titlebar.Visibility == Visibility.Visible; 31 | set { 32 | titlebar.Visibility = value ? Visibility.Visible : Visibility.Collapsed; 33 | } 34 | } 35 | 36 | 37 | public HiddifyUI() 38 | { 39 | InitializeComponent(); 40 | //FlowDirection = FlowDirection.RightToLeft; 41 | Task.Factory.StartNew(() => Thread.Sleep(2500)).ContinueWith(t => 42 | { 43 | //note you can use the message queue from any thread, but just for the demo here we 44 | //need to get the message queue from the snackbar, so need to be on the dispatcher 45 | MainSnackbar.MessageQueue?.Enqueue(ResUI.HomeWelcomeMsg); 46 | }, TaskScheduler.FromCurrentSynchronizationContext()); 47 | 48 | 49 | Global.Languages.ForEach(it => 50 | { 51 | cmbCurrentLanguage.Items.Add(it); 52 | }); 53 | 54 | ModifyTheme(false); 55 | 56 | } 57 | private void OnCopy(object sender, ExecutedRoutedEventArgs e) 58 | { 59 | if (e.Parameter is string stringValue) 60 | { 61 | try 62 | { 63 | Clipboard.SetDataObject(stringValue); 64 | } 65 | catch (Exception ex) 66 | { 67 | Trace.WriteLine(ex.ToString()); 68 | } 69 | } 70 | } 71 | 72 | private void MenuToggleButton_Click(object sender, RoutedEventArgs e) 73 | { 74 | 75 | } 76 | 77 | private void MenuDarkModeButton_Click(object sender, RoutedEventArgs e) 78 | { 79 | 80 | // => ModifyTheme(DarkModeToggleButton.IsChecked == true); 81 | } 82 | 83 | private static void ModifyTheme(bool isDarkTheme) 84 | { 85 | var paletteHelper = new PaletteHelper(); 86 | var theme = paletteHelper.GetTheme(); 87 | 88 | theme.SetBaseTheme(isDarkTheme ? Theme.Dark : Theme.Light); 89 | paletteHelper.SetTheme(theme); 90 | } 91 | 92 | private void DarkModeToggleButton_Click(object sender, RoutedEventArgs e) 93 | { 94 | 95 | } 96 | 97 | private void DarkModeToggleButton_Click_1(object sender, RoutedEventArgs e) 98 | { 99 | 100 | } 101 | private void CloseNotificationPanel_Click(object sender, RoutedEventArgs e) => NotificationPanel.Visibility = Visibility.Collapsed; 102 | 103 | private void FAB_Click(object sender, RoutedEventArgs e) 104 | { 105 | 106 | } 107 | 108 | private void ConnectVPN_Click(object sender, RoutedEventArgs e) 109 | { 110 | 111 | ConnectVPN.Background = new SolidColorBrush(Color.FromRgb(0xFF, 0xF2, 0x67)); 112 | //((HomeWindowViewModel)DataContext).ConnectProgress = true; 113 | connectlbl.Content = "Connecting..."; 114 | Task.Factory.StartNew(() => Thread.Sleep(2500)).ContinueWith(t => 115 | { 116 | speedpanel.Visibility = Visibility.Visible; 117 | //((ViewModels.HiddifyUIViewModel)DataContext).ConnectProgress = false; 118 | ConnectVPN.Background = new SolidColorBrush(Colors.LightGreen); 119 | connectlbl.Content = "Connected Successfully"; 120 | }, TaskScheduler.FromCurrentSynchronizationContext()); 121 | 122 | //var xx = this.DataContext as MainWindowViewModel; 123 | //Console.WriteLine(); 124 | } 125 | 126 | private void NewProfile_Click(object sender, RoutedEventArgs e) 127 | { 128 | MessageBox.Show("Going to User Page"); 129 | } 130 | 131 | 132 | private void ActiveProfile_PreviewMouseDown(object sender, MouseButtonEventArgs e) 133 | { 134 | MessageBox.Show("Going to User Page"); 135 | } 136 | 137 | private void UpdateUsage_Click(object sender, RoutedEventArgs e) 138 | { 139 | MessageBox.Show("Updateing Usage"); 140 | } 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/MainSubInfoView.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace v2rayN.Views 17 | { 18 | /// 19 | /// Interaction logic for MainSubInfoView.xaml 20 | /// 21 | public partial class MainSubInfoView : UserControl 22 | { 23 | public MainSubInfoView() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/MsgView.xaml: -------------------------------------------------------------------------------- 1 | 14 | 15 | 19 | 25 | 34 | 39 | 44 | 45 | 55 | 56 | 57 | 62 | 67 | 72 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/MsgView.xaml.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiddify/HiddifyN/cb0909f13ad6d7f0c592ed3eb80ac515703d2e66/v2rayN/v2rayN/Views/MsgView.xaml.cs -------------------------------------------------------------------------------- /v2rayN/v2rayN/Views/QrcodeView.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 36 | 37 |