22using System . Windows ;
33using System . Windows . Threading ;
44
5- using Microsoft . Win32 ;
5+ using Windows . Win32 ;
6+ using Windows . Win32 . Foundation ;
67
78namespace Bloxstrap
89{
@@ -17,10 +18,13 @@ public partial class App : Application
1718
1819 // used only for communicating between app and menu - use Directories.Base for anything else
1920 public static string BaseDirectory = null ! ;
21+ public static string ? CustomFontLocation ;
2022
2123 public static bool ShouldSaveConfigs { get ; set ; } = false ;
24+
2225 public static bool IsSetupComplete { get ; set ; } = true ;
23- public static bool IsFirstRun { get ; private set ; } = true ;
26+ public static bool IsFirstRun { get ; set ; } = true ;
27+
2428 public static bool IsQuiet { get ; private set ; } = false ;
2529 public static bool IsUninstall { get ; private set ; } = false ;
2630 public static bool IsNoLaunch { get ; private set ; } = false ;
@@ -39,7 +43,11 @@ public partial class App : Application
3943 public static readonly JsonManager < State > State = new ( ) ;
4044 public static readonly FastFlagManager FastFlags = new ( ) ;
4145
42- public static readonly HttpClient HttpClient = new ( new HttpClientLoggingHandler ( new HttpClientHandler { AutomaticDecompression = DecompressionMethods . All } ) ) ;
46+ public static readonly HttpClient HttpClient = new (
47+ new HttpClientLoggingHandler (
48+ new HttpClientHandler { AutomaticDecompression = DecompressionMethods . All }
49+ )
50+ ) ;
4351
4452 public static void Terminate ( ErrorCode exitCode = ErrorCode . ERROR_SUCCESS )
4553 {
@@ -51,7 +59,7 @@ public static void Terminate(ErrorCode exitCode = ErrorCode.ERROR_SUCCESS)
5159
5260 int exitCodeNum = ( int ) exitCode ;
5361
54- Logger . WriteLine ( $ "[ App::Terminate] Terminating with exit code { exitCodeNum } ({ exitCode } )") ;
62+ Logger . WriteLine ( " App::Terminate" , $ " Terminating with exit code { exitCodeNum } ({ exitCode } )") ;
5563
5664 Settings . Save ( ) ;
5765 State . Save ( ) ;
@@ -64,14 +72,16 @@ void GlobalExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs
6472 {
6573 e . Handled = true ;
6674
67- Logger . WriteLine ( "[App::OnStartup] An exception occurred when running the main thread" ) ;
68- Logger . WriteLine ( $ "[App::OnStartup] { e . Exception } ") ;
75+ Logger . WriteLine ( "App::GlobalExceptionHandler" , "An exception occurred" ) ;
6976
7077 FinalizeExceptionHandling ( e . Exception ) ;
7178 }
7279
73- void FinalizeExceptionHandling ( Exception exception )
80+ public static void FinalizeExceptionHandling ( Exception exception , bool log = true )
7481 {
82+ if ( log )
83+ Logger . WriteException ( "App::FinalizeExceptionHandling" , exception ) ;
84+
7585#if DEBUG
7686 throw exception ;
7787#else
@@ -84,94 +94,94 @@ void FinalizeExceptionHandling(Exception exception)
8494
8595 protected override void OnStartup ( StartupEventArgs e )
8696 {
97+ const string LOG_IDENT = "App::OnStartup" ;
98+
8799 base . OnStartup ( e ) ;
88100
89- Logger . WriteLine ( $ "[App::OnStartup] Starting { ProjectName } v{ Version } ") ;
101+ Logger . WriteLine ( LOG_IDENT , $ " Starting { ProjectName } v{ Version } ") ;
90102
91103 if ( String . IsNullOrEmpty ( BuildMetadata . CommitHash ) )
92- Logger . WriteLine ( $ "[App::OnStartup] Compiled { BuildMetadata . Timestamp . ToFriendlyString ( ) } from { BuildMetadata . Machine } ") ;
104+ Logger . WriteLine ( LOG_IDENT , $ " Compiled { BuildMetadata . Timestamp . ToFriendlyString ( ) } from { BuildMetadata . Machine } ") ;
93105 else
94- Logger . WriteLine ( $ "[App::OnStartup] Compiled { BuildMetadata . Timestamp . ToFriendlyString ( ) } from commit { BuildMetadata . CommitHash } ({ BuildMetadata . CommitRef } )") ;
106+ Logger . WriteLine ( LOG_IDENT , $ "Compiled { BuildMetadata . Timestamp . ToFriendlyString ( ) } from commit { BuildMetadata . CommitHash } ({ BuildMetadata . CommitRef } )") ;
107+
108+ Logger . WriteLine ( LOG_IDENT , $ "Loaded from { Paths . Process } ") ;
95109
96110 // To customize application configuration such as set high DPI settings or default font,
97111 // see https://aka.ms/applicationconfiguration.
98112 ApplicationConfiguration . Initialize ( ) ;
99113
100114 LaunchArgs = e . Args ;
101115
102- HttpClient . Timeout = TimeSpan . FromMinutes ( 5 ) ;
116+ HttpClient . Timeout = TimeSpan . FromSeconds ( 30 ) ;
103117 HttpClient . DefaultRequestHeaders . Add ( "User-Agent" , ProjectRepository ) ;
104118
105119 if ( LaunchArgs . Length > 0 )
106120 {
107121 if ( Array . IndexOf ( LaunchArgs , "-preferences" ) != - 1 || Array . IndexOf ( LaunchArgs , "-menu" ) != - 1 )
108122 {
109- Logger . WriteLine ( "[App::OnStartup] Started with IsMenuLaunch flag") ;
123+ Logger . WriteLine ( LOG_IDENT , " Started with IsMenuLaunch flag") ;
110124 IsMenuLaunch = true ;
111125 }
112126
113127 if ( Array . IndexOf ( LaunchArgs , "-quiet" ) != - 1 )
114128 {
115- Logger . WriteLine ( "[App::OnStartup] Started with IsQuiet flag") ;
129+ Logger . WriteLine ( LOG_IDENT , " Started with IsQuiet flag") ;
116130 IsQuiet = true ;
117131 }
118132
119133 if ( Array . IndexOf ( LaunchArgs , "-uninstall" ) != - 1 )
120134 {
121- Logger . WriteLine ( "[App::OnStartup] Started with IsUninstall flag") ;
135+ Logger . WriteLine ( LOG_IDENT , " Started with IsUninstall flag") ;
122136 IsUninstall = true ;
123137 }
124138
125139 if ( Array . IndexOf ( LaunchArgs , "-nolaunch" ) != - 1 )
126140 {
127- Logger . WriteLine ( "[App::OnStartup] Started with IsNoLaunch flag") ;
141+ Logger . WriteLine ( LOG_IDENT , " Started with IsNoLaunch flag") ;
128142 IsNoLaunch = true ;
129143 }
130144
131145 if ( Array . IndexOf ( LaunchArgs , "-upgrade" ) != - 1 )
132146 {
133- Logger . WriteLine ( "[App::OnStartup] Bloxstrap started with IsUpgrade flag") ;
147+ Logger . WriteLine ( LOG_IDENT , " Bloxstrap started with IsUpgrade flag") ;
134148 IsUpgrade = true ;
135149 }
136150 }
137151
138- // check if installed
139- using ( RegistryKey ? registryKey = Registry . CurrentUser . OpenSubKey ( $@ "Software\{ ProjectName } ") )
152+ if ( ! IsMenuLaunch )
140153 {
141- string ? installLocation = null ;
142-
143- if ( registryKey is not null )
144- installLocation = ( string ? ) registryKey . GetValue ( "InstallLocation" ) ;
154+ Logger . WriteLine ( LOG_IDENT , "Performing connectivity check..." ) ;
145155
146- if ( registryKey is null || installLocation is null )
156+ try
147157 {
148- Logger . WriteLine ( "[App::OnStartup] Running first-time install" ) ;
149-
150- BaseDirectory = Path . Combine ( Directories . LocalAppData , ProjectName ) ;
151- Logger . Initialize ( true ) ;
152-
153- if ( ! IsQuiet )
154- {
155- IsSetupComplete = false ;
156- FastFlags . Load ( ) ;
157- Controls . ShowMenu ( ) ;
158- }
158+ HttpClient . GetAsync ( "https://detectportal.firefox.com" ) . Wait ( ) ;
159+ Logger . WriteLine ( LOG_IDENT , "Connectivity check finished" ) ;
159160 }
160- else
161+ catch ( Exception ex )
161162 {
162- IsFirstRun = false ;
163- BaseDirectory = installLocation ;
163+ Logger . WriteLine ( LOG_IDENT , "Connectivity check failed!" ) ;
164+ Logger . WriteException ( LOG_IDENT , ex ) ;
165+
166+ if ( ex . GetType ( ) == typeof ( AggregateException ) )
167+ ex = ex . InnerException ! ;
168+
169+ Controls . ShowConnectivityDialog (
170+ "the internet" ,
171+ $ "Something may be preventing { ProjectName } from connecting to the internet, or you are currently offline. Please check and try again.",
172+ ex
173+ ) ;
174+
175+ Terminate ( ErrorCode . ERROR_CANCELLED ) ;
164176 }
165177 }
166-
167- // exit if we don't click the install button on installation
168- if ( ! IsSetupComplete )
178+
179+ using ( var checker = new InstallChecker ( ) )
169180 {
170- Logger . WriteLine ( "[App::OnStartup] Installation cancelled!" ) ;
171- Terminate ( ErrorCode . ERROR_CANCELLED ) ;
181+ checker . Check ( ) ;
172182 }
173183
174- Directories . Initialize ( BaseDirectory ) ;
184+ Paths . Initialize ( BaseDirectory ) ;
175185
176186 // we shouldn't save settings on the first run until the first installation is finished,
177187 // just in case the user decides to cancel the install
@@ -181,7 +191,7 @@ protected override void OnStartup(StartupEventArgs e)
181191
182192 if ( ! Logger . Initialized )
183193 {
184- Logger . WriteLine ( "[App::OnStartup] Possible duplicate launch detected, terminating.") ;
194+ Logger . WriteLine ( LOG_IDENT , " Possible duplicate launch detected, terminating.") ;
185195 Terminate ( ) ;
186196 }
187197
@@ -195,7 +205,7 @@ protected override void OnStartup(StartupEventArgs e)
195205
196206#if ! DEBUG
197207 if ( ! IsUninstall && ! IsFirstRun )
198- Updater . CheckInstalledVersion ( ) ;
208+ InstallChecker . CheckUpgrade ( ) ;
199209#endif
200210
201211 string commandLine = "" ;
@@ -206,9 +216,9 @@ protected override void OnStartup(StartupEventArgs e)
206216
207217 if ( menuProcess is not null )
208218 {
209- IntPtr handle = menuProcess . MainWindowHandle ;
210- Logger . WriteLine ( $ "[App::OnStartup] Found an already existing menu window with handle { handle } ") ;
211- NativeMethods . SetForegroundWindow ( handle ) ;
219+ var handle = menuProcess . MainWindowHandle ;
220+ Logger . WriteLine ( LOG_IDENT , $ " Found an already existing menu window with handle { handle } ") ;
221+ PInvoke . SetForegroundWindow ( ( HWND ) handle ) ;
212222 }
213223 else
214224 {
@@ -253,13 +263,13 @@ protected override void OnStartup(StartupEventArgs e)
253263 ShouldSaveConfigs = true ;
254264
255265 // start bootstrapper and show the bootstrapper modal if we're not running silently
256- Logger . WriteLine ( $ "[App::OnStartup] Initializing bootstrapper") ;
266+ Logger . WriteLine ( LOG_IDENT , " Initializing bootstrapper") ;
257267 Bootstrapper bootstrapper = new ( commandLine ) ;
258268 IBootstrapperDialog ? dialog = null ;
259269
260270 if ( ! IsQuiet )
261271 {
262- Logger . WriteLine ( $ "[App::OnStartup] Initializing bootstrapper dialog") ;
272+ Logger . WriteLine ( LOG_IDENT , " Initializing bootstrapper dialog") ;
263273 dialog = Settings . Prop . BootstrapperStyle . GetNew ( ) ;
264274 bootstrapper . Dialog = dialog ;
265275 dialog . Bootstrapper = bootstrapper ;
@@ -273,12 +283,12 @@ protected override void OnStartup(StartupEventArgs e)
273283
274284 if ( Settings . Prop . MultiInstanceLaunching )
275285 {
276- Logger . WriteLine ( "[App::OnStartup] Creating singleton mutex") ;
286+ Logger . WriteLine ( LOG_IDENT , " Creating singleton mutex") ;
277287
278288 try
279289 {
280290 Mutex . OpenExisting ( "ROBLOX_singletonMutex" ) ;
281- Logger . WriteLine ( "[App::OnStartup] Warning - singleton mutex already exists!") ;
291+ Logger . WriteLine ( LOG_IDENT , " Warning - singleton mutex already exists!") ;
282292 }
283293 catch
284294 {
@@ -287,22 +297,20 @@ protected override void OnStartup(StartupEventArgs e)
287297 }
288298 }
289299
290- Task bootstrapperTask = Task . Run ( ( ) => bootstrapper . Run ( ) ) ;
291-
292- bootstrapperTask . ContinueWith ( t =>
300+ Task bootstrapperTask = Task . Run ( ( ) => bootstrapper . Run ( ) ) . ContinueWith ( t =>
293301 {
294- Logger . WriteLine ( "[App::OnStartup] Bootstrapper task has finished") ;
302+ Logger . WriteLine ( LOG_IDENT , " Bootstrapper task has finished") ;
295303
296304 // notifyicon is blocking main thread, must be disposed here
297305 NotifyIcon ? . Dispose ( ) ;
298306
299307 if ( t . IsFaulted )
300- Logger . WriteLine ( "[App::OnStartup] An exception occurred when running the bootstrapper") ;
308+ Logger . WriteLine ( LOG_IDENT , " An exception occurred when running the bootstrapper") ;
301309
302310 if ( t . Exception is null )
303311 return ;
304312
305- Logger . WriteLine ( $ "[App::OnStartup] { t . Exception } " ) ;
313+ Logger . WriteException ( LOG_IDENT , t . Exception ) ;
306314
307315 Exception exception = t . Exception ;
308316
@@ -311,7 +319,7 @@ protected override void OnStartup(StartupEventArgs e)
311319 exception = t . Exception . InnerException ! ;
312320#endif
313321
314- FinalizeExceptionHandling ( exception ) ;
322+ FinalizeExceptionHandling ( exception , false ) ;
315323 } ) ;
316324
317325 // this ordering is very important as all wpf windows are shown as modal dialogs, mess it up and you'll end up blocking input to one of them
@@ -320,13 +328,13 @@ protected override void OnStartup(StartupEventArgs e)
320328 if ( ! IsNoLaunch && Settings . Prop . EnableActivityTracking )
321329 NotifyIcon ? . InitializeContextMenu ( ) ;
322330
323- Logger . WriteLine ( $ "[App::OnStartup] Waiting for bootstrapper task to finish") ;
331+ Logger . WriteLine ( LOG_IDENT , " Waiting for bootstrapper task to finish") ;
324332
325333 bootstrapperTask . Wait ( ) ;
326334
327335 if ( singletonMutex is not null )
328336 {
329- Logger . WriteLine ( $ "[App::OnStartup] We have singleton mutex ownership! Running in background until all Roblox processes are closed") ;
337+ Logger . WriteLine ( LOG_IDENT , " We have singleton mutex ownership! Running in background until all Roblox processes are closed") ;
330338
331339 // we've got ownership of the roblox singleton mutex!
332340 // if we stop running, everything will screw up once any more roblox instances launched
@@ -335,7 +343,7 @@ protected override void OnStartup(StartupEventArgs e)
335343 }
336344 }
337345
338- Logger . WriteLine ( $ "[App::OnStartup] Successfully reached end of main thread. Terminating...") ;
346+ Logger . WriteLine ( LOG_IDENT , " Successfully reached end of main thread. Terminating...") ;
339347
340348 Terminate ( ) ;
341349 }
0 commit comments