diff --git a/src/PSLauncher.Core/Health/OpenVR/OpenVrService.cs b/src/PSLauncher.Core/Health/OpenVR/OpenVrService.cs index 2872132..0eea724 100644 --- a/src/PSLauncher.Core/Health/OpenVR/OpenVrService.cs +++ b/src/PSLauncher.Core/Health/OpenVR/OpenVrService.cs @@ -27,6 +27,7 @@ public sealed class OpenVrService : IOpenVrService, IDisposable private bool _resolverEnsured; private bool _initAttempted; + private VrRuntimeState _lastLoggedState = (VrRuntimeState)(-99); // sentinelle « jamais loggé » private uint _initToken; private IntPtr _vrSystemVTable = IntPtr.Zero; @@ -50,6 +51,7 @@ public sealed class OpenVrService : IOpenVrService, IDisposable lock (_lock) { var state = EnsureReady(); + LogStateTransition(state); var label = ResolveLabel(deviceAlias); if (state != VrRuntimeState.Ready) { @@ -317,6 +319,28 @@ public sealed class OpenVrService : IOpenVrService, IDisposable catch { return null; } } + /// + /// Log au niveau INFO la première occurrence d'un état + chaque transition. + /// Évite de spammer (un check s'exécute toutes les 5 s, on aurait 700 messages + /// par heure si on loggait à chaque tick) tout en laissant une trace claire + /// dans le journal au cas où ça re-crasherait — la dernière ligne avant le + /// silence de Serilog dirait par exemple « OpenVR state: HmdAbsent ». + /// + private void LogStateTransition(VrRuntimeState newState) + { + if (newState == _lastLoggedState) return; + _lastLoggedState = newState; + var detail = newState switch + { + VrRuntimeState.RuntimeMissing => "openvr_api.dll introuvable (SteamVR pas installé)", + VrRuntimeState.HmdAbsent => "vrserver.exe pas lancé ou aucun HMD branché", + VrRuntimeState.InitFailed => "VR_InitInternal2 a échoué", + VrRuntimeState.Ready => "OK, vtable IVRSystem_022 bindée", + _ => "?", + }; + _logger.LogInformation("OpenVR state: {State} ({Detail})", newState, detail); + } + /// /// vrserver.exe est le process central de SteamVR ; sa présence garantit qu'on /// peut init OpenVR sans déclencher de chargement de drivers risqué. Cache de