FModel/FModel/ViewModels/ApiEndpoints/FModelApiEndpoint.cs
2023-07-09 04:03:13 +02:00

199 lines
8.4 KiB
C#

using System;
using AdonisUI.Controls;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using AutoUpdaterDotNET;
using FModel.Extensions;
using FModel.Framework;
using FModel.Services;
using FModel.Settings;
using FModel.ViewModels.ApiEndpoints.Models;
using Newtonsoft.Json;
using RestSharp;
using Serilog;
using MessageBox = AdonisUI.Controls.MessageBox;
using MessageBoxButton = AdonisUI.Controls.MessageBoxButton;
using MessageBoxImage = AdonisUI.Controls.MessageBoxImage;
using MessageBoxResult = AdonisUI.Controls.MessageBoxResult;
namespace FModel.ViewModels.ApiEndpoints;
public class FModelApiEndpoint : AbstractApiProvider
{
private News _news;
private Info _infos;
private Donator[] _donators;
private Backup[] _backups;
private Game _game;
private readonly IDictionary<string, CommunityDesign> _communityDesigns = new Dictionary<string, CommunityDesign>();
private ApplicationViewModel _applicationView => ApplicationService.ApplicationView;
public FModelApiEndpoint(RestClient client) : base(client) { }
public async Task<News> GetNewsAsync(CancellationToken token, string game)
{
var request = new FRestRequest($"https://api.fmodel.app/v1/news/{Constants.APP_VERSION}");
request.AddParameter("game", game);
var response = await _client.ExecuteAsync<News>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public News GetNews(CancellationToken token, string game)
{
return _news ??= GetNewsAsync(token, game).GetAwaiter().GetResult();
}
public async Task<Info> GetInfosAsync(CancellationToken token, EUpdateMode updateMode)
{
var request = new FRestRequest($"https://api.fmodel.app/v1/infos/{updateMode}");
var response = await _client.ExecuteAsync<Info>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public Info GetInfos(CancellationToken token, EUpdateMode updateMode)
{
return _infos ?? GetInfosAsync(token, updateMode).GetAwaiter().GetResult();
}
public async Task<Donator[]> GetDonatorsAsync()
{
var request = new FRestRequest($"https://api.fmodel.app/v1/donations/donators");
var response = await _client.ExecuteAsync<Donator[]>(request).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public Donator[] GetDonators()
{
return _donators ??= GetDonatorsAsync().GetAwaiter().GetResult();
}
public async Task<Backup[]> GetBackupsAsync(CancellationToken token, string gameName)
{
var request = new FRestRequest($"https://api.fmodel.app/v1/backups/{gameName}");
var response = await _client.ExecuteAsync<Backup[]>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public Backup[] GetBackups(CancellationToken token, string gameName)
{
return _backups ??= GetBackupsAsync(token, gameName).GetAwaiter().GetResult();
}
public async Task<Game> GetGamesAsync(CancellationToken token, string gameName)
{
var request = new FRestRequest($"https://api.fmodel.app/v1/games/{gameName}");
var response = await _client.ExecuteAsync<Game>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public Game GetGames(CancellationToken token, string gameName)
{
return _game ??= GetGamesAsync(token, gameName).GetAwaiter().GetResult();
}
public async Task<CommunityDesign> GetDesignAsync(string designName)
{
var request = new FRestRequest($"https://api.fmodel.app/v1/designs/{designName}");
var response = await _client.ExecuteAsync<Community>(request).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data != null ? new CommunityDesign(response.Data) : null;
}
public CommunityDesign GetDesign(string designName)
{
if (_communityDesigns.TryGetValue(designName, out var communityDesign) && communityDesign != null)
return communityDesign;
communityDesign = GetDesignAsync(designName).GetAwaiter().GetResult();
_communityDesigns[designName] = communityDesign;
return communityDesign;
}
public void CheckForUpdates(EUpdateMode updateMode)
{
AutoUpdater.ParseUpdateInfoEvent += ParseUpdateInfoEvent;
AutoUpdater.CheckForUpdateEvent += CheckForUpdateEvent;
AutoUpdater.Start($"https://api.fmodel.app/v1/infos/{updateMode}");
}
private void ParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
{
_infos = JsonConvert.DeserializeObject<Info>(args.RemoteData);
if (_infos != null)
{
args.UpdateInfo = new UpdateInfoEventArgs
{
CurrentVersion = _infos.Version,
ChangelogURL = _infos.ChangelogUrl,
DownloadURL = _infos.DownloadUrl
};
}
}
private void CheckForUpdateEvent(UpdateInfoEventArgs args)
{
if (args is { CurrentVersion: { } })
{
var currentVersion = new System.Version(args.CurrentVersion);
if (currentVersion == args.InstalledVersion)
{
if (UserSettings.Default.ShowChangelog)
ShowChangelog(args);
return;
}
var downgrade = currentVersion < args.InstalledVersion;
var messageBox = new MessageBoxModel
{
Text = $"The latest version of FModel {UserSettings.Default.UpdateMode} is {args.CurrentVersion}. You are using version {args.InstalledVersion}. Do you want to {(downgrade ? "downgrade" : "update")} the application now?",
Caption = $"{(downgrade ? "Downgrade" : "Update")} Available",
Icon = MessageBoxImage.Question,
Buttons = MessageBoxButtons.YesNo(),
IsSoundEnabled = false
};
MessageBox.Show(messageBox);
if (messageBox.Result != MessageBoxResult.Yes) return;
try
{
if (AutoUpdater.DownloadUpdate(args))
{
UserSettings.Default.ShowChangelog = true;
Application.Current.Shutdown();
}
}
catch (Exception exception)
{
UserSettings.Default.ShowChangelog = false;
MessageBox.Show(exception.Message, exception.GetType().ToString(), MessageBoxButton.OK, MessageBoxImage.Error);
}
}
else
{
MessageBox.Show(
"There is a problem reaching the update server, please check your internet connection or try again later.",
"Update Check Failed", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void ShowChangelog(UpdateInfoEventArgs args)
{
var request = new FRestRequest(args.ChangelogURL);
var response = _client.Execute(request);
if (string.IsNullOrEmpty(response.Content)) return;
_applicationView.CUE4Parse.TabControl.AddTab($"Release Notes: {args.CurrentVersion}");
_applicationView.CUE4Parse.TabControl.SelectedTab.Highlighter = AvalonExtensions.HighlighterSelector("changelog");
_applicationView.CUE4Parse.TabControl.SelectedTab.SetDocumentText(response.Content, false, false);
UserSettings.Default.ShowChangelog = false;
}
}