@@ -1,3 +1,6 @@ | |||
2.5.2 2015-08-04 | |||
- Add log viewer | |||
2.5.1 2015-07-26 | |||
- Prevent HA from switching servers too frequently | |||
- Fix server settings can not be updated when using HA | |||
@@ -18,7 +18,7 @@ namespace Shadowsocks.Controller | |||
public string LatestVersionURL; | |||
public event EventHandler NewVersionFound; | |||
public const string Version = "2.5.1"; | |||
public const string Version = "2.5.2"; | |||
public void CheckUpdate(Configuration config) | |||
{ | |||
@@ -0,0 +1,112 @@ | |||
namespace Shadowsocks.View | |||
{ | |||
partial class LogForm | |||
{ | |||
/// <summary> | |||
/// Required designer variable. | |||
/// </summary> | |||
private System.ComponentModel.IContainer components = null; | |||
/// <summary> | |||
/// Clean up any resources being used. | |||
/// </summary> | |||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> | |||
protected override void Dispose(bool disposing) | |||
{ | |||
if (disposing && (components != null)) | |||
{ | |||
components.Dispose(); | |||
} | |||
base.Dispose(disposing); | |||
} | |||
#region Windows Form Designer generated code | |||
/// <summary> | |||
/// Required method for Designer support - do not modify | |||
/// the contents of this method with the code editor. | |||
/// </summary> | |||
private void InitializeComponent() | |||
{ | |||
this.components = new System.ComponentModel.Container(); | |||
this.textBox1 = new System.Windows.Forms.TextBox(); | |||
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); | |||
this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components); | |||
this.menuItem1 = new System.Windows.Forms.MenuItem(); | |||
this.menuItem2 = new System.Windows.Forms.MenuItem(); | |||
this.menuItem4 = new System.Windows.Forms.MenuItem(); | |||
this.SuspendLayout(); | |||
// | |||
// textBox1 | |||
// | |||
this.textBox1.BackColor = System.Drawing.Color.Black; | |||
this.textBox1.Dock = System.Windows.Forms.DockStyle.Fill; | |||
this.textBox1.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); | |||
this.textBox1.ForeColor = System.Drawing.Color.White; | |||
this.textBox1.Location = new System.Drawing.Point(0, 0); | |||
this.textBox1.MaxLength = 2147483647; | |||
this.textBox1.Multiline = true; | |||
this.textBox1.Name = "textBox1"; | |||
this.textBox1.ReadOnly = true; | |||
this.textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both; | |||
this.textBox1.Size = new System.Drawing.Size(547, 382); | |||
this.textBox1.TabIndex = 0; | |||
this.textBox1.WordWrap = false; | |||
// | |||
// contextMenuStrip1 | |||
// | |||
this.contextMenuStrip1.Name = "contextMenuStrip1"; | |||
this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4); | |||
// | |||
// mainMenu1 | |||
// | |||
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||
this.menuItem1}); | |||
// | |||
// menuItem1 | |||
// | |||
this.menuItem1.Index = 0; | |||
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { | |||
this.menuItem2, | |||
this.menuItem4}); | |||
this.menuItem1.Text = "&File"; | |||
// | |||
// menuItem2 | |||
// | |||
this.menuItem2.Index = 0; | |||
this.menuItem2.Text = "&Open Location"; | |||
this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click); | |||
// | |||
// menuItem4 | |||
// | |||
this.menuItem4.Index = 1; | |||
this.menuItem4.Text = "E&xit"; | |||
this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click); | |||
// | |||
// LogForm | |||
// | |||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); | |||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; | |||
this.ClientSize = new System.Drawing.Size(547, 382); | |||
this.Controls.Add(this.textBox1); | |||
this.Menu = this.mainMenu1; | |||
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.ResumeLayout(false); | |||
this.PerformLayout(); | |||
} | |||
#endregion | |||
private System.Windows.Forms.TextBox textBox1; | |||
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; | |||
private System.Windows.Forms.MainMenu mainMenu1; | |||
private System.Windows.Forms.MenuItem menuItem1; | |||
private System.Windows.Forms.MenuItem menuItem2; | |||
private System.Windows.Forms.MenuItem menuItem4; | |||
} | |||
} |
@@ -0,0 +1,109 @@ | |||
using Shadowsocks.Properties; | |||
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; | |||
namespace Shadowsocks.View | |||
{ | |||
public partial class LogForm : Form | |||
{ | |||
FileSystemWatcher watcher; | |||
long lastOffset; | |||
string filename; | |||
Timer timer; | |||
const int BACK_OFFSET = 65536; | |||
public LogForm(string filename) | |||
{ | |||
this.filename = filename; | |||
InitializeComponent(); | |||
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon()); | |||
} | |||
private void Timer_Tick(object sender, EventArgs e) | |||
{ | |||
UpdateContent(); | |||
} | |||
private void InitContent() | |||
{ | |||
using (StreamReader reader = new StreamReader(new FileStream(filename, | |||
FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) | |||
{ | |||
if (reader.BaseStream.Length > BACK_OFFSET) | |||
{ | |||
reader.BaseStream.Seek(-BACK_OFFSET, SeekOrigin.End); | |||
reader.ReadLine(); | |||
} | |||
string line = ""; | |||
while ((line = reader.ReadLine()) != null) | |||
textBox1.AppendText(line + "\r\n"); | |||
textBox1.ScrollToCaret(); | |||
lastOffset = reader.BaseStream.Position; | |||
} | |||
} | |||
private void UpdateContent() | |||
{ | |||
using (StreamReader reader = new StreamReader(new FileStream(filename, | |||
FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) | |||
{ | |||
reader.BaseStream.Seek(lastOffset, SeekOrigin.Begin); | |||
string line = ""; | |||
bool changed = false; | |||
while ((line = reader.ReadLine()) != null) | |||
{ | |||
changed = true; | |||
textBox1.AppendText(line + "\r\n"); | |||
} | |||
if (changed) | |||
{ | |||
textBox1.ScrollToCaret(); | |||
} | |||
lastOffset = reader.BaseStream.Position; | |||
} | |||
} | |||
private void LogForm_Load(object sender, EventArgs e) | |||
{ | |||
InitContent(); | |||
timer = new Timer(); | |||
timer.Interval = 300; | |||
timer.Tick += Timer_Tick; | |||
timer.Start(); | |||
} | |||
private void LogForm_FormClosing(object sender, FormClosingEventArgs e) | |||
{ | |||
timer.Stop(); | |||
} | |||
private void menuItem2_Click(object sender, EventArgs e) | |||
{ | |||
string argument = @"/select, " + filename; | |||
System.Diagnostics.Process.Start("explorer.exe", argument); | |||
} | |||
private void menuItem3_Click(object sender, EventArgs e) | |||
{ | |||
} | |||
private void menuItem4_Click(object sender, EventArgs e) | |||
{ | |||
this.Close(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,126 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<root> | |||
<!-- | |||
Microsoft ResX Schema | |||
Version 2.0 | |||
The primary goals of this format is to allow a simple XML format | |||
that is mostly human readable. The generation and parsing of the | |||
various data types are done through the TypeConverter classes | |||
associated with the data types. | |||
Example: | |||
... ado.net/XML headers & schema ... | |||
<resheader name="resmimetype">text/microsoft-resx</resheader> | |||
<resheader name="version">2.0</resheader> | |||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> | |||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> | |||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> | |||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> | |||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> | |||
<value>[base64 mime encoded serialized .NET Framework object]</value> | |||
</data> | |||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> | |||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> | |||
<comment>This is a comment</comment> | |||
</data> | |||
There are any number of "resheader" rows that contain simple | |||
name/value pairs. | |||
Each data row contains a name, and value. The row also contains a | |||
type or mimetype. Type corresponds to a .NET class that support | |||
text/value conversion through the TypeConverter architecture. | |||
Classes that don't support this are serialized and stored with the | |||
mimetype set. | |||
The mimetype is used for serialized objects, and tells the | |||
ResXResourceReader how to depersist the object. This is currently not | |||
extensible. For a given mimetype the value must be set accordingly: | |||
Note - application/x-microsoft.net.object.binary.base64 is the format | |||
that the ResXResourceWriter will generate, however the reader can | |||
read any of the formats listed below. | |||
mimetype: application/x-microsoft.net.object.binary.base64 | |||
value : The object must be serialized with | |||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter | |||
: and then encoded with base64 encoding. | |||
mimetype: application/x-microsoft.net.object.soap.base64 | |||
value : The object must be serialized with | |||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter | |||
: and then encoded with base64 encoding. | |||
mimetype: application/x-microsoft.net.object.bytearray.base64 | |||
value : The object must be serialized into a byte array | |||
: using a System.ComponentModel.TypeConverter | |||
: and then encoded with base64 encoding. | |||
--> | |||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> | |||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> | |||
<xsd:element name="root" msdata:IsDataSet="true"> | |||
<xsd:complexType> | |||
<xsd:choice maxOccurs="unbounded"> | |||
<xsd:element name="metadata"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" use="required" type="xsd:string" /> | |||
<xsd:attribute name="type" type="xsd:string" /> | |||
<xsd:attribute name="mimetype" type="xsd:string" /> | |||
<xsd:attribute ref="xml:space" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="assembly"> | |||
<xsd:complexType> | |||
<xsd:attribute name="alias" type="xsd:string" /> | |||
<xsd:attribute name="name" type="xsd:string" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="data"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> | |||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> | |||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> | |||
<xsd:attribute ref="xml:space" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
<xsd:element name="resheader"> | |||
<xsd:complexType> | |||
<xsd:sequence> | |||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> | |||
</xsd:sequence> | |||
<xsd:attribute name="name" type="xsd:string" use="required" /> | |||
</xsd:complexType> | |||
</xsd:element> | |||
</xsd:choice> | |||
</xsd:complexType> | |||
</xsd:element> | |||
</xsd:schema> | |||
<resheader name="resmimetype"> | |||
<value>text/microsoft-resx</value> | |||
</resheader> | |||
<resheader name="version"> | |||
<value>2.0</value> | |||
</resheader> | |||
<resheader name="reader"> | |||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</resheader> | |||
<resheader name="writer"> | |||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> | |||
</resheader> | |||
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |||
<value>17, 17</value> | |||
</metadata> | |||
<metadata name="mainMenu1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> | |||
<value>172, 17</value> | |||
</metadata> | |||
</root> |