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 REPOSimpleTimer v1.0.1
REPOSimpleTimer.dll
Decompiled 2 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [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("REPOSimpleTimer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Shows the elapsed time since the level started on the R.E.P.O. HUD.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("REPO Simple Timer")] [assembly: AssemblyTitle("REPOSimpleTimer")] [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 REPOSimpleTimer { internal class LevelTimer : MonoBehaviour { private static readonly Vector2 LabelSize = new Vector2(400f, 48f); private int currentDirectorId; private float elapsed; private bool levelStarted; private bool hiddenByUser; private TextMeshProUGUI label; private bool layoutDirty = true; private string lastText; private void OnEnable() { ((BaseUnityPlugin)Plugin.Instance).Config.SettingChanged += OnSettingChanged; } private void OnDisable() { ((BaseUnityPlugin)Plugin.Instance).Config.SettingChanged -= OnSettingChanged; } private void OnSettingChanged(object sender, EventArgs e) { layoutDirty = true; } private void Update() { TimerSettings settings = Plugin.Settings; Tick(); HandleToggleKey(settings); if (!ShouldShow(settings)) { if ((Object)(object)label != (Object)null) { ((Behaviour)label).enabled = false; } } else if (EnsureLabel()) { if (layoutDirty) { ApplyLayout(settings); layoutDirty = false; } ((Behaviour)label).enabled = true; string text = settings.Prefix.Value + FormatElapsed(elapsed, settings.Format.Value); if (text != lastText) { ((TMP_Text)label).text = text; lastText = text; } } } private void Tick() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 GameDirector instance = GameDirector.instance; if ((Object)(object)instance == (Object)null) { currentDirectorId = 0; levelStarted = false; elapsed = 0f; return; } int instanceID = ((Object)instance).GetInstanceID(); if (instanceID != currentDirectorId) { currentDirectorId = instanceID; levelStarted = false; elapsed = 0f; } if ((int)instance.currentState == 2) { levelStarted = true; elapsed += Time.deltaTime; } } private void HandleToggleKey(TimerSettings settings) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = settings.ToggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !((Object)(object)RunManager.instance == (Object)null) && !SemiFunc.MenuLevel() && SemiFunc.NoTextInputsActive()) { hiddenByUser = !hiddenByUser; } } private bool ShouldShow(TimerSettings settings) { if (!settings.Enabled.Value || hiddenByUser || !levelStarted) { return false; } if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)RunManager.instance.levelCurrent == (Object)null || SemiFunc.MenuLevel()) { return false; } if ((Object)(object)HUD.instance != (Object)null && HUD.instance.hidden) { return false; } if (!settings.ShowOutsideLevels.Value && !SemiFunc.RunIsLevel() && !SemiFunc.RunIsArena()) { return false; } return true; } private bool EnsureLabel() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown if ((Object)(object)label != (Object)null) { return true; } HUDCanvas instance = HUDCanvas.instance; if ((Object)(object)instance == (Object)null) { return false; } TextMeshProUGUI componentInChildren = ((Component)instance).GetComponentInChildren<TextMeshProUGUI>(true); GameObject val = new GameObject("REPOSimpleTimer Label", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)instance).transform, false); label = val.AddComponent<TextMeshProUGUI>(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)label).font = ((TMP_Text)componentInChildren).font; ((TMP_Text)label).fontSharedMaterial = ((TMP_Text)componentInChildren).fontSharedMaterial; } ((TMP_Text)label).enableWordWrapping = false; ((TMP_Text)label).overflowMode = (TextOverflowModes)0; ((Graphic)label).raycastTarget = false; ((TMP_Text)label).richText = true; layoutDirty = true; lastText = null; return true; } private void ApplyLayout(TimerSettings settings) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) Vector2 val = AnchorToVector(settings.Anchor.Value); RectTransform rectTransform = ((TMP_Text)label).rectTransform; rectTransform.anchorMin = val; rectTransform.anchorMax = val; rectTransform.pivot = val; rectTransform.sizeDelta = LabelSize; ((Transform)rectTransform).localScale = Vector3.one; rectTransform.anchoredPosition = new Vector2(settings.OffsetX.Value, settings.OffsetY.Value); ((TMP_Text)label).fontSize = settings.FontSize.Value; ((Graphic)label).color = settings.ResolveColor(); ((TMP_Text)label).alignment = AnchorToAlignment(settings.Anchor.Value); } private static Vector2 AnchorToVector(ScreenAnchor anchor) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) return (Vector2)(anchor switch { ScreenAnchor.TopLeft => new Vector2(0f, 1f), ScreenAnchor.TopCenter => new Vector2(0.5f, 1f), ScreenAnchor.TopRight => new Vector2(1f, 1f), ScreenAnchor.MiddleLeft => new Vector2(0f, 0.5f), ScreenAnchor.MiddleRight => new Vector2(1f, 0.5f), ScreenAnchor.BottomLeft => new Vector2(0f, 0f), ScreenAnchor.BottomCenter => new Vector2(0.5f, 0f), ScreenAnchor.BottomRight => new Vector2(1f, 0f), _ => new Vector2(0.5f, 1f), }); } private static TextAlignmentOptions AnchorToAlignment(ScreenAnchor anchor) { switch (anchor) { case ScreenAnchor.TopLeft: case ScreenAnchor.MiddleLeft: case ScreenAnchor.BottomLeft: return (TextAlignmentOptions)513; case ScreenAnchor.TopRight: case ScreenAnchor.MiddleRight: case ScreenAnchor.BottomRight: return (TextAlignmentOptions)516; default: return (TextAlignmentOptions)514; } } private static string FormatElapsed(float seconds, TimeFormat format) { if (seconds < 0f) { seconds = 0f; } int num = (int)seconds; int num2 = num / 3600; int num3 = num / 60; int num4 = num % 60; switch (format) { case TimeFormat.MinutesSecondsCentis: { int num5 = (int)((seconds - (float)num) * 100f); return $"{num3:00}:{num4:00}.{num5:00}"; } case TimeFormat.HoursMinutesSeconds: return $"{num2:00}:{num3 % 60:00}:{num4:00}"; default: return $"{num3:00}:{num4:00}"; } } } [BepInPlugin("harukazelab.REPOSimpleTimer", "REPO Simple Timer", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static TimerSettings Settings { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Settings = new TimerSettings(((BaseUnityPlugin)this).Config); ((Component)this).gameObject.AddComponent<LevelTimer>(); Log.LogInfo((object)"REPO Simple Timer 1.0.0 loaded."); } } internal static class PluginInfo { public const string Guid = "harukazelab.REPOSimpleTimer"; public const string Name = "REPO Simple Timer"; public const string Version = "1.0.0"; } internal enum TimeFormat { MinutesSeconds, MinutesSecondsCentis, HoursMinutesSeconds } internal enum ScreenAnchor { TopLeft, TopCenter, TopRight, MiddleLeft, MiddleRight, BottomLeft, BottomCenter, BottomRight } internal class TimerSettings { public readonly ConfigEntry<bool> Enabled; public readonly ConfigEntry<bool> ShowOutsideLevels; public readonly ConfigEntry<KeyboardShortcut> ToggleKey; public readonly ConfigEntry<TimeFormat> Format; public readonly ConfigEntry<string> Prefix; public readonly ConfigEntry<ScreenAnchor> Anchor; public readonly ConfigEntry<float> OffsetX; public readonly ConfigEntry<float> OffsetY; public readonly ConfigEntry<float> FontSize; public readonly ConfigEntry<string> ColorHex; public TimerSettings(ConfigFile config) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown Enabled = config.Bind<bool>("1. General", "Enabled", true, "Show the level timer on the HUD."); ShowOutsideLevels = config.Bind<bool>("1. General", "ShowOutsideLevels", false, "Also show the timer in the truck, the shop and the tutorial. When false the timer only appears in run levels and the arena."); ToggleKey = config.Bind<KeyboardShortcut>("1. General", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Key that toggles the timer on and off while playing. The timer keeps counting while hidden."); Format = config.Bind<TimeFormat>("2. Text", "Format", TimeFormat.MinutesSeconds, "How the elapsed time is written out."); Prefix = config.Bind<string>("2. Text", "Prefix", "", "Text placed in front of the time, e.g. \"TIME \"."); Anchor = config.Bind<ScreenAnchor>("3. Layout", "Anchor", ScreenAnchor.TopCenter, "Corner or edge of the screen the timer is pinned to."); OffsetX = config.Bind<float>("3. Layout", "OffsetX", 0f, new ConfigDescription("Horizontal offset from the anchor, in canvas units. Positive moves right.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-960f, 960f), Array.Empty<object>())); OffsetY = config.Bind<float>("3. Layout", "OffsetY", -30f, new ConfigDescription("Vertical offset from the anchor, in canvas units. Positive moves up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-540f, 540f), Array.Empty<object>())); FontSize = config.Bind<float>("3. Layout", "FontSize", 24f, new ConfigDescription("Font size of the timer text.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 96f), Array.Empty<object>())); ColorHex = config.Bind<string>("3. Layout", "Color", "#FFFFFF", "Timer color as an HTML hex string, e.g. #FFFFFF or #7FFF7FCC."); } public Color ResolveColor() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (ColorUtility.TryParseHtmlString(ColorHex.Value, ref result)) { return result; } return Color.white; } } }