Decompiled source of StationItemReturn v1.0.0

StationItemReturn.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx;
using BepInEx.Configuration;
using ConditionalConfigSync;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Station Item Return")]
[assembly: AssemblyDescription("Returns stored items and fuel from supported Valheim stations.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("shudnal")]
[assembly: AssemblyProduct("Station Item Return")]
[assembly: AssemblyCopyright("Copyright © 2026 shudnal")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a2ef7f0f-9669-41c7-b98a-269eef06fc2e")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace StationItemReturn
{
	internal static class HoverHints
	{
		[HarmonyPatch(typeof(CookingStation), "GetHoverText")]
		private static class CookingStation_GetHoverText_AddReturnHint
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				return InjectRawReturnHint(instructions);
			}

			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPriority(0)]
			private static void Postfix(CookingStation __instance, ref string __result)
			{
				__result = AddLocalizedReturnHint(__result, __instance);
			}
		}

		[HarmonyPatch(typeof(Fireplace), "GetHoverText")]
		private static class Fireplace_GetHoverText_AddReturnHint
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				return InjectRawReturnHint(instructions);
			}

			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPriority(0)]
			private static void Postfix(Fireplace __instance, ref string __result)
			{
				__result = AddLocalizedReturnHint(__result, __instance);
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnHoverAddOre")]
		private static class Smelter_OnHoverAddOre_AddReturnHint
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				return InjectRawReturnHint(instructions);
			}

			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPriority(0)]
			private static void Postfix(Smelter __instance, ref string __result)
			{
				__result = AddLocalizedReturnHint(__result, __instance);
			}
		}

		[HarmonyPatch(typeof(Fermenter), "GetHoverText")]
		private static class Fermenter_GetHoverText_AddReturnHint
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				return InjectRawReturnHint(instructions);
			}

			[HarmonyBefore(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPriority(0)]
			private static void Postfix(Fermenter __instance, ref string __result)
			{
				__result = AddLocalizedReturnHint(__result, __instance);
			}
		}

		[HarmonyPatch(typeof(Turret), "GetHoverText")]
		private static class Turret_GetHoverText_AddReturnHint
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				return InjectRawReturnHint(instructions);
			}

			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPriority(0)]
			private static void Postfix(Turret __instance, ref string __result)
			{
				__result = AddLocalizedReturnHint(__result, __instance);
			}
		}

		[HarmonyPatch(typeof(Switch), "GetHoverText")]
		private static class Switch_GetHoverText_AddReturnHint
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				return InjectRawReturnHint(instructions);
			}

			[HarmonyAfter(new string[] { "shudnal.MyLittleUI" })]
			[HarmonyPriority(0)]
			private static void Postfix(Switch __instance, ref string __result)
			{
				__result = AddLocalizedReturnHint(__result, __instance);
			}
		}

		private const string UseKey = "$KEY_Use";

		private const string ReturnKeyCombination = "$KEY_AltPlace + $KEY_Use";

		private static readonly MethodInfo LocalizeMethod = AccessTools.Method(typeof(Localization), "Localize", new Type[1] { typeof(string) }, (Type[])null);

		private static readonly MethodInfo LocalizeWithReturnHintMethod = AccessTools.Method(typeof(HoverHints), "LocalizeWithReturnHint", new Type[3]
		{
			typeof(Localization),
			typeof(string),
			typeof(object)
		}, (Type[])null);

		private static string BuildReturnHint(string sharedName)
		{
			return "[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $hud_remove (<color=#add8e6ff>" + sharedName + "</color>)";
		}

		private static string InsertAfterFirstUseLine(string text, string hint, bool appendWhenUseIsMissing)
		{
			if (string.IsNullOrWhiteSpace(text) || string.IsNullOrEmpty(hint))
			{
				return text;
			}
			int num = text.IndexOf("$KEY_Use", StringComparison.Ordinal);
			if (num < 0)
			{
				return appendWhenUseIsMissing ? (text + "\n" + hint) : text;
			}
			int num2 = text.IndexOf('\n', num);
			if (num2 < 0)
			{
				return text + "\n" + hint;
			}
			return text.Insert(num2 + 1, hint + "\n");
		}

		private static string AddRawReturnHint(string text, object source)
		{
			if (!StationReturn.TryGetReturnableItem(source, out var sharedName) || string.IsNullOrEmpty(sharedName) || text.IndexOf("$KEY_AltPlace + $KEY_Use", StringComparison.Ordinal) >= 0)
			{
				return text;
			}
			return InsertAfterFirstUseLine(text, BuildReturnHint(sharedName), source is Fermenter);
		}

		private static string LocalizeWithReturnHint(Localization localization, string text, object source)
		{
			return localization.Localize(AddRawReturnHint(text, source));
		}

		private static string AddLocalizedReturnHint(string text, object source)
		{
			if (string.IsNullOrWhiteSpace(text) || !StationReturn.TryGetReturnableItem(source, out var sharedName) || string.IsNullOrEmpty(sharedName))
			{
				return text;
			}
			string value = Localization.instance.Localize("$KEY_AltPlace + $KEY_Use");
			if (!string.IsNullOrEmpty(value) && text.IndexOf(value, StringComparison.Ordinal) >= 0)
			{
				return text;
			}
			string text2 = Localization.instance.Localize("$KEY_Use");
			string value2 = "[<color=yellow><b>" + text2 + "</b></color>]";
			string text3 = Localization.instance.Localize(BuildReturnHint(sharedName));
			int num = text.IndexOf(value2, StringComparison.Ordinal);
			if (num < 0)
			{
				return (source is Fermenter) ? (text + "\n" + text3) : text;
			}
			int num2 = text.IndexOf('\n', num);
			if (num2 < 0)
			{
				return text + "\n" + text3;
			}
			return text.Insert(num2 + 1, text3 + "\n");
		}

		private static IEnumerable<CodeInstruction> InjectRawReturnHint(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				if (LocalizeMethod != null && LocalizeWithReturnHintMethod != null && CodeInstructionExtensions.Calls(instruction, LocalizeMethod))
				{
					CodeInstruction loadSource = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					loadSource.labels.AddRange(instruction.labels);
					instruction.labels.Clear();
					yield return loadSource;
					instruction.opcode = OpCodes.Call;
					instruction.operand = LocalizeWithReturnHintMethod;
				}
				yield return instruction;
			}
		}
	}
	[BepInPlugin("shudnal.StationItemReturn", "Station Item Return", "1.0.0")]
	[BepInDependency("_shudnal.ConditionalConfigSync", "1.0.6")]
	public sealed class StationItemReturn : BaseUnityPlugin
	{
		private sealed class ConfigurationManagerAttributes
		{
			public bool? ShowRangeAsPercent = false;
		}

		public const string PluginId = "shudnal.StationItemReturn";

		public const string PluginName = "Station Item Return";

		public const string PluginVersion = "1.0.0";

		public const string ConditionalConfigSyncGuid = "_shudnal.ConditionalConfigSync";

		internal static readonly ConfigSync ConfigSync = new ConfigSync("shudnal.StationItemReturn")
		{
			DisplayName = "Station Item Return",
			CurrentVersion = "1.0.0",
			MinimumRequiredVersion = "1.0.0",
			ModRequired = false,
			ModRequirementMode = (ModRequirementMode)0
		};

		internal static StationItemReturn Instance;

		internal static ConfigEntry<bool> ModEnabled;

		internal static ConfigEntry<bool> ConfigLocked;

		internal static ConfigEntry<bool> LoggingEnabled;

		internal static ConfigEntry<bool> CookingStationItemReturnEnabled;

		internal static ConfigEntry<float> CookingStationItemReturnProgressLimit;

		internal static ConfigEntry<bool> CookingStationFuelReturnEnabled;

		internal static ConfigEntry<bool> FireplaceFuelReturnEnabled;

		internal static ConfigEntry<string> FireplaceExcludedPrefabs;

		internal static ConfigEntry<bool> SmelterInputReturnEnabled;

		internal static ConfigEntry<bool> SmelterFuelReturnEnabled;

		internal static ConfigEntry<string> SmelterFuelExcludedPrefabs;

		internal static ConfigEntry<bool> FermenterIngredientReturnEnabled;

		internal static ConfigEntry<float> FermenterIngredientReturnProgressLimit;

		internal static ConfigEntry<bool> TurretAmmoReturnEnabled;

		private static readonly HashSet<string> ExcludedFireplacePrefabNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> ExcludedSmelterFuelPrefabNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private Harmony harmony;

		internal static bool IsAvailableForCurrentSession
		{
			get
			{
				if ((Object)(object)ZNet.instance == (Object)null)
				{
					return true;
				}
				if (ZNet.m_isServer)
				{
					return true;
				}
				return ((ConditionalConfigSync)ConfigSync).InitialSyncDone;
			}
		}

		private void Awake()
		{
			Instance = this;
			BindConfiguration();
			harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "shudnal.StationItemReturn");
			Game.isModded = true;
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void BindConfiguration()
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			ModEnabled = BindServerConfig("General", "Enabled", defaultValue: true, "Enable the mod. [Synced with Server]");
			LoggingEnabled = BindClientConfig("General", "Enable logging", defaultValue: false, "Enable diagnostic logging on this client.");
			ConfigLocked = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Lock Configuration", true, "Configuration is locked and can be changed by server administrators only. [Synced with Server]");
			((ConditionalConfigSync)ConfigSync).AddLockingConfigEntry<bool>(ConfigLocked);
			CookingStationItemReturnEnabled = BindServerConfig("Cooking stations", "Return uncooked items", defaultValue: true, "Allow returning the last uncooked item from cooking stations and ovens. [Synced with Server]");
			CookingStationItemReturnProgressLimit = BindServerConfig("Cooking stations", "Maximum return progress", 0f, new ConfigDescription("Maximum cooking progress at which an uncooked item can still be returned. 0 disables this restriction; values above 0 limit returns to that fraction of the cooking time. [Synced with Server]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					ShowRangeAsPercent = true
				}
			}));
			CookingStationFuelReturnEnabled = BindServerConfig("Cooking stations", "Return fuel", defaultValue: false, "Allow returning one remaining fuel item from cooking stations and ovens that use a fixed fuel item. [Synced with Server]");
			FireplaceFuelReturnEnabled = BindServerConfig("Fireplaces", "Return fuel", defaultValue: false, "Allow returning one remaining fuel item from refillable fireplaces that use a fixed fuel item. Fireplaces do not normally refund fuel when destroyed, so this feature is disabled by default. [Synced with Server]");
			FireplaceExcludedPrefabs = BindServerConfig("Fireplaces", "Excluded prefabs", string.Empty, "Comma-, semicolon-, or line-separated exact prefab names that must not return fuel. Use this for fireplaces modified to accept multiple fuel item types because Valheim stores only a single fuel amount and does not preserve which fuel items were added. [Synced with Server]");
			FireplaceExcludedPrefabs.SettingChanged += delegate
			{
				RefreshExcludedFireplacePrefabs();
			};
			RefreshExcludedFireplacePrefabs();
			SmelterInputReturnEnabled = BindServerConfig("Smelters", "Return input items", defaultValue: true, "Allow returning the newest raw item from a smelter input queue. [Synced with Server]");
			SmelterFuelReturnEnabled = BindServerConfig("Smelters", "Return fuel", defaultValue: true, "Allow returning one remaining fuel item from smelters that use a fixed fuel item. [Synced with Server]");
			SmelterFuelExcludedPrefabs = BindServerConfig("Smelters", "Fuel return excluded prefabs", string.Empty, "Comma-, semicolon-, or line-separated exact prefab names that must not return fuel. Use this for smelters modified to accept multiple fuel item types because Valheim stores only a single fuel amount and does not preserve which fuel items were added. [Synced with Server]");
			SmelterFuelExcludedPrefabs.SettingChanged += delegate
			{
				RefreshExcludedSmelterFuelPrefabs();
			};
			RefreshExcludedSmelterFuelPrefabs();
			FermenterIngredientReturnEnabled = BindServerConfig("Fermenters", "Return ingredient", defaultValue: true, "Allow returning the original ingredient while a fermenter is still fermenting. [Synced with Server]");
			FermenterIngredientReturnProgressLimit = BindServerConfig("Fermenters", "Maximum return progress", 0f, new ConfigDescription("Maximum fermentation progress at which the original ingredient can still be returned. 0 disables this restriction; values above 0 limit returns to that fraction of the fermentation time. For example 25% means mead can only be returned in first 15 minutes of fermenting. [Synced with Server]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					ShowRangeAsPercent = true
				}
			}));
			TurretAmmoReturnEnabled = BindServerConfig("Turrets", "Return ammunition", defaultValue: false, "Allow returning one loaded ammunition item from turrets configured to refund ammunition when destroyed. Turrets do not preserve cheated provenance, so returned ammunition is always cleared of the cheated marker. [Synced with Server]");
		}

		private static void RefreshExcludedPrefabNames(ConfigEntry<string> entry, HashSet<string> names)
		{
			names.Clear();
			string text = entry?.Value ?? string.Empty;
			string[] array = text.Split(new char[4] { ',', ';', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text2 in array)
			{
				string text3 = text2.Trim();
				if (!string.IsNullOrEmpty(text3))
				{
					names.Add(text3);
				}
			}
		}

		private static void RefreshExcludedFireplacePrefabs()
		{
			RefreshExcludedPrefabNames(FireplaceExcludedPrefabs, ExcludedFireplacePrefabNames);
		}

		private static void RefreshExcludedSmelterFuelPrefabs()
		{
			RefreshExcludedPrefabNames(SmelterFuelExcludedPrefabs, ExcludedSmelterFuelPrefabNames);
		}

		internal static bool IsFireplaceExcluded(Fireplace fireplace)
		{
			if (!Object.op_Implicit((Object)(object)fireplace))
			{
				return false;
			}
			string text = ((Object.op_Implicit((Object)(object)fireplace.m_nview) && fireplace.m_nview.IsValid()) ? fireplace.m_nview.GetPrefabName() : Utils.GetPrefabName(((Component)fireplace).gameObject));
			return !string.IsNullOrEmpty(text) && ExcludedFireplacePrefabNames.Contains(text);
		}

		internal static bool IsSmelterFuelExcluded(Smelter smelter)
		{
			if (!Object.op_Implicit((Object)(object)smelter))
			{
				return false;
			}
			string text = ((Object.op_Implicit((Object)(object)smelter.m_nview) && smelter.m_nview.IsValid()) ? smelter.m_nview.GetPrefabName() : Utils.GetPrefabName(((Component)smelter).gameObject));
			return !string.IsNullOrEmpty(text) && ExcludedSmelterFuelPrefabNames.Contains(text);
		}

		private ConfigEntry<T> BindServerConfig<T>(string section, string key, T defaultValue, ConfigDescription description)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description);
			((ConditionalConfigSync)ConfigSync).AddConfigEntry<T>(val, (ConfigSyncMode)0);
			return val;
		}

		private ConfigEntry<T> BindServerConfig<T>(string section, string key, T defaultValue, string description)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			return BindServerConfig(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		private ConfigEntry<T> BindClientConfig<T>(string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description);
			((ConditionalConfigSync)ConfigSync).AddConfigEntry<T>(val, (ConfigSyncMode)2);
			return val;
		}

		internal static void LogInfo(object value)
		{
			ConfigEntry<bool> loggingEnabled = LoggingEnabled;
			if (loggingEnabled != null && loggingEnabled.Value)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo(value);
			}
		}

		internal static void LogWarning(object value)
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning(value);
		}
	}
	internal static class StationReturn
	{
		private struct CookingInteractionState
		{
			internal bool HadDoneItem;

			internal int FreeSlot;

			internal string ExpectedPrefabName;
		}

		[HarmonyPatch(typeof(CookingStation), "Awake")]
		private static class CookingStation_Awake_RegisterRpcs
		{
			private static void Postfix(CookingStation __instance)
			{
				if (IsValidView(__instance.m_nview))
				{
					__instance.m_nview.Register<Vector3>("RPC_SIR_ReturnCookingItem", (Action<long, Vector3>)delegate(long sender, Vector3 userPoint)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						ReturnCookingItemOnOwner(__instance, userPoint);
					});
					__instance.m_nview.Register<Vector3>("RPC_SIR_ReturnCookingFuel", (Action<long, Vector3>)delegate(long sender, Vector3 userPoint)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						ReturnCookingFuelOnOwner(__instance, userPoint);
					});
					__instance.m_nview.Register<bool, bool>("RPC_SIR_RefreshCookingStation", (Action<long, bool, bool>)delegate(long sender, bool active, bool hasFuel)
					{
						RefreshCookingStation(__instance, active, hasFuel);
					});
					__instance.m_nview.Register<int, string>("RPC_SIR_RecordCookingSkill", (Action<long, int, string>)delegate(long sender, int slot, string expectedPrefabName)
					{
						MarkCookingSkillCreditOnOwner(__instance, sender, slot, expectedPrefabName);
					});
				}
			}
		}

		[HarmonyPatch(typeof(Fireplace), "Awake")]
		private static class Fireplace_Awake_RegisterRpcs
		{
			private static void Postfix(Fireplace __instance)
			{
				if (IsValidView(__instance.m_nview))
				{
					__instance.m_nview.Register<Vector3>("RPC_SIR_ReturnFireplaceFuel", (Action<long, Vector3>)delegate(long sender, Vector3 userPoint)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						ReturnFireplaceFuelOnOwner(__instance, userPoint);
					});
					__instance.m_nview.Register("RPC_SIR_RefreshFireplace", (Action<long>)delegate
					{
						RefreshFireplace(__instance);
					});
				}
			}
		}

		[HarmonyPatch(typeof(Smelter), "Awake")]
		private static class Smelter_Awake_RegisterRpcs
		{
			private static void Postfix(Smelter __instance)
			{
				if (IsValidView(__instance.m_nview))
				{
					__instance.m_nview.Register<Vector3>("RPC_SIR_ReturnSmelterInput", (Action<long, Vector3>)delegate(long sender, Vector3 userPoint)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						ReturnSmelterInputOnOwner(__instance, userPoint);
					});
					__instance.m_nview.Register<Vector3>("RPC_SIR_ReturnSmelterFuel", (Action<long, Vector3>)delegate(long sender, Vector3 userPoint)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						ReturnSmelterFuelOnOwner(__instance, userPoint);
					});
					__instance.m_nview.Register<bool, bool, bool>("RPC_SIR_RefreshSmelter", (Action<long, bool, bool, bool>)delegate(long sender, bool active, bool hasFuel, bool hasInput)
					{
						RefreshSmelter(__instance, active, hasFuel, hasInput);
					});
				}
			}
		}

		[HarmonyPatch(typeof(Fermenter), "Awake")]
		private static class Fermenter_Awake_RegisterRpcs
		{
			private static void Postfix(Fermenter __instance)
			{
				if (IsValidView(__instance.m_nview))
				{
					__instance.m_nview.Register<Vector3>("RPC_SIR_ReturnFermenterIngredient", (Action<long, Vector3>)delegate(long sender, Vector3 userPoint)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						ReturnFermenterIngredientOnOwner(__instance, userPoint);
					});
					__instance.m_nview.Register("RPC_SIR_RefreshFermenter", (Action<long>)delegate
					{
						RefreshFermenter(__instance);
					});
				}
			}
		}

		[HarmonyPatch(typeof(Turret), "Awake")]
		private static class Turret_Awake_RegisterRpcs
		{
			private static void Postfix(Turret __instance)
			{
				if (IsValidView(__instance.m_nview))
				{
					__instance.m_nview.Register<Vector3>("RPC_SIR_ReturnTurretAmmo", (Action<long, Vector3>)delegate(long sender, Vector3 userPoint)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						ReturnTurretAmmoOnOwner(__instance, userPoint);
					});
					__instance.m_nview.Register<int, string>("RPC_SIR_RefreshTurret", (Action<long, int, string>)delegate(long sender, int remainingAmmo, string ammoType)
					{
						RefreshTurret(__instance, remainingAmmo, ammoType);
					});
				}
			}
		}

		[HarmonyPatch(typeof(CookingStation), "RPC_AddItem")]
		private static class CookingStation_RPC_AddItem_CaptureAuthor
		{
			private static void Prefix(long sender, out long __state)
			{
				__state = activeCookingAuthor;
				activeCookingAuthor = sender;
			}

			private static void Finalizer(long __state)
			{
				activeCookingAuthor = __state;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "SetSlot")]
		private static class CookingStation_SetSlot_TrackReturnMetadata
		{
			private static void Postfix(CookingStation __instance, int slot, string itemName)
			{
				if (!IsValidOwner(__instance.m_nview))
				{
					return;
				}
				ZDO zDO = __instance.m_nview.GetZDO();
				if (string.IsNullOrEmpty(itemName))
				{
					zDO.Set(CookingAuthorKey(slot), 0L);
					zDO.Set(CookingSkillKey(slot), false);
					if (zDO.GetInt("SIR_LastCookingSlot", -1) == slot)
					{
						zDO.Set("SIR_LastCookingAuthor", 0L);
						zDO.Set("SIR_LastCookingSlot", -1);
					}
				}
				else if (activeCookingAuthor != 0)
				{
					zDO.Set(CookingAuthorKey(slot), activeCookingAuthor);
					zDO.Set(CookingSkillKey(slot), false);
					zDO.Set("SIR_LastCookingAuthor", activeCookingAuthor);
					zDO.Set("SIR_LastCookingSlot", slot);
				}
			}
		}

		[HarmonyPatch(typeof(CookingStation), "OnInteract")]
		private static class CookingStation_OnInteract_RecordSkillCredit
		{
			private static void Prefix(CookingStation __instance, Humanoid user, out CookingInteractionState __state)
			{
				bool flag = __instance.HaveDoneItem();
				ItemData val = ((!flag && Object.op_Implicit((Object)(object)user)) ? __instance.FindCookableItem(user.GetInventory()) : null);
				CookingInteractionState cookingInteractionState = new CookingInteractionState
				{
					HadDoneItem = flag,
					FreeSlot = __instance.GetFreeSlot()
				};
				object expectedPrefabName;
				if (val == null)
				{
					expectedPrefabName = null;
				}
				else
				{
					GameObject dropPrefab = val.m_dropPrefab;
					expectedPrefabName = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
				}
				cookingInteractionState.ExpectedPrefabName = (string)expectedPrefabName;
				__state = cookingInteractionState;
			}

			private static void Postfix(CookingStation __instance, bool __result, CookingInteractionState __state)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Invalid comparison between Unknown and I4
				if (__result && !__state.HadDoneItem && __state.FreeSlot >= 0 && !string.IsNullOrEmpty(__state.ExpectedPrefabName) && (int)__instance.m_skill > 0)
				{
					RequestCookingSkillCredit(__instance, __state.FreeSlot, __state.ExpectedPrefabName);
				}
			}
		}

		[HarmonyPatch(typeof(CookingStation), "Interact")]
		private static class CookingStation_Interact_ReturnStoredItem
		{
			[HarmonyPriority(800)]
			private static bool Prefix(CookingStation __instance, Humanoid user, bool hold, bool alt, bool __runOriginal)
			{
				if (!__runOriginal)
				{
					return false;
				}
				if (ShouldBlockFollowupHold((Component)(object)__instance, hold))
				{
					return false;
				}
				if (hold || !alt || Object.op_Implicit((Object)(object)__instance.m_addFoodSwitch))
				{
					return true;
				}
				if (!CanReturnCookingItem(__instance, checkAccess: true, out var _))
				{
					return true;
				}
				RequestReturn(__instance.m_nview, user, "RPC_SIR_ReturnCookingItem");
				BlockFollowupHold((Component)(object)__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(Fireplace), "Interact")]
		private static class Fireplace_Interact_ReturnFuel
		{
			[HarmonyBefore(new string[] { "shudnal.MyLittleUI", "shudnal.AnyWood" })]
			[HarmonyPriority(800)]
			private static bool Prefix(Fireplace __instance, Humanoid user, bool hold, bool alt, bool __runOriginal)
			{
				if (!__runOriginal)
				{
					return false;
				}
				if (ShouldBlockFollowupHold((Component)(object)__instance, hold))
				{
					return false;
				}
				if (hold || !alt || !CanReturnFireplaceFuel(__instance, checkAccess: true, out var _))
				{
					return true;
				}
				RequestReturn(__instance.m_nview, user, "RPC_SIR_ReturnFireplaceFuel");
				BlockFollowupHold((Component)(object)__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(Switch), "Interact")]
		private static class Switch_Interact_ReturnStoredItem
		{
			[HarmonyBefore(new string[] { "shudnal.MyLittleUI", "shudnal.AnyWood" })]
			[HarmonyPriority(800)]
			private static bool Prefix(Switch __instance, Humanoid character, bool hold, bool alt, bool __runOriginal)
			{
				if (!__runOriginal)
				{
					return false;
				}
				if (ShouldBlockFollowupHold((Component)(object)__instance, hold))
				{
					return false;
				}
				if (hold || !alt)
				{
					return true;
				}
				CookingStation val = ResolveCookingItemSwitch(__instance);
				if (Object.op_Implicit((Object)(object)val) && CanReturnCookingItem(val, checkAccess: true, out var sharedName))
				{
					RequestReturn(val.m_nview, character, "RPC_SIR_ReturnCookingItem");
					BlockFollowupHold((Component)(object)__instance);
					return false;
				}
				CookingStation val2 = ResolveCookingFuelSwitch(__instance);
				if (Object.op_Implicit((Object)(object)val2) && CanReturnCookingFuel(val2, checkAccess: true, out sharedName))
				{
					RequestReturn(val2.m_nview, character, "RPC_SIR_ReturnCookingFuel");
					BlockFollowupHold((Component)(object)__instance);
					return false;
				}
				Smelter val3 = ResolveSmelterInputSwitch(__instance);
				if (Object.op_Implicit((Object)(object)val3) && CanReturnSmelterInput(val3, checkAccess: true, out sharedName))
				{
					RequestReturn(val3.m_nview, character, "RPC_SIR_ReturnSmelterInput");
					BlockFollowupHold((Component)(object)__instance);
					return false;
				}
				Smelter val4 = ResolveSmelterFuelSwitch(__instance);
				if (Object.op_Implicit((Object)(object)val4) && CanReturnSmelterFuel(val4, checkAccess: true, out sharedName))
				{
					RequestReturn(val4.m_nview, character, "RPC_SIR_ReturnSmelterFuel");
					BlockFollowupHold((Component)(object)__instance);
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Fermenter), "Interact")]
		private static class Fermenter_Interact_ReturnIngredient
		{
			[HarmonyPriority(800)]
			private static bool Prefix(Fermenter __instance, Humanoid user, bool hold, bool alt, bool __runOriginal)
			{
				if (!__runOriginal)
				{
					return false;
				}
				if (ShouldBlockFollowupHold((Component)(object)__instance, hold))
				{
					return false;
				}
				if (hold || !alt || !CanReturnFermenterIngredient(__instance, checkAccess: true, out var _))
				{
					return true;
				}
				RequestReturn(__instance.m_nview, user, "RPC_SIR_ReturnFermenterIngredient");
				BlockFollowupHold((Component)(object)__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(Turret), "Interact")]
		private static class Turret_Interact_ReturnAmmo
		{
			[HarmonyPriority(800)]
			private static bool Prefix(Turret __instance, Humanoid character, bool hold, bool alt, bool __runOriginal)
			{
				if (!__runOriginal)
				{
					return false;
				}
				if (ShouldBlockFollowupHold((Component)(object)__instance, hold))
				{
					return false;
				}
				if (hold || !alt || !CanReturnTurretAmmo(__instance, checkAccess: true, out var _))
				{
					return true;
				}
				RequestReturn(__instance.m_nview, character, "RPC_SIR_ReturnTurretAmmo");
				BlockFollowupHold((Component)(object)__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "Start")]
		private static class ZoneSystem_Start_RegisterRoutedRpc
		{
			private static void Postfix()
			{
				if (ZRoutedRpc.instance != null && registeredRoutedRpc != ZRoutedRpc.instance)
				{
					registeredRoutedRpc = ZRoutedRpc.instance;
					registeredRoutedRpc.Register<int>("RPC_SIR_UndoStationSkill", (Action<long, int>)UndoStationSkill);
				}
			}
		}

		private const string ReturnCookingItemRpc = "RPC_SIR_ReturnCookingItem";

		private const string ReturnCookingFuelRpc = "RPC_SIR_ReturnCookingFuel";

		private const string RefreshCookingStationRpc = "RPC_SIR_RefreshCookingStation";

		private const string ReturnFireplaceFuelRpc = "RPC_SIR_ReturnFireplaceFuel";

		private const string RefreshFireplaceRpc = "RPC_SIR_RefreshFireplace";

		private const string RecordCookingSkillRpc = "RPC_SIR_RecordCookingSkill";

		private const string ReturnSmelterInputRpc = "RPC_SIR_ReturnSmelterInput";

		private const string ReturnSmelterFuelRpc = "RPC_SIR_ReturnSmelterFuel";

		private const string RefreshSmelterRpc = "RPC_SIR_RefreshSmelter";

		private const string ReturnFermenterIngredientRpc = "RPC_SIR_ReturnFermenterIngredient";

		private const string RefreshFermenterRpc = "RPC_SIR_RefreshFermenter";

		private const string ReturnTurretAmmoRpc = "RPC_SIR_ReturnTurretAmmo";

		private const string RefreshTurretRpc = "RPC_SIR_RefreshTurret";

		private const string UndoSkillRpc = "RPC_SIR_UndoStationSkill";

		private const string LastCookingAuthorKey = "SIR_LastCookingAuthor";

		private const string LastCookingSlotKey = "SIR_LastCookingSlot";

		private static long activeCookingAuthor;

		private static int blockedHoldSourceId;

		private static ZRoutedRpc registeredRoutedRpc;

		internal static bool IsEnabled
		{
			get
			{
				ConfigEntry<bool> modEnabled = StationItemReturn.ModEnabled;
				return modEnabled != null && modEnabled.Value && StationItemReturn.IsAvailableForCurrentSession;
			}
		}

		private static string CookingAuthorKey(int slot)
		{
			return "SIR_CookingAuthor_" + slot;
		}

		private static string CookingSkillKey(int slot)
		{
			return "SIR_CookingSkill_" + slot;
		}

		private static bool IsValidOwner(ZNetView view)
		{
			return Object.op_Implicit((Object)(object)view) && view.IsValid() && view.GetZDO() != null && view.IsOwner();
		}

		private static bool IsValidView(ZNetView view)
		{
			return Object.op_Implicit((Object)(object)view) && view.IsValid() && view.GetZDO() != null;
		}

		private static GameObject GetItemPrefab(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return null;
			}
			GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefabName) : null);
			if (!Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				val = ZNetScene.instance.GetPrefab(prefabName);
			}
			return val;
		}

		private static string GetSharedName(GameObject prefab)
		{
			return (!Object.op_Implicit((Object)(object)prefab)) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_name;
		}

		private static Piece GetPiece(Component component)
		{
			if (!Object.op_Implicit((Object)(object)component))
			{
				return null;
			}
			Piece componentInParent = component.GetComponentInParent<Piece>();
			return Object.op_Implicit((Object)(object)componentInParent) ? componentInParent : component.GetComponentInChildren<Piece>(true);
		}

		private static bool HasLocalAccess(Component component)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Piece piece = GetPiece(component);
			if (!Object.op_Implicit((Object)(object)piece))
			{
				return true;
			}
			return Object.op_Implicit((Object)(object)Player.m_localPlayer) && PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, false, false);
		}

		private static bool ShouldBlockFollowupHold(Component source, bool hold)
		{
			if (!Object.op_Implicit((Object)(object)source))
			{
				blockedHoldSourceId = 0;
				return false;
			}
			int instanceID = ((Object)source).GetInstanceID();
			if (hold)
			{
				return blockedHoldSourceId == instanceID;
			}
			blockedHoldSourceId = 0;
			return false;
		}

		private static void BlockFollowupHold(Component source)
		{
			blockedHoldSourceId = (Object.op_Implicit((Object)(object)source) ? ((Object)source).GetInstanceID() : 0);
		}

		private static bool PrepareRequest(ZNetView view)
		{
			if (!IsValidView(view))
			{
				return false;
			}
			if (!view.HasOwner())
			{
				view.ClaimOwnership();
			}
			return view.HasOwner();
		}

		private static void RequestReturn(ZNetView view, Humanoid user, string rpcName)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)user) && PrepareRequest(view))
			{
				view.InvokeRPC(rpcName, new object[1] { ((Component)user).transform.position });
			}
		}

		private static void RequestCookingSkillCredit(CookingStation station, int slot, string expectedPrefabName)
		{
			if (Object.op_Implicit((Object)(object)station) && slot >= 0 && !string.IsNullOrEmpty(expectedPrefabName) && PrepareRequest(station.m_nview))
			{
				station.m_nview.InvokeRPC("RPC_SIR_RecordCookingSkill", new object[2] { slot, expectedPrefabName });
			}
		}

		private static bool CreateItem(GameObject prefab, Vector3 position, Vector3 direction, float force, bool cheated, out ItemDrop spawnedItem)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			spawnedItem = null;
			ItemDrop val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<ItemDrop>() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			if (((Vector3)(ref direction)).sqrMagnitude <= 0.0001f)
			{
				direction = Vector3.forward;
			}
			((Vector3)(ref direction)).Normalize();
			GameObject val2 = Object.Instantiate<GameObject>(prefab, position, Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f));
			spawnedItem = val2.GetComponent<ItemDrop>();
			if (!Object.op_Implicit((Object)(object)spawnedItem))
			{
				Object.Destroy((Object)(object)val2);
				return false;
			}
			ItemDrop.OnCreateNew(spawnedItem, cheated);
			Rigidbody component = val2.GetComponent<Rigidbody>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.linearVelocity = direction * force;
			}
			return true;
		}

		private static bool SpawnItem(GameObject prefab, Vector3 origin, Vector3 fallbackDirection, Vector3 userPoint, float force, bool cheated, out ItemDrop spawnedItem)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_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_0071: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = userPoint - origin;
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f)
			{
				val = fallbackDirection;
				val.y = 0f;
			}
			if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f)
			{
				val = Vector3.forward;
			}
			((Vector3)(ref val)).Normalize();
			return CreateItem(prefab, origin + val * 0.5f, val, force, cheated, out spawnedItem);
		}

		private static T ResolveStationSwitch<T>(Switch switchRef, Func<T, Switch> getSwitch) where T : Component
		{
			if (!Object.op_Implicit((Object)(object)switchRef))
			{
				return default(T);
			}
			T componentInParent = ((Component)switchRef).GetComponentInParent<T>();
			if (Object.op_Implicit((Object)(object)componentInParent) && (Object)(object)getSwitch(componentInParent) == (Object)(object)switchRef)
			{
				return componentInParent;
			}
			if (switchRef.m_onUse == null)
			{
				return default(T);
			}
			Delegate[] invocationList = ((Delegate)(object)switchRef.m_onUse).GetInvocationList();
			foreach (Delegate obj in invocationList)
			{
				object? target = obj.Target;
				T val = (T)((target is T) ? target : null);
				if (val != null && (Object)(object)getSwitch(val) == (Object)(object)switchRef)
				{
					return val;
				}
			}
			return default(T);
		}

		internal static CookingStation ResolveCookingItemSwitch(Switch switchRef)
		{
			return ResolveStationSwitch<CookingStation>(switchRef, (Func<CookingStation, Switch>)((CookingStation station) => station.m_addFoodSwitch));
		}

		internal static CookingStation ResolveCookingFuelSwitch(Switch switchRef)
		{
			return ResolveStationSwitch<CookingStation>(switchRef, (Func<CookingStation, Switch>)((CookingStation station) => station.m_addFuelSwitch));
		}

		internal static Smelter ResolveSmelterInputSwitch(Switch switchRef)
		{
			return ResolveStationSwitch<Smelter>(switchRef, (Func<Smelter, Switch>)((Smelter station) => station.m_addOreSwitch));
		}

		internal static Smelter ResolveSmelterFuelSwitch(Switch switchRef)
		{
			return ResolveStationSwitch<Smelter>(switchRef, (Func<Smelter, Switch>)((Smelter station) => station.m_addWoodSwitch));
		}

		private static bool TryGetCookingItem(CookingStation station, out int slot, out GameObject prefab, out string sharedName, out bool cheated, out long author, out bool skillCredited)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Invalid comparison between Unknown and I4
			slot = -1;
			prefab = null;
			sharedName = null;
			cheated = false;
			author = 0L;
			skillCredited = false;
			if (!Object.op_Implicit((Object)(object)station) || !IsValidView(station.m_nview) || station.m_slots == null)
			{
				return false;
			}
			ZDO zDO = station.m_nview.GetZDO();
			float num = StationItemReturn.CookingStationItemReturnProgressLimit?.Value ?? 0f;
			string text = default(string);
			float num3 = default(float);
			Status val = default(Status);
			bool flag = default(bool);
			for (int num2 = station.m_slots.Length - 1; num2 >= 0; num2--)
			{
				station.GetSlot(num2, ref text, ref num3, ref val, ref flag);
				if (!string.IsNullOrEmpty(text) && (int)val <= 0)
				{
					ItemConversion itemConversion = station.GetItemConversion(text);
					if (itemConversion != null && Object.op_Implicit((Object)(object)itemConversion.m_from) && !(text != ((Object)itemConversion.m_from).name) && (!(num > 0f) || !(itemConversion.m_cookTime > 0f) || !(num3 > itemConversion.m_cookTime * num)))
					{
						GameObject itemPrefab = GetItemPrefab(text);
						string sharedName2 = GetSharedName(itemPrefab);
						if (Object.op_Implicit((Object)(object)itemPrefab) && !string.IsNullOrEmpty(sharedName2))
						{
							slot = num2;
							prefab = itemPrefab;
							sharedName = sharedName2;
							cheated = flag && !PlayerProfile.s_bypassCheatChecks;
							author = zDO.GetLong(CookingAuthorKey(num2), 0L);
							skillCredited = zDO.GetBool(CookingSkillKey(num2), false);
							return true;
						}
					}
				}
			}
			return false;
		}

		private static bool TryGetCookingFuel(CookingStation station, out GameObject prefab, out string sharedName, out bool cheated)
		{
			prefab = null;
			sharedName = null;
			cheated = false;
			if (!Object.op_Implicit((Object)(object)station) || !IsValidView(station.m_nview) || !Object.op_Implicit((Object)(object)station.m_fuelItem) || station.GetFuel() <= 0f)
			{
				return false;
			}
			GameObject gameObject = ((Component)station.m_fuelItem).gameObject;
			string sharedName2 = GetSharedName(gameObject);
			if (!Object.op_Implicit((Object)(object)gameObject) || string.IsNullOrEmpty(sharedName2))
			{
				return false;
			}
			prefab = gameObject;
			sharedName = sharedName2;
			cheated = station.m_nview.GetZDO().GetBool(ZDOVars.s_cheated, false) && !PlayerProfile.s_bypassCheatChecks;
			return true;
		}

		private static bool TryGetFireplaceFuel(Fireplace station, out GameObject prefab, out string sharedName)
		{
			prefab = null;
			sharedName = null;
			if (!Object.op_Implicit((Object)(object)station) || !IsValidView(station.m_nview) || station.m_infiniteFuel || !station.m_canRefill || !Object.op_Implicit((Object)(object)station.m_fuelItem) || StationItemReturn.IsFireplaceExcluded(station) || station.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f) <= 0f)
			{
				return false;
			}
			GameObject gameObject = ((Component)station.m_fuelItem).gameObject;
			string sharedName2 = GetSharedName(gameObject);
			if (!Object.op_Implicit((Object)(object)gameObject) || string.IsNullOrEmpty(sharedName2))
			{
				return false;
			}
			prefab = gameObject;
			sharedName = sharedName2;
			return true;
		}

		private static bool TryGetSmelterInput(Smelter station, out int queueIndex, out GameObject prefab, out string sharedName)
		{
			queueIndex = -1;
			prefab = null;
			sharedName = null;
			if (!Object.op_Implicit((Object)(object)station) || !IsValidView(station.m_nview))
			{
				return false;
			}
			int queueSize = station.GetQueueSize();
			if (queueSize <= 0)
			{
				return false;
			}
			ZDO zDO = station.m_nview.GetZDO();
			int num = queueSize - 1;
			string prefabName = zDO.GetString("item" + num, "");
			GameObject itemPrefab = GetItemPrefab(prefabName);
			string sharedName2 = GetSharedName(itemPrefab);
			if (!Object.op_Implicit((Object)(object)itemPrefab) || string.IsNullOrEmpty(sharedName2))
			{
				return false;
			}
			queueIndex = num;
			prefab = itemPrefab;
			sharedName = sharedName2;
			return true;
		}

		private static bool TryGetSmelterFuel(Smelter station, out GameObject prefab, out string sharedName)
		{
			prefab = null;
			sharedName = null;
			if (!Object.op_Implicit((Object)(object)station) || !IsValidView(station.m_nview) || !Object.op_Implicit((Object)(object)station.m_fuelItem) || StationItemReturn.IsSmelterFuelExcluded(station) || station.GetFuel() <= 0f)
			{
				return false;
			}
			GameObject gameObject = ((Component)station.m_fuelItem).gameObject;
			string sharedName2 = GetSharedName(gameObject);
			if (!Object.op_Implicit((Object)(object)gameObject) || string.IsNullOrEmpty(sharedName2))
			{
				return false;
			}
			prefab = gameObject;
			sharedName = sharedName2;
			return true;
		}

		private static bool TryGetFermenterIngredient(Fermenter station, out GameObject prefab, out string sharedName, out bool cheated)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			prefab = null;
			sharedName = null;
			cheated = false;
			if (!Object.op_Implicit((Object)(object)station) || !IsValidView(station.m_nview) || (int)station.GetStatus() != 1)
			{
				return false;
			}
			float num = StationItemReturn.FermenterIngredientReturnProgressLimit?.Value ?? 0f;
			if (num > 0f && station.m_fermentationDuration > 0f && station.GetFermentationTime() > (double)(station.m_fermentationDuration * num))
			{
				return false;
			}
			int content = station.GetContent();
			if (content == 0)
			{
				return false;
			}
			ItemConversion itemConversion = station.GetItemConversion(content);
			GameObject val = ((itemConversion != null && Object.op_Implicit((Object)(object)itemConversion.m_from)) ? ((Component)itemConversion.m_from).gameObject : (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab(content) : null));
			string sharedName2 = GetSharedName(val);
			if (!Object.op_Implicit((Object)(object)val) || string.IsNullOrEmpty(sharedName2))
			{
				return false;
			}
			prefab = val;
			sharedName = sharedName2;
			cheated = station.m_nview.GetZDO().GetBool(ZDOVars.s_cheatedQueued, false) && !PlayerProfile.s_bypassCheatChecks;
			return true;
		}

		private static bool TryGetTurretAmmo(Turret station, out GameObject prefab, out string sharedName)
		{
			prefab = null;
			sharedName = null;
			if (!Object.op_Implicit((Object)(object)station) || !IsValidView(station.m_nview) || !station.m_returnAmmoOnDestroy || station.m_maxAmmo <= 0 || station.GetAmmo() <= 0)
			{
				return false;
			}
			GameObject itemPrefab = GetItemPrefab(station.GetAmmoType());
			string sharedName2 = GetSharedName(itemPrefab);
			if (!Object.op_Implicit((Object)(object)itemPrefab) || string.IsNullOrEmpty(sharedName2))
			{
				return false;
			}
			prefab = itemPrefab;
			sharedName = sharedName2;
			return true;
		}

		internal static bool CanReturnCookingItem(CookingStation station, bool checkAccess, out string sharedName)
		{
			sharedName = null;
			int result;
			if (IsEnabled)
			{
				ConfigEntry<bool> cookingStationItemReturnEnabled = StationItemReturn.CookingStationItemReturnEnabled;
				if (cookingStationItemReturnEnabled != null && cookingStationItemReturnEnabled.Value && (!checkAccess || HasLocalAccess((Component)(object)station)))
				{
					result = (TryGetCookingItem(station, out var _, out var _, out sharedName, out var _, out var _, out var _) ? 1 : 0);
					goto IL_003d;
				}
			}
			result = 0;
			goto IL_003d;
			IL_003d:
			return (byte)result != 0;
		}

		internal static bool CanReturnCookingFuel(CookingStation station, bool checkAccess, out string sharedName)
		{
			sharedName = null;
			int result;
			if (IsEnabled)
			{
				ConfigEntry<bool> cookingStationFuelReturnEnabled = StationItemReturn.CookingStationFuelReturnEnabled;
				if (cookingStationFuelReturnEnabled != null && cookingStationFuelReturnEnabled.Value && (!checkAccess || HasLocalAccess((Component)(object)station)))
				{
					result = (TryGetCookingFuel(station, out var _, out sharedName, out var _) ? 1 : 0);
					goto IL_0037;
				}
			}
			result = 0;
			goto IL_0037;
			IL_0037:
			return (byte)result != 0;
		}

		internal static bool CanReturnFireplaceFuel(Fireplace station, bool checkAccess, out string sharedName)
		{
			sharedName = null;
			int result;
			if (IsEnabled)
			{
				ConfigEntry<bool> fireplaceFuelReturnEnabled = StationItemReturn.FireplaceFuelReturnEnabled;
				if (fireplaceFuelReturnEnabled != null && fireplaceFuelReturnEnabled.Value && (!checkAccess || HasLocalAccess((Component)(object)station)))
				{
					result = (TryGetFireplaceFuel(station, out var _, out sharedName) ? 1 : 0);
					goto IL_0035;
				}
			}
			result = 0;
			goto IL_0035;
			IL_0035:
			return (byte)result != 0;
		}

		internal static bool CanReturnSmelterInput(Smelter station, bool checkAccess, out string sharedName)
		{
			sharedName = null;
			int result;
			if (IsEnabled)
			{
				ConfigEntry<bool> smelterInputReturnEnabled = StationItemReturn.SmelterInputReturnEnabled;
				if (smelterInputReturnEnabled != null && smelterInputReturnEnabled.Value && (!checkAccess || HasLocalAccess((Component)(object)station)))
				{
					result = (TryGetSmelterInput(station, out var _, out var _, out sharedName) ? 1 : 0);
					goto IL_0037;
				}
			}
			result = 0;
			goto IL_0037;
			IL_0037:
			return (byte)result != 0;
		}

		internal static bool CanReturnSmelterFuel(Smelter station, bool checkAccess, out string sharedName)
		{
			sharedName = null;
			int result;
			if (IsEnabled)
			{
				ConfigEntry<bool> smelterFuelReturnEnabled = StationItemReturn.SmelterFuelReturnEnabled;
				if (smelterFuelReturnEnabled != null && smelterFuelReturnEnabled.Value && (!checkAccess || HasLocalAccess((Component)(object)station)))
				{
					result = (TryGetSmelterFuel(station, out var _, out sharedName) ? 1 : 0);
					goto IL_0035;
				}
			}
			result = 0;
			goto IL_0035;
			IL_0035:
			return (byte)result != 0;
		}

		internal static bool CanReturnFermenterIngredient(Fermenter station, bool checkAccess, out string sharedName)
		{
			sharedName = null;
			int result;
			if (IsEnabled)
			{
				ConfigEntry<bool> fermenterIngredientReturnEnabled = StationItemReturn.FermenterIngredientReturnEnabled;
				if (fermenterIngredientReturnEnabled != null && fermenterIngredientReturnEnabled.Value && (!checkAccess || HasLocalAccess((Component)(object)station)))
				{
					result = (TryGetFermenterIngredient(station, out var _, out sharedName, out var _) ? 1 : 0);
					goto IL_0037;
				}
			}
			result = 0;
			goto IL_0037;
			IL_0037:
			return (byte)result != 0;
		}

		internal static bool CanReturnTurretAmmo(Turret station, bool checkAccess, out string sharedName)
		{
			sharedName = null;
			int result;
			if (IsEnabled)
			{
				ConfigEntry<bool> turretAmmoReturnEnabled = StationItemReturn.TurretAmmoReturnEnabled;
				if (turretAmmoReturnEnabled != null && turretAmmoReturnEnabled.Value && (!checkAccess || HasLocalAccess((Component)(object)station)))
				{
					result = (TryGetTurretAmmo(station, out var _, out sharedName) ? 1 : 0);
					goto IL_0035;
				}
			}
			result = 0;
			goto IL_0035;
			IL_0035:
			return (byte)result != 0;
		}

		internal static bool TryGetReturnableItem(object source, out string sharedName)
		{
			sharedName = null;
			CookingStation val = (CookingStation)((source is CookingStation) ? source : null);
			if (val == null)
			{
				Fireplace val2 = (Fireplace)((source is Fireplace) ? source : null);
				if (val2 == null)
				{
					Smelter val3 = (Smelter)((source is Smelter) ? source : null);
					if (val3 == null)
					{
						Fermenter val4 = (Fermenter)((source is Fermenter) ? source : null);
						if (val4 == null)
						{
							Turret val5 = (Turret)((source is Turret) ? source : null);
							if (val5 == null)
							{
								Switch val6 = (Switch)((source is Switch) ? source : null);
								if (val6 != null)
								{
									CookingStation val7 = ResolveCookingItemSwitch(val6);
									if (Object.op_Implicit((Object)(object)val7) && CanReturnCookingItem(val7, checkAccess: true, out sharedName))
									{
										return true;
									}
									CookingStation val8 = ResolveCookingFuelSwitch(val6);
									if (Object.op_Implicit((Object)(object)val8) && CanReturnCookingFuel(val8, checkAccess: true, out sharedName))
									{
										return true;
									}
									Smelter val9 = ResolveSmelterInputSwitch(val6);
									if (Object.op_Implicit((Object)(object)val9) && CanReturnSmelterInput(val9, checkAccess: true, out sharedName))
									{
										return true;
									}
									Smelter val10 = ResolveSmelterFuelSwitch(val6);
									return Object.op_Implicit((Object)(object)val10) && CanReturnSmelterFuel(val10, checkAccess: true, out sharedName);
								}
								return false;
							}
							return CanReturnTurretAmmo(val5, checkAccess: true, out sharedName);
						}
						return CanReturnFermenterIngredient(val4, checkAccess: true, out sharedName);
					}
					return CanReturnSmelterInput(val3, checkAccess: true, out sharedName);
				}
				return CanReturnFireplaceFuel(val2, checkAccess: true, out sharedName);
			}
			return CanReturnCookingItem(val, checkAccess: true, out sharedName);
		}

		private static bool SpawnCookingItem(CookingStation station, int slot, GameObject prefab, Vector3 userPoint, bool cheated)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0083: 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_0068: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			if (slot < 0 || slot >= station.m_slots.Length || !Object.op_Implicit((Object)(object)station.m_slots[slot]))
			{
				return false;
			}
			Transform val = (Object.op_Implicit((Object)(object)station.m_spawnPoint) ? station.m_spawnPoint : station.m_slots[slot]);
			Vector3 val2;
			Vector3 position;
			if (Object.op_Implicit((Object)(object)station.m_spawnPoint))
			{
				val2 = val.forward;
				position = val.position;
			}
			else
			{
				val2 = userPoint - val.position;
				val2.y = 0f;
				if (((Vector3)(ref val2)).sqrMagnitude <= 0.0001f)
				{
					val2 = ((Component)station).transform.forward;
					val2.y = 0f;
				}
				if (((Vector3)(ref val2)).sqrMagnitude <= 0.0001f)
				{
					val2 = Vector3.forward;
				}
				((Vector3)(ref val2)).Normalize();
				position = val.position + val2 * 0.5f;
			}
			if (!CreateItem(prefab, position, val2, station.m_spawnForce, cheated, out var spawnedItem))
			{
				return false;
			}
			if (station.m_spawnFullDurability)
			{
				spawnedItem.m_itemData.m_durability = spawnedItem.m_itemData.m_shared.m_maxDurability;
			}
			station.m_pickEffector.Create(((Component)spawnedItem).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			return true;
		}

		private static void ReturnCookingItemOnOwner(CookingStation station, Vector3 userPoint)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected I4, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled)
			{
				return;
			}
			ConfigEntry<bool> cookingStationItemReturnEnabled = StationItemReturn.CookingStationItemReturnEnabled;
			if (cookingStationItemReturnEnabled != null && cookingStationItemReturnEnabled.Value && IsValidOwner(station.m_nview) && TryGetCookingItem(station, out var slot, out var prefab, out var _, out var cheated, out var author, out var skillCredited) && SpawnCookingItem(station, slot, prefab, userPoint, cheated))
			{
				station.SetSlot(slot, "", 0f, (Status)0, false);
				station.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetSlotVisual", new object[2] { slot, "" });
				StationItemReturn.LogInfo($"Returned cooking station item '{((Object)prefab).name}' from slot {slot}.");
				if (skillCredited && author != 0L && (int)station.m_skill != 0 && ZRoutedRpc.instance != null)
				{
					ZRoutedRpc.instance.InvokeRoutedRPC(author, "RPC_SIR_UndoStationSkill", new object[1] { (int)station.m_skill });
				}
			}
		}

		private static void ReturnCookingFuelOnOwner(CookingStation station, Vector3 userPoint)
		{
			//IL_006c: 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)
			if (!IsEnabled)
			{
				return;
			}
			ConfigEntry<bool> cookingStationFuelReturnEnabled = StationItemReturn.CookingStationFuelReturnEnabled;
			if (cookingStationFuelReturnEnabled != null && cookingStationFuelReturnEnabled.Value && IsValidOwner(station.m_nview) && TryGetCookingFuel(station, out var prefab, out var _, out var cheated))
			{
				Transform val = (Object.op_Implicit((Object)(object)station.m_addFuelSwitch) ? ((Component)station.m_addFuelSwitch).transform : ((Component)station).transform);
				if (SpawnItem(prefab, val.position, val.forward, userPoint, 2f, cheated, out var _))
				{
					station.SetFuel(Mathf.Max(0f, station.GetFuel() - 1f));
					bool flag = IsCookingStationActive(station);
					bool flag2 = station.GetFuel() > 0f;
					station.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SIR_RefreshCookingStation", new object[2] { flag, flag2 });
					StationItemReturn.LogInfo("Returned cooking station fuel '" + ((Object)prefab).name + "'.");
				}
			}
		}

		private static bool IsCookingStationActive(CookingStation station)
		{
			return (station.m_requireFire && station.IsFireLit()) || (station.m_useFuel && station.GetFuel() > 0f && (station.m_useFueldWhileEmpty || station.HaveUncookedItem()));
		}

		private static void RefreshCookingStation(CookingStation station, bool active, bool hasFuel)
		{
			if (Object.op_Implicit((Object)(object)station))
			{
				station.UpdateVisual(active);
				if (Object.op_Implicit((Object)(object)station.m_haveFuelObject))
				{
					station.m_haveFuelObject.SetActive(hasFuel);
				}
				if (Object.op_Implicit((Object)(object)station.m_cookingObject))
				{
					station.m_cookingObject.SetActive(!station.IsEverythingCooked() && hasFuel && !station.IsEmpty());
				}
			}
		}

		private static void ReturnFireplaceFuelOnOwner(Fireplace station, Vector3 userPoint)
		{
			//IL_006a: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled)
			{
				return;
			}
			ConfigEntry<bool> fireplaceFuelReturnEnabled = StationItemReturn.FireplaceFuelReturnEnabled;
			if (fireplaceFuelReturnEnabled != null && fireplaceFuelReturnEnabled.Value && IsValidOwner(station.m_nview) && TryGetFireplaceFuel(station, out var prefab, out var _))
			{
				Transform val = (Object.op_Implicit((Object)(object)station.m_enabledObject) ? station.m_enabledObject.transform : ((Component)station).transform);
				if (SpawnItem(prefab, val.position, val.forward, userPoint, 2f, cheated: false, out var _))
				{
					ZDO zDO = station.m_nview.GetZDO();
					float num = zDO.GetFloat(ZDOVars.s_fuel, 0f);
					zDO.Set(ZDOVars.s_fuel, Mathf.Max(0f, num - 1f));
					station.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SIR_RefreshFireplace", Array.Empty<object>());
					StationItemReturn.LogInfo("Returned fireplace fuel '" + ((Object)prefab).name + "' from '" + station.m_nview.GetPrefabName() + "'.");
				}
			}
		}

		private static void RefreshFireplace(Fireplace station)
		{
			if (Object.op_Implicit((Object)(object)station))
			{
				station.UpdateState();
			}
		}

		private static void ReturnSmelterInputOnOwner(Smelter station, Vector3 userPoint)
		{
			//IL_006c: 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)
			if (!IsEnabled)
			{
				return;
			}
			ConfigEntry<bool> smelterInputReturnEnabled = StationItemReturn.SmelterInputReturnEnabled;
			if (smelterInputReturnEnabled == null || !smelterInputReturnEnabled.Value || !IsValidOwner(station.m_nview) || !TryGetSmelterInput(station, out var queueIndex, out var prefab, out var _))
			{
				return;
			}
			Transform val = (Object.op_Implicit((Object)(object)station.m_addOreSwitch) ? ((Component)station.m_addOreSwitch).transform : ((Component)station).transform);
			if (SpawnItem(prefab, val.position, val.forward, userPoint, 2f, cheated: false, out var _))
			{
				ZDO zDO = station.m_nview.GetZDO();
				zDO.Set("item" + queueIndex, "");
				zDO.Set(ZDOVars.s_queued, queueIndex, false);
				if (queueIndex == 0)
				{
					station.SetBakeTimer(0f);
					zDO.Set(ZDOVars.s_cheatedQueued, false);
				}
				BroadcastSmelterRefresh(station);
				StationItemReturn.LogInfo($"Returned smelter input '{((Object)prefab).name}' from queue index {queueIndex}.");
			}
		}

		private static void ReturnSmelterFuelOnOwner(Smelter station, Vector3 userPoint)
		{
			//IL_0068: 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)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled)
			{
				return;
			}
			ConfigEntry<bool> smelterFuelReturnEnabled = StationItemReturn.SmelterFuelReturnEnabled;
			if (smelterFuelReturnEnabled != null && smelterFuelReturnEnabled.Value && IsValidOwner(station.m_nview) && TryGetSmelterFuel(station, out var prefab, out var _))
			{
				Transform val = (Object.op_Implicit((Object)(object)station.m_addWoodSwitch) ? ((Component)station.m_addWoodSwitch).transform : ((Component)station).transform);
				if (SpawnItem(prefab, val.position, val.forward, userPoint, 2f, cheated: false, out var _))
				{
					station.SetFuel(Mathf.Max(0f, station.GetFuel() - 1f));
					BroadcastSmelterRefresh(station);
					StationItemReturn.LogInfo("Returned smelter fuel '" + ((Object)prefab).name + "'.");
				}
			}
		}

		private static void BroadcastSmelterRefresh(Smelter station)
		{
			station.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SIR_RefreshSmelter", new object[3]
			{
				station.IsActive(),
				station.GetFuel() > 0f,
				station.GetQueueSize() > 0
			});
		}

		private static void RefreshSmelter(Smelter station, bool active, bool hasFuel, bool hasInput)
		{
			if (Object.op_Implicit((Object)(object)station))
			{
				if (Object.op_Implicit((Object)(object)station.m_enabledObject))
				{
					station.m_enabledObject.SetActive(active);
				}
				if (Object.op_Implicit((Object)(object)station.m_disabledObject))
				{
					station.m_disabledObject.SetActive(!active);
				}
				if (Object.op_Implicit((Object)(object)station.m_haveFuelObject))
				{
					station.m_haveFuelObject.SetActive(hasFuel);
				}
				if (Object.op_Implicit((Object)(object)station.m_haveOreObject))
				{
					station.m_haveOreObject.SetActive(hasInput);
				}
				if (Object.op_Implicit((Object)(object)station.m_noOreObject))
				{
					station.m_noOreObject.SetActive(!hasInput);
				}
				station.SetAnimation(active);
			}
		}

		private static void ReturnFermenterIngredientOnOwner(Fermenter station, Vector3 userPoint)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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)
			if (!IsEnabled)
			{
				return;
			}
			ConfigEntry<bool> fermenterIngredientReturnEnabled = StationItemReturn.FermenterIngredientReturnEnabled;
			if (fermenterIngredientReturnEnabled != null && fermenterIngredientReturnEnabled.Value && IsValidOwner(station.m_nview) && TryGetFermenterIngredient(station, out var prefab, out var _, out var cheated))
			{
				Transform val = (Object.op_Implicit((Object)(object)station.m_outputPoint) ? station.m_outputPoint : ((Component)station).transform);
				if (SpawnItem(prefab, val.position, val.forward, userPoint, 2f, cheated, out var _))
				{
					ZDO zDO = station.m_nview.GetZDO();
					zDO.Set(ZDOVars.s_content, 0, false);
					zDO.Set(ZDOVars.s_startTime, 0L);
					zDO.Set(ZDOVars.s_cheatedQueued, false);
					station.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SIR_RefreshFermenter", Array.Empty<object>());
					StationItemReturn.LogInfo("Returned fermenter ingredient '" + ((Object)prefab).name + "'.");
				}
			}
		}

		private static void RefreshFermenter(Fermenter station)
		{
			if (Object.op_Implicit((Object)(object)station))
			{
				if (Object.op_Implicit((Object)(object)station.m_fermentingObject))
				{
					station.m_fermentingObject.SetActive(false);
				}
				if (Object.op_Implicit((Object)(object)station.m_readyObject))
				{
					station.m_readyObject.SetActive(false);
				}
				if (Object.op_Implicit((Object)(object)station.m_topObject))
				{
					station.m_topObject.SetActive(false);
				}
			}
		}

		private static void ReturnTurretAmmoOnOwner(Turret station, Vector3 userPoint)
		{
			//IL_004e: 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_0058: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled)
			{
				return;
			}
			ConfigEntry<bool> turretAmmoReturnEnabled = StationItemReturn.TurretAmmoReturnEnabled;
			if (turretAmmoReturnEnabled != null && turretAmmoReturnEnabled.Value && IsValidOwner(station.m_nview) && TryGetTurretAmmo(station, out var prefab, out var _) && SpawnItem(prefab, ((Component)station).transform.position + Vector3.up, ((Component)station).transform.forward, userPoint, 2f, cheated: false, out var _))
			{
				int num = Mathf.Max(0, station.GetAmmo() - 1);
				ZDO zDO = station.m_nview.GetZDO();
				zDO.Set(ZDOVars.s_ammo, num, false);
				string text = station.GetAmmoType();
				if (num == 0 && !Object.op_Implicit((Object)(object)station.m_defaultAmmo))
				{
					zDO.Set(ZDOVars.s_ammoType, "");
					text = "";
				}
				station.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SIR_RefreshTurret", new object[2] { num, text });
				StationItemReturn.LogInfo($"Returned turret ammunition '{((Object)prefab).name}', remaining: {num}.");
			}
		}

		private static void RefreshTurret(Turret station, int remainingAmmo, string ammoType)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_005f: 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)
			if (!Object.op_Implicit((Object)(object)station))
			{
				return;
			}
			station.m_lastAmmo = null;
			bool flag = remainingAmmo > 0 && !station.IsCoolingDown();
			foreach (AmmoType item in station.m_allowedAmmo)
			{
				if (Object.op_Implicit((Object)(object)item.m_visual))
				{
					item.m_visual.SetActive(flag && Object.op_Implicit((Object)(object)item.m_ammo) && ((Object)item.m_ammo).name == ammoType);
				}
			}
		}

		private static bool IsMatchingCookingSlot(CookingStation station, ZDO zdo, int slot, long sender, string expectedPrefabName)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (slot < 0 || station.m_slots == null || slot >= station.m_slots.Length)
			{
				return false;
			}
			string text = default(string);
			float num = default(float);
			Status val = default(Status);
			bool flag = default(bool);
			station.GetSlot(slot, ref text, ref num, ref val, ref flag);
			return text == expectedPrefabName && (int)val == 0 && zdo.GetLong(CookingAuthorKey(slot), 0L) == sender;
		}

		private static void MarkCookingSkillCreditOnOwner(CookingStation station, long sender, int requestedSlot, string expectedPrefabName)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (!IsValidOwner(station.m_nview) || (int)station.m_skill == 0 || string.IsNullOrEmpty(expectedPrefabName))
			{
				return;
			}
			ZDO zDO = station.m_nview.GetZDO();
			long num = zDO.GetLong("SIR_LastCookingAuthor", 0L);
			int num2 = zDO.GetInt("SIR_LastCookingSlot", -1);
			int num3 = (IsMatchingCookingSlot(station, zDO, num2, sender, expectedPrefabName) ? num2 : requestedSlot);
			if (IsMatchingCookingSlot(station, zDO, num3, sender, expectedPrefabName))
			{
				zDO.Set(CookingSkillKey(num3), true);
				if (num == sender && num2 == num3)
				{
					zDO.Set("SIR_LastCookingAuthor", 0L);
					zDO.Set("SIR_LastCookingSlot", -1);
				}
			}
		}

		private static void UndoStationSkill(long sender, int skill)
		{
			if (Enum.IsDefined(typeof(SkillType), skill) && skill != 0 && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				((Character)Player.m_localPlayer).RaiseSkill((SkillType)skill, -0.4f);
			}
		}
	}
}