diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f2153e2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,86 @@
+# Cloning and Setting Up the Gml.Client Project
+
+This guide will help you clone the `Gml.Client` project from GitHub, set up the development environment, and publish the
+project.
+
+## Prerequisites
+
+Before you begin, ensure that you have the following software installed on your machine:
+
+- [Git](https://git-scm.com/)
+- .NET SDK (version 8.0)
+- [JetBrains Rider](https://www.jetbrains.com/rider/)
+
+## Cloning the Repository
+
+1. Open a terminal.
+2. Run the following command to clone the repository:
+
+ ```sh
+ git clone https://github.com/Gml-Launcher/Gml.Client.git
+ ```
+
+3. Navigate to the project directory:
+
+ ```sh
+ cd Gml.Client
+ ```
+
+## Setting Up the Development Environment
+
+1. Open JetBrains Rider.
+2. Open the cloned `Gml.Client` project in Rider:
+
+ - Select `Open` from the welcome screen.
+ - Navigate to the `Gml.Client` project directory and select it.
+
+3. After the project is loaded, Rider will restore the necessary dependencies. This may take some time.
+
+## Building the Project
+
+1. Ensure your project target framework is correctly set to .NET 8.0. You can verify and set the target framework in the
+ `.csproj` file(s) of your projects:
+
+ ```xml
+ net8.0
+ ```
+
+2. Build the project by selecting `Build > Build Solution` from the main menu or by pressing `Ctrl+Shift+B`.
+
+## Running the Project
+
+1. Ensure the correct startup configuration is selected (typically the main executable project).
+2. Run the project by selecting `Run > Run` from the main menu or by pressing `Shift+F10`.
+
+## Publishing the Project
+
+1. Open a terminal.
+2. Navigate to the project directory if not already there:
+
+ ```sh
+ cd Gml.Client
+ ```
+
+3. Run the publish command using the .NET CLI:
+
+ ```sh
+ dotnet publish -c Release -o ./publish
+ ```
+
+ This will publish the project in the `Release` configuration to the `./publish` directory.
+
+## Contributing
+
+If you'd like to contribute to the project, please fork the repository and create a pull request. Make sure your code
+adheres to the project's coding standards and passes all the tests.
+
+For any issues or feature requests, you can open an issue on
+the [GitHub Issues](https://github.com/Gml-Launcher/Gml.Client/issues) page of the repository.
+
+## Additional Resources
+
+- [JetBrains Rider Documentation](https://www.jetbrains.com/help/rider/Introduction.html)
+- [.NET Documentation](https://learn.microsoft.com/en-us/dotnet/)
+
+By following the above steps, you should be able to set up, develop, and publish the `Gml.Client` project successfully.
+Happy coding!
diff --git a/src/Gml.Client/GmlClientManager.cs b/src/Gml.Client/GmlClientManager.cs
index 3878daf..2a578cd 100644
--- a/src/Gml.Client/GmlClientManager.cs
+++ b/src/Gml.Client/GmlClientManager.cs
@@ -140,6 +140,23 @@ public async Task DownloadNotInstalledFiles(ProfileReadInfoDto profileInfo,
return user;
}
+ public async Task<(IUser User, string Message, IEnumerable Details)> Auth(string accessToken)
+ {
+ var user = await _apiProcedures.Auth(accessToken);
+
+ if (user.User?.IsAuth == true)
+ {
+ if (_launchbackendConnection?.DisposeAsync().AsTask() is {} task)
+ {
+ await task;
+ }
+
+ await OpenServerConnection(user.User);
+ }
+
+ return user;
+ }
+
public async Task OpenServerConnection(IUser user)
{
_launchbackendConnection = new SignalRConnect($"{_webSocketAddress}/ws/launcher", user);
diff --git a/src/Gml.Client/Helpers/ApiProcedures.cs b/src/Gml.Client/Helpers/ApiProcedures.cs
index 52c8d08..33522a8 100644
--- a/src/Gml.Client/Helpers/ApiProcedures.cs
+++ b/src/Gml.Client/Helpers/ApiProcedures.cs
@@ -254,6 +254,39 @@ public static async Task GetSentryLink(string hostUrl)
return (authUser, dto?.Message ?? string.Empty, dto?.Errors ?? []);
}
+ public async Task<(IUser User, string Message, IEnumerable Details)> Auth(string accessToken)
+ {
+ var model = JsonConvert.SerializeObject(new BaseUserPassword
+ {
+ AccessToken = accessToken,
+ });
+
+ var authUser = new AuthUser();
+
+ var data = new StringContent(model, Encoding.UTF8, "application/json");
+ var response = await _httpClient.PostAsync("/api/v1/integrations/auth/checkToken", data).ConfigureAwait(false);
+ _httpClient.DefaultRequestHeaders.Remove("X-HWID");
+ authUser.IsAuth = response.IsSuccessStatusCode;
+
+ var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
+
+ var dto = JsonConvert.DeserializeObject>(content);
+
+ if (response.IsSuccessStatusCode && dto != null)
+ {
+ authUser.Uuid = dto.Data!.Uuid;
+ authUser.Name = dto.Data.Name;
+ authUser.AccessToken = dto.Data!.AccessToken;
+ authUser.Has2Fa = false; //dto.Data!.Has2Fa;
+ authUser.ExpiredDate = dto.Data!.ExpiredDate;
+ authUser.TextureUrl = dto.Data.TextureSkinUrl;
+
+ return (authUser, string.Empty, Enumerable.Empty());
+ }
+
+ return (authUser, dto?.Message ?? string.Empty, dto?.Errors ?? []);
+ }
+
public async Task DownloadFiles(string installationDirectory, ProfileFileReadDto[] files, int loadFilesPartCount,
CancellationToken cancellationToken = default)
{
diff --git a/src/Gml.Client/Helpers/ProcessHelper.cs b/src/Gml.Client/Helpers/ProcessHelper.cs
new file mode 100644
index 0000000..66ecb17
--- /dev/null
+++ b/src/Gml.Client/Helpers/ProcessHelper.cs
@@ -0,0 +1,20 @@
+using System.Diagnostics;
+using System.Reactive;
+using System.Reactive.Linq;
+
+namespace Gml.Client.Helpers;
+
+public static class ProcessHelper
+{
+ private static IDisposable? _watchDisposable;
+
+ public static void StartWatch(this Process process)
+ {
+ _watchDisposable?.Dispose();
+
+ _watchDisposable = process.Modules
+ .Cast()
+ .ToObservable()
+ .Subscribe(module => Console.WriteLine($"Module added: {module}"), () => Console.WriteLine("A module was removed"));
+ }
+}
diff --git a/src/Gml.Client/Helpers/ProfileFileWatcher.cs b/src/Gml.Client/Helpers/ProfileFileWatcher.cs
index dd1af42..5c6fb60 100644
--- a/src/Gml.Client/Helpers/ProfileFileWatcher.cs
+++ b/src/Gml.Client/Helpers/ProfileFileWatcher.cs
@@ -52,9 +52,16 @@ private void OnNewFileCreated(object sender, FileSystemEventArgs e)
FileAdded?.Invoke(this, e.FullPath);
- if (_needKill)
+ if (_needKill && !_process.HasExited)
{
- _process.Kill();
+ try
+ {
+ _process.Kill();
+ }
+ catch (InvalidOperationException ex)
+ {
+ // Ignore
+ }
}
}
}
diff --git a/src/Gml.Client/Helpers/SystemIOProcedures.cs b/src/Gml.Client/Helpers/SystemIOProcedures.cs
index d54b045..eb3c4e6 100644
--- a/src/Gml.Client/Helpers/SystemIOProcedures.cs
+++ b/src/Gml.Client/Helpers/SystemIOProcedures.cs
@@ -10,6 +10,7 @@ public class SystemIoProcedures
{
private readonly string _installationDirectory;
private readonly OsType _osType;
+ private const long _oneHundredMB = 100 * 1024 * 1024;
public SystemIoProcedures(string installationDirectory, OsType osType)
{
@@ -37,6 +38,11 @@ public List FindErroneousFiles(
if (FileExists(localPath))
{
+ if (new FileInfo(localPath).Length >= _oneHundredMB)
+ {
+ return;
+ }
+
var hashIsCorrect = SystemHelper.CalculateFileHash(localPath, new SHA256Managed()) == downloadingFile.Hash;
if (hashIsCorrect)
{
@@ -44,7 +50,7 @@ public List FindErroneousFiles(
}
}
- if (!FileExists(localPath) || !whiteListFiles.Any(c => c.Hash.Equals(downloadingFile.Hash)))
+ if (!whiteListFiles.Any(c => c.Hash.Equals(downloadingFile.Hash)))
{
errorFiles.Add(downloadingFile);
}
diff --git a/src/Gml.Client/IGmlClientManager.cs b/src/Gml.Client/IGmlClientManager.cs
index d44e358..68e57b7 100644
--- a/src/Gml.Client/IGmlClientManager.cs
+++ b/src/Gml.Client/IGmlClientManager.cs
@@ -22,6 +22,7 @@ public interface IGmlClientManager : IDisposable
public Task GetProcess(ProfileReadInfoDto profileDto, OsType osType);
Task DownloadNotInstalledFiles(ProfileReadInfoDto profileInfo, CancellationToken cancellationToken);
Task<(IUser User, string Message, IEnumerable Details)> Auth(string login, string password, string hwid);
+ Task<(IUser User, string Message, IEnumerable Details)> Auth(string accessToken);
Task ClearFiles(ProfileReadInfoDto profile);
Task LoadDiscordRpc();
Task UpdateDiscordRpcState(string state);
diff --git a/src/Gml.Web.Api.Dto/User/BaseUserPassword.cs b/src/Gml.Web.Api.Dto/User/BaseUserPassword.cs
index ba1045e..c696ab5 100644
--- a/src/Gml.Web.Api.Dto/User/BaseUserPassword.cs
+++ b/src/Gml.Web.Api.Dto/User/BaseUserPassword.cs
@@ -4,4 +4,5 @@ public class BaseUserPassword
{
public string Login { get; set; }
public string Password { get; set; }
+ public string AccessToken { get; set; }
}