Skip to content

Commit b0bf334

Browse files
committed
Localize the storage units (MiB, GiB, etc.), in particular for the StorageUsageStatus component
Adds a fix for Yellow-Dog-Man/Resonite-Issues#1269 / Yellow-Dog-Man/Locale#186
1 parent 2bf3767 commit b0bf334

6 files changed

Lines changed: 179 additions & 3 deletions

File tree

CommunityBugFixCollection/Locale/de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"CommunityBugFixCollection.ImportMultipleAudioFiles.Description": "Macht es möglich mehrere Audiodateien auf einmal zu importieren.",
3131
"CommunityBugFixCollection.ImportWebFilesAsUrls.Description": "Sorgt dafür, dass URLs zu Textdateien oder Resonite Packages nicht importiert werden, statt als Hyperlink aufzutauchen.",
3232
"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.",
33+
"CommunityBugFixCollection.LocalizedByteFormatting.Description": "Lokalisiert die Speichereinheiten (MiB, GiB, etc.), inbsesondere bei der StorageUsageStatus Komponente.",
3334
"CommunityBugFixCollection.LongerWorldLoadingFailIndication.Description": "Lässt den Welt-Ladefortschritts-Indikator frühestens nach 20s verschwinden, falls der Vorgang fehlgeschlagen ist.",
3435
"CommunityBugFixCollection.NaNtEqual.Description": "Sorgt dafür, dass NaN float / double Werte sich bei den == und != ProtoFlux Nodes sowie bei der ValueEqualityDriver Komponente niemals gleichen.",
3536
"CommunityBugFixCollection.NoLossOfColorProfile.Description": "Verhindert, dass Farbprofile nicht bei allen Berechnungen erhalten bleiben.",

CommunityBugFixCollection/Locale/en.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"CommunityBugFixCollection.ImportMultipleAudioFiles.Description": "Fixes it not being possible to import multiple audio clips at once.",
3131
"CommunityBugFixCollection.ImportWebFilesAsUrls.Description": "Fixes URLs to text files or Resonite Packages failing to import instead of appearing as a hyperlink.",
3232
"CommunityBugFixCollection.IndependentlyScaleDirectCursor.Description": "Fixes direct cursor size becoming very large when snapped to an object much closer than the true cursor.",
33+
"CommunityBugFixCollection.LocalizedByteFormatting.Description": "Localizes the storage units (MiB, GiB, etc.), in particular for the StorageUsageStatus component.",
3334
"CommunityBugFixCollection.LongerWorldLoadingFailIndication.Description": "Only lets the World Load Progress Indicator disappear after 20s or more if the process failed.",
3435
"CommunityBugFixCollection.NaNtEqual.Description": "Makes NaN floats / doubles never equal to each other for the ProtoFlux == and != nodes, as well as the ValueEqualityDriver component.",
3536
"CommunityBugFixCollection.NoLossOfColorProfile.Description": "Fixes Color Profile not being preserved on all operations.",
@@ -44,6 +45,13 @@
4445
"CommunityBugFixCollection.TiltedUIAlignment.Description": "Tilts the UI-Focus camera to work around UIX rendering issues.",
4546
"CommunityBugFixCollection.UserInspectorAsNonHost.Description": "Fixes UserInspectors not listing existing users in the session for non-host users.",
4647
"CommunityBugFixCollection.ValidQuaternionInputs.Description": "Makes the ProtoFlux Tool spawn valid float and double quaternion inputs.",
47-
"CommunityBugFixCollection.ValueModDecimal.Description": "Adds a zero check to the Decimal ValueMod ProtoFlux node to prevent DIV/0 crashes"
48+
"CommunityBugFixCollection.ValueModDecimal.Description": "Adds a zero check to the Decimal ValueMod ProtoFlux node to prevent DIV/0 crashes",
49+
50+
"CommunityBugFixCollection.StorageUnits.B": "B",
51+
"CommunityBugFixCollection.StorageUnits.kB": "KiB",
52+
"CommunityBugFixCollection.StorageUnits.MB": "MiB",
53+
"CommunityBugFixCollection.StorageUnits.GB": "GiB",
54+
"CommunityBugFixCollection.StorageUnits.TB": "TiB",
55+
"CommunityBugFixCollection.StorageUnits.PB": "PiB"
4856
}
4957
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"localeCode": "fi",
3+
"authors": [ "Banane9" ],
4+
"messages": {
5+
"CommunityBugFixCollection.StorageUnits.B": "t",
6+
"CommunityBugFixCollection.StorageUnits.kB": "Kit",
7+
"CommunityBugFixCollection.StorageUnits.MB": "Mit",
8+
"CommunityBugFixCollection.StorageUnits.GB": "Git",
9+
"CommunityBugFixCollection.StorageUnits.TB": "Tit",
10+
"CommunityBugFixCollection.StorageUnits.PB": "Pit"
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"localeCode": "fr",
3+
"authors": [ "Banane9" ],
4+
"messages": {
5+
"CommunityBugFixCollection.StorageUnits.B": "o",
6+
"CommunityBugFixCollection.StorageUnits.kB": "Kio",
7+
"CommunityBugFixCollection.StorageUnits.MB": "Mio",
8+
"CommunityBugFixCollection.StorageUnits.GB": "Gio",
9+
"CommunityBugFixCollection.StorageUnits.TB": "Tio",
10+
"CommunityBugFixCollection.StorageUnits.PB": "Pio"
11+
}
12+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using Elements.Core;
2+
using FrooxEngine;
3+
using HarmonyLib;
4+
using MonkeyLoader.Resonite;
5+
using MonkeyLoader.Resonite.Locale;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Globalization;
9+
using System.Runtime.CompilerServices;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
13+
#pragma warning disable MHA008 // Assignment to non-ref patch method argument
14+
15+
namespace CommunityBugFixCollection
16+
{
17+
[HarmonyPatch]
18+
[HarmonyPatchCategory(nameof(LocalizedByteFormatting))]
19+
internal sealed class LocalizedByteFormatting : ResoniteAsyncEventHandlerMonkey<LocalizedByteFormatting, LocaleLoadingEvent>
20+
{
21+
public override IEnumerable<string> Authors => Contributors.Banane9;
22+
23+
public override bool CanBeDisabled => true;
24+
25+
public override int Priority => HarmonyLib.Priority.Last;
26+
27+
[HarmonyPrefix]
28+
[HarmonyPatch(typeof(UnitFormatting), nameof(UnitFormatting.FormatBytes))]
29+
private static bool UnitFormatBytesPrefix(double bytes, int decimalPlaces, ref string __result)
30+
{
31+
if (!Enabled)
32+
return true;
33+
34+
var format = $"F{decimalPlaces}";
35+
var absoluteBytes = MathX.Abs(bytes);
36+
var culture = Settings.GetActiveSetting<LocaleSettings>()?.ActiveCulture ?? CultureInfo.CurrentCulture;
37+
38+
foreach (var suffix in UnitFormatting.suffixes)
39+
{
40+
if (absoluteBytes < 1024.0 || suffix == UnitFormatting.suffixes[^1])
41+
{
42+
__result = $"{bytes.ToString(format, culture)} {Mod.GetMessageInCurrent($"StorageUnits.{suffix}")}";
43+
return false;
44+
}
45+
46+
bytes /= 1024;
47+
absoluteBytes /= 1024;
48+
}
49+
50+
return false;
51+
}
52+
53+
private static readonly ConditionalWeakTable<StorageUsageStatus, CultureInfo> _lastCultureByStorageStatus = new();
54+
55+
[HarmonyPrefix]
56+
[HarmonyPatch(typeof(StorageUsageStatus), nameof(StorageUsageStatus.OnCommonUpdate))]
57+
private static bool StorageUsageStatusOnCommonUpdatePrefix(StorageUsageStatus __instance)
58+
{
59+
if (!Enabled)
60+
return true;
61+
62+
if (__instance.World != Userspace.UserspaceWorld && __instance.World != Userspace.CloudHome)
63+
return false;
64+
65+
var storage = (__instance.OwnerId.Value is null || __instance.OwnerId.Value == __instance.Engine.Cloud.Session.CurrentUserID)
66+
? __instance.Engine.Cloud.Storage.CurrentStorage
67+
: ((!__instance.GroupMemberQuota.Value)
68+
? __instance.Engine.Cloud.Groups.TryGetGroupStorage(__instance.OwnerId.Value)
69+
: __instance.Engine.Cloud.Groups.TryGetMemberStorage(__instance.OwnerId.Value));
70+
71+
if (storage is null || storage.QuotaBytes <= 0)
72+
{
73+
__instance.HasValidData.Value = false;
74+
75+
__instance.StorageBytes.Value = -1L;
76+
__instance.FullStorageBytes.Value = -1L;
77+
__instance.ShareableStorageBytes.Value = -1L;
78+
__instance.SharedStorageBytes.Value = -1L;
79+
__instance.UsageBytes.Value = -1L;
80+
__instance.UsageRatio.Value = -1f;
81+
82+
__instance.StorageString.Value = "---";
83+
__instance.FullStorageString.Value = "---";
84+
__instance.ShareableStorageString.Value = "---";
85+
__instance.SharedStorageString.Value = "---";
86+
__instance.RatioString.Value = "---";
87+
__instance.UsageString.Value = "---";
88+
89+
return false;
90+
}
91+
92+
var activeCulture = Settings.GetActiveSetting<LocaleSettings>()?.ActiveCulture ?? CultureInfo.CurrentCulture;
93+
var cultureChanged = !_lastCultureByStorageStatus.TryGetValue(__instance, out _);
94+
95+
__instance.HasValidData.Value = true;
96+
97+
var quotaBytes = storage.QuotaBytes;
98+
var usedBytes = storage.UsedBytes;
99+
100+
__instance.StorageBytes.Value = quotaBytes;
101+
__instance.FullStorageBytes.Value = storage.FullQuotaBytes;
102+
__instance.ShareableStorageBytes.Value = storage.ShareableQuotaBytes;
103+
__instance.SharedStorageBytes.Value = storage.SharedQuotaBytes;
104+
__instance.UsageBytes.Value = usedBytes;
105+
__instance.UsageRatio.Value = (float)usedBytes / quotaBytes;
106+
107+
if (__instance.StorageBytes.GetWasChangedAndClear() || cultureChanged)
108+
__instance.StorageString.Value = UnitFormatting.FormatBytes(quotaBytes);
109+
110+
if (__instance.FullStorageBytes.GetWasChangedAndClear() || cultureChanged)
111+
__instance.FullStorageString.Value = UnitFormatting.FormatBytes(__instance.FullStorageBytes);
112+
113+
if (__instance.ShareableStorageBytes.GetWasChangedAndClear() || cultureChanged)
114+
__instance.ShareableStorageString.Value = UnitFormatting.FormatBytes(__instance.ShareableStorageBytes);
115+
116+
if (__instance.SharedStorageBytes.GetWasChangedAndClear() || cultureChanged)
117+
__instance.SharedStorageString.Value = UnitFormatting.FormatBytes(__instance.SharedStorageBytes);
118+
119+
if (__instance.UsageBytes.GetWasChangedAndClear() || cultureChanged)
120+
__instance.UsageString.Value = UnitFormatting.FormatBytes(usedBytes);
121+
122+
if (__instance.UsageRatio.GetWasChangedAndClear() || cultureChanged)
123+
__instance.RatioString.Value = $"{MathX.RoundToInt(__instance.UsageRatio.Value * 100f).ToString(activeCulture)} %";
124+
125+
_lastCultureByStorageStatus.Remove(__instance);
126+
_lastCultureByStorageStatus.Add(__instance, activeCulture);
127+
128+
return false;
129+
}
130+
131+
protected override Task Handle(LocaleLoadingEvent eventData)
132+
{
133+
Engine.Current.GlobalCoroutineManager.RunInSeconds(2, _lastCultureByStorageStatus.Clear);
134+
135+
return Task.CompletedTask;
136+
}
137+
}
138+
}
139+
140+
#pragma warning restore MHA008 // Assignment to non-ref patch method argument

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ just disable them in the settings in the meantime.
4949
* Context Menu label outline not fading out like everything else (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1027)
5050
* NaN floats / doubles compare as equal in ProtoFlux and ValueEqualityDriver (but only when not approximate) (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1046)
5151
* Ears and View Overrid(d)en ProtoFlux node names are spelled wrong (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1157)
52+
* Storage units can't be localized (and they use GB instead of GiB and so on)
53+
* https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1157
54+
* https://github.com/Yellow-Dog-Man/Locale/issues/186
5255
* ColorX From HexCode (ProtoFlux node) defaults to Linear profile (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1404)
5356
* UserInspectors not listing existing users in the session for non-host users (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1964)
5457
* ProtoFlux value casts from byte to other values converting incorrectly (mono / graphical client only) (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/2257)
@@ -72,8 +75,8 @@ just disable them in the settings in the meantime.
7275
* Sliders and Joints snapping in sessions hosted by a headless (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/399)
7376
* Missing Cloud Home template for Groups (fallback to User Cloud Home) (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1144)
7477
* ProtoFlux inputs for float and double quaternions being spawned with invalid values
75-
* https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1158
76-
* https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/2979
78+
* https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1158
79+
* https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/2979
7780
* UIX Rendering issues in UI-Focus mode (https://github.com/Yellow-Dog-Man/Resonite-Issues/issues/1292)
7881

7982

0 commit comments

Comments
 (0)