├── .editorconfig
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ ├── 01_bug_report.yml
│ └── 02_feature_request.yml
├── dependabot.yml
└── workflows
│ ├── build-all.yml
│ ├── build-linux.yml
│ ├── build-osx.yml
│ ├── build-windows-desktop.yml
│ ├── build-windows.yml
│ └── winget-publish.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── package-appimage.sh
├── package-debian.sh
├── package-osx.sh
├── package-release-zip.sh
├── pkg2appimage.yml
└── v2rayN
├── AmazTool
├── AmazTool.csproj
├── Program.cs
├── Resx
│ ├── Resource.Designer.cs
│ ├── Resource.resx
│ ├── Resource.zh-Hans.resx
│ └── Resource.zh-Hant.resx
├── UpgradeApp.cs
└── Utils.cs
├── Directory.Build.props
├── Directory.Packages.props
├── ServiceLib
├── Base
│ └── MyReactiveObject.cs
├── Common
│ ├── AesUtils.cs
│ ├── DesUtils.cs
│ ├── DownloaderHelper.cs
│ ├── EmbedUtils.cs
│ ├── FileManager.cs
│ ├── HttpClientHelper.cs
│ ├── Job.cs
│ ├── JsonUtils.cs
│ ├── Logging.cs
│ ├── ProcUtils.cs
│ ├── QRCodeHelper.cs
│ ├── SemanticVersion.cs
│ ├── SqliteHelper.cs
│ ├── StringEx.cs
│ ├── Utils.cs
│ ├── WindowsUtils.cs
│ └── YamlUtils.cs
├── Enums
│ ├── EConfigType.cs
│ ├── ECoreType.cs
│ ├── EGirdOrientation.cs
│ ├── EGlobalHotkey.cs
│ ├── EInboundProtocol.cs
│ ├── EMove.cs
│ ├── EMsgCommand.cs
│ ├── EMultipleLoad.cs
│ ├── EPresetType.cs
│ ├── ERuleMode.cs
│ ├── EServerColName.cs
│ ├── ESpeedActionType.cs
│ ├── ESysProxyType.cs
│ ├── ETheme.cs
│ ├── ETransport.cs
│ └── EViewAction.cs
├── FodyWeavers.xml
├── Global.cs
├── GlobalUsings.cs
├── Handler
│ ├── AppHandler.cs
│ ├── AutoStartupHandler.cs
│ ├── ClashApiHandler.cs
│ ├── ConfigHandler.cs
│ ├── ConnectionHandler.cs
│ ├── CoreAdminHandler.cs
│ ├── CoreConfigHandler.cs
│ ├── CoreHandler.cs
│ ├── CoreInfoHandler.cs
│ ├── Fmt
│ │ ├── BaseFmt.cs
│ │ ├── ClashFmt.cs
│ │ ├── FmtHandler.cs
│ │ ├── Hysteria2Fmt.cs
│ │ ├── NaiveproxyFmt.cs
│ │ ├── ShadowsocksFmt.cs
│ │ ├── SingboxFmt.cs
│ │ ├── SocksFmt.cs
│ │ ├── TrojanFmt.cs
│ │ ├── TuicFmt.cs
│ │ ├── V2rayFmt.cs
│ │ ├── VLESSFmt.cs
│ │ ├── VmessFmt.cs
│ │ └── WireguardFmt.cs
│ ├── NoticeHandler.cs
│ ├── PacHandler.cs
│ ├── ProfileExHandler.cs
│ ├── StatisticsHandler.cs
│ ├── SysProxy
│ │ ├── ProxySettingLinux.cs
│ │ ├── ProxySettingOSX.cs
│ │ ├── ProxySettingWindows.cs
│ │ └── SysProxyHandler.cs
│ ├── TaskHandler.cs
│ └── WebDavHandler.cs
├── Models
│ ├── CheckUpdateModel.cs
│ ├── ClashConnectionModel.cs
│ ├── ClashConnections.cs
│ ├── ClashProviders.cs
│ ├── ClashProxies.cs
│ ├── ClashProxyModel.cs
│ ├── CmdItem.cs
│ ├── ComboItem.cs
│ ├── Config.cs
│ ├── ConfigItems.cs
│ ├── CoreInfo.cs
│ ├── DNSItem.cs
│ ├── GitHubRelease.cs
│ ├── IPAPIInfo.cs
│ ├── ProfileExItem.cs
│ ├── ProfileItem.cs
│ ├── ProfileItemModel.cs
│ ├── RetResult.cs
│ ├── RoutingItem.cs
│ ├── RoutingItemModel.cs
│ ├── RoutingTemplate.cs
│ ├── RulesItem.cs
│ ├── RulesItemModel.cs
│ ├── ServerSpeedItem.cs
│ ├── ServerStatItem.cs
│ ├── ServerTestItem.cs
│ ├── SingboxConfig.cs
│ ├── SpeedTestResult.cs
│ ├── SsSIP008.cs
│ ├── SubItem.cs
│ ├── V2rayConfig.cs
│ ├── V2rayMetricsVars.cs
│ ├── V2rayTcpRequest.cs
│ └── VmessQRCode.cs
├── Resx
│ ├── ResUI.Designer.cs
│ ├── ResUI.fa-Ir.resx
│ ├── ResUI.hu.resx
│ ├── ResUI.resx
│ ├── ResUI.ru.resx
│ ├── ResUI.zh-Hans.resx
│ └── ResUI.zh-Hant.resx
├── Sample
│ ├── SampleClientConfig
│ ├── SampleHttpRequest
│ ├── SampleHttpResponse
│ ├── SampleInbound
│ ├── SampleOutbound
│ ├── SingboxSampleClientConfig
│ ├── SingboxSampleOutbound
│ ├── clash_mixin_yaml
│ ├── clash_tun_yaml
│ ├── custom_routing_black
│ ├── custom_routing_global
│ ├── custom_routing_white
│ ├── dns_singbox_normal
│ ├── dns_v2ray_normal
│ ├── linux_autostart_config
│ ├── pac
│ ├── proxy_set_linux_sh
│ ├── proxy_set_osx_sh
│ ├── tun_singbox_dns
│ ├── tun_singbox_inbound
│ └── tun_singbox_rules
├── ServiceLib.csproj
├── Services
│ ├── CoreConfig
│ │ ├── CoreConfigClashService.cs
│ │ ├── CoreConfigSingboxService.cs
│ │ └── CoreConfigV2rayService.cs
│ ├── DownloadService.cs
│ ├── SpeedtestService.cs
│ ├── Statistics
│ │ ├── StatisticsSingboxService.cs
│ │ └── StatisticsXrayService.cs
│ └── UpdateService.cs
└── ViewModels
│ ├── AddServer2ViewModel.cs
│ ├── AddServerViewModel.cs
│ ├── BackupAndRestoreViewModel.cs
│ ├── CheckUpdateViewModel.cs
│ ├── ClashConnectionsViewModel.cs
│ ├── ClashProxiesViewModel.cs
│ ├── DNSSettingViewModel.cs
│ ├── GlobalHotkeySettingViewModel.cs
│ ├── MainWindowViewModel.cs
│ ├── MsgViewModel.cs
│ ├── OptionSettingViewModel.cs
│ ├── ProfilesViewModel.cs
│ ├── RoutingRuleDetailsViewModel.cs
│ ├── RoutingRuleSettingViewModel.cs
│ ├── RoutingSettingViewModel.cs
│ ├── StatusBarViewModel.cs
│ ├── SubEditViewModel.cs
│ └── SubSettingViewModel.cs
├── v2rayN.Desktop
├── App.axaml
├── App.axaml.cs
├── Assets
│ ├── Fonts
│ │ └── NotoSansSC-Regular.ttf
│ ├── GlobalResources.axaml
│ ├── GlobalStyles.axaml
│ ├── NotifyIcon1.ico
│ ├── NotifyIcon2.ico
│ ├── NotifyIcon3.ico
│ ├── NotifyIcon4.ico
│ └── v2rayN.ico
├── Common
│ ├── AppBuilderExtension.cs
│ ├── AvaUtils.cs
│ └── UI.cs
├── Controls
│ ├── AutoCompleteBox.axaml
│ └── AutoCompleteBox.cs
├── Converters
│ └── DelayColorConverter.cs
├── FodyWeavers.xml
├── GlobalUsings.cs
├── Handler
│ └── HotkeyHandler.cs
├── Program.cs
├── ViewModels
│ └── ThemeSettingViewModel.cs
├── Views
│ ├── AddServer2Window.axaml
│ ├── AddServer2Window.axaml.cs
│ ├── AddServerWindow.axaml
│ ├── AddServerWindow.axaml.cs
│ ├── BackupAndRestoreView.axaml
│ ├── BackupAndRestoreView.axaml.cs
│ ├── CheckUpdateView.axaml
│ ├── CheckUpdateView.axaml.cs
│ ├── ClashConnectionsView.axaml
│ ├── ClashConnectionsView.axaml.cs
│ ├── ClashProxiesView.axaml
│ ├── ClashProxiesView.axaml.cs
│ ├── DNSSettingWindow.axaml
│ ├── DNSSettingWindow.axaml.cs
│ ├── GlobalHotkeySettingWindow.axaml
│ ├── GlobalHotkeySettingWindow.axaml.cs
│ ├── MainWindow.axaml
│ ├── MainWindow.axaml.cs
│ ├── MsgView.axaml
│ ├── MsgView.axaml.cs
│ ├── OptionSettingWindow.axaml
│ ├── OptionSettingWindow.axaml.cs
│ ├── ProfilesView.axaml
│ ├── ProfilesView.axaml.cs
│ ├── QrcodeView.axaml
│ ├── QrcodeView.axaml.cs
│ ├── RoutingRuleDetailsWindow.axaml
│ ├── RoutingRuleDetailsWindow.axaml.cs
│ ├── RoutingRuleSettingWindow.axaml
│ ├── RoutingRuleSettingWindow.axaml.cs
│ ├── RoutingSettingWindow.axaml
│ ├── RoutingSettingWindow.axaml.cs
│ ├── StatusBarView.axaml
│ ├── StatusBarView.axaml.cs
│ ├── SubEditWindow.axaml
│ ├── SubEditWindow.axaml.cs
│ ├── SubSettingWindow.axaml
│ ├── SubSettingWindow.axaml.cs
│ ├── SudoPasswordInputView.axaml
│ ├── SudoPasswordInputView.axaml.cs
│ ├── ThemeSettingView.axaml
│ └── ThemeSettingView.axaml.cs
├── v2rayN.Desktop.csproj
├── v2rayN.icns
└── v2rayN.png
├── v2rayN.sln
└── v2rayN
├── App.xaml
├── App.xaml.cs
├── AssemblyInfo.cs
├── Base
└── MyDGTextColumn.cs
├── Common
├── QRCodeHelper.cs
├── UI.cs
└── WindowsUtils.cs
├── Converters
├── DelayColorConverter.cs
├── InverseBooleanConverter.cs
└── MaterialDesignFonts.cs
├── FodyWeavers.xml
├── GlobalUsings.cs
├── Handler
├── HotkeyHandler.cs
└── WindowsHandler.cs
├── Properties
├── Resources.Designer.cs
└── Resources.resx
├── Resources
├── NotifyIcon1.ico
├── NotifyIcon2.ico
├── NotifyIcon3.ico
├── NotifyIcon4.ico
└── v2rayN.ico
├── ViewModels
└── ThemeSettingViewModel.cs
├── Views
├── AddServer2Window.xaml
├── AddServer2Window.xaml.cs
├── AddServerWindow.xaml
├── AddServerWindow.xaml.cs
├── BackupAndRestoreView.xaml
├── BackupAndRestoreView.xaml.cs
├── CheckUpdateView.xaml
├── CheckUpdateView.xaml.cs
├── ClashConnectionsView.xaml
├── ClashConnectionsView.xaml.cs
├── ClashProxiesView.xaml
├── ClashProxiesView.xaml.cs
├── DNSSettingWindow.xaml
├── DNSSettingWindow.xaml.cs
├── GlobalHotkeySettingWindow.xaml
├── GlobalHotkeySettingWindow.xaml.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── MsgView.xaml
├── MsgView.xaml.cs
├── OptionSettingWindow.xaml
├── OptionSettingWindow.xaml.cs
├── ProfilesView.xaml
├── ProfilesView.xaml.cs
├── QrcodeView.xaml
├── QrcodeView.xaml.cs
├── RoutingRuleDetailsWindow.xaml
├── RoutingRuleDetailsWindow.xaml.cs
├── RoutingRuleSettingWindow.xaml
├── RoutingRuleSettingWindow.xaml.cs
├── RoutingSettingWindow.xaml
├── RoutingSettingWindow.xaml.cs
├── StatusBarView.xaml
├── StatusBarView.xaml.cs
├── SubEditWindow.xaml
├── SubEditWindow.xaml.cs
├── SubSettingWindow.xaml
├── SubSettingWindow.xaml.cs
├── ThemeSettingView.xaml
└── ThemeSettingView.xaml.cs
├── app.manifest
└── v2rayN.csproj
/.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 |
--------------------------------------------------------------------------------
/.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: "os-version"
8 | attributes:
9 | label: "操作系统和版本"
10 | description: "操作系统和版本"
11 | validations:
12 | required: true
13 | - type: input
14 | id: "expectation"
15 | attributes:
16 | label: "预期情况"
17 | description: "描述你认为应该发生什么"
18 | validations:
19 | required: true
20 | - type: textarea
21 | id: "describe-the-bug"
22 | attributes:
23 | label: "实际情况"
24 | description: "描述实际发生了什么"
25 | validations:
26 | required: true
27 | - type: textarea
28 | id: "reproduction-method"
29 | attributes:
30 | label: "复现方法"
31 | description: "在BUG出现前执行了哪些操作"
32 | placeholder: 标序号
33 | validations:
34 | required: true
35 | - type: textarea
36 | id: "log"
37 | attributes:
38 | label: "日志信息"
39 | description: "位置在软件当前目录下的guiLogs"
40 | placeholder: 在日志开始和结束位置粘贴冒号后的内容:```
41 | validations:
42 | required: true
43 | - type: textarea
44 | id: "more"
45 | attributes:
46 | label: "额外信息"
47 | description: "可选"
48 | validations:
49 | required: false
50 | - type: checkboxes
51 | id: "latest-version"
52 | attributes:
53 | label: "我确认已更新至最新版本"
54 | description: "否则请更新后尝试"
55 | options:
56 | - label: 是
57 | required: true
58 | - type: checkboxes
59 | id: "issues"
60 | attributes:
61 | label: "我确认已查询历史issues"
62 | description: "否则请查询后提出"
63 | options:
64 | - label: 是
65 | required: true
66 |
--------------------------------------------------------------------------------
/.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/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 |
8 | - package-ecosystem: "nuget"
9 | directory: "/"
10 | schedule:
11 | interval: "daily"
12 |
--------------------------------------------------------------------------------
/.github/workflows/build-all.yml:
--------------------------------------------------------------------------------
1 | name: release all platforms
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | release_tag:
7 | required: false
8 | type: string
9 |
10 | jobs:
11 | update:
12 | runs-on: ubuntu-latest
13 | steps:
14 |
15 | - name: Trigger build windows
16 | if: github.event.inputs.release_tag != ''
17 | run: |
18 | curl -X POST \
19 | -H "Accept: application/vnd.github.v3+json" \
20 | -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
21 | https://api.github.com/repos/${{ github.repository }}/actions/workflows/build-windows.yml/dispatches \
22 | -d "{
23 | \"ref\": \"master\",
24 | \"inputs\": {
25 | \"release_tag\": \"${{ github.event.inputs.release_tag }}\"
26 | }
27 | }"
28 |
29 | - name: Trigger build linux
30 | if: github.event.inputs.release_tag != ''
31 | run: |
32 | curl -X POST \
33 | -H "Accept: application/vnd.github.v3+json" \
34 | -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
35 | https://api.github.com/repos/${{ github.repository }}/actions/workflows/build-linux.yml/dispatches \
36 | -d "{
37 | \"ref\": \"master\",
38 | \"inputs\": {
39 | \"release_tag\": \"${{ github.event.inputs.release_tag }}\"
40 | }
41 | }"
42 |
43 | - name: Trigger build osx
44 | if: github.event.inputs.release_tag != ''
45 | run: |
46 | curl -X POST \
47 | -H "Accept: application/vnd.github.v3+json" \
48 | -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
49 | https://api.github.com/repos/${{ github.repository }}/actions/workflows/build-osx.yml/dispatches \
50 | -d "{
51 | \"ref\": \"master\",
52 | \"inputs\": {
53 | \"release_tag\": \"${{ github.event.inputs.release_tag }}\"
54 | }
55 | }"
56 |
57 | - name: Trigger build windows desktop
58 | if: github.event.inputs.release_tag != ''
59 | run: |
60 | curl -X POST \
61 | -H "Accept: application/vnd.github.v3+json" \
62 | -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
63 | https://api.github.com/repos/${{ github.repository }}/actions/workflows/build-windows-desktop.yml/dispatches \
64 | -d "{
65 | \"ref\": \"master\",
66 | \"inputs\": {
67 | \"release_tag\": \"${{ github.event.inputs.release_tag }}\"
68 | }
69 | }"
--------------------------------------------------------------------------------
/.github/workflows/build-osx.yml:
--------------------------------------------------------------------------------
1 | name: release macOS
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | release_tag:
7 | required: false
8 | type: string
9 | push:
10 | branches:
11 | - master
12 |
13 | env:
14 | OutputArch: "macos-64"
15 | OutputArchArm: "macos-arm64"
16 | OutputPath64: "${{ github.workspace }}/v2rayN/Release/macos-64"
17 | OutputPathArm64: "${{ github.workspace }}/v2rayN/Release/macos-arm64"
18 |
19 | jobs:
20 | build:
21 | strategy:
22 | matrix:
23 | configuration: [Release]
24 |
25 | runs-on: macos-latest
26 |
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v4.2.2
30 | with:
31 | submodules: 'recursive'
32 | fetch-depth: '0'
33 |
34 | - name: Setup
35 | uses: actions/setup-dotnet@v4.3.1
36 | with:
37 | dotnet-version: '8.0.x'
38 |
39 | - name: Build
40 | run: |
41 | cd v2rayN
42 | dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-x64 --self-contained=true -o $OutputPath64
43 | dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-arm64 --self-contained=true -o $OutputPathArm64
44 | dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-x64 --self-contained=true -p:PublishTrimmed=true -o $OutputPath64
45 | dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 --self-contained=true -p:PublishTrimmed=true -o $OutputPathArm64
46 |
47 | - name: Upload build artifacts
48 | uses: actions/upload-artifact@v4.6.2
49 | with:
50 | name: v2rayN-macos
51 | path: |
52 | ${{ github.workspace }}/v2rayN/Release/macos*
53 |
54 | # release osx package
55 | - name: Package osx
56 | if: github.event.inputs.release_tag != ''
57 | run: |
58 | brew install create-dmg
59 | chmod 755 package-osx.sh
60 | ./package-osx.sh $OutputArch $OutputPath64 ${{ github.event.inputs.release_tag }}
61 | ./package-osx.sh $OutputArchArm $OutputPathArm64 ${{ github.event.inputs.release_tag }}
62 |
63 | - name: Upload dmg to release
64 | uses: svenstaro/upload-release-action@v2
65 | if: github.event.inputs.release_tag != ''
66 | with:
67 | file: ${{ github.workspace }}/v2rayN*.dmg
68 | tag: ${{ github.event.inputs.release_tag }}
69 | file_glob: true
70 | prerelease: true
71 |
72 | # release zip archive
73 | - name: Package release zip archive
74 | if: github.event.inputs.release_tag != ''
75 | run: |
76 | chmod 755 package-release-zip.sh
77 | ./package-release-zip.sh $OutputArch $OutputPath64
78 | ./package-release-zip.sh $OutputArchArm $OutputPathArm64
79 |
80 | - name: Upload zip archive to release
81 | uses: svenstaro/upload-release-action@v2
82 | if: github.event.inputs.release_tag != ''
83 | with:
84 | file: ${{ github.workspace }}/v2rayN*.zip
85 | tag: ${{ github.event.inputs.release_tag }}
86 | file_glob: true
87 | prerelease: true
--------------------------------------------------------------------------------
/.github/workflows/build-windows-desktop.yml:
--------------------------------------------------------------------------------
1 | name: release Windows desktop (Avalonia UI)
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | release_tag:
7 | required: false
8 | type: string
9 | push:
10 | branches:
11 | - master
12 |
13 | env:
14 | OutputArch: "windows-64"
15 | OutputArchArm: "windows-arm64"
16 | OutputPath64: "${{ github.workspace }}/v2rayN/Release/windows-64"
17 | OutputPathArm64: "${{ github.workspace }}/v2rayN/Release/windows-arm64"
18 |
19 | jobs:
20 | build:
21 | strategy:
22 | matrix:
23 | configuration: [Release]
24 |
25 | runs-on: ubuntu-latest
26 |
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v4.2.2
30 | with:
31 | submodules: 'recursive'
32 | fetch-depth: '0'
33 |
34 | - name: Setup
35 | uses: actions/setup-dotnet@v4.3.1
36 | with:
37 | dotnet-version: '8.0.x'
38 |
39 | - name: Build
40 | run: |
41 | cd v2rayN
42 | dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r win-x64 --self-contained=true -p:EnableWindowsTargeting=true -o $OutputPath64
43 | dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r win-arm64 --self-contained=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
44 | dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPath64
45 | dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
46 |
47 | - name: Upload build artifacts
48 | uses: actions/upload-artifact@v4.6.2
49 | with:
50 | name: v2rayN-windows-desktop
51 | path: |
52 | ${{ github.workspace }}/v2rayN/Release/windows*
53 |
54 | # release zip archive
55 | - name: Package release zip archive
56 | if: github.event.inputs.release_tag != ''
57 | run: |
58 | chmod 755 package-release-zip.sh
59 | ./package-release-zip.sh $OutputArch $OutputPath64
60 | mv "v2rayN-${OutputArch}.zip" "v2rayN-${OutputArch}-desktop.zip"
61 | ./package-release-zip.sh $OutputArchArm $OutputPathArm64
62 | mv "v2rayN-${OutputArchArm}.zip" "v2rayN-${OutputArchArm}-desktop.zip"
63 |
64 | - name: Upload zip archive to release
65 | uses: svenstaro/upload-release-action@v2
66 | if: github.event.inputs.release_tag != ''
67 | with:
68 | file: ${{ github.workspace }}/v2rayN*.zip
69 | tag: ${{ github.event.inputs.release_tag }}
70 | file_glob: true
71 | prerelease: true
72 |
--------------------------------------------------------------------------------
/.github/workflows/build-windows.yml:
--------------------------------------------------------------------------------
1 | name: release Windows
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | release_tag:
7 | required: false
8 | type: string
9 | push:
10 | branches:
11 | - master
12 |
13 | env:
14 | OutputArch: "windows-64"
15 | OutputArchArm: "windows-arm64"
16 | OutputPath64: "${{ github.workspace }}/v2rayN/Release/windows-64"
17 | OutputPathArm64: "${{ github.workspace }}/v2rayN/Release/windows-arm64"
18 | OutputPath64Sc: "${{ github.workspace }}/v2rayN/Release/windows-64-SelfContained"
19 |
20 | jobs:
21 | build:
22 | strategy:
23 | matrix:
24 | configuration: [Release]
25 |
26 | runs-on: ubuntu-latest
27 |
28 | steps:
29 | - name: Checkout
30 | uses: actions/checkout@v4.2.2
31 |
32 | - name: Setup
33 | uses: actions/setup-dotnet@v4.3.1
34 | with:
35 | dotnet-version: '8.0.x'
36 |
37 | - name: Build
38 | run: |
39 | cd v2rayN
40 | dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained=false -p:EnableWindowsTargeting=true -o $OutputPath64
41 | dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-arm64 --self-contained=false -p:EnableWindowsTargeting=true -o $OutputPathArm64
42 | dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained=true -p:EnableWindowsTargeting=true -o $OutputPath64Sc
43 | dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained=false -p:EnableWindowsTargeting=true -o $OutputPath64
44 | dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained=false -p:EnableWindowsTargeting=true -o $OutputPathArm64
45 | dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPath64Sc
46 |
47 |
48 | - name: Upload build artifacts
49 | uses: actions/upload-artifact@v4.6.2
50 | with:
51 | name: v2rayN-windows
52 | path: |
53 | ${{ github.workspace }}/v2rayN/Release/windows*
54 |
55 | # release zip archive
56 | - name: Package release zip archive
57 | if: github.event.inputs.release_tag != ''
58 | run: |
59 | chmod 755 package-release-zip.sh
60 | ./package-release-zip.sh $OutputArch $OutputPath64
61 | ./package-release-zip.sh $OutputArchArm $OutputPathArm64
62 | ./package-release-zip.sh "windows-64-SelfContained" $OutputPath64Sc
63 |
64 | - name: Upload zip archive to release
65 | uses: svenstaro/upload-release-action@v2
66 | if: github.event.inputs.release_tag != ''
67 | with:
68 | file: ${{ github.workspace }}/v2rayN*.zip
69 | tag: ${{ github.event.inputs.release_tag }}
70 | file_glob: true
71 | prerelease: true
--------------------------------------------------------------------------------
/.github/workflows/winget-publish.yml:
--------------------------------------------------------------------------------
1 | name: WinGet submission on release
2 | # based off of https://github.com/nushell/nushell/blob/main/.github/workflows/winget-submission.yml
3 | # inspired by https://github.com/microsoft/PowerToys/blob/main/.github/workflows/package-submissions.yml
4 | # Modified by @MerrickZ https://github.com/anpho
5 |
6 | on:
7 | workflow_dispatch:
8 | release:
9 | types: [released]
10 |
11 | jobs:
12 | winget:
13 | name: Publish winget package
14 | runs-on: windows-latest
15 | steps:
16 | - name: Submit v2ray package to Windows Package Manager Community Repository
17 | run: |
18 |
19 | $wingetPackage = "2dust.v2rayN"
20 | $gitToken = "${{ secrets.PT_WINGET }}"
21 |
22 | $github = Invoke-RestMethod -uri "https://api.github.com/repos/2dust/v2rayN/releases"
23 |
24 | $targetRelease = $github | Where-Object -Property prerelease -match 'False' | Select -First 1
25 | $installerUrl = $targetRelease | Select -ExpandProperty assets -First 1 | Where-Object -Property name -match 'v2rayN-windows-64\.zip*' | Select -ExpandProperty browser_download_url
26 |
27 | $ver = $targetRelease.tag_name
28 |
29 | # getting latest wingetcreate file
30 | iwr https://aka.ms/wingetcreate/latest -OutFile wingetcreate.exe
31 | .\wingetcreate.exe update $wingetPackage -s -v $ver -u "$installerUrl|x64" -t $gitToken
32 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "v2rayN/GlobalHotKeys"]
2 | path = v2rayN/GlobalHotKeys
3 | url = https://github.com/2dust/GlobalHotKeys
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # v2rayN
2 |
3 | A GUI client for Windows, Linux and macOS, support [Xray](https://github.com/XTLS/Xray-core)
4 | and [sing-box](https://github.com/SagerNet/sing-box)
5 | and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
6 |
7 | [](https://github.com/2dust/v2rayN/commits/master)
8 | [](https://www.codefactor.io/repository/github/2dust/v2rayn)
9 | [](https://github.com/2dust/v2rayN/releases)
10 | [](https://t.me/v2rayn)
11 |
12 | ## How to use
13 |
14 | Read the [Wiki](https://github.com/2dust/v2rayN/wiki) for details.
15 |
16 | ## Telegram Channel
17 |
18 | [github_2dust](https://t.me/github_2dust)
19 |
--------------------------------------------------------------------------------
/package-appimage.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | sudo apt update -y
4 | sudo apt install -y libfuse2
5 | wget -O pkg2appimage https://github.com/AppImageCommunity/pkg2appimage/releases/download/continuous/pkg2appimage-1eceb30-x86_64.AppImage
6 | chmod a+x pkg2appimage
7 | export AppImageOutputArch=$OutputArch
8 | export OutputPath=$OutputPath64
9 | ./pkg2appimage ./pkg2appimage.yml
10 | mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage
11 | export AppImageOutputArch=$OutputArchArm
12 | export OutputPath=$OutputPathArm64
13 | ./pkg2appimage ./pkg2appimage.yml
14 | mv out/*.AppImage v2rayN-${AppImageOutputArch}.AppImage
15 |
--------------------------------------------------------------------------------
/package-debian.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | Arch="$1"
4 | OutputPath="$2"
5 | Version="$3"
6 |
7 | FileName="v2rayN-${Arch}.zip"
8 | wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
9 | 7z x $FileName
10 | cp -rf v2rayN-${Arch}/* $OutputPath
11 |
12 | PackagePath="v2rayN-Package-${Arch}"
13 | mkdir -p "${PackagePath}/DEBIAN"
14 | mkdir -p "${PackagePath}/opt"
15 | cp -rf $OutputPath "${PackagePath}/opt/v2rayN"
16 | echo "When this file exists, app will not store configs under this folder" > "${PackagePath}/opt/v2rayN/NotStoreConfigHere.txt"
17 |
18 | if [ $Arch = "linux-64" ]; then
19 | Arch2="amd64"
20 | else
21 | Arch2="arm64"
22 | fi
23 | echo $Arch2
24 |
25 | # basic
26 | cat >"${PackagePath}/DEBIAN/control" <<-EOF
27 | Package: v2rayN
28 | Version: $Version
29 | Architecture: $Arch2
30 | Maintainer: https://github.com/2dust/v2rayN
31 | Description: A GUI client for Windows and Linux, support Xray core and sing-box-core and others
32 | EOF
33 |
34 | cat >"${PackagePath}/DEBIAN/postinst" <<-EOF
35 | if [ ! -s /usr/share/applications/v2rayN.desktop ]; then
36 | cat >/usr/share/applications/v2rayN.desktop<<-END
37 | [Desktop Entry]
38 | Name=v2rayN
39 | Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
40 | Exec=/opt/v2rayN/v2rayN
41 | Icon=/opt/v2rayN/v2rayN.png
42 | Terminal=false
43 | Type=Application
44 | Categories=Network;Application;
45 | END
46 | fi
47 |
48 | update-desktop-database
49 | EOF
50 |
51 | sudo chmod 0755 "${PackagePath}/DEBIAN/postinst"
52 | sudo chmod 0755 "${PackagePath}/opt/v2rayN/v2rayN"
53 | sudo chmod 0755 "${PackagePath}/opt/v2rayN/AmazTool"
54 |
55 | # desktop && PATH
56 |
57 | sudo dpkg-deb -Zxz --build $PackagePath
58 | sudo mv "${PackagePath}.deb" "v2rayN-${Arch}.deb"
--------------------------------------------------------------------------------
/package-osx.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | Arch="$1"
4 | OutputPath="$2"
5 | Version="$3"
6 |
7 | FileName="v2rayN-${Arch}.zip"
8 | wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
9 | 7z x $FileName
10 | cp -rf v2rayN-${Arch}/* $OutputPath
11 |
12 | PackagePath="v2rayN-Package-${Arch}"
13 | mkdir -p "$PackagePath/v2rayN.app/Contents/Resources"
14 | cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS"
15 | cp -f "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN.icns" "$PackagePath/v2rayN.app/Contents/Resources/AppIcon.icns"
16 | echo "When this file exists, app will not store configs under this folder" > "$PackagePath/v2rayN.app/Contents/MacOS/NotStoreConfigHere.txt"
17 | chmod +x "$PackagePath/v2rayN.app/Contents/MacOS/v2rayN"
18 |
19 | cat >"$PackagePath/v2rayN.app/Contents/Info.plist" <<-EOF
20 |
21 |
22 |
23 |
24 | CFBundleDevelopmentRegion
25 | English
26 | CFBundleDisplayName
27 | v2rayN
28 | CFBundleExecutable
29 | v2rayN
30 | CFBundleIconFile
31 | AppIcon
32 | CFBundleIconName
33 | AppIcon
34 | CFBundleIdentifier
35 | 2dust.v2rayN
36 | CFBundleName
37 | v2rayN
38 | CFBundlePackageType
39 | APPL
40 | CFBundleShortVersionString
41 | ${Version}
42 | CSResourcesFileMapped
43 |
44 | NSHighResolutionCapable
45 |
46 |
47 |
48 | EOF
49 |
50 | create-dmg \
51 | --volname "v2rayN Installer" \
52 | --window-size 700 420 \
53 | --icon-size 100 \
54 | --icon "v2rayN.app" 160 185 \
55 | --hide-extension "v2rayN.app" \
56 | --app-drop-link 500 185 \
57 | "v2rayN-${Arch}.dmg" \
58 | "$PackagePath/v2rayN.app"
--------------------------------------------------------------------------------
/package-release-zip.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | Arch="$1"
4 | OutputPath="$2"
5 |
6 | OutputArch="v2rayN-${Arch}"
7 | FileName="v2rayN-${Arch}.zip"
8 |
9 | wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
10 |
11 | ZipPath64="./$OutputArch"
12 | mkdir $ZipPath64
13 |
14 | cp -rf $OutputPath "$ZipPath64/$OutputArch"
15 | 7z a -tZip $FileName "$ZipPath64/$OutputArch" -mx1
--------------------------------------------------------------------------------
/pkg2appimage.yml:
--------------------------------------------------------------------------------
1 | app: v2rayN
2 | binpatch: true
3 |
4 | ingredients:
5 | script:
6 | - export FileName="v2rayN-${AppImageOutputArch}.zip"
7 | - wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/${FileName}"
8 | - 7z x $FileName -aoa
9 | - cp -rf v2rayN-${AppImageOutputArch}/* $OutputPath
10 |
11 | script:
12 | - mkdir -p usr/bin usr/lib
13 | - cp -rf $OutputPath usr/lib/v2rayN
14 | - echo "When this file exists, app will not store configs under this folder" > usr/lib/v2rayN/NotStoreConfigHere.txt
15 | - ln -sf usr/lib/v2rayN/v2rayN usr/bin/v2rayN
16 | - chmod a+x usr/lib/v2rayN/v2rayN
17 | - find usr -type f -exec sh -c 'file "{}" | grep -qi "executable" && chmod +x "{}"' \;
18 | - install -Dm644 usr/lib/v2rayN/v2rayN.png v2rayN.png
19 | - install -Dm644 usr/lib/v2rayN/v2rayN.png usr/share/pixmaps/v2rayN.png
20 | - cat > v2rayN.desktop < AppRun <<\EOF
32 | - #!/bin/sh
33 | - HERE="$(dirname "$(readlink -f "${0}")")"
34 | - cd ${HERE}/usr/lib/v2rayN
35 | - exec ${HERE}/usr/lib/v2rayN/v2rayN $@
36 | - EOF
37 | - chmod a+x AppRun
38 |
--------------------------------------------------------------------------------
/v2rayN/AmazTool/AmazTool.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
9 | ResXFileCodeGenerator
10 | Resource.Designer.cs
11 |
12 |
13 |
14 | True
15 | True
16 | Resource.resx
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/v2rayN/AmazTool/Program.cs:
--------------------------------------------------------------------------------
1 | namespace AmazTool;
2 |
3 | internal static class Program
4 | {
5 | [STAThread]
6 | private static void Main(string[] args)
7 | {
8 | try
9 | {
10 | // If no arguments are provided, display usage guidelines and exit
11 | if (args.Length == 0)
12 | {
13 | ShowHelp();
14 | return;
15 | }
16 |
17 | // Log all arguments for debugging purposes
18 | foreach (var arg in args)
19 | {
20 | Console.WriteLine(arg);
21 | }
22 |
23 | // Parse command based on first argument
24 | switch (args[0].ToLowerInvariant())
25 | {
26 | case "rebootas":
27 | // Handle application restart
28 | HandleRebootAsync();
29 | break;
30 |
31 | case "help":
32 | case "--help":
33 | case "-h":
34 | case "/?":
35 | // Display help information
36 | ShowHelp();
37 | break;
38 |
39 | default:
40 | // Default behavior: handle as upgrade data
41 | // Maintain backward compatibility with existing usage pattern
42 | var argData = Uri.UnescapeDataString(string.Join(" ", args));
43 | HandleUpgrade(argData);
44 | break;
45 | }
46 | }
47 | catch (Exception ex)
48 | {
49 | // Global exception handling
50 | Console.WriteLine($"An error occurred: {ex.Message}");
51 | Console.WriteLine("Press any key to exit...");
52 | Console.ReadKey();
53 | }
54 | }
55 |
56 | ///
57 | /// Display help information and usage guidelines
58 | ///
59 | private static void ShowHelp()
60 | {
61 | Console.WriteLine(Resx.Resource.Guidelines);
62 | Console.WriteLine("Available commands:");
63 | Console.WriteLine(" rebootas - Restart the application");
64 | Console.WriteLine(" help - Display this help information");
65 | Thread.Sleep(5000);
66 | }
67 |
68 | ///
69 | /// Handle application restart
70 | ///
71 | private static void HandleRebootAsync()
72 | {
73 | Console.WriteLine("Restarting application...");
74 | Thread.Sleep(1000);
75 | Utils.StartV2RayN();
76 | }
77 |
78 | ///
79 | /// Handle application upgrade with the provided data
80 | ///
81 | /// Data for the upgrade process
82 | private static void HandleUpgrade(string upgradeData)
83 | {
84 | Console.WriteLine("Upgrading application...");
85 | UpgradeApp.Upgrade(upgradeData);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/v2rayN/AmazTool/Utils.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace AmazTool;
4 |
5 | internal class Utils
6 | {
7 | public static string GetExePath()
8 | {
9 | return Environment.ProcessPath ?? Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty;
10 | }
11 |
12 | public static string StartupPath()
13 | {
14 | return AppDomain.CurrentDomain.BaseDirectory;
15 | }
16 |
17 | public static string GetPath(string fileName)
18 | {
19 | var startupPath = StartupPath();
20 | if (string.IsNullOrEmpty(fileName))
21 | {
22 | return startupPath;
23 | }
24 | return Path.Combine(startupPath, fileName);
25 | }
26 |
27 | public static string V2rayN => "v2rayN";
28 |
29 | public static void StartV2RayN()
30 | {
31 | Process process = new()
32 | {
33 | StartInfo = new()
34 | {
35 | UseShellExecute = true,
36 | FileName = V2rayN,
37 | WorkingDirectory = StartupPath()
38 | }
39 | };
40 | process.Start();
41 | }
42 |
43 | public static void Waiting(int second)
44 | {
45 | for (var i = second; i > 0; i--)
46 | {
47 | Console.WriteLine(i);
48 | Thread.Sleep(1000);
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/v2rayN/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 7.12.5
5 |
6 |
7 |
8 | net8.0
9 | true
10 | true
11 | CA1031;CS1591;NU1507;CA1416;IDE0058
12 | annotations
13 | enable
14 | 2dust
15 | GPL-3.0
16 | Copyright © 2017-$([System.DateTime]::UtcNow.Year) $(Authors)
17 | false
18 |
19 |
20 |
21 | embedded
22 | false
23 | false
24 | false
25 | false
26 | false
27 | false
28 |
29 | true
30 | true
31 | false
32 |
33 |
34 |
--------------------------------------------------------------------------------
/v2rayN/Directory.Packages.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | true
5 | false
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Base/MyReactiveObject.cs:
--------------------------------------------------------------------------------
1 | using ReactiveUI;
2 |
3 | namespace ServiceLib.Base;
4 |
5 | public class MyReactiveObject : ReactiveObject
6 | {
7 | protected static Config? _config;
8 | protected Func>? _updateView;
9 | }
10 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/DesUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 | using System.Text;
3 |
4 | namespace ServiceLib.Common;
5 |
6 | public class DesUtils
7 | {
8 | ///
9 | /// Encrypt
10 | ///
11 | ///
12 | /// ///
13 | ///
14 | public static string Encrypt(string? text, string? key = null)
15 | {
16 | if (text.IsNullOrEmpty())
17 | {
18 | return string.Empty;
19 | }
20 | GetKeyIv(key ?? GetDefaultKey(), out var rgbKey, out var rgbIv);
21 | var dsp = DES.Create();
22 | using var memStream = new MemoryStream();
23 | using var cryStream = new CryptoStream(memStream, dsp.CreateEncryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
24 | using var sWriter = new StreamWriter(cryStream);
25 | sWriter.Write(text);
26 | sWriter.Flush();
27 | cryStream.FlushFinalBlock();
28 | memStream.Flush();
29 | return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
30 | }
31 |
32 | ///
33 | /// Decrypt
34 | ///
35 | ///
36 | ///
37 | ///
38 | public static string Decrypt(string? encryptText, string? key = null)
39 | {
40 | if (encryptText.IsNullOrEmpty())
41 | {
42 | return string.Empty;
43 | }
44 | GetKeyIv(key ?? GetDefaultKey(), out var rgbKey, out var rgbIv);
45 | var dsp = DES.Create();
46 | var buffer = Convert.FromBase64String(encryptText);
47 |
48 | using var memStream = new MemoryStream();
49 | using var cryStream = new CryptoStream(memStream, dsp.CreateDecryptor(rgbKey, rgbIv), CryptoStreamMode.Write);
50 | cryStream.Write(buffer, 0, buffer.Length);
51 | cryStream.FlushFinalBlock();
52 | return Encoding.UTF8.GetString(memStream.ToArray());
53 | }
54 |
55 | private static void GetKeyIv(string key, out byte[] rgbKey, out byte[] rgbIv)
56 | {
57 | if (key.IsNullOrEmpty())
58 | {
59 | throw new ArgumentNullException("The key cannot be null");
60 | }
61 | if (key.Length <= 8)
62 | {
63 | throw new ArgumentNullException("The key length cannot be less than 8 characters.");
64 | }
65 |
66 | rgbKey = Encoding.ASCII.GetBytes(key.Substring(0, 8));
67 | rgbIv = Encoding.ASCII.GetBytes(key.Insert(0, "w").Substring(0, 8));
68 | }
69 |
70 | private static string GetDefaultKey()
71 | {
72 | return Utils.GetMd5(Utils.GetHomePath() + "DesUtils");
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/EmbedUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 | using System.Reflection;
3 |
4 | namespace ServiceLib.Common;
5 |
6 | public static class EmbedUtils
7 | {
8 | private static readonly string _tag = "EmbedUtils";
9 | private static readonly ConcurrentDictionary _dicEmbedCache = new();
10 |
11 | ///
12 | /// Get embedded text resources
13 | ///
14 | ///
15 | ///
16 | public static string GetEmbedText(string res)
17 | {
18 | if (_dicEmbedCache.TryGetValue(res, out var value))
19 | {
20 | return value;
21 | }
22 | var result = string.Empty;
23 |
24 | try
25 | {
26 | var assembly = Assembly.GetExecutingAssembly();
27 | using var stream = assembly.GetManifestResourceStream(res);
28 | ArgumentNullException.ThrowIfNull(stream);
29 | using StreamReader reader = new(stream);
30 | result = reader.ReadToEnd();
31 | }
32 | catch (Exception ex)
33 | {
34 | Logging.SaveLog(_tag, ex);
35 | }
36 |
37 | _dicEmbedCache.TryAdd(res, result);
38 | return result;
39 | }
40 |
41 | ///
42 | /// Get local storage resources
43 | ///
44 | ///
45 | public static string? LoadResource(string? res)
46 | {
47 | try
48 | {
49 | if (File.Exists(res))
50 | {
51 | return File.ReadAllText(res);
52 | }
53 | }
54 | catch (Exception ex)
55 | {
56 | Logging.SaveLog(_tag, ex);
57 | }
58 |
59 | return null;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/Logging.cs:
--------------------------------------------------------------------------------
1 | using NLog;
2 | using NLog.Config;
3 | using NLog.Targets;
4 |
5 | namespace ServiceLib.Common;
6 |
7 | public class Logging
8 | {
9 | private static readonly Logger _logger1 = LogManager.GetLogger("Log1");
10 | private static readonly Logger _logger2 = LogManager.GetLogger("Log2");
11 |
12 | public static void Setup()
13 | {
14 | LoggingConfiguration config = new();
15 | FileTarget fileTarget = new();
16 | config.AddTarget("file", fileTarget);
17 | fileTarget.Layout = "${longdate}-${level:uppercase=true} ${message}";
18 | fileTarget.FileName = Utils.GetLogPath("${shortdate}.txt");
19 | config.LoggingRules.Add(new LoggingRule("*", LogLevel.Debug, fileTarget));
20 | LogManager.Configuration = config;
21 | }
22 |
23 | public static void LoggingEnabled(bool enable)
24 | {
25 | if (!enable)
26 | {
27 | LogManager.SuspendLogging();
28 | }
29 | }
30 |
31 | public static void SaveLog(string strContent)
32 | {
33 | if (!LogManager.IsLoggingEnabled())
34 | {
35 | return;
36 | }
37 |
38 | _logger1.Info(strContent);
39 | }
40 |
41 | public static void SaveLog(string strTitle, Exception ex)
42 | {
43 | if (!LogManager.IsLoggingEnabled())
44 | {
45 | return;
46 | }
47 |
48 | _logger2.Debug($"{strTitle},{ex.Message}");
49 | _logger2.Debug(ex.StackTrace);
50 | if (ex?.InnerException != null)
51 | {
52 | _logger2.Error(ex.InnerException);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/QRCodeHelper.cs:
--------------------------------------------------------------------------------
1 | using QRCoder;
2 | using SkiaSharp;
3 | using ZXing.SkiaSharp;
4 |
5 | namespace ServiceLib.Common;
6 |
7 | public class QRCodeHelper
8 | {
9 | public static byte[]? GenQRCode(string? url)
10 | {
11 | using QRCodeGenerator qrGenerator = new();
12 | using var qrCodeData = qrGenerator.CreateQrCode(url ?? string.Empty, QRCodeGenerator.ECCLevel.Q);
13 | using PngByteQRCode qrCode = new(qrCodeData);
14 | return qrCode.GetGraphic(20);
15 | }
16 |
17 | public static string? ParseBarcode(string? fileName)
18 | {
19 | if (fileName == null || !File.Exists(fileName))
20 | {
21 | return null;
22 | }
23 |
24 | try
25 | {
26 | var image = SKImage.FromEncodedData(fileName);
27 | var bitmap = SKBitmap.FromImage(image);
28 |
29 | return ReaderBarcode(bitmap);
30 | }
31 | catch
32 | {
33 | // ignored
34 | }
35 |
36 | return null;
37 | }
38 |
39 | public static string? ParseBarcode(byte[]? bytes)
40 | {
41 | try
42 | {
43 | var bitmap = SKBitmap.Decode(bytes);
44 | //using var stream = new FileStream("test2.png", FileMode.Create, FileAccess.Write);
45 | //using var image = SKImage.FromBitmap(bitmap);
46 | //using var encodedImage = image.Encode();
47 | //encodedImage.SaveTo(stream);
48 | return ReaderBarcode(bitmap);
49 | }
50 | catch
51 | {
52 | // ignored
53 | }
54 |
55 | return null;
56 | }
57 |
58 | private static string? ReaderBarcode(SKBitmap? bitmap)
59 | {
60 | var reader = new BarcodeReader();
61 | var result = reader.Decode(bitmap);
62 |
63 | if (result != null && result.Text.IsNotEmpty())
64 | {
65 | return result.Text;
66 | }
67 |
68 | //FlipBitmap
69 | var result2 = reader.Decode(FlipBitmap(bitmap));
70 | return result2?.Text;
71 | }
72 |
73 | private static SKBitmap FlipBitmap(SKBitmap bmp)
74 | {
75 | // Create a bitmap (to return)
76 | var flipped = new SKBitmap(bmp.Width, bmp.Height, bmp.Info.ColorType, bmp.Info.AlphaType);
77 |
78 | // Create a canvas to draw into the bitmap
79 | using var canvas = new SKCanvas(flipped);
80 |
81 | // Set a transform matrix which moves the bitmap to the right,
82 | // and then "scales" it by -1, which just flips the pixels
83 | // horizontally
84 | canvas.Translate(bmp.Width, 0);
85 | canvas.Scale(-1, 1);
86 | canvas.DrawBitmap(bmp, 0, 0);
87 | return flipped;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/SqliteHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using SQLite;
3 |
4 | namespace ServiceLib.Common;
5 |
6 | public sealed class SQLiteHelper
7 | {
8 | private static readonly Lazy _instance = new(() => new());
9 | public static SQLiteHelper Instance => _instance.Value;
10 | private readonly string _connstr;
11 | private SQLiteConnection _db;
12 | private SQLiteAsyncConnection _dbAsync;
13 | private readonly string _configDB = "guiNDB.db";
14 |
15 | public SQLiteHelper()
16 | {
17 | _connstr = Utils.GetConfigPath(_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 async Task InsertAllAsync(IEnumerable models)
28 | {
29 | return await _dbAsync.InsertAllAsync(models);
30 | }
31 |
32 | public async Task InsertAsync(object model)
33 | {
34 | return await _dbAsync.InsertAsync(model);
35 | }
36 |
37 | public async Task ReplaceAsync(object model)
38 | {
39 | return await _dbAsync.InsertOrReplaceAsync(model);
40 | }
41 |
42 | public async Task UpdateAsync(object model)
43 | {
44 | return await _dbAsync.UpdateAsync(model);
45 | }
46 |
47 | public async Task UpdateAllAsync(IEnumerable models)
48 | {
49 | return await _dbAsync.UpdateAllAsync(models);
50 | }
51 |
52 | public async Task DeleteAsync(object model)
53 | {
54 | return await _dbAsync.DeleteAsync(model);
55 | }
56 |
57 | public async Task DeleteAllAsync()
58 | {
59 | return await _dbAsync.DeleteAllAsync();
60 | }
61 |
62 | public async Task ExecuteAsync(string sql)
63 | {
64 | return await _dbAsync.ExecuteAsync(sql);
65 | }
66 |
67 | public async Task> QueryAsync(string sql) where T : new()
68 | {
69 | return await _dbAsync.QueryAsync(sql);
70 | }
71 |
72 | public AsyncTableQuery TableAsync() where T : new()
73 | {
74 | return _dbAsync.Table();
75 | }
76 |
77 | public async Task DisposeDbConnectionAsync()
78 | {
79 | await Task.Factory.StartNew(() =>
80 | {
81 | _db?.Close();
82 | _db?.Dispose();
83 | _db = null;
84 |
85 | _dbAsync?.GetConnection()?.Close();
86 | _dbAsync?.GetConnection()?.Dispose();
87 | _dbAsync = null;
88 | });
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/StringEx.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics.CodeAnalysis;
2 |
3 | namespace ServiceLib.Common;
4 |
5 | public static class StringEx
6 | {
7 | public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value)
8 | {
9 | return string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value);
10 | }
11 |
12 | public static bool IsNullOrWhiteSpace([NotNullWhen(false)] this string? value)
13 | {
14 | return string.IsNullOrWhiteSpace(value);
15 | }
16 |
17 | public static bool IsNotEmpty([NotNullWhen(false)] this string? value)
18 | {
19 | return !string.IsNullOrEmpty(value);
20 | }
21 |
22 | public static bool BeginWithAny(this string s, IEnumerable chars)
23 | {
24 | if (s.IsNullOrEmpty())
25 | {
26 | return false;
27 | }
28 | return chars.Contains(s.First());
29 | }
30 |
31 | private static bool IsWhiteSpace(this string value)
32 | {
33 | return value.All(char.IsWhiteSpace);
34 | }
35 |
36 | public static IEnumerable NonWhiteSpaceLines(this TextReader reader)
37 | {
38 | while (reader.ReadLine() is { } line)
39 | {
40 | if (line.IsWhiteSpace())
41 | {
42 | continue;
43 | }
44 | yield return line;
45 | }
46 | }
47 |
48 | public static string TrimEx(this string? value)
49 | {
50 | return value == null ? string.Empty : value.Trim();
51 | }
52 |
53 | public static string RemovePrefix(this string value, char prefix)
54 | {
55 | return value.StartsWith(prefix) ? value[1..] : value;
56 | }
57 |
58 | public static string RemovePrefix(this string value, string prefix)
59 | {
60 | return value.StartsWith(prefix) ? value[prefix.Length..] : value;
61 | }
62 |
63 | public static string UpperFirstChar(this string value)
64 | {
65 | if (string.IsNullOrEmpty(value))
66 | {
67 | return string.Empty;
68 | }
69 |
70 | return char.ToUpper(value.First()) + value[1..];
71 | }
72 |
73 | public static string AppendQuotes(this string value)
74 | {
75 | return string.IsNullOrEmpty(value) ? string.Empty : $"\"{value}\"";
76 | }
77 |
78 | public static int ToInt(this string? value, int defaultValue = 0)
79 | {
80 | return int.TryParse(value, out var result) ? result : defaultValue;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/WindowsUtils.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Cryptography;
2 | using System.Text;
3 | using Microsoft.Win32;
4 |
5 | namespace ServiceLib.Common;
6 |
7 | internal static class WindowsUtils
8 | {
9 | private static readonly string _tag = "WindowsUtils";
10 |
11 | public static string? RegReadValue(string path, string name, string def)
12 | {
13 | RegistryKey? regKey = null;
14 | try
15 | {
16 | regKey = Registry.CurrentUser.OpenSubKey(path, false);
17 | var value = regKey?.GetValue(name) as string;
18 | return value.IsNullOrEmpty() ? def : value;
19 | }
20 | catch (Exception ex)
21 | {
22 | Logging.SaveLog(_tag, ex);
23 | }
24 | finally
25 | {
26 | regKey?.Close();
27 | }
28 | return def;
29 | }
30 |
31 | public static void RegWriteValue(string path, string name, object value)
32 | {
33 | RegistryKey? regKey = null;
34 | try
35 | {
36 | regKey = Registry.CurrentUser.CreateSubKey(path);
37 | if (value.ToString().IsNullOrEmpty())
38 | {
39 | regKey?.DeleteValue(name, false);
40 | }
41 | else
42 | {
43 | regKey?.SetValue(name, value);
44 | }
45 | }
46 | catch (Exception ex)
47 | {
48 | Logging.SaveLog(_tag, ex);
49 | }
50 | finally
51 | {
52 | regKey?.Close();
53 | }
54 | }
55 |
56 | public static async Task RemoveTunDevice()
57 | {
58 | try
59 | {
60 | var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun"));
61 | var guid = new Guid(sum);
62 | var pnpUtilPath = @"C:\Windows\System32\pnputil.exe";
63 | var arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
64 |
65 | // Try to remove the device
66 | _ = await Utils.GetCliWrapOutput(pnpUtilPath, arg);
67 | }
68 | catch (Exception ex)
69 | {
70 | Logging.SaveLog(_tag, ex);
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Common/YamlUtils.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Core;
2 | using YamlDotNet.Serialization;
3 | using YamlDotNet.Serialization.NamingConventions;
4 |
5 | namespace ServiceLib.Common;
6 |
7 | public class YamlUtils
8 | {
9 | private static readonly string _tag = "YamlUtils";
10 |
11 | #region YAML
12 |
13 | ///
14 | /// Deserialize
15 | ///
16 | ///
17 | ///
18 | ///
19 | public static T FromYaml(string str)
20 | {
21 | var deserializer = new DeserializerBuilder()
22 | .WithNamingConvention(PascalCaseNamingConvention.Instance)
23 | .Build();
24 | try
25 | {
26 | var obj = deserializer.Deserialize(str);
27 | return obj;
28 | }
29 | catch (Exception ex)
30 | {
31 | Logging.SaveLog(_tag, ex);
32 | return deserializer.Deserialize("");
33 | }
34 | }
35 |
36 | ///
37 | /// Serialize
38 | ///
39 | ///
40 | ///
41 | public static string ToYaml(object? obj)
42 | {
43 | var result = string.Empty;
44 | if (obj == null)
45 | {
46 | return result;
47 | }
48 | var serializer = new SerializerBuilder()
49 | .WithNamingConvention(HyphenatedNamingConvention.Instance)
50 | .Build();
51 |
52 | try
53 | {
54 | result = serializer.Serialize(obj);
55 | }
56 | catch (Exception ex)
57 | {
58 | Logging.SaveLog(_tag, ex);
59 | }
60 | return result;
61 | }
62 |
63 | public static string? PreprocessYaml(string str)
64 | {
65 | try
66 | {
67 | var mergingParser = new MergingParser(new Parser(new StringReader(str)));
68 | var obj = new DeserializerBuilder().Build().Deserialize(mergingParser);
69 | return ToYaml(obj);
70 | }
71 | catch (Exception ex)
72 | {
73 | Logging.SaveLog(_tag, ex);
74 | return null;
75 | }
76 | }
77 |
78 | #endregion YAML
79 | }
80 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EConfigType.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
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 | Hysteria2 = 7,
12 | TUIC = 8,
13 | WireGuard = 9,
14 | HTTP = 10
15 | }
16 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/ECoreType.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum ECoreType
4 | {
5 | v2fly = 1,
6 | Xray = 2,
7 | v2fly_v5 = 4,
8 | mihomo = 13,
9 | hysteria = 21,
10 | naiveproxy = 22,
11 | tuic = 23,
12 | sing_box = 24,
13 | juicity = 25,
14 | hysteria2 = 26,
15 | brook = 27,
16 | overtls = 28,
17 | v2rayN = 99
18 | }
19 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EGirdOrientation.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EGirdOrientation
4 | {
5 | Horizontal,
6 | Vertical,
7 | Tab,
8 | }
9 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EGlobalHotkey.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EGlobalHotkey
4 | {
5 | ShowForm = 0,
6 | SystemProxyClear = 1,
7 | SystemProxySet = 2,
8 | SystemProxyUnchanged = 3,
9 | SystemProxyPac = 4,
10 | }
11 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EInboundProtocol.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EInboundProtocol
4 | {
5 | socks = 0,
6 | socks2,
7 | socks3,
8 | pac,
9 | api,
10 | api2,
11 | mixed,
12 | speedtest = 21
13 | }
14 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EMove.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EMove
4 | {
5 | Top = 1,
6 | Up = 2,
7 | Down = 3,
8 | Bottom = 4,
9 | Position = 5
10 | }
11 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EMsgCommand.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EMsgCommand
4 | {
5 | ClearMsg,
6 | SendMsgView,
7 | SendSnackMsg,
8 | RefreshProfiles,
9 | AppExit
10 | }
11 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EMultipleLoad.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EMultipleLoad
4 | {
5 | Random,
6 | RoundRobin,
7 | LeastPing,
8 | LeastLoad
9 | }
10 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EPresetType.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EPresetType
4 | {
5 | Default = 0,
6 | Russia = 1,
7 | Iran = 2,
8 | }
9 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/ERuleMode.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum ERuleMode
4 | {
5 | Rule = 0,
6 | Global = 1,
7 | Direct = 2,
8 | Unchanged = 3
9 | }
10 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EServerColName.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EServerColName
4 | {
5 | Def = 0,
6 | ConfigType,
7 | Remarks,
8 | Address,
9 | Port,
10 | Network,
11 | StreamSecurity,
12 | SubRemarks,
13 | DelayVal,
14 | SpeedVal,
15 |
16 | TodayDown,
17 | TodayUp,
18 | TotalDown,
19 | TotalUp
20 | }
21 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/ESpeedActionType.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum ESpeedActionType
4 | {
5 | Tcping,
6 | Realping,
7 | Speedtest,
8 | Mixedtest
9 | }
10 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/ESysProxyType.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum ESysProxyType
4 | {
5 | ForcedClear = 0,
6 | ForcedChange = 1,
7 | Unchanged = 2,
8 | Pac = 3
9 | }
10 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/ETheme.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum ETheme
4 | {
5 | FollowSystem,
6 | Dark,
7 | Light,
8 | Aquatic,
9 | Desert,
10 | Dusk,
11 | NightSky
12 | }
13 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/ETransport.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum ETransport
4 | {
5 | tcp,
6 | kcp,
7 | ws,
8 | httpupgrade,
9 | xhttp,
10 | h2,
11 | http,
12 | quic,
13 | grpc
14 | }
15 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Enums/EViewAction.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Enums;
2 |
3 | public enum EViewAction
4 | {
5 | CloseWindow,
6 | ShowYesNo,
7 | SaveFileDialog,
8 | AddBatchRoutingRulesYesNo,
9 | AdjustMainLvColWidth,
10 | SetClipboardData,
11 | AddServerViaClipboard,
12 | ImportRulesFromClipboard,
13 | ProfilesFocus,
14 | ShareSub,
15 | ShareServer,
16 | ShowHideWindow,
17 | ScanScreenTask,
18 | ScanImageTask,
19 | Shutdown,
20 | BrowseServer,
21 | ImportRulesFromFile,
22 | InitSettingFont,
23 | PasswordInput,
24 | SubEditWindow,
25 | RoutingRuleSettingWindow,
26 | RoutingRuleDetailsWindow,
27 | AddServerWindow,
28 | AddServer2Window,
29 | DNSSettingWindow,
30 | RoutingSettingWindow,
31 | OptionSettingWindow,
32 | GlobalHotkeySettingWindow,
33 | SubSettingWindow,
34 | DispatcherSpeedTest,
35 | DispatcherRefreshConnections,
36 | DispatcherRefreshProxyGroups,
37 | DispatcherProxiesDelayTest,
38 | DispatcherStatistics,
39 | DispatcherServerAvailability,
40 | DispatcherReload,
41 | DispatcherRefreshServersBiz,
42 | DispatcherRefreshIcon,
43 | DispatcherCheckUpdate,
44 | DispatcherCheckUpdateFinished,
45 | DispatcherShowMsg,
46 | }
47 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using ServiceLib.Base;
2 | global using ServiceLib.Common;
3 | global using ServiceLib.Enums;
4 | global using ServiceLib.Handler;
5 | global using ServiceLib.Handler.Fmt;
6 | global using ServiceLib.Services;
7 | global using ServiceLib.Services.Statistics;
8 | global using ServiceLib.Services.CoreConfig;
9 | global using ServiceLib.Models;
10 | global using ServiceLib.Resx;
11 | global using ServiceLib.Handler.SysProxy;
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Handler/ConnectionHandler.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Handler;
2 |
3 | public class ConnectionHandler
4 | {
5 | private static readonly Lazy _instance = new(() => new());
6 | public static ConnectionHandler Instance => _instance.Value;
7 |
8 | public async Task RunAvailabilityCheck()
9 | {
10 | var downloadHandle = new DownloadService();
11 | var time = await downloadHandle.RunAvailabilityCheck(null);
12 | var ip = time > 0 ? await GetIPInfo(downloadHandle) ?? Global.None : Global.None;
13 |
14 | return string.Format(ResUI.TestMeOutput, time, ip);
15 | }
16 |
17 | private async Task GetIPInfo(DownloadService downloadHandle)
18 | {
19 | var url = AppHandler.Instance.Config.SpeedTestItem.IPAPIUrl;
20 | if (url.IsNullOrEmpty())
21 | {
22 | return null;
23 | }
24 |
25 | var result = await downloadHandle.TryDownloadString(url, true, "");
26 | if (result == null)
27 | {
28 | return null;
29 | }
30 |
31 | var ipInfo = JsonUtils.Deserialize(result);
32 | if (ipInfo == null)
33 | {
34 | return null;
35 | }
36 |
37 | var ip = ipInfo.ip ?? ipInfo.clientIp ?? ipInfo.ip_addr ?? ipInfo.query;
38 | var country = ipInfo.country_code ?? ipInfo.country ?? ipInfo.countryCode ?? ipInfo.location?.country_code;
39 |
40 | return $"({country ?? "unknown"}) {ip}";
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Handler/Fmt/ClashFmt.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Handler.Fmt;
2 |
3 | public class ClashFmt : BaseFmt
4 | {
5 | public static ProfileItem? ResolveFull(string strData, string? subRemarks)
6 | {
7 | if (Contains(strData, "port", "socks-port", "proxies"))
8 | {
9 | var fileName = WriteAllText(strData, "yaml");
10 |
11 | var profileItem = new ProfileItem
12 | {
13 | CoreType = ECoreType.mihomo,
14 | Address = fileName,
15 | Remarks = subRemarks ?? "clash_custom"
16 | };
17 | return profileItem;
18 | }
19 |
20 | return null;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Handler/Fmt/NaiveproxyFmt.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Handler.Fmt;
2 |
3 | public class NaiveproxyFmt : BaseFmt
4 | {
5 | public static ProfileItem? ResolveFull(string strData, string? subRemarks)
6 | {
7 | if (Contains(strData, "listen", "proxy", "", ""))
8 | {
9 | var fileName = WriteAllText(strData);
10 |
11 | var profileItem = new ProfileItem
12 | {
13 | CoreType = ECoreType.naiveproxy,
14 | Address = fileName,
15 | Remarks = subRemarks ?? "naiveproxy_custom"
16 | };
17 | return profileItem;
18 | }
19 |
20 | return null;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/v2rayN/ServiceLib/Handler/Fmt/SingboxFmt.cs:
--------------------------------------------------------------------------------
1 | namespace ServiceLib.Handler.Fmt;
2 |
3 | public class SingboxFmt : BaseFmt
4 | {
5 | public static List? ResolveFullArray(string strData, string? subRemarks)
6 | {
7 | var configObjects = JsonUtils.Deserialize