Skip to content

Commit

Permalink
Merge pull request #17 from tekgator/dev
Browse files Browse the repository at this point in the history
v1.3.2
  • Loading branch information
tekgator committed Sep 16, 2022
2 parents 16ce16c + 8f03c2f commit ed28bcb
Show file tree
Hide file tree
Showing 23 changed files with 264 additions and 67 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
## [Unreleased]


## [1.3.2] - 2022-16-09
### Added
- Add LauncherOption to also search for additional executables within a game install directory
- Add Executables property to IGame interface to list all additional executables within a game install directory

### Fixed
- Steam plugin was not processing manifest entries in parallel


## [1.3.1] - 2022-11-09
### Fixed
- Activate parallel processing of installed games for Battle.net and Rockstar Games
Expand Down
5 changes: 5 additions & 0 deletions GameLib.Core/IGame.cs
Expand Up @@ -34,6 +34,11 @@ public interface IGame
/// </summary>
public Icon? ExecutableIcon { get; }

/// <summary>
/// Additional executables found within the install directory
/// </summary>
public IEnumerable<string> Executables { get; }

/// <summary>
/// Working directory of the game
/// </summary>
Expand Down
9 changes: 7 additions & 2 deletions GameLib.Core/LauncherOptions.cs
Expand Up @@ -3,7 +3,7 @@
public class LauncherOptions
{
/// <summary>
/// Define if Launcher plugin should use local catalog data (if present)
/// Define if Launcher plugin should use local catalog data (if present)
/// to get more detailed information about specific games
/// Note: Can in increase load time for the plugin
/// </summary>
Expand All @@ -23,5 +23,10 @@ public class LauncherOptions
/// <summary>
/// Defines the timeout time for online query's
/// </summary>
public TimeSpan? OnlineQueryTimeout { get; init; } = null;
public TimeSpan? OnlineQueryTimeout { get; init; }

/// <summary>
/// Search all possible game executables within the install directory and sub directories
/// </summary>
public bool SearchExecutables { get; init; } = true;
}
5 changes: 5 additions & 0 deletions GameLib.Core/Util/PathUtil.cs
Expand Up @@ -109,4 +109,9 @@ public static class PathUtil

return null;
}

public static List<string> GetExecutables(string path)
{
return Directory.GetFiles(path, "*.exe", SearchOption.AllDirectories).ToList();
}
}
19 changes: 15 additions & 4 deletions GameLib.Demo/GameLib.Demo.Wpf/ViewModels/GameViewModel.cs
Expand Up @@ -162,13 +162,24 @@ public static void OpenPath(string? path)
}

[RelayCommand]
public static void CopyToClipboard(string? text)
public static void CopyToClipboard(object? obj)
{
if (string.IsNullOrEmpty(text))
var copyText = string.Empty;

switch (obj)
{
return;
case string text:
copyText = text;
break;
case IEnumerable<string> list:
copyText = string.Join("\n", list);
break;
}

Clipboard.SetText(text);
if (string.IsNullOrEmpty(copyText))
{
return;
}
Clipboard.SetText(copyText);
}
}
56 changes: 47 additions & 9 deletions GameLib.Demo/GameLib.Demo.Wpf/Views/GameView.xaml
Expand Up @@ -27,6 +27,12 @@
<Setter Property="IsReadOnlyCaretVisible" Value="True" />
</Style>

<Style TargetType="ListBox">
<Setter Property="Width" Value="500" />
<Setter Property="Height" Value="100" />

</Style>

<Style TargetType="Button">
<Setter Property="Background" Value="#373737" />
</Style>
Expand Down Expand Up @@ -441,20 +447,52 @@
</StackPanel>
<!--#endregion-->

<!--#region Working directory-->
<!--#region Executables-->
<TextBlock
Grid.Row="15"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Text="Addtl. executables: " />
<ListBox
Grid.Row="15"
Grid.Column="2"
VerticalAlignment="Center"
ItemsSource="{Binding SelectedGame.Executables, Mode=OneWay}" />
<StackPanel
Grid.Row="15"
Grid.Column="4"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Orientation="Horizontal">
<Button
Command="{Binding CopyToClipboardCommand}"
CommandParameter="{Binding SelectedGame.Executables}"
ToolTip="Copy to clipboard">
<Image
Width="20"
Height="20"
Margin="2"
Source="/Resources/copy-white.png" />
</Button>
</StackPanel>

<!--#endregion-->

<!--#region Working directory-->
<TextBlock
Grid.Row="17"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Text="Working directory: " />
<TextBox
Grid.Row="15"
Grid.Row="17"
Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding SelectedGame.WorkingDir, Mode=OneWay}" />
<StackPanel
Grid.Row="15"
Grid.Row="17"
Grid.Column="4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Expand Down Expand Up @@ -485,18 +523,18 @@

<!--#region Launch string-->
<TextBlock
Grid.Row="17"
Grid.Row="19"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Text="Launch string: " />
<TextBox
Grid.Row="17"
Grid.Row="19"
Grid.Column="2"
VerticalAlignment="Center"
Text="{Binding SelectedGame.LaunchString, Mode=OneWay}" />
<StackPanel
Grid.Row="17"
Grid.Row="19"
Grid.Column="4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Expand Down Expand Up @@ -526,22 +564,22 @@

<!--#region IsRunning-->
<TextBlock
Grid.Row="19"
Grid.Row="21"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Text="Is running: " />

<Image
Grid.Row="19"
Grid.Row="21"
Grid.Column="2"
Width="24"
Height="24"
HorizontalAlignment="Left"
Source="{Binding IsRunningLogo}" />

<StackPanel
Grid.Row="19"
Grid.Row="21"
Grid.Column="4"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Expand Down
28 changes: 23 additions & 5 deletions GameLib.Plugin/GameLib.Plugin.BattleNet/BattleNetGameFactory.cs
Expand Up @@ -19,6 +19,7 @@ public static IEnumerable<BattleNetGame> GetGames(ILauncher launcher, Cancellati
.Where(game => game is not null)
.Select(game => AddLauncherId(launcher, game))
.Select(game => AddCatalogData(launcher, game, catalog))
.Select(game => AddExecutables(launcher, game))
.ToList()!;
}

Expand All @@ -31,6 +32,22 @@ private static BattleNetGame AddLauncherId(ILauncher launcher, BattleNetGame gam
return game;
}

/// <summary>
/// Find executables within the install directory
/// </summary>
private static BattleNetGame AddExecutables(ILauncher launcher, BattleNetGame game)
{
if (launcher.LauncherOptions.SearchExecutables)
{
var executables = PathUtil.GetExecutables(game.InstallDir);

executables.AddRange(game.Executables);
game.Executables = executables.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
}

return game;
}

/// <summary>
/// Load local catalog data
/// </summary>
Expand Down Expand Up @@ -122,11 +139,12 @@ private static BattleNetGame AddCatalogData(ILauncher launcher, BattleNetGame ga
game.LaunchString = $"\"{launcher.Executable}\" --exec=\"launch {game.ProductCode}\"";
}

var executable = catalogItem.Executables.FirstOrDefault(defaultValue: string.Empty);
if (!string.IsNullOrEmpty(executable))
{
game.Executable = Path.Combine(game.InstallDir, executable);
}
game.Executables = catalogItem.Executables
.Where(e => !string.IsNullOrEmpty(e))
.Select(e => Path.Combine(game.InstallDir, e))
.ToList();

game.Executable = game.Executables.FirstOrDefault(defaultValue: string.Empty);

return game;
}
Expand Down
14 changes: 1 addition & 13 deletions GameLib.Plugin/GameLib.Plugin.BattleNet/Model/BattleNetGame.cs
Expand Up @@ -8,33 +8,21 @@ public class BattleNetGame : IGame
{
#region Interface implementations
public string Id { get; internal set; } = string.Empty;

public Guid LauncherId { get; internal set; } = Guid.Empty;

public string Name { get; internal set; } = string.Empty;

public string InstallDir { get; internal set; } = string.Empty;

public string Executable { get; internal set; } = string.Empty;

public Icon? ExecutableIcon => PathUtil.GetFileIcon(Executable);

public IEnumerable<string> Executables { get; internal set; } = Enumerable.Empty<string>();
public string WorkingDir { get; internal set; } = string.Empty;

public string LaunchString { get; internal set; } = string.Empty;

public DateTime InstallDate { get; internal set; } = DateTime.MinValue;

public bool IsRunning => ProcessUtil.IsProcessRunning(Executable);
#endregion

public string ProductCode { get; internal set; } = string.Empty;

public string SpeechLanguage { get; internal set; } = string.Empty;

public string TextLanguage { get; internal set; } = string.Empty;

public string PlayRegion { get; internal set; } = string.Empty;

public string Version { get; internal set; } = string.Empty;
}
41 changes: 39 additions & 2 deletions GameLib.Plugin/GameLib.Plugin.Epic/EpicGameFactory.cs
Expand Up @@ -22,6 +22,7 @@ public static IEnumerable<EpicGame> GetGames(ILauncher launcher, CancellationTok
.Select(DeserializeManifest)
.Where(game => game is not null)
.Select(game => AddLauncherId(launcher, game!))
.Select(game => AddExecutables(launcher, game!))
.ToList()!;
}

Expand All @@ -34,6 +35,22 @@ private static EpicGame AddLauncherId(ILauncher launcher, EpicGame game)
return game;
}

/// <summary>
/// Find executables within the install directory
/// </summary>
private static EpicGame AddExecutables(ILauncher launcher, EpicGame game)
{
if (launcher.LauncherOptions.SearchExecutables)
{
var executables = PathUtil.GetExecutables(game.InstallDir);

executables.AddRange(game.Executables);
game.Executables = executables.Distinct(StringComparer.OrdinalIgnoreCase).ToList();
}

return game;
}

/// <summary>
/// Get the meta data directory from registry; if not found try to locate in Common Application data
/// </summary>
Expand Down Expand Up @@ -81,9 +98,29 @@ private static EpicGame AddLauncherId(ILauncher launcher, EpicGame game)
}
catch { return null; }

var game = deserializedEpicGame.EpicGameBuilder();
var game = new EpicGame()
{
Id = deserializedEpicGame.AppName,
Name = deserializedEpicGame.DisplayName,
InstallDir = PathUtil.Sanitize(deserializedEpicGame.InstallLocation) ?? string.Empty,
WorkingDir = deserializedEpicGame.InstallLocation,
InstallSize = deserializedEpicGame.InstallSize,
Version = deserializedEpicGame.AppVersionString,
};

if (PathUtil.IsExecutable(deserializedEpicGame.MainWindowProcessName))
{
game.Executable = Path.Combine(game.InstallDir, deserializedEpicGame.MainWindowProcessName);
if (PathUtil.IsExecutable(deserializedEpicGame.MainWindowProcessName))
{
game.Executables = new List<string>() { Path.Combine(game.InstallDir, deserializedEpicGame.LaunchExecutable) };
}
}
else if (PathUtil.IsExecutable(deserializedEpicGame.LaunchExecutable))
{
game.Executable = Path.Combine(game.InstallDir, deserializedEpicGame.LaunchExecutable);
}

game.Executable = Path.Combine(PathUtil.Sanitize(game.InstallDir)!, game.Executable);
game.LaunchString = $"com.epicgames.launcher://apps/{game.Id}?action=launch&silent=true";
game.InstallDate = PathUtil.GetCreationTime(game.InstallDir) ?? DateTime.MinValue;

Expand Down
14 changes: 1 addition & 13 deletions GameLib.Plugin/GameLib.Plugin.Epic/Model/DeserializedEpicGame.cs
@@ -1,5 +1,4 @@
using Gamelib.Core.Util;
using Newtonsoft.Json;
using Newtonsoft.Json;

namespace GameLib.Plugin.Epic.Model;

Expand Down Expand Up @@ -118,15 +117,4 @@ public class DeserializedEpicGame

[JsonProperty("MainGameAppName")]
public string MainGameAppName { get; set; } = string.Empty;

public EpicGame EpicGameBuilder() => new()
{
Id = AppName,
Name = DisplayName,
InstallDir = InstallLocation,
Executable = PathUtil.IsExecutable(MainWindowProcessName) ? MainWindowProcessName : LaunchExecutable,
WorkingDir = InstallLocation,
InstallSize = InstallSize,
Version = AppVersionString,
};
}
1 change: 1 addition & 0 deletions GameLib.Plugin/GameLib.Plugin.Epic/Model/EpicGame.cs
Expand Up @@ -13,6 +13,7 @@ public class EpicGame : IGame
public string InstallDir { get; internal set; } = string.Empty;
public string Executable { get; internal set; } = string.Empty;
public Icon? ExecutableIcon => PathUtil.GetFileIcon(Executable);
public IEnumerable<string> Executables { get; internal set; } = Enumerable.Empty<string>();
public string WorkingDir { get; internal set; } = string.Empty;
public string LaunchString { get; internal set; } = string.Empty;
public DateTime InstallDate { get; internal set; } = DateTime.MinValue;
Expand Down

0 comments on commit ed28bcb

Please sign in to comment.