Feature : GT7 "B" Telemetry format
Hi !
After a random contact message pointing out that if a "B" heartbeat was sent to GT7 another, longer, reply is retrieved. I did some investigations around it.
Turns out that the "IV" is not the same, but the base key is. After some short bruteforce (short as the new key was not that far) : 0xDEADBEAF is replaced by 0xDEADBEEF
The message has the same structure but adds 5 additional floats (316 bytes long in total).
Overall this takes place after the carcode :
public int CarCode;
public float WheelRotationRadians; public float FillerFloatFB; public float Sway; public float Heave; public float Surge;
I'm not sure yet what is FillerFloatFB, it's clearly direction related, maybe a lateral slip angle. This clearly is an extra bundle of "motion related" fields
I was hoping for a track id .... but ... no ... shame :D
Since lot of people got inspiration from your discoveries, including me I believe giving back my findings to you is the minimum I could do ;)
The only major struggle with that, just like Highlander there must be one. The first heartbeat wins (A/B), and the format can be only changed after the games stops sending telemetry after stopping sending the heartbeat for long enough. And since the crypto differs (length and key) cross compatibility across various software is tedious. I guess it has to be a choice.
I also tested other heartbeats (C ...) , this time it's a shorter message coming back I did not bothered trying to brute force it.
Very interesting research, thanks. I'll see if I can track down when this was introduced.
On another note (and for reference), A was seen sent by the tool mentioned initially here, at the time the games were just open to any sort of data which would act as a ping of sorts
If true then PDI expanded over it by making sure to restrict it to specific bytes
I found this in 1.44.
Try
~? You should get a packet of 344 bytes. Xor is 0x55FABB4F.
Yeah overall the person who brought my attention to it, probably have seen A, and probably thought what if it is a version ? I don't have the whole story but based on the message I got it was just trial and error. Overall the B package was unusable without the new salt. I almost gave up, but the curiosity took the lead. In simhub I was extracting already those accelerations but making the speed difference between two packets. But those new values are more stable
I found this in 1.44.
Try
~? You should get a packet of 344 bytes.
Wooo ... You're telling there is a third version??? Please tell me it has track id ...
And damn ... The key is right here ... No brute force needed ... Ok it's time to get my best to guess what is added!
I'll see if I can track down the precise version that extended it.
I'm not good at decompiling, can you guess from the code the layout (I guess not the fields names). Mapping only names, or the whole layout and name is another story :D assuming it's only floats or similar that's only 7 fields I already did more complex trial and errors :D that said I knew what I was looking for :D I had the names but not the layout.
From this point I guess it's really not worth any extra efforts on this B version and only the ~ version is worth investigating (for the conflicting reasons I was mentioning)
1.40 seems to had plans to implement it (switch table with 3 cases, but all three handle A)
1.42 added both B and ~ variants, so 25/01/2024.
I'll see if I can figure out anything. Once again thanks for reaching out 😄
I confirm ~ works :D Time to make some sense of it,
The green field is the last I did map previously (Surge), then comes brake, accelerator (probably filtered, as we already had it) there is a wide zeroed range, and a static 00 01 which is ... not ... my dreamt track id. and finally two floats which seems to be acceleration tied, and working around -1 / +1 (but can eventually go above) maybe some sort of torque ratio / power scale ?
So far I have:
public byte? Unk1 { get; set; } // Throttle? Filtered?
public byte? Unk2 { get; set; } // Brake? Filtered?
public byte? Unk3 { get; set; } // 2 = tomahawk? 4 = electric?
public byte? Unk4 { get; set; } // 1 on some electric cars? aero related?
public Vector4? Unk5 { get; set; } // confirmed vec4 through code, only the tomahawk seems to trigger these so far
public float? EnergyRecovery { get; set; } // confirmed
public float? Unk7 { get; set; } // ???
When Nicolas dreams about the TrackID is would like to add the following to the whishlist
- Time left within a time based race/session
- Session Type
- Position within a session
Regards, Joerg
Great finding indeed, thanks. I updated the GT7Proxy code to use this, and it works nicely. Less compute and more accurate. It is a win/win. https://github.com/vthinsel/GT7Proxy/commit/f4fe6ed46a2eb14b58d9361b5e57680aa5210348
Can anyone confirm whether Telemetry packet format B works in Online Sport Mode?
I just had a user tell me that since switching to this format telemetry is no longer there when entering Online Sport Mode, but for single player it works.
He reverted to my previous plugin before Packet B and he says its working online in sport mode.
hopefully one day we could have info like delta to front car and to the leader...
So far I have:
public byte? Unk1 { get; set; } // Throttle? Filtered? public byte? Unk2 { get; set; } // Brake? Filtered? public byte? Unk3 { get; set; } // 2 = tomahawk? 4 = electric? public byte? Unk4 { get; set; } // 1 on some electric cars? aero related? public Vector4? Unk5 { get; set; } // confirmed vec4 through code, only the tomahawk seems to trigger these so far public float? EnergyRecovery { get; set; } // confirmed public float? Unk7 { get; set; } // ???
I seem to be getting some strange behavior for the Skoda VGT (maybe the cars properties in the game are bugged?). It seems to be given 9 while everything else gets 2 or 4 for Unk3 and it's the only other car I've found that triggers the vector and gives values between ±0.15.
Some observations after playing around with the new data fields:
- 0x128 (WheelRotationRadians) it wasn't clear to me at first but this is the physical steering wheel angle in radians
- 0x12c (FillerFloatFB) I think this might be the steering wheel force feedback signal, it correlates quite well
- 0x13c (unk1) Unfiltered physical throttle input value (0-255 percent)
- Graphing this value along with the original throttle signal shows a clear difference correlating with the presence of TCS engagement in the original signal
- 0x13d (unk2) Actuated brake output value (0-255 percent).
- This field is only populated in live sessions
- Graphing this value along with the original brake signal shows a clear difference correlating with ABS engagement which is present in this new signal
- 0x13e (unk3) Possibly a bit field with decimal values of:
- 0 (Chaparral 2X McLaren VGT, TS050, ID.R, Valkyrie, FXX K, Porsche VGT, McLaren P1 GTR, Tomahawk GR.1, Hyundai VGT GR.1, Taycan, Ioniq, Model S, Model 3, Afeela, i3)
- 2 (Tomahawk, Ferrari VGT, Nissan Concept VGT, 918 Spyder, Italdesign)
- 4 (Jaguar VGT, Audi e-tron VGT, Mission X)
- 9 (Hyundai VGT and Skoda VGT)
- 0x13f (unk4) Possibly another bitfield but only seen with decimal 0 or 1
- Usually for vehicles with energy recovery
- The Chaparral 2X is an odd one as it is set to 1 but does not report values for energy recovery (0x150).
- 0x140-0x14c (unk5 Vector4) May be related to torque vectoring or energy recovery perhaps?
- Tomahawk populates the first two fields. In the description of the car it has some sort of pneumatic energy recovery/drive front to rear on each side which might explain why it only populates two fields.
- Hyundai VGT and Skoda VGT populate all 4 fields. The descriptions on both suggest torque vectoring is a feature however other vehicles like the Italdesign also mention this feature but don't populate the fields.
- 0x154 (unk7) not too sure what this is but definitely motion related
Also I've noticed that the new sway, heave and surge values are heavily aliased for replays compared to live data. In general I've also noticed aliasing on pretty much all of the replay data (only checked with heartbeat "~" so far so not sure if that is a factor).
- 0 (Chaparral 2X McLaren VGT, TS050, ID.R, Valkyrie, FXX K, Porsche VGT, McLaren P1 GTR, Tomahawk GR.1, Hyundai VGT GR.1, Taycan, Ioniq, Model S, Model 3, Afeela, i3)
- 2 (Tomahawk, Ferrari VGT, Nissan Concept VGT, 918 Spyder, Italdesign)
- 4 (Jaguar VGT, Audi e-tron VGT, Mission X)
- 9 (Hyundai VGT and Skoda VGT)
I've been trying to work out if there is some sort of drivetrain flag with these values, so far all I have is:
(1) Bit 0: Supports full per-wheel vectoring (2) Bit 1: Partial/2-wheel vectoring (some cars from testing dont send data even with this flag?) (4) Bit 2: ??? (Potentially full vectoring supportable and simulated but not broadcast?) (8) Bit 3: 4 Wheel-vectoring
It would seem like a pretty strange bit flag to have. And it doesn't explain why some cars, for example the ID.R, which is supposed to have 4 wheel torque vectoring IRL has a value of 0.
Hi @Nenkai, From this issue, it's clear that GT7 telemetry data uses Salsa20 encryption with XOR constants like 0xDEADBEEF or 0x55FABB4F (for version 1.42/1.44). Are the UGC server replay files encrypted with the same Salsa20 scheme as the telemetry packets, or is there a different encryption/key/IV approach for UGC replays? Thanks for any insights!
So far I have:
public byte? Unk1 { get; set; } // Throttle? Filtered? public byte? Unk2 { get; set; } // Brake? Filtered? public byte? Unk3 { get; set; } // 2 = tomahawk? 4 = electric? public byte? Unk4 { get; set; } // 1 on some electric cars? aero related? public Vector4? Unk5 { get; set; } // confirmed vec4 through code, only the tomahawk seems to trigger these so far public float? EnergyRecovery { get; set; } // confirmed public float? Unk7 { get; set; } // ???
Hi @Nenkai, From this issue, it's clear that GT7 telemetry data uses Salsa20 encryption with XOR constants like 0xDEADBEEF or 0x55FABB4F (for version 1.42/1.44). Are the UGC server replay files encrypted with the same Salsa20 scheme as the telemetry packets, or is there a different encryption/key/IV approach for UGC replays? Thanks for any insights!
For obvious reasons this isn't something I will address due to its sensitive nature (besides, this is off-topic in regards to this issue).