diff options
author | mageven <62494521+mageven@users.noreply.github.com> | 2020-07-21 09:44:42 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-21 06:14:42 +0200 |
commit | 4aa47a66c6d72707ccdf7618bcad2a8e65797e3d (patch) | |
tree | 878b44ad4b07f6cefcdbc2362c45d8c851c292f6 /Ryujinx.HLE/HOS/Services | |
parent | 21dfa4974a6697fff6a476a87a2d31d408f74e0d (diff) |
Better TimeZone entry in System Settings (#1254)
* Better timezone labels in System TimeZone
Replace with GtkEntry with auto-complete
Also removed async task as now loading is fast
Address Thog's comments
self-nit: Remove string alias
Address AcK's comments
* Improve parsing
* Optimize and fix string matching
Address jD's comments
* Also, make abbreviations searchable
* Optimize EntryCompletion's MatchFunc
* nit: Result.IsFailure()
* Fix potential crash on opening Settings window w/o FW installed
Diffstat (limited to 'Ryujinx.HLE/HOS/Services')
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs index 70e1dcb4..e2576425 100644 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs +++ b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs @@ -10,6 +10,7 @@ using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem.Content; using Ryujinx.HLE.HOS.Services.Time.Clock; using Ryujinx.HLE.Utilities; +using System; using System.Collections.Generic; using System.IO; @@ -117,6 +118,73 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone } } + public IEnumerable<(int Offset, string Location, string Abbr)> ParseTzOffsets() + { + var tzBinaryContentPath = GetTimeZoneBinaryTitleContentPath(); + + if (string.IsNullOrEmpty(tzBinaryContentPath)) + { + return new[] { (0, "UTC", "UTC") }; + } + + List<(int Offset, string Location, string Abbr)> outList = new List<(int Offset, string Location, string Abbr)>(); + var now = System.DateTimeOffset.Now.ToUnixTimeSeconds(); + using (IStorage ncaStorage = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(tzBinaryContentPath), FileAccess.Read, FileMode.Open)) + using (IFileSystem romfs = new Nca(_virtualFileSystem.KeySet, ncaStorage).OpenFileSystem(NcaSectionType.Data, _fsIntegrityCheckLevel)) + { + foreach (string locName in LocationNameCache) + { + if (locName.StartsWith("Etc")) + { + continue; + } + + if (romfs.OpenFile(out IFile tzif, $"/zoneinfo/{locName}".ToU8Span(), OpenMode.Read).IsFailure()) + { + Logger.PrintError(LogClass.ServiceTime, $"Error opening /zoneinfo/{locName}"); + continue; + } + + using (tzif) + { + TimeZone.ParseTimeZoneBinary(out TimeZoneRule tzRule, tzif.AsStream()); + + TimeTypeInfo ttInfo; + if (tzRule.TimeCount > 0) // Find the current transition period + { + int fin = 0; + for (int i = 0; i < tzRule.TimeCount; ++i) + { + if (tzRule.Ats[i] <= now) + { + fin = i; + } + } + ttInfo = tzRule.Ttis[tzRule.Types[fin]]; + } + else if (tzRule.TypeCount >= 1) // Otherwise, use the first offset in TTInfo + { + ttInfo = tzRule.Ttis[0]; + } + else + { + Logger.PrintError(LogClass.ServiceTime, $"Couldn't find UTC offset for zone {locName}"); + continue; + } + + var abbrStart = tzRule.Chars.AsSpan(ttInfo.AbbreviationListIndex); + int abbrEnd = abbrStart.IndexOf('\0'); + + outList.Add((ttInfo.GmtOffset, locName, abbrStart.Slice(0, abbrEnd).ToString())); + } + } + } + + outList.Sort(); + + return outList; + } + private bool IsLocationNameValid(string locationName) { foreach (string cachedLocationName in LocationNameCache) |