diff --git a/Shadowsocks.WPF/Models/Group.cs b/Shadowsocks.WPF/Models/Group.cs
new file mode 100644
index 00000000..ff0dfe30
--- /dev/null
+++ b/Shadowsocks.WPF/Models/Group.cs
@@ -0,0 +1,18 @@
+namespace Shadowsocks.WPF.Models
+{
+ public class Group : Shadowsocks.Models.Group
+ {
+ ///
+ /// Gets or sets the URL of SIP008 online configuration delivery source.
+ ///
+ public string OnlineConfigSource { get; set; }
+
+ public Group() : this(string.Empty)
+ { }
+
+ public Group(string name) : base(name)
+ {
+ OnlineConfigSource = "";
+ }
+ }
+}
diff --git a/Shadowsocks.WPF/Models/Server.cs b/Shadowsocks.WPF/Models/Server.cs
new file mode 100644
index 00000000..9e5c6107
--- /dev/null
+++ b/Shadowsocks.WPF/Models/Server.cs
@@ -0,0 +1,30 @@
+namespace Shadowsocks.WPF.Models
+{
+ public class Server : Shadowsocks.Models.Server
+ {
+ ///
+ /// Gets or sets the arguments passed to the plugin process.
+ ///
+ public string PluginArgs { get; set; }
+
+ public Server()
+ {
+ PluginArgs = "";
+ }
+
+ public Server(
+ string name,
+ string uuid,
+ string host,
+ int port,
+ string password,
+ string method,
+ string plugin = "",
+ string pluginOpts = "",
+ string pluginArgs = "")
+ : base(name, uuid, host, port, password, method, plugin, pluginOpts)
+ {
+ PluginArgs = pluginArgs;
+ }
+ }
+}
diff --git a/Shadowsocks.WPF/Models/Settings.cs b/Shadowsocks.WPF/Models/Settings.cs
index 30407a8d..5345dc28 100644
--- a/Shadowsocks.WPF/Models/Settings.cs
+++ b/Shadowsocks.WPF/Models/Settings.cs
@@ -1,10 +1,7 @@
using Shadowsocks.Interop.Settings;
-using Shadowsocks.Models;
using Shadowsocks.Net.Settings;
using Shadowsocks.PAC;
-using System;
using System.Collections.Generic;
-using System.Text;
namespace Shadowsocks.WPF.Models
{
diff --git a/Shadowsocks.WPF/Properties/PublishProfiles/FolderProfile.pubxml b/Shadowsocks.WPF/Properties/PublishProfiles/FolderProfile.pubxml
index dad542e5..7c7740f6 100644
--- a/Shadowsocks.WPF/Properties/PublishProfiles/FolderProfile.pubxml
+++ b/Shadowsocks.WPF/Properties/PublishProfiles/FolderProfile.pubxml
@@ -1,4 +1,4 @@
-
+
@@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
Release
Any CPU
- bin\Release\net5.0-windows\publish\
+ bin\Release\net5.0-windows10.0.19041.0\publish\
FileSystem
\ No newline at end of file
diff --git a/Shadowsocks.WPF/Properties/PublishProfiles/win-arm.pubxml b/Shadowsocks.WPF/Properties/PublishProfiles/win-arm.pubxml
index d38edafb..7d876c08 100644
--- a/Shadowsocks.WPF/Properties/PublishProfiles/win-arm.pubxml
+++ b/Shadowsocks.WPF/Properties/PublishProfiles/win-arm.pubxml
@@ -1,4 +1,4 @@
-
+
@@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
Release
Any CPU
- bin\Release\net5.0-windows\win-arm\publish\
+ bin\Release\net5.0-windows10.0.19041.0\win-arm\publish\
FileSystem
net5.0-windows
win-arm
diff --git a/Shadowsocks.WPF/Properties/PublishProfiles/win-x64.pubxml b/Shadowsocks.WPF/Properties/PublishProfiles/win-x64.pubxml
index d130a3fc..09790675 100644
--- a/Shadowsocks.WPF/Properties/PublishProfiles/win-x64.pubxml
+++ b/Shadowsocks.WPF/Properties/PublishProfiles/win-x64.pubxml
@@ -1,4 +1,4 @@
-
+
@@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
Release
Any CPU
- bin\Release\net5.0-windows\win-x64\publish\
+ bin\Release\net5.0-windows10.0.19041.0\win-x64\publish\
FileSystem
net5.0-windows
win-x64
diff --git a/Shadowsocks.WPF/Properties/PublishProfiles/win-x86.pubxml b/Shadowsocks.WPF/Properties/PublishProfiles/win-x86.pubxml
index 83be6696..ba8e4806 100644
--- a/Shadowsocks.WPF/Properties/PublishProfiles/win-x86.pubxml
+++ b/Shadowsocks.WPF/Properties/PublishProfiles/win-x86.pubxml
@@ -1,4 +1,4 @@
-
+
@@ -6,7 +6,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
Release
Any CPU
- bin\Release\net5.0-windows\win-x86\publish\
+ bin\Release\net5.0-windows10.0.19041.0\win-x86\publish\
FileSystem
net5.0-windows
win-x86
diff --git a/Shadowsocks.WPF/Services/OnlineConfigService.cs b/Shadowsocks.WPF/Services/OnlineConfigService.cs
index 0a0e4132..81f9392b 100644
--- a/Shadowsocks.WPF/Services/OnlineConfigService.cs
+++ b/Shadowsocks.WPF/Services/OnlineConfigService.cs
@@ -1,4 +1,4 @@
-using Shadowsocks.Models;
+using Shadowsocks.WPF.Models;
using Splat;
using System;
using System.Collections.Generic;
diff --git a/Shadowsocks.WPF/Services/Sip003Plugin.cs b/Shadowsocks.WPF/Services/Sip003Plugin.cs
index e00c698b..2da18b72 100644
--- a/Shadowsocks.WPF/Services/Sip003Plugin.cs
+++ b/Shadowsocks.WPF/Services/Sip003Plugin.cs
@@ -1,4 +1,4 @@
-using Shadowsocks.Models;
+using Shadowsocks.WPF.Models;
using System;
using System.Collections.Specialized;
using System.Diagnostics;
@@ -34,7 +34,7 @@ namespace Shadowsocks.WPF.Services
return new Sip003Plugin(
server.Plugin,
server.PluginOpts,
- server.plugin_args,
+ server.PluginArgs,
server.Host,
server.Port,
showPluginOutput);
diff --git a/Shadowsocks.WPF/Services/UpdateChecker.cs b/Shadowsocks.WPF/Services/UpdateChecker.cs
index 6084253d..87e4e0e1 100644
--- a/Shadowsocks.WPF/Services/UpdateChecker.cs
+++ b/Shadowsocks.WPF/Services/UpdateChecker.cs
@@ -9,6 +9,7 @@ using System.Windows;
using NLog;
using Shadowsocks.WPF.Localization;
using Shadowsocks.WPF.Models;
+using Shadowsocks.WPF.ViewModels;
using Shadowsocks.WPF.Views;
using Splat;
@@ -98,6 +99,10 @@ namespace Shadowsocks.WPF.Services
{
if (versionUpdatePromptWindow == null)
{
+ var versionUpdatePromptView = new VersionUpdatePromptView()
+ {
+ ViewModel = new VersionUpdatePromptViewModel(releaseObject),
+ };
versionUpdatePromptWindow = new Window()
{
Title = LocalizationProvider.GetLocalizedValue("VersionUpdate"),
@@ -105,7 +110,7 @@ namespace Shadowsocks.WPF.Services
Width = 640,
MinHeight = 480,
MinWidth = 640,
- Content = new VersionUpdatePromptView(releaseObject)
+ Content = versionUpdatePromptView,
};
versionUpdatePromptWindow.Closed += VersionUpdatePromptWindow_Closed;
versionUpdatePromptWindow.Show();
diff --git a/Shadowsocks.WPF/Shadowsocks.WPF.csproj b/Shadowsocks.WPF/Shadowsocks.WPF.csproj
index 158aab7e..9d886785 100644
--- a/Shadowsocks.WPF/Shadowsocks.WPF.csproj
+++ b/Shadowsocks.WPF/Shadowsocks.WPF.csproj
@@ -2,13 +2,13 @@
Exe
- net5.0-windows
+ net5.0-windows10.0.19041.0
true
App.manifest
Shadowsocks for Windows WPF GUI
Clowwindy & The Community
5.0.0
- Assets\shadowsocks.ico
+ shadowsocks.ico
enable
© 2020 Clowwindy & The Community
LICENSE.txt
@@ -36,7 +36,6 @@
-
@@ -60,6 +59,7 @@
+
@@ -113,7 +113,6 @@
-
diff --git a/Shadowsocks.WPF/ViewModels/ServerSharingViewModel.cs b/Shadowsocks.WPF/ViewModels/ServerSharingViewModel.cs
index ab86896d..6acca5d4 100644
--- a/Shadowsocks.WPF/ViewModels/ServerSharingViewModel.cs
+++ b/Shadowsocks.WPF/ViewModels/ServerSharingViewModel.cs
@@ -1,6 +1,6 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
-using Shadowsocks.Models;
+using Shadowsocks.WPF.Models;
using System;
using System.Collections.Generic;
using System.Drawing;
diff --git a/Shadowsocks.WPF/Views/DashboardView.xaml.cs b/Shadowsocks.WPF/Views/DashboardView.xaml.cs
index f7188688..8a0789be 100644
--- a/Shadowsocks.WPF/Views/DashboardView.xaml.cs
+++ b/Shadowsocks.WPF/Views/DashboardView.xaml.cs
@@ -18,7 +18,7 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for DashboardView.xaml
///
- public partial class DashboardView : ReactiveUserControl
+ public partial class DashboardView
{
public DashboardView()
{
diff --git a/Shadowsocks.WPF/Views/ForwardProxyView.xaml.cs b/Shadowsocks.WPF/Views/ForwardProxyView.xaml.cs
index c4180266..8d647e68 100644
--- a/Shadowsocks.WPF/Views/ForwardProxyView.xaml.cs
+++ b/Shadowsocks.WPF/Views/ForwardProxyView.xaml.cs
@@ -1,4 +1,4 @@
-using ReactiveUI;
+using ReactiveUI;
using Shadowsocks.WPF.ViewModels;
using System.Reactive.Disposables;
@@ -7,7 +7,7 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for ForwardProxyView.xaml
///
- public partial class ForwardProxyView : ReactiveUserControl
+ public partial class ForwardProxyView
{
public ForwardProxyView()
{
diff --git a/Shadowsocks.WPF/Views/MainWindow.xaml b/Shadowsocks.WPF/Views/MainWindow.xaml
index 455e7e4b..03ef07f3 100644
--- a/Shadowsocks.WPF/Views/MainWindow.xaml
+++ b/Shadowsocks.WPF/Views/MainWindow.xaml
@@ -13,7 +13,7 @@
lex:ResxLocalizationProvider.DefaultAssembly="Shadowsocks"
lex:ResxLocalizationProvider.DefaultDictionary="Strings"
mc:Ignorable="d"
- Title="Shadowsocks" Width="800" Height="600" MinWidth="800" MinHeight="600"
+ Title="Shadowsocks" Width="960" Height="720" MinWidth="800" MinHeight="600"
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
TextElement.FontWeight="Regular"
TextElement.FontSize="13"
@@ -25,7 +25,9 @@
+ Style="{StaticResource MaterialDesignNavigationRailTabItem}"
+ Height="56"
+ Width="56">
+ Style="{StaticResource MaterialDesignNavigationRailTabItem}"
+ Height="56"
+ Width="56">
+ Style="{StaticResource MaterialDesignNavigationRailTabItem}"
+ Height="56"
+ Width="56">
+ Style="{StaticResource MaterialDesignNavigationRailTabItem}"
+ Height="56"
+ Width="56">
/// Interaction logic for MainWindow.xaml
///
- public partial class MainWindow : ReactiveWindow
+ public partial class MainWindow
{
public MainWindow()
{
diff --git a/Shadowsocks.WPF/Views/OnlineConfigView.xaml.cs b/Shadowsocks.WPF/Views/OnlineConfigView.xaml.cs
index ba212d02..ba5ea879 100644
--- a/Shadowsocks.WPF/Views/OnlineConfigView.xaml.cs
+++ b/Shadowsocks.WPF/Views/OnlineConfigView.xaml.cs
@@ -1,4 +1,4 @@
-using ReactiveUI;
+using ReactiveUI;
using Shadowsocks.WPF.ViewModels;
using System.Reactive.Disposables;
@@ -7,7 +7,7 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for OnlineConfigView.xaml
///
- public partial class OnlineConfigView : ReactiveUserControl
+ public partial class OnlineConfigView
{
public OnlineConfigView()
{
diff --git a/Shadowsocks.WPF/Views/RoutingView.xaml.cs b/Shadowsocks.WPF/Views/RoutingView.xaml.cs
index 987811b2..d32678ad 100644
--- a/Shadowsocks.WPF/Views/RoutingView.xaml.cs
+++ b/Shadowsocks.WPF/Views/RoutingView.xaml.cs
@@ -18,7 +18,7 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for RoutingView.xaml
///
- public partial class RoutingView : ReactiveUserControl
+ public partial class RoutingView
{
public RoutingView()
{
diff --git a/Shadowsocks.WPF/Views/ServerSharingView.xaml.cs b/Shadowsocks.WPF/Views/ServerSharingView.xaml.cs
index cc263693..e4288a3a 100644
--- a/Shadowsocks.WPF/Views/ServerSharingView.xaml.cs
+++ b/Shadowsocks.WPF/Views/ServerSharingView.xaml.cs
@@ -1,4 +1,4 @@
-using ReactiveUI;
+using ReactiveUI;
using Shadowsocks.WPF.ViewModels;
using System.Reactive.Disposables;
using System.Windows.Input;
@@ -8,12 +8,11 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for ServerSharingView.xaml
///
- public partial class ServerSharingView : ReactiveUserControl
+ public partial class ServerSharingView
{
public ServerSharingView()
{
InitializeComponent();
- ViewModel = new ServerSharingViewModel();
this.WhenActivated(disposables =>
{
this.OneWayBind(ViewModel,
diff --git a/Shadowsocks.WPF/Views/ServersView.xaml.cs b/Shadowsocks.WPF/Views/ServersView.xaml.cs
index 0d2fa9f2..3a4f993a 100644
--- a/Shadowsocks.WPF/Views/ServersView.xaml.cs
+++ b/Shadowsocks.WPF/Views/ServersView.xaml.cs
@@ -18,7 +18,7 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for ServersView.xaml
///
- public partial class ServersView : ReactiveUserControl
+ public partial class ServersView
{
public ServersView()
{
diff --git a/Shadowsocks.WPF/Views/SettingsView.xaml.cs b/Shadowsocks.WPF/Views/SettingsView.xaml.cs
index 798d9520..6cb879c8 100644
--- a/Shadowsocks.WPF/Views/SettingsView.xaml.cs
+++ b/Shadowsocks.WPF/Views/SettingsView.xaml.cs
@@ -18,7 +18,7 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for SettingsView.xaml
///
- public partial class SettingsView : ReactiveUserControl
+ public partial class SettingsView
{
public SettingsView()
{
diff --git a/Shadowsocks.WPF/Views/VersionUpdatePromptView.xaml.cs b/Shadowsocks.WPF/Views/VersionUpdatePromptView.xaml.cs
index b7a9e152..ffaddbcd 100644
--- a/Shadowsocks.WPF/Views/VersionUpdatePromptView.xaml.cs
+++ b/Shadowsocks.WPF/Views/VersionUpdatePromptView.xaml.cs
@@ -8,12 +8,11 @@ namespace Shadowsocks.WPF.Views
///
/// Interaction logic for VersionUpdatePromptView.xaml
///
- public partial class VersionUpdatePromptView : ReactiveUserControl
+ public partial class VersionUpdatePromptView
{
- public VersionUpdatePromptView(JsonElement releaseObject)
+ public VersionUpdatePromptView()
{
InitializeComponent();
- ViewModel = new VersionUpdatePromptViewModel(releaseObject);
DataContext = ViewModel; // for compatibility with MdXaml
this.WhenActivated(disposables =>
{
diff --git a/Shadowsocks.WPF/Resources/shadowsocks.ico b/Shadowsocks.WPF/shadowsocks.ico
similarity index 100%
rename from Shadowsocks.WPF/Resources/shadowsocks.ico
rename to Shadowsocks.WPF/shadowsocks.ico
diff --git a/Shadowsocks/Models/Group.cs b/Shadowsocks/Models/Group.cs
index 5cd88fa2..ad817d28 100644
--- a/Shadowsocks/Models/Group.cs
+++ b/Shadowsocks/Models/Group.cs
@@ -5,61 +5,43 @@ using System.Text.Json.Serialization;
namespace Shadowsocks.Models
{
- public class Group
+ public class Group : IGroup
{
///
- /// Group name.
+ /// Gets or sets the group name.
///
public string Name { get; set; }
///
- /// UUID of the group.
+ /// Gets or sets the UUID of the group.
///
public Guid Id { get; set; }
- ///
- /// URL of SIP008 online configuration delivery source.
- ///
- public string OnlineConfigSource { get; set; }
-
- ///
- /// SIP008 configuration version.
- ///
+ ///
public int Version { get; set; }
- ///
- /// A list of servers in the group.
- ///
+ ///
public List Servers { get; set; }
///
- /// Data used in bytes.
+ /// Gets or sets the data usage in bytes.
/// The value is fetched from SIP008 provider.
///
public ulong BytesUsed { get; set; }
///
- /// Data remaining to be used in bytes.
+ /// Gets or sets the data remaining to be used in bytes.
/// The value is fetched from SIP008 provider.
///
public ulong BytesRemaining { get; set; }
- public Group()
- {
- Name = "";
- Id = new Guid();
- OnlineConfigSource = "";
- Version = 1;
- BytesUsed = 0UL;
- BytesRemaining = 0UL;
- Servers = new List();
- }
+ public Group() : this(string.Empty)
+ { }
public Group(string name)
{
Name = name;
Id = new Guid();
- OnlineConfigSource = "";
Version = 1;
BytesUsed = 0UL;
BytesRemaining = 0UL;
diff --git a/Shadowsocks/Models/IGroup.cs b/Shadowsocks/Models/IGroup.cs
new file mode 100644
index 00000000..58772048
--- /dev/null
+++ b/Shadowsocks/Models/IGroup.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+
+namespace Shadowsocks.Models
+{
+ public interface IGroup
+ {
+ ///
+ /// Gets or sets the SIP008 configuration version.
+ ///
+ public int Version { get; set; }
+
+ ///
+ /// Gets or sets the list of servers in the group.
+ ///
+ public List Servers { get; set; }
+ }
+}
diff --git a/Shadowsocks/Models/IServer.cs b/Shadowsocks/Models/IServer.cs
new file mode 100644
index 00000000..e4f65798
--- /dev/null
+++ b/Shadowsocks/Models/IServer.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Text.Json.Serialization;
+
+namespace Shadowsocks.Models
+{
+ public interface IServer : IEquatable
+ {
+ [JsonPropertyName("server")]
+ public string Host { get; set; }
+ [JsonPropertyName("server_port")]
+ public int Port { get; set; }
+ public string Password { get; set; }
+ public string Method { get; set; }
+ public string Plugin { get; set; }
+ public string PluginOpts { get; set; }
+ [JsonPropertyName("remarks")]
+ public string Name { get; set; }
+ }
+}
diff --git a/Shadowsocks/Models/Server.cs b/Shadowsocks/Models/Server.cs
index 33d59f9e..cc1212d5 100644
--- a/Shadowsocks/Models/Server.cs
+++ b/Shadowsocks/Models/Server.cs
@@ -5,7 +5,7 @@ using System.Text.Json.Serialization;
namespace Shadowsocks.Models
{
- public class Server
+ public class Server : IServer
{
[JsonPropertyName("server")]
public string Host { get; set; }
@@ -52,8 +52,8 @@ namespace Shadowsocks.Models
Uuid = uuid;
}
- public override bool Equals(object? obj) => obj is Server server && Uuid == server.Uuid;
- public override int GetHashCode() => base.GetHashCode();
+ public bool Equals(IServer? other) => other is Server anotherServer && Uuid == anotherServer.Uuid;
+ public override int GetHashCode() => Uuid.GetHashCode();
public override string ToString() => Name;
///
diff --git a/appveyor.yml b/appveyor.yml
index 1d1ea443..2f7475f7 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -144,10 +144,10 @@ after_build:
$ZipMinimal = "$WorkingFolder\shadowsocks-windows-$env:APPVEYOR_BUILD_VERSION-minimal.zip"
$ZipSingleExeX64 = "$WorkingFolder\shadowsocks-windows-$env:APPVEYOR_BUILD_VERSION-portable-x64.zip"
$ZipSingleExeX86 = "$WorkingFolder\shadowsocks-windows-$env:APPVEYOR_BUILD_VERSION-portable-x86.zip"
- 7z a $ZipDev "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\$env:CONFIGURATION\netcoreapp3.1\*"
- 7z a $ZipMinimal "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\Any CPU\$env:CONFIGURATION\netcoreapp3.1\publish\*"
- 7z a $ZipSingleExeX64 "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\Any CPU\$env:CONFIGURATION\netcoreapp3.1\win-x64\publish\Shadowsocks.exe"
- 7z a $ZipSingleExeX86 "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\Any CPU\$env:CONFIGURATION\netcoreapp3.1\win-x86\publish\Shadowsocks.exe"
+ 7z a $ZipDev "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\$env:CONFIGURATION\net5.0-windows10.0.19041.0\*"
+ 7z a $ZipMinimal "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\Any CPU\$env:CONFIGURATION\net5.0-windows10.0.19041.0\publish\*"
+ 7z a $ZipSingleExeX64 "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\Any CPU\$env:CONFIGURATION\net5.0-windows10.0.19041.0\win-x64\publish\Shadowsocks.exe"
+ 7z a $ZipSingleExeX86 "$env:APPVEYOR_BUILD_FOLDER\Shadowsocks.WPF\bin\Any CPU\$env:CONFIGURATION\net5.0-windows10.0.19041.0\win-x86\publish\Shadowsocks.exe"
Calculate-Hash -file $ZipDev | Out-File -FilePath $HashFile -Append
Calculate-Hash -file $ZipMinimal | Out-File -FilePath $HashFile -Append
Calculate-Hash -file $ZipSingleExeX64 | Out-File -FilePath $HashFile -Append