diff --git a/README.md b/README.md index 9a962f994..0149d4944 100644 --- a/README.md +++ b/README.md @@ -35,10 +35,10 @@ Free code signing provided by [SignPath.io](https://signpath.io?utm_source=found - [iFuSiiOnzZ](https://github.com/iFuSiiOnzZ) - [KrisV147](https://github.com/KrisV147) - [floriwan](https://github.com/floriwan) +- [ConnorMolz](https://github.com/ConnorMolz) - [Andrei-Jianu](https://github.com/Andrei-Jianu) - [Dirk](https://github.com/Dirk) - [Florian](https://github.com/Florian) -- [ConnorMolz](https://github.com/ConnorMolz) - [goeflo](https://github.com/goeflo) - [GitHub-Action](https://github.com/GitHub-Action) - [Andi-Maier](https://github.com/Andi-Maier) diff --git a/Race Element.Core/Race Element.Core.csproj b/Race Element.Core/Race Element.Core.csproj index 5f31630ad..d9e1f945c 100644 --- a/Race Element.Core/Race Element.Core.csproj +++ b/Race Element.Core/Race Element.Core.csproj @@ -20,6 +20,6 @@ - + \ No newline at end of file diff --git a/Race Element.HUD.Common/Overlays/Driving/AccelerationTester/AccelerationTester.cs b/Race Element.HUD.Common/Overlays/Driving/AccelerationTester/AccelerationTester.cs new file mode 100644 index 000000000..686d5352f --- /dev/null +++ b/Race Element.HUD.Common/Overlays/Driving/AccelerationTester/AccelerationTester.cs @@ -0,0 +1,196 @@ +using RaceElement.Core.Jobs.Loop; +using RaceElement.Data.Common; +using RaceElement.HUD.Overlay.Internal; +using RaceElement.HUD.Overlay.Util; +using System.Drawing; + +namespace RaceElement.HUD.Common.Overlays.Driving.AccelerationTester; + +[Overlay( + Name = "Acceleration Tester", + Description = "Ready? Set! Go! The Acceleration Tester." + + "\nPrecision is Limited to Simulator Specification.", + Authors = ["Reinier Klarenberg"] +)] +internal sealed class AccelerationTester : CommonAbstractOverlay +{ + private readonly InfoPanel _infoPanel; + private readonly AccelerationTimingJob _timingJob; + + public AccelerationTester(Rectangle rectangle) : base(rectangle, "Acceleration Tester") + { + Width = 400; + Height = 200; + + _infoPanel = new InfoPanel(12, 400); + _timingJob = new AccelerationTimingJob() { IntervalMillis = 5 }; + } + + public sealed override void BeforeStart() => _timingJob?.Run(); + + public sealed override void BeforeStop() + { + _infoPanel?.Dispose(); + _timingJob?.CancelJoin(); + } + + public sealed override void Render(Graphics g) + { + if (_timingJob == null) + return; + + _infoPanel.AddLine("Phase", _timingJob?.PhaseDescriptions[_timingJob.Phase]); + + TimeSpan previous = TimeSpan.Zero; + foreach (var accType in Enum.GetValues()) + { + TimeSpan fromZero = _timingJob.RecordedTimes[accType]; + TimeSpan fromPrevious = fromZero - previous; + if (accType != AccelerationTypes.ZeroToHundred) // show delta times + _infoPanel.AddLine(_timingJob.DeltaAccelerationTypeDescriptions[accType], _timingJob.RecordedTimes[accType] == default ? "-" : fromPrevious.ToString(@"s\.fff") + " s"); + + _infoPanel.AddLine(_timingJob.ZeroToAccelerationTypeDescriptions[accType], _timingJob.RecordedTimes[accType] == default ? "-" : fromZero.ToString(@"s\.fff") + " s"); + previous += fromPrevious; + } + + _infoPanel.Draw(g); + } + + internal enum AccelerationPhase + { + Reset, + HandbrakePulled, + Ready, + Accelerating, + Completed + } + + internal enum AccelerationTypes + { + ZeroToHundred, + HundredToTwoHundred, + TwoHundredToThreeHundred, + ThreeHundredToFourHundred, + } + + private sealed class AccelerationTimingJob : AbstractLoopJob + { + private long _lastHandbrakePullTime = default; + private long _accelerationStartTime = default; + private static bool IsHandBrakePulled { get => SimDataProvider.LocalCar.Inputs.HandBrake > 0; } + + public AccelerationPhase Phase = AccelerationPhase.Reset; + + public Dictionary PhaseDescriptions = new() + { + { AccelerationPhase.Reset, "Stop car & Hold Handbrake" }, + { AccelerationPhase.HandbrakePulled, "Hold Handbrake for 1 Sec" }, + { AccelerationPhase.Ready, "Ready? Release Handbrake!" }, + { AccelerationPhase.Accelerating, "Accelerating..." }, + { AccelerationPhase.Completed, "Completed!" } + }; + + public Dictionary DeltaAccelerationTypeDescriptions = new() + { + { AccelerationTypes.ZeroToHundred, "0-100 km/h" }, + { AccelerationTypes.HundredToTwoHundred, "100-200 km/h" }, + { AccelerationTypes.TwoHundredToThreeHundred, "200-300 km/h" }, + { AccelerationTypes.ThreeHundredToFourHundred, "300-400 km/h" }, + }; + + public Dictionary ZeroToAccelerationTypeDescriptions = new() + { + { AccelerationTypes.ZeroToHundred, "0-100 km/h" }, + { AccelerationTypes.HundredToTwoHundred, "0-200 km/h" }, + { AccelerationTypes.TwoHundredToThreeHundred, "0-300 km/h" }, + { AccelerationTypes.ThreeHundredToFourHundred, "0-400 km/h" }, + }; + + public Dictionary RecordedTimes = new() + { + { AccelerationTypes.ZeroToHundred, default }, + { AccelerationTypes.HundredToTwoHundred, default }, + { AccelerationTypes.TwoHundredToThreeHundred, default }, + { AccelerationTypes.ThreeHundredToFourHundred, default }, + }; + + public Dictionary AccelerationTresholds = new() + { + { AccelerationTypes.ZeroToHundred, 100 }, + { AccelerationTypes.HundredToTwoHundred, 200 }, + { AccelerationTypes.TwoHundredToThreeHundred, 300 }, + { AccelerationTypes.ThreeHundredToFourHundred, 400 }, + }; + + public sealed override void RunAction() + { + switch (Phase) + { + case AccelerationPhase.Reset: + { + foreach (var accType in Enum.GetValues()) + RecordedTimes[accType] = default; + + if (IsHandBrakePulled && SimDataProvider.LocalCar.Physics.Velocity < 0.5f) + { + _lastHandbrakePullTime = TimeProvider.System.GetTimestamp(); + Phase = AccelerationPhase.HandbrakePulled; + } + + break; + } + case AccelerationPhase.HandbrakePulled: + { + if (!IsHandBrakePulled) + { + _lastHandbrakePullTime = default; + Phase = AccelerationPhase.Reset; + } + + if (SimDataProvider.LocalCar.Physics.Velocity < 0.1f) + { + if (TimeProvider.System.GetElapsedTime(_lastHandbrakePullTime) >= TimeSpan.FromSeconds(1)) + Phase = AccelerationPhase.Ready; + } + break; + } + case AccelerationPhase.Ready: + { + if (!IsHandBrakePulled && SimDataProvider.LocalCar.Physics.Velocity > 0.1f) + { + Phase = AccelerationPhase.Accelerating; + _accelerationStartTime = TimeProvider.System.GetTimestamp(); + break; + } + + break; + } + case AccelerationPhase.Accelerating: + { + if (SimDataProvider.LocalCar.Physics.Velocity < 1 && IsHandBrakePulled) + { + Phase = AccelerationPhase.Reset; + } + + foreach (var accType in Enum.GetValues()) + foreach (var treshold in AccelerationTresholds) + if (accType == treshold.Key && RecordedTimes[accType] == default && SimDataProvider.LocalCar.Physics.Velocity >= treshold.Value) + RecordedTimes[accType] = TimeProvider.System.GetElapsedTime(_accelerationStartTime); + + if (SimDataProvider.LocalCar.Inputs.Brake > 0) + Phase = AccelerationPhase.Completed; + + break; + } + case AccelerationPhase.Completed: + { + if (SimDataProvider.LocalCar.Physics.Velocity < 1 && IsHandBrakePulled) + { + Phase = AccelerationPhase.Reset; + } + break; + } + } + } + } +} diff --git a/Race Element.HUD.Common/Overlays/Driving/Accellerometer/AccelerometerOverlay.cs b/Race Element.HUD.Common/Overlays/Driving/Accelerometer/AccelerometerOverlay.cs similarity index 99% rename from Race Element.HUD.Common/Overlays/Driving/Accellerometer/AccelerometerOverlay.cs rename to Race Element.HUD.Common/Overlays/Driving/Accelerometer/AccelerometerOverlay.cs index c9d38f747..26f0ead72 100644 --- a/Race Element.HUD.Common/Overlays/Driving/Accellerometer/AccelerometerOverlay.cs +++ b/Race Element.HUD.Common/Overlays/Driving/Accelerometer/AccelerometerOverlay.cs @@ -7,7 +7,7 @@ using System.Drawing; using System.Drawing.Drawing2D; -namespace RaceElement.HUD.Common.Overlays.Driving.Accellerometer; +namespace RaceElement.HUD.Common.Overlays.Driving.Accelerometer; [Overlay( Name = "Accelerometer", diff --git a/Race Element.HUD.Common/Overlays/Driving/DSX/DsxJob.cs b/Race Element.HUD.Common/Overlays/Driving/DSX/DsxJob.cs index c7cbc399b..ca2d4c950 100644 --- a/Race Element.HUD.Common/Overlays/Driving/DSX/DsxJob.cs +++ b/Race Element.HUD.Common/Overlays/Driving/DSX/DsxJob.cs @@ -1,47 +1,61 @@ using RaceElement.Core.Jobs.Loop; +using RaceElement.Data.Games; +using System.Diagnostics; using static RaceElement.HUD.Common.Overlays.Driving.DSX.Resources; namespace RaceElement.HUD.Common.Overlays.Driving.DSX; -internal sealed class DsxJob(DsxOverlay overlay) : AbstractLoopJob +internal sealed class DsxJob(DsxOverlay? overlay) : AbstractLoopJob { public sealed override void RunAction() { - //if (!overlay.ShouldRender()) - // return; + if (overlay == null) + return; - if (overlay._client == null) + if (!GameManager.IsGameRunning) + { + if (overlay._hasSetLighting) + { + overlay?.StopClient(); + } + + return; + } + + if (overlay?._client == null) { try { - overlay.CreateEndPoint(); - overlay.SetLighting(); + overlay?.CreateEndPoint(); + overlay?.SetLighting(); } - catch (Exception) + catch (Exception e) { - // let's not cause an app crash, shall we? + Debug.WriteLine(e); } + Debug.WriteLine("Created enpoint and set lighting!"); + return; } - DsxPacket tcPacket = TriggerHaptics.HandleAcceleration(overlay._config); + DsxPacket tcPacket = TriggerHaptics.HandleAcceleration(overlay?._config); if (tcPacket != null) { - overlay.Send(tcPacket); + overlay?.Send(tcPacket); //ServerResponse response = Receive(); //HandleResponse(response); } - DsxPacket absPacket = TriggerHaptics.HandleBraking(overlay._config); + DsxPacket absPacket = TriggerHaptics.HandleBraking(overlay?._config); if (absPacket != null) { - overlay.Send(absPacket); + overlay?.Send(absPacket); //ServerResponse response = Receive(); //HandleResponse(response); } } + public override void AfterCancel() { - overlay?._client?.Close(); - overlay?._client?.Dispose(); + overlay?.StopClient(); } } diff --git a/Race Element.HUD.Common/Overlays/Driving/DSX/DsxOverlay.cs b/Race Element.HUD.Common/Overlays/Driving/DSX/DsxOverlay.cs index d5a616b00..1ffbb4c50 100644 --- a/Race Element.HUD.Common/Overlays/Driving/DSX/DsxOverlay.cs +++ b/Race Element.HUD.Common/Overlays/Driving/DSX/DsxOverlay.cs @@ -26,6 +26,8 @@ internal sealed class DsxOverlay : CommonAbstractOverlay internal UdpClient _client; internal IPEndPoint _endPoint; + internal bool _hasSetLighting = false; + public DsxOverlay(Rectangle rectangle) : base(rectangle, "DSX") { Width = 1; Height = 1; @@ -70,6 +72,7 @@ internal void SetLighting() { HandleResponse(lightingReponse); } + _hasSetLighting = true; } internal void CreateEndPoint() @@ -78,6 +81,18 @@ internal void CreateEndPoint() _endPoint = new IPEndPoint(Triggers.localhost, _config.UDP.Port); } + internal void StopClient() + { + _hasSetLighting = false; + DsxPacket resetPacket = new(); + resetPacket.AddResetToPacket(0); + Send(resetPacket); + + _client?.Close(); + _client?.Dispose(); + _client = null; + } + internal void Send(DsxPacket data) { string packet = Triggers.PacketToJson(data); diff --git a/Race Element.HUD.Common/Overlays/Driving/ShiftBar/ShiftBarOverlay.cs b/Race Element.HUD.Common/Overlays/Driving/ShiftBar/ShiftBarOverlay.cs index 9b5265a63..468927488 100644 --- a/Race Element.HUD.Common/Overlays/Driving/ShiftBar/ShiftBarOverlay.cs +++ b/Race Element.HUD.Common/Overlays/Driving/ShiftBar/ShiftBarOverlay.cs @@ -179,43 +179,14 @@ public sealed override void BeforeStop() _upshiftDataPanel?.Dispose(); } - // demo stuff - private int shiftsDone = 0; - private bool up = true; - // demo stuff - public sealed override void Render(Graphics g) { if (!IsPreviewing) - { // SET MODEL: Before release, uncomment line below and remove everything in-between the test data. it emulates the rpm going up + { _model.Rpm = SimDataProvider.LocalCar.Engine.Rpm; _model.MaxRpm = SimDataProvider.LocalCar.Engine.MaxRpm; - // test data ------------ - //_model.MaxRpm = 10000; - //if (_model.Rpm < _model.MaxRpm / 3) _model.Rpm = _model.MaxRpm / 3; - //int increment = Random.Shared.Next(0, 2) == 1 ? Random.Shared.Next(0, 43) : -7; - //if (!up) increment *= -4; - //_model.Rpm = _model.Rpm + increment; - //if (up && _model.Rpm > _model.MaxRpm) - //{ - // _model.Rpm = _model.MaxRpm - _model.MaxRpm / 4; - // shiftsDone++; - //} - //if (!up && _model.Rpm < _model.MaxRpm * _config.Upshift.EarlyPercentage / 100f - _model.MaxRpm / 5f) - //{ - // _model.Rpm = _model.MaxRpm; - // shiftsDone++; - //} - //if (shiftsDone > 3) - //{ - // up = !up; - // shiftsDone = 0; - //} - - // test data ------------ - if (_model.Rpm < 0) _model.Rpm = 0; if (_model.Rpm > _model.MaxRpm) _model.Rpm = _model.MaxRpm; } @@ -237,9 +208,8 @@ public sealed override void Render(Graphics g) } } - /// - /// + /// Secret sauce to hide a certain amount of RPM from the bar. /// /// /// diff --git a/Race Element.HUD.Common/Race Element.HUD.Common.csproj b/Race Element.HUD.Common/Race Element.HUD.Common.csproj index ce063ac38..e0a6e4974 100644 --- a/Race Element.HUD.Common/Race Element.HUD.Common.csproj +++ b/Race Element.HUD.Common/Race Element.HUD.Common.csproj @@ -29,7 +29,7 @@ - + diff --git a/Race_Element.Broadcast/BroadcastConfig.cs b/Race_Element.Broadcast/BroadcastConfig.cs index 548524307..060920669 100644 --- a/Race_Element.Broadcast/BroadcastConfig.cs +++ b/Race_Element.Broadcast/BroadcastConfig.cs @@ -19,7 +19,7 @@ public class Root public string CommandPassword { get; set; } } - private readonly static Lock _lock = new(); + private static readonly Lock _lock = new(); public static Root GetConfiguration() { diff --git a/Race_Element.Data.ACC/Race Element.Data.ACC.csproj b/Race_Element.Data.ACC/Race Element.Data.ACC.csproj index d457b4a49..901977bd2 100644 --- a/Race_Element.Data.ACC/Race Element.Data.ACC.csproj +++ b/Race_Element.Data.ACC/Race Element.Data.ACC.csproj @@ -19,45 +19,45 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + diff --git a/Race_Element.HUD.ACC/Race Element.HUD.ACC.csproj b/Race_Element.HUD.ACC/Race Element.HUD.ACC.csproj index e79a22240..93aa5191e 100644 --- a/Race_Element.HUD.ACC/Race Element.HUD.ACC.csproj +++ b/Race_Element.HUD.ACC/Race Element.HUD.ACC.csproj @@ -89,9 +89,9 @@ 4.1.69 - + - + diff --git a/Race_Element.HUD/Overlay/OverlayUtil/InfoPanel.cs b/Race_Element.HUD/Overlay/OverlayUtil/InfoPanel.cs index 732e56422..0c65e2b6d 100644 --- a/Race_Element.HUD/Overlay/OverlayUtil/InfoPanel.cs +++ b/Race_Element.HUD/Overlay/OverlayUtil/InfoPanel.cs @@ -1,4 +1,5 @@ using RaceElement.HUD.Overlay.OverlayUtil; +using RaceElement.Util; using RaceElement.Util.SystemExtensions; using System; using System.Collections.Generic; @@ -73,6 +74,12 @@ public void SetBackground() public void Draw(Graphics g) { + if (_font == null) + { + LogWriter.WriteToLog("InfoPanel font is null, cannot draw panel."); + return; + } + if (!MaxTitleWidthSet) { UpdateMaxTitleWidth(g); diff --git a/Race_Element/Controls/Info/ReleaseNotes.cs b/Race_Element/Controls/Info/ReleaseNotes.cs index 4692a688e..c74bfdffe 100644 --- a/Race_Element/Controls/Info/ReleaseNotes.cs +++ b/Race_Element/Controls/Info/ReleaseNotes.cs @@ -6,7 +6,9 @@ public static class ReleaseNotes { internal static readonly Dictionary Notes = new() { - {"2.5.2.0", "iRacing"+ + {"2.5.3.0", "DSX"+ + "\n- Race Element now disconnects from DSX if there is no supported game running."+ + "\n\niRacing"+ "\n- Lap Delta Bar HUD: Added 3 sources for delta calculation: Session Best, Last Lap and Optimal Lap. (By ConnorMolz)" }, {"2.5.1.0", "Race Element"+ diff --git a/Race_Element/Race Element.csproj b/Race_Element/Race Element.csproj index b77ea4239..eb382ee63 100644 --- a/Race_Element/Race Element.csproj +++ b/Race_Element/Race Element.csproj @@ -1,183 +1,183 @@  - - net10.0-windows - WinExe - RaceElement - RaceElement - false - publish\ - false - Race Element - Reinier Klarenberg - Race Element - false - true - 2.5.1.1 - 2.5.1.1 - 2.5.1.1 - True - true - true - true - true - Copyright © Reinier Klarenberg 2022 - - - MinimumRecommendedRules.ruleset - false - - - Properties\app.manifest - x64 - True - Race Element - race element icon 2.png - Element Future - Race Element - - - RaceElement.App - - - Resources\race element icon 2.ico - - - false - - - false - - - key.snk - - - 9FBE825EC0ACCC58542DA8C54DA8899183BDE274 - - - ACCSetupApp_TemporaryKey.pfx - - - false - - - Custom - + + net10.0-windows + WinExe + RaceElement + RaceElement + false + publish\ + false + Race Element + Reinier Klarenberg + Race Element + false + true + 2.5.3.1 + 2.5.3.1 + 2.5.3.1 + True + true + true + true + true + Copyright © Reinier Klarenberg 2022 + + + MinimumRecommendedRules.ruleset + false + + + Properties\app.manifest + x64 + True + Race Element + race element icon 2.png + Element Future + Race Element + + + RaceElement.App + + + Resources\race element icon 2.ico + + + false + + + false + + + key.snk + + + 9FBE825EC0ACCC58542DA8C54DA8899183BDE274 + + + ACCSetupApp_TemporaryKey.pfx + + + false + + + Custom + - - true - bin\Debug Minimized\ - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .editorconfig - - - True - \ - - - - - - False - Microsoft .NET Framework 4.8 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - - - - - - - - - - - - - - - - - - - - - True - True - Settings.settings - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - + + true + bin\Debug Minimized\ + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + .editorconfig + + + True + \ + + + + + + False + Microsoft .NET Framework 4.8 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + + + + + + + + + + + + + + + + True + True + Settings.settings + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + \ No newline at end of file