diff --git a/Kiseki.Launcher.Windows/Kiseki.Launcher.Windows.csproj b/Kiseki.Launcher.Windows/Kiseki.Launcher.Windows.csproj index f0d573b..1517034 100644 --- a/Kiseki.Launcher.Windows/Kiseki.Launcher.Windows.csproj +++ b/Kiseki.Launcher.Windows/Kiseki.Launcher.Windows.csproj @@ -45,4 +45,8 @@ + + + + \ No newline at end of file diff --git a/Kiseki.Launcher.Windows/Launcher.cs b/Kiseki.Launcher.Windows/Launcher.cs index c1a53d1..c4b1398 100644 --- a/Kiseki.Launcher.Windows/Launcher.cs +++ b/Kiseki.Launcher.Windows/Launcher.cs @@ -2,6 +2,8 @@ using System.Reflection; using Microsoft.Win32; +using Syroot.Windows.IO; + namespace Kiseki.Launcher.Windows { public class Launcher : ILauncher @@ -24,10 +26,20 @@ namespace Kiseki.Launcher.Windows else { // We are in maintenance mode, so let's ask for a license. - AskForLicense(Directories.License); - Web.LoadLicense(File.ReadAllText(Directories.License)); + if (!File.Exists(Directories.License)) + { + AskForLicense(Directories.License); + } + + // ... load the license ... + while (!Web.LoadLicense(File.ReadAllText(Directories.License))) + { + // ... and if it's invalid, keep asking for a new one. + File.Delete(Directories.License); + AskForLicense(Directories.License, false); + } - // ... try this again; + // ... and then try this again; Install(); } } @@ -35,21 +47,27 @@ namespace Kiseki.Launcher.Windows // okay, now download the launcher from the Kiseki website... } - private static void AskForLicense(string licensePath) + private static void AskForLicense(string licensePath, bool showDialog = true) { - using OpenFileDialog dialog = new() + DialogResult answer = showDialog ? MessageBox.Show($"{Constants.ProjectName} is currently under maintenance and requires a license in order to access games. Would you like to look for the license file now?", Constants.ProjectName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) : DialogResult.Yes; + + if (answer == DialogResult.Yes) { - Title = "Select your license file", - Filter = "License files (*.bin)|*.bin", - InitialDirectory = Directories.Base - }; + using OpenFileDialog dialog = new() + { + Title = "Select your license file", + Filter = "License files (*.bin)|*.bin", + InitialDirectory = KnownFolders.Downloads.Path + }; - if (dialog.ShowDialog() == DialogResult.OK) - { - File.Copy(dialog.FileName, licensePath, true); + if (dialog.ShowDialog() == DialogResult.OK) + { + File.Copy(dialog.FileName, licensePath, true); + } } } + // TODO: Implement this public static void Register() { using (RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{Constants.ProjectName}")) @@ -76,6 +94,7 @@ namespace Kiseki.Launcher.Windows uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{Constants.ProjectRepository}/releases/latest"); } + // TODO: Implement this public static void Unregister() { Registry.CurrentUser.DeleteSubKey($@"Software\{Constants.ProjectName}"); diff --git a/Kiseki.Launcher/Web.cs b/Kiseki.Launcher/Web.cs index 738509f..9a2c55a 100644 --- a/Kiseki.Launcher/Web.cs +++ b/Kiseki.Launcher/Web.cs @@ -1,3 +1,6 @@ +using System.Net; +using System.Text.Json; + namespace Kiseki.Launcher { public static class Web @@ -23,11 +26,36 @@ namespace Kiseki.Launcher return response is null ? RESPONSE_FAILURE : response.Status; } - public static void LoadLicense(string license) + public static bool LoadLicense(string license) { CurrentUrl = $"{MaintenanceDomain}.{CurrentUrl}"; + // the "license" is actually just headers required to access the website. + // this can be cloudflare zero-trust headers (like what Kiseki does), or however + // else you'd like to do auth-walls. either way; it's just a JSON document that + // has each byte XORed by 55 (for some basic obfuscation). + try + { + string json = ""; + for (int i = 0; i < license.Length; i++) + { + json += (char)(license[i] ^ 55); + } + + var headers = JsonSerializer.Deserialize>(json)!; + for (int i = 0; i < headers.Count; i++) + { + HttpClient.DefaultRequestHeaders.Add(headers.ElementAt(i).Key, headers.ElementAt(i).Value); + } + } + catch + { + MessageBox.Show($"Corrupt license file! Please verify the contents of your license file (it should be named \"license.bin\".)", Constants.ProjectName, MessageBoxButtons.OK, MessageBoxIcon.Error); + return false; + } + + return true; } } } \ No newline at end of file