using 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(true); GameObject val = new GameObject("REPOSimpleTimer Label", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)instance).transform, false); label = val.AddComponent(); 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(); 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 Enabled; public readonly ConfigEntry ShowOutsideLevels; public readonly ConfigEntry ToggleKey; public readonly ConfigEntry Format; public readonly ConfigEntry Prefix; public readonly ConfigEntry Anchor; public readonly ConfigEntry OffsetX; public readonly ConfigEntry OffsetY; public readonly ConfigEntry FontSize; public readonly ConfigEntry 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("1. General", "Enabled", true, "Show the level timer on the HUD."); ShowOutsideLevels = config.Bind("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("1. General", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty()), "Key that toggles the timer on and off while playing. The timer keeps counting while hidden."); Format = config.Bind("2. Text", "Format", TimeFormat.MinutesSeconds, "How the elapsed time is written out."); Prefix = config.Bind("2. Text", "Prefix", "", "Text placed in front of the time, e.g. \"TIME \"."); Anchor = config.Bind("3. Layout", "Anchor", ScreenAnchor.TopCenter, "Corner or edge of the screen the timer is pinned to."); OffsetX = config.Bind("3. Layout", "OffsetX", 0f, new ConfigDescription("Horizontal offset from the anchor, in canvas units. Positive moves right.", (AcceptableValueBase)(object)new AcceptableValueRange(-960f, 960f), Array.Empty())); OffsetY = config.Bind("3. Layout", "OffsetY", -30f, new ConfigDescription("Vertical offset from the anchor, in canvas units. Positive moves up.", (AcceptableValueBase)(object)new AcceptableValueRange(-540f, 540f), Array.Empty())); FontSize = config.Bind("3. Layout", "FontSize", 24f, new ConfigDescription("Font size of the timer text.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 96f), Array.Empty())); ColorHex = config.Bind("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; } } }