fix invalid Epic login details due to format change

fixes #157
This commit is contained in:
Chris
2025-04-08 17:52:44 -06:00
parent b31db0e218
commit a3117a9ead
6 changed files with 73 additions and 22 deletions

View File

@ -62,9 +62,10 @@ let private epicValues = lazy (
let credIdProp = credType.GetProperty("ClientId")
let credSecretProp = credType.GetProperty("ClientSecret")
let depIdProp = optType.GetProperty("DeploymentId")
let sandboxIdProp = optType.GetProperty("SandboxId")
let credsProp = optType.GetProperty("ClientCredentials")
if methodInfo <> null && credIdProp <> null && credSecretProp <> null && depIdProp <> null && credsProp <> null then
if methodInfo <> null && credIdProp <> null && credSecretProp <> null && depIdProp <> null && sandboxIdProp <> null && credsProp <> null then
let eosIf = Activator.CreateInstance(eosIfType, null)
let options = methodInfo.Invoke(eosIf, null)
@ -72,11 +73,12 @@ let private epicValues = lazy (
let credentials = credsProp.GetValue(options)
if credentials <> null then
let depId = depIdProp.GetValue(options) :?> string
let sandboxId = sandboxIdProp.GetValue(options) :?> string
let cId = credIdProp.GetValue(credentials) :?> string
let cSecret = credSecretProp.GetValue(credentials) :?> string
if depId <> null && cId <> null && cSecret <> null then
Ok (cId, cSecret, depId)
if depId <> null && sandboxId <> null && cId <> null && cSecret <> null then
Ok (cId, cSecret, depId, sandboxId)
else
err "Unable to get values of IDs"
else
@ -104,9 +106,9 @@ let private requestToStr formValues contentHeaders (request: HttpRequestMessage)
let private requestToken launcherVersion (formValues: string list) : Task<Result<RefreshableToken, string>> =
match epicValues.Force() with
| Ok (clientId, clientSecret, dId) -> task {
| Ok (clientId, clientSecret, depId, _) -> task {
let formValues =
[ $"deployment_id={dId}"
[ $"deployment_id={depId}"
"scope=basic_profile friends_list presence" ]
|> List.append formValues
use content = new StringContent(String.Join("&", formValues), Encoding.UTF8, "application/x-www-form-urlencoded")
@ -156,6 +158,14 @@ let private generateExchangeCode token = task {
Log.debug $"Requesting epic exchange code failed: %s{content}"
return $"%i{int response.StatusCode}: %s{response.ReasonPhrase}" |> Error }
let getDeploymentId() =
epicValues.Force()
|> Result.map (fun (_, _, depId, _) -> depId)
let getSandboxId() =
epicValues.Force()
|> Result.map (fun (_, _, _, sandboxId) -> sandboxId)
let loginWithCode launcherVersion exchangeCode =
requestToken launcherVersion [ "grant_type=exchange_code"; $"exchange_code=%s{exchangeCode}" ]

View File

@ -144,9 +144,11 @@ let createArgString vr (lang: string option) edSession machineId timestamp watch
if lang.IsSome then "/language " + lang.Value
match platform, product.VInfo.SteamAware with
| Steam, true -> "/steam"
| Epic _, _ ->
let refresh = edSession.PlatformToken.GetRefreshToken() |> Option.defaultValue ""
$"\"EpicToken {refresh}\""
| Epic p, _ ->
let refresh = edSession.PlatformToken.GetRefreshToken() |> Option.defaultValue "[none]"
let sId = p.SandboxId |> Option.defaultValue "[none]"
let dId = p.DeploymentId |> Option.defaultValue "[none]"
$"\"ConfigureEpic %s{refresh} %s{sId} %s{dId}\""
| _, _ -> ()
match vr with
| Vr -> "/vr"

View File

@ -70,8 +70,29 @@ let applyDeviceAuth settings =
| Cobra.CredResult.Failure msg -> return Error msg }
| _ -> Ok settings |> Task.fromResult
let applyFallbackEpidIds settings =
match settings.Platform with
| Epic details -> result {
let! depId =
details.DeploymentId
|> Option.map Ok
|> Option.defaultWith (fun () ->
Epic.getDeploymentId()
|> Result.mapError (fun e -> $"Failed to get Epic deployment id: {e}")
)
let! sandboxId =
details.SandboxId
|> Option.map Ok
|> Option.defaultWith (fun () ->
Epic.getDeploymentId()
|> Result.mapError (fun e -> $"Failed to get Epic sandbox id: {e}")
)
return { settings with Platform = Epic { details with DeploymentId = Some depId; SandboxId = Some sandboxId } }
}
| _ -> Ok settings
let private doesntEndWith (value: string) (str: string) = not (str.EndsWith(value))
type private EpicArg = ExchangeCode of string | Type of string | AppId of string
type private EpicArg = ExchangeCode of string | Type of string | AppId of string | SandboxId of string | DeploymentId of string
let parseArgs defaults (findCbLaunchDir: Platform -> Result<string,string>) (argv: string[]) =
let launcherIndex =
argv
@ -102,9 +123,11 @@ let parseArgs defaults (findCbLaunchDir: Platform -> Result<string,string>) (arg
arg
|> Option.map (fun arg ->
match arg with
| ExchangeCode p -> { details with ExchangeCode = p }
| Type t -> { details with Type = t }
| AppId id -> { details with AppId = id })
| ExchangeCode p -> { details with ExchangeCode = p }
| Type t -> { details with Type = t }
| AppId id -> { details with AppId = id }
| SandboxId id -> { details with SandboxId = Some id }
| DeploymentId id -> { details with DeploymentId = Some id })
|> Option.defaultValue details
|> Epic
@ -133,6 +156,8 @@ let parseArgs defaults (findCbLaunchDir: Platform -> Result<string,string>) (arg
| "-auth_password", Some password -> { s with Platform = epicArg (ExchangeCode password) }
| "-auth_type", Some t -> { s with Platform = epicArg (Type t) }
| "-epicapp", Some id -> { s with Platform = epicArg (AppId id) }
| "-epicsandboxid", Some id -> { s with Platform = epicArg (SandboxId id) }
| "-epicdeploymentid", Some id -> { s with Platform = epicArg (DeploymentId id) }
| "/oculus", Some nonce -> { s with Platform = Oculus nonce; ForceLocal = true }
| "/restart", PosDouble delay -> { s with Restart = delay * 1000. |> int64 |> Some }
| "/vr", _ -> { s with DisplayMode = Vr }
@ -261,6 +286,7 @@ let getSettings args appDir fileConfig = task {
let! settings =
parseArgs defaults fallbackDirs args
|> Result.tee (fun s -> Directory.SetCurrentDirectory(s.CbLauncherDir))
|> Result.bind applyFallbackEpidIds
|> Result.bindTask applyDeviceAuth
return settings

View File

@ -54,10 +54,14 @@ type SampledProgress<'T>(interval: TimeSpan, handler: 'T -> unit, finishedHandle
type EpicDetails =
{ ExchangeCode: string
Type: string
AppId: string }
AppId: string
SandboxId: string option
DeploymentId: string option }
with static member Empty = { ExchangeCode = ""
Type = ""
AppId = "" }
AppId = ""
SandboxId = None
DeploymentId = None }
type Credentials = { Username: string; Password: string }
type FrontierDetails =
{ Profile: string; Credentials: Credentials option; AuthToken: string option }

View File

@ -63,19 +63,20 @@ open MinEdLauncher.Tests.Extensions
Expect.notStringContains actual "/steam" ""
}
test "Epic platform contains refresh token" {
let get = fun () -> { RefreshableToken.Empty with RefreshToken = "asdf" }
let token = { EdSession.Empty with PlatformToken = Expires {| Get = get; Renew = fun () -> Task.fromResult (Result.Ok()) |} }
let actual = createArgString Vr None token "" getTimestamp false (Epic EpicDetails.Empty) hashFile product
test "Epic platform contains refresh token, sandbox id and deployment id" {
let getToken = fun () -> { RefreshableToken.Empty with RefreshToken = "asdf" }
let epicDetails = { EpicDetails.Empty with SandboxId = Some "sId"; DeploymentId = Some "depId" }
let token = { EdSession.Empty with PlatformToken = Expires {| Get = getToken; Renew = fun () -> Task.fromResult (Result.Ok()) |} }
let actual = createArgString Vr None token "" getTimestamp false (Epic epicDetails) hashFile product
Expect.stringContains actual "\"EpicToken asdf\"" ""
Expect.stringContains actual "\"ConfigureEpic asdf sId depId\"" ""
}
test "Non epic platform doesn't contain refresh token" {
let get = fun () -> { RefreshableToken.Empty with RefreshToken = "asdf" }
let token = { EdSession.Empty with PlatformToken = Expires {| Get = get; Renew = fun _ -> Task.fromResult (Result.Ok()) |} }
let getToken = fun () -> { RefreshableToken.Empty with RefreshToken = "asdf" }
let token = { EdSession.Empty with PlatformToken = Expires {| Get = getToken; Renew = fun _ -> Task.fromResult (Result.Ok()) |} }
let actual = createArgString Vr None token "" getTimestamp false Dev hashFile product
Expect.notStringContains actual "\"EpicToken" ""
Expect.notStringContains actual "\"ConfigureEpic" ""
}
test "VR mode" {
let actual = createArgString Vr None token "" getTimestamp false Dev hashFile product

View File

@ -61,6 +61,14 @@ let tests =
let settings = parse [| "-epicapp=asdf" |]
Expect.equal settings.Platform (Epic { EpicDetails.Empty with AppId = "asdf" }) ""
}
test "Matches epic sandbox id" {
let settings = parse [| "-epicsandboxid=asdf" |]
Expect.equal settings.Platform (Epic { EpicDetails.Empty with SandboxId = Some "asdf" }) ""
}
test "Matches epic deployment id" {
let settings = parse [| "-epicdeploymentid=asdf" |]
Expect.equal settings.Platform (Epic { EpicDetails.Empty with DeploymentId = Some "asdf" }) ""
}
test "Matches /oculus nonce" {
let settings = parse [| "/oculus"; "123" |]
Expect.equal settings.Platform (Oculus "123") ""