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 CommandQueueSaveLoad v1.0.0
BepInEx/plugins/CommandQueueSaveLoad.dll
Decompiled 16 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CommandQueue; using Microsoft.CodeAnalysis; using On.RoR2.UI; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.UI; using SimpleJSON; using UnityEngine; using UnityEngine.Events; 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("CommandQueueSaveLoad")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+bacd851801530791c3e8d43de4e7f52c0009337e")] [assembly: AssemblyProduct("CommandQueueSaveLoad")] [assembly: AssemblyTitle("CommandQueueSaveLoad")] [assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially or fully created with the assistance of Generative AI (e.g., Code Suggestions, Refactoring, Documentation Generation).")] [assembly: AssemblyMetadata("AI_Model_Vendor", "DeepSeek")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [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 TeamTayne.CommandQueueSaveLoad { [BepInPlugin("TeamTayne.CommandQueueSaveLoad", "CommandQueueSaveLoad", "1.0.0")] [BepInDependency("com.kuberoot.commandqueue", "1.7.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class CommandQueueSaveLoadPlugin : BaseUnityPlugin { internal const string PluginGuid = "TeamTayne.CommandQueueSaveLoad"; internal const string PluginName = "CommandQueueSaveLoad"; internal const string PluginVersion = "1.0.0"; internal const string CommandQueueGuid = "com.kuberoot.commandqueue"; private void Awake() { Log.Init(((BaseUnityPlugin)this).Logger); ConfigState.Initialize(((BaseUnityPlugin)this).Config); SaveLoadController.Install(); ScoreboardQueueButtons.Install(); RiskOfOptionsIntegration.TryRegister(); Log.Info("CommandQueueSaveLoad 1.0.0 is ready; saved queues live in " + SaveLoadController.QueueFilePath); } private void OnDestroy() { ScoreboardQueueButtons.Uninstall(); SaveLoadController.Uninstall(); } } internal static class ConfigState { private const string GeneralSection = "General"; internal static ConfigEntry<bool> AutoLoadOnRunStart { get; private set; } internal static bool AutoLoadEnabled { get { if (AutoLoadOnRunStart != null) { return AutoLoadOnRunStart.Value; } return false; } } internal static void Initialize(ConfigFile config) { AutoLoadOnRunStart = config.Bind<bool>("General", "AutoLoadOnRunStart", true, "true: the saved queue for your survivor is applied when a run starts.\nfalse: nothing is loaded automatically; use the open button on the Command Queue tab or cq_queues_load."); } } internal static class ConsoleCommands { [ConCommand(/*Could not decode attribute arguments.*/)] private static void SaveQueue(ConCommandArgs args) { SaveLoadController.SaveNow(); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void LoadQueue(ConCommandArgs args) { SaveLoadController.LoadNow(); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void ClearQueues(ConCommandArgs args) { SaveLoadController.ClearSaved(); } } internal static class Log { private static ManualLogSource _source; internal static void Init(ManualLogSource source) { _source = source; } internal static void Info(object message) { ManualLogSource source = _source; if (source != null) { source.LogInfo(message); } } internal static void Warning(object message) { ManualLogSource source = _source; if (source != null) { source.LogWarning(message); } } internal static void Error(object message) { ManualLogSource source = _source; if (source != null) { source.LogError(message); } } } internal readonly struct SavedQueueEntry { internal string Item { get; } internal int Count { get; } internal SavedQueueEntry(string item, int count) { Item = item; Count = count; } } internal static class QueueStore { internal const int Version = 1; internal const int MaxCount = 999; internal static Dictionary<string, List<SavedQueueEntry>> Read(string path, out string error) { error = null; Dictionary<string, List<SavedQueueEntry>> dictionary = new Dictionary<string, List<SavedQueueEntry>>(StringComparer.OrdinalIgnoreCase); if (!File.Exists(path)) { return dictionary; } string json; try { json = File.ReadAllText(path); } catch (IOException ex) { error = ex.Message; return dictionary; } try { ParseInto(json, dictionary); } catch (Exception ex2) { error = ex2.Message; dictionary.Clear(); Quarantine(path); } return dictionary; } internal static void Write(string path, Dictionary<string, List<SavedQueueEntry>> queues, Func<string, string> describe) { string directoryName = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } string text = path + ".tmp"; File.WriteAllText(text, Serialize(queues, describe)); if (File.Exists(path)) { File.Replace(text, path, null); } else { File.Move(text, path); } } internal static string Serialize(Dictionary<string, List<SavedQueueEntry>> queues, Func<string, string> describe) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown JSONObject val = new JSONObject { ["version"] = JSONNode.op_Implicit(1) }; JSONArray val2 = new JSONArray(); foreach (string item in OrderedKeys(queues)) { JSONArray val3 = new JSONArray(); foreach (SavedQueueEntry item2 in queues[item]) { ((JSONNode)val3).Add((JSONNode)new JSONObject { ["item"] = JSONNode.op_Implicit(item2.Item), ["count"] = JSONNode.op_Implicit(item2.Count) }); } JSONObject val4 = new JSONObject { ["survivor"] = JSONNode.op_Implicit(item), ["items"] = (JSONNode)(object)val3 }; string text = Describe(describe, item); if (!string.IsNullOrEmpty(text)) { ((JSONNode)val4)["name"] = JSONNode.op_Implicit(text); } ((JSONNode)val2).Add((JSONNode)(object)val4); } ((JSONNode)val)["queues"] = (JSONNode)(object)val2; return ((JSONNode)val).ToString(2); } internal static Dictionary<string, List<SavedQueueEntry>> Parse(string json) { Dictionary<string, List<SavedQueueEntry>> dictionary = new Dictionary<string, List<SavedQueueEntry>>(StringComparer.OrdinalIgnoreCase); ParseInto(json, dictionary); return dictionary; } internal static void ParseInto(string json, Dictionary<string, List<SavedQueueEntry>> queues) { JSONNode val = JSON.Parse(json); if (val == (object)null || !val.IsObject) { throw new InvalidDataException("root is not an object"); } JSONNode val2 = val["queues"]; if (val2 == (object)null || !val2.IsArray) { throw new InvalidDataException("no queues array"); } foreach (JSONNode child in val2.Children) { if (child == (object)null || !child.IsObject) { continue; } JSONNode val3 = child["survivor"]; string text = ((val3 != (object)null && val3.IsString) ? val3.Value.Trim() : null); if (string.IsNullOrEmpty(text)) { continue; } if (!queues.TryGetValue(text, out var value)) { value = (queues[text] = new List<SavedQueueEntry>()); } JSONNode val4 = child["items"]; if (val4 == (object)null || !val4.IsArray) { continue; } foreach (JSONNode child2 in val4.Children) { if (!(child2 == (object)null) && child2.IsObject) { JSONNode val5 = child2["item"]; if (!(val5 == (object)null) && val5.IsString) { Add(value, val5.Value.Trim(), child2["count"].AsInt); } } } } } internal static bool TryGetSection(Dictionary<string, List<SavedQueueEntry>> queues, string key, out List<SavedQueueEntry> entries) { entries = null; if (key != null) { return queues.TryGetValue(key, out entries); } return false; } internal static List<SavedQueueEntry> Section(Dictionary<string, List<SavedQueueEntry>> queues, string key) { if (!TryGetSection(queues, key, out var entries)) { return new List<SavedQueueEntry>(); } return entries; } private static void Add(List<SavedQueueEntry> queue, string item, int count) { if (item.Length == 0 || count <= 0) { return; } if (count > 999) { count = 999; } for (int i = 0; i < queue.Count; i++) { if (string.Equals(queue[i].Item, item, StringComparison.OrdinalIgnoreCase)) { int num = queue[i].Count + count; queue[i] = new SavedQueueEntry(queue[i].Item, (num > 999) ? 999 : num); return; } } queue.Add(new SavedQueueEntry(item, count)); } private static IEnumerable<string> OrderedKeys(Dictionary<string, List<SavedQueueEntry>> queues) { return queues.Keys.OrderBy<string, string>((string key) => key, StringComparer.OrdinalIgnoreCase); } private static string Describe(Func<string, string> describe, string key) { if (describe == null) { return null; } try { return describe(key); } catch (Exception) { return null; } } private static void Quarantine(string path) { try { string text = path + ".invalid"; if (File.Exists(text)) { File.Delete(text); } File.Move(path, text); } catch (IOException) { } } } internal static class RiskOfOptionsIntegration { [CompilerGenerated] private static class <>O { public static UnityAction <0>__ClearSaved; } internal const string PluginGuid = "com.rune580.riskofoptions"; private const string IconResourceName = "TeamTayne.CommandQueueSaveLoad.icon.png"; private const string Category = "Saved Queues"; private const string ModGuid = "TeamTayne.CommandQueueSaveLoad"; private const string ModName = "CommandQueueSaveLoad"; private static bool? _available; internal static bool Available { get { bool valueOrDefault = _available == true; if (!_available.HasValue) { valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); _available = valueOrDefault; } return _available.Value; } } internal static void TryRegister() { if (!Available) { return; } try { Register(); Log.Info("Risk of Options settings registered."); } catch (Exception ex) { Log.Warning("Risk of Options integration failed; the config file and console commands remain available: " + ex.Message); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static void Register() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown ModSettingsManager.SetModDescription("Remembers the queue you save for each survivor and applies it when a run starts.", "TeamTayne.CommandQueueSaveLoad", "CommandQueueSaveLoad"); Sprite val = LoadIcon(); if ((Object)(object)val != (Object)null) { ModSettingsManager.SetModIcon(val, "TeamTayne.CommandQueueSaveLoad", "CommandQueueSaveLoad"); } else { Log.Warning("Risk of Options icon resource was not found or could not be decoded."); } ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ConfigState.AutoLoadOnRunStart, new CheckBoxConfig { name = "Load Saved Queue At Run Start", category = "Saved Queues", description = "Apply the saved queue for your survivor automatically when a run starts." }), "TeamTayne.CommandQueueSaveLoad", "CommandQueueSaveLoad"); object obj = <>O.<0>__ClearSaved; if (obj == null) { UnityAction val2 = SaveLoadController.ClearSaved; <>O.<0>__ClearSaved = val2; obj = (object)val2; } ModSettingsManager.AddOption((BaseOption)new GenericButtonOption("Clear Saved Queues", "Saved Queues", "Deletes every saved queue from disk. Save, open, and reset happen in a run, from CommandQueue's button row.", "Clear", (UnityAction)obj), "TeamTayne.CommandQueueSaveLoad", "CommandQueueSaveLoad"); } private static Sprite LoadIcon() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("TeamTayne.CommandQueueSaveLoad.icon.png"); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), true)) { Object.Destroy((Object)(object)val); return null; } ((Object)val).name = "CommandQueueSaveLoadIcon"; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } } internal static class SaveLoadController { private const string QueueFileName = "CommandQueueSaveLoad.queues.json"; private static string _survivorKey; private static bool _loadedThisRun; private static bool _installed; internal static string QueueFilePath => Path.Combine(Paths.ConfigPath, "CommandQueueSaveLoad.queues.json"); internal static void Install() { if (_installed) { return; } try { Run.onRunStartGlobal += OnRunStart; CharacterBody.onBodyStartGlobal += OnBodyStart; _installed = true; } catch (Exception arg) { Log.Error($"could not install game hooks; queue saving and loading is unavailable: {arg}"); } } internal static void Uninstall() { if (_installed) { try { Run.onRunStartGlobal -= OnRunStart; CharacterBody.onBodyStartGlobal -= OnBodyStart; } catch (Exception ex) { Log.Warning("could not remove game hooks during shutdown: " + ex.Message); } _installed = false; } } internal static void SaveNow() { if (!TryGetSurvivorKey("save", out var key)) { return; } try { List<SavedQueueEntry> list = SnapshotLiveQueue(); Dictionary<string, List<SavedQueueEntry>> dictionary = ReadFile(); dictionary[key] = list; QueueStore.Write(QueueFilePath, dictionary, DescribeSurvivor); Notify("CommandQueue: saved " + DescribeItemCount(list) + " for " + DescribeSurvivor(key) + "."); } catch (Exception arg) { Log.Error($"saving the queue failed: {arg}"); Notify("CommandQueue: saving the queue failed, see the log for details."); } } internal static void LoadNow() { if (!TryGetSurvivorKey("load", out var key)) { return; } try { ApplySaved(key, automatic: false); } catch (Exception arg) { Log.Error($"loading the saved queue failed: {arg}"); Notify("CommandQueue: loading the saved queue failed, see the log for details."); } } internal static void ResetNow() { if (!TryGetSurvivorKey("reset", out var _)) { return; } try { if (!TryClearLiveQueue(out var _)) { Notify("CommandQueue: cannot reset, CommandQueue is not ready."); } else { Notify("CommandQueue: reset the current queue; saved queue unchanged."); } } catch (Exception arg) { Log.Error($"resetting the queue failed: {arg}"); Notify("CommandQueue: resetting the queue failed, see the log for details."); } } internal static void ClearSaved() { try { if (!File.Exists(QueueFilePath)) { Notify("CommandQueue: there are no saved queues to clear."); return; } File.Delete(QueueFilePath); Log.Info("deleted " + QueueFilePath); Notify("CommandQueue: saved queues cleared."); } catch (Exception arg) { Log.Error($"clearing saved queues failed: {arg}"); Notify("CommandQueue: clearing saved queues failed, see the log for details."); } } private static void OnRunStart(Run run) { _loadedThisRun = false; _survivorKey = null; } private static void OnBodyStart(CharacterBody body) { try { if ((Object)(object)body == (Object)null || (Object)(object)Run.instance == (Object)null || !IsLocalPlayerBody(body)) { return; } string text = SurvivorKeyFor(body); if (text != null) { _survivorKey = text; if (!_loadedThisRun && ConfigState.AutoLoadEnabled) { _loadedThisRun = true; ApplySaved(text, automatic: true); } } } catch (Exception arg) { Log.Error($"applying the saved queue at run start failed: {arg}"); } } private static void ApplySaved(string key, bool automatic) { if (!QueueStore.TryGetSection(ReadFile(), key, out var entries)) { if (!automatic) { Notify("CommandQueue: no saved queue for " + DescribeSurvivor(key) + "."); } } else { int num = Apply(entries); Notify($"CommandQueue: loaded {DescribeItemCount(entries)} ({num} queued) " + "from the saved queue for " + DescribeSurvivor(key) + "."); } } private static int Apply(List<SavedQueueEntry> entries) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!TryClearLiveQueue(out var _)) { return 0; } int num = 0; foreach (SavedQueueEntry entry in entries) { if (TryResolvePickup(entry.Item, out var pickupIndex)) { for (int i = 0; i < entry.Count; i++) { QueueManager.Enqueue(pickupIndex); num++; } } } return num; } private static bool TryClearLiveQueue(out int removed) { //IL_002b: 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_0040: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) removed = 0; Dictionary<ItemTier, List<QueueEntry>> mainQueues = QueueManager.mainQueues; if (mainQueues == null) { Log.Error("CommandQueue queues are unavailable, so the live queue cannot be reset."); return false; } ItemTier[] array = mainQueues.Keys.ToArray(); foreach (ItemTier val in array) { if (mainQueues.TryGetValue(val, out var value) && value != null) { while (value.Count > 0) { QueueEntry val2 = value[0]; QueueManager.Remove(val, 0, val2.count); removed += val2.count; } } } return true; } private static List<SavedQueueEntry> SnapshotLiveQueue() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Invalid comparison between Unknown and I4 //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) List<SavedQueueEntry> list = new List<SavedQueueEntry>(); Dictionary<ItemTier, List<QueueEntry>> mainQueues = QueueManager.mainQueues; if (mainQueues == null) { return list; } foreach (KeyValuePair<ItemTier, List<QueueEntry>> item in mainQueues) { if (item.Value == null) { continue; } foreach (QueueEntry item2 in item.Value) { PickupDef pickupDef = PickupCatalog.GetPickupDef(item2.pickupIndex); if (pickupDef != null && (int)pickupDef.itemIndex != -1) { ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex); if (!((Object)(object)itemDef == (Object)null) && !string.IsNullOrEmpty(((Object)itemDef).name)) { list.Add(new SavedQueueEntry(((Object)itemDef).name, item2.count)); } } } } return list; } private static bool TryResolvePickup(string itemName, out PickupIndex pickupIndex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) pickupIndex = PickupIndex.none; if (string.IsNullOrEmpty(itemName)) { return false; } ItemIndex val = ItemCatalog.FindItemIndex(itemName); if ((int)val == -1) { return false; } ItemDef itemDef = ItemCatalog.GetItemDef(val); if ((Object)(object)itemDef == (Object)null) { return false; } Dictionary<ItemTier, List<QueueEntry>> mainQueues = QueueManager.mainQueues; if (mainQueues == null || !mainQueues.ContainsKey(itemDef.tier)) { return false; } pickupIndex = PickupCatalog.FindPickupIndex(val); return ((PickupIndex)(ref pickupIndex)).isValid; } private static bool TryGetSurvivorKey(string action, out string key) { key = null; if ((Object)(object)Run.instance == (Object)null) { Notify("CommandQueue: cannot " + action + ", start a run first."); return false; } if (QueueManager.mainQueues == null) { Notify("CommandQueue: cannot " + action + ", CommandQueue is not ready."); return false; } key = _survivorKey; if (key == null) { Notify("CommandQueue: cannot " + action + ", your survivor is not known yet."); return false; } return true; } private static Dictionary<string, List<SavedQueueEntry>> ReadFile() { string error; Dictionary<string, List<SavedQueueEntry>> result = QueueStore.Read(QueueFilePath, out error); if (error != null) { Log.Warning("could not read " + QueueFilePath + " (" + error + "); it was moved aside and an empty set is used."); } return result; } private static bool IsLocalPlayerBody(CharacterBody body) { CharacterMaster master = body.master; if ((Object)(object)master == (Object)null) { return false; } PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController; if ((Object)(object)playerCharacterMasterController != (Object)null && (Object)(object)playerCharacterMasterController.networkUser != (Object)null && playerCharacterMasterController.networkUser.localUser != null) { return true; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); if (firstLocalUser != null) { if (!((Object)(object)firstLocalUser.cachedMaster == (Object)(object)master)) { return (Object)(object)firstLocalUser.cachedBody == (Object)(object)body; } return true; } return false; } private static string SurvivorKeyFor(CharacterBody body) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) BodyIndex bodyIndex = body.bodyIndex; if ((int)bodyIndex == -1) { return null; } string bodyName = BodyCatalog.GetBodyName(bodyIndex); if (!string.IsNullOrEmpty(bodyName)) { return bodyName; } return null; } private static string DescribeSurvivor(string key) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(key)) { return "unknown survivor"; } try { BodyIndex val = BodyCatalog.FindBodyIndex(key); if ((int)val != -1) { SurvivorDef survivorDef = SurvivorCatalog.GetSurvivorDef(SurvivorCatalog.GetSurvivorIndexFromBodyIndex(val)); string text = (((Object)(object)survivorDef != (Object)null) ? survivorDef.displayNameToken : null); if (!string.IsNullOrEmpty(text) && !Language.IsTokenInvalid(text)) { string text2 = Language.GetString(text); if (!string.IsNullOrEmpty(text2)) { return text2; } } } } catch (Exception ex) { Log.Warning("could not resolve a display name for " + key + ": " + ex.Message); } return key; } private static string DescribeItemCount(List<SavedQueueEntry> items) { int num = items.Sum((SavedQueueEntry entry) => entry.Count); return string.Format("{0} item{1}", num, (num == 1) ? string.Empty : "s"); } private static void Notify(string message) { Log.Info(message); if ((Object)(object)Run.instance != (Object)null) { Chat.AddMessage(message); } } } internal sealed class ScoreboardQueueButtons : MonoBehaviour { private sealed class QueueButton { internal RectTransform Rect; internal int Slot; } [CompilerGenerated] private static class <>O { public static hook_Awake <0>__ScoreboardAwake; public static UnityAction <1>__SaveNow; public static UnityAction <2>__LoadNow; public static UnityAction <3>__ResetNow; } private const string SaveIconResource = "TeamTayne.CommandQueueSaveLoad.save.png"; private const string OpenIconResource = "TeamTayne.CommandQueueSaveLoad.open.png"; private const string ResetIconResource = "TeamTayne.CommandQueueSaveLoad.reset.png"; private const string QueueContainerName = "CommandQueueContainer"; private const string LoopGlyphMarker = "RepeatButtonImageHolder"; private const float IconInset = 7f; private const float ButtonGap = 5f; private static readonly Dictionary<string, Texture2D> Icons = new Dictionary<string, Texture2D>(StringComparer.Ordinal); private static bool _installAttempted; private RectTransform _scoreboard; private RectTransform _queueContainer; private RectTransform _loopButton; private readonly List<QueueButton> _buttons = new List<QueueButton>(); private bool _warnedNoLoopButton; internal static void Install() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (_installAttempted) { return; } try { object obj = <>O.<0>__ScoreboardAwake; if (obj == null) { hook_Awake val = ScoreboardAwake; <>O.<0>__ScoreboardAwake = val; obj = (object)val; } ScoreboardController.Awake += (hook_Awake)obj; HUD[] array = Object.FindObjectsOfType<HUD>(); foreach (HUD val2 in array) { if ((Object)(object)val2 != (Object)null) { Attach(val2.scoreboardPanel); } } _installAttempted = true; } catch (Exception arg) { Log.Error($"could not hook the scoreboard, so the in-game queue buttons are unavailable: {arg}"); } } internal static void Uninstall() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (!_installAttempted) { return; } try { object obj = <>O.<0>__ScoreboardAwake; if (obj == null) { hook_Awake val = ScoreboardAwake; <>O.<0>__ScoreboardAwake = val; obj = (object)val; } ScoreboardController.Awake -= (hook_Awake)obj; } catch (Exception ex) { Log.Warning("could not remove the scoreboard hook during shutdown: " + ex.Message); } _installAttempted = false; } private static void ScoreboardAwake(orig_Awake orig, ScoreboardController self) { orig.Invoke(self); try { Attach(((Component)self).gameObject); } catch (Exception arg) { Log.Error($"could not add the in-game queue buttons: {arg}"); } } private static void Attach(GameObject scoreboardPanel) { if (!((Object)(object)scoreboardPanel == (Object)null) && !((Object)(object)scoreboardPanel.GetComponent<ScoreboardQueueButtons>() != (Object)null)) { scoreboardPanel.AddComponent<ScoreboardQueueButtons>(); } } private void Awake() { ref RectTransform scoreboard = ref _scoreboard; Transform transform = ((Component)this).transform; scoreboard = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)_scoreboard == (Object)null) { Object.Destroy((Object)(object)this); } } private void OnDestroy() { ClearButtons(); } private void LateUpdate() { RectTransform val = ResolveLoopButton(); if ((Object)(object)val == (Object)null) { SetButtonsActive(active: false); return; } try { SyncButtons(val); SetButtonsActive(active: true); } catch (Exception arg) { Log.Error($"could not place the saved-queue buttons on the scoreboard: {arg}"); SetButtonsActive(active: false); } } private RectTransform ResolveLoopButton() { if ((Object)(object)_queueContainer == (Object)null) { ref RectTransform queueContainer = ref _queueContainer; Transform obj = FindDescendant((Transform)(object)_scoreboard, "CommandQueueContainer"); queueContainer = (RectTransform)(object)((obj is RectTransform) ? obj : null); } if ((Object)(object)_queueContainer == (Object)null || !((Component)_queueContainer).gameObject.activeInHierarchy) { _loopButton = null; return null; } if ((Object)(object)_loopButton != (Object)null && ((Component)_loopButton).gameObject.activeInHierarchy) { return _loopButton; } _loopButton = FindLoopButton(); if ((Object)(object)_loopButton == (Object)null && !_warnedNoLoopButton) { _warnedNoLoopButton = true; Log.Warning("CommandQueue's loop button was not found on the scoreboard, so the saved-queue buttons stay hidden. They expect the CommandQueue 1.7.0 layout."); } return _loopButton; } private RectTransform FindLoopButton() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown foreach (Transform item in (Transform)_queueContainer) { Transform val = item; if (((Component)val).gameObject.activeInHierarchy) { Transform val2 = FindDescendant(val, "RepeatButtonImageHolder"); if ((Object)(object)val2 != (Object)null) { Transform parent = val2.parent; return (RectTransform)(object)((parent is RectTransform) ? parent : null); } } } return null; } private void SyncButtons(RectTransform loopButton) { //IL_00a0: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) Transform parent = ((Transform)loopButton).parent; if (NeedsRebuild()) { ClearButtons(); object obj = <>O.<1>__SaveNow; if (obj == null) { UnityAction val = SaveLoadController.SaveNow; <>O.<1>__SaveNow = val; obj = (object)val; } CreateButton(loopButton, "CommandQueueSaveButton", "TeamTayne.CommandQueueSaveLoad.save.png", 3, (UnityAction)obj); object obj2 = <>O.<2>__LoadNow; if (obj2 == null) { UnityAction val2 = SaveLoadController.LoadNow; <>O.<2>__LoadNow = val2; obj2 = (object)val2; } CreateButton(loopButton, "CommandQueueOpenButton", "TeamTayne.CommandQueueSaveLoad.open.png", 2, (UnityAction)obj2); object obj3 = <>O.<3>__ResetNow; if (obj3 == null) { UnityAction val3 = SaveLoadController.ResetNow; <>O.<3>__ResetNow = val3; obj3 = (object)val3; } CreateButton(loopButton, "CommandQueueResetButton", "TeamTayne.CommandQueueSaveLoad.reset.png", 1, (UnityAction)obj3); } float num = loopButton.sizeDelta.x + 5f; foreach (QueueButton button in _buttons) { RectTransform rect = button.Rect; if ((Object)(object)((Transform)rect).parent != (Object)(object)parent) { ((Transform)rect).SetParent(parent, false); } if (rect.anchorMin != loopButton.anchorMin) { rect.anchorMin = loopButton.anchorMin; } if (rect.anchorMax != loopButton.anchorMax) { rect.anchorMax = loopButton.anchorMax; } if (rect.pivot != loopButton.pivot) { rect.pivot = loopButton.pivot; } if (rect.sizeDelta != loopButton.sizeDelta) { rect.sizeDelta = loopButton.sizeDelta; } Vector2 anchoredPosition = loopButton.anchoredPosition; anchoredPosition.x -= num * (float)button.Slot; if (rect.anchoredPosition != anchoredPosition) { rect.anchoredPosition = anchoredPosition; } } } private bool NeedsRebuild() { if (_buttons.Count == 0) { return true; } foreach (QueueButton button in _buttons) { if ((Object)(object)button.Rect == (Object)null) { return true; } } return false; } private void SetButtonsActive(bool active) { foreach (QueueButton button in _buttons) { if ((Object)(object)button.Rect != (Object)null && ((Component)button.Rect).gameObject.activeSelf != active) { ((Component)button.Rect).gameObject.SetActive(active); } } } private void ClearButtons() { foreach (QueueButton button in _buttons) { if ((Object)(object)button.Rect != (Object)null) { Object.Destroy((Object)(object)((Component)button.Rect).gameObject); } } _buttons.Clear(); } private void CreateButton(RectTransform loopButton, string name, string iconResource, int slot, UnityAction action) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = Icon(iconResource); if ((Object)(object)val == (Object)null) { return; } GameObject val2 = Object.Instantiate<GameObject>(((Component)loopButton).gameObject, ((Transform)loopButton).parent); ((Object)val2).name = name; RectTransform val3 = (RectTransform)val2.transform; HGButton component = val2.GetComponent<HGButton>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); Log.Warning("CommandQueue loop button " + ((Object)loopButton).name + " has no HGButton component."); return; } ((MPButton)component).onSelect = new UnityEvent(); ((MPButton)component).onDeselect = new UnityEvent(); ((Button)component).onClick = new ButtonClickedEvent(); ((UnityEvent)((Button)component).onClick).AddListener(action); Transform val4 = FindDescendant((Transform)(object)val3, "RepeatButtonImageHolder"); GameObject val5 = new GameObject("Icon", new Type[1] { typeof(RectTransform) }); RectTransform val6 = (RectTransform)val5.transform; ((Transform)val6).SetParent((Transform)(object)val3, false); RectTransform val7 = (RectTransform)(object)((val4 is RectTransform) ? val4 : null); if (val7 != null) { val6.anchorMin = val7.anchorMin; val6.anchorMax = val7.anchorMax; val6.anchoredPosition = val7.anchoredPosition; val6.sizeDelta = val7.sizeDelta; val6.pivot = val7.pivot; ((Object)val4).name = "RemovedLoopGlyph"; ((Component)val4).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)val4).gameObject); } else { val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.offsetMin = new Vector2(7f, 7f); val6.offsetMax = new Vector2(-7f, -7f); } RawImage obj = val5.AddComponent<RawImage>(); obj.texture = (Texture)(object)val; ((Graphic)obj).raycastTarget = false; _buttons.Add(new QueueButton { Rect = val3, Slot = slot }); } private static Transform FindDescendant(Transform root, string name) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown foreach (Transform item in root) { Transform val = item; if (((Object)val).name.IndexOf(name, StringComparison.Ordinal) >= 0) { return val; } Transform val2 = FindDescendant(val, name); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } private static Texture2D Icon(string resourceName) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown if (Icons.TryGetValue(resourceName, out var value)) { return value; } try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { Log.Warning("queue button icon " + resourceName + " was not found in the assembly"); return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), true)) { Object.Destroy((Object)(object)val); Log.Warning("queue button icon " + resourceName + " could not be decoded"); return null; } ((Object)val).name = Path.GetFileNameWithoutExtension(resourceName); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)2; Icons[resourceName] = val; return val; } catch (Exception arg) { Log.Error($"loading queue button icon {resourceName} failed: {arg}"); return null; } } } }