-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMainForm.cs
282 lines (235 loc) · 10.7 KB
/
MainForm.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
using iRacingSdkWrapper;
using iSimpleRadar.Entities;
using iSimpleRadar.Overlay;
using NHotkey;
using NHotkey.WindowsForms;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Forms;
namespace iSimpleRadar
{
public partial class MainForm : Form
{
private SdkWrapper iracingWrapper;
private iSimpleRadarOverlayWindow overlay;
private List<Driver> drivers;
private bool isUpdatingDrivers;
private int currentSessionNum;
private float carSize = 5f;
private float trackLen;
public MainForm()
{
InitializeComponent();
// HotkeyManager.Current.AddOrReplace("Start", Keys.Alt| Keys.R, OnHotPress);
// Create a new instance of the SdkWrapper object
iracingWrapper = new SdkWrapper();
// Set some properties
iracingWrapper.EventRaiseType = SdkWrapper.EventRaiseTypes.CurrentThread;
iracingWrapper.TelemetryUpdateFrequency = 10;
// Listen for various events
iracingWrapper.Connected += iracingWrapper_Connected;
iracingWrapper.Disconnected += iracingWrapper_Disconnected;
iracingWrapper.SessionInfoUpdated += iracingWrapper_SessionInfoUpdated;
iracingWrapper.TelemetryUpdated += iracingWrapper_TelemetryUpdated;
drivers = new List<Driver>();
overlay = new iSimpleRadarOverlayWindow();
}
#region Connecting, disconnecting, etc
private void btn_start_Click(object sender, EventArgs e)
{
// If the wrapper is running, stop it. Otherwise, start it.
if (iracingWrapper.IsRunning)
{
iracingWrapper.Stop();
overlay.Stop();
btn_start.Text = "Start";
}
else
{
iracingWrapper.Start();
overlay.Run();
btn_start.Text = "Stop";
}
this.StatusChanged();
}
private void StatusChanged()
{
if (iracingWrapper.IsConnected)
{
if (iracingWrapper.IsRunning)
{
statusLabel.Text = "Status: connected!";
}
else
{
statusLabel.Text = "Status: disconnected.";
}
}
else
{
if (iracingWrapper.IsRunning)
{
statusLabel.Text = "Status: disconnected, waiting for sim...";
}
else
{
statusLabel.Text = "Status: disconnected";
}
}
}
private void iracingWrapper_Connected(object sender, EventArgs e)
{
this.StatusChanged();
}
private void iracingWrapper_Disconnected(object sender, EventArgs e)
{
this.StatusChanged();
}
#endregion
#region events
private void iracingWrapper_SessionInfoUpdated(object sender, SdkWrapper.SessionInfoUpdatedEventArgs e)
{
// Indicate that we are updating the drivers list
isUpdatingDrivers = true;
trackLen = float.Parse(e.SessionInfo["WeekendInfo"]["TrackLength"].GetValue("0").Replace(" km", "")) * 1000f;
// Parse the Drivers section of the session info into a list of drivers
this.ParseDrivers(e.SessionInfo);
// Indicate we are finished updating drivers
isUpdatingDrivers = false;
}
private void iracingWrapper_TelemetryUpdated(object sender, SdkWrapper.TelemetryUpdatedEventArgs e)
{
// Besides the driver details found in the session info, there's also things in the telemetry
// that are properties of a driver, such as their lap, lap distance, track surface, distance relative
// to yourself and more.
// We update the existing list of drivers with the telemetry values here.
// If we are currently renewing the drivers list it makes little sense to update the existing drivers
// because they will change anyway
if (isUpdatingDrivers) return;
// Store the current session number so we know which session to read
// There can be multiple sessions in a server (practice, Q, race, or warmup, race, etc).
currentSessionNum = e.TelemetryInfo.SessionNum.Value;
this.UpdateDriversTelemetry(e.TelemetryInfo);
}
#endregion
#region Drivers
// Parse the YAML DriverInfo section that contains information such as driver id, name, license, car number, etc.
private void ParseDrivers(SessionInfo sessionInfo)
{
int id = 0;
Driver? driver;
var newDrivers = new List<Driver>();
// Loop through drivers until none are found anymore
do
{
driver = null;
// Construct a yaml query that finds each driver and his info in the Session Info yaml string
// This query can be re-used for every property for one driver (with the specified id)
YamlQuery query = sessionInfo["DriverInfo"]["Drivers"]["CarIdx", id];
// Try to get the UserName of the driver (because its the first value given)
// If the UserName value is not found (name == null) then we found all drivers and we can stop
string name = query["UserName"].GetValue();
if (name != null)
{
// Find this driver in the list
// This strange " => " syntax is called a lambda expression and is short for a loop through all drivers
// Read as: select the first driver 'd', if any, whose Name is equal to name.
driver = drivers.Find(d => d.Name == name);
if (driver == null)
{
// Or create a new Driver if we didn't find him before
driver = new Driver();
driver.Id = id;
driver.Name = name;
// driver.CustomerId = int.Parse(query["UserID"].GetValue("0")); // default value 0
driver.Number = query["CarNumber"].GetValue("").TrimStart('\"').TrimEnd('\"'); // trim the quotes
// driver.ClassId = int.Parse(query["CarClassID"].GetValue("0"));
// driver.CarPath = query["CarPath"].GetValue();
// driver.CarClassRelSpeed = int.Parse(query["CarClassRelSpeed"].GetValue("0"));
// driver.Rating = int.Parse(query["IRating"].GetValue("0"));
}
newDrivers.Add(driver);
id++;
}
} while (driver != null);
// Replace old list of drivers with new list of drivers and update the grid
drivers.Clear();
drivers.AddRange(newDrivers);
}
private void UpdateDriversTelemetry(TelemetryInfo info)
{
// Get your own driver entry
// This strange " => " syntax is called a lambda expression and is short for a loop through all drivers
Driver? me = drivers.Find(d => d.Id == iracingWrapper.DriverId);
// Get arrays of the laps, distances, track surfaces of every driver
var laps = info.CarIdxLap.Value;
var lapDistances = info.CarIdxLapDistPct.Value;
var trackSurfaces = info.CarIdxTrackSurface.Value;
bool closeCar = false;
bool closeCarDanger = false;
// Loop through the list of current drivers
foreach (Driver driver in drivers)
{
// Set the lap, distance, tracksurface belonging to this driver
driver.Lap = laps[driver.Id];
driver.LapDistance = lapDistances[driver.Id];
driver.TrackSurface = trackSurfaces[driver.Id];
// If your own driver exists, use it to calculate the relative distance between you and the other driver
if (me != null && driver.TrackSurface == TrackSurfaces.OnTrack)
{
var relative = driver.LapDistance - me.LapDistance;
// If driver is more than half the track behind, subtract 100% track length
// and vice versa
if (relative > 0.5) relative -= 1;
else if (relative < -0.5) relative += 1;
driver.RelativeLapDistance = relative;
driver.DistFromMe = (trackLen * relative) + carSize;
if (driver.DistFromMe >= -20f && driver.DistFromMe < -10f)
{
overlay.CarBehindWarn = "Car: " + driver.Number + "|Dist: " + Math.Round(driver.DistFromMe + 5f, 1) + "m";
overlay.posY = driver.DistFromMe;
closeCar = true;
}
else if (driver.DistFromMe >= -10f && driver.DistFromMe < 0f)
{
overlay.CarBehindDanger = "Car: " + driver.Number + "|Dist: " + Math.Round(driver.DistFromMe, 1) + "m";
closeCarDanger = true;
overlay.posY = driver.DistFromMe + 5f;
}
}
else
{
driver.RelativeLapDistance = -1;
}
}
if (!closeCar)
overlay.CarBehindWarn = "";
if (!closeCarDanger)
overlay.CarBehindDanger = "";
Enums.CarLeftRight carLeftRight = (Enums.CarLeftRight)iracingWrapper.GetData("CarLeftRight");
if (carLeftRight == Enums.CarLeftRight.irsdk_LRClear)
{
overlay.carLeft = false;
overlay.carRight = false;
}
if (carLeftRight == Enums.CarLeftRight.irsdk_LRCarLeft || carLeftRight == Enums.CarLeftRight.irsdk_LR2CarsLeft)
{
overlay.carLeft = true;
}
if (carLeftRight == Enums.CarLeftRight.irsdk_LRCarRight || carLeftRight == Enums.CarLeftRight.irsdk_LR2CarsRight)
{
overlay.carRight = true;
}
if (carLeftRight == Enums.CarLeftRight.irsdk_LRCarRight)
{
overlay.carLeft = true;
overlay.carRight = true;
}
}
#endregion
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
iracingWrapper.Stop();
}
}
}