Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of WorldClock v1.0.0
plugins/WorldClock.dll
Decompiled an hour agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Hoose")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) Hoose 2026")] [assembly: AssemblyDescription("Displays the current in-game time in a configurable screen position.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+be6f85042814c449b706f2a9f0cd4f68aa7a9f44")] [assembly: AssemblyProduct("Valheim WorldClock")] [assembly: AssemblyTitle("WorldClock")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WorldClock { internal sealed class ClockDisplayCache { private static readonly IReadOnlyList<(string FontName, string Text, bool IsTime, string Prefix, string Suffix)> _invalidRuns = new(string, string, bool, string, string)[1] { (null, "Invalid clock format", false, string.Empty, string.Empty) }; private string _template; private bool _hasTemplate; private bool _requiresDay; private bool _hasInput; private int _seconds; private int _day; private string _timeFormat; private bool _linearColorSpace; private string _renderedTemplate; private string _renderedTime; private string _renderedTimeFormat; private string _renderedPhase; private int _renderedDay; private bool _renderedLinearColorSpace; internal bool RequiresDay => _requiresDay; internal string Error { get; private set; } internal IReadOnlyList<(string FontName, string Text, bool IsTime, string Prefix, string Suffix)> Runs { get; private set; } internal void SetTemplate(string template) { if (!_hasTemplate || !(_template == template)) { _template = template; _hasTemplate = true; _requiresDay = ClockTextFormatter.RequiresDay(template); _hasInput = false; } } internal void Update(float fraction, string timeFormat, int day, bool linearColorSpace) { int num = ClockTimeFormatter.SecondsIntoDay(fraction); if (_hasInput && _seconds == num && _day == day && _timeFormat == timeFormat && _linearColorSpace == linearColorSpace) { return; } _hasInput = true; _seconds = num; _day = day; _timeFormat = timeFormat; _linearColorSpace = linearColorSpace; try { var (text, text2) = ClockTimeFormatter.FormatSeconds(num, timeFormat); if (Error != null || Runs == null || !(_renderedTemplate == _template) || !(_renderedTime == text) || !(_renderedTimeFormat == timeFormat) || !(_renderedPhase == text2) || _renderedDay != day || _renderedLinearColorSpace != linearColorSpace) { string formattedText = ClockTextFormatter.Format(_template, text, day, text2, markTime: true); formattedText = ClockTextFormatter.PrepareColorsForRendering(formattedText, linearColorSpace); Runs = ClockTextFormatter.SplitDisplayRuns(formattedText); _renderedTemplate = _template; _renderedTime = text; _renderedTimeFormat = timeFormat; _renderedPhase = text2; _renderedDay = day; _renderedLinearColorSpace = linearColorSpace; Error = null; } } catch (FormatException ex) { Runs = _invalidRuns; Error = ex.Message; } } } internal static class ClockLayout { internal static float HorizontalOffset(float screenWidth, float labelWidth, float position) { float val = position * screenWidth - labelWidth / 2f; return Math.Max(0f, Math.Min(val, screenWidth - labelWidth)); } internal static (float Width, float Height) LabelSize(float screenWidth, float screenHeight, float textWidth, float textHeight) { return (Width: Math.Min(screenWidth, textWidth + 4f), Height: Math.Min(screenHeight, textHeight + 8f)); } internal static float TimeAdvance(float maximumWidth, float actualWidth) { return Math.Max(0f, Math.Max(maximumWidth, actualWidth) - 2f); } internal static (float NameWidth, float SampleOffset, float SampleWidth) FontDemoColumns(float availableWidth, float maximumNameWidth) { float num = Math.Max(1f, availableWidth); float num2 = Math.Min(16f, num / 10f); float num3 = Math.Min(Math.Max(0f, maximumNameWidth), (num - num2) / 2f); float num4 = num3 + num2; return (NameWidth: num3, SampleOffset: num4, SampleWidth: num - num4); } internal static (float Height, float NameOffset, float SampleOffset) FontDemoRow(float nameHeight, float sampleHeight) { float num = Math.Max(0f, nameHeight); float num2 = Math.Max(0f, sampleHeight); float num3 = Math.Max(30f, (float)Math.Ceiling(Math.Max(num, num2)) + 8f); return (Height: num3, NameOffset: (num3 - num) / 2f, SampleOffset: (num3 - num2) / 2f); } } internal static class ClockTextFormatter { internal const string DefaultTemplate = "<b><font size=24 color=#FF8E0080>Day {day} <font size=18 color=#B4B4B480>|</font> {time} <font size=18 color=#B4B4B480>|</font> {phase}</font></b>"; private static readonly Regex _placeholder = new Regex("\\{([a-z]+)\\}", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); private static readonly Regex _fontTag = new Regex("</?font\\b[^>]*>", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); private static readonly Regex _attribute = new Regex("\\G\\s+(size|color|name)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"']+))", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); private static readonly Regex _hexColor = new Regex("^#(?:[0-9a-f]{6}|[0-9a-f]{8})$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); private static readonly Regex _colorTag = new Regex("</?color(?:\\s*=\\s*[^>]*)?>", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); private static readonly Regex _hexColorTag = new Regex("(<color=)#([0-9a-f]{6})([0-9a-f]{2})?(>)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); private static readonly Regex _runTokens = new Regex("<worldclockfont(?:=([^>]*))?>|<worldclocktime(?:=end)?>|</?(?:b|i|size|color)(?:=[^>]*)?>", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); internal static bool RequiresDay(string template) { if (template != null) { return Regex.IsMatch(template, "\\{day\\}", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); } return false; } internal static string Format(string template, string time, int day, string phase, bool markTime = false) { if (string.IsNullOrWhiteSpace(template)) { throw new FormatException("The display format cannot be empty."); } if (template.IndexOf("<worldclockfont", StringComparison.OrdinalIgnoreCase) >= 0 || template.IndexOf("<worldclocktime", StringComparison.OrdinalIgnoreCase) >= 0) { throw new FormatException("The display format contains a reserved tag."); } string text = _placeholder.Replace(template, delegate(Match match3) { switch (match3.Groups[1].Value.ToLowerInvariant()) { case "time": { int num3 = template.LastIndexOf('<', match3.Index); int num4 = template.LastIndexOf('>', match3.Index); if (markTime && num3 > num4) { return time; } if (markTime) { return "<worldclocktime>" + time + "<worldclocktime=end>"; } return time; } case "day": return day.ToString(CultureInfo.InvariantCulture); case "phase": return phase; default: throw new FormatException("Unknown placeholder '" + match3.Value + "'. Use {time}, {day}, or {phase}."); } }); StringBuilder stringBuilder = new StringBuilder(); Stack<(string, string)> stack = new Stack<(string, string)>(); string text2 = null; int num = 0; foreach (Match item2 in _fontTag.Matches(text)) { stringBuilder.Append(text, num, item2.Index - num); if (item2.Value.StartsWith("</", StringComparison.Ordinal)) { if (!string.Equals(item2.Value, "</font>", StringComparison.OrdinalIgnoreCase) || stack.Count == 0) { throw new FormatException("Unexpected closing font tag."); } (string, string) tuple = stack.Pop(); stringBuilder.Append(tuple.Item1); if (text2 != tuple.Item2) { text2 = tuple.Item2; AppendFontMarker(stringBuilder, text2); } } else { string text3 = item2.Value.Substring(5, item2.Value.Length - 6); string text4 = null; string text5 = null; string text6 = null; int num2 = 0; while (num2 < text3.Length && !string.IsNullOrWhiteSpace(text3.Substring(num2))) { Match match2 = _attribute.Match(text3, num2); if (!match2.Success) { throw new FormatException("Font tags support only name, size and color attributes."); } string value = match2.Groups[1].Value; string text7 = (match2.Groups[2].Success ? match2.Groups[2].Value : (match2.Groups[3].Success ? match2.Groups[3].Value : match2.Groups[4].Value)); if (string.Equals(value, "size", StringComparison.OrdinalIgnoreCase)) { if (text4 != null || !int.TryParse(text7, NumberStyles.None, CultureInfo.InvariantCulture, out var result) || result < 1 || result > 256) { throw new FormatException("Font size must be an integer from 1 to 256 and appear only once."); } text4 = result.ToString(CultureInfo.InvariantCulture); } else if (string.Equals(value, "color", StringComparison.OrdinalIgnoreCase)) { if (text5 != null || !_hexColor.IsMatch(text7)) { throw new FormatException("Font color must be a single #RRGGBB or #RRGGBBAA value."); } text5 = text7; } else { if (text6 != null || !FontCatalog.IsValidName(text7)) { throw new FormatException("Font name must be nonempty and cannot contain angle brackets, quotes or control characters."); } text6 = text7; } num2 = match2.Index + match2.Length; } if (text4 == null && text5 == null && text6 == null) { throw new FormatException("Font tags require a name, size or color attribute."); } string text8 = string.Empty; string item = text2; if (text6 != null && text6 != text2) { text2 = text6; AppendFontMarker(stringBuilder, text2); } if (text4 != null) { stringBuilder.Append("<size=").Append(text4).Append('>'); text8 = "</size>"; } if (text5 != null) { stringBuilder.Append("<color=").Append(text5).Append('>'); text8 = "</color>" + text8; } stack.Push((text8, item)); } num = item2.Index + item2.Length; } stringBuilder.Append(text, num, text.Length - num); if (stack.Count != 0 || _fontTag.IsMatch(stringBuilder.ToString()) || Regex.IsMatch(stringBuilder.ToString(), "</?font\\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)) { throw new FormatException("A font tag is unclosed or malformed."); } return stringBuilder.ToString(); } internal static string Shadow(string formattedText) { return _colorTag.Replace(formattedText, string.Empty); } internal static string PrepareColorsForRendering(string formattedText, bool linearColorSpace) { if (!linearColorSpace) { return formattedText; } return _hexColorTag.Replace(formattedText, delegate(Match match) { string value = match.Groups[2].Value; string text = EncodeColorChannel(value.Substring(0, 2)); string text2 = EncodeColorChannel(value.Substring(2, 2)); string text3 = EncodeColorChannel(value.Substring(4, 2)); return match.Groups[1].Value + "#" + text + text2 + text3 + match.Groups[3].Value + match.Groups[4].Value; }); } internal static IReadOnlyList<(string FontName, string Text)> SplitRuns(string formattedText) { List<(string, string)> list = new List<(string, string)>(); foreach (var item in SplitDisplayRuns(formattedText)) { list.Add((item.FontName, item.Text)); } return list; } internal static IReadOnlyList<(string FontName, string Text, bool IsTime, string Prefix, string Suffix)> SplitDisplayRuns(string formattedText) { List<(string, string, bool, string, string)> list = new List<(string, string, bool, string, string)>(); List<(string, string)> list2 = new List<(string, string)>(); StringBuilder stringBuilder = new StringBuilder(); string item = null; int num = 0; bool flag = false; bool item2 = false; string item3 = string.Empty; foreach (Match item4 in _runTokens.Matches(formattedText)) { string text = formattedText.Substring(num, item4.Index - num); stringBuilder.Append(text); flag |= text.Length > 0; if (item4.Value.StartsWith("<worldclockfont", StringComparison.OrdinalIgnoreCase) || item4.Value.StartsWith("<worldclocktime", StringComparison.OrdinalIgnoreCase)) { if (flag) { StringBuilder stringBuilder2 = new StringBuilder(); for (int num2 = list2.Count - 1; num2 >= 0; num2--) { stringBuilder2.Append("</").Append(list2[num2].Item1).Append('>'); } stringBuilder.Append(stringBuilder2); list.Add((item, stringBuilder.ToString(), item2, item3, stringBuilder2.ToString())); } stringBuilder.Clear(); foreach (var item5 in list2) { stringBuilder.Append(item5.Item2); } item3 = stringBuilder.ToString(); flag = false; if (item4.Value.StartsWith("<worldclockfont", StringComparison.OrdinalIgnoreCase)) { item = (item4.Groups[1].Success ? item4.Groups[1].Value : null); } else { item2 = !item4.Value.Equals("<worldclocktime=end>", StringComparison.OrdinalIgnoreCase); } } else { stringBuilder.Append(item4.Value); bool flag2 = item4.Value.StartsWith("</", StringComparison.Ordinal); int num3 = ((!flag2) ? 1 : 2); int num4 = item4.Value.IndexOfAny(new char[2] { '=', '>' }, num3); string text2 = item4.Value.Substring(num3, num4 - num3).ToLowerInvariant(); if (flag2) { if (list2.Count == 0 || list2[list2.Count - 1].Item1 != text2) { throw new FormatException("Unbalanced rich-text tag: " + item4.Value + "."); } list2.RemoveAt(list2.Count - 1); } else { list2.Add((text2, item4.Value)); } } num = item4.Index + item4.Length; } string text3 = formattedText.Substring(num); stringBuilder.Append(text3); flag |= text3.Length > 0; if (list2.Count != 0) { throw new FormatException("Rich-text tags must be properly closed."); } if (flag) { list.Add((item, stringBuilder.ToString(), item2, item3, string.Empty)); } return list; } private static string EncodeColorChannel(string hex) { double num = (double)int.Parse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture) / 255.0; return ((int)Math.Round(((num <= 0.0031308) ? (num * 12.92) : (1.055 * Math.Pow(num, 5.0 / 12.0) - 0.055)) * 255.0, MidpointRounding.AwayFromZero)).ToString("X2", CultureInfo.InvariantCulture); } private static void AppendFontMarker(StringBuilder output, string fontName) { output.Append("<worldclockfont"); if (fontName != null) { output.Append('=').Append(fontName); } output.Append('>'); } } internal static class ClockTimeFormatter { private const int SecondsPerDay = 86400; internal static (string Time, string Phase) Format(float dayFraction, string timeFormat) { return FormatSeconds(SecondsIntoDay(dayFraction), timeFormat); } internal static int SecondsIntoDay(float dayFraction) { if (float.IsNaN(dayFraction) || float.IsInfinity(dayFraction)) { throw new ArgumentOutOfRangeException("dayFraction", "The day fraction must be finite."); } return (int)Math.Floor(((double)dayFraction - Math.Floor(dayFraction)) * 86400.0); } internal static (string Time, string Phase) FormatSeconds(int secondsIntoDay, string timeFormat) { if (string.IsNullOrWhiteSpace(timeFormat)) { throw new FormatException("The time format cannot be empty."); } int num = secondsIntoDay / 3600; string item = DateTime.MinValue.AddSeconds(secondsIntoDay).ToString(timeFormat, CultureInfo.InvariantCulture); string text = ((num < 12) ? ((num < 6) ? ((num >= 4) ? "Before dawn" : "Late night") : ((num >= 8) ? "Morning" : "Dawn")) : ((num < 17) ? ((num >= 14) ? "Afternoon" : "Midday") : ((num >= 20) ? "Night" : "Evening"))); string item2 = text; return (Time: item, Phase: item2); } } internal static class FontCatalog { internal const string DefaultName = "Norsebold"; internal const int DefaultSize = 22; internal const string DemoLabelName = "AveriaSansLibre-Bold"; private static readonly Regex _validName = new Regex("^[^<>\"'\\x00-\\x1f\\x7f]+$", RegexOptions.CultureInvariant); internal static bool IsValidName(string name) { if (!string.IsNullOrWhiteSpace(name)) { return _validName.IsMatch(name); } return false; } internal static string EffectiveName(string name) { return name ?? "Norsebold"; } internal static string DisplayName(string name) { if (!string.Equals(name, "Norsebold", StringComparison.OrdinalIgnoreCase)) { return name; } return name + " (default)"; } internal static IReadOnlyList<string> AvailableNames(IEnumerable<string> names, Predicate<string> isAvailable) { List<string> list = new List<string>(); foreach (string name in names) { if (IsValidName(name) && isAvailable(name)) { list.Add(name); } } list.Sort(StringComparer.OrdinalIgnoreCase); return list; } } internal sealed class TimeWidthCandidates { private readonly HashSet<string> _values = new HashSet<string>(StringComparer.Ordinal); internal TimeWidthCandidates(string format) { for (int i = 0; i < 86400; i++) { _values.Add(DateTime.MinValue.AddSeconds(i).ToString(format, CultureInfo.InvariantCulture)); } } internal float Measure(Func<string, float> measure) { float num = 0f; foreach (string value in _values) { num = Math.Max(num, measure(value)); } return num; } } [BepInPlugin("hoose.valheim.worldclock", "WorldClock", "1.0.0")] [BepInProcess("valheim.exe")] public sealed class WorldClockPlugin : BaseUnityPlugin { public const string PluginName = "WorldClock"; public const string PluginAuthor = "Hoose"; public const string PluginGuid = "hoose.valheim.worldclock"; public const string PluginVersion = "1.0.0"; private ConfigEntry<float> _horizontalPosition; private ConfigEntry<float> _verticalPosition; private ConfigEntry<string> _displayFormat; private ConfigEntry<string> _timeFormat; private ConfigEntry<bool> _showFontDemo; private ConfigEntry<string> _fontDemoText; private readonly ClockDisplayCache _displayCache = new ClockDisplayCache(); private IReadOnlyList<(string FontName, string Text, bool IsTime, string Prefix, string Suffix)> _runs; private IReadOnlyList<(string FontName, string Text, bool IsTime, string Prefix, string Suffix)> _measuredRuns; private List<(GUIStyle Style, GUIStyle ShadowStyle, string Text, string ShadowText, Vector2 Size, float Advance)> _measured; private readonly Dictionary<(Font Font, string Prefix, string Suffix), float> _timeWidths = new Dictionary<(Font, string, string), float>(); private string _widthTimeFormat; private TimeWidthCandidates _timeCandidates; private float _measuredWidth; private float _measuredHeight; private bool _formatErrorLogged; private bool _demoFontWarningLogged; private string _missingFont; private float _nextFontRefresh; private Vector2 _demoScroll; private List<(string Name, string Sample, GUIStyle SampleStyle, float Height, float NameHeight, float SampleHeight, float NameOffset, float SampleOffset)> _demoRows; private GUIStyle _demoNameStyle; private GUIStyle _demoHintStyle; private float _demoContentWidth; private float _demoContentHeight; private string _demoSample; private (float NameWidth, float SampleOffset, float SampleWidth) _demoColumns; private readonly Dictionary<string, Font> _fonts = new Dictionary<string, Font>(StringComparer.OrdinalIgnoreCase); private GUIStyle _clockStyle; private GUIStyle _shadowStyle; private void Awake() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) _displayFormat = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "Display format", "<b><font size=24 color=#FF8E0080>Day {day} <font size=18 color=#B4B4B480>|</font> {time} <font size=18 color=#B4B4B480>|</font> {phase}</font></b>", "Whole clock template. Use {time}, {day}, and {phase}. Style with <b> and <font name=\"Norse\" size=24 color=#FFFFFF>."); _timeFormat = ((BaseUnityPlugin)this).Config.Bind<string>("Display", "Time format", "HH:mm", "A .NET custom date and time format string."); _horizontalPosition = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "Horizontal position", 0.07f, new ConfigDescription("Horizontal center of the clock as a fraction of screen width: 0 = left edge, 0.5 = center, 1 = right edge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _verticalPosition = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "Vertical position", 0f, new ConfigDescription("Top edge of the clock, as a fraction of screen height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); _showFontDemo = ((BaseUnityPlugin)this).Config.Bind<bool>("Font demo", "Show font demo", false, "Display all currently available fonts on screen, one per row. Open the game menu to use the mouse wheel over the list."); _fontDemoText = ((BaseUnityPlugin)this).Config.Bind<string>("Font demo", "Sample text", "Day 42 | 12:00", "Text shown after each font name in the sampler."); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Active color space: {2}.", "WorldClock", "1.0.0", QualitySettings.activeColorSpace)); } private void Update() { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 _displayCache.SetTemplate(_displayFormat.Value); if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Hud.instance == (Object)null || (Object)(object)EnvMan.instance == (Object)null || (_displayCache.RequiresDay && (Object)(object)ZNet.instance == (Object)null)) { _runs = null; return; } int day = (_displayCache.RequiresDay ? EnvMan.instance.GetDay() : 0); _displayCache.Update(EnvMan.instance.GetDayFraction(), _timeFormat.Value, day, (int)QualitySettings.activeColorSpace == 1); _runs = _displayCache.Runs; if (_displayCache.Error == null) { _formatErrorLogged = false; } else if (!_formatErrorLogged) { ((BaseUnityPlugin)this).Logger.LogError((object)("Invalid WorldClock display or time format: " + _displayCache.Error)); _formatErrorLogged = true; } } private void OnGUI() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (_runs == null && (!_showFontDemo.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Hud.instance == (Object)null)) { return; } Color color = GUI.color; Color contentColor = GUI.contentColor; try { GUI.color = Color.white; GUI.contentColor = Color.white; DrawOverlay(); } finally { GUI.color = color; GUI.contentColor = contentColor; } } private void DrawOverlay() { //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) EnsureStyles(); if (Time.unscaledTime >= _nextFontRefresh) { RefreshFonts(); } if (_runs == null) { DrawFontDemo(); return; } if (_measured != null) { foreach (var item3 in _measured) { if ((Object)(object)item3.Style.font == (Object)null) { _measuredRuns = null; break; } } } if (_measuredRuns != _runs) { List<(GUIStyle, GUIStyle, string, string, Vector2, float)> list = new List<(GUIStyle, GUIStyle, string, string, Vector2, float)>(); float num = 0f; float num2 = 0f; for (int i = 0; i < _runs.Count; i++) { (string, string, bool, string, string) tuple = _runs[i]; GUIStyle val = new GUIStyle(_clockStyle); string text = FontCatalog.EffectiveName(tuple.Item1); if (!_fonts.TryGetValue(text, out var value) || (Object)(object)value == (Object)null) { if (_missingFont != text) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("WorldClock font '" + text + "' is not currently loaded. Check the font demo or choose another font.")); _missingFont = text; } GUI.Label(new Rect(0f, 0f, (float)Screen.width, 30f), "WorldClock font unavailable: " + text, _clockStyle); if (_showFontDemo.Value) { DrawFontDemo(); } return; } val.font = value; Vector2 val2 = val.CalcSize(new GUIContent(tuple.Item2)); GUIStyle val3 = new GUIStyle(val); val3.normal.textColor = _shadowStyle.normal.textColor; float num3 = (tuple.Item3 ? TimeWidth(val, value, tuple.Item4, tuple.Item5, val2.x) : val2.x) + ((i == _runs.Count - 1 || !string.Equals(tuple.Item1, _runs[i + 1].FontName, StringComparison.OrdinalIgnoreCase)) ? 4f : 0f); list.Add((val, val3, tuple.Item2, ClockTextFormatter.Shadow(tuple.Item2), val2, num3)); num += num3; num2 = Mathf.Max(num2, val2.y); } _measured = list; _measuredRuns = _runs; _measuredWidth = num; _measuredHeight = num2; } _missingFont = null; (float Width, float Height) tuple2 = ClockLayout.LabelSize(Screen.width, Screen.height, _measuredWidth, _measuredHeight); float item = tuple2.Width; float item2 = tuple2.Height; float num4 = ClockLayout.HorizontalOffset(Screen.width, item, _horizontalPosition.Value); float num5 = Mathf.Clamp(_verticalPosition.Value * (float)Screen.height, 0f, Mathf.Max(0f, (float)Screen.height - item2)); GUI.BeginGroup(new Rect(num4, num5, item, item2)); float num6 = Mathf.Max(0f, (item - _measuredWidth) / 2f); Rect val4 = default(Rect); foreach (var item4 in _measured) { ((Rect)(ref val4))..ctor(num6, 0f, item4.Size.x + 4f, item2 - 2f); GUI.Label(new Rect(((Rect)(ref val4)).x + 2f, ((Rect)(ref val4)).y + 2f, ((Rect)(ref val4)).width, ((Rect)(ref val4)).height), item4.ShadowText, item4.ShadowStyle); GUI.Label(val4, item4.Text, item4.Style); num6 += item4.Advance; } GUI.EndGroup(); if (_showFontDemo.Value) { DrawFontDemo(); } } private float TimeWidth(GUIStyle style, Font font, string prefix, string suffix, float actualWidth) { string value = _timeFormat.Value; if (_timeCandidates == null || _widthTimeFormat != value) { _timeCandidates = new TimeWidthCandidates(value); _widthTimeFormat = value; _timeWidths.Clear(); } (Font, string, string) key = (font, prefix, suffix); if (!_timeWidths.TryGetValue(key, out var value2)) { value2 = _timeCandidates.Measure((string text) => style.CalcSize(new GUIContent(prefix + text + suffix)).x); value2 = Mathf.Ceil(value2); _timeWidths.Add(key, value2); } return ClockLayout.TimeAdvance(value2, actualWidth); } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0060: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (_clockStyle == null) { _clockStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 22, richText = true, wordWrap = false, fixedWidth = 0f, fixedHeight = 0f, padding = new RectOffset(0, 0, 0, 0) }; _clockStyle.normal.textColor = Color.white; _shadowStyle = new GUIStyle(_clockStyle); _shadowStyle.normal.textColor = new Color(0f, 0f, 0f, 0.8f); } } private void RefreshFonts() { _measuredRuns = null; _demoRows = null; _fonts.Clear(); Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val in array) { if ((Object)(object)val != (Object)null && FontCatalog.IsValidName(((Object)val).name) && !_fonts.ContainsKey(((Object)val).name)) { _fonts.Add(((Object)val).name, val); } } _nextFontRefresh = Time.unscaledTime + 5f; } private void DrawFontDemo() { //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Expected O, but got Unknown //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Expected O, but got Unknown float num = Mathf.Max(1f, (float)Screen.width * 0.9f); float num2 = Mathf.Max(1f, (float)Screen.height * 0.65f); Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - num) / 2f, (float)Screen.height * 0.2f, num, num2); Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 4f, ((Rect)(ref val)).y + 44f, Mathf.Max(1f, ((Rect)(ref val)).width - 8f), Mathf.Max(1f, ((Rect)(ref val)).height - 48f)); float num3 = Mathf.Max(1f, ((Rect)(ref val2)).width - 20f); if (_demoRows != null) { foreach (var demoRow in _demoRows) { if ((Object)(object)demoRow.SampleStyle.font == (Object)null) { _demoRows = null; break; } } } if (_demoRows == null || _demoContentWidth != num3 || _demoSample != _fontDemoText.Value) { GUIStyle val3 = new GUIStyle(_clockStyle) { fontSize = 18, richText = false, wordWrap = true, alignment = (TextAnchor)0 }; if (_fonts.TryGetValue("AveriaSansLibre-Bold", out var value) && (Object)(object)value != (Object)null) { val3.font = value; _demoFontWarningLogged = false; } else if (!_demoFontWarningLogged) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"WorldClock font demo label font 'AveriaSansLibre-Bold' is not currently loaded; using the Unity GUI label font."); _demoFontWarningLogged = true; } float num4 = 0f; IReadOnlyList<string> readOnlyList = FontCatalog.AvailableNames(_fonts.Keys, (string name) => (Object)(object)_fonts[name] != (Object)null); foreach (string item in readOnlyList) { num4 = Mathf.Max(num4, val3.CalcSize(new GUIContent(FontCatalog.DisplayName(item))).x); } (float, float, float) demoColumns = ClockLayout.FontDemoColumns(num3, num4); List<(string, string, GUIStyle, float, float, float, float, float)> list = new List<(string, string, GUIStyle, float, float, float, float, float)>(); float num5 = 0f; foreach (string item2 in readOnlyList) { GUIStyle val4 = new GUIStyle(val3); val4.font = _fonts[item2]; string value2 = _fontDemoText.Value; string text = FontCatalog.DisplayName(item2); float num6 = Mathf.Ceil(Mathf.Max(val3.lineHeight, val3.CalcHeight(new GUIContent(text), Mathf.Max(1f, demoColumns.Item1)))); float num7 = Mathf.Ceil(Mathf.Max(val4.lineHeight, val4.CalcHeight(new GUIContent(value2), Mathf.Max(1f, demoColumns.Item3)))); (float, float, float) tuple = ClockLayout.FontDemoRow(num6, num7); list.Add((text, value2, val4, tuple.Item1, num6, num7, tuple.Item2, tuple.Item3)); num5 += tuple.Item1 + 2f; } _demoNameStyle = val3; _demoHintStyle = new GUIStyle(val3) { fontSize = 14 }; _demoColumns = demoColumns; _demoRows = list; _demoContentHeight = num5; _demoContentWidth = num3; _demoSample = _fontDemoText.Value; } GUI.Box(val, string.Empty); GUI.Label(new Rect(((Rect)(ref val)).x + 8f, ((Rect)(ref val)).y + 4f, Mathf.Max(1f, ((Rect)(ref val)).width - 16f), 38f), "Font demo: open the game menu (Esc), then use the mouse wheel over the list to scroll.", _demoHintStyle); if (_demoRows.Count == 0) { GUI.Label(val2, "No usable fonts are currently loaded.", _demoNameStyle); return; } _demoScroll = GUI.BeginScrollView(val2, _demoScroll, new Rect(0f, 0f, num3, _demoContentHeight)); float num8 = 0f; foreach (var demoRow2 in _demoRows) { GUI.BeginGroup(new Rect(0f, num8, num3, demoRow2.Height)); GUI.Label(new Rect(0f, demoRow2.NameOffset, _demoColumns.NameWidth, demoRow2.NameHeight), demoRow2.Name, _demoNameStyle); GUI.Label(new Rect(_demoColumns.SampleOffset, demoRow2.Rest.Item1, _demoColumns.SampleWidth, demoRow2.SampleHeight), demoRow2.Sample, demoRow2.SampleStyle); GUI.EndGroup(); num8 += demoRow2.Height + 2f; } GUI.EndScrollView(); } } }