Skip to content

Commit

Permalink
Update UMod startup action
Browse files Browse the repository at this point in the history
Minor mod fixes
  • Loading branch information
AlexMacocian committed Nov 9, 2023
1 parent df71a17 commit a84945e
Show file tree
Hide file tree
Showing 16 changed files with 187 additions and 61 deletions.
3 changes: 2 additions & 1 deletion Daybreak/Configuration/ProjectConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ public override void RegisterStartupActions(IStartupActionProducer startupAction

startupActionProducer.RegisterAction<RenameInstallerAction>();
startupActionProducer.RegisterAction<FixSymbolicLinkStartupAction>();
startupActionProducer.RegisterAction<UpdateUModAction>();
}

public override void RegisterPostUpdateActions(IPostUpdateActionProducer postUpdateActionProducer)
Expand Down Expand Up @@ -438,11 +439,11 @@ public override void RegisterNotificationHandlers(INotificationHandlerProducer n

public override void RegisterMods(IModsManager modsManager)
{
modsManager.RegisterMod<IReShadeService, ReShadeService>();
modsManager.RegisterMod<IUModService, UModService>();
modsManager.RegisterMod<IToolboxService, ToolboxService>();
modsManager.RegisterMod<IDSOALService, DSOALService>();
modsManager.RegisterMod<IGuildwarsScreenPlacer, GuildwarsScreenPlacer>();
modsManager.RegisterMod<IReShadeService, ReShadeService>();
modsManager.RegisterMod<IGWCAInjector, GWCAInjector>();
modsManager.RegisterMod<IDirectSongService, DirectSongService>(singleton: true);
}
Expand Down
2 changes: 1 addition & 1 deletion Daybreak/Daybreak.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<LangVersion>preview</LangVersion>
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
<IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
<Version>0.9.8.141</Version>
<Version>0.9.8.142</Version>
<EnableWindowsTargeting>true</EnableWindowsTargeting>
<UserSecretsId>cfb2a489-db80-448d-a969-80270f314c46</UserSecretsId>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
Expand Down
8 changes: 8 additions & 0 deletions Daybreak/Models/ApplicationLauncherContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Diagnostics;

namespace Daybreak.Models;
public readonly struct ApplicationLauncherContext
{
public string ExecutablePath { get; init; }
public Process Process { get; init; }
}
46 changes: 40 additions & 6 deletions Daybreak/Services/ApplicationLauncher/ApplicationLauncher.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Daybreak.Configuration.Options;
using Daybreak.Exceptions;
using Daybreak.Models;
using Daybreak.Models.LaunchConfigurations;
using Daybreak.Services.Mods;
using Daybreak.Services.Mutex;
Expand Down Expand Up @@ -204,12 +205,13 @@ public void RestartDaybreakAsNormalUser()
}
};

var applicationLauncherContext = new ApplicationLauncherContext { Process = process, ExecutablePath = executable };
foreach(var mod in disabledmods)
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(this.launcherOptions.Value.ModStartupTimeout));
try
{
await mod.OnGuildWarsStartingDisabled(process, cts.Token);
await mod.OnGuildWarsStartingDisabled(applicationLauncherContext, cts.Token);
}
catch (TaskCanceledException)
{
Expand All @@ -233,7 +235,7 @@ public void RestartDaybreakAsNormalUser()
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(this.launcherOptions.Value.ModStartupTimeout));
try
{
await mod.OnGuildWarsStarting(process, cts.Token);
await mod.OnGuildWarsStarting(applicationLauncherContext, cts.Token);
}
catch (TaskCanceledException)
{
Expand All @@ -253,14 +255,39 @@ public void RestartDaybreakAsNormalUser()
}

var pId = LaunchClient(executable, string.Join(" ", args), this.privilegeManager.AdminPrivileges, out var clientHandle);
process = Process.GetProcessById(pId);
do
{
process = Process.GetProcessById(pId);
} while (process is null);

while (true)
{
// We need to verify that the process is actually started. This needs to be in a try/catch block because process.Id throws when the process is invalid
try
{
if (process.Id != 0)
{
break;
}
}
catch
{
}
}

while (!process.Responding)
{
await Task.Delay(1000, CancellationToken.None);
}

// Reset launch context with the launched process
applicationLauncherContext = new ApplicationLauncherContext { ExecutablePath = executable, Process = process };
foreach (var mod in mods)
{
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(this.launcherOptions.Value.ModStartupTimeout));
try
{
await mod.OnGuildWarsCreated(process, cts.Token);
await mod.OnGuildWarsCreated(applicationLauncherContext, cts.Token);
}
catch (TaskCanceledException)
{
Expand Down Expand Up @@ -331,7 +358,7 @@ public void RestartDaybreakAsNormalUser()
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(this.launcherOptions.Value.ModStartupTimeout));
try
{
await mod.OnGuildWarsStarted(process, cts.Token);
await mod.OnGuildWarsStarted(applicationLauncherContext, cts.Token);
}
catch (TaskCanceledException)
{
Expand Down Expand Up @@ -457,7 +484,14 @@ private bool SetRegistryGuildwarsPath(string path)
return Process.GetProcessesByName(ProcessName)
.Where(p =>
{
return launchConfigurationWithCredentials.FirstOrDefault(l => l.ExecutablePath == p.MainModule?.FileName) is not null;
try
{
return launchConfigurationWithCredentials.FirstOrDefault(l => l.ExecutablePath == p.MainModule?.FileName) is not null;
}
catch
{
return false;
}
})
.Select(p =>
{
Expand Down
13 changes: 7 additions & 6 deletions Daybreak/Services/DSOAL/DSOALService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Daybreak.Configuration.Options;
using Daybreak.Models;
using Daybreak.Models.Progress;
using Daybreak.Services.Downloads;
using Daybreak.Services.Notifications;
Expand Down Expand Up @@ -120,19 +121,19 @@ public IEnumerable<string> GetCustomArguments()
}
}

public Task OnGuildWarsCreated(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsCreated(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public Task OnGuildWarsStarted(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStarted(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public Task OnGuildWarsStarting(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStarting(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
var guildwarsDirectory = new FileInfo(process.StartInfo.FileName).Directory!.FullName;
var guildwarsDirectory = new FileInfo(applicationLauncherContext.ExecutablePath).Directory!.FullName;
if (this.IsInstalled)
{
this.EnsureSymbolicLinkExists();
Expand All @@ -147,9 +148,9 @@ public Task OnGuildWarsStarting(Process process, CancellationToken cancellationT
return Task.CompletedTask;
}

public Task OnGuildWarsStartingDisabled(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStartingDisabled(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
var guildwarsDirectory = new FileInfo(process.StartInfo.FileName).Directory!.FullName;
var guildwarsDirectory = new FileInfo(applicationLauncherContext.ExecutablePath).Directory!.FullName;
EnsureFileDoesNotExistInGuildwarsDirectory(DsoundDll, guildwarsDirectory);
EnsureFileDoesNotExistInGuildwarsDirectory(DSOALAldrvDll, guildwarsDirectory);
EnsureFileDoesNotExistInGuildwarsDirectory(AlsoftIni, guildwarsDirectory);
Expand Down
13 changes: 7 additions & 6 deletions Daybreak/Services/DirectSong/DirectSongService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Daybreak.Configuration.Options;
using Daybreak.Models;
using Daybreak.Models.Progress;
using Daybreak.Services.Downloads;
using Daybreak.Services.Notifications;
Expand Down Expand Up @@ -68,18 +69,18 @@ public DirectSongService(

public IEnumerable<string> GetCustomArguments() => Array.Empty<string>();

public Task OnGuildWarsCreated(Process process, CancellationToken cancellationToken) => Task.CompletedTask;
public Task OnGuildWarsCreated(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken) => Task.CompletedTask;

public Task OnGuildWarsStarted(Process process, CancellationToken cancellationToken) => Task.CompletedTask;
public Task OnGuildWarsStarted(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken) => Task.CompletedTask;

public Task OnGuildWarsStarting(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStarting(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
if (!this.IsInstalled)
{
return Task.CompletedTask;
}

var gwPath = Path.GetFullPath(process.StartInfo.FileName);
var gwPath = Path.GetFullPath(applicationLauncherContext.ExecutablePath);
var gwDirectory = Path.GetDirectoryName(gwPath)!;
var wmCorePath = Path.Combine(gwDirectory, WMVCOREDll);
var dsGuildWarsDll = Path.Combine(gwDirectory, DsGuildwarsDll);
Expand All @@ -99,9 +100,9 @@ public Task OnGuildWarsStarting(Process process, CancellationToken cancellationT
return Task.CompletedTask;
}

public Task OnGuildWarsStartingDisabled(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStartingDisabled(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
var gwPath = Path.GetFullPath(process.StartInfo.FileName);
var gwPath = Path.GetFullPath(applicationLauncherContext.ExecutablePath);
var gwDirectory = Path.GetDirectoryName(gwPath)!;
var wmCorePath = Path.Combine(gwDirectory, WMVCOREDll);
var dsGuildWarsDll = Path.Combine(gwDirectory, DsGuildwarsDll);
Expand Down
15 changes: 8 additions & 7 deletions Daybreak/Services/GWCA/GWCAInjector.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Daybreak.Models.GWCA;
using Daybreak.Models;
using Daybreak.Models.GWCA;
using Daybreak.Services.Injection;
using Daybreak.Services.Notifications;
using System.Collections.Generic;
Expand Down Expand Up @@ -35,32 +36,32 @@ public GWCAInjector(

public IEnumerable<string> GetCustomArguments() => Enumerable.Empty<string>();

public Task OnGuildWarsStarting(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStarting(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public Task OnGuildWarsStartingDisabled(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStartingDisabled(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}

public async Task OnGuildWarsCreated(Process process, CancellationToken cancellationToken)
public async Task OnGuildWarsCreated(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
if (!await this.injector.Inject(process, ModulePath, cancellationToken))
if (!await this.injector.Inject(applicationLauncherContext.Process, ModulePath, cancellationToken))
{
this.notificationService.NotifyError(
title: "Unable to inject GWCA into Guild Wars process",
description: "Daybreak integration with the Guild Wars process will be affected. Some Daybreak functionality might not work");
}
}

public async Task OnGuildWarsStarted(Process process, CancellationToken cancellationToken)
public async Task OnGuildWarsStarted(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
ConnectionContext? connectionContext = default;
for(var i = 0; i < MaxRetries; i++)
{
if (await this.gwcaClient.Connect(process, cancellationToken) is ConnectionContext newContext)
if (await this.gwcaClient.Connect(applicationLauncherContext.Process, cancellationToken) is ConnectionContext newContext)
{
connectionContext = newContext;
break;
Expand Down
12 changes: 6 additions & 6 deletions Daybreak/Services/Mods/IModService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Collections.Generic;
using System.Diagnostics;
using Daybreak.Models;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -15,20 +15,20 @@ public interface IModService
/// Called before starting the guild wars process.
/// Do mod preparation here.
/// </summary>
Task OnGuildWarsStarting(Process process, CancellationToken cancellationToken);
Task OnGuildWarsStarting(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken);
/// <summary>
/// Called when the process is created in suspended state.
/// Do dll injection here.
/// </summary>
Task OnGuildWarsCreated(Process process, CancellationToken cancellationToken);
Task OnGuildWarsCreated(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken);
/// <summary>
/// Called after the process has been resumed.
/// Do clean-up/integration with the guild wars process here.
/// </summary>
Task OnGuildWarsStarted(Process process, CancellationToken cancellationToken);
Task OnGuildWarsStarted(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken);
/// <summary>
/// Called before starting the guild wars process, when the mod is disabled.
/// Use this method to clean up the GuildWars folder of any residual mod files.
/// </summary>
Task OnGuildWarsStartingDisabled(Process process, CancellationToken cancellationToken);
Task OnGuildWarsStartingDisabled(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken);
}
17 changes: 9 additions & 8 deletions Daybreak/Services/ReShade/ReShadeService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Daybreak.Configuration.Options;
using Daybreak.Models;
using Daybreak.Models.Progress;
using Daybreak.Models.ReShade;
using Daybreak.Services.Downloads;
Expand Down Expand Up @@ -120,10 +121,10 @@ public void OnClosing()

public IEnumerable<string> GetCustomArguments() => Enumerable.Empty<string>();

public async Task OnGuildWarsCreated(Process process, CancellationToken cancellationToken)
public async Task OnGuildWarsCreated(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
var scopedLogger = this.logger.CreateScopedLogger(nameof(this.OnGuildWarsCreated), process?.MainModule?.FileName ?? string.Empty);
if (await this.processInjector.Inject(process!, ReShadeDllPath, cancellationToken))
var scopedLogger = this.logger.CreateScopedLogger(nameof(this.OnGuildWarsCreated), applicationLauncherContext.ExecutablePath ?? string.Empty);
if (await this.processInjector.Inject(applicationLauncherContext.Process, ReShadeDllPath, cancellationToken))
{
scopedLogger.LogInformation("Injected ReShade dll");
this.notificationService.NotifyInformation(
Expand All @@ -139,11 +140,11 @@ public async Task OnGuildWarsCreated(Process process, CancellationToken cancella
}
}

public Task OnGuildWarsStarted(Process process, CancellationToken cancellationToken) => Task.CompletedTask;
public Task OnGuildWarsStarted(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken) => Task.CompletedTask;

public Task OnGuildWarsStarting(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStarting(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
var destinationDirectory = Path.GetFullPath(new FileInfo(process.StartInfo.FileName).DirectoryName!);
var destinationDirectory = Path.GetFullPath(new FileInfo(applicationLauncherContext.ExecutablePath).DirectoryName!);
EnsureFileExistsInGuildwarsDirectory(ReShadeLog, destinationDirectory);
EnsureFileExistsInGuildwarsDirectory(ReShadePreset, destinationDirectory);
EnsureFileExistsInGuildwarsDirectory(ConfigIni, destinationDirectory);
Expand All @@ -152,9 +153,9 @@ public Task OnGuildWarsStarting(Process process, CancellationToken cancellationT
return Task.CompletedTask;
}

public Task OnGuildWarsStartingDisabled(Process process, CancellationToken cancellationToken)
public Task OnGuildWarsStartingDisabled(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
var destinationDirectory = Path.GetFullPath(new FileInfo(process.StartInfo.FileName).DirectoryName!);
var destinationDirectory = Path.GetFullPath(new FileInfo(applicationLauncherContext.ExecutablePath).DirectoryName!);
var destination = Path.Combine(Path.GetFullPath(destinationDirectory), PresetsFolder);
if (Directory.Exists(destination))
{
Expand Down
11 changes: 5 additions & 6 deletions Daybreak/Services/Screens/GuildwarsScreenPlacer.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using Daybreak.Configuration.Options;
using Daybreak.Models;
using Daybreak.Services.Scanner;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Core.Extensions;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -46,7 +45,7 @@ public bool IsEnabled

public bool IsInstalled => true;

public async Task OnGuildWarsStarted(Process process, CancellationToken cancellationToken)
public async Task OnGuildWarsStarted(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken)
{
var screen = this.screenManager.Screens.Skip(this.liveOptions.Value.DesiredGuildwarsScreen).FirstOrDefault();
if (screen is null)
Expand All @@ -72,9 +71,9 @@ public async Task OnGuildWarsStarted(Process process, CancellationToken cancella

public IEnumerable<string> GetCustomArguments() => Enumerable.Empty<string>();

public Task OnGuildWarsStarting(Process process, CancellationToken cancellationToken) => Task.CompletedTask;
public Task OnGuildWarsStarting(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken) => Task.CompletedTask;

public Task OnGuildWarsStartingDisabled(Process process, CancellationToken cancellationToken) => Task.CompletedTask;
public Task OnGuildWarsStartingDisabled(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken) => Task.CompletedTask;

public Task OnGuildWarsCreated(Process process, CancellationToken cancellationToken) => Task.CompletedTask;
public Task OnGuildWarsCreated(ApplicationLauncherContext applicationLauncherContext, CancellationToken cancellationToken) => Task.CompletedTask;
}
5 changes: 3 additions & 2 deletions Daybreak/Services/Startup/Actions/StartupActionBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;

namespace Daybreak.Services.Startup.Actions;

Expand All @@ -9,7 +10,7 @@ public virtual void ExecuteOnStartup()

}

public virtual Task ExecuteOnStartupAsync()
public virtual Task ExecuteOnStartupAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
Expand Down
Loading

0 comments on commit a84945e

Please sign in to comment.