2222using System . Text ;
2323using Newtonsoft . Json ;
2424using ORTS . Common ;
25+ using ORTS . Settings ;
2526using ORTS . Updater ;
2627using static ORTS . Common . SystemInfo ;
2728using static ORTS . NotificationPage ;
@@ -44,11 +45,13 @@ class NotificationManager
4445
4546 private MainForm MainForm ; // Needed so we can add controls to the NotificationPage
4647 private UpdateManager UpdateManager ;
48+ private UserSettings Settings ;
4749
48- public NotificationManager ( MainForm mainForm , UpdateManager updateManager )
50+ public NotificationManager ( MainForm mainForm , UpdateManager updateManager , UserSettings settings )
4951 {
5052 MainForm = mainForm ;
5153 this . UpdateManager = updateManager ;
54+ this . Settings = settings ;
5255 }
5356
5457 // Make this a background task
@@ -72,18 +75,23 @@ public void CheckNotifications()
7275
7376 public Notifications GetNotifications ( )
7477 {
75- //// Input from local file
76- //var filename = @"c:\_tmp\notifications .json";
78+ String notificationsSerial ;
79+ // To support testing of a new menu .json file, GetNotifications tests for a local file first and uses that if present.
7780
78- //// read file into a string and deserialize JSON into Notifications
79- //var notificationsSerial = File.ReadAllText(filename);
80-
81-
82- // Input from remote file
83- var notificationsSerial = GetRemoteJson ( ) ;
81+ var filename = @"menu.json" ;
82+ if ( System . IO . File . Exists ( filename ) )
83+ {
84+ // Input from local file into a string
85+ notificationsSerial = System . IO . File . ReadAllText ( filename ) ;
86+ }
87+ else
88+ {
89+ // Input from remote file into a string
90+ notificationsSerial = GetRemoteJson ( ) ;
91+ }
8492
85- var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling . Auto } ;
86- var jsonInput = JsonConvert . DeserializeObject < Notifications > ( notificationsSerial , settings ) ;
93+ var jsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling . Auto } ;
94+ var jsonInput = JsonConvert . DeserializeObject < Notifications > ( notificationsSerial , jsonSettings ) ;
8795
8896 return jsonInput ;
8997 }
@@ -103,6 +111,10 @@ private string GetRemoteJson()
103111
104112 // Trial for glTD and PBR graphics
105113 //return client.DownloadString(new Uri("https://wepp.co.uk/openrails/notifications/menu_testing_direct3d.json"));
114+
115+ // Trial for UserSettings
116+ //return client.DownloadString(new Uri("https://wepp.co.uk/openrails/notifications/menu_testing_user_settings.json"));
117+
106118 return client . DownloadString ( new Uri ( "https://wepp.co.uk/openrails/notifications/menu.json" ) ) ;
107119 }
108120
@@ -128,7 +140,7 @@ void SetUpdateNotificationPage()
128140 if ( UpdateManager . LastCheckError != null || Error != null )
129141 {
130142 NewPageCount = 0 ;
131- var message = ( UpdateManager . LastCheckError != null )
143+ var message = ( UpdateManager . LastCheckError != null )
132144 ? UpdateManager . LastCheckError . Message
133145 : Error . Message ;
134146
@@ -159,32 +171,65 @@ void SetUpdateNotificationPage()
159171 AddItemToPage ( page , item ) ;
160172 }
161173
162- // Check constraints
174+ // Check constraints if there is a MetList.
175+ // If a check fails then its UnmetList is added to the page, otherwise the MetList is added.
176+ if ( n . MetLists != null || n . MetLists . ItemList . Count == 0 )
177+ {
178+ CheckConstraints ( page , n ) ;
179+ }
180+
181+ foreach ( var item in n . SuffixItemList )
182+ {
183+ AddItemToPage ( page , item ) ;
184+ }
185+ PageList . Add ( page ) ;
186+ }
187+
188+ /// <summary>
189+ /// IncludesAnyOf() implements D == d OR E == e OR ...
190+ /// ExcludesAllOf() implements A != a AND B != b AND ...
191+ /// CheckConstraints() implements ExcludesAnyOf() AND IncludesAnyOf(), but all parts are optional.
192+ /// </summary>
193+ /// <param name="page"></param>
194+ /// <param name="n"></param>
195+ private void CheckConstraints ( NotificationPage page , Notification n )
196+ {
163197 var excludesMet = true ;
164198 var includesMet = true ;
165199 foreach ( var nc in n . MetLists . CheckIdList )
166200 {
167201 foreach ( var c in Notifications . CheckList . Where ( c => c . Id == nc . Id ) )
168202 {
169- var checkFailed = CheckExcludes ( c ) ;
170- excludesMet = ( checkFailed == null ) ;
171- if ( excludesMet == false )
203+ if ( c . ExcludesAllOf == null ) // ExcludesAnyOf is optional
204+ excludesMet = true ;
205+ else
172206 {
173- foreach ( var item in checkFailed . UnmetItemList )
207+ var checkFailed = CheckExcludes ( c ) ;
208+ excludesMet = ( checkFailed == null ) ;
209+ if ( excludesMet == false )
174210 {
175- AddItemToPage ( page , item ) ;
211+ foreach ( var item in checkFailed . UnmetItemList )
212+ {
213+ AddItemToPage ( page , item ) ;
214+ }
215+ break ;
176216 }
177- break ;
178217 }
179218
180- includesMet = ( c . IncludesAnyOf . Count == 0 || CheckIncludes ( c ) != null ) ;
181- if ( includesMet == false )
219+ if ( c . IncludesAnyOf == null ) // IncludesAnyOf is optional
220+ includesMet = true ;
221+ else
182222 {
183- foreach ( var item in c . UnmetItemList )
223+ var checkPassed = CheckIncludes ( c ) ;
224+ includesMet = ( checkPassed != null ) ;
225+ if ( includesMet == false )
184226 {
185- AddItemToPage ( page , item ) ;
227+ foreach ( var item in c . UnmetItemList )
228+ {
229+ AddItemToPage ( page , item ) ;
230+ }
231+ break ;
186232 }
187- break ;
188233 }
189234 }
190235 if ( excludesMet == false || includesMet == false )
@@ -197,12 +242,6 @@ void SetUpdateNotificationPage()
197242 AddItemToPage ( page , item ) ;
198243 }
199244 }
200-
201- foreach ( var item in n . SuffixItemList )
202- {
203- AddItemToPage ( page , item ) ;
204- }
205- PageList . Add ( page ) ;
206245 }
207246
208247 private void AddItemToPage ( NotificationPage page , Item item )
@@ -236,12 +275,9 @@ private void AddItemToPage(NotificationPage page, Item item)
236275 /// <returns></returns>
237276 private Check CheckExcludes ( Check check )
238277 {
239- if ( check . ExcludesAllOf == null )
240- return null ;
241-
242278 foreach ( var c in check . ExcludesAllOf )
243279 {
244- if ( c is Contains )
280+ if ( c is Contains ) // Other criteria might be added such as greater_than and less_than
245281 {
246282 return CheckContains ( check , c ) ;
247283 }
@@ -256,12 +292,12 @@ private Check CheckExcludes(Check check)
256292 /// <returns></returns>
257293 private Check CheckIncludes ( Check check )
258294 {
259- if ( check . IncludesAnyOf == null )
260- return null ;
261-
262295 foreach ( var c in check . IncludesAnyOf )
263296 {
264- return CheckContains ( check , c ) ;
297+ if ( c is Contains )
298+ {
299+ return CheckContains ( check , c ) ;
300+ }
265301 }
266302 return null ;
267303 }
@@ -285,12 +321,36 @@ private Check CheckContains(Check check, Criteria c)
285321 if ( system . IndexOf ( c . Value , StringComparison . OrdinalIgnoreCase ) > - 1 )
286322 return check ;
287323 break ;
288- default : // Any check that is not recognised succeeds.
289- return null ;
324+ default :
325+ if ( GetSetting ( c . Name ) . IndexOf ( c . Value , StringComparison . OrdinalIgnoreCase ) > - 1 )
326+ {
327+ return check ;
328+ }
329+ if ( c . Name . IndexOf ( c . Value , StringComparison . OrdinalIgnoreCase ) > - 1 )
330+ {
331+ return check ;
332+ }
333+ return null ; // Any check that is not recognised is skipped.
290334 }
291335 return null ;
292336 }
293337
338+ /// <summary>
339+ /// Gets the property value of a UserSetting. The setting must match case as in "Setting.SimpleControlPhysics".
340+ /// </summary>
341+ /// <param name="settingText"></param>
342+ /// <returns></returns>
343+ string GetSetting ( string settingText )
344+ {
345+ var nameArray = settingText . Split ( '.' ) ; // 2 elements: "Settings, "<property>", e.g. "SimpleControlPhysics"
346+ if ( nameArray [ 0 ] == "Settings" && nameArray . Length == 2 )
347+ {
348+ return Settings . GetType ( ) . GetProperty ( nameArray [ 1 ] ) ? . GetValue ( Settings ) . ToString ( ) ?? "" ;
349+ }
350+ return "" ;
351+ }
352+
353+
294354 /// <summary>
295355 /// Drop any notifications for the channel not selected
296356 /// </summary>
@@ -406,6 +466,10 @@ private string ReplaceParameter(string field)
406466 replacement = string . Join ( "," , Direct3DFeatureLevels ) ;
407467 break ;
408468 default :
469+ var propertyValue = GetSetting ( field ) ;
470+ replacement = ( propertyValue == "" )
471+ ? field // strings that are not recognised are not replaced.
472+ : propertyValue ;
409473 break ;
410474 }
411475
0 commit comments