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 Bloxstrap.Enums;
using Bloxstrap.Extensions;
using Bloxstrap.Models;
using Bloxstrap.Models.Attributes;
@ -34,6 +35,7 @@ namespace Bloxstrap
// used only for communicating between app and menu - use Directories.Base for anything else
public static string BaseDirectory = null!;
public static bool ShouldSaveConfigs { get; set; } = false;
public static bool IsSetupComplete { get; 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 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();
State.Save();
Notification.Dispose();
Environment.Exit(code);
}
private void InitLog()
{
// 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();
}
}
Environment.Exit(exitCodeNum);
}
void GlobalExceptionHandler(object sender, DispatcherUnhandledExceptionEventArgs e)
@ -111,7 +97,7 @@ namespace Bloxstrap
if (!IsQuiet)
Controls.ShowExceptionDialog(exception);
Terminate(Bootstrapper.ERROR_INSTALL_FAILURE);
Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
#pragma warning restore 162
}
@ -193,7 +179,7 @@ namespace Bloxstrap
Logger.WriteLine("[App::OnStartup] Running first-time install");
BaseDirectory = Path.Combine(Directories.LocalAppData, ProjectName);
InitLog();
Logger.Initialize(true);
if (!IsQuiet)
{
@ -213,7 +199,7 @@ namespace Bloxstrap
if (!IsSetupComplete)
{
Logger.WriteLine("[App::OnStartup] Installation cancelled!");
Environment.Exit(Bootstrapper.ERROR_INSTALL_USEREXIT);
Terminate(ErrorCode.ERROR_CANCELLED);
}
Directories.Initialize(BaseDirectory);
@ -222,7 +208,7 @@ namespace Bloxstrap
// just in case the user decides to cancel the install
if (!IsFirstRun)
{
InitLog();
Logger.Initialize(IsUninstall);
Settings.Load();
State.Load();
FastFlags.Load();

View File

@ -24,12 +24,6 @@ namespace Bloxstrap
public class Bootstrapper
{
#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
// 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?
@ -109,7 +103,7 @@ namespace Bloxstrap
Dialog.Message = message;
}
private void UpdateProgressbar()
private void UpdateProgressBar()
{
int newProgress = (int)Math.Floor(_progressIncrement * _totalDownloadedBytes);
@ -378,7 +372,7 @@ namespace Bloxstrap
{
if (!_isInstalling)
{
App.Terminate(ERROR_INSTALL_USEREXIT);
App.Terminate(ErrorCode.ERROR_CANCELLED);
return;
}
@ -401,7 +395,7 @@ namespace Bloxstrap
App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {ex}");
}
App.Terminate(ERROR_INSTALL_USEREXIT);
App.Terminate(ErrorCode.ERROR_CANCELLED);
}
#endregion
@ -581,9 +575,9 @@ namespace Bloxstrap
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)
{
@ -629,10 +623,11 @@ namespace Bloxstrap
startInfo.ArgumentList.Add(arg);
App.Settings.Save();
App.ShouldSaveConfigs = false;
Process.Start(startInfo);
Environment.Exit(0);
App.Terminate();
}
private void Uninstall()
@ -649,7 +644,7 @@ namespace Bloxstrap
);
if (result != MessageBoxResult.OK)
Environment.Exit(ERROR_INSTALL_USEREXIT);
App.Terminate(ErrorCode.ERROR_CANCELLED);
try
{
@ -669,7 +664,6 @@ namespace Bloxstrap
SetStatus($"Uninstalling {App.ProjectName}...");
//App.Settings.ShouldSave = false;
App.ShouldSaveConfigs = false;
// check if stock bootstrapper is still installed
@ -759,7 +753,7 @@ namespace Bloxstrap
MessageBoxImage.Error
);
App.Terminate(ERROR_INSTALL_FAILURE);
App.Terminate(ErrorCode.ERROR_INSTALL_FAILURE);
return;
}
@ -1135,7 +1129,7 @@ namespace Bloxstrap
{
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] {package.Name} is already downloaded, skipping...");
_totalDownloadedBytes += package.PackedSize;
UpdateProgressbar();
UpdateProgressBar();
return;
}
}
@ -1147,7 +1141,7 @@ namespace Bloxstrap
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] Found existing version of {package.Name} ({robloxPackageLocation})! Copying to Downloads folder...");
File.Copy(robloxPackageLocation, packageLocation);
_totalDownloadedBytes += package.PackedSize;
UpdateProgressbar();
UpdateProgressBar();
return;
}
@ -1179,7 +1173,7 @@ namespace Bloxstrap
await fileStream.WriteAsync(buffer, 0, bytesRead, _cancelTokenSource.Token);
_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()
{
App.Logger.WriteLine($"[FastFlagManager::Save] Attempting to save JSON to {FileLocation}...");
// reload for any changes made while the menu was open
Load();
@ -163,12 +161,9 @@ namespace Bloxstrap
Prop[change.Key] = change.Value;
}
Directory.CreateDirectory(Path.GetDirectoryName(FileLocation)!);
File.WriteAllText(FileLocation, JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true }));
base.Save();
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}");
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)
{
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe ID!");
@ -129,7 +129,7 @@ namespace Bloxstrap.Integrations
_activityWatcher.ActivityIsTeleport = false;
_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())
{
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe info!");
@ -139,7 +139,7 @@ namespace Bloxstrap.Integrations
GameDetailResponse universeDetails = gameDetailResponse.Data.ToArray()[0];
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())
{
App.Logger.WriteLine($"[DiscordRichPresence::SetCurrentGame] Could not get Universe thumbnail info!");

View File

@ -11,7 +11,7 @@ namespace Bloxstrap
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
{
@ -22,28 +22,28 @@ namespace Bloxstrap
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)
{
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()
{
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Attempting to save JSON to {FileLocation}...");
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;
}
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Saving to {FileLocation}...");
Directory.CreateDirectory(Path.GetDirectoryName(FileLocation)!);
File.WriteAllText(FileLocation, JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true }));
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] 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 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");
string? directory = Path.GetDirectoryName(filename);
Directory.CreateDirectory(directory);
if (directory is not null)
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)
WriteToLog(string.Join("\r\n", Backlog));
WriteLine($"[Logger::Logger] Initialized at {filename}");
WriteLine($"[Logger::Initialize] Finished initializing!");
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)

View File

@ -63,7 +63,7 @@ namespace Bloxstrap
MessageBoxResult result = App.Settings.Prop.ChannelChangeMode == ChannelChangeMode.Automatic
? MessageBoxResult.Yes
: 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}?",
MessageBoxImage.Question,
MessageBoxButton.YesNo

View File

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

View File

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

View File

@ -1,8 +1,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
namespace Bloxstrap
{
@ -21,21 +19,6 @@ namespace Bloxstrap
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)
{
// 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;
}
}
}
}