Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TTS Download #230

Merged
merged 9 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using UnitystationLauncher.Tests.MocksRepository.PingService;
using UnitystationLauncher.Tests.MocksRepository.ServerService;
using UnitystationLauncher.ViewModels;
using Xunit.Sdk;

namespace UnitystationLauncher.Tests.ViewModels;

Expand All @@ -16,7 +17,7 @@ public static void ServersPanelViewModel_ShouldFetchServers()
IPingService mockPingService = new MockPingStaticPingTime(5);
IServerService mockServerService = new MockRandomServers(1, 20);

ServersPanelViewModel serversPanelViewModel = new(mockInstallationService, mockPingService, mockServerService);
ServersPanelViewModel serversPanelViewModel = new(mockInstallationService, mockPingService, mockServerService, null, null);
serversPanelViewModel.ServerViews.Should().NotBeEmpty();
}

Expand All @@ -27,7 +28,7 @@ public static void ServersPanelViewModel_ShouldHandleExceptionInServerService()
IPingService mockPingService = new MockPingStaticPingTime(5);
IServerService mockServerService = new MockServersThrowsException();

Func<ServersPanelViewModel> act = () => new(mockInstallationService, mockPingService, mockServerService);
Func<ServersPanelViewModel> act = () => new(mockInstallationService, mockPingService, mockServerService, null, null);
act.Should().NotThrow();
act.Invoke().ServerViews.Should().NotBeNull().And.BeEmpty();
}
Expand Down
3 changes: 3 additions & 0 deletions UnitystationLauncher/Constants/ApiUrls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@

private static string RawGitHubFileBaseUrl => "https://raw.githubusercontent.com/unitystation/unitystation/develop";
public static string CodeScanListUrl => $"{RawGitHubFileBaseUrl}/CodeScanList.json";
public static string TTSFiles => $"{CdnBaseUrl}/STTBundleTTS/TTS";

Check notice on line 21 in UnitystationLauncher/Constants/ApiUrls.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Constants/ApiUrls.cs#L21

Rename property 'TTSFiles' to match pascal case naming rules, consider using 'TtsFiles'.
public static string TTSVersionFile => $"{TTSFiles}/version.txt";

Check notice on line 22 in UnitystationLauncher/Constants/ApiUrls.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Constants/ApiUrls.cs#L22

Rename property 'TTSVersionFile' to match pascal case naming rules, consider using 'TtsVersionFile'.

}
3 changes: 3 additions & 0 deletions UnitystationLauncher/Infrastructure/MessageBoxBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Collections.Generic;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using MsBox.Avalonia;
using MsBox.Avalonia.Base;
using MsBox.Avalonia.Dto;
Expand All @@ -14,6 +16,7 @@ public static IMsBox<string> CreateMessageBox(MessageBoxButtons buttonLayout, st
{
IMsBox<string> msgBox = MessageBoxManager.GetMessageBoxCustom(new MessageBoxCustomParams
{
Topmost = true,
SystemDecorations = Avalonia.Controls.SystemDecorations.BorderOnly,
WindowStartupLocation = Avalonia.Controls.WindowStartupLocation.CenterScreen,
ContentHeader = header,
Expand Down
2 changes: 1 addition & 1 deletion UnitystationLauncher/Models/Api/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public Server(string forkName, int buildVersion, string serverIp, int serverPort
public string? OsxDownload { get; set; }
public string? LinuxDownload { get; set; }

public string ServerGoodFileVersion { get; set; } = string.Empty;
public string GoodFileVersion { get; set; } = string.Empty;

public (string, int) ForkAndVersion => (ForkName, BuildVersion);

Expand Down
9 changes: 9 additions & 0 deletions UnitystationLauncher/Models/Api/VersionModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Text.Json.Serialization;

namespace UnitystationLauncher.Models.Api;

public class VersionModel
{
[JsonPropertyName("version")]
public required string Version { get; set; }
}
7 changes: 7 additions & 0 deletions UnitystationLauncher/Models/ConfigFile/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
private bool _autoRemove = true;
private int _ignoreVersionUpdate;
private string _installationPath = string.Empty;
private bool? _TTSEnabled = null;

public bool AutoRemove
{
Expand All @@ -25,4 +26,10 @@
get => _installationPath;
set => this.RaiseAndSetIfChanged(ref _installationPath, value);
}

public bool? TTSEnabled

Check notice on line 30 in UnitystationLauncher/Models/ConfigFile/Preferences.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Models/ConfigFile/Preferences.cs#L30

Rename property 'TTSEnabled' to match pascal case naming rules, consider using 'TtsEnabled'.
{
get => _TTSEnabled;
set => this.RaiseAndSetIfChanged(ref _TTSEnabled, value);
}
}
3 changes: 2 additions & 1 deletion UnitystationLauncher/Models/Enums/DownloadState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ public enum DownloadState
InProgress,
Scanning,
Installed,
Failed
Failed,
Extracting
}
10 changes: 5 additions & 5 deletions UnitystationLauncher/Services/CodeScanConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ public CodeScanConfigService(HttpClient httpClient, IPreferencesService preferen

string pathBase = _preferencesService.GetPreferences().InstallationPath;
string folderName = GetFolderName(version);
string versionPath = Path.Combine(pathBase, version, folderName);
string versionPath = Path.Combine(pathBase, "nonbuild", version, folderName);

if (Directory.Exists(versionPath) == false)
{
string zipExtractPath = Path.Combine(pathBase, version);
string zipExtractPath = Path.Combine(pathBase, "nonbuild", version);
HttpResponseMessage request = await _httpClient.GetAsync($"{ApiUrls.GoodFilesBaseUrl}/{version}/{folderName}.zip", HttpCompletionOption.ResponseHeadersRead);
await using Stream responseStream = await request.Content.ReadAsStreamAsync();
ZipArchive archive = new(responseStream);
Expand Down Expand Up @@ -183,12 +183,12 @@ private string GetZipFolderName()
switch (os)
{
case CurrentEnvironment.WindowsStandalone:
return "Windows";
return "StandaloneWindows64";
case CurrentEnvironment.LinuxFlatpak:
case CurrentEnvironment.LinuxStandalone:
return "Linux";
return "StandaloneLinux64";
case CurrentEnvironment.MacOsStandalone:
return "Mac";
return "StandaloneOSX";
default:
throw new UnsupportedPlatformException($"Unable to determine OS Version {os}");
}
Expand Down
6 changes: 4 additions & 2 deletions UnitystationLauncher/Services/CodeScanService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ public async Task<bool> OnScanAsync(ZipArchive archive, string targetDirectory,
// TODO: Enable extraction cancelling
DirectoryInfo root = new(_preferencesService.GetPreferences().InstallationPath);

DirectoryInfo stagingDirectory = root.CreateSubdirectory("UnsafeBuildZipDirectory");
DirectoryInfo processingDirectory = root.CreateSubdirectory("UnsafeBuildProcessing");
var nonbuild = root.CreateSubdirectory("nonbuild");

DirectoryInfo stagingDirectory = nonbuild.CreateSubdirectory("UnsafeBuildZipDirectory");
DirectoryInfo processingDirectory = nonbuild.CreateSubdirectory("UnsafeBuildProcessing");
DirectoryInfo? dataPath = null;
archive.ExtractToDirectory(stagingDirectory.ToString(), true);
try
Expand Down
41 changes: 29 additions & 12 deletions UnitystationLauncher/Services/InstallationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,19 @@
private readonly List<Download> _downloads;
private List<Installation> _installations = new();
private readonly string _installationsJsonFilePath;
private readonly ITTSService _TTSVersionService;

public InstallationService(HttpClient httpClient, IPreferencesService preferencesService,
IEnvironmentService environmentService, IServerService serverService, ICodeScanService codeScanService,
ICodeScanConfigService codeScanConfigService)
ICodeScanConfigService codeScanConfigService, ITTSService ITTSVersionService)
{
_httpClient = httpClient;
_preferencesService = preferencesService;
_environmentService = environmentService;
_serverService = serverService;
_codeScanService = codeScanService;
_codeScanConfigService = codeScanConfigService;
_TTSVersionService = ITTSVersionService;

_downloads = new();
_installationsJsonFilePath = Path.Combine(_environmentService.GetUserdataDirectory(), "installations.json");
Expand Down Expand Up @@ -93,14 +95,12 @@
return (null!, failureReason);
}

server.ServerGoodFileVersion = "1.0.0"; //TODO

bool result = await _codeScanConfigService.ValidGoodFilesVersionAsync(server.ServerGoodFileVersion);
bool result = await _codeScanConfigService.ValidGoodFilesVersionAsync(server.GoodFileVersion);

if (result == false)
{
const string failureReason = "server does not have a valid ServerGoodFileVersion ";
Log.Warning(failureReason + $" ServerName: {server.ServerName} ServerGoodFileVersion : {server.ServerGoodFileVersion}");
Log.Warning(failureReason + $" ServerName: {server.ServerName} ServerGoodFileVersion : {server.GoodFileVersion}");
return (null!, failureReason);
}

Expand All @@ -115,9 +115,20 @@

string installationBasePath = _preferencesService.GetPreferences().InstallationPath;
// should be something like {basePath}/{forkName}/{version}
string installationPath = Path.Combine(installationBasePath, server.ForkName.SanitiseStringPath(), server.ServerGoodFileVersion.SanitiseStringPath(), server.BuildVersion.ToString());
if (server.ForkName.SanitiseStringPath() == "nonbuild")
{
throw new Exception($" bad server ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (nonbuild)");
}

if (server.ForkName.SanitiseStringPath() == "tts")
{
throw new Exception($" bad server ForkName {server.ForkName.SanitiseStringPath()} Not allowed as save location (tts) ");

Check warning on line 125 in UnitystationLauncher/Services/InstallationService.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Services/InstallationService.cs#L125

'System.Exception' should not be thrown by user code.

Check failure on line 125 in UnitystationLauncher/Services/InstallationService.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Services/InstallationService.cs#L125

Replace the string 'server' with 'nameof(server)'.
}


download = new(downloadUrl, installationPath, server.ForkName, server.BuildVersion, server.ServerGoodFileVersion);
string installationPath = Path.Combine(installationBasePath, server.ForkName.SanitiseStringPath(), server.GoodFileVersion.SanitiseStringPath(), server.BuildVersion.ToString());

download = new(downloadUrl, installationPath, server.ForkName, server.BuildVersion, server.GoodFileVersion);

(bool canStartDownload, string cantDownloadReason) = CanStartDownload(download);

Expand All @@ -133,12 +144,17 @@
}

_downloads.Add(download);



RxApp.MainThreadScheduler.ScheduleAsync((_, _) => StartDownloadAsync(download));
return (download, string.Empty);
}

public (bool, string) StartInstallation(Guid installationId, string? server = null, short? port = null)
{
_TTSVersionService.StartTTS();

Installation? installation = GetInstallationById(installationId);
if (installation == null)
{
Expand Down Expand Up @@ -422,6 +438,9 @@

private async Task StartDownloadAsync(Download download)
{
//Update TTS if it's needed
await _TTSVersionService.CheckAndDownloadLatestVersion(download);

Log.Information("Download requested, Installation Path '{Path}', Url '{Url}'", download.InstallPath, download.DownloadUrl);
try
{
Expand All @@ -433,13 +452,11 @@
await using Stream responseStream = await request.Content.ReadAsStreamAsync();
Log.Information("Download connection established");
await using ProgressStream progressStream = new(responseStream);
download.Size = request.Content.Headers.ContentLength ??
throw new ContentLengthNullException(download.DownloadUrl);
download.Size = request.Content.Headers.ContentLength ?? throw new ContentLengthNullException(download.DownloadUrl);

using IDisposable logProgressDisposable = LogProgress(progressStream, download);

using IDisposable progressDisposable = progressStream.Progress
.Subscribe(p => { download.Downloaded = p; });
using IDisposable progressDisposable = progressStream.Progress.Subscribe(p => { download.Downloaded = p; });

// ExtractAndScan() must be run in a separate thread, but we want this one to wait for that one to finish
// Without this download progress will not work properly
Expand Down Expand Up @@ -558,7 +575,7 @@
}
}

private static IDisposable LogProgress(ProgressStream progressStream, Download download)
public static IDisposable LogProgress(ProgressStream progressStream, Download download)
{
long lastPosition = 0L;
DateTime lastTime = DateTime.Now;
Expand Down
12 changes: 12 additions & 0 deletions UnitystationLauncher/Services/Interface/ITTSService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Threading.Tasks;
using UnitystationLauncher.Models;

namespace UnitystationLauncher.Services.Interface;

public interface ITTSService
{
public Task CheckAndDownloadLatestVersion(Download Download);

public void StartTTS();

Check notice on line 10 in UnitystationLauncher/Services/Interface/ITTSService.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Services/Interface/ITTSService.cs#L10

Rename method 'StartTTS' to match pascal case naming rules, consider using 'StartTts'.
public void StopTTS();

Check notice on line 11 in UnitystationLauncher/Services/Interface/ITTSService.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Services/Interface/ITTSService.cs#L11

Rename method 'StopTTS' to match pascal case naming rules, consider using 'StopTts'.
}
Loading
Loading