1818using System ;
1919using System . Collections . Generic ;
2020using System . Diagnostics ;
21- using System . Net ;
22- using Newtonsoft . Json . Linq ;
21+ using System . Net . Http ;
22+ using System . Threading . Tasks ;
23+ using Newtonsoft . Json ;
2324using ORTS . Common ;
2425
2526namespace ORTS . Settings
@@ -43,6 +44,7 @@ public class TelemetryManager
4344 internal static readonly DateTime StateDisabled = new DateTime ( 1899 , 1 , 2 ) ;
4445 internal static readonly DateTime StateEnabledMin = new DateTime ( 1900 , 1 , 1 ) ;
4546
47+ static readonly HttpClient HttpClient = new HttpClient ( ) ;
4648 static readonly Dictionary < TelemetryType , TimeSpan > Frequency = new Dictionary < TelemetryType , TimeSpan >
4749 {
4850 { TelemetryType . System , TimeSpan . FromDays ( 7 ) } ,
@@ -67,6 +69,8 @@ public TelemetryManager(TelemetrySettings settings)
6769 {
6870 RandomNumber1000 . Value = new Random ( ) . Next ( 1 , 1001 ) ;
6971 }
72+
73+ HttpClient . DefaultRequestHeaders . Add ( "User-Agent" , $ "{ ApplicationInfo . ProductName } /{ VersionInfo . VersionOrBuild } ") ;
7074 }
7175
7276 /// <summary>
@@ -95,5 +99,53 @@ public void SetState(TelemetryType type, TelemetryState state)
9599 State [ type ] . Value = state == TelemetryState . Enabled ? StateEnabledMin : state == TelemetryState . Disabled ? StateDisabled : StateUndecided ;
96100 }
97101 }
102+
103+ /// <summary>
104+ /// Returns true if the specified telemetry type is enabled and due to be sent.
105+ /// </summary>
106+ /// <param name="type">Which telemetry type to check</param>
107+ /// <returns>Whether to send the telemetry</returns>
108+ public bool IsDue ( TelemetryType type )
109+ {
110+ Debug . Assert ( State . ContainsKey ( type ) , "Telemetry type is not valid" ) ;
111+ if ( GetState ( type ) != TelemetryState . Enabled ) return false ;
112+ // If the frequency is not set, it is always due (i.e. not rate limited)
113+ if ( ! Frequency . ContainsKey ( type ) ) return true ;
114+ var lastPeriod = State [ type ] . Value . Ticks / Frequency [ type ] . Ticks ;
115+ var thisPeriod = DateTime . Now . Ticks / Frequency [ type ] . Ticks ;
116+ return lastPeriod != thisPeriod ;
117+ }
118+
119+ /// <summary>
120+ /// Submits the specified telemetry type if it is enabled and due to be sent.
121+ /// </summary>
122+ /// <param name="type">Which telemetry type to submit</param>
123+ /// <param name="generator">Function to generate the telemetry data</param>
124+ public async Task SubmitIfDue ( TelemetryType type , Func < object > generator )
125+ {
126+ Debug . Assert ( State . ContainsKey ( type ) , "Telemetry type is not valid" ) ;
127+ if ( ! IsDue ( type ) ) return ;
128+ var url = $ "{ Settings . ServerURL } /api/collect/{ type . ToString ( ) . ToLowerInvariant ( ) } ";
129+ var data = JsonConvert . SerializeObject ( generator ( ) ) ;
130+ try
131+ {
132+ await HttpClient . PostAsync ( url , new StringContent ( data , System . Text . Encoding . UTF8 , "application/json" ) ) ;
133+ SetSent ( type ) ;
134+ }
135+ catch ( Exception )
136+ {
137+ // FIXME:
138+ }
139+ }
140+
141+ /// <summary>
142+ /// Sets the specified telemetry type as sent, recording the current date/time.
143+ /// </summary>
144+ /// <param name="type">Which telemetry type to set</param>
145+ public void SetSent ( TelemetryType type )
146+ {
147+ Debug . Assert ( State . ContainsKey ( type ) , "Telemetry type is not valid" ) ;
148+ State [ type ] . Value = DateTime . Now ;
149+ }
98150 }
99151}
0 commit comments