mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-18 16:41:36 -07:00
Minor restructuring
This commit is contained in:
parent
28bcf57dff
commit
e7fd0b9642
@ -15,10 +15,10 @@ using Microsoft.Win32;
|
|||||||
|
|
||||||
using Bloxstrap.Extensions;
|
using Bloxstrap.Extensions;
|
||||||
using Bloxstrap.Models;
|
using Bloxstrap.Models;
|
||||||
using Bloxstrap.Singletons;
|
|
||||||
using Bloxstrap.UI.BootstrapperDialogs;
|
using Bloxstrap.UI.BootstrapperDialogs;
|
||||||
using Bloxstrap.UI.Menu.Views;
|
using Bloxstrap.UI.Menu.Views;
|
||||||
|
using Bloxstrap.Utility;
|
||||||
|
|
||||||
namespace Bloxstrap
|
namespace Bloxstrap
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -256,7 +256,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
|
if (_launchCommandLine == "--app" && App.Settings.Prop.UseDisableAppPatch)
|
||||||
{
|
{
|
||||||
Utilities.OpenWebsite("https://www.roblox.com/games");
|
Utilities.ShellExecute("https://www.roblox.com/games");
|
||||||
Dialog?.CloseBootstrapper();
|
Dialog?.CloseBootstrapper();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -562,7 +562,7 @@ namespace Bloxstrap
|
|||||||
private async Task CheckForUpdates()
|
private async Task 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 (Utilities.GetProcessCount(App.ProjectName) > 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($"[Bootstrapper::CheckForUpdates] More than one Bloxstrap instance running, aborting update check");
|
||||||
return;
|
return;
|
||||||
@ -616,7 +616,7 @@ namespace Bloxstrap
|
|||||||
private void Uninstall()
|
private void Uninstall()
|
||||||
{
|
{
|
||||||
// prompt to shutdown roblox if its currently running
|
// prompt to shutdown roblox if its currently running
|
||||||
if (Utilities.CheckIfRobloxRunning())
|
if (Process.GetProcessesByName(App.RobloxAppName).Any())
|
||||||
{
|
{
|
||||||
App.Logger.WriteLine($"[Bootstrapper::Uninstall] Prompting to shut down all open Roblox instances");
|
App.Logger.WriteLine($"[Bootstrapper::Uninstall] Prompting to shut down all open Roblox instances");
|
||||||
|
|
||||||
@ -1004,7 +1004,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
if (File.Exists(fileVersionFolder))
|
if (File.Exists(fileVersionFolder))
|
||||||
{
|
{
|
||||||
if (Utilities.MD5File(fileModFolder) == Utilities.MD5File(fileVersionFolder))
|
if (Utility.MD5Hash.FromFile(fileModFolder) == Utility.MD5Hash.FromFile(fileVersionFolder))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1072,7 +1072,7 @@ namespace Bloxstrap
|
|||||||
await File.WriteAllBytesAsync(modFolderLocation, binaryData);
|
await File.WriteAllBytesAsync(modFolderLocation, binaryData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (File.Exists(modFolderLocation) && Utilities.MD5File(modFolderLocation) == Utilities.MD5Data(binaryData))
|
else if (File.Exists(modFolderLocation) && Utility.MD5Hash.FromFile(modFolderLocation) == Utility.MD5Hash.FromBytes(binaryData))
|
||||||
{
|
{
|
||||||
File.Delete(modFolderLocation);
|
File.Delete(modFolderLocation);
|
||||||
}
|
}
|
||||||
@ -1091,7 +1091,8 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
FileInfo file = new(packageLocation);
|
FileInfo file = new(packageLocation);
|
||||||
|
|
||||||
string calculatedMD5 = Utilities.MD5File(packageLocation);
|
string calculatedMD5 = Utility.MD5Hash.FromFile(packageLocation);
|
||||||
|
|
||||||
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($"[Bootstrapper::DownloadPackage] {package.Name} is corrupted ({calculatedMD5} != {package.Signature})! Deleting and re-downloading...");
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
using Newtonsoft.Json.Linq;
|
using System.Collections.Generic;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Bloxstrap.Singletons
|
namespace Bloxstrap
|
||||||
{
|
{
|
||||||
public class FastFlagManager : JsonManager<Dictionary<string, object>>
|
public class FastFlagManager : JsonManager<Dictionary<string, object>>
|
||||||
{
|
{
|
||||||
@ -103,18 +101,18 @@ namespace Bloxstrap.Singletons
|
|||||||
|
|
||||||
// this will set the flag to the corresponding value if the condition is true
|
// this will set the flag to the corresponding value if the condition is true
|
||||||
// if the condition is not true, the flag will be erased
|
// if the condition is not true, the flag will be erased
|
||||||
public void SetValueIf(bool condition, string key, object? value)
|
public void SetValueIf(bool condition, string key, object? value)
|
||||||
{
|
{
|
||||||
if (condition)
|
if (condition)
|
||||||
SetValue(key, value);
|
SetValue(key, value);
|
||||||
else if (GetValue(key) is not null)
|
else if (GetValue(key) is not null)
|
||||||
SetValue(key, null);
|
SetValue(key, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetValueOnce(string key, object? value)
|
public void SetValueOnce(string key, object? value)
|
||||||
{
|
{
|
||||||
if (GetValue(key) is null)
|
if (GetValue(key) is null)
|
||||||
SetValue(key, value);
|
SetValue(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this returns null if the fflag doesn't exist
|
// this returns null if the fflag doesn't exist
|
@ -2,7 +2,7 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Bloxstrap.Singletons
|
namespace Bloxstrap
|
||||||
{
|
{
|
||||||
public class JsonManager<T> where T : new()
|
public class JsonManager<T> where T : new()
|
||||||
{
|
{
|
@ -5,7 +5,7 @@ using System.IO;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Bloxstrap.Singletons
|
namespace Bloxstrap
|
||||||
{
|
{
|
||||||
// https://stackoverflow.com/a/53873141/11852173
|
// https://stackoverflow.com/a/53873141/11852173
|
||||||
// TODO - this kind of sucks
|
// TODO - this kind of sucks
|
@ -1,7 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
using Bloxstrap.Extensions;
|
using Bloxstrap.Extensions;
|
||||||
|
using Bloxstrap.Utility;
|
||||||
|
|
||||||
namespace Bloxstrap.UI.BootstrapperDialogs.WinForms
|
namespace Bloxstrap.UI.BootstrapperDialogs.WinForms
|
||||||
{
|
{
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
|
||||||
using Bloxstrap.Singletons;
|
|
||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
namespace Bloxstrap.UI.Menu.ViewModels
|
namespace Bloxstrap.UI.Menu.ViewModels
|
||||||
{
|
{
|
||||||
public class FastFlagsViewModel : INotifyPropertyChanged
|
public class FastFlagsViewModel : INotifyPropertyChanged
|
||||||
@ -17,7 +14,7 @@ namespace Bloxstrap.UI.Menu.ViewModels
|
|||||||
|
|
||||||
public ICommand OpenClientSettingsCommand => new RelayCommand(OpenClientSettings);
|
public ICommand OpenClientSettingsCommand => new RelayCommand(OpenClientSettings);
|
||||||
|
|
||||||
private void OpenClientSettings() => Utilities.OpenWebsite(Path.Combine(Directories.Modifications, "ClientSettings\\ClientAppSettings.json"));
|
private void OpenClientSettings() => Utilities.ShellExecute(Path.Combine(Directories.Modifications, "ClientSettings\\ClientAppSettings.json"));
|
||||||
|
|
||||||
public int FramerateLimit
|
public int FramerateLimit
|
||||||
{
|
{
|
||||||
@ -40,19 +37,19 @@ namespace Bloxstrap.UI.Menu.ViewModels
|
|||||||
return "Automatic";
|
return "Automatic";
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
foreach (var mode in RenderingModes)
|
foreach (var mode in RenderingModes)
|
||||||
{
|
{
|
||||||
if (mode.Key != "Automatic")
|
if (mode.Key != "Automatic")
|
||||||
App.FastFlags.SetValue(mode.Value, null);
|
App.FastFlags.SetValue(mode.Value, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value == "Automatic")
|
if (value == "Automatic")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
App.FastFlags.SetValue(RenderingModes[value], "True");
|
App.FastFlags.SetValue(RenderingModes[value], "True");
|
||||||
App.FastFlags.SetValueIf(value == "Vulkan", "FFlagRenderVulkanFixMinimizeWindow", "True");
|
App.FastFlags.SetValueIf(value == "Vulkan", "FFlagRenderVulkanFixMinimizeWindow", "True");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ namespace Bloxstrap.UI.Menu.ViewModels
|
|||||||
if (location is null)
|
if (location is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Utilities.OpenWebsite(location);
|
Utilities.ShellExecute(location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ namespace Bloxstrap
|
|||||||
|
|
||||||
if (isAutoUpgrade)
|
if (isAutoUpgrade)
|
||||||
{
|
{
|
||||||
EventHandler ReleaseNotesLauncher = new((_, _) => Utilities.OpenWebsite($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}"));
|
EventHandler ReleaseNotesLauncher = new((_, _) => Utilities.ShellExecute($"https://github.com/{App.ProjectRepository}/releases/tag/v{currentVersionInfo.ProductVersion}"));
|
||||||
|
|
||||||
App.Notification.BalloonTipTitle = $"Bloxstrap has been upgraded to v{currentVersionInfo.ProductVersion}";
|
App.Notification.BalloonTipTitle = $"Bloxstrap has been upgraded to v{currentVersionInfo.ProductVersion}";
|
||||||
App.Notification.BalloonTipText = "Click here to see what's new in this version";
|
App.Notification.BalloonTipText = "Click here to see what's new in this version";
|
||||||
|
@ -10,11 +10,6 @@ namespace Bloxstrap
|
|||||||
{
|
{
|
||||||
static class Utilities
|
static class Utilities
|
||||||
{
|
{
|
||||||
public static bool IsDirectoryEmpty(string path)
|
|
||||||
{
|
|
||||||
return !Directory.EnumerateFileSystemEntries(path).Any();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long GetFreeDiskSpace(string path)
|
public static long GetFreeDiskSpace(string path)
|
||||||
{
|
{
|
||||||
foreach (DriveInfo drive in DriveInfo.GetDrives())
|
foreach (DriveInfo drive in DriveInfo.GetDrives())
|
||||||
@ -26,24 +21,7 @@ namespace Bloxstrap
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetProcessCount(string processName, bool log = true)
|
public static void ShellExecute(string website) => Process.Start(new ProcessStartInfo { FileName = website, UseShellExecute = true });
|
||||||
{
|
|
||||||
if (log)
|
|
||||||
App.Logger.WriteLine($"[Utilities::CheckIfProcessRunning] Checking if '{processName}' is running...");
|
|
||||||
|
|
||||||
Process[] processes = Process.GetProcessesByName(processName);
|
|
||||||
|
|
||||||
if (log)
|
|
||||||
App.Logger.WriteLine($"[Utilities::CheckIfProcessRunning] Found {processes.Length} process(es) running for '{processName}'");
|
|
||||||
|
|
||||||
return processes.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool CheckIfProcessRunning(string processName, bool log = true) => GetProcessCount(processName, log) >= 1;
|
|
||||||
|
|
||||||
public static bool CheckIfRobloxRunning(bool log = true) => CheckIfProcessRunning("RobloxPlayerBeta", log);
|
|
||||||
|
|
||||||
public static void OpenWebsite(string website) => Process.Start(new ProcessStartInfo { FileName = website, UseShellExecute = true });
|
|
||||||
|
|
||||||
public static async Task<T?> GetJson<T>(string url)
|
public static async Task<T?> GetJson<T>(string url)
|
||||||
{
|
{
|
||||||
@ -61,41 +39,5 @@ namespace Bloxstrap
|
|||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string MD5File(string filename)
|
|
||||||
{
|
|
||||||
using (MD5 md5 = MD5.Create())
|
|
||||||
{
|
|
||||||
using (FileStream stream = File.OpenRead(filename))
|
|
||||||
{
|
|
||||||
byte[] hash = md5.ComputeHash(stream);
|
|
||||||
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string MD5Data(byte[] data)
|
|
||||||
{
|
|
||||||
using (MD5 md5 = MD5.Create())
|
|
||||||
{
|
|
||||||
byte[] hash = md5.ComputeHash(data);
|
|
||||||
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// quick and hacky way of getting a value from any key/value pair formatted list
|
|
||||||
// (command line args, uri params, etc)
|
|
||||||
public static string? GetKeyValue(string subject, string key, char delimiter)
|
|
||||||
{
|
|
||||||
if (subject.LastIndexOf(key) == -1)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
string substr = subject.Substring(subject.LastIndexOf(key) + key.Length);
|
|
||||||
|
|
||||||
if (!substr.Contains(delimiter))
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return substr.Split(delimiter)[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,102 +1,102 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Bloxstrap.Tools
|
namespace Bloxstrap.Tools
|
||||||
{
|
{
|
||||||
// https://gist.github.com/dfederm/35c729f6218834b764fa04c219181e4e
|
// https://gist.github.com/dfederm/35c729f6218834b764fa04c219181e4e
|
||||||
|
|
||||||
public sealed class AsyncMutex : IAsyncDisposable
|
public sealed class AsyncMutex : IAsyncDisposable
|
||||||
{
|
{
|
||||||
private readonly string _name;
|
private readonly string _name;
|
||||||
private Task? _mutexTask;
|
private Task? _mutexTask;
|
||||||
private ManualResetEventSlim? _releaseEvent;
|
private ManualResetEventSlim? _releaseEvent;
|
||||||
private CancellationTokenSource? _cancellationTokenSource;
|
private CancellationTokenSource? _cancellationTokenSource;
|
||||||
|
|
||||||
public AsyncMutex(string name)
|
public AsyncMutex(string name)
|
||||||
{
|
{
|
||||||
_name = name;
|
_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task AcquireAsync(CancellationToken cancellationToken)
|
public Task AcquireAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
TaskCompletionSource taskCompletionSource = new();
|
TaskCompletionSource taskCompletionSource = new();
|
||||||
|
|
||||||
_releaseEvent = new ManualResetEventSlim();
|
_releaseEvent = new ManualResetEventSlim();
|
||||||
_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
_cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||||
|
|
||||||
// Putting all mutex manipulation in its own task as it doesn't work in async contexts
|
// Putting all mutex manipulation in its own task as it doesn't work in async contexts
|
||||||
// Note: this task should not throw.
|
// Note: this task should not throw.
|
||||||
_mutexTask = Task.Factory.StartNew(
|
_mutexTask = Task.Factory.StartNew(
|
||||||
state =>
|
state =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CancellationToken cancellationToken = _cancellationTokenSource.Token;
|
CancellationToken cancellationToken = _cancellationTokenSource.Token;
|
||||||
using var mutex = new Mutex(false, _name);
|
using var mutex = new Mutex(false, _name);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Wait for either the mutex to be acquired, or cancellation
|
// Wait for either the mutex to be acquired, or cancellation
|
||||||
if (WaitHandle.WaitAny(new[] { mutex, cancellationToken.WaitHandle }) != 0)
|
if (WaitHandle.WaitAny(new[] { mutex, cancellationToken.WaitHandle }) != 0)
|
||||||
{
|
{
|
||||||
taskCompletionSource.SetCanceled(cancellationToken);
|
taskCompletionSource.SetCanceled(cancellationToken);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AbandonedMutexException)
|
catch (AbandonedMutexException)
|
||||||
{
|
{
|
||||||
// Abandoned by another process, we acquired it.
|
// Abandoned by another process, we acquired it.
|
||||||
}
|
}
|
||||||
|
|
||||||
taskCompletionSource.SetResult();
|
taskCompletionSource.SetResult();
|
||||||
|
|
||||||
// Wait until the release call
|
// Wait until the release call
|
||||||
_releaseEvent.Wait();
|
_releaseEvent.Wait();
|
||||||
|
|
||||||
mutex.ReleaseMutex();
|
mutex.ReleaseMutex();
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
taskCompletionSource.TrySetCanceled(cancellationToken);
|
taskCompletionSource.TrySetCanceled(cancellationToken);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
taskCompletionSource.TrySetException(ex);
|
taskCompletionSource.TrySetException(ex);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
state: null,
|
state: null,
|
||||||
cancellationToken,
|
cancellationToken,
|
||||||
TaskCreationOptions.LongRunning,
|
TaskCreationOptions.LongRunning,
|
||||||
TaskScheduler.Default);
|
TaskScheduler.Default);
|
||||||
|
|
||||||
return taskCompletionSource.Task;
|
return taskCompletionSource.Task;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ReleaseAsync()
|
public async Task ReleaseAsync()
|
||||||
{
|
{
|
||||||
_releaseEvent?.Set();
|
_releaseEvent?.Set();
|
||||||
|
|
||||||
if (_mutexTask != null)
|
if (_mutexTask != null)
|
||||||
{
|
{
|
||||||
await _mutexTask;
|
await _mutexTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
public async ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
// Ensure the mutex task stops waiting for any acquire
|
// Ensure the mutex task stops waiting for any acquire
|
||||||
_cancellationTokenSource?.Cancel();
|
_cancellationTokenSource?.Cancel();
|
||||||
|
|
||||||
// Ensure the mutex is released
|
// Ensure the mutex is released
|
||||||
await ReleaseAsync();
|
await ReleaseAsync();
|
||||||
|
|
||||||
_releaseEvent?.Dispose();
|
_releaseEvent?.Dispose();
|
||||||
_cancellationTokenSource?.Dispose();
|
_cancellationTokenSource?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
34
Bloxstrap/Utility/MD5Hash.cs
Normal file
34
Bloxstrap/Utility/MD5Hash.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Bloxstrap.Utility
|
||||||
|
{
|
||||||
|
public static class MD5Hash
|
||||||
|
{
|
||||||
|
public static string FromFile(string filename)
|
||||||
|
{
|
||||||
|
using (MD5 md5 = MD5.Create())
|
||||||
|
{
|
||||||
|
using (FileStream stream = File.OpenRead(filename))
|
||||||
|
{
|
||||||
|
byte[] hash = md5.ComputeHash(stream);
|
||||||
|
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string FromBytes(byte[] data)
|
||||||
|
{
|
||||||
|
using (MD5 md5 = MD5.Create())
|
||||||
|
{
|
||||||
|
byte[] hash = md5.ComputeHash(data);
|
||||||
|
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,8 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Bloxstrap
|
namespace Bloxstrap.Utility
|
||||||
{
|
{
|
||||||
static class NativeMethods
|
static class NativeMethods
|
||||||
{
|
{
|
@ -1,47 +1,47 @@
|
|||||||
/*
|
/*
|
||||||
* Roblox Studio Mod Manager (ProjectSrc/Utility/SystemEvent.cs)
|
* Roblox Studio Mod Manager (ProjectSrc/Utility/SystemEvent.cs)
|
||||||
* MIT License
|
* MIT License
|
||||||
* Copyright (c) 2015-present MaximumADHD
|
* Copyright (c) 2015-present MaximumADHD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Bloxstrap.Tools
|
namespace Bloxstrap.Tools
|
||||||
{
|
{
|
||||||
public class SystemEvent : EventWaitHandle
|
public class SystemEvent : EventWaitHandle
|
||||||
{
|
{
|
||||||
public string Name { get; private set; }
|
public string Name { get; private set; }
|
||||||
|
|
||||||
public SystemEvent(string name, bool init = false, EventResetMode mode = EventResetMode.AutoReset) : base(init, mode, name)
|
public SystemEvent(string name, bool init = false, EventResetMode mode = EventResetMode.AutoReset) : base(init, mode, name)
|
||||||
{
|
{
|
||||||
if (init)
|
if (init)
|
||||||
Reset();
|
Reset();
|
||||||
else
|
else
|
||||||
Set();
|
Set();
|
||||||
|
|
||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> WaitForEvent()
|
public Task<bool> WaitForEvent()
|
||||||
{
|
{
|
||||||
return Task.Run(WaitOne);
|
return Task.Run(WaitOne);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> WaitForEvent(TimeSpan timeout, bool exitContext = false)
|
public Task<bool> WaitForEvent(TimeSpan timeout, bool exitContext = false)
|
||||||
{
|
{
|
||||||
return Task.Run(() => WaitOne(timeout, exitContext));
|
return Task.Run(() => WaitOne(timeout, exitContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<bool> WaitForEvent(int millisecondsTimeout, bool exitContext = false)
|
public Task<bool> WaitForEvent(int millisecondsTimeout, bool exitContext = false)
|
||||||
{
|
{
|
||||||
return Task.Run(() => WaitOne(millisecondsTimeout, exitContext));
|
return Task.Run(() => WaitOne(millisecondsTimeout, exitContext));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,34 +1,31 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace Bloxstrap
|
namespace Bloxstrap.Utility
|
||||||
{
|
{
|
||||||
public static class WindowScaling
|
public static class WindowScaling
|
||||||
{
|
{
|
||||||
public static double GetFactor()
|
public static double ScaleFactor => Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;
|
||||||
{
|
|
||||||
return Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;
|
public static int GetScaledNumber(int number)
|
||||||
}
|
{
|
||||||
|
return (int)Math.Ceiling(number * ScaleFactor);
|
||||||
public static int GetScaledNumber(int number)
|
}
|
||||||
{
|
|
||||||
return (int)Math.Ceiling(number * GetFactor());
|
public static System.Drawing.Size GetScaledSize(System.Drawing.Size size)
|
||||||
}
|
{
|
||||||
|
return new System.Drawing.Size(GetScaledNumber(size.Width), GetScaledNumber(size.Height));
|
||||||
public static System.Drawing.Size GetScaledSize(System.Drawing.Size size)
|
}
|
||||||
{
|
|
||||||
return new System.Drawing.Size(GetScaledNumber(size.Width), GetScaledNumber(size.Height));
|
public static System.Drawing.Point GetScaledPoint(System.Drawing.Point point)
|
||||||
}
|
{
|
||||||
|
return new System.Drawing.Point(GetScaledNumber(point.X), GetScaledNumber(point.Y));
|
||||||
public static System.Drawing.Point GetScaledPoint(System.Drawing.Point point)
|
}
|
||||||
{
|
|
||||||
return new System.Drawing.Point(GetScaledNumber(point.X), GetScaledNumber(point.Y));
|
public static Padding GetScaledPadding(Padding padding)
|
||||||
}
|
{
|
||||||
|
return new Padding(GetScaledNumber(padding.Left), GetScaledNumber(padding.Top), GetScaledNumber(padding.Right), GetScaledNumber(padding.Bottom));
|
||||||
public static Padding GetScaledPadding(Padding padding)
|
}
|
||||||
{
|
}
|
||||||
return new Padding(GetScaledNumber(padding.Left), GetScaledNumber(padding.Top), GetScaledNumber(padding.Right), GetScaledNumber(padding.Bottom));
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user