diff --git a/.gitignore b/.gitignore
index 8e4d453..ebdb2de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,11 @@
+### VisualStudio template
## 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
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
+*.rsuser
*.suo
*.user
*.userosscache
@@ -12,6 +14,9 @@
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
+# Mono auto generated files
+mono_crash.*
+
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -19,43 +24,62 @@
[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 cache/options directory
+# 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
+# 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/
-**/Properties/launchSettings.json
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
*_i.c
*_p.c
-*_i.h
+*_h.h
*.ilk
*.meta
*.obj
+*.iobj
*.pch
*.pdb
+*.ipdb
*.pgc
*.pgd
*.rsp
@@ -65,7 +89,9 @@ artifacts/
*.tlh
*.tmp
*.tmp_proj
+*_wpftmp.csproj
*.log
+*.tlog
*.vspscc
*.vssscc
.builds
@@ -93,6 +119,9 @@ ipch/
*.vspx
*.sap
+# Visual Studio Trace Files
+*.e2e
+
# TFS 2012 Local Workspace
$tf/
@@ -104,15 +133,21 @@ _ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
-# JustCode is a .NET coding add-in
-.JustCode
-
# 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
@@ -148,7 +183,7 @@ publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
-# TODO: Comment the next line if you want to checkin your web deploy settings
+# 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
@@ -160,12 +195,14 @@ PublishScripts/
# NuGet Packages
*.nupkg
+# NuGet Symbol Packages
+*.snupkg
# The packages folder can be ignored because of Package Restore
-**/packages/*
+**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
-!**/packages/build/
+!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
-#!**/packages/repositories.config
+#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
@@ -183,12 +220,15 @@ 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/
+!?*.[Cc]ache/
# Others
ClientBin/
@@ -201,6 +241,10 @@ ClientBin/
*.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/
@@ -215,6 +259,8 @@ _UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
# SQL Server files
*.mdf
@@ -225,6 +271,10 @@ UpgradeLog*.htm
*.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/
@@ -236,9 +286,6 @@ FakesAssemblies/
.ntvs_analysis.dat
node_modules/
-# Typescript v1 declaration files
-typings/
-
# Visual Studio 6 build log
*.plg
@@ -248,6 +295,17 @@ typings/
# 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
@@ -263,12 +321,8 @@ paket-files/
# FAKE - F# Make
.fake/
-# JetBrains Rider
-.idea/
-*.sln.iml
-
-# CodeRush
-.cr/
+# CodeRush personal settings
+.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
@@ -278,6 +332,9 @@ __pycache__/
# tools/**
# !tools/packages.config
+# Tabs Studio
+*.tss
+
# Telerik's JustMock configuration file
*.jmconfig
@@ -287,5 +344,139 @@ __pycache__/
*.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
+
# WiX harvested files
*.heat.wxs
+
+# JetBrains Rider
+*.sln.iml
+
+### Rider template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
diff --git a/src/.editorconfig b/src/.editorconfig
new file mode 100644
index 0000000..291faa1
--- /dev/null
+++ b/src/.editorconfig
@@ -0,0 +1,41 @@
+[*]
+
+# Microsoft .NET properties
+csharp_new_line_before_members_in_object_initializers = false
+csharp_preferred_modifier_order = private, public, protected, internal, file, new, static, sealed, override, virtual, abstract, async, extern, unsafe, volatile, readonly, required:suggestion
+csharp_style_namespace_declarations = block_scoped:suggestion
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:none
+
+# ReSharper properties
+resharper_align_linq_query = true
+resharper_align_multiline_binary_expressions_chain = false
+resharper_align_multiline_statement_conditions = false
+resharper_blank_lines_after_block_statements = 0
+resharper_blank_lines_around_single_line_auto_property = 1
+resharper_braces_for_foreach = required
+resharper_braces_for_using = required
+resharper_braces_for_while = required
+resharper_braces_redundant = false
+resharper_csharp_blank_lines_around_field = 0
+resharper_csharp_blank_lines_around_region = 0
+resharper_csharp_blank_lines_around_single_line_invocable = 1
+resharper_csharp_insert_final_newline = true
+resharper_csharp_max_line_length = 201
+resharper_csharp_remove_blank_lines_near_braces_in_code = false
+resharper_csharp_remove_blank_lines_near_braces_in_declarations = false
+resharper_indent_pars = outside_and_inside
+resharper_instance_members_qualify_declared_in =
+resharper_keep_existing_attribute_arrangement = true
+resharper_nested_ternary_style = simple_wrap
+resharper_object_creation_when_type_evident = explicitly_typed
+resharper_parentheses_redundancy_style = remove
+resharper_parentheses_same_type_operations = true
+resharper_place_accessorholder_attribute_on_same_line = false
+resharper_place_expr_accessor_on_single_line = true
+resharper_place_expr_method_on_single_line = true
+resharper_place_simple_embedded_statement_on_same_line = false
+resharper_place_simple_initializer_on_single_line = false
+resharper_space_within_single_line_array_initializer_braces = false
+resharper_wrap_object_and_collection_initializer_style = chop_always
diff --git a/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/.gitignore b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/.gitignore
new file mode 100644
index 0000000..8c363ae
--- /dev/null
+++ b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/contentModel.xml
+/.idea.QBittorrent.CommandLineInterface.iml
+/projectSettingsUpdater.xml
+/modules.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/.name b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/.name
new file mode 100644
index 0000000..f236102
--- /dev/null
+++ b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/.name
@@ -0,0 +1 @@
+QBittorrent.CommandLineInterface
\ No newline at end of file
diff --git a/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/encodings.xml b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/encodings.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/indexLayout.xml b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/indexLayout.xml
new file mode 100644
index 0000000..f9b49bd
--- /dev/null
+++ b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/indexLayout.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ ../../qbittorrent-cli
+
+
+
+
+
\ No newline at end of file
diff --git a/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/vcs.xml b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/vcs.xml
new file mode 100644
index 0000000..62bd7a0
--- /dev/null
+++ b/src/.idea/.idea.QBittorrent.CommandLineInterface/.idea/vcs.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/QBittorrent.CommandLineInterface.sln.DotSettings b/src/QBittorrent.CommandLineInterface.sln.DotSettings
index eb72693..4f34420 100644
--- a/src/QBittorrent.CommandLineInterface.sln.DotSettings
+++ b/src/QBittorrent.CommandLineInterface.sln.DotSettings
@@ -1,47 +1,4 @@
- UI
- True
- True
- True
- 3
- True
- 0
- True
- 2
- True
- completeSmart()
- 1
- True
- True
- 2.0
- InCSharpTypeMember
- jdprop
- True
- /// <summary>
-///
-/// </summary>
-[JsonProperty("$JSON_NAME$")]
-[Display(Name = "$DISP_NAME$")]
-public $TYPE$ $PROP$ { get; set; }
- True
- True
- 0
- True
- 2
- True
- completeSmart()
- 1
- jprop
- JSON Property
- True
- True
- True
- True
- InCSharpTypeMember
- 2.0
- /// <summary>
-///
-/// </summary>
-[JsonProperty("$JSON_NAME$")]
-public $TYPE$ $PROP$ { get; set; }
- True
\ No newline at end of file
+ BT
+ DHT
+ UI
\ No newline at end of file
diff --git a/src/QBittorrent.CommandLineInterface/App.config b/src/QBittorrent.CommandLineInterface/App.config
deleted file mode 100644
index badb1a5..0000000
--- a/src/QBittorrent.CommandLineInterface/App.config
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/QBittorrent.CommandLineInterface/Attributes/EnumValidationAttribute.cs b/src/QBittorrent.CommandLineInterface/Attributes/EnumValidationAttribute.cs
index 8ea419e..0494fc3 100644
--- a/src/QBittorrent.CommandLineInterface/Attributes/EnumValidationAttribute.cs
+++ b/src/QBittorrent.CommandLineInterface/Attributes/EnumValidationAttribute.cs
@@ -22,15 +22,15 @@ public EnumValidationAttribute(Type enumType)
public bool AllowEmpty { get; set; }
- protected override ValidationResult IsValid(object value, ValidationContext validationContext)
+ protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
- if (value == null && AllowEmpty)
- return ValidationResult.Success;
-
- if (value is string str &&
- (EnumHelper.TryParse(EnumType, str, !CaseSensitive, out _) || (AllowEmpty && string.IsNullOrEmpty(str)))
- )
- return ValidationResult.Success;
+ switch (value)
+ {
+ case null when AllowEmpty:
+ case string str when
+ Enum.TryParse(EnumType, str, !CaseSensitive, out _) || AllowEmpty && string.IsNullOrEmpty(str):
+ return ValidationResult.Success;
+ }
var values = string.Join(", ", Enum.GetValues(EnumType).Cast