From ae5774967d71dc5d3193d0fee5de0ee7fe851492 Mon Sep 17 00:00:00 2001 From: Aragas Date: Wed, 14 Dec 2016 03:21:14 +0300 Subject: [PATCH] Added per-file update Added new project that is building UpdateInfo.yml Improved kinda the UI control in downloaders, but still needs some improving Removed NAppUpdate Added Polish --- .../Crc32.cs | 119 +++++++++ .../Data/UpdateInfo.cs | 22 ++ ...D-Legacy Launcher UpdateInfoBuilder.csproj | 66 +++++ .../Program.cs | 51 ++++ .../Properties/AssemblyInfo.cs | 36 +++ .../packages.config | 4 + P3D-Legacy Launcher.sln | 6 + P3D-Legacy Launcher/Crc32.cs | 119 +++++++++ P3D-Legacy Launcher/Data/OnlineGameRelease.cs | 2 +- P3D-Legacy Launcher/Data/Settings.cs | 14 +- P3D-Legacy Launcher/Data/UpdateInfo.cs | 33 +++ .../Extensions/ReleaseExtensions.cs | 2 +- .../Forms/CustomUpdaterForm.Designer.cs | 108 ++++++++ .../Forms/CustomUpdaterForm.cs | 235 ++++++++++++++++++ .../Forms/CustomUpdaterForm.de.resx | 101 ++++++++ .../Forms/CustomUpdaterForm.es.resx | 129 ++++++++++ .../Forms/CustomUpdaterForm.lt.resx | 101 ++++++++ .../Forms/CustomUpdaterForm.nl.resx | 129 ++++++++++ ...pdaterForm.resx => CustomUpdaterForm.resx} | 0 .../Forms/CustomUpdaterForm.ru.resx | 129 ++++++++++ .../Forms/DirectUpdaterForm.Designer.cs | 18 +- .../Forms/DirectUpdaterForm.cs | 114 ++++----- .../Forms/DirectUpdaterForm.resx | 20 +- P3D-Legacy Launcher/Forms/MBLang.Designer.cs | 90 +++++++ P3D-Legacy Launcher/Forms/MBLang.es.resx | 33 ++- P3D-Legacy Launcher/Forms/MBLang.nl.resx | 33 ++- P3D-Legacy Launcher/Forms/MBLang.resx | 30 +++ P3D-Legacy Launcher/Forms/MBLang.ru.resx | 26 +- .../Forms/MainForm.Designer.cs | 43 +++- P3D-Legacy Launcher/Forms/MainForm.cs | 123 +++++---- P3D-Legacy Launcher/Forms/MainForm.es.resx | 6 + P3D-Legacy Launcher/Forms/MainForm.nl.resx | 6 + P3D-Legacy Launcher/Forms/MainForm.resx | 140 +++++++++-- P3D-Legacy Launcher/Forms/MainForm.ru.resx | 2 +- .../Forms/NAppUpdaterForm.Designer.cs | 48 ---- P3D-Legacy Launcher/Forms/NAppUpdaterForm.cs | 21 -- .../P3D-Legacy Launcher.csproj | 32 ++- .../Properties/AssemblyInfo.cs | 4 +- P3D-Legacy Launcher/Yaml/UriConverter.cs | 26 ++ P3D-Legacy Launcher/packages.config | 1 - 40 files changed, 1976 insertions(+), 246 deletions(-) create mode 100644 P3D-Legacy Launcher UpdateInfoBuilder/Crc32.cs create mode 100644 P3D-Legacy Launcher UpdateInfoBuilder/Data/UpdateInfo.cs create mode 100644 P3D-Legacy Launcher UpdateInfoBuilder/P3D-Legacy Launcher UpdateInfoBuilder.csproj create mode 100644 P3D-Legacy Launcher UpdateInfoBuilder/Program.cs create mode 100644 P3D-Legacy Launcher UpdateInfoBuilder/Properties/AssemblyInfo.cs create mode 100644 P3D-Legacy Launcher UpdateInfoBuilder/packages.config create mode 100644 P3D-Legacy Launcher/Crc32.cs create mode 100644 P3D-Legacy Launcher/Data/UpdateInfo.cs create mode 100644 P3D-Legacy Launcher/Forms/CustomUpdaterForm.Designer.cs create mode 100644 P3D-Legacy Launcher/Forms/CustomUpdaterForm.cs create mode 100644 P3D-Legacy Launcher/Forms/CustomUpdaterForm.de.resx create mode 100644 P3D-Legacy Launcher/Forms/CustomUpdaterForm.es.resx create mode 100644 P3D-Legacy Launcher/Forms/CustomUpdaterForm.lt.resx create mode 100644 P3D-Legacy Launcher/Forms/CustomUpdaterForm.nl.resx rename P3D-Legacy Launcher/Forms/{NAppUpdaterForm.resx => CustomUpdaterForm.resx} (100%) create mode 100644 P3D-Legacy Launcher/Forms/CustomUpdaterForm.ru.resx delete mode 100644 P3D-Legacy Launcher/Forms/NAppUpdaterForm.Designer.cs delete mode 100644 P3D-Legacy Launcher/Forms/NAppUpdaterForm.cs create mode 100644 P3D-Legacy Launcher/Yaml/UriConverter.cs diff --git a/P3D-Legacy Launcher UpdateInfoBuilder/Crc32.cs b/P3D-Legacy Launcher UpdateInfoBuilder/Crc32.cs new file mode 100644 index 0000000..4ecee9d --- /dev/null +++ b/P3D-Legacy Launcher UpdateInfoBuilder/Crc32.cs @@ -0,0 +1,119 @@ +// Copyright (c) Damien Guard. All rights reserved. +// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +// Originally published at http://damieng.com/blog/2006/08/08/calculating_crc32_in_c_and_net + +using System; +using System.Collections.Generic; +using System.Security.Cryptography; + +namespace DamienG.Security.Cryptography +{ + /// + /// Implements a 32-bit CRC hash algorithm compatible with Zip etc. + /// + /// + /// Crc32 should only be used for backward compatibility with older file formats + /// and algorithms. It is not secure enough for new applications. + /// If you need to call multiple times for the same data either use the HashAlgorithm + /// interface or remember that the result of one Compute call needs to be ~ (XOR) before + /// being passed in as the seed for the next Compute call. + /// + public sealed class Crc32 : HashAlgorithm + { + public const UInt32 DefaultPolynomial = 0xedb88320u; + public const UInt32 DefaultSeed = 0xffffffffu; + + static UInt32[] defaultTable; + + readonly UInt32 seed; + readonly UInt32[] table; + UInt32 hash; + + public Crc32() + : this(DefaultPolynomial, DefaultSeed) + { + } + + public Crc32(UInt32 polynomial, UInt32 seed) + { + table = InitializeTable(polynomial); + this.seed = hash = seed; + } + + public override void Initialize() + { + hash = seed; + } + + protected override void HashCore(byte[] array, int ibStart, int cbSize) + { + hash = CalculateHash(table, hash, array, ibStart, cbSize); + } + + protected override byte[] HashFinal() + { + var hashBuffer = UInt32ToBigEndianBytes(~hash); + HashValue = hashBuffer; + return hashBuffer; + } + + public override int HashSize { get { return 32; } } + + public static UInt32 Compute(byte[] buffer) + { + return Compute(DefaultSeed, buffer); + } + + public static UInt32 Compute(UInt32 seed, byte[] buffer) + { + return Compute(DefaultPolynomial, seed, buffer); + } + + public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); + } + + static UInt32[] InitializeTable(UInt32 polynomial) + { + if (polynomial == DefaultPolynomial && defaultTable != null) + return defaultTable; + + var createTable = new UInt32[256]; + for (var i = 0; i < 256; i++) + { + var entry = (UInt32) i; + for (var j = 0; j < 8; j++) + if ((entry & 1) == 1) + entry = (entry >> 1) ^ polynomial; + else + entry = entry >> 1; + createTable[i] = entry; + } + + if (polynomial == DefaultPolynomial) + defaultTable = createTable; + + return createTable; + } + + static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList buffer, int start, int size) + { + var hash = seed; + for (var i = start; i < start + size; i++) + hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff]; + return hash; + } + + static byte[] UInt32ToBigEndianBytes(UInt32 uint32) + { + var result = BitConverter.GetBytes(uint32); + + if (BitConverter.IsLittleEndian) + Array.Reverse(result); + + return result; + } + } +} \ No newline at end of file diff --git a/P3D-Legacy Launcher UpdateInfoBuilder/Data/UpdateInfo.cs b/P3D-Legacy Launcher UpdateInfoBuilder/Data/UpdateInfo.cs new file mode 100644 index 0000000..08e6c27 --- /dev/null +++ b/P3D-Legacy Launcher UpdateInfoBuilder/Data/UpdateInfo.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +using YamlDotNet.Serialization; + +namespace P3D.Legacy.Launcher.UpdateInfoBuilder.Data +{ + public class UpdateInfo + { + public static SerializerBuilder SerializerBuilder { get; } = new SerializerBuilder(); + public static DeserializerBuilder DeserializerBuilder { get; } = new DeserializerBuilder(); + + public List Files { get; set; } = new List(); + } + + public class UpdateFileEntry + { + public string AbsoluteFilePath { get; set; } + public string CRC32 { get; set; } + public string SHA1 { get; set; } + public long Size { get; set; } + } +} \ No newline at end of file diff --git a/P3D-Legacy Launcher UpdateInfoBuilder/P3D-Legacy Launcher UpdateInfoBuilder.csproj b/P3D-Legacy Launcher UpdateInfoBuilder/P3D-Legacy Launcher UpdateInfoBuilder.csproj new file mode 100644 index 0000000..c439e25 --- /dev/null +++ b/P3D-Legacy Launcher UpdateInfoBuilder/P3D-Legacy Launcher UpdateInfoBuilder.csproj @@ -0,0 +1,66 @@ + + + + + Debug + AnyCPU + {317AA66C-58E7-4005-9568-93CFAF5353CD} + Exe + Properties + P3D.Legacy.Launcher.UpdateInfoBuilder + P3D-Legacy Launcher UpdateInfoBuilder + v4.5.2 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + ..\packages\YamlDotNet.4.0.0\lib\net35\YamlDotNet.dll + True + + + + + + + + + + + + + + \ No newline at end of file diff --git a/P3D-Legacy Launcher UpdateInfoBuilder/Program.cs b/P3D-Legacy Launcher UpdateInfoBuilder/Program.cs new file mode 100644 index 0000000..40b9ea7 --- /dev/null +++ b/P3D-Legacy Launcher UpdateInfoBuilder/Program.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; + +using DamienG.Security.Cryptography; + +using P3D.Legacy.Launcher.UpdateInfoBuilder.Data; + +namespace P3D.Legacy.Launcher.UpdateInfoBuilder +{ + public static class Program + { + private static string MainFolderPath { get; } = AppDomain.CurrentDomain.BaseDirectory; + + private const string OutputFilename = "UpdateInfo.yml"; + private static string OutputFilePath { get; } = Path.Combine(MainFolderPath, OutputFilename); + + public static void Main(string[] args) + { + var updateInfoPath = args[0]; + + + //var allAbsoluteFilePaths = Directory.GetFiles(updateInfoPath, "*.*", SearchOption.AllDirectories).Select(filePath => filePath.Replace(updateInfoPath, "")); + var allAbsoluteFilePaths = Directory.GetFiles(updateInfoPath, "*.*", SearchOption.AllDirectories).Select(filePath => filePath.Substring(updateInfoPath.Length + 1)); + + var crc32 = new Crc32(); + var sha1 = new SHA1Managed(); + var updateFileEntries = new List(); + foreach (var absoluteFilePath in allAbsoluteFilePaths) + { + var filePath = Path.Combine(updateInfoPath, absoluteFilePath); + var length = new FileInfo(filePath).Length; + using (var fs = File.OpenRead(filePath)) + { + var crc32Hash = string.Empty; + var sha1Hash = string.Empty; + crc32Hash = crc32.ComputeHash(fs).Aggregate(crc32Hash, (current, b) => current + b.ToString("x2").ToLower()); + sha1Hash = sha1.ComputeHash(fs).Aggregate(sha1Hash, (current, b) => current + b.ToString("x2").ToLower()); + updateFileEntries.Add(new UpdateFileEntry { AbsoluteFilePath = absoluteFilePath, CRC32 = crc32Hash, SHA1 = sha1Hash, Size = length }); + } + } + + var serializer = UpdateInfo.SerializerBuilder.Build(); + var content = serializer.Serialize(new UpdateInfo { Files = updateFileEntries }); + + File.WriteAllText(OutputFilePath, content); + } + } +} diff --git a/P3D-Legacy Launcher UpdateInfoBuilder/Properties/AssemblyInfo.cs b/P3D-Legacy Launcher UpdateInfoBuilder/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3f97288 --- /dev/null +++ b/P3D-Legacy Launcher UpdateInfoBuilder/Properties/AssemblyInfo.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("P3D-Legacy Launcher UpdateInfoBuilder")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("P3D-Legacy Launcher UpdateInfoBuilder")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2016")] +[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("317aa66c-58e7-4005-9568-93cfaf5353cd")] + +// 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")] diff --git a/P3D-Legacy Launcher UpdateInfoBuilder/packages.config b/P3D-Legacy Launcher UpdateInfoBuilder/packages.config new file mode 100644 index 0000000..c2ddba2 --- /dev/null +++ b/P3D-Legacy Launcher UpdateInfoBuilder/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/P3D-Legacy Launcher.sln b/P3D-Legacy Launcher.sln index d5b6d3c..ead3847 100644 --- a/P3D-Legacy Launcher.sln +++ b/P3D-Legacy Launcher.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "P3D-Legacy Launcher", "P3D- EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "P3D-Legacy Launcher Updater", "P3D-Legacy Launcher Updater\P3D-Legacy Launcher Updater.csproj", "{6EE47050-ED83-4944-ACBB-D7F74E8C14F3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "P3D-Legacy Launcher UpdateInfoBuilder", "P3D-Legacy Launcher UpdateInfoBuilder\P3D-Legacy Launcher UpdateInfoBuilder.csproj", "{317AA66C-58E7-4005-9568-93CFAF5353CD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {6EE47050-ED83-4944-ACBB-D7F74E8C14F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {6EE47050-ED83-4944-ACBB-D7F74E8C14F3}.Release|Any CPU.ActiveCfg = Release|Any CPU {6EE47050-ED83-4944-ACBB-D7F74E8C14F3}.Release|Any CPU.Build.0 = Release|Any CPU + {317AA66C-58E7-4005-9568-93CFAF5353CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {317AA66C-58E7-4005-9568-93CFAF5353CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {317AA66C-58E7-4005-9568-93CFAF5353CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {317AA66C-58E7-4005-9568-93CFAF5353CD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/P3D-Legacy Launcher/Crc32.cs b/P3D-Legacy Launcher/Crc32.cs new file mode 100644 index 0000000..4ecee9d --- /dev/null +++ b/P3D-Legacy Launcher/Crc32.cs @@ -0,0 +1,119 @@ +// Copyright (c) Damien Guard. All rights reserved. +// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 +// Originally published at http://damieng.com/blog/2006/08/08/calculating_crc32_in_c_and_net + +using System; +using System.Collections.Generic; +using System.Security.Cryptography; + +namespace DamienG.Security.Cryptography +{ + /// + /// Implements a 32-bit CRC hash algorithm compatible with Zip etc. + /// + /// + /// Crc32 should only be used for backward compatibility with older file formats + /// and algorithms. It is not secure enough for new applications. + /// If you need to call multiple times for the same data either use the HashAlgorithm + /// interface or remember that the result of one Compute call needs to be ~ (XOR) before + /// being passed in as the seed for the next Compute call. + /// + public sealed class Crc32 : HashAlgorithm + { + public const UInt32 DefaultPolynomial = 0xedb88320u; + public const UInt32 DefaultSeed = 0xffffffffu; + + static UInt32[] defaultTable; + + readonly UInt32 seed; + readonly UInt32[] table; + UInt32 hash; + + public Crc32() + : this(DefaultPolynomial, DefaultSeed) + { + } + + public Crc32(UInt32 polynomial, UInt32 seed) + { + table = InitializeTable(polynomial); + this.seed = hash = seed; + } + + public override void Initialize() + { + hash = seed; + } + + protected override void HashCore(byte[] array, int ibStart, int cbSize) + { + hash = CalculateHash(table, hash, array, ibStart, cbSize); + } + + protected override byte[] HashFinal() + { + var hashBuffer = UInt32ToBigEndianBytes(~hash); + HashValue = hashBuffer; + return hashBuffer; + } + + public override int HashSize { get { return 32; } } + + public static UInt32 Compute(byte[] buffer) + { + return Compute(DefaultSeed, buffer); + } + + public static UInt32 Compute(UInt32 seed, byte[] buffer) + { + return Compute(DefaultPolynomial, seed, buffer); + } + + public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); + } + + static UInt32[] InitializeTable(UInt32 polynomial) + { + if (polynomial == DefaultPolynomial && defaultTable != null) + return defaultTable; + + var createTable = new UInt32[256]; + for (var i = 0; i < 256; i++) + { + var entry = (UInt32) i; + for (var j = 0; j < 8; j++) + if ((entry & 1) == 1) + entry = (entry >> 1) ^ polynomial; + else + entry = entry >> 1; + createTable[i] = entry; + } + + if (polynomial == DefaultPolynomial) + defaultTable = createTable; + + return createTable; + } + + static UInt32 CalculateHash(UInt32[] table, UInt32 seed, IList buffer, int start, int size) + { + var hash = seed; + for (var i = start; i < start + size; i++) + hash = (hash >> 8) ^ table[buffer[i] ^ hash & 0xff]; + return hash; + } + + static byte[] UInt32ToBigEndianBytes(UInt32 uint32) + { + var result = BitConverter.GetBytes(uint32); + + if (BitConverter.IsLittleEndian) + Array.Reverse(result); + + return result; + } + } +} \ No newline at end of file diff --git a/P3D-Legacy Launcher/Data/OnlineGameRelease.cs b/P3D-Legacy Launcher/Data/OnlineGameRelease.cs index a67dcf2..173dcba 100644 --- a/P3D-Legacy Launcher/Data/OnlineGameRelease.cs +++ b/P3D-Legacy Launcher/Data/OnlineGameRelease.cs @@ -10,7 +10,7 @@ public class OnlineGameRelease { private Release Release { get; } public ReleaseAsset ReleaseAsset => Release.GetRelease(); - public ReleaseAsset UpdateFeedAsset => Release.GetUpdateFeed(); + public ReleaseAsset UpdateInfoAsset => Release.GetUpdateInfo(); public Version Version => new Version(Release.TagName ?? "0.0"); public DateTime ReleaseDate => Release.CreatedAt.DateTime; diff --git a/P3D-Legacy Launcher/Data/Settings.cs b/P3D-Legacy Launcher/Data/Settings.cs index eb920a0..978fc12 100644 --- a/P3D-Legacy Launcher/Data/Settings.cs +++ b/P3D-Legacy Launcher/Data/Settings.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using P3D.Legacy.Launcher.Yaml; @@ -8,14 +9,14 @@ namespace P3D.Legacy.Launcher.Data { public class Settings { - public static SerializerBuilder SerializerBuilder { get; } = new SerializerBuilder().WithTypeConverter(new CultureInfoConverter()); - public static DeserializerBuilder DeserializerBuilder { get; } = new DeserializerBuilder().WithTypeConverter(new CultureInfoConverter()); + public static SerializerBuilder SerializerBuilder { get; } = new SerializerBuilder().WithTypeConverter(new CultureInfoConverter()).WithTypeConverter(new UriConverter()); + public static DeserializerBuilder DeserializerBuilder { get; } = new DeserializerBuilder().WithTypeConverter(new CultureInfoConverter()).WithTypeConverter(new UriConverter()); public static CultureInfo[] AvailableCultureInfo { get; } = { new CultureInfo("en"), new CultureInfo("ru"), new CultureInfo("lt"), - new CultureInfo("lt"), new CultureInfo("nl"), new CultureInfo("es"), - new CultureInfo("de"), /* new CultureInfo("fr"), new CultureInfo("it"), - new CultureInfo("pl"), new CultureInfo("pt") */ + new CultureInfo("nl"), new CultureInfo("es"), new CultureInfo("de"), + /* new CultureInfo("fr"), new CultureInfo("it"), new CultureInfo("pl"), + new CultureInfo("pt") */ }; public static Settings Default => new Settings { GameUpdates = true, Language = new CultureInfo("en") }; @@ -23,5 +24,6 @@ public class Settings public bool GameUpdates { get; set; } public CultureInfo Language { get; set; } + public Uri SelectedDL { get; set; } } } \ No newline at end of file diff --git a/P3D-Legacy Launcher/Data/UpdateInfo.cs b/P3D-Legacy Launcher/Data/UpdateInfo.cs new file mode 100644 index 0000000..8a3bbba --- /dev/null +++ b/P3D-Legacy Launcher/Data/UpdateInfo.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; + +using YamlDotNet.Serialization; + +namespace P3D.Legacy.Launcher.Data +{ + public class UpdateInfo + { + public static SerializerBuilder SerializerBuilder { get; } = new SerializerBuilder(); + public static DeserializerBuilder DeserializerBuilder { get; } = new DeserializerBuilder(); + + public static Uri[] DLUris { get; } = GetDLUris(); + private static Uri[] GetDLUris() + { + var downloaded = new WebClient().DownloadString("https://raw.githubusercontent.com/P3D-Legacy/P3D-Legacy-Data/master/DLUris.txt"); + var strings = string.IsNullOrEmpty(downloaded) ? new string[0] : downloaded.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); + return strings.All(string.IsNullOrEmpty) ? new Uri[0] : strings.Select(str => new Uri(str)).ToArray(); + } + + public List Files { get; set; } = new List(); + } + + public class UpdateFileEntry + { + public string AbsoluteFilePath { get; set; } + public string CRC32 { get; set; } + public string SHA1 { get; set; } + public long Size { get; set; } + } +} \ No newline at end of file diff --git a/P3D-Legacy Launcher/Extensions/ReleaseExtensions.cs b/P3D-Legacy Launcher/Extensions/ReleaseExtensions.cs index b89a3e7..64a498c 100644 --- a/P3D-Legacy Launcher/Extensions/ReleaseExtensions.cs +++ b/P3D-Legacy Launcher/Extensions/ReleaseExtensions.cs @@ -6,7 +6,7 @@ namespace P3D.Legacy.Launcher.Extensions { public static class ReleaseExtensions { - public static ReleaseAsset GetUpdateFeed(this Release release) => release.Assets?.SingleOrDefault(asset => asset.Name == "UpdateFeed.xml"); + public static ReleaseAsset GetUpdateInfo(this Release release) => release.Assets?.SingleOrDefault(asset => asset.Name == "UpdateInfo.yml"); public static ReleaseAsset GetRelease(this Release release) => release.Assets?.SingleOrDefault(asset => asset.Name == "Release.zip"); } } \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/CustomUpdaterForm.Designer.cs b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.Designer.cs new file mode 100644 index 0000000..5c5c70a --- /dev/null +++ b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.Designer.cs @@ -0,0 +1,108 @@ +namespace P3D.Legacy.Launcher.Forms +{ + partial class CustomUpdaterForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CustomUpdaterForm)); + this.Label_ProgressBar1 = new System.Windows.Forms.Label(); + this.ProgressBar = new System.Windows.Forms.ProgressBar(); + this.Label_ProgressBar2 = new System.Windows.Forms.Label(); + this.Label_ProgressBar3 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // Label_ProgressBar1 + // + this.Label_ProgressBar1.AutoSize = true; + this.Label_ProgressBar1.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.Label_ProgressBar1.Location = new System.Drawing.Point(12, 9); + this.Label_ProgressBar1.Name = "Label_ProgressBar1"; + this.Label_ProgressBar1.Size = new System.Drawing.Size(110, 13); + this.Label_ProgressBar1.TabIndex = 4; + this.Label_ProgressBar1.Text = "Update Info Progress:"; + // + // ProgressBar + // + this.ProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.ProgressBar.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.ProgressBar.Location = new System.Drawing.Point(15, 25); + this.ProgressBar.Name = "ProgressBar"; + this.ProgressBar.Size = new System.Drawing.Size(257, 25); + this.ProgressBar.TabIndex = 3; + // + // Label_ProgressBar2 + // + this.Label_ProgressBar2.AutoSize = true; + this.Label_ProgressBar2.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.Label_ProgressBar2.Location = new System.Drawing.Point(13, 9); + this.Label_ProgressBar2.Name = "Label_ProgressBar2"; + this.Label_ProgressBar2.Size = new System.Drawing.Size(109, 13); + this.Label_ProgressBar2.TabIndex = 5; + this.Label_ProgressBar2.Text = "Comparsion Progress:"; + this.Label_ProgressBar2.Visible = false; + // + // Label_ProgressBar3 + // + this.Label_ProgressBar3.AutoSize = true; + this.Label_ProgressBar3.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.Label_ProgressBar3.Location = new System.Drawing.Point(13, 9); + this.Label_ProgressBar3.Name = "Label_ProgressBar3"; + this.Label_ProgressBar3.Size = new System.Drawing.Size(102, 13); + this.Label_ProgressBar3.TabIndex = 6; + this.Label_ProgressBar3.Text = "Download Progress:"; + this.Label_ProgressBar3.Visible = false; + // + // CustomUpdaterForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(284, 62); + this.Controls.Add(this.Label_ProgressBar1); + this.Controls.Add(this.ProgressBar); + this.Controls.Add(this.Label_ProgressBar2); + this.Controls.Add(this.Label_ProgressBar3); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MaximumSize = new System.Drawing.Size(300, 100); + this.MinimumSize = new System.Drawing.Size(300, 100); + this.Name = "CustomUpdaterForm"; + this.Text = "NAppUpdater"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.NAppUpdaterForm_FormClosing); + this.Shown += new System.EventHandler(this.CustomUpdaterForm_Shown); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label Label_ProgressBar1; + private System.Windows.Forms.ProgressBar ProgressBar; + private System.Windows.Forms.Label Label_ProgressBar2; + private System.Windows.Forms.Label Label_ProgressBar3; + } +} \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/CustomUpdaterForm.cs b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.cs new file mode 100644 index 0000000..0976fb4 --- /dev/null +++ b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Security.Cryptography; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; + +using DamienG.Security.Cryptography; + +using Octokit; + +using P3D.Legacy.Launcher.Data; + +namespace P3D.Legacy.Launcher.Forms +{ + public partial class CustomUpdaterForm : Form + { + private SynchronizationContext SynchronizationContext { get; } = SynchronizationContext.Current; + + private WebClient Downloader { get; set; } + private bool Cancelled { get; set; } + + private ReleaseAsset UpdateInfoAsset { get; } + private string ReleaseInfoFilePath => FileSystemInfo.TempFilePath(UpdateInfoAsset.Name); + private string UpdatedFolderPath { get; } + private Uri DLUri { get; } + private long DLSize { get; set; } + + public CustomUpdaterForm(ReleaseAsset updateInfoAsset, string updatedFolderPath, Uri dlUri) + { + UpdateInfoAsset = updateInfoAsset; + UpdatedFolderPath = updatedFolderPath; + DLUri = dlUri; + + InitializeComponent(); + } + + private async void CustomUpdaterForm_Shown(object sender, EventArgs e) + { + if (!Directory.Exists(FileSystemInfo.TempFolderPath)) + Directory.CreateDirectory(FileSystemInfo.TempFolderPath); + + await Task.Run(DownloadFile); + Close(); + } + + private async Task DownloadFile() + { + if (File.Exists(ReleaseInfoFilePath)) + File.Delete(ReleaseInfoFilePath); + + DLSize = UpdateInfoAsset.Size; + + try + { + using (Downloader = new WebClient()) + { + Downloader.DownloadProgressChanged += client_DownloadProgressChanged; + await Downloader.DownloadFileTaskAsync(UpdateInfoAsset.BrowserDownloadUrl, ReleaseInfoFilePath); + Downloader.DownloadProgressChanged -= client_DownloadProgressChanged; + } + } + catch (Exception) { DownloadErrorMessage(); return; } + if (Cancelled) return; + + + if (File.Exists(ReleaseInfoFilePath)) + { + var list = StartUpdate(); + if (Cancelled) return; + + if (list.Any()) + { + await UpdateFiles(list); + if (Cancelled) return; + UpdatedMessage(); + } + else + NoUpdateNeededMessage(); + } + else + DownloadErrorMessage(); + } + + private List StartUpdate() + { + if (Cancelled) return new List(); + + SynchronizationContext.Send(obj => Label_ProgressBar1.Text = Label_ProgressBar2.Text, null); + + var releaseInfoContent = File.ReadAllText(ReleaseInfoFilePath); + var deserializer = UpdateInfo.DeserializerBuilder.Build(); + var updateInfo = deserializer.Deserialize(releaseInfoContent); + + var crc32 = new Crc32(); + var sha1 = new SHA1Managed(); + var notValidFileEntries = new List(); + SynchronizationContext.Send(delegate { ProgressBar.Value = 0; ProgressBar.Step = 1; ProgressBar.Maximum = updateInfo.Files.Count; }, null); + foreach (var updateFileEntry in updateInfo.Files) + { + if (Cancelled) return new List(); + + SynchronizationContext.Send(obj => ProgressBar.PerformStep(), null); + + var filePath = Path.Combine(UpdatedFolderPath, updateFileEntry.AbsoluteFilePath); + if (!File.Exists(filePath)) + { + notValidFileEntries.Add(updateFileEntry); + continue; + } + using (var fs = File.Open(filePath, System.IO.FileMode.Open, FileAccess.Read)) + { + var crc32Hash = string.Empty; + var sha1Hash = string.Empty; + crc32Hash = crc32.ComputeHash(fs) + .Aggregate(crc32Hash, (current, b) => current + b.ToString("x2").ToLower()); + if (crc32Hash == updateFileEntry.CRC32) + { + sha1Hash = sha1.ComputeHash(fs) + .Aggregate(sha1Hash, (current, b) => current + b.ToString("x2").ToLower()); + if (sha1Hash == updateFileEntry.SHA1) + continue; + else + { + notValidFileEntries.Add(updateFileEntry); + continue; + } + } + else + { + notValidFileEntries.Add(updateFileEntry); + continue; + } + } + } + + return notValidFileEntries; + } + + private async Task UpdateFiles(List updateFileEntries) + { + if (Cancelled) return; + + SynchronizationContext.Send(obj => Label_ProgressBar1.Text = Label_ProgressBar3.Text, null); + + try + { + DLSize = updateFileEntries.Sum(updateFileEntry => updateFileEntry.Size); + foreach (var updateFileEntry in updateFileEntries) + { + if (Cancelled) return; + + var dlUri = new Uri(DLUri, updateFileEntry.AbsoluteFilePath); + var tempFilePath = FileSystemInfo.TempFilePath(updateFileEntry.AbsoluteFilePath); + + using (Downloader = new WebClient()) + { + Downloader.DownloadProgressChanged += client_DownloadProgressChanged; + await Downloader.DownloadFileTaskAsync(dlUri, tempFilePath); + Downloader.DownloadProgressChanged -= client_DownloadProgressChanged; + } + } + } + catch (Exception) { DownloadErrorMessage(); return; } + + ReplaceFiles(updateFileEntries); + } + private void ReplaceFiles(List updateFileEntries) + { + if (Cancelled) return; + + try + { + foreach (var updateFileEntry in updateFileEntries) + { + if (Cancelled) return; + + var tempFilePath = FileSystemInfo.TempFilePath(updateFileEntry.AbsoluteFilePath); + var filePath = Path.Combine(UpdatedFolderPath, updateFileEntry.AbsoluteFilePath); + + if (File.Exists(filePath)) + File.Delete(filePath); + File.Move(tempFilePath, filePath); + File.Delete(tempFilePath); + } + } + catch (Exception) { FileReplacementErrorMessage(); return; } + } + + private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) + { + SynchronizationContext.Send(delegate + { + ProgressBar.Maximum = (int) DLSize; + ProgressBar.Value = (int) e.BytesReceived; + }, null); + } + + private void NAppUpdaterForm_FormClosing(object sender, FormClosingEventArgs e) + { + Downloader.DownloadProgressChanged -= client_DownloadProgressChanged; + Downloader?.CancelAsync(); + Cancelled = true; + } + + + private void DownloadErrorMessage() + { + MessageBox.Show(MBLang.DownloadError, MBLang.DownloadErrorTitle, MessageBoxButtons.OK); + if (Cancelled) return; + SynchronizationContext.Send(obj => Close(), null); + } + private void FileReplacementErrorMessage() + { + MessageBox.Show(MBLang.FileReplacementError, MBLang.FileReplacementErrorTitle, MessageBoxButtons.OK); + if (Cancelled) return; + SynchronizationContext.Send(obj => Close(), null); + } + private void NoUpdateNeededMessage() + { + MessageBox.Show(MBLang.NoUpdateNeeded, MBLang.NoUpdateNeededTitle, MessageBoxButtons.OK); + if (Cancelled) return; + SynchronizationContext.Send(obj => Close(), null); + } + private void UpdatedMessage() + { + MessageBox.Show(MBLang.Updated, MBLang.UpdatedTitle, MessageBoxButtons.OK); + if (Cancelled) return; + SynchronizationContext.Send(obj => Close(), null); + } + } +} diff --git a/P3D-Legacy Launcher/Forms/CustomUpdaterForm.de.resx b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.de.resx new file mode 100644 index 0000000..4fdb1b6 --- /dev/null +++ b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.de.resx @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/CustomUpdaterForm.es.resx b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.es.resx new file mode 100644 index 0000000..72c3ea1 --- /dev/null +++ b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.es.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Actualizando información: + + + Comparando: + + + Descargando: + + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/CustomUpdaterForm.lt.resx b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.lt.resx new file mode 100644 index 0000000..4fdb1b6 --- /dev/null +++ b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.lt.resx @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/CustomUpdaterForm.nl.resx b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.nl.resx new file mode 100644 index 0000000..cc1551f --- /dev/null +++ b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.nl.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Update info progres: + + + Vergelijking progres: + + + Download progres: + + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/NAppUpdaterForm.resx b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.resx similarity index 100% rename from P3D-Legacy Launcher/Forms/NAppUpdaterForm.resx rename to P3D-Legacy Launcher/Forms/CustomUpdaterForm.resx diff --git a/P3D-Legacy Launcher/Forms/CustomUpdaterForm.ru.resx b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.ru.resx new file mode 100644 index 0000000..4c94145 --- /dev/null +++ b/P3D-Legacy Launcher/Forms/CustomUpdaterForm.ru.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Update Info Progress: + + + Comparsion Progress: + + + Download Progress: + + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/DirectUpdaterForm.Designer.cs b/P3D-Legacy Launcher/Forms/DirectUpdaterForm.Designer.cs index c61883d..fdd62d7 100644 --- a/P3D-Legacy Launcher/Forms/DirectUpdaterForm.Designer.cs +++ b/P3D-Legacy Launcher/Forms/DirectUpdaterForm.Designer.cs @@ -29,15 +29,15 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DirectUpdaterForm)); - this.progressBar1 = new System.Windows.Forms.ProgressBar(); + this.ProgressBar = new System.Windows.Forms.ProgressBar(); this.Label_ProgressBar1 = new System.Windows.Forms.Label(); this.Label_ProgressBar2 = new System.Windows.Forms.Label(); this.SuspendLayout(); // - // progressBar1 + // ProgressBar // - resources.ApplyResources(this.progressBar1, "progressBar1"); - this.progressBar1.Name = "progressBar1"; + resources.ApplyResources(this.ProgressBar, "ProgressBar"); + this.ProgressBar.Name = "ProgressBar"; // // Label_ProgressBar1 // @@ -49,16 +49,16 @@ private void InitializeComponent() resources.ApplyResources(this.Label_ProgressBar2, "Label_ProgressBar2"); this.Label_ProgressBar2.Name = "Label_ProgressBar2"; // - // DirectDownloaderForm + // DirectUpdaterForm // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.Label_ProgressBar1); - this.Controls.Add(this.progressBar1); + this.Controls.Add(this.ProgressBar); this.Controls.Add(this.Label_ProgressBar2); - this.Name = "DirectDownloaderForm"; + this.Name = "DirectUpdaterForm"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.DirectDownloaderForm_FormClosing); - this.Load += new System.EventHandler(this.DirectDownloaderForm_Load); + this.Shown += new System.EventHandler(this.DirectUpdaterForm_Shown); this.ResumeLayout(false); this.PerformLayout(); @@ -66,7 +66,7 @@ private void InitializeComponent() #endregion - private System.Windows.Forms.ProgressBar progressBar1; + private System.Windows.Forms.ProgressBar ProgressBar; private System.Windows.Forms.Label Label_ProgressBar1; private System.Windows.Forms.Label Label_ProgressBar2; } diff --git a/P3D-Legacy Launcher/Forms/DirectUpdaterForm.cs b/P3D-Legacy Launcher/Forms/DirectUpdaterForm.cs index 458ab0f..68f40b7 100644 --- a/P3D-Legacy Launcher/Forms/DirectUpdaterForm.cs +++ b/P3D-Legacy Launcher/Forms/DirectUpdaterForm.cs @@ -3,20 +3,20 @@ using System.Linq; using System.Net; using System.Threading; +using System.Threading.Tasks; using System.Windows.Forms; using Ionic.Zip; using Octokit; -using FileMode = System.IO.FileMode; - namespace P3D.Legacy.Launcher.Forms { public partial class DirectUpdaterForm : Form { - private WebClient Downloader { get; } = new WebClient(); - private Thread Extractor { get; set; } + private SynchronizationContext SynchronizationContext { get; } = SynchronizationContext.Current; + + private WebClient Downloader { get; set; } private bool Cancelled { get; set; } private ReleaseAsset ReleaseAsset { get; } @@ -34,106 +34,102 @@ public DirectUpdaterForm(ReleaseAsset releaseAsset, string extractionFolder) InitializeComponent(); } - private void DirectDownloaderForm_Load(object sender, EventArgs e) + + private async void DirectUpdaterForm_Shown(object sender, EventArgs e) { if (!Directory.Exists(FileSystemInfo.TempFolderPath)) Directory.CreateDirectory(FileSystemInfo.TempFolderPath); - DownloadFile(); + await Task.Run(DownloadFile); + Close(); } - private void DownloadFile() + private async Task DownloadFile() { if (File.Exists(TempFilePath)) File.Delete(TempFilePath); - Downloader.DownloadProgressChanged += client_DownloadProgressChanged; - Downloader.DownloadFileAsync(new Uri(ReleaseAsset.BrowserDownloadUrl), TempFilePath); - Downloader.DownloadFileCompleted += client_DownloadFileCompleted; - } - private void client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) - { - if(!Cancelled) + try + { + using (Downloader = new WebClient()) + { + Downloader.DownloadProgressChanged += client_DownloadProgressChanged; + await Downloader.DownloadFileTaskAsync(ReleaseAsset.BrowserDownloadUrl, TempFilePath); + Downloader.DownloadProgressChanged -= client_DownloadProgressChanged; + } + } + catch (Exception) { return; } + if (Cancelled) return; + + if (File.Exists(TempFilePath)) ExtractFile(); + else + ; } private void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) { - if (Cancelled || Disposing || IsDisposed) - return; - - Invoke((MethodInvoker) delegate - { - progressBar1.Maximum = ReleaseAsset.Size / 100; - progressBar1.Value = (int) e.BytesReceived / 100; - }); + SynchronizationContext.Send(delegate { ProgressBar.Maximum = ReleaseAsset.Size / 100; ProgressBar.Value = (int) e.BytesReceived / 100; }, null); } private void ExtractFile() { - Label_ProgressBar1.Text = Label_ProgressBar2.Text; + if (Cancelled) return; + + SynchronizationContext.Send(obj => Label_ProgressBar1.Text = Label_ProgressBar2.Text, null); if (!Directory.Exists(ExtractionFolder)) Directory.CreateDirectory(ExtractionFolder); - if(Extractor != null && Extractor.ThreadState != ThreadState.Stopped) - Extractor.Abort(); - Extractor = new Thread(() => + using (var zip = ZipFile.Read(TempFilePath)) { - using (var zip = ZipFile.Read(TempFilePath)) - { - zip.ExtractProgress += zip_ExtractProgress; + zip.ExtractProgress += zip_ExtractProgress; - var result = zip.Skip(1).Where(entry => entry.FileName.Contains(zip[0].FileName)).ToList(); - result = result.Select(c => - { - c.FileName = c.FileName.Replace(zip[0].FileName, ""); - return c; - }).ToList(); + var result = zip.Skip(1).Where(entry => entry.FileName.Contains(zip[0].FileName)).ToList(); + result = result.Select(c => + { + c.FileName = c.FileName.Replace(zip[0].FileName, ""); + return c; + }).ToList(); - _totalFiles = result.Count; - _filesExtracted = 0; + _totalFiles = result.Count; + _filesExtracted = 0; - // -- We skip the Main folder. - foreach (var entry in result) - entry.Extract(ExtractionFolder, ExtractExistingFileAction.OverwriteSilently); + // -- We skip the Main folder. + foreach (var entry in result) + { + if (Cancelled) return; + entry.Extract(ExtractionFolder, ExtractExistingFileAction.OverwriteSilently); } + } - File.Delete(TempFilePath); - - - if (Cancelled || Disposing || IsDisposed) - return; - Invoke((MethodInvoker) Close); - }); - Extractor.Start(); + File.Delete(TempFilePath); } + private void zip_ExtractProgress(object sender, ExtractProgressEventArgs e) { - if (Cancelled || Disposing || IsDisposed) - return; - - Invoke((MethodInvoker) delegate + SynchronizationContext.Send(delegate { if (e.EventType != ZipProgressEventType.Extracting_BeforeExtractEntry) return; _filesExtracted++; - progressBar1.Maximum = _totalFiles / 100; - progressBar1.Value = _filesExtracted / 100; - }); + ProgressBar.Maximum = _totalFiles / 100; + ProgressBar.Value = _filesExtracted / 100; + }, null); } - private void DirectDownloaderForm_FormClosing(object sender, FormClosingEventArgs e) + private async void DirectDownloaderForm_FormClosing(object sender, FormClosingEventArgs e) { + Downloader.DownloadProgressChanged -= client_DownloadProgressChanged; + Downloader?.CancelAsync(); Cancelled = true; - Downloader.CancelAsync(); if (File.Exists(TempFilePath)) { var x = 0; while (x < 10 && IsFileLocked(TempFilePath)) // -- Wait only 1 second. { - Thread.Sleep(100); + await Task.Delay(100); x++; } File.Delete(TempFilePath); @@ -143,7 +139,7 @@ private static bool IsFileLocked(string path) { FileStream stream = null; - try { stream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None); } + try { stream = File.Open(path, System.IO.FileMode.Open, FileAccess.ReadWrite, FileShare.None); } catch (IOException) { return true; } finally { stream?.Close(); } diff --git a/P3D-Legacy Launcher/Forms/DirectUpdaterForm.resx b/P3D-Legacy Launcher/Forms/DirectUpdaterForm.resx index fdc554a..8e83e99 100644 --- a/P3D-Legacy Launcher/Forms/DirectUpdaterForm.resx +++ b/P3D-Legacy Launcher/Forms/DirectUpdaterForm.resx @@ -118,30 +118,30 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + Top, Left, Right - + 15, 25 - + 257, 25 - + 0 - - progressBar1 + + ProgressBar - + System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + $this - + 1 @@ -625,7 +625,7 @@ Updater - DirectDownloaderForm + DirectUpdaterForm System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/P3D-Legacy Launcher/Forms/MBLang.Designer.cs b/P3D-Legacy Launcher/Forms/MBLang.Designer.cs index 952a6b0..e7c1fe1 100644 --- a/P3D-Legacy Launcher/Forms/MBLang.Designer.cs +++ b/P3D-Legacy Launcher/Forms/MBLang.Designer.cs @@ -60,6 +60,24 @@ internal MBLang() { } } + /// + /// Looks up a localized string similar to Can't update! Select a DL first in Settings tab!. + /// + internal static string DLNotSelected { + get { + return ResourceManager.GetString("DLNotSelected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error!. + /// + internal static string DLNotSelectedTitle { + get { + return ResourceManager.GetString("DLNotSelectedTitle", resourceCulture); + } + } + /// /// Looks up a localized string similar to Pokémon 3D requires Microsoft .NET Framework 4.0. ///Please visit http://www.microsoft.com/en-us/download/details.aspx?id=17851 to download. @@ -89,6 +107,42 @@ internal static string DotNetErrorTitle { } } + /// + /// Looks up a localized string similar to Failed to download a file. Please try again!. + /// + internal static string DownloadError { + get { + return ResourceManager.GetString("DownloadError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error!. + /// + internal static string DownloadErrorTitle { + get { + return ResourceManager.GetString("DownloadErrorTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Where was an error while replacing the old files with the new ones!. + /// + internal static string FileReplacementError { + get { + return ResourceManager.GetString("FileReplacementError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error!. + /// + internal static string FileReplacementErrorTitle { + get { + return ResourceManager.GetString("FileReplacementErrorTitle", resourceCulture); + } + } + /// /// Looks up a localized string similar to A new Launcher version is available! ///Would you like to update?. @@ -145,6 +199,24 @@ internal static string NotDownloadedTitle { } } + /// + /// Looks up a localized string similar to The Profile doesn't need an update!. + /// + internal static string NoUpdateNeeded { + get { + return ResourceManager.GetString("NoUpdateNeeded", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Done!. + /// + internal static string NoUpdateNeededTitle { + get { + return ResourceManager.GetString("NoUpdateNeededTitle", resourceCulture); + } + } + /// /// Looks up a localized string similar to Pokémon 3D requires OpenAL. ///Please visit https://www.openal.org/downloads/ to download. @@ -209,5 +281,23 @@ internal static string UpdateAvailableTitle { return ResourceManager.GetString("UpdateAvailableTitle", resourceCulture); } } + + /// + /// Looks up a localized string similar to The Profile was successfully updated!. + /// + internal static string Updated { + get { + return ResourceManager.GetString("Updated", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Success!. + /// + internal static string UpdatedTitle { + get { + return ResourceManager.GetString("UpdatedTitle", resourceCulture); + } + } } } diff --git a/P3D-Legacy Launcher/Forms/MBLang.es.resx b/P3D-Legacy Launcher/Forms/MBLang.es.resx index 1bfd977..5cda48f 100644 --- a/P3D-Legacy Launcher/Forms/MBLang.es.resx +++ b/P3D-Legacy Launcher/Forms/MBLang.es.resx @@ -121,7 +121,19 @@ Pokémon 3D requiere Microsoft .NET Framework 4.0 Por favor, visite http://www.microsoft.com/en-us/download/details.aspx?id=17851 to para descargarlo. ¿Le gustaría abrir dicha página web ahora? - ¡Error! + Error + + + Error al descargar un archivo. Por favor, intente de nuevo. + + + Error + + + Hubo un error al reemplazar los archivos. + + + Error Una nueva versión del Launcher se encuentra disponible. @@ -144,16 +156,22 @@ No descargado + + El perfil no necesita ser actualizado. + + + Actualización no necesaria + Pokémon 3D requiere OpenAL. Por favor, visite https://www.openal.org/downloads/ para descargarlo. ¿Le gustaría abrir dicha página web ahora? - ¡Error! + Error - El profile '{0}' se encuenta actualizado + El perfil '{0}' se encuenta actualizado Validación de versión @@ -162,6 +180,13 @@ Por favor, visite https://www.openal.org/downloads/ para descargarlo. ¿Le gustaría actualizar de la versión [{0}] a la versión [{1}] (Sí) o le gustaría descargarla como una versión independiente (No)? - ¡Hay una actualización disponible! + Hay una actualización disponible. + + + El perfil ha sido actualizado con éxito. + + + Actualización completada + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/MBLang.nl.resx b/P3D-Legacy Launcher/Forms/MBLang.nl.resx index d54fa45..302fe3c 100644 --- a/P3D-Legacy Launcher/Forms/MBLang.nl.resx +++ b/P3D-Legacy Launcher/Forms/MBLang.nl.resx @@ -121,17 +121,27 @@ Pokémon 3D heeft Microsoft .NET Framework 4.0 nodig. Deze kun je hier downloaden: http://www.microsoft.com/en-us/download/details.aspx?id=17851 to download. Wil je de pagina openen? - - - Er ging iets mis! + + Het downloaden van een bestand is mislukt. + + + + Er ging iets mis! + + + Er ging iets mis tijdens het vervangen van oude bestanden met nieuwe bestanden! + + + Er ging iets mis! + Er is een nieuwe versie beschikbaar! Wil je het spel updaten? - Update is beschikbaar! + Update beschikbaar! Connectie naar GitHub mislukt! Is er een werkende internetverbinding beschikbaar? @@ -145,13 +155,16 @@ Wil je de pagina openen? Niet gedownload! + + Het profiel heeft geen update nodig! + + + Voltooid! + Pokémon 3D heeft OpenAL nodig. Je kunt OpenAL hier downloaden: https://www.openal.org/downloads/ to download. Wil je naar deze pagina gaan? - - - Er ging iets mis! @@ -167,4 +180,10 @@ Wil je naar deze pagina gaan? Update is beschikbaar! + + Dit profiel was succesvol geupdated! + + + Succes! + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/MBLang.resx b/P3D-Legacy Launcher/Forms/MBLang.resx index 167bd24..34e93aa 100644 --- a/P3D-Legacy Launcher/Forms/MBLang.resx +++ b/P3D-Legacy Launcher/Forms/MBLang.resx @@ -117,6 +117,12 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Can't update! Select a DL first in Settings tab! + + + Error! + Pokémon 3D requires Microsoft .NET Framework 4.0. Please visit http://www.microsoft.com/en-us/download/details.aspx?id=17851 to download. @@ -128,6 +134,18 @@ Would you like to open the webpage now? Error! + + Failed to download a file. Please try again! + + + Error! + + + Where was an error while replacing the old files with the new ones! + + + Error! + A new Launcher version is available! Would you like to update? @@ -148,6 +166,12 @@ Would you like to download it? Not Downloaded! + + The Profile doesn't need an update! + + + Done! + Pokémon 3D requires OpenAL. Please visit https://www.openal.org/downloads/ to download. @@ -171,4 +195,10 @@ Would you like to open the webpage now? Update is Available! + + The Profile was successfully updated! + + + Success! + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/MBLang.ru.resx b/P3D-Legacy Launcher/Forms/MBLang.ru.resx index d17b628..c7101c0 100644 --- a/P3D-Legacy Launcher/Forms/MBLang.ru.resx +++ b/P3D-Legacy Launcher/Forms/MBLang.ru.resx @@ -125,6 +125,18 @@ Ошибка! + + Возникла ошибка при скачивании файла! Повторите попытку! + + + Ошибка! + + + Возникла ошибка во время обновления старых файлов! + + + Ошибка! + Доступна новая версия лаунчера! Хотите обновиться? @@ -145,6 +157,12 @@ Ошибка! + + Профиль уже был обновлен! + + + Готово! + Pokémon 3D требует OpenAL. Вы можете скачать это по данной ссылке https://www.openal.org/downloads/ @@ -160,9 +178,15 @@ Проверка обновления - Would you like to update the [{0}] version to [{1}] (Yes) or would you like to download it as an independent version (No)? + Вы хотите обновить версию [{0}] до версии [{1}] (Да), или вы хотите скачать версию [{0}] как отдельную версию? (Нет)? Доступно обновление! + + Профиль был обновлен! + + + Готово! + \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/MainForm.Designer.cs b/P3D-Legacy Launcher/Forms/MainForm.Designer.cs index 68851c7..85fcb8d 100644 --- a/P3D-Legacy Launcher/Forms/MainForm.Designer.cs +++ b/P3D-Legacy Launcher/Forms/MainForm.Designer.cs @@ -43,12 +43,16 @@ private void InitializeComponent() this.TabPage_Logger = new System.Windows.Forms.TabPage(); this.TextBox_Logger = new System.Windows.Forms.TextBox(); this.TabPage_Settings = new System.Windows.Forms.TabPage(); + this.GroupBox_Netwok = new System.Windows.Forms.GroupBox(); + this.ComboBox_SelectedDL = new System.Windows.Forms.ComboBox(); + this.Label_SelectedDL = new System.Windows.Forms.Label(); this.Button_SaveSettings = new System.Windows.Forms.Button(); this.GroupBox_Startup = new System.Windows.Forms.GroupBox(); this.Label_Language = new System.Windows.Forms.Label(); this.ComboBox_Language = new System.Windows.Forms.ComboBox(); this.Check_Updates = new System.Windows.Forms.CheckBox(); this.TabPage_About = new System.Windows.Forms.TabPage(); + this.TextBox_Credits = new System.Windows.Forms.TextBox(); this.Label_Version = new System.Windows.Forms.Label(); this.LinkLabel_Pokemon3D = new System.Windows.Forms.LinkLabel(); this.TextBox_About = new System.Windows.Forms.TextBox(); @@ -56,6 +60,7 @@ private void InitializeComponent() this.TabPage_News.SuspendLayout(); this.TabPage_Logger.SuspendLayout(); this.TabPage_Settings.SuspendLayout(); + this.GroupBox_Netwok.SuspendLayout(); this.GroupBox_Startup.SuspendLayout(); this.TabPage_About.SuspendLayout(); this.SuspendLayout(); @@ -140,12 +145,32 @@ private void InitializeComponent() // // TabPage_Settings // + this.TabPage_Settings.Controls.Add(this.GroupBox_Netwok); this.TabPage_Settings.Controls.Add(this.Button_SaveSettings); this.TabPage_Settings.Controls.Add(this.GroupBox_Startup); resources.ApplyResources(this.TabPage_Settings, "TabPage_Settings"); this.TabPage_Settings.Name = "TabPage_Settings"; this.TabPage_Settings.UseVisualStyleBackColor = true; // + // GroupBox_Netwok + // + this.GroupBox_Netwok.Controls.Add(this.ComboBox_SelectedDL); + this.GroupBox_Netwok.Controls.Add(this.Label_SelectedDL); + resources.ApplyResources(this.GroupBox_Netwok, "GroupBox_Netwok"); + this.GroupBox_Netwok.Name = "GroupBox_Netwok"; + this.GroupBox_Netwok.TabStop = false; + // + // ComboBox_SelectedDL + // + resources.ApplyResources(this.ComboBox_SelectedDL, "ComboBox_SelectedDL"); + this.ComboBox_SelectedDL.FormattingEnabled = true; + this.ComboBox_SelectedDL.Name = "ComboBox_SelectedDL"; + // + // Label_SelectedDL + // + resources.ApplyResources(this.Label_SelectedDL, "Label_SelectedDL"); + this.Label_SelectedDL.Name = "Label_SelectedDL"; + // // Button_SaveSettings // resources.ApplyResources(this.Button_SaveSettings, "Button_SaveSettings"); @@ -169,8 +194,8 @@ private void InitializeComponent() // // ComboBox_Language // - this.ComboBox_Language.FormattingEnabled = true; resources.ApplyResources(this.ComboBox_Language, "ComboBox_Language"); + this.ComboBox_Language.FormattingEnabled = true; this.ComboBox_Language.Name = "ComboBox_Language"; // // Check_Updates @@ -181,6 +206,7 @@ private void InitializeComponent() // // TabPage_About // + this.TabPage_About.Controls.Add(this.TextBox_Credits); this.TabPage_About.Controls.Add(this.Label_Version); this.TabPage_About.Controls.Add(this.LinkLabel_Pokemon3D); this.TabPage_About.Controls.Add(this.TextBox_About); @@ -188,6 +214,14 @@ private void InitializeComponent() this.TabPage_About.Name = "TabPage_About"; this.TabPage_About.UseVisualStyleBackColor = true; // + // TextBox_Credits + // + this.TextBox_Credits.BackColor = System.Drawing.Color.White; + this.TextBox_Credits.BorderStyle = System.Windows.Forms.BorderStyle.None; + resources.ApplyResources(this.TextBox_Credits, "TextBox_Credits"); + this.TextBox_Credits.Name = "TextBox_Credits"; + this.TextBox_Credits.ReadOnly = true; + // // Label_Version // resources.ApplyResources(this.Label_Version, "Label_Version"); @@ -222,13 +256,14 @@ private void InitializeComponent() this.Controls.Add(this.Putton_StartGame); this.Name = "MainForm"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); - this.Load += new System.EventHandler(this.MainForm_Load); this.Shown += new System.EventHandler(this.MainForm_Shown); this.TabControl.ResumeLayout(false); this.TabPage_News.ResumeLayout(false); this.TabPage_Logger.ResumeLayout(false); this.TabPage_Logger.PerformLayout(); this.TabPage_Settings.ResumeLayout(false); + this.GroupBox_Netwok.ResumeLayout(false); + this.GroupBox_Netwok.PerformLayout(); this.GroupBox_Startup.ResumeLayout(false); this.GroupBox_Startup.PerformLayout(); this.TabPage_About.ResumeLayout(false); @@ -260,6 +295,10 @@ private void InitializeComponent() private ComboBox ComboBox_Language; private Button Button_SaveSettings; private Label Label_Version; + private GroupBox GroupBox_Netwok; + private ComboBox ComboBox_SelectedDL; + private Label Label_SelectedDL; + private TextBox TextBox_Credits; } } diff --git a/P3D-Legacy Launcher/Forms/MainForm.cs b/P3D-Legacy Launcher/Forms/MainForm.cs index 89afc5c..deaa241 100644 --- a/P3D-Legacy Launcher/Forms/MainForm.cs +++ b/P3D-Legacy Launcher/Forms/MainForm.cs @@ -20,6 +20,8 @@ namespace P3D.Legacy.Launcher.Forms { public partial class MainForm : Form { + public static StringBuilder Logger { get; } = new StringBuilder(); + #region GitHub private Version OnlineLastGameReleaseVersion => OnlineLastGameRelease?.Version ?? new Version("0.0"); @@ -36,41 +38,42 @@ private static IEnumerable GetOnlineGameReleases() => private OperatingSystemInfo OSInfo { get; } = OperatingSystemInfo.GetOperatingSystemInfo(); - private Profiles Profiles { get; set; } - private Profile CurrentProfile => Profiles.GetProfile(); - private Settings Settings { get; set; } = LoadSettings(); + private Profiles Profiles { get; set; } = LoadProfiles(); + private Profile CurrentProfile => Profiles.GetProfile(); + public MainForm() { - var lang = CultureInfo.CurrentUICulture.DisplayName; + FormPreInitialize(); + InitializeComponent(); + FormInitialize(); + } + private void FormPreInitialize() + { + foreach (Control control in Controls) + control.Dispose(); + Controls.Clear(); Thread.CurrentThread.CurrentCulture = Settings.Language; Thread.CurrentThread.CurrentUICulture = Settings.Language; CultureInfo.DefaultThreadCurrentCulture = Settings.Language; - - InitializeComponent(); - FormInitialize(); - - var builder = new StringBuilder(TextBox_Logger.Text); - builder.AppendLine($"System Language: {lang}"); - TextBox_Logger.Text = builder.ToString(); } private void FormInitialize() { + Logger.Clear(); + Log($"System Language: {CultureInfo.InstalledUICulture.EnglishName}"); + Label_Version.Text = Assembly.GetExecutingAssembly().GetName().Version.ToString(); TabPage_Settings.VisibleChanged += TabPage_Settings_VisibleChanged; - - ReloadProfileList(); } - private void MainForm_Load(object sender, EventArgs e) - { - - } private void MainForm_Shown(object sender, EventArgs e) { + ReloadSettings(); + ReloadProfileList(); + CheckLauncherForUpdate(); if (Settings.GameUpdates) @@ -88,13 +91,21 @@ private void Button_Start_Click(object sender, EventArgs e) if (!IsOpenALInstalled()) { if (MessageBox.Show(MBLang.OpenALError, MBLang.OpenALErrorTitle, MessageBoxButtons.YesNo) == DialogResult.Yes) + { Process.Start(MBLang.OpenALErrorLink); + Invoke((MethodInvoker) Close); + return; + } } } else { if (MessageBox.Show(MBLang.DotNetError, MBLang.DotNetErrorTitle, MessageBoxButtons.YesNo) == DialogResult.Yes) + { Process.Start(MBLang.DotNetErrorLink); + Invoke((MethodInvoker) Close); + return; + } } @@ -104,7 +115,8 @@ private void Button_Start_Click(object sender, EventArgs e) if (Directory.Exists(path) && File.Exists(pathexe)) { Process.Start(pathexe); - Close(); + Invoke((MethodInvoker) Close); + return; } else { @@ -125,9 +137,6 @@ private bool IsOpenALInstalled() if (OSInfo.OperatingSystemType == OperatingSystemType.Unix) return true; - if (OSInfo.OperatingSystemType == OperatingSystemType.Unity5) - return true; - if (OSInfo.OperatingSystemType == OperatingSystemType.MacOSX) return true; @@ -170,15 +179,7 @@ private void ComboBox_CurrentProfile_SelectedIndexChanged(object sender, EventAr private void TabPage_Settings_VisibleChanged(object sender, EventArgs e) { if ((sender as TabPage).Visible) - { - Settings = LoadSettings(); - - Check_Updates.Checked = Settings.GameUpdates; - ComboBox_Language.Items.Clear(); - foreach (var cultureInfo in Settings.AvailableCultureInfo) - ComboBox_Language.Items.Add(cultureInfo.NativeName); - ComboBox_Language.SelectedIndex = Array.IndexOf(Settings.AvailableCultureInfo, Settings.Language); - } + ReloadSettings(); } private void Button_SaveSettings_Click(object sender, EventArgs e) { @@ -187,6 +188,7 @@ private void Button_SaveSettings_Click(object sender, EventArgs e) { GameUpdates = Check_Updates.Checked, Language = Settings.AvailableCultureInfo[ComboBox_Language.SelectedIndex], + SelectedDL = UpdateInfo.DLUris.Length >= ComboBox_SelectedDL.SelectedIndex ? null : UpdateInfo.DLUris[ComboBox_SelectedDL.SelectedIndex], }; SaveSettings(Settings); @@ -195,11 +197,7 @@ private void Button_SaveSettings_Click(object sender, EventArgs e) { var tabIndex = TabControl.SelectedIndex; - Thread.CurrentThread.CurrentCulture = Settings.Language; - Thread.CurrentThread.CurrentUICulture = Settings.Language; - CultureInfo.DefaultThreadCurrentCulture = Settings.Language; - - Controls.Clear(); + FormPreInitialize(); InitializeComponent(); FormInitialize(); @@ -213,6 +211,12 @@ private void LinkLabel_Pokemon3D_LinkClicked(object sender, LinkLabelLinkClicked } + private void Log(string message) + { + Logger.AppendLine(message); + TextBox_Logger.Text = Logger.ToString(); + } + private void CheckLauncherForUpdate() { var launcherReleases = GitHubInfo.GetAllLauncherReleases.ToList(); @@ -229,15 +233,12 @@ private void CheckLauncherForUpdate() directUpdater.ShowDialog(); Program.ActionsBeforeExit.Add(() => - new Process - { - StartInfo = + new Process { StartInfo = { UseShellExecute = false, FileName = Path.Combine(FileSystemInfo.MainFolderPath, FileSystemInfo.UpdaterExeFilename), CreateNoWindow = true - } - }.Start()); + } }.Start()); Close(); break; @@ -293,15 +294,16 @@ private bool DownloadCurrentProfile() } private void UpdateCurrentProfile(OnlineGameRelease onlineRelease) { - // -- Would you like to update the [%OLDVERSION%] version to [%NEWVERSION%] or would you like to download it as an independent version? - // -- If Update, use UpdateManager - // -- Else, just download latesr Release.Zip - switch (MessageBox.Show(string.Format(MBLang.UpdateAvailable, CurrentProfile.Version, onlineRelease.Version), MBLang.UpdateAvailableTitle, MessageBoxButtons.YesNoCancel)) { case DialogResult.Yes: - using (var nAppUpdater = new NAppUpdaterForm(onlineRelease)) - nAppUpdater.ShowDialog(); + if (Settings.SelectedDL != null && !string.IsNullOrEmpty(Settings.SelectedDL.AbsolutePath)) + { + using (var nAppUpdater = new CustomUpdaterForm(onlineRelease.UpdateInfoAsset, Path.Combine(FileSystemInfo.GameReleasesFolderPath, CurrentProfile.Name), new Uri(Settings.SelectedDL, $"{CurrentProfile.Version}/"))) + nAppUpdater.ShowDialog(); + } + else + MessageBox.Show(MBLang.DLNotSelected, MBLang.DLNotSelectedTitle, MessageBoxButtons.OK); break; case DialogResult.No: @@ -317,14 +319,39 @@ private void UpdateCurrentProfile(OnlineGameRelease onlineRelease) private void ReloadProfileList() { Profiles = LoadProfiles(); + + if (Controls.Count == 0) + return; + ComboBox_CurrentProfile.Items.Clear(); foreach (var profile in Profiles.ProfileList) ComboBox_CurrentProfile.Items.Add(profile.Name); ComboBox_CurrentProfile.SelectedIndex = Profiles.ProfileIndex; } + private void ReloadSettings() + { + Settings = LoadSettings(); + if(Controls.Count == 0) + return; + + Check_Updates.Checked = Settings.GameUpdates; + + ComboBox_Language.Items.Clear(); + foreach (var cultureInfo in Settings.AvailableCultureInfo) + ComboBox_Language.Items.Add(cultureInfo.NativeName); + ComboBox_Language.SelectedIndex = Array.IndexOf(Settings.AvailableCultureInfo, Settings.Language); + + if (Settings.SelectedDL == null) + Settings.SelectedDL = UpdateInfo.DLUris.FirstOrDefault(); + + ComboBox_SelectedDL.Items.Clear(); + foreach (var dlUri in UpdateInfo.DLUris) + ComboBox_SelectedDL.Items.Add(dlUri); + ComboBox_SelectedDL.SelectedIndex = Array.IndexOf(UpdateInfo.DLUris, Settings.SelectedDL); + } - public static void SaveSettings(Settings settings) + private static void SaveSettings(Settings settings) { if (!File.Exists(FileSystemInfo.SettingsFilePath)) File.Create(FileSystemInfo.SettingsFilePath).Dispose(); @@ -332,7 +359,7 @@ public static void SaveSettings(Settings settings) var serializer = Settings.SerializerBuilder.Build(); File.WriteAllText(FileSystemInfo.SettingsFilePath, serializer.Serialize(settings)); } - public static Settings LoadSettings() + private static Settings LoadSettings() { if (!File.Exists(FileSystemInfo.SettingsFilePath)) File.Create(FileSystemInfo.SettingsFilePath).Dispose(); diff --git a/P3D-Legacy Launcher/Forms/MainForm.es.resx b/P3D-Legacy Launcher/Forms/MainForm.es.resx index 17dc365..c1ced8d 100644 --- a/P3D-Legacy Launcher/Forms/MainForm.es.resx +++ b/P3D-Legacy Launcher/Forms/MainForm.es.resx @@ -138,12 +138,18 @@ Buscar actualizaciones al iniciar + + Network + Común Idioma: + + Selected DL: + Pokémon3D diff --git a/P3D-Legacy Launcher/Forms/MainForm.nl.resx b/P3D-Legacy Launcher/Forms/MainForm.nl.resx index 37389e7..8807d1d 100644 --- a/P3D-Legacy Launcher/Forms/MainForm.nl.resx +++ b/P3D-Legacy Launcher/Forms/MainForm.nl.resx @@ -138,12 +138,18 @@ Check voor updates bij het opstarten + + Netwerk + Algemeen Taal + + Geselecteerde download: + Pokémon3D diff --git a/P3D-Legacy Launcher/Forms/MainForm.resx b/P3D-Legacy Launcher/Forms/MainForm.resx index 459012a..c989689 100644 --- a/P3D-Legacy Launcher/Forms/MainForm.resx +++ b/P3D-Legacy Launcher/Forms/MainForm.resx @@ -405,6 +405,81 @@ 1 + + Top, Left, Right + + + 82, 20 + + + 733, 21 + + + 1 + + + ComboBox_SelectedDL + + + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + GroupBox_Netwok + + + 0 + + + True + + + 7, 23 + + + 69, 13 + + + 0 + + + Selected DL: + + + Label_SelectedDL + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + GroupBox_Netwok + + + 1 + + + 8, 92 + + + 822, 58 + + + 7 + + + Network + + + GroupBox_Netwok + + + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TabPage_Settings + + + 0 + 710, 357 @@ -427,7 +502,7 @@ TabPage_Settings - 0 + 1 Top, Left, Right @@ -459,6 +534,9 @@ 0 + + Top, Left, Right + 70, 42 @@ -511,7 +589,7 @@ 8, 6 - 822, 95 + 822, 80 5 @@ -529,7 +607,7 @@ TabPage_Settings - 1 + 2 4, 22 @@ -558,6 +636,39 @@ 2 + + Bottom + + + 3, 303 + + + True + + + 830, 80 + + + 13 + + + Launcher by Aragas +Translation: +SViper, Capt_Segis, Biggda76, Blurgaro, Aragas + + + + TextBox_Credits + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + TabPage_About + + + 0 + Top, Right @@ -586,19 +697,22 @@ TabPage_About - 0 + 1 - - True + + Top, Left, Right Segoe UI, 9.75pt, style=Bold + + NoControl + 0, 3 - 83, 17 + 830, 17 4 @@ -616,10 +730,7 @@ TabPage_About - 1 - - - Bottom + 2 3, 23 @@ -627,11 +738,8 @@ True - - Vertical - - 830, 360 + 830, 274 3 @@ -656,7 +764,7 @@ Pokémon 3D and The P3D Team neither owns nor claims to own any portion of the P TabPage_About - 2 + 3 4, 22 diff --git a/P3D-Legacy Launcher/Forms/MainForm.ru.resx b/P3D-Legacy Launcher/Forms/MainForm.ru.resx index c9b012e..f49ee22 100644 --- a/P3D-Legacy Launcher/Forms/MainForm.ru.resx +++ b/P3D-Legacy Launcher/Forms/MainForm.ru.resx @@ -151,7 +151,7 @@ Играть - Помощь + О программе... Логгер diff --git a/P3D-Legacy Launcher/Forms/NAppUpdaterForm.Designer.cs b/P3D-Legacy Launcher/Forms/NAppUpdaterForm.Designer.cs deleted file mode 100644 index 6475a85..0000000 --- a/P3D-Legacy Launcher/Forms/NAppUpdaterForm.Designer.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace P3D.Legacy.Launcher.Forms -{ - partial class NAppUpdaterForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NAppUpdaterForm)); - this.SuspendLayout(); - // - // NAppUpdaterForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(284, 262); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Name = "NAppUpdaterForm"; - this.Text = "NAppUpdater"; - this.ResumeLayout(false); - - } - - #endregion - } -} \ No newline at end of file diff --git a/P3D-Legacy Launcher/Forms/NAppUpdaterForm.cs b/P3D-Legacy Launcher/Forms/NAppUpdaterForm.cs deleted file mode 100644 index 4ad663d..0000000 --- a/P3D-Legacy Launcher/Forms/NAppUpdaterForm.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Windows.Forms; - -using P3D.Legacy.Launcher.Data; - -namespace P3D.Legacy.Launcher.Forms -{ - public partial class NAppUpdaterForm : Form - { - private OnlineGameRelease onlineRelease; - - public NAppUpdaterForm() - { - InitializeComponent(); - } - - public NAppUpdaterForm(OnlineGameRelease onlineRelease) - { - this.onlineRelease = onlineRelease; - } - } -} diff --git a/P3D-Legacy Launcher/P3D-Legacy Launcher.csproj b/P3D-Legacy Launcher/P3D-Legacy Launcher.csproj index ef4f4bc..71ba4c9 100644 --- a/P3D-Legacy Launcher/P3D-Legacy Launcher.csproj +++ b/P3D-Legacy Launcher/P3D-Legacy Launcher.csproj @@ -43,10 +43,6 @@ ..\packages\DotNetZip.1.10.1\lib\net20\DotNetZip.dll True - - ..\packages\NAppUpdate.Framework.0.5.1.0\lib\net40\NAppUpdate.Framework.dll - True - ..\packages\Octokit.0.23.0\lib\net45\Octokit.dll True @@ -67,6 +63,8 @@ + + @@ -75,6 +73,7 @@ True MBLang.resx + @@ -91,11 +90,11 @@ MainForm.cs - + Form - - NAppUpdaterForm.cs + + CustomUpdaterForm.cs Form @@ -107,6 +106,21 @@ + + CustomUpdaterForm.cs + + + CustomUpdaterForm.cs + + + CustomUpdaterForm.cs + + + CustomUpdaterForm.cs + + + CustomUpdaterForm.cs + DirectUpdaterForm.cs @@ -148,8 +162,8 @@ - - NAppUpdaterForm.cs + + CustomUpdaterForm.cs ProfileForm.cs diff --git a/P3D-Legacy Launcher/Properties/AssemblyInfo.cs b/P3D-Legacy Launcher/Properties/AssemblyInfo.cs index f29d313..32fbdb7 100644 --- a/P3D-Legacy Launcher/Properties/AssemblyInfo.cs +++ b/P3D-Legacy Launcher/Properties/AssemblyInfo.cs @@ -11,5 +11,5 @@ [assembly: Guid("d2a9c01e-686f-4aea-8b8c-5ae04387f0e0")] -[assembly: AssemblyVersion("1.1.5.0")] -[assembly: AssemblyFileVersion("1.1.5.0")] +[assembly: AssemblyVersion("1.1.6.0")] +[assembly: AssemblyFileVersion("1.1.6.0")] diff --git a/P3D-Legacy Launcher/Yaml/UriConverter.cs b/P3D-Legacy Launcher/Yaml/UriConverter.cs new file mode 100644 index 0000000..cc91708 --- /dev/null +++ b/P3D-Legacy Launcher/Yaml/UriConverter.cs @@ -0,0 +1,26 @@ +using System; + +using YamlDotNet.Core; +using YamlDotNet.Core.Events; +using YamlDotNet.Serialization; + +namespace P3D.Legacy.Launcher.Yaml +{ + public class UriConverter : IYamlTypeConverter + { + public bool Accepts(Type type) => type == typeof(Uri); + + public object ReadYaml(IParser parser, Type type) + { + var value = ((Scalar) parser.Current).Value; + parser.MoveNext(); + return new Uri(value); + } + + public void WriteYaml(IEmitter emitter, object value, Type type) + { + var uri = (Uri) value; + emitter.Emit(new Scalar(null, null, uri.AbsoluteUri, ScalarStyle.Plain, true, false)); + } + } +} \ No newline at end of file diff --git a/P3D-Legacy Launcher/packages.config b/P3D-Legacy Launcher/packages.config index 95fd396..53550c8 100644 --- a/P3D-Legacy Launcher/packages.config +++ b/P3D-Legacy Launcher/packages.config @@ -1,7 +1,6 @@  -