Skip to content

Commit

Permalink
Remove debug force launch
Browse files Browse the repository at this point in the history
  • Loading branch information
suchmememanyskill committed May 19, 2024
1 parent e52eee1 commit bdccad6
Show file tree
Hide file tree
Showing 14 changed files with 992 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Launcher.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamGridDbMiddleware", "St
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HideGamesMiddleware", "HideGamesMiddleware\HideGamesMiddleware.csproj", "{35AB17CA-C0D8-4112-B78D-0DCC9DB70435}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoteDownloaderPlugin", "RemoteDownloaderPlugin\RemoteDownloaderPlugin.csproj", "{068D7641-F9EA-40D3-B313-3FBCD09E71F5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -75,6 +77,10 @@ Global
{35AB17CA-C0D8-4112-B78D-0DCC9DB70435}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35AB17CA-C0D8-4112-B78D-0DCC9DB70435}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35AB17CA-C0D8-4112-B78D-0DCC9DB70435}.Release|Any CPU.Build.0 = Release|Any CPU
{068D7641-F9EA-40D3-B313-3FBCD09E71F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{068D7641-F9EA-40D3-B313-3FBCD09E71F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{068D7641-F9EA-40D3-B313-3FBCD09E71F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{068D7641-F9EA-40D3-B313-3FBCD09E71F5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
1 change: 0 additions & 1 deletion Launcher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ internal class Program
[STAThread]
public static void Main(string[] args)
{
args = new[] { "epic-games", "Salt", "Launch" };
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

if (args.Length <= 2)
Expand Down
9 changes: 9 additions & 0 deletions LauncherGamePlugin/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,13 @@ public static async Task<bool> HasNetworkAsync()
return combinations.FirstOrDefault(File.Exists);
}
}

public static Platform GuessPlatformBasedOnString(string? path)
{
if (path == null)
return Platform.Unknown;

List<string> windowsFileExt = [".exe", ".bat", ".msi", ".cmd"];
return windowsFileExt.Any(path.EndsWith) ? Platform.Windows : Platform.Linux;
}
}
165 changes: 165 additions & 0 deletions RemoteDownloaderPlugin/Game/GameDownload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
using System.IO.Compression;
using LauncherGamePlugin;
using LauncherGamePlugin.Interfaces;
using RemoteDownloaderPlugin.Utils;

namespace RemoteDownloaderPlugin.Game;

public class GameDownload : ProgressStatus
{
private IEntry _entry;
private int _lastSecond = 0;
private readonly CancellationTokenSource _cts = new();
private bool _doneDownloading = false;
public long TotalSize { get; private set; }
public string Version { get; private set; }
public GameType Type { get; private set; }
public string BaseFileName { get; private set; }

public GameDownload(IEntry entry)
{
_entry = entry;
}

private void OnProgressUpdate(object? obj, float progress)
{
if (_doneDownloading || _lastSecond == DateTime.Now.Second) // Only make the UI respond once a second
return;

_lastSecond = DateTime.Now.Second;

progress *= 100;
Line1 = $"Downloading: {progress:0}%";
Percentage = progress;
InvokeOnUpdate();
}

public async Task Download(IApp app)
{
_doneDownloading = false;

if (_entry is EmuEntry emuEntry)
await DownloadEmu(app, emuEntry);
else if (_entry is PcEntry pcEntry)
await DownloadPc(app, pcEntry);
else
throw new Exception("Download failed: Unknown type");
}

private async Task DownloadEmu(IApp app, EmuEntry entry)
{
Type = GameType.Emu;
if (entry.Files.Count(x => x.Type == "base") != 1)
{
throw new Exception("Multiple base images, impossible download");
}

var basePath = Path.Join(app.GameDir, "Remote", entry.Emu);
string baseGamePath = null;
var extraFilesPath = Path.Join(app.GameDir, "Remote", entry.Emu, entry.GameId);
Directory.CreateDirectory(basePath);
Directory.CreateDirectory(extraFilesPath);

using HttpClient client = new();

for (int i = 0; i < entry.Files.Count; i++)
{
Progress<float> localProcess = new();
localProcess.ProgressChanged += (sender, f) =>
{
var part = (float)1 / entry.Files.Count;
var add = (float)i / entry.Files.Count;
OnProgressUpdate(null, part * f + add);
};

var fileEntry = entry.Files[i];
var destPath = Path.Join(fileEntry.Type == "base" ? basePath : extraFilesPath, fileEntry.Name);

if (fileEntry.Type == "base")
{
baseGamePath = destPath;
BaseFileName = fileEntry.Name;
}

var fs = new FileStream(destPath, FileMode.Create);

try
{
await client.DownloadAsync(fileEntry.Url, fs, localProcess, _cts.Token);
}
catch (TaskCanceledException e)
{
await Task.Run(() => fs.Dispose());

if (baseGamePath != null && File.Exists(baseGamePath))
{
File.Delete(baseGamePath);
}

Directory.Delete(extraFilesPath, true);

throw;
}

Line1 = "Saving file...";
InvokeOnUpdate();
await Task.Run(() => fs.Dispose());
}

TotalSize = (await Task.Run(() => LauncherGamePlugin.Utils.DirSize(new(extraFilesPath)))) + (new FileInfo(baseGamePath!)).Length;
Version = entry.Files.Last(x => x.Type is "base" or "update").Version;
}

private async Task DownloadPc(IApp app, PcEntry entry)
{
Type = GameType.Pc;
var basePath = Path.Join(app.GameDir, "Remote", "Pc", entry.GameId);
Directory.CreateDirectory(basePath);
var zipFilePath = Path.Join(basePath, "__game__.zip");

using HttpClient client = new();
var fs = new FileStream(zipFilePath, FileMode.Create);

Progress<float> progress = new();
progress.ProgressChanged += OnProgressUpdate;

try
{
await client.DownloadAsync(entry.Url, fs, progress, _cts.Token);
}
catch (TaskCanceledException e)
{
await Task.Run(() => fs.Dispose());

Directory.Delete(basePath);

throw;
}


Percentage = 100;
Line1 = "Saving...";
InvokeOnUpdate();
await Task.Run(() => fs.Dispose());
Line1 = "Unzipping...";
InvokeOnUpdate();
await Task.Run(() => ZipFile.ExtractToDirectory(zipFilePath, basePath));
File.Delete(zipFilePath);

if (_cts.IsCancellationRequested)
{
Directory.Delete(basePath);
}

TotalSize = await Task.Run(() => LauncherGamePlugin.Utils.DirSize(new(basePath)));
Version = entry.Version;
}

public void Stop()
{
if (_doneDownloading)
return;

_cts.Cancel();
}
}
171 changes: 171 additions & 0 deletions RemoteDownloaderPlugin/Game/InstalledGame.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
using LauncherGamePlugin;
using LauncherGamePlugin.Enums;
using LauncherGamePlugin.Forms;
using LauncherGamePlugin.Interfaces;
using LauncherGamePlugin.Launcher;

namespace RemoteDownloaderPlugin.Game;

public class InstalledGame : IGame
{
public string InternalName => Game.Id;
public string Name => Game.Name;
public bool IsRunning { get; set; } = false;
public IGameSource Source => _plugin;
public long? Size => Game.GameSize;
public bool HasImage(ImageType type)
=> ImageTypeToUri(type) != null;

public Task<byte[]?> GetImage(ImageType type)
{
Uri? url = ImageTypeToUri(type);

if (url == null)
return Task.FromResult<byte[]?>(null);

return Storage.Cache($"{Game.Id}_{type}", () => Storage.ImageDownload(url));
}

public InstalledStatus InstalledStatus => InstalledStatus.Installed;

public Platform EstimatedGamePlatform => (_type == GameType.Emu)
? LauncherGamePlugin.Utils.GuessPlatformBasedOnString(_plugin.Storage.Data.EmuProfiles.FirstOrDefault(x => x.Platform == _emuGame!.Emu)?.ExecPath)
: LauncherGamePlugin.Utils.GuessPlatformBasedOnString(_pcLaunchDetails!.LaunchExec);

public ProgressStatus? ProgressStatus => null;
public event Action? OnUpdate;

public void InvokeOnUpdate()
=> OnUpdate?.Invoke();

public IInstalledGame Game { get; }
private Plugin _plugin;
private PcLaunchDetails? _pcLaunchDetails;
private InstalledEmuGame? _emuGame;
private GameType _type;

public InstalledGame(IInstalledGame game, Plugin plugin)
{
Game = game;
_plugin = plugin;
_type = game is InstalledEmuGame ? GameType.Emu : GameType.Pc;
_pcLaunchDetails = null;

if (_type == GameType.Pc)
{
var fullPath = Path.Join(plugin.App.GameDir, "Remote", "Pc", Game.Id, "game.json");
_pcLaunchDetails = PcLaunchDetails.GetFromPath(fullPath);
}
else
{
_emuGame = (game as InstalledEmuGame)!;
}
}

public void Play()
{
try
{
if (_type == GameType.Emu)
{
var emuProfile = _plugin.Storage.Data.EmuProfiles.FirstOrDefault(x => x.Platform == _emuGame!.Emu);

if (emuProfile == null)
{
throw new Exception($"No '{_emuGame!.Emu}' emulation profile exists");
}

var baseGamePath = Path.Join(_plugin.App.GameDir, "Remote", _emuGame!.Emu, _emuGame.BaseFilename);

LaunchParams args = new(emuProfile.ExecPath,
emuProfile.CliArgs.Replace("{EXEC}", $"\"{baseGamePath}\""), emuProfile.WorkingDirectory, this,
EstimatedGamePlatform);
_plugin.App.Launch(args);
}
else
{
var execPath = Path.Join(_plugin.App.GameDir, "Remote", "Pc", Game.Id, _pcLaunchDetails!.LaunchExec);
var workingDir = Path.Join(_plugin.App.GameDir, "Remote", "Pc", Game.Id, _pcLaunchDetails!.WorkingDir);
LaunchParams args = new(execPath, _pcLaunchDetails.LaunchArgs, Path.GetDirectoryName(workingDir)!, this,
EstimatedGamePlatform);
_plugin.App.Launch(args);
}
}
catch (Exception e)
{
_plugin.App.ShowDismissibleTextPrompt($"Game Failed to launch: {e.Message}");
}
}

public void Delete()
{
if (_type == GameType.Emu)
{
var baseGamePath = Path.Join(_plugin.App.GameDir, "Remote", _emuGame!.Emu, _emuGame.BaseFilename);
var extraDir = Path.Join(_plugin.App.GameDir, "Remote", _emuGame!.Emu, Game.Id);
var success = false;

try
{
File.Delete(baseGamePath);
Directory.Delete(extraDir, true);
success = true;
}
catch {}

var game = _plugin.Storage.Data.EmuGames.Find(x => x.Id == Game.Id);
_plugin.Storage.Data.EmuGames.Remove(game!);

if (!success)
{
_plugin.App.ShowTextPrompt("Failed to delete files. Game has been unlinked");
}
}
else
{
var path = Path.Join(_plugin.App.GameDir, "Remote", "Pc", Game.Id);
var success = false;

try
{
Directory.Delete(path, true);
success = true;
}
catch {}

var game = _plugin.Storage.Data.PcGames.Find(x => x.Id == Game.Id);
_plugin.Storage.Data.PcGames.Remove(game!);

if (!success)
{
_plugin.App.ShowTextPrompt("Failed to delete files. Game has been unlinked");
}
}

_plugin.App.ReloadGames();
_plugin.Storage.Save();
}

public void OpenInFileManager()
{
if (_type == GameType.Emu)
{
LauncherGamePlugin.Utils.OpenFolderWithHighlightedFile(Path.Join(_plugin.App.GameDir, "Remote", _emuGame!.Emu, _emuGame.BaseFilename));
}
else
{
LauncherGamePlugin.Utils.OpenFolder(Path.Join(_plugin.App.GameDir, "Remote", "Pc", Game.Id));
}
}

private Uri? ImageTypeToUri(ImageType type)
=> type switch
{
ImageType.Background => Game.Images.Background,
ImageType.VerticalCover => Game.Images.VerticalCover,
ImageType.HorizontalCover => Game.Images.HorizontalCover,
ImageType.Logo => Game.Images.Logo,
ImageType.Icon => Game.Images.Icon,
_ => null
};
}
Loading

0 comments on commit bdccad6

Please sign in to comment.