Skip to content

Commit ff1c0f0

Browse files
committed
this might work, let's see
1 parent 1d8c8e5 commit ff1c0f0

File tree

5 files changed

+139
-52
lines changed

5 files changed

+139
-52
lines changed

telemetry.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ type accTelemetry struct {
5252
udpConnection *net.UDPConn
5353

5454
realtimeCarUpdate *RealtimeCarUpdate
55-
realtimeUpdate *RealtimeUpdate
5655
}
5756

5857
type accDataHolder[T AccGraphic | AccPhysics | AccStatic] struct {
@@ -158,16 +157,11 @@ func (t *accTelemetry) PhysicsPointer() *AccPhysics {
158157
return nil
159158
}
160159

161-
// reads from UDP
162-
// returns current state of RealtimeUpdate
163-
// by it's async nature, it's just best effort these data are latest and correct
164-
func (t *accTelemetry) RealtimeUpdate() *RealtimeUpdate {
165-
return t.realtimeUpdate
166-
}
167-
168160
// reads from UDP
169161
// returns current state of RealtimeCarUpdate
170162
// by it's async nature, it's just best effort these data are latest and correct
163+
// it returns pointer to same struct so it will change over time. It's up to the client to handle this and be careful.
164+
// it can even be in the middle of updating the struct.
171165
func (t *accTelemetry) RealtimeCarUpdate() *RealtimeCarUpdate {
172166
return t.realtimeCarUpdate
173167
}

telemetry_udp.go

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ func (telemetry *accTelemetry) connect() error {
6868
}
6969
} else {
7070
fmt.Println("UDP Connected")
71-
telemetry.realtimeCarUpdate = &RealtimeCarUpdate{}
72-
telemetry.realtimeUpdate = &RealtimeUpdate{}
71+
telemetry.realtimeCarUpdate = &RealtimeCarUpdate{
72+
BestSessionLap: &LapInfo{Splits: [8]int32{}},
73+
LastLap: &LapInfo{Splits: [8]int32{}},
74+
CurrentLap: &LapInfo{Splits: [8]int32{}},
75+
}
7376
}
7477

7578
connectionResult, err := readConnectionResult(bytes.NewBuffer(inBuffer))
@@ -125,19 +128,6 @@ func (telemetry *accTelemetry) createConnectMessage() ([]byte, error) {
125128
return outBuffer.Bytes(), nil
126129
}
127130

128-
func writeString(buffer *bytes.Buffer, str string) error {
129-
lengthBytes := make([]byte, 2)
130-
binary.LittleEndian.PutUint16(lengthBytes, uint16(len(str)))
131-
132-
var writeErr error
133-
_, writeErr = buffer.Write(lengthBytes)
134-
_, writeErr = buffer.Write([]byte(str))
135-
if writeErr != nil {
136-
return fmt.Errorf("failed to write string '%s' to byte buffer: %w", str, writeErr)
137-
}
138-
return nil
139-
}
140-
141131
// response format:
142132
// 1 byte - message type
143133
// 4 bytes - int32 connectionId
@@ -157,17 +147,10 @@ func readConnectionResult(payload *bytes.Buffer) (*connectionResult, error) {
157147
}
158148

159149
// read connectionId
160-
connectionIdBytes := make([]byte, 4)
161-
_, err = payload.Read(connectionIdBytes)
150+
connectionId, err := readInt32(payload)
162151
if err != nil {
163152
return nil, fmt.Errorf("failed to read connectionId: %w", err)
164153
}
165-
166-
var connectionId int32
167-
err = binary.Read(bytes.NewReader(connectionIdBytes), binary.LittleEndian, &connectionId)
168-
if err != nil {
169-
return nil, fmt.Errorf("failed to convert connectionId: %w", err)
170-
}
171154
result.connectionId = connectionId
172155

173156
// read success
@@ -185,17 +168,12 @@ func readConnectionResult(payload *bytes.Buffer) (*connectionResult, error) {
185168
result.readOnly = readonly == 0
186169

187170
// read error
188-
errorLengthBytes := make([]byte, 2)
189-
_, err = payload.Read(errorLengthBytes)
190-
if err != nil {
191-
return nil, fmt.Errorf("failed to read error length: %w", err)
192-
}
193-
var errorLength uint16
194-
err = binary.Read(bytes.NewReader(errorLengthBytes), binary.LittleEndian, &errorLength)
171+
errorLength, err := readUint16(payload)
195172
if err != nil {
196-
return nil, fmt.Errorf("failed to convert errorLength: %w", err)
173+
return nil, fmt.Errorf("failed to read error message length: %w", err)
197174
}
198175

176+
//TODO: handle reading error message if this is non zero
199177
if errorLength > 0 {
200178
result.errorMessage = "some error"
201179
}
@@ -210,12 +188,10 @@ func (t *accTelemetry) readMessage(payload []byte) error {
210188
return fmt.Errorf("failed to read message type: %w", err)
211189
}
212190
switch messageType {
213-
case REALTIME_UPDATE:
214-
updateRealtimeUpdate(buffer, t.realtimeUpdate)
215191
case REALTIME_CAR_UPDATE:
216192
updateRealtimeCarUpdate(buffer, t.realtimeCarUpdate)
217193
default:
218-
return fmt.Errorf("received unexpected message type: '%d' => %+v", messageType, payload)
194+
return fmt.Errorf("we don't currently support this type of message: '%d' => %+v", messageType, payload)
219195
}
220196

221197
return nil

type_realtimecarupdate.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,70 @@ package acctelemetry
33
import "bytes"
44

55
type RealtimeCarUpdate struct {
6+
CarIndex uint16
7+
DriverIndex uint16
8+
DriverCount byte
9+
Gear byte
10+
WorldPosX float32
11+
WorldPosY float32
12+
Yaw float32
13+
CarLocation byte // 0=NONE, 1=TRACK, 2=PITLANE, 3=PITENTRY, 4=PITEXIT
14+
Kmh uint16
15+
Position uint16
16+
CupPosition uint16
17+
TrackPosition uint16
18+
TrackRelativePosition float32
19+
Laps uint16
20+
Delta int32
21+
BestSessionLap *LapInfo
22+
LastLap *LapInfo
23+
CurrentLap *LapInfo
24+
}
25+
26+
type LapInfo struct {
27+
LaptimeMs int32
28+
CarIndex uint16
29+
DriverIndex uint16
30+
SplitCount byte
31+
Splits [8]int32 // let's assume no track will have more than 8 splits (all should have 3...)
32+
IsInvalid byte
33+
InValidForBest byte
34+
IsOutlap byte
35+
IsInlaop byte
636
}
737

838
func updateRealtimeCarUpdate(payload *bytes.Buffer, toUpdate *RealtimeCarUpdate) {
39+
toUpdate.CarIndex, _ = readUint16(payload)
40+
toUpdate.DriverIndex, _ = readUint16(payload)
41+
toUpdate.DriverCount, _ = payload.ReadByte()
42+
toUpdate.Gear, _ = payload.ReadByte()
43+
toUpdate.WorldPosX, _ = readFloat32(payload)
44+
toUpdate.WorldPosY, _ = readFloat32(payload)
45+
toUpdate.Yaw, _ = readFloat32(payload)
46+
toUpdate.CarLocation, _ = payload.ReadByte()
47+
toUpdate.Kmh, _ = readUint16(payload)
48+
toUpdate.Position, _ = readUint16(payload)
49+
toUpdate.CupPosition, _ = readUint16(payload)
50+
toUpdate.TrackPosition, _ = readUint16(payload)
51+
toUpdate.TrackRelativePosition, _ = readFloat32(payload)
52+
toUpdate.Laps, _ = readUint16(payload)
53+
toUpdate.Delta, _ = readInt32(payload)
54+
toUpdate.Kmh, _ = readUint16(payload)
55+
updateLap(payload, toUpdate.BestSessionLap)
56+
updateLap(payload, toUpdate.LastLap)
57+
updateLap(payload, toUpdate.CurrentLap)
58+
}
959

60+
func updateLap(payload *bytes.Buffer, lap *LapInfo) {
61+
lap.LaptimeMs, _ = readInt32(payload)
62+
lap.CarIndex, _ = readUint16(payload)
63+
lap.DriverIndex, _ = readUint16(payload)
64+
lap.SplitCount, _ = payload.ReadByte()
65+
for i := 0; i < int(lap.SplitCount); i++ {
66+
lap.Splits[i], _ = readInt32(payload)
67+
}
68+
lap.IsInvalid, _ = payload.ReadByte()
69+
lap.InValidForBest, _ = payload.ReadByte()
70+
lap.IsOutlap, _ = payload.ReadByte()
71+
lap.IsInlaop, _ = payload.ReadByte()
1072
}

type_realtimeupdate.go

Lines changed: 0 additions & 10 deletions
This file was deleted.

util_bytes.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package acctelemetry
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"fmt"
7+
)
8+
9+
func writeString(buffer *bytes.Buffer, str string) error {
10+
lengthBytes := make([]byte, 2)
11+
binary.LittleEndian.PutUint16(lengthBytes, uint16(len(str)))
12+
13+
var writeErr error
14+
_, writeErr = buffer.Write(lengthBytes)
15+
_, writeErr = buffer.Write([]byte(str))
16+
if writeErr != nil {
17+
return fmt.Errorf("failed to write string '%s' to byte buffer: %w", str, writeErr)
18+
}
19+
return nil
20+
}
21+
22+
func readInt32(buffer *bytes.Buffer) (int32, error) {
23+
readBytes := make([]byte, 4)
24+
_, err := buffer.Read(readBytes)
25+
if err != nil {
26+
return 0, fmt.Errorf("failed to read int32: %w", err)
27+
}
28+
29+
var result int32
30+
err = binary.Read(bytes.NewReader(readBytes), binary.LittleEndian, &result)
31+
if err != nil {
32+
return 0, fmt.Errorf("failed to convert int32: %w", err)
33+
}
34+
return result, nil
35+
}
36+
37+
func readUint16(buffer *bytes.Buffer) (uint16, error) {
38+
readBytes := make([]byte, 2)
39+
_, err := buffer.Read(readBytes)
40+
if err != nil {
41+
return 0, fmt.Errorf("failed to read uint: %w", err)
42+
}
43+
var result uint16
44+
err = binary.Read(bytes.NewReader(readBytes), binary.LittleEndian, &result)
45+
if err != nil {
46+
return 0, fmt.Errorf("failed to convert uint: %w", err)
47+
}
48+
49+
return result, nil
50+
}
51+
52+
func readFloat32(buffer *bytes.Buffer) (float32, error) {
53+
readBytes := make([]byte, 4)
54+
_, err := buffer.Read(readBytes)
55+
if err != nil {
56+
return 0, fmt.Errorf("failed to read float32: %w", err)
57+
}
58+
59+
var result float32
60+
err = binary.Read(bytes.NewReader(readBytes), binary.LittleEndian, &result)
61+
if err != nil {
62+
return 0, fmt.Errorf("failed to convert float32: %w", err)
63+
}
64+
return result, nil
65+
}

0 commit comments

Comments
 (0)