diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 98e21396..cc64143e 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -5,6 +5,7 @@ using System.IO.Compression; using System.Linq; using System.Net.Http; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; @@ -115,7 +116,7 @@ private void UpdateProgressBar() if (Dialog is not null) Dialog.ProgressValue = newProgress; } - + public async Task Run() { App.Logger.WriteLine("[Bootstrapper::Run] Running bootstrapper"); @@ -1035,6 +1036,44 @@ private async Task ApplyModifications() await response.Content.CopyToAsync(fileStream); } + // check custom font mod + // instead of replacing the fonts themselves, we'll just alter the font family manifests + + string modFontFamiliesFolder = Path.Combine(Directories.Modifications, "content\\fonts\\families"); + string customFontLocation = Path.Combine(Directories.Modifications, "content\\fonts\\CustomFont.ttf"); + + if (File.Exists(customFontLocation)) + { + App.Logger.WriteLine("[Bootstrapper::ApplyModifications] Begin font check"); + + Directory.CreateDirectory(modFontFamiliesFolder); + + foreach (string jsonFilePath in Directory.GetFiles(Path.Combine(_versionFolder, "content\\fonts\\families"))) + { + string jsonFilename = Path.GetFileName(jsonFilePath); + string modFilepath = Path.Combine(modFontFamiliesFolder, jsonFilename); + + if (File.Exists(modFilepath)) + continue; + + FontFamily? fontFamilyData = JsonSerializer.Deserialize(File.ReadAllText(jsonFilePath)); + + if (fontFamilyData is null) + continue; + + foreach (FontFace fontFace in fontFamilyData.Faces) + fontFace.AssetId = "rbxasset://fonts/CustomFont.ttf"; + + File.WriteAllText(modFilepath, JsonSerializer.Serialize(fontFamilyData, new JsonSerializerOptions { WriteIndented = true })); + } + + App.Logger.WriteLine("[Bootstrapper::ApplyModifications] End font check"); + } + else + { + Directory.Delete(modFontFamiliesFolder, true); + } + foreach (string file in Directory.GetFiles(modFolder, "*.*", SearchOption.AllDirectories)) { // get relative directory path diff --git a/Bloxstrap/Models/FontFace.cs b/Bloxstrap/Models/FontFace.cs new file mode 100644 index 00000000..50bb179c --- /dev/null +++ b/Bloxstrap/Models/FontFace.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Bloxstrap.Models +{ + public class FontFace + { + [JsonPropertyName("name")] + public string Name { get; set; } = null!; + + [JsonPropertyName("weight")] + public int Weight { get; set; } + + [JsonPropertyName("style")] + public string Style { get; set; } = null!; + + [JsonPropertyName("assetId")] + public string AssetId { get; set; } = null!; + } +} diff --git a/Bloxstrap/Models/FontFamily.cs b/Bloxstrap/Models/FontFamily.cs new file mode 100644 index 00000000..9a846e1e --- /dev/null +++ b/Bloxstrap/Models/FontFamily.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Text.Json.Serialization; + +namespace Bloxstrap.Models +{ + public class FontFamily + { + [JsonPropertyName("name")] + public string Name { get; set; } = null!; + + [JsonPropertyName("faces")] + public IEnumerable Faces { get; set; } = null!; + } +} diff --git a/Bloxstrap/UI/Elements/Menu/Pages/InstallationPage.xaml b/Bloxstrap/UI/Elements/Menu/Pages/InstallationPage.xaml index 72764105..2790bc2a 100644 --- a/Bloxstrap/UI/Elements/Menu/Pages/InstallationPage.xaml +++ b/Bloxstrap/UI/Elements/Menu/Pages/InstallationPage.xaml @@ -27,7 +27,7 @@ - + diff --git a/Bloxstrap/UI/Elements/Menu/Pages/ModsPage.xaml b/Bloxstrap/UI/Elements/Menu/Pages/ModsPage.xaml index 9e3e57e9..c69873dd 100644 --- a/Bloxstrap/UI/Elements/Menu/Pages/ModsPage.xaml +++ b/Bloxstrap/UI/Elements/Menu/Pages/ModsPage.xaml @@ -113,6 +113,20 @@ + + + + + + Forces every in-game font to be a font that you choose. + + + + + + + + @@ -122,7 +136,7 @@ - + diff --git a/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs b/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs index 4e5e6f10..c22ba1f1 100644 --- a/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs +++ b/Bloxstrap/UI/ViewModels/Menu/AppearanceViewModel.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Windows; using System.Windows.Controls; -using System.Windows.Forms; +using Microsoft.Win32; using System.Windows.Input; using System.Windows.Media; @@ -40,14 +40,16 @@ private void PreviewBootstrapper() private void BrowseCustomIconLocation() { - using var dialog = new OpenFileDialog(); - dialog.Filter = "Icon files (*.ico)|*.ico|All files (*.*)|*.*"; - - if (dialog.ShowDialog() == DialogResult.OK) + var dialog = new OpenFileDialog { - CustomIconLocation = dialog.FileName; - OnPropertyChanged(nameof(CustomIconLocation)); - } + Filter = "Icon files|*.ico|All files|*.*" + }; + + if (dialog.ShowDialog() != true) + return; + + CustomIconLocation = dialog.FileName; + OnPropertyChanged(nameof(CustomIconLocation)); } public AppearanceViewModel(Page page) diff --git a/Bloxstrap/UI/ViewModels/Menu/ModsViewModel.cs b/Bloxstrap/UI/ViewModels/Menu/ModsViewModel.cs index 86cac7e3..b02209fe 100644 --- a/Bloxstrap/UI/ViewModels/Menu/ModsViewModel.cs +++ b/Bloxstrap/UI/ViewModels/Menu/ModsViewModel.cs @@ -1,21 +1,56 @@ using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; +using System.IO; using System.Linq; +using System.Windows; using System.Windows.Input; using Bloxstrap.Enums; using Bloxstrap.Extensions; +using Microsoft.Win32; + using CommunityToolkit.Mvvm.Input; namespace Bloxstrap.UI.ViewModels.Menu { - public class ModsViewModel + public class ModsViewModel : INotifyPropertyChanged { - public ICommand OpenModsFolderCommand => new RelayCommand(OpenModsFolder); + public event PropertyChangedEventHandler? PropertyChanged; + public void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); private void OpenModsFolder() => Process.Start("explorer.exe", Directories.Modifications); + private string _customFontLocation = Path.Combine(Directories.Modifications, "content\\fonts\\CustomFont.ttf"); + private bool _usingCustomFont => File.Exists(_customFontLocation); + + private void ManageCustomFont() + { + if (_usingCustomFont) + { + File.Delete(_customFontLocation); + } + else + { + var dialog = new OpenFileDialog + { + Filter = "Font files|*.ttf;*.otf|All files|*.*" + }; + + if (dialog.ShowDialog() != true) + return; + + Directory.CreateDirectory(Path.GetDirectoryName(_customFontLocation)!); + File.Copy(dialog.FileName, _customFontLocation); + } + + OnPropertyChanged(nameof(ChooseCustomFontVisibility)); + OnPropertyChanged(nameof(DeleteCustomFontVisibility)); + } + + public ICommand OpenModsFolderCommand => new RelayCommand(OpenModsFolder); + public bool OldDeathSoundEnabled { get => App.Settings.Prop.UseOldDeathSound; @@ -50,7 +85,12 @@ public string SelectedEmojiType set => App.Settings.Prop.EmojiType = EmojiTypes[value]; } - public bool DisableFullscreenOptimizationsEnabled + public Visibility ChooseCustomFontVisibility => _usingCustomFont ? Visibility.Collapsed : Visibility.Visible; + public Visibility DeleteCustomFontVisibility => _usingCustomFont ? Visibility.Visible : Visibility.Collapsed; + + public ICommand ManageCustomFontCommand => new RelayCommand(ManageCustomFont); + + public bool DisableFullscreenOptimizations { get => App.Settings.Prop.DisableFullscreenOptimizations; set => App.Settings.Prop.DisableFullscreenOptimizations = value;