mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-06-23 23:00:23 -07:00
Add logging
saves to bloxstrap folder if installed, temp local appdata folder if not installed or uninstalling
This commit is contained in:
parent
72783ec391
commit
a634351c9d
@ -30,7 +30,7 @@ namespace Bloxstrap
|
||||
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; } = false;
|
||||
public static bool IsFirstRun { get; private set; } = true;
|
||||
public static bool IsQuiet { get; private set; } = false;
|
||||
public static bool IsUninstall { get; private set; } = false;
|
||||
public static bool IsNoLaunch { get; private set; } = false;
|
||||
@ -40,6 +40,8 @@ namespace Bloxstrap
|
||||
|
||||
public static string Version = Assembly.GetExecutingAssembly().GetName().Version!.ToString()[..^2];
|
||||
|
||||
// singletons
|
||||
public static Logger Logger { get; private set; } = null!;
|
||||
public static readonly JsonManager<Settings> Settings = new();
|
||||
public static readonly JsonManager<State> State = new();
|
||||
public static readonly HttpClient HttpClient = new(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.All });
|
||||
@ -55,7 +57,7 @@ namespace Bloxstrap
|
||||
|
||||
public static void Terminate(int code = Bootstrapper.ERROR_SUCCESS)
|
||||
{
|
||||
Debug.WriteLine($"[App] Terminating with exit code {code}");
|
||||
Logger.WriteLine($"[App::Terminate] Terminating with exit code {code}");
|
||||
Settings.Save();
|
||||
State.Save();
|
||||
Environment.Exit(code);
|
||||
@ -94,7 +96,6 @@ namespace Bloxstrap
|
||||
|
||||
if (registryKey is null)
|
||||
{
|
||||
IsFirstRun = true;
|
||||
BaseDirectory = Path.Combine(Directories.LocalAppData, ProjectName);
|
||||
|
||||
if (!IsQuiet)
|
||||
@ -105,6 +106,7 @@ namespace Bloxstrap
|
||||
}
|
||||
else
|
||||
{
|
||||
IsFirstRun = false;
|
||||
BaseDirectory = (string)registryKey.GetValue("InstallLocation")!;
|
||||
registryKey.Close();
|
||||
}
|
||||
@ -115,6 +117,10 @@ namespace Bloxstrap
|
||||
|
||||
Directories.Initialize(BaseDirectory);
|
||||
|
||||
string logdir = IsFirstRun || IsUninstall ? Path.Combine(Directories.LocalAppData, "Temp") : Path.Combine(Directories.Base, "Logs");
|
||||
string timestamp = DateTime.UtcNow.ToString("yyyyMMdd'T'HHmmss'Z'");
|
||||
Logger = new(Path.Combine(logdir, $"{ProjectName}_{timestamp}.log"));
|
||||
|
||||
// we shouldn't save settings on the first run until the first installation is finished,
|
||||
// just in case the user decides to cancel the install
|
||||
if (!IsFirstRun)
|
||||
@ -182,16 +188,19 @@ namespace Bloxstrap
|
||||
|
||||
Task bootstrapperTask = Task.Run(() => bootstrapper.Run()).ContinueWith(t =>
|
||||
{
|
||||
// TODO: add error logging
|
||||
Debug.WriteLine("[App] Bootstrapper task has finished");
|
||||
Logger.WriteLine("[App::OnStartup] Bootstrapper task has finished");
|
||||
|
||||
if (t.Exception is null)
|
||||
return;
|
||||
|
||||
Logger.WriteLine("[App::OnStartup] An exception occurred when running the bootstrapper");
|
||||
Logger.WriteLine($"[App::OnStartup] {t.Exception}");
|
||||
|
||||
#if DEBUG
|
||||
throw t.Exception;
|
||||
#else
|
||||
dialog?.ShowError(t.Exception.ToString());
|
||||
var exception = t.Exception.InnerExceptions.Count >= 1 ? t.Exception.InnerExceptions[0] : t.Exception;
|
||||
dialog?.ShowError($"{exception.GetType()}: {exception.Message}");
|
||||
#endif
|
||||
});
|
||||
|
||||
|
@ -91,7 +91,7 @@ namespace Bloxstrap
|
||||
|
||||
private void SetStatus(string message)
|
||||
{
|
||||
Debug.WriteLine($"[Bootstrapper] {message}");
|
||||
App.Logger.WriteLine($"[Bootstrapper::SetStatus] {message}");
|
||||
|
||||
if (Dialog is not null)
|
||||
Dialog.Message = message;
|
||||
@ -99,6 +99,8 @@ namespace Bloxstrap
|
||||
|
||||
public async Task Run()
|
||||
{
|
||||
App.Logger.WriteLine("[Bootstrapper::Run] Running bootstrapper");
|
||||
|
||||
if (App.IsUninstall)
|
||||
{
|
||||
Uninstall();
|
||||
@ -142,10 +144,15 @@ namespace Bloxstrap
|
||||
{
|
||||
string currentVersion = $"{App.ProjectName} v{App.Version}";
|
||||
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Checking for {App.ProjectName} updates...");
|
||||
|
||||
var releaseInfo = await Utilities.GetJson<GithubRelease>($"https://api.github.com/repos/{App.ProjectRepository}/releases/latest");
|
||||
|
||||
if (releaseInfo?.Assets is null || currentVersion == releaseInfo.Name)
|
||||
{
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] No updates found");
|
||||
return;
|
||||
}
|
||||
|
||||
SetStatus($"Getting the latest {App.ProjectName}...");
|
||||
|
||||
@ -155,7 +162,7 @@ namespace Bloxstrap
|
||||
|
||||
Directory.CreateDirectory(Directories.Updates);
|
||||
|
||||
Debug.WriteLine($"Downloading {releaseInfo.Name}...");
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Downloading {releaseInfo.Name}...");
|
||||
|
||||
if (!File.Exists(downloadLocation))
|
||||
{
|
||||
@ -165,7 +172,7 @@ namespace Bloxstrap
|
||||
await response.Content.CopyToAsync(fileStream);
|
||||
}
|
||||
|
||||
Debug.WriteLine($"Starting {releaseInfo.Name}...");
|
||||
App.Logger.WriteLine($"[Bootstrapper::CheckForUpdates] Starting {releaseInfo.Name}...");
|
||||
|
||||
ProcessStartInfo startInfo = new()
|
||||
{
|
||||
@ -257,6 +264,8 @@ namespace Bloxstrap
|
||||
|
||||
if (App.Settings.Prop.RFUEnabled && Process.GetProcessesByName("rbxfpsunlocker").Length == 0)
|
||||
{
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Using rbxfpsunlocker");
|
||||
|
||||
ProcessStartInfo startInfo = new()
|
||||
{
|
||||
WorkingDirectory = Path.Combine(Directories.Integrations, "rbxfpsunlocker"),
|
||||
@ -269,8 +278,16 @@ namespace Bloxstrap
|
||||
shouldWait = true;
|
||||
}
|
||||
|
||||
if (App.Settings.Prop.UseDiscordRichPresence)
|
||||
{
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Using Discord Rich Presence");
|
||||
richPresence = new DiscordRichPresence();
|
||||
shouldWait = true;
|
||||
}
|
||||
|
||||
if (App.Settings.Prop.MultiInstanceLaunching)
|
||||
{
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Creating singleton mutex");
|
||||
// this might be a bit problematic since this mutex will be released when the first launched instance is closed...
|
||||
singletonMutex = new Mutex(true, "ROBLOX_singletonMutex");
|
||||
shouldWait = true;
|
||||
@ -278,25 +295,21 @@ namespace Bloxstrap
|
||||
|
||||
// event fired, wait for 3 seconds then close
|
||||
await Task.Delay(3000);
|
||||
Dialog?.CloseBootstrapper();
|
||||
|
||||
if (App.Settings.Prop.UseDiscordRichPresence)
|
||||
{
|
||||
richPresence = new DiscordRichPresence();
|
||||
richPresence.MonitorGameActivity();
|
||||
shouldWait = true;
|
||||
}
|
||||
|
||||
// keep bloxstrap open in the background if needed
|
||||
if (!shouldWait)
|
||||
return;
|
||||
|
||||
// keep bloxstrap open in the background
|
||||
Dialog?.CloseBootstrapper();
|
||||
richPresence?.MonitorGameActivity();
|
||||
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Waiting for Roblox to close");
|
||||
await gameClient.WaitForExitAsync();
|
||||
|
||||
richPresence?.Dispose();
|
||||
|
||||
if (App.Settings.Prop.RFUAutoclose && rbxFpsUnlocker is not null)
|
||||
rbxFpsUnlocker.Kill();
|
||||
if (App.Settings.Prop.RFUAutoclose)
|
||||
rbxFpsUnlocker?.Kill();
|
||||
}
|
||||
|
||||
public void CancelInstall()
|
||||
@ -307,6 +320,8 @@ namespace Bloxstrap
|
||||
return;
|
||||
}
|
||||
|
||||
App.Logger.WriteLine("[Bootstrapper::CancelInstall] Cancelling install...");
|
||||
|
||||
_cancelTokenSource.Cancel();
|
||||
_cancelFired = true;
|
||||
|
||||
@ -320,8 +335,8 @@ namespace Bloxstrap
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("[Bootstrapper} Could not fully clean up installation!");
|
||||
Debug.WriteLine(e);
|
||||
App.Logger.WriteLine("[Bootstrapper::CancelInstall] Could not fully clean up installation!");
|
||||
App.Logger.WriteLine($"[Bootstrapper::CancelInstall] {e}");
|
||||
}
|
||||
|
||||
App.Terminate(ERROR_INSTALL_USEREXIT);
|
||||
@ -371,10 +386,14 @@ namespace Bloxstrap
|
||||
uninstallKey.SetValue("URLInfoAbout", $"https://github.com/{App.ProjectRepository}");
|
||||
uninstallKey.SetValue("URLUpdateInfo", $"https://github.com/{App.ProjectRepository}/releases/latest");
|
||||
uninstallKey.Close();
|
||||
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Registered application version");
|
||||
}
|
||||
|
||||
public static void CheckInstall()
|
||||
{
|
||||
App.Logger.WriteLine("[Bootstrapper::StartRoblox] Checking install");
|
||||
|
||||
// check if launch uri is set to our bootstrapper
|
||||
// this doesn't go under register, so we check every launch
|
||||
// just in case the stock bootstrapper changes it back
|
||||
@ -470,7 +489,7 @@ namespace Bloxstrap
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine($"Could not fully uninstall! ({e})");
|
||||
App.Logger.WriteLine($"Could not fully uninstall! ({e})");
|
||||
}
|
||||
|
||||
Dialog?.ShowSuccess($"{App.ProjectName} has succesfully uninstalled");
|
||||
@ -563,7 +582,10 @@ namespace Bloxstrap
|
||||
foreach (string filename in Directory.GetFiles(Directories.Downloads))
|
||||
{
|
||||
if (!_versionPackageManifest.Exists(package => filename.Contains(package.Signature)))
|
||||
{
|
||||
App.Logger.WriteLine($"Deleting unused package {filename}");
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
|
||||
string oldVersionFolder = Path.Combine(Directories.Versions, App.State.Prop.VersionGuid);
|
||||
@ -716,12 +738,12 @@ namespace Bloxstrap
|
||||
string calculatedMD5 = Utilities.MD5File(packageLocation);
|
||||
if (calculatedMD5 != package.Signature)
|
||||
{
|
||||
Debug.WriteLine($"{package.Name} is corrupted ({calculatedMD5} != {package.Signature})! Deleting and re-downloading...");
|
||||
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] {package.Name} is corrupted ({calculatedMD5} != {package.Signature})! Deleting and re-downloading...");
|
||||
file.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine($"{package.Name} is already downloaded, skipping...");
|
||||
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] {package.Name} is already downloaded, skipping...");
|
||||
_totalDownloadedBytes += package.PackedSize;
|
||||
UpdateProgressbar();
|
||||
return;
|
||||
@ -732,7 +754,7 @@ namespace Bloxstrap
|
||||
// let's cheat! if the stock bootstrapper already previously downloaded the file,
|
||||
// then we can just copy the one from there
|
||||
|
||||
Debug.WriteLine($"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);
|
||||
_totalDownloadedBytes += package.PackedSize;
|
||||
UpdateProgressbar();
|
||||
@ -741,7 +763,7 @@ namespace Bloxstrap
|
||||
|
||||
if (!File.Exists(packageLocation))
|
||||
{
|
||||
Debug.WriteLine($"Downloading {package.Name} ({package.Signature})...");
|
||||
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] Downloading {package.Name} ({package.Signature})...");
|
||||
|
||||
{
|
||||
var response = await App.HttpClient.GetAsync(packageUrl, HttpCompletionOption.ResponseHeadersRead, _cancelTokenSource.Token);
|
||||
@ -771,7 +793,7 @@ namespace Bloxstrap
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine($"Finished downloading {package.Name}!");
|
||||
App.Logger.WriteLine($"[Bootstrapper::DownloadPackage] Finished downloading {package.Name}!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,7 +806,7 @@ namespace Bloxstrap
|
||||
string packageFolder = Path.Combine(_versionFolder, PackageDirectories[package.Name]);
|
||||
string extractPath;
|
||||
|
||||
Debug.WriteLine($"Extracting {package.Name} to {packageFolder}...");
|
||||
App.Logger.WriteLine($"[Bootstrapper::ExtractPackage] Extracting {package.Name} to {packageFolder}...");
|
||||
|
||||
using (ZipArchive archive = await Task.Run(() => ZipFile.OpenRead(packageLocation)))
|
||||
{
|
||||
@ -798,7 +820,7 @@ namespace Bloxstrap
|
||||
|
||||
extractPath = Path.Combine(packageFolder, entry.FullName);
|
||||
|
||||
//Debug.WriteLine($"[{package.Name}] Writing {extractPath}...");
|
||||
//App.Logger.WriteLine($"[{package.Name}] Writing {extractPath}...");
|
||||
|
||||
string? directory = Path.GetDirectoryName(extractPath);
|
||||
|
||||
@ -811,7 +833,7 @@ namespace Bloxstrap
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine($"Finished extracting {package.Name}");
|
||||
App.Logger.WriteLine($"[Bootstrapper::ExtractPackage] Finished extracting {package.Name}");
|
||||
|
||||
_packagesExtracted += 1;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ namespace Bloxstrap.Helpers
|
||||
{
|
||||
// note that these are directories that aren't tethered to the basedirectory
|
||||
// so these can safely be called before initialization
|
||||
public static string UserProfile => Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
public static string LocalAppData => Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
public static string Desktop => Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
|
||||
public static string StartMenu => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Programs", App.ProjectName);
|
||||
|
@ -32,12 +32,28 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public DiscordRichPresence()
|
||||
{
|
||||
RichPresence.OnReady += (_, e) =>
|
||||
App.Logger.WriteLine($"[DiscordRichPresence::DiscordRichPresence] Received ready from user {e.User.Username} ({e.User.ID})");
|
||||
|
||||
RichPresence.OnPresenceUpdate += (_, e) =>
|
||||
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Updated presence");
|
||||
|
||||
RichPresence.OnConnectionEstablished += (_, e) =>
|
||||
App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Established connection with Discord RPC!");
|
||||
|
||||
//spams log as it tries to connect every ~15 sec when discord is closed so not now
|
||||
//RichPresence.OnConnectionFailed += (_, e) =>
|
||||
// App.Logger.WriteLine("[DiscordRichPresence::DiscordRichPresence] Failed to establish connection with Discord RPC!");
|
||||
|
||||
RichPresence.OnClose += (_, e) =>
|
||||
App.Logger.WriteLine($"[DiscordRichPresence::DiscordRichPresence] Lost connection to Discord RPC - {e.Reason} ({e.Code})");
|
||||
|
||||
RichPresence.Initialize();
|
||||
}
|
||||
|
||||
private async Task ExamineLogEntry(string entry)
|
||||
{
|
||||
Debug.WriteLine(entry);
|
||||
// App.Logger.WriteLine(entry);
|
||||
|
||||
if (entry.Contains(GameJoiningEntry) && !ActivityInGame && ActivityPlaceId == 0)
|
||||
{
|
||||
@ -51,7 +67,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
ActivityJobId = match.Groups[1].Value;
|
||||
ActivityMachineAddress = match.Groups[3].Value;
|
||||
|
||||
Debug.WriteLine($"[DiscordRichPresence] Joining Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
|
||||
App.Logger.WriteLine($"[DiscordRichPresence::ExamineLogEntry] Joining Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
|
||||
}
|
||||
else if (entry.Contains(GameJoinedEntry) && !ActivityInGame && ActivityPlaceId != 0)
|
||||
{
|
||||
@ -60,14 +76,14 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
if (match.Groups.Count != 3 || match.Groups[1].Value != ActivityMachineAddress)
|
||||
return;
|
||||
|
||||
Debug.WriteLine($"[DiscordRichPresence] Joined Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
|
||||
App.Logger.WriteLine($"[DiscordRichPresence::ExamineLogEntry] Joined Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
|
||||
|
||||
ActivityInGame = true;
|
||||
await SetPresence();
|
||||
}
|
||||
else if (entry.Contains(GameDisconnectedEntry) && ActivityInGame && ActivityPlaceId != 0)
|
||||
{
|
||||
Debug.WriteLine($"[DiscordRichPresence] Disconnected from Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
|
||||
App.Logger.WriteLine($"[DiscordRichPresence::ExamineLogEntry] Disconnected from Game ({ActivityPlaceId}/{ActivityJobId}/{ActivityMachineAddress})");
|
||||
|
||||
ActivityInGame = false;
|
||||
ActivityPlaceId = 0;
|
||||
@ -136,7 +152,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.WriteLine(log);
|
||||
//App.Logger.WriteLine(log);
|
||||
await ExamineLogEntry(log);
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
File.Delete(fileLocation);
|
||||
}
|
||||
|
||||
Debug.WriteLine("Installing/Updating rbxfpsunlocker...");
|
||||
App.Logger.WriteLine("[RbxFpsUnlocker::CheckInstall] Installing/Updating rbxfpsunlocker...");
|
||||
|
||||
{
|
||||
byte[] bytes = await App.HttpClient.GetByteArrayAsync(downloadUrl);
|
||||
|
@ -69,7 +69,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public static async Task DownloadConfig()
|
||||
{
|
||||
Debug.WriteLine("[ReShade] Downloading/Upgrading config file...");
|
||||
App.Logger.WriteLine("[ReShade::DownloadConfig] Downloading/Upgrading config file...");
|
||||
|
||||
{
|
||||
byte[] bytes = await App.HttpClient.GetByteArrayAsync($"{BaseUrl}/config.zip");
|
||||
@ -117,7 +117,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public static void SynchronizeConfigFile()
|
||||
{
|
||||
Debug.WriteLine($"[ReShade] Synchronizing configuration file...");
|
||||
App.Logger.WriteLine($"[ReShade::SynchronizeConfigFile] Synchronizing configuration file...");
|
||||
|
||||
// yeah, this is going to be a bit of a pain
|
||||
// keep in mind the config file is going to be in two places: the mod folder and the version folder
|
||||
@ -134,21 +134,21 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
// we shouldn't be here if the mod config doesn't already exist
|
||||
if (!File.Exists(modFolderConfigPath))
|
||||
{
|
||||
Debug.WriteLine($"[ReShade] ReShade.ini in modifications folder does not exist, aborting sync");
|
||||
App.Logger.WriteLine($"[ReShade::SynchronizeConfigFile] ReShade.ini in modifications folder does not exist, aborting sync");
|
||||
return;
|
||||
}
|
||||
|
||||
// copy to the version folder if it doesn't already exist there
|
||||
if (!File.Exists(versionFolderConfigPath))
|
||||
{
|
||||
Debug.WriteLine($"[ReShade] ReShade.ini in version folder does not exist, synchronized with modifications folder");
|
||||
App.Logger.WriteLine($"[ReShade::SynchronizeConfigFile] ReShade.ini in version folder does not exist, synchronized with modifications folder");
|
||||
File.Copy(modFolderConfigPath, versionFolderConfigPath);
|
||||
}
|
||||
|
||||
// if both the mod and version configs match, then we don't need to do anything
|
||||
if (Utilities.MD5File(modFolderConfigPath) == Utilities.MD5File(versionFolderConfigPath))
|
||||
{
|
||||
Debug.WriteLine($"[ReShade] ReShade.ini in version and modifications folder match");
|
||||
App.Logger.WriteLine($"[ReShade::SynchronizeConfigFile] ReShade.ini in version and modifications folder match");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -158,13 +158,13 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
if (modFolderConfigFile.LastWriteTime > versionFolderConfigFile.LastWriteTime)
|
||||
{
|
||||
// overwrite version config if mod config was modified most recently
|
||||
Debug.WriteLine($"[ReShade] ReShade.ini in version folder is older, synchronized with modifications folder");
|
||||
App.Logger.WriteLine($"[ReShade::SynchronizeConfigFile] ReShade.ini in version folder is older, synchronized with modifications folder");
|
||||
File.Copy(modFolderConfigPath, versionFolderConfigPath, true);
|
||||
}
|
||||
else if (versionFolderConfigFile.LastWriteTime > modFolderConfigFile.LastWriteTime)
|
||||
{
|
||||
// overwrite mod config if version config was modified most recently
|
||||
Debug.WriteLine($"[ReShade] ReShade.ini in modifications folder is older, synchronized with version folder");
|
||||
App.Logger.WriteLine($"[ReShade::SynchronizeConfigFile] ReShade.ini in modifications folder is older, synchronized with version folder");
|
||||
File.Copy(versionFolderConfigPath, modFolderConfigPath, true);
|
||||
}
|
||||
}
|
||||
@ -177,7 +177,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
if (Directory.Exists(Path.Combine(ShadersFolder, name)))
|
||||
return;
|
||||
|
||||
Debug.WriteLine($"[ReShade] Downloading shaders for {name}");
|
||||
App.Logger.WriteLine($"[ReShade::DownloadShaders] Downloading shaders for {name}");
|
||||
|
||||
{
|
||||
byte[] bytes = await App.HttpClient.GetByteArrayAsync(downloadUrl);
|
||||
@ -238,7 +238,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public static void DeleteShaders(string name)
|
||||
{
|
||||
Debug.WriteLine($"[ReShade] Deleting shaders for {name}");
|
||||
App.Logger.WriteLine($"[ReShade::DeleteShaders] Deleting shaders for {name}");
|
||||
|
||||
string shadersPath = Path.Combine(ShadersFolder, name);
|
||||
string texturesPath = Path.Combine(TexturesFolder, name);
|
||||
@ -276,7 +276,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public static async Task InstallExtraviPresets()
|
||||
{
|
||||
Debug.WriteLine("[ReShade] Installing Extravi's presets...");
|
||||
App.Logger.WriteLine("[ReShade::InstallExtraviPresets] Installing Extravi's presets...");
|
||||
|
||||
foreach (string name in ExtraviPresetsShaders)
|
||||
await DownloadShaders(name);
|
||||
@ -303,7 +303,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
if (!Directory.Exists(PresetsFolder))
|
||||
return;
|
||||
|
||||
Debug.WriteLine("[ReShade] Uninstalling Extravi's presets...");
|
||||
App.Logger.WriteLine("[ReShade::UninstallExtraviPresets] Uninstalling Extravi's presets...");
|
||||
|
||||
FileInfo[] presets = new DirectoryInfo(PresetsFolder).GetFiles();
|
||||
|
||||
@ -319,7 +319,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
public static async Task CheckModifications()
|
||||
{
|
||||
Debug.WriteLine("[ReShade] Checking ReShade modifications... ");
|
||||
App.Logger.WriteLine("[ReShade::CheckModifications] Checking ReShade modifications... ");
|
||||
|
||||
string injectorLocation = Path.Combine(Directories.Modifications, "dxgi.dll");
|
||||
|
||||
@ -332,7 +332,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
if (!App.Settings.Prop.UseReShade)
|
||||
{
|
||||
Debug.WriteLine("[ReShade] Uninstalling ReShade...");
|
||||
App.Logger.WriteLine("[ReShade::CheckModifications] Uninstalling ReShade...");
|
||||
|
||||
// delete any stock config files
|
||||
File.Delete(injectorLocation);
|
||||
@ -380,7 +380,7 @@ namespace Bloxstrap.Helpers.Integrations
|
||||
|
||||
if (shouldFetchReShade)
|
||||
{
|
||||
Debug.WriteLine("[ReShade] Installing/Upgrading ReShade...");
|
||||
App.Logger.WriteLine("[ReShade::CheckModifications] Installing/Upgrading ReShade...");
|
||||
|
||||
{
|
||||
byte[] bytes = await App.HttpClient.GetByteArrayAsync($"{BaseUrl}/dxgi.zip");
|
||||
|
@ -25,42 +25,42 @@ namespace Bloxstrap.Helpers
|
||||
//if (String.IsNullOrEmpty(FileLocation))
|
||||
// throw new ArgumentNullException("No FileLocation has been set");
|
||||
|
||||
Debug.WriteLine($"[JsonManager<{typeof(T).Name}>] Loading JSON from {FileLocation}...");
|
||||
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Loading JSON from {FileLocation}...");
|
||||
|
||||
try
|
||||
{
|
||||
T? settings = JsonSerializer.Deserialize<T>(File.ReadAllText(FileLocation));
|
||||
Prop = settings ?? throw new ArgumentNullException("Deserialization returned null");
|
||||
Debug.WriteLine($"[JsonManager<{typeof(T).Name}>] JSON loaded successfully!");
|
||||
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] JSON loaded successfully!");
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"[JsonManager<{typeof(T).Name}>] Failed to load JSON! ({ex.Message})");
|
||||
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Load] Failed to load JSON! ({ex.Message})");
|
||||
}
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
Debug.WriteLine($"[JsonManager<{typeof(T).Name}>] Attempting to save JSON to {FileLocation}...");
|
||||
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Attempting to save JSON to {FileLocation}...");
|
||||
|
||||
//if (!ShouldSave || String.IsNullOrEmpty(FileLocation))
|
||||
//{
|
||||
// Debug.WriteLine($"[JsonManager<{typeof(T).Name}>] Aborted save (ShouldSave set to false or FileLocation not set)");
|
||||
// App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>] Aborted save (ShouldSave set to false or FileLocation not set)");
|
||||
// return;
|
||||
//}
|
||||
|
||||
//if (!ShouldSave)
|
||||
if (!App.ShouldSaveConfigs)
|
||||
{
|
||||
Debug.WriteLine($"[JsonManager<{typeof(T).Name}>] Aborted save (ShouldSave set to false)");
|
||||
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] Aborted save (ShouldSave set to false)");
|
||||
return;
|
||||
}
|
||||
|
||||
string json = JsonSerializer.Serialize(Prop, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(FileLocation, json);
|
||||
|
||||
Debug.WriteLine($"[JsonManager<{typeof(T).Name}>] JSON saved!");
|
||||
App.Logger.WriteLine($"[JsonManager<{typeof(T).Name}>::Save] JSON saved!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
50
Bloxstrap/Helpers/Logger.cs
Normal file
50
Bloxstrap/Helpers/Logger.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Printing;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bloxstrap.Helpers
|
||||
{
|
||||
// https://stackoverflow.com/a/53873141/11852173
|
||||
public class Logger
|
||||
{
|
||||
private readonly SemaphoreSlim _semaphore = new(1, 1);
|
||||
private readonly FileStream _filestream;
|
||||
|
||||
public Logger(string filename)
|
||||
{
|
||||
string? directory = Path.GetDirectoryName(filename);
|
||||
|
||||
if (directory is not null)
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
_filestream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read);
|
||||
WriteLine($"[Logger::Logger] {App.ProjectName} v{App.Version} - Initialized at {filename}");
|
||||
}
|
||||
|
||||
public async void WriteLine(string message)
|
||||
{
|
||||
string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
string conout = $"{timestamp} {message}";
|
||||
byte[] fileout = Encoding.Unicode.GetBytes($"{conout.Replace(Directories.UserProfile, "<UserProfileFolder>")}\r\n");
|
||||
|
||||
Debug.WriteLine(conout);
|
||||
|
||||
try
|
||||
{
|
||||
await _semaphore.WaitAsync();
|
||||
await _filestream.WriteAsync(fileout);
|
||||
await _filestream.FlushAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -61,7 +61,10 @@ namespace Bloxstrap.Helpers
|
||||
);
|
||||
|
||||
if (result == MessageBoxResult.Yes)
|
||||
{
|
||||
App.Logger.WriteLine($"[Protocol::ParseUri] Changed Roblox build channel from {App.Settings.Prop.Channel} to {val}");
|
||||
App.Settings.Prop.Channel = val;
|
||||
}
|
||||
}
|
||||
|
||||
// we'll set the arg when launching
|
||||
@ -106,7 +109,7 @@ namespace Bloxstrap.Helpers
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine($"Failed to unregister {key}: {e}");
|
||||
App.Logger.WriteLine($"[Protocol::Unregister] Failed to unregister {key}: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800"
|
||||
d:DesignHeight="700" d:DesignWidth="800"
|
||||
Title="AboutPage"
|
||||
Scrollable="True">
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
<Border Grid.Column="0" Width="60" Height="60" VerticalAlignment="Center">
|
||||
<Border.Background>
|
||||
<ImageBrush ImageSource="pack://application:,,,/Resources/IconBloxstrap-png.png" />
|
||||
<ImageBrush ImageSource="pack://application:,,,/Bloxstrap.ico" />
|
||||
</Border.Background>
|
||||
</Border>
|
||||
<StackPanel Grid.Column="1" Margin="12,0,0,0" VerticalAlignment="Center">
|
||||
|
@ -11,7 +11,7 @@
|
||||
Scrollable="True">
|
||||
|
||||
<StackPanel Margin="0,0,14,14">
|
||||
<TextBlock Text="Configure how Bloxstrap should function and look." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Text="Configure how Bloxstrap should behave and look." FontSize="14" Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
|
||||
<TextBlock Text="Behaviour" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
|
||||
<ui:CardControl Margin="0,8,0,0">
|
||||
|
@ -33,10 +33,18 @@
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Margin="0,0,16,8" FontSize="14" FontWeight="Medium" Text="Take Screenshot" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="1" Margin="0,0,0,8" VerticalAlignment="Bottom" Text="Print Screen" Foreground="{DynamicResource TextFillColorTertiaryBrush}" />
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="2" Grid.RowSpan="3" Margin="32,0,0,0" TextWrapping="Wrap" Text="If you're using a laptop keyboard, you may have to hold down the Fn key when pressing F6. Any screenshots you take are saved to your pictures folder." Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Grid.Row="0" Grid.Column="2" Grid.RowSpan="3" Margin="32,0,0,0" TextWrapping="Wrap" Foreground="{DynamicResource TextFillColorSecondaryBrush}">
|
||||
If you're using a laptop keyboard, you may have to hold down the Fn key when pressing F6.
|
||||
<LineBreak />
|
||||
<LineBreak />
|
||||
Any screenshots you take are saved to your pictures folder.
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
|
||||
<TextBlock Text="Adding your own shaders and presets" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
|
||||
<TextBlock Text="Selecting a preset" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
|
||||
<TextBlock Margin="0,8,0,0" TextWrapping="Wrap" Text="Presets are how ReShade is configured to use shaders and textures. To select a preset, open the menu with Shift + Tab, and select the dropdown beneath the tabs to show all available presets to pick from. If you don't have any available, you can either use Extravi's ReShade presets in the Integrations menu, or add your own as detailed below." Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
|
||||
<TextBlock Text="Adding your own presets and shaders" FontSize="16" FontWeight="Medium" Margin="0,16,0,0" />
|
||||
<TextBlock Margin="0,8,0,0" TextWrapping="Wrap" Text="While Bloxstrap provides Extravi's ReShade presets as a great way to enhance Roblox's graphics, it also provides the ability to install custom shaders and presets." Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Margin="0,8,0,0" TextWrapping="Wrap" Text="To install custom presets, just extract the necessary .ini files to the ReShade Presets folder. Though, you may also need to add additional shaders and textures." Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
<TextBlock Margin="0,8,0,0" TextWrapping="Wrap" Text="To install shaders (known as effects), extract the necessary files to the ReShade Shaders folder. The same goes for textures, where you extract them to the ReShade Textures folder. You could alternatively extract them to organized subfolders like how Bloxstrap does them, though you'll have to configure ReShade to look in those folders." Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
|
||||
|
Loading…
Reference in New Issue
Block a user