132 lines
4.1 KiB
C#
132 lines
4.1 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AlayaCore.Abstractions.Interfaces.Services;
|
|
using AlayaCore.Models.Configuration;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace AlayaCore.Services
|
|
{
|
|
public sealed class SettingsService : ISettingsService
|
|
{
|
|
private const string LauncherSettingsFileName = "Launcher.json";
|
|
|
|
public LauncherOptions LauncherOptions { get; }
|
|
|
|
public SettingsService(LauncherOptions launcherOptions)
|
|
{
|
|
LauncherOptions = launcherOptions ?? throw new ArgumentNullException(nameof(launcherOptions));
|
|
}
|
|
|
|
public async Task SetForceReinstallAsync(bool value, CancellationToken cancellationToken = default)
|
|
{
|
|
LauncherOptions.ForceReinstall = value;
|
|
await SaveLauncherOptionsAsync(cancellationToken).ConfigureAwait(false);
|
|
}
|
|
|
|
public async Task SaveLauncherOptionsAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
await SaveAsync(
|
|
LauncherSettingsFileName,
|
|
LauncherOptions,
|
|
cancellationToken).ConfigureAwait(false);
|
|
}
|
|
|
|
public async Task LoadLauncherOptionsAsync(CancellationToken cancellationToken = default)
|
|
{
|
|
LauncherOptions? loadedOptions = await LoadAsync<LauncherOptions>(
|
|
LauncherSettingsFileName,
|
|
cancellationToken).ConfigureAwait(false);
|
|
|
|
if (loadedOptions == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LauncherOptions.ForceReinstall = loadedOptions.ForceReinstall;
|
|
}
|
|
|
|
private async Task SaveAsync<T>(
|
|
string fileName,
|
|
T value,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
throw new ArgumentException("File name cannot be null, empty, or whitespace.", nameof(fileName));
|
|
}
|
|
|
|
if (value == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(value));
|
|
}
|
|
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
string fullPath = GetFullPath(fileName);
|
|
string? directoryPath = Path.GetDirectoryName(fullPath);
|
|
|
|
if (string.IsNullOrWhiteSpace(directoryPath))
|
|
{
|
|
throw new InvalidOperationException("Could not resolve the settings directory path.");
|
|
}
|
|
|
|
Directory.CreateDirectory(directoryPath);
|
|
|
|
string temporaryPath = fullPath + ".tmp";
|
|
string json = JsonConvert.SerializeObject(value, Formatting.Indented);
|
|
|
|
await File.WriteAllTextAsync(temporaryPath, json, cancellationToken).ConfigureAwait(false);
|
|
|
|
if (File.Exists(fullPath))
|
|
{
|
|
File.Delete(fullPath);
|
|
}
|
|
|
|
File.Move(temporaryPath, fullPath);
|
|
}
|
|
|
|
private async Task<T?> LoadAsync<T>(
|
|
string fileName,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(fileName))
|
|
{
|
|
throw new ArgumentException("File name cannot be null, empty, or whitespace.", nameof(fileName));
|
|
}
|
|
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|
|
|
string fullPath = GetFullPath(fileName);
|
|
|
|
if (!File.Exists(fullPath))
|
|
{
|
|
return default;
|
|
}
|
|
|
|
string json = await File.ReadAllTextAsync(fullPath, cancellationToken).ConfigureAwait(false);
|
|
|
|
if (string.IsNullOrWhiteSpace(json))
|
|
{
|
|
return default;
|
|
}
|
|
|
|
try
|
|
{
|
|
return JsonConvert.DeserializeObject<T>(json);
|
|
}
|
|
catch (JsonException ex)
|
|
{
|
|
throw new InvalidDataException(
|
|
$"Failed to deserialize settings file '{fullPath}' to {typeof(T).Name}.",
|
|
ex);
|
|
}
|
|
}
|
|
|
|
private static string GetFullPath(string fileName)
|
|
{
|
|
return Path.Combine(AppContext.BaseDirectory, "Config", fileName);
|
|
}
|
|
}
|
|
} |