@@ -1,6 +1,7 @@ | |||
Backup/ | |||
shadowsocks-csharp/bin/ | |||
shadowsocks-csharp/obj/ | |||
bin/ | |||
obj/ | |||
shadowsocks-csharp/shadowsocks-csharp.csproj.user | |||
TestResults | |||
*.suo | |||
@@ -3,6 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# 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}" | |||
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 | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
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}.Release|x86.ActiveCfg = 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 | |||
GlobalSection(SolutionProperties) = preSolution | |||
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> | |||
/// 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__" | |||
///socksProxyType = socks5 | |||
@@ -13,6 +13,7 @@ namespace Shadowsocks.View | |||
public partial class ConfigForm : Form | |||
{ | |||
private ShadowsocksController controller; | |||
private UpdateChecker updateChecker; | |||
// this is a copy of configuration that we are working on | |||
private Configuration modifiedConfiguration; | |||
@@ -30,6 +31,9 @@ namespace Shadowsocks.View | |||
controller.PACFileReadyToOpen += controller_PACFileReadyToOpen; | |||
controller.ShareOverLANStatusChanged += controller_ShareOverLANStatusChanged; | |||
this.updateChecker = new UpdateChecker(); | |||
updateChecker.NewVersionFound += updateChecker_NewVersionFound; | |||
LoadCurrentConfiguration(); | |||
} | |||
@@ -55,6 +59,21 @@ namespace Shadowsocks.View | |||
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() | |||
{ | |||
@@ -176,6 +195,7 @@ namespace Shadowsocks.View | |||
{ | |||
isFirstRun = true; | |||
} | |||
updateChecker.CheckUpdate(); | |||
} | |||
private void ServersListBox_SelectedIndexChanged(object sender, EventArgs e) | |||
@@ -242,6 +262,7 @@ namespace Shadowsocks.View | |||
{ | |||
notifyIcon1.BalloonTipTitle = "Shadowsocks is here"; | |||
notifyIcon1.BalloonTipText = "You can turn on/off Shadowsocks in the context menu"; | |||
notifyIcon1.BalloonTipIcon = ToolTipIcon.Info; | |||
notifyIcon1.ShowBalloonTip(0); | |||
isFirstRun = false; | |||
} | |||
@@ -10,7 +10,7 @@ | |||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||
<RootNamespace>Shadowsocks</RootNamespace> | |||
<AssemblyName>Shadowsocks</AssemblyName> | |||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion> | |||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> | |||
<FileAlignment>512</FileAlignment> | |||
<StartupObject> | |||
</StartupObject> | |||
@@ -21,8 +21,7 @@ | |||
<UpgradeBackupLocation> | |||
</UpgradeBackupLocation> | |||
<OldToolsVersion>3.5</OldToolsVersion> | |||
<TargetFrameworkProfile> | |||
</TargetFrameworkProfile> | |||
<TargetFrameworkProfile>Client</TargetFrameworkProfile> | |||
<PublishUrl>publish\</PublishUrl> | |||
<Install>true</Install> | |||
<InstallFrom>Disk</InstallFrom> | |||
@@ -63,12 +62,14 @@ | |||
<Reference Include="System.Data" /> | |||
<Reference Include="System.Drawing" /> | |||
<Reference Include="System.Windows.Forms" /> | |||
<Reference Include="System.XML" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Compile Include="3rd\QRCodeCS.cs" /> | |||
<Compile Include="3rd\SimpleJson.cs" /> | |||
<Compile Include="Controller\FileManager.cs" /> | |||
<Compile Include="Controller\Logging.cs" /> | |||
<Compile Include="Controller\UpdateChecker.cs" /> | |||
<Compile Include="Encrypt\EncryptorBase.cs" /> | |||
<Compile Include="Encrypt\EncryptorFactory.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> |