Decompiled source of RuneClock v1.0.0

BepInEx/plugins/RuneClock/RuneClock.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace RuneClock
{
	internal static class ClockFormatter
	{
		public static string Format(float dayFraction, TimeFormatMode format, bool showPeriodLabel, bool isDay)
		{
			int num = Mathf.FloorToInt(Mathf.Repeat(dayFraction, 1f) * 1440f + 0.5f) % 1440;
			int num2 = num / 60;
			int num3 = num % 60;
			if (format == TimeFormatMode.TwentyFourHour)
			{
				string text = string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}", num2, num3);
				if (!showPeriodLabel)
				{
					return text;
				}
				return text + (isDay ? " Day" : " Night");
			}
			int num4 = num2 % 12;
			if (num4 == 0)
			{
				num4 = 12;
			}
			string arg = ((num2 >= 12) ? "PM" : "AM");
			return string.Format(CultureInfo.InvariantCulture, "{0:00}:{1:00}{2}", num4, num3, arg);
		}
	}
	[BepInPlugin("com.runeclock.valheim", "Rune Clock", "1.0.0")]
	[BepInProcess("valheim.exe")]
	public sealed class RuneClockPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.runeclock.valheim";

		public const string PluginName = "Rune Clock";

		public const string PluginVersion = "1.0.0";

		private RuneClockSettings settings;

		private string displayText = string.Empty;

		private bool clockAvailable;

		private float nextRefresh;

		private GUIStyle? textStyle;

		private GUIStyle? shadowStyle;

		private string styleKey = string.Empty;

		private void Awake()
		{
			settings = new RuneClockSettings(((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Rune Clock 1.0.0 loaded.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"The clock reads Valheim's live EnvMan day fraction and follows the world's actual cycle.");
		}

		private void Update()
		{
			if (settings.Enabled.Value && !(Time.unscaledTime < nextRefresh))
			{
				nextRefresh = Time.unscaledTime + 0.1f;
				RefreshClock();
			}
		}

		private void RefreshClock()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)EnvMan.instance == (Object)null)
			{
				clockAvailable = false;
				return;
			}
			float dayFraction = Mathf.Repeat(EnvMan.instance.GetDayFraction(), 1f);
			bool isDay = EnvMan.IsDay();
			displayText = ClockFormatter.Format(dayFraction, settings.Format, settings.ShowPeriodLabel.Value, isDay);
			clockAvailable = true;
		}

		private void OnGUI()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			if (settings.Enabled.Value && clockAvailable && !string.IsNullOrEmpty(displayText))
			{
				EnsureStyles();
				Vector2 val = textStyle.CalcSize(new GUIContent(displayText));
				float width = Mathf.Max(val.x + 16f, (float)settings.FontSize.Value * 4.5f);
				float height = Mathf.Max(val.y + 8f, (float)settings.FontSize.Value + 8f);
				Rect screenRect = GetScreenRect(width, height);
				int depth = GUI.depth;
				GUI.depth = -1000;
				if (settings.EnableShadow.Value && settings.ShadowOffset.Value > 0)
				{
					GUI.Label(new Rect(((Rect)(ref screenRect)).x + (float)settings.ShadowOffset.Value, ((Rect)(ref screenRect)).y + (float)settings.ShadowOffset.Value, ((Rect)(ref screenRect)).width, ((Rect)(ref screenRect)).height), displayText, shadowStyle);
				}
				GUI.Label(screenRect, displayText, textStyle);
				GUI.depth = depth;
			}
		}

		private void EnsureStyles()
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			string text = string.Join("|", settings.FontSize.Value, settings.TextColor.Value, settings.ShadowColor.Value, settings.FontWeight.Value);
			if (textStyle == null || shadowStyle == null || !(text == styleKey))
			{
				styleKey = text;
				textStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = Mathf.Clamp(settings.FontSize.Value, 10, 96),
					alignment = GetTextAnchor(settings.HorizontalAlignment.Value),
					richText = false,
					wordWrap = false,
					clipping = (TextClipping)1,
					fontStyle = GetFontStyle(settings.FontWeight.Value)
				};
				textStyle.normal.textColor = SettingsColor.Parse(settings.TextColor.Value, Color.white);
				shadowStyle = new GUIStyle(textStyle);
				shadowStyle.normal.textColor = SettingsColor.Parse(settings.ShadowColor.Value, Color.black);
			}
		}

		private Rect GetScreenRect(float width, float height)
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			int value = settings.HorizontalOffset.Value;
			int value2 = settings.VerticalOffset.Value;
			string text = settings.HorizontalAlignment.Value.ToLowerInvariant();
			float num = ((text == "left") ? ((float)value) : ((!(text == "right")) ? (((float)Screen.width - width) * 0.5f + (float)value) : ((float)Screen.width - width - (float)value)));
			float num2 = num;
			text = settings.VerticalAlignment.Value.ToLowerInvariant();
			num = ((text == "bottom") ? ((float)Screen.height - height - (float)value2) : ((!(text == "center")) ? ((float)value2) : (((float)Screen.height - height) * 0.5f + (float)value2)));
			float num3 = num;
			return new Rect(num2, num3, width, height);
		}

		private static TextAnchor GetTextAnchor(string horizontalAlignment)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			string text = horizontalAlignment.ToLowerInvariant();
			if (!(text == "left"))
			{
				if (text == "right")
				{
					return (TextAnchor)5;
				}
				return (TextAnchor)4;
			}
			return (TextAnchor)3;
		}

		private static FontStyle GetFontStyle(string fontWeight)
		{
			if (fontWeight.Equals("bold", StringComparison.OrdinalIgnoreCase))
			{
				return (FontStyle)1;
			}
			return (FontStyle)0;
		}
	}
	public sealed class RuneClockSettings
	{
		public readonly ConfigEntry<bool> Enabled;

		public readonly ConfigEntry<string> TimeFormat;

		public readonly ConfigEntry<bool> ShowPeriodLabel;

		public readonly ConfigEntry<string> HorizontalAlignment;

		public readonly ConfigEntry<string> VerticalAlignment;

		public readonly ConfigEntry<int> HorizontalOffset;

		public readonly ConfigEntry<int> VerticalOffset;

		public readonly ConfigEntry<int> FontSize;

		public readonly ConfigEntry<string> FontWeight;

		public readonly ConfigEntry<string> TextColor;

		public readonly ConfigEntry<bool> EnableShadow;

		public readonly ConfigEntry<string> ShadowColor;

		public readonly ConfigEntry<int> ShadowOffset;

		public TimeFormatMode Format
		{
			get
			{
				if (!TimeFormat.Value.Equals("24Hour", StringComparison.OrdinalIgnoreCase))
				{
					return TimeFormatMode.TwelveHour;
				}
				return TimeFormatMode.TwentyFourHour;
			}
		}

		public RuneClockSettings(ConfigFile config)
		{
			Enabled = config.Bind<bool>("General", "Enabled", true, "Show the clock overlay while playing.");
			TimeFormat = config.Bind<string>("General", "TimeFormat", "12Hour", "Display format. Use 12Hour for 00:00AM / PM or 24Hour for 00:00 Day / Night.");
			ShowPeriodLabel = config.Bind<bool>("General", "ShowPeriodLabel", true, "Append Day or Night when using 24Hour format.");
			HorizontalAlignment = config.Bind<string>("Position", "HorizontalAlignment", "Center", "Horizontal anchor: Left, Center, or Right.");
			VerticalAlignment = config.Bind<string>("Position", "VerticalAlignment", "Top", "Vertical anchor: Top, Center, or Bottom.");
			HorizontalOffset = config.Bind<int>("Position", "HorizontalOffset", 0, "Horizontal offset in pixels. Center moves right with positive values; Right moves left.");
			VerticalOffset = config.Bind<int>("Position", "VerticalOffset", 22, "Vertical offset in pixels. Top moves down with positive values; Bottom moves up.");
			FontSize = config.Bind<int>("Appearance", "FontSize", 28, "Clock font size in pixels.");
			FontWeight = config.Bind<string>("Appearance", "FontWeight", "Bold", "Font weight: Normal or Bold.");
			TextColor = config.Bind<string>("Appearance", "TextColor", "F6D589", "Clock text color as RRGGBB or RRGGBBAA.");
			EnableShadow = config.Bind<bool>("Appearance", "EnableShadow", true, "Draw a dark shadow behind the clock for readability.");
			ShadowColor = config.Bind<string>("Appearance", "ShadowColor", "10151C", "Shadow color as RRGGBB or RRGGBBAA.");
			ShadowOffset = config.Bind<int>("Appearance", "ShadowOffset", 2, "Shadow offset in pixels.");
		}
	}
	public enum TimeFormatMode
	{
		TwelveHour,
		TwentyFourHour
	}
	internal static class SettingsColor
	{
		public static Color Parse(string value, Color fallback)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			if (string.IsNullOrWhiteSpace(value))
			{
				return fallback;
			}
			string text = value.Trim();
			if (!text.StartsWith("#", StringComparison.Ordinal))
			{
				text = "#" + text;
			}
			Color result = default(Color);
			if (!ColorUtility.TryParseHtmlString(text, ref result))
			{
				return fallback;
			}
			return result;
		}
	}
}