From 6ed32ff7094e9776262bf113bf4c51f60ebeb8dc Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Thu, 20 Aug 2015 17:17:21 +0800
Subject: [PATCH 01/26] improved `log viewer`: 1. add menu items for `clear
logs`, `change fonts`, `wrap text` and `top most` functions. 2. hide toolbar
default. but you can trigger it out by menu.
---
shadowsocks-csharp/Data/cn.txt | 6 +-
shadowsocks-csharp/View/LogForm.Designer.cs | 159 ++++++++++++++------
shadowsocks-csharp/View/LogForm.cs | 109 +++++++++++++-
shadowsocks-csharp/View/LogForm.resx | 5 +-
4 files changed, 217 insertions(+), 62 deletions(-)
diff --git a/shadowsocks-csharp/Data/cn.txt b/shadowsocks-csharp/Data/cn.txt
index 81022f99..79f8d6f4 100644
--- a/shadowsocks-csharp/Data/cn.txt
+++ b/shadowsocks-csharp/Data/cn.txt
@@ -50,10 +50,12 @@ Move D&own=下移(&O)
&File=文件(&F)
&Open Location=在资源管理器中打开(&O)
E&xit=退出(&X)
-&Clean logs=清空(&C)
-&Font=字体(&F)
+&View=视图(&V)
+&Clean logs=清空日志(&C)
+Change &font=设置字体(&F)
&Wrap text=自动换行(&W)
&Top most=置顶(&T)
+&Show toolbar=显示工具栏(&S)
Log Viewer=日志查看器
# QRCode Form
diff --git a/shadowsocks-csharp/View/LogForm.Designer.cs b/shadowsocks-csharp/View/LogForm.Designer.cs
index d0913d16..187ab948 100644
--- a/shadowsocks-csharp/View/LogForm.Designer.cs
+++ b/shadowsocks-csharp/View/LogForm.Designer.cs
@@ -30,19 +30,25 @@
{
this.components = new System.ComponentModel.Container();
this.LogMessageTextBox = new System.Windows.Forms.TextBox();
- this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
- this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
+ this.MainMenu = new System.Windows.Forms.MainMenu(this.components);
this.FileMenuItem = new System.Windows.Forms.MenuItem();
this.OpenLocationMenuItem = new System.Windows.Forms.MenuItem();
this.ExitMenuItem = new System.Windows.Forms.MenuItem();
- this.panel1 = new System.Windows.Forms.Panel();
+ this.ViewMenuItem = new System.Windows.Forms.MenuItem();
+ this.CleanLogsMenuItem = new System.Windows.Forms.MenuItem();
+ this.ChangeFontMenuItem = new System.Windows.Forms.MenuItem();
+ this.WrapTextMenuItem = new System.Windows.Forms.MenuItem();
+ this.TopMostMenuItem = new System.Windows.Forms.MenuItem();
+ this.MenuItemSeparater = new System.Windows.Forms.MenuItem();
+ this.ShowToolbarMenuItem = new System.Windows.Forms.MenuItem();
+ this.TopMostCheckBox = new System.Windows.Forms.CheckBox();
this.ChangeFontButton = new System.Windows.Forms.Button();
this.CleanLogsButton = new System.Windows.Forms.Button();
this.WrapTextCheckBox = new System.Windows.Forms.CheckBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
- this.TopMostCheckBox = new System.Windows.Forms.CheckBox();
- this.panel1.SuspendLayout();
+ this.ToolbarFlowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
this.tableLayoutPanel1.SuspendLayout();
+ this.ToolbarFlowLayoutPanel.SuspendLayout();
this.SuspendLayout();
//
// LogMessageTextBox
@@ -51,25 +57,20 @@
this.LogMessageTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.LogMessageTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LogMessageTextBox.ForeColor = System.Drawing.Color.White;
- this.LogMessageTextBox.Location = new System.Drawing.Point(3, 43);
+ this.LogMessageTextBox.Location = new System.Drawing.Point(3, 38);
this.LogMessageTextBox.MaxLength = 2147483647;
this.LogMessageTextBox.Multiline = true;
this.LogMessageTextBox.Name = "LogMessageTextBox";
this.LogMessageTextBox.ReadOnly = true;
this.LogMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.LogMessageTextBox.Size = new System.Drawing.Size(541, 307);
+ this.LogMessageTextBox.Size = new System.Drawing.Size(584, 377);
this.LogMessageTextBox.TabIndex = 0;
- this.LogMessageTextBox.WordWrap = false;
- //
- // contextMenuStrip1
//
- this.contextMenuStrip1.Name = "contextMenuStrip1";
- this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4);
+ // MainMenu
//
- // mainMenu1
- //
- this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
- this.FileMenuItem});
+ this.MainMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
+ this.FileMenuItem,
+ this.ViewMenuItem});
//
// FileMenuItem
//
@@ -91,21 +92,70 @@
this.ExitMenuItem.Text = "E&xit";
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
//
- // panel1
+ // ViewMenuItem
+ //
+ this.ViewMenuItem.Index = 1;
+ this.ViewMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
+ this.CleanLogsMenuItem,
+ this.ChangeFontMenuItem,
+ this.WrapTextMenuItem,
+ this.TopMostMenuItem,
+ this.MenuItemSeparater,
+ this.ShowToolbarMenuItem});
+ this.ViewMenuItem.Text = "&View";
+ //
+ // CleanLogsMenuItem
+ //
+ this.CleanLogsMenuItem.Index = 0;
+ this.CleanLogsMenuItem.Text = "&Clean logs";
+ this.CleanLogsMenuItem.Click += new System.EventHandler(this.CleanLogsMenuItem_Click);
+ //
+ // ChangeFontMenuItem
+ //
+ this.ChangeFontMenuItem.Index = 1;
+ this.ChangeFontMenuItem.Text = "Change &font";
+ this.ChangeFontMenuItem.Click += new System.EventHandler(this.ChangeFontMenuItem_Click);
//
- this.panel1.Controls.Add(this.TopMostCheckBox);
- this.panel1.Controls.Add(this.ChangeFontButton);
- this.panel1.Controls.Add(this.CleanLogsButton);
- this.panel1.Controls.Add(this.WrapTextCheckBox);
- this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.panel1.Location = new System.Drawing.Point(3, 3);
- this.panel1.Name = "panel1";
- this.panel1.Size = new System.Drawing.Size(541, 34);
- this.panel1.TabIndex = 1;
+ // WrapTextMenuItem
+ //
+ this.WrapTextMenuItem.Index = 2;
+ this.WrapTextMenuItem.Text = "&Wrap text";
+ this.WrapTextMenuItem.Click += new System.EventHandler(this.WrapTextMenuItem_Click);
+ //
+ // TopMostMenuItem
+ //
+ this.TopMostMenuItem.Index = 3;
+ this.TopMostMenuItem.Text = "&Top most";
+ this.TopMostMenuItem.Click += new System.EventHandler(this.TopMostMenuItem_Click);
+ //
+ // MenuItemSeparater
+ //
+ this.MenuItemSeparater.Index = 4;
+ this.MenuItemSeparater.Text = "-";
+ //
+ // ShowToolbarMenuItem
+ //
+ this.ShowToolbarMenuItem.Index = 5;
+ this.ShowToolbarMenuItem.Text = "&Show toolbar";
+ this.ShowToolbarMenuItem.Click += new System.EventHandler(this.ShowToolbarMenuItem_Click);
+ //
+ // TopMostCheckBox
+ //
+ this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)));
+ this.TopMostCheckBox.AutoSize = true;
+ this.TopMostCheckBox.Location = new System.Drawing.Point(249, 3);
+ this.TopMostCheckBox.Name = "TopMostCheckBox";
+ this.TopMostCheckBox.Size = new System.Drawing.Size(72, 23);
+ this.TopMostCheckBox.TabIndex = 3;
+ this.TopMostCheckBox.Text = "&Top most";
+ this.TopMostCheckBox.UseVisualStyleBackColor = true;
+ this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged);
//
// ChangeFontButton
//
- this.ChangeFontButton.Location = new System.Drawing.Point(107, 4);
+ this.ChangeFontButton.AutoSize = true;
+ this.ChangeFontButton.Location = new System.Drawing.Point(84, 3);
this.ChangeFontButton.Name = "ChangeFontButton";
this.ChangeFontButton.Size = new System.Drawing.Size(75, 23);
this.ChangeFontButton.TabIndex = 2;
@@ -115,7 +165,8 @@
//
// CleanLogsButton
//
- this.CleanLogsButton.Location = new System.Drawing.Point(9, 4);
+ this.CleanLogsButton.AutoSize = true;
+ this.CleanLogsButton.Location = new System.Drawing.Point(3, 3);
this.CleanLogsButton.Name = "CleanLogsButton";
this.CleanLogsButton.Size = new System.Drawing.Size(75, 23);
this.CleanLogsButton.TabIndex = 1;
@@ -125,10 +176,12 @@
//
// WrapTextCheckBox
//
+ this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)));
this.WrapTextCheckBox.AutoSize = true;
- this.WrapTextCheckBox.Location = new System.Drawing.Point(209, 9);
+ this.WrapTextCheckBox.Location = new System.Drawing.Point(165, 3);
this.WrapTextCheckBox.Name = "WrapTextCheckBox";
- this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 16);
+ this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 23);
this.WrapTextCheckBox.TabIndex = 0;
this.WrapTextCheckBox.Text = "&Wrap text";
this.WrapTextCheckBox.UseVisualStyleBackColor = true;
@@ -138,45 +191,47 @@
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
- this.tableLayoutPanel1.Controls.Add(this.panel1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.LogMessageTextBox, 0, 1);
+ this.tableLayoutPanel1.Controls.Add(this.ToolbarFlowLayoutPanel, 0, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
- this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
- this.tableLayoutPanel1.Size = new System.Drawing.Size(547, 353);
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(590, 418);
this.tableLayoutPanel1.TabIndex = 2;
//
- // TopMostCheckBox
+ // ToolbarFlowLayoutPanel
//
- this.TopMostCheckBox.AutoSize = true;
- this.TopMostCheckBox.Location = new System.Drawing.Point(311, 9);
- this.TopMostCheckBox.Name = "TopMostCheckBox";
- this.TopMostCheckBox.Size = new System.Drawing.Size(72, 16);
- this.TopMostCheckBox.TabIndex = 3;
- this.TopMostCheckBox.Text = "&Top most";
- this.TopMostCheckBox.UseVisualStyleBackColor = true;
- this.TopMostCheckBox.CheckedChanged += new System.EventHandler(this.TopMostCheckBox_CheckedChanged);
+ this.ToolbarFlowLayoutPanel.AutoSize = true;
+ this.ToolbarFlowLayoutPanel.Controls.Add(this.CleanLogsButton);
+ this.ToolbarFlowLayoutPanel.Controls.Add(this.ChangeFontButton);
+ this.ToolbarFlowLayoutPanel.Controls.Add(this.WrapTextCheckBox);
+ this.ToolbarFlowLayoutPanel.Controls.Add(this.TopMostCheckBox);
+ this.ToolbarFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ToolbarFlowLayoutPanel.Location = new System.Drawing.Point(3, 3);
+ this.ToolbarFlowLayoutPanel.Name = "ToolbarFlowLayoutPanel";
+ this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(584, 29);
+ this.ToolbarFlowLayoutPanel.TabIndex = 2;
//
// LogForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(547, 353);
+ this.ClientSize = new System.Drawing.Size(590, 418);
this.Controls.Add(this.tableLayoutPanel1);
- this.Menu = this.mainMenu1;
+ this.Menu = this.MainMenu;
this.Name = "LogForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Log Viewer";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.LogForm_FormClosing);
this.Load += new System.EventHandler(this.LogForm_Load);
this.Shown += new System.EventHandler(this.LogForm_Shown);
- this.panel1.ResumeLayout(false);
- this.panel1.PerformLayout();
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
+ this.ToolbarFlowLayoutPanel.ResumeLayout(false);
+ this.ToolbarFlowLayoutPanel.PerformLayout();
this.ResumeLayout(false);
}
@@ -184,16 +239,22 @@
#endregion
private System.Windows.Forms.TextBox LogMessageTextBox;
- private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
- private System.Windows.Forms.MainMenu mainMenu1;
+ private System.Windows.Forms.MainMenu MainMenu;
private System.Windows.Forms.MenuItem FileMenuItem;
private System.Windows.Forms.MenuItem OpenLocationMenuItem;
private System.Windows.Forms.MenuItem ExitMenuItem;
- private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.CheckBox WrapTextCheckBox;
private System.Windows.Forms.Button CleanLogsButton;
private System.Windows.Forms.Button ChangeFontButton;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.CheckBox TopMostCheckBox;
+ private System.Windows.Forms.MenuItem ViewMenuItem;
+ private System.Windows.Forms.MenuItem CleanLogsMenuItem;
+ private System.Windows.Forms.MenuItem ChangeFontMenuItem;
+ private System.Windows.Forms.MenuItem WrapTextMenuItem;
+ private System.Windows.Forms.MenuItem TopMostMenuItem;
+ private System.Windows.Forms.FlowLayoutPanel ToolbarFlowLayoutPanel;
+ private System.Windows.Forms.MenuItem MenuItemSeparater;
+ private System.Windows.Forms.MenuItem ShowToolbarMenuItem;
}
}
\ No newline at end of file
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index c4fcaf51..dcbbf1e2 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -34,9 +34,15 @@ namespace Shadowsocks.View
OpenLocationMenuItem.Text = I18N.GetString("&Open Location");
ExitMenuItem.Text = I18N.GetString("E&xit");
CleanLogsButton.Text = I18N.GetString("&Clean logs");
- ChangeFontButton.Text = I18N.GetString("&Font");
+ ChangeFontButton.Text = I18N.GetString("Change &font");
WrapTextCheckBox.Text = I18N.GetString("&Wrap text");
TopMostCheckBox.Text = I18N.GetString("&Top most");
+ ViewMenuItem.Text = I18N.GetString("&View");
+ CleanLogsMenuItem.Text = I18N.GetString("&Clean logs");
+ ChangeFontMenuItem.Text = I18N.GetString("Change &font");
+ WrapTextMenuItem.Text = I18N.GetString("&Wrap text");
+ TopMostMenuItem.Text = I18N.GetString("&Top most");
+ ShowToolbarMenuItem.Text = I18N.GetString("&Show toolbar");
this.Text = I18N.GetString("Log Viewer");
}
@@ -97,6 +103,9 @@ namespace Shadowsocks.View
timer.Interval = 300;
timer.Tick += Timer_Tick;
timer.Start();
+ this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger;
+ LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = WrapTextTrigger;
+ ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger;
}
private void LogForm_FormClosing(object sender, FormClosingEventArgs e)
@@ -121,18 +130,25 @@ namespace Shadowsocks.View
LogMessageTextBox.ScrollToCaret();
}
- private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e)
+ #region Clean up the content in LogMessageTextBox.
+ private void DoCleanLogs()
{
- LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked;
- LogMessageTextBox.ScrollToCaret();
+ LogMessageTextBox.Clear();
+ }
+
+ private void CleanLogsMenuItem_Click(object sender, EventArgs e)
+ {
+ DoCleanLogs();
}
private void CleanLogsButton_Click(object sender, EventArgs e)
{
- LogMessageTextBox.Clear();
+ DoCleanLogs();
}
+ #endregion
- private void ChangeFontButton_Click(object sender, EventArgs e)
+ #region Change the font settings applied in LogMessageTextBox.
+ private void DoChangeFont()
{
FontDialog fd = new FontDialog();
fd.Font = LogMessageTextBox.Font;
@@ -142,9 +158,88 @@ namespace Shadowsocks.View
}
}
+ private void ChangeFontMenuItem_Click(object sender, EventArgs e)
+ {
+ DoChangeFont();
+ }
+
+ private void ChangeFontButton_Click(object sender, EventArgs e)
+ {
+ DoChangeFont();
+ }
+ #endregion
+
+ #region Trigger the log messages wrapable, or not.
+ bool WrapTextTrigger = false;
+ bool WrapTextTriggerLock = false;
+
+ private void TriggerWrapText()
+ {
+ WrapTextTriggerLock = true;
+
+ WrapTextTrigger = !WrapTextTrigger;
+ LogMessageTextBox.WordWrap = WrapTextTrigger;
+ LogMessageTextBox.ScrollToCaret();
+ WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = WrapTextTrigger;
+
+ WrapTextTriggerLock = false;
+ }
+
+ private void WrapTextMenuItem_Click(object sender, EventArgs e)
+ {
+ if (!WrapTextTriggerLock)
+ {
+ TriggerWrapText();
+ }
+ }
+
+ private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ if (!WrapTextTriggerLock)
+ {
+ TriggerWrapText();
+ }
+ }
+ #endregion
+
+ #region Trigger this window top most, or not.
+ bool TopMostTrigger = false;
+ bool TopMostTriggerLock = false;
+
+ private void TriggerTopMost()
+ {
+ TopMostTriggerLock = true;
+
+ TopMostTrigger = !TopMostTrigger;
+ this.TopMost = TopMostTrigger;
+ TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger;
+
+ TopMostTriggerLock = false;
+ }
+
private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e)
{
- this.TopMost = TopMostCheckBox.Checked;
+ if (!TopMostTriggerLock)
+ {
+ TriggerTopMost();
+ }
+ }
+
+ private void TopMostMenuItem_Click(object sender, EventArgs e)
+ {
+ if (!TopMostTriggerLock)
+ {
+ TriggerTopMost();
+ }
+ }
+ #endregion
+
+ private bool ShowToolbarTrigger = false;
+ private void ShowToolbarMenuItem_Click(object sender, EventArgs e)
+ {
+ ShowToolbarTrigger = !ShowToolbarTrigger;
+ ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger;
+ ShowToolbarMenuItem.Checked = ShowToolbarTrigger;
}
}
}
diff --git a/shadowsocks-csharp/View/LogForm.resx b/shadowsocks-csharp/View/LogForm.resx
index 34b690ce..e8bf04bf 100644
--- a/shadowsocks-csharp/View/LogForm.resx
+++ b/shadowsocks-csharp/View/LogForm.resx
@@ -117,10 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
+
17, 17
-
- 172, 17
-
\ No newline at end of file
From 9953ae2e6821148bb41d698ff97d26d856b229b2 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Thu, 20 Aug 2015 21:01:40 +0800
Subject: [PATCH 02/26] fix variables' name: (first letter uppercase ->
lowercase) 1. WrapTextTrigger -> wrapTextTrigger 2. WrapTextTriggerLock ->
wrapTextTriggerLock 3. TopMostTrigger -> topMostTrigger 4. TopMostTriggerLock
-> topMostTriggerLock 5. ShowToolbarTrigger -> toolbarTrigger
---
shadowsocks-csharp/View/LogForm.cs | 50 +++++++++++++++---------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index dcbbf1e2..214dbba3 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -103,9 +103,9 @@ namespace Shadowsocks.View
timer.Interval = 300;
timer.Tick += Timer_Tick;
timer.Start();
- this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger;
- LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = WrapTextTrigger;
- ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger;
+ this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
+ LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = wrapTextTrigger;
+ ToolbarFlowLayoutPanel.Visible = toolbarTrigger;
}
private void LogForm_FormClosing(object sender, FormClosingEventArgs e)
@@ -170,24 +170,24 @@ namespace Shadowsocks.View
#endregion
#region Trigger the log messages wrapable, or not.
- bool WrapTextTrigger = false;
- bool WrapTextTriggerLock = false;
+ bool wrapTextTrigger = false;
+ bool wrapTextTriggerLock = false;
private void TriggerWrapText()
{
- WrapTextTriggerLock = true;
+ wrapTextTriggerLock = true;
- WrapTextTrigger = !WrapTextTrigger;
- LogMessageTextBox.WordWrap = WrapTextTrigger;
+ wrapTextTrigger = !wrapTextTrigger;
+ LogMessageTextBox.WordWrap = wrapTextTrigger;
LogMessageTextBox.ScrollToCaret();
- WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = WrapTextTrigger;
+ WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger;
- WrapTextTriggerLock = false;
+ wrapTextTriggerLock = false;
}
private void WrapTextMenuItem_Click(object sender, EventArgs e)
{
- if (!WrapTextTriggerLock)
+ if (!wrapTextTriggerLock)
{
TriggerWrapText();
}
@@ -195,7 +195,7 @@ namespace Shadowsocks.View
private void WrapTextCheckBox_CheckedChanged(object sender, EventArgs e)
{
- if (!WrapTextTriggerLock)
+ if (!wrapTextTriggerLock)
{
TriggerWrapText();
}
@@ -203,23 +203,23 @@ namespace Shadowsocks.View
#endregion
#region Trigger this window top most, or not.
- bool TopMostTrigger = false;
- bool TopMostTriggerLock = false;
+ bool topMostTrigger = false;
+ bool topMostTriggerLock = false;
private void TriggerTopMost()
{
- TopMostTriggerLock = true;
+ topMostTriggerLock = true;
- TopMostTrigger = !TopMostTrigger;
- this.TopMost = TopMostTrigger;
- TopMostMenuItem.Checked = TopMostCheckBox.Checked = TopMostTrigger;
+ topMostTrigger = !topMostTrigger;
+ this.TopMost = topMostTrigger;
+ TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
- TopMostTriggerLock = false;
+ topMostTriggerLock = false;
}
private void TopMostCheckBox_CheckedChanged(object sender, EventArgs e)
{
- if (!TopMostTriggerLock)
+ if (!topMostTriggerLock)
{
TriggerTopMost();
}
@@ -227,19 +227,19 @@ namespace Shadowsocks.View
private void TopMostMenuItem_Click(object sender, EventArgs e)
{
- if (!TopMostTriggerLock)
+ if (!topMostTriggerLock)
{
TriggerTopMost();
}
}
#endregion
- private bool ShowToolbarTrigger = false;
+ private bool toolbarTrigger = false;
private void ShowToolbarMenuItem_Click(object sender, EventArgs e)
{
- ShowToolbarTrigger = !ShowToolbarTrigger;
- ToolbarFlowLayoutPanel.Visible = ShowToolbarTrigger;
- ShowToolbarMenuItem.Checked = ShowToolbarTrigger;
+ toolbarTrigger = !toolbarTrigger;
+ ToolbarFlowLayoutPanel.Visible = toolbarTrigger;
+ ShowToolbarMenuItem.Checked = toolbarTrigger;
}
}
}
From 79e9a23d94feaa5324cf769acf1d71b70c535040 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Thu, 20 Aug 2015 21:03:38 +0800
Subject: [PATCH 03/26] add feature: save LogForm's config into json file.
---
shadowsocks-csharp/Model/Configuration.cs | 1 +
shadowsocks-csharp/Model/LogViewerConfig.cs | 63 ++++++++++++++++++++
shadowsocks-csharp/View/LogForm.cs | 36 ++++++++++-
shadowsocks-csharp/shadowsocks-csharp.csproj | 1 +
4 files changed, 99 insertions(+), 2 deletions(-)
create mode 100644 shadowsocks-csharp/Model/LogViewerConfig.cs
diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs
index 1ccba56c..d9de24f5 100755
--- a/shadowsocks-csharp/Model/Configuration.cs
+++ b/shadowsocks-csharp/Model/Configuration.cs
@@ -23,6 +23,7 @@ namespace Shadowsocks.Model
public string pacUrl;
public bool useOnlinePac;
public bool availabilityStatistics;
+ public LogViewerConfig logViewer;
private static string CONFIG_FILE = "gui-config.json";
diff --git a/shadowsocks-csharp/Model/LogViewerConfig.cs b/shadowsocks-csharp/Model/LogViewerConfig.cs
new file mode 100644
index 00000000..28471084
--- /dev/null
+++ b/shadowsocks-csharp/Model/LogViewerConfig.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Drawing;
+
+namespace Shadowsocks.Model
+{
+ [Serializable]
+ public class LogViewerConfig
+ {
+ public string fontName;
+ public float fontSize;
+ public string bgColor;
+ public string textColor;
+ public bool topMost;
+ public bool wrapText;
+ public bool toolbarShown;
+
+ public LogViewerConfig()
+ {
+ this.fontName = "Console";
+ this.fontSize = 8;
+ this.bgColor = "black";
+ this.textColor = "white";
+ this.topMost = false;
+ this.wrapText = false;
+ this.toolbarShown = false;
+ }
+
+ public Color GetBackgroundColor()
+ {
+ try
+ {
+ return ColorTranslator.FromHtml(bgColor);
+ }
+ catch (Exception)
+ {
+ return ColorTranslator.FromHtml("black");
+ }
+ }
+
+ public void SetBackgroundColor(Color color)
+ {
+ bgColor = ColorTranslator.ToHtml(color);
+ }
+
+ public Color GetTextColor()
+ {
+ try
+ {
+ return ColorTranslator.FromHtml(textColor);
+ }
+ catch (Exception)
+ {
+ return ColorTranslator.FromHtml("white");
+ throw;
+ }
+ }
+
+ public void SetTextColor(Color color)
+ {
+ textColor = ColorTranslator.ToHtml(color);
+ }
+ }
+}
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index 214dbba3..91eb69bb 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -18,6 +18,7 @@ namespace Shadowsocks.View
string filename;
Timer timer;
const int BACK_OFFSET = 65536;
+ Model.Configuration config;
public LogForm(string filename)
{
@@ -25,6 +26,21 @@ namespace Shadowsocks.View
InitializeComponent();
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
+ config = Model.Configuration.Load();
+ if (config.logViewer == null)
+ {
+ config.logViewer = new Model.LogViewerConfig();
+ }
+ else
+ {
+ topMostTrigger = config.logViewer.topMost;
+ wrapTextTrigger = config.logViewer.wrapText;
+ toolbarTrigger = config.logViewer.toolbarShown;
+ LogMessageTextBox.Font = new Font(config.logViewer.fontName, config.logViewer.fontSize);
+ LogMessageTextBox.BackColor = config.logViewer.GetBackgroundColor();
+ LogMessageTextBox.ForeColor = config.logViewer.GetTextColor();
+ }
+
UpdateTexts();
}
@@ -103,14 +119,29 @@ namespace Shadowsocks.View
timer.Interval = 300;
timer.Tick += Timer_Tick;
timer.Start();
+
+ topMostTriggerLock = true;
this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
- LogMessageTextBox.WordWrap = WrapTextCheckBox.Checked = WrapTextMenuItem.Checked = wrapTextTrigger;
- ToolbarFlowLayoutPanel.Visible = toolbarTrigger;
+ topMostTriggerLock = false;
+
+ wrapTextTriggerLock = true;
+ LogMessageTextBox.WordWrap = WrapTextMenuItem.Checked = WrapTextCheckBox.Checked = wrapTextTrigger;
+ wrapTextTriggerLock = false;
+
+ ToolbarFlowLayoutPanel.Visible = ShowToolbarMenuItem.Checked = toolbarTrigger;
}
private void LogForm_FormClosing(object sender, FormClosingEventArgs e)
{
timer.Stop();
+ config.logViewer.topMost = topMostTrigger;
+ config.logViewer.wrapText = wrapTextTrigger;
+ config.logViewer.toolbarShown = toolbarTrigger;
+ config.logViewer.fontName = LogMessageTextBox.Font.Name;
+ config.logViewer.fontSize = LogMessageTextBox.Font.Size;
+ config.logViewer.SetBackgroundColor(LogMessageTextBox.BackColor);
+ config.logViewer.SetTextColor(LogMessageTextBox.ForeColor);
+ Model.Configuration.Save(config);
}
private void OpenLocationMenuItem_Click(object sender, EventArgs e)
@@ -235,6 +266,7 @@ namespace Shadowsocks.View
#endregion
private bool toolbarTrigger = false;
+
private void ShowToolbarMenuItem_Click(object sender, EventArgs e)
{
toolbarTrigger = !toolbarTrigger;
diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj
index 8200aa07..dd957ffb 100644
--- a/shadowsocks-csharp/shadowsocks-csharp.csproj
+++ b/shadowsocks-csharp/shadowsocks-csharp.csproj
@@ -145,6 +145,7 @@
+
From b1f17e02a11a07627e5d0b4da920ee434db8aba1 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Fri, 21 Aug 2015 16:47:56 +0800
Subject: [PATCH 04/26] 1. limit the windows' minimized size 2. store window's
size & position in config file. 3. fix: scroll bar sometimes disappear while
sizing the window.
---
shadowsocks-csharp/Model/LogViewerConfig.cs | 9 +++++++++
shadowsocks-csharp/View/LogForm.Designer.cs | 9 +++++----
shadowsocks-csharp/View/LogForm.cs | 9 +++++++++
3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/shadowsocks-csharp/Model/LogViewerConfig.cs b/shadowsocks-csharp/Model/LogViewerConfig.cs
index 28471084..80bb220d 100644
--- a/shadowsocks-csharp/Model/LogViewerConfig.cs
+++ b/shadowsocks-csharp/Model/LogViewerConfig.cs
@@ -1,5 +1,6 @@
using System;
using System.Drawing;
+using System.Windows.Forms;
namespace Shadowsocks.Model
{
@@ -13,6 +14,10 @@ namespace Shadowsocks.Model
public bool topMost;
public bool wrapText;
public bool toolbarShown;
+ public int width;
+ public int height;
+ public int top;
+ public int left;
public LogViewerConfig()
{
@@ -23,6 +28,10 @@ namespace Shadowsocks.Model
this.topMost = false;
this.wrapText = false;
this.toolbarShown = false;
+ this.width = 600;
+ this.height = 400;
+ this.top = (Screen.PrimaryScreen.WorkingArea.Height - height) / 2;
+ this.left = (Screen.PrimaryScreen.WorkingArea.Width - width) / 2;
}
public Color GetBackgroundColor()
diff --git a/shadowsocks-csharp/View/LogForm.Designer.cs b/shadowsocks-csharp/View/LogForm.Designer.cs
index 187ab948..ba090850 100644
--- a/shadowsocks-csharp/View/LogForm.Designer.cs
+++ b/shadowsocks-csharp/View/LogForm.Designer.cs
@@ -63,7 +63,7 @@
this.LogMessageTextBox.Name = "LogMessageTextBox";
this.LogMessageTextBox.ReadOnly = true;
this.LogMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.LogMessageTextBox.Size = new System.Drawing.Size(584, 377);
+ this.LogMessageTextBox.Size = new System.Drawing.Size(378, 99);
this.LogMessageTextBox.TabIndex = 0;
//
// MainMenu
@@ -199,7 +199,7 @@
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
- this.tableLayoutPanel1.Size = new System.Drawing.Size(590, 418);
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(384, 140);
this.tableLayoutPanel1.TabIndex = 2;
//
// ToolbarFlowLayoutPanel
@@ -212,16 +212,17 @@
this.ToolbarFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.ToolbarFlowLayoutPanel.Location = new System.Drawing.Point(3, 3);
this.ToolbarFlowLayoutPanel.Name = "ToolbarFlowLayoutPanel";
- this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(584, 29);
+ this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(378, 29);
this.ToolbarFlowLayoutPanel.TabIndex = 2;
//
// LogForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(590, 418);
+ this.ClientSize = new System.Drawing.Size(384, 140);
this.Controls.Add(this.tableLayoutPanel1);
this.Menu = this.MainMenu;
+ this.MinimumSize = new System.Drawing.Size(400, 200);
this.Name = "LogForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Log Viewer";
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index 91eb69bb..a80965fd 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -120,6 +120,11 @@ namespace Shadowsocks.View
timer.Tick += Timer_Tick;
timer.Start();
+ this.Top = config.logViewer.top;
+ this.Left = config.logViewer.left;
+ this.Height = config.logViewer.height;
+ this.Width = config.logViewer.width;
+
topMostTriggerLock = true;
this.TopMost = TopMostMenuItem.Checked = TopMostCheckBox.Checked = topMostTrigger;
topMostTriggerLock = false;
@@ -141,6 +146,10 @@ namespace Shadowsocks.View
config.logViewer.fontSize = LogMessageTextBox.Font.Size;
config.logViewer.SetBackgroundColor(LogMessageTextBox.BackColor);
config.logViewer.SetTextColor(LogMessageTextBox.ForeColor);
+ config.logViewer.top = this.Top;
+ config.logViewer.left = this.Left;
+ config.logViewer.height = this.Height;
+ config.logViewer.width = this.Width;
Model.Configuration.Save(config);
}
From 17c75de9c064f20342e4b832e420c31476a7b59e Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Fri, 21 Aug 2015 17:12:11 +0800
Subject: [PATCH 05/26] convert "\r\n" -> Environment.NewLine
---
shadowsocks-csharp/View/LogForm.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index a80965fd..ee85698c 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -80,7 +80,7 @@ namespace Shadowsocks.View
string line = "";
while ((line = reader.ReadLine()) != null)
- LogMessageTextBox.AppendText(line + "\r\n");
+ LogMessageTextBox.AppendText(line + Environment.NewLine);
LogMessageTextBox.ScrollToCaret();
@@ -100,7 +100,7 @@ namespace Shadowsocks.View
while ((line = reader.ReadLine()) != null)
{
changed = true;
- LogMessageTextBox.AppendText(line + "\r\n");
+ LogMessageTextBox.AppendText(line + Environment.NewLine);
}
if (changed)
From b2c2d05c940cf7249c3597274cd5a3281b93749b Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Fri, 21 Aug 2015 22:12:14 +0800
Subject: [PATCH 06/26] support auto check `user-rule.txt`'s change, and update
the PAC file.
Note: This is a dirty hack.
---
.../Controller/Service/GfwListUpdater.cs | 3 +-
.../Controller/Service/PACServer.cs | 57 ++++++++++++++-----
.../Controller/ShadowsocksController.cs | 43 ++++++++++++++
3 files changed, 88 insertions(+), 15 deletions(-)
diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
index 70720fb9..dc8d692c 100644
--- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
+++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
@@ -36,6 +36,7 @@ namespace Shadowsocks.Controller
{
try
{
+ File.WriteAllText(Utils.GetTempPath() + "\\gfwlist.txt", e.Result, Encoding.UTF8);
List lines = ParseResult(e.Result);
if (File.Exists(USER_RULE_FILE))
{
@@ -82,7 +83,7 @@ namespace Shadowsocks.Controller
http.DownloadStringAsync(new Uri(GFWLIST_URL));
}
- public List ParseResult(string response)
+ public static List ParseResult(string response)
{
byte[] bytes = Convert.FromBase64String(response);
string content = Encoding.ASCII.GetString(bytes);
diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs
index f8fc80e8..52ea241d 100644
--- a/shadowsocks-csharp/Controller/Service/PACServer.cs
+++ b/shadowsocks-csharp/Controller/Service/PACServer.cs
@@ -18,14 +18,17 @@ namespace Shadowsocks.Controller
public static string USER_RULE_FILE = "user-rule.txt";
- FileSystemWatcher watcher;
+ FileSystemWatcher PACFileWatcher;
+ FileSystemWatcher UserRuleFileWatcher;
private Configuration _config;
public event EventHandler PACFileChanged;
+ public event EventHandler UserRuleFileChanged;
public PACServer()
{
this.WatchPacFile();
+ this.WatchUserRuleFile();
}
public void UpdateConfiguration(Configuration config)
@@ -167,28 +170,54 @@ Connection: Close
private void WatchPacFile()
{
- if (watcher != null)
- {
- watcher.Dispose();
- }
- watcher = new FileSystemWatcher(Directory.GetCurrentDirectory());
- watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
- watcher.Filter = PAC_FILE;
- watcher.Changed += Watcher_Changed;
- watcher.Created += Watcher_Changed;
- watcher.Deleted += Watcher_Changed;
- watcher.Renamed += Watcher_Changed;
- watcher.EnableRaisingEvents = true;
+ if (PACFileWatcher != null)
+ {
+ PACFileWatcher.Dispose();
+ }
+ PACFileWatcher = new FileSystemWatcher(Directory.GetCurrentDirectory());
+ PACFileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
+ PACFileWatcher.Filter = PAC_FILE;
+ PACFileWatcher.Changed += PACFileWatcher_Changed;
+ PACFileWatcher.Created += PACFileWatcher_Changed;
+ PACFileWatcher.Deleted += PACFileWatcher_Changed;
+ PACFileWatcher.Renamed += PACFileWatcher_Changed;
+ PACFileWatcher.EnableRaisingEvents = true;
+ }
+
+ private void WatchUserRuleFile()
+ {
+ if (UserRuleFileWatcher != null)
+ {
+ UserRuleFileWatcher.Dispose();
+ }
+ UserRuleFileWatcher = new FileSystemWatcher(Directory.GetCurrentDirectory());
+ UserRuleFileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
+ UserRuleFileWatcher.Filter = USER_RULE_FILE;
+ UserRuleFileWatcher.Changed += UserRuleFileWatcher_Changed;
+ UserRuleFileWatcher.Created += UserRuleFileWatcher_Changed;
+ UserRuleFileWatcher.Deleted += UserRuleFileWatcher_Changed;
+ UserRuleFileWatcher.Renamed += UserRuleFileWatcher_Changed;
+ UserRuleFileWatcher.EnableRaisingEvents = true;
}
- private void Watcher_Changed(object sender, FileSystemEventArgs e)
+ private void PACFileWatcher_Changed(object sender, FileSystemEventArgs e)
{
if (PACFileChanged != null)
{
+ Console.WriteLine("Detected: PAC file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
PACFileChanged(this, new EventArgs());
}
}
+ private void UserRuleFileWatcher_Changed(object sender, FileSystemEventArgs e)
+ {
+ if (UserRuleFileChanged != null)
+ {
+ Console.WriteLine("Detected: User Rule file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
+ UserRuleFileChanged(this, new EventArgs());
+ }
+ }
+
private string GetPACAddress(byte[] requestBuf, int length, IPEndPoint localEndPoint, bool useSocks)
{
//try
diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs
index 2e2f5528..87496199 100755
--- a/shadowsocks-csharp/Controller/ShadowsocksController.cs
+++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs
@@ -7,6 +7,8 @@ using System.Threading;
using System.Net.Sockets;
using Shadowsocks.Controller.Strategy;
using System.Net;
+using Shadowsocks.Util;
+using Shadowsocks.Properties;
namespace Shadowsocks.Controller
{
@@ -293,6 +295,7 @@ namespace Shadowsocks.Controller
{
_pacServer = new PACServer();
_pacServer.PACFileChanged += pacServer_PACFileChanged;
+ _pacServer.UserRuleFileChanged += pacServer_UserRuleFileChanged;
}
_pacServer.UpdateConfiguration(_config);
if (gfwListUpdater == null)
@@ -404,6 +407,46 @@ namespace Shadowsocks.Controller
UpdatePACFromGFWListError(this, e);
}
+ private void pacServer_UserRuleFileChanged(object sender, EventArgs e)
+ {
+ // TODO: this is a dirty hack. (from code GListUpdater.http_DownloadStringCompleted())
+
+ //UpdatePACFromGFWList(); // TODO: code like this temporary
+ //try
+ //{
+ List lines = GFWListUpdater.ParseResult(File.ReadAllText(Utils.GetTempPath() + "\\gfwlist.txt"));
+ if (File.Exists(PACServer.USER_RULE_FILE))
+ {
+ string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8);
+ string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (string rule in rules)
+ {
+ if (rule.StartsWith("!") || rule.StartsWith("["))
+ continue;
+ lines.Add(rule);
+ }
+ }
+ string abpContent = Utils.UnGzip(Resources.abp_js);
+ abpContent = abpContent.Replace("__RULES__", SimpleJson.SimpleJson.SerializeObject(lines));
+ if (File.Exists(PACServer.PAC_FILE))
+ {
+ string original = File.ReadAllText(PACServer.PAC_FILE, Encoding.UTF8);
+ if (original == abpContent)
+ {
+ return;
+ }
+ }
+ File.WriteAllText(PACServer.PAC_FILE, abpContent, Encoding.UTF8);
+ //}
+ //catch (Exception ex)
+ //{
+ // if (Error != null)
+ // {
+ // Error(this, new ErrorEventArgs(ex));
+ // }
+ //}
+ }
+
private void StartReleasingMemory()
{
_ramThread = new Thread(new ThreadStart(ReleaseMemory));
From 3283c93857c791ee41f1e187157dea86ecf77968 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Sat, 22 Aug 2015 12:26:26 +0800
Subject: [PATCH 07/26] fix: auto detected `user-rule.txt`'s change while no
`gfwlist.txt` file, the application crashs.
---
shadowsocks-csharp/Controller/ShadowsocksController.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs
index 87496199..263852a0 100755
--- a/shadowsocks-csharp/Controller/ShadowsocksController.cs
+++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs
@@ -414,7 +414,12 @@ namespace Shadowsocks.Controller
//UpdatePACFromGFWList(); // TODO: code like this temporary
//try
//{
- List lines = GFWListUpdater.ParseResult(File.ReadAllText(Utils.GetTempPath() + "\\gfwlist.txt"));
+ if (!File.Exists(Utils.GetTempPath() + "\\gfwlist.txt"))
+ {
+ UpdatePACFromGFWList();
+ return;
+ }
+ List lines = GFWListUpdater.ParseResult(File.ReadAllText(Utils.GetTempPath() + "\\gfwlist.txt"));
if (File.Exists(PACServer.USER_RULE_FILE))
{
string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8);
From bdd29e8384eebd12b3d08d13021b630c12b95497 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Thu, 27 Aug 2015 04:38:52 +0800
Subject: [PATCH 08/26] fixed: Log Form will hidden when restart Windows
---
shadowsocks-csharp/View/LogForm.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index ee85698c..babf11f7 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -120,8 +120,8 @@ namespace Shadowsocks.View
timer.Tick += Timer_Tick;
timer.Start();
- this.Top = config.logViewer.top;
- this.Left = config.logViewer.left;
+ this.Top = (config.logViewer.top >=0) ? config.logViewer.top : 0;
+ this.Left = (config.logViewer.left >=0) ? config.logViewer.left : 0;
this.Height = config.logViewer.height;
this.Width = config.logViewer.width;
From 1280f43878d4874d93f8e988f5973a05090366f9 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Thu, 27 Aug 2015 06:04:04 +0800
Subject: [PATCH 09/26] fixed: file changes event triggers twice
---
.../Controller/Service/PACServer.cs | 40 ++++++++++++++++---
1 file changed, 34 insertions(+), 6 deletions(-)
diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs
index 52ea241d..a4aa33b6 100644
--- a/shadowsocks-csharp/Controller/Service/PACServer.cs
+++ b/shadowsocks-csharp/Controller/Service/PACServer.cs
@@ -2,6 +2,7 @@
using Shadowsocks.Properties;
using Shadowsocks.Util;
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
@@ -200,24 +201,51 @@ Connection: Close
UserRuleFileWatcher.EnableRaisingEvents = true;
}
+ #region FileSystemWatcher.OnChanged()
+
+ // FileSystemWatcher Changed event is raised twice
+ // http://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice
+ private static Hashtable fileChangedTime = new Hashtable();
+
private void PACFileWatcher_Changed(object sender, FileSystemEventArgs e)
{
- if (PACFileChanged != null)
+ string path = e.FullPath.ToString();
+ string currentLastWriteTime = File.GetLastWriteTime(e.FullPath).ToString();
+
+ // if there is no path info stored yet or stored path has different time of write then the one now is inspected
+ if (!fileChangedTime.ContainsKey(path) || fileChangedTime[path].ToString() != currentLastWriteTime)
{
- Console.WriteLine("Detected: PAC file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
- PACFileChanged(this, new EventArgs());
+ if (PACFileChanged != null)
+ {
+ Console.WriteLine("Detected: PAC file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
+ PACFileChanged(this, new EventArgs());
+ }
+
+ //lastly we update the last write time in the hashtable
+ fileChangedTime[path] = currentLastWriteTime;
}
}
private void UserRuleFileWatcher_Changed(object sender, FileSystemEventArgs e)
{
- if (UserRuleFileChanged != null)
+ string path = e.FullPath.ToString();
+ string currentLastWriteTime = File.GetLastWriteTime(e.FullPath).ToString();
+
+ // if there is no path info stored yet or stored path has different time of write then the one now is inspected
+ if (!fileChangedTime.ContainsKey(path) || fileChangedTime[path].ToString() != currentLastWriteTime)
{
- Console.WriteLine("Detected: User Rule file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
- UserRuleFileChanged(this, new EventArgs());
+ if (UserRuleFileChanged != null)
+ {
+ Console.WriteLine("Detected: User Rule file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
+ UserRuleFileChanged(this, new EventArgs());
+ }
+ //lastly we update the last write time in the hashtable
+ fileChangedTime[path] = currentLastWriteTime;
}
}
+ #endregion
+
private string GetPACAddress(byte[] requestBuf, int length, IPEndPoint localEndPoint, bool useSocks)
{
//try
From 0bf8132d564e84287ee3aa0be221b7c97c5b17fe Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Sun, 30 Aug 2015 03:46:20 +0800
Subject: [PATCH 10/26] update urls
---
README.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/README.md b/README.md
index 83bff1ef..52a39e5b 100644
--- a/README.md
+++ b/README.md
@@ -75,9 +75,9 @@ Visual Studio 2015 is required.
GPLv3
-[Appveyor]: https://ci.appveyor.com/project/clowwindy/shadowsocks-csharp
-[Build Status]: https://ci.appveyor.com/api/projects/status/gknc8l1lxy423ehv/branch/master
-[latest release]: https://github.com/shadowsocks/shadowsocks-csharp/releases
+[Appveyor]: https://ci.appveyor.com/project/kimw/shadowsocks-windows
+[Build Status]: https://ci.appveyor.com/api/projects/status/q0h3wsyisbic5fpt/branch/master
+[latest release]: https://github.com/kimw/shadowsocks-windows/releases
[GFWList]: https://github.com/gfwlist/gfwlist
-[Servers]: https://github.com/shadowsocks/shadowsocks/wiki/Ports-and-Clients#linux--server-side
-[中文说明]: https://github.com/shadowsocks/shadowsocks-windows/wiki/Shadowsocks-Windows-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
+[Servers]: https://github.com/kimw/shadowsocks/wiki/Ports-and-Clients#linux--server-side
+[中文说明]: https://github.com/kimw/shadowsocks-windows/wiki/Shadowsocks-Windows-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
From 0759bc894fea2373c1c2b89e17a3796ead2fe8d0 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Fri, 11 Sep 2015 23:29:17 +0800
Subject: [PATCH 11/26] Move: gfwlist from googelcode -> github
---
shadowsocks-csharp/Controller/Service/GfwListUpdater.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
index dc8d692c..800379f2 100644
--- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
+++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
@@ -12,7 +12,7 @@ namespace Shadowsocks.Controller
{
public class GFWListUpdater
{
- private const string GFWLIST_URL = "https://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt";
+ private const string GFWLIST_URL = "https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt";
private static string PAC_FILE = PACServer.PAC_FILE;
From 7a5451976cbc70df0b357327f8def35db5815946 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Mon, 14 Sep 2015 12:58:15 +0800
Subject: [PATCH 12/26] fixed: remove useless exception throw out.
---
shadowsocks-csharp/Model/LogViewerConfig.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/shadowsocks-csharp/Model/LogViewerConfig.cs b/shadowsocks-csharp/Model/LogViewerConfig.cs
index 80bb220d..6dc8929d 100644
--- a/shadowsocks-csharp/Model/LogViewerConfig.cs
+++ b/shadowsocks-csharp/Model/LogViewerConfig.cs
@@ -60,7 +60,6 @@ namespace Shadowsocks.Model
catch (Exception)
{
return ColorTranslator.FromHtml("white");
- throw;
}
}
From b4f02853077c545064e98773932334acb3c72709 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Mon, 14 Sep 2015 12:58:44 +0800
Subject: [PATCH 13/26] fixed: typo
---
shadowsocks-csharp/View/LogForm.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index babf11f7..907783bb 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -209,7 +209,7 @@ namespace Shadowsocks.View
}
#endregion
- #region Trigger the log messages wrapable, or not.
+ #region Trigger the log messages to wrapable, or not.
bool wrapTextTrigger = false;
bool wrapTextTriggerLock = false;
@@ -242,7 +242,7 @@ namespace Shadowsocks.View
}
#endregion
- #region Trigger this window top most, or not.
+ #region Trigger the window to top most, or not.
bool topMostTrigger = false;
bool topMostTriggerLock = false;
From a66441ea714c74e6751f6e1dff5f60c4da58944c Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Mon, 14 Sep 2015 13:01:44 +0800
Subject: [PATCH 14/26] feature: double click on tray icon shows up LogForm
instead of ConfigForm.
---
shadowsocks-csharp/View/MenuViewController.cs | 37 +++++++++++++++++--
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs
index c8a4c0eb..bae81e72 100755
--- a/shadowsocks-csharp/View/MenuViewController.cs
+++ b/shadowsocks-csharp/View/MenuViewController.cs
@@ -43,6 +43,8 @@ namespace Shadowsocks.View
private MenuItem editGFWUserRuleItem;
private MenuItem editOnlinePACItem;
private ConfigForm configForm;
+ private List logForms = new List();
+ private bool logFormsVisible = false;
private string _urlToOpen;
public MenuViewController(ShadowsocksController controller)
@@ -251,7 +253,6 @@ namespace Shadowsocks.View
_notifyIcon.BalloonTipClicked -= notifyIcon1_BalloonTipClicked;
}
-
private void LoadCurrentConfiguration()
{
Configuration config = controller.GetConfigurationCopy();
@@ -319,6 +320,32 @@ namespace Shadowsocks.View
}
}
+ private void ShowLogForms()
+ {
+ if (logForms.Count == 0)
+ {
+ LogForm f = new LogForm(Logging.LogFile);
+ f.Show();
+ f.FormClosed += logForm_FormClosed;
+
+ logForms.Add(f);
+ logFormsVisible = true;
+ }
+ else
+ {
+ logFormsVisible = !logFormsVisible;
+ foreach (LogForm f in logForms)
+ {
+ f.Visible = logFormsVisible;
+ }
+ }
+ }
+
+ void logForm_FormClosed(object sender, FormClosedEventArgs e)
+ {
+ logForms.Remove((LogForm)sender);
+ }
+
void configForm_FormClosed(object sender, FormClosedEventArgs e)
{
configForm = null;
@@ -359,7 +386,7 @@ namespace Shadowsocks.View
{
if (e.Button == MouseButtons.Left)
{
- ShowConfigForm();
+ ShowLogForms();
}
}
@@ -413,9 +440,11 @@ namespace Shadowsocks.View
private void ShowLogItem_Click(object sender, EventArgs e)
{
- string argument = Logging.LogFile;
+ LogForm f = new LogForm(Logging.LogFile);
+ f.Show();
+ f.FormClosed += logForm_FormClosed;
- new LogForm(argument).Show();
+ logForms.Add(f);
}
private void QRCodeItem_Click(object sender, EventArgs e)
From 2a71bd7ed7597a617a8a318697d40faae627d4d6 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Mon, 14 Sep 2015 14:44:14 +0800
Subject: [PATCH 15/26] fixed: rename LogFile -> LogFilePath, for more
understandable
---
shadowsocks-csharp/Controller/Logging.cs | 6 +++---
shadowsocks-csharp/View/MenuViewController.cs | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs
index d77a3fbe..2ef247a6 100755
--- a/shadowsocks-csharp/Controller/Logging.cs
+++ b/shadowsocks-csharp/Controller/Logging.cs
@@ -9,15 +9,15 @@ namespace Shadowsocks.Controller
{
public class Logging
{
- public static string LogFile;
+ public static string LogFilePath;
public static bool OpenLogFile()
{
try
{
string temppath = Utils.GetTempPath();
- LogFile = Path.Combine(temppath, "shadowsocks.log");
- FileStream fs = new FileStream(LogFile, FileMode.Append);
+ LogFilePath = Path.Combine(temppath, "shadowsocks.log");
+ FileStream fs = new FileStream(LogFilePath, FileMode.Append);
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs);
sw.AutoFlush = true;
Console.SetOut(sw);
diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs
index bae81e72..62f0a88d 100755
--- a/shadowsocks-csharp/View/MenuViewController.cs
+++ b/shadowsocks-csharp/View/MenuViewController.cs
@@ -324,7 +324,7 @@ namespace Shadowsocks.View
{
if (logForms.Count == 0)
{
- LogForm f = new LogForm(Logging.LogFile);
+ LogForm f = new LogForm(Logging.LogFilePath);
f.Show();
f.FormClosed += logForm_FormClosed;
@@ -440,7 +440,7 @@ namespace Shadowsocks.View
private void ShowLogItem_Click(object sender, EventArgs e)
{
- LogForm f = new LogForm(Logging.LogFile);
+ LogForm f = new LogForm(Logging.LogFilePath);
f.Show();
f.FormClosed += logForm_FormClosed;
From 0a733c61b8de38378dcc6d15605d9146ee15a381 Mon Sep 17 00:00:00 2001
From: kimw <1@kimwong.me>
Date: Mon, 14 Sep 2015 14:58:46 +0800
Subject: [PATCH 16/26] fixed: standardize Logging usage
1. Add Logging.Info()
2. Console.WriteLine() -> Logging.Info()
3. Console.WriteLine() in exceptions -> Logging.LogUsefulException()
---
shadowsocks-csharp/Controller/FileManager.cs | 5 ++---
shadowsocks-csharp/Controller/Logging.cs | 8 ++++++--
.../Service/AvailabilityStatistics.cs | 2 +-
.../Controller/Service/Listener.cs | 6 +++---
.../Controller/Service/PACServer.cs | 8 ++++----
.../Controller/Service/PolipoRunner.cs | 4 ++--
.../Controller/Service/PortForwarder.cs | 2 +-
.../Controller/Service/TCPRelay.cs | 19 +++++++++----------
.../Strategy/HighAvailabilityStrategy.cs | 10 +++++-----
.../SimplyChooseByStatisticsStrategy.cs | 7 +++----
shadowsocks-csharp/Encryption/PolarSSL.cs | 2 +-
shadowsocks-csharp/Encryption/Sodium.cs | 2 +-
shadowsocks-csharp/Model/Configuration.cs | 2 +-
shadowsocks-csharp/Util/Util.cs | 2 +-
shadowsocks-csharp/View/LogForm.cs | 2 +-
shadowsocks-csharp/View/MenuViewController.cs | 2 +-
16 files changed, 42 insertions(+), 41 deletions(-)
diff --git a/shadowsocks-csharp/Controller/FileManager.cs b/shadowsocks-csharp/Controller/FileManager.cs
index cc8f3bf9..0dac0224 100755
--- a/shadowsocks-csharp/Controller/FileManager.cs
+++ b/shadowsocks-csharp/Controller/FileManager.cs
@@ -19,10 +19,9 @@ namespace Shadowsocks.Controller
_FileStream.Close();
return true;
}
- catch (Exception _Exception)
+ catch (Exception e)
{
- Console.WriteLine("Exception caught in process: {0}",
- _Exception.ToString());
+ Logging.LogUsefulException(e);
}
return false;
}
diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs
index 2ef247a6..49fdde34 100755
--- a/shadowsocks-csharp/Controller/Logging.cs
+++ b/shadowsocks-csharp/Controller/Logging.cs
@@ -32,11 +32,15 @@ namespace Shadowsocks.Controller
}
}
- public static void Debug(object o)
+ public static void Info(object o)
{
+ Console.WriteLine(o);
+ }
+ public static void Debug(object o)
+ {
#if DEBUG
- Console.WriteLine(o);
+ Console.WriteLine("[D] " + o);
#endif
}
diff --git a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
index 08125e92..494e1afc 100644
--- a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
+++ b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
@@ -81,7 +81,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
- Console.WriteLine($"An exception occured when eveluating {server.FriendlyName()}");
+ Logging.Info($"An exception occured while eveluating {server.FriendlyName()}");
Logging.LogUsefulException(e);
}
}
diff --git a/shadowsocks-csharp/Controller/Service/Listener.cs b/shadowsocks-csharp/Controller/Service/Listener.cs
index fe59fe98..06994787 100644
--- a/shadowsocks-csharp/Controller/Service/Listener.cs
+++ b/shadowsocks-csharp/Controller/Service/Listener.cs
@@ -78,7 +78,7 @@ namespace Shadowsocks.Controller
_tcpSocket.Listen(1024);
// Start an asynchronous socket to listen for connections.
- Console.WriteLine("Shadowsocks started");
+ Logging.Info("Shadowsocks started");
_tcpSocket.BeginAccept(
new AsyncCallback(AcceptCallback),
_tcpSocket);
@@ -163,7 +163,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
- Console.WriteLine(e);
+ Logging.LogUsefulException(e);
}
finally
{
@@ -208,7 +208,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
- Console.WriteLine(e);
+ Logging.LogUsefulException(e);
conn.Close();
}
}
diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs
index a4aa33b6..6f8fa414 100644
--- a/shadowsocks-csharp/Controller/Service/PACServer.cs
+++ b/shadowsocks-csharp/Controller/Service/PACServer.cs
@@ -153,7 +153,7 @@ Connection: Close
}
catch (Exception e)
{
- Console.WriteLine(e);
+ Logging.LogUsefulException(e);
socket.Close();
}
}
@@ -217,7 +217,7 @@ Connection: Close
{
if (PACFileChanged != null)
{
- Console.WriteLine("Detected: PAC file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
+ Logging.Info($"Detected: PAC file '{e.Name}' was {e.ChangeType.ToString().ToLower()}.");
PACFileChanged(this, new EventArgs());
}
@@ -236,7 +236,7 @@ Connection: Close
{
if (UserRuleFileChanged != null)
{
- Console.WriteLine("Detected: User Rule file '{0}' was {1}.", e.Name, e.ChangeType.ToString().ToLower());
+ Logging.Info($"Detected: User Rule file '{e.Name}' was {e.ChangeType.ToString().ToLower()}.");
UserRuleFileChanged(this, new EventArgs());
}
//lastly we update the last write time in the hashtable
@@ -259,7 +259,7 @@ Connection: Close
//}
//catch (Exception e)
//{
- // Console.WriteLine(e);
+ // Logging.LogUsefulException(e);
//}
return (useSocks ? "SOCKS5 " : "PROXY ") + localEndPoint.Address + ":" + this._config.localPort + ";";
}
diff --git a/shadowsocks-csharp/Controller/Service/PolipoRunner.cs b/shadowsocks-csharp/Controller/Service/PolipoRunner.cs
index 5b784bcd..ad582d1e 100644
--- a/shadowsocks-csharp/Controller/Service/PolipoRunner.cs
+++ b/shadowsocks-csharp/Controller/Service/PolipoRunner.cs
@@ -56,7 +56,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
- Console.WriteLine(e.ToString());
+ Logging.LogUsefulException(e);
}
}
string polipoConfig = Resources.privoxy_conf;
@@ -94,7 +94,7 @@ namespace Shadowsocks.Controller
}
catch (Exception e)
{
- Console.WriteLine(e.ToString());
+ Logging.LogUsefulException(e);
}
_process = null;
}
diff --git a/shadowsocks-csharp/Controller/Service/PortForwarder.cs b/shadowsocks-csharp/Controller/Service/PortForwarder.cs
index 63848079..46f2cf10 100644
--- a/shadowsocks-csharp/Controller/Service/PortForwarder.cs
+++ b/shadowsocks-csharp/Controller/Service/PortForwarder.cs
@@ -140,7 +140,7 @@ namespace Shadowsocks.Controller
}
else
{
- //Console.WriteLine("bytesRead: " + bytesRead.ToString());
+ Logging.Debug($"bytes read: {bytesRead}");
_local.Shutdown(SocketShutdown.Send);
_localShutdown = true;
CheckClose();
diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs
index bf0497d4..2bb0eb98 100644
--- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs
+++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs
@@ -49,7 +49,7 @@ namespace Shadowsocks.Controller
lock (this.Handlers)
{
this.Handlers.Add(handler);
- Logging.Debug($"connections: {Handlers.Count}");
+ Logging.Debug($"TCP connections: {Handlers.Count}");
DateTime now = DateTime.Now;
if (now - _lastSweepTime > TimeSpan.FromSeconds(1))
{
@@ -65,10 +65,10 @@ namespace Shadowsocks.Controller
}
foreach (Handler handler1 in handlersToClose)
{
- Logging.Debug("Closing timed out connection");
+ Logging.Debug("Closing timed out TCP connection.");
handler1.Close();
}
- return true;
+ return true;
}
}
@@ -148,7 +148,7 @@ namespace Shadowsocks.Controller
{
lock (relay.Handlers)
{
- Logging.Debug($"connections: {relay.Handlers.Count}");
+ Logging.Debug($"TCP connections: {relay.Handlers.Count}");
relay.Handlers.Remove(this);
}
lock (this)
@@ -212,7 +212,7 @@ namespace Shadowsocks.Controller
{
// reject socks 4
response = new byte[] { 0, 91 };
- Console.WriteLine("socks 5 protocol error");
+ Logging.Info("socks 5 protocol error");
}
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(HandshakeSendCallback), null);
}
@@ -280,7 +280,7 @@ namespace Shadowsocks.Controller
}
else
{
- Console.WriteLine("failed to recv data in handshakeReceive2Callback");
+ Logging.Info("failed to recv data in handshakeReceive2Callback");
this.Close();
}
}
@@ -423,7 +423,7 @@ namespace Shadowsocks.Controller
{
strategy.SetFailure(server);
}
- Console.WriteLine(String.Format("{0} timed out", server.FriendlyName()));
+ Logging.Info($"{server.FriendlyName()} timed out");
remote.Close();
RetryConnect();
}
@@ -462,8 +462,7 @@ namespace Shadowsocks.Controller
connected = true;
- //Console.WriteLine("Socket connected to {0}",
- // remote.RemoteEndPoint.ToString());
+ Logging.Debug($"Socket connected to {remote.RemoteEndPoint}");
var latency = DateTime.Now - _startConnectTime;
IStrategy strategy = controller.GetCurrentStrategy();
@@ -545,7 +544,7 @@ namespace Shadowsocks.Controller
}
else
{
- //Console.WriteLine("bytesRead: " + bytesRead.ToString());
+ Logging.Debug($"bytes read: {bytesRead}");
connection.Shutdown(SocketShutdown.Send);
connectionShutdown = true;
CheckClose();
diff --git a/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs b/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs
index fa05a0c1..ba25ee18 100644
--- a/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs
+++ b/shadowsocks-csharp/Controller/Strategy/HighAvailabilityStrategy.cs
@@ -132,14 +132,14 @@ namespace Shadowsocks.Controller.Strategy
if (_currentServer == null || max.score - _currentServer.score > 200)
{
_currentServer = max;
- Console.WriteLine("HA switching to server: {0}", _currentServer.server.FriendlyName());
+ Logging.Info($"HA switching to server: {_currentServer.server.FriendlyName()}");
}
}
}
public void UpdateLatency(Model.Server server, TimeSpan latency)
{
- Logging.Debug(String.Format("latency: {0} {1}", server.FriendlyName(), latency));
+ Logging.Debug($"latency: {server.FriendlyName()} {latency}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))
@@ -151,7 +151,7 @@ namespace Shadowsocks.Controller.Strategy
public void UpdateLastRead(Model.Server server)
{
- Logging.Debug(String.Format("last read: {0}", server.FriendlyName()));
+ Logging.Debug($"last read: {server.FriendlyName()}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))
@@ -162,7 +162,7 @@ namespace Shadowsocks.Controller.Strategy
public void UpdateLastWrite(Model.Server server)
{
- Logging.Debug(String.Format("last write: {0}", server.FriendlyName()));
+ Logging.Debug($"last write: {server.FriendlyName()}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))
@@ -173,7 +173,7 @@ namespace Shadowsocks.Controller.Strategy
public void SetFailure(Model.Server server)
{
- Logging.Debug(String.Format("failure: {0}", server.FriendlyName()));
+ Logging.Debug($"failure: {server.FriendlyName()}");
ServerStatus status;
if (_serverStatus.TryGetValue(server, out status))
diff --git a/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs b/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs
index 0cdfcfc5..ab684256 100644
--- a/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs
+++ b/shadowsocks-csharp/Controller/Strategy/SimplyChooseByStatisticsStrategy.cs
@@ -47,7 +47,7 @@ namespace Shadowsocks.Controller.Strategy
try
{
var path = AvailabilityStatistics.AvailabilityStatisticsFile;
- Logging.Debug(string.Format("loading statistics from{0}", path));
+ Logging.Debug($"loading statistics from {path}");
statistics = (from l in File.ReadAllLines(path)
.Skip(1)
let strings = l.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)
@@ -113,7 +113,7 @@ namespace Shadowsocks.Controller.Strategy
if (_controller.GetCurrentStrategy().ID == ID && _currentServer != bestResult.server) //output when enabled
{
- Console.WriteLine("Switch to server: {0} by package loss:{1}", bestResult.server.FriendlyName(), 1 - bestResult.score);
+ Logging.Info($"Switch to server: {bestResult.server.FriendlyName()} by package loss:{1 - bestResult.score}");
}
_currentServer = bestResult.server;
}
@@ -154,7 +154,7 @@ namespace Shadowsocks.Controller.Strategy
public void SetFailure(Server server)
{
- Logging.Debug(String.Format("failure: {0}", server.FriendlyName()));
+ Logging.Debug($"failure: {server.FriendlyName()}");
}
public void UpdateLastRead(Server server)
@@ -171,6 +171,5 @@ namespace Shadowsocks.Controller.Strategy
{
//TODO: combine this part of data with ICMP statics
}
-
}
}
diff --git a/shadowsocks-csharp/Encryption/PolarSSL.cs b/shadowsocks-csharp/Encryption/PolarSSL.cs
index 42ce5bf7..3c1d8831 100755
--- a/shadowsocks-csharp/Encryption/PolarSSL.cs
+++ b/shadowsocks-csharp/Encryption/PolarSSL.cs
@@ -30,7 +30,7 @@ namespace Shadowsocks.Encryption
}
catch (Exception e)
{
- Console.WriteLine(e.ToString());
+ Logging.LogUsefulException(e);
}
LoadLibrary(dllPath);
}
diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs
index 564aaeda..9580dea5 100755
--- a/shadowsocks-csharp/Encryption/Sodium.cs
+++ b/shadowsocks-csharp/Encryption/Sodium.cs
@@ -27,7 +27,7 @@ namespace Shadowsocks.Encryption
}
catch (Exception e)
{
- Console.WriteLine(e.ToString());
+ Logging.LogUsefulException(e);
}
LoadLibrary(dllPath);
}
diff --git a/shadowsocks-csharp/Model/Configuration.cs b/shadowsocks-csharp/Model/Configuration.cs
index d9de24f5..74d40f0b 100755
--- a/shadowsocks-csharp/Model/Configuration.cs
+++ b/shadowsocks-csharp/Model/Configuration.cs
@@ -70,7 +70,7 @@ namespace Shadowsocks.Model
{
if (!(e is FileNotFoundException))
{
- Console.WriteLine(e);
+ Logging.LogUsefulException(e);
}
return new Configuration
{
diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs
index 1858ee90..219978b2 100755
--- a/shadowsocks-csharp/Util/Util.cs
+++ b/shadowsocks-csharp/Util/Util.cs
@@ -21,7 +21,7 @@ namespace Shadowsocks.Util
Directory.CreateDirectory(Application.StartupPath + "\\temp");
} catch (Exception e)
{
- Console.WriteLine(e);
+ Logging.LogUsefulException(e);
}
// don't use "/", it will fail when we call explorer /select xxx/temp\xxx.log
return Application.StartupPath + "\\temp";
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index 907783bb..fe12c5a1 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -156,7 +156,7 @@ namespace Shadowsocks.View
private void OpenLocationMenuItem_Click(object sender, EventArgs e)
{
string argument = "/select, \"" + filename + "\"";
- Console.WriteLine(argument);
+ Logging.Debug(argument);
System.Diagnostics.Process.Start("explorer.exe", argument);
}
diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs
index 62f0a88d..0c581c13 100755
--- a/shadowsocks-csharp/View/MenuViewController.cs
+++ b/shadowsocks-csharp/View/MenuViewController.cs
@@ -231,7 +231,7 @@ namespace Shadowsocks.View
void controller_UpdatePACFromGFWListError(object sender, System.IO.ErrorEventArgs e)
{
ShowBalloonTip(I18N.GetString("Failed to update PAC file"), e.GetException().Message, ToolTipIcon.Error, 5000);
- Logging.LogUsefulException(e.GetException());
+ Logging.LogUsefulException(e);
}
void controller_UpdatePACFromGFWListCompleted(object sender, GFWListUpdater.ResultEventArgs e)
From 2cce64670019740e8b9c1903b5a12abb377adf7b Mon Sep 17 00:00:00 2001
From: kimw
Date: Mon, 4 Jan 2016 23:21:53 +0800
Subject: [PATCH 17/26] featured show bandwidth in log form's title
---
.../Controller/Service/Listener.cs | 10 +-
.../Controller/Service/PortForwarder.cs | 2 -
.../Controller/Service/TCPRelay.cs | 174 +++++++++---------
.../Controller/Service/UDPRelay.cs | 22 ++-
.../Controller/ShadowsocksController.cs | 27 ++-
shadowsocks-csharp/Util/Util.cs | 29 ++-
shadowsocks-csharp/View/LogForm.Designer.cs | 28 +--
shadowsocks-csharp/View/LogForm.cs | 9 +-
shadowsocks-csharp/View/LogForm.resx | 24 +++
9 files changed, 194 insertions(+), 131 deletions(-)
diff --git a/shadowsocks-csharp/Controller/Service/Listener.cs b/shadowsocks-csharp/Controller/Service/Listener.cs
index 06994787..e9744988 100644
--- a/shadowsocks-csharp/Controller/Service/Listener.cs
+++ b/shadowsocks-csharp/Controller/Service/Listener.cs
@@ -1,10 +1,10 @@
-using Shadowsocks.Model;
-using System;
+using System;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
-using System.Text;
+
+using Shadowsocks.Model;
namespace Shadowsocks.Controller
{
@@ -79,9 +79,7 @@ namespace Shadowsocks.Controller
// Start an asynchronous socket to listen for connections.
Logging.Info("Shadowsocks started");
- _tcpSocket.BeginAccept(
- new AsyncCallback(AcceptCallback),
- _tcpSocket);
+ _tcpSocket.BeginAccept(new AsyncCallback(AcceptCallback), _tcpSocket);
UDPState udpState = new UDPState();
_udpSocket.BeginReceiveFrom(udpState.buffer, 0, udpState.buffer.Length, 0, ref udpState.remoteEndPoint, new AsyncCallback(RecvFromCallback), udpState);
}
diff --git a/shadowsocks-csharp/Controller/Service/PortForwarder.cs b/shadowsocks-csharp/Controller/Service/PortForwarder.cs
index e577b535..4f78a24c 100644
--- a/shadowsocks-csharp/Controller/Service/PortForwarder.cs
+++ b/shadowsocks-csharp/Controller/Service/PortForwarder.cs
@@ -1,8 +1,6 @@
using System;
-using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
-using System.Text;
namespace Shadowsocks.Controller
{
diff --git a/shadowsocks-csharp/Controller/Service/TCPRelay.cs b/shadowsocks-csharp/Controller/Service/TCPRelay.cs
index 061345dc..4944c44c 100644
--- a/shadowsocks-csharp/Controller/Service/TCPRelay.cs
+++ b/shadowsocks-csharp/Controller/Service/TCPRelay.cs
@@ -1,31 +1,30 @@
using System;
using System.Collections.Generic;
-using System.Text;
-using System.Net.Sockets;
using System.Net;
+using System.Net.Sockets;
+using System.Timers;
+
+using Shadowsocks.Controller.Strategy;
using Shadowsocks.Encryption;
using Shadowsocks.Model;
-using Shadowsocks.Controller.Strategy;
-using System.Timers;
namespace Shadowsocks.Controller
{
-
class TCPRelay : Listener.Service
{
private ShadowsocksController _controller;
private DateTime _lastSweepTime;
- public ISet Handlers
+ public ISet Handlers
{
get; set;
}
public TCPRelay(ShadowsocksController controller)
{
- this._controller = controller;
- this.Handlers = new HashSet();
- this._lastSweepTime = DateTime.Now;
+ _controller = controller;
+ Handlers = new HashSet();
+ _lastSweepTime = DateTime.Now;
}
public bool Handle(byte[] firstPacket, int length, Socket socket, object state)
@@ -39,22 +38,21 @@ namespace Shadowsocks.Controller
return false;
}
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
- Handler handler = new Handler();
+ TCPHandler handler = new TCPHandler(this);
handler.connection = socket;
handler.controller = _controller;
handler.relay = this;
handler.Start(firstPacket, length);
- IList handlersToClose = new List();
- lock (this.Handlers)
+ IList handlersToClose = new List();
+ lock (Handlers)
{
- this.Handlers.Add(handler);
- Logging.Debug($"TCP connections: {Handlers.Count}");
+ Handlers.Add(handler);
DateTime now = DateTime.Now;
if (now - _lastSweepTime > TimeSpan.FromSeconds(1))
{
_lastSweepTime = now;
- foreach (Handler handler1 in this.Handlers)
+ foreach (TCPHandler handler1 in Handlers)
{
if (now - handler1.lastActivity > TimeSpan.FromSeconds(900))
{
@@ -63,18 +61,28 @@ namespace Shadowsocks.Controller
}
}
}
- foreach (Handler handler1 in handlersToClose)
+ foreach (TCPHandler handler1 in handlersToClose)
{
Logging.Debug("Closing timed out TCP connection.");
handler1.Close();
}
return true;
}
+
+ public void UpdateInboundCounter(long n)
+ {
+ _controller.UpdateInboundCounter(n);
+ }
+
+ public void UpdateOutboundCounter(long n)
+ {
+ _controller.UpdateOutboundCounter(n);
+ }
}
- class Handler
+ class TCPHandler
{
- //public Encryptor encryptor;
+ // public Encryptor encryptor;
public IEncryptor encryptor;
public Server server;
// Client socket.
@@ -85,6 +93,7 @@ namespace Shadowsocks.Controller
public DateTime lastActivity;
+ private const int maxRetry = 4;
private int retryCount = 0;
private bool connected;
@@ -117,6 +126,12 @@ namespace Shadowsocks.Controller
private object decryptionLock = new object();
private DateTime _startConnectTime;
+ private TCPRelay tcprelay; // TODO: tcprelay ?= relay
+
+ public TCPHandler(TCPRelay tcprelay)
+ {
+ this.tcprelay = tcprelay;
+ }
public void CreateRemote()
{
@@ -125,23 +140,23 @@ namespace Shadowsocks.Controller
{
throw new ArgumentException("No server configured");
}
- this.encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.auth, false);
+ encryptor = EncryptorFactory.GetEncryptor(server.method, server.password, server.auth, false);
this.server = server;
}
public void Start(byte[] firstPacket, int length)
{
- this._firstPacket = firstPacket;
- this._firstPacketLength = length;
- this.HandshakeReceive();
- this.lastActivity = DateTime.Now;
+ _firstPacket = firstPacket;
+ _firstPacketLength = length;
+ HandshakeReceive();
+ lastActivity = DateTime.Now;
}
private void CheckClose()
{
if (connectionShutdown && remoteShutdown)
{
- this.Close();
+ Close();
}
}
@@ -149,7 +164,6 @@ namespace Shadowsocks.Controller
{
lock (relay.Handlers)
{
- Logging.Debug($"TCP connections: {relay.Handlers.Count}");
relay.Handlers.Remove(this);
}
lock (this)
@@ -215,18 +229,17 @@ namespace Shadowsocks.Controller
response = new byte[] { 0, 91 };
Logging.Error("socks 5 protocol error");
}
- Logging.Debug($"======Send Local Port, size:" + response.Length);
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(HandshakeSendCallback), null);
}
else
{
- this.Close();
+ Close();
}
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -240,21 +253,19 @@ namespace Shadowsocks.Controller
{
connection.EndSend(ar);
- // +----+-----+-------+------+----------+----------+
- // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
- // +----+-----+-------+------+----------+----------+
- // | 1 | 1 | X'00' | 1 | Variable | 2 |
- // +----+-----+-------+------+----------+----------+
+ // +-----+-----+-------+------+----------+----------+
+ // | VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+ // +-----+-----+-------+------+----------+----------+
+ // | 1 | 1 | X'00' | 1 | Variable | 2 |
+ // +-----+-----+-------+------+----------+----------+
// Skip first 3 bytes
// TODO validate
- Logging.Debug($"======Receive Local Port, size:" + 3);
- connection.BeginReceive(connetionRecvBuffer, 0, 3, 0,
- new AsyncCallback(handshakeReceive2Callback), null);
+ connection.BeginReceive(connetionRecvBuffer, 0, 3, 0, new AsyncCallback(handshakeReceive2Callback), null);
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -274,7 +285,6 @@ namespace Shadowsocks.Controller
if (command == 1)
{
byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 };
- Logging.Debug($"======Send Local Port, size:" + response.Length);
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(ResponseCallback), null);
}
else if (command == 3)
@@ -284,14 +294,14 @@ namespace Shadowsocks.Controller
}
else
{
- Logging.Error("failed to recv data in handshakeReceive2Callback");
- this.Close();
+ Logging.Debug("failed to recv data in Shadowsocks.Controller.TCPHandler.handshakeReceive2Callback()");
+ Close();
}
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -313,7 +323,6 @@ namespace Shadowsocks.Controller
address.CopyTo(response, 4);
response[response.Length - 1] = (byte)(port & 0xFF);
response[response.Length - 2] = (byte)((port >> 8) & 0xFF);
- Logging.Debug($"======Send Local Port, size:" + response.Length);
connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(ReadAll), true);
}
@@ -328,29 +337,27 @@ namespace Shadowsocks.Controller
if (ar.AsyncState != null)
{
connection.EndSend(ar);
- Logging.Debug($"======Receive Local Port, size:" + RecvSize);
- connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
- new AsyncCallback(ReadAll), null);
+ Logging.Debug(remote, RecvSize, "TCP Relay");
+ connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(ReadAll), null);
}
else
{
int bytesRead = connection.EndReceive(ar);
if (bytesRead > 0)
{
- Logging.Debug($"======Receive Local Port, size:" + RecvSize);
- connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
- new AsyncCallback(ReadAll), null);
+ Logging.Debug(remote, RecvSize, "TCP Relay");
+ connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(ReadAll), null);
}
else
{
- this.Close();
+ Close();
}
}
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -366,15 +373,16 @@ namespace Shadowsocks.Controller
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
+ // inner class
private class ServerTimer : Timer
{
public Server Server;
- public ServerTimer(int p) :base(p)
+ public ServerTimer(int p) : base(p)
{
}
}
@@ -408,14 +416,12 @@ namespace Shadowsocks.Controller
connected = false;
// Connect to the remote endpoint.
- Logging.Debug($"++++++Connect Server Port");
- remote.BeginConnect(remoteEP,
- new AsyncCallback(ConnectCallback), connectTimer);
+ remote.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), connectTimer);
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -438,15 +444,15 @@ namespace Shadowsocks.Controller
private void RetryConnect()
{
- if (retryCount < 4)
+ if (retryCount < maxRetry)
{
- Logging.Debug("Connection failed, retrying");
+ Logging.Debug($"Connection failed, retry ({retryCount})");
StartConnect();
retryCount++;
}
else
{
- this.Close();
+ Close();
}
}
@@ -507,17 +513,13 @@ namespace Shadowsocks.Controller
}
try
{
- Logging.Debug($"++++++Receive Server Port, size:" + RecvSize);
- remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0,
- new AsyncCallback(PipeRemoteReceiveCallback), null);
- Logging.Debug($"======Receive Local Port, size:"+ RecvSize);
- connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0,
- new AsyncCallback(PipeConnectionReceiveCallback), null);
+ remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeRemoteReceiveCallback), null);
+ connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeConnectionReceiveCallback), null);
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -531,10 +533,11 @@ namespace Shadowsocks.Controller
{
int bytesRead = remote.EndReceive(ar);
totalRead += bytesRead;
+ tcprelay.UpdateInboundCounter(bytesRead);
if (bytesRead > 0)
{
- this.lastActivity = DateTime.Now;
+ lastActivity = DateTime.Now;
int bytesToSend;
lock (decryptionLock)
{
@@ -544,13 +547,13 @@ namespace Shadowsocks.Controller
}
encryptor.Decrypt(remoteRecvBuffer, bytesRead, remoteSendBuffer, out bytesToSend);
}
- Logging.Debug($"======Send Local Port, size:" + bytesToSend);
+ Logging.Debug(remote, bytesToSend, "TCP Relay", "@PipeRemoteReceiveCallback() (download)");
connection.BeginSend(remoteSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeConnectionSendCallback), null);
IStrategy strategy = controller.GetCurrentStrategy();
if (strategy != null)
{
- strategy.UpdateLastRead(this.server);
+ strategy.UpdateLastRead(server);
}
}
else
@@ -559,18 +562,18 @@ namespace Shadowsocks.Controller
connectionShutdown = true;
CheckClose();
- if (totalRead == 0)
- {
- // closed before anything received, reports as failure
- // disable this feature
- // controller.GetCurrentStrategy().SetFailure(this.server);
- }
+ //if (totalRead == 0)
+ //{
+ // // closed before anything received, reports as failure
+ // // disable this feature
+ // controller.GetCurrentStrategy().SetFailure(this.server);
+ //}
}
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -584,6 +587,7 @@ namespace Shadowsocks.Controller
{
int bytesRead = connection.EndReceive(ar);
totalWrite += bytesRead;
+ tcprelay.UpdateOutboundCounter(bytesRead);
if (bytesRead > 0)
{
@@ -596,13 +600,13 @@ namespace Shadowsocks.Controller
}
encryptor.Encrypt(connetionRecvBuffer, bytesRead, connetionSendBuffer, out bytesToSend);
}
- Logging.Debug($"++++++Send Server Port, size:" + bytesToSend);
+ Logging.Debug(remote, bytesToSend, "TCP Relay", "@PipeConnectionReceiveCallback() (upload)");
remote.BeginSend(connetionSendBuffer, 0, bytesToSend, 0, new AsyncCallback(PipeRemoteSendCallback), null);
IStrategy strategy = controller.GetCurrentStrategy();
if (strategy != null)
{
- strategy.UpdateLastWrite(this.server);
+ strategy.UpdateLastWrite(server);
}
}
else
@@ -615,7 +619,7 @@ namespace Shadowsocks.Controller
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -628,14 +632,12 @@ namespace Shadowsocks.Controller
try
{
remote.EndSend(ar);
- Logging.Debug($"======Receive Local Port, size:" + RecvSize);
- connection.BeginReceive(this.connetionRecvBuffer, 0, RecvSize, 0,
- new AsyncCallback(PipeConnectionReceiveCallback), null);
+ connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeConnectionReceiveCallback), null);
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
@@ -648,14 +650,12 @@ namespace Shadowsocks.Controller
try
{
connection.EndSend(ar);
- Logging.Debug($"++++++Receive Server Port, size:" + RecvSize);
- remote.BeginReceive(this.remoteRecvBuffer, 0, RecvSize, 0,
- new AsyncCallback(PipeRemoteReceiveCallback), null);
+ remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, new AsyncCallback(PipeRemoteReceiveCallback), null);
}
catch (Exception e)
{
Logging.LogUsefulException(e);
- this.Close();
+ Close();
}
}
}
diff --git a/shadowsocks-csharp/Controller/Service/UDPRelay.cs b/shadowsocks-csharp/Controller/Service/UDPRelay.cs
index 5f8d2433..e1325a3d 100644
--- a/shadowsocks-csharp/Controller/Service/UDPRelay.cs
+++ b/shadowsocks-csharp/Controller/Service/UDPRelay.cs
@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
-using System.Text;
-using Shadowsocks.Encryption;
-using Shadowsocks.Model;
-using System.Net.Sockets;
using System.Net;
+using System.Net.Sockets;
using System.Runtime.CompilerServices;
+
using Shadowsocks.Controller.Strategy;
+using Shadowsocks.Encryption;
+using Shadowsocks.Model;
namespace Shadowsocks.Controller
{
@@ -14,6 +14,10 @@ namespace Shadowsocks.Controller
{
private ShadowsocksController _controller;
private LRUCache _cache;
+
+ public long outbound = 0;
+ public long inbound = 0;
+
public UDPRelay(ShadowsocksController controller)
{
this._controller = controller;
@@ -70,8 +74,8 @@ namespace Shadowsocks.Controller
}
_remoteEndPoint = new IPEndPoint(ipAddress, server.server_port);
_remote = new Socket(_remoteEndPoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
-
}
+
public void Send(byte[] data, int length)
{
IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password, _server.auth, true);
@@ -80,15 +84,17 @@ namespace Shadowsocks.Controller
byte[] dataOut = new byte[length - 3 + 16 + IVEncryptor.ONETIMEAUTH_BYTES];
int outlen;
encryptor.Encrypt(dataIn, length - 3, dataOut, out outlen);
- Logging.Debug($"++++++Send Server Port, size:" + outlen);
+ Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
_remote.SendTo(dataOut, outlen, SocketFlags.None, _remoteEndPoint);
}
+
public void Receive()
{
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
Logging.Debug($"++++++Receive Server Port, size:" + _buffer.Length);
_remote.BeginReceiveFrom(_buffer, 0, _buffer.Length, 0, ref remoteEndPoint, new AsyncCallback(RecvFromCallback), null);
}
+
public void RecvFromCallback(IAsyncResult ar)
{
try
@@ -105,7 +111,7 @@ namespace Shadowsocks.Controller
byte[] sendBuf = new byte[outlen + 3];
Array.Copy(dataOut, 0, sendBuf, 3, outlen);
- Logging.Debug($"======Send Local Port, size:" + (outlen + 3));
+ Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay");
_local.SendTo(sendBuf, outlen + 3, 0, _localEndPoint);
Receive();
}
@@ -121,6 +127,7 @@ namespace Shadowsocks.Controller
{
}
}
+
public void Close()
{
try
@@ -142,7 +149,6 @@ namespace Shadowsocks.Controller
}
}
-
// cc by-sa 3.0 http://stackoverflow.com/a/3719378/1124054
class LRUCache where V : UDPRelay.UDPHandler
{
diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs
index 9e1693c4..e826f8e7 100755
--- a/shadowsocks-csharp/Controller/ShadowsocksController.cs
+++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs
@@ -1,14 +1,15 @@
-using System.IO;
-using Shadowsocks.Model;
-using System;
+using System;
using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
using System.Text;
using System.Threading;
-using System.Net.Sockets;
+
using Shadowsocks.Controller.Strategy;
-using System.Net;
-using Shadowsocks.Util;
+using Shadowsocks.Model;
using Shadowsocks.Properties;
+using Shadowsocks.Util;
namespace Shadowsocks.Controller
{
@@ -30,6 +31,9 @@ namespace Shadowsocks.Controller
public AvailabilityStatistics availabilityStatistics { get; private set; }
public StatisticsStrategyConfiguration StatisticsConfiguration { get; private set; }
+ public long inboundCounter = 0;
+ public long outboundCounter = 0;
+
private bool stopped = false;
private bool _systemProxyIsDirty = false;
@@ -62,7 +66,6 @@ namespace Shadowsocks.Controller
StartReleasingMemory();
}
-
public void Start()
{
Reload();
@@ -302,6 +305,16 @@ namespace Shadowsocks.Controller
Configuration.Save(_config);
}
+ public void UpdateInboundCounter(long n)
+ {
+ inboundCounter += n;
+ }
+
+ public void UpdateOutboundCounter(long n)
+ {
+ outboundCounter += n;
+ }
+
protected void Reload()
{
// some logic in configuration updated the config when saving, we need to read it again
diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs
index eaa79501..450faa56 100755
--- a/shadowsocks-csharp/Util/Util.cs
+++ b/shadowsocks-csharp/Util/Util.cs
@@ -1,10 +1,8 @@
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
-using System.Text;
using System.Windows.Forms;
using Shadowsocks.Controller;
@@ -85,6 +83,33 @@ namespace Shadowsocks.Util
}
}
+ public static string FormatBandwide(long n)
+ {
+ float f = n;
+ string unit = "B";
+ if (f > 1024)
+ {
+ f = f / 1024;
+ unit = "KiB";
+ }
+ if (f > 1024)
+ {
+ f = f / 1024;
+ unit = "MiB";
+ }
+ if (f > 1024)
+ {
+ f = f / 1024;
+ unit = "GiB";
+ }
+ if (f > 1024)
+ {
+ f = f / 1024;
+ unit = "TiB";
+ }
+ return $"{f:.##}{unit}";
+ }
+
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetProcessWorkingSetSize(IntPtr process,
diff --git a/shadowsocks-csharp/View/LogForm.Designer.cs b/shadowsocks-csharp/View/LogForm.Designer.cs
index 8f5e35c7..3ac114ba 100644
--- a/shadowsocks-csharp/View/LogForm.Designer.cs
+++ b/shadowsocks-csharp/View/LogForm.Designer.cs
@@ -57,13 +57,13 @@
this.LogMessageTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.LogMessageTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LogMessageTextBox.ForeColor = System.Drawing.Color.White;
- this.LogMessageTextBox.Location = new System.Drawing.Point(3, 38);
+ this.LogMessageTextBox.Location = new System.Drawing.Point(3, 40);
this.LogMessageTextBox.MaxLength = 2147483647;
this.LogMessageTextBox.Multiline = true;
this.LogMessageTextBox.Name = "LogMessageTextBox";
this.LogMessageTextBox.ReadOnly = true;
this.LogMessageTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
- this.LogMessageTextBox.Size = new System.Drawing.Size(378, 99);
+ this.LogMessageTextBox.Size = new System.Drawing.Size(378, 131);
this.LogMessageTextBox.TabIndex = 0;
//
// MainMenu
@@ -141,12 +141,12 @@
//
// TopMostCheckBox
//
- this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ this.TopMostCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.TopMostCheckBox.AutoSize = true;
- this.TopMostCheckBox.Location = new System.Drawing.Point(249, 3);
+ this.TopMostCheckBox.Location = new System.Drawing.Point(247, 3);
this.TopMostCheckBox.Name = "TopMostCheckBox";
- this.TopMostCheckBox.Size = new System.Drawing.Size(72, 23);
+ this.TopMostCheckBox.Size = new System.Drawing.Size(71, 25);
this.TopMostCheckBox.TabIndex = 3;
this.TopMostCheckBox.Text = "&Top Most";
this.TopMostCheckBox.UseVisualStyleBackColor = true;
@@ -157,7 +157,7 @@
this.ChangeFontButton.AutoSize = true;
this.ChangeFontButton.Location = new System.Drawing.Point(84, 3);
this.ChangeFontButton.Name = "ChangeFontButton";
- this.ChangeFontButton.Size = new System.Drawing.Size(75, 23);
+ this.ChangeFontButton.Size = new System.Drawing.Size(75, 25);
this.ChangeFontButton.TabIndex = 2;
this.ChangeFontButton.Text = "&Font";
this.ChangeFontButton.UseVisualStyleBackColor = true;
@@ -168,7 +168,7 @@
this.CleanLogsButton.AutoSize = true;
this.CleanLogsButton.Location = new System.Drawing.Point(3, 3);
this.CleanLogsButton.Name = "CleanLogsButton";
- this.CleanLogsButton.Size = new System.Drawing.Size(75, 23);
+ this.CleanLogsButton.Size = new System.Drawing.Size(75, 25);
this.CleanLogsButton.TabIndex = 1;
this.CleanLogsButton.Text = "&Clean Logs";
this.CleanLogsButton.UseVisualStyleBackColor = true;
@@ -176,12 +176,12 @@
//
// WrapTextCheckBox
//
- this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ this.WrapTextCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)));
this.WrapTextCheckBox.AutoSize = true;
this.WrapTextCheckBox.Location = new System.Drawing.Point(165, 3);
this.WrapTextCheckBox.Name = "WrapTextCheckBox";
- this.WrapTextCheckBox.Size = new System.Drawing.Size(78, 23);
+ this.WrapTextCheckBox.Size = new System.Drawing.Size(76, 25);
this.WrapTextCheckBox.TabIndex = 0;
this.WrapTextCheckBox.Text = "&Wrap Text";
this.WrapTextCheckBox.UseVisualStyleBackColor = true;
@@ -199,7 +199,7 @@
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
- this.tableLayoutPanel1.Size = new System.Drawing.Size(384, 140);
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(384, 174);
this.tableLayoutPanel1.TabIndex = 2;
//
// ToolbarFlowLayoutPanel
@@ -212,17 +212,17 @@
this.ToolbarFlowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.ToolbarFlowLayoutPanel.Location = new System.Drawing.Point(3, 3);
this.ToolbarFlowLayoutPanel.Name = "ToolbarFlowLayoutPanel";
- this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(378, 29);
+ this.ToolbarFlowLayoutPanel.Size = new System.Drawing.Size(378, 31);
this.ToolbarFlowLayoutPanel.TabIndex = 2;
//
// LogForm
//
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(384, 140);
+ this.ClientSize = new System.Drawing.Size(384, 174);
this.Controls.Add(this.tableLayoutPanel1);
this.Menu = this.MainMenu;
- this.MinimumSize = new System.Drawing.Size(400, 200);
+ this.MinimumSize = new System.Drawing.Size(400, 213);
this.Name = "LogForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Log Viewer";
diff --git a/shadowsocks-csharp/View/LogForm.cs b/shadowsocks-csharp/View/LogForm.cs
index a8fe2e4c..cf3f1732 100644
--- a/shadowsocks-csharp/View/LogForm.cs
+++ b/shadowsocks-csharp/View/LogForm.cs
@@ -1,16 +1,12 @@
using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Data;
using System.Drawing;
using System.IO;
-using System.Linq;
-using System.Text;
using System.Windows.Forms;
using Shadowsocks.Controller;
using Shadowsocks.Properties;
using Shadowsocks.Model;
+using Shadowsocks.Util;
namespace Shadowsocks.View
{
@@ -112,11 +108,14 @@ namespace Shadowsocks.View
lastOffset = reader.BaseStream.Position;
}
+
+ this.Text = $"Log Viewer [in: {Utils.FormatBandwide(controller.inboundCounter)}, out: {Utils.FormatBandwide(controller.outboundCounter)}]";
}
private void LogForm_Load(object sender, EventArgs e)
{
InitContent();
+
timer = new Timer();
timer.Interval = 300;
timer.Tick += Timer_Tick;
diff --git a/shadowsocks-csharp/View/LogForm.resx b/shadowsocks-csharp/View/LogForm.resx
index e8bf04bf..c921ecfb 100644
--- a/shadowsocks-csharp/View/LogForm.resx
+++ b/shadowsocks-csharp/View/LogForm.resx
@@ -117,7 +117,31 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ True
+
17, 17
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ True
+
\ No newline at end of file
From 64390d45ac6eb10d5f1b6928a9dde61cbe146cda Mon Sep 17 00:00:00 2001
From: kimw
Date: Mon, 4 Jan 2016 23:56:43 +0800
Subject: [PATCH 18/26] GetTempPath() now supports: return a full path with
filename combined which pointed to the temporary directory
---
shadowsocks-csharp/Controller/Logging.cs | 32 ++++++++---
.../Service/AvailabilityStatistics.cs | 56 +++++++++----------
.../Controller/Service/GfwListUpdater.cs | 12 ++--
.../Controller/Service/PACServer.cs | 4 +-
.../Controller/Service/PolipoRunner.cs | 30 ++++------
.../Controller/Service/UpdateChecker.cs | 11 +---
.../Controller/ShadowsocksController.cs | 4 +-
shadowsocks-csharp/Encryption/MbedTLS.cs | 17 +++---
shadowsocks-csharp/Encryption/PolarSSL.cs | 15 ++---
shadowsocks-csharp/Encryption/Sodium.cs | 15 ++---
shadowsocks-csharp/Program.cs | 24 ++++----
shadowsocks-csharp/Util/Util.cs | 39 +++++++++----
12 files changed, 137 insertions(+), 122 deletions(-)
diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs
index fb07dcae..3db34658 100755
--- a/shadowsocks-csharp/Controller/Logging.cs
+++ b/shadowsocks-csharp/Controller/Logging.cs
@@ -1,9 +1,9 @@
-using Shadowsocks.Util;
-using System;
-using System.Collections.Generic;
+using System;
using System.IO;
using System.Net.Sockets;
-using System.Text;
+using System.Net;
+
+using Shadowsocks.Util;
namespace Shadowsocks.Controller
{
@@ -15,8 +15,7 @@ namespace Shadowsocks.Controller
{
try
{
- string temppath = Utils.GetTempPath();
- LogFile = Path.Combine(temppath, "shadowsocks.log");
+ LogFile = Utils.GetTempPath("shadowsocks.log");
FileStream fs = new FileStream(LogFile, FileMode.Append);
StreamWriterWithTimestamp sw = new StreamWriterWithTimestamp(fs);
sw.AutoFlush = true;
@@ -34,7 +33,7 @@ namespace Shadowsocks.Controller
public static void Error(object o)
{
- Console.WriteLine("[E] "+ o);
+ Console.WriteLine("[E] " + o);
}
public static void Info(object o)
@@ -49,6 +48,25 @@ namespace Shadowsocks.Controller
#endif
}
+#if DEBUG
+ public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
+ {
+ if (header == null && tailer == null)
+ Debug($"{local} => {remote} (size={len})");
+ else if (header == null && tailer != null)
+ Debug($"{local} => {remote} (size={len}), {tailer}");
+ else if (header != null && tailer == null)
+ Debug($"{header}: {local} => {remote} (size={len})");
+ else
+ Debug($"{header}: {local} => {remote} (size={len}), {tailer}");
+ }
+
+ public static void Debug(Socket sock, int len, string header = null, string tailer = null)
+ {
+ Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
+ }
+#endif
+
public static void LogUsefulException(Exception e)
{
// just log useful exceptions, not all of them
diff --git a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
index 4d3bc119..bbb7a9c2 100644
--- a/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
+++ b/shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs
@@ -9,6 +9,7 @@ using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
+
using Shadowsocks.Model;
using Shadowsocks.Util;
@@ -30,8 +31,8 @@ namespace Shadowsocks.Controller
public Statistics FilteredStatistics { get; private set; }
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 const int RetryInterval = 2 * 60 * 1000; //retry 2 minutes after failed
+ private int Interval => (int)TimeSpan.FromMinutes(_config.DataCollectionMinutes).TotalMilliseconds;
private Timer _timer;
private State _state;
private List _servers;
@@ -42,8 +43,7 @@ namespace Shadowsocks.Controller
//static constructor to initialize every public static fields before refereced
static AvailabilityStatistics()
{
- var temppath = Utils.GetTempPath();
- AvailabilityStatisticsFile = Path.Combine(temppath, StatisticsFilesName);
+ AvailabilityStatisticsFile = Utils.GetTempPath(StatisticsFilesName);
}
public AvailabilityStatistics(Configuration config, StatisticsStrategyConfiguration statisticsConfig)
@@ -181,11 +181,11 @@ namespace Shadowsocks.Controller
if (!File.Exists(AvailabilityStatisticsFile))
{
var headerLine = string.Join(Delimiter, data.Select(kv => kv.Key).ToArray());
- lines = new[] {headerLine, dataLine};
+ lines = new[] { headerLine, dataLine };
}
else
{
- lines = new[] {dataLine};
+ lines = new[] { dataLine };
}
try
{
@@ -248,30 +248,29 @@ namespace Shadowsocks.Controller
Logging.Debug($"loading statistics from {path}");
if (!File.Exists(path))
{
- Console.WriteLine($"statistics file does not exist, try to reload {RetryInterval/60/1000} minutes later");
+ Console.WriteLine($"statistics file does not exist, try to reload {RetryInterval / 60 / 1000} minutes later");
_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()
- }).ToDictionary(server => server.ServerName, server=> server.data);
+ 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)
{
@@ -300,7 +299,7 @@ namespace Shadowsocks.Controller
public string ICMPStatus;
public int RoundtripTime;
public string Geolocation;
- public string ISP ;
+ public string ISP;
}
public class StatisticsData
@@ -310,6 +309,5 @@ namespace Shadowsocks.Controller
public int MinResponse;
public int MaxResponse;
}
-
}
}
diff --git a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
index 96d86ba0..e0fd12f4 100644
--- a/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
+++ b/shadowsocks-csharp/Controller/Service/GfwListUpdater.cs
@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
-using System.Text;
-using System.Net;
using System.IO;
+using System.Net;
+using System.Text;
+
+using Shadowsocks.Model;
using Shadowsocks.Properties;
-using SimpleJson;
using Shadowsocks.Util;
-using Shadowsocks.Model;
namespace Shadowsocks.Controller
{
@@ -38,13 +38,13 @@ namespace Shadowsocks.Controller
{
try
{
- File.WriteAllText(Utils.GetTempPath() + "\\gfwlist.txt", e.Result, Encoding.UTF8);
+ File.WriteAllText(Utils.GetTempPath("gfwlist.txt"), e.Result, Encoding.UTF8);
List lines = ParseResult(e.Result);
if (File.Exists(USER_RULE_FILE))
{
string local = File.ReadAllText(USER_RULE_FILE, Encoding.UTF8);
string[] rules = local.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
- foreach(string rule in rules)
+ foreach (string rule in rules)
{
if (rule.StartsWith("!") || rule.StartsWith("["))
continue;
diff --git a/shadowsocks-csharp/Controller/Service/PACServer.cs b/shadowsocks-csharp/Controller/Service/PACServer.cs
index c428fe0c..ac8b762a 100644
--- a/shadowsocks-csharp/Controller/Service/PACServer.cs
+++ b/shadowsocks-csharp/Controller/Service/PACServer.cs
@@ -146,8 +146,8 @@ Content-Type: application/x-ns-proxy-autoconfig
Content-Length: {0}
Connection: Close
-", System.Text.Encoding.UTF8.GetBytes(pac).Length) + pac;
- byte[] response = System.Text.Encoding.UTF8.GetBytes(text);
+", 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);
}
diff --git a/shadowsocks-csharp/Controller/Service/PolipoRunner.cs b/shadowsocks-csharp/Controller/Service/PolipoRunner.cs
index ad582d1e..f824c2e5 100644
--- a/shadowsocks-csharp/Controller/Service/PolipoRunner.cs
+++ b/shadowsocks-csharp/Controller/Service/PolipoRunner.cs
@@ -1,14 +1,14 @@
-using Shadowsocks.Model;
-using Shadowsocks.Properties;
-using System;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
-using System.IO.Compression;
-using System.Text;
-using System.Net.NetworkInformation;
using System.Net;
+using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
+using System.Text;
+
+using Shadowsocks.Model;
+using Shadowsocks.Properties;
using Shadowsocks.Util;
namespace Shadowsocks.Controller
@@ -16,16 +16,14 @@ namespace Shadowsocks.Controller
class PolipoRunner
{
private Process _process;
- private static string temppath;
private int _runningPort;
static PolipoRunner()
{
- temppath = Utils.GetTempPath();
try
{
- FileManager.UncompressFile(temppath + "/ss_privoxy.exe", Resources.privoxy_exe);
- FileManager.UncompressFile(temppath + "/mgwz.dll", Resources.mgwz_dll);
+ FileManager.UncompressFile(Utils.GetTempPath("ss_privoxy.exe"), Resources.privoxy_exe);
+ FileManager.UncompressFile(Utils.GetTempPath("mgwz.dll"), Resources.mgwz_dll);
}
catch (IOException e)
{
@@ -64,20 +62,16 @@ namespace Shadowsocks.Controller
polipoConfig = polipoConfig.Replace("__SOCKS_PORT__", configuration.localPort.ToString());
polipoConfig = polipoConfig.Replace("__POLIPO_BIND_PORT__", _runningPort.ToString());
polipoConfig = polipoConfig.Replace("__POLIPO_BIND_IP__", configuration.shareOverLan ? "0.0.0.0" : "127.0.0.1");
- FileManager.ByteArrayToFile(temppath + "/privoxy.conf", System.Text.Encoding.UTF8.GetBytes(polipoConfig));
+ FileManager.ByteArrayToFile(Utils.GetTempPath("privoxy.conf"), Encoding.UTF8.GetBytes(polipoConfig));
- if (!(temppath.EndsWith("\\") || temppath.EndsWith("/"))) {
- temppath = temppath + "\\";
- }
_process = new Process();
// Configure the process using the StartInfo properties.
- _process.StartInfo.FileName = temppath + "ss_privoxy.exe";
- _process.StartInfo.Arguments = " \"" + temppath + "privoxy.conf\"";
+ _process.StartInfo.FileName = "ss_privoxy.exe";
+ _process.StartInfo.Arguments = "privoxy.conf";
+ _process.StartInfo.WorkingDirectory = Utils.GetTempPath();
_process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
_process.StartInfo.UseShellExecute = true;
_process.StartInfo.CreateNoWindow = true;
- //_process.StartInfo.RedirectStandardOutput = true;
- //_process.StartInfo.RedirectStandardError = true;
_process.Start();
}
RefreshTrayArea();
diff --git a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs
index 45962353..59ff3cf6 100644
--- a/shadowsocks-csharp/Controller/Service/UpdateChecker.cs
+++ b/shadowsocks-csharp/Controller/Service/UpdateChecker.cs
@@ -1,11 +1,8 @@
using System;
-using System.Collections;
using System.Collections.Generic;
using System.Net;
-using System.Reflection;
-using System.Text;
using System.Text.RegularExpressions;
-using System.IO;
+
using SimpleJson;
using Shadowsocks.Model;
@@ -129,8 +126,7 @@ namespace Shadowsocks.Controller
{
try
{
- string temppath = Utils.GetTempPath();
- LatestVersionLocalName = Path.Combine(temppath, LatestVersionName);
+ LatestVersionLocalName = Utils.GetTempPath(LatestVersionName);
WebClient http = CreateWebClient();
http.DownloadFileCompleted += Http_DownloadFileCompleted;
http.DownloadFileAsync(new Uri(LatestVersionURL), LatestVersionLocalName);
@@ -145,7 +141,7 @@ namespace Shadowsocks.Controller
{
try
{
- if(e.Error != null)
+ if (e.Error != null)
{
Logging.LogUsefulException(e.Error);
return;
@@ -241,6 +237,5 @@ namespace Shadowsocks.Controller
return Asset.CompareVersion(x.version, y.version);
}
}
-
}
}
diff --git a/shadowsocks-csharp/Controller/ShadowsocksController.cs b/shadowsocks-csharp/Controller/ShadowsocksController.cs
index e826f8e7..1dfd81d2 100755
--- a/shadowsocks-csharp/Controller/ShadowsocksController.cs
+++ b/shadowsocks-csharp/Controller/ShadowsocksController.cs
@@ -443,12 +443,12 @@ namespace Shadowsocks.Controller
private void pacServer_UserRuleFileChanged(object sender, EventArgs e)
{
// TODO: this is a dirty hack. (from code GListUpdater.http_DownloadStringCompleted())
- if (!File.Exists(Utils.GetTempPath() + "\\gfwlist.txt"))
+ if (!File.Exists(Utils.GetTempPath("gfwlist.txt")))
{
UpdatePACFromGFWList();
return;
}
- List lines = GFWListUpdater.ParseResult(File.ReadAllText(Utils.GetTempPath() + "\\gfwlist.txt"));
+ List lines = GFWListUpdater.ParseResult(File.ReadAllText(Utils.GetTempPath("gfwlist.txt")));
if (File.Exists(PACServer.USER_RULE_FILE))
{
string local = File.ReadAllText(PACServer.USER_RULE_FILE, Encoding.UTF8);
diff --git a/shadowsocks-csharp/Encryption/MbedTLS.cs b/shadowsocks-csharp/Encryption/MbedTLS.cs
index a9266a2c..8ad9cd09 100644
--- a/shadowsocks-csharp/Encryption/MbedTLS.cs
+++ b/shadowsocks-csharp/Encryption/MbedTLS.cs
@@ -1,11 +1,10 @@
-using Shadowsocks.Controller;
-using Shadowsocks.Properties;
-using Shadowsocks.Util;
-using System;
-using System.Collections.Generic;
+using System;
using System.IO;
using System.Runtime.InteropServices;
-using System.Text;
+
+using Shadowsocks.Controller;
+using Shadowsocks.Properties;
+using Shadowsocks.Util;
namespace Shadowsocks.Encryption
{
@@ -15,8 +14,7 @@ namespace Shadowsocks.Encryption
static MbedTLS()
{
- string tempPath = Utils.GetTempPath();
- string dllPath = tempPath + "/libsscrypto.dll";
+ string dllPath = Utils.GetTempPath("libsscrypto.dll");
try
{
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
@@ -59,10 +57,9 @@ namespace Shadowsocks.Encryption
public extern static void md5_starts(IntPtr ctx);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
- public extern static void md5_update(IntPtr ctx, byte[] input, uint ilen );
+ public extern static void md5_update(IntPtr ctx, byte[] input, uint ilen);
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static void md5_finish(IntPtr ctx, byte[] output);
-
}
}
diff --git a/shadowsocks-csharp/Encryption/PolarSSL.cs b/shadowsocks-csharp/Encryption/PolarSSL.cs
index 3c1d8831..ddf59564 100755
--- a/shadowsocks-csharp/Encryption/PolarSSL.cs
+++ b/shadowsocks-csharp/Encryption/PolarSSL.cs
@@ -1,11 +1,10 @@
-using Shadowsocks.Controller;
-using Shadowsocks.Properties;
-using Shadowsocks.Util;
-using System;
-using System.Collections.Generic;
+using System;
using System.IO;
using System.Runtime.InteropServices;
-using System.Text;
+
+using Shadowsocks.Controller;
+using Shadowsocks.Properties;
+using Shadowsocks.Util;
namespace Shadowsocks.Encryption
{
@@ -19,8 +18,7 @@ namespace Shadowsocks.Encryption
static PolarSSL()
{
- string tempPath = Utils.GetTempPath();
- string dllPath = tempPath + "/libsscrypto.dll";
+ string dllPath = Utils.GetTempPath("libsscrypto.dll");
try
{
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
@@ -63,6 +61,5 @@ namespace Shadowsocks.Encryption
[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
public extern static int arc4_crypt(IntPtr ctx, int length, byte[] input, byte[] output);
-
}
}
diff --git a/shadowsocks-csharp/Encryption/Sodium.cs b/shadowsocks-csharp/Encryption/Sodium.cs
index 7a9d0c3c..3d20bdea 100755
--- a/shadowsocks-csharp/Encryption/Sodium.cs
+++ b/shadowsocks-csharp/Encryption/Sodium.cs
@@ -1,11 +1,10 @@
-using Shadowsocks.Controller;
-using Shadowsocks.Properties;
-using Shadowsocks.Util;
-using System;
-using System.Collections.Generic;
+using System;
using System.IO;
using System.Runtime.InteropServices;
-using System.Text;
+
+using Shadowsocks.Controller;
+using Shadowsocks.Properties;
+using Shadowsocks.Util;
namespace Shadowsocks.Encryption
{
@@ -15,8 +14,7 @@ namespace Shadowsocks.Encryption
static Sodium()
{
- string tempPath = Utils.GetTempPath();
- string dllPath = tempPath + "/libsscrypto.dll";
+ string dllPath = Utils.GetTempPath("libsscrypto.dll");
try
{
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
@@ -47,7 +45,6 @@ namespace Shadowsocks.Encryption
public extern static void ss_sha1_hmac_ex(byte[] key, uint keylen,
byte[] input, int ioff, uint ilen,
byte[] output);
-
}
}
diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs
index efa241e9..977ebffd 100755
--- a/shadowsocks-csharp/Program.cs
+++ b/shadowsocks-csharp/Program.cs
@@ -1,13 +1,13 @@
-using Shadowsocks.Controller;
-using Shadowsocks.Properties;
-using Shadowsocks.View;
-using System;
-using System.Collections.Generic;
+using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Windows.Forms;
+using Shadowsocks.Controller;
+using Shadowsocks.Util;
+using Shadowsocks.View;
+
namespace Shadowsocks
{
static class Program
@@ -18,7 +18,7 @@ namespace Shadowsocks
[STAThread]
static void Main()
{
- Util.Utils.ReleaseMemory(true);
+ Utils.ReleaseMemory(true);
using (Mutex mutex = new Mutex(false, "Global\\Shadowsocks_" + Application.StartupPath.GetHashCode()))
{
Application.EnableVisualStyles();
@@ -37,15 +37,19 @@ namespace Shadowsocks
return;
}
Directory.SetCurrentDirectory(Application.StartupPath);
-
+#if DEBUG
Logging.OpenLogFile();
+ // truncate privoxy log file while debugging
+ string privoxyLogFilename = Utils.GetTempPath("privoxy.log");
+ if (File.Exists(privoxyLogFilename))
+ using (new FileStream(privoxyLogFilename, FileMode.Truncate)) { }
+#else
+ Logging.OpenLogFile();
+#endif
ShadowsocksController controller = new ShadowsocksController();
-
MenuViewController viewController = new MenuViewController(controller);
-
controller.Start();
-
Application.Run();
}
}
diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs
index 450faa56..0fe193c7 100755
--- a/shadowsocks-csharp/Util/Util.cs
+++ b/shadowsocks-csharp/Util/Util.cs
@@ -11,23 +11,38 @@ namespace Shadowsocks.Util
{
public class Utils
{
+ private static string TempPath = null;
+
// return path to store temporary files
public static string GetTempPath()
{
- if (File.Exists(Application.StartupPath + "\\shadowsocks_portable_mode.txt"))
+ if (TempPath == null)
{
- try
- {
- Directory.CreateDirectory(Application.StartupPath + "\\temp");
- }
- catch (Exception e)
- {
- Logging.LogUsefulException(e);
- }
- // don't use "/", it will fail when we call explorer /select xxx/temp\xxx.log
- return Application.StartupPath + "\\temp";
+ if (File.Exists(Path.Combine(Application.StartupPath, "shadowsocks_portable_mode.txt")))
+ try
+ {
+ Directory.CreateDirectory(Path.Combine(Application.StartupPath, "temp"));
+ }
+ catch (Exception e)
+ {
+ TempPath = Path.GetTempPath();
+ Logging.LogUsefulException(e);
+ }
+ finally
+ {
+ // don't use "/", it will fail when we call explorer /select xxx/temp\xxx.log
+ TempPath = Path.Combine(Application.StartupPath, "temp");
+ }
+ else
+ TempPath = Path.GetTempPath();
}
- return Path.GetTempPath();
+ return TempPath;
+ }
+
+ // return a full path with filename combined which pointed to the temporary directory
+ public static string GetTempPath(string filename)
+ {
+ return Path.Combine(GetTempPath(), filename);
}
public static void ReleaseMemory(bool removePages)
From 9194b0325fe27f46eb43a0dc0a51b7d5c0785f02 Mon Sep 17 00:00:00 2001
From: kimw
Date: Mon, 4 Jan 2016 23:57:30 +0800
Subject: [PATCH 19/26] avoid warning message while compile
---
shadowsocks-csharp/Encryption/MbedTLS.cs | 2 +-
.../Model/StatisticsStrategyConfiguration.cs | 15 +++++++--------
2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/shadowsocks-csharp/Encryption/MbedTLS.cs b/shadowsocks-csharp/Encryption/MbedTLS.cs
index 8ad9cd09..a7162f66 100644
--- a/shadowsocks-csharp/Encryption/MbedTLS.cs
+++ b/shadowsocks-csharp/Encryption/MbedTLS.cs
@@ -19,7 +19,7 @@ namespace Shadowsocks.Encryption
{
FileManager.UncompressFile(dllPath, Resources.libsscrypto_dll);
}
- catch (IOException ex)
+ catch (IOException)
{
}
catch (Exception e)
diff --git a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs
index 62a48c2e..70433117 100644
--- a/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs
+++ b/shadowsocks-csharp/Model/StatisticsStrategyConfiguration.cs
@@ -3,17 +3,17 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
-using Shadowsocks.Controller;
-using Shadowsocks.Controller.Strategy;
-using SimpleJson;
+
using Newtonsoft.Json;
+using Shadowsocks.Controller;
+
namespace Shadowsocks.Model
{
[Serializable]
public class StatisticsStrategyConfiguration
{
- public static readonly string ID = "com.shadowsocks.strategy.statistics";
+ public static readonly string ID = "com.shadowsocks.strategy.statistics";
private bool _statisticsEnabled = true;
private bool _byIsp = false;
private bool _byHourOfDay = false;
@@ -21,7 +21,6 @@ namespace Shadowsocks.Model
private int _dataCollectionMinutes = 10;
private int _repeatTimesNum = 4;
-
private const string ConfigFile = "statistics-config.json";
public static StatisticsStrategyConfiguration Load()
@@ -32,7 +31,7 @@ namespace Shadowsocks.Model
var configuration = JsonConvert.DeserializeObject(content);
return configuration;
}
- catch (FileNotFoundException e)
+ catch (FileNotFoundException)
{
var configuration = new StatisticsStrategyConfiguration();
Save(configuration);
@@ -62,10 +61,10 @@ namespace Shadowsocks.Model
public StatisticsStrategyConfiguration()
{
- var availabilityStatisticsType = typeof (AvailabilityStatistics);
+ var availabilityStatisticsType = typeof(AvailabilityStatistics);
var statisticsData = availabilityStatisticsType.GetNestedType("StatisticsData");
var properties = statisticsData.GetFields(BindingFlags.Instance | BindingFlags.Public);
- Calculations = properties.ToDictionary(p => p.Name, _ => (float) 0);
+ Calculations = properties.ToDictionary(p => p.Name, _ => (float)0);
}
public bool StatisticsEnabled
From b813d9eebc0f322ccc6354c4dd30e66be655b973 Mon Sep 17 00:00:00 2001
From: kimw
Date: Mon, 4 Jan 2016 23:58:24 +0800
Subject: [PATCH 20/26] featured middle click on tray pops up log viewer
---
shadowsocks-csharp/View/MenuViewController.cs | 25 ++++++++++++++-----
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs
index b47fe038..25a3b3e8 100755
--- a/shadowsocks-csharp/View/MenuViewController.cs
+++ b/shadowsocks-csharp/View/MenuViewController.cs
@@ -1,16 +1,17 @@
-using Shadowsocks.Controller;
-using Shadowsocks.Model;
-using Shadowsocks.Properties;
-using System;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
-using System.Text;
using System.Windows.Forms;
+
using ZXing;
using ZXing.Common;
using ZXing.QrCode;
+using Shadowsocks.Controller;
+using Shadowsocks.Model;
+using Shadowsocks.Properties;
+
namespace Shadowsocks.View
{
public class MenuViewController
@@ -69,6 +70,7 @@ namespace Shadowsocks.View
_notifyIcon.Visible = true;
_notifyIcon.ContextMenu = contextMenu1;
_notifyIcon.BalloonTipClicked += notifyIcon1_BalloonTipClicked;
+ _notifyIcon.MouseClick += notifyIcon1_Click;
_notifyIcon.MouseDoubleClick += notifyIcon1_DoubleClick;
_notifyIcon.BalloonTipClosed += _notifyIcon_BalloonTipClosed;
@@ -204,7 +206,6 @@ namespace Shadowsocks.View
});
}
-
private void controller_ConfigChanged(object sender, EventArgs e)
{
LoadCurrentConfiguration();
@@ -420,6 +421,18 @@ namespace Shadowsocks.View
Process.Start("https://github.com/shadowsocks/shadowsocks-windows");
}
+ private void notifyIcon1_Click(object sender, MouseEventArgs e)
+ {
+ if (e.Button == MouseButtons.Left)
+ {
+ // TODO: show something interesting
+ }
+ else if (e.Button == MouseButtons.Middle)
+ {
+ ShowLogForms();
+ }
+ }
+
private void notifyIcon1_DoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
From 84f14d71c9a516649e55a1c09a2a823018fd83cf Mon Sep 17 00:00:00 2001
From: kimw
Date: Tue, 5 Jan 2016 00:01:06 +0800
Subject: [PATCH 21/26] clean up avoid log message on timeout and network cut
off. it's useless but confuse users.
---
shadowsocks-csharp/Controller/Logging.cs | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs
index 3db34658..edf84144 100755
--- a/shadowsocks-csharp/Controller/Logging.cs
+++ b/shadowsocks-csharp/Controller/Logging.cs
@@ -84,11 +84,19 @@ namespace Shadowsocks.Controller
}
else if (se.SocketErrorCode == SocketError.NotConnected)
{
- // close when not connected
+ // The application tried to send or receive data, and the System.Net.Sockets.Socket is not connected.
+ }
+ else if (se.SocketErrorCode == SocketError.HostUnreachable)
+ {
+ // There is no network route to the specified host.
+ }
+ else if (se.SocketErrorCode == SocketError.TimedOut)
+ {
+ // The connection attempt timed out, or the connected host has failed to respond.
}
else
{
- Console.WriteLine(e);
+ Info(e);
}
}
else if (e is ObjectDisposedException)
@@ -96,7 +104,7 @@ namespace Shadowsocks.Controller
}
else
{
- Console.WriteLine(e);
+ Info(e);
}
}
}
From 04486094f786e2ae3fc5802715709b5aa2fdf0bc Mon Sep 17 00:00:00 2001
From: kimw
Date: Tue, 5 Jan 2016 03:26:55 +0800
Subject: [PATCH 22/26] fixed compile errors in Release mode
---
shadowsocks-csharp/Controller/Logging.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/shadowsocks-csharp/Controller/Logging.cs b/shadowsocks-csharp/Controller/Logging.cs
index edf84144..38201660 100755
--- a/shadowsocks-csharp/Controller/Logging.cs
+++ b/shadowsocks-csharp/Controller/Logging.cs
@@ -48,9 +48,9 @@ namespace Shadowsocks.Controller
#endif
}
-#if DEBUG
public static void Debug(EndPoint local, EndPoint remote, int len, string header = null, string tailer = null)
{
+#if DEBUG
if (header == null && tailer == null)
Debug($"{local} => {remote} (size={len})");
else if (header == null && tailer != null)
@@ -59,13 +59,15 @@ namespace Shadowsocks.Controller
Debug($"{header}: {local} => {remote} (size={len})");
else
Debug($"{header}: {local} => {remote} (size={len}), {tailer}");
+#endif
}
public static void Debug(Socket sock, int len, string header = null, string tailer = null)
{
+#if DEBUG
Debug(sock.LocalEndPoint, sock.RemoteEndPoint, len, header, tailer);
- }
#endif
+ }
public static void LogUsefulException(Exception e)
{
From c2095b5ad7ef7120f8cee15fdf1dbf28957a1654 Mon Sep 17 00:00:00 2001
From: kimw
Date: Tue, 5 Jan 2016 03:38:30 +0800
Subject: [PATCH 23/26] migrated SimpleJson => Newtonesoft.Json, and of cause
removed SimpleJson source files.
---
shadowsocks-csharp/3rd/SimpleJson.cs | 1902 -----------------
.../Service/AvailabilityStatistics.cs | 58 +-
.../Controller/Service/GfwListUpdater.cs | 6 +-
.../Controller/Service/UpdateChecker.cs | 32 +-
.../Controller/ShadowsocksController.cs | 2 +
.../Controller/Strategy/StatisticsStrategy.cs | 3 +-
shadowsocks-csharp/Model/Configuration.cs | 27 +-
shadowsocks-csharp/Model/Server.cs | 7 +-
.../StatisticsStrategyConfigurationForm.cs | 14 +-
shadowsocks-csharp/shadowsocks-csharp.csproj | 2 +-
10 files changed, 74 insertions(+), 1979 deletions(-)
delete mode 100644 shadowsocks-csharp/3rd/SimpleJson.cs
diff --git a/shadowsocks-csharp/3rd/SimpleJson.cs b/shadowsocks-csharp/3rd/SimpleJson.cs
deleted file mode 100644
index e3301f4e..00000000
--- a/shadowsocks-csharp/3rd/SimpleJson.cs
+++ /dev/null
@@ -1,1902 +0,0 @@
-//-----------------------------------------------------------------------
-//
-// Copyright (c) 2011, The Outercurve Foundation.
-//
-// Licensed under the MIT License (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-// http://www.opensource.org/licenses/mit-license.php
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// Nathan Totten (ntotten.com), Jim Zimmerman (jimzimmerman.com) and Prabir Shrestha (prabir.me)
-// https://github.com/facebook-csharp-sdk/simple-json
-//-----------------------------------------------------------------------
-
-// VERSION:
-
-// NOTE: uncomment the following line to make SimpleJson class internal.
-//#define SIMPLE_JSON_INTERNAL
-
-// NOTE: uncomment the following line to make JsonArray and JsonObject class internal.
-//#define SIMPLE_JSON_OBJARRAYINTERNAL
-
-// NOTE: uncomment the following line to enable dynamic support.
-//#define SIMPLE_JSON_DYNAMIC
-
-// NOTE: uncomment the following line to enable DataContract support.
-//#define SIMPLE_JSON_DATACONTRACT
-
-// NOTE: uncomment the following line to use Reflection.Emit (better performance) instead of method.invoke().
-// don't enable ReflectionEmit for WinRT, Silverlight and WP7.
-//#define SIMPLE_JSON_REFLECTIONEMIT
-
-// NOTE: uncomment the following line if you are compiling under Window Metro style application/library.
-// usually already defined in properties
-//#define NETFX_CORE;
-
-// original json parsing code from http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
-#if SIMPLE_JSON_DYNAMIC
-using System.Dynamic;
-#endif
-using System.Globalization;
-using System.Reflection;
-#if SIMPLE_JSON_REFLECTIONEMIT
-using System.Reflection.Emit;
-#endif
-#if SIMPLE_JSON_DATACONTRACT
-using System.Runtime.Serialization;
-#endif
-using System.Text;
-using SimpleJson.Reflection;
-
-namespace SimpleJson
-{
- #region JsonArray
-
- ///
- /// Represents the json array.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
-#if SIMPLE_JSON_OBJARRAYINTERNAL
- internal
-#else
- public
-#endif
- class JsonArray : List