Skip to content

Commit

Permalink
Add auto update; Release 1.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
sunnycase committed May 3, 2017
1 parent 4cee884 commit c785422
Show file tree
Hide file tree
Showing 19 changed files with 485 additions and 41 deletions.
41 changes: 41 additions & 0 deletions src/Moesocks.Client.Services/Configuration/ConfigurationBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;

namespace Moesocks.Client.Services.Configuration
{
public abstract class ConfigurationBase : INotifyPropertyChanged
{
[JsonIgnore]
public bool AutoSave { get; set; }

public event PropertyChangedEventHandler PropertyChanged;
public event EventHandler Saving;

protected bool SetProperty<T>(ref T property, T value, [CallerMemberName]string propertyName = null)
{
if(!EqualityComparer<T>.Default.Equals(property, value))
{
property = value;
OnPropertyChanged(propertyName);
if (AutoSave)
Save();
return true;
}
return false;
}

public void Save()
{
Saving?.Invoke(this, EventArgs.Empty);
}

protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Moesocks.Client.Services.Configuration
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class ConfigurationSectionNameAttribute : Attribute
{
public string SectionName { get; }

public ConfigurationSectionNameAttribute(string sectionName)
{
SectionName = sectionName;
}
}
}
27 changes: 27 additions & 0 deletions src/Moesocks.Client.Services/Configuration/UpdateConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text;

namespace Moesocks.Client.Services.Configuration
{
[ConfigurationSectionName("update")]
public class UpdateConfiguration : ConfigurationBase, IOptions<UpdateConfiguration>
{
private bool _enabled = true;
public bool Enabled
{
get => _enabled;
set => SetProperty(ref _enabled, value);
}

private bool _useByteBasisNetwork;
public bool UseByteBasisNetwork
{
get => _useByteBasisNetwork;
set => SetProperty(ref _useByteBasisNetwork, value);
}

UpdateConfiguration IOptions<UpdateConfiguration>.Value => this;
}
}
12 changes: 12 additions & 0 deletions src/Moesocks.Client.Services/IProductInformation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Moesocks.Client
{
public interface IProductInformation
{
string ProductName { get; }
Version ProductVersion { get; }
}
}
26 changes: 26 additions & 0 deletions src/Moesocks.Client.Services/IUpdateService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace Moesocks.Client.Services
{
public class NewReleaseFoundEventArgs : EventArgs
{
public string Version { get; }
public FileInfo UpdatePack { get; }

public NewReleaseFoundEventArgs(string version, FileInfo updatePack)
{
Version = version;
UpdatePack = updatePack;
}
}

public interface IUpdateService
{
event EventHandler<NewReleaseFoundEventArgs> NewReleaseFound;

void Startup();
}
}
2 changes: 2 additions & 0 deletions src/Moesocks.Client.Services/Moesocks.Client.Services.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.1" />
<PackageReference Include="Octokit" Version="0.24.1-alpha0001" />
<PackageReference Include="System.Net.NetworkInformation" Version="4.3.0" />
<PackageReference Include="System.Net.Security" Version="4.3.0" />
<PackageReference Include="Tomato.Threading" Version="1.0.1" />
</ItemGroup>
Expand Down
7 changes: 7 additions & 0 deletions src/Moesocks.Client.Services/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Moesocks.Client.Services;
using Moesocks.Client.Services.Network;
using Moesocks.Client.Services.Update;
using System;
using System.Collections.Generic;
using System.Text;
Expand All @@ -20,5 +22,10 @@ public static IServiceCollection AddSecurity(this IServiceCollection services, I
{
return services.Configure<SecuritySettings>(configuration);
}

public static IServiceCollection AddUpdate(this IServiceCollection services)
{
return services.AddSingleton<IUpdateService, UpdateService>();
}
}
}
133 changes: 133 additions & 0 deletions src/Moesocks.Client.Services/Update/UpdateService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using Microsoft.Extensions.Options;
using Moesocks.Client.Services.Configuration;
using Octokit;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Moesocks.Client.Services.Update
{
class UpdateService : IUpdateService
{
private readonly UpdateConfiguration _update;
private CancellationTokenSource _cts;
private readonly Timer _checkUpdate;
private readonly TimeSpan _checkPeriod = TimeSpan.FromHours(1);
private readonly GitHubClient _github;
private readonly Version _currentVersion;
private FileInfo _updatePack = null;
private string _newVersion;

public event EventHandler<NewReleaseFoundEventArgs> NewReleaseFound;

protected bool CanUpdate => _updatePack == null && _update.Enabled && NetworkInterface.GetIsNetworkAvailable();

public UpdateService(IOptions<UpdateConfiguration> updateConfig, IProductInformation productInfo)
{
_currentVersion = productInfo.ProductVersion;
_github = new GitHubClient(new ProductHeaderValue(productInfo.ProductName, _currentVersion.ToString()));
_checkUpdate = new Timer(CheckUpdate, this, Timeout.InfiniteTimeSpan, _checkPeriod);
_update = updateConfig.Value;
_update.PropertyChanged += update_PropertyChanged;
}

private void update_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
UpdateJob();
}

private void UpdateJob()
{
if (!CanUpdate)
{
var oldCts = Interlocked.Exchange(ref _cts, null);
if (oldCts != null)
{
oldCts.Cancel();
_checkUpdate.Change(Timeout.InfiniteTimeSpan, _checkPeriod);
_cts = null;
}
}
else
{
var cts = new CancellationTokenSource();
if (Interlocked.CompareExchange(ref _cts, cts, null) == null)
_checkUpdate.Change(TimeSpan.Zero, _checkPeriod);
}
UpdateProduct();
}

private static async void CheckUpdate(object me)
{
var service = (UpdateService)me;
try
{
var token = service._cts.Token;
token.ThrowIfCancellationRequested();
if (service.CanUpdate)
{
var releaseClient = service._github.Repository.Release;
var latest = await releaseClient.GetLatest("sunnycase", "Moesocks");
token.ThrowIfCancellationRequested();
var latestVersion = Version.Parse(latest.TagName);
if (latestVersion > service._currentVersion)
{
var asset = latest.Assets.FirstOrDefault(o => o.Name == "client.bin.zip");
if (asset != null)
{
var updatePackFile = CreateUpdatePackFile(latestVersion);
if (!updatePackFile.Exists || updatePackFile.Length != asset.Size)
{
updatePackFile.Directory.Create();
using (var updatePack = updatePackFile.OpenWrite())
using (var client = new HttpClient())
{
token.ThrowIfCancellationRequested();
var source = await client.GetStreamAsync(asset.BrowserDownloadUrl);
token.ThrowIfCancellationRequested();
await source.CopyToAsync(updatePack);
}
}
token.ThrowIfCancellationRequested();
service._newVersion = latest.Name;
service._updatePack = updatePackFile;
service.UpdateProduct();
}
}
}
}
catch
{

}
finally
{
Interlocked.Exchange(ref service._cts, null);
}
}

private void UpdateProduct()
{
var pack = _updatePack;
if (pack != null)
NewReleaseFound?.Invoke(this, new NewReleaseFoundEventArgs(_newVersion, pack));
}

private static FileInfo CreateUpdatePackFile(Version latestVersion)
{
return new FileInfo(Path.Combine("update", "client-v" + latestVersion + ".zip"));
}

public void Startup()
{
UpdateJob();
}
}
}
22 changes: 11 additions & 11 deletions src/Moesocks.Client/App.config
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0" />
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-1.2.1.0" newVersion="1.2.1.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0" />
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-4.1.2.0" newVersion="4.1.2.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
</configuration>
Loading

0 comments on commit c785422

Please sign in to comment.