Make logging more consistent

consistent prefix names, and logging exceptions in english
This commit is contained in:
pizzaboxer 2023-07-25 19:08:43 +01:00
parent b5f4017326
commit 1df1a8495c
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
18 changed files with 258 additions and 175 deletions

View File

@ -53,7 +53,7 @@ namespace Bloxstrap
int exitCodeNum = (int)exitCode; int exitCodeNum = (int)exitCode;
Logger.WriteLine($"[App::Terminate] Terminating with exit code {exitCodeNum} ({exitCode})"); Logger.WriteLine("App::Terminate", $"Terminating with exit code {exitCodeNum} ({exitCode})");
Settings.Save(); Settings.Save();
State.Save(); State.Save();
@ -66,8 +66,8 @@ namespace Bloxstrap
{ {
e.Handled = true; e.Handled = true;
Logger.WriteLine("[App::OnStartup] An exception occurred when running the main thread"); Logger.WriteLine("App::GlobalExceptionHandler", "An exception occurred");
Logger.WriteLine($"[App::OnStartup] {e.Exception}"); Logger.WriteLine("App::GlobalExceptionHandler", $"{e.Exception}");
FinalizeExceptionHandling(e.Exception); FinalizeExceptionHandling(e.Exception);
} }
@ -86,14 +86,16 @@ namespace Bloxstrap
protected override void OnStartup(StartupEventArgs e) protected override void OnStartup(StartupEventArgs e)
{ {
const string LOG_IDENT = "App::OnStartup";
base.OnStartup(e); base.OnStartup(e);
Logger.WriteLine($"[App::OnStartup] Starting {ProjectName} v{Version}"); Logger.WriteLine(LOG_IDENT, $"Starting {ProjectName} v{Version}");
if (String.IsNullOrEmpty(BuildMetadata.CommitHash)) if (String.IsNullOrEmpty(BuildMetadata.CommitHash))
Logger.WriteLine($"[App::OnStartup] Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from {BuildMetadata.Machine}"); Logger.WriteLine(LOG_IDENT, $"Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from {BuildMetadata.Machine}");
else else
Logger.WriteLine($"[App::OnStartup] Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from commit {BuildMetadata.CommitHash} ({BuildMetadata.CommitRef})"); Logger.WriteLine(LOG_IDENT, $"Compiled {BuildMetadata.Timestamp.ToFriendlyString()} from commit {BuildMetadata.CommitHash} ({BuildMetadata.CommitRef})");
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
@ -108,31 +110,31 @@ namespace Bloxstrap
{ {
if (Array.IndexOf(LaunchArgs, "-preferences") != -1 || Array.IndexOf(LaunchArgs, "-menu") != -1) if (Array.IndexOf(LaunchArgs, "-preferences") != -1 || Array.IndexOf(LaunchArgs, "-menu") != -1)
{ {
Logger.WriteLine("[App::OnStartup] Started with IsMenuLaunch flag"); Logger.WriteLine(LOG_IDENT, "Started with IsMenuLaunch flag");
IsMenuLaunch = true; IsMenuLaunch = true;
} }
if (Array.IndexOf(LaunchArgs, "-quiet") != -1) if (Array.IndexOf(LaunchArgs, "-quiet") != -1)
{ {
Logger.WriteLine("[App::OnStartup] Started with IsQuiet flag"); Logger.WriteLine(LOG_IDENT, "Started with IsQuiet flag");
IsQuiet = true; IsQuiet = true;
} }
if (Array.IndexOf(LaunchArgs, "-uninstall") != -1) if (Array.IndexOf(LaunchArgs, "-uninstall") != -1)
{ {
Logger.WriteLine("[App::OnStartup] Started with IsUninstall flag"); Logger.WriteLine(LOG_IDENT, "Started with IsUninstall flag");
IsUninstall = true; IsUninstall = true;
} }
if (Array.IndexOf(LaunchArgs, "-nolaunch") != -1) if (Array.IndexOf(LaunchArgs, "-nolaunch") != -1)
{ {
Logger.WriteLine("[App::OnStartup] Started with IsNoLaunch flag"); Logger.WriteLine(LOG_IDENT, "Started with IsNoLaunch flag");
IsNoLaunch = true; IsNoLaunch = true;
} }
if (Array.IndexOf(LaunchArgs, "-upgrade") != -1) if (Array.IndexOf(LaunchArgs, "-upgrade") != -1)
{ {
Logger.WriteLine("[App::OnStartup] Bloxstrap started with IsUpgrade flag"); Logger.WriteLine(LOG_IDENT, "Bloxstrap started with IsUpgrade flag");
IsUpgrade = true; IsUpgrade = true;
} }
} }
@ -147,7 +149,7 @@ namespace Bloxstrap
if (registryKey is null || installLocation is null) if (registryKey is null || installLocation is null)
{ {
Logger.WriteLine("[App::OnStartup] Running first-time install"); Logger.WriteLine(LOG_IDENT, "Running first-time install");
BaseDirectory = Path.Combine(Directories.LocalAppData, ProjectName); BaseDirectory = Path.Combine(Directories.LocalAppData, ProjectName);
Logger.Initialize(true); Logger.Initialize(true);
@ -169,7 +171,7 @@ namespace Bloxstrap
// exit if we don't click the install button on installation // exit if we don't click the install button on installation
if (!IsSetupComplete) if (!IsSetupComplete)
{ {
Logger.WriteLine("[App::OnStartup] Installation cancelled!"); Logger.WriteLine(LOG_IDENT, "Installation cancelled!");
Terminate(ErrorCode.ERROR_CANCELLED); Terminate(ErrorCode.ERROR_CANCELLED);
} }
@ -183,7 +185,7 @@ namespace Bloxstrap
if (!Logger.Initialized) if (!Logger.Initialized)
{ {
Logger.WriteLine("[App::OnStartup] Possible duplicate launch detected, terminating."); Logger.WriteLine(LOG_IDENT, "Possible duplicate launch detected, terminating.");
Terminate(); Terminate();
} }
@ -209,7 +211,7 @@ namespace Bloxstrap
if (menuProcess is not null) if (menuProcess is not null)
{ {
IntPtr handle = menuProcess.MainWindowHandle; IntPtr handle = menuProcess.MainWindowHandle;
Logger.WriteLine($"[App::OnStartup] Found an already existing menu window with handle {handle}"); Logger.WriteLine(LOG_IDENT, $"Found an already existing menu window with handle {handle}");
NativeMethods.SetForegroundWindow(handle); NativeMethods.SetForegroundWindow(handle);
} }
else else
@ -255,13 +257,13 @@ namespace Bloxstrap
ShouldSaveConfigs = true; ShouldSaveConfigs = true;
// start bootstrapper and show the bootstrapper modal if we're not running silently // start bootstrapper and show the bootstrapper modal if we're not running silently
Logger.WriteLine($"[App::OnStartup] Initializing bootstrapper"); Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper");
Bootstrapper bootstrapper = new(commandLine); Bootstrapper bootstrapper = new(commandLine);
IBootstrapperDialog? dialog = null; IBootstrapperDialog? dialog = null;
if (!IsQuiet) if (!IsQuiet)
{ {
Logger.WriteLine($"[App::OnStartup] Initializing bootstrapper dialog"); Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper dialog");
dialog = Settings.Prop.BootstrapperStyle.GetNew(); dialog = Settings.Prop.BootstrapperStyle.GetNew();
bootstrapper.Dialog = dialog; bootstrapper.Dialog = dialog;
dialog.Bootstrapper = bootstrapper; dialog.Bootstrapper = bootstrapper;
@ -275,12 +277,12 @@ namespace Bloxstrap
if (Settings.Prop.MultiInstanceLaunching) if (Settings.Prop.MultiInstanceLaunching)
{ {
Logger.WriteLine("[App::OnStartup] Creating singleton mutex"); Logger.WriteLine(LOG_IDENT, "Creating singleton mutex");
try try
{ {
Mutex.OpenExisting("ROBLOX_singletonMutex"); Mutex.OpenExisting("ROBLOX_singletonMutex");
Logger.WriteLine("[App::OnStartup] Warning - singleton mutex already exists!"); Logger.WriteLine(LOG_IDENT, "Warning - singleton mutex already exists!");
} }
catch catch
{ {
@ -293,18 +295,18 @@ namespace Bloxstrap
bootstrapperTask.ContinueWith(t => bootstrapperTask.ContinueWith(t =>
{ {
Logger.WriteLine("[App::OnStartup] Bootstrapper task has finished"); Logger.WriteLine(LOG_IDENT, "Bootstrapper task has finished");
// notifyicon is blocking main thread, must be disposed here // notifyicon is blocking main thread, must be disposed here
NotifyIcon?.Dispose(); NotifyIcon?.Dispose();
if (t.IsFaulted) if (t.IsFaulted)
Logger.WriteLine("[App::OnStartup] An exception occurred when running the bootstrapper"); Logger.WriteLine(LOG_IDENT, "An exception occurred when running the bootstrapper");
if (t.Exception is null) if (t.Exception is null)
return; return;
Logger.WriteLine($"[App::OnStartup] {t.Exception}"); Logger.WriteLine(LOG_IDENT, $"{t.Exception}");
Exception exception = t.Exception; Exception exception = t.Exception;
@ -322,13 +324,13 @@ namespace Bloxstrap
if (!IsNoLaunch && Settings.Prop.EnableActivityTracking) if (!IsNoLaunch && Settings.Prop.EnableActivityTracking)
NotifyIcon?.InitializeContextMenu(); NotifyIcon?.InitializeContextMenu();
Logger.WriteLine($"[App::OnStartup] Waiting for bootstrapper task to finish"); Logger.WriteLine(LOG_IDENT, "Waiting for bootstrapper task to finish");
bootstrapperTask.Wait(); bootstrapperTask.Wait();
if (singletonMutex is not null) if (singletonMutex is not null)
{ {
Logger.WriteLine($"[App::OnStartup] We have singleton mutex ownership! Running in background until all Roblox processes are closed"); Logger.WriteLine(LOG_IDENT, "We have singleton mutex ownership! Running in background until all Roblox processes are closed");
// we've got ownership of the roblox singleton mutex! // we've got ownership of the roblox singleton mutex!
// if we stop running, everything will screw up once any more roblox instances launched // if we stop running, everything will screw up once any more roblox instances launched
@ -337,7 +339,7 @@ namespace Bloxstrap
} }
} }
Logger.WriteLine($"[App::OnStartup] Successfully reached end of main thread. Terminating..."); Logger.WriteLine(LOG_IDENT, "Successfully reached end of main thread. Terminating...");
Terminate(); Terminate();
} }

View File

@ -79,7 +79,7 @@ namespace Bloxstrap
private void SetStatus(string message) private void SetStatus(string message)
{ {
App.Logger.WriteLine($"[Bootstrapper::SetStatus] {message}"); App.Logger.WriteLine("Bootstrapper::SetStatus", message);
// yea idk // yea idk
if (App.Settings.Prop.BootstrapperStyle == BootstrapperStyle.ByfronDialog) if (App.Settings.Prop.BootstrapperStyle == BootstrapperStyle.ByfronDialog)
@ -104,7 +104,9 @@ namespace Bloxstrap
public async Task Run() public async Task Run()
{ {
App.Logger.WriteLine("[Bootstrapper::Run] Running bootstrapper"); const string LOG_IDENT = "Bootstrapper::Run";
App.Logger.WriteLine(LOG_IDENT, "Running bootstrapper");
if (App.IsUninstall) if (App.IsUninstall)
{ {
@ -125,7 +127,7 @@ namespace Bloxstrap
try try
{ {
Mutex.OpenExisting("Bloxstrap_BootstrapperMutex").Close(); Mutex.OpenExisting("Bloxstrap_BootstrapperMutex").Close();
App.Logger.WriteLine("[Bootstrapper::Run] Bloxstrap_BootstrapperMutex mutex exists, waiting..."); App.Logger.WriteLine(LOG_IDENT, "Bloxstrap_BootstrapperMutex mutex exists, waiting...");
mutexExists = true; mutexExists = true;
} }
catch (Exception) catch (Exception)
@ -196,6 +198,8 @@ namespace Bloxstrap
private async Task StartRoblox() private async Task StartRoblox()
{ {
const string LOG_IDENT = "Bootstrapper::StartRoblox";
SetStatus("Starting Roblox..."); SetStatus("Starting Roblox...");
if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch) if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
@ -235,7 +239,7 @@ namespace Bloxstrap
RobloxActivity? activityWatcher = null; RobloxActivity? activityWatcher = null;
DiscordRichPresence? richPresence = null; DiscordRichPresence? richPresence = null;
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Started Roblox (PID {gameClientPid})"); App.Logger.WriteLine(LOG_IDENT, $"Started Roblox (PID {gameClientPid})");
using (SystemEvent startEvent = new("www.roblox.com/robloxStartedEvent")) using (SystemEvent startEvent = new("www.roblox.com/robloxStartedEvent"))
{ {
@ -256,7 +260,7 @@ namespace Bloxstrap
if (App.Settings.Prop.UseDiscordRichPresence) if (App.Settings.Prop.UseDiscordRichPresence)
{ {
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Using Discord Rich Presence"); App.Logger.WriteLine(LOG_IDENT, "Using Discord Rich Presence");
richPresence = new(activityWatcher); richPresence = new(activityWatcher);
App.NotifyIcon?.SetRichPresenceHandler(richPresence); App.NotifyIcon?.SetRichPresenceHandler(richPresence);
@ -266,7 +270,7 @@ namespace Bloxstrap
// launch custom integrations now // launch custom integrations now
foreach (CustomIntegration integration in App.Settings.Prop.CustomIntegrations) foreach (CustomIntegration integration in App.Settings.Prop.CustomIntegrations)
{ {
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Launching custom integration '{integration.Name}' ({integration.Location} {integration.LaunchArgs} - autoclose is {integration.AutoClose})"); App.Logger.WriteLine(LOG_IDENT, $"Launching custom integration '{integration.Name}' ({integration.Location} {integration.LaunchArgs} - autoclose is {integration.AutoClose})");
try try
{ {
@ -280,7 +284,8 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Failed to launch integration '{integration.Name}'! ({ex.Message})"); App.Logger.WriteLine(LOG_IDENT, $"Failed to launch integration '{integration.Name}'!");
App.Logger.WriteLine(LOG_IDENT, $"{ex.Message}");
} }
} }
@ -294,12 +299,12 @@ namespace Bloxstrap
activityWatcher?.StartWatcher(); activityWatcher?.StartWatcher();
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Waiting for Roblox to close"); App.Logger.WriteLine(LOG_IDENT, "Waiting for Roblox to close");
while (Process.GetProcesses().Any(x => x.Id == gameClientPid)) while (Process.GetProcesses().Any(x => x.Id == gameClientPid))
await Task.Delay(1000); await Task.Delay(1000);
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Roblox has exited"); App.Logger.WriteLine(LOG_IDENT, $"Roblox has exited");
richPresence?.Dispose(); richPresence?.Dispose();
@ -308,20 +313,22 @@ namespace Bloxstrap
if (process.HasExited) if (process.HasExited)
continue; continue;
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Autoclosing process '{process.ProcessName}' (PID {process.Id})"); App.Logger.WriteLine(LOG_IDENT, $"Autoclosing process '{process.ProcessName}' (PID {process.Id})");
process.Kill(); process.Kill();
} }
} }
public void CancelInstall() public void CancelInstall()
{ {
const string LOG_IDENT = "Bootstrapper::CancelInstall";
if (!_isInstalling) if (!_isInstalling)
{ {
App.Terminate(ErrorCode.ERROR_CANCELLED); App.Terminate(ErrorCode.ERROR_CANCELLED);
return; return;
} }
App.Logger.WriteLine("[Bootstrapper::CancelInstall] Cancelling install..."); App.Logger.WriteLine(LOG_IDENT, "Cancelling install...");
_cancelTokenSource.Cancel(); _cancelTokenSource.Cancel();
_cancelFired = true; _cancelFired = true;
@ -336,8 +343,8 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine("[Bootstrapper::CancelInstall] Could not fully clean up installation!"); App.Logger.WriteLine(LOG_IDENT, "Could not fully clean up installation!");
App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {ex}"); App.Logger.WriteException(LOG_IDENT, ex);
} }
App.Terminate(ErrorCode.ERROR_CANCELLED); App.Terminate(ErrorCode.ERROR_CANCELLED);
@ -347,6 +354,8 @@ namespace Bloxstrap
#region App Install #region App Install
public static void Register() public static void Register()
{ {
const string LOG_IDENT = "Bootstrapper::Register";
using (RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}")) using (RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"))
{ {
applicationKey.SetValue("InstallLocation", Directories.Base); applicationKey.SetValue("InstallLocation", Directories.Base);
@ -372,12 +381,14 @@ namespace Bloxstrap
uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest"); uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest");
} }
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application"); App.Logger.WriteLine(LOG_IDENT, "Registered application");
} }
public void RegisterProgramSize() public void RegisterProgramSize()
{ {
App.Logger.WriteLine("[Bootstrapper::RegisterProgramSize] Registering approximate program size..."); const string LOG_IDENT = "Bootstrapper::RegisterProgramSize";
App.Logger.WriteLine(LOG_IDENT, "Registering approximate program size...");
using RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{App.ProjectName}"); using RegistryKey uninstallKey = Registry.CurrentUser.CreateSubKey($"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{App.ProjectName}");
@ -386,11 +397,13 @@ namespace Bloxstrap
uninstallKey.SetValue("EstimatedSize", totalSize); uninstallKey.SetValue("EstimatedSize", totalSize);
App.Logger.WriteLine($"[Bootstrapper::RegisterProgramSize] Registered as {totalSize} KB"); App.Logger.WriteLine(LOG_IDENT, $"Registered as {totalSize} KB");
} }
private void CheckInstallMigration() private void CheckInstallMigration()
{ {
const string LOG_IDENT = "Bootstrapper::CheckInstallMigration";
// check if we've changed our install location since the last time we started // check if we've changed our install location since the last time we started
// in which case, we'll have to copy over all our folders so we don't lose any mods and stuff // in which case, we'll have to copy over all our folders so we don't lose any mods and stuff
@ -405,7 +418,7 @@ namespace Bloxstrap
if (Directory.Exists(oldInstallLocation)) if (Directory.Exists(oldInstallLocation))
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Moving all files in {oldInstallLocation} to {Directories.Base}..."); App.Logger.WriteLine(LOG_IDENT, $"Moving all files in {oldInstallLocation} to {Directories.Base}...");
foreach (string oldFileLocation in Directory.GetFiles(oldInstallLocation, "*.*", SearchOption.AllDirectories)) foreach (string oldFileLocation in Directory.GetFiles(oldInstallLocation, "*.*", SearchOption.AllDirectories))
{ {
@ -422,18 +435,18 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to move {oldFileLocation} to {newFileLocation}! {ex}"); App.Logger.WriteLine(LOG_IDENT, $"Failed to move {oldFileLocation} to {newFileLocation}! {ex}");
} }
} }
try try
{ {
Directory.Delete(oldInstallLocation, true); Directory.Delete(oldInstallLocation, true);
App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Deleted old install location"); App.Logger.WriteLine(LOG_IDENT, "Deleted old install location");
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckInstallMigration] Failed to delete old install location! {ex}"); App.Logger.WriteLine(LOG_IDENT, $"Failed to delete old install location! {ex}");
} }
} }
@ -449,12 +462,14 @@ namespace Bloxstrap
App.Settings.Prop.CreateDesktopIcon = true; App.Settings.Prop.CreateDesktopIcon = true;
} }
App.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Finished migrating install location!"); App.Logger.WriteLine(LOG_IDENT, "Finished migrating install location!");
} }
public static void CheckInstall() public static void CheckInstall()
{ {
App.Logger.WriteLine("[Bootstrapper::CheckInstall] Checking install"); const string LOG_IDENT = "Bootstrapper::CheckInstall";
App.Logger.WriteLine(LOG_IDENT, "Checking install");
// check if launch uri is set to our bootstrapper // check if launch uri is set to our bootstrapper
// this doesn't go under register, so we check every launch // this doesn't go under register, so we check every launch
@ -509,8 +524,8 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine("[Bootstrapper::CheckInstall] Could not create desktop shortcut, aborting"); App.Logger.WriteLine(LOG_IDENT, "Could not create desktop shortcut, aborting");
App.Logger.WriteLine($"[Bootstrapper::CheckInstall] {ex}"); App.Logger.WriteException(LOG_IDENT, ex);
} }
} }
@ -521,14 +536,16 @@ namespace Bloxstrap
private async Task CheckForUpdates() private async Task CheckForUpdates()
{ {
const string LOG_IDENT = "Bootstrapper::CheckForUpdates";
// don't update if there's another instance running (likely running in the background) // don't update if there's another instance running (likely running in the background)
if (Process.GetProcessesByName(App.ProjectName).Count() > 1) if (Process.GetProcessesByName(App.ProjectName).Count() > 1)
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] More than one Bloxstrap instance running, aborting update check"); App.Logger.WriteLine(LOG_IDENT, $"More than one Bloxstrap instance running, aborting update check");
return; return;
} }
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Checking for updates..."); App.Logger.WriteLine(LOG_IDENT, $"Checking for updates...");
GithubRelease? releaseInfo; GithubRelease? releaseInfo;
try try
@ -537,13 +554,13 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Failed to fetch releases: {ex}"); App.Logger.WriteLine(LOG_IDENT, $"Failed to fetch releases: {ex}");
return; return;
} }
if (releaseInfo is null || releaseInfo.Assets is null) if (releaseInfo is null || releaseInfo.Assets is null)
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] No updates found"); App.Logger.WriteLine(LOG_IDENT, $"No updates found");
return; return;
} }
@ -552,7 +569,7 @@ namespace Bloxstrap
// check if we aren't using a deployed build, so we can update to one if a new version comes out // check if we aren't using a deployed build, so we can update to one if a new version comes out
if (versionComparison == 0 && App.BuildMetadata.CommitRef.StartsWith("tag") || versionComparison == 1) if (versionComparison == 0 && App.BuildMetadata.CommitRef.StartsWith("tag") || versionComparison == 1)
{ {
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] No updates found"); App.Logger.WriteLine(LOG_IDENT, $"No updates found");
return; return;
} }
@ -563,7 +580,7 @@ namespace Bloxstrap
GithubReleaseAsset asset = releaseInfo.Assets[0]; GithubReleaseAsset asset = releaseInfo.Assets[0];
string downloadLocation = Path.Combine(Directories.LocalAppData, "Temp", asset.Name); string downloadLocation = Path.Combine(Directories.LocalAppData, "Temp", asset.Name);
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Downloading {releaseInfo.TagName}..."); App.Logger.WriteLine(LOG_IDENT, $"Downloading {releaseInfo.TagName}...");
if (!File.Exists(downloadLocation)) if (!File.Exists(downloadLocation))
{ {
@ -573,7 +590,7 @@ namespace Bloxstrap
await response.Content.CopyToAsync(fileStream); await response.Content.CopyToAsync(fileStream);
} }
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Starting {releaseInfo.TagName}..."); App.Logger.WriteLine(LOG_IDENT, $"Starting {releaseInfo.TagName}...");
ProcessStartInfo startInfo = new() ProcessStartInfo startInfo = new()
{ {
@ -593,10 +610,12 @@ namespace Bloxstrap
private void Uninstall() private void Uninstall()
{ {
const string LOG_IDENT = "Bootstrapper::Uninstall";
// prompt to shutdown roblox if its currently running // prompt to shutdown roblox if its currently running
if (Process.GetProcessesByName(App.RobloxAppName).Any()) if (Process.GetProcessesByName(App.RobloxAppName).Any())
{ {
App.Logger.WriteLine($"[Bootstrapper::Uninstall] Prompting to shut down all open Roblox instances"); App.Logger.WriteLine(LOG_IDENT, $"Prompting to shut down all open Roblox instances");
MessageBoxResult result = Controls.ShowMessageBox( MessageBoxResult result = Controls.ShowMessageBox(
"Roblox is currently running, but must be closed before uninstalling Bloxstrap. Would you like close Roblox now?", "Roblox is currently running, but must be closed before uninstalling Bloxstrap. Would you like close Roblox now?",
@ -617,10 +636,10 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Bootstrapper::ShutdownIfRobloxRunning] Failed to close process! {ex}"); App.Logger.WriteLine(LOG_IDENT, $"Failed to close process! {ex}");
} }
App.Logger.WriteLine($"[Bootstrapper::Uninstall] All Roblox processes closed"); App.Logger.WriteLine(LOG_IDENT, $"All Roblox processes closed");
} }
SetStatus($"Uninstalling {App.ProjectName}..."); SetStatus($"Uninstalling {App.ProjectName}...");
@ -680,8 +699,8 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Bootstrapper::Uninstall] Encountered exception when running cleanup sequence (#{cleanupSequence.IndexOf(process)})"); App.Logger.WriteLine(LOG_IDENT, $"Encountered exception when running cleanup sequence (#{cleanupSequence.IndexOf(process)})");
App.Logger.WriteLine($"[Bootstrapper::Uninstall] {ex}"); App.Logger.WriteException(LOG_IDENT, ex);
} }
} }
@ -719,6 +738,8 @@ namespace Bloxstrap
#region Roblox Install #region Roblox Install
private async Task InstallLatestVersion() private async Task InstallLatestVersion()
{ {
const string LOG_IDENT = "Bootstrapper::InstallLatestVersion";
_isInstalling = true; _isInstalling = true;
SetStatus(FreshInstall ? "Installing Roblox..." : "Upgrading Roblox..."); SetStatus(FreshInstall ? "Installing Roblox..." : "Upgrading Roblox...");
@ -800,7 +821,7 @@ namespace Bloxstrap
{ {
if (!_versionPackageManifest.Exists(package => filename.Contains(package.Signature))) if (!_versionPackageManifest.Exists(package => filename.Contains(package.Signature)))
{ {
App.Logger.WriteLine($"[Bootstrapper::InstallLatestVersion] Deleting unused package {filename}"); App.Logger.WriteLine(LOG_IDENT, $"Deleting unused package {filename}");
File.Delete(filename); File.Delete(filename);
} }
} }
@ -815,7 +836,7 @@ namespace Bloxstrap
if (appFlags is not null) if (appFlags is not null)
{ {
App.Logger.WriteLine($"[Bootstrapper::InstallLatestVersion] Migrating app compatibility flags from {oldGameClientLocation} to {_playerLocation}..."); App.Logger.WriteLine(LOG_IDENT, $"Migrating app compatibility flags from {oldGameClientLocation} to {_playerLocation}...");
appFlagsKey.SetValue(_playerLocation, appFlags); appFlagsKey.SetValue(_playerLocation, appFlags);
appFlagsKey.DeleteValue(oldGameClientLocation); appFlagsKey.DeleteValue(oldGameClientLocation);
} }
@ -831,7 +852,7 @@ namespace Bloxstrap
if (dir.Name == _latestVersionGuid || !dir.Name.StartsWith("version-")) if (dir.Name == _latestVersionGuid || !dir.Name.StartsWith("version-"))
continue; continue;
App.Logger.WriteLine($"[Bootstrapper::InstallLatestVersion] Removing old version folder for {dir.Name}"); App.Logger.WriteLine(LOG_IDENT, $"Removing old version folder for {dir.Name}");
dir.Delete(true); dir.Delete(true);
} }
} }
@ -851,6 +872,8 @@ namespace Bloxstrap
private async Task InstallWebView2() private async Task InstallWebView2()
{ {
const string LOG_IDENT = "Bootstrapper::InstallWebView2";
// check if the webview2 runtime needs to be installed // check if the webview2 runtime needs to be installed
// webview2 can either be installed be per-user or globally, so we need to check in both hklm and hkcu // webview2 can either be installed be per-user or globally, so we need to check in both hklm and hkcu
// https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#detect-if-a-suitable-webview2-runtime-is-already-installed // https://learn.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#detect-if-a-suitable-webview2-runtime-is-already-installed
@ -861,7 +884,7 @@ namespace Bloxstrap
if (hklmKey is not null || hkcuKey is not null) if (hklmKey is not null || hkcuKey is not null)
return; return;
App.Logger.WriteLine($"[Bootstrapper::InstallWebView2] Installing runtime..."); App.Logger.WriteLine(LOG_IDENT, "Installing runtime...");
string baseDirectory = Path.Combine(_versionFolder, "WebView2RuntimeInstaller"); string baseDirectory = Path.Combine(_versionFolder, "WebView2RuntimeInstaller");
@ -871,7 +894,7 @@ namespace Bloxstrap
if (package is null) if (package is null)
{ {
App.Logger.WriteLine($"[Bootstrapper::InstallWebView2] Aborted runtime install because package does not exist, has WebView2 been added in this Roblox version yet?"); App.Logger.WriteLine(LOG_IDENT, "Aborted runtime install because package does not exist, has WebView2 been added in this Roblox version yet?");
return; return;
} }
@ -889,7 +912,7 @@ namespace Bloxstrap
await Process.Start(startInfo)!.WaitForExitAsync(); await Process.Start(startInfo)!.WaitForExitAsync();
App.Logger.WriteLine($"[Bootstrapper::InstallWebView2] Finished installing runtime"); App.Logger.WriteLine(LOG_IDENT, "Finished installing runtime");
} }
public static void MigrateIntegrations() public static void MigrateIntegrations()
@ -921,10 +944,12 @@ namespace Bloxstrap
private async Task ApplyModifications() private async Task ApplyModifications()
{ {
const string LOG_IDENT = "Bootstrapper::ApplyModifications";
SetStatus("Applying Roblox modifications..."); SetStatus("Applying Roblox modifications...");
// set executable flags for fullscreen optimizations // set executable flags for fullscreen optimizations
App.Logger.WriteLine("[Bootstrapper::ApplyModifications] Checking executable flags..."); App.Logger.WriteLine(LOG_IDENT, "Checking executable flags...");
using (RegistryKey appFlagsKey = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers")) using (RegistryKey appFlagsKey = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"))
{ {
string flag = " DISABLEDXMAXIMIZEDWINDOWEDMODE"; string flag = " DISABLEDXMAXIMIZEDWINDOWEDMODE";
@ -939,7 +964,7 @@ namespace Bloxstrap
} }
else if (appFlags is not null && appFlags.Contains(flag)) else if (appFlags is not null && appFlags.Contains(flag))
{ {
App.Logger.WriteLine($"[Bootstrapper::ApplyModifications] Deleting flag '{flag.Trim()}'"); App.Logger.WriteLine(LOG_IDENT, $"Deleting flag '{flag.Trim()}'");
// if there's more than one space, there's more flags set we need to preserve // if there's more than one space, there's more flags set we need to preserve
if (appFlags.Split(' ').Length > 2) if (appFlags.Split(' ').Length > 2)
@ -955,7 +980,7 @@ namespace Bloxstrap
if (appFlags is not null && appFlags.Contains(flag)) if (appFlags is not null && appFlags.Contains(flag))
{ {
App.Logger.WriteLine($"[Bootstrapper::ApplyModifications] Deleting flag '{flag.Trim()}'"); App.Logger.WriteLine(LOG_IDENT, $"Deleting flag '{flag.Trim()}'");
// if there's more than one space, there's more flags set we need to preserve // if there's more than one space, there's more flags set we need to preserve
if (appFlags.Split(' ').Length > 2) if (appFlags.Split(' ').Length > 2)
@ -966,7 +991,7 @@ namespace Bloxstrap
} }
// handle file mods // handle file mods
App.Logger.WriteLine("[Bootstrapper::ApplyModifications] Checking file mods..."); App.Logger.WriteLine(LOG_IDENT, "Checking file mods...");
string modFolder = Path.Combine(Directories.Modifications); string modFolder = Path.Combine(Directories.Modifications);
// manifest has been moved to State.json // manifest has been moved to State.json
@ -1044,7 +1069,7 @@ namespace Bloxstrap
if (File.Exists(Directories.CustomFont)) if (File.Exists(Directories.CustomFont))
{ {
App.Logger.WriteLine("[Bootstrapper::ApplyModifications] Begin font check"); App.Logger.WriteLine(LOG_IDENT, "Begin font check");
Directory.CreateDirectory(modFontFamiliesFolder); Directory.CreateDirectory(modFontFamiliesFolder);
@ -1067,7 +1092,7 @@ namespace Bloxstrap
File.WriteAllText(modFilepath, JsonSerializer.Serialize(fontFamilyData, new JsonSerializerOptions { WriteIndented = true })); File.WriteAllText(modFilepath, JsonSerializer.Serialize(fontFamilyData, new JsonSerializerOptions { WriteIndented = true }));
} }
App.Logger.WriteLine("[Bootstrapper::ApplyModifications] End font check"); App.Logger.WriteLine(LOG_IDENT, "End font check");
} }
else if (Directory.Exists(modFontFamiliesFolder)) else if (Directory.Exists(modFontFamiliesFolder))
{ {
@ -1182,6 +1207,8 @@ namespace Bloxstrap
private async Task DownloadPackage(Package package) private async Task DownloadPackage(Package package)
{ {
const string LOG_IDENT = "Bootstrapper::DownloadPackage";
if (_cancelFired) if (_cancelFired)
return; return;
@ -1197,12 +1224,12 @@ namespace Bloxstrap
if (calculatedMD5 != package.Signature) if (calculatedMD5 != package.Signature)
{ {
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] {package.Name} is corrupted ({calculatedMD5} != {package.Signature})! Deleting and re-downloading..."); App.Logger.WriteLine(LOG_IDENT, $"{package.Name} is corrupted ({calculatedMD5} != {package.Signature})! Deleting and re-downloading...");
file.Delete(); file.Delete();
} }
else else
{ {
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] {package.Name} is already downloaded, skipping..."); App.Logger.WriteLine(LOG_IDENT, $"{package.Name} is already downloaded, skipping...");
_totalDownloadedBytes += package.PackedSize; _totalDownloadedBytes += package.PackedSize;
UpdateProgressBar(); UpdateProgressBar();
return; return;
@ -1213,7 +1240,7 @@ namespace Bloxstrap
// let's cheat! if the stock bootstrapper already previously downloaded the file, // let's cheat! if the stock bootstrapper already previously downloaded the file,
// then we can just copy the one from there // then we can just copy the one from there
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] Found existing version of {package.Name} ({robloxPackageLocation})! Copying to Downloads folder..."); App.Logger.WriteLine(LOG_IDENT, $"Found existing version of {package.Name} ({robloxPackageLocation})! Copying to Downloads folder...");
File.Copy(robloxPackageLocation, packageLocation); File.Copy(robloxPackageLocation, packageLocation);
_totalDownloadedBytes += package.PackedSize; _totalDownloadedBytes += package.PackedSize;
UpdateProgressBar(); UpdateProgressBar();
@ -1222,7 +1249,7 @@ namespace Bloxstrap
if (!File.Exists(packageLocation)) if (!File.Exists(packageLocation))
{ {
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] Downloading {package.Name} ({package.Signature})..."); App.Logger.WriteLine(LOG_IDENT, $"Downloading {package.Name} ({package.Signature})...");
{ {
var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead, _cancelTokenSource.Token); var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead, _cancelTokenSource.Token);
@ -1252,12 +1279,14 @@ namespace Bloxstrap
} }
} }
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] Finished downloading {package.Name}!"); App.Logger.WriteLine(LOG_IDENT, $"Finished downloading {package.Name}!");
} }
} }
private async Task ExtractPackage(Package package) private async Task ExtractPackage(Package package)
{ {
const string LOG_IDENT = "Bootstrapper::ExtractPackage";
if (_cancelFired) if (_cancelFired)
return; return;
@ -1265,7 +1294,7 @@ namespace Bloxstrap
string packageFolder = Path.Combine(_versionFolder, PackageDirectories[package.Name]); string packageFolder = Path.Combine(_versionFolder, PackageDirectories[package.Name]);
string extractPath; string extractPath;
App.Logger.WriteLine($"[Bootstrapper::ExtractPackage] Extracting {package.Name} to {packageFolder}..."); App.Logger.WriteLine(LOG_IDENT, $"Extracting {package.Name} to {packageFolder}...");
using ZipArchive archive = await Task.Run(() => ZipFile.OpenRead(packageLocation)); using ZipArchive archive = await Task.Run(() => ZipFile.OpenRead(packageLocation));
@ -1279,7 +1308,7 @@ namespace Bloxstrap
extractPath = Path.Combine(packageFolder, entry.FullName); extractPath = Path.Combine(packageFolder, entry.FullName);
//App.Logger.WriteLine($"[{package.Name}] Writing {extractPath}..."); //App.Logger.WriteLine("{package.Name}", $"Writing {extractPath}...");
string? directory = Path.GetDirectoryName(extractPath); string? directory = Path.GetDirectoryName(extractPath);
@ -1296,7 +1325,7 @@ namespace Bloxstrap
File.SetLastWriteTime(extractPath, entry.LastWriteTime.DateTime); File.SetLastWriteTime(extractPath, entry.LastWriteTime.DateTime);
} }
App.Logger.WriteLine($"[Bootstrapper::ExtractPackage] Finished extracting {package.Name}"); App.Logger.WriteLine(LOG_IDENT, $"Finished extracting {package.Name}");
_packagesExtracted += 1; _packagesExtracted += 1;
} }

View File

@ -10,6 +10,8 @@ namespace Bloxstrap.Extensions
public static Icon GetIcon(this BootstrapperIcon icon) public static Icon GetIcon(this BootstrapperIcon icon)
{ {
const string LOG_IDENT = "BootstrapperIconEx::GetIcon";
// load the custom icon file // load the custom icon file
if (icon == BootstrapperIcon.IconCustom) if (icon == BootstrapperIcon.IconCustom)
{ {
@ -21,7 +23,8 @@ namespace Bloxstrap.Extensions
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[BootstrapperIconEx::GetIcon] Failed to load custom icon! {ex}"); App.Logger.WriteLine(LOG_IDENT, $"Failed to load custom icon!");
App.Logger.WriteException(LOG_IDENT, ex);
} }
return customIcon ?? Properties.Resources.IconBloxstrap; return customIcon ?? Properties.Resources.IconBloxstrap;

View File

@ -106,19 +106,21 @@ namespace Bloxstrap
// to delete a flag, set the value as null // to delete a flag, set the value as null
public void SetValue(string key, object? value) public void SetValue(string key, object? value)
{ {
const string LOG_IDENT = "FastFlagManager::SetValue";
if (value is null) if (value is null)
{ {
if (Prop.ContainsKey(key)) if (Prop.ContainsKey(key))
App.Logger.WriteLine($"[FastFlagManager::SetValue] Deletion of '{key}' is pending"); App.Logger.WriteLine(LOG_IDENT, $"Deletion of '{key}' is pending");
Prop.Remove(key); Prop.Remove(key);
} }
else else
{ {
if (Prop.ContainsKey(key)) if (Prop.ContainsKey(key))
App.Logger.WriteLine($"[FastFlagManager::SetValue] Setting of '{key}' from '{Prop[key]}' to '{value}' is pending"); App.Logger.WriteLine(LOG_IDENT, $"Setting of '{key}' from '{Prop[key]}' to '{value}' is pending");
else else
App.Logger.WriteLine($"[FastFlagManager::SetValue] Setting of '{key}' to '{value}' is pending"); App.Logger.WriteLine(LOG_IDENT, $"Setting of '{key}' to '{value}' is pending");
Prop[key] = value.ToString()!; Prop[key] = value.ToString()!;
} }

View File

@ -9,13 +9,13 @@
protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, CancellationToken cancellationToken) protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, CancellationToken cancellationToken)
{ {
App.Logger.WriteLine($"[HttpClientLoggingHandler::HttpRequestMessage] {request.Method} {request.RequestUri}"); App.Logger.WriteLine("HttpClientLoggingHandler::HttpRequestMessage", $"{request.Method} {request.RequestUri}");
return request; return request;
} }
protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken) protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken)
{ {
App.Logger.WriteLine($"[HttpClientLoggingHandler::HttpResponseMessage] {(int)response.StatusCode} {response.ReasonPhrase} {response.RequestMessage!.RequestUri}"); App.Logger.WriteLine("HttpClientLoggingHandler::HttpResponseMessage", $"{(int)response.StatusCode} {response.ReasonPhrase} {response.RequestMessage!.RequestUri}");
return response; return response;
} }
} }

View File

@ -15,6 +15,8 @@ namespace Bloxstrap.Integrations
public DiscordRichPresence(RobloxActivity activityWatcher) public DiscordRichPresence(RobloxActivity activityWatcher)
{ {
const string LOG_IDENT = "DiscordRichPresence::<construct>";
_activityWatcher = activityWatcher; _activityWatcher = activityWatcher;
_activityWatcher.OnGameJoin += (_, _) => Task.Run(() => SetCurrentGame()); _activityWatcher.OnGameJoin += (_, _) => Task.Run(() => SetCurrentGame());
@ -22,23 +24,23 @@ namespace Bloxstrap.Integrations
_activityWatcher.OnGameMessage += (_, message) => OnGameMessage(message); _activityWatcher.OnGameMessage += (_, message) => OnGameMessage(message);
_rpcClient.OnReady += (_, e) => _rpcClient.OnReady += (_, e) =>
App.Logger.WriteLine($"[DiscordRichPresence::DiscordRichPresence] Received ready from user {e.User.Username} ({e.User.ID})"); App.Logger.WriteLine(LOG_IDENT, $"Received ready from user {e.User.Username} ({e.User.ID})");
_rpcClient.OnPresenceUpdate += (_, e) => _rpcClient.OnPresenceUpdate += (_, e) =>
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Presence updated"); App.Logger.WriteLine(LOG_IDENT, "Presence updated");
_rpcClient.OnError += (_, e) => _rpcClient.OnError += (_, e) =>
App.Logger.WriteLine($"[DiscordRichPresence::DiscordRichPresence] An RPC error occurred - {e.Message}"); App.Logger.WriteLine(LOG_IDENT, $"An RPC error occurred - {e.Message}");
_rpcClient.OnConnectionEstablished += (_, e) => _rpcClient.OnConnectionEstablished += (_, e) =>
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Established connection with Discord RPC"); App.Logger.WriteLine(LOG_IDENT, "Established connection with Discord RPC");
//spams log as it tries to connect every ~15 sec when discord is closed so not now //spams log as it tries to connect every ~15 sec when discord is closed so not now
//_rpcClient.OnConnectionFailed += (_, e) => //_rpcClient.OnConnectionFailed += (_, e) =>
// App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Failed to establish connection with Discord RPC"); // App.Logger.WriteLine(LOG_IDENT, "Failed to establish connection with Discord RPC");
_rpcClient.OnClose += (_, e) => _rpcClient.OnClose += (_, e) =>
App.Logger.WriteLine($"[DiscordRichPresence::DiscordRichPresence] Lost connection to Discord RPC - {e.Reason} ({e.Code})"); App.Logger.WriteLine(LOG_IDENT, $"Lost connection to Discord RPC - {e.Reason} ({e.Code})");
_rpcClient.Initialize(); _rpcClient.Initialize();
} }
@ -51,17 +53,19 @@ namespace Bloxstrap.Integrations
public void SetStatus(string status) public void SetStatus(string status)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetStatus] Setting status to '{status}'"); const string LOG_IDENT = "DiscordRichPresence::SetStatus";
App.Logger.WriteLine(LOG_IDENT, $"Setting status to '{status}'");
if (_currentPresence is null) if (_currentPresence is null)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetStatus] Presence is not set, aborting"); App.Logger.WriteLine(LOG_IDENT, $"Presence is not set, aborting");
return; return;
} }
if (status.Length > 128) if (status.Length > 128)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetStatus] Status cannot be longer than 128 characters, aborting"); App.Logger.WriteLine(LOG_IDENT, $"Status cannot be longer than 128 characters, aborting");
return; return;
} }
@ -72,7 +76,7 @@ namespace Bloxstrap.Integrations
if (string.IsNullOrEmpty(status)) if (string.IsNullOrEmpty(status))
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetStatus] Status is empty, reverting to initial status"); App.Logger.WriteLine(LOG_IDENT, $"Status is empty, reverting to initial status");
finalStatus = _initialStatus; finalStatus = _initialStatus;
} }
else else
@ -82,7 +86,7 @@ namespace Bloxstrap.Integrations
if (_currentPresence.State == finalStatus) if (_currentPresence.State == finalStatus)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetStatus] Status is unchanged, aborting"); App.Logger.WriteLine(LOG_IDENT, $"Status is unchanged, aborting");
return; return;
} }
@ -92,7 +96,7 @@ namespace Bloxstrap.Integrations
public void SetVisibility(bool visible) public void SetVisibility(bool visible)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetVisibility] Setting presence visibility ({visible})"); App.Logger.WriteLine("DiscordRichPresence::SetVisibility", $"Setting presence visibility ({visible})");
_visible = visible; _visible = visible;
@ -104,9 +108,11 @@ namespace Bloxstrap.Integrations
public async Task<bool> SetCurrentGame() public async Task<bool> SetCurrentGame()
{ {
const string LOG_IDENT = "DiscordRichPresence::SetCurrentGame";
if (!_activityWatcher.ActivityInGame) if (!_activityWatcher.ActivityInGame)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Not in game, clearing presence"); App.Logger.WriteLine(LOG_IDENT, "Not in game, clearing presence");
_currentPresence = null; _currentPresence = null;
_initialStatus = null; _initialStatus = null;
UpdatePresence(); UpdatePresence();
@ -116,17 +122,17 @@ namespace Bloxstrap.Integrations
string icon = "roblox"; string icon = "roblox";
long placeId = _activityWatcher.ActivityPlaceId; long placeId = _activityWatcher.ActivityPlaceId;
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Setting presence for Place ID {placeId}"); App.Logger.WriteLine(LOG_IDENT, $"Setting presence for Place ID {placeId}");
var universeIdResponse = await Http.GetJson<UniverseIdResponse>($"https://apis.roblox.com/universes/v1/places/{placeId}/universe"); var universeIdResponse = await Http.GetJson<UniverseIdResponse>($"https://apis.roblox.com/universes/v1/places/{placeId}/universe");
if (universeIdResponse is null) if (universeIdResponse is null)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe ID!"); App.Logger.WriteLine(LOG_IDENT, "Could not get Universe ID!");
return false; return false;
} }
long universeId = universeIdResponse.UniverseId; long universeId = universeIdResponse.UniverseId;
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Got Universe ID as {universeId}"); App.Logger.WriteLine(LOG_IDENT, $"Got Universe ID as {universeId}");
// preserve time spent playing if we're teleporting between places in the same universe // preserve time spent playing if we're teleporting between places in the same universe
if (_timeStartedUniverse is null || !_activityWatcher.ActivityIsTeleport || universeId != _currentUniverseId) if (_timeStartedUniverse is null || !_activityWatcher.ActivityIsTeleport || universeId != _currentUniverseId)
@ -137,22 +143,22 @@ namespace Bloxstrap.Integrations
var gameDetailResponse = await Http.GetJson<ApiArrayResponse<GameDetailResponse>>($"https://games.roblox.com/v1/games?universeIds={universeId}"); var gameDetailResponse = await Http.GetJson<ApiArrayResponse<GameDetailResponse>>($"https://games.roblox.com/v1/games?universeIds={universeId}");
if (gameDetailResponse is null || !gameDetailResponse.Data.Any()) if (gameDetailResponse is null || !gameDetailResponse.Data.Any())
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe info!"); App.Logger.WriteLine(LOG_IDENT, "Could not get Universe info!");
return false; return false;
} }
GameDetailResponse universeDetails = gameDetailResponse.Data.ToArray()[0]; GameDetailResponse universeDetails = gameDetailResponse.Data.ToArray()[0];
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Got Universe details"); App.Logger.WriteLine(LOG_IDENT, "Got Universe details");
var universeThumbnailResponse = await Http.GetJson<ApiArrayResponse<ThumbnailResponse>>($"https://thumbnails.roblox.com/v1/games/icons?universeIds={universeId}&returnPolicy=PlaceHolder&size=512x512&format=Png&isCircular=false"); var universeThumbnailResponse = await Http.GetJson<ApiArrayResponse<ThumbnailResponse>>($"https://thumbnails.roblox.com/v1/games/icons?universeIds={universeId}&returnPolicy=PlaceHolder&size=512x512&format=Png&isCircular=false");
if (universeThumbnailResponse is null || !universeThumbnailResponse.Data.Any()) if (universeThumbnailResponse is null || !universeThumbnailResponse.Data.Any())
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe thumbnail info!"); App.Logger.WriteLine(LOG_IDENT, "Could not get Universe thumbnail info!");
} }
else else
{ {
icon = universeThumbnailResponse.Data.ToArray()[0].ImageUrl; icon = universeThumbnailResponse.Data.ToArray()[0].ImageUrl;
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Got Universe thumbnail as {icon}"); App.Logger.WriteLine(LOG_IDENT, $"Got Universe thumbnail as {icon}");
} }
List<Button> buttons = new(); List<Button> buttons = new();
@ -174,7 +180,7 @@ namespace Bloxstrap.Integrations
if (!_activityWatcher.ActivityInGame || placeId != _activityWatcher.ActivityPlaceId) if (!_activityWatcher.ActivityInGame || placeId != _activityWatcher.ActivityPlaceId)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Aborting presence set because game activity has changed"); App.Logger.WriteLine(LOG_IDENT, "Aborting presence set because game activity has changed");
return false; return false;
} }
@ -207,14 +213,16 @@ namespace Bloxstrap.Integrations
public void UpdatePresence() public void UpdatePresence()
{ {
const string LOG_IDENT = "DiscordRichPresence::UpdatePresence";
if (_currentPresence is null) if (_currentPresence is null)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::UpdatePresence] Presence is empty, clearing"); App.Logger.WriteLine(LOG_IDENT, $"Presence is empty, clearing");
_rpcClient.ClearPresence(); _rpcClient.ClearPresence();
return; return;
} }
App.Logger.WriteLine($"[DiscordRichPresence::UpdatePresence] Updating presence"); App.Logger.WriteLine(LOG_IDENT, $"Updating presence");
if (_visible) if (_visible)
_rpcClient.SetPresence(_currentPresence); _rpcClient.SetPresence(_currentPresence);
@ -222,7 +230,7 @@ namespace Bloxstrap.Integrations
public void Dispose() public void Dispose()
{ {
App.Logger.WriteLine("[DiscordRichPresence::Dispose] Cleaning up Discord RPC and Presence"); App.Logger.WriteLine("DiscordRichPresence::Dispose", "Cleaning up Discord RPC and Presence");
_rpcClient.ClearPresence(); _rpcClient.ClearPresence();
_rpcClient.Dispose(); _rpcClient.Dispose();
GC.SuppressFinalize(this); GC.SuppressFinalize(this);

View File

@ -1,13 +1,19 @@
namespace Bloxstrap using System.Runtime.CompilerServices;
namespace Bloxstrap
{ {
public class JsonManager<T> where T : new() public class JsonManager<T> where T : new()
{ {
public T Prop { get; set; } = new(); public T Prop { get; set; } = new();
public virtual string FileLocation => Path.Combine(Directories.Base, $"{typeof(T).Name}.json"); public virtual string FileLocation => Path.Combine(Directories.Base, $"{typeof(T).Name}.json");
private string LOG_IDENT_CLASS => $"JsonManager<{typeof(T).Name}>";
public virtual void Load() public virtual void Load()
{ {
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Loading from {FileLocation}..."); string LOG_IDENT = $"{LOG_IDENT_CLASS}::Load";
App.Logger.WriteLine(LOG_IDENT, $"Loading from {FileLocation}...");
try try
{ {
@ -18,28 +24,31 @@
Prop = settings; Prop = settings;
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Loaded successfully!"); App.Logger.WriteLine(LOG_IDENT, "Loaded successfully!");
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Failed to load! ({ex.Message})"); App.Logger.WriteLine(LOG_IDENT, "Failed to load!");
App.Logger.WriteLine(LOG_IDENT, $"{ex.Message}");
} }
} }
public virtual void Save() public virtual void Save()
{ {
string LOG_IDENT = $"{LOG_IDENT_CLASS}::Save";
if (!App.ShouldSaveConfigs) if (!App.ShouldSaveConfigs)
{ {
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Save request ignored"); App.Logger.WriteLine(LOG_IDENT, "Save request ignored");
return; return;
} }
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Saving to {FileLocation}..."); App.Logger.WriteLine(LOG_IDENT, $"Saving to {FileLocation}...");
Directory.CreateDirectory(Path.GetDirectoryName(FileLocation)!); Directory.CreateDirectory(Path.GetDirectoryName(FileLocation)!);
File.WriteAllText(FileLocation, JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true })); File.WriteAllText(FileLocation, JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true }));
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Save complete!"); App.Logger.WriteLine(LOG_IDENT, "Save complete!");
} }
} }
} }

View File

@ -17,16 +17,18 @@
public void Initialize(bool useTempDir = false) public void Initialize(bool useTempDir = false)
{ {
const string LOG_IDENT = "Logger::Initialize";
string directory = useTempDir ? Path.Combine(Directories.LocalAppData, "Temp") : Path.Combine(Directories.Base, "Logs"); string directory = useTempDir ? Path.Combine(Directories.LocalAppData, "Temp") : Path.Combine(Directories.Base, "Logs");
string timestamp = DateTime.UtcNow.ToString("yyyyMMdd'T'HHmmss'Z'"); string timestamp = DateTime.UtcNow.ToString("yyyyMMdd'T'HHmmss'Z'");
string filename = $"{App.ProjectName}_{timestamp}.log"; string filename = $"{App.ProjectName}_{timestamp}.log";
string location = Path.Combine(directory, filename); string location = Path.Combine(directory, filename);
WriteLine($"[Logger::Initialize] Initializing at {location}"); WriteLine(LOG_IDENT, $"Initializing at {location}");
if (Initialized) if (Initialized)
{ {
WriteLine("[Logger::Initialize] Failed to initialize because logger is already initialized"); WriteLine(LOG_IDENT, "Failed to initialize because logger is already initialized");
return; return;
} }
@ -34,7 +36,7 @@
if (File.Exists(location)) if (File.Exists(location))
{ {
WriteLine("[Logger::Initialize] Failed to initialize because log file already exists"); WriteLine(LOG_IDENT, "Failed to initialize because log file already exists");
return; return;
} }
@ -45,7 +47,7 @@
if (Backlog.Count > 0) if (Backlog.Count > 0)
WriteToLog(string.Join("\r\n", Backlog)); WriteToLog(string.Join("\r\n", Backlog));
WriteLine($"[Logger::Initialize] Finished initializing!"); WriteLine(LOG_IDENT, "Finished initializing!");
FileLocation = location; FileLocation = location;
@ -57,13 +59,13 @@
if (log.LastWriteTimeUtc.AddDays(7) > DateTime.UtcNow) if (log.LastWriteTimeUtc.AddDays(7) > DateTime.UtcNow)
continue; continue;
App.Logger.WriteLine($"[Logger::Initialize] Cleaning up old log file '{log.Name}'"); WriteLine(LOG_IDENT, $"Cleaning up old log file '{log.Name}'");
log.Delete(); log.Delete();
} }
} }
} }
public void WriteLine(string message) private void WriteLine(string message)
{ {
string timestamp = DateTime.UtcNow.ToString("s") + "Z"; string timestamp = DateTime.UtcNow.ToString("s") + "Z";
string outcon = $"{timestamp} {message}"; string outcon = $"{timestamp} {message}";
@ -73,6 +75,16 @@
WriteToLog(outlog); WriteToLog(outlog);
} }
public void WriteLine(string identifier, string message) => WriteLine($"[{identifier}] {message}");
public void WriteException(string identifier, Exception ex)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
WriteLine($"[{identifier}] {ex}");
}
private async void WriteToLog(string message) private async void WriteToLog(string message)
{ {
if (!Initialized) if (!Initialized)

View File

@ -94,7 +94,7 @@ namespace Bloxstrap
return; return;
} }
App.Logger.WriteLine($"[Protocol::ParseUri] Changed Roblox build channel from {App.Settings.Prop.Channel} to {channel}"); App.Logger.WriteLine("Protocol::ParseUri", $"Changed Roblox build channel from {App.Settings.Prop.Channel} to {channel}");
App.Settings.Prop.Channel = channel; App.Settings.Prop.Channel = channel;
} }
@ -137,7 +137,7 @@ namespace Bloxstrap
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Protocol::Unregister] Failed to unregister {key}: {ex}"); App.Logger.WriteLine("Protocol::Unregister", $"Failed to unregister {key}: {ex}");
} }
} }
} }

View File

@ -44,6 +44,8 @@
public async void StartWatcher() public async void StartWatcher()
{ {
const string LOG_IDENT = "RobloxActivity::StartWatcher";
// okay, here's the process: // okay, here's the process:
// //
// - tail the latest log file from %localappdata%\roblox\logs // - tail the latest log file from %localappdata%\roblox\logs
@ -71,7 +73,7 @@
// if roblox doesn't start quickly enough, we can wind up fetching the previous log file // if roblox doesn't start quickly enough, we can wind up fetching the previous log file
// good rule of thumb is to find a log file that was created in the last 15 seconds or so // good rule of thumb is to find a log file that was created in the last 15 seconds or so
App.Logger.WriteLine("[RobloxActivity::StartWatcher] Opening Roblox log file..."); App.Logger.WriteLine(LOG_IDENT, "Opening Roblox log file...");
while (true) while (true)
{ {
@ -84,13 +86,13 @@
if (logFileInfo.CreationTime.AddSeconds(15) > DateTime.Now) if (logFileInfo.CreationTime.AddSeconds(15) > DateTime.Now)
break; break;
App.Logger.WriteLine($"[RobloxActivity::StartWatcher] Could not find recent enough log file, waiting... (newest is {logFileInfo.Name})"); App.Logger.WriteLine(LOG_IDENT, $"Could not find recent enough log file, waiting... (newest is {logFileInfo.Name})");
await Task.Delay(1000); await Task.Delay(1000);
} }
LogLocation = logFileInfo.FullName; LogLocation = logFileInfo.FullName;
FileStream logFileStream = logFileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite); FileStream logFileStream = logFileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
App.Logger.WriteLine($"[RobloxActivity::StartWatcher] Opened {LogLocation}"); App.Logger.WriteLine(LOG_IDENT, $"Opened {LogLocation}");
AutoResetEvent logUpdatedEvent = new(false); AutoResetEvent logUpdatedEvent = new(false);
FileSystemWatcher logWatcher = new() FileSystemWatcher logWatcher = new()
@ -116,6 +118,8 @@
private void ExamineLogEntry(string entry) private void ExamineLogEntry(string entry)
{ {
const string LOG_IDENT = "RobloxActivity::ExamineLogEntry";
OnLogEntry?.Invoke(this, entry); OnLogEntry?.Invoke(this, entry);
_logEntriesRead += 1; _logEntriesRead += 1;
@ -123,9 +127,9 @@
// debug stats to ensure that the log reader is working correctly // debug stats to ensure that the log reader is working correctly
// if more than 1000 log entries have been read, only log per 100 to save on spam // if more than 1000 log entries have been read, only log per 100 to save on spam
if (_logEntriesRead <= 1000 && _logEntriesRead % 50 == 0) if (_logEntriesRead <= 1000 && _logEntriesRead % 50 == 0)
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Read {_logEntriesRead} log entries"); App.Logger.WriteLine(LOG_IDENT, $"Read {_logEntriesRead} log entries");
else if (_logEntriesRead % 100 == 0) else if (_logEntriesRead % 100 == 0)
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Read {_logEntriesRead} log entries"); App.Logger.WriteLine(LOG_IDENT, $"Read {_logEntriesRead} log entries");
if (!ActivityInGame && ActivityPlaceId == 0) if (!ActivityInGame && ActivityPlaceId == 0)
{ {
@ -140,8 +144,8 @@
if (match.Groups.Count != 4) if (match.Groups.Count != 4)
{ {
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Failed to assert format for game join entry"); App.Logger.WriteLine(LOG_IDENT, $"Failed to assert format for game join entry");
App.Logger.WriteLine(entry); App.Logger.WriteLine(LOG_IDENT, entry);
return; return;
} }
@ -162,7 +166,7 @@
_reservedTeleportMarker = false; _reservedTeleportMarker = false;
} }
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Joining Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})"); App.Logger.WriteLine(LOG_IDENT, $"Joining Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
} }
} }
else if (!ActivityInGame && ActivityPlaceId != 0) else if (!ActivityInGame && ActivityPlaceId != 0)
@ -173,15 +177,15 @@
if (match.Groups.Count != 3 || match.Groups[2].Value != ActivityMachineAddress) if (match.Groups.Count != 3 || match.Groups[2].Value != ActivityMachineAddress)
{ {
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Failed to assert format for game join UDMUX entry"); App.Logger.WriteLine(LOG_IDENT, $"Failed to assert format for game join UDMUX entry");
App.Logger.WriteLine(entry); App.Logger.WriteLine(LOG_IDENT, entry);
return; return;
} }
ActivityMachineAddress = match.Groups[1].Value; ActivityMachineAddress = match.Groups[1].Value;
ActivityMachineUDMUX = true; ActivityMachineUDMUX = true;
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Server is UDMUX protected ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})"); App.Logger.WriteLine(LOG_IDENT, $"Server is UDMUX protected ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
} }
else if (entry.Contains(GameJoinedEntry)) else if (entry.Contains(GameJoinedEntry))
{ {
@ -189,12 +193,12 @@
if (match.Groups.Count != 2 || match.Groups[1].Value != ActivityMachineAddress) if (match.Groups.Count != 2 || match.Groups[1].Value != ActivityMachineAddress)
{ {
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Failed to assert format for game joined entry"); App.Logger.WriteLine(LOG_IDENT, $"Failed to assert format for game joined entry");
App.Logger.WriteLine(entry); App.Logger.WriteLine(LOG_IDENT, entry);
return; return;
} }
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Joined Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})"); App.Logger.WriteLine(LOG_IDENT, $"Joined Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
ActivityInGame = true; ActivityInGame = true;
OnGameJoin?.Invoke(this, new EventArgs()); OnGameJoin?.Invoke(this, new EventArgs());
@ -204,7 +208,7 @@
{ {
if (entry.Contains(GameDisconnectedEntry)) if (entry.Contains(GameDisconnectedEntry))
{ {
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Disconnected from Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})"); App.Logger.WriteLine(LOG_IDENT, $"Disconnected from Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
ActivityInGame = false; ActivityInGame = false;
ActivityPlaceId = 0; ActivityPlaceId = 0;
@ -218,7 +222,7 @@
} }
else if (entry.Contains(GameTeleportingEntry)) else if (entry.Contains(GameTeleportingEntry))
{ {
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Initiating teleport to server ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})"); App.Logger.WriteLine(LOG_IDENT, $"Initiating teleport to server ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
_teleportMarker = true; _teleportMarker = true;
} }
else if (_teleportMarker && entry.Contains(GameJoiningReservedServerEntry)) else if (_teleportMarker && entry.Contains(GameJoiningReservedServerEntry))
@ -231,7 +235,7 @@
string messagePlain = entry.Substring(entry.IndexOf(GameMessageEntry) + GameMessageEntry.Length + 1); string messagePlain = entry.Substring(entry.IndexOf(GameMessageEntry) + GameMessageEntry.Length + 1);
GameMessage? message; GameMessage? message;
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Received message: '{messagePlain}'"); App.Logger.WriteLine(LOG_IDENT, $"Received message: '{messagePlain}'");
try try
{ {
@ -239,19 +243,19 @@
} }
catch (Exception) catch (Exception)
{ {
App.Logger.WriteLine($"[Utilities::ExamineLogEntry] Failed to parse message! (JSON deserialization threw an exception)"); App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization threw an exception)");
return; return;
} }
if (message is null) if (message is null)
{ {
App.Logger.WriteLine($"[Utilities::ExamineLogEntry] Failed to parse message! (JSON deserialization returned null)"); App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (JSON deserialization returned null)");
return; return;
} }
if (String.IsNullOrEmpty(message.Command)) if (String.IsNullOrEmpty(message.Command))
{ {
App.Logger.WriteLine($"[Utilities::ExamineLogEntry] Failed to parse message! (Command is empty)"); App.Logger.WriteLine(LOG_IDENT, "Failed to parse message! (Command is empty)");
return; return;
} }
@ -262,6 +266,8 @@
public async Task<string> GetServerLocation() public async Task<string> GetServerLocation()
{ {
const string LOG_IDENT = "RobloxActivity::GetServerLocation";
if (GeolcationCache.ContainsKey(ActivityMachineAddress)) if (GeolcationCache.ContainsKey(ActivityMachineAddress))
return GeolcationCache[ActivityMachineAddress]; return GeolcationCache[ActivityMachineAddress];
@ -275,8 +281,8 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[RobloxActivity::GetServerLocation] Failed to get server location for {ActivityMachineAddress}"); App.Logger.WriteLine(LOG_IDENT, $"Failed to get server location for {ActivityMachineAddress}");
App.Logger.WriteLine($"[RobloxActivity::GetServerLocation] {ex}"); App.Logger.WriteException(LOG_IDENT, ex);
return "N/A (lookup failed)"; return "N/A (lookup failed)";
} }

View File

@ -23,24 +23,26 @@ namespace Bloxstrap
{ {
get get
{ {
const string LOG_IDENT = "DeployManager::DefaultBaseUrl.Set";
if (string.IsNullOrEmpty(_baseUrl)) if (string.IsNullOrEmpty(_baseUrl))
{ {
// check for a working accessible deployment domain // check for a working accessible deployment domain
foreach (string attemptedUrl in BaseUrls) foreach (string attemptedUrl in BaseUrls)
{ {
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Testing connection to '{attemptedUrl}'..."); App.Logger.WriteLine(LOG_IDENT, $"Testing connection to '{attemptedUrl}'...");
try try
{ {
App.HttpClient.GetAsync($"{attemptedUrl}/version").Wait(); App.HttpClient.GetAsync($"{attemptedUrl}/version").Wait();
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Connection successful!"); App.Logger.WriteLine(LOG_IDENT, "Connection successful!");
_baseUrl = attemptedUrl; _baseUrl = attemptedUrl;
break; break;
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Connection failed!"); App.Logger.WriteLine(LOG_IDENT, "Connection failed!");
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] {ex}"); App.Logger.WriteException(LOG_IDENT, ex);
continue; continue;
} }
} }
@ -83,13 +85,15 @@ namespace Bloxstrap
public static async Task<ClientVersion> GetInfo(string channel, bool extraInformation = false) public static async Task<ClientVersion> GetInfo(string channel, bool extraInformation = false)
{ {
App.Logger.WriteLine($"[RobloxDeployment::GetInfo] Getting deploy info for channel {channel} (extraInformation={extraInformation})"); const string LOG_IDENT = "RobloxDeployment::GetInfo";
App.Logger.WriteLine(LOG_IDENT, $"Getting deploy info for channel {channel} (extraInformation={extraInformation})");
ClientVersion clientVersion; ClientVersion clientVersion;
if (ClientVersionCache.ContainsKey(channel)) if (ClientVersionCache.ContainsKey(channel))
{ {
App.Logger.WriteLine($"[RobloxDeployment::GetInfo] Deploy information is cached"); App.Logger.WriteLine(LOG_IDENT, "Deploy information is cached");
clientVersion = ClientVersionCache[channel]; clientVersion = ClientVersionCache[channel];
} }
else else
@ -105,8 +109,8 @@ namespace Bloxstrap
// 500 = Error while fetching version information. // 500 = Error while fetching version information.
// either way, we throw // either way, we throw
App.Logger.WriteLine( App.Logger.WriteLine(LOG_IDENT,
"[RobloxDeployment::GetInfo] Failed to fetch deploy info!\r\n" + "Failed to fetch deploy info!\r\n" +
$"\tStatus code: {deployInfoResponse.StatusCode}\r\n" + $"\tStatus code: {deployInfoResponse.StatusCode}\r\n" +
$"\tResponse: {rawResponse}" $"\tResponse: {rawResponse}"
); );
@ -121,7 +125,7 @@ namespace Bloxstrap
// for preferences // for preferences
if (extraInformation && clientVersion.Timestamp is null) if (extraInformation && clientVersion.Timestamp is null)
{ {
App.Logger.WriteLine("[RobloxDeployment::GetInfo] Getting extra information..."); App.Logger.WriteLine(LOG_IDENT, "Getting extra information...");
string manifestUrl = GetLocation($"/{clientVersion.VersionGuid}-rbxPkgManifest.txt", channel); string manifestUrl = GetLocation($"/{clientVersion.VersionGuid}-rbxPkgManifest.txt", channel);
@ -131,7 +135,7 @@ namespace Bloxstrap
if (pkgResponse.Content.Headers.TryGetValues("last-modified", out var values)) if (pkgResponse.Content.Headers.TryGetValues("last-modified", out var values))
{ {
string lastModified = values.First(); string lastModified = values.First();
App.Logger.WriteLine($"[RobloxDeployment::GetInfo] {manifestUrl} - Last-Modified: {lastModified}"); App.Logger.WriteLine(LOG_IDENT, $"{manifestUrl} - Last-Modified: {lastModified}");
clientVersion.Timestamp = DateTime.Parse(lastModified).ToLocalTime(); clientVersion.Timestamp = DateTime.Parse(lastModified).ToLocalTime();
} }

View File

@ -98,7 +98,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
NativeMethods.SetWindowLongPtr(wndHelper.Handle, NativeMethods.GWL_EXSTYLE, (IntPtr)exStyle); NativeMethods.SetWindowLongPtr(wndHelper.Handle, NativeMethods.GWL_EXSTYLE, (IntPtr)exStyle);
} }
private void Window_Closed(object sender, EventArgs e) => App.Logger.WriteLine("[MenuContainer::Window_Closed] Context menu container closed"); private void Window_Closed(object sender, EventArgs e) => App.Logger.WriteLine("MenuContainer::Window_Closed", "Context menu container closed");
private void RichPresenceMenuItem_Click(object sender, RoutedEventArgs e) => _richPresenceHandler?.SetVisibility(((MenuItem)sender).IsChecked); private void RichPresenceMenuItem_Click(object sender, RoutedEventArgs e) => _richPresenceHandler?.SetVisibility(((MenuItem)sender).IsChecked);

View File

@ -19,7 +19,7 @@ namespace Bloxstrap.UI.Elements.Menu
public MainWindow() public MainWindow()
{ {
App.Logger.WriteLine("[MainWindow::MainWindow] Initializing menu"); App.Logger.WriteLine("MainWindow::MainWindow", "Initializing menu");
DataContext = new MainWindowViewModel(this, _dialogService); DataContext = new MainWindowViewModel(this, _dialogService);
SetTheme(); SetTheme();

View File

@ -21,7 +21,7 @@ namespace Bloxstrap.UI
public NotifyIconWrapper() public NotifyIconWrapper()
{ {
App.Logger.WriteLine("[NotifyIconWrapper::NotifyIconWrapper] Initializing notification area icon"); App.Logger.WriteLine("NotifyIconWrapper::NotifyIconWrapper", "Initializing notification area icon");
_notifyIcon = new() _notifyIcon = new()
{ {
@ -60,7 +60,7 @@ namespace Bloxstrap.UI
if (_menuContainer is not null) if (_menuContainer is not null)
return; return;
App.Logger.WriteLine("[NotifyIconWrapper::InitializeContextMenu] Initializing context menu"); App.Logger.WriteLine("NotifyIconWrapper::InitializeContextMenu", "Initializing context menu");
_menuContainer = new(_activityWatcher, _richPresenceHandler); _menuContainer = new(_activityWatcher, _richPresenceHandler);
_menuContainer.ShowDialog(); _menuContainer.ShowDialog();
@ -94,15 +94,17 @@ namespace Bloxstrap.UI
{ {
string id = Guid.NewGuid().ToString()[..8]; string id = Guid.NewGuid().ToString()[..8];
App.Logger.WriteLine($"[NotifyIconWrapper::ShowAlert] [{id}] Showing alert for {duration} seconds (clickHandler={clickHandler is not null})"); string LOG_IDENT = $"NotifyIconWrapper::ShowAlert.{id}";
App.Logger.WriteLine($"[NotifyIconWrapper::ShowAlert] [{id}] {caption}: {message.Replace("\n", "\\n")}");
App.Logger.WriteLine(LOG_IDENT, $"Showing alert for {duration} seconds (clickHandler={clickHandler is not null})");
App.Logger.WriteLine(LOG_IDENT, $"{caption}: {message.Replace("\n", "\\n")}");
_notifyIcon.BalloonTipTitle = caption; _notifyIcon.BalloonTipTitle = caption;
_notifyIcon.BalloonTipText = message; _notifyIcon.BalloonTipText = message;
if (_alertClickHandler is not null) if (_alertClickHandler is not null)
{ {
App.Logger.WriteLine($"[NotifyIconWrapper::ShowAlert] [{id}] Previous alert still present, erasing click handler"); App.Logger.WriteLine(LOG_IDENT, "Previous alert still present, erasing click handler");
_notifyIcon.BalloonTipClicked -= _alertClickHandler; _notifyIcon.BalloonTipClicked -= _alertClickHandler;
} }
@ -117,12 +119,12 @@ namespace Bloxstrap.UI
_notifyIcon.BalloonTipClicked -= clickHandler; _notifyIcon.BalloonTipClicked -= clickHandler;
App.Logger.WriteLine($"[NotifyIconWrapper::ShowAlert] [{id}] Duration over, erasing current click handler"); App.Logger.WriteLine(LOG_IDENT, "Duration over, erasing current click handler");
if (_alertClickHandler == clickHandler) if (_alertClickHandler == clickHandler)
_alertClickHandler = null; _alertClickHandler = null;
else else
App.Logger.WriteLine($"[NotifyIconWrapper::ShowAlert] [{id}] Click handler has been overriden by another alert"); App.Logger.WriteLine(LOG_IDENT, "Click handler has been overriden by another alert");
}); });
} }
@ -133,7 +135,7 @@ namespace Bloxstrap.UI
_disposing = true; _disposing = true;
App.Logger.WriteLine($"[NotifyIconWrapper::Dispose] Disposing NotifyIcon"); App.Logger.WriteLine("NotifyIconWrapper::Dispose", "Disposing NotifyIcon");
_menuContainer?.Dispatcher.Invoke(_menuContainer.Close); _menuContainer?.Dispatcher.Invoke(_menuContainer.Close);
_notifyIcon?.Dispose(); _notifyIcon?.Dispose();

View File

@ -15,6 +15,8 @@ namespace Bloxstrap.UI.ViewModels.Menu
private async Task LoadChannelDeployInfo(string channel) private async Task LoadChannelDeployInfo(string channel)
{ {
const string LOG_IDENT = "BehaviourViewModel::LoadChannelDeployInfo";
LoadingSpinnerVisibility = Visibility.Visible; LoadingSpinnerVisibility = Visibility.Visible;
LoadingErrorVisibility = Visibility.Collapsed; LoadingErrorVisibility = Visibility.Collapsed;
ChannelInfoLoadingText = "Fetching latest deploy info, please wait..."; ChannelInfoLoadingText = "Fetching latest deploy info, please wait...";
@ -61,8 +63,8 @@ namespace Bloxstrap.UI.ViewModels.Menu
LoadingSpinnerVisibility = Visibility.Collapsed; LoadingSpinnerVisibility = Visibility.Collapsed;
LoadingErrorVisibility = Visibility.Visible; LoadingErrorVisibility = Visibility.Visible;
App.Logger.WriteLine("[BehaviourViewModel::LoadChannelDeployInfo] An exception occurred while fetching channel information"); App.Logger.WriteLine(LOG_IDENT, "An exception occurred while fetching channel information");
App.Logger.WriteLine($"[BehaviourViewModel::LoadChannelDeployInfo] {ex}"); App.Logger.WriteException(LOG_IDENT, ex);
ChannelInfoLoadingText = $"Failed to fetch information! ({ex.Message})"; ChannelInfoLoadingText = $"Failed to fetch information! ({ex.Message})";

View File

@ -122,7 +122,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
if (shouldCheckInstallLocation) if (shouldCheckInstallLocation)
{ {
App.Logger.WriteLine($"[MainWindowViewModel::ConfirmSettings] Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}"); App.Logger.WriteLine("MainWindowViewModel::ConfirmSettings", $"Changing install location from {_originalBaseDirectory} to {App.BaseDirectory}");
Controls.ShowMessageBox( Controls.ShowMessageBox(
$"{App.ProjectName} will install to the new location you've set the next time it runs.", $"{App.ProjectName} will install to the new location you've set the next time it runs.",

View File

@ -6,6 +6,8 @@ namespace Bloxstrap
{ {
public static void CheckInstalledVersion() public static void CheckInstalledVersion()
{ {
const string LOG_IDENT = "Updater::CheckInstalledVersion";
if (Environment.ProcessPath is null || !File.Exists(Directories.Application) || Environment.ProcessPath == Directories.Application) if (Environment.ProcessPath is null || !File.Exists(Directories.Application) || Environment.ProcessPath == Directories.Application)
return; return;
@ -51,7 +53,7 @@ namespace Bloxstrap
catch (Exception) catch (Exception)
{ {
if (attempts == 1) if (attempts == 1)
App.Logger.WriteLine("[Updater::CheckInstalledVersion] Waiting for write permissions to update version"); App.Logger.WriteLine(LOG_IDENT, "Waiting for write permissions to update version");
Thread.Sleep(500); Thread.Sleep(500);
} }
@ -59,7 +61,7 @@ namespace Bloxstrap
if (attempts == 10) if (attempts == 10)
{ {
App.Logger.WriteLine("[Updater::CheckInstalledVersion] Failed to update! (Could not get write permissions after 5 seconds)"); App.Logger.WriteLine(LOG_IDENT, "Failed to update! (Could not get write permissions after 5 seconds)");
return; return;
} }

View File

@ -4,6 +4,8 @@
{ {
public static async Task<T?> GetJson<T>(string url) public static async Task<T?> GetJson<T>(string url)
{ {
string LOG_IDENT = $"Http::GetJson<{typeof(T).Name}>";
string json = await App.HttpClient.GetStringAsync(url); string json = await App.HttpClient.GetStringAsync(url);
try try
@ -12,8 +14,8 @@
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[Http::GetJson<{typeof(T).Name}>] Failed to deserialize JSON for {url}!"); App.Logger.WriteLine(LOG_IDENT, $"Failed to deserialize JSON for {url}!");
App.Logger.WriteLine($"[Http::GetJson<{typeof(T).Name}>] {ex}"); App.Logger.WriteException(LOG_IDENT, ex);
return default; return default;
} }
} }