Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.0.0" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.1.0" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion Samples/LocationAndWarnings/LocationAndWarnings.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.0.0" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.1.0" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion Samples/MinimalExample/MinimalExample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.0.0" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.1.0" />
</ItemGroup>

</Project>
2 changes: 1 addition & 1 deletion Samples/SpeedRPMGear/SpeedRPMGear.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<PackageReference Include="Microsoft.Extensions.Diagnostics" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.0.0" />
<PackageReference Include="SVappsLAB.iRacingTelemetrySDK" Version="2.1.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="5.6.0" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public enum SessionFlags
Serviceable = 0x00040000, // car is allowed service (not a flag)
Furled = 0x00080000,
Repair = 0x00100000,
DqScoringInvalid = 0x00200000, // car is disqualified and scoring is disabled

// start lights
StartHidden = 0x10000000,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* Copyright (C) 2024-2026 Scott Velez
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand Down Expand Up @@ -120,9 +120,8 @@ public string GetSessionInfoYaml()
var offSet = header.sessionInfoOffset;
var maxLen = header.sessionInfoLen;

var span = new Span<byte>(_dataPtr + offSet, maxLen);
var sessInfo = ExtractNullTerminatedString(span, maxLen);
return sessInfo;
var span = new ReadOnlySpan<byte>(_dataPtr + offSet, maxLen);
return SessionInfoDecoder.Decode(span);
}

public object? GetVarValue(string varName)
Expand Down Expand Up @@ -198,6 +197,42 @@ protected void CopyNewTelemetryDataToBuffer(int recNum = 0)
ros.CopyTo(_telemetryDataBuffer);
}

// live telemetry can be overwritten by the sim while we read it. mirror the
// official sdk's torn-read detection: 'tickCountBegin' is updated before a
// write starts and 'tickCount' after it completes. if the tickCount read
// before the copy matches tickCountBegin after, no write was in progress
protected bool TryCopyLiveTelemetryDataToBuffer(out int validTickCount)
{
const int MAX_ATTEMPTS = 2;

// try a few times to get the data out
for (var attempt = 0; attempt < MAX_ATTEMPTS; attempt++)
{
var header = GetHeader();
var bufIndex = header.GetMostRecentBufferIndex();
var varBuf = header.GetVarBuf(bufIndex);

var curTickCount = varBuf.tickCount;
Thread.MemoryBarrier();

var ros = new ReadOnlySpan<byte>(_dataPtr + varBuf.bufOffset, header.bufLen);
ros.CopyTo(_telemetryDataBuffer);

Thread.MemoryBarrier();

// re-read from shared memory to see if a write was in progress
if (curTickCount == GetHeader().GetVarBuf(bufIndex).tickCountBegin)
{
validTickCount = curTickCount;
return true;
}
}

// the data changed out from under us
validTickCount = 0;
return false;
}

VarHeaderDictionary ReadVarHeaders()
{
var ros = new ReadOnlySpan<irsdk_varHeader>(_dataPtr + _header.varHeaderOffset, _header.numVars);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using SVappsLAB.iRacingTelemetrySDK.irSDKDefines;

namespace SVappsLAB.iRacingTelemetrySDK.DataProviders
{
Expand Down Expand Up @@ -58,7 +57,13 @@ public override Task<bool> WaitForDataReady(TimeSpan timeSpan, CancellationToken

internal bool ProcessNewData()
{
var latestTickCount = GetLatestVarBuff().tickCount;
// copy new data to the access buffer,
// validating data is good and no write was in progress
if (!TryCopyLiveTelemetryDataToBuffer(out var latestTickCount))
{
_logger.LogWarning("data changed while we were reading it. skipping this sample");
return false;
}

// if we missed any telemetry data, log that it happened
if (latestTickCount > _lastTickCount)
Expand All @@ -67,7 +72,7 @@ internal bool ProcessNewData()
if (_lastTickCount != 0 && tickDiff > 0)
{
_dataDropCount += tickDiff;
_logger.LogWarning("dropped {count} data records. {total} total. last tick: {lastTick}, current tick: {currentTick}", tickDiff, _dataDropCount, _lastTickCount, latestTickCount);
_logger.LogWarning("dropped {count} data records. a total of {total} missed so far. last tick: {lastTick}, current tick: {currentTick}", tickDiff, _dataDropCount, _lastTickCount, latestTickCount);
}
}

Expand All @@ -78,28 +83,11 @@ internal bool ProcessNewData()
_logger.LogDebug("new data is older than our last sample. lost connection? will resync");
}

// copy new data to the access buffer for later reading
CopyNewTelemetryDataToBuffer();
// resync - update our last tick count
_lastTickCount = latestTickCount;

return true;
}

irsdk_varBuf GetLatestVarBuff()
{
var header = GetHeader();

var vb = header.varBuf1;
if (header.varBuf2.tickCount > vb.tickCount)
vb = header.varBuf2;
if (header.varBuf3.tickCount > vb.tickCount)
vb = header.varBuf3;
if (header.varBuf4.tickCount > vb.tickCount)
vb = header.varBuf4;
return vb;

}
public override ValueTask DisposeAsync()
{
if (_dataReadyEvent != null)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Copyright (C) 2024-2026 Scott Velez
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/

using System;
using System.Text;

namespace SVappsLAB.iRacingTelemetrySDK.DataProviders
{
// Decodes the raw session-info bytes from the memory-mapped file / IBT file
// into a string, depending on the WeekendInfo:Encoding: tag (UTF8).
internal static class SessionInfoDecoder
{
private static readonly byte[] EncodingKey = Encoding.ASCII.GetBytes("Encoding:");
private static readonly byte[] Utf8Value = Encoding.ASCII.GetBytes("UTF8");

/// <summary>
/// Decode using the encoding declared by the WeekendInfo:Encoding: tag
/// Older session info without "UTF8" use ISO-8859-1
/// </summary>
public static string Decode(ReadOnlySpan<byte> raw)
{
// trim at the first null terminator
var nullIdx = raw.IndexOf((byte)0);
if (nullIdx >= 0)
raw = raw.Slice(0, nullIdx);

if (IsUtf8(raw))
return Encoding.UTF8.GetString(raw);

return Encoding.Latin1.GetString(raw);
}

public static bool IsUtf8(ReadOnlySpan<byte> raw)
{
var keyIdx = raw.IndexOf(EncodingKey);
if (keyIdx < 0)
return false;

// the value is on the same line, immediately after the key
var value = raw.Slice(keyIdx + EncodingKey.Length);
var eol = value.IndexOf((byte)'\n');
if (eol >= 0)
value = value.Slice(0, eol);

return value.IndexOf(Utf8Value) >= 0;
}
}
}
10 changes: 5 additions & 5 deletions Sdk/SVappsLAB.iRacingTelemetrySDK/Models/DriverInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class DriverInfo
public int DriverCarIdx { get; set; } // 0
public int DriverUserID { get; set; } // 22176
public int PaceCarIdx { get; set; } // -1
public int DriverIsAdmin { get; set; } // 0/1 - the player is an admin and can have access to the admin chat commands
public float DriverHeadPosX { get; set; } // in units of length (mm, m, etc.)
public float DriverHeadPosY { get; set; } // in units of length (mm, m, etc.)
public float DriverHeadPosZ { get; set; } // in units of length (mm, m, etc.)
Expand All @@ -38,6 +39,9 @@ public class DriverInfo
public int DriverCarGearNumForward { get; set; } // 6
public int DriverCarGearNeutral { get; set; } // 1
public int DriverCarGearReverse { get; set; } // 1
public string DriverGearboxType { get; set; } // Sequential/H-Pattern/Automatic/Unknown - transmission type in virtual car
public string DriverGearboxControlType { get; set; } // Sequential/H-Pattern/H-Pattern Direct/Automatic/Unknown - physical shifter type player is using
public string DriverCarShiftAid { get; set; } // Manual/Antistall/Antistall_Clutch/Antistall_Clutch_Throttle/Automatic - type of shift aids the driver has turned on
public float DriverCarSLFirstRPM { get; set; } // 5600.000
public float DriverCarSLShiftRPM { get; set; } // 7200.000
public float DriverCarSLLastRPM { get; set; } // 7200.000
Expand All @@ -51,12 +55,8 @@ public class DriverInfo
public int DriverSetupPassedTech { get; set; } // 1
public int DriverIncidentCount { get; set; } // 0
public float DriverBrakeCurvingFactor { get; set; } // 0.001
public int DriverIsAdmin { get; set; } // 0/1 - the player is an admin and can have access to the admin chat commands
public string DriverGearboxType { get; set; } // Sequential/H-Pattern/Automatic/Unknown - transmission type in virtual car
public string DriverGearboxControlType { get; set; } // Sequential/H-Pattern/H-Pattern Direct/Automatic/Unknown - physical shifter type player is using
public string DriverCarShiftAid { get; set; } // Manual/Antistall/Antistall_Clutch/Antistall_Clutch_Throttle/Automatic - type of shift aids the driver has turned on
public List<Driver> Drivers { get; set; }
public List<DriverTire> DriverTires { get; set; }
public List<Driver> Drivers { get; set; }
}

public class Driver
Expand Down
9 changes: 5 additions & 4 deletions Sdk/SVappsLAB.iRacingTelemetrySDK/Models/WeekendInfo.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* Copyright (C) 2024-2026 Scott Velez
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -21,6 +21,7 @@ namespace SVappsLAB.iRacingTelemetrySDK
{
public class WeekendInfo
{
public string Encoding { get; set; } // "UTF8"
public string TrackName { get; set; } // spa up
public int TrackID { get; set; } // 143
public string TrackLength { get; set; } // 6.93 km (10cm accuracy)
Expand Down Expand Up @@ -116,7 +117,7 @@ public class WeekendOptions
public string IncidentWarningInitialLimit { get; set; } // 'unlimited' or '0'..'n
public object IncidentWarningSubsequentLimit { get; set; } // 'unlimited' or '0'..'n'
public string FastRepairsLimit { get; set; } // 'unlimited' or '0'..'n'
public string GreenWhiteCheckeredLimit { get; set; } //'unlimited' or '0'..'n'
public string GreenWhiteCheckeredLimit { get; set; } //'unlimited' or '0'..'n'

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Diagnostics.Abstractions" Version="10.0.8" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.8" />
<PackageReference Include="YamlDotNet" Version="17.1.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.Abstractions" Version="10.0.9" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.9" />
<PackageReference Include="YamlDotNet" Version="18.1.0" />
<ProjectReference Include="..\SVappsLAB.iRacingTelemetrySDK.CodeGen\SVappsLAB.iRacingTelemetrySDK.CodeGen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\SVappsLAB.iRacingTelemetrySDK.EnumsAndFlags\SVappsLAB.iRacingTelemetrySDK.EnumsAndFlags.csproj" PrivateAssets="all" />

Expand All @@ -47,7 +47,7 @@
<PackageTags>iRacing iRacingSDK irsdk IBT Telemetry SDK API</PackageTags>
<PackageReadmeFile>NUGET.md</PackageReadmeFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<Version>2.0.0</Version>
<Version>2.1.0</Version>
<Authors>Scott Velez</Authors>
<Company>SVappsLAB</Company>
<Copyright>Copyright (c) 2026 SVappsLAB</Copyright>
Expand Down
Loading
Loading