using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using SoftReferenceableAssets; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.TextCore; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Advize_Armoire")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Valheim Game Modification")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8424dd46-f4b9-4fae-873e-59bc805d8112")] [assembly: AssemblyFileVersion("1.1.5.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.5.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; } } } namespace Advize_Armoire { [BepInPlugin("advize.Armoire", "Armoire", "1.1.5")] public sealed class Armoire : BaseUnityPlugin { public const string PluginID = "advize.Armoire"; public const string PluginName = "Armoire"; public const string Version = "1.1.5"; internal void Awake() { Runtime.MakeAllAssetsLoadable(); Logger.Sources.Add((ILogSource)(object)StaticMembers.ModLogger); StaticMembers.config = new ModConfig(((BaseUnityPlugin)this).Config); StaticMembers.assetBundle = StaticMembers.LoadAssetBundle("armoire"); StaticMembers.guiPrefab = StaticMembers.assetBundle.LoadAsset("ArmoireGUI"); StaticMembers.armoireSlot = StaticMembers.assetBundle.LoadAsset("ArmoireSlot"); StaticMembers.armoirePiecePrefab = StaticMembers.assetBundle.LoadAsset("ArmoirePiece"); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "advize.Armoire"); } } public class ArmoireDoor : MonoBehaviour, Hoverable, Interactable { [Header("Transform References")] public Transform playerAttachPoint; public Transform cameraPosition; public GameObject equipmentAttachPoint; private const string AttachAnimation = "onGround"; private const float UseDistance = 2f; private static Gradient _hoverGradient; private static readonly StringBuilder _hoverText = new StringBuilder(128); private static float _lastPercentage = -1f; private static string _lastUseText = null; private static string _cachedHoverText = null; internal static List SoundEffects = new List(); private ZNetView _nview; private Animator _animator; private uint _lastDataRevision = uint.MaxValue; private static Gradient HoverGradient => _hoverGradient ?? InitializeGradient(); internal bool CanInteract { get { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0); return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsTag("openable"); } } public void Awake() { _nview = ((Component)this).GetComponent(); if (Object.op_Implicit((Object)(object)_nview) && _nview.IsValid()) { _animator = ((Component)this).GetComponentInChildren(); _nview.Register("UseArmoire", (Action)RPC_UseArmoire); ((MonoBehaviour)this).InvokeRepeating("UpdateState", 0f, 5f); } } private void RPC_UseArmoire(long uid) { if (CanInteract) { int @int = _nview.GetZDO().GetInt(ZDOVars.s_state, 0); _nview.GetZDO().Set(ZDOVars.s_state, 1 - @int, false); UpdateState(); } } private void UpdateState() { if (_nview.IsValid()) { ZDO zdo = _nview.m_zdo; if (zdo != null && zdo.DataRevision != _lastDataRevision) { _lastDataRevision = zdo.DataRevision; SetState(zdo.GetInt(ZDOVars.s_state, 0)); } } } private void SetState(int state) { //IL_0024: 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) if (_animator.GetInteger("state") != state) { SoundEffects[state].Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); _animator.SetInteger("state", state); } } public void ResetState() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) _nview.InvokeRPC("UseArmoire", Array.Empty()); playerAttachPoint.localRotation = Quaternion.Euler(0f, 0f, 0f); } public string GetHoverText() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ArmoireUIController.IsArmoirePanelActive()) { return string.Empty; } float num = Mathf.Clamp01((float)AppearanceTracker.UnlockedPercentage); bool num2 = !Mathf.Approximately(num, _lastPercentage); string text = Localization.instance.Localize("[$KEY_Use] $piece_use"); bool flag = text != _lastUseText; if (!num2 && !flag) { return _cachedHoverText; } _lastPercentage = num; _lastUseText = text; string value = ColorUtility.ToHtmlStringRGB(HoverGradient.Evaluate(num)); _hoverText.Clear(); _hoverText.Append(GetHoverName()).Append('\n'); _hoverText.Append("Collected: ') .Append(AppearanceTracker.TotalUnlocked) .Append('/') .Append(AppearanceTracker.TotalCollectable) .Append("\n"); _hoverText.Append(text); _cachedHoverText = _hoverText.ToString(); return _cachedHoverText; } public string GetHoverName() { return "Armoire"; } public bool Interact(Humanoid character, bool hold, bool alt) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) StaticMembers.Dbgl("Interacted with armoire", forceLog: false, (LogLevel)16); if (hold || !CanInteract) { return false; } Player val = (Player)(object)((character is Player) ? character : null); if (val == null || !InUsingDistance((Humanoid)(object)val) || ((Character)val).IsEncumbered()) { return false; } Player closestPlayer = Player.GetClosestPlayer(playerAttachPoint.position, 0.1f); if (Object.op_Implicit((Object)(object)closestPlayer) && (Object)(object)closestPlayer != (Object)(object)Player.m_localPlayer) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$msg_blocked", 0, (Sprite)null); return false; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0); if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("opened")) { ((Character)val).AttachStart(playerAttachPoint, (GameObject)null, false, false, false, "onGround", default(Vector3), cameraPosition); ArmoireUIController.ToggleArmoirePanel(this); equipmentAttachPoint.SetActive(true); _nview.ClaimOwnership(); } _nview.InvokeRPC("UseArmoire", Array.Empty()); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } private static Gradient InitializeGradient() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) //IL_005c: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) //IL_008d: Unknown result type (might be due to invalid IL or missing references) _hoverGradient = new Gradient(); _hoverGradient.SetKeys((GradientColorKey[])(object)new GradientColorKey[5] { new GradientColorKey(Color.red, 0f), new GradientColorKey(new Color(1f, 0.6470588f, 0f), 0.3f), new GradientColorKey(Color.yellow, 0.6f), new GradientColorKey(Color.green, 0.9f), new GradientColorKey(Color.cyan, 1f) }, Array.Empty()); return _hoverGradient; } private bool InUsingDistance(Humanoid human) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(((Component)human).transform.position, playerAttachPoint.position) < 2f; } } [HarmonyPatch] internal static class VersionHandshake { private static readonly List ValidatedPeers = new List(); private static string ConnectionError = string.Empty; private static bool ClientVersionValidated = false; private static void RPC_ArmoireVersionCheck(ZRpc rpc, ZPackage pkg) { string text = pkg.ReadString(); bool flag = ZNet.instance.IsServer(); StaticMembers.Dbgl("Version check, local: 1.1.5, remote: " + text, forceLog: false, (LogLevel)16); if (text != "1.1.5") { ConnectionError = "Armoire Installed: 1.1.5\n Needed: " + text; if (flag) { StaticMembers.Dbgl("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting...", forceLog: true, (LogLevel)4); rpc.Invoke("Error", new object[1] { 3 }); } } else if (flag) { StaticMembers.Dbgl("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list", forceLog: false, (LogLevel)16); ValidatedPeers.Add(rpc); } else { StaticMembers.Dbgl("Received same version from server!", forceLog: false, (LogLevel)16); ClientVersionValidated = true; } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPrefix] private static void InitiateVersionHandshake(ZNetPeer peer) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown string text = "ArmoireVersionCheck"; StaticMembers.Dbgl("Registering version RPC handler", forceLog: false, (LogLevel)16); peer.m_rpc.Register(text, (Action)RPC_ArmoireVersionCheck); StaticMembers.Dbgl("Invoking version check", forceLog: false, (LogLevel)16); ZPackage val = new ZPackage(); val.Write("1.1.5"); peer.m_rpc.Invoke(text, new object[1] { val }); } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPrefix] private static bool EnforceValidationStatus(ZRpc rpc, ref ZNet __instance) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) bool flag = __instance.IsServer(); if (ValidatedPeers.Contains(rpc) || (!flag && ClientVersionValidated)) { return true; } ConnectionError = "No Armoire version received"; if (flag) { StaticMembers.Dbgl("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting", forceLog: true, (LogLevel)4); rpc.Invoke("Error", new object[1] { 3 }); } else { StaticMembers.Dbgl("No version number received, mod may not be installed on server", forceLog: true, (LogLevel)4); Game.instance.Logout(true, true); ZNet.m_connectionStatus = (ConnectionStatus)3; } return false; } [HarmonyPatch(typeof(ZNet), "Disconnect")] [HarmonyPrefix] private static void InvalidateDisconnectingPeer(ZNetPeer peer, ref ZNet __instance) { if (__instance.IsServer()) { StaticMembers.Dbgl("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list", forceLog: false, (LogLevel)16); ValidatedPeers.Remove(peer.m_rpc); } else { ClientVersionValidated = false; } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] [HarmonyPostfix] private static void ShowConnectionError(FejdStartup __instance) { if (__instance.m_connectionFailedPanel.activeSelf) { TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + ConnectionError; } } } public class ArmoireInputMonitor : MonoBehaviour { private Button button; private Toggle toggle; public GameObject hint; public string zInputKey; public KeyCode keyCode; public void Start() { button = ((Component)this).GetComponent