Skip to content

Commit

Permalink
Fix game detection / communication to work with HMW naming (#137)
Browse files Browse the repository at this point in the history
* Fix game detection / communication to work with HMW naming

* Fix equals

* Update nuget packages
  • Loading branch information
tobibodamer authored Oct 19, 2024
1 parent 6d764a0 commit fe65296
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 41 deletions.
54 changes: 34 additions & 20 deletions H2MLauncher.Core/Game/H2MCommunicationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ namespace H2MLauncher.Core.Game
{
public sealed class H2MCommunicationService : IDisposable
{
private const string GAME_WINDOW_TITLE = "H2M-Mod";
// Exact names of the actual game window
private static readonly string[] GAME_WINDOW_TITLES = ["H2M-Mod", "HorizonMW"];

// Mod executable file names (to automatically find game file in directory)
private static readonly string[] GAME_EXECUTABLE_NAMES = ["hmw-mod.exe", "h2m-mod.exe", "h2m-revived.exe"];

// Strings to match game / mod window titles
private static readonly string[] H2M_WINDOW_TITLE_STRINGS = ["h2m-mod", "HorizonMW"];

//Windows API constants
private const int WM_CHAR = 0x0102; // Message code for sending a character
Expand Down Expand Up @@ -128,13 +135,17 @@ private static IEnumerable<nint> EnumerateWindowHandles()

private bool TryFindValidGameFile(out string fileName)
{
const string exeFileName = "h2m-mod.exe";

if (string.IsNullOrEmpty(_h2mLauncherSettings.CurrentValue.MWRLocation))
{
// no location set, try relative path
fileName = Path.GetFullPath(exeFileName);
return File.Exists(fileName);
foreach (string exeFileName in GAME_EXECUTABLE_NAMES)
{
// no location set, try relative path
fileName = Path.GetFullPath(exeFileName);
if (File.Exists(fileName))
{
return true;
}
}
}

string userDefinedLocation = Path.GetFullPath(_h2mLauncherSettings.CurrentValue.MWRLocation);
Expand All @@ -149,9 +160,14 @@ private bool TryFindValidGameFile(out string fileName)
if (File.GetAttributes(userDefinedLocation).HasFlag(FileAttributes.Directory))
{
// is a directory, get full file name
fileName = Path.Combine(userDefinedLocation, exeFileName);

return File.Exists(fileName);
foreach (string exeFileName in GAME_EXECUTABLE_NAMES)
{
fileName = Path.Combine(userDefinedLocation, exeFileName);
if (File.Exists(fileName))
{
return true;
}
}
}

// is a file?
Expand All @@ -166,11 +182,9 @@ public void LaunchH2MMod()
try
{
// Check if the process is already running
Process? runningProcess = Process.GetProcessesByName("h2m-mod").FirstOrDefault();

if (runningProcess != null)
if (GameDetection.DetectedGame is not null)
{
_errorHandlingService.HandleError("h2m-mod.exe is already running.");
_errorHandlingService.HandleError($"{Path.GetFileName(GameDetection.DetectedGame.FileName)} is already running.");
return;
}

Expand All @@ -188,8 +202,8 @@ public void LaunchH2MMod()
else
{
_errorHandlingService.HandleException(
new FileNotFoundException("h2m-mod.exe was not found."),
$"The h2m-mod.exe could not be found at {gameFileName}!");
new FileNotFoundException("H2M executable was not found."),
$"The H2M executable could not be found at '{gameFileName}'!");
}
}
catch (Exception ex)
Expand Down Expand Up @@ -280,11 +294,11 @@ private static nint FindH2MConHostProcess()
foreach (var handle in EnumerateWindowHandles())
{
string? title = GetWindowTitle(handle);
if (title != null && title.Contains("h2m-mod", StringComparison.OrdinalIgnoreCase))
if (title != null && H2M_WINDOW_TITLE_STRINGS.Any(str => title.Contains(str, StringComparison.OrdinalIgnoreCase)))
{
GetWindowThreadProcessId(handle, out var processId);

if (title == GAME_WINDOW_TITLE)
if (GAME_WINDOW_TITLES.Contains(title))
{
continue;
}
Expand All @@ -306,7 +320,7 @@ private static nint FindH2MConHostProcess()
{
// find processes with matching title
var processesWithTitle = Process.GetProcesses().Where(p =>
p.MainWindowTitle.Contains("h2m-mod", StringComparison.OrdinalIgnoreCase)).ToList();
H2M_WINDOW_TITLE_STRINGS.Any(str => p.MainWindowTitle.Contains(str, StringComparison.OrdinalIgnoreCase))).ToList();

// find process that loaded H1 MP binary
var gameProc = processesWithTitle.FirstOrDefault(p =>
Expand All @@ -317,7 +331,7 @@ private static nint FindH2MConHostProcess()

private static bool IsH2MModProcess(Process p)
{
return p.MainWindowTitle.Contains("h2m-mod", StringComparison.OrdinalIgnoreCase) &&
return H2M_WINDOW_TITLE_STRINGS.Any(str => p.MainWindowTitle.Contains(str, StringComparison.OrdinalIgnoreCase)) &&
p.Modules.OfType<ProcessModule>().Any(m => m.ModuleName.Equals(Constants.GAME_EXECUTABLE_NAME));
}

Expand All @@ -327,7 +341,7 @@ private static nint FindH2MModGameWindow(Process process)
foreach (nint hChild in EnumerateProcessWindowHandles(process.Id))
{
string? title = GetWindowTitle(hChild);
if (title != null && title.Equals(GAME_WINDOW_TITLE))
if (title != null && GAME_WINDOW_TITLES.Contains(title))
{
return hChild;
}
Expand Down
12 changes: 6 additions & 6 deletions H2MLauncher.Core/H2MLauncher.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
<PackageReference Include="ConcurrentHashSet" Version="1.3.0" />
<PackageReference Include="Haukcode.HighResolutionTimer" Version="1.1.0" />
<PackageReference Include="Flurl" Version="4.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.8" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="8.0.10" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
<PackageReference Include="Nogic.WritableOptions" Version="3.1.0" />
<PackageReference Include="System.Interactive.Async" Version="6.0.1" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="System.Reactive" Version="6.0.1" />
<PackageReference Include="System.Reactive.Linq" Version="6.0.1" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="System.Text.Json" Version="8.0.5" />
<PackageReference Include="TypedSignalR.Client" Version="3.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
16 changes: 8 additions & 8 deletions H2MLauncher.UI/H2MLauncher.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,22 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.122" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageReference Include="MvvmDialogs" Version="9.1.2" />
<PackageReference Include="NHotkey.Wpf" Version="3.0.0" />
<PackageReference Include="Nogic.WritableOptions" Version="3.1.0" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog" Version="4.0.2" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.4" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
Expand Down
14 changes: 7 additions & 7 deletions MatchmakingServer/MatchmakingServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@
<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.10.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.5" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.8" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Common" Version="8.0.10" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
<PackageReference Include="Nito.AsyncEx.Interop.WaitHandles" Version="5.1.2" />
<PackageReference Include="Nito.AsyncEx.Tasks" Version="5.1.2" />
<PackageReference Include="Serilog" Version="4.0.1" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog" Version="4.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Serilog.Expressions" Version="5.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.2" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.4" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit fe65296

Please sign in to comment.