diff --git a/Launcher-Core/Launcher-Core.csproj b/Launcher-Core/Launcher-Core.csproj index 839f8a6..c4ab723 100644 --- a/Launcher-Core/Launcher-Core.csproj +++ b/Launcher-Core/Launcher-Core.csproj @@ -8,16 +8,17 @@ true true - false + false - + + - + diff --git a/Launcher-Core/Launcher.cs b/Launcher-Core/Launcher.cs index 511dcc3..fcf7170 100644 --- a/Launcher-Core/Launcher.cs +++ b/Launcher-Core/Launcher.cs @@ -4,7 +4,9 @@ using System.Runtime.InteropServices; using System.Security.AccessControl; using CmlLib.Core; using CmlLib.Core.Auth; +using CmlLib.Core.Auth.Microsoft; using CmlLib.Core.ProcessBuilder; +using XboxAuthNet.Game.Msal; namespace Plombir; @@ -15,17 +17,15 @@ namespace Plombir; public class Launcher { private readonly string _version; - private readonly string _nickname; static private MinecraftPath? _mcPath; static private MinecraftLauncher? _mcLauncher; public int DownloadProgress; public string? DownloadStatus; - public Launcher(string userName, string version, string? location = null) + public Launcher(string version, string? location = null) { _version = version; - _nickname = userName; _mcPath = new($"{location}/{version}/minecraft"); _mcLauncher = new(_mcPath); } @@ -41,7 +41,7 @@ public class Launcher DownloadProgress = (int)(args.ProgressedBytes * 100 / args.TotalBytes); }; - DownloadStatus = "Installing minecraft..."; + DownloadStatus = "Getting the assets from Mojang..."; Console.WriteLine(DownloadStatus); await _mcLauncher.InstallAsync(_version); DownloadStatus = "Finished!"; @@ -49,15 +49,29 @@ public class Launcher return; } - async public Task RunLauncher() + public MSession CreateOfflineSession(string nickname) + { + var s = MSession.CreateOfflineSession(nickname); + if (s is null) throw new NullReferenceException("Tried creating offline session, but it's resulted in null!"); + return s; + } + + public MSession CreateLicensedSession(string uuid, string accsessToken, string nickname) + { + var s = new MSession(nickname, accsessToken, uuid); + if (s is null) throw new NullReferenceException("Tried creating licensed session, but it's resulted in null!"); + return s; + } + + async public Task RunLauncher(MSession session) { if (_mcLauncher is null) throw new NullReferenceException("Failed to run launcher! Launcher is null!"); var process = await _mcLauncher.BuildProcessAsync(_version, new MLaunchOption { - - Session = MSession.CreateOfflineSession(_nickname), + // Passing session, to support offline and licensed login methods. + Session = session, MaximumRamMb = 4096, }) ?? throw new Exception("Failed to start minecraft process!"); diff --git a/Launcher-Core/Program.cs b/Launcher-Core/Program.cs index 7a3ff86..c48c13e 100644 --- a/Launcher-Core/Program.cs +++ b/Launcher-Core/Program.cs @@ -2,8 +2,12 @@ namespace Plombir; sealed class Program { - public static void Main() + public static async Task Main() { Console.WriteLine("init: launcher"); + // var ln = new Launcher("test", "1.20.1"); + // var s = await Utils.GetLicensedSession(); + + // Console.WriteLine(s.CheckIsValid()); } } diff --git a/Launcher-Core/Utils.cs b/Launcher-Core/Utils.cs index 86cf813..724dff6 100644 --- a/Launcher-Core/Utils.cs +++ b/Launcher-Core/Utils.cs @@ -1,11 +1,8 @@ -using System.IO.Compression; -using System; -using System.IO; -using SharpCompress.Archives; -using SharpCompress.Common; -using SharpCompress.Readers; -using System.Diagnostics; + using CmlLib.Core; +using CmlLib.Core.Auth; +using XboxAuthNet.Game.Msal; +using CmlLib.Core.Auth.Microsoft; namespace Plombir; @@ -27,6 +24,34 @@ static public class Utils } + /* + ID is approved, we are so ready. + */ + public static async Task? GetLicensedSession() + { + try + { + var app = await MsalClientHelper.BuildApplicationWithCache( + "d87c436c-aad0-46ea-b392-b53b3ed787b1" + ); + var loginHandler = JELoginHandlerBuilder.BuildDefault(); - + var authenticator = loginHandler.CreateAuthenticatorWithNewAccount(default); + authenticator.AddMsalOAuth(app, msal => msal.SystemBrowser()); + // authenticator.AddMsalOAuth(app, msal => msal.DeviceCode(deviceCode => + // { + // Console.WriteLine(deviceCode.Message); + // return Task.CompletedTask; + // })); + // Im too lazy to implement this type of auth + authenticator.AddMsalOAuth(app, msal => msal.Silent()); + authenticator.AddXboxAuthForJE(xbox => xbox.Basic()); + authenticator.AddJEAuthenticator(); + return await authenticator.ExecuteForLauncherAsync(); + } + catch (Exception e) + { + throw new Exception($"Failed to authentificate! {e}"); + } + } } diff --git a/Launcher-UI/Assets/Sprites/account-logo.png b/Launcher-UI/Assets/Sprites/account-logo.png new file mode 100644 index 0000000..b4aeee2 Binary files /dev/null and b/Launcher-UI/Assets/Sprites/account-logo.png differ diff --git a/Launcher-UI/Assets/background.jpg b/Launcher-UI/Assets/Sprites/background.jpg similarity index 100% rename from Launcher-UI/Assets/background.jpg rename to Launcher-UI/Assets/Sprites/background.jpg diff --git a/Launcher-UI/Assets/cog.png b/Launcher-UI/Assets/Sprites/cog.png similarity index 100% rename from Launcher-UI/Assets/cog.png rename to Launcher-UI/Assets/Sprites/cog.png diff --git a/Launcher-UI/Assets/gitlab-logo.png b/Launcher-UI/Assets/Sprites/gitlab-logo.png similarity index 100% rename from Launcher-UI/Assets/gitlab-logo.png rename to Launcher-UI/Assets/Sprites/gitlab-logo.png diff --git a/Launcher-UI/Assets/icon.png b/Launcher-UI/Assets/Sprites/icon.png similarity index 100% rename from Launcher-UI/Assets/icon.png rename to Launcher-UI/Assets/Sprites/icon.png diff --git a/Launcher-UI/Assets/Sprites/microsoft-logo.png b/Launcher-UI/Assets/Sprites/microsoft-logo.png new file mode 100644 index 0000000..cdce9c1 Binary files /dev/null and b/Launcher-UI/Assets/Sprites/microsoft-logo.png differ diff --git a/Launcher-UI/Assets/title.png b/Launcher-UI/Assets/Sprites/title.png similarity index 100% rename from Launcher-UI/Assets/title.png rename to Launcher-UI/Assets/Sprites/title.png diff --git a/Launcher-UI/Assets/Sprites/toml-paper.png b/Launcher-UI/Assets/Sprites/toml-paper.png new file mode 100644 index 0000000..a3e0067 Binary files /dev/null and b/Launcher-UI/Assets/Sprites/toml-paper.png differ diff --git a/Launcher-UI/Assets/toml-paper.png b/Launcher-UI/Assets/toml-paper.png deleted file mode 100644 index bff4312..0000000 Binary files a/Launcher-UI/Assets/toml-paper.png and /dev/null differ diff --git a/Launcher-UI/ConfigManager.cs b/Launcher-UI/ConfigManager.cs index 5a3e796..dfa34dd 100644 --- a/Launcher-UI/ConfigManager.cs +++ b/Launcher-UI/ConfigManager.cs @@ -6,25 +6,41 @@ namespace Plombir; public class ConfigManager { + static private readonly string defaultRuntime = "./runtime"; + static private readonly string defaultVersion = "1.20.1"; + static private readonly string defaultNickname = "slugcat"; + + static private readonly string currentTweaksVersion = "1.2.1"; + + static private readonly string defaultLoginType = "offline"; + static private readonly string defaultUuid = "offline"; + static private readonly string defaultAccsessToken = "offline"; + public static void BuildDefault() { TomlTable toml = new TomlTable { ["title"] = "Launcher tweaks file!", + ["tweaks-version"] = currentTweaksVersion, ["runtime-path"] = new TomlString { - Value = "./runtime", + Value = defaultRuntime, Comment = "Path to folder that will hold all minecraft versions" }, ["last-version-launched"] = new TomlString { - Value = "1.20.1", + Value = defaultVersion, Comment = "Saving last launched version to use it after launch" }, - ["nickname"] = "slugcat" + ["nickname"] = defaultNickname, + ["login-method"] = defaultLoginType, + ["uuid"] = defaultUuid, + ["accsess-token"] = defaultAccsessToken, + + }; using (StreamWriter writer = File.CreateText("tweaks.toml")) @@ -45,10 +61,58 @@ public class ConfigManager { TomlTable table = TOML.Parse(reader); - return table[key]; + // If config don't contains it means it's oudated or broken. + if (!IsValueExists(table, key)) + { + WriteInConfig(key, "NaN"); + } + + // In case if config is fine return its value + if (table[key].ToString() != "NaN") + { + if ((key == "tweaks-version") & (table[key] != currentTweaksVersion)) + { + Console.WriteLine("Warning! Tweaks version mismatch!"); + WriteInConfig("tweaks-version", "wrong-version"); + } + return table[key]; + } + + return RepairConfig(key); + } } + public static bool IsValueExists(TomlTable table, string key) + { + if (table.TryGetNode(key, out var _)) + return true; + return false; + } + + private static string? RepairConfig(string key) + { + Console.WriteLine($"Warning! Can't locate {key} in tweaks! Fallback to defaults!"); + // Handling out-dated or broken toml files by filling with defaults + switch (key) + { + case "runtime-path": { WriteInConfig(key, defaultRuntime); return defaultRuntime; } + case "last-version-launched": { WriteInConfig(key, defaultVersion); return defaultVersion; } + case "nickname": { WriteInConfig(key, defaultNickname); return defaultNickname; } + + case "accsess-token": { WriteInConfig(key, defaultAccsessToken); return defaultAccsessToken; } + case "uuid": { WriteInConfig(key, defaultUuid); return defaultUuid; } + case "login-method": { WriteInConfig(key, defaultLoginType); return defaultLoginType; } + case "tweaks-version": + { + WriteInConfig(key, currentTweaksVersion); + return "possibly broken"; + } + } + + return null; + } + public static void WriteInConfig(string key, dynamic value) { if (!File.Exists("tweaks.toml")) diff --git a/Launcher-UI/LauncherUtils.cs b/Launcher-UI/LauncherUtils.cs index dc0dd1f..90befe0 100644 --- a/Launcher-UI/LauncherUtils.cs +++ b/Launcher-UI/LauncherUtils.cs @@ -10,18 +10,33 @@ public class LauncherUtils { public async static Task CreateMinecraftInstance(MainWindowViewModel vm, Window windowCaller) { + var licenseStatus = ConfigManager.ReadConfig("login-method"); + if (vm.Usernick is null) throw new NullReferenceException("Failed to create minecraft instance! Nickname is null!"); if (vm.SelectedVersion is null) throw new NullReferenceException("Failed to create minecraft instance! Selected version is null!"); System.Console.WriteLine($"Creating minecraft instance for {vm.Usernick}, {vm.SelectedVersion} in {vm.RuntimeLocation}"); - LoadingWindow loading = new(vm.Usernick, vm.SelectedVersion, vm.RuntimeLocation); - ConfigManager.WriteInConfig("last-version-launched", vm.SelectedVersion); - ConfigManager.WriteInConfig("nickname", vm.Usernick); + LoadingWindow loading = new(vm); + + SaveCurrentVariablesToConfig(vm); loading.Show(); await loading.InitLoading(); loading.Close(); - await loading.RunMinecraft(); + + if (licenseStatus == "microsoft") await loading.RunMinecraft(true); + else await loading.RunMinecraft(false); + return; } + + private static async Task CreateLicensedMinecraftInstance() + { + + } + + private static void SaveCurrentVariablesToConfig(MainWindowViewModel vm) + { + ConfigManager.WriteInConfig("last-version-launched", vm.SelectedVersion); + } } diff --git a/Launcher-UI/ViewModels/MainWindowViewModel.cs b/Launcher-UI/ViewModels/MainWindowViewModel.cs index f334bfd..f700160 100644 --- a/Launcher-UI/ViewModels/MainWindowViewModel.cs +++ b/Launcher-UI/ViewModels/MainWindowViewModel.cs @@ -15,4 +15,18 @@ public partial class MainWindowViewModel : ViewModelBase private string? _runtimeLocation = ConfigManager.ReadConfig("runtime-path"); public string? RuntimeLocation { get => _runtimeLocation; set { _runtimeLocation = value; OnPropertyChanged(nameof(RuntimeLocation)); } } + + // Session information + private string? _loginMethod = ConfigManager.ReadConfig("login-method"); + public string? LoginMethod { get => _loginMethod; set { _loginMethod = value; OnPropertyChanged(nameof(LoginMethod)); } } + + private string? _accsessToken = ConfigManager.ReadConfig("accsess-token"); + public string? AccsesToken { get => _accsessToken; set { _accsessToken = value; OnPropertyChanged(nameof(AccsesToken)); } } + + private string? _uuid = ConfigManager.ReadConfig("uuid"); + public string? UUID { get => _uuid; set { _uuid = value; OnPropertyChanged(nameof(UUID)); } } + + // Tweaks managment + private string? _tweaksVersion = ConfigManager.ReadConfig("tweaks-version"); + public string? TweaksVersion { get => _tweaksVersion; set { _tweaksVersion = value; OnPropertyChanged(nameof(TweaksVersion)); } } } diff --git a/Launcher-UI/ViewModels/SettingsWindowViewModel.cs b/Launcher-UI/ViewModels/SettingsWindowViewModel.cs deleted file mode 100644 index 3848b0f..0000000 --- a/Launcher-UI/ViewModels/SettingsWindowViewModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace LauncherGUI.ViewModels; - -public partial class SettingsWindowViewModel : ViewModelBase -{ - // I save launcher data mostly in MainWindowViewModel. -} diff --git a/Launcher-UI/ViewModels/VersionSelectorWindowViewModel.cs b/Launcher-UI/ViewModels/VersionSelectorWindowViewModel.cs deleted file mode 100644 index 5c26947..0000000 --- a/Launcher-UI/ViewModels/VersionSelectorWindowViewModel.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; -using Plombir; -using LauncherGUI.ViewModels; - -namespace LauncherGUI.ViewModels; - -public partial class VersionSelectorWindowViewModel : ViewModelBase -{ - // I save launcher data mostly in MainWindowViewModel. -} diff --git a/Launcher-UI/Views/LoadingWindow.axaml b/Launcher-UI/Views/LoadingWindow.axaml index 4c287ab..468abbd 100644 --- a/Launcher-UI/Views/LoadingWindow.axaml +++ b/Launcher-UI/Views/LoadingWindow.axaml @@ -9,7 +9,7 @@ d:DesignHeight="200" x:Class="LauncherGUI.Views.LoadingWindow" x:DataType="vm:LoadingWindowViewModel" - Icon="/Assets/icon.png" + Icon="/Assets/Sprites/icon.png" Title="Loading" RequestedThemeVariant="Dark" Width="400" diff --git a/Launcher-UI/Views/LoadingWindow.axaml.cs b/Launcher-UI/Views/LoadingWindow.axaml.cs index 1f9aeac..53d317c 100644 --- a/Launcher-UI/Views/LoadingWindow.axaml.cs +++ b/Launcher-UI/Views/LoadingWindow.axaml.cs @@ -13,12 +13,14 @@ public partial class LoadingWindow : Window { private Launcher ln; private Task? _buildingTask; + private readonly MainWindowViewModel _mainWindowVM; // Tokens for controlling download task. CancellationTokenSource tokenSource = new CancellationTokenSource(); - public LoadingWindow(string nickname, string? version = null, string? location = null) + public LoadingWindow(MainWindowViewModel mainWindowVM) { - ln = new Launcher(nickname, version ?? "1.20.1", location ?? "./runtime"); + _mainWindowVM = mainWindowVM; + ln = new Launcher(_mainWindowVM.SelectedVersion ?? "1.20.1", _mainWindowVM.RuntimeLocation ?? "./runtime"); InitializeComponent(); DataContext = new LoadingWindowViewModel(); } @@ -52,9 +54,14 @@ public partial class LoadingWindow : Window } - public async Task RunMinecraft() + public async Task RunMinecraft(bool IsLicensed) { - await ln.RunLauncher(); + var session = ln.CreateOfflineSession(_mainWindowVM.Usernick); + if (IsLicensed) + { + session = ln.CreateLicensedSession(_mainWindowVM.UUID, _mainWindowVM.AccsesToken, _mainWindowVM.Usernick); + } + await ln.RunLauncher(session); } private void onStopDownloadClick(object sender, RoutedEventArgs e) diff --git a/Launcher-UI/Views/MainWindow.axaml b/Launcher-UI/Views/MainWindow.axaml index 20ea829..a2d276d 100644 --- a/Launcher-UI/Views/MainWindow.axaml +++ b/Launcher-UI/Views/MainWindow.axaml @@ -6,7 +6,7 @@ mc:Ignorable="d" d:DesignWidth="750" d:DesignHeight="500" x:Class="LauncherGUI.Views.MainWindow" x:DataType="vm:MainWindowViewModel" - Icon="/Assets/icon.png" + Icon="/Assets/Sprites/icon.png" Title="PlombirLauncher" RequestedThemeVariant="Dark" Width="750" Height="500" @@ -14,14 +14,8 @@ MaxWidth="750" MaxHeight="500"> - + - - - - - @@ -33,7 +27,7 @@ - + @@ -43,13 +37,15 @@ Padding="10" Margin="3" CornerRadius="10"> - + HorizontalAlignment="Right" Text="v1.2.1 - Plombir Contribuitors"/> + + - + - + + + -