@@ -371,7 +371,7 @@ namespace Shadowsocks.Controller | |||||
public string GetServerURLForCurrentServer() | public string GetServerURLForCurrentServer() | ||||
{ | { | ||||
return GetCurrentServer().URL; | |||||
return GetCurrentServer().GetURL(_config.generateLegacyUrl); | |||||
} | } | ||||
public void UpdatePACFromGeosite() | public void UpdatePACFromGeosite() | ||||
@@ -24,11 +24,13 @@ namespace Shadowsocks.Model | |||||
public bool enabled; | public bool enabled; | ||||
public bool shareOverLan; | public bool shareOverLan; | ||||
public bool isDefault; | public bool isDefault; | ||||
// hidden | |||||
public bool isIPv6Enabled = false; | public bool isIPv6Enabled = false; | ||||
public int localPort; | public int localPort; | ||||
public bool portableMode = true; | public bool portableMode = true; | ||||
public bool showPluginOutput; | public bool showPluginOutput; | ||||
public string pacUrl; | public string pacUrl; | ||||
// geosite config is hidden | |||||
public string geositeUrl; | public string geositeUrl; | ||||
public string geositeGroup = "geolocation-!cn"; | public string geositeGroup = "geolocation-!cn"; | ||||
public bool geositeBlacklistMode = true; | public bool geositeBlacklistMode = true; | ||||
@@ -39,6 +41,10 @@ namespace Shadowsocks.Model | |||||
public bool autoCheckUpdate; | public bool autoCheckUpdate; | ||||
public bool checkPreRelease; | public bool checkPreRelease; | ||||
public bool isVerboseLogging; | public bool isVerboseLogging; | ||||
// hidden config | |||||
public bool generateLegacyUrl = false; | |||||
//public NLogConfig.LogLevel logLevel; | //public NLogConfig.LogLevel logLevel; | ||||
public LogViewerConfig logViewer; | public LogViewerConfig logViewer; | ||||
public ProxyConfig proxy; | public ProxyConfig proxy; | ||||
@@ -56,47 +56,50 @@ namespace Shadowsocks.Model | |||||
: $"{remarks} ({serverStr})"; | : $"{remarks} ({serverStr})"; | ||||
} | } | ||||
public string URL | |||||
public string GetURL(bool legacyUrl = false) | |||||
{ | { | ||||
get | |||||
{ | |||||
string tag = string.Empty; | |||||
string url = string.Empty; | |||||
string tag = string.Empty; | |||||
string url = string.Empty; | |||||
if (string.IsNullOrWhiteSpace(plugin)) | |||||
{ | |||||
// For backwards compatiblity, if no plugin, use old url format | |||||
string parts = $"{method}:{password}@{server}:{server_port}"; | |||||
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); | |||||
url = base64; | |||||
} | |||||
else | |||||
if (legacyUrl && string.IsNullOrWhiteSpace(plugin)) | |||||
{ | |||||
// For backwards compatiblity, if no plugin, use old url format | |||||
string parts = $"{method}:{password}@{server}:{server_port}"; | |||||
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); | |||||
url = base64; | |||||
} | |||||
else | |||||
{ | |||||
// SIP002 | |||||
string parts = $"{method}:{password}"; | |||||
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); | |||||
string websafeBase64 = base64.Replace('+', '-').Replace('/', '_').TrimEnd('='); | |||||
url = string.Format( | |||||
"{0}@{1}:{2}/", | |||||
websafeBase64, | |||||
FormalHostName, | |||||
server_port | |||||
); | |||||
if (!plugin.IsNullOrWhiteSpace()) | |||||
{ | { | ||||
// SIP002 | |||||
string parts = $"{method}:{password}"; | |||||
string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); | |||||
string websafeBase64 = base64.Replace('+', '-').Replace('/', '_').TrimEnd('='); | |||||
string pluginPart = plugin; | string pluginPart = plugin; | ||||
if (!string.IsNullOrWhiteSpace(plugin_opts)) | if (!string.IsNullOrWhiteSpace(plugin_opts)) | ||||
{ | { | ||||
pluginPart += ";" + plugin_opts; | pluginPart += ";" + plugin_opts; | ||||
} | } | ||||
url = string.Format( | |||||
"{0}@{1}:{2}/?plugin={3}", | |||||
websafeBase64, | |||||
FormalHostName, | |||||
server_port, | |||||
HttpUtility.UrlEncode(pluginPart, Encoding.UTF8)); | |||||
string pluginQuery = "?plugin=" + HttpUtility.UrlEncode(pluginPart, Encoding.UTF8); | |||||
url += pluginQuery; | |||||
} | } | ||||
} | |||||
if (!remarks.IsNullOrEmpty()) | |||||
{ | |||||
tag = $"#{HttpUtility.UrlEncode(remarks, Encoding.UTF8)}"; | |||||
} | |||||
return $"ss://{url}{tag}"; | |||||
if (!remarks.IsNullOrEmpty()) | |||||
{ | |||||
tag = $"#{HttpUtility.UrlEncode(remarks, Encoding.UTF8)}"; | |||||
} | } | ||||
return $"ss://{url}{tag}"; | |||||
} | } | ||||
public string FormalHostName | public string FormalHostName | ||||
@@ -64,14 +64,14 @@ namespace Shadowsocks.View | |||||
private void QRCodeForm_Load(object sender, EventArgs e) | private void QRCodeForm_Load(object sender, EventArgs e) | ||||
{ | { | ||||
var servers = Configuration.Load(); | |||||
var serverDatas = servers.configs.Select( | |||||
Configuration config = Configuration.Load(); | |||||
List<KeyValuePair<string, string>> serverDatas = config.configs.Select( | |||||
server => | server => | ||||
new KeyValuePair<string, string>(server.URL, server.ToString()) | |||||
new KeyValuePair<string, string>(server.GetURL(config.generateLegacyUrl), server.ToString()) | |||||
).ToList(); | ).ToList(); | ||||
listBox1.DataSource = serverDatas; | listBox1.DataSource = serverDatas; | ||||
var selectIndex = serverDatas.FindIndex(serverData => serverData.Key.StartsWith(code)); | |||||
int selectIndex = serverDatas.FindIndex(serverData => serverData.Key.StartsWith(code)); | |||||
if (selectIndex >= 0) listBox1.SetSelected(selectIndex, true); | if (selectIndex >= 0) listBox1.SetSelected(selectIndex, true); | ||||
} | } | ||||
@@ -243,7 +243,7 @@ namespace Shadowsocks.Test | |||||
string expected = testCase.Key; | string expected = testCase.Key; | ||||
Server config = testCase.Value; | Server config = testCase.Value; | ||||
var actual = config.URL; | |||||
var actual = config.GetURL(true); | |||||
Assert.AreEqual(expected, actual); | Assert.AreEqual(expected, actual); | ||||
} | } | ||||
} | } | ||||