-
Notifications
You must be signed in to change notification settings - Fork 0
/
RBRCustomReader.cs
187 lines (167 loc) · 8.27 KB
/
RBRCustomReader.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
//
// RBRCustomReader - Custom SimHub addon plugin for Richard Burns Rally racing game
//
// Note! This is SIMHUB plugin, not RBR plugin. The User.RBRCustomReader.dll file goes into SimHub folder, not into RBR Plugins folder.
//
// Copyright (c) 2023 mika-n, www.rallysimfans.hu. No promises and/or warranty given what so ever. This may or may not work. Use at your own risk.
//
// WTFPL licensed to public domain, free for commercial and personal use, modifications and redistribution allowed. http://www.wtfpl.net/
// If you modify and create a derivated version using this app then please leave the above shown copyright text in the derived work as a credit to the original work (readme.txt and source code files).
//
// SimHub addon plugin installation:
// - Copy User.RBRCustomReader.dll file into the SimHub application folder (ie. the folder where you have SimHubWPF.exe)
// - Launch SimHub and it will probably notify you it detected a new addon plugin.
// - Enable the RBRCustomReader plugin
// - No need to tick "show in left menu" option
// - The plugin should be now shown as enabled in SimHub/Settings/Plugins tab page
//
// How to use RSFCarName and RSFCarID custom properties in SimHub dashboard layout?
// - Add a text object into SimHub dashboard layout and set the text object to use NCalc formula with RSFCarName or RSFCarID property reference
//
using GameReaderCommon;
using SimHub.Plugins;
using System;
using System.Windows.Media;
using System.Diagnostics;
using SimpleIniFile;
namespace User.RBRCustomReader
{
[PluginDescription("RBR Custom property reader for Rallysimfans RBR mod")]
[PluginAuthor("mika-n. www.rallysimfans.hu")]
[PluginName("RBR Custom Reader")]
public class RBRCustomReader : IPlugin, IDataPlugin, IWPFSettingsV2
{
// Custom RBR properties shown for SimHub NCalc expressions
public int RSFCarID; // RSF car ID (0...N)
public string RSFCarName; // The true car name and not just a model name as by default in SimHub (for example "Citroen DS3 R5" instead of just "DS3_R5")
// The timestamp of the previous RBR racing session. Car attributes are updated only once per new session (=new session start time)
private DateTime prevSessionStartTime;
// Timespan of the current race
private bool updateRaceTimespan; // When TRUE when dataReader starts a new timespan as soon race time is >0 (ie. the race is started)
private Stopwatch raceStopWatch;
// RBR game path (initialized only once because no one probably re-installs RBR while SimHub rbr dashboard is running
private string RBRGamePath;
private string GetRBRGamePath()
{
if (string.IsNullOrEmpty(RBRGamePath))
{
Process[] rbrProcessArray = Process.GetProcessesByName("RichardBurnsRally_SSE");
if (rbrProcessArray != null && rbrProcessArray.Length > 0)
{
RBRGamePath = System.IO.Path.GetDirectoryName(rbrProcessArray[0].MainModule.FileName);
rbrProcessArray[0].Dispose();
SimHub.Logging.Current.Info($"[RBRCustomReader] {RBRGamePath}\\RichardBurnsRally_SSE.exe");
}
}
return RBRGamePath;
}
/// <summary>
/// Instance of the current plugin manager
/// </summary>
public PluginManager PluginManager { get; set; }
/// <summary>
/// Gets the left menu icon. Icon must be 24x24 and compatible with black and white display.
/// </summary>
public ImageSource PictureIcon => this.ToIcon(Properties.Resources.sdkmenuicon);
/// <summary>
/// Gets a short plugin title to show in left menu. Return null if you want to use the title as defined in PluginName attribute.
/// </summary>
public string LeftMenuTitle => "RBR Custom Reader";
/// <summary>
/// Called one time per game data update, contains all normalized game data,
/// raw data are intentionnally "hidden" under a generic object type (A plugin SHOULD NOT USE IT)
///
/// This method is on the critical path, it must execute as fast as possible and avoid throwing any error
///
/// </summary>
/// <param name="pluginManager"></param>
/// <param name="data">Current game data, including current and previous data frame.</param>
public void DataUpdate(PluginManager pluginManager, ref GameData data)
{
//if (data.GameRunning && data.NewData != null && data.NewData.CarModel != oldCarModelName)
if (data.NewData != null)
{
if (data.SessionStartDate > prevSessionStartTime)
{
// A new car loaded in RBR. Refresh car attributes up-to-date
//SimHub.Logging.Current.Info("[RBRCustomReader] New car selection. Refreshing car attributes");
prevSessionStartTime = data.SessionStartDate.AddSeconds(2);
raceStopWatch.Reset();
updateRaceTimespan = true;
if (string.IsNullOrEmpty(data.NewData.CarModel))
{
RSFCarID = 0;
RSFCarName = "";
}
else
{
// New car selection. Refresh settinsg up-to-date
int rsfCarSlotID = IniFile.ReadInt("cars", "slot", 5, $"{GetRBRGamePath()}\\rallysimfans.ini");
string carsIniFile = $"{GetRBRGamePath()}\\Cars\\Cars.ini";
RSFCarID = IniFile.ReadInt($"Car0{rsfCarSlotID}", "RSFCarID", 0, carsIniFile);
RSFCarName = IniFile.ReadString($"Car0{rsfCarSlotID}", "CarName", "", carsIniFile);
}
}
if (updateRaceTimespan)
{
if (data.NewData.CurrentLapTime.Ticks > 0)
{
// Start the race stopWatch when the RBR "lap" begins
raceStopWatch.Restart();
updateRaceTimespan = false;
}
}
else if (!data.GamePaused)
{
// RBR is NOT in paused state. Start the raceStopWatch if it not yet running
if (!raceStopWatch.IsRunning)
{
raceStopWatch.Start();
}
}
else if (raceStopWatch.IsRunning)
{
// RBR paused. Stop the raceStopWatch
raceStopWatch.Stop();
}
}
}
/// <summary>
/// Called at plugin manager stop, close/dispose anything needed here !
/// Plugins are rebuilt at game change
/// </summary>
/// <param name="pluginManager"></param>
public void End(PluginManager pluginManager)
{
// Do nothing
}
/// <summary>
/// Returns the settings control, return null if no settings control is required
/// </summary>
/// <param name="pluginManager"></param>
/// <returns></returns>
public System.Windows.Controls.Control GetWPFSettingsControl(PluginManager pluginManager)
{
return null;
}
/// <summary>
/// Called once after plugins startup
/// Plugins are rebuilt at game change
/// </summary>
/// <param name="pluginManager"></param>
public void Init(PluginManager pluginManager)
{
SimHub.Logging.Current.Info("[RBRCustomReader] Starting the plugin");
RSFCarID = 0;
RSFCarName = "";
prevSessionStartTime = DateTime.MinValue;
updateRaceTimespan = false;
raceStopWatch = new Stopwatch();
raceStopWatch.Reset();
// Declare a property available in the property list, this gets evaluated "on demand" (when shown or used in formulas)
this.AttachDelegate("RSFCarID", () => RSFCarID);
this.AttachDelegate("RSFCarName", () => RSFCarName);
this.AttachDelegate("ExternalRaceTime", () => raceStopWatch.Elapsed);
}
}
}