@@ -10,6 +10,9 @@ using System.Net.Sockets; | |||||
using System.Threading; | using System.Threading; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using Newtonsoft.Json; | |||||
using Newtonsoft.Json.Linq; | |||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Util; | using Shadowsocks.Util; | ||||
@@ -32,7 +35,7 @@ namespace Shadowsocks.Controller | |||||
public static readonly DateTime UnknownDateTime = new DateTime(1970, 1, 1); | public static readonly DateTime UnknownDateTime = new DateTime(1970, 1, 1); | ||||
private int Repeat => _config.RepeatTimesNum; | private int Repeat => _config.RepeatTimesNum; | ||||
private const int RetryInterval = 2 * 60 * 1000; //retry 2 minutes after failed | private const int RetryInterval = 2 * 60 * 1000; //retry 2 minutes after failed | ||||
private int Interval => (int)TimeSpan.FromMinutes(_config.DataCollectionMinutes).TotalMilliseconds; | |||||
private int Interval => (int)TimeSpan.FromMinutes(_config.DataCollectionMinutes).TotalMilliseconds; | |||||
private Timer _timer; | private Timer _timer; | ||||
private State _state; | private State _state; | ||||
private List<Server> _servers; | private List<Server> _servers; | ||||
@@ -107,11 +110,18 @@ namespace Shadowsocks.Controller | |||||
Logging.LogUsefulException(e); | Logging.LogUsefulException(e); | ||||
return null; | return null; | ||||
} | } | ||||
dynamic obj; | |||||
if (!SimpleJson.SimpleJson.TryDeserializeObject(jsonString, out obj)) return null; | |||||
string country = obj["country"]; | |||||
string city = obj["city"]; | |||||
string isp = obj["isp"]; | |||||
JObject obj; | |||||
try | |||||
{ | |||||
obj = JObject.Parse(jsonString); | |||||
} | |||||
catch (JsonReaderException) | |||||
{ | |||||
return null; | |||||
} | |||||
string country = (string)obj["country"]; | |||||
string city = (string)obj["city"]; | |||||
string isp = (string)obj["isp"]; | |||||
if (country == null || city == null || isp == null) return null; | if (country == null || city == null || isp == null) return null; | ||||
return new DataList { | return new DataList { | ||||
new DataUnit(State.Geolocation, $"\"{country} {city}\""), | new DataUnit(State.Geolocation, $"\"{country} {city}\""), | ||||
@@ -252,24 +262,24 @@ namespace Shadowsocks.Controller | |||||
_timer.Change(RetryInterval, Interval); | _timer.Change(RetryInterval, Interval); | ||||
return; | return; | ||||
} | } | ||||
RawStatistics = (from l in File.ReadAllLines(path).Skip(1) | |||||
let strings = l.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) | |||||
let rawData = new RawStatisticsData | |||||
{ | |||||
Timestamp = ParseExactOrUnknown(strings[0]), | |||||
ServerName = strings[1], | |||||
ICMPStatus = strings[2], | |||||
RoundtripTime = int.Parse(strings[3]), | |||||
Geolocation = 5 > strings.Length ? | |||||
null | |||||
: strings[4], | |||||
ISP = 6 > strings.Length ? null : strings[5] | |||||
} | |||||
group rawData by rawData.ServerName into server | |||||
select new | |||||
{ | |||||
ServerName = server.Key, | |||||
data = server.ToList() | |||||
RawStatistics = (from l in File.ReadAllLines(path).Skip(1) | |||||
let strings = l.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries) | |||||
let rawData = new RawStatisticsData | |||||
{ | |||||
Timestamp = ParseExactOrUnknown(strings[0]), | |||||
ServerName = strings[1], | |||||
ICMPStatus = strings[2], | |||||
RoundtripTime = int.Parse(strings[3]), | |||||
Geolocation = 5 > strings.Length ? | |||||
null | |||||
: strings[4], | |||||
ISP = 6 > strings.Length ? null : strings[5] | |||||
} | |||||
group rawData by rawData.ServerName into server | |||||
select new | |||||
{ | |||||
ServerName = server.Key, | |||||
data = server.ToList() | |||||
}).ToDictionary(server => server.ServerName, server => server.data); | }).ToDictionary(server => server.ServerName, server => server.data); | ||||
} | } | ||||
catch (Exception e) | catch (Exception e) | ||||
@@ -4,6 +4,8 @@ using System.IO; | |||||
using System.Net; | using System.Net; | ||||
using System.Text; | using System.Text; | ||||
using Newtonsoft.Json; | |||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Properties; | using Shadowsocks.Properties; | ||||
using Shadowsocks.Util; | using Shadowsocks.Util; | ||||
@@ -60,8 +62,8 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
abpContent = Utils.UnGzip(Resources.abp_js); | abpContent = Utils.UnGzip(Resources.abp_js); | ||||
} | } | ||||
abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines)); | |||||
if (File.Exists(PAC_FILE)) | |||||
abpContent = abpContent.Replace("__RULES__", JsonConvert.SerializeObject(lines, Formatting.Indented)); | |||||
if (File.Exists(PACServer.PAC_FILE)) | |||||
{ | { | ||||
string original = File.ReadAllText(PAC_FILE, Encoding.UTF8); | string original = File.ReadAllText(PAC_FILE, Encoding.UTF8); | ||||
if (original == abpContent) | if (original == abpContent) | ||||
@@ -3,7 +3,7 @@ using System.Collections.Generic; | |||||
using System.Net; | using System.Net; | ||||
using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||
using SimpleJson; | |||||
using Newtonsoft.Json.Linq; | |||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Util; | using Shadowsocks.Util; | ||||
@@ -23,7 +23,7 @@ namespace Shadowsocks.Controller | |||||
public string LatestVersionLocalName; | public string LatestVersionLocalName; | ||||
public event EventHandler CheckUpdateCompleted; | public event EventHandler CheckUpdateCompleted; | ||||
public const string Version = "2.5.8"; | |||||
public const string Version = "2.5.8.1"; | |||||
private class CheckUpdateTimer : System.Timers.Timer | private class CheckUpdateTimer : System.Timers.Timer | ||||
{ | { | ||||
@@ -76,26 +76,28 @@ namespace Shadowsocks.Controller | |||||
{ | { | ||||
string response = e.Result; | string response = e.Result; | ||||
JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result); | |||||
JArray result = JArray.Parse(response); | |||||
List<Asset> asserts = new List<Asset>(); | List<Asset> asserts = new List<Asset>(); | ||||
foreach (JsonObject release in result) | |||||
if (result != null) | |||||
{ | { | ||||
if ((bool)release["prerelease"]) | |||||
foreach (JObject release in result) | |||||
{ | { | ||||
continue; | |||||
} | |||||
foreach (JsonObject asset in (JsonArray)release["assets"]) | |||||
{ | |||||
Asset ass = new Asset(); | |||||
ass.Parse(asset); | |||||
if (ass.IsNewVersion(Version)) | |||||
if ((bool)release["prerelease"]) | |||||
{ | { | ||||
asserts.Add(ass); | |||||
continue; | |||||
} | |||||
foreach (JObject asset in (JArray)release["assets"]) | |||||
{ | |||||
Asset ass = new Asset(); | |||||
ass.Parse(asset); | |||||
if (ass.IsNewVersion(Version)) | |||||
{ | |||||
asserts.Add(ass); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (asserts.Count != 0) | if (asserts.Count != 0) | ||||
{ | { | ||||
SortByVersions(asserts); | SortByVersions(asserts); | ||||
@@ -191,7 +193,7 @@ namespace Shadowsocks.Controller | |||||
return CompareVersion(version, currentVersion) > 0; | return CompareVersion(version, currentVersion) > 0; | ||||
} | } | ||||
public void Parse(JsonObject asset) | |||||
public void Parse(JObject asset) | |||||
{ | { | ||||
name = (string)asset["name"]; | name = (string)asset["name"]; | ||||
browser_download_url = (string)asset["browser_download_url"]; | browser_download_url = (string)asset["browser_download_url"]; | ||||
@@ -6,6 +6,8 @@ using System.Net.Sockets; | |||||
using System.Text; | using System.Text; | ||||
using System.Threading; | using System.Threading; | ||||
using Newtonsoft.Json; | |||||
using Shadowsocks.Controller.Strategy; | using Shadowsocks.Controller.Strategy; | ||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using Shadowsocks.Properties; | using Shadowsocks.Properties; | ||||
@@ -4,7 +4,9 @@ using System.Linq; | |||||
using System.Net; | using System.Net; | ||||
using System.Net.NetworkInformation; | using System.Net.NetworkInformation; | ||||
using System.Threading; | using System.Threading; | ||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
namespace Shadowsocks.Controller.Strategy | namespace Shadowsocks.Controller.Strategy | ||||
@@ -147,6 +149,5 @@ namespace Shadowsocks.Controller.Strategy | |||||
{ | { | ||||
//TODO: combine this part of data with ICMP statics | //TODO: combine this part of data with ICMP statics | ||||
} | } | ||||
} | } | ||||
} | } |
@@ -1,10 +1,9 @@ | |||||
using Shadowsocks.Controller; | |||||
using System; | |||||
using System; | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.IO; | using System.IO; | ||||
using System.Text; | |||||
using System.Windows.Forms; | |||||
using SimpleJson; | |||||
using Shadowsocks.Controller; | |||||
using Newtonsoft.Json; | |||||
namespace Shadowsocks.Model | namespace Shadowsocks.Model | ||||
{ | { | ||||
@@ -53,7 +52,7 @@ namespace Shadowsocks.Model | |||||
try | try | ||||
{ | { | ||||
string configContent = File.ReadAllText(CONFIG_FILE); | string configContent = File.ReadAllText(CONFIG_FILE); | ||||
Configuration config = SimpleJson.SimpleJson.DeserializeObject<Configuration>(configContent, new JsonSerializerStrategy()); | |||||
Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent); | |||||
config.isDefault = false; | config.isDefault = false; | ||||
if (config.localPort == 0) | if (config.localPort == 0) | ||||
{ | { | ||||
@@ -110,7 +109,7 @@ namespace Shadowsocks.Model | |||||
{ | { | ||||
using (StreamWriter sw = new StreamWriter(File.Open(CONFIG_FILE, FileMode.Create))) | using (StreamWriter sw = new StreamWriter(File.Open(CONFIG_FILE, FileMode.Create))) | ||||
{ | { | ||||
string jsonString = SimpleJson.SimpleJson.SerializeObject(config); | |||||
string jsonString = JsonConvert.SerializeObject(config, Formatting.Indented); | |||||
sw.Write(jsonString); | sw.Write(jsonString); | ||||
sw.Flush(); | sw.Flush(); | ||||
} | } | ||||
@@ -166,19 +165,5 @@ namespace Shadowsocks.Model | |||||
throw new ArgumentException(I18N.GetString("Server IP can not be blank")); | throw new ArgumentException(I18N.GetString("Server IP can not be blank")); | ||||
} | } | ||||
} | } | ||||
// internal class | |||||
private class JsonSerializerStrategy : SimpleJson.PocoJsonSerializerStrategy | |||||
{ | |||||
// convert string to int | |||||
public override object DeserializeObject(object value, Type type) | |||||
{ | |||||
if (type == typeof(Int32) && value.GetType() == typeof(string)) | |||||
{ | |||||
return Int32.Parse(value.ToString()); | |||||
} | |||||
return base.DeserializeObject(value, type); | |||||
} | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,12 +1,9 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Text; | using System.Text; | ||||
using System.IO; | |||||
using System.Diagnostics; | |||||
using SimpleJson; | |||||
using Shadowsocks.Controller; | |||||
using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||
using Shadowsocks.Controller; | |||||
namespace Shadowsocks.Model | namespace Shadowsocks.Model | ||||
{ | { | ||||
[Serializable] | [Serializable] | ||||
@@ -2,16 +2,15 @@ | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Data; | using System.Data; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Net.NetworkInformation; | |||||
using System.Windows.Forms; | using System.Windows.Forms; | ||||
using System.Windows.Forms.DataVisualization.Charting; | |||||
using Shadowsocks.Controller; | using Shadowsocks.Controller; | ||||
using Shadowsocks.Model; | using Shadowsocks.Model; | ||||
using SimpleJson; | |||||
using System.Net.NetworkInformation; | |||||
namespace Shadowsocks.View | namespace Shadowsocks.View | ||||
{ | { | ||||
public partial class StatisticsStrategyConfigurationForm: Form | |||||
public partial class StatisticsStrategyConfigurationForm : Form | |||||
{ | { | ||||
private readonly ShadowsocksController _controller; | private readonly ShadowsocksController _controller; | ||||
private StatisticsStrategyConfiguration _configuration; | private StatisticsStrategyConfiguration _configuration; | ||||
@@ -51,9 +50,9 @@ namespace Shadowsocks.View | |||||
serverSelector.DataSource = _servers; | serverSelector.DataSource = _servers; | ||||
_dataTable.Columns.Add("Timestamp", typeof (DateTime)); | |||||
_dataTable.Columns.Add("Package Loss", typeof (int)); | |||||
_dataTable.Columns.Add("Ping", typeof (int)); | |||||
_dataTable.Columns.Add("Timestamp", typeof(DateTime)); | |||||
_dataTable.Columns.Add("Package Loss", typeof(int)); | |||||
_dataTable.Columns.Add("Ping", typeof(int)); | |||||
StatisticsChart.Series["Package Loss"].XValueMember = "Timestamp"; | StatisticsChart.Series["Package Loss"].XValueMember = "Timestamp"; | ||||
StatisticsChart.Series["Package Loss"].YValueMembers = "Package Loss"; | StatisticsChart.Series["Package Loss"].YValueMembers = "Package Loss"; | ||||
@@ -64,7 +63,6 @@ namespace Shadowsocks.View | |||||
StatisticsChart.DataBind(); | StatisticsChart.DataBind(); | ||||
} | } | ||||
private void CancelButton_Click(object sender, EventArgs e) | private void CancelButton_Click(object sender, EventArgs e) | ||||
{ | { | ||||
Close(); | Close(); | ||||
@@ -48,6 +48,7 @@ | |||||
<ErrorReport>prompt</ErrorReport> | <ErrorReport>prompt</ErrorReport> | ||||
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet> | <CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet> | ||||
<Prefer32Bit>false</Prefer32Bit> | <Prefer32Bit>false</Prefer32Bit> | ||||
<Optimize>false</Optimize> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> | ||||
<OutputPath>bin\x86\Release\</OutputPath> | <OutputPath>bin\x86\Release\</OutputPath> | ||||
@@ -169,7 +170,6 @@ | |||||
<Compile Include="3rd\zxing\qrcode\encoder\MaskUtil.cs" /> | <Compile Include="3rd\zxing\qrcode\encoder\MaskUtil.cs" /> | ||||
<Compile Include="3rd\zxing\qrcode\encoder\MatrixUtil.cs" /> | <Compile Include="3rd\zxing\qrcode\encoder\MatrixUtil.cs" /> | ||||
<Compile Include="3rd\zxing\qrcode\encoder\QRCode.cs" /> | <Compile Include="3rd\zxing\qrcode\encoder\QRCode.cs" /> | ||||
<Compile Include="3rd\SimpleJson.cs" /> | |||||
<Compile Include="3rd\zxing\qrcode\QRCodeReader.cs" /> | <Compile Include="3rd\zxing\qrcode\QRCodeReader.cs" /> | ||||
<Compile Include="3rd\zxing\Result.cs" /> | <Compile Include="3rd\zxing\Result.cs" /> | ||||
<Compile Include="3rd\zxing\ResultMetadataType.cs" /> | <Compile Include="3rd\zxing\ResultMetadataType.cs" /> | ||||