@@ -26,35 +26,21 @@ namespace Shadowsocks.Controller.Service | |||||
httpClientHandler.Proxy = proxy; | httpClientHandler.Proxy = proxy; | ||||
} | } | ||||
try | |||||
{ | |||||
string str = await httpClient.GetStringAsync(url); | |||||
var ret = Get(str); | |||||
foreach (var item in ret) | |||||
{ | |||||
item.group = url; | |||||
} | |||||
return ret; | |||||
} | |||||
catch (Exception e) | |||||
_ = Task.Delay(2000).ContinueWith(_ => httpClient.CancelPendingRequests()); | |||||
string str = await httpClient.GetStringAsync(url); | |||||
var ret = Get(str); | |||||
foreach (var item in ret) | |||||
{ | { | ||||
logger.LogUsefulException(e); | |||||
return new List<Server>(); | |||||
item.group = url; | |||||
} | } | ||||
return ret; | |||||
} | } | ||||
public static List<Server> Get(string json) | public static List<Server> Get(string json) | ||||
{ | { | ||||
try | |||||
{ | |||||
var t = JToken.Parse(json); | |||||
return SearchJToken(t).ToList(); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
logger.LogUsefulException(e); | |||||
return new List<Server>(); | |||||
} | |||||
var t = JToken.Parse(json); | |||||
return SearchJToken(t).ToList(); | |||||
} | } | ||||
private static IEnumerable<Server> SearchJArray(JArray a) | private static IEnumerable<Server> SearchJArray(JArray a) | ||||
@@ -688,33 +688,56 @@ namespace Shadowsocks.Controller | |||||
#region SIP008 | #region SIP008 | ||||
public async Task UpdateOnlineConfig(string url) | |||||
public async Task<int> UpdateOnlineConfigInternal(string url) | |||||
{ | { | ||||
var selected = GetCurrentServer(); | |||||
var onlineServer = await OnlineConfigResolver.GetOnline(url, _config.WebProxy); | var onlineServer = await OnlineConfigResolver.GetOnline(url, _config.WebProxy); | ||||
_config.configs = Configuration.SortByOnlineConfig( | _config.configs = Configuration.SortByOnlineConfig( | ||||
_config.configs | _config.configs | ||||
.Where(c => c.group != url) | .Where(c => c.group != url) | ||||
.Concat(onlineServer) | .Concat(onlineServer) | ||||
); | ); | ||||
logger.Info($"updated {onlineServer.Count} server from {url}"); | |||||
return onlineServer.Count; | |||||
} | |||||
public async Task<bool> UpdateOnlineConfig(string url) | |||||
{ | |||||
var selected = GetCurrentServer(); | |||||
try | |||||
{ | |||||
int count = await UpdateOnlineConfigInternal(url); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
logger.LogUsefulException(e); | |||||
return false; | |||||
} | |||||
_config.index = _config.configs.IndexOf(selected); | _config.index = _config.configs.IndexOf(selected); | ||||
SaveConfig(_config); | SaveConfig(_config); | ||||
return true; | |||||
} | } | ||||
public async Task UpdateAllOnlineConfig() | |||||
public async Task<int> UpdateAllOnlineConfig() | |||||
{ | { | ||||
var selected = GetCurrentServer(); | var selected = GetCurrentServer(); | ||||
var r = await Task.WhenAll( | |||||
_config.onlineConfigSource.Select(url => OnlineConfigResolver.GetOnline(url, _config.WebProxy)) | |||||
); | |||||
var results = r.SelectMany(s => s); | |||||
_config.configs = Configuration.SortByOnlineConfig( | |||||
_config.configs | |||||
.Where(c => string.IsNullOrEmpty(c.group)) | |||||
.Concat(r.SelectMany(s => s)) | |||||
); | |||||
int failCount = 0; | |||||
foreach (var url in _config.onlineConfigSource) | |||||
{ | |||||
try | |||||
{ | |||||
await UpdateOnlineConfigInternal(url); | |||||
} | |||||
catch (Exception e) | |||||
{ | |||||
logger.LogUsefulException(e); | |||||
failCount++; | |||||
} | |||||
} | |||||
_config.index = _config.configs.IndexOf(selected); | _config.index = _config.configs.IndexOf(selected); | ||||
SaveConfig(_config); | SaveConfig(_config); | ||||
return failCount; | |||||
} | } | ||||
public void SaveOnlineConfigSource(IEnumerable<string> vs) | public void SaveOnlineConfigSource(IEnumerable<string> vs) | ||||
@@ -723,6 +746,15 @@ namespace Shadowsocks.Controller | |||||
SaveConfig(_config); | SaveConfig(_config); | ||||
} | } | ||||
public void RemoveOnlineConfig(string url) | |||||
{ | |||||
_config.onlineConfigSource.RemoveAll(v => v == url); | |||||
_config.configs = Configuration.SortByOnlineConfig( | |||||
_config.configs.Where(c => c.group != url) | |||||
); | |||||
SaveConfig(_config); | |||||
} | |||||
#endregion | #endregion | ||||
} | } | ||||
} | } |
@@ -123,7 +123,14 @@ namespace Shadowsocks | |||||
HotKeys.Init(MainController); | HotKeys.Init(MainController); | ||||
MainController.Start(); | MainController.Start(); | ||||
#region IPC Handler and Arguement Process | |||||
// Update online config | |||||
Task.Run(async () => | |||||
{ | |||||
await Task.Delay(10 * 1000); | |||||
await MainController.UpdateAllOnlineConfig(); | |||||
}); | |||||
#region IPC Handler and Arguement Process | |||||
IPCService ipcService = new IPCService(); | IPCService ipcService = new IPCService(); | ||||
Task.Run(() => ipcService.RunServer()); | Task.Run(() => ipcService.RunServer()); | ||||
ipcService.OpenUrlRequested += (_1, e) => MainController.AskAddServerBySSURL(e.Url); | ipcService.OpenUrlRequested += (_1, e) => MainController.AskAddServerBySSURL(e.Url); | ||||
@@ -132,7 +139,7 @@ namespace Shadowsocks | |||||
{ | { | ||||
MainController.AskAddServerBySSURL(Options.OpenUrl); | MainController.AskAddServerBySSURL(Options.OpenUrl); | ||||
} | } | ||||
#endregion | |||||
#endregion | |||||
Application.Run(); | Application.Run(); | ||||
@@ -153,6 +153,7 @@ | |||||
this.OkButton.TabIndex = 7; | this.OkButton.TabIndex = 7; | ||||
this.OkButton.Text = "OK"; | this.OkButton.Text = "OK"; | ||||
this.OkButton.UseVisualStyleBackColor = true; | this.OkButton.UseVisualStyleBackColor = true; | ||||
this.OkButton.Click += new System.EventHandler(this.OkButton_Click); | |||||
// | // | ||||
// UpdateAllButton | // UpdateAllButton | ||||
// | // | ||||
@@ -180,6 +181,7 @@ | |||||
this.CancelButton.TabIndex = 8; | this.CancelButton.TabIndex = 8; | ||||
this.CancelButton.Text = "Cancel"; | this.CancelButton.Text = "Cancel"; | ||||
this.CancelButton.UseVisualStyleBackColor = true; | this.CancelButton.UseVisualStyleBackColor = true; | ||||
this.CancelButton.Click += new System.EventHandler(this.CancelButton_Click); | |||||
// | // | ||||
// OnlineConfigForm | // OnlineConfigForm | ||||
// | // | ||||
@@ -188,7 +190,7 @@ | |||||
this.ClientSize = new System.Drawing.Size(488, 465); | this.ClientSize = new System.Drawing.Size(488, 465); | ||||
this.Controls.Add(this.tableLayoutPanel1); | this.Controls.Add(this.tableLayoutPanel1); | ||||
this.Name = "OnlineConfigForm"; | this.Name = "OnlineConfigForm"; | ||||
this.Text = "OnlineConfigForm"; | |||||
this.Text = "Online config"; | |||||
this.tableLayoutPanel1.ResumeLayout(false); | this.tableLayoutPanel1.ResumeLayout(false); | ||||
this.tableLayoutPanel1.PerformLayout(); | this.tableLayoutPanel1.PerformLayout(); | ||||
this.ResumeLayout(false); | this.ResumeLayout(false); | ||||
@@ -1,14 +1,10 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.ComponentModel; | |||||
using System.Data; | using System.Data; | ||||
using System.Drawing; | |||||
using System.Linq; | using System.Linq; | ||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
using System.Windows.Forms; | using System.Windows.Forms; | ||||
using Shadowsocks.Controller; | using Shadowsocks.Controller; | ||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Properties; | |||||
namespace Shadowsocks.View | namespace Shadowsocks.View | ||||
{ | { | ||||
@@ -17,13 +13,13 @@ namespace Shadowsocks.View | |||||
private ShadowsocksController controller; | private ShadowsocksController controller; | ||||
private Configuration config; | private Configuration config; | ||||
private const string DefaultPrefix = "http://www.baidu.com/"; | |||||
public OnlineConfigForm(ShadowsocksController controller) | public OnlineConfigForm(ShadowsocksController controller) | ||||
{ | { | ||||
this.controller = controller; | this.controller = controller; | ||||
InitializeComponent(); | InitializeComponent(); | ||||
LoadConfig(); | LoadConfig(); | ||||
Icon = System.Drawing.Icon.FromHandle(Resources.ssw128.GetHicon()); | |||||
I18N.TranslateForm(this); | |||||
} | } | ||||
private void LoadConfig() | private void LoadConfig() | ||||
@@ -38,6 +34,8 @@ namespace Shadowsocks.View | |||||
} | } | ||||
if (idx >= UrlListBox.Items.Count) idx = 0; | if (idx >= UrlListBox.Items.Count) idx = 0; | ||||
if (idx < 0 && UrlListBox.Items.Count > 0) idx = 0; | |||||
if (UrlListBox.Items.Count == 0) return; | |||||
UrlListBox.SelectedIndex = idx; | UrlListBox.SelectedIndex = idx; | ||||
SelectItem(); | SelectItem(); | ||||
} | } | ||||
@@ -53,6 +51,7 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
var scheme = new Uri(UrlTextBox.Text).Scheme; | var scheme = new Uri(UrlTextBox.Text).Scheme; | ||||
if (scheme != "http" && scheme != "https") return false; | if (scheme != "http" && scheme != "https") return false; | ||||
if (UrlListBox.Items.OfType<string>().Contains(UrlTextBox.Text)) return false; | |||||
} | } | ||||
catch | catch | ||||
{ | { | ||||
@@ -61,31 +60,47 @@ namespace Shadowsocks.View | |||||
return true; | return true; | ||||
} | } | ||||
private bool Commit() | |||||
private void Commit() | |||||
{ | { | ||||
if (UrlListBox.SelectedIndex < 0) return; | |||||
if ((string)UrlListBox.SelectedItem == UrlTextBox.Text) | |||||
{ | |||||
LoadConfig(); | |||||
return; | |||||
} | |||||
if (ValidateUrl()) | if (ValidateUrl()) | ||||
{ | { | ||||
UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; | UrlListBox.Items[UrlListBox.SelectedIndex] = UrlTextBox.Text; | ||||
} | } | ||||
controller.SaveOnlineConfigSource(UrlListBox.Items.OfType<string>().Where(s => !string.IsNullOrWhiteSpace(s))); | |||||
controller.SaveOnlineConfigSource(UrlListBox.Items.OfType<string>().Where(s => !string.IsNullOrWhiteSpace(s)).Distinct()); | |||||
LoadConfig(); | LoadConfig(); | ||||
return true; | |||||
return; | |||||
} | } | ||||
private void AddButton_Click(object sender, EventArgs e) | private void AddButton_Click(object sender, EventArgs e) | ||||
{ | { | ||||
if (string.IsNullOrWhiteSpace(UrlTextBox.Text)) return; | |||||
Commit(); | Commit(); | ||||
// string txt = UrlTextBox.Text; | |||||
UrlListBox.Items.Add(""); | UrlListBox.Items.Add(""); | ||||
UrlTextBox.Text = DefaultPrefix; | |||||
UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; | UrlListBox.SelectedIndex = UrlListBox.Items.Count - 1; | ||||
UrlTextBox.Text = ""; | |||||
} | } | ||||
private void UpdateButton_Click(object sender, EventArgs e) | |||||
private async void UpdateButton_Click(object sender, EventArgs e) | |||||
{ | { | ||||
// update content, also update online config | // update content, also update online config | ||||
Commit(); | Commit(); | ||||
_ = controller.UpdateOnlineConfig(UrlTextBox.Text); | |||||
if (UrlListBox.Items.Count == 0) return; | |||||
tableLayoutPanel1.Enabled = false; | |||||
bool ok = await controller.UpdateOnlineConfig((string)UrlListBox.SelectedItem); | |||||
if (!ok) | |||||
{ | |||||
MessageBox.Show(I18N.GetString("online config failed to update")); | |||||
} | |||||
tableLayoutPanel1.Enabled = true; | |||||
} | } | ||||
private void UrlListBox_SelectedIndexChanged(object sender, EventArgs e) | private void UrlListBox_SelectedIndexChanged(object sender, EventArgs e) | ||||
@@ -99,14 +114,36 @@ namespace Shadowsocks.View | |||||
private void DeleteButton_Click(object sender, EventArgs e) | private void DeleteButton_Click(object sender, EventArgs e) | ||||
{ | { | ||||
int idx = UrlListBox.SelectedIndex; | |||||
UrlListBox.Items.RemoveAt(idx); | |||||
if (UrlListBox.Items.Count == 0) return; | |||||
string url = (string)UrlListBox.SelectedItem; | |||||
if (!string.IsNullOrWhiteSpace(url)) | |||||
{ | |||||
controller.RemoveOnlineConfig(url); | |||||
} | |||||
LoadConfig(); | |||||
} | |||||
private async void UpdateAllButton_Click(object sender, EventArgs e) | |||||
{ | |||||
if (UrlListBox.Items.Count == 0) return; | |||||
tableLayoutPanel1.Enabled = false; | |||||
int fail = await controller.UpdateAllOnlineConfig(); | |||||
if (fail > 0) | |||||
{ | |||||
MessageBox.Show(I18N.GetString("{0} online config failed to update", fail)); | |||||
} | |||||
tableLayoutPanel1.Enabled = true; | |||||
} | |||||
private void OkButton_Click(object sender, EventArgs e) | |||||
{ | |||||
Commit(); | Commit(); | ||||
Close(); | |||||
} | } | ||||
private void UpdateAllButton_Click(object sender, EventArgs e) | |||||
private void CancelButton_Click(object sender, EventArgs e) | |||||
{ | { | ||||
_ = controller.UpdateAllOnlineConfig(); | |||||
Close(); | |||||
} | } | ||||
} | } | ||||
} | } |