@@ -10,6 +10,9 @@ using System.Net.Sockets; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using Newtonsoft.Json; | |||
using Newtonsoft.Json.Linq; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Util; | |||
@@ -32,7 +35,7 @@ namespace Shadowsocks.Controller | |||
public static readonly DateTime UnknownDateTime = new DateTime(1970, 1, 1); | |||
private int Repeat => _config.RepeatTimesNum; | |||
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 State _state; | |||
private List<Server> _servers; | |||
@@ -107,11 +110,18 @@ namespace Shadowsocks.Controller | |||
Logging.LogUsefulException(e); | |||
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; | |||
return new DataList { | |||
new DataUnit(State.Geolocation, $"\"{country} {city}\""), | |||
@@ -252,24 +262,24 @@ namespace Shadowsocks.Controller | |||
_timer.Change(RetryInterval, Interval); | |||
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); | |||
} | |||
catch (Exception e) | |||
@@ -4,6 +4,8 @@ using System.IO; | |||
using System.Net; | |||
using System.Text; | |||
using Newtonsoft.Json; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
using Shadowsocks.Util; | |||
@@ -60,8 +62,8 @@ namespace Shadowsocks.Controller | |||
{ | |||
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); | |||
if (original == abpContent) | |||
@@ -3,7 +3,7 @@ using System.Collections.Generic; | |||
using System.Net; | |||
using System.Text.RegularExpressions; | |||
using SimpleJson; | |||
using Newtonsoft.Json.Linq; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Util; | |||
@@ -23,7 +23,7 @@ namespace Shadowsocks.Controller | |||
public string LatestVersionLocalName; | |||
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 | |||
{ | |||
@@ -76,26 +76,28 @@ namespace Shadowsocks.Controller | |||
{ | |||
string response = e.Result; | |||
JsonArray result = (JsonArray)SimpleJson.SimpleJson.DeserializeObject(e.Result); | |||
JArray result = JArray.Parse(response); | |||
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) | |||
{ | |||
SortByVersions(asserts); | |||
@@ -191,7 +193,7 @@ namespace Shadowsocks.Controller | |||
return CompareVersion(version, currentVersion) > 0; | |||
} | |||
public void Parse(JsonObject asset) | |||
public void Parse(JObject asset) | |||
{ | |||
name = (string)asset["name"]; | |||
browser_download_url = (string)asset["browser_download_url"]; | |||
@@ -6,6 +6,8 @@ using System.Net.Sockets; | |||
using System.Text; | |||
using System.Threading; | |||
using Newtonsoft.Json; | |||
using Shadowsocks.Controller.Strategy; | |||
using Shadowsocks.Model; | |||
using Shadowsocks.Properties; | |||
@@ -4,7 +4,9 @@ using System.Linq; | |||
using System.Net; | |||
using System.Net.NetworkInformation; | |||
using System.Threading; | |||
using Newtonsoft.Json; | |||
using Shadowsocks.Model; | |||
namespace Shadowsocks.Controller.Strategy | |||
@@ -147,6 +149,5 @@ namespace Shadowsocks.Controller.Strategy | |||
{ | |||
//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.IO; | |||
using System.Text; | |||
using System.Windows.Forms; | |||
using SimpleJson; | |||
using Shadowsocks.Controller; | |||
using Newtonsoft.Json; | |||
namespace Shadowsocks.Model | |||
{ | |||
@@ -53,7 +52,7 @@ namespace Shadowsocks.Model | |||
try | |||
{ | |||
string configContent = File.ReadAllText(CONFIG_FILE); | |||
Configuration config = SimpleJson.SimpleJson.DeserializeObject<Configuration>(configContent, new JsonSerializerStrategy()); | |||
Configuration config = JsonConvert.DeserializeObject<Configuration>(configContent); | |||
config.isDefault = false; | |||
if (config.localPort == 0) | |||
{ | |||
@@ -110,7 +109,7 @@ namespace Shadowsocks.Model | |||
{ | |||
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.Flush(); | |||
} | |||
@@ -166,19 +165,5 @@ namespace Shadowsocks.Model | |||
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.Collections.Generic; | |||
using System.Text; | |||
using System.IO; | |||
using System.Diagnostics; | |||
using SimpleJson; | |||
using Shadowsocks.Controller; | |||
using System.Text.RegularExpressions; | |||
using Shadowsocks.Controller; | |||
namespace Shadowsocks.Model | |||
{ | |||
[Serializable] | |||
@@ -2,16 +2,15 @@ | |||
using System.Collections.Generic; | |||
using System.Data; | |||
using System.Linq; | |||
using System.Net.NetworkInformation; | |||
using System.Windows.Forms; | |||
using System.Windows.Forms.DataVisualization.Charting; | |||
using Shadowsocks.Controller; | |||
using Shadowsocks.Model; | |||
using SimpleJson; | |||
using System.Net.NetworkInformation; | |||
namespace Shadowsocks.View | |||
{ | |||
public partial class StatisticsStrategyConfigurationForm: Form | |||
public partial class StatisticsStrategyConfigurationForm : Form | |||
{ | |||
private readonly ShadowsocksController _controller; | |||
private StatisticsStrategyConfiguration _configuration; | |||
@@ -51,9 +50,9 @@ namespace Shadowsocks.View | |||
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"].YValueMembers = "Package Loss"; | |||
@@ -64,7 +63,6 @@ namespace Shadowsocks.View | |||
StatisticsChart.DataBind(); | |||
} | |||
private void CancelButton_Click(object sender, EventArgs e) | |||
{ | |||
Close(); | |||
@@ -48,6 +48,7 @@ | |||
<ErrorReport>prompt</ErrorReport> | |||
<CodeAnalysisRuleSet>ManagedMinimumRules.ruleset</CodeAnalysisRuleSet> | |||
<Prefer32Bit>false</Prefer32Bit> | |||
<Optimize>false</Optimize> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> | |||
<OutputPath>bin\x86\Release\</OutputPath> | |||
@@ -169,7 +170,6 @@ | |||
<Compile Include="3rd\zxing\qrcode\encoder\MaskUtil.cs" /> | |||
<Compile Include="3rd\zxing\qrcode\encoder\MatrixUtil.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\Result.cs" /> | |||
<Compile Include="3rd\zxing\ResultMetadataType.cs" /> | |||