mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-21 10:01:27 -07:00
Make logging more consistent
consistent prefix names, and logging exceptions in english
This commit is contained in:
parent
b5f4017326
commit
1df1a8495c
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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()!;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)";
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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})";
|
||||||
|
|
||||||
|
@ -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.",
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user