chore: refactor project, bug fixes
This commit is contained in:
parent
8dba3ab782
commit
10c2103762
|
|
@ -9,7 +9,78 @@ namespace Kiseki.Launcher.Windows
|
|||
{
|
||||
public readonly static string Version = Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2];
|
||||
|
||||
#region IBootstrapper implementation
|
||||
private readonly string Payload;
|
||||
private readonly Dictionary<string, string> Arguments = new();
|
||||
|
||||
public event EventHandler<string>? OnHeadingChange;
|
||||
public event EventHandler<int>? OnProgressBarAdd;
|
||||
public event EventHandler<Enums.ProgressBarState>? OnProgressBarStateChange;
|
||||
public event EventHandler<string[]>? OnError;
|
||||
|
||||
public Bootstrapper(string payload)
|
||||
{
|
||||
Payload = payload;
|
||||
}
|
||||
|
||||
public bool Initialize()
|
||||
{
|
||||
if (!Helpers.Base64.IsBase64String(Payload))
|
||||
{
|
||||
Error($"Failed to launch {Constants.PROJECT_NAME}", $"Try launching {Constants.PROJECT_NAME} from the website again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// mode, version, ticket, joinscript
|
||||
string[] pieces = Helpers.Base64.ConvertBase64ToString(Payload).Split("|");
|
||||
if (pieces.Length != 4)
|
||||
{
|
||||
Error($"Failed to launch {Constants.PROJECT_NAME}", $"Try launching {Constants.PROJECT_NAME} from the website again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Arguments["Mode"] = pieces[0];
|
||||
Arguments["Version"] = pieces[1];
|
||||
Arguments["Ticket"] = pieces[2];
|
||||
Arguments["JoinScript"] = pieces[3];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public void Abort()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
#region MainWindow
|
||||
|
||||
protected virtual void HeadingChange(string heading)
|
||||
{
|
||||
OnHeadingChange!.Invoke(this, heading);
|
||||
}
|
||||
|
||||
protected virtual void ProgressBarAdd(int value)
|
||||
{
|
||||
OnProgressBarAdd!.Invoke(this, value);
|
||||
}
|
||||
|
||||
protected virtual void ProgressBarStateChange(Enums.ProgressBarState state)
|
||||
{
|
||||
OnProgressBarStateChange!.Invoke(this, state);
|
||||
}
|
||||
|
||||
protected virtual void Error(string heading, string text)
|
||||
{
|
||||
// ugly hack for now (I don't want to derive EventHandler just for this)
|
||||
OnError!.Invoke(this, new string[] { heading, text });
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region Installation
|
||||
|
||||
public static void Install()
|
||||
{
|
||||
|
|
@ -97,6 +168,9 @@ namespace Kiseki.Launcher.Windows
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region Registration
|
||||
|
||||
public static void Register()
|
||||
{
|
||||
using RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{Constants.PROJECT_NAME}");
|
||||
|
|
@ -136,7 +210,7 @@ namespace Kiseki.Launcher.Windows
|
|||
#endregion
|
||||
#region Licensing
|
||||
|
||||
public static void TryLoadLicense()
|
||||
public static void License()
|
||||
{
|
||||
if (!File.Exists(Directories.License))
|
||||
{
|
||||
|
|
@ -157,6 +231,14 @@ namespace Kiseki.Launcher.Windows
|
|||
}
|
||||
}
|
||||
|
||||
public static void Unlicense()
|
||||
{
|
||||
if (File.Exists(Directories.License))
|
||||
{
|
||||
File.Delete(Directories.License);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool AskForLicense(string licensePath, bool showDialog = true)
|
||||
{
|
||||
DialogResult answer = showDialog ? MessageBox.Show($"{Constants.PROJECT_NAME} is currently under maintenance and requires a license in order to access games. Would you like to look for the license file now?", Constants.PROJECT_NAME, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) : DialogResult.Yes;
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ namespace Kiseki.Launcher.Windows
|
|||
|
||||
if (!Directory.Exists(Base))
|
||||
{
|
||||
// just in case
|
||||
Directory.CreateDirectory(Base);
|
||||
Directory.CreateDirectory(Base); // just in case
|
||||
}
|
||||
|
||||
Logs = Path.Combine(Base, "Logs");
|
||||
|
|
|
|||
|
|
@ -7,16 +7,15 @@ namespace Kiseki.Launcher.Windows
|
|||
{
|
||||
private readonly TaskDialogButton CloseButton;
|
||||
private readonly TaskDialogPage Page;
|
||||
private readonly Controller Controller;
|
||||
private readonly Bootstrapper Bootstrapper;
|
||||
|
||||
public MainWindow(string payload)
|
||||
{
|
||||
Controller = new Controller(payload);
|
||||
Controller.OnPageHeadingChange += Controller_PageHeadingChanged;
|
||||
Controller.OnProgressBarAdd += Controller_ProgressBarAdded;
|
||||
Controller.OnProgressBarStateChange += Controller_ProgressBarStateChanged;
|
||||
Controller.OnErrorShow += Controller_ErrorShown;
|
||||
Controller.OnLaunch += (s, e) => Environment.Exit(0);
|
||||
Bootstrapper = new Bootstrapper(payload);
|
||||
Bootstrapper.OnHeadingChange += Bootstrapper_HeadingChanged;
|
||||
Bootstrapper.OnProgressBarAdd += Bootstrapper_ProgressBarAdded;
|
||||
Bootstrapper.OnProgressBarStateChange += Bootstrapper_ProgressBarStateChanged;
|
||||
Bootstrapper.OnError += Bootstrapper_Errored;
|
||||
|
||||
CloseButton = TaskDialogButton.Close;
|
||||
Page = new TaskDialogPage()
|
||||
|
|
@ -34,59 +33,51 @@ namespace Kiseki.Launcher.Windows
|
|||
|
||||
Page.Created += (s, e) =>
|
||||
{
|
||||
Controller.Start();
|
||||
};
|
||||
|
||||
Page.Destroyed += (s, e) =>
|
||||
{
|
||||
Controller.Dispose();
|
||||
Environment.Exit(0);
|
||||
Bootstrapper.Run();
|
||||
};
|
||||
|
||||
ShowProgressDialog();
|
||||
ShowTaskDialog();
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object? sender, EventArgs e)
|
||||
{
|
||||
Controller.Dispose();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private void Controller_PageHeadingChanged(object? sender, string heading)
|
||||
{
|
||||
Page.Heading = heading;
|
||||
}
|
||||
|
||||
private void Controller_ProgressBarAdded(object? sender, int value)
|
||||
{
|
||||
Page.ProgressBar!.Value += value;
|
||||
}
|
||||
|
||||
private void Controller_ProgressBarStateChanged(object? sender, ProgressBarState state)
|
||||
{
|
||||
Page.ProgressBar!.State = state switch
|
||||
{
|
||||
ProgressBarState.Normal => TaskDialogProgressBarState.Normal,
|
||||
ProgressBarState.Marquee => TaskDialogProgressBarState.Marquee,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
private void Controller_ErrorShown(object? sender, string[] texts)
|
||||
{
|
||||
Page.Icon = TaskDialogIcon.Error;
|
||||
Page.Heading = texts[0];
|
||||
Page.Text = texts[1];
|
||||
|
||||
Controller.Dispose();
|
||||
}
|
||||
|
||||
private void ShowProgressDialog()
|
||||
private void ShowTaskDialog()
|
||||
{
|
||||
TaskDialogIcon logo = new(Resources.IconKiseki);
|
||||
Page.Icon = logo;
|
||||
|
||||
TaskDialog.ShowDialog(Page);
|
||||
}
|
||||
|
||||
private void CloseButton_Click(object? sender, EventArgs e)
|
||||
{
|
||||
Bootstrapper.Abort();
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private void Bootstrapper_HeadingChanged(object? sender, string heading)
|
||||
{
|
||||
Page.Heading = heading;
|
||||
}
|
||||
|
||||
private void Bootstrapper_ProgressBarAdded(object? sender, int value)
|
||||
{
|
||||
Page.ProgressBar!.Value += value;
|
||||
}
|
||||
|
||||
private void Bootstrapper_ProgressBarStateChanged(object? sender, Enums.ProgressBarState state)
|
||||
{
|
||||
Page.ProgressBar!.State = state switch
|
||||
{
|
||||
Enums.ProgressBarState.Normal => TaskDialogProgressBarState.Normal,
|
||||
Enums.ProgressBarState.Marquee => TaskDialogProgressBarState.Marquee,
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
|
||||
private void Bootstrapper_Errored(object? sender, string[] texts)
|
||||
{
|
||||
Page.Icon = TaskDialogIcon.Error;
|
||||
Page.Heading = texts[0];
|
||||
Page.Text = texts[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,11 +7,12 @@ namespace Kiseki.Launcher.Windows
|
|||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Initialize directories
|
||||
string parentFolder = Path.GetDirectoryName(Application.ExecutablePath)!;
|
||||
|
||||
if (Path.GetDirectoryName(parentFolder)!.ToLower().Contains(Constants.PROJECT_NAME.ToLower()))
|
||||
{
|
||||
// Set to the current directory (either user-installed or default; it has "Kiseki" in the path, so that's good enough for us)
|
||||
// Set to the current directory (user likely has installed the launcher, seeing as parent folder name contains the project name)
|
||||
Directories.Initialize(parentFolder);
|
||||
}
|
||||
else
|
||||
|
|
@ -23,40 +24,49 @@ namespace Kiseki.Launcher.Windows
|
|||
bool isConnected = Web.Initialize();
|
||||
if (!isConnected && Web.IsInMaintenance)
|
||||
{
|
||||
// Try again with the maintenance domain
|
||||
Bootstrapper.TryLoadLicense();
|
||||
// Try licensing this launcher and attempt to connect again
|
||||
Bootstrapper.License();
|
||||
isConnected = Web.Initialize();
|
||||
}
|
||||
|
||||
if (!isConnected)
|
||||
{
|
||||
if (Web.IsInMaintenance)
|
||||
{
|
||||
// Unlicense this launcher
|
||||
Bootstrapper.Unlicense();
|
||||
}
|
||||
|
||||
MessageBox.Show($"Failed to connect to {Constants.PROJECT_NAME}. Please check your internet connection and try again.", Constants.PROJECT_NAME, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(Directories.Application))
|
||||
{
|
||||
// The launcher is not installed, so let's run the install process - this will also exit the application
|
||||
Bootstrapper.Install();
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
if (args.Length == 0)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
// Nothing for us to do :P
|
||||
Process.Start(new ProcessStartInfo()
|
||||
{
|
||||
// Nothing for us to do :P
|
||||
Process.Start($"open {Web.Url("/games")}");
|
||||
return;
|
||||
}
|
||||
FileName = Web.Url("/games"),
|
||||
UseShellExecute = true
|
||||
});
|
||||
|
||||
if (args[0] == "-uninstall")
|
||||
{
|
||||
Bootstrapper.Uninstall(args[0] == "-quiet");
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new MainWindow(args[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[0] == "-uninstall")
|
||||
{
|
||||
Bootstrapper.Uninstall(args[0] == "-quiet");
|
||||
return;
|
||||
}
|
||||
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new MainWindow(args[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
using Kiseki.Launcher.Helpers;
|
||||
|
||||
namespace Kiseki.Launcher
|
||||
{
|
||||
public enum ProgressBarState
|
||||
{
|
||||
Normal,
|
||||
Marquee
|
||||
}
|
||||
|
||||
public class Controller
|
||||
{
|
||||
private readonly Dictionary<string, string> Arguments = new();
|
||||
|
||||
public event EventHandler<string>? OnPageHeadingChange;
|
||||
public event EventHandler<int>? OnProgressBarAdd;
|
||||
public event EventHandler<ProgressBarState>? OnProgressBarStateChange;
|
||||
public event EventHandler<string[]>? OnErrorShow;
|
||||
public event EventHandler? OnLaunch;
|
||||
|
||||
public Controller(string payload)
|
||||
{
|
||||
if (!Base64.IsBase64String(payload))
|
||||
{
|
||||
ErrorShow($"Failed to launch {Constants.PROJECT_NAME}", $"Try launching {Constants.PROJECT_NAME} from the website again.");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: The payload will soon include more members; update this accordingly
|
||||
payload = Base64.ConvertBase64ToString(payload);
|
||||
if (payload.Split("|").Length != 2)
|
||||
{
|
||||
ErrorShow($"Failed to launch {Constants.PROJECT_NAME}", $"Try launching {Constants.PROJECT_NAME} from the website again.");
|
||||
return;
|
||||
}
|
||||
|
||||
Arguments["JoinScriptURL"] = payload.Split("|")[0];
|
||||
Arguments["Ticket"] = payload.Split("|")[1];
|
||||
}
|
||||
|
||||
public async void Start()
|
||||
{
|
||||
PageHeadingChange("Connecting to Kiseki...");
|
||||
|
||||
bool marquee = true;
|
||||
await foreach (int progressValue in StreamBackgroundOperationProgressAsync())
|
||||
{
|
||||
if (marquee)
|
||||
{
|
||||
PageHeadingChange("Downloading Kiseki...");
|
||||
ProgressBarStateChange(ProgressBarState.Normal);
|
||||
|
||||
marquee = false;
|
||||
}
|
||||
|
||||
ProgressBarAdd(progressValue);
|
||||
}
|
||||
|
||||
static async IAsyncEnumerable<int> StreamBackgroundOperationProgressAsync()
|
||||
{
|
||||
await Task.Delay(2800);
|
||||
|
||||
yield return 4;
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
PageHeadingChange("Installing Kiseki...");
|
||||
ProgressBarStateChange(ProgressBarState.Marquee);
|
||||
|
||||
await Task.Delay(2200);
|
||||
PageHeadingChange("Configuring Kiseki...");
|
||||
|
||||
await Task.Delay(1200);
|
||||
PageHeadingChange("Launching Kiseki...");
|
||||
|
||||
await Task.Delay(3000);
|
||||
Launch();
|
||||
}
|
||||
|
||||
public async void Dispose()
|
||||
{
|
||||
// TODO: This will only be called when the user closes the window OR we're done (i.e. the Launched event is called.)
|
||||
}
|
||||
|
||||
protected virtual void PageHeadingChange(string heading)
|
||||
{
|
||||
OnPageHeadingChange!.Invoke(this, heading);
|
||||
}
|
||||
|
||||
protected virtual void ProgressBarAdd(int value)
|
||||
{
|
||||
OnProgressBarAdd!.Invoke(this, value);
|
||||
}
|
||||
|
||||
protected virtual void ProgressBarStateChange(ProgressBarState state)
|
||||
{
|
||||
OnProgressBarStateChange!.Invoke(this, state);
|
||||
}
|
||||
|
||||
protected virtual void ErrorShow(string heading, string text)
|
||||
{
|
||||
// ugly hack for now (I don't want to derive EventHandler just for this)
|
||||
OnErrorShow!.Invoke(this, new string[] { heading, text });
|
||||
}
|
||||
|
||||
protected virtual void Launch()
|
||||
{
|
||||
OnLaunch!.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace Kiseki.Launcher.Enums
|
||||
{
|
||||
public enum PackageType
|
||||
{
|
||||
Bootstrapper,
|
||||
Client,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
namespace Kiseki.Launcher.Enums
|
||||
{
|
||||
public enum ProgressBarState
|
||||
{
|
||||
Normal,
|
||||
Marquee
|
||||
}
|
||||
}
|
||||
|
|
@ -2,9 +2,27 @@ namespace Kiseki.Launcher
|
|||
{
|
||||
public interface IBootstrapper
|
||||
{
|
||||
// These connect to MainWindow
|
||||
event EventHandler<string>? OnHeadingChange;
|
||||
event EventHandler<int>? OnProgressBarAdd;
|
||||
event EventHandler<Enums.ProgressBarState>? OnProgressBarStateChange;
|
||||
event EventHandler<string[]>? OnError;
|
||||
|
||||
// Actual bootstrapping
|
||||
bool Initialize();
|
||||
void Run();
|
||||
void Abort();
|
||||
|
||||
// Installation (i.e. putting the launcher in the Kiseki folder)
|
||||
static abstract void Install();
|
||||
static abstract void Uninstall(bool quiet = false);
|
||||
|
||||
// Registering the launcher onto the system (as well as creating shortcuts)
|
||||
static abstract void Register();
|
||||
static abstract void Unregister();
|
||||
|
||||
// Licensing the launcher
|
||||
static abstract void License();
|
||||
static abstract void Unlicense();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
namespace Kiseki.Launcher
|
||||
{
|
||||
// This is responsible for handling registration of the Kiseki protcool handler
|
||||
public interface IProtocol
|
||||
{
|
||||
static abstract void Register();
|
||||
|
|
|
|||
Loading…
Reference in New Issue