diff --git a/CommunityBugFixCollection/BugFixOptions.cs b/CommunityBugFixCollection/BugFixOptions.cs new file mode 100644 index 0000000..e2baedb --- /dev/null +++ b/CommunityBugFixCollection/BugFixOptions.cs @@ -0,0 +1,26 @@ +using MonkeyLoader.Configuration; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CommunityBugFixCollection +{ + internal sealed class BugFixOptions : ConfigSection + { + private static readonly DefiningConfigKey _useIecByteFormat = new("UseIecByteFormat", "Whether to format bytes using IEC as opposed to decimal format when LocalizedByteFormatting is enabled.", () => true); + + /// + public override string Description => "Contains the settings for the few fixes that offer them."; + + /// + public override string Id => "Options"; + + /// + /// Gets whether should format bytes using IEC or decimal format. + /// + public bool UseIecByteFormat => _useIecByteFormat.GetValue(); + + /// + public override Version Version { get; } = new(1, 0, 0); + } +} \ No newline at end of file diff --git a/CommunityBugFixCollection/CommunityBugFixCollection.csproj b/CommunityBugFixCollection/CommunityBugFixCollection.csproj index 5f08d96..a82c5cf 100644 --- a/CommunityBugFixCollection/CommunityBugFixCollection.csproj +++ b/CommunityBugFixCollection/CommunityBugFixCollection.csproj @@ -10,7 +10,7 @@ True CommunityBugFixCollection Community Bug-Fix Collection - Banane9; Nytra; art0007i; LeCloutPanda; goat; __Choco__ + Banane9; Nytra; art0007i; LeCloutPanda; goat; __Choco__; LJ 0.5.0-beta This MonkeyLoader mod for Resonite that fixes various small Resonite-issues that are still open. README.md diff --git a/CommunityBugFixCollection/Contributors.cs b/CommunityBugFixCollection/Contributors.cs index d6171b6..c2b76f9 100644 --- a/CommunityBugFixCollection/Contributors.cs +++ b/CommunityBugFixCollection/Contributors.cs @@ -1,12 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Text; +using System.Diagnostics.CodeAnalysis; namespace CommunityBugFixCollection { + [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Usernames")] internal static class Contributors { + public static string[] __Choco__ { get; } = ["__Choco__"]; + public static string[] Art0007i { get; } = ["art0007i"]; public static string[] Banane9 { get; } = ["Banane9"]; @@ -15,8 +15,8 @@ internal static class Contributors public static string[] LeCloutPanda { get; } = ["LeCloutPanda"]; - public static string[] Nytra { get; } = ["Nytra"]; + public static string[] LJ { get; } = ["LJ"]; - public static string[] __Choco__ { get; } = ["__Choco__"]; + public static string[] Nytra { get; } = ["Nytra"]; } } \ No newline at end of file diff --git a/CommunityBugFixCollection/Locale/de.json b/CommunityBugFixCollection/Locale/de.json index 45df38a..1496dad 100644 --- a/CommunityBugFixCollection/Locale/de.json +++ b/CommunityBugFixCollection/Locale/de.json @@ -30,7 +30,7 @@ "CommunityBugFixCollection.ImportMultipleAudioFiles.Description": "Macht es möglich mehrere Audiodateien auf einmal zu importieren.", "CommunityBugFixCollection.ImportWebFilesAsUrls.Description": "Sorgt dafür, dass URLs zu Textdateien oder Resonite Packages nicht importiert werden, statt als Hyperlink aufzutauchen.", "CommunityBugFixCollection.IndependentlyScaleDirectCursor.Description": "Verhindert, dass der direkte Cursor sehr groß wird, wenn er an einem deutlich nährem Objekt hängt als der echte Cursor.", - "CommunityBugFixCollection.LocalizedByteFormatting.Description": "Lokalisiert die Speichereinheiten (MiB, GiB, etc.), inbsesondere bei der StorageUsageStatus Komponente.", + "CommunityBugFixCollection.LocalizedByteFormatting.Description": "Lokalisiert die Speichereinheiten (MiB, GiB, etc.), inbsesondere bei der StorageUsageStatus Komponente. Es gibt eine Einstellung dafür, die Bytes nach IEC (Faktor 1024) statt dezimal (Faktor 1000) zu formatieren.", "CommunityBugFixCollection.LongerWorldLoadingFailIndication.Description": "Lässt den Welt-Ladefortschritts-Indikator frühestens nach 20s verschwinden, falls der Vorgang fehlgeschlagen ist.", "CommunityBugFixCollection.NaNtEqual.Description": "Sorgt dafür, dass NaN float / double Werte sich bei den == und != ProtoFlux Nodes sowie bei der ValueEqualityDriver Komponente niemals gleichen.", "CommunityBugFixCollection.NoLossOfColorProfile.Description": "Verhindert, dass Farbprofile nicht bei allen Berechnungen erhalten bleiben.", @@ -44,6 +44,11 @@ "CommunityBugFixCollection.TiltedUIAlignment.Description": "Kippt die UI-fokussierte Kamera, um UIX-Renderprobleme zum umgehen.", "CommunityBugFixCollection.StationaryGrabWorldActivation.Description": "Verhindert, dass die Welt-Greifen Fortbewegung den Spieler bei jeder Aktivierung bewegt.", "CommunityBugFixCollection.ValidQuaternionInputs.Description": "Lässt das ProtoFlux-Tool valide float und double Quaternions spawnen.", - "CommunityBugFixCollection.UserInspectorAsNonHost.Description": "Sorgt dafür, dass Benutzer-Inspektoren bereits präsente Benutzer auch in Sessions anzeigen, in denen man nicht der Host ist." + "CommunityBugFixCollection.UserInspectorAsNonHost.Description": "Sorgt dafür, dass Benutzer-Inspektoren bereits präsente Benutzer auch in Sessions anzeigen, in denen man nicht der Host ist.", + + "CommunityBugFixCollection.Config.Options.Name": "Optionen", + "CommunityBugFixCollection.Config.Options.Description": "Enthällt die Einstellungen für die wenigen Fixes die diese anbieten.", + "CommunityBugFixCollection.Config.Options.UseIecByteFormat.Name": "IEC Byte-Format Benutzen", + "CommunityBugFixCollection.Config.Options.UseIecByteFormat.Description": "Ob Bytes nach IEC (Faktor 1024) statt dezimal (Faktor 1000) formatiert werden sollen, wenn LocalizedByteFormatting aktiviert ist." } } \ No newline at end of file diff --git a/CommunityBugFixCollection/Locale/en.json b/CommunityBugFixCollection/Locale/en.json index ffbb192..fe1fbda 100644 --- a/CommunityBugFixCollection/Locale/en.json +++ b/CommunityBugFixCollection/Locale/en.json @@ -1,6 +1,11 @@ { "localeCode": "en", - "authors": [ "Banane9", "__Choco__", "Nytra" ], + "authors": [ + "Banane9", + "__Choco__", + "Nytra", + "LJ" + ], "messages": { "CommunityBugFixCollection.Name": "Community Bug-Fix Collection", "CommunityBugFixCollection.Description": "This mod contains fixes for various small Resonite Issues that are still open.", @@ -30,7 +35,7 @@ "CommunityBugFixCollection.ImportMultipleAudioFiles.Description": "Fixes it not being possible to import multiple audio clips at once.", "CommunityBugFixCollection.ImportWebFilesAsUrls.Description": "Fixes URLs to text files or Resonite Packages failing to import instead of appearing as a hyperlink.", "CommunityBugFixCollection.IndependentlyScaleDirectCursor.Description": "Fixes direct cursor size becoming very large when snapped to an object much closer than the true cursor.", - "CommunityBugFixCollection.LocalizedByteFormatting.Description": "Localizes the storage units (MiB, GiB, etc.), in particular for the StorageUsageStatus component.", + "CommunityBugFixCollection.LocalizedByteFormatting.Description": "Localizes the storage units (MiB, GiB, etc.), in particular for the StorageUsageStatus component. There's an option to use IEC format (factor 1024) over decimal (factor 1000).", "CommunityBugFixCollection.LongerWorldLoadingFailIndication.Description": "Only lets the World Load Progress Indicator disappear after 20s or more if the process failed.", "CommunityBugFixCollection.NaNtEqual.Description": "Makes NaN floats / doubles never equal to each other for the ProtoFlux == and != nodes, as well as the ValueEqualityDriver component.", "CommunityBugFixCollection.NoLossOfColorProfile.Description": "Fixes Color Profile not being preserved on all operations.", @@ -47,11 +52,23 @@ "CommunityBugFixCollection.ValidQuaternionInputs.Description": "Makes the ProtoFlux Tool spawn valid float and double quaternion inputs.", "CommunityBugFixCollection.ValueModDecimal.Description": "Adds a zero check to the Decimal ValueMod ProtoFlux node to prevent DIV/0 crashes", + "CommunityBugFixCollection.Config.Options.Name": "Options", + "CommunityBugFixCollection.Config.Options.Description": "Contains the settings for the few fixes that offer them.", + "CommunityBugFixCollection.Config.Options.UseIecByteFormat.Name": "Use IEC Byte Format", + "CommunityBugFixCollection.Config.Options.UseIecByteFormat.Description": "Whether to format bytes using IEC (factor 1024) as opposed to decimal format (factor 1000) when LocalizedByteFormatting is enabled.", + + "CommunityBugFixCollection.StorageUnits.Bi": "B", + "CommunityBugFixCollection.StorageUnits.kiB": "KiB", + "CommunityBugFixCollection.StorageUnits.MiB": "MiB", + "CommunityBugFixCollection.StorageUnits.GiB": "GiB", + "CommunityBugFixCollection.StorageUnits.TiB": "TiB", + "CommunityBugFixCollection.StorageUnits.PiB": "PiB", + "CommunityBugFixCollection.StorageUnits.B": "B", - "CommunityBugFixCollection.StorageUnits.kB": "KiB", - "CommunityBugFixCollection.StorageUnits.MB": "MiB", - "CommunityBugFixCollection.StorageUnits.GB": "GiB", - "CommunityBugFixCollection.StorageUnits.TB": "TiB", - "CommunityBugFixCollection.StorageUnits.PB": "PiB" + "CommunityBugFixCollection.StorageUnits.kB": "kB", + "CommunityBugFixCollection.StorageUnits.MB": "MB", + "CommunityBugFixCollection.StorageUnits.GB": "GB", + "CommunityBugFixCollection.StorageUnits.TB": "TB", + "CommunityBugFixCollection.StorageUnits.PB": "PB" } } \ No newline at end of file diff --git a/CommunityBugFixCollection/Locale/fi.json b/CommunityBugFixCollection/Locale/fi.json index 4247be9..9fe2eeb 100644 --- a/CommunityBugFixCollection/Locale/fi.json +++ b/CommunityBugFixCollection/Locale/fi.json @@ -1,12 +1,12 @@ { "localeCode": "fi", - "authors": [ "Banane9" ], + "authors": [ "LJ" ], "messages": { "CommunityBugFixCollection.StorageUnits.B": "t", - "CommunityBugFixCollection.StorageUnits.kB": "Kit", - "CommunityBugFixCollection.StorageUnits.MB": "Mit", - "CommunityBugFixCollection.StorageUnits.GB": "Git", - "CommunityBugFixCollection.StorageUnits.TB": "Tit", - "CommunityBugFixCollection.StorageUnits.PB": "Pit" + "CommunityBugFixCollection.StorageUnits.kB": "kt", + "CommunityBugFixCollection.StorageUnits.MB": "Mt", + "CommunityBugFixCollection.StorageUnits.GB": "Gt", + "CommunityBugFixCollection.StorageUnits.TB": "Tt", + "CommunityBugFixCollection.StorageUnits.PB": "Pt" } } \ No newline at end of file diff --git a/CommunityBugFixCollection/Locale/fr.json b/CommunityBugFixCollection/Locale/fr.json index fa2363d..6de9853 100644 --- a/CommunityBugFixCollection/Locale/fr.json +++ b/CommunityBugFixCollection/Locale/fr.json @@ -3,10 +3,10 @@ "authors": [ "Banane9" ], "messages": { "CommunityBugFixCollection.StorageUnits.B": "o", - "CommunityBugFixCollection.StorageUnits.kB": "Kio", - "CommunityBugFixCollection.StorageUnits.MB": "Mio", - "CommunityBugFixCollection.StorageUnits.GB": "Gio", - "CommunityBugFixCollection.StorageUnits.TB": "Tio", - "CommunityBugFixCollection.StorageUnits.PB": "Pio" + "CommunityBugFixCollection.StorageUnits.kB": "Ko", + "CommunityBugFixCollection.StorageUnits.MB": "Mo", + "CommunityBugFixCollection.StorageUnits.GB": "Go", + "CommunityBugFixCollection.StorageUnits.TB": "To", + "CommunityBugFixCollection.StorageUnits.PB": "Po" } } \ No newline at end of file diff --git a/CommunityBugFixCollection/LocalizedByteFormatting.cs b/CommunityBugFixCollection/LocalizedByteFormatting.cs index b1ca12a..55d5fea 100644 --- a/CommunityBugFixCollection/LocalizedByteFormatting.cs +++ b/CommunityBugFixCollection/LocalizedByteFormatting.cs @@ -1,6 +1,7 @@ using Elements.Core; using FrooxEngine; using HarmonyLib; +using MonkeyLoader.Configuration; using MonkeyLoader.Resonite; using MonkeyLoader.Resonite.Locale; using System; @@ -10,47 +11,41 @@ using System.Text; using System.Threading.Tasks; -#pragma warning disable MHA008 // Assignment to non-ref patch method argument - namespace CommunityBugFixCollection { [HarmonyPatch] [HarmonyPatchCategory(nameof(LocalizedByteFormatting))] - internal sealed class LocalizedByteFormatting : ResoniteAsyncEventHandlerMonkey + internal sealed class LocalizedByteFormatting : ConfiguredResoniteAsyncEventHandlerMonkey { - public override IEnumerable Authors => Contributors.Banane9; + private static readonly ConditionalWeakTable _lastCultureByStorageStatus = new(); + + public override IEnumerable Authors { get; } = [.. Contributors.Banane9, .. Contributors.LJ]; public override bool CanBeDisabled => true; public override int Priority => HarmonyLib.Priority.Last; - [HarmonyPrefix] - [HarmonyPatch(typeof(UnitFormatting), nameof(UnitFormatting.FormatBytes))] - private static bool UnitFormatBytesPrefix(double bytes, int decimalPlaces, ref string __result) + protected override Task Handle(LocaleLoadingEvent eventData) { - if (!Enabled) - return true; + Engine.Current.GlobalCoroutineManager.RunInSeconds(2, _lastCultureByStorageStatus.Clear); - var format = $"F{decimalPlaces}"; - var absoluteBytes = MathX.Abs(bytes); - var culture = Settings.GetActiveSetting()?.ActiveCulture ?? CultureInfo.CurrentCulture; + return Task.CompletedTask; + } - foreach (var suffix in UnitFormatting.suffixes) - { - if (absoluteBytes < 1024.0 || suffix == UnitFormatting.suffixes[^1]) - { - __result = $"{bytes.ToString(format, culture)} {Mod.GetMessageInCurrent($"StorageUnits.{suffix}")}"; - return false; - } - - bytes /= 1024; - absoluteBytes /= 1024; - } + protected override bool OnEngineReady() + { + ConfigSection.ItemChanged += ConfigSectionItemChanged; - return false; + return base.OnEngineReady(); } - private static readonly ConditionalWeakTable _lastCultureByStorageStatus = new(); + protected override bool OnShutdown(bool applicationExiting) + { + if (!applicationExiting) + ConfigSection.ItemChanged -= ConfigSectionItemChanged; + + return base.OnShutdown(applicationExiting); + } [HarmonyPrefix] [HarmonyPatch(typeof(StorageUsageStatus), nameof(StorageUsageStatus.OnCommonUpdate))] @@ -128,13 +123,35 @@ private static bool StorageUsageStatusOnCommonUpdatePrefix(StorageUsageStatus __ return false; } - protected override Task Handle(LocaleLoadingEvent eventData) + [HarmonyPrefix] + [HarmonyPatch(typeof(UnitFormatting), nameof(UnitFormatting.FormatBytes))] + private static bool UnitFormatBytesPrefix(double bytes, int decimalPlaces, ref string __result) { - Engine.Current.GlobalCoroutineManager.RunInSeconds(2, _lastCultureByStorageStatus.Clear); + if (!Enabled) + return true; - return Task.CompletedTask; + var format = $"F{decimalPlaces}"; + var culture = Settings.GetActiveSetting()?.ActiveCulture ?? CultureInfo.CurrentCulture; + + // Select base and divisor for suffix determination + var baseNum = ConfigSection.UseIecByteFormat ? 2 : 10; + var divNum = ConfigSection.UseIecByteFormat ? 10 : 3; + + // Either `2^(10*n)` or `10^(3*n)`, but also limited to max unit index. + var index = MathX.Min(MathX.FloorToUInt(MathX.Log(MathX.Abs(bytes), baseNum) / divNum), (uint)(UnitFormatting.suffixes.Length - 1)); + var suffix = UnitFormatting.suffixes[index]; + + if (ConfigSection.UseIecByteFormat) + suffix = suffix.Insert(suffix.Length - 1, "i"); + + // AKA scaled bytes in IEC/decimal format + var numToFormat = bytes / MathX.Pow(baseNum, divNum * index); + __result = $"{numToFormat.ToString(format, culture)} {Mod.GetMessageInCurrent($"StorageUnits.{suffix}")}"; + + return false; } - } -} -#pragma warning restore MHA008 // Assignment to non-ref patch method argument \ No newline at end of file + private void ConfigSectionItemChanged(object sender, IConfigKeyChangedEventArgs configKeyChangedEventArgs) + => Engine.Current.GlobalCoroutineManager.RunInSeconds(0, _lastCultureByStorageStatus.Clear); + } +} \ No newline at end of file