Consolidate stuff

yea
This commit is contained in:
pizzaboxer 2023-07-02 21:41:45 +01:00
parent 94fe52245e
commit 0a7ae17473
No known key found for this signature in database
GPG Key ID: 59D4A1DBAD0F2BA8
12 changed files with 110 additions and 95 deletions

View File

@ -13,6 +13,7 @@ using System.Windows.Threading;
using Microsoft.Win32; using Microsoft.Win32;
using Bloxstrap.Enums;
using Bloxstrap.Extensions; using Bloxstrap.Extensions;
using Bloxstrap.Models; using Bloxstrap.Models;
using Bloxstrap.Models.Attributes; using Bloxstrap.Models.Attributes;
@ -34,6 +35,7 @@ namespace Bloxstrap
// used only for communicating between app and menu - use Directories.Base for anything else // used only for communicating between app and menu - use Directories.Base for anything else
public static string BaseDirectory = null!; public static string BaseDirectory = null!;
public static bool ShouldSaveConfigs { get; set; } = false; public static bool ShouldSaveConfigs { get; set; } = false;
public static bool IsSetupComplete { get; set; } = true; public static bool IsSetupComplete { get; set; } = true;
public static bool IsFirstRun { get; private set; } = true; public static bool IsFirstRun { get; private set; } = true;
@ -56,39 +58,23 @@ namespace Bloxstrap
public static System.Windows.Forms.NotifyIcon Notification { get; private set; } = null!; public static System.Windows.Forms.NotifyIcon Notification { get; private set; } = null!;
public static void Terminate(int code = Bootstrapper.ERROR_SUCCESS) public static void Terminate(ErrorCode exitCode = ErrorCode.ERROR_SUCCESS)
{ {
Logger.WriteLine($"[App::Terminate] Terminating with exit code {code}"); if (IsFirstRun)
{
if (exitCode == ErrorCode.ERROR_CANCELLED)
exitCode = ErrorCode.ERROR_INSTALL_USEREXIT;
}
int exitCodeNum = (int)exitCode;
Logger.WriteLine($"[App::Terminate] Terminating with exit code {exitCodeNum} ({exitCode})");
Settings.Save(); Settings.Save();
State.Save(); State.Save();
Notification.Dispose(); Notification.Dispose();
Environment.Exit(code);
}
private void InitLog() Environment.Exit(exitCodeNum);
{
// if we're running for the first time or uninstalling, log to temp folder
// else, log to bloxstrap folder
bool isUsingTempDir = IsFirstRun || IsUninstall;
string logdir = isUsingTempDir ? Path.Combine(Directories.LocalAppData, "Temp") : Path.Combine(Directories.Base, "Logs");
string timestamp = DateTime.UtcNow.ToString("yyyyMMdd'T'HHmmss'Z'");
int processId = Process.GetCurrentProcess().Id;
Logger.Initialize(Path.Combine(logdir, $"{ProjectName}_{timestamp}_{processId}.log"));
// clean up any logs older than a week
if (!isUsingTempDir)
{
foreach (FileInfo log in new DirectoryInfo(logdir).GetFiles())
{
if (log.LastWriteTimeUtc.AddDays(7) > DateTime.UtcNow)
continue;
Logger.WriteLine($"[App::InitLog] Cleaning up old log file '{log.Name}'");
log.Delete();
}
}
} }
void GlobalExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e) void GlobalExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e)
@ -111,7 +97,7 @@ namespace Bloxstrap
if (!IsQuiet) if (!IsQuiet)
Controls.ShowExceptionDialog(exception); Controls.ShowExceptionDialog(exception);
Terminate(Bootstrapper.ERROR_INSTALL_FAILURE); Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
#pragma warning restore 162 #pragma warning restore 162
} }
@ -193,7 +179,7 @@ namespace Bloxstrap
Logger.WriteLine("[App::OnStartup] Running first-time install"); Logger.WriteLine("[App::OnStartup] Running first-time install");
BaseDirectory = Path.Combine(Directories.LocalAppData, ProjectName); BaseDirectory = Path.Combine(Directories.LocalAppData, ProjectName);
InitLog(); Logger.Initialize(true);
if (!IsQuiet) if (!IsQuiet)
{ {
@ -213,7 +199,7 @@ namespace Bloxstrap
if (!IsSetupComplete) if (!IsSetupComplete)
{ {
Logger.WriteLine("[App::OnStartup] Installation cancelled!"); Logger.WriteLine("[App::OnStartup] Installation cancelled!");
Environment.Exit(Bootstrapper.ERROR_INSTALL_USEREXIT); Terminate(ErrorCode.ERROR_CANCELLED);
} }
Directories.Initialize(BaseDirectory); Directories.Initialize(BaseDirectory);
@ -222,7 +208,7 @@ namespace Bloxstrap
// just in case the user decides to cancel the install // just in case the user decides to cancel the install
if (!IsFirstRun) if (!IsFirstRun)
{ {
InitLog(); Logger.Initialize(IsUninstall);
Settings.Load(); Settings.Load();
State.Load(); State.Load();
FastFlags.Load(); FastFlags.Load();

View File

@ -24,12 +24,6 @@ namespace Bloxstrap
public class Bootstrapper public class Bootstrapper
{ {
#region Properties #region Properties
// https://learn.microsoft.com/en-us/windows/win32/msi/error-codes
public const int ERROR_SUCCESS = 0;
public const int ERROR_INSTALL_USEREXIT = 1602;
public const int ERROR_INSTALL_FAILURE = 1603;
// in case a new package is added, you can find the corresponding directory // in case a new package is added, you can find the corresponding directory
// by opening the stock bootstrapper in a hex editor // by opening the stock bootstrapper in a hex editor
// TODO - there ideally should be a less static way to do this that's not hardcoded? // TODO - there ideally should be a less static way to do this that's not hardcoded?
@ -109,7 +103,7 @@ namespace Bloxstrap
Dialog.Message = message; Dialog.Message = message;
} }
private void UpdateProgressbar() private void UpdateProgressBar()
{ {
int newProgress = (int)Math.Floor(_progressIncrement * _totalDownloadedBytes); int newProgress = (int)Math.Floor(_progressIncrement * _totalDownloadedBytes);
@ -378,7 +372,7 @@ namespace Bloxstrap
{ {
if (!_isInstalling) if (!_isInstalling)
{ {
App.Terminate(ERROR_INSTALL_USEREXIT); App.Terminate(ErrorCode.ERROR_CANCELLED);
return; return;
} }
@ -401,7 +395,7 @@ namespace Bloxstrap
App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {ex}"); App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {ex}");
} }
App.Terminate(ERROR_INSTALL_USEREXIT); App.Terminate(ErrorCode.ERROR_CANCELLED);
} }
#endregion #endregion
@ -581,9 +575,9 @@ namespace Bloxstrap
return; return;
} }
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Checking for {App.ProjectName} updates..."); App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Checking for updates...");
var releaseInfo = await Utilities.GetJson<GithubRelease>($"https://api.github.com/repos/{App.ProjectRepository}/releases/latest"); var releaseInfo = await Utility.Http.GetJson<GithubRelease>($"https://api.github.com/repos/{App.ProjectRepository}/releases/latest");
if (releaseInfo is null || releaseInfo.Assets is null) if (releaseInfo is null || releaseInfo.Assets is null)
{ {
@ -629,10 +623,11 @@ namespace Bloxstrap
startInfo.ArgumentList.Add(arg); startInfo.ArgumentList.Add(arg);
App.Settings.Save(); App.Settings.Save();
App.ShouldSaveConfigs = false;
Process.Start(startInfo); Process.Start(startInfo);
Environment.Exit(0); App.Terminate();
} }
private void Uninstall() private void Uninstall()
@ -649,7 +644,7 @@ namespace Bloxstrap
); );
if (result != MessageBoxResult.OK) if (result != MessageBoxResult.OK)
Environment.Exit(ERROR_INSTALL_USEREXIT); App.Terminate(ErrorCode.ERROR_CANCELLED);
try try
{ {
@ -669,7 +664,6 @@ namespace Bloxstrap
SetStatus($"Uninstalling {App.ProjectName}..."); SetStatus($"Uninstalling {App.ProjectName}...");
//App.Settings.ShouldSave = false;
App.ShouldSaveConfigs = false; App.ShouldSaveConfigs = false;
// check if stock bootstrapper is still installed // check if stock bootstrapper is still installed
@ -759,7 +753,7 @@ namespace Bloxstrap
MessageBoxImage.Error MessageBoxImage.Error
); );
App.Terminate(ERROR_INSTALL_FAILURE); App.Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
return; return;
} }
@ -1135,7 +1129,7 @@ namespace Bloxstrap
{ {
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] {package.Name} is already downloaded, skipping..."); App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] {package.Name} is already downloaded, skipping...");
_totalDownloadedBytes += package.PackedSize; _totalDownloadedBytes += package.PackedSize;
UpdateProgressbar(); UpdateProgressBar();
return; return;
} }
} }
@ -1147,7 +1141,7 @@ namespace Bloxstrap
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] Found existing version of {package.Name} ({robloxPackageLocation})! Copying to Downloads folder..."); App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] 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();
return; return;
} }
@ -1179,7 +1173,7 @@ namespace Bloxstrap
await fileStream.WriteAsync(buffer, 0, bytesRead, _cancelTokenSource.Token); await fileStream.WriteAsync(buffer, 0, bytesRead, _cancelTokenSource.Token);
_totalDownloadedBytes += bytesRead; _totalDownloadedBytes += bytesRead;
UpdateProgressbar(); UpdateProgressBar();
} }
} }

View File

@ -0,0 +1,14 @@
namespace Bloxstrap.Enums
{
// https://learn.microsoft.com/en-us/windows/win32/msi/error-codes
// https://i-logic.com/serial/errorcodes.htm
// just the ones that we're interested in
public enum ErrorCode
{
ERROR_SUCCESS = 0,
ERROR_INSTALL_USEREXIT = 1602,
ERROR_INSTALL_FAILURE = 1603,
ERROR_CANCELLED = 1223
}
}

View File

@ -139,8 +139,6 @@ namespace Bloxstrap
public override void Save() public override void Save()
{ {
App.Logger.WriteLine($"[FastFlagManager::Save] Attempting to save JSON to {FileLocation}...");
// reload for any changes made while the menu was open // reload for any changes made while the menu was open
Load(); Load();
@ -163,12 +161,9 @@ namespace Bloxstrap
Prop[change.Key] = change.Value; Prop[change.Key] = change.Value;
} }
Directory.CreateDirectory(Path.GetDirectoryName(FileLocation)!); base.Save();
File.WriteAllText(FileLocation, JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true }));
Changes.Clear(); Changes.Clear();
App.Logger.WriteLine($"[FastFlagManager::Save] JSON saved!");
} }
} }
} }

View File

@ -112,7 +112,7 @@ namespace Bloxstrap.Integrations
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Setting presence for Place ID {_activityWatcher.ActivityPlaceId}"); App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Setting presence for Place ID {_activityWatcher.ActivityPlaceId}");
var universeIdResponse = await Utilities.GetJson<UniverseIdResponse>($"https://apis.roblox.com/universes/v1/places/{_activityWatcher.ActivityPlaceId}/universe"); var universeIdResponse = await Utility.Http.GetJson<UniverseIdResponse>($"https://apis.roblox.com/universes/v1/places/{_activityWatcher.ActivityPlaceId}/universe");
if (universeIdResponse is null) if (universeIdResponse is null)
{ {
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe ID!"); App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe ID!");
@ -129,7 +129,7 @@ namespace Bloxstrap.Integrations
_activityWatcher.ActivityIsTeleport = false; _activityWatcher.ActivityIsTeleport = false;
_currentUniverseId = universeId; _currentUniverseId = universeId;
var gameDetailResponse = await Utilities.GetJson<ApiArrayResponse<GameDetailResponse>>($"https://games.roblox.com/v1/games?universeIds={universeId}"); var gameDetailResponse = await Utility.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($"[DiscordRichPresence::SetCurrentGame] Could not get Universe info!");
@ -139,7 +139,7 @@ namespace Bloxstrap.Integrations
GameDetailResponse universeDetails = gameDetailResponse.Data.ToArray()[0]; GameDetailResponse universeDetails = gameDetailResponse.Data.ToArray()[0];
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Got Universe details"); App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Got Universe details");
var universeThumbnailResponse = await Utilities.GetJson<ApiArrayResponse<ThumbnailResponse>>($"https://thumbnails.roblox.com/v1/games/icons?universeIds={universeId}&returnPolicy=PlaceHolder&size=512x512&format=Png&isCircular=false"); var universeThumbnailResponse = await Utility.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($"[DiscordRichPresence::SetCurrentGame] Could not get Universe thumbnail info!");

View File

@ -11,7 +11,7 @@ namespace Bloxstrap
public virtual void Load() public virtual void Load()
{ {
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Loading JSON from {FileLocation}..."); App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Loading from {FileLocation}...");
try try
{ {
@ -22,28 +22,28 @@ namespace Bloxstrap
Prop = settings; Prop = settings;
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] JSON loaded successfully!"); App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Loaded successfully!");
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Failed to load JSON! ({ex.Message})"); App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Failed to load! ({ex.Message})");
} }
} }
public virtual void Save() public virtual void Save()
{ {
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Attempting to save JSON to {FileLocation}...");
if (!App.ShouldSaveConfigs) if (!App.ShouldSaveConfigs)
{ {
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Aborted save (ShouldSave set to false)"); App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Save request ignored");
return; return;
} }
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] 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] JSON saved!"); App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Save complete!");
} }
} }
} }

View File

@ -20,27 +20,44 @@ namespace Bloxstrap
public readonly List<string> Backlog = new(); public readonly List<string> Backlog = new();
public bool Initialized = false; public bool Initialized = false;
public string? Filename; public string? FileLocation;
public void Initialize(string filename) public void Initialize(bool useTempDir = false)
{ {
if (_filestream is not null) 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}");
if (Initialized)
throw new Exception("Logger is already initialized"); throw new Exception("Logger is already initialized");
string? directory = Path.GetDirectoryName(filename);
if (directory is not null)
Directory.CreateDirectory(directory); Directory.CreateDirectory(directory);
_filestream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read); _filestream = File.Open(location, FileMode.Create, FileAccess.Write, FileShare.Read);
if (Backlog.Count > 0) if (Backlog.Count > 0)
WriteToLog(string.Join("\r\n", Backlog)); WriteToLog(string.Join("\r\n", Backlog));
WriteLine($"[Logger::Logger] Initialized at {filename}"); WriteLine($"[Logger::Initialize] Finished initializing!");
Initialized = true; Initialized = true;
Filename = filename; FileLocation = location;
// clean up any logs older than a week
if (!useTempDir)
{
foreach (FileInfo log in new DirectoryInfo(directory).GetFiles())
{
if (log.LastWriteTimeUtc.AddDays(7) > DateTime.UtcNow)
continue;
App.Logger.WriteLine($"[Logger::Initialize] Cleaning up old log file '{log.Name}'");
log.Delete();
}
}
} }
public void WriteLine(string message) public void WriteLine(string message)

View File

@ -63,7 +63,7 @@ namespace Bloxstrap
MessageBoxResult result = App.Settings.Prop.ChannelChangeMode == ChannelChangeMode.Automatic MessageBoxResult result = App.Settings.Prop.ChannelChangeMode == ChannelChangeMode.Automatic
? MessageBoxResult.Yes ? MessageBoxResult.Yes
: Controls.ShowMessageBox( : Controls.ShowMessageBox(
$"{App.ProjectName} was launched with the Roblox build channel set to {val}, however your current preferred channel is {App.Settings.Prop.Channel}.\n\n" + $"Roblox is attempting to set your channel to {val}, however your current preferred channel is {App.Settings.Prop.Channel}.\n\n" +
$"Would you like to switch channels from {App.Settings.Prop.Channel} to {val}?", $"Would you like to switch channels from {App.Settings.Prop.Channel} to {val}?",
MessageBoxImage.Question, MessageBoxImage.Question,
MessageBoxButton.YesNo MessageBoxButton.YesNo

View File

@ -29,7 +29,7 @@ namespace Bloxstrap.UI
LocateLogFileButton.Click += delegate LocateLogFileButton.Click += delegate
{ {
if (App.Logger.Initialized) if (App.Logger.Initialized)
Process.Start("explorer.exe", $"/select,\"{App.Logger.Filename}\""); Process.Start("explorer.exe", $"/select,\"{App.Logger.FileLocation}\"");
else else
Clipboard.SetText(String.Join("\r\n", App.Logger.Backlog)); Clipboard.SetText(String.Join("\r\n", App.Logger.Backlog));
}; };

View File

@ -98,6 +98,7 @@ namespace Bloxstrap
); );
Controls.ShowMenu(); Controls.ShowMenu();
App.Terminate(); App.Terminate();
} }
} }

View File

@ -1,8 +1,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
namespace Bloxstrap namespace Bloxstrap
{ {
@ -21,21 +19,6 @@ namespace Bloxstrap
public static void ShellExecute(string website) => Process.Start(new ProcessStartInfo { FileName = website, UseShellExecute = true }); public static void ShellExecute(string website) => Process.Start(new ProcessStartInfo { FileName = website, UseShellExecute = true });
public static async Task<T?> GetJson<T>(string url)
{
try
{
string json = await App.HttpClient.GetStringAsync(url);
return JsonSerializer.Deserialize<T>(json);
}
catch (Exception ex)
{
App.Logger.WriteLine($"[Utilities::GetJson<{typeof(T).Name}>] Failed to deserialize JSON for {url}!");
App.Logger.WriteLine($"[Utilities::GetJson<{typeof(T).Name}>] {ex}");
return default;
}
}
public static int VersionToNumber(string version) public static int VersionToNumber(string version)
{ {
// yes this is kinda stupid lol // yes this is kinda stupid lol

25
Bloxstrap/Utility/Http.cs Normal file
View File

@ -0,0 +1,25 @@
using System;
using System.Text.Json;
using System.Threading.Tasks;
namespace Bloxstrap.Utility
{
internal static class Http
{
public static async Task<T?> GetJson<T>(string url)
{
string json = await App.HttpClient.GetStringAsync(url);
try
{
return JsonSerializer.Deserialize<T>(json);
}
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}");
return default;
}
}
}
}