diff --git a/shadowsocks-csharp/Controller/FileManager.cs b/shadowsocks-csharp/Controller/FileManager.cs index cc8f3bf9..7c681f9c 100755 --- a/shadowsocks-csharp/Controller/FileManager.cs +++ b/shadowsocks-csharp/Controller/FileManager.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.IO; using System.IO.Compression; -using System.Text; namespace Shadowsocks.Controller { @@ -12,9 +10,7 @@ namespace Shadowsocks.Controller { try { - System.IO.FileStream _FileStream = - new System.IO.FileStream(fileName, System.IO.FileMode.Create, - System.IO.FileAccess.Write); + FileStream _FileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write); _FileStream.Write(content, 0, content.Length); _FileStream.Close(); return true; @@ -31,7 +27,7 @@ namespace Shadowsocks.Controller { FileStream destinationFile = File.Create(fileName); - // Because the uncompressed size of the file is unknown, + // Because the uncompressed size of the file is unknown, // we are using an arbitrary buffer size. byte[] buffer = new byte[4096]; int n; @@ -39,17 +35,33 @@ namespace Shadowsocks.Controller using (GZipStream input = new GZipStream(new MemoryStream(content), CompressionMode.Decompress, false)) { - while (true) + while ((n = input.Read(buffer, 0, buffer.Length)) > 0) { - n = input.Read(buffer, 0, buffer.Length); - if (n == 0) - { - break; - } destinationFile.Write(buffer, 0, n); } } destinationFile.Close(); } + + public static void CompressFile(string fileName, byte[] content) + { + FileStream destinationFile = File.Create(fileName); + MemoryStream ms = new MemoryStream(content); + + // Because the compressed size of the file is unknown, + // we are using an arbitrary buffer size. + byte[] buffer = new byte[4096]; + int n; + + using (GZipStream output = new GZipStream(destinationFile, + CompressionMode.Compress, false)) + { + while ((n = ms.Read(buffer, 0, buffer.Length)) > 0) + { + output.Write(buffer, 0, n); + } + } + destinationFile.Close(); + } } } diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs index 38201660..aa06c24e 100755 --- a/shadowsocks-csharp/Controller/Logging.cs +++ b/shadowsocks-csharp/Controller/Logging.cs @@ -9,18 +9,29 @@ namespace Shadowsocks.Controller { public class Logging { - public static string LogFile; + public static string LogFilePath; + private static DateTime LogFileCreationTime; public static bool OpenLogFile() { try { - LogFile = Utils.GetTempPath("shadowsocks.log"); - FileStream fs = new FileStream(LogFile, FileMode.Append); - StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs); - sw.AutoFlush = true; - Console.SetOut(sw); - Console.SetError(sw); + LogFilePath = Utils.GetTempPath("shadowsocks.log"); + + if (!File.Exists(LogFilePath)) + using (File.Create(LogFilePath)) { } + LogFileCreationTime = File.GetCreationTime(LogFilePath); + + if ((DateTime.Now - LogFileCreationTime).Days >= 1) + RollLogFile(); + else + { + FileStream fs = new FileStream(LogFilePath, FileMode.Append); + StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs); + sw.AutoFlush = true; + Console.SetOut(sw); + Console.SetError(sw); + } return true; } @@ -31,20 +42,53 @@ namespace Shadowsocks.Controller } } + private static void RollLogFile() + { + Console.Out.Close(); + Console.Error.Close(); + + MemoryStream ms = new MemoryStream(); + StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(ms); + sw.AutoFlush = true; + Console.SetOut(sw); + Console.SetError(sw); + + byte[] logContents = File.ReadAllBytes(LogFilePath); + string datestr = DateTime.Now.AddDays(-1).ToString("yyyyMMdd"); + string filepath = Utils.GetTempPath($"shadowsocks.{datestr}.log.zip"); + FileManager.CompressFile(filepath, logContents); + + File.Delete(LogFilePath); + FileStream fs = new FileStream(LogFilePath, FileMode.CreateNew); + LogFileCreationTime = DateTime.Now; + ms.CopyTo(fs); + StreamWriterWithTimestamp sw2 = new StreamWriterWithTimestamp(fs); + sw2.AutoFlush = true; + Console.SetOut(sw2); + Console.SetError(sw2); + } + + private static void WriteToLogFile(object o) + { + if ((DateTime.Now - LogFileCreationTime).Days >= 1) + RollLogFile(); + Console.WriteLine(o); + } + public static void Error(object o) { - Console.WriteLine("[E] " + o); + WriteToLogFile("[E] " + o); } public static void Info(object o) { - Console.WriteLine(o); + WriteToLogFile(o); } public static void Debug(object o) { #if DEBUG - Console.WriteLine("[D] " + o); + WriteToLogFile("[D] " + o); #endif } diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs index 5db8b64a..c6853331 100644 --- a/shadowsocks-csharp/Controller/Service/PACServer.cs +++ b/shadowsocks-csharp/Controller/Service/PACServer.cs @@ -147,7 +147,7 @@ Connection: Close ", Encoding.UTF8.GetBytes(pac).Length) + pac; byte[] response = Encoding.UTF8.GetBytes(text); socket.BeginSend(response, 0, response.Length, 0, new AsyncCallback(SendCallback), socket); - Util.Utils.ReleaseMemory(true); + Utils.ReleaseMemory(true); } catch (Exception e) { diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs index da8a5f83..4701f2d5 100644 --- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs +++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs @@ -23,7 +23,7 @@ namespace Shadowsocks.Controller public string LatestVersionLocalName; public event EventHandler CheckUpdateCompleted; - public const string Version = "2.5.8.1"; + public const string Version = "2.5.8.2"; private class CheckUpdateTimer : System.Timers.Timer { diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs index 982d6237..356f58cb 100755 --- a/shadowsocks-csharp/Controller/ShadowsocksController.cs +++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs @@ -63,6 +63,8 @@ namespace Shadowsocks.Controller public ShadowsocksController() { _config = Configuration.Load(); + inboundCounter = _config.GetCurrentServer().bandwidthIn; + outboundCounter = _config.GetCurrentServer().bandwidthOut; StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); _strategyManager = new StrategyManager(this); StartReleasingMemory(); @@ -253,7 +255,7 @@ namespace Shadowsocks.Controller public static string GetQRCode(Server server) { string parts = server.method + ":" + server.password + "@" + server.server + ":" + server.server_port; - string base64 = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); + string base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(parts)); return "ss://" + base64; } @@ -310,17 +312,21 @@ namespace Shadowsocks.Controller public void UpdateInboundCounter(long n) { Interlocked.Add(ref inboundCounter, n); + _config.GetCurrentServer().bandwidthIn = inboundCounter; } public void UpdateOutboundCounter(long n) { Interlocked.Add(ref outboundCounter, n); + _config.GetCurrentServer().bandwidthOut = outboundCounter; } protected void Reload() { // some logic in configuration updated the config when saving, we need to read it again _config = Configuration.Load(); + inboundCounter = _config.GetCurrentServer().bandwidthIn; + outboundCounter = _config.GetCurrentServer().bandwidthOut; StatisticsConfiguration = StatisticsStrategyConfiguration.Load(); if (polipoRunner == null) @@ -398,7 +404,7 @@ namespace Shadowsocks.Controller } UpdateSystemProxy(); - Util.Utils.ReleaseMemory(true); + Utils.ReleaseMemory(true); } protected void SaveConfig(Configuration newConfig) @@ -494,7 +500,7 @@ namespace Shadowsocks.Controller { while (true) { - Util.Utils.ReleaseMemory(false); + Utils.ReleaseMemory(false); Thread.Sleep(30 * 1000); } } diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs index 66fab2f4..d65c23a9 100755 --- a/shadowsocks-csharp/Model/Configuration.cs +++ b/shadowsocks-csharp/Model/Configuration.cs @@ -31,13 +31,9 @@ namespace Shadowsocks.Model public Server GetCurrentServer() { if (index >= 0 && index < configs.Count) - { return configs[index]; - } else - { return GetDefaultServer(); - } } public static void CheckServer(Server server) @@ -55,24 +51,15 @@ namespace Shadowsocks.Model Configuration config = JsonConvert.DeserializeObject(configContent); config.isDefault = false; if (config.localPort == 0) - { config.localPort = 1080; - } - if (config.index == -1) - { - if (config.strategy == null) - { - config.index = 0; - } - } + if (config.index == -1 && config.strategy == null) + config.index = 0; return config; } catch (Exception e) { if (!(e is FileNotFoundException)) - { Logging.LogUsefulException(e); - } return new Configuration { index = 0, @@ -90,20 +77,11 @@ namespace Shadowsocks.Model public static void Save(Configuration config) { if (config.index >= config.configs.Count) - { config.index = config.configs.Count - 1; - } if (config.index < -1) - { config.index = -1; - } - if (config.index == -1) - { - if (config.strategy == null) - { - config.index = 0; - } - } + if (config.index == -1 && config.strategy == null) + config.index = 0; config.isDefault = false; try { @@ -128,42 +106,32 @@ namespace Shadowsocks.Model private static void Assert(bool condition) { if (!condition) - { throw new Exception(I18N.GetString("assertion failure")); - } } public static void CheckPort(int port) { if (port <= 0 || port > 65535) - { throw new ArgumentException(I18N.GetString("Port out of range")); - } } public static void CheckLocalPort(int port) { CheckPort(port); if (port == 8123) - { throw new ArgumentException(I18N.GetString("Port can't be 8123")); - } } private static void CheckPassword(string password) { if (string.IsNullOrEmpty(password)) - { throw new ArgumentException(I18N.GetString("Password can not be blank")); - } } private static void CheckServer(string server) { if (string.IsNullOrEmpty(server)) - { throw new ArgumentException(I18N.GetString("Server IP can not be blank")); - } } } } diff --git a/shadowsocks-csharp/Model/Server.cs b/shadowsocks-csharp/Model/Server.cs index e21f3576..4ae22fde 100755 --- a/shadowsocks-csharp/Model/Server.cs +++ b/shadowsocks-csharp/Model/Server.cs @@ -15,6 +15,8 @@ namespace Shadowsocks.Model public string method; public string remarks; public bool auth; + public long bandwidthIn; + public long bandwidthOut; public override int GetHashCode() { @@ -24,7 +26,7 @@ namespace Shadowsocks.Model public override bool Equals(object obj) { Server o2 = (Server)obj; - return this.server == o2.server && this.server_port == o2.server_port; + return server == o2.server && server_port == o2.server_port; } public string FriendlyName() @@ -45,12 +47,12 @@ namespace Shadowsocks.Model public Server() { - this.server = ""; - this.server_port = 8388; - this.method = "aes-256-cfb"; - this.password = ""; - this.remarks = ""; - this.auth = false; + server = ""; + server_port = 8388; + method = "aes-256-cfb"; + password = ""; + remarks = ""; + auth = false; } public Server(string ssURL) : this() @@ -62,7 +64,7 @@ namespace Shadowsocks.Model { try { - bytes = System.Convert.FromBase64String(base64); + bytes = Convert.FromBase64String(base64); } catch (FormatException) { @@ -80,16 +82,15 @@ namespace Shadowsocks.Model string afterAt = data.Substring(indexLastAt + 1); int indexLastColon = afterAt.LastIndexOf(':'); - this.server_port = int.Parse(afterAt.Substring(indexLastColon + 1)); - this.server = afterAt.Substring(0, indexLastColon); + server_port = int.Parse(afterAt.Substring(indexLastColon + 1)); + server = afterAt.Substring(0, indexLastColon); string beforeAt = data.Substring(0, indexLastAt); string[] parts = beforeAt.Split(new[] { ':' }); - this.method = parts[0]; - this.password = parts[1]; + method = parts[0]; + password = parts[1]; //TODO: read one_time_auth - } catch (IndexOutOfRangeException) { diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 25a3b3e8..32eb992d 100755 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -11,6 +11,7 @@ using ZXing.QrCode; using Shadowsocks.Controller; using Shadowsocks.Model; using Shadowsocks.Properties; +using Shadowsocks.Util; namespace Shadowsocks.View { @@ -341,7 +342,6 @@ namespace Shadowsocks.View { item.Checked = true; } - } } @@ -363,7 +363,7 @@ namespace Shadowsocks.View { if (logForms.Count == 0) { - LogForm f = new LogForm(controller, Logging.LogFile); + LogForm f = new LogForm(controller, Logging.LogFilePath); f.Show(); f.FormClosed += logForm_FormClosed; @@ -388,7 +388,7 @@ namespace Shadowsocks.View void configForm_FormClosed(object sender, FormClosedEventArgs e) { configForm = null; - Util.Utils.ReleaseMemory(true); + Utils.ReleaseMemory(true); ShowFirstTimeBalloon(); } @@ -491,7 +491,7 @@ namespace Shadowsocks.View private void ShowLogItem_Click(object sender, EventArgs e) { - LogForm f = new LogForm(controller, Logging.LogFile); + LogForm f = new LogForm(controller, Logging.LogFilePath); f.Show(); f.FormClosed += logForm_FormClosed; diff --git a/shadowsocks-csharp/app.config b/shadowsocks-csharp/app.config index a7ba1069..c96d7c75 100755 --- a/shadowsocks-csharp/app.config +++ b/shadowsocks-csharp/app.config @@ -8,11 +8,11 @@ - + - + diff --git a/shadowsocks-csharp/packages.config b/shadowsocks-csharp/packages.config index cd42cb7e..2230519e 100644 --- a/shadowsocks-csharp/packages.config +++ b/shadowsocks-csharp/packages.config @@ -1,11 +1,11 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 8ce00215..69f7b546 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -69,21 +69,18 @@ 3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll True - False 3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll True - False 3rd\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll True - False - - 3rd\Newtonsoft.Json.7.0.1\lib\net40\Newtonsoft.Json.dll + + 3rd\Newtonsoft.Json.8.0.2\lib\net40\Newtonsoft.Json.dll True @@ -91,10 +88,9 @@ - - 3rd\Microsoft.Bcl.1.1.8\lib\net40\System.IO.dll + + 3rd\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll True - False @@ -105,15 +101,13 @@ 3rd\Microsoft.Net.Http.2.0.20710.0\lib\net40\System.Net.Http.WebRequest.dll True - - 3rd\Microsoft.Bcl.1.1.8\lib\net40\System.Runtime.dll + + 3rd\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll True - False - - 3rd\Microsoft.Bcl.1.1.8\lib\net40\System.Threading.Tasks.dll + + 3rd\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll True - False @@ -330,18 +324,15 @@ - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + + +