simplify arg parsing

Pass compat tool args as is instead of manually inserting python3 entrypoint.

There was an issue when Steam first started using reaper that required arg manipulation that has since been fixed.

should fix #151
This commit is contained in:
Chris
2025-02-09 22:02:51 -07:00
parent 5e06858b29
commit caa6e108aa
2 changed files with 28 additions and 58 deletions

View File

@ -73,32 +73,23 @@ let applyDeviceAuth settings =
let private doesntEndWith (value: string) (str: string) = not (str.EndsWith(value))
type private EpicArg = ExchangeCode of string | Type of string | AppId of string
let parseArgs defaults (findCbLaunchDir: Platform -> Result<string,string>) (argv: string[]) =
let launcherIndex =
argv
|> Array.tryFindIndex (fun s -> s <> null && s.EndsWith("EDLaunch.exe", StringComparison.OrdinalIgnoreCase))
|> Option.defaultValue -1
let compatTool, cbLaunchDir, args =
let isOldProton (args: string[]) = // Proton < 5.13 doesn't run via steam linux runtime
args.Length > 2 && args.[0] <> null
&& [ Path.Combine("steamapps", "common", "Proton"); Path.Combine("Steam", "compatibilitytools.d", "Proton") ]
|> List.exists (fun p -> args.[0].Contains(p, StringComparison.OrdinalIgnoreCase))
let isNewProton (args: string[]) = // Proton >= 5.13 runs via steam linux runtime
args.Length > 2 && args |> Array.filter (fun a -> a <> null) |> Array.exists (fun a -> a.Contains("SteamLinuxRuntime"))
let isWine() = argv.Length > 0 && argv[0] <> null && argv[0].EndsWith("wine")
if isNewProton argv then
let runtimeArgs = argv.[1..] |> Array.takeWhile (doesntEndWith "proton")
let protonArgs = argv.[1..] |> Array.skipWhile (doesntEndWith "proton") |> Array.takeWhile (doesntEndWith "EDLaunch.exe")
let args = seq { runtimeArgs; [| "python3" |]; protonArgs } |> Array.concat
let launcherIndex = args.Length
Some { EntryPoint = argv.[0]; Args = args }, Path.GetDirectoryName(argv.[launcherIndex]) |> Some, argv.[launcherIndex + 1..]
else if isOldProton argv then
Some { EntryPoint = "python3"; Args = argv.[..1] }, Path.GetDirectoryName(argv.[2]) |> Some, argv.[3..]
else if isWine() then
Some { EntryPoint = argv[0]; Args = [||] }, Path.GetDirectoryName(argv.[1]) |> Some, argv.[2..]
else if argv.Length > 0 && argv.[0] <> null && argv.[0].EndsWith("EDLaunch.exe", StringComparison.OrdinalIgnoreCase) then
None, Path.GetDirectoryName(argv.[0]) |> Some, argv.[1..]
else
if launcherIndex < 0 then
None, None, argv
else if launcherIndex = 0 then
None, Path.GetDirectoryName(argv[launcherIndex]) |> Some, argv[1..]
else if argv.Length > 1 then
Some { EntryPoint = argv[0]; Args = argv[1..launcherIndex - 1] }, Path.GetDirectoryName(argv[launcherIndex]) |> Some, argv[launcherIndex + 1..]
else
Some { EntryPoint = argv[0]; Args = [||] }, Path.GetDirectoryName(argv[launcherIndex]) |> Some, [||]
let getArg (arg:string) i =
if i + 1 < args.Length && not (String.IsNullOrEmpty args.[i + 1]) && (not (args.[i + 1].StartsWith '/') && not (args.[i].StartsWith '-')) then // /arg argValue
if i + 1 < args.Length && not (String.IsNullOrEmpty args[i + 1]) && (not (args[i + 1].StartsWith '/') && not (args[i].StartsWith '-')) then // /arg argValue
arg.ToLowerInvariant(), Some args.[i + 1]
else if arg.Contains("=") then // -arg=argvalue
let parts = arg.Split("=")

View File

@ -146,49 +146,28 @@ let tests =
}
yield! [
"non steam linux runtime", [ Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"non steam linux runtime custom folder", [ Path.Combine("Steam", "compatibilitytools.d", "Proton 5.0", "proton"); "protonAction" ]
"non steam linux runtime custom folder case insensitive", [ Path.Combine("sTeAm", "compatibilitytools.d", "proton 5.0", "Proton"); "protonAction" ]
] |> List.map (fun (name, protonArgs) ->
test $"Matches proton args {name}" {
"proton - no wrapper", [ Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"proton - no wrapper - custom folder", [ Path.Combine("sTeAm", "compatibilitytools.d", "compat-tool", "proton"); "protonAction" ]
"proton - reaper", [ Path.Combine("Steam", "ubuntu12_32", "reaper"); "SteamLaunch"; "AppId=359320"; "--"; Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--deploy=soldier"; "--suite=soldier"; "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"proton - steam-launch-wrapper", [ Path.Combine("Steam", "ubuntu12_32", "steam-launch-wrapper"); "--"; Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--deploy=soldier"; "--suite=soldier"; "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"proton - extra args", [ Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--deploy=soldier"; "--suite=soldier"; "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"proton - steam linux runtime", [ Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"proton - cachyos", [ Path.Combine("Steam", "ubuntu12_32", "steam-launch-wrapper"); "--"; Path.Combine("Steam", "ubuntu12_32", "reaper"); "SteamLaunch"; "AppId=359320"; "--"; Path.Combine("steam", "compatibilitytools.d", "proton-cachyos", "proton"); "waitforexitandrun" ]
"wine", [ "wine" ]
] |> List.map(fun (name, protonArgs) ->
test $"Matches compat tool args {name}" {
let launcherDir = "launchDir"
let launcherPath = Path.Combine(launcherDir, "EDLaunch.exe")
let args = protonArgs @ [launcherPath; "/other"; "/args"] |> List.toArray
let launcherArgs = [Path.Combine(launcherDir, "EDLaunch.exe"); "/other"; "/args"]
let args = protonArgs @ launcherArgs |> List.toArray
let settings = parse args
let expected = { EntryPoint = "python3"; Args = args.[..^3] }
Expect.equal settings.CompatTool (Some expected) ""
let expected = Some { EntryPoint = args[0]; Args = args[1..^launcherArgs.Length] }
Expect.equal settings.CompatTool expected ""
Expect.equal settings.CbLauncherDir launcherDir ""
}
)
yield! [
"steam linux runtime - reaper", [ Path.Combine("Steam", "ubuntu12_32", "reaper"); "SteamLaunch"; "AppId=359320"; "--"; Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--deploy=soldier"; "--suite=soldier"; "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"steam linux runtime - steam-launch-wrapper", [ Path.Combine("Steam", "ubuntu12_32", "steam-launch-wrapper"); "--"; Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--deploy=soldier"; "--suite=soldier"; "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"steam linux runtime - extra args", [ Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--deploy=soldier"; "--suite=soldier"; "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
"steam linux runtime", [ Path.Combine("steamapps", "common", "SteamLinuxRuntime_soldier", "_v2-entry-point"); "--verb=protonAction"; "--"; Path.Combine("steamapps", "common", "Proton 5.0", "proton"); "protonAction" ]
] |> List.map (fun (name, protonArgs) ->
test $"Matches proton args {name}" {
let launcherDir = "launchDir"
let launcherPath = Path.Combine(launcherDir, "EDLaunch.exe")
let args = protonArgs @ [launcherPath; "/other"; "/args"] |> List.toArray
let settings = parse args
let expectedArgs = protonArgs.[1..^2] @ [ "python3" ] @ protonArgs.[^1..] |> List.toArray
let expected = { EntryPoint = args.[0]; Args = expectedArgs }
Expect.equal settings.CompatTool (Some expected) ""
Expect.equal settings.CbLauncherDir launcherDir ""
}
)
test "Matches wine args" {
let launcherDir = "launchDir"
let launcherPath = Path.Combine(launcherDir, "EDLaunch.exe")
let settings = parse [| "wine"; launcherPath |]
let expected = { EntryPoint = "wine"; Args = [||] } |> Some
Expect.equal settings.CompatTool expected ""
}
test "First arg doesn't contain steamapps/common/Proton or SteamRuntimeLinux means no Proton" {
let settings = parse [| "asdf"; "fdsa"; "launchDir" |]
Expect.equal settings.CompatTool None ""