using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Newtonsoft.Json;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("crashout_crew_mod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("crashout_crew_mod")]
[assembly: AssemblyTitle("crashout_crew_mod")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SpeedrunMod;
[BepInPlugin("com.sialala.speedrun", "Speedrun Mod", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.sialala.speedrun";
public const string PLUGIN_NAME = "Speedrun Mod";
public const string PLUGIN_VERSION = "1.0.0";
}
public static bool IsTimerRunning = false;
public static float ElapsedTime = 0f;
public static TextMeshProUGUI TimerText;
public static TextMeshProUGUI DeltaText;
private static GameObject UiCanvasObject;
public static string CurrentLevelName = "UnknownLevel";
public static List<float> CurrentSplits = new List<float>();
public static int CurrentSplitIndex = 0;
public static bool HasFinishedSplit = false;
public static List<float> LoadedPBSplits = new List<float>();
public static List<float> LoadedBestSegments = new List<float>();
public static ConfigEntry<bool> ConfigEnableTimer;
public static ConfigEntry<bool> ConfigEnableDelta;
public static ConfigEntry<bool> ConfigEnableQuickReset;
public static ConfigEntry<KeyCode> ConfigQuickResetKey;
public static ConfigEntry<bool> ConfigShowMenuTime;
public static ConfigEntry<string> ConfigTimerColor;
public static ConfigEntry<string> ConfigDeltaColorNegative;
public static ConfigEntry<string> ConfigDeltaColorPositive;
public static ConfigEntry<string> ConfigDeltaColorGold;
public static ConfigEntry<string> ConfigMenuTimeColor;
public static ConfigEntry<int> ConfigTimerFontSize;
public static ConfigEntry<int> ConfigDeltaFontSize;
private void Awake()
{
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Expected O, but got Unknown
ConfigEnableTimer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableTimer", true, "Enables or disables the main speedrun timer.");
ConfigEnableDelta = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableDeltaTimer", true, "Enables or disables live delta comparisons.");
ConfigEnableQuickReset = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableQuickReset", true, "Enables quick reset shortcut.");
ConfigQuickResetKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "QuickResetKey", (KeyCode)290, "The key used for quick reset (returns to lobby or restarts run).");
ConfigShowMenuTime = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMenuTime", true, "Enables or disables displaying mod PB time in the level selection menu.");
ConfigTimerColor = ((BaseUnityPlugin)this).Config.Bind<string>("UI.Colors", "TimerColor", "#FFFFFF", "Hex color code for the main timer.");
ConfigDeltaColorNegative = ((BaseUnityPlugin)this).Config.Bind<string>("UI.Colors", "DeltaColorNegative", "#00FF00", "Hex color code for negative delta (time save).");
ConfigDeltaColorPositive = ((BaseUnityPlugin)this).Config.Bind<string>("UI.Colors", "DeltaColorPositive", "#FF0000", "Hex color code for positive delta (time loss).");
ConfigDeltaColorGold = ((BaseUnityPlugin)this).Config.Bind<string>("UI.Colors", "DeltaColorGold", "#FFD700", "Hex color code for a gold split (best segment).");
ConfigMenuTimeColor = ((BaseUnityPlugin)this).Config.Bind<string>("UI.Colors", "MenuTimeColor", "#9544B7", "Hex color code for the PB time displayed in the level selection menu.");
ConfigTimerFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI.Sizes", "TimerFontSize", 70, "Font size for the main timer.");
ConfigDeltaFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI.Sizes", "DeltaFontSize", 50, "Font size for the live delta timer.");
SceneManager.sceneLoaded += OnSceneLoaded;
Harmony val = new Harmony("com.sialala.speedrun");
val.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Mod Speedrun Mod loaded and Harmony injected");
}
public static string FormatTime(float timeInSeconds)
{
TimeSpan timeSpan = TimeSpan.FromSeconds(timeInSeconds);
return $"{Math.Floor(timeSpan.TotalMinutes):00}:{timeSpan.Seconds:00}:{timeSpan.Milliseconds / 10:00}";
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Expected O, but got Unknown
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Expected O, but got Unknown
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_021b: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
//IL_0243: Expected O, but got Unknown
//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
//IL_031c: Unknown result type (might be due to invalid IL or missing references)
//IL_033c: Unknown result type (might be due to invalid IL or missing references)
ElapsedTime = 0f;
IsTimerRunning = false;
CurrentSplitIndex = 0;
HasFinishedSplit = false;
CurrentSplits.Clear();
LoadedPBSplits.Clear();
LoadedBestSegments.Clear();
if ((Object)(object)UiCanvasObject != (Object)null)
{
if ((Object)(object)TimerText != (Object)null)
{
((TMP_Text)TimerText).text = "00:00:00";
((Component)TimerText).gameObject.SetActive(false);
}
if ((Object)(object)DeltaText != (Object)null)
{
((TMP_Text)DeltaText).text = "";
((Component)DeltaText).gameObject.SetActive(false);
}
return;
}
UiCanvasObject = new GameObject("ModTimerCanvas");
Canvas val = UiCanvasObject.AddComponent<Canvas>();
val.renderMode = (RenderMode)0;
val.sortingOrder = 999;
UiCanvasObject.AddComponent<CanvasScaler>();
UiCanvasObject.AddComponent<GraphicRaycaster>();
UiCanvasObject.AddComponent<TimerUpdater>();
Object.DontDestroyOnLoad((Object)(object)UiCanvasObject);
GameObject val2 = new GameObject("ModTimerText");
val2.transform.SetParent(UiCanvasObject.transform, false);
TimerText = val2.AddComponent<TextMeshProUGUI>();
((TMP_Text)TimerText).text = "00:00:00";
((TMP_Text)TimerText).fontSize = ConfigTimerFontSize.Value;
Color color = default(Color);
ColorUtility.TryParseHtmlString(ConfigTimerColor.Value, ref color);
((Graphic)TimerText).color = color;
((TMP_Text)TimerText).alignment = (TextAlignmentOptions)1025;
((TMP_Text)TimerText).enableWordWrapping = false;
RectTransform component = ((Component)TimerText).GetComponent<RectTransform>();
component.anchorMin = new Vector2(0f, 0f);
component.anchorMax = new Vector2(0f, 0f);
component.pivot = new Vector2(0f, 0f);
component.anchoredPosition = new Vector2(20f, 20f);
component.sizeDelta = new Vector2(500f, (float)(ConfigTimerFontSize.Value + 20));
((Component)TimerText).gameObject.SetActive(false);
GameObject val3 = new GameObject("ModDeltaText");
val3.transform.SetParent(UiCanvasObject.transform, false);
DeltaText = val3.AddComponent<TextMeshProUGUI>();
((TMP_Text)DeltaText).text = "";
((TMP_Text)DeltaText).fontSize = ConfigDeltaFontSize.Value;
((TMP_Text)DeltaText).alignment = (TextAlignmentOptions)1025;
((TMP_Text)DeltaText).enableWordWrapping = false;
RectTransform component2 = ((Component)DeltaText).GetComponent<RectTransform>();
component2.anchorMin = new Vector2(0f, 0f);
component2.anchorMax = new Vector2(0f, 0f);
component2.pivot = new Vector2(0f, 0f);
float num = 20f + (float)ConfigTimerFontSize.Value + 10f;
component2.anchoredPosition = new Vector2(20f, num);
component2.sizeDelta = new Vector2(500f, (float)(ConfigDeltaFontSize.Value + 20));
((Component)DeltaText).gameObject.SetActive(false);
Debug.Log((object)"[SpeedrunMod] Timer UI successfully injected into the scene.");
}
}
public class TimerUpdater : MonoBehaviour
{
private void Update()
{
//IL_0301: Unknown result type (might be due to invalid IL or missing references)
//IL_035b: Unknown result type (might be due to invalid IL or missing references)
//IL_0331: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: 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)
if ((Object)(object)Plugin.TimerText != (Object)null && !Plugin.ConfigEnableTimer.Value)
{
if (((Component)Plugin.TimerText).gameObject.activeSelf)
{
((Component)Plugin.TimerText).gameObject.SetActive(false);
}
if ((Object)(object)Plugin.DeltaText != (Object)null && ((Component)Plugin.DeltaText).gameObject.activeSelf)
{
((Component)Plugin.DeltaText).gameObject.SetActive(false);
}
}
if (Plugin.IsTimerRunning && (Object)(object)Plugin.TimerText != (Object)null)
{
Plugin.ElapsedTime += Time.deltaTime;
((TMP_Text)Plugin.TimerText).text = Plugin.FormatTime(Plugin.ElapsedTime);
if (Plugin.ConfigEnableTimer.Value && Plugin.ConfigEnableDelta.Value)
{
if (!Plugin.HasFinishedSplit && (Object)(object)Plugin.DeltaText != (Object)null && Plugin.LoadedPBSplits != null && Plugin.CurrentSplitIndex < Plugin.LoadedPBSplits.Count)
{
float num = Plugin.LoadedPBSplits[Plugin.CurrentSplitIndex];
float num2 = ((Plugin.LoadedBestSegments.Count > Plugin.CurrentSplitIndex) ? Plugin.LoadedBestSegments[Plugin.CurrentSplitIndex] : float.MaxValue);
float num3 = ((Plugin.CurrentSplitIndex == 0) ? Plugin.ElapsedTime : (Plugin.ElapsedTime - Plugin.CurrentSplits[Plugin.CurrentSplitIndex - 1]));
float value = Plugin.ElapsedTime - num;
if (Plugin.ElapsedTime > num)
{
((TMP_Text)Plugin.DeltaText).text = "+" + Plugin.FormatTime(Math.Abs(value));
Color color = default(Color);
if (ColorUtility.TryParseHtmlString(Plugin.ConfigDeltaColorPositive.Value, ref color))
{
((Graphic)Plugin.DeltaText).color = color;
}
if (!((Component)Plugin.DeltaText).gameObject.activeSelf)
{
((Component)Plugin.DeltaText).gameObject.SetActive(true);
}
}
else if (num3 > num2)
{
((TMP_Text)Plugin.DeltaText).text = "-" + Plugin.FormatTime(Math.Abs(value));
Color color2 = default(Color);
if (ColorUtility.TryParseHtmlString(Plugin.ConfigDeltaColorNegative.Value, ref color2))
{
((Graphic)Plugin.DeltaText).color = color2;
}
if (!((Component)Plugin.DeltaText).gameObject.activeSelf)
{
((Component)Plugin.DeltaText).gameObject.SetActive(true);
}
}
else if (((Component)Plugin.DeltaText).gameObject.activeSelf)
{
((Component)Plugin.DeltaText).gameObject.SetActive(false);
}
}
}
else if ((Object)(object)Plugin.DeltaText != (Object)null && ((Component)Plugin.DeltaText).gameObject.activeSelf)
{
((Component)Plugin.DeltaText).gameObject.SetActive(false);
}
}
if (Plugin.ConfigEnableQuickReset.Value && Input.GetKeyDown(Plugin.ConfigQuickResetKey.Value))
{
if (GameUtil.isLobby)
{
GameManager.NextRun();
Debug.Log((object)$"[SpeedrunMod] Quick start from Lobby ({Plugin.ConfigQuickResetKey.Value})!");
}
else
{
GameManager.Next((GameNextType)1);
Debug.Log((object)$"[SpeedrunMod] Run aborted! Safe return to Lobby ({Plugin.ConfigQuickResetKey.Value}).");
}
}
}
}
public static class SplitsManager
{
public static string SaveFilePath => Path.Combine(Paths.PluginPath, "SpeedrunSplits.json");
public static SplitsSaveFile LoadSplits()
{
if (!File.Exists(SaveFilePath))
{
Debug.Log((object)"[SpeedrunMod] No existing splits file found. Creating a new one.");
return new SplitsSaveFile();
}
try
{
string text = File.ReadAllText(SaveFilePath);
return JsonConvert.DeserializeObject<SplitsSaveFile>(text) ?? new SplitsSaveFile();
}
catch (Exception ex)
{
Debug.LogError((object)("[SpeedrunMod] Error loading splits: " + ex.Message));
return new SplitsSaveFile();
}
}
public static void SaveSplits(SplitsSaveFile data)
{
try
{
string contents = JsonConvert.SerializeObject((object)data, (Formatting)1);
File.WriteAllText(SaveFilePath, contents);
Debug.Log((object)"[SpeedrunMod] Splits saved successfully.");
}
catch (Exception ex)
{
Debug.LogError((object)("[SpeedrunMod] Failed to save splits: " + ex.Message));
}
}
public static void LoadLevelDataIntoMemory(string levelName)
{
Plugin.LoadedPBSplits.Clear();
Plugin.LoadedBestSegments.Clear();
SplitsSaveFile splitsSaveFile = LoadSplits();
SplitRecord splitRecord = splitsSaveFile.records.Find((SplitRecord r) => r.levelName == levelName);
if (splitRecord != null)
{
if (splitRecord.pbSplits != null)
{
Plugin.LoadedPBSplits = new List<float>(splitRecord.pbSplits);
}
if (splitRecord.bestSegments != null)
{
Plugin.LoadedBestSegments = new List<float>(splitRecord.bestSegments);
}
}
if (splitRecord != null)
{
Debug.Log((object)("[SpeedrunMod] Loaded PB data for " + levelName + ". Total time to beat: " + Plugin.FormatTime(splitRecord.totalTime)));
}
else
{
Debug.Log((object)("[SpeedrunMod] No previous PB found for " + levelName + ". This is a new run!"));
}
}
public static void ProcessAndSaveRun(string levelName, List<float> runSplits, bool isRunCompleted)
{
if (runSplits.Count == 0 || string.IsNullOrEmpty(levelName) || levelName == "UnknownLevel")
{
return;
}
SplitsSaveFile splitsSaveFile = LoadSplits();
SplitRecord splitRecord = splitsSaveFile.records.Find((SplitRecord r) => r.levelName == levelName);
bool flag = false;
if (splitRecord == null)
{
splitRecord = new SplitRecord
{
levelName = levelName,
totalTime = float.MaxValue
};
splitsSaveFile.records.Add(splitRecord);
flag = true;
}
if (splitRecord.bestSegments == null)
{
splitRecord.bestSegments = new List<float>();
}
if (splitRecord.pbSplits == null)
{
splitRecord.pbSplits = new List<float>();
}
for (int num = 0; num < runSplits.Count; num++)
{
float num2 = runSplits[num];
if (num > 0)
{
num2 -= runSplits[num - 1];
}
if (splitRecord.bestSegments.Count <= num)
{
splitRecord.bestSegments.Add(num2);
flag = true;
}
else if (num2 < splitRecord.bestSegments[num])
{
splitRecord.bestSegments[num] = num2;
flag = true;
Debug.Log((object)$"[SpeedrunMod] GOLD SPLIT! Shift {num + 1} completed in {num2:F2}s");
}
}
if (isRunCompleted)
{
float num3 = runSplits[runSplits.Count - 1];
if (num3 < splitRecord.totalTime)
{
splitRecord.totalTime = num3;
splitRecord.pbSplits = new List<float>(runSplits);
flag = true;
Debug.Log((object)$"[SpeedrunMod] NEW PB! Total time: {num3:F2}s");
}
}
if (flag)
{
SaveSplits(splitsSaveFile);
}
}
}
[HarmonyPatch(typeof(ShiftManager))]
public class ShiftManagerPatches
{
[HarmonyPatch("ShiftChanged")]
[HarmonyPostfix]
public static void Postfix_ShiftChanged(ShiftPhase phase, int shift, int outboundsRequired)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Invalid comparison between Unknown and I4
if ((Object)(object)Plugin.TimerText != (Object)null && !((Component)Plugin.TimerText).gameObject.activeSelf && Plugin.ConfigEnableTimer.Value)
{
((Component)Plugin.TimerText).gameObject.SetActive(true);
}
if ((int)phase == 3)
{
Plugin.HasFinishedSplit = false;
if ((Object)(object)Plugin.DeltaText != (Object)null)
{
((Component)Plugin.DeltaText).gameObject.SetActive(false);
}
if (shift == 1 && !Plugin.IsTimerRunning && Plugin.ElapsedTime < 0.1f && (Object)(object)GameUtil.contract != (Object)null)
{
Plugin.CurrentLevelName = ((Object)GameUtil.contract).name;
SplitsManager.LoadLevelDataIntoMemory(Plugin.CurrentLevelName);
Debug.Log((object)("[SpeedrunMod] Started: " + Plugin.CurrentLevelName));
}
Plugin.IsTimerRunning = true;
}
else
{
Plugin.IsTimerRunning = false;
}
}
private static void RecordSplit(byte shiftCount, bool isRunCompleted)
{
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
Debug.Log((object)$"[SpeedrunMod] Shift {shiftCount} completed at {Plugin.FormatTime(Plugin.ElapsedTime)}");
Plugin.IsTimerRunning = false;
int count = Plugin.CurrentSplits.Count;
Plugin.CurrentSplits.Add(Plugin.ElapsedTime);
if (Plugin.ConfigEnableTimer.Value && Plugin.ConfigEnableDelta.Value && Plugin.LoadedPBSplits != null && count < Plugin.LoadedPBSplits.Count)
{
float num = Plugin.LoadedPBSplits[count];
float num2 = Plugin.ElapsedTime - num;
float num3 = ((count == 0) ? Plugin.ElapsedTime : (Plugin.ElapsedTime - Plugin.CurrentSplits[count - 1]));
bool flag = false;
if (Plugin.LoadedBestSegments != null && count < Plugin.LoadedBestSegments.Count && num3 < Plugin.LoadedBestSegments[count])
{
flag = true;
}
string text = ((num2 > 0f) ? "+" : "-");
((TMP_Text)Plugin.DeltaText).text = text + Plugin.FormatTime(Math.Abs(num2));
Color color3 = default(Color);
if (flag)
{
Color color = default(Color);
if (ColorUtility.TryParseHtmlString(Plugin.ConfigDeltaColorGold.Value, ref color))
{
((Graphic)Plugin.DeltaText).color = color;
}
}
else if (num2 <= 0f)
{
Color color2 = default(Color);
if (ColorUtility.TryParseHtmlString(Plugin.ConfigDeltaColorNegative.Value, ref color2))
{
((Graphic)Plugin.DeltaText).color = color2;
}
}
else if (ColorUtility.TryParseHtmlString(Plugin.ConfigDeltaColorPositive.Value, ref color3))
{
((Graphic)Plugin.DeltaText).color = color3;
}
((Component)Plugin.DeltaText).gameObject.SetActive(true);
Plugin.HasFinishedSplit = true;
}
else if ((Object)(object)Plugin.DeltaText != (Object)null)
{
((Component)Plugin.DeltaText).gameObject.SetActive(false);
}
Plugin.CurrentSplitIndex = Plugin.CurrentSplits.Count;
SplitsManager.ProcessAndSaveRun(Plugin.CurrentLevelName, Plugin.CurrentSplits, isRunCompleted);
}
[HarmonyPatch("UserCode_RpcTransitionShiftToShiftWon__Byte__ContractScore__Vector3")]
[HarmonyPostfix]
public static void StopTimer_ShiftWon(byte shiftCount)
{
RecordSplit(shiftCount, isRunCompleted: false);
}
[HarmonyPatch("UserCode_RpcTransitionShiftToShiftWonPhase1__Byte__ContractScore__Vector3")]
[HarmonyPostfix]
public static void StopTimer_ShiftWonPhase1(byte shiftCount)
{
RecordSplit(shiftCount, isRunCompleted: false);
}
[HarmonyPatch("UserCode_RpcTransitionShiftToGameWon__Byte__ContractScore__ContractScore__Int32__Vector3__PlayerResult[]")]
[HarmonyPostfix]
public static void StopTimer_GameWon(byte shiftCount)
{
RecordSplit(shiftCount, isRunCompleted: true);
}
[HarmonyPatch("UserCode_RpcTransitionShiftToGameLost__Byte__Int32__Vector3__PlayerResult[]")]
[HarmonyPostfix]
public static void StopTimer_GameLost(byte shiftCount)
{
Plugin.IsTimerRunning = false;
Debug.Log((object)"[SpeedrunMod] Run lost! Timer stopped. Splits ignored.");
}
}
[HarmonyPatch(typeof(ContractSelectionUI))]
public class ContractSelectionUIPatches
{
[HarmonyPatch("SetUp")]
[HarmonyPostfix]
public static void Postfix_SetUp(ContractSelectionUI __instance)
{
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Invalid comparison between Unknown and I4
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Expected O, but got Unknown
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Invalid comparison between Unknown and I4
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.ConfigShowMenuTime.Value)
{
return;
}
SplitsSaveFile splitsSaveFile = SplitsManager.LoadSplits();
for (int i = 0; i < __instance._contracts.Count; i++)
{
ContractObject contract = __instance._contracts[i];
if (i >= __instance.contractGroup.childCount)
{
continue;
}
ContractUI component = ((Component)__instance.contractGroup.GetChild(i)).GetComponent<ContractUI>();
if (!((Object)(object)component != (Object)null))
{
continue;
}
SplitRecord splitRecord = splitsSaveFile.records.Find((SplitRecord r) => r.levelName == ((Object)contract).name);
if (splitRecord == null || !(splitRecord.totalTime < float.MaxValue))
{
continue;
}
string text = Plugin.FormatTime(splitRecord.totalTime);
Transform val = (((int)contract.type != 1) ? ((TMP_Text)component.bestTimeText).transform.parent : ((Component)component).transform);
Transform val2 = val.Find("ModSpeedrunText");
TextMeshProUGUI val5;
if ((Object)(object)val2 == (Object)null)
{
GameObject val3 = new GameObject("ModSpeedrunText");
val3.transform.SetParent(val, false);
RectTransform val4 = val3.AddComponent<RectTransform>();
val5 = val3.AddComponent<TextMeshProUGUI>();
RectTransform component2 = ((Component)component.bestTimeText).GetComponent<RectTransform>();
val4.anchorMin = component2.anchorMin;
val4.anchorMax = component2.anchorMax;
val4.pivot = component2.pivot;
val4.sizeDelta = new Vector2(component2.sizeDelta.x * 1.5f, 150f);
if ((int)contract.type == 1)
{
val4.anchoredPosition = component2.anchoredPosition + new Vector2(95f, -350f);
}
else
{
val4.anchoredPosition = component2.anchoredPosition + new Vector2(65f, -110f);
}
((TMP_Text)val5).font = ((TMP_Text)component.bestTimeText).font;
((TMP_Text)val5).fontSize = 60f;
((TMP_Text)val5).alignment = (TextAlignmentOptions)257;
((TMP_Text)val5).enableAutoSizing = false;
((TMP_Text)val5).overflowMode = (TextOverflowModes)0;
}
else
{
val5 = ((Component)val2).GetComponent<TextMeshProUGUI>();
}
((TMP_Text)val5).text = "<color=" + Plugin.ConfigMenuTimeColor.Value + "><b>" + text + "</b></color>";
}
}
}
[Serializable]
public class SplitRecord
{
public string levelName;
public float totalTime;
public List<float> pbSplits = new List<float>();
public List<float> bestSegments = new List<float>();
}
[Serializable]
public class SplitsSaveFile
{
public List<SplitRecord> records = new List<SplitRecord>();
}