Compare commits

...

48 Commits
7.6.2 ... 7.7.1

Author SHA1 Message Date
2dust
ce7303bd0d up 7.7.1 2025-02-01 14:16:54 +08:00
2dust
4c3318ac86 Revert "Update MainWindow.axaml.cs"
This reverts commit 4d95d7d8c0.
2025-02-01 14:11:12 +08:00
2dust
db25fdeee1 Revert "Remove using System.Reflection"
This reverts commit 732c3eee8b.
2025-02-01 13:51:28 +08:00
2dust
732c3eee8b Remove using System.Reflection 2025-02-01 10:34:05 +08:00
2dust
2b0d805b2f Update Directory.Build.props 2025-02-01 10:33:11 +08:00
2dust
4faa94b2a3 Cache when reading embedded resources 2025-01-31 16:02:29 +08:00
2dust
331d11aee2 Update .editorconfig 2025-01-31 15:59:44 +08:00
2dust
4d95d7d8c0 Update MainWindow.axaml.cs
if (Utils.IsOSX() || _config.UiItem.Hide2TrayWhenClose)
2025-01-31 15:59:35 +08:00
dependabot[bot]
fd82623c74 Bump actions/setup-dotnet from 4.2.0 to 4.3.0 (#6604)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v4.2.0...v4.3.0)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-31 09:17:42 +08:00
2dust
4a32b2c814 Fixed the issue of update the Windows self contained version 2025-01-30 18:06:13 +08:00
2dust
45264005a4 Code clean 2025-01-30 17:10:05 +08:00
2dust
253219dd16 Update .editorconfig 2025-01-30 16:35:48 +08:00
ShiinaRinne
b2feaf3ba9 [macOS] feat: auto run. https://github.com/2dust/v2rayN/issues/6383 (#6597) 2025-01-30 13:24:01 +08:00
2dust
6c5011ad68 Try to remove the tun device when restarting the service in Windows
https://github.com/2dust/v2rayN/pull/6561
2025-01-30 10:46:04 +08:00
ShiinaRinne
c0f8b6b84c [macOS] amend: Child window visibility handling (#6598)
https://github.com/2dust/v2rayN/pull/6596

When the main window is hidden, open child windows are mistakenly hidden as well.
This prevents reopening child windows after the main window is shown again.
2025-01-30 10:12:59 +08:00
ShiinaRinne
f71125d8f3 macOS 一些优化 (#6596)
* [macOS] hide icon in Dock

* [macOS] fix: close button not work

* [macOS] fix: cant directly show window when click `Show or hide the main window` on minimized
2025-01-29 19:26:40 +08:00
2dust
e674a025d8 Adjust Directory.Build.props
https://learn.microsoft.com/zh-cn/dotnet/core/deploying/trimming/trimming-options

https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/compiler-options/code-generation
2025-01-29 15:17:30 +08:00
2dust
dadc24876f Change Directory 2025-01-29 14:22:30 +08:00
Anatoliy
98d4801b7e Use Directory.Build.props for centralized configuration management (#6591)
* use Directory.Buld.props

* remove some properties
2025-01-28 20:01:59 +08:00
Anatoliy
0e50bfb6eb create editorconfig (#6592) 2025-01-28 12:16:04 +08:00
2dust
a5aa286535 Add Name to App.axaml 2025-01-25 20:45:56 +08:00
2dust
3caf025c3c Update README.md 2025-01-25 20:19:02 +08:00
2dust
c943c6c60a Update README.md 2025-01-25 20:15:16 +08:00
2dust
8c55c629cd Fix PackageReference 2025-01-24 20:28:04 +08:00
2dust
0c38ebb63f Added Avalonia UI Windows version compilation script 2025-01-24 20:01:36 +08:00
2dust
75df85f598 Release script adjust prerelease = true 2025-01-24 19:48:34 +08:00
2dust
59e99b2316 Downgrade ZXing.Net.Bindings.SkiaSharp to version 0.16.14
In linux report
Unhandled exception. System.TypeInitializationException: The type initializer for 'SkiaSharp.SKFontManager' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'SkiaSharp.SKObject' threw an exception.
 ---> System.InvalidOperationException: The version of the native libSkiaSharp library (88.1) is incompatible with this version of SkiaSharp. Supported versions of the native libSkiaSharp library are in the range [116.0, 117.0).
   at SkiaSharp.SkiaSharpVersion.CheckNativeLibraryCompatible(Version minSupported, Version current, Boolean throwIfIncompatible)
   at SkiaSharp.SkiaSharpVersion.CheckNativeLibraryCompatible(Boolean throwIfIncompatible)
   at SkiaSharp.SKObject..cctor()
2025-01-24 19:46:28 +08:00
Anatoliy
02f4dcbaf7 use Directory.Packages.props (#6581) 2025-01-24 19:00:21 +08:00
2dust
470dec5588 up PackageReference 2025-01-24 17:24:07 +08:00
2dust
be1e37ddd0 Hide the upgrade core in Windows 7 2025-01-24 14:26:51 +08:00
2dust
fdc32601a9 Update ResUI.Designer.cs 2025-01-24 14:25:56 +08:00
2dust
d3b86858e1 Revert "Use Directory.Packages.props (#6575)"
This reverts commit 9c20d9cb1f.
2025-01-24 14:25:13 +08:00
Anatoliy
9c20d9cb1f Use Directory.Packages.props (#6575) 2025-01-24 09:57:38 +08:00
alphax-hue3682
d2cda16378 Update Persian Translate (#6559) 2025-01-22 10:00:33 +08:00
aucub
2ab00d5b6f Add Package AppImage script (#6556) 2025-01-21 09:27:38 +08:00
OnceUponATimeInAmerica
1b8a58cd07 Update English translation (#6555) 2025-01-21 09:15:48 +08:00
Anatoliy
0c3293045f Remove extra .gitignore file and move .gitattributes to the root folder for consistent storage of .git-related files. (#6545) 2025-01-20 09:28:30 +08:00
2dust
4c4ce7e8d1 Revert "增加macos dmg软件签名 (#6541)"
This reverts commit a0d4a3f2e8.
2025-01-19 18:58:32 +08:00
zjt003
a0d4a3f2e8 增加macos dmg软件签名 (#6541)
* Update package-osx.sh

* Update build-osx.yml
2025-01-19 18:34:39 +08:00
2dust
26abe7e7d7 up 7.7.0 2025-01-19 09:36:43 +08:00
2dust
b9c86ed3a1 Modify the file name in winget release package 2025-01-19 09:35:19 +08:00
2dust
b7cff66a80 Remove the core name in the Windows release version 2025-01-19 09:34:37 +08:00
2dust
61a40d2860 up PackageReference 2025-01-19 09:27:20 +08:00
2dust
80eb569366 The bin folder is added to the package
54fe669d89
2025-01-18 21:10:41 +08:00
2dust
54fe669d89 Copy the bin folder to the storage location (for init) 2025-01-18 16:58:44 +08:00
2dust
0953237e9e Improvements 2025-01-18 16:01:52 +08:00
2dust
cf1a8599eb When updating the bin folder, skip the file if it already exists.
https://github.com/2dust/v2rayN/issues/6515
2025-01-17 10:27:29 +08:00
alphax-hue3682
171132be12 Update Persian Translate (#6513) 2025-01-16 15:56:05 +08:00
135 changed files with 2252 additions and 1337 deletions

170
.editorconfig Normal file
View File

@@ -0,0 +1,170 @@
root = true
[*]
charset = utf-8
indent_style = space
tab_width = 4
indent_size = 4
end_of_line = crlf
trim_trailing_whitespace = true
insert_final_newline = true
[*.{yml,yaml}]
indent_style = space
indent_size = 2
[*.cs]
dotnet_hide_advanced_members = true
dotnet_member_insertion_location = with_other_members_of_the_same_kind
dotnet_property_generation_behavior = prefer_throwing_properties
dotnet_search_reference_assemblies = true
dotnet_separate_import_directive_groups = false:warning
dotnet_sort_system_directives_first = true:warning
file_header_template = unset
dotnet_style_qualification_for_event = false:warning
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_method = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = always_for_clarity:warning
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
dotnet_style_require_accessibility_modifiers = always:warning
dotnet_prefer_system_hash_code = true:warning
dotnet_style_coalesce_expression = true:warning
dotnet_style_collection_initializer = false:warning
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_namespace_match_folder = true:warning
dotnet_style_null_propagation = true:warning
dotnet_style_object_initializer = true:warning
dotnet_style_operator_placement_when_wrapping = beginning_of_line
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_collection_expression = false:warning
dotnet_style_prefer_compound_assignment = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = false:warning
dotnet_style_prefer_conditional_expression_over_return = false:warning
dotnet_style_prefer_foreach_explicit_cast_in_source = always:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_simplified_boolean_expressions = true:warning
dotnet_style_prefer_simplified_interpolation = true:warning
dotnet_style_readonly_field = true:warning
dotnet_code_quality_unused_parameters = all:warning
dotnet_remove_unnecessary_suppression_exclusions = none
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true:warning
csharp_style_var_elsewhere = true:warning
csharp_style_var_for_built_in_types = true:warning
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_expression_bodied_accessors = when_on_single_line:warning
csharp_style_expression_bodied_constructors = false:warning
csharp_style_expression_bodied_indexers = when_on_single_line:warning
csharp_style_expression_bodied_lambdas = when_on_single_line:warning
csharp_style_expression_bodied_local_functions = false:warning
csharp_style_expression_bodied_methods = false:warning
csharp_style_expression_bodied_operators = false:warning
csharp_style_expression_bodied_properties = when_on_single_line:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_prefer_extended_property_pattern = true:warning
csharp_style_prefer_not_pattern = true:warning
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_switch_expression = false:warning
csharp_style_conditional_delegate_call = true:warning
csharp_prefer_static_anonymous_function = true:warning
csharp_prefer_static_local_function = true:warning
csharp_preferred_modifier_order = public,internal,private,protected,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:warning
csharp_style_prefer_readonly_struct = true:warning
csharp_style_prefer_readonly_struct_member = true:warning
csharp_prefer_braces = true:warning
csharp_prefer_simple_using_statement = true:warning
csharp_prefer_system_threading_lock = true:warning
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_prefer_method_group_conversion = true:warning
csharp_style_prefer_primary_constructors = true:warning
csharp_style_prefer_top_level_statements = false:warning
csharp_prefer_simple_default_expression = true:warning
csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
csharp_style_inlined_variable_declaration = true:warning
csharp_style_prefer_index_operator = false:warning
csharp_style_prefer_local_over_anonymous_function = true:warning
csharp_style_prefer_null_check_over_type_check = true:warning
csharp_style_prefer_range_operator = false:warning
csharp_style_prefer_tuple_swap = true:warning
csharp_style_prefer_utf8_string_literals = true:warning
csharp_style_throw_expression = true:warning
csharp_style_unused_value_assignment_preference = discard_variable:warning
csharp_style_unused_value_expression_statement_preference = discard_variable:warning
csharp_using_directive_placement = outside_namespace:warning
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:warning
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:warning
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false:warning
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:warning
csharp_style_allow_embedded_statements_on_same_line_experimental = false:warning
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = true
csharp_indent_labels = no_change
csharp_indent_switch_labels = true
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false:warning
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = false
dotnet_naming_rule.interface_should_be_pascal.severity = warning
dotnet_naming_rule.interface_should_be_pascal.symbols = interface
dotnet_naming_rule.interface_should_be_pascal.style = pascal
dotnet_naming_rule.types_should_be_pascal.severity = warning
dotnet_naming_rule.types_should_be_pascal.symbols = types
dotnet_naming_rule.types_should_be_pascal.style = pascal
dotnet_naming_rule.non_field_members_should_be_pascal.severity = warning
dotnet_naming_rule.non_field_members_should_be_pascal.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal.style = pascal
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = *
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = *
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = *
dotnet_naming_symbols.non_field_members.required_modifiers =
dotnet_naming_style.pascal.required_prefix =
dotnet_naming_style.pascal.required_suffix =
dotnet_naming_style.pascal.word_separator =
dotnet_naming_style.pascal.capitalization = pascal_case

View File

@@ -1,10 +1,11 @@
# Set update schedule for GitHub Actions
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every daily
interval: "daily"
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "daily"

View File

@@ -26,18 +26,23 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.2.2
- name: Setup
uses: actions/setup-dotnet@v4.3.0
with:
dotnet-version: '8.0.x'
- name: Build
run: |
cd v2rayN
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPath64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPathArm64
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r linux-arm64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPath64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPathArm64
- name: Upload build artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v4.6.0
with:
name: v2rayN-linux
path: |
@@ -58,6 +63,23 @@ jobs:
file: ${{ github.workspace }}/v2rayN*.deb
tag: ${{ github.event.inputs.release_tag }}
file_glob: true
prerelease: true
- name: Package AppImage
if: github.event.inputs.release_tag != ''
run: |
chmod 755 package-appimage.sh
./package-appimage.sh $OutputArch $OutputPath64 ${{ github.event.inputs.release_tag }}
./package-appimage.sh $OutputArchArm $OutputPathArm64 ${{ github.event.inputs.release_tag }}
- name: Upload AppImage to release
uses: svenstaro/upload-release-action@v2
if: github.event.inputs.release_tag != ''
with:
file: ${{ github.workspace }}/v2rayN*.AppImage
tag: ${{ github.event.inputs.release_tag }}
file_glob: true
prerelease: true
# release zip archive
- name: Package release zip archive

View File

@@ -26,18 +26,23 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.2.2
- name: Setup
uses: actions/setup-dotnet@v4.3.0
with:
dotnet-version: '8.0.x'
- name: Build
run: |
cd v2rayN
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPath64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPathArm64
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPath64
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r osx-arm64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -o $OutputPathArm64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPath64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -o $OutputPathArm64
- name: Upload build artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v4.6.0
with:
name: v2rayN-macos
path: |
@@ -59,6 +64,7 @@ jobs:
file: ${{ github.workspace }}/v2rayN*.dmg
tag: ${{ github.event.inputs.release_tag }}
file_glob: true
prerelease: true
# release zip archive
- name: Package release zip archive

View File

@@ -0,0 +1,50 @@
name: release Windows desktop (Avalonia UI)
on:
workflow_dispatch:
inputs:
release_tag:
required: false
type: string
push:
branches:
- master
env:
OutputArch: "windows-64"
OutputArchArm: "windows-arm64"
OutputPath64: "${{ github.workspace }}/v2rayN/Release/windows-64"
OutputPathArm64: "${{ github.workspace }}/v2rayN/Release/windows-arm64"
jobs:
build:
strategy:
matrix:
configuration: [Release]
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.2.2
- name: Setup
uses: actions/setup-dotnet@v4.3.0
with:
dotnet-version: '8.0.x'
- name: Build
run: |
cd v2rayN
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r win-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64
dotnet publish ./v2rayN.Desktop/v2rayN.Desktop.csproj -c Release -r win-arm64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -p:EnableWindowsTargeting=true -o $OutputPath64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
- name: Upload build artifacts
uses: actions/upload-artifact@v4.6.0
with:
name: v2rayN-windows-desktop
path: |
${{ github.workspace }}/v2rayN/Release/windows*

View File

@@ -27,26 +27,26 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v4.2.2
- name: Setup
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v4.3.0
with:
dotnet-version: '8.0.x'
- name: Build
run: |
cd v2rayN
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-arm64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64Sc
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -p:EnableWindowsTargeting=true -o $OutputPath64Sc
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained=false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-arm64 --self-contained=false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
dotnet publish ./v2rayN/v2rayN.csproj -c Release -r win-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64Sc
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained=false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPath64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 --self-contained=false -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:EnableWindowsTargeting=true -o $OutputPathArm64
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-x64 --self-contained=true -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:PublishTrimmed=true -p:EnableWindowsTargeting=true -o $OutputPath64Sc
- name: Upload build artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v4.6.0
with:
name: v2rayN-windows
path: |
@@ -58,10 +58,8 @@ jobs:
run: |
chmod 755 package-release-zip.sh
./package-release-zip.sh $OutputArch $OutputPath64
./package-release-zip.sh "windows-64-With-Core" $OutputPath64
./package-release-zip.sh $OutputArchArm $OutputPathArm64
./package-release-zip.sh "windows-64-SelfContained" $OutputPath64Sc
./package-release-zip.sh "windows-64-SelfContained-With-Core" $OutputPath64Sc
- name: Upload zip archive to release
uses: svenstaro/upload-release-action@v2

View File

@@ -22,7 +22,7 @@ jobs:
$github = Invoke-RestMethod -uri "https://api.github.com/repos/2dust/v2rayN/releases"
$targetRelease = $github | Where-Object -Property prerelease -match 'False' | Select -First 1
$installerUrl = $targetRelease | Select -ExpandProperty assets -First 1 | Where-Object -Property name -match 'v2rayN-windows-64-With-Core\.zip*' | Select -ExpandProperty browser_download_url
$installerUrl = $targetRelease | Select -ExpandProperty assets -First 1 | Where-Object -Property name -match 'v2rayN-windows-64\.zip*' | Select -ExpandProperty browser_download_url
$ver = $targetRelease.tag_name

415
.gitignore vendored
View File

@@ -1,19 +1,400 @@
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
/v2rayN/.vs/
/v2rayN/v2rayN/bin/Debug/app.publish
/v2rayN/v2rayN/bin/Debug
/v2rayN/v2rayN/bin/Release
/v2rayN/v2rayN/obj/
/v2rayN/.vs/v2rayN/DesignTimeBuild
/v2rayN/packages
.vs/ProjectSettings.json
.vs/slnx.sqlite
.vs/VSWorkspaceState.json
/v2rayN/v2rayUpgrade/bin/Debug
/v2rayN/v2rayUpgrade/bin/Release
/v2rayN/v2rayUpgrade/obj/
# User-specific files
*.rsuser
*.suo
*.user
/.vs/v2rayN
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
# but not Directory.Build.rsp, as it configures directory-level build defaults
!Directory.Build.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml

View File

@@ -1,5 +1,5 @@
# v2rayN
A GUI client for Windows, Linux and macOS, support [Xray core](https://github.com/XTLS/Xray-core) and [sing-box-core](https://github.com/SagerNet/sing-box/releases) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
A GUI client for Windows, Linux and macOS, support [Xray](https://github.com/XTLS/Xray-core) and [sing-box](https://github.com/SagerNet/sing-box/releases) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/v2rayN)](https://github.com/2dust/v2rayN/commits/master)
@@ -9,26 +9,8 @@ A GUI client for Windows, Linux and macOS, support [Xray core](https://github.co
## How to use
Check [Release files introduction](https://github.com/2dust/v2rayN/wiki/Release-files-introduction) and select the version you need to download
### Windows
- Run `v2rayN.exe`
### Linux
- `chmod +x v2rayN` Run `./v2rayN` under user permissions
```
Debian 9+
Ubuntu 16.04+
Fedora 30+
```
### macOS
- `chmod +x v2rayN` Run `./v2rayN` under user permissions
```
macOS 11+
```
## Requirements
- [Microsoft .NET 8.0 Desktop Runtime ](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
- [Supported cores](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)
Read the [Wiki](https://github.com/2dust/v2rayN/wiki) for details.
## Telegram Channel
[github_2dust](https://t.me/github_2dust)

71
package-appimage.sh Normal file
View File

@@ -0,0 +1,71 @@
#!/bin/bash
Arch="$1"
OutputPath="$2"
Version="$3"
FileName="v2rayN-${Arch}.zip"
wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
7z x $FileName -aoa
cp -rf v2rayN-${Arch}/* $OutputPath
PackagePath="v2rayN-Package-${Arch}"
mkdir -p "${PackagePath}/AppDir/opt"
cp -rf $OutputPath "${PackagePath}/AppDir/opt/v2rayN"
echo "When this file exists, app will not store configs under this folder" >"${PackagePath}/AppDir/opt/v2rayN/NotStoreConfigHere.txt"
if [ $Arch = "linux-64" ]; then
Arch2="x86_64"
Arch3="amd64"
else
Arch2="aarch64"
Arch3="arm64"
fi
echo $Arch2
# basic
cat >"${PackagePath}/AppDir/AppRun" <<-EOF
#!/bin/sh
HERE="\$(dirname "\$(readlink -f "\${0}")")"
export PATH="\${HERE}"/opt/v2rayN/:"\${PATH}"
export LD_LIBRARY_PATH="\${HERE}"/opt/v2rayN/:"\${LD_LIBRARY_PATH}"
exec "\${HERE}/opt/v2rayN/v2rayN" \$@
EOF
cat >"${PackagePath}/AppDir/v2rayN.desktop" <<-EOF
[Desktop Entry]
Name=v2rayN
Comment=A GUI client for Windows and Linux, support Xray core and sing-box-core and others
Exec=v2rayN
Icon=v2rayN
Terminal=false
Type=Application
Categories=Network;
EOF
sudo cp "${PackagePath}/AppDir/opt/v2rayN/v2rayN.png" "${PackagePath}/AppDir/v2rayN.png"
sudo dpkg --add-architecture ${Arch3}
mkdir deb_folder
cd deb_folder
apt download libicu74:${Arch3}
apt download libfontconfig1:${Arch3} || true
apt download libfontconfig:${Arch3} || true
mkdir ../output_folder
for deb in *.deb; do
dpkg-deb -x "$deb" ../output_folder/
done
cd ..
find output_folder -type f -name "*.so*" -exec cp {} ${PackagePath}/AppDir/opt/v2rayN/ \;
find output_folder -type l -name "*.so*" -exec cp {} ${PackagePath}/AppDir/opt/v2rayN/ \;
rm -rf deb_folder output_folder
sudo chmod 0755 "${PackagePath}/AppDir/opt/v2rayN/v2rayN"
sudo chmod 0755 "${PackagePath}/AppDir/AppRun"
# desktop && PATH
wget "https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage"
chmod a+x appimagetool-x86_64.AppImage
sudo apt install -y libfuse2
sudo ./appimagetool-x86_64.AppImage "${PackagePath}/AppDir"
sudo mv "v2rayN-${Arch2}.AppImage" "v2rayN-${Arch}.AppImage"

View File

@@ -4,6 +4,11 @@ Arch="$1"
OutputPath="$2"
Version="$3"
FileName="v2rayN-${Arch}.zip"
wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
7z x $FileName
cp -rf v2rayN-${Arch}/* $OutputPath
PackagePath="v2rayN-Package-${Arch}"
mkdir -p "${PackagePath}/DEBIAN"
mkdir -p "${PackagePath}/opt"

View File

@@ -4,6 +4,11 @@ Arch="$1"
OutputPath="$2"
Version="$3"
FileName="v2rayN-${Arch}.zip"
wget -nv -O $FileName "https://github.com/2dust/v2rayN-core-bin/raw/refs/heads/master/$FileName"
7z x $FileName
cp -rf v2rayN-${Arch}/* $OutputPath
PackagePath="v2rayN-Package-${Arch}"
mkdir -p "$PackagePath/v2rayN.app/Contents/Resources"
cp -rf "$OutputPath" "$PackagePath/v2rayN.app/Contents/MacOS"

363
v2rayN/.gitignore vendored
View File

@@ -1,363 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd

View File

@@ -2,14 +2,14 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Copyright>Copyright © 2017-2025 (GPLv3)</Copyright>
<FileVersion>1.3.1</FileVersion>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Update="Resx\Resource.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Update="Resx\Resource.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
@@ -17,11 +17,4 @@
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resx\Resource.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

View File

@@ -1,4 +1,4 @@
using System.Diagnostics;
using System.Diagnostics;
using System.IO.Compression;
using System.Text;
@@ -10,7 +10,7 @@ namespace AmazTool
{
Console.WriteLine($"{Resx.Resource.StartUnzipping}\n{fileName}");
Waiting(5);
Utils.Waiting(5);
if (!File.Exists(fileName))
{
@@ -42,12 +42,12 @@ namespace AmazTool
StringBuilder sb = new();
try
{
string thisAppOldFile = $"{Utils.GetExePath()}.tmp";
var thisAppOldFile = $"{Utils.GetExePath()}.tmp";
File.Delete(thisAppOldFile);
string splitKey = "/";
var splitKey = "/";
using ZipArchive archive = ZipFile.OpenRead(fileName);
foreach (ZipArchiveEntry entry in archive.Entries)
using var archive = ZipFile.OpenRead(fileName);
foreach (var entry in archive.Entries)
{
try
{
@@ -59,16 +59,22 @@ namespace AmazTool
Console.WriteLine(entry.FullName);
var lst = entry.FullName.Split(splitKey);
if (lst.Length == 1) continue;
string fullName = string.Join(splitKey, lst[1..lst.Length]);
if (lst.Length == 1)
continue;
var fullName = string.Join(splitKey, lst[1..lst.Length]);
if (string.Equals(Utils.GetExePath(), Utils.GetPath(fullName), StringComparison.OrdinalIgnoreCase))
{
File.Move(Utils.GetExePath(), thisAppOldFile);
}
string entryOutputPath = Utils.GetPath(fullName);
var entryOutputPath = Utils.GetPath(fullName);
Directory.CreateDirectory(Path.GetDirectoryName(entryOutputPath)!);
//In the bin folder, if the file already exists, it will be skipped
if (fullName.StartsWith("bin") && File.Exists(entryOutputPath))
{
continue;
}
entry.ExtractToFile(entryOutputPath, true);
Console.WriteLine(entryOutputPath);
@@ -91,18 +97,9 @@ namespace AmazTool
}
Console.WriteLine(Resx.Resource.Restartv2rayN);
Waiting(2);
Utils.Waiting(2);
Utils.StartV2RayN();
}
public static void Waiting(int second)
{
for (var i = second; i > 0; i--)
{
Console.WriteLine(i);
Thread.Sleep(1000);
}
}
}
}

View File

@@ -39,5 +39,14 @@ namespace AmazTool
};
process.Start();
}
public static void Waiting(int second)
{
for (var i = second; i > 0; i--)
{
Console.WriteLine(i);
Thread.Sleep(1000);
}
}
}
}

View File

@@ -0,0 +1,33 @@
<Project>
<PropertyGroup>
<Version>7.7.1</Version>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<NoWarn>CA1031;CS1591;NU1507</NoWarn>
<Nullable>annotations</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Authors>2dust</Authors>
<PackageLicenseExpression>GPL-3.0</PackageLicenseExpression>
<Copyright>Copyright © 2017-$([System.DateTime]::UtcNow.Year) $(Authors)</Copyright>
<InvariantGlobalization>false</InvariantGlobalization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<DebugType>embedded</DebugType>
<EventSourceSupport>false</EventSourceSupport>
<StackTraceSupport>false</StackTraceSupport>
<MetricsSupport>false</MetricsSupport>
<MetadataUpdaterSupport>false</MetadataUpdaterSupport>
<EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
<EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
<UseSystemResourceKeys>true</UseSystemResourceKeys>
<PublishSingleFile>true</PublishSingleFile>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,33 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.2.3"/>
<PackageVersion Include="Avalonia.Desktop" Version="11.2.3" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.3" />
<PackageVersion Include="Avalonia.ReactiveUI" Version="11.2.3" />
<PackageVersion Include="CliWrap" Version="3.7.1" />
<PackageVersion Include="Downloader" Version="3.3.3" />
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.2.0" />
<PackageVersion Include="MaterialDesignThemes" Version="5.2.1" />
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
<PackageVersion Include="QRCoder" Version="1.6.0" />
<PackageVersion Include="ReactiveUI" Version="20.1.63" />
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
<PackageVersion Include="ReactiveUI.WPF" Version="20.1.63" />
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.4" />
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.4" />
<PackageVersion Include="Splat.NLog" Version="15.2.22" />
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
<PackageVersion Include="TaskScheduler" Version="2.11.0" />
<PackageVersion Include="WebDav.Client" Version="2.8.0" />
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
</ItemGroup>
</Project>

View File

@@ -1,5 +1,5 @@
using Downloader;
using System.Net;
using Downloader;
namespace ServiceLib.Common
{

View File

@@ -0,0 +1,61 @@
using System.Collections.Concurrent;
using System.Reflection;
namespace ServiceLib.Common;
public static class EmbedUtils
{
private static readonly string _tag = "EmbedUtils";
private static readonly ConcurrentDictionary<string, string> _dicEmbedCache = new();
/// <summary>
/// Get embedded text resources
/// </summary>
/// <param name="res"></param>
/// <returns></returns>
public static string GetEmbedText(string res)
{
if (_dicEmbedCache.TryGetValue(res, out var value))
{
return value;
}
var result = string.Empty;
try
{
var assembly = Assembly.GetExecutingAssembly();
using var stream = assembly.GetManifestResourceStream(res);
ArgumentNullException.ThrowIfNull(stream);
using StreamReader reader = new(stream);
result = reader.ReadToEnd();
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
_dicEmbedCache.TryAdd(res, result);
return result;
}
/// <summary>
/// Get local storage resources
/// </summary>
/// <returns></returns>
public static string? LoadResource(string? res)
{
try
{
if (File.Exists(res))
{
return File.ReadAllText(res);
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return null;
}
}

View File

@@ -156,7 +156,7 @@ namespace ServiceLib.Common
return true;
}
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive, string? ignoredName)
public static void CopyDirectory(string sourceDir, string destinationDir, bool recursive, bool overwrite, string? ignoredName = null)
{
// Get information about the source directory
var dir = new DirectoryInfo(sourceDir);
@@ -183,7 +183,11 @@ namespace ServiceLib.Common
continue;
}
var targetFilePath = Path.Combine(destinationDir, file.Name);
file.CopyTo(targetFilePath, true);
if (!overwrite && File.Exists(targetFilePath))
{
continue;
}
file.CopyTo(targetFilePath, overwrite);
}
// If recursive and copying subdirectories, recursively call this method
@@ -192,7 +196,7 @@ namespace ServiceLib.Common
foreach (var subDir in dirs)
{
var newDestinationDir = Path.Combine(destinationDir, subDir.Name);
CopyDirectory(subDir.FullName, newDestinationDir, true, ignoredName);
CopyDirectory(subDir.FullName, newDestinationDir, true, overwrite, ignoredName);
}
}
}

View File

@@ -38,13 +38,15 @@ namespace ServiceLib.Common
public async Task<string?> GetAsync(string url)
{
if (Utils.IsNullOrEmpty(url)) return null;
if (Utils.IsNullOrEmpty(url))
return null;
return await httpClient.GetStringAsync(url);
}
public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default)
{
if (Utils.IsNullOrEmpty(url)) return null;
if (Utils.IsNullOrEmpty(url))
return null;
return await client.GetStringAsync(url, token);
}
@@ -75,11 +77,13 @@ namespace ServiceLib.Common
{
ArgumentNullException.ThrowIfNull(url);
ArgumentNullException.ThrowIfNull(fileName);
if (File.Exists(fileName)) File.Delete(fileName);
if (File.Exists(fileName))
File.Delete(fileName);
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
if (!response.IsSuccessStatusCode) throw new Exception(response.StatusCode.ToString());
if (!response.IsSuccessStatusCode)
throw new Exception(response.StatusCode.ToString());
var total = response.Content.Headers.ContentLength ?? -1L;
var canReportProgress = total != -1 && progress != null;
@@ -97,7 +101,8 @@ namespace ServiceLib.Common
var read = await stream.ReadAsync(buffer, token);
totalRead += read;
if (read == 0) break;
if (read == 0)
break;
await file.WriteAsync(buffer.AsMemory(0, read), token);
if (canReportProgress)

View File

@@ -1,4 +1,4 @@
using System.Diagnostics;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ServiceLib.Common
@@ -75,7 +75,8 @@ namespace ServiceLib.Common
private void Dispose(bool disposing)
{
if (disposed) return;
if (disposed)
return;
disposed = true;
if (disposing)

View File

@@ -1,4 +1,4 @@
using NLog;
using NLog;
using NLog.Config;
using NLog.Targets;
@@ -27,14 +27,16 @@ namespace ServiceLib.Common
public static void SaveLog(string strContent)
{
if (!LogManager.IsLoggingEnabled()) return;
if (!LogManager.IsLoggingEnabled())
return;
LogManager.GetLogger("Log1").Info(strContent);
}
public static void SaveLog(string strTitle, Exception ex)
{
if (!LogManager.IsLoggingEnabled()) return;
if (!LogManager.IsLoggingEnabled())
return;
var logger = LogManager.GetLogger("Log2");
logger.Debug($"{strTitle},{ex.Message}");

View File

@@ -19,8 +19,10 @@ public static class ProcUtils
}
try
{
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes();
if (arguments.Contains(' ')) arguments = arguments.AppendQuotes();
if (fileName.Contains(' '))
fileName = fileName.AppendQuotes();
if (arguments.Contains(' '))
arguments = arguments.AppendQuotes();
Process process = new()
{
@@ -83,10 +85,18 @@ public static class ProcUtils
GetProcessKeyInfo(proc, review, out var procId, out var fileName, out var processName);
try { proc?.Kill(true); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Kill(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Close(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try { proc?.Dispose(); } catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try
{ proc?.Kill(true); }
catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try
{ proc?.Kill(); }
catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try
{ proc?.Close(); }
catch (Exception ex) { Logging.SaveLog(_tag, ex); }
try
{ proc?.Dispose(); }
catch (Exception ex) { Logging.SaveLog(_tag, ex); }
await Task.Delay(300);
await ProcessKillByKeyInfo(review, procId, fileName, processName);
@@ -97,7 +107,8 @@ public static class ProcUtils
procId = null;
fileName = null;
processName = null;
if (!review) return;
if (!review)
return;
try
{
procId = proc?.Id;

View File

@@ -1,5 +1,5 @@
using SQLite;
using System.Collections;
using SQLite;
namespace ServiceLib.Common
{

View File

@@ -1,4 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;
namespace ServiceLib.Common
{
@@ -21,7 +21,8 @@ namespace ServiceLib.Common
public static bool BeginWithAny(this string s, IEnumerable<char> chars)
{
if (s.IsNullOrEmpty()) return false;
if (s.IsNullOrEmpty())
return false;
return chars.Contains(s.First());
}
@@ -34,7 +35,8 @@ namespace ServiceLib.Common
{
while (reader.ReadLine() is { } line)
{
if (line.IsWhiteSpace()) continue;
if (line.IsWhiteSpace())
continue;
yield return line;
}
}

View File

@@ -1,5 +1,3 @@
using CliWrap;
using CliWrap.Buffered;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Net;
@@ -10,6 +8,8 @@ using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using CliWrap;
using CliWrap.Buffered;
namespace ServiceLib.Common
{
@@ -17,56 +17,6 @@ namespace ServiceLib.Common
{
private static readonly string _tag = "Utils";
#region
/// <summary>
/// 获取嵌入文本资源
/// </summary>
/// <param name="res"></param>
/// <returns></returns>
public static string GetEmbedText(string res)
{
var result = string.Empty;
try
{
var assembly = Assembly.GetExecutingAssembly();
using var stream = assembly.GetManifestResourceStream(res);
ArgumentNullException.ThrowIfNull(stream);
using StreamReader reader = new(stream);
result = reader.ReadToEnd();
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return result;
}
/// <summary>
/// 取得存储资源
/// </summary>
/// <returns></returns>
public static string? LoadResource(string? res)
{
try
{
if (File.Exists(res))
{
return File.ReadAllText(res);
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
return null;
}
#endregion
#region
/// <summary>
@@ -176,7 +126,8 @@ namespace ServiceLib.Common
{
try
{
if (plainText.IsNullOrEmpty()) return "";
if (plainText.IsNullOrEmpty())
return "";
plainText = plainText.Trim()
.Replace(Environment.NewLine, "")
.Replace("\n", "")
@@ -372,7 +323,8 @@ namespace ServiceLib.Common
public static bool IsBase64String(string? plainText)
{
if (plainText.IsNullOrEmpty()) return false;
if (plainText.IsNullOrEmpty())
return false;
var buffer = new Span<byte>(new byte[plainText.Length]);
return Convert.TryFromBase64String(plainText, buffer, out var _);
}
@@ -462,9 +414,12 @@ namespace ServiceLib.Common
if (IPAddress.TryParse(ip, out var address))
{
var ipBytes = address.GetAddressBytes();
if (ipBytes[0] == 10) return true;
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31) return true;
if (ipBytes[0] == 192 && ipBytes[1] == 168) return true;
if (ipBytes[0] == 10)
return true;
if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31)
return true;
if (ipBytes[0] == 192 && ipBytes[1] == 168)
return true;
}
return false;
@@ -519,7 +474,7 @@ namespace ServiceLib.Common
public static bool UpgradeAppExists(out string upgradeFileName)
{
upgradeFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, GetExeName("AmazTool"));
upgradeFileName = Path.Combine(GetBaseDirectory(), GetExeName("AmazTool"));
return File.Exists(upgradeFileName);
}
@@ -604,9 +559,11 @@ namespace ServiceLib.Common
foreach (var host in hostsList)
{
if (host.StartsWith("#")) continue;
if (host.StartsWith("#"))
continue;
var hostItem = host.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (hostItem.Length != 2) continue;
if (hostItem.Length != 2)
continue;
systemHosts.Add(hostItem.Last(), hostItem.First());
}
}
@@ -666,12 +623,12 @@ namespace ServiceLib.Common
try
{
//When this file exists, it is equivalent to having no permission to read and write
if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NotStoreConfigHere.txt")))
if (File.Exists(Path.Combine(GetBaseDirectory(), "NotStoreConfigHere.txt")))
{
return false;
}
var tempPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "guiTemps");
var tempPath = Path.Combine(GetBaseDirectory(), "guiTemps");
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
@@ -699,6 +656,11 @@ namespace ServiceLib.Common
return Path.Combine(startupPath, fileName);
}
public static string GetBaseDirectory(string fileName = "")
{
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
}
public static string GetExePath()
{
return Environment.ProcessPath ?? Process.GetCurrentProcess().MainModule?.FileName ?? string.Empty;
@@ -706,12 +668,12 @@ namespace ServiceLib.Common
public static string StartupPath()
{
if (Utils.IsNonWindows() && Environment.GetEnvironmentVariable("V2RAYN_LOCAL_APPLICATION_DATA") == "1")
if (Environment.GetEnvironmentVariable(Global.LocalAppData) == "1")
{
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "v2rayN");
}
return AppDomain.CurrentDomain.BaseDirectory;
return GetBaseDirectory();
}
public static string GetTempPath(string filename = "")
@@ -870,8 +832,10 @@ namespace ServiceLib.Common
public static async Task<string?> SetLinuxChmod(string? fileName)
{
if (fileName.IsNullOrEmpty()) return null;
if (fileName.Contains(' ')) fileName = fileName.AppendQuotes();
if (fileName.IsNullOrEmpty())
return null;
if (fileName.Contains(' '))
fileName = fileName.AppendQuotes();
//File.SetUnixFileMode(fileName, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
var arg = new List<string>() { "-c", $"chmod +x {fileName}" };
return await GetCliWrapOutput("/bin/bash", arg);

View File

@@ -1,4 +1,6 @@
using Microsoft.Win32;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Win32;
namespace ServiceLib.Common
{
@@ -50,5 +52,23 @@ namespace ServiceLib.Common
regKey?.Close();
}
}
public static async Task RemoveTunDevice()
{
try
{
var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun"));
var guid = new Guid(sum);
var pnpUtilPath = @"C:\Windows\System32\pnputil.exe";
var arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
// Try to remove the device
await Utils.GetCliWrapOutput(pnpUtilPath, arg);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
}
}

View File

@@ -18,7 +18,6 @@
public const string GeoUrl = "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/{0}.dat";
public const string SpeedPingTestUrl = @"https://www.google.com/generate_204";
public const string JuicityCoreUrl = "https://github.com/juicity/juicity/releases";
public const string CustomRoutingListUrl = @"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/";
public const string SingboxRulesetUrl = @"https://raw.githubusercontent.com/2dust/sing-box-rules/rule-set-{0}/{1}.srs";
public const string IPAPIUrl = "https://api.ip.sb/geoip";
@@ -68,7 +67,6 @@
public const string UserEMail = "t@t.tt";
public const string AutoRunRegPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
public const string AutoRunName = "v2rayNAutoRun";
public const string CustomIconName = "v2rayN.ico";
public const string SystemProxyExceptionsWindows = "localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*";
public const string SystemProxyExceptionsLinux = "localhost,127.0.0.0/8,::1";
public const string RoutingRuleComma = "<COMMA>";
@@ -80,71 +78,82 @@
public const int MinFontSize = 8;
public const string RebootAs = "rebootas";
public const string AvaAssets = "avares://v2rayN/Assets/";
public const string LocalAppData = "V2RAYN_LOCAL_APPLICATION_DATA";
public const string V2RayLocalAsset = "V2RAY_LOCATION_ASSET";
public const string XrayLocalAsset = "XRAY_LOCATION_ASSET";
public static readonly List<string> IEProxyProtocols = new() {
public static readonly List<string> IEProxyProtocols =
[
"{ip}:{http_port}",
"socks={ip}:{socks_port}",
"http={ip}:{http_port};https={ip}:{http_port};ftp={ip}:{http_port};socks={ip}:{socks_port}",
"http=http://{ip}:{http_port};https=http://{ip}:{http_port}",
""
};
];
public static readonly List<string> SubConvertUrls = new List<string> {
public static readonly List<string> SubConvertUrls =
[
@"https://sub.xeton.dev/sub?url={0}",
@"https://api.dler.io/sub?url={0}",
@"http://127.0.0.1:25500/sub?url={0}",
""
};
];
public static readonly List<string> SubConvertConfig = new List<string> {
@"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini"
};
public static readonly List<string> SubConvertConfig =
[@"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini"];
public static readonly List<string> SubConvertTargets = new List<string> {
public static readonly List<string> SubConvertTargets =
[
"",
"mixed",
"v2ray",
"clash",
"ss",
};
"ss"
];
public static readonly List<string> SpeedTestUrls = new() {
public static readonly List<string> SpeedTestUrls =
[
@"https://speed.cloudflare.com/__down?bytes=100000000",
@"https://speed.cloudflare.com/__down?bytes=50000000",
@"https://speed.cloudflare.com/__down?bytes=10000000",
@"https://cachefly.cachefly.net/50mb.test",
};
@"https://cachefly.cachefly.net/50mb.test"
];
public static readonly List<string> SpeedPingTestUrls = new() {
public static readonly List<string> SpeedPingTestUrls =
[
@"https://www.google.com/generate_204",
@"https://www.gstatic.com/generate_204",
@"https://www.apple.com/library/test/success.html",
@"http://www.msftconnecttest.com/connecttest.txt",
};
@"http://www.msftconnecttest.com/connecttest.txt"
];
public static readonly List<string> GeoFilesSources = new() {
public static readonly List<string> GeoFilesSources =
[
"",
@"https://github.com/runetfreedom/russia-v2ray-rules-dat/releases/latest/download/{0}.dat",
@"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/{0}.dat",
};
@"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-v2ray-rules@release/{0}.dat"
];
public static readonly List<string> SingboxRulesetSources = new() {
public static readonly List<string> SingboxRulesetSources =
[
"",
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-rules-dat@release/sing-box/rule-set-{0}/{1}.srs",
@"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-sing-box-rules@rule-set/{1}.srs",
};
@"https://cdn.jsdelivr.net/gh/chocolate4u/Iran-sing-box-rules@rule-set/{1}.srs"
];
public static readonly List<string> RoutingRulesSources = new() {
public static readonly List<string> RoutingRulesSources =
[
"",
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/template.json",
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/template.json",
};
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/template.json"
];
public static readonly List<string> DNSTemplateSources = new() {
public static readonly List<string> DNSTemplateSources =
[
"",
@"https://cdn.jsdelivr.net/gh/runetfreedom/russia-v2ray-custom-routing-list@main/v2rayN/",
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/",
};
@"https://cdn.jsdelivr.net/gh/Chocolate4U/Iran-v2ray-rules@main/v2rayN/"
];
public static readonly Dictionary<string, string> UserAgentTexts = new()
{
@@ -182,42 +191,314 @@
{EConfigType.WireGuard,"wireguard"}
};
public static readonly List<string> VmessSecurities = new() { "aes-128-gcm", "chacha20-poly1305", "auto", "none", "zero" };
public static readonly List<string> SsSecurities = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "none", "plain" };
public static readonly List<string> SsSecuritiesInXray = new() { "aes-256-gcm", "aes-128-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305", "xchacha20-poly1305", "xchacha20-ietf-poly1305", "none", "plain", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305" };
public static readonly List<string> SsSecuritiesInSingbox = new() { "aes-256-gcm", "aes-192-gcm", "aes-128-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "none", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20" };
public static readonly List<string> Flows = new() { "", "xtls-rprx-vision", "xtls-rprx-vision-udp443" };
public static readonly List<string> Networks = new() { "tcp", "kcp", "ws", "httpupgrade", "xhttp", "h2", "quic", "grpc" };
public static readonly List<string> KcpHeaderTypes = new() { "srtp", "utp", "wechat-video", "dtls", "wireguard" };
public static readonly List<string> CoreTypes = new() { "Xray", "sing_box" };
public static readonly List<string> DomainStrategies = new() { "AsIs", "IPIfNonMatch", "IPOnDemand" };
public static readonly List<string> DomainStrategies4Singbox = new() { "ipv4_only", "ipv6_only", "prefer_ipv4", "prefer_ipv6", "" };
public static readonly List<string> DomainMatchers = new() { "linear", "mph", "" };
public static readonly List<string> Fingerprints = new() { "chrome", "firefox", "safari", "ios", "android", "edge", "360", "qq", "random", "randomized", "" };
public static readonly List<string> UserAgent = new() { "chrome", "firefox", "safari", "edge", "none" };
public static readonly List<string> XhttpMode = new() { "auto", "packet-up", "stream-up", "stream-one" };
public static readonly List<string> VmessSecurities =
[
"aes-128-gcm",
"chacha20-poly1305",
"auto",
"none",
"zero"
];
public static readonly List<string> AllowInsecure = new() { "true", "false", "" };
public static readonly List<string> DomainStrategy4Freedoms = new() { "AsIs", "UseIP", "UseIPv4", "UseIPv6", "" };
public static readonly List<string> SingboxDomainStrategy4Out = new() { "ipv4_only", "prefer_ipv4", "prefer_ipv6", "ipv6_only", "" };
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru", "hu" };
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
public static readonly List<string> InboundTags = new() { "socks", "socks2", "socks3" };
public static readonly List<string> RuleProtocols = new() { "http", "tls", "bittorrent" };
public static readonly List<string> RuleNetworks = new() { "", "tcp", "udp", "tcp,udp" };
public static readonly List<string> destOverrideProtocols = ["http", "tls", "quic", "fakedns", "fakedns+others"];
public static readonly List<string> TunMtus = new() { "1280", "1408", "1500", "9000" };
public static readonly List<string> TunStacks = new() { "gvisor", "system", "mixed" };
public static readonly List<string> PresetMsgFilters = new() { "proxy", "direct", "block", "" };
public static readonly List<string> SingboxMuxs = new() { "h2mux", "smux", "yamux", "" };
public static readonly List<string> TuicCongestionControls = new() { "cubic", "new_reno", "bbr" };
public static readonly List<string> SsSecurities =
[
"aes-256-gcm",
"aes-128-gcm",
"chacha20-poly1305",
"chacha20-ietf-poly1305",
"none",
"plain"
];
public static readonly List<string> allowSelectType = new() { "selector", "urltest", "loadbalance", "fallback" };
public static readonly List<string> notAllowTestType = new() { "selector", "urltest", "direct", "reject", "compatible", "pass", "loadbalance", "fallback" };
public static readonly List<string> proxyVehicleType = new() { "file", "http" };
public static readonly List<string> SsSecuritiesInXray =
[
"aes-256-gcm",
"aes-128-gcm",
"chacha20-poly1305",
"chacha20-ietf-poly1305",
"xchacha20-poly1305",
"xchacha20-ietf-poly1305",
"none",
"plain",
"2022-blake3-aes-128-gcm",
"2022-blake3-aes-256-gcm",
"2022-blake3-chacha20-poly1305"
];
public static readonly List<string> SsSecuritiesInSingbox =
[
"aes-256-gcm",
"aes-192-gcm",
"aes-128-gcm",
"chacha20-ietf-poly1305",
"xchacha20-ietf-poly1305",
"none",
"2022-blake3-aes-128-gcm",
"2022-blake3-aes-256-gcm",
"2022-blake3-chacha20-poly1305",
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"aes-128-cfb",
"aes-192-cfb",
"aes-256-cfb",
"rc4-md5",
"chacha20-ietf",
"xchacha20"
];
public static readonly List<string> Flows =
[
"",
"xtls-rprx-vision",
"xtls-rprx-vision-udp443"
];
public static readonly List<string> Networks =
[
"tcp",
"kcp",
"ws",
"httpupgrade",
"xhttp",
"h2",
"quic",
"grpc"
];
public static readonly List<string> KcpHeaderTypes =
[
"srtp",
"utp",
"wechat-video",
"dtls",
"wireguard"
];
public static readonly List<string> CoreTypes =
[
"Xray",
"sing_box"
];
public static readonly List<string> DomainStrategies =
[
"AsIs",
"IPIfNonMatch",
"IPOnDemand"
];
public static readonly List<string> DomainStrategies4Singbox =
[
"ipv4_only",
"ipv6_only",
"prefer_ipv4",
"prefer_ipv6",
""
];
public static readonly List<string> DomainMatchers =
[
"linear",
"mph",
""
];
public static readonly List<string> Fingerprints =
[
"chrome",
"firefox",
"safari",
"ios",
"android",
"edge",
"360",
"qq",
"random",
"randomized",
""
];
public static readonly List<string> UserAgent =
[
"chrome",
"firefox",
"safari",
"edge",
"none"
];
public static readonly List<string> XhttpMode =
[
"auto",
"packet-up",
"stream-up",
"stream-one"
];
public static readonly List<string> AllowInsecure =
[
"true",
"false",
""
];
public static readonly List<string> DomainStrategy4Freedoms =
[
"AsIs",
"UseIP",
"UseIPv4",
"UseIPv6",
""
];
public static readonly List<string> SingboxDomainStrategy4Out =
[
"ipv4_only",
"prefer_ipv4",
"prefer_ipv6",
"ipv6_only",
""
];
public static readonly List<string> DomainDNSAddress =
[
"223.5.5.5",
"223.6.6.6",
"localhost"
];
public static readonly List<string> SingboxDomainDNSAddress =
[
"223.5.5.5",
"223.6.6.6",
"dhcp://auto"
];
public static readonly List<string> Languages =
[
"zh-Hans",
"zh-Hant",
"en",
"fa-Ir",
"ru",
"hu"
];
public static readonly List<string> Alpns =
[
"h3",
"h2",
"http/1.1",
"h3,h2",
"h2,http/1.1",
"h3,h2,http/1.1",
""
];
public static readonly List<string> LogLevels =
[
"debug",
"info",
"warning",
"error",
"none"
];
public static readonly List<string> InboundTags =
[
"socks",
"socks2",
"socks3"
];
public static readonly List<string> RuleProtocols =
[
"http",
"tls",
"bittorrent"
];
public static readonly List<string> RuleNetworks =
[
"",
"tcp",
"udp",
"tcp,udp"
];
public static readonly List<string> destOverrideProtocols =
[
"http",
"tls",
"quic",
"fakedns",
"fakedns+others"
];
public static readonly List<string> TunMtus =
[
"1280",
"1408",
"1500",
"9000"
];
public static readonly List<string> TunStacks =
[
"gvisor",
"system",
"mixed"
];
public static readonly List<string> PresetMsgFilters =
[
"proxy",
"direct",
"block",
""
];
public static readonly List<string> SingboxMuxs =
[
"h2mux",
"smux",
"yamux",
""
];
public static readonly List<string> TuicCongestionControls =
[
"cubic",
"new_reno",
"bbr"
];
public static readonly List<string> allowSelectType =
[
"selector",
"urltest",
"loadbalance",
"fallback"
];
public static readonly List<string> notAllowTestType =
[
"selector",
"urltest",
"direct",
"reject",
"compatible",
"pass",
"loadbalance",
"fallback"
];
public static readonly List<string> proxyVehicleType =
[
"file",
"http"
];
#endregion const
}

View File

@@ -46,9 +46,9 @@
public bool InitApp()
{
if (Utils.IsNonWindows() && Utils.HasWritePermission() == false)
if (Utils.HasWritePermission() == false)
{
Environment.SetEnvironmentVariable("V2RAYN_LOCAL_APPLICATION_DATA", "1", EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable(Global.LocalAppData, "1", EnvironmentVariableTarget.Process);
}
Logging.Setup();

View File

@@ -1,4 +1,4 @@
using System.Security.Principal;
using System.Security.Principal;
using System.Text.RegularExpressions;
namespace ServiceLib.Handler
@@ -29,7 +29,12 @@ namespace ServiceLib.Handler
}
else if (Utils.IsOSX())
{
//TODO
await ClearTaskOSX();
if (config.GuiItem.AutoRun)
{
await SetTaskOSX();
}
}
return true;
@@ -137,7 +142,7 @@ namespace ServiceLib.Handler
{
try
{
var linuxConfig = Utils.GetEmbedText(Global.LinuxAutostartConfig);
var linuxConfig = EmbedUtils.GetEmbedText(Global.LinuxAutostartConfig);
if (linuxConfig.IsNotEmpty())
{
linuxConfig = linuxConfig.Replace("$ExecPath$", Utils.GetExePath());
@@ -161,5 +166,77 @@ namespace ServiceLib.Handler
}
#endregion Linux
#region macOS
private static async Task ClearTaskOSX()
{
try
{
var launchAgentPath = GetLaunchAgentPathMacOS();
if (File.Exists(launchAgentPath))
{
var args = new[] { "-c", $"launchctl unload -w \"{launchAgentPath}\"" };
await Utils.GetCliWrapOutput("/bin/bash", args);
File.Delete(launchAgentPath);
}
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
private static async Task SetTaskOSX()
{
try
{
var plistContent = GenerateLaunchAgentPlist();
var launchAgentPath = GetLaunchAgentPathMacOS();
await File.WriteAllTextAsync(launchAgentPath, plistContent);
var args = new[] { "-c", $"launchctl load -w \"{launchAgentPath}\"" };
await Utils.GetCliWrapOutput("/bin/bash", args);
}
catch (Exception ex)
{
Logging.SaveLog(_tag, ex);
}
}
private static string GetLaunchAgentPathMacOS()
{
var homePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
var launchAgentPath = Path.Combine(homePath, "Library", "LaunchAgents", $"{Global.AppName}-LaunchAgent.plist");
Directory.CreateDirectory(Path.GetDirectoryName(launchAgentPath));
return launchAgentPath;
}
private static string GenerateLaunchAgentPlist()
{
var exePath = Utils.GetExePath();
var appName = Path.GetFileNameWithoutExtension(exePath);
return $@"<?xml version=""1.0"" encoding=""UTF-8""?>
<!DOCTYPE plist PUBLIC ""-//Apple//DTD PLIST 1.0//EN"" ""http://www.apple.com/DTDs/PropertyList-1.0.dtd"">
<plist version=""1.0"">
<dict>
<key>Label</key>
<string>{Global.AppName}-LaunchAgent</string>
<key>ProgramArguments</key>
<array>
<string>/bin/sh</string>
<string>-c</string>
<string>if ! pgrep -x ""{appName}"" > /dev/null; then ""{exePath}""; fi</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
</dict>
</plist>";
}
#endregion macOS
}
}

View File

@@ -21,7 +21,7 @@ namespace ServiceLib.Handler
public static Config? LoadConfig()
{
Config? config = null;
var result = Utils.LoadResource(Utils.GetConfigPath(_configRes));
var result = EmbedUtils.LoadResource(Utils.GetConfigPath(_configRes));
if (Utils.IsNotEmpty(result))
{
config = JsonUtils.Deserialize<Config>(result);
@@ -873,7 +873,8 @@ namespace ServiceLib.Handler
List<ProfileItem> lstKeep = new();
List<ProfileItem> lstRemove = new();
if (!config.GuiItem.KeepOlderDedupl) lstProfile.Reverse();
if (!config.GuiItem.KeepOlderDedupl)
lstProfile.Reverse();
foreach (ProfileItem item in lstProfile)
{
@@ -1363,7 +1364,8 @@ namespace ServiceLib.Handler
};
var uri = Utils.TryUri(url);
if (uri == null) return -1;
if (uri == null)
return -1;
//Do not allow http protocol
if (url.StartsWith(Global.HttpProtocol) && !Utils.IsPrivateNetwork(uri.IdnHost))
{
@@ -1733,7 +1735,7 @@ namespace ServiceLib.Handler
Url = string.Empty,
Sort = maxSort + 1,
};
await AddBatchRoutingRules(item2, Utils.GetEmbedText(Global.CustomRoutingFileName + "white"));
await AddBatchRoutingRules(item2, EmbedUtils.GetEmbedText(Global.CustomRoutingFileName + "white"));
//Blacklist
var item3 = new RoutingItem()
@@ -1742,7 +1744,7 @@ namespace ServiceLib.Handler
Url = string.Empty,
Sort = maxSort + 2,
};
await AddBatchRoutingRules(item3, Utils.GetEmbedText(Global.CustomRoutingFileName + "black"));
await AddBatchRoutingRules(item3, EmbedUtils.GetEmbedText(Global.CustomRoutingFileName + "black"));
//Global
var item1 = new RoutingItem()
@@ -1751,7 +1753,7 @@ namespace ServiceLib.Handler
Url = string.Empty,
Sort = maxSort + 3,
};
await AddBatchRoutingRules(item1, Utils.GetEmbedText(Global.CustomRoutingFileName + "global"));
await AddBatchRoutingRules(item1, EmbedUtils.GetEmbedText(Global.CustomRoutingFileName + "global"));
if (!blImportAdvancedRules)
{

View File

@@ -1,4 +1,4 @@
using System.Diagnostics;
using System.Diagnostics;
using System.Text;
namespace ServiceLib.Handler
@@ -22,8 +22,19 @@ namespace ServiceLib.Handler
_config = config;
_updateFunc = updateFunc;
Environment.SetEnvironmentVariable("V2RAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("XRAY_LOCATION_ASSET", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable(Global.V2RayLocalAsset, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable(Global.XrayLocalAsset, Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
//Copy the bin folder to the storage location (for init)
if (Environment.GetEnvironmentVariable(Global.LocalAppData) == "1")
{
var fromPath = Utils.GetBaseDirectory("bin");
var toPath = Utils.GetBinPath("");
if (fromPath != toPath)
{
FileManager.CopyDirectory(fromPath, toPath, true, false);
}
}
if (Utils.IsNonWindows())
{
@@ -72,6 +83,13 @@ namespace ServiceLib.Handler
UpdateFunc(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
await CoreStop();
await Task.Delay(100);
if (Utils.IsWindows() && _config.TunModeItem.EnableTun)
{
await Task.Delay(100);
await WindowsUtils.RemoveTunDevice();
}
await CoreStart(node);
await CoreStartPreService(node);
if (_process != null)
@@ -228,12 +246,14 @@ namespace ServiceLib.Handler
{
proc.OutputDataReceived += (sender, e) =>
{
if (Utils.IsNullOrEmpty(e.Data)) return;
if (Utils.IsNullOrEmpty(e.Data))
return;
UpdateFunc(false, e.Data + Environment.NewLine);
};
proc.ErrorDataReceived += (sender, e) =>
{
if (Utils.IsNullOrEmpty(e.Data)) return;
if (Utils.IsNullOrEmpty(e.Data))
return;
UpdateFunc(false, e.Data + Environment.NewLine);
};
}
@@ -247,7 +267,8 @@ namespace ServiceLib.Handler
await Task.Delay(10);
await proc.StandardInput.WriteLineAsync(pwd);
}
if (isNeedSudo) _linuxSudoPid = proc.Id;
if (isNeedSudo)
_linuxSudoPid = proc.Id;
if (displayLog)
{

View File

@@ -1,4 +1,4 @@
using System.Collections.Specialized;
using System.Collections.Specialized;
namespace ServiceLib.Handler.Fmt
{
@@ -214,7 +214,8 @@ namespace ServiceLib.Handler.Fmt
{
foreach (var item in s)
{
if (str.Contains(item, StringComparison.OrdinalIgnoreCase)) return true;
if (str.Contains(item, StringComparison.OrdinalIgnoreCase))
return true;
}
return false;
}

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
public class Hysteria2Fmt : BaseFmt
{
@@ -11,7 +11,8 @@
};
var url = Utils.TryUri(str);
if (url == null) return null;
if (url == null)
return null;
item.Address = url.IdnHost;
item.Port = url.Port;
@@ -28,7 +29,8 @@
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
string url = string.Empty;
string remark = string.Empty;

View File

@@ -1,4 +1,4 @@
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
namespace ServiceLib.Handler.Fmt
{
@@ -26,7 +26,8 @@ namespace ServiceLib.Handler.Fmt
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
string url = string.Empty;
string remark = string.Empty;
@@ -82,7 +83,8 @@ namespace ServiceLib.Handler.Fmt
private static ProfileItem? ResolveSip002(string result)
{
var parsedUrl = Utils.TryUri(result);
if (parsedUrl == null) return null;
if (parsedUrl == null)
return null;
ProfileItem item = new()
{

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
public class SocksFmt : BaseFmt
{
@@ -23,7 +23,8 @@
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
var url = string.Empty;
var remark = string.Empty;
@@ -86,7 +87,8 @@
private static ProfileItem? ResolveSocksNew(string result)
{
var parsedUrl = Utils.TryUri(result);
if (parsedUrl == null) return null;
if (parsedUrl == null)
return null;
ProfileItem item = new()
{

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
public class TrojanFmt : BaseFmt
{
@@ -12,7 +12,8 @@
};
var url = Utils.TryUri(str);
if (url == null) return null;
if (url == null)
return null;
item.Address = url.IdnHost;
item.Port = url.Port;
@@ -27,7 +28,8 @@
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
string url = string.Empty;
string remark = string.Empty;

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
public class TuicFmt : BaseFmt
{
@@ -12,7 +12,8 @@
};
var url = Utils.TryUri(str);
if (url == null) return null;
if (url == null)
return null;
item.Address = url.IdnHost;
item.Port = url.Port;
@@ -34,7 +35,8 @@
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
string url = string.Empty;
string remark = string.Empty;

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
public class VLESSFmt : BaseFmt
{
@@ -13,7 +13,8 @@
};
var url = Utils.TryUri(str);
if (url == null) return null;
if (url == null)
return null;
item.Address = url.IdnHost;
item.Port = url.Port;
@@ -30,7 +31,8 @@
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
string url = string.Empty;
string remark = string.Empty;

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
public class VmessFmt : BaseFmt
{
@@ -19,7 +19,8 @@
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
string url = string.Empty;
VmessQRCode vmessQRCode = new()
@@ -106,7 +107,8 @@
};
var url = Utils.TryUri(str);
if (url == null) return null;
if (url == null)
return null;
item.Address = url.IdnHost;
item.Port = url.Port;

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Handler.Fmt
namespace ServiceLib.Handler.Fmt
{
public class WireguardFmt : BaseFmt
{
@@ -12,7 +12,8 @@
};
var url = Utils.TryUri(str);
if (url == null) return null;
if (url == null)
return null;
item.Address = url.IdnHost;
item.Port = url.Port;
@@ -31,7 +32,8 @@
public static string? ToUri(ProfileItem? item)
{
if (item == null) return null;
if (item == null)
return null;
string url = string.Empty;
string remark = string.Empty;

View File

@@ -1,4 +1,4 @@
using System.Net.Sockets;
using System.Net.Sockets;
using System.Text;
namespace ServiceLib.Handler
@@ -35,7 +35,7 @@ namespace ServiceLib.Handler
var path = Path.Combine(_configPath, "pac.txt");
if (!File.Exists(path))
{
var pac = Utils.GetEmbedText(Global.PacFileName);
var pac = EmbedUtils.GetEmbedText(Global.PacFileName);
await File.AppendAllTextAsync(path, pac);
}
@@ -89,7 +89,8 @@ namespace ServiceLib.Handler
public static void Stop()
{
if (_tcpListener == null) return;
if (_tcpListener == null)
return;
try
{
_isRunning = false;

View File

@@ -176,7 +176,8 @@ namespace ServiceLib.Handler.SysProxy
}
// FREE the data ASAP
if (list.szConnection != nint.Zero) Marshal.FreeHGlobal(list.szConnection); // release mem 3
if (list.szConnection != nint.Zero)
Marshal.FreeHGlobal(list.szConnection); // release mem 3
if (optionCount > 1)
{
Marshal.FreeHGlobal(options[1].m_Value.m_StringPtr); // release mem 1

View File

@@ -1,4 +1,4 @@
using System.Net;
using System.Net;
using WebDav;
namespace ServiceLib.Handler
@@ -61,7 +61,8 @@ namespace ServiceLib.Handler
private async Task<bool> TryCreateDir()
{
if (_client is null) return false;
if (_client is null)
return false;
try
{
var result2 = await _client.Mkcol(_webDir);

View File

@@ -403,7 +403,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Custom Icon 的本地化字符串。
/// 查找类似 Custom icon 的本地化字符串。
/// </summary>
public static string LvCustomIcon {
get {
@@ -610,7 +610,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 URL(Optional) 的本地化字符串。
/// 查找类似 URL (optional) 的本地化字符串。
/// </summary>
public static string LvUrl {
get {
@@ -1006,7 +1006,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 One-click multi test Latency and speed (Ctrl+E) 的本地化字符串。
/// 查找类似 One-click multi-test latency and speed (Ctrl+E) 的本地化字符串。
/// </summary>
public static string menuMixedTestServer {
get {
@@ -2294,7 +2294,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Support DnsObject, Click to view the document 的本地化字符串。
/// 查找类似 Supports DnsObject; Click to view documentation 的本地化字符串。
/// </summary>
public static string TbDnsObjectDoc {
get {
@@ -2384,7 +2384,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Set directly by pressing the keyboard, take effect after restart 的本地化字符串。
/// 查找类似 Set directly by pressing the keyboard; Takes effect after restart 的本地化字符串。
/// </summary>
public static string TbGlobalHotkeySettingTip {
get {
@@ -2663,7 +2663,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 *Set the rules, separated by commas (,); The comma in the regular is replaced by &lt;COMMA&gt; 的本地化字符串。
/// 查找类似 *Separate rules by commas (,); For a literal comma use &lt;COMMA&gt;; Prefix # to ignore a rule 的本地化字符串。
/// </summary>
public static string TbRoutingTips {
get {
@@ -2771,7 +2771,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Automatic update interval of Geo (hours) 的本地化字符串。
/// 查找类似 Automatic update interval for Geo files (hours) 的本地化字符串。
/// </summary>
public static string TbSettingsAutoUpdateInterval {
get {
@@ -2843,7 +2843,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 FontFamily(Require restart) 的本地化字符串。
/// 查找类似 Font family (requires restart) 的本地化字符串。
/// </summary>
public static string TbSettingsCurrentFontFamily {
get {
@@ -2861,7 +2861,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Copy the font TTF/TTC file to the directory guiFonts, restart the settings 的本地化字符串。
/// 查找类似 Copy the font TTF/TTC file to the directory guiFonts; Reopen the settings window 的本地化字符串。
/// </summary>
public static string TbSettingsCurrentFontFamilyTip {
get {
@@ -2915,7 +2915,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Display real-time speed 的本地化字符串。
/// 查找类似 Display real-time speed (requires restart) 的本地化字符串。
/// </summary>
public static string TbSettingsDisplayRealTimeSpeed {
get {
@@ -2951,7 +2951,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Double-click server make active 的本地化字符串。
/// 查找类似 Double-clicking server makes it active 的本地化字符串。
/// </summary>
public static string TbSettingsDoubleClick2Activate {
get {
@@ -2960,7 +2960,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Automatically adjust column width after updating subscription 的本地化字符串。
/// 查找类似 Automatically adjust column width after subscription update 的本地化字符串。
/// </summary>
public static string TbSettingsEnableAutoAdjustMainLvColWidth {
get {
@@ -2987,7 +2987,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Enable Server Drag Drop Sort(Require restart) 的本地化字符串。
/// 查找类似 Enable sorting servers by drag-n-drop (requires restart) 的本地化字符串。
/// </summary>
public static string TbSettingsEnableDragDropSort {
get {
@@ -3023,7 +3023,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Enable hardware acceleration(Require restart) 的本地化字符串。
/// 查找类似 Enable hardware acceleration (requires restart) 的本地化字符串。
/// </summary>
public static string TbSettingsEnableHWA {
get {
@@ -3059,7 +3059,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Exception. Do not use proxy server for addresses beginning with,Use semicolon (;) 的本地化字符串。
/// 查找类似 Exclusions: Do not use proxy server for addresses beginning with the following. Use semicolon (;) to separate entries. 的本地化字符串。
/// </summary>
public static string TbSettingsExceptionTip {
get {
@@ -3068,7 +3068,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Exception. Do not use proxy server for addresses,with a comma (,) 的本地化字符串。
/// 查找类似 Exclusions: Do not use proxy server for the following addresses. Use comma (,) to separate entries. 的本地化字符串。
/// </summary>
public static string TbSettingsExceptionTip2 {
get {
@@ -3122,7 +3122,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Keep older when deduplication 的本地化字符串。
/// 查找类似 Keep the older when de-duplicating 的本地化字符串。
/// </summary>
public static string TbSettingsKeepOlderDedupl {
get {
@@ -3203,7 +3203,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Main layout orientation(Require restart) 的本地化字符串。
/// 查找类似 Main layout orientation (requires restart) 的本地化字符串。
/// </summary>
public static string TbSettingsMainGirdOrientation {
get {
@@ -3401,7 +3401,7 @@ namespace ServiceLib.Resx {
}
/// <summary>
/// 查找类似 Enable traffic statistics (Require restart) 的本地化字符串。
/// 查找类似 Enable traffic statistics (requires restart) 的本地化字符串。
/// </summary>
public static string TbSettingsStatistics {
get {

View File

@@ -683,7 +683,7 @@
<value>راه اندازی مخفی کردن خودکار</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>فاصله به روز رسانی خودکار و Geo (ساعت)</value>
<value>فاصله به روز رسانی خودکار برای فایل های Geo (ساعت)</value>
</data>
<data name="TbSettingsCore" xml:space="preserve">
<value>هسته: تنظیمات اولیه</value>
@@ -704,7 +704,7 @@
<value>Outbound Freedom domainStrategy</value>
</data>
<data name="TbSettingsEnableAutoAdjustMainLvColWidth" xml:space="preserve">
<value>پس از به‌روزرسانی اشتراک، عرض ستون را به صورت خودکار تنظیم شود</value>
<value>پس از به‌روزرسانی اشتراک، عرض ستون به صورت خودکار تنظیم شود</value>
</data>
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>به روز رسانی های پیش از انتشار را بررسی شود</value>
@@ -713,16 +713,16 @@
<value>استثنا</value>
</data>
<data name="TbSettingsExceptionTip" xml:space="preserve">
<value>استثنا: از سرور پروکسی برای آدرس هایی که با شروع می شوند استفاده نکنید، از نقطه ویرگول (;) استفاده کنید.</value>
<value>استثناها: از سرور پروکسی برای آدرس هایی که با موارد زیر شروع می شوند استفاده نکنید. برای جدا کردن ورودی ها از نقطه ویرگول (;) استفاده کنید.</value>
</data>
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>پورت Http</value>
</data>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Display real-time speed</value>
<value>نمایش سرعت واقعی (نیاز به راه اندازی مجدد)</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>هنگام کپی برداری، نگه داری قدیمی تر ها</value>
<value>هنگام حذف کپی، قدیمی تر را نگه دارید</value>
</data>
<data name="TbSettingsLogEnabled" xml:space="preserve">
<value>ثبت گزارش های محلی</value>
@@ -755,7 +755,7 @@
<value>درهنگام راه ائدازی شروع شود</value>
</data>
<data name="TbSettingsStatistics" xml:space="preserve">
<value>فعال کردن آمار (نیاز به راه اندازی مجدد)</value>
<value>فعال کردن آمار ترافیک (نیاز به راه اندازی مجدد)</value>
</data>
<data name="TbSettingsSubConvert" xml:space="preserve">
<value>آدرس اینترنتی تبدیل اشتراک</value>
@@ -863,7 +863,7 @@
<value>لیست مجموعه قوانین از پیش تعریف شده</value>
</data>
<data name="TbRoutingTips" xml:space="preserve">
<value>*قوانین را تنظیم کنید که با کاما از هم جدا شده اند (,); کاما در حالت عادی با &lt;COMMA&gt;</value>
<value>*قوانین را با کاما (,) جدا کنید. برای کاما به معنای واقعی کلمه از &lt;COMMA&gt;; پیشوند # برای نادیده گرفتن یک قانون</value>
</data>
<data name="menuImportRulesFromClipboard" xml:space="preserve">
<value>وارد کردن قوانین از کلیپ بورد</value>
@@ -899,7 +899,7 @@
<value>مستندات شی قانون</value>
</data>
<data name="TbDnsObjectDoc" xml:space="preserve">
<value>پشتیبانی از DnsObject</value>
<value>پشتیبانی از DnsObject. برای مشاهده مستندات کلیک کنید</value>
</data>
<data name="SubUrlTips" xml:space="preserve">
<value>گروه لطفا اینجا را خالی بگذارید</value>
@@ -1208,7 +1208,7 @@
<value>انتقال به گروه</value>
</data>
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
<value>فعال کردن مرتب سازی با کشیدن سرور (نیاز به راه اندازی مجدد)</value>
<value>فعال کردن مرتبسازی سرورها با کشیدن و رها کردن (نیاز به راهاندازی مجدد)</value>
</data>
<data name="TbAutoRefresh" xml:space="preserve">
<value>بازخوانی خودکار</value>
@@ -1220,7 +1220,7 @@
<value>ویرایش سرور (Ctrl+D)</value>
</data>
<data name="TbSettingsDoubleClick2Activate" xml:space="preserve">
<value>روی server make active دوبار کلیک کنید</value>
<value>دوبار کلیک کردن سرور باعث فعال شدن آن می شود</value>
</data>
<data name="SpeedtestingCompleted" xml:space="preserve">
<value>تست تکمیل شد</value>
@@ -1232,7 +1232,7 @@
<value>FontFamily (نیاز به راه اندازی مجدد)</value>
</data>
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>فایل TTF/TTC فونت را در دایرکتوری guiFonts کپی کنید، تنظیمات را مجددا راه اندازی کنید</value>
<value>فایل TTF/TTC فونت را در دایرکتوری guiFonts کپی کنید. پنجره تنظیمات را دوباره باز کنید</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>پورت Pac = +3; پورت Xray API = +4; پورت mihomo API = +5;</value>
@@ -1376,7 +1376,7 @@
<value>تعداد در هر زمان برای دسته خودکار در طول تست سرعت (حداکثر 1000)</value>
</data>
<data name="TbSettingsExceptionTip2" xml:space="preserve">
<value>استثنا:از سرور پروکسی برای آدرس ها، با کاما (،) استفاده نکنید</value>
<value>موارد استثنا: از سرور پروکسی برای آدرس های زیر استفاده نکنید. برای جدا کردن ورودی ها از کاما (،) استفاده کنید.</value>
</data>
<data name="TbSettingsDestOverride" xml:space="preserve">
<value>نوع Sniffing</value>

View File

@@ -320,7 +320,7 @@
<value>Remarks</value>
</data>
<data name="LvUrl" xml:space="preserve">
<value>URL(Optional)</value>
<value>URL (optional)</value>
</data>
<data name="LvCount" xml:space="preserve">
<value>Count</value>
@@ -338,7 +338,7 @@
<value>Information</value>
</data>
<data name="LvCustomIcon" xml:space="preserve">
<value>Custom Icon</value>
<value>Custom icon</value>
</data>
<data name="FillCorrectDNSText" xml:space="preserve">
<value>Please fill in the correct custom DNS</value>
@@ -683,7 +683,7 @@
<value>Auto hide startup</value>
</data>
<data name="TbSettingsAutoUpdateInterval" xml:space="preserve">
<value>Automatic update interval of Geo (hours)</value>
<value>Automatic update interval for Geo files (hours)</value>
</data>
<data name="TbSettingsCore" xml:space="preserve">
<value>Core: basic settings</value>
@@ -704,7 +704,7 @@
<value>Outbound Freedom domainStrategy</value>
</data>
<data name="TbSettingsEnableAutoAdjustMainLvColWidth" xml:space="preserve">
<value>Automatically adjust column width after updating subscription</value>
<value>Automatically adjust column width after subscription update</value>
</data>
<data name="TbSettingsEnableCheckPreReleaseUpdate" xml:space="preserve">
<value>Check for pre-release updates</value>
@@ -713,16 +713,16 @@
<value>Exception</value>
</data>
<data name="TbSettingsExceptionTip" xml:space="preserve">
<value>Exception. Do not use proxy server for addresses beginning with,Use semicolon (;)</value>
<value>Exclusions: Do not use proxy server for addresses beginning with the following. Use semicolon (;) to separate entries.</value>
</data>
<data name="TbSettingsHttpPort" xml:space="preserve">
<value>HTTP Port</value>
</data>
<data name="TbSettingsDisplayRealTimeSpeed" xml:space="preserve">
<value>Display real-time speed (Require restart)</value>
<value>Display real-time speed (requires restart)</value>
</data>
<data name="TbSettingsKeepOlderDedupl" xml:space="preserve">
<value>Keep older when deduplication</value>
<value>Keep the older when de-duplicating</value>
</data>
<data name="TbSettingsLogEnabled" xml:space="preserve">
<value>Enable Log</value>
@@ -755,7 +755,7 @@
<value>Start on boot</value>
</data>
<data name="TbSettingsStatistics" xml:space="preserve">
<value>Enable traffic statistics (Require restart)</value>
<value>Enable traffic statistics (requires restart)</value>
</data>
<data name="TbSettingsSubConvert" xml:space="preserve">
<value>Subscription conversion URL</value>
@@ -785,7 +785,7 @@
<value>Global Hotkey Settings</value>
</data>
<data name="TbGlobalHotkeySettingTip" xml:space="preserve">
<value>Set directly by pressing the keyboard, take effect after restart</value>
<value>Set directly by pressing the keyboard; Takes effect after restart</value>
</data>
<data name="TbNotChangeSystemProxy" xml:space="preserve">
<value>Do not change system proxy</value>
@@ -863,7 +863,7 @@
<value>Pre-defined Rule Set List</value>
</data>
<data name="TbRoutingTips" xml:space="preserve">
<value>*Set the rules, separated by commas (,); The comma in the regular is replaced by &lt;COMMA&gt;</value>
<value>*Separate rules by commas (,); For a literal comma use &lt;COMMA&gt;; Prefix # to ignore a rule</value>
</data>
<data name="menuImportRulesFromClipboard" xml:space="preserve">
<value>Import Rules From Clipboard</value>
@@ -899,7 +899,7 @@
<value>Ruleobject Doc</value>
</data>
<data name="TbDnsObjectDoc" xml:space="preserve">
<value>Support DnsObject, Click to view the document</value>
<value>Supports DnsObject; Click to view documentation</value>
</data>
<data name="SubUrlTips" xml:space="preserve">
<value>For group please leave blank here</value>
@@ -917,7 +917,7 @@
<value>Do not use proxy servers for local (intranet) addresses</value>
</data>
<data name="menuMixedTestServer" xml:space="preserve">
<value>One-click multi test Latency and speed (Ctrl+E)</value>
<value>One-click multi-test latency and speed (Ctrl+E)</value>
</data>
<data name="LvTestDelay" xml:space="preserve">
<value>Delay(ms)</value>
@@ -947,7 +947,7 @@
<value>Move to group</value>
</data>
<data name="TbSettingsEnableDragDropSort" xml:space="preserve">
<value>Enable Server Drag Drop Sort(Require restart)</value>
<value>Enable sorting servers by drag-n-drop (requires restart)</value>
</data>
<data name="TbAutoRefresh" xml:space="preserve">
<value>AutoRefresh</value>
@@ -959,7 +959,7 @@
<value>Edit Server (Ctrl+D)</value>
</data>
<data name="TbSettingsDoubleClick2Activate" xml:space="preserve">
<value>Double-click server make active</value>
<value>Double-clicking server makes it active</value>
</data>
<data name="SpeedtestingCompleted" xml:space="preserve">
<value>Test completed</value>
@@ -974,10 +974,10 @@
<value>This parameter is valid only for tcp/http and ws</value>
</data>
<data name="TbSettingsCurrentFontFamily" xml:space="preserve">
<value>FontFamily(Require restart)</value>
<value>Font family (requires restart)</value>
</data>
<data name="TbSettingsCurrentFontFamilyTip" xml:space="preserve">
<value>Copy the font TTF/TTC file to the directory guiFonts, restart the settings</value>
<value>Copy the font TTF/TTC file to the directory guiFonts; Reopen the settings window</value>
</data>
<data name="TbSettingsSocksPortTip" xml:space="preserve">
<value>Pac port = +3; Xray API port = +4; mihomo API port = +5;</value>
@@ -1007,7 +1007,7 @@
<value>SpiderX</value>
</data>
<data name="TbSettingsEnableHWA" xml:space="preserve">
<value>Enable hardware acceleration(Require restart)</value>
<value>Enable hardware acceleration (requires restart)</value>
</data>
<data name="SpeedtestingWait" xml:space="preserve">
<value>Waiting for testing (press ESC to terminate)...</value>
@@ -1235,7 +1235,7 @@
<value>Multi-Server lowest latency</value>
</data>
<data name="TbSettingsMainGirdOrientation" xml:space="preserve">
<value>Main layout orientation(Require restart)</value>
<value>Main layout orientation (requires restart)</value>
</data>
<data name="menuSetDefaultLoadBalanceServer" xml:space="preserve">
<value>Multi-server load balancing</value>
@@ -1376,7 +1376,7 @@
<value>Number per time for auto batch during speedtest(max 1000)</value>
</data>
<data name="TbSettingsExceptionTip2" xml:space="preserve">
<value>Exception. Do not use proxy server for addresses,with a comma (,)</value>
<value>Exclusions: Do not use proxy server for the following addresses. Use comma (,) to separate entries.</value>
</data>
<data name="TbSettingsDestOverride" xml:space="preserve">
<value>Sniffing type</value>

View File

@@ -1,26 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>7.6.2</Version>
<OutputType>Library</OutputType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Downloader" Version="3.3.1" />
<PackageReference Include="ReactiveUI" Version="20.1.63" />
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
<PackageReference Include="Splat.NLog" Version="15.2.22" />
<PackageReference Include="WebDav.Client" Version="2.8.0" />
<PackageReference Include="YamlDotNet" Version="16.3.0" />
<PackageReference Include="QRCoder" Version="1.6.0" />
<PackageReference Include="CliWrap" Version="3.7.0" />
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
<PackageReference Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
<PackageReference Include="TaskScheduler" Version="2.11.0" />
<PackageReference Include="Downloader" />
<PackageReference Include="ReactiveUI">
<TreatAsUsed>true</TreatAsUsed>
</PackageReference>
<PackageReference Include="ReactiveUI.Fody" />
<PackageReference Include="sqlite-net-pcl" />
<PackageReference Include="Splat.NLog" />
<PackageReference Include="WebDav.Client" />
<PackageReference Include="YamlDotNet" />
<PackageReference Include="QRCoder" />
<PackageReference Include="CliWrap" />
<PackageReference Include="ZXing.Net.Bindings.SkiaSharp" />
<PackageReference Include="TaskScheduler" />
</ItemGroup>
<ItemGroup>
@@ -51,9 +48,6 @@
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resx\ResUI.fa-Ir.resx">
<SubType>Designer</SubType>
<Generator>PublicResXFileCodeGenerator</Generator>

View File

@@ -116,7 +116,7 @@ namespace ServiceLib.Services.CoreConfig
//enable tun mode
if (_config.TunModeItem.EnableTun)
{
string tun = Utils.GetEmbedText(Global.ClashTunYaml);
string tun = EmbedUtils.GetEmbedText(Global.ClashTunYaml);
if (Utils.IsNotEmpty(tun))
{
var tunContent = YamlUtils.FromYaml<Dictionary<string, object>>(tun);

View File

@@ -35,7 +35,7 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.SingboxSampleClient);
string result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
if (Utils.IsNullOrEmpty(result))
{
ret.Msg = ResUI.FailedGetDefaultConfiguration;
@@ -91,8 +91,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration;
var result = Utils.GetEmbedText(Global.SingboxSampleClient);
var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
var result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{
ret.Msg = ResUI.FailedGetDefaultConfiguration;
@@ -255,8 +255,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.SingboxSampleClient);
string txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
string result = EmbedUtils.GetEmbedText(Global.SingboxSampleClient);
string txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{
ret.Msg = ResUI.FailedGetDefaultConfiguration;
@@ -546,7 +546,7 @@ namespace ServiceLib.Services.CoreConfig
_config.TunModeItem.Stack = Global.TunStacks.First();
}
var tunInbound = JsonUtils.Deserialize<Inbound4Sbox>(Utils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { };
var tunInbound = JsonUtils.Deserialize<Inbound4Sbox>(EmbedUtils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { };
tunInbound.interface_name = Utils.IsOSX() ? $"utun{new Random().Next(99)}" : "singbox_tun";
tunInbound.mtu = _config.TunModeItem.Mtu;
tunInbound.strict_route = _config.TunModeItem.StrictRoute;
@@ -867,7 +867,7 @@ namespace ServiceLib.Services.CoreConfig
//current proxy
var outbound = singboxConfig.outbounds.First();
var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
var txtOutbound = EmbedUtils.GetEmbedText(Global.SingboxSampleOutbound);
//Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
@@ -934,7 +934,7 @@ namespace ServiceLib.Services.CoreConfig
{
singboxConfig.route.auto_detect_interface = true;
var tunRules = JsonUtils.Deserialize<List<Rule4Sbox>>(Utils.GetEmbedText(Global.TunSingboxRulesFileName));
var tunRules = JsonUtils.Deserialize<List<Rule4Sbox>>(EmbedUtils.GetEmbedText(Global.TunSingboxRulesFileName));
if (tunRules != null)
{
singboxConfig.route.rules.AddRange(tunRules);
@@ -1048,7 +1048,8 @@ namespace ServiceLib.Services.CoreConfig
var countDomain = 0;
foreach (var it in item.Domain)
{
if (ParseV2Domain(it, rule1)) countDomain++;
if (ParseV2Domain(it, rule1))
countDomain++;
}
if (countDomain > 0)
{
@@ -1062,7 +1063,8 @@ namespace ServiceLib.Services.CoreConfig
var countIp = 0;
foreach (var it in item.Ip)
{
if (ParseV2Address(it, rule2)) countIp++;
if (ParseV2Address(it, rule2))
countIp++;
}
if (countIp > 0)
{
@@ -1148,12 +1150,14 @@ namespace ServiceLib.Services.CoreConfig
}
else if (address.StartsWith("geoip:"))
{
if (rule.geoip is null) { rule.geoip = new(); }
if (rule.geoip is null)
{ rule.geoip = new(); }
rule.geoip?.Add(address.Substring(6));
}
else
{
if (rule.ip_cidr is null) { rule.ip_cidr = new(); }
if (rule.ip_cidr is null)
{ rule.ip_cidr = new(); }
rule.ip_cidr?.Add(address);
}
return true;
@@ -1167,11 +1171,11 @@ namespace ServiceLib.Services.CoreConfig
var strDNS = string.Empty;
if (_config.TunModeItem.EnableTun)
{
strDNS = Utils.IsNullOrEmpty(item?.TunDNS) ? Utils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS;
strDNS = Utils.IsNullOrEmpty(item?.TunDNS) ? EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName) : item?.TunDNS;
}
else
{
strDNS = Utils.IsNullOrEmpty(item?.NormalDNS) ? Utils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS;
strDNS = Utils.IsNullOrEmpty(item?.NormalDNS) ? EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName) : item?.NormalDNS;
}
var dns4Sbox = JsonUtils.Deserialize<Dns4Sbox>(strDNS);
@@ -1271,7 +1275,8 @@ namespace ServiceLib.Services.CoreConfig
{
static void AddRuleSets(List<string> ruleSets, List<string>? rule_set)
{
if (rule_set != null) ruleSets.AddRange(rule_set);
if (rule_set != null)
ruleSets.AddRange(rule_set);
}
var geosite = "geosite";
var geoip = "geoip";
@@ -1321,7 +1326,7 @@ namespace ServiceLib.Services.CoreConfig
var routing = await ConfigHandler.GetDefaultRouting(_config);
if (Utils.IsNotEmpty(routing.CustomRulesetPath4Singbox))
{
var result = Utils.LoadResource(routing.CustomRulesetPath4Singbox);
var result = EmbedUtils.LoadResource(routing.CustomRulesetPath4Singbox);
if (Utils.IsNotEmpty(result))
{
customRulesets = (JsonUtils.Deserialize<List<Ruleset4Sbox>>(result) ?? [])
@@ -1339,7 +1344,8 @@ namespace ServiceLib.Services.CoreConfig
singboxConfig.route.rule_set = [];
foreach (var item in new HashSet<string>(ruleSets))
{
if (Utils.IsNullOrEmpty(item)) { continue; }
if (Utils.IsNullOrEmpty(item))
{ continue; }
var customRuleset = customRulesets.FirstOrDefault(t => t.tag != null && t.tag.Equals(item));
if (customRuleset is null)
{

View File

@@ -1,4 +1,4 @@
using System.Net;
using System.Net;
using System.Net.NetworkInformation;
using System.Text.Json.Nodes;
@@ -36,7 +36,7 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration;
var result = Utils.GetEmbedText(Global.V2raySampleClient);
var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
if (Utils.IsNullOrEmpty(result))
{
ret.Msg = ResUI.FailedGetDefaultConfiguration;
@@ -91,8 +91,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.V2raySampleClient);
string txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
string result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
string txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{
ret.Msg = ResUI.FailedGetDefaultConfiguration;
@@ -214,8 +214,8 @@ namespace ServiceLib.Services.CoreConfig
ret.Msg = ResUI.InitialConfiguration;
var result = Utils.GetEmbedText(Global.V2raySampleClient);
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{
ret.Msg = ResUI.FailedGetDefaultConfiguration;
@@ -428,7 +428,7 @@ namespace ServiceLib.Services.CoreConfig
private Inbounds4Ray GetInbound(InItem inItem, EInboundProtocol protocol, bool bSocks)
{
string result = Utils.GetEmbedText(Global.V2raySampleInbound);
string result = EmbedUtils.GetEmbedText(Global.V2raySampleInbound);
if (Utils.IsNullOrEmpty(result))
{
return new();
@@ -992,7 +992,7 @@ namespace ServiceLib.Services.CoreConfig
};
//request Host
string request = Utils.GetEmbedText(Global.V2raySampleHttpRequestFileName);
string request = EmbedUtils.GetEmbedText(Global.V2raySampleHttpRequestFileName);
string[] arrHost = host.Split(',');
string host2 = string.Join(",".AppendQuotes(), arrHost);
request = request.Replace("$requestHost$", $"{host2.AppendQuotes()}");
@@ -1028,7 +1028,7 @@ namespace ServiceLib.Services.CoreConfig
var domainStrategy4Freedom = item?.DomainStrategy4Freedom;
if (Utils.IsNullOrEmpty(normalDNS))
{
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);
normalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
}
//Outbound Freedom domainStrategy
@@ -1196,7 +1196,7 @@ namespace ServiceLib.Services.CoreConfig
//current proxy
var outbound = v2rayConfig.outbounds.First();
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
var txtOutbound = EmbedUtils.GetEmbedText(Global.V2raySampleOutbound);
//Previous proxy
var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);

View File

@@ -1,7 +1,7 @@
using ReactiveUI;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using ReactiveUI;
namespace ServiceLib.Services
{
@@ -119,7 +119,8 @@ namespace ServiceLib.Services
private void ExitLoop(string x)
{
if (_exitLoop) return;
if (_exitLoop)
return;
_exitLoop = true;
UpdateFunc("", ResUI.SpeedtestingStop);
}
@@ -261,7 +262,8 @@ namespace ServiceLib.Services
UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) continue;
if (item is null)
continue;
var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
@@ -323,7 +325,8 @@ namespace ServiceLib.Services
UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) continue;
if (item is null)
continue;
var webProxy = new WebProxy($"socks5://{Global.Loopback}:{it.Port}");
_ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (success, msg) =>

View File

@@ -1,4 +1,4 @@
using System.Net.WebSockets;
using System.Net.WebSockets;
using System.Text;
namespace ServiceLib.Services.Statistics
@@ -109,7 +109,8 @@ namespace ServiceLib.Services.Statistics
private void ParseOutput(string source, out ulong up, out ulong down)
{
up = 0; down = 0;
up = 0;
down = 0;
try
{
var trafficItem = JsonUtils.Deserialize<TrafficItem>(source);

View File

@@ -1,4 +1,4 @@
namespace ServiceLib.Services.Statistics
namespace ServiceLib.Services.Statistics
{
public class StatisticsXrayService
{
@@ -63,7 +63,8 @@
foreach (string key in source.stats.outbound.Keys)
{
var value = source.stats.outbound[key];
if (value == null) continue;
if (value == null)
continue;
var state = JsonUtils.Deserialize<V2rayMetricsVarsLink>(value.ToString());
if (key.StartsWith(Global.ProxyTag))

View File

@@ -368,6 +368,7 @@ namespace ServiceLib.Services
try
{
var coreInfo = CoreInfoHandler.Instance.GetCoreInfo(type);
var coreUrl = await GetUrlFromCore(coreInfo) ?? string.Empty;
SemanticVersion curVersion;
string message;
string? url;
@@ -379,28 +380,28 @@ namespace ServiceLib.Services
{
curVersion = await GetCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"));
url = string.Format(coreUrl, version.ToVersionString("v"));
break;
}
case ECoreType.mihomo:
{
curVersion = await GetCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, type, curVersion);
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"));
url = string.Format(coreUrl, version.ToVersionString("v"));
break;
}
case ECoreType.sing_box:
{
curVersion = await GetCoreVersion(type);
message = string.Format(ResUI.IsLatestCore, type, curVersion.ToVersionString("v"));
url = string.Format(GetUrlFromCore(coreInfo), version.ToVersionString("v"), version);
url = string.Format(coreUrl, version.ToVersionString("v"), version);
break;
}
case ECoreType.v2rayN:
{
curVersion = new SemanticVersion(Utils.GetVersionInfo());
message = string.Format(ResUI.IsLatestN, type, curVersion);
url = string.Format(GetUrlFromCore(coreInfo), version);
url = string.Format(coreUrl, version);
break;
}
default:
@@ -422,18 +423,19 @@ namespace ServiceLib.Services
}
}
private string? GetUrlFromCore(CoreInfo? coreInfo)
private async Task<string?> GetUrlFromCore(CoreInfo? coreInfo)
{
if (Utils.IsWindows())
{
//Check for standalone windows .Net version
if (coreInfo?.CoreType == ECoreType.v2rayN
&& File.Exists(Path.Combine(Utils.StartupPath(), "wpfgfx_cor3.dll"))
&& File.Exists(Path.Combine(Utils.StartupPath(), "D3DCompiler_47_cor3.dll"))
)
if (coreInfo?.CoreType == ECoreType.v2rayN && RuntimeInformation.ProcessArchitecture == Architecture.X64)
{
var runtimes = await Utils.GetCliWrapOutput("dotnet", "--list-runtimes");
if (runtimes == null || runtimes.Contains("Microsoft.WindowsDesktop.App 8") == false)
{
return coreInfo?.DownloadUrlWin64?.Replace(".zip", "-SelfContained.zip");
}
}
return RuntimeInformation.ProcessArchitecture switch
{

View File

@@ -1,6 +1,6 @@
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels
{

View File

@@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels
{

View File

@@ -1,7 +1,7 @@
using ReactiveUI;
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
namespace ServiceLib.ViewModels
{
@@ -173,7 +173,7 @@ namespace ServiceLib.ViewModels
var configDirZipTemp = Utils.GetTempPath($"v2rayN_{DateTime.Now:yyyyMMddHHmmss}");
var configDirTemp = Path.Combine(configDirZipTemp, _guiConfigs);
FileManager.CopyDirectory(configDir, configDirTemp, false, "cache.db");
FileManager.CopyDirectory(configDir, configDirTemp, false, true, "cache.db");
var ret = FileManager.CreateFromDirectory(configDirZipTemp, fileName);
Directory.Delete(configDirZipTemp, true);
return await Task.FromResult(ret);

View File

@@ -1,10 +1,10 @@
using DynamicData;
using System.Reactive;
using System.Runtime.InteropServices;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Runtime.InteropServices;
namespace ServiceLib.ViewModels
{
@@ -46,10 +46,14 @@ namespace ServiceLib.ViewModels
if (RuntimeInformation.ProcessArchitecture != Architecture.X86)
{
_checkUpdateModel.Add(GetCheckUpdateModel(_v2rayN));
//Not Windows and under Win10
if (!(Utils.IsWindows() && Environment.OSVersion.Version.Major < 10))
{
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.Xray.ToString()));
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.mihomo.ToString()));
_checkUpdateModel.Add(GetCheckUpdateModel(ECoreType.sing_box.ToString()));
}
}
_checkUpdateModel.Add(GetCheckUpdateModel(_geo));
}
@@ -79,7 +83,8 @@ namespace ServiceLib.ViewModels
for (var k = _checkUpdateModel.Count - 1; k >= 0; k--)
{
var item = _checkUpdateModel[k];
if (item.IsSelected != true) continue;
if (item.IsSelected != true)
continue;
UpdateView(item.CoreType, "...");
if (item.CoreType == _geo)
@@ -248,7 +253,7 @@ namespace ServiceLib.ViewModels
{
foreach (var subDir in dir.GetDirectories())
{
FileManager.CopyDirectory(subDir.FullName, toPath, false, null);
FileManager.CopyDirectory(subDir.FullName, toPath, false, true);
subDir.Delete(true);
}
}
@@ -293,7 +298,8 @@ namespace ServiceLib.ViewModels
public void UpdateViewResult(CheckUpdateModel model)
{
var found = _checkUpdateModel.FirstOrDefault(t => t.CoreType == model.CoreType);
if (found == null) return;
if (found == null)
return;
var itemCopy = JsonUtils.DeepCopy(found);
itemCopy.Remarks = model.Remarks;
_checkUpdateModel.Replace(found, itemCopy);

View File

@@ -1,9 +1,9 @@
using System.Reactive;
using System.Reactive.Linq;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using System.Reactive.Linq;
namespace ServiceLib.ViewModels
{
@@ -115,7 +115,8 @@ namespace ServiceLib.ViewModels
lstModel.Add(model);
}
if (lstModel.Count <= 0) { return; }
if (lstModel.Count <= 0)
{ return; }
_connectionItems.AddRange(lstModel);
}

View File

@@ -1,9 +1,9 @@
using System.Reactive;
using System.Reactive.Linq;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using System.Reactive.Linq;
using static ServiceLib.Models.ClashProviders;
using static ServiceLib.Models.ClashProxies;

View File

@@ -1,6 +1,6 @@
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels
{
@@ -31,14 +31,14 @@ namespace ServiceLib.ViewModels
ImportDefConfig4V2rayCmd = ReactiveCommand.CreateFromTask(async () =>
{
normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);
normalDNS = EmbedUtils.GetEmbedText(Global.DNSV2rayNormalFileName);
await Task.CompletedTask;
});
ImportDefConfig4SingboxCmd = ReactiveCommand.CreateFromTask(async () =>
{
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
normalDNS2 = EmbedUtils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = EmbedUtils.GetEmbedText(Global.TunSingboxDNSFileName);
await Task.CompletedTask;
});

View File

@@ -1,7 +1,7 @@
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
namespace ServiceLib.ViewModels
{
@@ -570,7 +570,8 @@ namespace ServiceLib.ViewModels
{
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
}
else { TabMainSelectedIndex = 0; }
else
{ TabMainSelectedIndex = 0; }
}
private async Task LoadCore()

View File

@@ -1,7 +1,7 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Collections.Concurrent;
using System.Text.RegularExpressions;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels
{

View File

@@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels
{

View File

@@ -1,11 +1,11 @@
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
namespace ServiceLib.ViewModels
{

View File

@@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels
{

View File

@@ -1,9 +1,9 @@
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using System.Text.Json;
using System.Text.Json.Serialization;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels
{
@@ -257,7 +257,7 @@ namespace ServiceLib.ViewModels
return;
}
var result = Utils.LoadResource(fileName);
var result = EmbedUtils.LoadResource(fileName);
if (Utils.IsNullOrEmpty(result))
{
return;

View File

@@ -1,7 +1,7 @@
using DynamicData.Binding;
using System.Reactive;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels
{

View File

@@ -1,9 +1,9 @@
using DynamicData.Binding;
using System.Reactive;
using System.Text;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Text;
namespace ServiceLib.ViewModels
{
@@ -225,19 +225,22 @@ namespace ServiceLib.ViewModels
private async Task AddServerViaClipboard()
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.AddServerViaClipboardAsync(null);
if (service != null)
await service.AddServerViaClipboardAsync(null);
}
private async Task AddServerViaScan()
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.AddServerViaScanAsync();
if (service != null)
await service.AddServerViaScanAsync();
}
private async Task UpdateSubscriptionProcess(bool blProxy)
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.UpdateSubscriptionProcess("", blProxy);
if (service != null)
await service.UpdateSubscriptionProcess("", blProxy);
}
public async Task RefreshServersBiz()

View File

@@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ServiceLib.ViewModels
{

View File

@@ -1,8 +1,8 @@
using DynamicData;
using System.Reactive;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using System.Reactive;
namespace ServiceLib.ViewModels
{

View File

@@ -2,16 +2,18 @@
x:Class="v2rayN.Desktop.App"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dialogHost="clr-namespace:DialogHostAvalonia;assembly=DialogHost.Avalonia"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:semi="https://irihi.tech/semi"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
x:DataType="vms:StatusBarViewModel"
Name="v2rayN"
RequestedThemeVariant="Default">
<Application.Styles>
<semi:SemiTheme />
<StyleInclude Source="Assets/GlobalStyles.axaml" />
<StyleInclude Source="avares://Semi.Avalonia.DataGrid/Index.axaml" />
<StyleInclude Source="avares://DialogHost.Avalonia/Styles.xaml" />
<dialogHost:DialogHostStyles />
</Application.Styles>
<Application.Resources>
<ResourceDictionary>

View File

@@ -64,7 +64,8 @@ public partial class App : Application
{
var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow);
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) _ = service.AddServerViaClipboardAsync(clipboardData);
if (service != null)
_ = service.AddServerViaClipboardAsync(clipboardData);
}
}
}
@@ -72,7 +73,8 @@ public partial class App : Application
private async void MenuExit_Click(object? sender, EventArgs e)
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null) await service.MyAppExitAsync(true);
if (service != null)
await service.MyAppExitAsync(true);
service?.Shutdown(true);
}
}

View File

@@ -1,4 +1,4 @@
using Avalonia;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Media.Imaging;
@@ -13,7 +13,8 @@ namespace v2rayN.Desktop.Common
try
{
var clipboard = TopLevel.GetTopLevel(owner)?.Clipboard;
if (clipboard == null) return null;
if (clipboard == null)
return null;
return await clipboard.GetTextAsync();
}
catch
@@ -27,7 +28,8 @@ namespace v2rayN.Desktop.Common
try
{
var clipboard = TopLevel.GetTopLevel(visual)?.Clipboard;
if (clipboard == null) return;
if (clipboard == null)
return;
var dataObject = new DataObject();
dataObject.Set(DataFormats.Text, strData);
await clipboard.SetDataObjectAsync(dataObject);

View File

@@ -1,4 +1,4 @@
using Avalonia.Controls;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
@@ -18,7 +18,8 @@ namespace v2rayN.Desktop.Common
public static async Task<string?> OpenFileDialog(Window owner, FilePickerFileType? filter)
{
var sp = GetStorageProvider(owner);
if (sp is null) return null;
if (sp is null)
return null;
// Start async operation to open the dialog.
var files = await sp.OpenFilePickerAsync(new FilePickerOpenOptions
@@ -33,7 +34,8 @@ namespace v2rayN.Desktop.Common
public static async Task<string?> SaveFileDialog(Window owner, string filter)
{
var sp = GetStorageProvider(owner);
if (sp is null) return null;
if (sp is null)
return null;
// Start async operation to open the dialog.
var files = await sp.SaveFilePickerAsync(new FilePickerSaveOptions

View File

@@ -1,6 +1,6 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
using System.Globalization;
using Avalonia.Data.Converters;
using Avalonia.Media;
namespace v2rayN.Desktop.Converters
{

View File

@@ -52,5 +52,6 @@ internal class Program
//.WithInterFont()
.WithFontByDefault()
.LogToTrace()
.UseReactiveUI();
.UseReactiveUI()
.With(new MacOSPlatformOptions { ShowInDock = false });
}

View File

@@ -1,3 +1,4 @@
using System.Reactive.Linq;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
@@ -7,7 +8,6 @@ using Avalonia.Styling;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Semi.Avalonia;
using System.Reactive.Linq;
namespace v2rayN.Desktop.ViewModels
{
@@ -100,7 +100,8 @@ namespace v2rayN.Desktop.ViewModels
private void ModifyFontSize()
{
double size = CurrentFontSize;
if (size < Global.MinFontSize) return;
if (size < Global.MinFontSize)
return;
Style style = new(x => Selectors.Or(
x.OfType<Button>(),

View File

@@ -1,7 +1,7 @@
using Avalonia.Interactivity;
using System.Reactive.Disposables;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views

View File

@@ -1,8 +1,8 @@
using Avalonia.Controls;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{

View File

@@ -1,8 +1,8 @@
using Avalonia.Controls;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views

View File

@@ -1,7 +1,7 @@
using Avalonia.ReactiveUI;
using System.Reactive.Disposables;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{
@@ -27,14 +27,16 @@ namespace v2rayN.Desktop.Views
switch (action)
{
case EViewAction.DispatcherCheckUpdate:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.UpdateViewResult((CheckUpdateModel)obj),
DispatcherPriority.Default);
break;
case EViewAction.DispatcherCheckUpdateFinished:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.UpdateFinishedResult((bool)obj),
DispatcherPriority.Default);

View File

@@ -1,9 +1,9 @@
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{
@@ -34,7 +34,8 @@ namespace v2rayN.Desktop.Views
switch (action)
{
case EViewAction.DispatcherRefreshConnections:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.RefreshConnections((List<ConnectionItem>?)obj),
DispatcherPriority.Default);

View File

@@ -1,10 +1,10 @@
using System.Reactive.Disposables;
using Avalonia.Input;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using DynamicData;
using ReactiveUI;
using Splat;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{
@@ -49,7 +49,8 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.DispatcherProxiesDelayTest:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.ProxiesDelayTestResult((SpeedTestResult)obj),
DispatcherPriority.Default);

View File

@@ -1,7 +1,7 @@
using Avalonia.Interactivity;
using System.Reactive.Disposables;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{

View File

@@ -1,4 +1,5 @@
using Avalonia;
using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Notifications;
@@ -10,7 +11,6 @@ using DialogHostAvalonia;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using Splat;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views
@@ -181,11 +181,13 @@ namespace v2rayN.Desktop.Views
switch (action)
{
case EViewAction.AddServerWindow:
if (obj is null) return false;
if (obj is null)
return false;
return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(this);
case EViewAction.AddServer2Window:
if (obj is null) return false;
if (obj is null)
return false;
return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(this);
case EViewAction.DNSSettingWindow:
@@ -210,7 +212,8 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.DispatcherStatistics:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.SetStatisticsResult((ServerSpeedItem)obj),
DispatcherPriority.Default);
@@ -398,7 +401,7 @@ namespace v2rayN.Desktop.Views
public void ShowHideWindow(bool? blShow)
{
var bl = blShow ?? !_config.UiItem.ShowInTaskbar;
var bl = blShow ?? (!_config.UiItem.ShowInTaskbar ^ (WindowState == WindowState.Minimized));
if (bl)
{
this.Show();
@@ -411,8 +414,12 @@ namespace v2rayN.Desktop.Views
}
else
{
if (_config.UiItem.Hide2TrayWhenClose)
if (Utils.IsOSX() || _config.UiItem.Hide2TrayWhenClose)
{
foreach (var ownedWindow in this.OwnedWindows)
{
ownedWindow.Close();
}
this.Hide();
}
else

View File

@@ -1,8 +1,8 @@
using System.Reactive.Disposables;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views
@@ -27,7 +27,8 @@ namespace v2rayN.Desktop.Views
switch (action)
{
case EViewAction.DispatcherShowMsg:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ShowMsg(obj),

View File

@@ -1,7 +1,7 @@
using Avalonia.Controls;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{
@@ -176,13 +176,6 @@ namespace v2rayN.Desktop.Views
txbSettingsExceptionTip.IsVisible = false;
panSystemProxyAdvanced.IsVisible = false;
}
if (Utils.IsOSX())
{
tbAutoRun.IsVisible = false;
togAutoRun.IsVisible = false;
//TODO
}
}
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)

View File

@@ -1,3 +1,4 @@
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
@@ -7,7 +8,6 @@ using DialogHostAvalonia;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using Splat;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views
@@ -112,7 +112,8 @@ namespace v2rayN.Desktop.Views
switch (action)
{
case EViewAction.SetClipboardData:
if (obj is null) return false;
if (obj is null)
return false;
await AvaUtils.SetClipboardData(this, (string)obj);
break;
@@ -135,7 +136,8 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.SaveFileDialog:
if (obj is null) return false;
if (obj is null)
return false;
var fileName = await UI.SaveFileDialog(_window, "");
if (fileName.IsNullOrEmpty())
{
@@ -145,24 +147,29 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.AddServerWindow:
if (obj is null) return false;
if (obj is null)
return false;
return await new AddServerWindow((ProfileItem)obj).ShowDialog<bool>(_window);
case EViewAction.AddServer2Window:
if (obj is null) return false;
if (obj is null)
return false;
return await new AddServer2Window((ProfileItem)obj).ShowDialog<bool>(_window);
case EViewAction.ShareServer:
if (obj is null) return false;
if (obj is null)
return false;
await ShareServer((string)obj);
break;
case EViewAction.SubEditWindow:
if (obj is null) return false;
if (obj is null)
return false;
return await new SubEditWindow((SubItem)obj).ShowDialog<bool>(_window);
case EViewAction.DispatcherSpeedTest:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.SetSpeedTestResult((SpeedTestResult)obj),
DispatcherPriority.Default);
@@ -198,7 +205,8 @@ namespace v2rayN.Desktop.Views
private void LstProfiles_DoubleTapped(object? sender, Avalonia.Input.TappedEventArgs e)
{
var source = e.Source as Border;
if (source?.Name == "HeaderBackground") return;
if (source?.Name == "HeaderBackground")
return;
if (_config.UiItem.DoubleClick2Activate)
{
ViewModel?.SetDefaultServer();

View File

@@ -1,4 +1,4 @@
using Avalonia.Controls;
using Avalonia.Controls;
using Avalonia.Media.Imaging;
namespace v2rayN.Desktop.Views
@@ -28,7 +28,8 @@ namespace v2rayN.Desktop.Views
private Bitmap? ByteToBitmap(byte[]? bytes)
{
if (bytes is null) return null;
if (bytes is null)
return null;
using var ms = new MemoryStream(bytes);
return new Bitmap(ms);

View File

@@ -1,8 +1,8 @@
using Avalonia.Controls;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{

View File

@@ -1,11 +1,10 @@
using Avalonia.Controls;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using Avalonia.ReactiveUI;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views
@@ -95,7 +94,8 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.RoutingRuleDetailsWindow:
if (obj is null) return false;
if (obj is null)
return false;
return await new RoutingRuleDetailsWindow((RulesItem)obj).ShowDialog<bool>(this);
case EViewAction.ImportRulesFromFile:
@@ -108,7 +108,8 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.SetClipboardData:
if (obj is null) return false;
if (obj is null)
return false;
await AvaUtils.SetClipboardData(this, (string)obj);
break;

View File

@@ -1,10 +1,10 @@
using Avalonia.Controls;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views
@@ -75,7 +75,8 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.RoutingRuleSettingWindow:
if (obj is null) return false;
if (obj is null)
return false;
return await new RoutingRuleSettingWindow((RoutingItem)obj).ShowDialog<bool>(this);
}
return await Task.FromResult(true);

View File

@@ -1,3 +1,4 @@
using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
@@ -5,7 +6,6 @@ using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
using Splat;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views
@@ -50,7 +50,8 @@ namespace v2rayN.Desktop.Views
switch (action)
{
case EViewAction.DispatcherServerAvailability:
if (obj is null) return false;
if (obj is null)
return false;
Dispatcher.UIThread.Post(() =>
ViewModel?.TestServerAvailabilityResult((string)obj),
DispatcherPriority.Default);
@@ -71,7 +72,8 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.SetClipboardData:
if (obj is null) return false;
if (obj is null)
return false;
await AvaUtils.SetClipboardData(this, (string)obj);
break;
}

View File

@@ -1,8 +1,8 @@
using System.Reactive.Disposables;
using Avalonia;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using ReactiveUI;
using System.Reactive.Disposables;
namespace v2rayN.Desktop.Views
{

View File

@@ -1,11 +1,11 @@
using Avalonia.Controls;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using DialogHostAvalonia;
using DynamicData;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using System.Reactive.Disposables;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views
@@ -52,13 +52,15 @@ namespace v2rayN.Desktop.Views
break;
case EViewAction.SubEditWindow:
if (obj is null) return false;
if (obj is null)
return false;
var window = new SubEditWindow((SubItem)obj);
await window.ShowDialog(this);
break;
case EViewAction.ShareSub:
if (obj is null) return false;
if (obj is null)
return false;
await ShareSub((string)obj);
break;
}

Some files were not shown because too many files have changed in this diff Show More