Decompiled source of CookBook v1.2.10
CookBook.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CookBook; using HG; using Microsoft.CodeAnalysis; using On.RoR2; using On.RoR2.UI; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.ContentManagement; using RoR2.Items; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.TextCore; 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("CookBook")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+237d6957d0f956ad03bba299394a18093e053517")] [assembly: AssemblyProduct("CookBook")] [assembly: AssemblyTitle("CookBook")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } internal static class RecipeFilter { public enum RecipeFilterCategory { All, Damage, Healing, Utility } public static RecipeFilterCategory CurrentCategory = RecipeFilterCategory.All; private static readonly Dictionary<RecipeFilterCategory, ItemTag> CategoryToTag = new Dictionary<RecipeFilterCategory, ItemTag> { { RecipeFilterCategory.Damage, (ItemTag)1 }, { RecipeFilterCategory.Healing, (ItemTag)2 }, { RecipeFilterCategory.Utility, (ItemTag)3 } }; public static void ApplyFiltersToUI(List<CraftUI.RecipeRowUI> rows, string searchTerm) { if (rows == null) { return; } string text = searchTerm?.Trim().ToLowerInvariant(); foreach (CraftUI.RecipeRowUI row in rows) { if (!((Object)(object)row.RowGO == (Object)null)) { bool flag = string.IsNullOrEmpty(text) || EntryMatchesSearch(row.Entry, text); bool flag2 = EntryMatchesFilter(row.Entry); row.RowGO.SetActive(flag && flag2); } } } public static void CycleCategory() { int num = (int)(CurrentCategory + 1); if (num > 3) { num = 0; } CurrentCategory = (RecipeFilterCategory)num; } public static string GetLabel() { return CurrentCategory switch { RecipeFilterCategory.Damage => "<size=150%><sprite name=\"icon\"></size> DMG", RecipeFilterCategory.Healing => "<size=150%><sprite name=\"icon\"></size> HEAL", RecipeFilterCategory.Utility => "<size=150%><sprite name=\"icon\"></size> UTIL", _ => "ALL", }; } private static bool EntryMatchesFilter(CraftPlanner.CraftableEntry entry) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (entry == null) { return false; } if (CurrentCategory == RecipeFilterCategory.All) { return true; } int resultIndex = entry.ResultIndex; if (resultIndex < 0) { return false; } if (resultIndex >= ItemCatalog.itemCount) { return true; } ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)resultIndex); if ((Object)(object)itemDef != (Object)null) { return itemDef.ContainsTag(CategoryToTag[CurrentCategory]); } return false; } private static bool EntryMatchesSearch(CraftPlanner.CraftableEntry entry, string term) { if (string.IsNullOrEmpty(term)) { return true; } if (entry == null) { return false; } string entryDisplayName = CraftUI.GetEntryDisplayName(entry); if (!string.IsNullOrEmpty(entryDisplayName)) { return entryDisplayName.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0; } return false; } public static void PatchVanillaNRE(orig_FilterAvailableOptions orig, CraftingController self) { NetworkUIPromptController component = ((Component)self).GetComponent<NetworkUIPromptController>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.currentParticipantMaster == (Object)null)) { orig.Invoke(self); } } } namespace CookBook { internal static class ChatNetworkHandler { [CompilerGenerated] private static class <>O { public static hook_AddMessage_string <0>__OnAddMessage; public static hook_OnProcessed <1>__OnUserChatMessageProcessed; } [CompilerGenerated] private sealed class <CheckAckTimeout>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public NetworkUser target; public int idx; public int qty; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckAckTimeout>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0042: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: { <>1__state = -1; Dictionary<uint, float> pendingAcks = _pendingAcks; NetworkInstanceId netId = ((NetworkBehaviour)target).netId; if (pendingAcks.ContainsKey(((NetworkInstanceId)(ref netId)).Value)) { Dictionary<uint, float> pendingAcks2 = _pendingAcks; netId = ((NetworkBehaviour)target).netId; pendingAcks2.Remove(((NetworkInstanceId)(ref netId)).Value); DebugLog.Trace(_log, "[Net] No ACK from " + target.userName + ". Falling back to raw text."); SendRawTextFallback(target, idx, qty); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string NetPrefix = "CB_NET:"; private static ManualLogSource _log; private static bool _enabled; private static readonly Dictionary<uint, float> _pendingAcks = new Dictionary<uint, float>(); private const float AckTimeout = 2f; internal static event Action<NetworkUser, string, int, int> OnIncomingObjective; internal static void Init(ManualLogSource log) { _log = log; } internal static void Enable() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (!_enabled) { _enabled = true; object obj = <>O.<0>__OnAddMessage; if (obj == null) { hook_AddMessage_string val = OnAddMessage; <>O.<0>__OnAddMessage = val; obj = (object)val; } Chat.AddMessage_string += (hook_AddMessage_string)obj; object obj2 = <>O.<1>__OnUserChatMessageProcessed; if (obj2 == null) { hook_OnProcessed val2 = OnUserChatMessageProcessed; <>O.<1>__OnUserChatMessageProcessed = val2; obj2 = (object)val2; } UserChatMessage.OnProcessed += (hook_OnProcessed)obj2; } } internal static void Disable() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (_enabled) { _enabled = false; object obj = <>O.<0>__OnAddMessage; if (obj == null) { hook_AddMessage_string val = OnAddMessage; <>O.<0>__OnAddMessage = val; obj = (object)val; } Chat.AddMessage_string -= (hook_AddMessage_string)obj; object obj2 = <>O.<1>__OnUserChatMessageProcessed; if (obj2 == null) { hook_OnProcessed val2 = OnUserChatMessageProcessed; <>O.<1>__OnUserChatMessageProcessed = val2; obj2 = (object)val2; } UserChatMessage.OnProcessed -= (hook_OnProcessed)obj2; } } private static void OnUserChatMessageProcessed(orig_OnProcessed orig, UserChatMessage self) { if (self.text == null || !self.text.Contains("CB_NET:")) { orig.Invoke(self); } } public static void SendObjectiveRequest(NetworkUser target, string command, int unifiedIdx, int quantity) { //IL_0042: 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_0058: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) if (_enabled && !((Object)(object)target == (Object)null)) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null); if (Object.op_Implicit((Object)(object)val)) { object[] obj = new object[6] { "CB_NET:", null, null, null, null, null }; NetworkInstanceId netId = ((NetworkBehaviour)val).netId; obj[1] = ((NetworkInstanceId)(ref netId)).Value; netId = ((NetworkBehaviour)target).netId; obj[2] = ((NetworkInstanceId)(ref netId)).Value; obj[3] = command; obj[4] = unifiedIdx; obj[5] = quantity; string text = string.Format("{0}{1}:{2}:{3}:{4}:{5}", obj); DebugLog.Trace(_log, "[Net Out] Sending packet to " + target.userName + ": " + text); Console.instance.SubmitCmd(val, "say \"" + text + "\"", false); Dictionary<uint, float> pendingAcks = _pendingAcks; netId = ((NetworkBehaviour)target).netId; pendingAcks[((NetworkInstanceId)(ref netId)).Value] = Time.time; ((MonoBehaviour)RoR2Application.instance).StopCoroutine("CheckAckTimeout"); ((MonoBehaviour)RoR2Application.instance).StartCoroutine(CheckAckTimeout(target, unifiedIdx, quantity)); } } } [IteratorStateMachine(typeof(<CheckAckTimeout>d__13))] private static IEnumerator CheckAckTimeout(NetworkUser target, int idx, int qty) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckAckTimeout>d__13(0) { target = target, idx = idx, qty = qty }; } private static void SendRawTextFallback(NetworkUser target, int unifiedIdx, int qty) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); if (!Object.op_Implicit((Object)(object)((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null)) || (Object)(object)target == (Object)null) { return; } string text = "Unknown Item"; string text2 = "ffffff"; if (unifiedIdx < ItemCatalog.itemCount) { ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)unifiedIdx); if ((Object)(object)itemDef != (Object)null) { text = Language.currentLanguage.GetLocalizedStringByToken(itemDef.nameToken); ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(itemDef.tier); ColorCatalog.GetColor(itemTierDef.colorIndex); if ((Object)(object)itemTierDef != (Object)null) { text2 = ColorCatalog.GetColorHexString(itemTierDef.colorIndex); } } } else { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(unifiedIdx - ItemCatalog.itemCount)); if ((Object)(object)equipmentDef != (Object)null) { text = Language.currentLanguage.GetLocalizedStringByToken(equipmentDef.nameToken); text2 = ColorCatalog.GetColorHexString(equipmentDef.colorIndex); } } string text3 = $"<color=#d299ff>[CookBook]</color> @{target.userName}, I'm looking for ({qty}) <color=#{text2}>{text}</color>!"; SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "{0}"; val.paramTokens = new string[1] { text3 }; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } private static void SendAck(uint senderID, string originalCmd) { //IL_0028: 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) LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null); object[] obj = new object[4] { "CB_NET:", null, null, null }; NetworkInstanceId netId = ((NetworkBehaviour)val).netId; obj[1] = ((NetworkInstanceId)(ref netId)).Value; obj[2] = senderID; obj[3] = originalCmd; string text = string.Format("{0}{1}:{2}:ACK:{3}:0", obj); Console.instance.SubmitCmd(val, "say \"" + text + "\"", false); } public static void SendGlobalAbort() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (_enabled) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null); if (Object.op_Implicit((Object)(object)val)) { NetworkInstanceId netId = ((NetworkBehaviour)val).netId; string text = string.Format("{0}{1}:0:ABORT:0:0", "CB_NET:", ((NetworkInstanceId)(ref netId)).Value); DebugLog.Trace(_log, "[Net Out] Sending Global Abort: " + text); Console.instance.SubmitCmd(val, "say \"" + text + "\"", false); } } } public static void SendObjectiveSuccess(NetworkUser target, int unifiedIdx) { //IL_0042: 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_0058: 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) if (_enabled && !((Object)(object)target == (Object)null)) { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null); if (Object.op_Implicit((Object)(object)val)) { object[] obj = new object[4] { "CB_NET:", null, null, null }; NetworkInstanceId netId = ((NetworkBehaviour)val).netId; obj[1] = ((NetworkInstanceId)(ref netId)).Value; netId = ((NetworkBehaviour)target).netId; obj[2] = ((NetworkInstanceId)(ref netId)).Value; obj[3] = unifiedIdx; string text = string.Format("{0}{1}:{2}:SUCCESS:{3}:0", obj); DebugLog.Trace(_log, $"[Net Out] Sending Success signal to {target.userName} for item {unifiedIdx}"); Console.instance.SubmitCmd(val, "say \"" + text + "\"", false); } } } private static void OnAddMessage(orig_AddMessage_string orig, string message) { if (_enabled && message.Contains("CB_NET:")) { int num = message.IndexOf("CB_NET:"); ParseAndProcess(message.Substring(num + "CB_NET:".Length)); } else { orig.Invoke(message); } } private static void ParseAndProcess(string data) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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) try { string text = data; int num = data.IndexOf('<'); if (num != -1) { text = data.Substring(0, num); } string[] array = text.Split(':'); if (array.Length < 5 || !uint.TryParse(array[0], out var senderID) || !uint.TryParse(array[1], out var result)) { return; } string text2 = array[2].ToUpper(); LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null); if ((Object)(object)val == (Object)null) { return; } NetworkInstanceId netId; if (text2 == "ACK") { uint num2 = result; netId = ((NetworkBehaviour)val).netId; if (num2 == ((NetworkInstanceId)(ref netId)).Value) { DebugLog.Trace(_log, $"[Net In] ACK received from {senderID}. Request confirmed."); _pendingAcks.Remove(senderID); return; } } if (result != 0) { netId = ((NetworkBehaviour)val).netId; if (((NetworkInstanceId)(ref netId)).Value != result) { return; } } if (text2 != "ACK") { SendAck(senderID, text2); } int result3; int result4; if (text2 == "ABORT") { DebugLog.Trace(_log, $"[Net In] Global Abort received from Sender {senderID}"); ObjectiveTracker.ClearObjectivesFromSender(senderID); } else if (text2 == "SUCCESS") { if (int.TryParse(array[3], out var result2)) { ObjectiveTracker.ClearSpecificRequest(senderID, result2); } } else if (int.TryParse(array[3], out result3) && int.TryParse(array[4], out result4)) { NetworkUser arg = ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)delegate(NetworkUser u) { //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) NetworkInstanceId netId2 = ((NetworkBehaviour)u).netId; return ((NetworkInstanceId)(ref netId2)).Value == senderID; }); ChatNetworkHandler.OnIncomingObjective?.Invoke(arg, text2, result3, result4); } } catch (Exception ex) { _log.LogError((object)("[Net] Parse Error: " + ex.Message)); } } } internal static class CraftingExecutionHandler { [CompilerGenerated] private sealed class <CraftChainRoutine>d__10 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CraftPlanner.RecipeChain chain; public int repeatCount; private CharacterBody <body>5__2; private NetworkUser <localUser>5__3; private Dictionary<int, int> <startCounts>5__4; private Dictionary<int, int> <currentProgress>5__5; private Queue<ChefRecipe> <craftQueue>5__6; private PickupIndex <lastPickup>5__7; private int <lastQty>5__8; private int <totalSteps>5__9; private int <completedSteps>5__10; private CraftPlanner.DroneRequirement[] <>7__wrap10; private int <>7__wrap11; private CraftPlanner.DroneRequirement <req>5__13; private CraftPlanner.TradeRequirement[] <>7__wrap13; private CraftPlanner.TradeRequirement <req>5__15; private ChefRecipe <step>5__16; private string <stepName>5__17; private CraftingController <controller>5__18; private Ingredient[] <>7__wrap18; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CraftChainRoutine>d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <body>5__2 = null; <localUser>5__3 = null; <startCounts>5__4 = null; <currentProgress>5__5 = null; <craftQueue>5__6 = null; <>7__wrap10 = null; <req>5__13 = default(CraftPlanner.DroneRequirement); <>7__wrap13 = null; <req>5__15 = default(CraftPlanner.TradeRequirement); <step>5__16 = null; <stepName>5__17 = null; <controller>5__18 = null; <>7__wrap18 = null; <>1__state = -2; } private bool MoveNext() { //IL_06b2: Unknown result type (might be due to invalid IL or missing references) //IL_06b7: Unknown result type (might be due to invalid IL or missing references) //IL_091a: Unknown result type (might be due to invalid IL or missing references) //IL_0924: Expected O, but got Unknown //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_05d7: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_0974: Unknown result type (might be due to invalid IL or missing references) //IL_0979: Unknown result type (might be due to invalid IL or missing references) //IL_0701: Unknown result type (might be due to invalid IL or missing references) //IL_0706: Unknown result type (might be due to invalid IL or missing references) //IL_08a3: Unknown result type (might be due to invalid IL or missing references) //IL_08a8: Unknown result type (might be due to invalid IL or missing references) //IL_098c: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_0723: Unknown result type (might be due to invalid IL or missing references) //IL_0729: Invalid comparison between Unknown and I4 //IL_08ef: Unknown result type (might be due to invalid IL or missing references) //IL_08f9: Expected O, but got Unknown //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_074e: Unknown result type (might be due to invalid IL or missing references) //IL_063c: Unknown result type (might be due to invalid IL or missing references) //IL_0641: Unknown result type (might be due to invalid IL or missing references) //IL_09c5: Unknown result type (might be due to invalid IL or missing references) //IL_064e: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0687: Unknown result type (might be due to invalid IL or missing references) List<ChefRecipe> list; KeyboardShortcut value; List<PickupIndex> desired; switch (<>1__state) { default: return false; case 0: { <>1__state = -1; CompleteCurrentObjective(); StateController.BatchMode = false; LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); <body>5__2 = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); LocalUser firstLocalUser2 = LocalUserManager.GetFirstLocalUser(); <localUser>5__3 = ((firstLocalUser2 != null) ? firstLocalUser2.currentNetworkUser : null); Dictionary<int, int> dictionary = new Dictionary<int, int>(); if (chain.DroneCostSparse != null) { CraftPlanner.DroneRequirement[] droneCostSparse = chain.DroneCostSparse; for (int j = 0; j < droneCostSparse.Length; j++) { CraftPlanner.DroneRequirement droneRequirement = droneCostSparse[j]; if (!dictionary.ContainsKey(droneRequirement.ScrapIndex)) { dictionary[droneRequirement.ScrapIndex] = 0; } dictionary[droneRequirement.ScrapIndex] += droneRequirement.Count; } } <startCounts>5__4 = new Dictionary<int, int>(); <currentProgress>5__5 = new Dictionary<int, int>(); if (chain.DroneCostSparse != null && chain.DroneCostSparse.Length != 0) { LocalUser firstLocalUser3 = LocalUserManager.GetFirstLocalUser(); <localUser>5__3 = ((firstLocalUser3 != null) ? firstLocalUser3.currentNetworkUser : null); <>7__wrap10 = chain.DroneCostSparse; <>7__wrap11 = 0; goto IL_03a2; } goto IL_03bc; } case 1: <>1__state = -1; goto IL_0388; case 2: <>1__state = -1; ChatNetworkHandler.SendObjectiveSuccess(<req>5__13.Owner, <req>5__13.ScrapIndex); goto IL_0388; case 3: <>1__state = -1; ChatNetworkHandler.SendObjectiveSuccess(<req>5__15.Donor, <req>5__15.UnifiedIndex); <req>5__15 = default(CraftPlanner.TradeRequirement); <>7__wrap11++; goto IL_04f5; case 4: <>1__state = -1; CompleteCurrentObjective(); <lastPickup>5__7 = PickupIndex.none; goto IL_06bc; case 5: <>1__state = -1; goto IL_076d; case 6: <>1__state = -1; goto IL_07bd; case 7: <>1__state = -1; if ((Object)(object)<controller>5__18 != (Object)null && <controller>5__18.AllSlotsFilled() && IngredientsMatchMultiset(<controller>5__18.ingredients, ResolveStepIngredients(<step>5__16))) { DebugLog.Trace(_log, "[Execution] " + <stepName>5__17 + " verified. Confirming craft..."); <craftQueue>5__6.Dequeue(); <completedSteps>5__10++; <lastQty>5__8 = <step>5__16.ResultCount; <lastPickup>5__7 = GetPickupIndex(<step>5__16); NetworkUIPromptController component = ((Component)<controller>5__18).GetComponent<NetworkUIPromptController>(); if (!Object.op_Implicit((Object)(object)component) || (Object)(object)component.currentParticipantMaster == (Object)null) { _log.LogWarning((object)"[Execution] Not confirming: participant master is null."); return false; } <controller>5__18.ConfirmSelection(); <>2__current = (object)new WaitForEndOfFrame(); <>1__state = 8; return true; } if (Object.op_Implicit((Object)(object)StateController.ActiveCraftingController)) { CraftUI.CloseCraftPanel(StateController.ActiveCraftingController); } <step>5__16 = null; <stepName>5__17 = null; <controller>5__18 = null; goto IL_0962; case 8: <>1__state = -1; CraftUI.CloseCraftPanel(<controller>5__18); <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 9; return true; case 9: <>1__state = -1; goto IL_0962; case 10: { <>1__state = -1; CompleteCurrentObjective(); break; } IL_06bc: if (<step>5__16.Ingredients != null) { <>7__wrap18 = <step>5__16.Ingredients; <>7__wrap11 = 0; goto IL_077b; } goto IL_0795; IL_050f: <craftQueue>5__6 = new Queue<ChefRecipe>(); list = chain.Steps.Where((ChefRecipe s) => !(s is CraftPlanner.TradeRecipe)).ToList(); for (int i = 0; i < repeatCount; i++) { foreach (ChefRecipe item in list) { <craftQueue>5__6.Enqueue(item); } } <lastPickup>5__7 = PickupIndex.none; <lastQty>5__8 = 0; <totalSteps>5__9 = <craftQueue>5__6.Count; <completedSteps>5__10 = 0; StateController.BatchMode = true; goto IL_0962; IL_03a2: if (<>7__wrap11 < <>7__wrap10.Length) { <req>5__13 = <>7__wrap10[<>7__wrap11]; if (!<startCounts>5__4.ContainsKey(<req>5__13.ScrapIndex)) { PickupIndex pickupIndexFromUnified = GetPickupIndexFromUnified(<req>5__13.ScrapIndex); <startCounts>5__4[<req>5__13.ScrapIndex] = GetOwnedCount(PickupCatalog.GetPickupDef(pickupIndexFromUnified), <body>5__2); <currentProgress>5__5[<req>5__13.ScrapIndex] = 0; } <currentProgress>5__5[<req>5__13.ScrapIndex] += <req>5__13.Count; int inventoryGoal = <startCounts>5__4[<req>5__13.ScrapIndex] + <currentProgress>5__5[<req>5__13.ScrapIndex]; string droneName = GetDroneName(<req>5__13.DroneIdx); if ((Object)(object)<req>5__13.Owner == (Object)null || (Object)(object)<req>5__13.Owner == (Object)(object)<localUser>5__3) { <>2__current = HandleAcquisition(GetPickupIndexFromUnified(<req>5__13.ScrapIndex), inventoryGoal, "Scrap " + droneName + " for"); <>1__state = 1; return true; } ChatNetworkHandler.SendObjectiveRequest(<req>5__13.Owner, "SCRAP", <req>5__13.ScrapIndex, <req>5__13.Count); string text = <req>5__13.Owner?.userName ?? "Teammate"; <>2__current = HandleAcquisition(GetPickupIndexFromUnified(<req>5__13.ScrapIndex), inventoryGoal, "Wait for " + text + " to scrap " + droneName + " for"); <>1__state = 2; return true; } <>7__wrap10 = null; goto IL_03bc; IL_04f5: if (<>7__wrap11 < <>7__wrap13.Length) { <req>5__15 = <>7__wrap13[<>7__wrap11]; PickupIndex pickupIndexFromUnified2 = GetPickupIndexFromUnified(<req>5__15.UnifiedIndex); int inventoryGoal2 = GetOwnedCount(PickupCatalog.GetPickupDef(pickupIndexFromUnified2), <body>5__2) + <req>5__15.Count; ChatNetworkHandler.SendObjectiveRequest(<req>5__15.Donor, "TRADE", <req>5__15.UnifiedIndex, <req>5__15.Count); string text2 = <req>5__15.Donor?.userName ?? "Ally"; <>2__current = HandleAcquisition(pickupIndexFromUnified2, inventoryGoal2, "Wait for " + text2 + " to trade"); <>1__state = 3; return true; } <>7__wrap13 = null; goto IL_050f; IL_077b: if (<>7__wrap11 < <>7__wrap18.Length) { Ingredient ingredient = <>7__wrap18[<>7__wrap11]; value = CookBook.AbortKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { Abort(); return false; } if (!ingredient.IsItem && (int)ingredient.EquipIndex != -1) { SetObjectiveText("Preparing " + <stepName>5__17 + "..."); <>2__current = EnsureEquipmentIsActive(<body>5__2, ingredient.EquipIndex); <>1__state = 5; return true; } goto IL_076d; } <>7__wrap18 = null; goto IL_0795; IL_03bc: if (chain.AlliedTradeSparse != null && chain.AlliedTradeSparse.Length != 0) { <>7__wrap13 = chain.AlliedTradeSparse; <>7__wrap11 = 0; goto IL_04f5; } goto IL_050f; IL_076d: <>7__wrap11++; goto IL_077b; IL_0795: if ((Object)(object)StateController.ActiveCraftingController == (Object)null) { <>2__current = EnsureCraftingControllerOpen(); <>1__state = 6; return true; } goto IL_07bd; IL_0388: <req>5__13 = default(CraftPlanner.DroneRequirement); <>7__wrap11++; goto IL_03a2; IL_07bd: <controller>5__18 = StateController.ActiveCraftingController; if (!Object.op_Implicit((Object)(object)<controller>5__18)) { Cleanup(closeUi: true); return false; } desired = ResolveStepIngredients(<step>5__16); <>2__current = SubmitIngredientsClientSafe(<controller>5__18, desired); <>1__state = 7; return true; IL_0962: if (<craftQueue>5__6.Count > 0) { value = CookBook.AbortKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { Abort(); return false; } LocalUser firstLocalUser4 = LocalUserManager.GetFirstLocalUser(); <body>5__2 = ((firstLocalUser4 != null) ? firstLocalUser4.cachedBody : null); if (!Object.op_Implicit((Object)(object)<body>5__2)) { Abort(); return false; } <step>5__16 = <craftQueue>5__6.Peek(); <stepName>5__17 = GetStepName(<step>5__16); if (<lastPickup>5__7 != PickupIndex.none) { SetObjectiveText("Collect " + Language.GetString(PickupCatalog.GetPickupDef(<lastPickup>5__7)?.nameToken ?? "Result")); <>2__current = WaitForPendingPickup(<lastPickup>5__7, <lastQty>5__8); <>1__state = 4; return true; } goto IL_06bc; } if (<lastPickup>5__7 != PickupIndex.none) { StateController.BatchMode = false; SetObjectiveText("Collect " + Language.GetString(PickupCatalog.GetPickupDef(<lastPickup>5__7)?.nameToken ?? "Result")); <>2__current = WaitForPendingPickup(<lastPickup>5__7, <lastQty>5__8); <>1__state = 10; return true; } break; } DebugLog.Trace(_log, $"[ExecutionHandler] Finished {<completedSteps>5__10}/{<totalSteps>5__9} steps."); Cleanup(closeUi: true); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <EnsureCraftingControllerOpen>d__12 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private float <t>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnsureCraftingControllerOpen>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <t>5__2 = 0f; break; case 1: <>1__state = -1; break; } if (!IsCraftingSessionReady(StateController.ActiveCraftingController)) { KeyboardShortcut value = CookBook.AbortKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { Abort(); return false; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); Interactor val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<Interactor>() : null); if (!Object.op_Implicit((Object)(object)StateController.TargetCraftingObject) && Object.op_Implicit((Object)(object)val)) { StateController.TargetCraftingObject = TryResolveChefStationObject(val); } if (!Object.op_Implicit((Object)(object)StateController.TargetCraftingObject) || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2)) { _log.LogWarning((object)"[Execution] Lost target/body/interactor while trying to open crafting UI. Aborting."); Abort(); return false; } SetObjectiveText("Approach Wandering CHEF"); float num = val2.maxInteractionDistance + 6f; Vector3 val3 = val.corePosition - StateController.TargetCraftingObject.transform.position; if (((Vector3)(ref val3)).sqrMagnitude <= num * num) { val2.AttemptInteraction(StateController.TargetCraftingObject); } <t>5__2 += Time.unscaledDeltaTime; if (<t>5__2 >= 12f) { _log.LogWarning((object)"[Execution] Timed out opening crafting UI."); Cleanup(closeUi: true); return false; } <>2__current = (object)new WaitForSecondsRealtime(0.2f); <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <EnsureEquipmentIsActive>d__23 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CharacterBody body; public EquipmentIndex target; private Inventory <inv>5__2; private int <targetSlot>5__3; private int <targetSet>5__4; private GenericSkill <skill>5__5; private float <timeout>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnsureEquipmentIsActive>d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <inv>5__2 = null; <skill>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Expected O, but got Unknown //IL_026a: 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_00a3: Unknown result type (might be due to invalid IL or missing references) int num; int equipmentSetCount2; int num2; switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <inv>5__2 = body.inventory; if (!Object.op_Implicit((Object)(object)<inv>5__2) || (int)target == -1) { return false; } int activeEquipmentSlot = <inv>5__2.activeEquipmentSlot; int equipmentSlotCount = <inv>5__2.GetEquipmentSlotCount(); <targetSlot>5__3 = -1; <targetSet>5__4 = -1; for (int i = 0; i < equipmentSlotCount; i++) { int equipmentSetCount = <inv>5__2.GetEquipmentSetCount((uint)i); for (int j = 0; j < equipmentSetCount; j++) { if (<inv>5__2.GetEquipment((uint)i, (uint)j).equipmentIndex == target) { <targetSlot>5__3 = i; <targetSet>5__4 = j; break; } } if (<targetSlot>5__3 != -1) { break; } } if (<targetSlot>5__3 == -1) { return false; } if (<targetSlot>5__3 != activeEquipmentSlot) { <skill>5__5 = body.skillLocator?.special; if (Object.op_Implicit((Object)(object)<skill>5__5)) { if (Object.op_Implicit((Object)(object)StateController.ActiveCraftingController)) { CraftUI.CloseCraftPanel(StateController.ActiveCraftingController); } goto IL_0158; } goto IL_01ef; } goto IL_01f6; } case 1: <>1__state = -1; goto IL_0158; case 2: <>1__state = -1; goto IL_01cf; case 3: { <>1__state = -1; goto IL_02d9; } IL_02d9: if (<inv>5__2.activeEquipmentSet[<inv>5__2.activeEquipmentSlot] != <targetSet>5__4 && <timeout>5__6 > 0f) { <timeout>5__6 -= 0.1f; <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 3; return true; } break; IL_01cf: if (<inv>5__2.activeEquipmentSlot != <targetSlot>5__3 && <timeout>5__6 > 0f) { <timeout>5__6 -= 0.1f; <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; } goto IL_01ef; IL_01f6: num = <inv>5__2.activeEquipmentSet[<inv>5__2.activeEquipmentSlot]; equipmentSetCount2 = <inv>5__2.GetEquipmentSetCount((uint)<inv>5__2.activeEquipmentSlot); if (<targetSet>5__4 == num) { break; } if (Object.op_Implicit((Object)(object)StateController.ActiveCraftingController)) { CraftUI.CloseCraftPanel(StateController.ActiveCraftingController); } num2 = (<targetSet>5__4 - num + equipmentSetCount2) % equipmentSetCount2; DebugLog.Trace(_log, $"[Execution] Cycling sets ({num2} clicks) for {target}."); for (int k = 0; k < num2; k++) { <inv>5__2.CallCmdSwitchToNextEquipmentInSet(); } <timeout>5__6 = 2f; goto IL_02d9; IL_01ef: <skill>5__5 = null; goto IL_01f6; IL_0158: if (!<skill>5__5.CanExecute()) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } DebugLog.Trace(_log, $"[Execution] Retooling to Slot {<targetSlot>5__3}."); <skill>5__5.ExecuteIfReady(); <timeout>5__6 = 1f; goto IL_01cf; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <HandleAcquisition>d__25 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PickupIndex pi; public int inventoryGoal; public string actionPrefix; private CharacterBody <body>5__2; private PickupDef <def>5__3; private string <itemName>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <HandleAcquisition>d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <body>5__2 = null; <def>5__3 = null; <itemName>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0033: 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) //IL_00bf: Expected O, but got Unknown int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); <body>5__2 = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); <def>5__3 = PickupCatalog.GetPickupDef(pi); if (!Object.op_Implicit((Object)(object)<body>5__2) || <def>5__3 == null) { return false; } <itemName>5__4 = Language.GetString(<def>5__3.nameToken); } int ownedCount = GetOwnedCount(<def>5__3, <body>5__2); int num2 = inventoryGoal - ownedCount; if (num2 > 0) { SetObjectiveText($"{actionPrefix} {<itemName>5__4} <style=cSub>(Need {num2})</style>"); <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } CompleteCurrentObjective(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SubmitIngredientsClientSafe>d__17 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CraftingController controller; public List<PickupIndex> desired; private NetworkUIPromptController <prompt>5__2; private float <t>5__3; private float <clearBudget>5__4; private float <syncBudget>5__5; private int <k>5__6; private PickupIndex <want>5__7; private bool <inserted>5__8; private float <insertBudget>5__9; private int <filledBefore>5__10; private int <wantCountBefore>5__11; private float <progressBudget>5__12; private bool <progressed>5__13; private float <settleBudget>5__14; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SubmitIngredientsClientSafe>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <prompt>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (!Object.op_Implicit((Object)(object)controller) || desired == null) { return false; } <prompt>5__2 = ((Component)controller).GetComponent<NetworkUIPromptController>(); <t>5__3 = 2f; goto IL_0098; case 1: <>1__state = -1; goto IL_0098; case 2: <>1__state = -1; goto IL_023d; case 3: <>1__state = -1; goto IL_05c9; case 4: <>1__state = -1; goto IL_05c9; case 5: <>1__state = -1; <progressBudget>5__12 = 1f; <progressed>5__13 = false; goto IL_04c7; case 6: <>1__state = -1; goto IL_04c7; case 7: <>1__state = -1; goto IL_0583; case 8: { <>1__state = -1; break; } IL_04c7: if (<progressBudget>5__12 > 0f) { if (!Object.op_Implicit((Object)(object)controller)) { return false; } PickupIndex[] ingredients = controller.ingredients; if (CountFilled(ingredients) < <filledBefore>5__10 + 1 || CountOf(ingredients, <want>5__7) <= <wantCountBefore>5__11) { <progressBudget>5__12 -= Time.unscaledDeltaTime; <>2__current = null; <>1__state = 6; return true; } <progressed>5__13 = true; } if (!<progressed>5__13) { DebugLog.Trace(_log, $"[Crafting] No fill-progress observed for {<want>5__7}, retrying..."); <insertBudget>5__9 -= 0.25f; goto IL_05c9; } <settleBudget>5__14 = 0.75f; goto IL_0583; IL_05c9: if (!<inserted>5__8 && <insertBudget>5__9 > 0f) { if (!Object.op_Implicit((Object)(object)controller)) { return false; } if (controller.AllSlotsFilled() && !IngredientsMatchMultiset(controller.ingredients, desired)) { _log.LogWarning((object)"[Crafting] Station became full with wrong ingredients. Aborting insert to avoid accidental confirm."); return false; } Option[] options = ((PickupPickerController)controller).options; if (options == null || options.Length == 0) { <insertBudget>5__9 -= Time.unscaledDeltaTime; <>2__current = null; <>1__state = 3; return true; } if (!TryFindChoiceIndex(controller, <want>5__7, out var choiceIndex) || !IsChoiceIndexStillValid(controller, choiceIndex, <want>5__7)) { <insertBudget>5__9 -= Time.unscaledDeltaTime; <>2__current = null; <>1__state = 4; return true; } Option val = ((PickupPickerController)controller).options[choiceIndex]; DebugLog.Trace(_log, $"[Crafting] Pick want={<want>5__7} choiceIndex={choiceIndex} optPickup={val.pickup.pickupIndex} available={val.available}"); <filledBefore>5__10 = CountFilled(controller.ingredients); <wantCountBefore>5__11 = CountOf(controller.ingredients, <want>5__7); SubmitChoiceToCraftingController(controller, choiceIndex); <>2__current = (object)new WaitForSecondsRealtime(0.1f); <>1__state = 5; return true; } if (!<inserted>5__8) { _log.LogWarning((object)$"[Crafting] Failed to insert ingredient {<k>5__6 + 1}/{desired.Count}: {<want>5__7}"); return false; } <k>5__6++; goto IL_0639; IL_0639: if (<k>5__6 < desired.Count) { if (!Object.op_Implicit((Object)(object)controller)) { return false; } <want>5__7 = desired[<k>5__6]; <inserted>5__8 = false; <insertBudget>5__9 = 2f; goto IL_05c9; } <syncBudget>5__5 = 2f; break; IL_0583: if (<settleBudget>5__14 > 0f) { if (!Object.op_Implicit((Object)(object)controller)) { return false; } if (!IngredientsMatchPrefixMultiset(controller.ingredients, desired, <k>5__6 + 1)) { <settleBudget>5__14 -= Time.unscaledDeltaTime; <>2__current = null; <>1__state = 7; return true; } <inserted>5__8 = true; } if (!<inserted>5__8) { DebugLog.Trace(_log, $"[Crafting] Change observed but state did not settle for {<want>5__7}, retrying..."); <insertBudget>5__9 -= 0.25f; } goto IL_05c9; IL_024d: <k>5__6 = 0; goto IL_0639; IL_023d: if (<clearBudget>5__4 > 0f) { if (!Object.op_Implicit((Object)(object)controller)) { return false; } PickupIndex[] ingredients2 = controller.ingredients; if (ingredients2 != null) { bool flag = false; for (int i = 0; i < ingredients2.Length; i++) { if (ingredients2[i] != PickupIndex.none) { flag = true; break; } } if (!flag) { goto IL_024d; } } <clearBudget>5__4 -= Time.unscaledDeltaTime; <>2__current = null; <>1__state = 2; return true; } goto IL_024d; IL_0098: if (<t>5__3 > 0f && (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)<prompt>5__2) || (Object)(object)<prompt>5__2.currentParticipantMaster == (Object)null)) { <t>5__3 -= Time.unscaledDeltaTime; <>2__current = null; <>1__state = 1; return true; } if (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)<prompt>5__2) || (Object)(object)<prompt>5__2.currentParticipantMaster == (Object)null) { _log.LogError((object)"[Crafting] Participant Master not ready. Station not synced."); return false; } if (desired.Count != controller.ingredientCount) { _log.LogWarning((object)$"[Crafting] Ingredient count mismatch. step needs {desired.Count}, controller has {controller.ingredientCount} slots."); return false; } for (int j = 0; j < controller.ingredientCount; j++) { if (controller.ingredients != null && j < controller.ingredients.Length && controller.ingredients[j] != PickupIndex.none) { controller.ClearSlot(j); } } <clearBudget>5__4 = 1f; goto IL_023d; } if (<syncBudget>5__5 > 0f) { if (!Object.op_Implicit((Object)(object)controller)) { return false; } if (IngredientsMatchMultiset(controller.ingredients, desired)) { return false; } <syncBudget>5__5 -= Time.unscaledDeltaTime; <>2__current = null; <>1__state = 8; return true; } _log.LogWarning((object)"[Crafting] Timed out waiting for ingredient sync."); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WaitForPendingPickup>d__26 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PickupIndex pickupIndex; public int expectedGain; private CharacterBody <body>5__2; private PickupDef <def>5__3; private int <targetCount>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPendingPickup>d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <body>5__2 = null; <def>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); <body>5__2 = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if (!Object.op_Implicit((Object)(object)<body>5__2) || !Object.op_Implicit((Object)(object)<body>5__2.inventory)) { return false; } <def>5__3 = PickupCatalog.GetPickupDef(pickupIndex); if (<def>5__3 == null) { return false; } <targetCount>5__4 = GetOwnedCount(<def>5__3, <body>5__2) + expectedGain; } if (GetOwnedCount(<def>5__3, <body>5__2) >= <targetCount>5__4) { DebugLog.Trace(_log, "[Chain] Confirmed pickup of " + <def>5__3.internalName + "."); return false; } <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static ManualLogSource _log; private static ObjectiveTracker.ObjectiveToken _currentObjective; private static Coroutine _craftingRoutine; private static MonoBehaviour _runner; public static bool IsAutoCrafting => _craftingRoutine != null; internal static void Init(ManualLogSource log, MonoBehaviour runner) { _log = log; _runner = runner; } public static void ExecuteChain(CraftPlanner.RecipeChain chain, int repeatCount) { if (CookBook.isDebugMode) { DumpChain(chain, repeatCount); } Abort(); _craftingRoutine = _runner.StartCoroutine(CraftChainRoutine(chain, repeatCount)); } private static void Cleanup(bool closeUi = false) { _craftingRoutine = null; StateController.BatchMode = false; CompleteCurrentObjective(); if (closeUi && Object.op_Implicit((Object)(object)StateController.ActiveCraftingController)) { CraftUI.CloseCraftPanel(StateController.ActiveCraftingController); } } public static void Abort() { if ((Object)(object)_runner != (Object)null && _craftingRoutine != null) { _runner.StopCoroutine(_craftingRoutine); } Cleanup(closeUi: true); } [IteratorStateMachine(typeof(<CraftChainRoutine>d__10))] private static IEnumerator CraftChainRoutine(CraftPlanner.RecipeChain chain, int repeatCount) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CraftChainRoutine>d__10(0) { chain = chain, repeatCount = repeatCount }; } private static bool IsCraftingSessionReady(CraftingController c) { if (!Object.op_Implicit((Object)(object)c)) { return false; } NetworkUIPromptController component = ((Component)c).GetComponent<NetworkUIPromptController>(); if (!Object.op_Implicit((Object)(object)component)) { return false; } if ((Object)(object)component.currentParticipantMaster == (Object)null) { return false; } if (!component.isDisplaying) { return false; } CraftingPanel[] array = Object.FindObjectsOfType<CraftingPanel>(); for (int i = 0; i < array.Length; i++) { if (Object.op_Implicit((Object)(object)array[i]) && (Object)(object)array[i].craftingController == (Object)(object)c) { return true; } } return false; } [IteratorStateMachine(typeof(<EnsureCraftingControllerOpen>d__12))] private static IEnumerator EnsureCraftingControllerOpen() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnsureCraftingControllerOpen>d__12(0); } private static List<PickupIndex> ResolveStepIngredients(ChefRecipe step) { //IL_0070: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) List<PickupIndex> list = new List<PickupIndex>(step.Ingredients.Sum((Ingredient i) => Mathf.Max(0, i.Count))); Ingredient[] ingredients = step.Ingredients; for (int j = 0; j < ingredients.Length; j++) { Ingredient ingredient = ingredients[j]; int num = Mathf.Max(0, ingredient.Count); if (num != 0) { PickupIndex item = ((!ingredient.IsItem) ? PickupCatalog.FindPickupIndex(ingredient.EquipIndex) : PickupCatalog.FindPickupIndex(ingredient.ItemIndex)); for (int k = 0; k < num; k++) { list.Add(item); } } } return list; } private static bool TryFindChoiceIndex(CraftingController c, PickupIndex desired, out int choiceIndex) { //IL_001f: 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) choiceIndex = -1; Option[] options = ((PickupPickerController)c).options; if (options == null) { return false; } for (int i = 0; i < options.Length; i++) { if (options[i].pickup.pickupIndex == desired) { choiceIndex = i; return true; } } return false; } private static bool IsChoiceIndexStillValid(CraftingController c, int idx, PickupIndex desired) { //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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) Option[] options = ((PickupPickerController)c).options; if (options == null) { return false; } if ((uint)idx >= (uint)options.Length) { return false; } Option val = options[idx]; if (val.available) { return val.pickup.pickupIndex == desired; } return false; } private static void SubmitChoiceToCraftingController(CraftingController c, int choiceIndex) { NetworkUIPromptController component = ((Component)c).GetComponent<NetworkUIPromptController>(); if (Object.op_Implicit((Object)(object)component)) { NetworkWriter val = component.BeginMessageToServer(); if (val != null) { val.Write((byte)0); val.Write(choiceIndex); component.FinishMessageToServer(val); } } } [IteratorStateMachine(typeof(<SubmitIngredientsClientSafe>d__17))] private static IEnumerator SubmitIngredientsClientSafe(CraftingController controller, List<PickupIndex> desired) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SubmitIngredientsClientSafe>d__17(0) { controller = controller, desired = desired }; } private static bool IngredientsMatchPrefixMultiset(PickupIndex[] current, List<PickupIndex> desired, int insertedCount) { //IL_0014: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) if (current == null || desired == null) { return false; } Dictionary<int, int> dictionary = new Dictionary<int, int>(); for (int i = 0; i < insertedCount; i++) { int value = desired[i].value; dictionary.TryGetValue(value, out var value2); dictionary[value] = value2 + 1; } Dictionary<int, int> dictionary2 = new Dictionary<int, int>(); foreach (PickupIndex val in current) { if (!(val == PickupIndex.none)) { int value3 = val.value; dictionary2.TryGetValue(value3, out var value4); dictionary2[value3] = value4 + 1; } } if (dictionary2.Count != dictionary.Count) { return false; } foreach (KeyValuePair<int, int> item in dictionary) { if (!dictionary2.TryGetValue(item.Key, out var value5)) { return false; } if (value5 != item.Value) { return false; } } return true; } private static bool IngredientsMatchMultiset(PickupIndex[] actualSlots, List<PickupIndex> desired) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (actualSlots == null) { return false; } if (actualSlots.Length != desired.Count) { return false; } Dictionary<PickupIndex, int> dictionary = new Dictionary<PickupIndex, int>(); Dictionary<PickupIndex, int> dictionary2 = new Dictionary<PickupIndex, int>(); foreach (PickupIndex val in actualSlots) { if (val == PickupIndex.none) { return false; } dictionary[val] = ((!dictionary.TryGetValue(val, out var value)) ? 1 : (value + 1)); } for (int j = 0; j < desired.Count; j++) { PickupIndex key = desired[j]; dictionary2[key] = ((!dictionary2.TryGetValue(key, out var value2)) ? 1 : (value2 + 1)); } if (dictionary.Count != dictionary2.Count) { return false; } foreach (KeyValuePair<PickupIndex, int> item in dictionary) { if (!dictionary2.TryGetValue(item.Key, out var value3)) { return false; } if (value3 != item.Value) { return false; } } return true; } private static int HashIngredients(PickupIndex[] arr) { if (arr == null) { return 0; } int num = 17; for (int i = 0; i < arr.Length; i++) { num = num * 31 + arr[i].value; } return num; } private static int CountFilled(PickupIndex[] slots) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (slots == null) { return 0; } int num = 0; for (int i = 0; i < slots.Length; i++) { if (slots[i] != PickupIndex.none) { num++; } } return num; } private static int CountOf(PickupIndex[] slots, PickupIndex p) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (slots == null) { return 0; } int num = 0; for (int i = 0; i < slots.Length; i++) { if (slots[i] == p) { num++; } } return num; } [IteratorStateMachine(typeof(<EnsureEquipmentIsActive>d__23))] private static IEnumerator EnsureEquipmentIsActive(CharacterBody body, EquipmentIndex target) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnsureEquipmentIsActive>d__23(0) { body = body, target = target }; } private static GameObject TryResolveChefStationObject(CharacterBody body) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)body)) { return null; } MealPrepController[] array = Object.FindObjectsOfType<MealPrepController>(); if (array == null || array.Length == 0) { return null; } MealPrepController val = null; float num = float.PositiveInfinity; Vector3 corePosition = body.corePosition; MealPrepController[] array2 = array; foreach (MealPrepController val2 in array2) { if (Object.op_Implicit((Object)(object)val2)) { Vector3 val3 = ((Component)val2).transform.position - corePosition; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; val = val2; } } } if (!Object.op_Implicit((Object)(object)val)) { return null; } IInteractable componentInChildren = ((Component)val).GetComponentInChildren<IInteractable>(); Component val4 = (Component)(object)((componentInChildren is Component) ? componentInChildren : null); if (!Object.op_Implicit((Object)(object)val4)) { return ((Component)val).gameObject; } return val4.gameObject; } [IteratorStateMachine(typeof(<HandleAcquisition>d__25))] private static IEnumerator HandleAcquisition(PickupIndex pi, int inventoryGoal, string actionPrefix) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <HandleAcquisition>d__25(0) { pi = pi, inventoryGoal = inventoryGoal, actionPrefix = actionPrefix }; } [IteratorStateMachine(typeof(<WaitForPendingPickup>d__26))] private static IEnumerator WaitForPendingPickup(PickupIndex pickupIndex, int expectedGain) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPendingPickup>d__26(0) { pickupIndex = pickupIndex, expectedGain = expectedGain }; } private static int GetOwnedCount(PickupDef def, CharacterBody body) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0010: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((int)def.itemIndex != -1) { return body.inventory.GetItemCountPermanent(def.itemIndex); } if ((int)def.equipmentIndex != -1) { Inventory inventory = body.inventory; int equipmentSlotCount = inventory.GetEquipmentSlotCount(); for (int i = 0; i < equipmentSlotCount; i++) { int equipmentSetCount = inventory.GetEquipmentSetCount((uint)i); for (int j = 0; j < equipmentSetCount; j++) { if (inventory.GetEquipment((uint)i, (uint)j).equipmentIndex == def.equipmentIndex) { return 1; } } } } return 0; } private static string GetStepName(ChefRecipe step) { string text = ((step.ResultIndex < ItemCatalog.itemCount) ? Language.GetString(ItemCatalog.GetItemDef((ItemIndex)step.ResultIndex)?.nameToken) : Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(step.ResultIndex - ItemCatalog.itemCount))?.nameToken)); if (step is CraftPlanner.TradeRecipe) { return "<style=cIsUtility>Trade: " + text + "</style>"; } return text; } private static PickupIndex GetPickupIndex(ChefRecipe step) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (step.ResultIndex < ItemCatalog.itemCount) { return PickupCatalog.FindPickupIndex((ItemIndex)step.ResultIndex); } return PickupCatalog.FindPickupIndex((EquipmentIndex)(step.ResultIndex - ItemCatalog.itemCount)); } private static string GetDroneName(DroneIndex droneIdx) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) if ((int)droneIdx != -1) { GameObject val = DroneCatalog.GetDroneDef(droneIdx)?.bodyPrefab; if (Object.op_Implicit((Object)(object)val)) { CharacterBody component = val.GetComponent<CharacterBody>(); if (component != null) { return Language.GetString(component.baseNameToken); } } } return "Drone"; } private static PickupIndex GetPickupIndexFromUnified(int unifiedIndex) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (unifiedIndex < ItemCatalog.itemCount) { return PickupCatalog.FindPickupIndex((ItemIndex)unifiedIndex); } return PickupCatalog.FindPickupIndex((EquipmentIndex)(unifiedIndex - ItemCatalog.itemCount)); } private static void SetObjectiveText(string text) { if ((Object)(object)_currentObjective == (Object)null) { _currentObjective = ObjectiveTracker.CreateObjective(text); } else { _currentObjective.UpdateText(text); } } private static void CompleteCurrentObjective() { if ((Object)(object)_currentObjective != (Object)null) { _currentObjective.Complete(); _currentObjective = null; } } private static void DumpChain(CraftPlanner.RecipeChain chain, int repeatCount) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) DebugLog.Trace(_log, "┌──────────────────────────────────────────────────────────┐"); DebugLog.Trace(_log, $"│ CHAIN EXECUTION: {GetItemName(chain.ResultIndex)} (x{repeatCount})"); DebugLog.Trace(_log, "├──────────────────────────────────────────────────────────┘"); if (chain.DroneCostSparse.Length != 0) { DebugLog.Trace(_log, "│ [Resources] Drones Needed:"); CraftPlanner.DroneRequirement[] droneCostSparse = chain.DroneCostSparse; for (int i = 0; i < droneCostSparse.Length; i++) { CraftPlanner.DroneRequirement droneRequirement = droneCostSparse[i]; DebugLog.Trace(_log, "│ - " + GetDroneName(droneRequirement.DroneIdx) + " -> 1x " + GetItemName(droneRequirement.ScrapIndex)); } } if (chain.AlliedTradeSparse.Length != 0) { DebugLog.Trace(_log, "│ [Resources] Allied Trades:"); CraftPlanner.TradeRequirement[] alliedTradeSparse = chain.AlliedTradeSparse; for (int i = 0; i < alliedTradeSparse.Length; i++) { CraftPlanner.TradeRequirement tradeRequirement = alliedTradeSparse[i]; DebugLog.Trace(_log, string.Format("│ - {0}: {1}x {2}", tradeRequirement.Donor?.userName ?? "Ally", tradeRequirement.Count, GetItemName(tradeRequirement.UnifiedIndex))); } } DebugLog.Trace(_log, "│ [Workflow] Sequence:"); List<ChefRecipe> list = chain.Steps.Where((ChefRecipe s) => !(s is CraftPlanner.TradeRecipe)).ToList(); for (int j = 0; j < list.Count; j++) { ChefRecipe chefRecipe = list[j]; string text = string.Join(", ", chefRecipe.Ingredients.Select((Ingredient ing) => $"{ing.Count}x {GetItemName(ing.UnifiedIndex)}")); DebugLog.Trace(_log, $"│ Step {j + 1}: [{text}] —> {chefRecipe.ResultCount}x {GetItemName(chefRecipe.ResultIndex)}"); } DebugLog.Trace(_log, "└──────────────────────────────────────────────────────────"); } private static string GetItemName(int unifiedIndex) { if (unifiedIndex < ItemCatalog.itemCount) { return Language.GetString(ItemCatalog.GetItemDef((ItemIndex)unifiedIndex)?.nameToken ?? "Unknown Item"); } return Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(unifiedIndex - ItemCatalog.itemCount))?.nameToken ?? "Unknown Equip"); } } internal static class ObjectiveTracker { public class ObjectiveToken : ScriptableObject { private class CancelWatcher : MonoBehaviour { public ObjectiveToken TargetToken; private float _holdTimer; private const float THRESHOLD = 0.6f; private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = CookBook.AbortKey.Value; if (((KeyboardShortcut)(ref value)).IsPressed()) { _holdTimer += Time.deltaTime; if (_holdTimer >= 0.6f) { TargetToken.Complete(); } } else { _holdTimer = 0f; } } } public string RawText; public uint SenderNetID; public int TrackedItemIdx; private GameObject _inputWatcher; public void Init(string text, uint senderID = 0u, int itemIdx = -1) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown RawText = text; SenderNetID = senderID; TrackedItemIdx = itemIdx; _inputWatcher = new GameObject("CookBook_ObjectiveWatcher"); _inputWatcher.AddComponent<CancelWatcher>().TargetToken = this; } public void UpdateText(string text) { RawText = text; } public void Complete() { if (Object.op_Implicit((Object)(object)_inputWatcher)) { Object.Destroy((Object)(object)_inputWatcher); } RemoveToken(this); Object.Destroy((Object)(object)this); } } private class ChefObjectiveTracker : ObjectiveTracker { private ObjectiveToken MyToken => base.sourceDescriptor.source as ObjectiveToken; protected override bool IsDirty() { if ((Object)(object)MyToken != (Object)null) { return base.cachedString != ((ObjectiveTracker)this).GenerateString(); } return false; } protected override string GenerateString() { //IL_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)MyToken)) { return string.Empty; } KeyboardShortcut value = CookBook.AbortKey.Value; KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey; string text = ((object)(KeyCode)(ref mainKey)).ToString(); return MyToken.RawText + " <style=cSub>[Hold " + text + " to Cancel]</style>"; } } private static readonly List<ObjectiveToken> _activeObjectives = new List<ObjectiveToken>(); internal static void Init() { ObjectivePanelController.collectObjectiveSources += OnCollectObjectiveSources; } internal static void Cleanup() { ObjectivePanelController.collectObjectiveSources -= OnCollectObjectiveSources; ClearAllObjectives(); } internal static bool HasActiveObjectives() { return _activeObjectives.Count > 0; } internal static ObjectiveToken CreateObjective(string message, uint senderID = 0u, int itemIdx = -1) { ObjectiveToken objectiveToken = ScriptableObject.CreateInstance<ObjectiveToken>(); objectiveToken.Init(message, senderID, itemIdx); _activeObjectives.Add(objectiveToken); return objectiveToken; } internal static void ClearSpecificRequest(uint senderID, int itemIdx) { for (int num = _activeObjectives.Count - 1; num >= 0; num--) { ObjectiveToken objectiveToken = _activeObjectives[num]; if (objectiveToken.SenderNetID == senderID && objectiveToken.TrackedItemIdx == itemIdx) { objectiveToken.Complete(); } } } internal static void ClearObjectivesFromSender(uint senderID) { for (int num = _activeObjectives.Count - 1; num >= 0; num--) { if (_activeObjectives[num].SenderNetID == senderID) { _activeObjectives[num].Complete(); } } } internal static void AddAlliedRequest(NetworkUser sender, string command, int unifiedIdx, int quantity) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)sender == (Object)null)) { string userName = sender.userName; string itemName = GetItemName(unifiedIdx); string text = string.Empty; if (command == "TRADE") { text = $"<style=cIsUtility>{userName} needs:</style> {quantity}x {itemName} <style=cStack>(Trade an Item)</style>"; } else if (command == "SCRAP") { text = "<style=cIsUtility>" + userName + " needs:</style> " + itemName + " <style=cStack>(Scrap a Drone)</style>"; } if (!string.IsNullOrEmpty(text)) { string message = text; NetworkInstanceId netId = ((NetworkBehaviour)sender).netId; CreateObjective(message, ((NetworkInstanceId)(ref netId)).Value, unifiedIdx); } } } private static void RemoveToken(ObjectiveToken token) { if (_activeObjectives.Contains(token)) { _activeObjectives.Remove(token); } } private static void OnCollectObjectiveSources(CharacterMaster viewerMaster, List<ObjectiveSourceDescriptor> output) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); if ((Object)(object)viewerMaster != (Object)(object)((firstLocalUser != null) ? firstLocalUser.cachedMaster : null)) { return; } for (int num = _activeObjectives.Count - 1; num >= 0; num--) { ObjectiveToken objectiveToken = _activeObjectives[num]; if (!Object.op_Implicit((Object)(object)objectiveToken)) { _activeObjectives.RemoveAt(num); } else { output.Add(new ObjectiveSourceDescriptor { source = (Object)(object)objectiveToken, master = viewerMaster, objectiveType = typeof(ChefObjectiveTracker) }); } } } internal static void ClearAllObjectives() { for (int num = _activeObjectives.Count - 1; num >= 0; num--) { if (Object.op_Implicit((Object)(object)_activeObjectives[num])) { _activeObjectives[num].Complete(); } } _activeObjectives.Clear(); } private static string GetItemName(int unifiedIdx) { int itemCount = ItemCatalog.itemCount; if (unifiedIdx < itemCount) { ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)unifiedIdx); if (!Object.op_Implicit((Object)(object)itemDef)) { return "Unknown Item"; } return Language.GetString(itemDef.nameToken); } EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(unifiedIdx - itemCount)); if (!Object.op_Implicit((Object)(object)equipmentDef)) { return "Unknown Equipment"; } return Language.GetString(equipmentDef.nameToken); } } internal sealed class CraftPlanner { internal sealed class TradeRecipe : ChefRecipe { public NetworkUser Donor; public int ItemUnifiedIndex; public TradeRecipe(NetworkUser donor, int itemIndex) : base(itemIndex, 1, Array.Empty<Ingredient>()) { Donor = donor; ItemUnifiedIndex = itemIndex; } public override int GetHashCode() { //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) NetworkInstanceId netId = ((NetworkBehaviour)Donor).netId; return ((object)(NetworkInstanceId)(ref netId)).GetHashCode() * 31 + ItemUnifiedIndex; } } internal sealed class CraftableEntry { public int ResultIndex; public int ResultCount; public int MinDepth; public List<RecipeChain> Chains = new List<RecipeChain>(); public bool IsItem => ResultIndex < ItemCatalog.itemCount; public ItemIndex ResultItem { get { if (IsItem) { return (ItemIndex)ResultIndex; } return (ItemIndex)(-1); } } public EquipmentIndex ResultEquipment { get { if (IsItem) { return (EquipmentIndex)(-1); } return (EquipmentIndex)(ResultIndex - ItemCatalog.itemCount); } } } internal struct TradeRequirement { public NetworkUser Donor; public int UnifiedIndex; public int Count; } internal sealed class RecipeChain { private readonly Dictionary<int, int> SurplusProfile; internal IReadOnlyList<ChefRecipe> Steps { get; } internal Ingredient[] PhysicalCostSparse { get; } internal DroneRequirement[] DroneCostSparse { get; } internal TradeRequirement[] AlliedTradeSparse { get; } internal int ResultIndex { get; } internal int ResultCount { get; } internal int ResultSurplus { get; } internal long CanonicalSignature { get; } internal int Depth => Steps.Count; public int GetNetSurplusFor(int itemIndex) { if (!SurplusProfile.TryGetValue(itemIndex, out var value)) { return 0; } return value; } internal RecipeChain(ChefRecipe recipe, Ingredient[] phys, DroneRequirement[] drones, TradeRequirement[] trades, long sig) { Steps = new ChefRecipe[1] { recipe }; ResultIndex = recipe.ResultIndex; ResultCount = recipe.ResultCount; ResultSurplus = recipe.ResultCount; PhysicalCostSparse = phys; DroneCostSparse = drones; AlliedTradeSparse = trades; CanonicalSignature = sig; SurplusProfile = new Dictionary<int, int> { { recipe.ResultIndex, recipe.ResultCount } }; Ingredient[] ingredients = recipe.Ingredients; for (int i = 0; i < ingredients.Length; i++) { Ingredient ingredient = ingredients[i]; SurplusProfile.TryGetValue(ingredient.UnifiedIndex, out var value); SurplusProfile[ingredient.UnifiedIndex] = value - ingredient.Count; } } internal RecipeChain(RecipeChain parent, ChefRecipe next, Ingredient[] phys, DroneRequirement[] drones, TradeRequirement[] trades, long sig) { Steps = parent.Steps.Append(next).ToArray(); ResultIndex = next.ResultIndex; ResultCount = next.ResultCount; PhysicalCostSparse = phys; DroneCostSparse = drones; AlliedTradeSparse = trades; CanonicalSignature = sig; SurplusProfile = new Dictionary<int, int>(parent.SurplusProfile); SurplusProfile.TryGetValue(next.ResultIndex, out var value); SurplusProfile[next.ResultIndex] = value + next.ResultCount; Ingredient[] ingredients = next.Ingredients; for (int i = 0; i < ingredients.Length; i++) { Ingredient ingredient = ingredients[i]; SurplusProfile.TryGetValue(ingredient.UnifiedIndex, out var value2); SurplusProfile[ingredient.UnifiedIndex] = value2 - ingredient.Count; } ResultSurplus = SurplusProfile[next.ResultIndex]; } public int GetMaxAffordable(int[] localPhysical, int[] dronePotential, Dictionary<NetworkUser, int[]> alliedSnapshots, Dictionary<NetworkUser, int> remainingTrades) { int num = int.MaxValue; Ingredient[] physicalCostSparse = PhysicalCostSparse; for (int i = 0; i < physicalCostSparse.Length; i++) { Ingredient ingredient = physicalCostSparse[i]; if (ingredient.Count != 0) { num = Math.Min(num, localPhysical[ingredient.UnifiedIndex] / ingredient.Count); } } Dictionary<int, int> dictionary = new Dictionary<int, int>(); DroneRequirement[] droneCostSparse = DroneCostSparse; for (int i = 0; i < droneCostSparse.Length; i++) { DroneRequirement droneRequirement = droneCostSparse[i]; if (droneRequirement.Count != 0) { if (!dictionary.ContainsKey(droneRequirement.ScrapIndex)) { dictionary[droneRequirement.ScrapIndex] = 0; } dictionary[droneRequirement.ScrapIndex] += droneRequirement.Count; } } foreach (KeyValuePair<int, int> item in dictionary) { num = Math.Min(num, dronePotential[item.Key] / item.Value); } TradeRequirement[] alliedTradeSparse = AlliedTradeSparse; for (int i = 0; i < alliedTradeSparse.Length; i++) { TradeRequirement tradeRequirement = alliedTradeSparse[i]; if (tradeRequirement.Count != 0) { if (!alliedSnapshots.TryGetValue(tradeRequirement.Donor, out var value)) { return 0; } if (!remainingTrades.TryGetValue(tradeRequirement.Donor, out var value2)) { return 0; } num = Math.Min(num, Math.Min(value[tradeRequirement.UnifiedIndex] / tradeRequirement.Count, value2 / tradeRequirement.Count)); } } if (num != int.MaxValue) { return num; } return 0; } internal static long CalculateCanonicalSignature(IEnumerable<ChefRecipe> chain) { if (chain == null) { return 0L; } long num = 0L; foreach (ChefRecipe item in chain) { num += item.GetHashCode(); } return num; } internal static long CalculateRollingSignature(long currentSignature, ChefRecipe next) { return currentSignature + next.GetHashCode(); } } internal struct DroneRequirement { public NetworkUser Owner; public DroneIndex DroneIdx; public int Count; public int TotalUpgradeCount; public int ScrapIndex; } private readonly ManualLogSource _log; private int _maxDepth; private readonly int _itemCount; private readonly int _totalDefCount; private readonly HashSet<int> _dirtyIndices = new HashSet<int>(); private readonly HashSet<int> _allIngredientIndices = new HashSet<int>(); private readonly HashSet<int> _transientIngredients = new HashSet<int>(); private HashSet<ItemIndex> _lastKnownCorrupted = new HashSet<ItemIndex>(); private readonly int[] _maxDemand; private readonly int[] _needsBuffer; private readonly int[] _productionBuffer; private readonly List<Ingredient> _tempPhysList = new List<Ingredient>(); private readonly List<DroneRequirement> _tempDroneReqList = new List<DroneRequirement>(); private readonly IReadOnlyList<ChefRecipe> _recipes; private Dictionary<int, CraftableEntry> _entryCache = new Dictionary<int, CraftableEntry>(); public int SourceItemCount { get; } internal event Action<List<CraftableEntry>> OnCraftablesUpdated; public CraftPlanner(IReadOnlyList<ChefRecipe> recipes, int maxDepth, ManualLogSource log) { _recipes = recipes?.Distinct().ToList() ?? throw new ArgumentNullException("recipes"); _maxDepth = maxDepth; _itemCount = ItemCatalog.itemCount; _totalDefCount = _itemCount + EquipmentCatalog.equipmentCount; _log = log; SourceItemCount = ItemCatalog.itemCount; int num = _totalDefCount + 10; _maxDemand = new int[num]; _needsBuffer = new int[num]; _productionBuffer = new int[num]; BuildRecipeIndex(); } internal void SetMaxDepth(int newDepth) { _maxDepth = Math.Max(0, newDepth); } private void BuildRecipeIndex() { _allIngredientIndices.Clear(); Array.Clear(_maxDemand, 0, _maxDemand.Length); DebugLog.Trace(_log, $"[Planner] Building Demand Index for {_recipes.Count} recipes..."); foreach (ChefRecipe recipe in _recipes) { Ingredient[] ingredients = recipe.Ingredients; for (int i = 0; i < ingredients.Length; i++) { Ingredient ingredient = ingredients[i]; int unifiedIndex = ingredient.UnifiedIndex; _allIngredientIndices.Add(unifiedIndex); if (ingredient.Count > _maxDemand[unifiedIndex]) { _maxDemand[unifiedIndex] = ingredient.Count; } } } } public void ComputeCraftable(int[] unifiedStacks, IReadOnlyList<ChefRecipe> recipes, bool canScrapDrones, HashSet<int> changedIndices = null, bool forceUpdate = false) { if (!StateController.IsChefStage() || unifiedStacks == null) { return; } if (!forceUpdate && changedIndices != null && changedIndices.Count > 0 && _entryCache.Count > 0) { bool flag = false; foreach (int changedIndex in changedIndices) { if (_allIngredientIndices.Contains(changedIndex) || _entryCache.ContainsKey(changedIndex)) { flag = true; break; } if (IsTransformedItemRelevant(changedIndex)) { flag = true; break; } } if (!flag) { RefreshVisualOverridesAndEmit(); return; } } Stopwatch stopwatch = Stopwatch.StartNew(); _transientIngredients.Clear(); foreach (ChefRecipe recipe in recipes) { Ingredient[] ingredients = recipe.Ingredients; for (int i = 0; i < ingredients.Length; i++) { Ingredient ingredient = ingredients[i]; _transientIngredients.Add(ingredient.UnifiedIndex); } } Dictionary<int, List<RecipeChain>> dictionary = new Dictionary<int, List<RecipeChain>>(); HashSet<long> hashSet = new HashSet<long>(); Queue<RecipeChain> queue = new Queue<RecipeChain>(); foreach (ChefRecipe recipe2 in recipes) { if (!isRecipeAffordable(unifiedStacks, recipe2, canScrapDrones, null)) { continue; } var (array, drones, trades) = CalculateSplitCosts(null, recipe2, canScrapDrones, unifiedStacks); if (array != null) { long sig = recipe2.GetHashCode(); RecipeChain recipeChain = new RecipeChain(recipe2, array, drones, trades, sig); if (hashSet.Add(recipeChain.CanonicalSignature)) { AddChainToResults(dictionary, queue, recipeChain); } } } if (CookBook.IsPoolingEnabled) { InjectTradeRecipes(null, dictionary, queue, hashSet, _transientIngredients); } for (int j = 2; j <= _maxDepth; j++) { int count = queue.Count; if (count == 0) { break; } for (int k = 0; k < count; k++) { RecipeChain recipeChain2 = queue.Dequeue(); foreach (ChefRecipe recipe3 in recipes) { if (!IsCausallyLinked(recipeChain2, recipe3)) { continue; } long num = RecipeChain.CalculateRollingSignature(recipeChain2.CanonicalSignature, recipe3); if (hashSet.Add(num) && isRecipeAffordable(unifiedStacks, recipe3, canScrapDrones, recipeChain2)) { var (array2, drones2, trades2) = CalculateSplitCosts(recipeChain2, recipe3, canScrapDrones, unifiedStacks); if (array2 != null) { recipeChain2.Steps.Concat(new ChefRecipe[1] { recipe3 }).ToList(); RecipeChain chain = new RecipeChain(recipeChain2, recipe3, array2, drones2, trades2, num); AddChainToResults(dictionary, queue, chain); } } } } } _entryCache = (from e in dictionary.Select(delegate(KeyValuePair<int, List<RecipeChain>> kvp) { List<RecipeChain> list2 = (from c in kvp.Value where c.ResultIndex == kvp.Key where c.Steps.Count != 1 || !(c.Steps[0] is TradeRecipe) where c.ResultSurplus == c.ResultCount orderby c.DroneCostSparse.Length, c.Depth select c).ToList(); return (list2.Count == 0) ? null : new CraftableEntry { ResultIndex = kvp.Key, ResultCount = list2[0].ResultCount, MinDepth = list2[0].Depth, Chains = list2 }; }) where e != null select e).ToDictionary((CraftableEntry e) => e.ResultIndex); List<CraftableEntry> list = _entryCache.Values.ToList(); RefreshVisualOverridesAndEmit(); list.Sort(TierManager.CompareCraftableEntries); stopwatch.Stop(); DebugLog.Trace(_log, $"[Planner] Rebuild complete: {stopwatch.ElapsedMilliseconds}ms for {list.Count} entries."); } private string GetChainSummary(RecipeChain chain) { string text = string.Join(" -> ", chain.Steps.Select((ChefRecipe s) => (!(s is TradeRecipe tradeRecipe)) ? GetItemName(s.ResultIndex) : ("Trade(" + GetItemName(tradeRecipe.ItemUnifiedIndex) + ")"))); int weightedCost = GetWeightedCost(chain); int resultSurplus = chain.ResultSurplus; return $"[Depth {chain.Depth}, Weight {weightedCost}, Surplus {resultSurplus}] {text}"; } private string GetItemName(int unifiedIndex) { if (unifiedIndex < ItemCatalog.itemCount) { return Language.GetString(ItemCatalog.GetItemDef((ItemIndex)unifiedIndex)?.nameToken ?? "Unknown Item"); } return Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(unifiedIndex - ItemCatalog.itemCount))?.nameToken ?? "Unknown Equip"); } private bool IsCausallyLinked(RecipeChain chain, ChefRecipe next) { Ingredient[] ingredients = next.Ingredients; for (int i = 0; i < ingredients.Length; i++) { Ingredient ingredient = ingredients[i]; if (chain.GetNetSurplusFor(ingredient.UnifiedIndex) > 0) { return true; } } int resultIndex = next.ResultIndex; int num = _maxDemand[resultIndex]; if (num > 1) { int netSurplusFor = chain.GetNetSurplusFor(resultIndex); if (netSurplusFor > 0 && netSurplusFor < num) { return true; } } return false; } private bool IsChainInefficient(RecipeChain chain) { int weightedCost = GetWeightedCost(chain); int num = chain.ResultSurplus * GetItemWeight(chain.ResultIndex); return weightedCost > num * 2; } private bool IsChainDominated(RecipeChain newChain, Dictionary<int, List<RecipeChain>> discovered) { if (!discovered.TryGetValue(newChain.ResultIndex, out var value)) { return false; } int weightedCost = GetWeightedCost(newChain); foreach (RecipeChain item in value) { int weightedCost2 = GetWeightedCost(item); if (item.Depth < newChain.Depth && weightedCost2 <= weightedCost && HasSuperiorSurplusProfile(item, newChain)) { return true; } } return false; } private bool isRecipeAffordable(int[] totalStacks, ChefRecipe recipe, bool scrapperPresent, RecipeChain existingChain) { Ingredient[] ingredients = recipe.Ingredients; for (int i = 0; i < ingredients.Length; i++) { Ingredient ingredient = ingredients[i]; int unifiedIndex = ingredient.UnifiedIndex; int num = existingChain?.GetNetSurplusFor(unifiedIndex) ?? 0; int num2 = Math.Max(0, ingredient.Count - num); if (num2 > 0) { int num3 = totalStacks[unifiedIndex]; int num4 = (scrapperPresent ? InventoryTracker.GetGlobalDronePotentialCount(unifiedIndex) : 0); if (num3 + num4 < num2) { return false; } } } return true; } private void InjectTradeRecipes(RecipeChain chain, Dictionary<int, List<RecipeChain>> discovered, Queue<RecipeChain> queue, HashSet<long> signatures, HashSet<int> validIngredients) { Dictionary<NetworkUser, int[]> alliedS