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 Chest Preview v1.0.15
plugins/ChestContentsPreview.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ChestContentsPreview")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ChestContentsPreview")] [assembly: AssemblyTitle("ChestContentsPreview")] [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 ChestContentsPreview { [BepInPlugin("com.chestcontentspreview.valheim", "Chest Contents Preview", "1.0.15")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.chestcontentspreview.valheim"; public const string PluginName = "Chest Contents Preview"; public const string PluginVersion = "1.0.15"; internal static ConfigEntry<bool> IsModEnabled; internal static ConfigEntry<bool> StartHidden; internal static ConfigEntry<KeyboardShortcut> ToggleShortcut; private Harmony _harmony; private void Awake() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown IsModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("_Global", "isModEnabled", true, "Globally enable or disable the chest contents preview."); StartHidden = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "startHidden", false, "Start with the chest contents preview hidden until the shortcut is pressed."); ToggleShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "toggleShowContentsShortcut", new KeyboardShortcut((KeyCode)112, (KeyCode[])(object)new KeyCode[1] { (KeyCode)303 }), "Toggle the chest contents preview."); PreviewController.Initialize(((BaseUnityPlugin)this).Logger); PreviewController.SetVisible(!StartHidden.Value); _harmony = new Harmony("com.chestcontentspreview.valheim"); _harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Chest Contents Preview 1.0.15 loaded."); } private void Update() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) NoScrollWardrobesCompatibilityPatch.TryInstall(_harmony, ((BaseUnityPlugin)this).Logger); if (!IsModEnabled.Value) { return; } KeyboardShortcut value = ToggleShortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { PreviewController.ToggleVisible(); if (!PreviewController.IsVisible && !PreviewController.IsRealGuiVisible && (Object)(object)InventoryGui.instance != (Object)null) { InventoryGui.instance.Hide(); } } } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } } internal static class PreviewController { private static readonly FieldInfo PlayerHoveringField = AccessTools.Field(typeof(Player), "m_hovering"); private static readonly FieldInfo GuiAnimatorField = AccessTools.Field(typeof(InventoryGui), "m_animator"); private static readonly FieldInfo GuiHiddenFramesField = AccessTools.Field(typeof(InventoryGui), "m_hiddenFrames"); private static readonly FieldInfo GuiPlayerField = AccessTools.Field(typeof(InventoryGui), "m_player"); private static readonly FieldInfo GuiInfoPanelField = AccessTools.Field(typeof(InventoryGui), "m_infoPanel"); private static readonly FieldInfo GuiInventoryRootField = AccessTools.Field(typeof(InventoryGui), "m_inventoryRoot"); private static readonly FieldInfo GuiContainerField = AccessTools.Field(typeof(InventoryGui), "m_container"); private static readonly FieldInfo GuiContainerGridField = AccessTools.Field(typeof(InventoryGui), "m_containerGrid"); private static readonly FieldInfo GuiTakeAllButtonField = AccessTools.Field(typeof(InventoryGui), "m_takeAllButton"); private static readonly FieldInfo GuiStackAllButtonField = AccessTools.Field(typeof(InventoryGui), "m_stackAllButton"); private static readonly FieldInfo GuiContainerNameField = AccessTools.Field(typeof(InventoryGui), "m_containerName"); private static readonly FieldInfo GuiContainerWeightField = AccessTools.Field(typeof(InventoryGui), "m_containerWeight"); private static readonly FieldInfo GuiCurrentContainerField = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); private static readonly FieldInfo GamePlayerProfileField = AccessTools.Field(typeof(Game), "m_playerProfile"); private static readonly FieldInfo ProfilePlayerIdField = AccessTools.Field(typeof(PlayerProfile), "m_playerID"); private static readonly MethodInfo ContainerCheckAccessMethod = (from method in typeof(Container).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where method.Name == "CheckAccess" orderby method.GetParameters().Length select method).FirstOrDefault(); private static readonly Dictionary<GameObject, bool> PreviewObjectActiveStates = new Dictionary<GameObject, bool>(); private static readonly Dictionary<Behaviour, bool> PreviewBehaviourEnabledStates = new Dictionary<Behaviour, bool>(); private static ManualLogSource _log; private static bool _visible = true; private static bool _realGuiVisible; private static bool _previewUiSuppressed; private static Container _hoveredContainer; private static GameObject _hoveredObject; private static Container _lastAccessLogContainer; private static bool _lastAccessLogValue; private static bool _hasAccessLogValue; private static bool _isPreviewGridUpdate; private static InventoryGui _previewGridGui; private static Container _previewGridContainer; private static InventoryGui _cachedGui; private static Transform _playerPanelTransform; private static GameObject _infoPanel; private static GameObject _craftingPanel; private static GameObject _takeAllButton; private static GameObject _stackAllButton; private static GameObject _containerName; private static GameObject _containerWeight; private static Component[] _textComponents; internal static bool IsVisible => _visible; internal static bool IsRealGuiVisible => _realGuiVisible; internal static void Initialize(ManualLogSource logger) { _log = logger; if (GuiCurrentContainerField == null) { _log.LogWarning((object)"InventoryGui.m_currentContainer was not found. Grid layout compatibility may be unavailable."); } } internal static Container ResolveLayoutContainer(object ignoredAccessor, InventoryGui gui) { if (_isPreviewGridUpdate && (Object)(object)gui == (Object)(object)_previewGridGui) { return _previewGridContainer; } object obj = Get(GuiCurrentContainerField, gui); return (Container)((obj is Container) ? obj : null); } internal static void SetVisible(bool value) { _visible = value; } internal static void ToggleVisible() { _visible = !_visible; } internal static void TrackHover(Player player) { if (!((Object)(object)player == (Object)null) && Plugin.IsModEnabled != null && Plugin.IsModEnabled.Value) { object obj = Get(PlayerHoveringField, player); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)_hoveredObject == (Object)(object)val)) { _hoveredObject = val; _hoveredContainer = (((Object)(object)val != (Object)null) ? val.GetComponentInParent<Container>() : null); } } } internal static void CacheGui(InventoryGui gui) { if (!((Object)(object)gui == (Object)null) && !((Object)(object)gui == (Object)(object)_cachedGui)) { _cachedGui = gui; _playerPanelTransform = AsTransform(Get(GuiPlayerField, gui)); _infoPanel = AsGameObject(Get(GuiInfoPanelField, gui)); _takeAllButton = AsGameObject(Get(GuiTakeAllButtonField, gui)); _stackAllButton = AsGameObject(Get(GuiStackAllButtonField, gui)); _containerName = AsGameObject(Get(GuiContainerNameField, gui)); _containerWeight = AsGameObject(Get(GuiContainerWeightField, gui)); _textComponents = (from component in ((Component)gui).GetComponentsInChildren<Component>(true) where (Object)(object)component != (Object)null && GetTextProperty(((object)component).GetType()) != null select component).ToArray(); Transform val = AsTransform(Get(GuiInventoryRootField, gui)); Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("Crafting") : null); if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.auga")) { val2 = (((Object)(object)val != (Object)null) ? val.Find("RightPanel") : null); } _craftingPanel = (((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null); } } internal static void OnShow() { _realGuiVisible = true; RestorePreviewUi(); } internal static void OnHide() { bool realGuiVisible = _realGuiVisible; _realGuiVisible = false; if (realGuiVisible) { RestorePreviewUi(); } } internal static void BeforeGuiUpdate(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return; } CacheGui(gui); if (!ShowRealGui()) { object obj = Get(GuiAnimatorField, gui); Animator val = (Animator)((obj is Animator) ? obj : null); if ((Object)(object)val != (Object)null) { val.SetBool("visible", false); } } } internal static void AfterGuiUpdate(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return; } CacheGui(gui); if (ShowRealGui()) { if (_realGuiVisible) { RestorePreviewUi(); return; } object obj = Get(GuiAnimatorField, gui); Animator val = (Animator)((obj is Animator) ? obj : null); if ((Object)(object)val != (Object)null) { val.SetBool("visible", false); } return; } bool num = HasContainerAccess(_hoveredContainer); LogHoverAccessState(num); if (!num || !ShowPreviewContainer(gui, _hoveredContainer)) { object obj2 = Get(GuiAnimatorField, gui); Animator val2 = (Animator)((obj2 is Animator) ? obj2 : null); if ((Object)(object)val2 != (Object)null) { val2.SetBool("visible", false); } if (!_previewUiSuppressed) { RestorePreviewUi(); } } } private static void LogHoverAccessState(bool hasAccess) { if ((Object)(object)_hoveredContainer == (Object)null) { _lastAccessLogContainer = null; _hasAccessLogValue = false; } else if (!((Object)(object)_hoveredContainer == (Object)(object)_lastAccessLogContainer) || !_hasAccessLogValue || _lastAccessLogValue != hasAccess) { _lastAccessLogContainer = _hoveredContainer; _lastAccessLogValue = hasAccess; _hasAccessLogValue = true; _log.LogInfo((object)("Hover target " + ((Object)_hoveredContainer).name + ": preview access " + (hasAccess ? "granted." : "denied."))); } } internal static bool AllowDrag() { return ShowRealGui(); } private static bool ShowRealGui() { if (Plugin.IsModEnabled == null || !Plugin.IsModEnabled.Value || !_visible) { return true; } return _realGuiVisible; } private static bool ShowPreviewContainer(InventoryGui gui, Container container) { if ((Object)(object)container == (Object)null) { return false; } Inventory inventory = container.GetInventory(); object obj = Get(GuiContainerGridField, gui); InventoryGrid val = (InventoryGrid)((obj is InventoryGrid) ? obj : null); Transform val2 = AsTransform(Get(GuiContainerField, gui)); if (inventory == null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } object obj2 = Get(GuiAnimatorField, gui); Animator val3 = (Animator)((obj2 is Animator) ? obj2 : null); if ((Object)(object)val3 != (Object)null) { val3.SetBool("visible", true); } Set(GuiHiddenFramesField, gui, 10); ((Component)val2).gameObject.SetActive(true); HidePreviewUi(gui, val2); bool isPreviewGridUpdate = _isPreviewGridUpdate; InventoryGui previewGridGui = _previewGridGui; Container previewGridContainer = _previewGridContainer; try { _isPreviewGridUpdate = true; _previewGridGui = gui; _previewGridContainer = container; val.UpdateInventory(inventory, (Player)null, (ItemData)null); val.ResetView(); UpdateContainerLabels(gui, inventory); return true; } finally { _isPreviewGridUpdate = isPreviewGridUpdate; _previewGridGui = previewGridGui; _previewGridContainer = previewGridContainer; } } private static void HidePreviewUi(InventoryGui gui, Transform containerPanel) { _previewUiSuppressed = true; if ((Object)(object)_playerPanelTransform != (Object)null) { for (int i = 0; i < _playerPanelTransform.childCount; i++) { Transform child = _playerPanelTransform.GetChild(i); if ((Object)(object)child != (Object)null && !IsContainerBranch(child, containerPanel)) { SetPreviewObjectActive(((Component)child).gameObject, active: false); } } } SetPreviewObjectActive(_infoPanel, active: false); SetPreviewObjectActive(_craftingPanel, active: false); SetPreviewObjectActive(_takeAllButton, active: false); SetPreviewObjectActive(_stackAllButton, active: false); SetPreviewObjectActive(_containerName, active: true); SetPreviewObjectActive(_containerWeight, active: true); HideActionHints(); HideContainerFrame(containerPanel); HideQuickStackButtons(); } private static void HideActionHints() { if (_textComponents == null) { return; } for (int i = 0; i < _textComponents.Length; i++) { Component val = _textComponents[i]; if (!((Object)(object)val == (Object)null)) { PropertyInfo textProperty = GetTextProperty(((object)val).GetType()); if (IsActionHint((textProperty != null && textProperty.CanRead) ? (textProperty.GetValue(val, null) as string) : null)) { SetPreviewObjectActive(val.gameObject, active: false); } } } } private static bool IsActionHint(string value) { if (string.IsNullOrEmpty(value)) { return false; } string text = value.ToUpperInvariant().Replace(" ", ""); if (!text.Contains("[LMB]") && !text.Contains("[RMB]") && !text.Contains("[SHIFT+LMB]")) { return text.Contains("[CTRL+LMB]"); } return true; } private static void HideContainerFrame(Transform containerPanel) { if (!((Object)(object)containerPanel == (Object)null)) { SetPreviewBehaviourEnabled((Behaviour)(object)((Component)containerPanel).GetComponent<Image>(), enabled: false); SetPreviewBehaviourEnabled((Behaviour)(object)((Component)containerPanel).GetComponent<Outline>(), enabled: false); } } private static void SetPreviewBehaviourEnabled(Behaviour behaviour, bool enabled) { if (!((Object)(object)behaviour == (Object)null)) { if (!PreviewBehaviourEnabledStates.ContainsKey(behaviour)) { PreviewBehaviourEnabledStates.Add(behaviour, behaviour.enabled); } behaviour.enabled = enabled; } } private static bool IsContainerBranch(Transform child, Transform containerPanel) { if ((Object)(object)child == (Object)null) { return false; } if ((Object)(object)containerPanel != (Object)null && ((Object)(object)child == (Object)(object)containerPanel || containerPanel.IsChildOf(child))) { return true; } return ((Object)child).name == "Container"; } private static void HideQuickStackButtons() { if ((Object)(object)_takeAllButton == (Object)null || (Object)(object)_takeAllButton.transform.parent == (Object)null) { return; } Transform parent = _takeAllButton.transform.parent; for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (!((Object)(object)child == (Object)null)) { switch (((Object)child).name) { case "quickStackToContainerButton": case "storeAllButton": case "sortContainerButton": case "restockFromContainerButton": SetPreviewObjectActive(((Component)child).gameObject, active: false); break; } } } } private static void SetPreviewObjectActive(GameObject gameObject, bool active) { if (!((Object)(object)gameObject == (Object)null)) { if (!PreviewObjectActiveStates.ContainsKey(gameObject)) { PreviewObjectActiveStates.Add(gameObject, gameObject.activeSelf); } gameObject.SetActive(active); } } private static void SetPreviewObjectActive(Component component, bool active) { if ((Object)(object)component != (Object)null) { SetPreviewObjectActive(component.gameObject, active); } } private static void RestorePreviewUi() { foreach (KeyValuePair<GameObject, bool> previewObjectActiveState in PreviewObjectActiveStates) { if ((Object)(object)previewObjectActiveState.Key != (Object)null) { previewObjectActiveState.Key.SetActive(previewObjectActiveState.Value); } } PreviewObjectActiveStates.Clear(); foreach (KeyValuePair<Behaviour, bool> previewBehaviourEnabledState in PreviewBehaviourEnabledStates) { if ((Object)(object)previewBehaviourEnabledState.Key != (Object)null) { previewBehaviourEnabledState.Key.enabled = previewBehaviourEnabledState.Value; } } PreviewBehaviourEnabledStates.Clear(); _previewUiSuppressed = false; } private static void UpdateContainerLabels(InventoryGui gui, Inventory inventory) { if (!((Object)(object)gui == (Object)null) && inventory != null) { string text = inventory.GetName(); if (Localization.instance != null) { text = Localization.instance.Localize(text); } SetTextValue(Get(GuiContainerNameField, gui), text); SetTextValue(Get(GuiContainerWeightField, gui), Mathf.CeilToInt(inventory.GetTotalWeight()).ToString()); } } private static PropertyInfo GetTextProperty(Type type) { if (type == null) { return null; } PropertyInfo property = type.GetProperty("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null || property.PropertyType != typeof(string) || property.GetIndexParameters().Length != 0) { return null; } return property; } private static void SetTextValue(object textComponent, string value) { PropertyInfo propertyInfo = ((textComponent != null) ? GetTextProperty(textComponent.GetType()) : null); if (propertyInfo != null && propertyInfo.CanWrite) { propertyInfo.SetValue(textComponent, value, null); } } private static bool HasContainerAccess(Container container) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)container == (Object)null) { return false; } bool flag = PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false); if (ContainerCheckAccessMethod == null) { return flag; } object instance = Get(GamePlayerProfileField, Game.instance); object obj = Get(ProfilePlayerIdField, instance); if (obj == null) { return flag; } ParameterInfo[] parameters = ContainerCheckAccessMethod.GetParameters(); if (parameters.Length == 0) { return flag; } try { object[] array = new object[parameters.Length]; array[0] = Convert.ChangeType(obj, parameters[0].ParameterType); for (int i = 1; i < parameters.Length; i++) { array[i] = (parameters[i].HasDefaultValue ? parameters[i].DefaultValue : DefaultValue(parameters[i].ParameterType)); } bool flag2 = (bool)ContainerCheckAccessMethod.Invoke(container, array); return flag && flag2; } catch (Exception ex) { _log.LogWarning((object)("Container access check failed; preview hidden. " + ex.GetBaseException().Message)); return false; } } private static object DefaultValue(Type type) { if (!type.IsValueType) { return null; } return Activator.CreateInstance(type); } private static object Get(FieldInfo field, object instance) { if (!(field != null) || instance == null) { return null; } return field.GetValue(instance); } private static void Set(FieldInfo field, object instance, object value) { if (field != null && instance != null) { field.SetValue(instance, value); } } private static Transform AsTransform(object value) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (value is Transform) { return (Transform)value; } if (value is Component) { return ((Component)value).transform; } if (value is GameObject) { return ((GameObject)value).transform; } return null; } private static GameObject AsGameObject(object value) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (value is GameObject) { return (GameObject)value; } if (value is Component) { return ((Component)value).gameObject; } return null; } } [HarmonyPatch(typeof(Player), "UpdateHover")] internal static class PlayerHoverPatch { private static void Postfix(Player __instance) { PreviewController.TrackHover(__instance); } } [HarmonyPatch] internal static class InventoryGuiAwakePatch { private static IEnumerable<MethodBase> TargetMethods() { return from method in AccessTools.GetDeclaredMethods(typeof(InventoryGui)) where method.Name == "Awake" select method; } [HarmonyPriority(200)] private static void Postfix(InventoryGui __instance) { PreviewController.CacheGui(__instance); } } [HarmonyPatch] internal static class InventoryGuiShowPatch { private static IEnumerable<MethodBase> TargetMethods() { return from method in AccessTools.GetDeclaredMethods(typeof(InventoryGui)) where method.Name == "Show" select method; } private static void Postfix() { PreviewController.OnShow(); } } [HarmonyPatch] internal static class InventoryGuiHidePatch { private static IEnumerable<MethodBase> TargetMethods() { return from method in AccessTools.GetDeclaredMethods(typeof(InventoryGui)) where method.Name == "Hide" select method; } private static void Postfix() { PreviewController.OnHide(); } } [HarmonyPatch(typeof(InventoryGui), "Update")] internal static class InventoryGuiUpdatePatch { private static void Prefix(InventoryGui __instance) { PreviewController.BeforeGuiUpdate(__instance); } private static void Postfix(InventoryGui __instance) { PreviewController.AfterGuiUpdate(__instance); } } [HarmonyPatch(typeof(InventoryGui), "SetupDragItem")] internal static class SetupDragItemPatch { private static bool Prefix() { return PreviewController.AllowDrag(); } } internal static class NoScrollWardrobesCompatibilityPatch { private static bool _attempted; private static bool _accessorReplaced; private static int _frame; private static int _nextLookupFrame; private static Container _resolvedContainer; internal static void TryInstall(Harmony harmony, ManualLogSource log) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown if (_attempted || harmony == null) { return; } _frame++; if (_frame < _nextLookupFrame) { return; } _nextLookupFrame = _frame + 30; Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { if (!(type == null)) { break; } type = assemblies[i].GetType("NoScrollWardrobes.ContainerLayout", throwOnError: false); } if (type == null) { return; } MethodInfo methodInfo = AccessTools.Method(type, "Postfix", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(NoScrollWardrobesCompatibilityPatch), "Transpiler", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { _attempted = true; log.LogWarning((object)"No Scroll Wardrobes was found, but its grid layout method could not be patched."); return; } _attempted = true; _accessorReplaced = false; try { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null); if (_accessorReplaced) { log.LogInfo((object)"No Scroll Wardrobes preview layout compatibility installed."); } else { log.LogWarning((object)"No Scroll Wardrobes loaded, but its container accessor was not recognized; previews may use its vanilla layout."); } } catch (Exception ex) { log.LogWarning((object)("Could not install No Scroll Wardrobes preview layout compatibility. " + ex.GetBaseException().Message)); } } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { bool replaced = false; foreach (CodeInstruction instruction in instructions) { MethodInfo methodInfo = instruction.operand as MethodInfo; if (!replaced && methodInfo != null && methodInfo.Name == "Invoke" && methodInfo.GetParameters().Length == 1 && methodInfo.GetParameters()[0].ParameterType == typeof(InventoryGui)) { MethodInfo methodInfo2 = null; if (methodInfo.ReturnType == typeof(Container)) { methodInfo2 = AccessTools.Method(typeof(NoScrollWardrobesCompatibilityPatch), "ResolveContainer", (Type[])null, (Type[])null); } else if (methodInfo.ReturnType.IsByRef && methodInfo.ReturnType.GetElementType() == typeof(Container)) { methodInfo2 = AccessTools.Method(typeof(NoScrollWardrobesCompatibilityPatch), "ResolveContainerReference", (Type[])null, (Type[])null); } if (methodInfo2 != null) { instruction.opcode = OpCodes.Call; instruction.operand = methodInfo2; replaced = true; _accessorReplaced = true; } } yield return instruction; } } private static Container ResolveContainer(object currentContainerAccessor, InventoryGui gui) { return PreviewController.ResolveLayoutContainer(currentContainerAccessor, gui); } private static ref Container ResolveContainerReference(object currentContainerAccessor, InventoryGui gui) { _resolvedContainer = PreviewController.ResolveLayoutContainer(currentContainerAccessor, gui); return ref _resolvedContainer; } } }