From 24304151b3bdd5b5296d5ee9a1eb3ab691234d2d Mon Sep 17 00:00:00 2001 From: RenCloud Date: Fri, 11 Nov 2022 12:56:11 +0100 Subject: [PATCH 1/2] Raise version number to 1.12 last update has changes to the offset, so 1.12 is more correct --- README.md | 6 +++--- changelog.md | 4 +++- scs-telemetry/inc/scs-telemetry-common.hpp | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 53b1a46..5931f5a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ This plug-in stores it's data inside a Memory Mapped File, or "Shared Memory". T Rev Numbers shows big changes on the shared memory and sometimes on the C# object. That means Rev 10 wont work with Rev 9. Doesn't matter which side is not updated. Sub Versions that you can see in changelog.md should work with small errors or completely without. The C# object is mostly not changed. Only if needed, because of new values (most of the cases) or structure changes (less the case). If this occurs i will notice that. (See changelog.md. If you directly access the shared memory you will find an overview about the changes here.) -### Plugin for 1.45/SDK1.14 +### Plugin for 1.46/SDK1.14 Lower SDK Version means there are less values / values that are zero. To get an overview which values that are look at the list at the middle of this document. Note to the SDK Version: SDK 1.13 is not the same like the sdk version of ETS2 or ATS. Both games have an own SDK version. See list under ATS. @@ -54,7 +54,7 @@ A version number with an asterisk (e.g. 1.46*) indicates that this version is cu | 1.36 | 1.15 | Should work | | - 1.40 | 1.16 | Should work | | 1.41 - 1.44 | 1.17 | Should work | -| 1.45 - 1.46* | 1.18 | Works, Test Version | +| 1.45 - 1.46 | 1.18 | Works, Test Version | ### ATS @@ -66,7 +66,7 @@ A version number with an asterisk (e.g. 1.46*) indicates that this version is cu | 1.36 | 1.02 | Should work | | - 1.40 | 1.03 | Should work | | 1.41 - 1.44 | 1.04 | Should work | -| 1.45 - 1.46* | 1.05 | Works, Test Version | +| 1.45 - 1.46 | 1.05 | Works, Test Version | ### SDK VERSION AND GAME SDK VERSION diff --git a/changelog.md b/changelog.md index 22a6d8c..4c85cad 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,8 @@ # Changelog -## Rev 11 Update 1 (Some breaking changes for Trailer, but 12 is reserved) +## Rev 12, former Rev 11 Update 1 + +Change version to 12, because of offset changes. This leads to a rev change and not just an update like it was before. ### Important Changes diff --git a/scs-telemetry/inc/scs-telemetry-common.hpp b/scs-telemetry/inc/scs-telemetry-common.hpp index 08ad157..c14ff70 100644 --- a/scs-telemetry/inc/scs-telemetry-common.hpp +++ b/scs-telemetry/inc/scs-telemetry-common.hpp @@ -7,7 +7,7 @@ // - Shared memory map struct layout // - [..] -#define PLUGIN_REVID 11 +#define PLUGIN_REVID 12 #define ETS2 1 #define ATS 2 From 6e3e50d4c3ca10af75f7b545a0055c2f300de17a Mon Sep 17 00:00:00 2001 From: Jonas Fabisiak Date: Sat, 11 Feb 2023 09:15:37 +0100 Subject: [PATCH 2/2] fix: check against race condition while converting data Add a check, if the converting is still ongoing, to simply skip it in the current thread to avoid race conditions --- changelog.md | 4 ++ scs-client/C#/SCSSdkClient/SCSSdkConvert.cs | 22 ++++---- scs-client/C#/SCSSdkClient/SCSSdkTelemetry.cs | 50 ++++++++++++------- scs-client/C#/SCSSdkClient/SharedMemory.cs | 4 +- 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/changelog.md b/changelog.md index 4c85cad..3982681 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # Changelog +## Rev 12, Update 1 + +- fix: add check to avoid a race condition when converting the data + ## Rev 12, former Rev 11 Update 1 Change version to 12, because of offset changes. This leads to a rev change and not just an update like it was before. diff --git a/scs-client/C#/SCSSdkClient/SCSSdkConvert.cs b/scs-client/C#/SCSSdkClient/SCSSdkConvert.cs index b78483d..d3615b8 100644 --- a/scs-client/C#/SCSSdkClient/SCSSdkConvert.cs +++ b/scs-client/C#/SCSSdkClient/SCSSdkConvert.cs @@ -1,9 +1,4 @@ -// -// Ets2SdkClient -// Ets2SdkDataAlt.cs -// 22:51 - -using System; +using System; using System.Text; using SCSSdkClient.Object; @@ -14,8 +9,8 @@ namespace SCSSdkClient { /// public class SCSSdkConvert { private const int StringSize = 64; - private const int Substances = 25; private const int WheelSize = 16; + private const int Substances = 25; private readonly int[] _offsetAreas = {0, 40, 500, 700, 1500, 1640, 2000, 2200, 2300, 4000, 4200, 4300, 4400, 6000}; @@ -25,6 +20,8 @@ public class SCSSdkConvert { private int _offsetArea; + private bool currentlyActive = false; + /// /// Convert the Shared Memory Byte data structure in a C# object /// @@ -35,6 +32,12 @@ public class SCSSdkConvert { /// C# object with game data of the shared memory /// public SCSTelemetry Convert(byte[] structureDataBytes) { + if (currentlyActive) { + return null; + } + + currentlyActive = true; + _offsetArea = 0; SetOffset(); @@ -388,6 +391,8 @@ public SCSTelemetry Convert(byte[] structureDataBytes) { #endregion 14TH ZONE + currentlyActive = false; + return retData; } @@ -399,6 +404,7 @@ private bool GetBool() { private bool[] GetBoolArray(int length) { var res = new bool[length]; + for (var i = 0; i < length; i++) { res[i] = GetBool(); } @@ -594,7 +600,6 @@ private SCSTelemetry.Trailer GetTrailer() { private SCSTelemetry.Trailer[] GetTrailers() { var trailer = new SCSTelemetry.Trailer[10]; - //TODO : only 1 for old game versions for (var i = 0; i < 10; i++) { trailer[i] = GetTrailer(); @@ -640,7 +645,6 @@ private void NextOffsetArea() { } private void SetOffset() { - // Debug Fix? if (_offsetArea >= _offsetAreas.Length) { return; } diff --git a/scs-client/C#/SCSSdkClient/SCSSdkTelemetry.cs b/scs-client/C#/SCSSdkClient/SCSSdkTelemetry.cs index 8934b5e..776f4c8 100644 --- a/scs-client/C#/SCSSdkClient/SCSSdkTelemetry.cs +++ b/scs-client/C#/SCSSdkClient/SCSSdkTelemetry.cs @@ -3,14 +3,15 @@ using SCSSdkClient.Object; namespace SCSSdkClient { + /// /// Data Event - /// + /// /// The parameter **newTimeStamp** is deprecated and will be removed in a future release. - /// + /// /// - /// - /// + /// + /// /// All data of the telemetry /// Flag if the data changed public delegate void TelemetryData(SCSTelemetry data, bool newTimestamp); @@ -19,27 +20,27 @@ namespace SCSSdkClient { /// Handle the SCSSdkTelemetry. /// Currently IDisposable. Was implemented because of an error /// - public class SCSSdkTelemetry : IDisposable { + public class SCSSdkTelemetry: IDisposable { private const string DefaultSharedMemoryMap = "Local\\SCSTelemetry"; private const int DefaultUpdateInterval = 100; private const int DefaultPausedUpdateInterval = 1000; private int updateInterval; - // todo: enhancement: some way to set this value + // todo: enhancement: some way to set this value private readonly int pausedUpdateInterval = DefaultPausedUpdateInterval; private Timer _updateTimer; private ulong lastTime = 0xFFFFFFFFFFFFFFFF; - #if LOGGING public void Dispose() { _updateTimer?.Dispose(); Log.SaveShutdown(); } #else + public void Dispose() => _updateTimer?.Dispose(); #endif @@ -69,20 +70,28 @@ public void Dispose() { public string Map { get; private set; } public int UpdateInterval => paused ? pausedUpdateInterval : updateInterval; - public Exception Error { get; private set; } public event TelemetryData Data; public event EventHandler JobStarted; + public event EventHandler JobCancelled; + public event EventHandler JobDelivered; + public event EventHandler Fined; + public event EventHandler Tollgate; + public event EventHandler Ferry; + public event EventHandler Train; + public event EventHandler RefuelStart; + public event EventHandler RefuelEnd; + public event EventHandler RefuelPayed; public void pause() => _updateTimer.Change(Timeout.Infinite, Timeout.Infinite); @@ -127,9 +136,13 @@ private void Setup(string map, int interval) { private void _updateTimer_Elapsed(object sender) { var scsTelemetry = SharedMemory.Update(); + if (scsTelemetry == null) { + return; + } + // check if sdk is NOT running if (!scsTelemetry.SdkActive && !paused) { - // if so don't check so often the data + // if so don't check so often the data var tsInterval = new TimeSpan(0, 0, 0, 0, DefaultPausedUpdateInterval); _updateTimer.Change(tsInterval.Add(tsInterval), tsInterval); paused = true; @@ -182,43 +195,41 @@ private void _updateTimer_Elapsed(object sender) { if (delivered != scsTelemetry.SpecialEventsValues.JobDelivered) { delivered = scsTelemetry.SpecialEventsValues.JobDelivered; - + if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; } - JobDelivered?.Invoke(this, new EventArgs()); + JobDelivered?.Invoke(this, new EventArgs()); } if (fined != scsTelemetry.SpecialEventsValues.Fined) { fined = scsTelemetry.SpecialEventsValues.Fined; - - Fined?.Invoke(this, new EventArgs()); + + Fined?.Invoke(this, new EventArgs()); } if (tollgate != scsTelemetry.SpecialEventsValues.Tollgate) { tollgate = scsTelemetry.SpecialEventsValues.Tollgate; - Tollgate?.Invoke(this, new EventArgs()); - } if (ferry != scsTelemetry.SpecialEventsValues.Ferry) { ferry = scsTelemetry.SpecialEventsValues.Ferry; - + if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; } - Ferry?.Invoke(this, new EventArgs()); + Ferry?.Invoke(this, new EventArgs()); } if (train != scsTelemetry.SpecialEventsValues.Train) { train = scsTelemetry.SpecialEventsValues.Train; - + if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; @@ -252,6 +263,7 @@ private void _updateTimer_Elapsed(object sender) { Data?.Invoke(scsTelemetry, false); } } + #if LOGGING private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { try { @@ -269,4 +281,4 @@ private static void CurrentDomain_UnhandledException(object sender, UnhandledExc } #endif } -} \ No newline at end of file +} diff --git a/scs-client/C#/SCSSdkClient/SharedMemory.cs b/scs-client/C#/SCSSdkClient/SharedMemory.cs index b2330f0..5bdeb27 100644 --- a/scs-client/C#/SCSSdkClient/SharedMemory.cs +++ b/scs-client/C#/SCSSdkClient/SharedMemory.cs @@ -3,10 +3,12 @@ using SCSSdkClient.Object; namespace SCSSdkClient { + /// /// Manage the shared memory /// public class SharedMemory { + /// /// size of the shared memory in bytes /// @@ -119,4 +121,4 @@ public void Update() { /// Managed object from given bytes protected SCSTelemetry ToObject(byte[] structureDataBytes) => _sdkconvert.Convert(structureDataBytes); } -} \ No newline at end of file +}