mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Offer to restart game from VEH exception handler (#936)
This commit is contained in:
parent
98e421a227
commit
58ceb1dc87
16 changed files with 1279 additions and 616 deletions
|
|
@ -7,7 +7,7 @@ using System.Linq;
|
|||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using Dalamud.Game;
|
||||
using Newtonsoft.Json;
|
||||
using Reloaded.Memory.Buffers;
|
||||
|
|
@ -484,6 +484,7 @@ namespace Dalamud.Injector
|
|||
var withoutDalamud = false;
|
||||
var noFixAcl = false;
|
||||
var waitForGameWindow = true;
|
||||
var encryptArguments = false;
|
||||
|
||||
var parsingGameArgument = false;
|
||||
for (var i = 2; i < args.Count; i++)
|
||||
|
|
@ -520,6 +521,43 @@ namespace Dalamud.Injector
|
|||
throw new CommandLineException($"\"{args[i]}\" is not a command line argument.");
|
||||
}
|
||||
|
||||
var checksumTable = "fX1pGtdS5CAP4_VL";
|
||||
var argDelimiterRegex = new Regex(" (?<!(?:^|[^ ])(?: )*)/");
|
||||
var kvDelimiterRegex = new Regex(" (?<!(?:^|[^ ])(?: )*)=");
|
||||
gameArguments = gameArguments.SelectMany(x =>
|
||||
{
|
||||
if (!x.StartsWith("//**sqex0003") || !x.EndsWith("**//"))
|
||||
return new List<string>() { x };
|
||||
|
||||
var checksum = checksumTable.IndexOf(x[x.Length - 5]);
|
||||
if (checksum == -1)
|
||||
return new List<string>() { x };
|
||||
|
||||
var encData = Convert.FromBase64String(x.Substring(12, x.Length - 12 - 5).Replace('-', '+').Replace('_', '/').Replace('*', '='));
|
||||
var rawData = new byte[encData.Length];
|
||||
|
||||
for (var i = (uint)checksum; i < 0x10000u; i += 0x10)
|
||||
{
|
||||
var bf = new LegacyBlowfish(Encoding.UTF8.GetBytes($"{i << 16:x08}"));
|
||||
Buffer.BlockCopy(encData, 0, rawData, 0, rawData.Length);
|
||||
bf.Decrypt(ref rawData);
|
||||
var rawString = Encoding.UTF8.GetString(rawData).Split('\0', 2).First();
|
||||
encryptArguments = true;
|
||||
var args = argDelimiterRegex.Split(rawString).Skip(1).Select(y => string.Join('=', kvDelimiterRegex.Split(y, 2)).Replace(" ", " ")).ToList();
|
||||
if (!args.Any())
|
||||
continue;
|
||||
if (!args.First().StartsWith("T="))
|
||||
continue;
|
||||
if (!uint.TryParse(args.First().Substring(2), out var tickCount))
|
||||
continue;
|
||||
if (tickCount >> 16 != i)
|
||||
continue;
|
||||
return args.Skip(1);
|
||||
}
|
||||
|
||||
return new List<string>() { x };
|
||||
}).ToList();
|
||||
|
||||
if (showHelp)
|
||||
{
|
||||
ProcessHelpCommand(args, "launch");
|
||||
|
|
@ -603,7 +641,39 @@ namespace Dalamud.Injector
|
|||
});
|
||||
}
|
||||
|
||||
var gameArgumentString = string.Join(" ", gameArguments.Select(x => EncodeParameterArgument(x)));
|
||||
string gameArgumentString;
|
||||
if (encryptArguments)
|
||||
{
|
||||
var rawTickCount = (uint)Environment.TickCount;
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
[System.Runtime.InteropServices.DllImport("c")]
|
||||
static extern ulong clock_gettime_nsec_np(int clock_id);
|
||||
|
||||
const int CLOCK_MONOTONIC_RAW = 4;
|
||||
var rawTickCountFixed = (clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) / 1000000);
|
||||
Log.Information("ArgumentBuilder::DeriveKey() fixing up rawTickCount from {0} to {1} on macOS", rawTickCount, rawTickCountFixed);
|
||||
rawTickCount = (uint)rawTickCountFixed;
|
||||
}
|
||||
|
||||
var ticks = rawTickCount & 0xFFFF_FFFFu;
|
||||
var key = ticks & 0xFFFF_0000u;
|
||||
gameArguments.Insert(0, $"T={ticks}");
|
||||
|
||||
var escapeValue = (string x) => x.Replace(" ", " ");
|
||||
gameArgumentString = gameArguments.Select(x => x.Split('=', 2)).Aggregate(new StringBuilder(), (whole, part) => whole.Append($" /{escapeValue(part[0])} ={escapeValue(part.Length > 1 ? part[1] : string.Empty)}")).ToString();
|
||||
var bf = new LegacyBlowfish(Encoding.UTF8.GetBytes($"{key:x08}"));
|
||||
var ciphertext = bf.Encrypt(Encoding.UTF8.GetBytes(gameArgumentString));
|
||||
var base64Str = Convert.ToBase64String(ciphertext).Replace('+', '-').Replace('/', '_').Replace('=', '*');
|
||||
var checksum = checksumTable[(int)(key >> 16) & 0xF];
|
||||
gameArgumentString = $"//**sqex0003{base64Str}{checksum}**//";
|
||||
}
|
||||
else
|
||||
{
|
||||
gameArgumentString = string.Join(" ", gameArguments.Select(x => EncodeParameterArgument(x)));
|
||||
}
|
||||
|
||||
var process = GameStart.LaunchGame(Path.GetDirectoryName(gamePath), gamePath, gameArgumentString, noFixAcl, (Process p) =>
|
||||
{
|
||||
if (!withoutDalamud && mode == "entrypoint")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue