Improvements to try resolve the issues with login checksums.
This commit is contained in:
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
from dataclasses import asdict, dataclass
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import platform
|
||||
import socket
|
||||
@@ -17,6 +18,7 @@ from .overlay import (
|
||||
COMPATIBILITY_BINARY_HASHES,
|
||||
CURRENT_V21_BINARY_HASHES,
|
||||
PATCHED_V21_GAME_DLL_SHA256,
|
||||
RETIRED_POST_AUTH_GAME_DLL_SHA256,
|
||||
)
|
||||
from .paths import AppPaths
|
||||
from .runtime import (
|
||||
@@ -41,9 +43,6 @@ DEFAULT_LOGIN_TIMEOUT_SECONDS = 5.0
|
||||
VERIFIED_GAME_PROFILES = frozenset(
|
||||
{"v21.75.83", "verified-compatibility"}
|
||||
)
|
||||
RETIRED_POST_AUTH_GAME_DLL_SHA256 = (
|
||||
"93cd27284eb294753da1111c99bfc9689f82b6d4a59302aee9fdbd8cb52452dd"
|
||||
)
|
||||
|
||||
|
||||
class _Closable(Protocol):
|
||||
@@ -82,7 +81,13 @@ class LoginDiagnosticReport:
|
||||
game_exe_sha256: str | None
|
||||
game_dll: str
|
||||
game_dll_sha256: str | None
|
||||
source_game_exe_sha256: str | None
|
||||
source_game_dll_sha256: str | None
|
||||
runtime_matches_managed_source: bool
|
||||
game_profile: str
|
||||
depot_build: int | None
|
||||
depot_version: str | None
|
||||
depot_completed_at: str | None
|
||||
world_fix_helper: str
|
||||
world_fix_helper_sha256: str | None
|
||||
world_fix_helper_ready: bool
|
||||
@@ -168,7 +173,16 @@ def inspect_login_environment(
|
||||
game_dll = game_root / "game.dll"
|
||||
game_exe_sha256 = _sha256_if_file(game_exe)
|
||||
game_dll_sha256 = _sha256_if_file(game_dll)
|
||||
source_game_exe_sha256 = _sha256_if_file(paths.source_game / "Game.exe")
|
||||
source_game_dll_sha256 = _sha256_if_file(paths.source_game / "game.dll")
|
||||
runtime_matches_managed_source = (
|
||||
game_exe_sha256 is not None
|
||||
and game_dll_sha256 is not None
|
||||
and game_exe_sha256 == source_game_exe_sha256
|
||||
and game_dll_sha256 == source_game_dll_sha256
|
||||
)
|
||||
game_profile = classify_game_profile(game_exe_sha256, game_dll_sha256)
|
||||
depot_state = _read_json_object(paths.native_depot_state)
|
||||
world_fix_helper = packaged_world_fix_helper()
|
||||
world_fix_helper_sha256 = _sha256_if_file(world_fix_helper)
|
||||
world_fix_helper_ready = (
|
||||
@@ -186,11 +200,13 @@ def inspect_login_environment(
|
||||
prefix_ready,
|
||||
directx_ready,
|
||||
latest_log,
|
||||
runtime_matches_managed_source,
|
||||
)
|
||||
return LoginDiagnosticReport(
|
||||
preflight_ok=(
|
||||
probe.reachable
|
||||
and game_profile in VERIFIED_GAME_PROFILES
|
||||
and runtime_matches_managed_source
|
||||
and selection is not None
|
||||
and prefix_ready
|
||||
and directx_ready
|
||||
@@ -208,7 +224,13 @@ def inspect_login_environment(
|
||||
game_exe_sha256=game_exe_sha256,
|
||||
game_dll=str(game_dll),
|
||||
game_dll_sha256=game_dll_sha256,
|
||||
source_game_exe_sha256=source_game_exe_sha256,
|
||||
source_game_dll_sha256=source_game_dll_sha256,
|
||||
runtime_matches_managed_source=runtime_matches_managed_source,
|
||||
game_profile=game_profile,
|
||||
depot_build=_integer_or_none(depot_state.get("build")),
|
||||
depot_version=_string_or_none(depot_state.get("version")),
|
||||
depot_completed_at=_string_or_none(depot_state.get("completed_at")),
|
||||
world_fix_helper=str(world_fix_helper),
|
||||
world_fix_helper_sha256=world_fix_helper_sha256,
|
||||
world_fix_helper_ready=world_fix_helper_ready,
|
||||
@@ -331,6 +353,7 @@ def _diagnostic_warnings(
|
||||
prefix_ready: bool,
|
||||
directx_ready: bool,
|
||||
latest_log: Path | None,
|
||||
runtime_matches_managed_source: bool,
|
||||
) -> tuple[str, ...]:
|
||||
warnings: list[str] = []
|
||||
if not probe.reachable:
|
||||
@@ -356,6 +379,11 @@ def _diagnostic_warnings(
|
||||
"The retired 0.5.8 disk-patched game.dll is active and can stall login; "
|
||||
"run prepare or launch with the current launcher to restore the publisher DLL."
|
||||
)
|
||||
if not runtime_matches_managed_source:
|
||||
warnings.append(
|
||||
"The runtime Game.exe/game.dll pair does not match the managed updater "
|
||||
"source; run prepare after update --repair before testing login again."
|
||||
)
|
||||
if runtime_error is not None:
|
||||
warnings.append(runtime_error)
|
||||
elif not prefix_ready:
|
||||
@@ -367,6 +395,24 @@ def _diagnostic_warnings(
|
||||
return tuple(warnings)
|
||||
|
||||
|
||||
def _read_json_object(path: Path) -> dict[str, object]:
|
||||
try:
|
||||
value = json.loads(path.read_text(encoding="utf-8"))
|
||||
except (OSError, UnicodeError, json.JSONDecodeError):
|
||||
return {}
|
||||
return value if isinstance(value, dict) else {}
|
||||
|
||||
|
||||
def _integer_or_none(value: object) -> int | None:
|
||||
if isinstance(value, bool) or not isinstance(value, int):
|
||||
return None
|
||||
return value
|
||||
|
||||
|
||||
def _string_or_none(value: object) -> str | None:
|
||||
return value if isinstance(value, str) else None
|
||||
|
||||
|
||||
def _sha256(path: Path) -> str:
|
||||
digest = hashlib.sha256()
|
||||
with path.open("rb") as handle:
|
||||
|
||||
Reference in New Issue
Block a user