@@ -3,28 +3,19 @@ namespace Shadowsocks.WPF.Models | |||||
public class Server : Shadowsocks.Models.Server | public class Server : Shadowsocks.Models.Server | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
/// Gets or sets the arguments passed to the plugin process. | |||||
/// Gets or sets the amount of data ingress in bytes. | |||||
/// </summary> | /// </summary> | ||||
public string PluginArgs { get; set; } | |||||
public ulong BytesIngress { get; set; } | |||||
public Server() | |||||
{ | |||||
PluginArgs = ""; | |||||
} | |||||
/// <summary> | |||||
/// Gets or sets the amount of data egress in bytes. | |||||
/// </summary> | |||||
public ulong BytesEgress { get; set; } | |||||
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) | |||||
public Server() | |||||
{ | { | ||||
PluginArgs = pluginArgs; | |||||
BytesIngress = 0UL; | |||||
BytesEgress = 0UL; | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -1,5 +1,6 @@ | |||||
using Shadowsocks.WPF.Models; | using Shadowsocks.WPF.Models; | ||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Collections.Specialized; | using System.Collections.Specialized; | ||||
using System.Diagnostics; | using System.Diagnostics; | ||||
using System.IO; | using System.IO; | ||||
@@ -40,7 +41,7 @@ namespace Shadowsocks.WPF.Services | |||||
showPluginOutput); | showPluginOutput); | ||||
} | } | ||||
private Sip003Plugin(string plugin, string pluginOpts, string pluginArgs, string serverAddress, int serverPort, bool showPluginOutput) | |||||
private Sip003Plugin(string plugin, string pluginOpts, List<string> pluginArgs, string serverAddress, int serverPort, bool showPluginOutput) | |||||
{ | { | ||||
if (plugin == null) throw new ArgumentNullException(nameof(plugin)); | if (plugin == null) throw new ArgumentNullException(nameof(plugin)); | ||||
if (string.IsNullOrWhiteSpace(serverAddress)) | if (string.IsNullOrWhiteSpace(serverAddress)) | ||||
@@ -52,24 +53,27 @@ namespace Shadowsocks.WPF.Services | |||||
throw new ArgumentOutOfRangeException("serverPort"); | throw new ArgumentOutOfRangeException("serverPort"); | ||||
} | } | ||||
_pluginProcess = new Process | |||||
var pluginProcessStartInfo = new ProcessStartInfo | |||||
{ | { | ||||
StartInfo = new ProcessStartInfo | |||||
{ | |||||
FileName = plugin, | |||||
Arguments = pluginArgs, | |||||
UseShellExecute = false, | |||||
CreateNoWindow = !showPluginOutput, | |||||
ErrorDialog = false, | |||||
WindowStyle = ProcessWindowStyle.Hidden, | |||||
WorkingDirectory = Utils.Utilities.WorkingDirectory ?? Environment.CurrentDirectory, | |||||
Environment = | |||||
FileName = plugin, | |||||
UseShellExecute = false, | |||||
CreateNoWindow = !showPluginOutput, | |||||
ErrorDialog = false, | |||||
WindowStyle = ProcessWindowStyle.Hidden, | |||||
WorkingDirectory = Utils.Utilities.WorkingDirectory ?? Environment.CurrentDirectory, | |||||
Environment = | |||||
{ | { | ||||
["SS_REMOTE_HOST"] = serverAddress, | ["SS_REMOTE_HOST"] = serverAddress, | ||||
["SS_REMOTE_PORT"] = serverPort.ToString(), | ["SS_REMOTE_PORT"] = serverPort.ToString(), | ||||
["SS_PLUGIN_OPTIONS"] = pluginOpts | ["SS_PLUGIN_OPTIONS"] = pluginOpts | ||||
} | } | ||||
} | |||||
}; | |||||
foreach (var arg in pluginArgs) | |||||
pluginProcessStartInfo.ArgumentList.Add(arg); | |||||
_pluginProcess = new Process() | |||||
{ | |||||
StartInfo = pluginProcessStartInfo, | |||||
}; | }; | ||||
} | } | ||||
@@ -5,14 +5,43 @@ namespace Shadowsocks.Models | |||||
{ | { | ||||
public interface IServer : IEquatable<IServer> | public interface IServer : IEquatable<IServer> | ||||
{ | { | ||||
/// <summary> | |||||
/// Gets or sets the server address. | |||||
/// </summary> | |||||
[JsonPropertyName("server")] | [JsonPropertyName("server")] | ||||
public string Host { get; set; } | public string Host { get; set; } | ||||
/// <summary> | |||||
/// Gets or sets the server port. | |||||
/// </summary> | |||||
[JsonPropertyName("server_port")] | [JsonPropertyName("server_port")] | ||||
public int Port { get; set; } | public int Port { get; set; } | ||||
/// <summary> | |||||
/// Gets or sets the password for the server. | |||||
/// </summary> | |||||
public string Password { get; set; } | public string Password { get; set; } | ||||
/// <summary> | |||||
/// Gets or sets the method used for the server. | |||||
/// </summary> | |||||
public string Method { get; set; } | public string Method { get; set; } | ||||
/// <summary> | |||||
/// Gets or sets the plugin executable filename. | |||||
/// </summary> | |||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] | |||||
public string Plugin { get; set; } | public string Plugin { get; set; } | ||||
/// <summary> | |||||
/// Gets or sets the plugin options passed as environment variables. | |||||
/// </summary> | |||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] | |||||
public string PluginOpts { get; set; } | public string PluginOpts { get; set; } | ||||
/// <summary> | |||||
/// Gets or sets the server name. | |||||
/// </summary> | |||||
[JsonPropertyName("remarks")] | [JsonPropertyName("remarks")] | ||||
public string Name { get; set; } | public string Name { get; set; } | ||||
} | } | ||||
@@ -7,16 +7,39 @@ namespace Shadowsocks.Models | |||||
{ | { | ||||
public class Server : IServer | public class Server : IServer | ||||
{ | { | ||||
/// <inheritdoc/> | |||||
[JsonPropertyName("server")] | [JsonPropertyName("server")] | ||||
public string Host { get; set; } | public string Host { get; set; } | ||||
/// <inheritdoc/> | |||||
[JsonPropertyName("server_port")] | [JsonPropertyName("server_port")] | ||||
public int Port { get; set; } | public int Port { get; set; } | ||||
/// <inheritdoc/> | |||||
public string Password { get; set; } | public string Password { get; set; } | ||||
/// <inheritdoc/> | |||||
public string Method { get; set; } | public string Method { get; set; } | ||||
/// <inheritdoc/> | |||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] | |||||
public string Plugin { get; set; } | public string Plugin { get; set; } | ||||
/// <inheritdoc/> | |||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] | |||||
public string PluginOpts { get; set; } | public string PluginOpts { get; set; } | ||||
/// <summary> | |||||
/// Gets or sets the arguments passed to the plugin process. | |||||
/// </summary> | |||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] | |||||
public List<string> PluginArgs { get; set; } | |||||
/// <inheritdoc/> | |||||
[JsonPropertyName("remarks")] | [JsonPropertyName("remarks")] | ||||
public string Name { get; set; } | public string Name { get; set; } | ||||
/// <inheritdoc/> | |||||
[JsonPropertyName("id")] | [JsonPropertyName("id")] | ||||
public string Uuid { get; set; } | public string Uuid { get; set; } | ||||
@@ -28,30 +51,11 @@ namespace Shadowsocks.Models | |||||
Method = "chacha20-ietf-poly1305"; | Method = "chacha20-ietf-poly1305"; | ||||
Plugin = ""; | Plugin = ""; | ||||
PluginOpts = ""; | PluginOpts = ""; | ||||
PluginArgs = new(); | |||||
Name = ""; | Name = ""; | ||||
Uuid = ""; | Uuid = ""; | ||||
} | } | ||||
public Server( | |||||
string name, | |||||
string uuid, | |||||
string host, | |||||
int port, | |||||
string password, | |||||
string method, | |||||
string plugin = "", | |||||
string pluginOpts = "") | |||||
{ | |||||
Host = host; | |||||
Port = port; | |||||
Password = password; | |||||
Method = method; | |||||
Plugin = plugin; | |||||
PluginOpts = pluginOpts; | |||||
Name = name; | |||||
Uuid = uuid; | |||||
} | |||||
public bool Equals(IServer? other) => other is Server anotherServer && Uuid == anotherServer.Uuid; | public bool Equals(IServer? other) => other is Server anotherServer && Uuid == anotherServer.Uuid; | ||||
public override int GetHashCode() => Uuid.GetHashCode(); | public override int GetHashCode() => Uuid.GetHashCode(); | ||||
public override string ToString() => Name; | public override string ToString() => Name; | ||||
@@ -95,7 +99,15 @@ namespace Shadowsocks.Models | |||||
var userinfoSplitArray = userinfo.Split(':', 2); | var userinfoSplitArray = userinfo.Split(':', 2); | ||||
var method = userinfoSplitArray[0]; | var method = userinfoSplitArray[0]; | ||||
var password = userinfoSplitArray[1]; | var password = userinfoSplitArray[1]; | ||||
server = new Server(uri.Fragment, new Guid().ToString(), uri.Host, uri.Port, password, method); | |||||
server = new Server() | |||||
{ | |||||
Name = uri.Fragment, | |||||
Uuid = new Guid().ToString(), | |||||
Host = uri.Host, | |||||
Port = uri.Port, | |||||
Password = password, | |||||
Method = method, | |||||
}; | |||||
// find the plugin query | // find the plugin query | ||||
var parsedQueriesArray = uri.Query.Split("?&"); | var parsedQueriesArray = uri.Query.Split("?&"); | ||||
var pluginQueryContent = ""; | var pluginQueryContent = ""; | ||||