@@ -1,6 +1,7 @@ | |||||
Backup/ | Backup/ | ||||
shadowsocks-csharp/bin/ | |||||
shadowsocks-csharp/obj/ | |||||
bin/ | |||||
obj/ | |||||
shadowsocks-csharp/shadowsocks-csharp.csproj.user | shadowsocks-csharp/shadowsocks-csharp.csproj.user | ||||
TestResults | |||||
*.suo | *.suo | ||||
@@ -3,6 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio Express 2012 for Windows Desktop | # Visual Studio Express 2012 for Windows Desktop | ||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "shadowsocks-csharp", "shadowsocks-csharp\shadowsocks-csharp.csproj", "{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}" | ||||
EndProject | EndProject | ||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test\test.csproj", "{45913187-0685-4903-B250-DCEF0479CD86}" | |||||
ProjectSection(ProjectDependencies) = postProject | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} = {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} | |||||
EndProjectSection | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|x86 = Debug|x86 | Debug|x86 = Debug|x86 | ||||
@@ -14,6 +19,10 @@ Global | |||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Debug|x86.Deploy.0 = Debug|x86 | ||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.ActiveCfg = Release|x86 | ||||
{8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 | {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062}.Release|x86.Build.0 = Release|x86 | ||||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.ActiveCfg = Debug|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Debug|x86.Build.0 = Debug|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.ActiveCfg = Release|x86 | |||||
{45913187-0685-4903-B250-DCEF0479CD86}.Release|x86.Build.0 = Release|x86 | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -0,0 +1,152 @@ | |||||
using System; | |||||
using System.Collections; | |||||
using System.Collections.Generic; | |||||
using System.Net; | |||||
using System.Reflection; | |||||
using System.Text; | |||||
using System.Text.RegularExpressions; | |||||
using System.Xml; | |||||
namespace Shadowsocks.Controller | |||||
{ | |||||
public class UpdateChecker | |||||
{ | |||||
private const string UpdateURL = "https://sourceforge.net/api/file/index/project-id/1817190/path/dist/mtime/desc/limit/10/rss"; | |||||
public string LatestVersionNumber; | |||||
public string LatestVersionURL; | |||||
public event EventHandler NewVersionFound; | |||||
public void CheckUpdate() | |||||
{ | |||||
// TODO test failures | |||||
WebClient http = new WebClient(); | |||||
http.DownloadStringCompleted += http_DownloadStringCompleted; | |||||
http.DownloadStringAsync(new Uri(UpdateURL)); | |||||
} | |||||
public static int CompareVersion(string l, string r) | |||||
{ | |||||
var ls = l.Split('.'); | |||||
var rs = r.Split('.'); | |||||
for (int i = 0; i < Math.Max(ls.Length, rs.Length); i++) | |||||
{ | |||||
int lp = (i < ls.Length) ? int.Parse(ls[i]) : 0; | |||||
int rp = (i < rs.Length) ? int.Parse(rs[i]) : 0; | |||||
if (lp != rp) | |||||
{ | |||||
return lp - rp; | |||||
} | |||||
} | |||||
return 0; | |||||
} | |||||
public class VersionComparer : IComparer<string> | |||||
{ | |||||
// Calls CaseInsensitiveComparer.Compare with the parameters reversed. | |||||
public int Compare(string x, string y) | |||||
{ | |||||
return CompareVersion(ParseVersionFromURL(x), ParseVersionFromURL(y)); | |||||
} | |||||
} | |||||
private static string ParseVersionFromURL(string url) | |||||
{ | |||||
Match match = Regex.Match(url, @".*Shadowsocks-win.*?-([\d\.]+)\.\w+", RegexOptions.IgnoreCase); | |||||
if (match.Success) | |||||
{ | |||||
if (match.Groups.Count == 2) | |||||
{ | |||||
return match.Groups[1].Value; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
private void SortVersions(List<string> versions) | |||||
{ | |||||
versions.Sort(new VersionComparer()); | |||||
} | |||||
private bool IsNewVersion(string url) | |||||
{ | |||||
// check dotnet 4.0 | |||||
AssemblyName[] references = Assembly.GetExecutingAssembly().GetReferencedAssemblies(); | |||||
Version dotNetVersion = Environment.Version; | |||||
foreach (AssemblyName reference in references) | |||||
{ | |||||
if (reference.Name == "mscorlib") | |||||
{ | |||||
dotNetVersion = reference.Version; | |||||
} | |||||
} | |||||
if (dotNetVersion.Major >= 4) | |||||
{ | |||||
if (url.IndexOf("dotnet4.0") < 0) | |||||
{ | |||||
return false; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
if (url.IndexOf("dotnet4.0") >= 0) | |||||
{ | |||||
return false; | |||||
} | |||||
} | |||||
string version = ParseVersionFromURL(url); | |||||
if (version == null) | |||||
{ | |||||
return false; | |||||
} | |||||
string currentVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString(); | |||||
return CompareVersion(version, currentVersion) > 0; | |||||
} | |||||
private void http_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) | |||||
{ | |||||
try | |||||
{ | |||||
string response = e.Result; | |||||
XmlDocument xmlDoc = new XmlDocument(); | |||||
xmlDoc.LoadXml(response); | |||||
XmlNodeList elements = xmlDoc.GetElementsByTagName("media:content"); | |||||
List<string> versions = new List<string>(); | |||||
foreach (XmlNode el in elements) | |||||
{ | |||||
foreach (XmlAttribute attr in el.Attributes) | |||||
{ | |||||
if (attr.Name == "url") | |||||
{ | |||||
Console.WriteLine(attr.Value); | |||||
if (IsNewVersion(attr.Value)) | |||||
{ | |||||
versions.Add(attr.Value); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
if (versions.Count == 0) | |||||
{ | |||||
return; | |||||
} | |||||
// sort versions | |||||
SortVersions(versions); | |||||
LatestVersionURL = versions[versions.Count - 1]; | |||||
LatestVersionNumber = ParseVersionFromURL(LatestVersionURL); | |||||
if (NewVersionFound != null) | |||||
{ | |||||
NewVersionFound(this, new EventArgs()); | |||||
} | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
Console.Write(ex.ToString()); | |||||
return; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -71,7 +71,7 @@ namespace Shadowsocks.Properties { | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
/// Looks up a localized string similar to proxyAddress = "127.0.0.1" | |||||
/// Looks up a localized string similar to proxyAddress = "__POLIPO_BIND_IP__" | |||||
/// | /// | ||||
///socksParentProxy = "127.0.0.1:__SOCKS_PORT__" | ///socksParentProxy = "127.0.0.1:__SOCKS_PORT__" | ||||
///socksProxyType = socks5 | ///socksProxyType = socks5 | ||||
@@ -13,6 +13,7 @@ namespace Shadowsocks.View | |||||
public partial class ConfigForm : Form | public partial class ConfigForm : Form | ||||
{ | { | ||||
private ShadowsocksController controller; | private ShadowsocksController controller; | ||||
private UpdateChecker updateChecker; | |||||
// this is a copy of configuration that we are working on | // this is a copy of configuration that we are working on | ||||
private Configuration modifiedConfiguration; | private Configuration modifiedConfiguration; | ||||
@@ -30,6 +31,9 @@ namespace Shadowsocks.View | |||||
controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | ||||
controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | ||||
this.updateChecker = new UpdateChecker(); | |||||
updateChecker.NewVersionFound += updateChecker_NewVersionFound; | |||||
LoadCurrentConfiguration(); | LoadCurrentConfiguration(); | ||||
} | } | ||||
@@ -55,6 +59,21 @@ namespace Shadowsocks.View | |||||
System.Diagnostics.Process.Start("explorer.exe", argument); | System.Diagnostics.Process.Start("explorer.exe", argument); | ||||
} | } | ||||
void updateChecker_NewVersionFound(object sender, EventArgs e) | |||||
{ | |||||
notifyIcon1.BalloonTipTitle = "Shadowsocks " + updateChecker.LatestVersionNumber + " Update Found"; | |||||
notifyIcon1.BalloonTipText = "You can click here to download"; | |||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.BalloonTipClicked += notifyIcon1_BalloonTipClicked; | |||||
notifyIcon1.ShowBalloonTip(5000); | |||||
isFirstRun = false; | |||||
} | |||||
void notifyIcon1_BalloonTipClicked(object sender, EventArgs e) | |||||
{ | |||||
Process.Start(updateChecker.LatestVersionURL); | |||||
} | |||||
private void ShowWindow() | private void ShowWindow() | ||||
{ | { | ||||
@@ -176,6 +195,7 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
isFirstRun = true; | isFirstRun = true; | ||||
} | } | ||||
updateChecker.CheckUpdate(); | |||||
} | } | ||||
private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) | private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) | ||||
@@ -242,6 +262,7 @@ namespace Shadowsocks.View | |||||
{ | { | ||||
notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; | notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; | ||||
notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; | notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; | ||||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||||
notifyIcon1.ShowBalloonTip(0); | notifyIcon1.ShowBalloonTip(0); | ||||
isFirstRun = false; | isFirstRun = false; | ||||
} | } | ||||
@@ -10,7 +10,7 @@ | |||||
<AppDesignerFolder>Properties</AppDesignerFolder> | <AppDesignerFolder>Properties</AppDesignerFolder> | ||||
<RootNamespace>Shadowsocks</RootNamespace> | <RootNamespace>Shadowsocks</RootNamespace> | ||||
<AssemblyName>Shadowsocks</AssemblyName> | <AssemblyName>Shadowsocks</AssemblyName> | ||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion> | |||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | |||||
<FileAlignment>512</FileAlignment> | <FileAlignment>512</FileAlignment> | ||||
<StartupObject> | <StartupObject> | ||||
</StartupObject> | </StartupObject> | ||||
@@ -21,8 +21,7 @@ | |||||
<UpgradeBackupLocation> | <UpgradeBackupLocation> | ||||
</UpgradeBackupLocation> | </UpgradeBackupLocation> | ||||
<OldToolsVersion>3.5</OldToolsVersion> | <OldToolsVersion>3.5</OldToolsVersion> | ||||
<TargetFrameworkProfile> | |||||
</TargetFrameworkProfile> | |||||
<TargetFrameworkProfile>Client</TargetFrameworkProfile> | |||||
<PublishUrl>publish\</PublishUrl> | <PublishUrl>publish\</PublishUrl> | ||||
<Install>true</Install> | <Install>true</Install> | ||||
<InstallFrom>Disk</InstallFrom> | <InstallFrom>Disk</InstallFrom> | ||||
@@ -63,12 +62,14 @@ | |||||
<Reference Include="System.Data" /> | <Reference Include="System.Data" /> | ||||
<Reference Include="System.Drawing" /> | <Reference Include="System.Drawing" /> | ||||
<Reference Include="System.Windows.Forms" /> | <Reference Include="System.Windows.Forms" /> | ||||
<Reference Include="System.XML" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Compile Include="3rd\QRCodeCS.cs" /> | <Compile Include="3rd\QRCodeCS.cs" /> | ||||
<Compile Include="3rd\SimpleJson.cs" /> | <Compile Include="3rd\SimpleJson.cs" /> | ||||
<Compile Include="Controller\FileManager.cs" /> | <Compile Include="Controller\FileManager.cs" /> | ||||
<Compile Include="Controller\Logging.cs" /> | <Compile Include="Controller\Logging.cs" /> | ||||
<Compile Include="Controller\UpdateChecker.cs" /> | |||||
<Compile Include="Encrypt\EncryptorBase.cs" /> | <Compile Include="Encrypt\EncryptorBase.cs" /> | ||||
<Compile Include="Encrypt\EncryptorFactory.cs" /> | <Compile Include="Encrypt\EncryptorFactory.cs" /> | ||||
<Compile Include="Encrypt\PolarSSL.cs" /> | <Compile Include="Encrypt\PolarSSL.cs" /> | ||||
@@ -0,0 +1,36 @@ | |||||
using System.Reflection; | |||||
using System.Runtime.CompilerServices; | |||||
using System.Runtime.InteropServices; | |||||
// General Information about an assembly is controlled through the following | |||||
// set of attributes. Change these attribute values to modify the information | |||||
// associated with an assembly. | |||||
[assembly: AssemblyTitle("test")] | |||||
[assembly: AssemblyDescription("")] | |||||
[assembly: AssemblyConfiguration("")] | |||||
[assembly: AssemblyCompany("")] | |||||
[assembly: AssemblyProduct("test")] | |||||
[assembly: AssemblyCopyright("Copyright © 2014")] | |||||
[assembly: AssemblyTrademark("")] | |||||
[assembly: AssemblyCulture("")] | |||||
// Setting ComVisible to false makes the types in this assembly not visible | |||||
// to COM components. If you need to access a type in this assembly from | |||||
// COM, set the ComVisible attribute to true on that type. | |||||
[assembly: ComVisible(false)] | |||||
// The following GUID is for the ID of the typelib if this project is exposed to COM | |||||
[assembly: Guid("f74e87ac-7e3a-444b-a1d9-8b91a674c60f")] | |||||
// Version information for an assembly consists of the following four values: | |||||
// | |||||
// Major Version | |||||
// Minor Version | |||||
// Build Number | |||||
// Revision | |||||
// | |||||
// You can specify all the values or you can default the Build and Revision Numbers | |||||
// by using the '*' as shown below: | |||||
// [assembly: AssemblyVersion("1.0.*")] | |||||
[assembly: AssemblyVersion("1.0.0.0")] | |||||
[assembly: AssemblyFileVersion("1.0.0.0")] |
@@ -0,0 +1,22 @@ | |||||
using System; | |||||
using Microsoft.VisualStudio.TestTools.UnitTesting; | |||||
using Shadowsocks.Controller; | |||||
namespace test | |||||
{ | |||||
[TestClass] | |||||
public class UnitTest | |||||
{ | |||||
[TestMethod] | |||||
public void TestCompareVersion() | |||||
{ | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1.0", "2.3.1") == 0); | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("1.2", "1.3") < 0); | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.2") > 0); | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("1.3", "1.3") == 0); | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("1.2.1", "1.2") > 0); | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("2.3.1", "2.4") < 0); | |||||
Assert.IsTrue(UpdateChecker.CompareVersion("1.3.2", "1.3.1") > 0); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,81 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||||
<PropertyGroup> | |||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||||
<ProjectGuid>{45913187-0685-4903-B250-DCEF0479CD86}</ProjectGuid> | |||||
<OutputType>Library</OutputType> | |||||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||||
<RootNamespace>test</RootNamespace> | |||||
<AssemblyName>test</AssemblyName> | |||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | |||||
<FileAlignment>512</FileAlignment> | |||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> | |||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> | |||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath> | |||||
<IsCodedUITest>False</IsCodedUITest> | |||||
<TestProjectType>UnitTest</TestProjectType> | |||||
<TargetFrameworkProfile /> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> | |||||
<OutputPath>bin\x86\Debug\</OutputPath> | |||||
<PlatformTarget>x86</PlatformTarget> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> | |||||
<OutputPath>bin\x86\Release\</OutputPath> | |||||
<PlatformTarget>x86</PlatformTarget> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<Reference Include="System" /> | |||||
</ItemGroup> | |||||
<Choose> | |||||
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'"> | |||||
<ItemGroup> | |||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> | |||||
</ItemGroup> | |||||
</When> | |||||
<Otherwise> | |||||
<ItemGroup> | |||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" /> | |||||
</ItemGroup> | |||||
</Otherwise> | |||||
</Choose> | |||||
<ItemGroup> | |||||
<Compile Include="UnitTest.cs" /> | |||||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<ProjectReference Include="..\shadowsocks-csharp\shadowsocks-csharp.csproj"> | |||||
<Project>{8c02d2f7-7cdb-4d55-9f25-cd03ef4aa062}</Project> | |||||
<Name>shadowsocks-csharp</Name> | |||||
</ProjectReference> | |||||
</ItemGroup> | |||||
<Choose> | |||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'"> | |||||
<ItemGroup> | |||||
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<Private>False</Private> | |||||
</Reference> | |||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<Private>False</Private> | |||||
</Reference> | |||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<Private>False</Private> | |||||
</Reference> | |||||
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"> | |||||
<Private>False</Private> | |||||
</Reference> | |||||
</ItemGroup> | |||||
</When> | |||||
</Choose> | |||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" /> | |||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | |||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. | |||||
Other similar extension points exist, see Microsoft.Common.targets. | |||||
<Target Name="BeforeBuild"> | |||||
</Target> | |||||
<Target Name="AfterBuild"> | |||||
</Target> | |||||
--> | |||||
</Project> |