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;
Logger.WriteLine($"[App::Terminate] Terminating with exit code {exitCodeNum} ({exitCode})");
Logger.WriteLine("App::Terminate", $"Terminating with exit code {exitCodeNum} ({exitCode})");
Settings.Save();
State.Save();
@ -66,8 +66,8 @@ namespace Bloxstrap
{
e.Handled = true;
Logger.WriteLine("[App::OnStartup] An exception occurred when running the main thread");
Logger.WriteLine($"[App::OnStartup] {e.Exception}");
Logger.WriteLine("App::GlobalExceptionHandler", "An exception occurred");
Logger.WriteLine("App::GlobalExceptionHandler", $"{e.Exception}");
FinalizeExceptionHandling(e.Exception);
}
@ -86,14 +86,16 @@ namespace Bloxstrap
protected override void OnStartup(StartupEventArgs e)
{
const string LOG_IDENT = "App::OnStartup";
base.OnStartup(e);
Logger.WriteLine($"[App::OnStartup] Starting {ProjectName} v{Version}");
Logger.WriteLine(LOG_IDENT, $"Starting {ProjectName} v{Version}");
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
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,
// see https://aka.ms/applicationconfiguration.
@ -108,31 +110,31 @@ namespace Bloxstrap
{
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;
}
if (Array.IndexOf(LaunchArgs, "-quiet") != -1)
{
Logger.WriteLine("[App::OnStartup] Started with IsQuiet flag");
Logger.WriteLine(LOG_IDENT, "Started with IsQuiet flag");
IsQuiet = true;
}
if (Array.IndexOf(LaunchArgs, "-uninstall") != -1)
{
Logger.WriteLine("[App::OnStartup] Started with IsUninstall flag");
Logger.WriteLine(LOG_IDENT, "Started with IsUninstall flag");
IsUninstall = true;
}
if (Array.IndexOf(LaunchArgs, "-nolaunch") != -1)
{
Logger.WriteLine("[App::OnStartup] Started with IsNoLaunch flag");
Logger.WriteLine(LOG_IDENT, "Started with IsNoLaunch flag");
IsNoLaunch = true;
}
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;
}
}
@ -147,7 +149,7 @@ namespace Bloxstrap
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);
Logger.Initialize(true);
@ -169,7 +171,7 @@ namespace Bloxstrap
// exit if we don't click the install button on installation
if (!IsSetupComplete)
{
Logger.WriteLine("[App::OnStartup] Installation cancelled!");
Logger.WriteLine(LOG_IDENT, "Installation cancelled!");
Terminate(ErrorCode.ERROR_CANCELLED);
}
@ -183,7 +185,7 @@ namespace Bloxstrap
if (!Logger.Initialized)
{
Logger.WriteLine("[App::OnStartup] Possible duplicate launch detected, terminating.");
Logger.WriteLine(LOG_IDENT, "Possible duplicate launch detected, terminating.");
Terminate();
}
@ -209,7 +211,7 @@ namespace Bloxstrap
if (menuProcess is not null)
{
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);
}
else
@ -255,13 +257,13 @@ namespace Bloxstrap
ShouldSaveConfigs = true;
// 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);
IBootstrapperDialog? dialog = null;
if (!IsQuiet)
{
Logger.WriteLine($"[App::OnStartup] Initializing bootstrapper dialog");
Logger.WriteLine(LOG_IDENT, "Initializing bootstrapper dialog");
dialog = Settings.Prop.BootstrapperStyle.GetNew();
bootstrapper.Dialog = dialog;
dialog.Bootstrapper = bootstrapper;
@ -275,12 +277,12 @@ namespace Bloxstrap
if (Settings.Prop.MultiInstanceLaunching)
{
Logger.WriteLine("[App::OnStartup] Creating singleton mutex");
Logger.WriteLine(LOG_IDENT, "Creating singleton mutex");
try
{
Mutex.OpenExisting("ROBLOX_singletonMutex");
Logger.WriteLine("[App::OnStartup] Warning - singleton mutex already exists!");
Logger.WriteLine(LOG_IDENT, "Warning - singleton mutex already exists!");
}
catch
{
@ -293,18 +295,18 @@ namespace Bloxstrap
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?.Dispose();
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)
return;
Logger.WriteLine($"[App::OnStartup] {t.Exception}");
Logger.WriteLine(LOG_IDENT, $"{t.Exception}");
Exception exception = t.Exception;
@ -322,13 +324,13 @@ namespace Bloxstrap
if (!IsNoLaunch && Settings.Prop.EnableActivityTracking)
NotifyIcon?.InitializeContextMenu();
Logger.WriteLine($"[App::OnStartup] Waiting for bootstrapper task to finish");
Logger.WriteLine(LOG_IDENT, "Waiting for bootstrapper task to finish");
bootstrapperTask.Wait();
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!
// 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();
}

View File

@ -79,7 +79,7 @@ namespace Bloxstrap
private void SetStatus(string message)
{
App.Logger.WriteLine($"[Bootstrapper::SetStatus] {message}");
App.Logger.WriteLine("Bootstrapper::SetStatus", message);
// yea idk
if (App.Settings.Prop.BootstrapperStyle == BootstrapperStyle.ByfronDialog)
@ -104,7 +104,9 @@ namespace Bloxstrap
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)
{
@ -125,7 +127,7 @@ namespace Bloxstrap
try
{
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;
}
catch (Exception)
@ -196,6 +198,8 @@ namespace Bloxstrap
private async Task StartRoblox()
{
const string LOG_IDENT = "Bootstrapper::StartRoblox";
SetStatus("Starting Roblox...");
if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
@ -235,7 +239,7 @@ namespace Bloxstrap
RobloxActivity? activityWatcher = 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"))
{
@ -256,7 +260,7 @@ namespace Bloxstrap
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);
App.NotifyIcon?.SetRichPresenceHandler(richPresence);
@ -266,7 +270,7 @@ namespace Bloxstrap
// launch custom integrations now
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
{
@ -280,7 +284,8 @@ namespace Bloxstrap
}
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();
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))
await Task.Delay(1000);
App.Logger.WriteLine($"[Bootstrapper::StartRoblox] Roblox has exited");
App.Logger.WriteLine(LOG_IDENT, $"Roblox has exited");
richPresence?.Dispose();
@ -308,20 +313,22 @@ namespace Bloxstrap
if (process.HasExited)
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();
}
}
public void CancelInstall()
{
const string LOG_IDENT = "Bootstrapper::CancelInstall";
if (!_isInstalling)
{
App.Terminate(ErrorCode.ERROR_CANCELLED);
return;
}
App.Logger.WriteLine("[Bootstrapper::CancelInstall] Cancelling install...");
App.Logger.WriteLine(LOG_IDENT, "Cancelling install...");
_cancelTokenSource.Cancel();
_cancelFired = true;
@ -336,8 +343,8 @@ namespace Bloxstrap
}
catch (Exception ex)
{
App.Logger.WriteLine("[Bootstrapper::CancelInstall] Could not fully clean up installation!");
App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {ex}");
App.Logger.WriteLine(LOG_IDENT, "Could not fully clean up installation!");
App.Logger.WriteException(LOG_IDENT, ex);
}
App.Terminate(ErrorCode.ERROR_CANCELLED);
@ -347,6 +354,8 @@ namespace Bloxstrap
#region App Install
public static void Register()
{
const string LOG_IDENT = "Bootstrapper::Register";
using (RegistryKey applicationKey = Registry.CurrentUser.CreateSubKey($@"Software\{App.ProjectName}"))
{
applicationKey.SetValue("InstallLocation", Directories.Base);
@ -372,12 +381,14 @@ namespace Bloxstrap
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()
{
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}");
@ -386,11 +397,13 @@ namespace Bloxstrap
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()
{
const string LOG_IDENT = "Bootstrapper::CheckInstallMigration";
// 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
@ -405,7 +418,7 @@ namespace Bloxstrap
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))
{
@ -422,18 +435,18 @@ namespace Bloxstrap
}
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
{
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)
{
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.Logger.WriteLine("[Bootstrapper::CheckInstallMigration] Finished migrating install location!");
App.Logger.WriteLine(LOG_IDENT, "Finished migrating install location!");
}
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
// this doesn't go under register, so we check every launch
@ -509,8 +524,8 @@ namespace Bloxstrap
}
catch (Exception ex)
{
App.Logger.WriteLine("[Bootstrapper::CheckInstall] Could not create desktop shortcut, aborting");
App.Logger.WriteLine($"[Bootstrapper::CheckInstall] {ex}");
App.Logger.WriteLine(LOG_IDENT, "Could not create desktop shortcut, aborting");
App.Logger.WriteException(LOG_IDENT, ex);
}
}
@ -521,14 +536,16 @@ namespace Bloxstrap
private async Task CheckForUpdates()
{
const string LOG_IDENT = "Bootstrapper::CheckForUpdates";
// don't update if there's another instance running (likely running in the background)
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;
}
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Checking for updates...");
App.Logger.WriteLine(LOG_IDENT, $"Checking for updates...");
GithubRelease? releaseInfo;
try
@ -537,13 +554,13 @@ namespace Bloxstrap
}
catch (Exception ex)
{
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Failed to fetch releases: {ex}");
App.Logger.WriteLine(LOG_IDENT, $"Failed to fetch releases: {ex}");
return;
}
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;
}
@ -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
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;
}
@ -563,7 +580,7 @@ namespace Bloxstrap
GithubReleaseAsset asset = releaseInfo.Assets[0];
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))
{
@ -573,7 +590,7 @@ namespace Bloxstrap
await response.Content.CopyToAsync(fileStream);
}
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Starting {releaseInfo.TagName}...");
App.Logger.WriteLine(LOG_IDENT, $"Starting {releaseInfo.TagName}...");
ProcessStartInfo startInfo = new()
{
@ -593,10 +610,12 @@ namespace Bloxstrap
private void Uninstall()
{
const string LOG_IDENT = "Bootstrapper::Uninstall";
// prompt to shutdown roblox if its currently running
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(
"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)
{
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}...");
@ -680,8 +699,8 @@ namespace Bloxstrap
}
catch (Exception ex)
{
App.Logger.WriteLine($"[Bootstrapper::Uninstall] Encountered exception when running cleanup sequence (#{cleanupSequence.IndexOf(process)})");
App.Logger.WriteLine($"[Bootstrapper::Uninstall] {ex}");
App.Logger.WriteLine(LOG_IDENT, $"Encountered exception when running cleanup sequence (#{cleanupSequence.IndexOf(process)})");
App.Logger.WriteException(LOG_IDENT, ex);
}
}
@ -719,6 +738,8 @@ namespace Bloxstrap
#region Roblox Install
private async Task InstallLatestVersion()
{
const string LOG_IDENT = "Bootstrapper::InstallLatestVersion";
_isInstalling = true;
SetStatus(FreshInstall ? "Installing Roblox..." : "Upgrading Roblox...");
@ -800,7 +821,7 @@ namespace Bloxstrap
{
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);
}
}
@ -815,7 +836,7 @@ namespace Bloxstrap
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.DeleteValue(oldGameClientLocation);
}
@ -831,7 +852,7 @@ namespace Bloxstrap
if (dir.Name == _latestVersionGuid || !dir.Name.StartsWith("version-"))
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);
}
}
@ -851,6 +872,8 @@ namespace Bloxstrap
private async Task InstallWebView2()
{
const string LOG_IDENT = "Bootstrapper::InstallWebView2";
// 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
// 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)
return;
App.Logger.WriteLine($"[Bootstrapper::InstallWebView2] Installing runtime...");
App.Logger.WriteLine(LOG_IDENT, "Installing runtime...");
string baseDirectory = Path.Combine(_versionFolder, "WebView2RuntimeInstaller");
@ -871,7 +894,7 @@ namespace Bloxstrap
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;
}
@ -889,7 +912,7 @@ namespace Bloxstrap
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()
@ -921,10 +944,12 @@ namespace Bloxstrap
private async Task ApplyModifications()
{
const string LOG_IDENT = "Bootstrapper::ApplyModifications";
SetStatus("Applying Roblox modifications...");
// 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"))
{
string flag = " DISABLEDXMAXIMIZEDWINDOWEDMODE";
@ -939,7 +964,7 @@ namespace Bloxstrap
}
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 (appFlags.Split(' ').Length > 2)
@ -955,7 +980,7 @@ namespace Bloxstrap
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 (appFlags.Split(' ').Length > 2)
@ -966,7 +991,7 @@ namespace Bloxstrap
}
// 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);
// manifest has been moved to State.json
@ -1044,7 +1069,7 @@ namespace Bloxstrap
if (File.Exists(Directories.CustomFont))
{
App.Logger.WriteLine("[Bootstrapper::ApplyModifications] Begin font check");
App.Logger.WriteLine(LOG_IDENT, "Begin font check");
Directory.CreateDirectory(modFontFamiliesFolder);
@ -1067,7 +1092,7 @@ namespace Bloxstrap
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))
{
@ -1182,6 +1207,8 @@ namespace Bloxstrap
private async Task DownloadPackage(Package package)
{
const string LOG_IDENT = "Bootstrapper::DownloadPackage";
if (_cancelFired)
return;
@ -1197,12 +1224,12 @@ namespace Bloxstrap
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();
}
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;
UpdateProgressBar();
return;
@ -1213,7 +1240,7 @@ namespace Bloxstrap
// let's cheat! if the stock bootstrapper already previously downloaded the file,
// 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);
_totalDownloadedBytes += package.PackedSize;
UpdateProgressBar();
@ -1222,7 +1249,7 @@ namespace Bloxstrap
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);
@ -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)
{
const string LOG_IDENT = "Bootstrapper::ExtractPackage";
if (_cancelFired)
return;
@ -1265,7 +1294,7 @@ namespace Bloxstrap
string packageFolder = Path.Combine(_versionFolder, PackageDirectories[package.Name]);
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));
@ -1279,7 +1308,7 @@ namespace Bloxstrap
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);
@ -1296,7 +1325,7 @@ namespace Bloxstrap
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;
}

View File

@ -10,6 +10,8 @@ namespace Bloxstrap.Extensions
public static Icon GetIcon(this BootstrapperIcon icon)
{
const string LOG_IDENT = "BootstrapperIconEx::GetIcon";
// load the custom icon file
if (icon == BootstrapperIcon.IconCustom)
{
@ -21,7 +23,8 @@ namespace Bloxstrap.Extensions
}
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;

View File

@ -106,19 +106,21 @@ namespace Bloxstrap
// to delete a flag, set the value as null
public void SetValue(string key, object? value)
{
const string LOG_IDENT = "FastFlagManager::SetValue";
if (value is null)
{
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);
}
else
{
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
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()!;
}

View File

@ -9,13 +9,13 @@
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;
}
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;
}
}

View File

@ -15,6 +15,8 @@ namespace Bloxstrap.Integrations
public DiscordRichPresence(RobloxActivity activityWatcher)
{
const string LOG_IDENT = "DiscordRichPresence::<construct>";
_activityWatcher = activityWatcher;
_activityWatcher.OnGameJoin += (_, _) => Task.Run(() => SetCurrentGame());
@ -22,23 +24,23 @@ namespace Bloxstrap.Integrations
_activityWatcher.OnGameMessage += (_, message) => OnGameMessage(message);
_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) =>
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Presence updated");
App.Logger.WriteLine(LOG_IDENT, "Presence updated");
_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) =>
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
//_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) =>
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();
}
@ -51,17 +53,19 @@ namespace Bloxstrap.Integrations
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)
{
App.Logger.WriteLine($"[DiscordRichPresence::SetStatus] Presence is not set, aborting");
App.Logger.WriteLine(LOG_IDENT, $"Presence is not set, aborting");
return;
}
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;
}
@ -72,7 +76,7 @@ namespace Bloxstrap.Integrations
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;
}
else
@ -82,7 +86,7 @@ namespace Bloxstrap.Integrations
if (_currentPresence.State == finalStatus)
{
App.Logger.WriteLine($"[DiscordRichPresence::SetStatus] Status is unchanged, aborting");
App.Logger.WriteLine(LOG_IDENT, $"Status is unchanged, aborting");
return;
}
@ -92,7 +96,7 @@ namespace Bloxstrap.Integrations
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;
@ -104,9 +108,11 @@ namespace Bloxstrap.Integrations
public async Task<bool> SetCurrentGame()
{
const string LOG_IDENT = "DiscordRichPresence::SetCurrentGame";
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;
_initialStatus = null;
UpdatePresence();
@ -116,17 +122,17 @@ namespace Bloxstrap.Integrations
string icon = "roblox";
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");
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;
}
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
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}");
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;
}
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");
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
{
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();
@ -174,7 +180,7 @@ namespace Bloxstrap.Integrations
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;
}
@ -207,14 +213,16 @@ namespace Bloxstrap.Integrations
public void UpdatePresence()
{
const string LOG_IDENT = "DiscordRichPresence::UpdatePresence";
if (_currentPresence is null)
{
App.Logger.WriteLine($"[DiscordRichPresence::UpdatePresence] Presence is empty, clearing");
App.Logger.WriteLine(LOG_IDENT, $"Presence is empty, clearing");
_rpcClient.ClearPresence();
return;
}
App.Logger.WriteLine($"[DiscordRichPresence::UpdatePresence] Updating presence");
App.Logger.WriteLine(LOG_IDENT, $"Updating presence");
if (_visible)
_rpcClient.SetPresence(_currentPresence);
@ -222,7 +230,7 @@ namespace Bloxstrap.Integrations
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.Dispose();
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 T Prop { get; set; } = new();
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()
{
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
{
@ -18,28 +24,31 @@
Prop = settings;
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Loaded successfully!");
App.Logger.WriteLine(LOG_IDENT, "Loaded successfully!");
}
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()
{
string LOG_IDENT = $"{LOG_IDENT_CLASS}::Save";
if (!App.ShouldSaveConfigs)
{
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Save request ignored");
App.Logger.WriteLine(LOG_IDENT, "Save request ignored");
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)!);
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)
{
const string LOG_IDENT = "Logger::Initialize";
string directory = useTempDir ? Path.Combine(Directories.LocalAppData, "Temp") : Path.Combine(Directories.Base, "Logs");
string timestamp = DateTime.UtcNow.ToString("yyyyMMdd'T'HHmmss'Z'");
string filename = $"{App.ProjectName}_{timestamp}.log";
string location = Path.Combine(directory, filename);
WriteLine($"[Logger::Initialize] Initializing at {location}");
WriteLine(LOG_IDENT, $"Initializing at {location}");
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;
}
@ -34,7 +36,7 @@
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;
}
@ -45,7 +47,7 @@
if (Backlog.Count > 0)
WriteToLog(string.Join("\r\n", Backlog));
WriteLine($"[Logger::Initialize] Finished initializing!");
WriteLine(LOG_IDENT, "Finished initializing!");
FileLocation = location;
@ -57,13 +59,13 @@
if (log.LastWriteTimeUtc.AddDays(7) > DateTime.UtcNow)
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();
}
}
}
public void WriteLine(string message)
private void WriteLine(string message)
{
string timestamp = DateTime.UtcNow.ToString("s") + "Z";
string outcon = $"{timestamp} {message}";
@ -73,6 +75,16 @@
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)
{
if (!Initialized)

View File

@ -94,7 +94,7 @@ namespace Bloxstrap
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;
}
@ -137,7 +137,7 @@ namespace Bloxstrap
}
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()
{
const string LOG_IDENT = "RobloxActivity::StartWatcher";
// okay, here's the process:
//
// - 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
// 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)
{
@ -84,13 +86,13 @@
if (logFileInfo.CreationTime.AddSeconds(15) > DateTime.Now)
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);
}
LogLocation = logFileInfo.FullName;
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);
FileSystemWatcher logWatcher = new()
@ -116,6 +118,8 @@
private void ExamineLogEntry(string entry)
{
const string LOG_IDENT = "RobloxActivity::ExamineLogEntry";
OnLogEntry?.Invoke(this, entry);
_logEntriesRead += 1;
@ -123,9 +127,9 @@
// 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 (_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)
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Read {_logEntriesRead} log entries");
App.Logger.WriteLine(LOG_IDENT, $"Read {_logEntriesRead} log entries");
if (!ActivityInGame && ActivityPlaceId == 0)
{
@ -140,8 +144,8 @@
if (match.Groups.Count != 4)
{
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Failed to assert format for game join entry");
App.Logger.WriteLine(entry);
App.Logger.WriteLine(LOG_IDENT, $"Failed to assert format for game join entry");
App.Logger.WriteLine(LOG_IDENT, entry);
return;
}
@ -162,7 +166,7 @@
_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)
@ -173,15 +177,15 @@
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(entry);
App.Logger.WriteLine(LOG_IDENT, $"Failed to assert format for game join UDMUX entry");
App.Logger.WriteLine(LOG_IDENT, entry);
return;
}
ActivityMachineAddress = match.Groups[1].Value;
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))
{
@ -189,12 +193,12 @@
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(entry);
App.Logger.WriteLine(LOG_IDENT, $"Failed to assert format for game joined entry");
App.Logger.WriteLine(LOG_IDENT, entry);
return;
}
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Joined Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
App.Logger.WriteLine(LOG_IDENT, $"Joined Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
ActivityInGame = true;
OnGameJoin?.Invoke(this, new EventArgs());
@ -204,7 +208,7 @@
{
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;
ActivityPlaceId = 0;
@ -218,7 +222,7 @@
}
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;
}
else if (_teleportMarker && entry.Contains(GameJoiningReservedServerEntry))
@ -231,7 +235,7 @@
string messagePlain = entry.Substring(entry.IndexOf(GameMessageEntry) + GameMessageEntry.Length + 1);
GameMessage? message;
App.Logger.WriteLine($"[RobloxActivity::ExamineLogEntry] Received message: '{messagePlain}'");
App.Logger.WriteLine(LOG_IDENT, $"Received message: '{messagePlain}'");
try
{
@ -239,19 +243,19 @@
}
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;
}
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;
}
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;
}
@ -262,6 +266,8 @@
public async Task<string> GetServerLocation()
{
const string LOG_IDENT = "RobloxActivity::GetServerLocation";
if (GeolcationCache.ContainsKey(ActivityMachineAddress))
return GeolcationCache[ActivityMachineAddress];
@ -275,8 +281,8 @@
}
catch (Exception ex)
{
App.Logger.WriteLine($"[RobloxActivity::GetServerLocation] Failed to get server location for {ActivityMachineAddress}");
App.Logger.WriteLine($"[RobloxActivity::GetServerLocation] {ex}");
App.Logger.WriteLine(LOG_IDENT, $"Failed to get server location for {ActivityMachineAddress}");
App.Logger.WriteException(LOG_IDENT, ex);
return "N/A (lookup failed)";
}

View File

@ -23,24 +23,26 @@ namespace Bloxstrap
{
get
{
const string LOG_IDENT = "DeployManager::DefaultBaseUrl.Set";
if (string.IsNullOrEmpty(_baseUrl))
{
// check for a working accessible deployment domain
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
{
App.HttpClient.GetAsync($"{attemptedUrl}/version").Wait();
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Connection successful!");
App.Logger.WriteLine(LOG_IDENT, "Connection successful!");
_baseUrl = attemptedUrl;
break;
}
catch (Exception ex)
{
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] Connection failed!");
App.Logger.WriteLine($"[DeployManager::DefaultBaseUrl.Set] {ex}");
App.Logger.WriteLine(LOG_IDENT, "Connection failed!");
App.Logger.WriteException(LOG_IDENT, ex);
continue;
}
}
@ -83,13 +85,15 @@ namespace Bloxstrap
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;
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];
}
else
@ -105,8 +109,8 @@ namespace Bloxstrap
// 500 = Error while fetching version information.
// either way, we throw
App.Logger.WriteLine(
"[RobloxDeployment::GetInfo] Failed to fetch deploy info!\r\n" +
App.Logger.WriteLine(LOG_IDENT,
"Failed to fetch deploy info!\r\n" +
$"\tStatus code: {deployInfoResponse.StatusCode}\r\n" +
$"\tResponse: {rawResponse}"
);
@ -121,7 +125,7 @@ namespace Bloxstrap
// for preferences
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);
@ -131,7 +135,7 @@ namespace Bloxstrap
if (pkgResponse.Content.Headers.TryGetValues("last-modified", out var values))
{
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();
}

View File

@ -98,7 +98,7 @@ namespace Bloxstrap.UI.Elements.ContextMenu
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);

View File

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

View File

@ -21,7 +21,7 @@ namespace Bloxstrap.UI
public NotifyIconWrapper()
{
App.Logger.WriteLine("[NotifyIconWrapper::NotifyIconWrapper] Initializing notification area icon");
App.Logger.WriteLine("NotifyIconWrapper::NotifyIconWrapper", "Initializing notification area icon");
_notifyIcon = new()
{
@ -60,7 +60,7 @@ namespace Bloxstrap.UI
if (_menuContainer is not null)
return;
App.Logger.WriteLine("[NotifyIconWrapper::InitializeContextMenu] Initializing context menu");
App.Logger.WriteLine("NotifyIconWrapper::InitializeContextMenu", "Initializing context menu");
_menuContainer = new(_activityWatcher, _richPresenceHandler);
_menuContainer.ShowDialog();
@ -94,15 +94,17 @@ namespace Bloxstrap.UI
{
string id = Guid.NewGuid().ToString()[..8];
App.Logger.WriteLine($"[NotifyIconWrapper::ShowAlert] [{id}] Showing alert for {duration} seconds (clickHandler={clickHandler is not null})");
App.Logger.WriteLine($"[NotifyIconWrapper::ShowAlert] [{id}] {caption}: {message.Replace("\n", "\\n")}");
string LOG_IDENT = $"NotifyIconWrapper::ShowAlert.{id}";
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.BalloonTipText = message;
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;
}
@ -117,12 +119,12 @@ namespace Bloxstrap.UI
_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)
_alertClickHandler = null;
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;
App.Logger.WriteLine($"[NotifyIconWrapper::Dispose] Disposing NotifyIcon");
App.Logger.WriteLine("NotifyIconWrapper::Dispose", "Disposing NotifyIcon");
_menuContainer?.Dispatcher.Invoke(_menuContainer.Close);
_notifyIcon?.Dispose();

View File

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

View File

@ -122,7 +122,7 @@ namespace Bloxstrap.UI.ViewModels.Menu
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(
$"{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()
{
const string LOG_IDENT = "Updater::CheckInstalledVersion";
if (Environment.ProcessPath is null || !File.Exists(Directories.Application) || Environment.ProcessPath == Directories.Application)
return;
@ -51,7 +53,7 @@ namespace Bloxstrap
catch (Exception)
{
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);
}
@ -59,7 +61,7 @@ namespace Bloxstrap
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;
}

View File

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