diff --git a/.gitignore b/.gitignore index 8dd4607..8ff2583 100644 --- a/.gitignore +++ b/.gitignore @@ -184,7 +184,7 @@ publish/ *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted -*.pubxml +# *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to diff --git a/Kiseki.Launcher.Core/Controller.cs b/Kiseki.Launcher.Core/Controller.cs new file mode 100644 index 0000000..23ea79b --- /dev/null +++ b/Kiseki.Launcher.Core/Controller.cs @@ -0,0 +1,88 @@ +using Newtonsoft.Json; + +namespace Kiseki.Launcher.Core +{ + public enum ProgressBarState + { + Normal, + Marquee + } + + public class Controller + { + private readonly string BaseURL; + private readonly string[] Arguments; + + public event EventHandler PageHeadingChanged; + public event EventHandler ProgressBarChanged; + public event EventHandler ProgressBarStateChanged; + public event EventHandler Launched; + + public Controller(string BaseURL, string[] Arguments) + { + this.BaseURL = BaseURL; + this.Arguments = Arguments; + } + + public async void Start() + { + this.OnPageHeadingChange("Connecting to Kiseki..."); + + bool marquee = true; + await foreach (int progressValue in StreamBackgroundOperationProgressAsync()) + { + if (marquee) + { + this.OnPageHeadingChange("Downloading Kiseki..."); + this.OnProgressBarStateChanged(ProgressBarState.Normal); + marquee = false; + } + + this.OnProgressBarChange(progressValue); + } + + static async IAsyncEnumerable StreamBackgroundOperationProgressAsync() + { + await Task.Delay(2800); + + for (int i = 0; i <= 100; i += 4) + { + yield return i; + await Task.Delay(200); + } + } + + this.OnPageHeadingChange("Installing Kiseki..."); + this.OnProgressBarStateChanged(ProgressBarState.Marquee); + + await Task.Delay(2200); + this.OnPageHeadingChange("Configuring Kiseki..."); + + await Task.Delay(1200); + this.OnPageHeadingChange("Launching Kiseki..."); + + await Task.Delay(3000); + this.OnLaunched(); + } + + protected virtual void OnPageHeadingChange(string Heading) + { + PageHeadingChanged.Invoke(this, Heading); + } + + protected virtual void OnProgressBarChange(int Value) + { + ProgressBarChanged.Invoke(this, Value); + } + + protected virtual void OnProgressBarStateChanged(ProgressBarState State) + { + ProgressBarStateChanged.Invoke(this, State); + } + + protected virtual void OnLaunched() + { + Launched.Invoke(this, EventArgs.Empty); + } + } +} diff --git a/Kiseki.Launcher.Core/Kiseki.Launcher.Core.projitems b/Kiseki.Launcher.Core/Kiseki.Launcher.Core.projitems new file mode 100644 index 0000000..1dc91cb --- /dev/null +++ b/Kiseki.Launcher.Core/Kiseki.Launcher.Core.projitems @@ -0,0 +1,14 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + 9da0f813-6151-496b-b907-c94a7b6a3889 + + + Kiseki.Launcher.Core + + + + + \ No newline at end of file diff --git a/Kiseki.Launcher.Core/Kiseki.Launcher.Core.shproj b/Kiseki.Launcher.Core/Kiseki.Launcher.Core.shproj new file mode 100644 index 0000000..0656f39 --- /dev/null +++ b/Kiseki.Launcher.Core/Kiseki.Launcher.Core.shproj @@ -0,0 +1,13 @@ + + + + 9da0f813-6151-496b-b907-c94a7b6a3889 + 14.0 + + + + + + + + diff --git a/Kiseki.Launcher.Linux/Kiseki.Launcher.Linux.csproj b/Kiseki.Launcher.Linux/Kiseki.Launcher.Linux.csproj new file mode 100644 index 0000000..3fb0f90 --- /dev/null +++ b/Kiseki.Launcher.Linux/Kiseki.Launcher.Linux.csproj @@ -0,0 +1,17 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + + + diff --git a/Kiseki.Launcher.Linux/MainWindow.cs b/Kiseki.Launcher.Linux/MainWindow.cs new file mode 100644 index 0000000..8049a0f --- /dev/null +++ b/Kiseki.Launcher.Linux/MainWindow.cs @@ -0,0 +1,32 @@ +using Gtk; +using Kiseki.Launcher.Core; + +using UI = Gtk.Builder.ObjectAttribute; + +namespace Kiseki.Launcher.Linux +{ + public class MainWindow : Window + { + [UI] private readonly Image Logo = null; + [UI] private readonly ProgressBar ProgressBar = null; + [UI] private readonly Label PageHeading = null; + [UI] private readonly Button CancelButton = null; + + private readonly Controller Controller; + + public MainWindow() : this(new Builder("MainWindow.glade")) { } + + private MainWindow(Builder builder) : base(builder.GetRawOwnedObject("MainWindow")) + { + builder.Autoconnect(this); + + DeleteEvent += Window_DeleteEvent; + CancelButton.Clicked += Window_DeleteEvent; + } + + private void Window_DeleteEvent(object? sender, EventArgs? e) + { + Application.Quit(); + } + } +} diff --git a/Kiseki.Launcher.Linux/MainWindow.glade b/Kiseki.Launcher.Linux/MainWindow.glade new file mode 100644 index 0000000..6bbc00d --- /dev/null +++ b/Kiseki.Launcher.Linux/MainWindow.glade @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Kiseki.Launcher.Linux/Program.cs b/Kiseki.Launcher.Linux/Program.cs new file mode 100644 index 0000000..2b03079 --- /dev/null +++ b/Kiseki.Launcher.Linux/Program.cs @@ -0,0 +1,22 @@ +using Gtk; + +namespace Kiseki.Launcher.Linux +{ + public class Program + { + [STAThread] + public static void Main(string[] args) + { + Application.Init(); + + var app = new Application("org.Kiseki.Launcher", GLib.ApplicationFlags.None); + app.Register(GLib.Cancellable.Current); + + var window = new MainWindow(); + app.AddWindow(window); + + window.Show(); + Application.Run(); + } + } +} \ No newline at end of file diff --git a/Kiseki.Launcher.Linux/Properties/PublishProfiles/Publish-x64.pubxml b/Kiseki.Launcher.Linux/Properties/PublishProfiles/Publish-x64.pubxml new file mode 100644 index 0000000..1616354 --- /dev/null +++ b/Kiseki.Launcher.Linux/Properties/PublishProfiles/Publish-x64.pubxml @@ -0,0 +1,18 @@ + + + + + Release + Any CPU + ..\bin\Release\linux-x64\ + FileSystem + <_TargetId>Folder + net6.0 + linux-x64 + false + true + false + + \ No newline at end of file diff --git a/Kiseki.Launcher.Windows/Kiseki.Launcher.Windows.csproj b/Kiseki.Launcher.Windows/Kiseki.Launcher.Windows.csproj new file mode 100644 index 0000000..e7698dc --- /dev/null +++ b/Kiseki.Launcher.Windows/Kiseki.Launcher.Windows.csproj @@ -0,0 +1,47 @@ + + + + WinExe + net6.0-windows + enable + true + Resources\IconKiseki.ico + enable + 1.0.0 + 1.0.0.0 + Kiseki.Launcher + + + + + + + + + True + True + Resources.resx + + + True + True + Settings.settings + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + \ No newline at end of file diff --git a/Kiseki.Launcher.Windows/MainWindow.cs b/Kiseki.Launcher.Windows/MainWindow.cs new file mode 100644 index 0000000..45ce0ba --- /dev/null +++ b/Kiseki.Launcher.Windows/MainWindow.cs @@ -0,0 +1,77 @@ +using Kiseki.Launcher.Windows.Properties; +using Kiseki.Launcher.Core; + +namespace Kiseki.Launcher.Windows +{ + [System.ComponentModel.DesignerCategory("")] + public class MainWindow : Form + { + private readonly TaskDialogButton CloseButton; + private readonly TaskDialogPage Page; + private readonly Controller Controller; + + public MainWindow(string[] args) + { + this.CloseButton = TaskDialogButton.Close; + + this.Page = new TaskDialogPage() + { + Caption = "Kiseki", + AllowMinimize = true, + + ProgressBar = new TaskDialogProgressBar() + { + State = TaskDialogProgressBarState.Marquee + }, + + Buttons = { this.CloseButton } + }; + + this.Controller = new Controller("kiseki.lol", args); + this.Controller.PageHeadingChanged += Controller_PageHeadingChanged; + this.Controller.ProgressBarChanged += Controller_ProgressBarChanged; + this.Controller.ProgressBarStateChanged += Controller_ProgressBarStateChanged; + this.Controller.Launched += Controller_Launched; + + this.ShowProgressDialog(); + } + + private void Controller_PageHeadingChanged(object sender, string Heading) + { + this.Page.Heading = Heading; + } + + private void Controller_ProgressBarChanged(object sender, int Value) + { + this.Page.ProgressBar.Value = Value; + } + + private void Controller_ProgressBarStateChanged(object sender, ProgressBarState State) + { + this.Page.ProgressBar.State = State switch + { + ProgressBarState.Normal => TaskDialogProgressBarState.Normal, + ProgressBarState.Marquee => TaskDialogProgressBarState.Marquee, + _ => throw new NotImplementedException() + }; + } + + private void Controller_Launched(object sender, EventArgs e) + { + Environment.Exit(0); + } + + private void ShowProgressDialog() + { + TaskDialogIcon logo = new(Resources.IconKiseki); + this.Page.Icon = logo; + + this.Page.Created += (s, e) => + { + this.Controller.Start(); + }; + + TaskDialog.ShowDialog(this.Page); + } + } +} diff --git a/Kiseki.Launcher/Program.cs b/Kiseki.Launcher.Windows/Program.cs similarity index 76% rename from Kiseki.Launcher/Program.cs rename to Kiseki.Launcher.Windows/Program.cs index 4f09483..91e0924 100644 --- a/Kiseki.Launcher/Program.cs +++ b/Kiseki.Launcher.Windows/Program.cs @@ -1,4 +1,4 @@ -namespace Kiseki.Launcher +namespace Kiseki.Launcher.Windows { internal static class Program { @@ -6,12 +6,12 @@ namespace Kiseki.Launcher /// The main entry point for the application. /// [STAThread] - static void Main() + static void Main(string[] args) { // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new Form1()); + Application.Run(new MainWindow(args)); } } } \ No newline at end of file diff --git a/Kiseki.Launcher.Windows/Properties/PublishProfiles/Publish-x64.pubxml b/Kiseki.Launcher.Windows/Properties/PublishProfiles/Publish-x64.pubxml new file mode 100644 index 0000000..6d6db53 --- /dev/null +++ b/Kiseki.Launcher.Windows/Properties/PublishProfiles/Publish-x64.pubxml @@ -0,0 +1,18 @@ + + + + + Release + Any CPU + ..\bin\Release\win-x64\ + FileSystem + <_TargetId>Folder + net6.0-windows + win-x64 + false + true + false + + \ No newline at end of file diff --git a/Kiseki.Launcher.Windows/Properties/Resources.Designer.cs b/Kiseki.Launcher.Windows/Properties/Resources.Designer.cs new file mode 100644 index 0000000..31bbf90 --- /dev/null +++ b/Kiseki.Launcher.Windows/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Kiseki.Launcher.Windows.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Kiseki.Launcher.Windows.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon IconKiseki { + get { + object obj = ResourceManager.GetObject("IconKiseki", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + } +} diff --git a/Kiseki.Launcher/Form1.resx b/Kiseki.Launcher.Windows/Properties/Resources.resx similarity index 93% rename from Kiseki.Launcher/Form1.resx rename to Kiseki.Launcher.Windows/Properties/Resources.resx index 1af7de1..84c37fb 100644 --- a/Kiseki.Launcher/Form1.resx +++ b/Kiseki.Launcher.Windows/Properties/Resources.resx @@ -117,4 +117,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\IconKiseki.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Kiseki.Launcher.Windows/Resources/IconKiseki.ico b/Kiseki.Launcher.Windows/Resources/IconKiseki.ico new file mode 100644 index 0000000..c0e5344 Binary files /dev/null and b/Kiseki.Launcher.Windows/Resources/IconKiseki.ico differ diff --git a/Kiseki.Launcher.sln b/Kiseki.Launcher.sln index d5df861..fd670f4 100644 --- a/Kiseki.Launcher.sln +++ b/Kiseki.Launcher.sln @@ -3,7 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.6.33712.159 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kiseki.Launcher", "Kiseki.Launcher\Kiseki.Launcher.csproj", "{BE53015E-6EB9-42F7-BA80-887D0A5F9977}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kiseki.Launcher.Windows", "Kiseki.Launcher.Windows\Kiseki.Launcher.Windows.csproj", "{38AAA6A8-C482-4F17-816F-E0A42B065033}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kiseki.Launcher.Linux", "Kiseki.Launcher.Linux\Kiseki.Launcher.Linux.csproj", "{40AB861A-C06C-4279-86F6-EC60BEC2C690}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Kiseki.Launcher.Core", "Kiseki.Launcher.Core\Kiseki.Launcher.Core.shproj", "{9DA0F813-6151-496B-B907-C94A7B6A3889}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +15,24 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {BE53015E-6EB9-42F7-BA80-887D0A5F9977}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BE53015E-6EB9-42F7-BA80-887D0A5F9977}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BE53015E-6EB9-42F7-BA80-887D0A5F9977}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BE53015E-6EB9-42F7-BA80-887D0A5F9977}.Release|Any CPU.Build.0 = Release|Any CPU + {38AAA6A8-C482-4F17-816F-E0A42B065033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38AAA6A8-C482-4F17-816F-E0A42B065033}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38AAA6A8-C482-4F17-816F-E0A42B065033}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38AAA6A8-C482-4F17-816F-E0A42B065033}.Release|Any CPU.Build.0 = Release|Any CPU + {40AB861A-C06C-4279-86F6-EC60BEC2C690}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {40AB861A-C06C-4279-86F6-EC60BEC2C690}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40AB861A-C06C-4279-86F6-EC60BEC2C690}.Release|Any CPU.ActiveCfg = Release|Any CPU + {40AB861A-C06C-4279-86F6-EC60BEC2C690}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {E283B6E8-7F09-414D-AA9C-0725447DC36B} + SolutionGuid = {E7B8D704-EF09-4D85-998B-ED22ECD4D09F} + EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + Kiseki.Launcher.Core\Kiseki.Launcher.Core.projitems*{38aaa6a8-c482-4f17-816f-e0a42b065033}*SharedItemsImports = 5 + Kiseki.Launcher.Core\Kiseki.Launcher.Core.projitems*{40ab861a-c06c-4279-86f6-ec60bec2c690}*SharedItemsImports = 5 + Kiseki.Launcher.Core\Kiseki.Launcher.Core.projitems*{9da0f813-6151-496b-b907-c94a7b6a3889}*SharedItemsImports = 13 EndGlobalSection EndGlobal diff --git a/Kiseki.Launcher/Form1.Designer.cs b/Kiseki.Launcher/Form1.Designer.cs deleted file mode 100644 index cf7f577..0000000 --- a/Kiseki.Launcher/Form1.Designer.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace Kiseki.Launcher -{ - partial class Form1 - { - /// - /// 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() - { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; - } - - #endregion - } -} \ No newline at end of file diff --git a/Kiseki.Launcher/Form1.cs b/Kiseki.Launcher/Form1.cs deleted file mode 100644 index 501e62c..0000000 --- a/Kiseki.Launcher/Form1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Kiseki.Launcher -{ - public partial class Form1 : Form - { - public Form1() - { - InitializeComponent(); - } - } -} \ No newline at end of file diff --git a/Kiseki.Launcher/Kiseki.Launcher.csproj b/Kiseki.Launcher/Kiseki.Launcher.csproj deleted file mode 100644 index b57c89e..0000000 --- a/Kiseki.Launcher/Kiseki.Launcher.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - WinExe - net6.0-windows - enable - true - enable - - - \ No newline at end of file