Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 7 additions & 0 deletions UnitystationLauncher/Models/ConfigFile/Preferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class Preferences : ReactiveObject
private int _ignoreVersionUpdate;
private string _installationPath = string.Empty;
private bool? _TTSEnabled = null;
private bool? _allowCodeScan = true;

public bool AutoRemove
{
Expand All @@ -32,4 +33,10 @@ public bool? TTSEnabled
get => _TTSEnabled;
set => this.RaiseAndSetIfChanged(ref _TTSEnabled, value);
}

public bool? AllowCodeScan
{
get => _allowCodeScan;
set => this.RaiseAndSetIfChanged(ref _allowCodeScan, value);
}
}
6 changes: 3 additions & 3 deletions UnitystationLauncher/Services/CodeScanConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public CodeScanConfigService(HttpClient httpClient, IPreferencesService preferen
}

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

if (Directory.Exists(versionPath) == false)
Expand Down Expand Up @@ -194,9 +194,9 @@ private string GetZipFolderName()
}
}

private string GetFolderName(string version)
public static string GetFolderName(string version, IEnvironmentService environmentService)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is envieronmentServicebeing injected now? I'm not familiar with this codebase. Where was it getting it from before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think almost all pages use envieronmentService for one reason or another. I've just decided to make this function static and public, so I don't have to rewrite this logic elsewhere.

{
CurrentEnvironment os = _environmentService.GetCurrentEnvironment();
CurrentEnvironment os = environmentService.GetCurrentEnvironment();
switch (os)
{
case CurrentEnvironment.WindowsStandalone:
Expand Down
103 changes: 81 additions & 22 deletions UnitystationLauncher/Services/InstallationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,22 @@
return (null!, failureReason);
}

bool result = await _codeScanConfigService.ValidGoodFilesVersionAsync(server.GoodFileVersion);
if (_preferencesService.GetPreferences().AllowCodeScan is true)
{
bool result = await _codeScanConfigService.ValidGoodFilesVersionAsync(server.GoodFileVersion);

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


Download? download = GetInProgressDownload(server.ForkName, server.BuildVersion);

if (download != null)
Expand Down Expand Up @@ -168,6 +174,7 @@
{
const string failureReason = "Couldn't find executable to start.";
Log.Warning(failureReason + $" Installation Path: {installation.InstallationPath ?? "null"}");
_ = ShowErrorWhenNoServerExecutable(installationId, server);
return (false, failureReason);
}

Expand Down Expand Up @@ -195,6 +202,30 @@
return (true, string.Empty);
}

private async Task ShowErrorWhenNoServerExecutable(Guid installationId, string? server)
{
if (server is "") return;

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

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Services/InstallationService.cs#L207

Add curly braces around the nested statement(s) in this 'if' block.

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

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

UnitystationLauncher/Services/InstallationService.cs#L207

Reformat the code to have only one statement per line.
IMsBox<string> msgBox = MessageBoxBuilder.CreateMessageBox(
MessageBoxButtons.YesNo,
"Executable Not Found",
"The executable for this installation could not be found. Would you like to re-download it?"
);
string response = await msgBox.ShowAsync();
if (response.Equals(MessageBoxResults.Yes))
{
DeleteInstallation(installationId);
Server? serverDetails = await _serverService.GetServerByIpAddress(server);

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

View workflow job for this annotation

GitHub Actions / Build Windows

Possible null reference argument for parameter 'ipAddress' in 'Task<Server?> IServerService.GetServerByIpAddress(string ipAddress)'.

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

View workflow job for this annotation

GitHub Actions / Build Linux

Possible null reference argument for parameter 'ipAddress' in 'Task<Server?> IServerService.GetServerByIpAddress(string ipAddress)'.

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

View workflow job for this annotation

GitHub Actions / Build MacOS

Possible null reference argument for parameter 'ipAddress' in 'Task<Server?> IServerService.GetServerByIpAddress(string ipAddress)'.

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

View workflow job for this annotation

GitHub Actions / Build Linux Flatpak

Possible null reference argument for parameter 'ipAddress' in 'Task<Server?> IServerService.GetServerByIpAddress(string ipAddress)'.
if (serverDetails != null)
{
_ = DownloadInstallationAsync(serverDetails);
}
}
else
{
DeleteInstallation(installationId);
}
}

public (bool, string) DeleteInstallation(Guid installationId)
{
Installation? installation = GetInstallationById(installationId);
Expand Down Expand Up @@ -460,7 +491,14 @@

// 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
await Task.Run(() => ExtractAndScan(download, progressStream));
if (_preferencesService.GetPreferences().AllowCodeScan is false)
{
await Task.Run(() => Extract(download, progressStream));
}
else
{
await Task.Run(() => ExtractAndScan(download, progressStream));
}
}
catch (Exception e)
{
Expand All @@ -474,6 +512,22 @@
}
}

private async Task Extract(Download download, ProgressStream progressStream)

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

View workflow job for this annotation

GitHub Actions / Build Windows

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

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

View workflow job for this annotation

GitHub Actions / Build Linux

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

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

View workflow job for this annotation

GitHub Actions / Build MacOS

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

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

View workflow job for this annotation

GitHub Actions / Build Linux Flatpak

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
try
{
ZipArchive archive = new(progressStream);
Log.Information($"Extracting without scan to: {download.InstallPath}");
archive.ExtractToDirectory(download.InstallPath, true);
InstallationDone(download);
}
catch (Exception e)
{
Log.Information($"Extracting stopped with {e}");
download.DownloadState = DownloadState.Failed;
}
}

private async Task ExtractAndScan(Download download, ProgressStream progressStream)
{
List<ScanLog> scanLogs = [];
Expand All @@ -498,26 +552,13 @@

scanLogs.Add(log);
}

download.DownloadState = DownloadState.Scanning;
bool scanTask = await _codeScanService.OnScanAsync(archive, download.InstallPath, download.GoodFileVersion, ScanLogs);

if (scanTask)
{
Log.Information("Download completed");

_installations.Add(new()
{
BuildVersion = download.BuildVersion,
ForkName = download.ForkName,
InstallationId = Guid.NewGuid(),
InstallationPath = download.InstallPath,
LastPlayedDate = DateTime.Now
});

WriteInstallations();
EnsureExecutableFlagOnUnixSystems(download.InstallPath);
download.DownloadState = DownloadState.Installed;
InstallationDone(download);
}
else
{
Expand Down Expand Up @@ -553,6 +594,24 @@
}
}

private void InstallationDone(Download download)
{
Log.Information("Download completed");

_installations.Add(new()
{
BuildVersion = download.BuildVersion,
ForkName = download.ForkName,
InstallationId = Guid.NewGuid(),
InstallationPath = download.InstallPath,
LastPlayedDate = DateTime.Now
});

WriteInstallations();
EnsureExecutableFlagOnUnixSystems(download.InstallPath);
download.DownloadState = DownloadState.Installed;
}

private static async Task ShowScanFailPopUp(string message, string logFolder)
{
IMsBox<string> msgBox = MessageBoxBuilder.CreateMessageBox(
Expand Down
8 changes: 8 additions & 0 deletions UnitystationLauncher/Services/Interface/IServerService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnitystationLauncher.Models;
using UnitystationLauncher.Models.Api;
Expand All @@ -19,4 +21,10 @@ public interface IServerService
/// <param name="installation">Installation to check</param>
/// <returns>true if at least one server is using this installation. false otherwise</returns>
public bool IsInstallationInUse(Installation installation);

public async Task<Server?> GetServerByIpAddress(string ipAddress)
{
var results = await GetServersAsync();
return results.Count == 0 ? null : results.Find(x => x.ServerIp == ipAddress);
}
}
35 changes: 35 additions & 0 deletions UnitystationLauncher/ViewModels/PreferencesPanelViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,20 @@ public bool? TTSEnabled
get => _TTSEnabled;
set => this.RaiseAndSetIfChanged(ref _TTSEnabled, value);
}

private bool? _allowCodeScan = true;

public bool? AllowCodeScan
{
get => _allowCodeScan;
set => this.RaiseAndSetIfChanged(ref _allowCodeScan, value);
}

private readonly IPreferencesService _preferencesService;
private readonly IInstallationService _installationService;
private readonly IEnvironmentService _environmentService;
private readonly ITTSService _ttsService;


public PreferencesPanelViewModel(
IPreferencesService preferencesService,
Expand All @@ -69,6 +78,7 @@ public PreferencesPanelViewModel(
_installationPath = preferences.InstallationPath;
_autoRemove = preferences.AutoRemove;
_TTSEnabled = preferences.TTSEnabled;
_allowCodeScan = preferences.AllowCodeScan;
this.WhenAnyValue(p => p.AutoRemove)
.Select(_ => Observable.FromAsync(OnAutoRemoveChangedAsync))
.Concat()
Expand All @@ -78,6 +88,11 @@ public PreferencesPanelViewModel(
.Select(_ => Observable.FromAsync(OnTTSChangedAsync))
.Concat()
.Subscribe();

this.WhenAnyValue(p => p.AllowCodeScan)
.Select(_ => Observable.FromAsync(OnAllowCodeScanChangedAsync))
.Concat()
.Subscribe();
}

public async Task OnAutoRemoveChangedAsync()
Expand Down Expand Up @@ -160,6 +175,26 @@ await MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.Ok, "Error moving ins
await MessageBoxBuilder.CreateMessageBox(MessageBoxButtons.Ok, "Invalid installation path", invalidReason).ShowAsync();
}
}

public async Task OnAllowCodeScanChangedAsync()
{
if (AllowCodeScan == false)
{
IMsBox<string> msgBox = MessageBoxBuilder.CreateMessageBox(
MessageBoxButtons.YesNo,
"Warning",
"For security reasons, we recommend you never disable the codescan feature unless you're trying to play on older servers that are no longer supported.\n Are you sure you want to proceed?"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

even if you are trying to play on older servers, this should not be recommended. I think the text should be

For security reasons, we recommend you never disable the codescan feature unless you understand what you are doing and you trust the server you are trying to play on.\n Are you sure you want to proceed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

);

string response = await msgBox.ShowAsync();
if (response.Equals(MessageBoxResults.No))
{
AllowCodeScan = true; // Revert the change
}
}

_preferencesService.GetPreferences().AllowCodeScan = AllowCodeScan;
}

public override void Refresh()
{
Expand Down
5 changes: 5 additions & 0 deletions UnitystationLauncher/Views/PreferencesPanelView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
<TextBlock FontSize="16" VerticalAlignment="Center"> Enable the Text-To-Speech System </TextBlock>
</CheckBox>
</Grid>
<Grid Grid.Row="4">
<CheckBox DockPanel.Dock="Right" Margin="5" IsChecked="{Binding AllowCodeScan}" HorizontalAlignment="Left">
<TextBlock FontSize="16" VerticalAlignment="Center"> Enable Code Scan Feature </TextBlock>
</CheckBox>
</Grid>
</Grid>
</Grid>
</Grid>
Expand Down
Loading