|
| 1 | +# G923 Xbox RPM LED Research - FFBArcadePlugin |
| 2 | + |
| 3 | +## Objectif |
| 4 | +Faire fonctionner les 5 LEDs RPM du Logitech G923 Xbox/PC (PID 0xC26E) avec FFBArcadePlugin, **avec G Hub qui tourne**. |
| 5 | + |
| 6 | +## Branche : `feature/g923-leds` (basee sur master) |
| 7 | + |
| 8 | +## Fichiers modifies |
| 9 | +- `Common Files/LogitechLED.h` - Classe LED controller |
| 10 | +- `Common Files/LogitechLED.cpp` - Implementation (actuellement v19) |
| 11 | +- `DllMain.cpp` - Ajout `g_bypassDIWrapper` pour bypass du wrapper DirectInput |
| 12 | + |
| 13 | +## Architecture du plugin |
| 14 | +- `dinput8.dll` wrapper qui hook DirectInput pour les jeux arcade (TeknoParrot) |
| 15 | +- Se charge via DLL_PROCESS_ATTACH, LED init dans `LogitechLED::Init()` |
| 16 | +- `SetLEDsFromPercent()` appele depuis la boucle FFB du jeu |
| 17 | +- Build : macOS dev -> GitHub Actions -> artifacts x86/x64 |
| 18 | + |
| 19 | +## Materiel |
| 20 | +- Logitech G923 Xbox/PC, VID=0x046D, PID=0xC26E |
| 21 | +- G Hub DOIT rester lance (sinon : pas de FFB, pas de boutons) |
| 22 | +- HID collections : |
| 23 | + - col02: UP=0xFF43, OUT=20, IN=20 (report 0x11) - **Legacy LED ici** |
| 24 | + - col03: UP=0xFF43, OUT=64, IN=64 (report 0x12) - HID++ 2.0 |
| 25 | + - mi_01: UP=0xFFFD, OUT=64, IN=64 |
| 26 | + - gamepad: UP=0x0001, IN=11, OUT=0 |
| 27 | + |
| 28 | +## Drivers kernel G Hub (la cause du blocage) |
| 29 | +- `logi_joy_xlcore.sys` - Translation core |
| 30 | +- `logi_joy_bus_enum.sys` - Bus enumerator |
| 31 | +- `logi_joy_vir_hid.sys` - Virtual HID |
| 32 | +- **Interceptent TOUS les HID output reports** : WriteFile retourne OK mais les donnees ne touchent jamais le bus USB |
| 33 | + |
| 34 | +## Approches testees et resultats |
| 35 | + |
| 36 | +### 1. Direct HID - Legacy [F8 12 mask] (v1-v6) |
| 37 | +- Format : `[reportId F8 12 ledMask]` sur col02 (20 bytes, report 0x11) |
| 38 | +- WriteFile retourne OK, mais **LEDs ne s'allument pas** |
| 39 | +- Confirme par USBlyzer : **zero OUT transfers sur le bus USB** meme pendant le FFB |
| 40 | +- Les drivers kernel mangent tout |
| 41 | + |
| 42 | +### 2. HID++ 2.0 Feature Discovery (v3-v4) |
| 43 | +- Fonctionne sur col03 (64-byte, report 0x12, device index 0xFF) |
| 44 | +- 21 features enumerees dont 0x807A (suspect LED) |
| 45 | +- Commandes acceptees mais aucun changement LED |
| 46 | +- Meme probleme : drivers kernel interceptent |
| 47 | + |
| 48 | +### 3. LED SDK - sdk_legacy_led_x86.dll (v5-v7) |
| 49 | +- Emplacement : `C:\Program Files\LGHUB\sdks\sdk_legacy_led_x86.dll` |
| 50 | +- 33 exports, version 75.71.76 |
| 51 | +- LogiLedInit() -> OK (se connecte a G Hub) |
| 52 | +- **Pour clavier/souris UNIQUEMENT, pas pour volant** |
| 53 | +- devType=0x8 zones 0-1 retournent OK mais rien ne s'allume |
| 54 | +- SetLightingForTargetZone(0x8, 0, ...) = clavier/souris, pas volant |
| 55 | + |
| 56 | +### 4. Steering Wheel SDK - LogitechSteeringWheelEnginesWrapper.dll (v5-v9) |
| 57 | +- SDK public v8.75.30 (2018), telecharge depuis Logitech |
| 58 | +- 50 exports dont LogiPlayLeds, LogiPlayLedsDInput |
| 59 | +- LogiSteeringInitializeWithWindow(false, desktop) -> **OK** |
| 60 | +- LogiIsConnected(0) -> **NO** (SDK ne connait pas PID 0xC26E, G923 sorti en 2020) |
| 61 | +- Le SDK ne connait que jusqu'au G920 (model 27) |
| 62 | + |
| 63 | +### 5. G Hub Internal Steering SDK (v7) |
| 64 | +- Cherche `sdk_legacy_steering_wheel_x86.dll` dans `C:\Program Files\LGHUB\` |
| 65 | +- **N'EXISTE PAS** sur la machine de test |
| 66 | +- Seuls `sdk_legacy_led_x64.dll` et `sdk_legacy_led_x86.dll` dans le dossier sdks |
| 67 | + |
| 68 | +### 6. Bypass DirectInput Wrapper (v8) |
| 69 | +- Notre dinput8.dll wrapper empeche le SDK d'enumerer les devices |
| 70 | +- Ajout `g_bypassDIWrapper` flag dans DllMain.cpp |
| 71 | +- Quand le SDK appelle DirectInput8Create, on retourne l'interface reelle |
| 72 | +- **Resultat : LogiIsConnected(0) toujours NO** |
| 73 | +- Le probleme n'est PAS le wrapper, c'est le SDK qui ne connait pas le PID |
| 74 | + |
| 75 | +### 7. LogiPlayLedsDInput Fallback (v9 - PAS ENCORE TESTE) |
| 76 | +- Charge le vrai dinput8.dll systeme depuis System32 |
| 77 | +- Cree un device DirectInput reel pour le G923 |
| 78 | +- Passe le device a LogiPlayLedsDInput() qui bypass la detection interne |
| 79 | +- **Build v9 pret, non teste** (user doit reboot) |
| 80 | + |
| 81 | +### 8. USB Sniffing |
| 82 | +- **USBlyzer** : fonctionne avec G Hub, mais capture au niveau HID (au-dessus des drivers) |
| 83 | + - Voit uniquement des IN (device -> host), zero OUT |
| 84 | + - Confirme : les drivers kernel interceptent TOUS les writes |
| 85 | + - PnP Remove Device quand on capture sur le device specifique -> capturer sur le Port/USB composite |
| 86 | +- **USBPcap + Wireshark** : pas reussi a configurer (Wireshark ne voit pas USBPcap) |
| 87 | +- **Conclusion sniffing** : les drivers kernel redirigent le trafic OUT par un chemin interne invisible aux sniffers HID-level |
| 88 | + |
| 89 | +## Decouverte cle : comment les jeux officiels font |
| 90 | +- Les jeux (Forza, F1, etc.) utilisent le meme `LogitechSteeringWheelEnginesWrapper.dll` |
| 91 | +- MAIS une **version plus recente** fournie par Logitech aux studios (pas la version publique) |
| 92 | +- Cette version connait le G923 PID -> LogiIsConnected retourne YES -> LogiPlayLeds fonctionne |
| 93 | +- Le SDK communique avec lghub_agent.exe via IPC, G Hub controle les LEDs via ses drivers kernel |
| 94 | +- Un user sur le forum Fanaleds confirme que le SteeringWheelSDKDemo fonctionne avec G923 |
| 95 | + |
| 96 | +### 9. Reverse-engineering du Wrapper SDK (v10-v11) - PERCEE MAJEURE |
| 97 | +- Analyse binaire de `LogitechSteeringWheelEnginesWrapper.dll` (13 KB, thin wrapper) |
| 98 | +- **Aucun PID dans le wrapper** - c'est juste un forwarder |
| 99 | +- Imports : `RegOpenKeyExW`, `RegQueryValueExW`, `LoadLibraryW`, `GetProcAddress` |
| 100 | +- **Cle registre decouverte** (wide string UTF-16 dans le binaire) : |
| 101 | + `SOFTWARE\Classes\CLSID\{63BD165D-1584-4E75-AB56-08330350545F}\ServerBinary` |
| 102 | +- Le wrapper lit cette cle pour trouver le VRAI DLL engines installe par G Hub |
| 103 | + |
| 104 | +### 10. Decouverte du vrai moteur SDK v9.1.0 installe par G Hub |
| 105 | +- **Cle registre x64** : `HKLM\SOFTWARE\Classes\CLSID\{63BD165D-...}\ServerBinary` |
| 106 | + -> `C:\Program Files\Logi\wheel_sdk\9_1_0\logi_steering_wheel_x64.dll` (93 KB) |
| 107 | +- **Cle registre x86** (WOW6432Node) : |
| 108 | + -> `C:\Program Files\Logi\wheel_sdk\9_1_0\logi_steering_wheel_x86.dll` (78 KB) |
| 109 | +- Date : 10/02/2026 - installe/mis a jour par G Hub |
| 110 | +- **C'est le vrai moteur** que le wrapper charge via LoadLibrary |
| 111 | +- Version 9.1.0 vs SDK public 8.75.30 = bien plus recent, devrait connaitre le G923 |
| 112 | +- Script `tools/scan_pids.ps1` cree pour scanner les PIDs dans ce DLL |
| 113 | +- Copie du DLL dans `tools/logi_steering_wheel_x86.dll` pour analyse locale |
| 114 | + |
| 115 | +### 11. Scan PIDs du moteur v9.1.0 - CONFIRME |
| 116 | +- Resultat du scan sur `logi_steering_wheel_x86.dll` (78,488 bytes) : |
| 117 | + ``` |
| 118 | + 0xC298 (DFP) : PRESENT (2x at 0x00EC3E, 0x0126A0) |
| 119 | + 0xC299 (G25) : PRESENT (1x at 0x00EC1A) |
| 120 | + 0xC29A (DFGT) : PRESENT (1x at 0x00EC0E) |
| 121 | + 0xC29B (G27) : PRESENT (1x at 0x00EC02) |
| 122 | + 0xC24F (G29) : PRESENT (2x at 0x00EC7A, 0x010DAE) |
| 123 | + 0xC260 (G920) : ABSENT |
| 124 | + 0xC262 (G920 alt) : PRESENT (1x at 0x00EC86) |
| 125 | + 0xC266 (G923 PS) : PRESENT (1x at 0x00EC92) |
| 126 | + 0xC26E (G923 Xbox) : PRESENT (2x at 0x009D9F, 0x00EC9E) <<< |
| 127 | + ``` |
| 128 | +- **G923 Xbox est PRESENT** -> le moteur v9.1.0 connait le G923 |
| 129 | +- **G920 standard (0xC260) est ABSENT** -> Logitech a change la table de PIDs |
| 130 | +- **Conclusion** : le probleme est le wrapper v8.75.30, pas le moteur |
| 131 | + |
| 132 | +### 12. Chargement direct du moteur v9.1.0 (v12-v12b) |
| 133 | +- Bypass du wrapper : charge `logi_steering_wheel_x86.dll` directement via LoadLibrary |
| 134 | +- Chemin lu depuis registre : `HKLM\SOFTWARE\WOW6432Node\Classes\CLSID\{63BD165D-...}\ServerBinary` |
| 135 | +- Exports resolus via GetProcAddress : LogiSteeringInitialize, LogiIsConnected, LogiPlayLeds, etc. |
| 136 | +- v12b : ajout CoInitializeEx, polling etendu (5x 500ms), multi-index (0-3) |
| 137 | +- **Resultat : LogiSteeringInitialize OK, mais LogiIsConnected(0..3) -> toujours NO** |
| 138 | +- Le moteur v9.1.0 utilise DirectInput en interne pour detecter les volants |
| 139 | + |
| 140 | +### 13. Scan exhaustif du LED SDK (v13) |
| 141 | +- Test de TOUS les device types (0x0 a 0xE) avec TOUTES les zones (0-5) |
| 142 | +- Confirme : LED SDK ne supporte que clavier/souris/headset |
| 143 | +- Aucun device type ne correspond au volant |
| 144 | +- **LED SDK = impasse definitive pour les volants** |
| 145 | + |
| 146 | +### 14. Integration WebSocket G Hub (v14-v14b) |
| 147 | +- G Hub expose un WebSocket IPC sur `ws://127.0.0.1:9010` (protocole JSON) |
| 148 | +- API : `{msgId, verb, path, payload}` (GET/SET/SUBSCRIBE) |
| 149 | +- Implementation WinHTTP dans le plugin C++ (WinHttpOpen, WinHttpWebSocketSend/Receive) |
| 150 | +- `/devices/list` retourne ~22KB de JSON avec tous les devices G Hub |
| 151 | +- G923 identifie : `id: "dev00000004"`, PID 49774 (0xC26E), deviceType `STEERING_WHEEL`, model `g923_xbox` |
| 152 | +- v14b : corrige le parsing deviceId (recherche backward depuis STEERING_WHEEL), activation ACTION avant WHEEL, timeouts WinHTTP |
| 153 | +- **Bug v14b** : JSON G Hub contient des espaces (`"deviceType": "STEERING_WHEEL"`) mais le code cherchait sans espaces |
| 154 | + |
| 155 | +### 15. Fix parsing JSON + activation WHEEL (v15) |
| 156 | +- Corrige la recherche : cherche `STEERING_WHEEL` en texte brut + `"dev0` pour le deviceId |
| 157 | +- STEERING_WHEEL trouve a offset 790, deviceId `dev00000004` correctement parse |
| 158 | +- **WHEEL activation : toujours INVALID_ARG** ("Invalid integration GUID") |
| 159 | +- Tous les endpoints HID++ via WebSocket : NO_SUCH_PATH |
| 160 | +- Tous les endpoints LED/RPM : NO_SUCH_PATH |
| 161 | + |
| 162 | +### 16. Chargement du vrai dinput8.dll systeme (v16) |
| 163 | +- Decouverte : `GetModuleHandleA("dinput8.dll")` retourne NOTRE wrapper (puisque nous SOMMES dinput8.dll) |
| 164 | +- Fix : `GetSystemDirectoryA` + `LoadLibraryA("C:\Windows\system32\dinput8.dll")` pour le vrai DLL systeme |
| 165 | +- DLL systeme charge a 0x685B0000 (adresse differente = vrai DLL) |
| 166 | +- DirectInput8Create reussit |
| 167 | +- **ZERO devices enumeres** : ni GAMECTRL ni ALL ne retournent de devices |
| 168 | +- **DECOUVERTE CRUCIALE** : le G923 Xbox est un device **XInput/GIP**, pas DirectInput |
| 169 | +- Windows 8+ cache les devices XInput de l'enumeration DirectInput |
| 170 | +- Le moteur SDK v9.1.0 utilise DirectInput pour detecter -> ne peut PAS voir le G923 Xbox |
| 171 | + |
| 172 | +### 17. Analyse de la reponse d'enregistrement (v17) |
| 173 | +- Buffer de log etendu de 300 a 800 chars pour voir la reponse complete |
| 174 | +- Reponse d'enregistrement (465 bytes) : **AUCUN champ integrationGuid** |
| 175 | +- `"integrationType": "INVALID_TYPE"` - l'enregistrement seul ne cree pas de GUID |
| 176 | +- Le GUID n'est cree qu'a l'activation |
| 177 | + |
| 178 | +### 18. Activation WHEEL - percee partielle (v18) |
| 179 | +- Strategie : ACTION d'abord pour obtenir un GUID, puis WHEEL avec ce GUID |
| 180 | +- **WHEEL avec integrationGuid dans le payload** : `INVALID_MESSAGE_RECEIVED` (champ non accepte) |
| 181 | +- **WHEEL sans GUID sur `ffb_arcade`** : `INVALID_ARG` (identifier deja consomme par ACTION) |
| 182 | +- **Register `ffb_wheel_sdk` + activate WHEEL : SUCCESS !** -> instanceGuid + integrationGuid |
| 183 | +- **Decouverte** : chaque sdkType a besoin de son PROPRE integrationIdentifier |
| 184 | +- Mais tous les endpoints LED/RPM : toujours NO_SUCH_PATH |
| 185 | +- G Hub ne fournit aucune API WebSocket pour controler les LEDs du volant |
| 186 | + |
| 187 | +### 19. WebSocket keep-alive pendant le polling SDK (v19) |
| 188 | +- Hypothese : l'activation WHEEL est session-based, fermer le WebSocket tue la session |
| 189 | +- WebSocket garde ouvert (handles statiques : g_wsSession, g_wsConnect, g_wsHandle) |
| 190 | +- Enregistrement simplifie : `ffb_wheel` + WHEEL uniquement |
| 191 | +- **WHEEL activation : SUCCESS, WebSocket reste ouvert** |
| 192 | +- Steering SDK polling : LogiIsConnected(0..3) -> **toujours NO** |
| 193 | +- DirectInput : toujours zero devices |
| 194 | +- **Conclusion** : garder le WebSocket actif ne aide pas le SDK a detecter le G923 |
| 195 | + |
| 196 | +## Diagnostic final |
| 197 | + |
| 198 | +### Cause racine identifiee |
| 199 | +Le G923 Xbox/PC (PID 0xC26E) est un device **XInput/GIP** (Gaming Input Protocol), PAS un device DirectInput. Windows 8+ cache systematiquement les devices XInput de l'enumeration DirectInput (`IDirectInput8::EnumDevices` ne les retourne jamais). |
| 200 | + |
| 201 | +Le moteur SDK Logitech v9.1.0 (`logi_steering_wheel_x86.dll`) utilise DirectInput en interne pour detecter les volants connectes. Meme si le PID du G923 est present dans le binaire, le SDK ne peut jamais voir le device car Windows ne le liste pas en DirectInput. |
| 202 | + |
| 203 | +### Chaine de blocage |
| 204 | +``` |
| 205 | +G923 Xbox = device XInput/GIP |
| 206 | + -> Invisible pour DirectInput (filtre Windows) |
| 207 | + -> SDK v9.1.0 utilise DirectInput pour la detection |
| 208 | + -> LogiIsConnected() retourne toujours NO |
| 209 | + -> LogiPlayLeds() ne peut pas fonctionner |
| 210 | +``` |
| 211 | + |
| 212 | +### Comment les jeux officiels font (hypothese mise a jour) |
| 213 | +Les jeux (Forza, F1) utilisent probablement : |
| 214 | +- Soit une version speciale du SDK qui detecte via **Windows.Gaming.Input (WGI)** au lieu de DirectInput |
| 215 | +- Soit un IPC direct avec lghub_agent.exe que le SDK public ne supporte pas |
| 216 | +- Le SDK v9.1.0 installe par G Hub est peut-etre utilise UNIQUEMENT par les jeux PS (G29, G923 PS qui sont bien DirectInput) |
| 217 | + |
| 218 | +### Toutes les approches epuisees |
| 219 | +| # | Approche | Resultat | |
| 220 | +|---|----------|----------| |
| 221 | +| 1 | Direct HID Legacy [F8 12] | Drivers kernel interceptent tout | |
| 222 | +| 2 | HID++ 2.0 Feature Discovery | Drivers kernel interceptent tout | |
| 223 | +| 3 | LED SDK (sdk_legacy_led) | Clavier/souris uniquement | |
| 224 | +| 4 | Steering SDK v8.75.30 (wrapper) | Ne connait pas le G923 | |
| 225 | +| 5 | G Hub Internal Steering SDK | N'existe pas | |
| 226 | +| 6 | Bypass DirectInput wrapper | SDK ne voit toujours pas le G923 | |
| 227 | +| 7 | LogiPlayLedsDInput | G923 invisible en DirectInput | |
| 228 | +| 8 | USB Sniffing | Confirme : drivers interceptent OUT | |
| 229 | +| 9 | Reverse wrapper -> moteur v9.1.0 | PID present mais detection via DI | |
| 230 | +| 10 | Chargement direct moteur v9.1.0 | IsConnected toujours NO | |
| 231 | +| 11 | Scan exhaustif LED SDK | Impasse definitive | |
| 232 | +| 12 | WebSocket G Hub (register/activate) | Pas d'API LED pour volant | |
| 233 | +| 13 | System dinput8.dll pour enum | Zero devices (XInput) | |
| 234 | +| 14 | WebSocket keep-alive + SDK | SDK toujours aveugle | |
| 235 | + |
| 236 | +## Pistes restantes (non testees) |
| 237 | + |
| 238 | +### A. Windows.Gaming.Input (WGI) |
| 239 | +- API moderne Microsoft pour les controllers Xbox/GIP |
| 240 | +- Inclut `RacingWheel` class avec support LED potentiel |
| 241 | +- Necessite C++/WinRT ou COM, compile comme UWP/desktop bridge |
| 242 | +- **Piste la plus prometteuse** car c'est la seule API qui "voit" le G923 Xbox |
| 243 | + |
| 244 | +### B. Kill lghub_agent.exe + HID direct |
| 245 | +- Tester si les drivers kernel laissent passer les HID writes quand l'agent est arrete |
| 246 | +- Risque : perte du FFB si G Hub est necessaire pour ca aussi |
| 247 | +- Test rapide : `taskkill /f /im lghub_agent.exe` puis envoyer [F8 12 mask] |
| 248 | + |
| 249 | +### C. Reverse-engineer l'IPC G Hub |
| 250 | +- G Hub WebSocket sur ws://localhost:9010 - explore mais pas d'endpoints LED trouves |
| 251 | +- Projet GitHub : LGSTrayBattery_GHUB |
| 252 | +- Extraire `app.asar` de G Hub pour trouver des endpoints caches |
| 253 | + |
| 254 | +### D. API Monitor sur lghub_agent.exe |
| 255 | +- Hook WriteFile/DeviceIoControl pour voir ce que G Hub envoie reellement |
| 256 | +- Fonctionne au user-mode, pas de driver |
| 257 | +- http://www.rohitab.com/apimonitor |
| 258 | + |
| 259 | +## Statut : EN PAUSE |
| 260 | +Recherche suspendue apres 19 iterations. La cause racine (XInput vs DirectInput) est un blocage fondamental au niveau OS/driver qui ne peut pas etre contourne par du code user-mode classique. |
| 261 | + |
| 262 | +## DLLs sur la machine de test |
| 263 | +- `C:\Program Files\LGHUB\sdks\sdk_legacy_led_x86.dll` (3.3 MB) |
| 264 | +- `C:\Program Files\LGHUB\sdks\sdk_legacy_led_x64.dll` (4.0 MB) |
| 265 | +- `LogitechSteeringWheelEnginesWrapper.dll` (dans le dossier du jeu, SDK v8.75.30) |
| 266 | +- `C:\Program Files\Logi\wheel_sdk\9_1_0\logi_steering_wheel_x86.dll` (78 KB) - **VRAI moteur G Hub** |
| 267 | +- `C:\Program Files\Logi\wheel_sdk\9_1_0\logi_steering_wheel_x64.dll` (93 KB) |
| 268 | + |
| 269 | +## Commits (du plus ancien au plus recent) |
| 270 | +``` |
| 271 | +9617965 feat: add Steering Wheel SDK support (LogiPlayLeds) |
| 272 | +2b6a87d fix: defer steering SDK init, try multiple window handles |
| 273 | +bcd2890 feat: enumerate all LED SDK exports, scan wider device types |
| 274 | +1feacc3 fix: TrySteeringSDK returns false when wheel not detected |
| 275 | +4befd8b feat: try G Hub internal steering wheel SDK (sdk_legacy_steering_wheel) |
| 276 | +2e3b63c feat: activate LED SDK devType=0x8 at runtime for G923 |
| 277 | +a72b6ce fix: bypass dinput8 wrapper for Logitech SDK enumeration |
| 278 | +540a7dd feat: fallback to LogiPlayLedsDInput when SDK can't detect G923 |
| 279 | +43eb3e6 fix: use LPVOID for LogiPlayLedsDInput to fix ANSI/Unicode build |
| 280 | +4f1caa4 chore: bump version to v9 for tracking |
| 281 | +a2535be fix: use proper __stdcall callback for DirectInput EnumDevices |
| 282 | +e7d58dc feat: v11 - add COM init, blind PlayLeds, NULL DInput, HMODULE diagnostics |
| 283 | +e47d493 chore: add PID scanner PowerShell script for Windows |
| 284 | +4e8975f fix: PowerShell 5.1 compatibility for scan script |
| 285 | +5b60d0a feat: v12 - load engine DLL directly via registry, bypass old wrapper |
| 286 | +1a88a98 feat: v12b - add COM init, extended polling, multi-index detection diagnostics |
| 287 | +379940e feat: v13 - exhaustive LED SDK scan (all device types + zones) |
| 288 | +d694505 feat: add G Hub WebSocket explorer script for LED discovery |
| 289 | +b86fd65 feat: add HTML WebSocket explorer (no PowerShell needed) |
| 290 | +b479fe4 feat: v14 - register with G Hub via WebSocket before engine init |
| 291 | +9ff3e4c fix: v14b - fix deviceId parsing, activate ACTION before WHEEL, add timeouts |
| 292 | +5daf31f feat: v15 - fix JSON space parsing, WHEEL-first activation, HID++ via WebSocket |
| 293 | +17efec5 fix: v16 - load real system dinput8.dll instead of our wrapper for DI enumeration |
| 294 | +f902248 feat: v17 - extract integrationGuid from registration, pass in WHEEL activation |
| 295 | +c00dcb9 feat: v18 - ACTION-first to get GUID, retry WHEEL with GUID, try integrationType=SDK |
| 296 | +638f064 feat: v19 - keep WebSocket alive during steering SDK polling, dedicated WHEEL registration |
| 297 | +fc36439 fix: move static WS handles before Close() to fix compilation |
| 298 | +``` |
0 commit comments