using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LightMyFire")] [assembly: AssemblyFileVersion("0.5.0")] [assembly: AssemblyCompany("R4V9N1")] [assembly: AssemblyDescription("Created by R4V9N1")] [assembly: AssemblyProduct("LightMyFire")] [assembly: AssemblyCopyright("Created by R4V9N1")] [assembly: AssemblyMetadata("Creator", "Created by R4V9N1")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.5.0.0")] namespace LightMyFire; public sealed class LightMyFireBarrel : MonoBehaviour { private struct PendingReservation { public int Amount; public float ReservedAtRealtime; } private const string RpcRequestFuel = "R4V9N1_LightMyFire_RequestFuel"; private const string RpcAckApplied = "R4V9N1_LightMyFire_AckApplied"; private const string RpcRefundFuel = "R4V9N1_LightMyFire_RefundFuel"; internal const int MaxRequestPerTransaction = 50; private const float ReservationTimeoutSeconds = 30f; private static readonly List ActiveBarrels = new List(); private ZNetView _nview; private Container _container; private Inventory _inventory; [SerializeField] private string _fuelItemName; private bool _rpcRegistered; private bool _inventoryHooksRegistered; private bool _runtimeInitialized; private bool _sanitizingInventory; private readonly Dictionary _pendingReservations = new Dictionary(); private float _nextReservationSweep; internal string FuelItemName { get { EnsureConfiguration(); return _fuelItemName; } } internal void Configure(string fuelItemName) { _fuelItemName = fuelItemName; } private void Awake() { _nview = ((Component)this).GetComponent(); _container = ((Component)this).GetComponent(); EnsureConfiguration(); } private void Start() { TryInitializeRuntime(); } private void Update() { if (!_runtimeInitialized) { TryInitializeRuntime(); } } private bool TryInitializeRuntime() { EnsureConfiguration(); if ((Object)(object)_nview == (Object)null) { _nview = ((Component)this).GetComponent(); } if ((Object)(object)_container == (Object)null) { _container = ((Component)this).GetComponent(); } if ((Object)(object)_container == (Object)null) { return false; } if (_inventory == null) { _inventory = _container.GetInventory(); } if (_inventory != null && !_inventoryHooksRegistered) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged)); LightMyFireItemFilter.RegisterFilteredInventory(_inventory, _fuelItemName); _inventoryHooksRegistered = true; } if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || _nview.GetZDO() == null || _inventory == null) { return false; } if (!_rpcRegistered) { _nview.Register("R4V9N1_LightMyFire_RequestFuel", (Action)RPC_RequestFuel); _nview.Register("R4V9N1_LightMyFire_AckApplied", (Action)RPC_AckApplied); _nview.Register("R4V9N1_LightMyFire_RefundFuel", (Action)RPC_RefundFuel); _rpcRegistered = true; } if (!ActiveBarrels.Contains(this)) { ActiveBarrels.Add(this); } _runtimeInitialized = true; LightMyFirePlugin.LogBarrelRuntimeReady(((Object)((Component)this).gameObject).name, _fuelItemName, GetFuelCount()); return true; } private void EnsureConfiguration() { if (string.IsNullOrEmpty(_fuelItemName)) { bool flag = ((Object)((Component)this).gameObject).name.IndexOf("ResinBarrel", StringComparison.OrdinalIgnoreCase) >= 0; _fuelItemName = (flag ? "$item_resin" : "$item_coal"); } } private void OnDestroy() { if (_inventory != null && _inventoryHooksRegistered) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(OnInventoryChanged)); LightMyFireItemFilter.UnregisterFilteredInventory(_inventory); _inventoryHooksRegistered = false; } _inventory = null; _runtimeInitialized = false; _rpcRegistered = false; _pendingReservations.Clear(); ActiveBarrels.Remove(this); } private void OnInventoryChanged() { if (!_sanitizingInventory) { EjectInvalidItems(); } } internal void EjectInvalidItems() { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner() || _inventory == null) { return; } EnsureConfiguration(); List allItems = _inventory.GetAllItems(); if (allItems == null || allItems.Count == 0) { return; } List list = null; for (int i = 0; i < allItems.Count; i++) { ItemData val = allItems[i]; if (val != null && val.m_shared != null && !string.Equals(val.m_shared.m_name, _fuelItemName, StringComparison.Ordinal)) { if (list == null) { list = new List(); } list.Add(val); } } if (list == null) { return; } _sanitizingInventory = true; try { for (int j = 0; j < list.Count; j++) { ItemData val2 = list[j]; _inventory.RemoveItem(val2); ItemDrop.DropItem(val2, val2.m_stack, ((Component)this).transform.position + Vector3.up * 0.5f, ((Component)this).transform.rotation); } } finally { _sanitizingInventory = false; } LightMyFirePlugin.LogInvalidItemEjection(list.Count, ((Object)((Component)this).gameObject).name); } internal void SweepStaleReservations() { if (_pendingReservations.Count == 0 || (Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner()) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup < _nextReservationSweep) { return; } _nextReservationSweep = realtimeSinceStartup + 5f; List list = null; foreach (KeyValuePair pendingReservation in _pendingReservations) { if (realtimeSinceStartup - pendingReservation.Value.ReservedAtRealtime >= 30f) { if (list == null) { list = new List(); } list.Add(pendingReservation.Key); } } if (list == null) { return; } for (int i = 0; i < list.Count; i++) { long key = list[i]; if (_pendingReservations.TryGetValue(key, out var value)) { _pendingReservations.Remove(key); RefundLocally(value.Amount); } } } private bool CanReceiveRequest(Vector3 targetPosition, float rangeSqr) { //IL_0063: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)this == (Object)null || !((Behaviour)this).isActiveAndEnabled) { return false; } if (!_runtimeInitialized && !TryInitializeRuntime()) { return false; } if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.HasOwner() || (Object)(object)_container == (Object)null) { return false; } Vector3 val = ((Component)this).transform.position - targetPosition; return ((Vector3)(ref val)).sqrMagnitude <= rangeSqr; } internal int GetFuelCount() { EnsureConfiguration(); if (_inventory == null && (Object)(object)_container != (Object)null) { _inventory = _container.GetInventory(); } if (_inventory != null) { return _inventory.CountItems(_fuelItemName, -1, false); } return 0; } private int RemoveFuelLocally(int requested) { if (requested <= 0 || _inventory == null) { return 0; } int num = _inventory.CountItems(_fuelItemName, -1, false); int num2 = Math.Min(num, requested); if (num2 <= 0) { return 0; } _inventory.RemoveItem(_fuelItemName, num2, -1, false); int num3 = _inventory.CountItems(_fuelItemName, -1, false); return Mathf.Clamp(num - num3, 0, num2); } private void RefundLocally(int amount) { if (amount > 0 && _inventory != null) { EnsureConfiguration(); _inventory.AddItem(_fuelItemName, amount, 1, 0, 0L, string.Empty, false); } } private void RPC_RequestFuel(long sender, long transactionId, ZDOID fireplaceId, int requestedAmount) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_0070: Unknown result type (might be due to invalid IL or missing references) if (!LightMyFirePlugin.IsEnabled() || (Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner() || _inventory == null || _pendingReservations.ContainsKey(transactionId)) { return; } int num = Mathf.Clamp(requestedAmount, 0, 50); if (num > 0) { EnsureConfiguration(); int num2 = RemoveFuelLocally(num); if (num2 <= 0) { LightMyFireFeeder.SendGrant(transactionId, GetZdoId(), fireplaceId, 0); return; } _pendingReservations[transactionId] = new PendingReservation { Amount = num2, ReservedAtRealtime = Time.realtimeSinceStartup }; LightMyFireFeeder.SendGrant(transactionId, GetZdoId(), fireplaceId, num2); } } private void RPC_AckApplied(long sender, long transactionId) { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && _nview.IsOwner()) { _pendingReservations.Remove(transactionId); } } private void RPC_RefundFuel(long sender, long transactionId, int amount) { if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && _nview.IsOwner() && _pendingReservations.TryGetValue(transactionId, out var value)) { _pendingReservations.Remove(transactionId); int amount2 = Mathf.Clamp(amount, 0, value.Amount); RefundLocally(amount2); } } internal ZDOID GetZdoId() { //IL_0027: 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) return (((Object)(object)_nview == (Object)null) ? null : _nview.GetZDO())?.m_uid ?? ZDOID.None; } internal void SendRequestFuel(long transactionId, ZDOID fireplaceId, int requestedAmount) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.HasOwner()) { _nview.InvokeRPC("R4V9N1_LightMyFire_RequestFuel", new object[3] { transactionId, fireplaceId, Mathf.Clamp(requestedAmount, 0, 50) }); } } internal void SendAckApplied(long transactionId) { if ((Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.HasOwner()) { _nview.InvokeRPC("R4V9N1_LightMyFire_AckApplied", new object[1] { transactionId }); } } internal void SendRefundFuel(long transactionId, int amount) { if ((Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.HasOwner() && amount > 0) { _nview.InvokeRPC("R4V9N1_LightMyFire_RefundFuel", new object[2] { transactionId, amount }); } } internal static LightMyFireBarrel FindByZdoId(ZDOID id) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) if (id == ZDOID.None) { return null; } for (int num = ActiveBarrels.Count - 1; num >= 0; num--) { LightMyFireBarrel lightMyFireBarrel = ActiveBarrels[num]; if ((Object)(object)lightMyFireBarrel == (Object)null) { ActiveBarrels.RemoveAt(num); } else if (lightMyFireBarrel.GetZdoId() == id) { return lightMyFireBarrel; } } return null; } internal static bool TryFindActiveMatchingBarrels(string fuelItemName, List results) { results.Clear(); for (int num = ActiveBarrels.Count - 1; num >= 0; num--) { LightMyFireBarrel lightMyFireBarrel = ActiveBarrels[num]; if ((Object)(object)lightMyFireBarrel == (Object)null) { ActiveBarrels.RemoveAt(num); } else { lightMyFireBarrel.EnsureConfiguration(); if (string.Equals(lightMyFireBarrel._fuelItemName, fuelItemName, StringComparison.Ordinal)) { results.Add(lightMyFireBarrel); } } } return results.Count > 0; } internal bool IsWithinRange(Vector3 targetPosition, float rangeSqr) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CanReceiveRequest(targetPosition, rangeSqr); } internal static bool HasActiveBarrels() { for (int num = ActiveBarrels.Count - 1; num >= 0; num--) { if ((Object)(object)ActiveBarrels[num] == (Object)null) { ActiveBarrels.RemoveAt(num); } } if (ActiveBarrels.Count == 0) { LightMyFireBarrel[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (LightMyFireBarrel lightMyFireBarrel in array) { if ((Object)(object)lightMyFireBarrel != (Object)null) { lightMyFireBarrel.TryInitializeRuntime(); } } } return ActiveBarrels.Count > 0; } internal static void TickMaintenance() { for (int num = ActiveBarrels.Count - 1; num >= 0; num--) { LightMyFireBarrel lightMyFireBarrel = ActiveBarrels[num]; if ((Object)(object)lightMyFireBarrel == (Object)null) { ActiveBarrels.RemoveAt(num); } else { lightMyFireBarrel.SweepStaleReservations(); } } } internal static void EjectInvalidItemsFromOwnedBarrels() { for (int num = ActiveBarrels.Count - 1; num >= 0; num--) { LightMyFireBarrel lightMyFireBarrel = ActiveBarrels[num]; if ((Object)(object)lightMyFireBarrel == (Object)null) { ActiveBarrels.RemoveAt(num); } else { lightMyFireBarrel.EjectInvalidItems(); } } } } internal static class LightMyFireFeeder { private struct OutboundState { public LightMyFireBarrel Barrel; public ZDOID FireplaceId; public int RequestedAmount; public float SentAtRealtime; } private readonly struct BarrelDistance { public readonly LightMyFireBarrel Barrel; public readonly float DistanceSqr; public BarrelDistance(LightMyFireBarrel barrel, float distanceSqr) { Barrel = barrel; DistanceSqr = distanceSqr; } } internal const string RpcGrantFuel = "R4V9N1_LightMyFire_GrantFuel"; private const float OutboundRequestTimeoutSeconds = 20f; private static readonly Dictionary PendingOutbound = new Dictionary(); private static readonly HashSet FireplacesAwaitingResponse = new HashSet(); private static long _txCounter; private static long NextTransactionId() { long uID = ZNet.GetUID(); _txCounter++; return (uID << 20) ^ (_txCounter & 0xFFFFF); } internal static void PruneStaleOutbound() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (PendingOutbound.Count == 0) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; List list = null; foreach (KeyValuePair item in PendingOutbound) { if (realtimeSinceStartup - item.Value.SentAtRealtime >= 20f) { if (list == null) { list = new List(); } list.Add(item.Key); } } if (list == null) { return; } for (int i = 0; i < list.Count; i++) { if (PendingOutbound.TryGetValue(list[i], out var value)) { PendingOutbound.Remove(list[i]); FireplacesAwaitingResponse.Remove(value.FireplaceId); } } } internal static void ScanAndRequestRefills() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) PruneStaleOutbound(); if (!LightMyFireBarrel.HasActiveBarrels()) { return; } Fireplace[] array = Object.FindObjectsByType((FindObjectsInactive)0, (FindObjectsSortMode)0); if (array == null || array.Length == 0) { LightMyFirePlugin.LogScanSummary(0, 0, 0, 0, 0, 0); return; } int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; float feedRange = LightMyFirePlugin.GetFeedRange(); float rangeSqr = feedRange * feedRange; List list = new List(); List list2 = new List(); foreach (Fireplace val in array) { if ((Object)(object)val == (Object)null) { continue; } ZNetView val2 = ResolveNetworkView(val); if ((Object)(object)val2 == (Object)null || !val2.IsValid() || !val2.IsOwner()) { continue; } num++; ZDO zDO = val2.GetZDO(); if (zDO == null) { continue; } ZDOID uid = zDO.m_uid; if (FireplacesAwaitingResponse.Contains(uid)) { continue; } string supportedFuelItemName = LightMyFirePlugin.GetSupportedFuelItemName(val); if (supportedFuelItemName == null) { continue; } num2++; float num6 = zDO.GetFloat(ZDOVars.s_fuel, 0f); int num7 = Mathf.FloorToInt(val.m_maxFuel - num6 + 0.001f); if (num7 <= 0) { continue; } num3++; if (!LightMyFireBarrel.TryFindActiveMatchingBarrels(supportedFuelItemName, list)) { continue; } Vector3 position = ((Component)val).transform.position; list2.Clear(); for (int j = 0; j < list.Count; j++) { LightMyFireBarrel lightMyFireBarrel = list[j]; if (lightMyFireBarrel.IsWithinRange(position, rangeSqr)) { Vector3 val3 = ((Component)lightMyFireBarrel).transform.position - position; list2.Add(new BarrelDistance(lightMyFireBarrel, ((Vector3)(ref val3)).sqrMagnitude)); } } if (list2.Count != 0) { num4++; list2.Sort(delegate(BarrelDistance left, BarrelDistance right) { float distanceSqr = left.DistanceSqr; return distanceSqr.CompareTo(right.DistanceSqr); }); LightMyFireBarrel barrel = list2[0].Barrel; int num8 = Mathf.Min(num7, 50); if (num8 > 0) { long num9 = NextTransactionId(); PendingOutbound[num9] = new OutboundState { Barrel = barrel, FireplaceId = uid, RequestedAmount = num8, SentAtRealtime = Time.realtimeSinceStartup }; FireplacesAwaitingResponse.Add(uid); barrel.SendRequestFuel(num9, uid, num8); num5++; } } } LightMyFirePlugin.LogScanSummary(array.Length, num, num2, num3, num4, num5); } internal static void SendGrant(long transactionId, ZDOID barrelId, ZDOID fireplaceId, int grantedAmount) { //IL_0014: 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_004f: Unknown result type (might be due to invalid IL or missing references) if (ZRoutedRpc.instance == null || ZDOMan.instance == null) { return; } ZDO zDO = ZDOMan.instance.GetZDO(fireplaceId); if (zDO != null) { long owner = zDO.GetOwner(); if (owner != 0L) { ZRoutedRpc.instance.InvokeRoutedRPC(owner, "R4V9N1_LightMyFire_GrantFuel", new object[4] { transactionId, barrelId, fireplaceId, grantedAmount }); } } } internal static void RPC_GrantFuel(long sender, long transactionId, ZDOID barrelId, ZDOID fireplaceId, int grantedAmount) { //IL_0039: 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_0053: Unknown result type (might be due to invalid IL or missing references) LightMyFireBarrel lightMyFireBarrel = null; OutboundState value; bool flag = PendingOutbound.TryGetValue(transactionId, out value); if (flag) { PendingOutbound.Remove(transactionId); FireplacesAwaitingResponse.Remove(value.FireplaceId); lightMyFireBarrel = value.Barrel; } else { lightMyFireBarrel = LightMyFireBarrel.FindByZdoId(barrelId); } if (grantedAmount <= 0) { return; } if (!flag) { RefundToBarrel(lightMyFireBarrel, transactionId, grantedAmount); return; } int num = TryApplyFuelToFireplace(fireplaceId, grantedAmount); int num2 = grantedAmount - num; if (num2 > 0) { RefundToBarrel(lightMyFireBarrel, transactionId, num2); } else if ((Object)(object)lightMyFireBarrel != (Object)null) { lightMyFireBarrel.SendAckApplied(transactionId); } } private static void RefundToBarrel(LightMyFireBarrel barrel, long transactionId, int amount) { if ((Object)(object)barrel != (Object)null && amount > 0) { barrel.SendRefundFuel(transactionId, amount); } } private static int TryApplyFuelToFireplace(ZDOID fireplaceId, int grantedAmount) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return 0; } GameObject val = ZNetScene.instance.FindInstance(fireplaceId); if ((Object)(object)val == (Object)null) { return 0; } Fireplace val2 = val.GetComponent(); if ((Object)(object)val2 == (Object)null) { val2 = val.GetComponentInChildren(true); } ZNetView val3 = ResolveNetworkView(val2); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || !val3.IsValid() || !val3.IsOwner()) { return 0; } ZDO zDO = val3.GetZDO(); if (zDO == null) { return 0; } float num = zDO.GetFloat(ZDOVars.s_fuel, 0f); int num2 = Mathf.Clamp(Mathf.FloorToInt(val2.m_maxFuel - num + 0.001f), 0, 50); int num3 = Mathf.Min(grantedAmount, num2); if (num3 <= 0) { return 0; } val2.AddFuel((float)num3); LightMyFirePlugin.LogTransfer(num3, LightMyFirePlugin.GetSupportedFuelItemName(val2), val2); return num3; } private static ZNetView ResolveNetworkView(Fireplace fireplace) { if ((Object)(object)fireplace == (Object)null) { return null; } ZNetView component = ((Component)fireplace).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } component = ((Component)fireplace).GetComponentInParent(); if ((Object)(object)component != (Object)null) { return component; } return ((Component)fireplace).GetComponentInChildren(true); } } internal static class LightMyFireItemFilter { private static readonly ConditionalWeakTable> FilteredInventories = new ConditionalWeakTable>(); internal static void RegisterFilteredInventory(Inventory inventory, string fuelItemName) { if (inventory != null && !string.IsNullOrEmpty(fuelItemName)) { if (FilteredInventories.TryGetValue(inventory, out var value)) { value.Value = fuelItemName; } else { FilteredInventories.Add(inventory, new StrongBox(fuelItemName)); } } } internal static void UnregisterFilteredInventory(Inventory inventory) { if (inventory != null) { FilteredInventories.Remove(inventory); } } internal static bool TryGetExpectedFuel(Inventory inventory, out string fuelItemName) { fuelItemName = null; if (inventory == null) { return false; } if (!FilteredInventories.TryGetValue(inventory, out var value) || value == null || string.IsNullOrEmpty(value.Value)) { return false; } fuelItemName = value.Value; return true; } internal static bool IsRejected(Inventory inventory, ItemData item) { if (!TryGetExpectedFuel(inventory, out var fuelItemName) || item == null || item.m_shared == null) { return false; } return !IsAcceptedFuelName(fuelItemName, item.m_shared.m_name); } internal static bool IsRejectedInvocation(Inventory inventory, MethodBase method, object[] args, out string rejectedItemName, out string expectedFuelName) { rejectedItemName = null; expectedFuelName = null; if (!TryGetExpectedFuel(inventory, out expectedFuelName) || method == null || args == null) { return false; } ParameterInfo[] parameters = method.GetParameters(); foreach (object obj in args) { if (obj == null) { continue; } ItemData val = (ItemData)((obj is ItemData) ? obj : null); if (val != null && val.m_shared != null) { string name = val.m_shared.m_name; if (!IsAcceptedFuelName(expectedFuelName, name)) { rejectedItemName = name; return true; } continue; } ItemDrop val2 = (ItemDrop)((obj is ItemDrop) ? obj : null); if ((Object)(object)val2 != (Object)null && val2.m_itemData != null && val2.m_itemData.m_shared != null) { string name2 = val2.m_itemData.m_shared.m_name; if (!IsAcceptedFuelName(expectedFuelName, name2)) { rejectedItemName = name2; return true; } continue; } GameObject val3 = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val3 != (Object)null)) { continue; } ItemDrop component = val3.GetComponent(); if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null) { string name3 = component.m_itemData.m_shared.m_name; if (!IsAcceptedFuelName(expectedFuelName, name3)) { rejectedItemName = name3; return true; } } } if (string.Equals(method.Name, "AddItem", StringComparison.Ordinal) || string.Equals(method.Name, "CanAddItem", StringComparison.Ordinal)) { int num = Math.Min(parameters.Length, args.Length); for (int j = 0; j < num; j++) { if (parameters[j].ParameterType != typeof(string) || !(args[j] is string)) { continue; } string text = (parameters[j].Name ?? string.Empty).ToLowerInvariant(); if (!text.Contains("crafter") && !text.Contains("player") && !text.Contains("creator") && (text == "name" || text.Contains("item") || text.Contains("prefab") || text.Contains("shared"))) { string text2 = (string)args[j]; if (IsAcceptedFuelName(expectedFuelName, text2)) { break; } rejectedItemName = text2; return true; } } } if (IsBulkMoveMethod(method.Name)) { foreach (object obj2 in args) { Inventory val4 = (Inventory)((obj2 is Inventory) ? obj2 : null); if (val4 == null || val4 == inventory) { continue; } List allItems = val4.GetAllItems(); if (allItems == null) { continue; } for (int l = 0; l < allItems.Count; l++) { ItemData val5 = allItems[l]; if (val5 != null && val5.m_shared != null) { string name4 = val5.m_shared.m_name; if (!IsAcceptedFuelName(expectedFuelName, name4)) { rejectedItemName = name4; return true; } } } } } return false; } private static bool IsBulkMoveMethod(string methodName) { if (!string.Equals(methodName, "MoveAll", StringComparison.Ordinal) && !string.Equals(methodName, "MoveInventoryToThis", StringComparison.Ordinal)) { return string.Equals(methodName, "MoveAllToThis", StringComparison.Ordinal); } return true; } internal static bool IsAcceptedFuelName(string expectedFuelName, string actualItemName) { if (string.IsNullOrEmpty(expectedFuelName) || string.IsNullOrEmpty(actualItemName)) { return false; } if (string.Equals(expectedFuelName, actualItemName, StringComparison.Ordinal)) { return true; } if (string.Equals(expectedFuelName, "$item_coal", StringComparison.Ordinal)) { return string.Equals(actualItemName, "Coal", StringComparison.OrdinalIgnoreCase); } if (string.Equals(expectedFuelName, "$item_resin", StringComparison.Ordinal)) { return string.Equals(actualItemName, "Resin", StringComparison.OrdinalIgnoreCase); } return false; } } internal static class LightMyFireHarmonyPatches { private static class InventoryItemGatePatch { public static bool Prefix(Inventory __instance, MethodBase __originalMethod, object[] __args) { if (!LightMyFireItemFilter.IsRejectedInvocation(__instance, __originalMethod, __args, out var rejectedItemName, out var expectedFuelName)) { return true; } LightMyFirePlugin.LogRejectedInsertion(expectedFuelName, rejectedItemName, (__originalMethod == null) ? "Inventory" : __originalMethod.Name); return false; } } private static Harmony _harmony; internal static void Apply(ManualLogSource log) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _harmony = new Harmony("r4v9n1.lightmyfire"); PatchCurrentInventoryEntryPoints(log); } internal static void Unpatch() { if (_harmony != null) { _harmony.UnpatchSelf(); _harmony = null; } } private static void PatchCurrentInventoryEntryPoints(ManualLogSource log) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown int num = 0; HashSet hashSet = new HashSet(); List declaredMethods = AccessTools.GetDeclaredMethods(typeof(Inventory)); for (int i = 0; i < declaredMethods.Count; i++) { MethodInfo methodInfo = declaredMethods[i]; if (methodInfo == null || hashSet.Contains(methodInfo) || !IsInsertionOrCheckMethod(methodInfo.Name)) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); bool flag = false; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; if (typeof(ItemData).IsAssignableFrom(parameterType) || typeof(ItemDrop).IsAssignableFrom(parameterType) || typeof(GameObject).IsAssignableFrom(parameterType) || parameterType == typeof(string) || (IsBulkMoveMethod(methodInfo.Name) && typeof(Inventory).IsAssignableFrom(parameterType))) { flag = true; break; } } if (flag) { try { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(InventoryItemGatePatch), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); hashSet.Add(methodInfo); num++; } catch (Exception ex) { log.LogWarning((object)("[LightMyFire] Could not patch current Inventory method " + Describe(methodInfo) + ": " + ex.Message)); } } } if (num > 0) { log.LogInfo((object)("[LightMyFire] Strict fuel-only item filter attached to " + num + " current Inventory insertion/check method(s).")); } else { log.LogWarning((object)"[LightMyFire] No compatible Inventory insertion methods were found to patch. Owner-side barrel sanitation remains active as a safety net."); } } private static bool IsInsertionOrCheckMethod(string methodName) { if (!string.Equals(methodName, "AddItem", StringComparison.Ordinal) && !string.Equals(methodName, "CanAddItem", StringComparison.Ordinal) && !string.Equals(methodName, "MoveItemToThis", StringComparison.Ordinal)) { return IsBulkMoveMethod(methodName); } return true; } private static bool IsBulkMoveMethod(string methodName) { if (!string.Equals(methodName, "MoveAll", StringComparison.Ordinal) && !string.Equals(methodName, "MoveInventoryToThis", StringComparison.Ordinal)) { return string.Equals(methodName, "MoveAllToThis", StringComparison.Ordinal); } return true; } private static string Describe(MethodInfo method) { ParameterInfo[] parameters = method.GetParameters(); string[] array = new string[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = parameters[i].ParameterType.Name; } return method.Name + "(" + string.Join(", ", array) + ")"; } } [BepInPlugin("r4v9n1.lightmyfire", "LightMyFire", "0.5.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class LightMyFirePlugin : BaseUnityPlugin { public const string PluginGuid = "r4v9n1.lightmyfire"; public const string PluginName = "LightMyFire"; public const string PluginVersion = "0.5.0"; public const string CreatorCredit = "Created by R4V9N1"; internal const string CoalItemName = "$item_coal"; internal const string ResinItemName = "$item_resin"; internal const string CoalBarrelPrefabName = "R4V9N1_LightMyFireCoalBarrel"; internal const string ResinBarrelPrefabName = "R4V9N1_LightMyFireResinBarrel"; private const string AssetBundleResourceName = "LightMyFire.Assets.lightmyfire_assets"; private const string CoalVisualAssetPath = "Assets/LightMyFire/Generated/Prefabs/LightMyFire_CoalBarrelVisual.prefab"; private const string ResinVisualAssetPath = "Assets/LightMyFire/Generated/Prefabs/LightMyFire_ResinBarrelVisual.prefab"; private static ConfigEntry _enabled; private static ConfigEntry _feedRange; private static ConfigEntry _refillIntervalMinutes; private static ConfigEntry _logTransfers; private static ConfigEntry _logDiagnostics; private static ManualLogSource _log; private bool _piecesRegistered; private float _nextRefillScan; private float _nextMaintenanceTick; private ZRoutedRpc _registeredRoutedRpcInstance; private AssetBundle _assetBundle; private GameObject _coalVisualPrefab; private GameObject _resinVisualPrefab; private void Awake() { //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) //IL_0037: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0077: 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_0084: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00c4: 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_00d1: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown _log = ((BaseUnityPlugin)this).Logger; _enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, new ConfigDescription("Enable automatic coal and resin feeding. Server-controlled.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); _feedRange = ((BaseUnityPlugin)this).Config.Bind("Feeding", "Range", 50f, new ConfigDescription("Maximum distance in metres from a matching LightMyFire barrel to a compatible light source. Server-controlled.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 100f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); _refillIntervalMinutes = ((BaseUnityPlugin)this).Config.Bind("Feeding", "RefillIntervalMinutes", 5f, new ConfigDescription("How often LightMyFire checks for compatible lights that need topping up, in minutes. Server-controlled.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 60f), new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); _logTransfers = ((BaseUnityPlugin)this).Config.Bind("Diagnostics", "LogTransfers", false, "Log successful automatic fuel transfers. Local/diagnostic only, not synced."); _logDiagnostics = ((BaseUnityPlugin)this).Config.Bind("Diagnostics", "LogDiagnostics", false, "Log barrel runtime initialization and refill-scan summaries. Useful when diagnosing a light that is not being fed."); if (Mathf.Approximately(_refillIntervalMinutes.Value, 15f)) { _refillIntervalMinutes.Value = 5f; ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated Feeding > RefillIntervalMinutes from the old 15-minute default to 5 minutes."); } _nextRefillScan = Time.realtimeSinceStartup + 10f; _nextMaintenanceTick = Time.realtimeSinceStartup + 5f; LightMyFireHarmonyPatches.Apply(((BaseUnityPlugin)this).Logger); if (!LoadVisualAssets()) { ((BaseUnityPlugin)this).Logger.LogError((object)"LightMyFire could not load its embedded barrel models; piece registration is disabled."); return; } PrefabManager.OnVanillaPrefabsAvailable += RegisterBarrels; ((BaseUnityPlugin)this).Logger.LogInfo((object)"LightMyFire 0.5.0 loaded."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"A shared timed scan tops up under-fueled coal and resin lights from matching barrels."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Created by R4V9N1."); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterBarrels; LightMyFireHarmonyPatches.Unpatch(); if ((Object)(object)_assetBundle != (Object)null) { _assetBundle.Unload(false); _assetBundle = null; } } private bool LoadVisualAssets() { try { using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("LightMyFire.Assets.lightmyfire_assets")) { if (stream == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Missing embedded resource 'LightMyFire.Assets.lightmyfire_assets'."); return false; } byte[] array = new byte[stream.Length]; int i; int num; for (i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } if (i != array.Length) { ((BaseUnityPlugin)this).Logger.LogError((object)"The embedded barrel AssetBundle could not be read completely."); return false; } _assetBundle = AssetBundle.LoadFromMemory(array); } if ((Object)(object)_assetBundle == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Unity could not load the embedded barrel AssetBundle."); return false; } _coalVisualPrefab = _assetBundle.LoadAsset("Assets/LightMyFire/Generated/Prefabs/LightMyFire_CoalBarrelVisual.prefab"); _resinVisualPrefab = _assetBundle.LoadAsset("Assets/LightMyFire/Generated/Prefabs/LightMyFire_ResinBarrelVisual.prefab"); if ((Object)(object)_coalVisualPrefab == (Object)null || (Object)(object)_resinVisualPrefab == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"The embedded AssetBundle is missing one or both barrel visual prefabs."); return false; } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded custom coal and resin barrel models from the embedded Unity AssetBundle."); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load custom barrel models: " + ex)); return false; } } private void Update() { if (ZRoutedRpc.instance != null && _registeredRoutedRpcInstance != ZRoutedRpc.instance) { ZRoutedRpc.instance.Register("R4V9N1_LightMyFire_GrantFuel", (Method)LightMyFireFeeder.RPC_GrantFuel); _registeredRoutedRpcInstance = ZRoutedRpc.instance; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered LightMyFire cross-peer fuel grant RPC."); } if (!_piecesRegistered) { return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup >= _nextMaintenanceTick) { _nextMaintenanceTick = realtimeSinceStartup + 10f; LightMyFireBarrel.TickMaintenance(); LightMyFireBarrel.EjectInvalidItemsFromOwnedBarrels(); } if (!IsEnabled()) { return; } if (!LightMyFireBarrel.HasActiveBarrels()) { if (realtimeSinceStartup >= _nextRefillScan) { float num = ((_refillIntervalMinutes == null) ? 5f : Mathf.Clamp(_refillIntervalMinutes.Value, 0.5f, 60f)); _nextRefillScan = realtimeSinceStartup + num * 60f; LogNoActiveBarrels(); } } else if (!(realtimeSinceStartup < _nextRefillScan)) { float num2 = ((_refillIntervalMinutes == null) ? 5f : Mathf.Clamp(_refillIntervalMinutes.Value, 0.5f, 60f)); _nextRefillScan = realtimeSinceStartup + num2 * 60f; LightMyFireFeeder.ScanAndRequestRefills(); } } private void RegisterBarrels() { if (_piecesRegistered) { return; } GameObject val = ResolveBaseBarrelPrefab(); if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not find any current Valheim build piece that behaves as a barrel/container. LightMyFire pieces were not registered."); return; } bool flag = RegisterBarrel("R4V9N1_LightMyFireCoalBarrel", "LightMyFire Coal Barrel", "Stores coal and refills empty coal-burning lights within range.", "$item_coal", _coalVisualPrefab, val); bool flag2 = RegisterBarrel("R4V9N1_LightMyFireResinBarrel", "LightMyFire Resin Barrel", "Stores resin and refills empty resin-burning lights within range.", "$item_resin", _resinVisualPrefab, val); _piecesRegistered = flag && flag2; if (_piecesRegistered) { PrefabManager.OnVanillaPrefabsAvailable -= RegisterBarrels; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered the coal and resin barrels in Hammer > Misc with 32 inventory slots each."); } } private GameObject ResolveBaseBarrelPrefab() { string[] array = new string[5] { "piece_chestbarrel", "piece_chest_barrel", "piece_barrel", "piece_barrel_wood", "barrel" }; for (int i = 0; i < array.Length; i++) { GameObject prefab = PrefabManager.Instance.GetPrefab(array[i]); if (IsUsableContainerPiece(prefab)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Using Valheim barrel base prefab '" + ((Object)prefab).name + "'.")); return prefab; } } GameObject val = null; int num = int.MinValue; foreach (KeyValuePair prefab3 in Cache.GetPrefabs(typeof(GameObject))) { Object value = prefab3.Value; GameObject val2 = (GameObject)(object)((value is GameObject) ? value : null); if (IsUsableContainerPiece(val2)) { string text = (string.IsNullOrEmpty(((Object)val2).name) ? prefab3.Key : ((Object)val2).name).ToLowerInvariant(); int num2 = 0; if (text.Contains("barrel")) { num2 += 1000; } if (text.StartsWith("piece_")) { num2 += 100; } if (text.Contains("wood")) { num2 += 30; } if (text.Contains("chest")) { num2 += 10; } if (text.Contains("blackmetal")) { num2 -= 20; } if (text.Contains("cart")) { num2 -= 500; } if (num2 > num) { val = val2; num = num2; } } } if ((Object)(object)val != (Object)null && num >= 1000) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Discovered current Valheim barrel base prefab '" + ((Object)val).name + "' dynamically.")); return val; } string[] array2 = new string[3] { "piece_chest", "piece_chest_wood", "piece_chest_private" }; for (int j = 0; j < array2.Length; j++) { GameObject prefab2 = PrefabManager.Instance.GetPrefab(array2[j]); if (IsUsableContainerPiece(prefab2)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("No barrel-named container prefab was found; using fallback container '" + ((Object)prefab2).name + "'.")); return prefab2; } } if ((Object)(object)val != (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("No barrel-named container prefab was found; using discovered container '" + ((Object)val).name + "'.")); return val; } return null; } private static bool IsUsableContainerPiece(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return false; } if ((Object)(object)prefab.GetComponent() != (Object)null && (Object)(object)prefab.GetComponent() != (Object)null && (Object)(object)prefab.GetComponent() != (Object)null && (Object)(object)prefab.GetComponent() != (Object)null) { return prefab.GetComponentsInChildren(true).Length != 0; } return false; } private bool RegisterBarrel(string prefabName, string displayName, string description, string fuelItemName, GameObject visualPrefab, GameObject baseBarrel) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown if (PieceManager.Instance.GetPiece(prefabName) != null) { return true; } PieceConfig val = new PieceConfig { Name = displayName, Description = description, PieceTable = "Hammer", Category = "Misc", CraftingStation = "Workbench" }; val.AddRequirement("Wood", 100, true); val.AddRequirement("Iron", 40, true); val.AddRequirement("Tar", 40, true); CustomPiece val2 = new CustomPiece(prefabName, ((Object)baseBarrel).name, val); GameObject piecePrefab = val2.PiecePrefab; if ((Object)(object)piecePrefab == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Jotunn could not clone custom piece '" + prefabName + "' from base '" + ((Object)baseBarrel).name + "'.")); return false; } if (!ValidateNativeBarrelClone(piecePrefab, out var error)) { ((BaseUnityPlugin)this).Logger.LogError((object)("Native barrel clone validation failed for '" + prefabName + "': " + error + ". Piece registration was cancelled.")); Object.Destroy((Object)(object)piecePrefab); return false; } Container component = piecePrefab.GetComponent(); component.m_name = displayName; component.m_width = 8; component.m_height = 4; component.m_autoDestroyEmpty = false; LightMyFireBarrel lightMyFireBarrel = piecePrefab.GetComponent(); if ((Object)(object)lightMyFireBarrel == (Object)null) { lightMyFireBarrel = piecePrefab.AddComponent(); } lightMyFireBarrel.Configure(fuelItemName); if (!AttachNativeRangeMarker(piecePrefab)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not attach LightMyFire dotted feeding-radius ring to '" + displayName + "'. The barrel will still function, but its feeding-radius ring will be unavailable.")); } if (!AttachBarrelDecoration(piecePrefab, visualPrefab)) { ((BaseUnityPlugin)this).Logger.LogError((object)("Could not attach the barrel decoration for '" + displayName + "'; registration was cancelled.")); Object.Destroy((Object)(object)piecePrefab); return false; } PieceManager.Instance.AddPiece(val2); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Prepared '" + displayName + "' as a Jotunn native clone of '" + ((Object)baseBarrel).name + "' with " + piecePrefab.GetComponentsInChildren(true).Length + " native collider(s); custom lid/plaque are visual-only.")); return true; } private static bool AttachNativeRangeMarker(GameObject prefab) { //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01b1: 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_00bb: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return false; } try { Material val = null; GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_workbench"); if ((Object)(object)prefab2 != (Object)null) { CraftingStation component = prefab2.GetComponent(); if ((Object)(object)component != (Object)null) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = typeof(CraftingStation).GetField("m_areaMarker", bindingAttr); GameObject val2 = (GameObject)((field == null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val2 != (Object)null) { Renderer componentInChildren = val2.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sharedMaterial != (Object)null) { val = new Material(componentInChildren.sharedMaterial); ((Object)val).name = "LightMyFire_DottedRangeMaterial"; if (val.HasProperty("_Color")) { val.SetColor("_Color", new Color(1f, 1f, 1f, 0.92f)); } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", new Color(1f, 1f, 1f, 0.92f)); } val.renderQueue = 3100; if (val.HasProperty("_ZWrite")) { val.SetInt("_ZWrite", 0); } } } } } if ((Object)(object)val == (Object)null) { Shader val3 = Shader.Find("Sprites/Default"); if ((Object)(object)val3 == (Object)null) { val3 = Shader.Find("Unlit/Transparent"); } if ((Object)(object)val3 == (Object)null) { return false; } val = new Material(val3); ((Object)val).name = "LightMyFire_DottedRangeMaterial"; val.color = new Color(1f, 1f, 1f, 0.92f); val.renderQueue = 3100; } GameObject val4 = new GameObject("R4V9N1_LightMyFire_RangeMarker"); val4.transform.SetParent(prefab.transform, false); val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = Quaternion.identity; val4.transform.localScale = Vector3.one; val4.AddComponent(); MeshRenderer obj = val4.AddComponent(); ((Renderer)obj).sharedMaterial = val; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; val4.SetActive(false); LightMyFireRangeMarker lightMyFireRangeMarker = prefab.GetComponent(); if ((Object)(object)lightMyFireRangeMarker == (Object)null) { lightMyFireRangeMarker = prefab.AddComponent(); } lightMyFireRangeMarker.Configure(val4); return true; } catch (Exception ex) { if (_log != null) { _log.LogWarning((object)("Failed to prepare dotted feeding-radius ring: " + ex.Message)); } return false; } } private static bool AttachBarrelDecoration(GameObject prefab, GameObject visualPrefab) { //IL_0043: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null || (Object)(object)visualPrefab == (Object)null) { return false; } if (!TryGetPhysicalLocalBounds(prefab.transform, out var bounds)) { Renderer[] componentsInChildren = prefab.GetComponentsInChildren(false); if (componentsInChildren.Length == 0) { return false; } bounds = GetCombinedLocalBounds(prefab.transform, componentsInChildren); } float num = Mathf.Min(((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.z); if (num <= 0.05f || float.IsNaN(num) || float.IsInfinity(num)) { return false; } GameObject val = Object.Instantiate(visualPrefab, prefab.transform, false); ((Object)val).name = "LightMyFireDecoration"; val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; if (val.GetComponentsInChildren(true).Length == 0) { Object.Destroy((Object)(object)val); return false; } Collider[] componentsInChildren2 = val.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.Destroy((Object)(object)componentsInChildren2[i]); } Transform val2 = val.transform.Find("MetalLid"); Transform val3 = val.transform.Find("FrontPlaque"); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { Object.Destroy((Object)(object)val); return false; } float num2 = num * 0.9f / 0.95f; val2.localScale = Vector3.one * num2; val2.localPosition = new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y + Mathf.Max(0.006f, num * 0.008f), ((Bounds)(ref bounds)).center.z); val2.localRotation = Quaternion.identity; float num3 = num * 0.42f / 0.56f; val3.localScale = new Vector3(0f - num3, num3, num3); val3.localPosition = new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).center.y + ((Bounds)(ref bounds)).size.y * 0.06f, ((Bounds)(ref bounds)).min.z - Mathf.Max(0.008f, num * 0.012f)); val3.localRotation = Quaternion.identity; return true; } private static bool ValidateNativeBarrelClone(GameObject prefab, out string error) { error = null; if ((Object)(object)prefab.GetComponent() == (Object)null) { error = "missing Piece"; return false; } if ((Object)(object)prefab.GetComponent() == (Object)null) { error = "missing ZNetView"; return false; } if ((Object)(object)prefab.GetComponent() == (Object)null) { error = "missing Container"; return false; } if ((Object)(object)prefab.GetComponent() == (Object)null) { error = "missing WearNTear"; return false; } if (prefab.GetComponentsInChildren(true).Length == 0) { error = "missing native collider hierarchy"; return false; } return true; } private static bool TryGetPhysicalLocalBounds(Transform root, out Bounds bounds) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); bool initialized = false; bounds = new Bounds(Vector3.zero, Vector3.zero); foreach (Collider val in componentsInChildren) { if ((Object)(object)val == (Object)null || val.isTrigger) { continue; } if (TryGetColliderLocalBounds(val, out var bounds2)) { EncapsulateLocalBounds(root, ((Component)val).transform, bounds2, ref bounds, ref initialized); continue; } Bounds bounds3 = val.bounds; Vector3 size = ((Bounds)(ref bounds3)).size; if (((Vector3)(ref size)).sqrMagnitude > 1E-06f) { EncapsulateWorldBounds(root, bounds3, ref bounds, ref initialized); } } return initialized; } private static bool TryGetColliderLocalBounds(Collider collider, out Bounds bounds) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //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_0022: 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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_006f: 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) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); Vector3 size; if ((Object)(object)val != (Object)null) { bounds = new Bounds(val.center, val.size); size = val.size; return ((Vector3)(ref size)).sqrMagnitude > 1E-06f; } SphereCollider val2 = (SphereCollider)(object)((collider is SphereCollider) ? collider : null); if ((Object)(object)val2 != (Object)null) { float num = val2.radius * 2f; bounds = new Bounds(val2.center, Vector3.one * num); return num > 0.0001f; } CapsuleCollider val3 = (CapsuleCollider)(object)((collider is CapsuleCollider) ? collider : null); if ((Object)(object)val3 != (Object)null) { float num2 = val3.radius * 2f; Vector3 val4 = Vector3.one * num2; float num3 = Mathf.Max(val3.height, num2); if (val3.direction == 0) { val4.x = num3; } else if (val3.direction == 1) { val4.y = num3; } else { val4.z = num3; } bounds = new Bounds(val3.center, val4); return ((Vector3)(ref val4)).sqrMagnitude > 1E-06f; } MeshCollider val5 = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if ((Object)(object)val5 != (Object)null && (Object)(object)val5.sharedMesh != (Object)null) { bounds = val5.sharedMesh.bounds; size = ((Bounds)(ref bounds)).size; return ((Vector3)(ref size)).sqrMagnitude > 1E-06f; } bounds = new Bounds(Vector3.zero, Vector3.zero); return false; } private static void EncapsulateLocalBounds(Transform root, Transform source, Bounds localBounds, ref Bounds result, ref bool initialized) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) //IL_0030: 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) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_004b: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) Vector3 min = ((Bounds)(ref localBounds)).min; Vector3 max = ((Bounds)(ref localBounds)).max; Vector3 val = default(Vector3); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { ((Vector3)(ref val))..ctor((i == 0) ? min.x : max.x, (j == 0) ? min.y : max.y, (k == 0) ? min.z : max.z); Vector3 val2 = root.InverseTransformPoint(source.TransformPoint(val)); if (!initialized) { result = new Bounds(val2, Vector3.zero); initialized = true; } else { ((Bounds)(ref result)).Encapsulate(val2); } } } } } private static void EncapsulateWorldBounds(Transform root, Bounds world, ref Bounds result, ref bool initialized) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) //IL_002d: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) Vector3 min = ((Bounds)(ref world)).min; Vector3 max = ((Bounds)(ref world)).max; Vector3 val = default(Vector3); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { ((Vector3)(ref val))..ctor((i == 0) ? min.x : max.x, (j == 0) ? min.y : max.y, (k == 0) ? min.z : max.z); Vector3 val2 = root.InverseTransformPoint(val); if (!initialized) { result = new Bounds(val2, Vector3.zero); initialized = true; } else { ((Bounds)(ref result)).Encapsulate(val2); } } } } } private static Bounds GetCombinedLocalBounds(Transform root, Renderer[] renderers) { //IL_0004: 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) //IL_003e: 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) bool initialized = false; Bounds result = default(Bounds); ((Bounds)(ref result))..ctor(Vector3.zero, Vector3.zero); for (int i = 0; i < renderers.Length; i++) { if (!((Object)(object)renderers[i] == (Object)null)) { EncapsulateWorldBounds(root, renderers[i].bounds, ref result, ref initialized); } } return result; } internal static bool IsDiagnosticsEnabled() { if (_logDiagnostics != null) { return _logDiagnostics.Value; } return false; } internal static void LogNoActiveBarrels() { if (IsDiagnosticsEnabled() && _log != null) { _log.LogWarning((object)"Refill scan skipped: no runtime-ready LightMyFire barrels are registered on this peer."); } } internal static void LogBarrelRuntimeReady(string objectName, string fuelItemName, int fuelCount) { if (IsDiagnosticsEnabled() && _log != null) { string text = (string.Equals(fuelItemName, "$item_resin", StringComparison.Ordinal) ? "resin" : "coal"); _log.LogInfo((object)("Runtime-ready " + text + " barrel '" + objectName + "' with " + fuelCount + " fuel item(s).")); } } internal static void LogScanSummary(int fireplacesFound, int ownedFireplaces, int compatibleFireplaces, int underFueledFireplaces, int inRangeMatches, int requestsSent) { if (IsDiagnosticsEnabled() && _log != null) { _log.LogInfo((object)("Refill scan: fireplaces=" + fireplacesFound + ", owned=" + ownedFireplaces + ", compatible=" + compatibleFireplaces + ", needFuel=" + underFueledFireplaces + ", inRange=" + inRangeMatches + ", requests=" + requestsSent + ".")); } } internal static bool IsEnabled() { if (_enabled != null) { return _enabled.Value; } return false; } internal static float GetFeedRange() { if (_feedRange != null) { return Mathf.Clamp(_feedRange.Value, 1f, 100f); } return 50f; } internal static void LogTransfer(int amount, string fuelItemName, Fireplace fireplace) { if (_logTransfers != null && _logTransfers.Value && _log != null && !((Object)(object)fireplace == (Object)null) && amount > 0) { string text = ((fuelItemName == "$item_resin") ? "resin" : "coal"); _log.LogInfo((object)("Topped up " + fireplace.GetHoverName() + " with " + amount + " " + text + ".")); } } internal static void LogInvalidItemEjection(int count, string barrelObjectName) { if (_log != null && count > 0) { _log.LogWarning((object)("Ejected " + count + " item stack(s) that did not match the configured fuel type from '" + barrelObjectName + "'.")); } } internal static void LogRejectedInsertion(string expectedFuelName, string rejectedItemName, string entryPoint) { if (IsDiagnosticsEnabled() && _log != null) { string text = (string.Equals(expectedFuelName, "$item_resin", StringComparison.Ordinal) ? "Resin" : "Coal"); string text2 = (string.IsNullOrEmpty(rejectedItemName) ? "unknown item" : rejectedItemName); _log.LogInfo((object)("Rejected '" + text2 + "' from " + text + " barrel via " + entryPoint + ".")); } } internal static string GetSupportedFuelItemName(Fireplace fireplace) { if ((Object)(object)fireplace == (Object)null || fireplace.m_infiniteFuel || fireplace.m_maxFuel <= 0f || (Object)(object)fireplace.m_fuelItem == (Object)null || fireplace.m_fuelItem.m_itemData == null || fireplace.m_fuelItem.m_itemData.m_shared == null) { return null; } string name = fireplace.m_fuelItem.m_itemData.m_shared.m_name; if (!string.Equals(name, "$item_coal", StringComparison.Ordinal) && !string.Equals(name, "$item_resin", StringComparison.Ordinal)) { return null; } return name; } internal static bool IsCompatibleFuelLight(Fireplace fireplace, string fuelItemName) { string supportedFuelItemName = GetSupportedFuelItemName(fireplace); if (supportedFuelItemName != null) { return string.Equals(supportedFuelItemName, fuelItemName, StringComparison.Ordinal); } return false; } } public sealed class LightMyFireRangeMarker : MonoBehaviour { private const string MarkerName = "R4V9N1_LightMyFire_RangeMarker"; private const float DotSpacingMetres = 1.25f; private const float DotLengthMetres = 0.34f; private const float DotWidthMetres = 0.14f; private const float HeightOffset = 0.055f; private const int MinDotCount = 32; private const int MaxDotCount = 512; private static readonly BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly FieldInfo PlacementGhostField = typeof(Player).GetField("m_placementGhost", Flags); private static readonly FieldInfo CurrentContainerField = typeof(InventoryGui).GetField("m_currentContainer", Flags); private static readonly MethodInfo ContainerIsInUseMethod = typeof(Container).GetMethod("IsInUse", Flags, null, Type.EmptyTypes, null); [SerializeField] private GameObject _marker; private MeshFilter _meshFilter; private Container _container; private ZNetView _nview; private Vector3 _lastMarkerWorldCenter = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity); private float _lastAppliedRange = -1f; private bool _lastVisible; internal void Configure(GameObject marker) { _marker = marker; CacheMarkerParts(); if ((Object)(object)_marker != (Object)null) { _marker.SetActive(false); } } private void Awake() { _container = ((Component)this).GetComponent(); _nview = ((Component)this).GetComponent(); RecoverMarkerReference(); if ((Object)(object)_marker != (Object)null) { _marker.SetActive(false); } } private void Start() { RecoverMarkerReference(); ApplyCurrentRange(force: true, visible: true); } private void Update() { RecoverMarkerReference(); if (!((Object)(object)_marker == (Object)null)) { bool flag = IsPlacementPreviewInstance() || IsThisPlacementGhost() || IsThisInventoryOpenLocally(); ApplyCurrentRange(force: false, flag); if (flag != _lastVisible || _marker.activeSelf != flag) { _marker.SetActive(flag); _lastVisible = flag; } } } private void RecoverMarkerReference() { if ((Object)(object)_marker == (Object)null) { Transform val = ((Component)this).transform.Find("R4V9N1_LightMyFire_RangeMarker"); if ((Object)(object)val == (Object)null) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (string.Equals(((Object)componentsInChildren[i]).name, "R4V9N1_LightMyFire_RangeMarker", StringComparison.Ordinal)) { val = componentsInChildren[i]; break; } } } if ((Object)(object)val != (Object)null) { _marker = ((Component)val).gameObject; } } CacheMarkerParts(); } private void CacheMarkerParts() { if ((Object)(object)_marker != (Object)null && (Object)(object)_meshFilter == (Object)null) { _meshFilter = _marker.GetComponent(); } } private void ApplyCurrentRange(bool force, bool visible) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_marker == (Object)null || (Object)(object)_meshFilter == (Object)null) { return; } float num = Mathf.Max(0.1f, LightMyFirePlugin.GetFeedRange()); Vector3 position = ((Component)this).transform.position; Vector3 val = position - _lastMarkerWorldCenter; bool flag = ((Vector3)(ref val)).sqrMagnitude > 0.25f; if (force || !(Mathf.Abs(num - _lastAppliedRange) < 0.01f) || (visible && flag)) { Mesh sharedMesh = _meshFilter.sharedMesh; _meshFilter.sharedMesh = BuildDottedRing(num); if ((Object)(object)sharedMesh != (Object)null && ((Object)sharedMesh).name.StartsWith("LightMyFire_DottedRange_", StringComparison.Ordinal)) { Object.Destroy((Object)(object)sharedMesh); } _lastAppliedRange = num; _lastMarkerWorldCenter = position; } } private Mesh BuildDottedRing(float radius) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: 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) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(Mathf.RoundToInt((float)Math.PI * 2f * radius / 1.25f), 32, 512); Vector3[] array = (Vector3[])(object)new Vector3[num * 4]; Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length]; Vector2[] array3 = (Vector2[])(object)new Vector2[array.Length]; int[] array4 = new int[num * 6]; float num2 = 0.17f; float num3 = 0.07f; Vector3 val = default(Vector3); RaycastHit val3 = default(RaycastHit); Vector3 val4 = default(Vector3); Vector3 val5 = default(Vector3); Vector3 val6 = default(Vector3); for (int i = 0; i < num; i++) { float num4 = (float)Math.PI * 2f * (float)i / (float)num; float num5 = Mathf.Cos(num4); float num6 = Mathf.Sin(num4); ((Vector3)(ref val))..ctor(num5 * radius, 0f, num6 * radius); Vector3 val2 = ((Component)this).transform.TransformPoint(val); float num7 = 0.055f; if (Physics.Raycast(val2 + Vector3.up * 120f, Vector3.down, ref val3, 240f, -1, (QueryTriggerInteraction)1)) { num7 = ((Component)this).transform.InverseTransformPoint(((RaycastHit)(ref val3)).point + ((RaycastHit)(ref val3)).normal * 0.055f).y; } ((Vector3)(ref val4))..ctor(num5 * radius, num7, num6 * radius); ((Vector3)(ref val5))..ctor(0f - num6, 0f, num5); ((Vector3)(ref val6))..ctor(num5, 0f, num6); int num8 = i * 4; array[num8] = val4 - val5 * num2 - val6 * num3; array[num8 + 1] = val4 + val5 * num2 - val6 * num3; array[num8 + 2] = val4 + val5 * num2 + val6 * num3; array[num8 + 3] = val4 - val5 * num2 + val6 * num3; array2[num8] = Vector3.up; array2[num8 + 1] = Vector3.up; array2[num8 + 2] = Vector3.up; array2[num8 + 3] = Vector3.up; array3[num8] = new Vector2(0f, 0f); array3[num8 + 1] = new Vector2(1f, 0f); array3[num8 + 2] = new Vector2(1f, 1f); array3[num8 + 3] = new Vector2(0f, 1f); int num9 = i * 6; array4[num9] = num8; array4[num9 + 1] = num8 + 1; array4[num9 + 2] = num8 + 2; array4[num9 + 3] = num8; array4[num9 + 4] = num8 + 2; array4[num9 + 5] = num8 + 3; } Mesh val7 = new Mesh { name = "LightMyFire_DottedRange_" + radius.ToString("0.##"), vertices = array, normals = array2, uv = array3, triangles = array4 }; val7.RecalculateBounds(); return val7; } private bool IsPlacementPreviewInstance() { if (!((Component)this).gameObject.activeInHierarchy) { return false; } if ((Object)(object)_nview == (Object)null) { _nview = ((Component)this).GetComponent(); } if (!((Object)(object)_nview == (Object)null) && _nview.IsValid()) { return _nview.GetZDO() == null; } return true; } private bool IsThisPlacementGhost() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || PlacementGhostField == null) { return false; } try { object? value = PlacementGhostField.GetValue(localPlayer); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { return false; } return (Object)(object)val == (Object)(object)((Component)this).gameObject || val.transform.IsChildOf(((Component)this).transform) || ((Component)this).transform.IsChildOf(val.transform); } catch { return false; } } private bool IsThisInventoryOpenLocally() { if ((Object)(object)_container == (Object)null) { _container = ((Component)this).GetComponent(); } if ((Object)(object)_container == (Object)null) { return false; } try { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance != (Object)null && CurrentContainerField != null && (Object)/*isinst with value type is only supported in some contexts*/ == (Object)(object)_container) { return true; } } catch { } try { return ContainerIsInUseMethod != null && (bool)ContainerIsInUseMethod.Invoke(_container, null); } catch { return false; } } private void OnDisable() { if ((Object)(object)_marker != (Object)null) { _marker.SetActive(false); } _lastVisible = false; } }