Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
145 changes: 140 additions & 5 deletions Knossos.NET/Classes/Knossos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,134 @@ static Knossos()
inSingleTCMode = CustomLauncher.IsCustomMode;
}

/// <summary>
/// Run only on first install, determines the default first library path by OS
/// Write checks are done to make sure we can write to this folder
///
/// Rutes:
/// -First try to look and use a library from Knossos Legacy
/// -Windows: C:\Games\KnossosNET\FreespaceOpen; If not writtable: %PUBLIC%\KnossosNET\FreespaceOpen
/// -MacOS: ~/Library/Application Support/io.github.KnossosNET.Knossos_NET/FreespaceOpen
/// -Linux: ~/KnossosNET/FreespaceOpen
/// -Android: {internal storage}/Android/data/com.knossosnet.knossosnet/files/library
/// Fallbacks: {user profile}\KnossosNET\FreespaceOpen, then {LocalApplicationData}\KnossosNET\FreespaceOpen
/// </summary>
private static void DetermineDefaultBasePath()
{
//Load base path from knossos legacy, if it exists
var legacyBasePath = KnUtils.GetBasePathFromKnossosLegacy();
if (Directory.Exists(legacyBasePath) && TrySetDefaultBasePath(legacyBasePath))
{
Log.Add(Log.LogSeverity.Information, "Knossos.DetermineDefaultBasePath()", $"Loading library path '{globalSettings.basePath}' from Knossos Legacy.");
globalSettings.Save(false);
return;
}

var userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

if (KnUtils.IsWindows)
{
var systemRoot = Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System));
if (string.IsNullOrWhiteSpace(systemRoot))
systemRoot = @"C:\";

TrySetDefaultBasePath(Path.Combine(systemRoot, "Games", "KnossosNET", "FreespaceOpen"));

if (globalSettings.basePath == null)
{
var publicProfile = Environment.GetEnvironmentVariable("PUBLIC");
if (string.IsNullOrWhiteSpace(publicProfile))
{
var commonDocuments = Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments);
if (!string.IsNullOrWhiteSpace(commonDocuments))
publicProfile = Directory.GetParent(commonDocuments)?.FullName;
}

if (!string.IsNullOrWhiteSpace(publicProfile))
TrySetDefaultBasePath(Path.Combine(publicProfile, "KnossosNET", "FreespaceOpen"));
}
}
else if (KnUtils.IsMacOS)
{
TrySetDefaultBasePath(Path.Combine(userProfile, "Library", "Application Support", "io.github.KnossosNET.Knossos_NET", "FreespaceOpen"));
}
else if (KnUtils.IsLinux)
{
TrySetDefaultBasePath(Path.Combine(userProfile, "KnossosNET", "FreespaceOpen"));
}

// General fallbacks for an unknown OS, or when the preferred OS path is not writable.
if (globalSettings.basePath == null && !string.IsNullOrWhiteSpace(userProfile))
TrySetDefaultBasePath(Path.Combine(userProfile, "KnossosNET", "FreespaceOpen"));

if (globalSettings.basePath == null)
{
var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
if (!string.IsNullOrWhiteSpace(localAppData))
TrySetDefaultBasePath(Path.Combine(localAppData, "KnossosNET", "FreespaceOpen"));
}

if (globalSettings.basePath == null)
TrySetDefaultBasePath(Path.Combine(KnUtils.GetKnossosDataFolderPath(), "FreespaceOpen"));

if (globalSettings.basePath != null)
{
Log.Add(Log.LogSeverity.Information, "Knossos.DetermineDefaultBasePath()", $"Choosing '{globalSettings.basePath}' as default library path.");
globalSettings.Save(false);
}
else
{
Log.Add(Log.LogSeverity.Error, "Knossos.DetermineDefaultBasePath()", "Unable to find a writable default library path.");
}
}

/// <summary>
/// Creates and verifies a possible default library path before selecting it.
/// </summary>
private static bool TrySetDefaultBasePath(string? path)
{
if (string.IsNullOrWhiteSpace(path))
return false;

string? writeTestPath = null;
try
{
var fullPath = Path.GetFullPath(path);
Directory.CreateDirectory(fullPath);

writeTestPath = Path.Combine(fullPath, $".knossos_write_test_{Guid.NewGuid():N}.tmp");
using (var writeTest = new FileStream(writeTestPath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
{
writeTest.WriteByte(0);
writeTest.Flush(true);
}

File.Delete(writeTestPath);
writeTestPath = null;
globalSettings.basePath = fullPath;
return true;
}
catch (Exception ex)
{
Log.Add(Log.LogSeverity.Warning, "Knossos.TrySetDefaultBasePath()", $"Cannot use '{path}' as the default library path: {ex.Message}");
return false;
}
finally
{
if (writeTestPath != null)
{
try
{
File.Delete(writeTestPath);
}
catch
{
// Best-effort cleanup of the temporary write test.
}
}
}
}

/// <summary>
/// StartUp sequence
/// </summary>
Expand Down Expand Up @@ -169,16 +297,23 @@ public static async void StartUp(bool isQuickLaunch, bool forceUpdate)
}
}

//Load base path from knossos legacy
if(globalSettings.basePath != null && !isQuickLaunch && !Directory.Exists(globalSettings.basePath))
{
//Reset and warn
Dispatcher.UIThread.Invoke(() => {
MessageBox.Show(MainWindow.instance, $"The previusly selected library folder:\n\n'{globalSettings.basePath}'\n\nNot longer exists, the library folder will be reset back to default.", "Library folder not found" , MessageBox.MessageBoxButtons.OK);
});
globalSettings.basePath = null;
}

if (globalSettings.basePath == null && !inSingleTCMode)
{
globalSettings.basePath = KnUtils.GetBasePathFromKnossosLegacy();
DetermineDefaultBasePath();
if (!isQuickLaunch)
OpenQuickSetup();
}

LoadBasePath(isQuickLaunch);

if (globalSettings.basePath == null && !isQuickLaunch && !inSingleTCMode)
OpenQuickSetup();
}
catch(Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion Knossos.NET/Models/GlobalSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Knossos.NET.Models
{
/// <summary>
/// Disabled = No option to compress is ever show
/// Manual = User can select to compress mods manually during install and in mod settings
/// Manual = Mods are not compressed during install; the user can compress them later in mod settings
/// Always = Always compress all mods during install, no matter what.
/// ModSupport = Compress only if the mod depends on a FSO verson that is higher or equal than the minimal required (23.2.0)
/// </summary>
Expand Down
8 changes: 8 additions & 0 deletions Knossos.NET/ViewModels/GlobalSettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,14 @@ internal CompressionSettings ModCompression
set { if (modCompression != value) { this.SetProperty(ref modCompression, value); UnCommitedChanges = true; } }
}

internal void UpdateModCompressionFromQuickSetup(CompressionSettings value)
{
if (modCompression != value)
{
this.SetProperty(ref modCompression, value, nameof(ModCompression));
}
}

private int compressionMaxParallelism = 2;
internal int CompressionMaxParallelism
{
Expand Down
1 change: 0 additions & 1 deletion Knossos.NET/ViewModels/Windows/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,6 @@ internal void ApplySettings()

public void UpdateBuildInstallButtons(){
DeveloperModView?.UpdateBuildNames(LatestStable, LatestNightly);
QuickSetupViewModel.Instance?.UpdateBuildName(LatestStable);
}

/// <summary>
Expand Down
Loading