Skip to content

Commit

Permalink
Merge pull request #122 from goatcorp/local-injection
Browse files Browse the repository at this point in the history
  • Loading branch information
Blooym authored Mar 6, 2024
2 parents 5d503fb + 26cb493 commit 0e69121
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 68 deletions.
21 changes: 10 additions & 11 deletions src/XIVLauncher.Core/Components/MainPage/MainPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,8 @@ public async Task<bool> Login(string username, string password, bool isOtp, bool

private async Task<Launcher.LoginResult> TryLoginToGame(string username, string password, string otp, bool isSteam, LoginAction action)
{
bool? gateStatus = null;

#if !DEBUG
bool? gateStatus = null;
try
{
// TODO: Also apply the login status fix here
Expand Down Expand Up @@ -339,7 +338,7 @@ private async Task<bool> TryProcessLoginResult(Launcher.LoginResult loginResult,

return false;
}

#if !DEBUG
bool? gateStatus = null;
try
Expand Down Expand Up @@ -689,7 +688,7 @@ public async Task<Process> StartGameAndAddon(Launcher.LoginResult loginResult, b
System.Environment.SetEnvironmentVariable("LC_ALL", Program.CType);
System.Environment.SetEnvironmentVariable("LC_CTYPE", Program.CType);
}

// Hack: Strip out gameoverlayrenderer.so entries from LD_PRELOAD
if (App.Settings.FixLDP.Value)
{
Expand All @@ -711,7 +710,7 @@ public async Task<Process> StartGameAndAddon(Launcher.LoginResult loginResult, b
// If there's only one launch option (no %command%) figure out whether it's args or env variables.
if (launchOptions.Length == 1)
{
if(launchOptions[0].StartsWith('-'))
if (launchOptions[0].StartsWith('-'))
gameArgs = launchOptions[0];
else
launchEnv = launchOptions[0];
Expand Down Expand Up @@ -750,7 +749,7 @@ public async Task<Process> StartGameAndAddon(Launcher.LoginResult loginResult, b
else if (!Directory.Exists(App.Settings.WineBinaryPath))
throw new Exception("Custom wine binary path is invalid: no such directory.\n" +
"Check path carefully for typos: " + App.Settings.WineBinaryPath);
else if (!File.Exists(Path.Combine(App.Settings.WineBinaryPath,"wine64")))
else if (!File.Exists(Path.Combine(App.Settings.WineBinaryPath, "wine64")))
throw new Exception("Custom wine binary path is invalid: no wine64 found at that location.\n" +
"Check path carefully for typos: " + App.Settings.WineBinaryPath);
}
Expand Down Expand Up @@ -1202,11 +1201,11 @@ private async Task<bool> RepairGame(Launcher.LoginResult loginResult)
case PatchVerifier.VerifyState.Done:
// TODO: ask the user if they want to login or rerun after repair
App.ShowMessageBlocking(verify.NumBrokenFiles switch
{
0 => Loc.Localize("GameRepairSuccess0", "All game files seem to be valid."),
1 => Loc.Localize("GameRepairSuccess1", "XIVLauncher has successfully repaired 1 game file."),
_ => string.Format(Loc.Localize("GameRepairSuccessPlural", "XIVLauncher has successfully repaired {0} game files."), verify.NumBrokenFiles),
});
{
0 => Loc.Localize("GameRepairSuccess0", "All game files seem to be valid."),
1 => Loc.Localize("GameRepairSuccess1", "XIVLauncher has successfully repaired 1 game file."),
_ => string.Format(Loc.Localize("GameRepairSuccessPlural", "XIVLauncher has successfully repaired {0} game files."), verify.NumBrokenFiles),
});

doVerify = false;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,57 @@ namespace XIVLauncher.Core.Components.SettingsPage.Tabs;

public class SettingsTabDalamud : SettingsTab
{
public override SettingsEntry[] Entries { get; } = {
new SettingsEntry<bool>("Enable Dalamud", "Enable the Dalamud plugin system", () => Program.Config.DalamudEnabled ?? true, b => Program.Config.DalamudEnabled = b),
public override string Title => "Dalamud";
public override SettingsEntry[] Entries { get; }
private SettingsEntry<bool> enableManualInjection;

new SettingsEntry<DalamudLoadMethod>("Load Method", "Choose how Dalamud is loaded.", () => Program.Config.DalamudLoadMethod ?? DalamudLoadMethod.DllInject, method => Program.Config.DalamudLoadMethod = method)
public SettingsTabDalamud()
{
this.Entries = new SettingsEntry[]
{
CheckValidity = x =>
{
if (x == DalamudLoadMethod.EntryPoint && !OperatingSystem.IsWindows())
return "Entry point injection is only supported on Windows.";

return null;
},
},
new SettingsEntry<bool>("Enable Dalamud", "Enable the Dalamud plugin system", () => Program.Config.DalamudEnabled ?? true, b => Program.Config.DalamudEnabled = b),

new NumericSettingsEntry("Injection Delay (ms)", "Choose how long to wait after the game has loaded before injecting.", () => Program.Config.DalamudLoadDelay, delay => Program.Config.DalamudLoadDelay = delay, 0, int.MaxValue, 1000),
};
new SettingsEntry<DalamudLoadMethod>("Load Method", "Choose how Dalamud is loaded.", () => Program.Config.DalamudLoadMethod ?? DalamudLoadMethod.DllInject, method => Program.Config.DalamudLoadMethod = method),

public override string Title => "Dalamud";
new NumericSettingsEntry("Injection Delay (ms)", "Choose how long to wait after the game has loaded before injecting.", () => Program.Config.DalamudLoadDelay, delay => Program.Config.DalamudLoadDelay = delay, 0, int.MaxValue, 1000),

enableManualInjection = new SettingsEntry<bool>("Enable Manual Injection", "Use a local build of Dalamud instead of the automatically provided one (For developers only!)", () => Program.Config.DalamudManualInjectionEnabled ?? false, (enabled) =>
{
Program.Config.DalamudManualInjectionEnabled = enabled;
if (!enabled)
{
Program.DalamudUpdater.RunnerOverride = null;
return;
}
if (Directory.Exists(Program.Config.DalamudManualInjectPath) && Directory.GetFiles(Program.Config.DalamudManualInjectPath).FirstOrDefault(x => x == "Dalamud.Injector.exe") is not null)
{
Program.DalamudUpdater.RunnerOverride = new FileInfo(Path.Combine(Program.Config.DalamudManualInjectPath, Program.DALAMUD_INJECTOR_NAME));
}
}),

new SettingsEntry<string>("Manual Injection Path", "The path to the local version of Dalamud where Dalamud.Injector.exe is located", () => Program.Config.DalamudManualInjectPath, (input) =>
{
Program.Config.DalamudManualInjectPath = input;
Program.DalamudUpdater.RunnerOverride = new FileInfo(Path.Combine(input, Program.DALAMUD_INJECTOR_NAME));
})
{
CheckVisibility = () => enableManualInjection.Value == true,
CheckValidity = input =>
{
if (!Directory.Exists(input))
{
return "There is no directory at that path.";
}
if (Directory.GetFiles(input).FirstOrDefault(x => x == Program.DALAMUD_INJECTOR_NAME) is not null)
{
return "Dalamud.Injector.exe was not found inside of the provided directory.";
}
return null;
},
},
};
}
}
2 changes: 2 additions & 0 deletions src/XIVLauncher.Core/Configuration/ILauncherConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ public interface ILauncherConfig
public bool? DalamudEnabled { get; set; }

public DalamudLoadMethod? DalamudLoadMethod { get; set; }
public bool? DalamudManualInjectionEnabled { get; set; }
public string? DalamudManualInjectPath { get; set; }

public int DalamudLoadDelay { get; set; }

Expand Down
81 changes: 54 additions & 27 deletions src/XIVLauncher.Core/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Numerics;
using System.IO;
using CheapLoc;
using Config.Net;
using ImGuiNET;
Expand Down Expand Up @@ -59,7 +58,7 @@ class Program

private const string APP_NAME = "xlcore";

private static string[] mainargs;
private static string[] mainArgs;

private static uint invalidationFrames = 0;
private static Vector2 lastMousePosition;
Expand Down Expand Up @@ -114,7 +113,7 @@ private static void LoadConfig(Storage storage)
Config.PatchAcquisitionMethod ??= AcquisitionMethod.Aria;

Config.DalamudEnabled ??= true;
Config.DalamudLoadMethod = !OperatingSystem.IsWindows() ? DalamudLoadMethod.DllInject : DalamudLoadMethod.EntryPoint;
Config.DalamudLoadMethod ??= DalamudLoadMethod.EntryPoint;

Config.GlobalScale ??= 1.0f;

Expand All @@ -136,9 +135,43 @@ private static void LoadConfig(Storage storage)
public const uint STEAM_APP_ID = 39210;
public const uint STEAM_APP_ID_FT = 312060;

/// <summary>
/// The name of the Dalamud injector executable file.
/// </summary>
// TODO: move this somewhere better.
public const string DALAMUD_INJECTOR_NAME = "Dalamud.Injector.exe";

/// <summary>
/// Creates a new instance of the Dalamud updater.
/// </summary>
/// <remarks>
/// If <see cref="ILauncherConfig.DalamudManualInjectionEnabled"/> is true and there is an injector at <see cref="ILauncherConfig.DalamudManualInjectPath"/> then
/// manual injection will be used instead of a Dalamud branch.
/// </remarks>
/// <returns>A <see cref="DalamudUpdater"/> instance.</returns>
private static DalamudUpdater CreateDalamudUpdater()
{
if (Config.DalamudManualInjectionEnabled == true &&
Directory.Exists(Config.DalamudManualInjectPath) &&
Directory.GetFiles(Config.DalamudManualInjectPath).FirstOrDefault(f => f == DALAMUD_INJECTOR_NAME) is not null)
{
var updater = new DalamudUpdater(new DirectoryInfo(Config.DalamudManualInjectPath), storage.GetFolder("runtime"), storage.GetFolder("dalamudAssets"), storage.Root, null, null)
{
Overlay = DalamudLoadInfo,
};
DalamudUpdater.RunnerOverride = new FileInfo(Path.Combine(Config.DalamudManualInjectPath, DALAMUD_INJECTOR_NAME));
return updater;
}

return new DalamudUpdater(storage.GetFolder("dalamud"), storage.GetFolder("runtime"), storage.GetFolder("dalamudAssets"), storage.Root, null, null)
{
Overlay = DalamudLoadInfo,
};
}

private static void Main(string[] args)
{
mainargs = args;
mainArgs = args;
storage = new Storage(APP_NAME);

if (CoreEnvironmentSettings.ClearAll)
Expand All @@ -153,8 +186,8 @@ private static void Main(string[] args)
if (CoreEnvironmentSettings.ClearTools) ClearTools();
if (CoreEnvironmentSettings.ClearLogs) ClearLogs();
}
SetupLogging(mainargs);

SetupLogging(mainArgs);
LoadConfig(storage);

Secrets = GetSecretProvider(storage);
Expand Down Expand Up @@ -210,11 +243,9 @@ private static void Main(string[] args)
Log.Error(ex, "Steam couldn't load");
}

// Manual or auto injection setup.
DalamudLoadInfo = new DalamudOverlayInfoProxy();
DalamudUpdater = new DalamudUpdater(storage.GetFolder("dalamud"), storage.GetFolder("runtime"), storage.GetFolder("dalamudAssets"), storage.Root, null, null)
{
Overlay = DalamudLoadInfo
};
DalamudUpdater = CreateDalamudUpdater();
DalamudUpdater.Run();

CreateCompatToolsInstance();
Expand Down Expand Up @@ -354,17 +385,17 @@ private static ISecretProvider GetSecretProvider(Storage storage)
return new FileSecretProvider(storage.GetFile(secretsFilePath));

case "KEYRING":
{
var keyChain = new KeychainSecretProvider();

if (!keyChain.IsAvailable)
{
Log.Error("An org.freedesktop.secrets provider is not available - no secrets will be stored");
return new DummySecretProvider();
}
var keyChain = new KeychainSecretProvider();

return keyChain;
}
if (!keyChain.IsAvailable)
{
Log.Error("An org.freedesktop.secrets provider is not available - no secrets will be stored");
return new DummySecretProvider();
}

return keyChain;
}

case "NONE":
return new DummySecretProvider();
Expand Down Expand Up @@ -405,10 +436,7 @@ public static void ClearPlugins(bool tsbutton = false)
if (tsbutton)
{
DalamudLoadInfo = new DalamudOverlayInfoProxy();
DalamudUpdater = new DalamudUpdater(storage.GetFolder("dalamud"), storage.GetFolder("runtime"), storage.GetFolder("dalamudAssets"), storage.Root, null, null)
{
Overlay = DalamudLoadInfo
};
DalamudUpdater = CreateDalamudUpdater();
DalamudUpdater.Run();
}
}
Expand All @@ -425,14 +453,13 @@ public static void ClearLogs(bool tsbutton = false)
{
storage.GetFolder("logs").Delete(true);
storage.GetFolder("logs");
string[] logfiles = { "dalamud.boot.log", "dalamud.boot.old.log", "dalamud.log", "dalamud.injector.log"};
string[] logfiles = { "dalamud.boot.log", "dalamud.boot.old.log", "dalamud.log", "dalamud.injector.log" };
foreach (string logfile in logfiles)
if (storage.GetFile(logfile).Exists) storage.GetFile(logfile).Delete();
if (tsbutton)
SetupLogging(mainargs);

}
SetupLogging(mainArgs);

}
public static void ClearAll(bool tsbutton = false)
{
ClearSettings(tsbutton);
Expand Down
53 changes: 36 additions & 17 deletions src/XIVLauncher.Core/XIVLauncher.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,20 @@
<PublishSingleFile>true</PublishSingleFile>
<!-- <SelfContained>true</SelfContained> -->

<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
<IsWindows
Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">
true</IsWindows>
<IsOSX
Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">
true</IsOSX>
<IsLinux
Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">
true</IsLinux>
</PropertyGroup>

<PropertyGroup>
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">
$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="'$(IsWindows)'=='true'">
Expand All @@ -42,10 +49,14 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="../XIVLauncher.VersionGenerator/XIVLauncher.VersionGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\..\lib\FFXIVQuickLauncher\src\XIVLauncher.Common.Unix\XIVLauncher.Common.Unix.csproj" />
<ProjectReference Include="..\..\lib\FFXIVQuickLauncher\src\XIVLauncher.Common.Windows\XIVLauncher.Common.Windows.csproj" />
<ProjectReference Include="..\..\lib\FFXIVQuickLauncher\src\XIVLauncher.Common\XIVLauncher.Common.csproj" />
<ProjectReference Include="../XIVLauncher.VersionGenerator/XIVLauncher.VersionGenerator.csproj"
OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference
Include="..\..\lib\FFXIVQuickLauncher\src\XIVLauncher.Common.Unix\XIVLauncher.Common.Unix.csproj" />
<ProjectReference
Include="..\..\lib\FFXIVQuickLauncher\src\XIVLauncher.Common.Windows\XIVLauncher.Common.Windows.csproj" />
<ProjectReference
Include="..\..\lib\FFXIVQuickLauncher\src\XIVLauncher.Common\XIVLauncher.Common.csproj" />
</ItemGroup>

<ItemGroup>
Expand All @@ -72,17 +83,22 @@
<ItemGroup>
<EmbeddedResource Include="Shaders/GLSL/imgui-vertex.glsl" LogicalName="imgui-vertex.glsl" />
<EmbeddedResource Include="Shaders/GLSL/imgui-frag.glsl" LogicalName="imgui-frag.glsl" />
<EmbeddedResource Include="Shaders/HLSL/imgui-vertex.hlsl.bytes" LogicalName="imgui-vertex.hlsl.bytes" />
<EmbeddedResource Include="Shaders/HLSL/imgui-frag.hlsl.bytes" LogicalName="imgui-frag.hlsl.bytes" />
<EmbeddedResource Include="Shaders/HLSL/imgui-vertex.hlsl.bytes"
LogicalName="imgui-vertex.hlsl.bytes" />
<EmbeddedResource Include="Shaders/HLSL/imgui-frag.hlsl.bytes"
LogicalName="imgui-frag.hlsl.bytes" />
<EmbeddedResource Include="Shaders/SPIR-V/imgui-vertex.spv" LogicalName="imgui-vertex.spv" />
<EmbeddedResource Include="Shaders/SPIR-V/imgui-frag.spv" LogicalName="imgui-frag.spv" />
<EmbeddedResource Include="Shaders/Metal/imgui-vertex.metallib" LogicalName="imgui-vertex.metallib" />
<EmbeddedResource Include="Shaders/Metal/imgui-vertex.metallib"
LogicalName="imgui-vertex.metallib" />
<EmbeddedResource Include="Shaders/Metal/imgui-frag.metallib" LogicalName="imgui-frag.metallib" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Resources/FontAwesome5FreeSolid.otf" LogicalName="FontAwesome5FreeSolid.otf" />
<EmbeddedResource Include="Resources/NotoSansCJKjp-Regular.otf" LogicalName="NotoSansCJKjp-Regular.otf" />
<EmbeddedResource Include="Resources/FontAwesome5FreeSolid.otf"
LogicalName="FontAwesome5FreeSolid.otf" />
<EmbeddedResource Include="Resources/NotoSansCJKjp-Regular.otf"
LogicalName="NotoSansCJKjp-Regular.otf" />

<EmbeddedResource Include="Resources/logo.png" LogicalName="logo.png" />

Expand All @@ -91,7 +107,8 @@

<EmbeddedResource Include="Resources/steamdeck_fts.png" LogicalName="steamdeck_fts.png" />
<EmbeddedResource Include="Resources/steamdeck_fterror.png" LogicalName="steamdeck_fterror.png" />
<EmbeddedResource Include="Resources/steamdeck_switchprompt.png" LogicalName="steamdeck_switchprompt.png" />
<EmbeddedResource Include="Resources/steamdeck_switchprompt.png"
LogicalName="steamdeck_switchprompt.png" />
<EmbeddedResource Include="Resources/xlcore_updatewarn.png" LogicalName="xlcore_updatewarn.png" />
</ItemGroup>

Expand All @@ -109,7 +126,8 @@
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
</PropertyGroup>
<!-- write the hash to the temp file.-->
<Exec Command="git -C &quot;$(ProjectDir.Replace('\','\\'))&quot; describe --long --always --dirty &gt; $(VerFile)" />
<Exec
Command="git -C &quot;$(ProjectDir.Replace('\','\\'))&quot; describe --long --always --dirty &gt; $(VerFile)" />
<!-- read the version into the GitVersion itemGroup-->
<ReadLinesFromFile File="$(VerFile)">
<Output TaskParameter="Lines" ItemName="GitVersion" />
Expand Down Expand Up @@ -141,7 +159,8 @@
</AssemblyAttributes>
</ItemGroup>
<!-- writes the attribute to the customAssemblyInfo file -->
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)"
AssemblyAttributes="@(AssemblyAttributes)" />
</Target>

</Project>
</Project>

0 comments on commit 0e69121

Please sign in to comment.