Decompiled source of SellMyScrap v1.8.0

com.github.zehsteam.SellMyScrap.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ShipInventory;
using ShipInventory.Helpers;
using ShipInventory.Objects;
using Steamworks;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
using com.github.zehsteam.SellMyScrap.Commands;
using com.github.zehsteam.SellMyScrap.Data;
using com.github.zehsteam.SellMyScrap.Dependencies;
using com.github.zehsteam.SellMyScrap.Dependencies.ShipInventoryProxy;
using com.github.zehsteam.SellMyScrap.Dependencies.ShipInventoryProxy.Patches;
using com.github.zehsteam.SellMyScrap.MonoBehaviours;
using com.github.zehsteam.SellMyScrap.NetcodePatcher;
using com.github.zehsteam.SellMyScrap.Patches;
using com.github.zehsteam.SellMyScrap.ScrapEaters;
using com.github.zehsteam.TakeyPlush;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.zehsteam.SellMyScrap")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Adds a few terminal commands to sell your scrap from the ship. Compatible with the ShipInventory mod. Highly Configurable. SellFromTerminal +")]
[assembly: AssemblyFileVersion("1.8.0.0")]
[assembly: AssemblyInformationalVersion("1.8.0+7dab18205889ddcda7adf02e7526001ada2fde21")]
[assembly: AssemblyProduct("SellMyScrap")]
[assembly: AssemblyTitle("com.github.zehsteam.SellMyScrap")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace com.github.zehsteam.SellMyScrap
{
	public static class ConfigHelper
	{
		private static List<ConfigItem> _generalConfigItems = new List<ConfigItem>();

		private static List<ConfigItem> _sellConfigItems = new List<ConfigItem>();

		private static List<ConfigItem> _advancedSellConfigItems = new List<ConfigItem>();

		private static List<ConfigItem> _terminalConfigItems = new List<ConfigItem>();

		private static List<ConfigItem> _miscConfigItems = new List<ConfigItem>();

		private static List<ConfigItem> _scrapEaterConfigItems = new List<ConfigItem>();

		private static List<ConfigItem> _allConfigItems
		{
			get
			{
				List<ConfigItem> list = new List<ConfigItem>();
				list.AddRange(_generalConfigItems);
				list.AddRange(_sellConfigItems);
				list.AddRange(_advancedSellConfigItems);
				list.AddRange(_terminalConfigItems);
				list.AddRange(_miscConfigItems);
				list.AddRange(_scrapEaterConfigItems);
				return list;
			}
		}

		internal static void Initialize()
		{
			SyncedConfigManager configManager = Plugin.ConfigManager;
			List<ConfigItem> list = new List<ConfigItem>(1);
			list.Add(new ConfigItem("ExtendedLogging", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.ExtendedLogging = bool.Parse(value);
			}, () => configManager.ExtendedLogging.ToString()));
			_generalConfigItems = list;
			list = new List<ConfigItem>(5);
			list.Add(new ConfigItem("SellGifts", typeof(bool), isHostOnly: true, delegate(string value)
			{
				configManager.SellGifts = bool.Parse(value);
			}, () => configManager.SellGifts.ToString()));
			list.Add(new ConfigItem("SellShotguns", typeof(bool), isHostOnly: true, delegate(string value)
			{
				configManager.SellShotguns = bool.Parse(value);
			}, () => configManager.SellShotguns.ToString()));
			list.Add(new ConfigItem("SellAmmo", typeof(bool), isHostOnly: true, delegate(string value)
			{
				configManager.SellAmmo = bool.Parse(value);
			}, () => configManager.SellAmmo.ToString()));
			list.Add(new ConfigItem("SellKnives", typeof(bool), isHostOnly: true, delegate(string value)
			{
				configManager.SellKnives = bool.Parse(value);
			}, () => configManager.SellKnives.ToString()));
			list.Add(new ConfigItem("SellPickles", typeof(bool), isHostOnly: true, delegate(string value)
			{
				configManager.SellPickles = bool.Parse(value);
			}, () => configManager.SellPickles.ToString()));
			_sellConfigItems = list;
			list = new List<ConfigItem>(5);
			list.Add(new ConfigItem("SellScrapWorthZero", typeof(bool), isHostOnly: true, delegate(string value)
			{
				configManager.SellScrapWorthZero = bool.Parse(value);
			}, () => configManager.SellScrapWorthZero.ToString()));
			list.Add(new ConfigItem("OnlySellScrapOnFloor", typeof(bool), isHostOnly: true, delegate(string value)
			{
				configManager.OnlySellScrapOnFloor = bool.Parse(value);
			}, () => configManager.OnlySellScrapOnFloor.ToString()));
			list.Add(new ConfigItem("PrioritySellList", typeof(string[]), isHostOnly: true, null, () => string.Join(", ", configManager.PrioritySellList)));
			list.Add(new ConfigItem("DontSellList", typeof(string[]), isHostOnly: true, null, () => string.Join(", ", configManager.DontSellList)));
			list.Add(new ConfigItem("SellList", typeof(string[]), isHostOnly: true, null, () => string.Join(", ", configManager.SellList)));
			_advancedSellConfigItems = list;
			list = new List<ConfigItem>(5);
			list.Add(new ConfigItem("OverrideWelcomeMessage", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.OverrideWelcomeMessage = bool.Parse(value);
			}, () => configManager.OverrideWelcomeMessage.ToString()));
			list.Add(new ConfigItem("OverrideHelpMessage", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.OverrideHelpMessage = bool.Parse(value);
			}, () => configManager.OverrideHelpMessage.ToString()));
			list.Add(new ConfigItem("ShowFoundItems", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.ShowFoundItems = bool.Parse(value);
			}, () => configManager.ShowFoundItems.ToString()));
			list.Add(new ConfigItem("SortFoundItemsPrice", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.SortFoundItemsPrice = bool.Parse(value);
			}, () => configManager.SortFoundItemsPrice.ToString()));
			list.Add(new ConfigItem("AlignFoundItemsPrice", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.AlignFoundItemsPrice = bool.Parse(value);
			}, () => configManager.AlignFoundItemsPrice.ToString()));
			_terminalConfigItems = list;
			list = new List<ConfigItem>(3);
			list.Add(new ConfigItem("SpeakInShip", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.SpeakInShip = bool.Parse(value);
			}, () => configManager.SpeakInShip.ToString()));
			list.Add(new ConfigItem("RareVoiceLineChance", typeof(float), isHostOnly: true, delegate(string value)
			{
				configManager.RareVoiceLineChance = float.Parse(value);
			}, () => configManager.RareVoiceLineChance.ToString()));
			list.Add(new ConfigItem("ShowQuotaWarning", typeof(bool), isHostOnly: false, delegate(string value)
			{
				configManager.ShowQuotaWarning = bool.Parse(value);
			}, () => configManager.ShowQuotaWarning.ToString()));
			_miscConfigItems = list;
			list = new List<ConfigItem>(9);
			list.Add(new ConfigItem("ScrapEaterChance", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.ScrapEaterChance = int.Parse(value);
			}, () => configManager.ScrapEaterChance.ToString()));
			list.Add(new ConfigItem("OctolarSpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.OctolarSpawnWeight = int.Parse(value);
			}, () => configManager.OctolarSpawnWeight.ToString()));
			list.Add(new ConfigItem("TakeySpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.TakeySpawnWeight = int.Parse(value);
			}, () => configManager.TakeySpawnWeight.ToString()));
			list.Add(new ConfigItem("MaxwellSpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.MaxwellSpawnWeight = int.Parse(value);
			}, () => configManager.MaxwellSpawnWeight.ToString()));
			list.Add(new ConfigItem("YippeeSpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.YippeeSpawnWeight = int.Parse(value);
			}, () => configManager.YippeeSpawnWeight.ToString()));
			list.Add(new ConfigItem("CookieFumoSpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.CookieFumoSpawnWeight = int.Parse(value);
			}, () => configManager.CookieFumoSpawnWeight.ToString()));
			list.Add(new ConfigItem("PsychoSpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.PsychoSpawnWeight = int.Parse(value);
			}, () => configManager.PsychoSpawnWeight.ToString()));
			list.Add(new ConfigItem("ZombiesSpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.ZombiesSpawnWeight = int.Parse(value);
			}, () => configManager.ZombiesSpawnWeight.ToString()));
			list.Add(new ConfigItem("WolfySpawnWeight", typeof(int), isHostOnly: true, delegate(string value)
			{
				configManager.WolfySpawnWeight = int.Parse(value);
			}, () => configManager.WolfySpawnWeight.ToString()));
			_scrapEaterConfigItems = list;
		}

		internal static bool TrySetConfigValue(string key, string value, out ConfigItem configItem, out string parsedValue)
		{
			parsedValue = string.Empty;
			configItem = GetConfigItem(key);
			if (configItem == null)
			{
				return false;
			}
			if (configItem.IsHostOnly && !NetworkUtils.IsServer)
			{
				return false;
			}
			if (configItem.Type == typeof(bool))
			{
				return TrySetBoolConfigValue(configItem, value, out parsedValue);
			}
			if (configItem.Type == typeof(int))
			{
				return TrySetIntConfigValue(configItem, value, out parsedValue);
			}
			if (configItem.Type == typeof(float))
			{
				return TrySetFloatConfigValue(configItem, value, out parsedValue);
			}
			return false;
		}

		private static bool TrySetBoolConfigValue(ConfigItem configItem, string value, out string parsedValue)
		{
			parsedValue = string.Empty;
			if (bool.TryParse(value, out var result))
			{
				configItem.SetValue(value);
				parsedValue = result.ToString();
				return true;
			}
			return false;
		}

		private static bool TrySetIntConfigValue(ConfigItem configItem, string value, out string parsedValue)
		{
			parsedValue = string.Empty;
			if (int.TryParse(value, out var result))
			{
				configItem.SetValue(value);
				parsedValue = result.ToString();
				return true;
			}
			return false;
		}

		private static bool TrySetFloatConfigValue(ConfigItem configItem, string value, out string parsedValue)
		{
			parsedValue = string.Empty;
			if (float.TryParse(value, out var result))
			{
				configItem.SetValue(value);
				parsedValue = result.ToString();
				return true;
			}
			return false;
		}

		public static void AddScrapEaterConfigItem(string key, Action<string> setValue, Func<string> getValue)
		{
			_scrapEaterConfigItems.Add(new ConfigItem(key, typeof(int), isHostOnly: true, setValue, getValue));
		}

		private static ConfigItem GetConfigItem(string key)
		{
			foreach (ConfigItem allConfigItem in _allConfigItems)
			{
				if (allConfigItem.Key.ToLower() == key.ToLower())
				{
					return allConfigItem;
				}
			}
			return null;
		}

		internal static string GetConfigSettingsMessage()
		{
			string empty = string.Empty;
			empty += GetConfigItemListMessage("[General Settings]", _generalConfigItems);
			empty += GetConfigItemListMessage("[Sell Settings]", _sellConfigItems, syncedWithHost: true);
			empty += GetConfigItemListMessage("[Advanced Sell Settings]", _advancedSellConfigItems, syncedWithHost: true);
			empty += GetConfigItemListMessage("[Terminal Settings]", _terminalConfigItems);
			empty += GetConfigItemListMessage("[Misc Settings]", _miscConfigItems);
			empty += GetConfigItemListMessage("[Scrap Eater Settings]", _scrapEaterConfigItems, syncedWithHost: false, hostOnly: true);
			return empty.Trim();
		}

		private static string GetConfigItemListMessage(string header, List<ConfigItem> list, bool syncedWithHost = false, bool hostOnly = false)
		{
			string[] array = list.Select((ConfigItem item) => item.Key).ToArray();
			int maxLength = Utils.GetLongestStringFromArray(array).Length + 1;
			string text = string.Empty;
			if (syncedWithHost && !NetworkUtils.IsServer)
			{
				text = " (Synced with host)";
			}
			if (hostOnly && !NetworkUtils.IsServer)
			{
				text = " (Host only)";
			}
			string message = header + text + "\n";
			list.ForEach(delegate(ConfigItem configItem)
			{
				if (configItem.GetValue == null)
				{
					Plugin.Logger.LogError((object)("Func<string> GetValue() for ConfigItem key: \"" + configItem.Key + "\" could not be found!"));
				}
				else
				{
					message = message + Utils.GetStringWithSpacingInBetween(configItem.Key + ":", Utils.GetStringWithColor(configItem.GetValue(), "#007f00"), maxLength) + "\n";
				}
			});
			return message.Trim() + "\n\n";
		}

		public static void SkipAutoGen()
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.SkipAutoGen();
			}
		}

		public static void AddButton(string section, string name, string description, string buttonText, Action callback)
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddButton(section, name, description, buttonText, callback);
			}
		}

		public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, bool requiresRestart, string description, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			if (configFile == null)
			{
				configFile = ((BaseUnityPlugin)Plugin.Instance).Config;
			}
			ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>())));
			if (settingChanged != null)
			{
				configEntry.SettingChanged += delegate
				{
					settingChanged?.Invoke(configEntry.Value);
				};
			}
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart);
			}
			return configEntry;
		}

		public static Dictionary<ConfigDefinition, string> GetOrphanedConfigEntries(ConfigFile configFile = null)
		{
			if (configFile == null)
			{
				configFile = ((BaseUnityPlugin)Plugin.Instance).Config;
			}
			PropertyInfo property = ((object)configFile).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			return (Dictionary<ConfigDefinition, string>)property.GetValue(configFile, null);
		}

		public static void SetConfigEntryValue<T>(ConfigEntry<T> configEntry, string value)
		{
			if (typeof(T) == typeof(int) && int.TryParse(value, out var result))
			{
				configEntry.Value = (T)(object)result;
				return;
			}
			if (typeof(T) == typeof(float) && float.TryParse(value, out var result2))
			{
				configEntry.Value = (T)(object)result2;
				return;
			}
			if (typeof(T) == typeof(double) && double.TryParse(value, out var result3))
			{
				configEntry.Value = (T)(object)result3;
				return;
			}
			if (typeof(T) == typeof(bool) && bool.TryParse(value, out var result4))
			{
				configEntry.Value = (T)(object)result4;
				return;
			}
			if (typeof(T) == typeof(string))
			{
				configEntry.Value = (T)(object)value;
				return;
			}
			throw new InvalidOperationException($"Unsupported type: {typeof(T)}");
		}

		public static void ClearUnusedEntries(ConfigFile configFile = null)
		{
			if (configFile == null)
			{
				configFile = ((BaseUnityPlugin)Plugin.Instance).Config;
			}
			Dictionary<ConfigDefinition, string> orphanedConfigEntries = GetOrphanedConfigEntries(configFile);
			if (orphanedConfigEntries != null)
			{
				orphanedConfigEntries.Clear();
				configFile.Save();
			}
		}
	}
	public class ConfigItem
	{
		public string Key { get; private set; }

		public Type Type { get; private set; }

		public bool IsHostOnly { get; private set; }

		public Action<string> SetValue { get; private set; }

		public Func<string> GetValue { get; private set; }

		public ConfigItem(string key, Type type, bool isHostOnly, Action<string> setValue, Func<string> getValue)
		{
			Key = key;
			Type = type;
			IsHostOnly = isHostOnly;
			SetValue = setValue;
			GetValue = getValue;
		}
	}
	internal static class Content
	{
		public static GameObject NetworkHandlerPrefab { get; private set; }

		public static GameObject OctolarScrapEaterPrefab { get; private set; }

		public static GameObject TakeyScrapEaterPrefab { get; private set; }

		public static GameObject MaxwellScrapEaterPrefab { get; private set; }

		public static GameObject YippeeScrapEaterPrefab { get; private set; }

		public static GameObject CookieFumoScrapEaterPrefab { get; private set; }

		public static GameObject PsychoScrapEaterPrefab { get; private set; }

		public static GameObject ZombiesScrapEaterPrefab { get; private set; }

		public static GameObject WolfyScrapEaterPrefab { get; private set; }

		public static void Load()
		{
			LoadAssetsFromAssetBundle();
		}

		private static void LoadAssetsFromAssetBundle()
		{
			AssetBundle val = LoadAssetBundle("sellmyscrap_assets");
			if (!((Object)(object)val == (Object)null))
			{
				NetworkHandlerPrefab = LoadAssetFromAssetBundle<GameObject>("NetworkHandler", val);
				NetworkHandlerPrefab.AddComponent<PluginNetworkBehaviour>();
				OctolarScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("OctolarScrapEater", val);
				TakeyScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("TakeyScrapEater", val);
				MaxwellScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("MaxwellScrapEater", val);
				YippeeScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("YippeeScrapEater", val);
				CookieFumoScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("CookieFumoScrapEater", val);
				PsychoScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("PsychoScrapEater", val);
				ZombiesScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("ZombiesScrapEater", val);
				WolfyScrapEaterPrefab = LoadAssetFromAssetBundle<GameObject>("WolfyScrapEater", val);
				Plugin.Logger.LogInfo((object)"Successfully loaded assets from AssetBundle!");
			}
		}

		private static AssetBundle LoadAssetBundle(string fileName)
		{
			try
			{
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
				string text = Path.Combine(directoryName, fileName);
				return AssetBundle.LoadFromFile(text);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to load AssetBundle \"{fileName}\". {arg}");
			}
			return null;
		}

		private static T LoadAssetFromAssetBundle<T>(string name, AssetBundle assetBundle) where T : Object
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace."));
				return default(T);
			}
			if ((Object)(object)assetBundle == (Object)null)
			{
				Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null."));
				return default(T);
			}
			T val = assetBundle.LoadAsset<T>(name);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Logger.LogError((object)("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name."));
				return default(T);
			}
			return val;
		}
	}
	internal static class ModpackSaveSystem
	{
		public const string FileName = "SellMyScrap_SaveData.json";

		private static JObject _saveFileObject;

		public static string FilePath
		{
			get
			{
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Config.ConfigFilePath);
				return Path.Combine(directoryName, "SellMyScrap_SaveData.json");
			}
		}

		public static bool FileExists => File.Exists(FilePath);

		public static void Initialize()
		{
			if (!FileExists)
			{
				WriteFile(JObject.Parse("{}"));
			}
			_saveFileObject = ReadFile();
		}

		public static bool ContainsKey(string key)
		{
			return _saveFileObject.ContainsKey(key);
		}

		public static T ReadValue<T>(string key, T defaultValue = default(T))
		{
			//IL_001e: Expected O, but got Unknown
			JToken val = default(JToken);
			if (_saveFileObject.TryGetValue(key, ref val))
			{
				try
				{
					return val.ToObject<T>();
				}
				catch (JsonException val2)
				{
					JsonException val3 = val2;
					Plugin.Logger.LogError((object)("JSON Conversion Error: " + ((Exception)(object)val3).Message));
				}
				catch (ArgumentNullException ex)
				{
					Plugin.Logger.LogError((object)("Argument Null Error: " + ex.Message));
				}
				catch (Exception ex2)
				{
					Plugin.Logger.LogError((object)("Unexpected Error: " + ex2.Message));
				}
				return defaultValue;
			}
			return defaultValue;
		}

		public static void WriteValue<T>(string key, T value)
		{
			JToken val = JToken.FromObject((object)value);
			if (_saveFileObject.ContainsKey(key))
			{
				_saveFileObject[key] = val;
			}
			else
			{
				_saveFileObject.Add(key, val);
			}
			WriteFile(_saveFileObject);
		}

		private static JObject ReadFile()
		{
			try
			{
				using FileStream stream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite);
				using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
				return JObject.Parse(streamReader.ReadToEnd());
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to read save file.\n\n{arg}");
			}
			return null;
		}

		private static bool WriteFile(JObject jObject)
		{
			try
			{
				using FileStream stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite);
				using StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8);
				streamWriter.WriteLine(((object)jObject).ToString());
				return true;
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to write save file.\n\n{arg}");
			}
			return false;
		}
	}
	public static class NetworkUtils
	{
		public static bool IsServer
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					return false;
				}
				return NetworkManager.Singleton.IsServer;
			}
		}

		public static bool IsHost
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					return false;
				}
				return NetworkManager.Singleton.IsHost;
			}
		}

		public static ulong GetLocalClientId()
		{
			return NetworkManager.Singleton.LocalClientId;
		}

		public static bool IsLocalClientId(ulong clientId)
		{
			return clientId == GetLocalClientId();
		}

		public static NetworkObjectReference[] GetNetworkObjectReferences(List<GrabbableObject> grabbableObjects)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (grabbableObjects == null || grabbableObjects.Count == 0)
			{
				return Array.Empty<NetworkObjectReference>();
			}
			List<NetworkObjectReference> list = new List<NetworkObjectReference>();
			NetworkObject val = default(NetworkObject);
			foreach (GrabbableObject grabbableObject in grabbableObjects)
			{
				if (((Component)grabbableObject).TryGetComponent<NetworkObject>(ref val))
				{
					list.Add(NetworkObjectReference.op_Implicit(val));
				}
			}
			return list.ToArray();
		}

		public static List<GrabbableObject> GetGrabbableObjects(NetworkObjectReference[] networkObjectReferences)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (networkObjectReferences == null || networkObjectReferences.Length == 0)
			{
				return new List<GrabbableObject>();
			}
			List<GrabbableObject> list = new List<GrabbableObject>();
			NetworkObject val2 = default(NetworkObject);
			GrabbableObject item = default(GrabbableObject);
			for (int i = 0; i < networkObjectReferences.Length; i++)
			{
				NetworkObjectReference val = networkObjectReferences[i];
				if (((NetworkObjectReference)(ref val)).TryGet(ref val2, (NetworkManager)null) && ((Component)val2).TryGetComponent<GrabbableObject>(ref item))
				{
					list.Add(item);
				}
			}
			return list;
		}
	}
	internal static class PlayerUtils
	{
		private static float _previousPlayerMovementSpeed;

		private static float _previousPlayerJumpForce;

		public static PlayerControllerB GetLocalPlayerScript()
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return null;
			}
			return GameNetworkManager.Instance.localPlayerController;
		}

		public static bool IsLocalPlayer(PlayerControllerB playerScript)
		{
			return (Object)(object)playerScript == (Object)(object)GetLocalPlayerScript();
		}

		public static bool IsLocalPlayer(PlayerName playerName)
		{
			return SteamUtils.IsLocalClient(playerName);
		}

		public static bool IsLocalPlayer(params PlayerName[] playerNames)
		{
			foreach (PlayerName playerName in playerNames)
			{
				if (SteamUtils.IsLocalClient(playerName))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsPlayer(PlayerControllerB playerScript, PlayerName playerName)
		{
			if ((Object)(object)playerScript == (Object)null)
			{
				return false;
			}
			return SteamUtils.IsPlayer(playerName, playerScript.playerUsername, playerScript.playerSteamId);
		}

		public static bool HasPlayer(PlayerName playerName)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB playerScript in allPlayerScripts)
			{
				if (IsPlayer(playerScript, playerName))
				{
					return true;
				}
			}
			return false;
		}

		public static bool HasPlayer(params PlayerName[] playerNames)
		{
			foreach (PlayerName playerName in playerNames)
			{
				if (HasPlayer(playerName))
				{
					return true;
				}
			}
			return false;
		}

		public static PlayerControllerB GetPlayerScript(PlayerName playerName)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (IsPlayer(val, playerName))
				{
					return val;
				}
			}
			return null;
		}

		public static PlayerControllerB GetPlayerScriptByClientId(ulong clientId)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.actualClientId == clientId)
				{
					return val;
				}
			}
			return null;
		}

		public static bool AreAllPlayersDead()
		{
			bool result = true;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!val.isPlayerDead)
				{
					result = false;
				}
			}
			return result;
		}

		public static void SetLocalPlayerMovementEnabled(bool enabled)
		{
			PlayerControllerB localPlayerScript = GetLocalPlayerScript();
			if (enabled)
			{
				if (_previousPlayerMovementSpeed == 0f)
				{
					_previousPlayerMovementSpeed = 4.6f;
				}
				if (_previousPlayerJumpForce == 0f)
				{
					_previousPlayerJumpForce = 13f;
				}
				localPlayerScript.movementSpeed = _previousPlayerMovementSpeed;
				localPlayerScript.jumpForce = _previousPlayerJumpForce;
			}
			else
			{
				if (localPlayerScript.movementSpeed > 0f)
				{
					_previousPlayerMovementSpeed = localPlayerScript.movementSpeed;
				}
				if (localPlayerScript.jumpForce > 0f)
				{
					_previousPlayerJumpForce = localPlayerScript.jumpForce;
				}
				localPlayerScript.movementSpeed = 0f;
				localPlayerScript.jumpForce = 0f;
			}
		}

		public static void SetLocalPlayerAllowDeathEnabled(bool enabled)
		{
			StartOfRound.Instance.allowLocalPlayerDeath = enabled;
		}

		public static void ReviveDeadPlayersAfterTime(float time)
		{
			((MonoBehaviour)StartOfRound.Instance).StartCoroutine(ReviveDeadPlayersAfterTimeCO(time));
		}

		private static IEnumerator ReviveDeadPlayersAfterTimeCO(float time)
		{
			yield return (object)new WaitForSeconds(time);
			if (AreAllPlayersDead())
			{
				StartOfRound.Instance.ReviveDeadPlayers();
			}
		}
	}
	[BepInPlugin("com.github.zehsteam.SellMyScrap", "SellMyScrap", "1.8.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.zehsteam.SellMyScrap");

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static SyncedConfigManager ConfigManager { get; private set; }

		public ScrapToSell ScrapToSell { get; private set; }

		public SellRequest SellRequest { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Logger = Logger.CreateLogSource("com.github.zehsteam.SellMyScrap");
			Logger.LogInfo((object)"SellMyScrap has awoken!");
			_harmony.PatchAll(typeof(GameNetworkManagerPatch));
			_harmony.PatchAll(typeof(StartOfRoundPatch));
			_harmony.PatchAll(typeof(TimeOfDayPatch));
			_harmony.PatchAll(typeof(HUDManagerPatch));
			_harmony.PatchAll(typeof(TerminalPatch));
			_harmony.PatchAll(typeof(DepositItemsDeskPatch));
			_harmony.PatchAll(typeof(StartMatchLeverPatch));
			_harmony.PatchAll(typeof(InteractTriggerPatch));
			if (ShipInventoryProxy.Enabled)
			{
				ShipInventoryProxy.PatchAll(_harmony);
			}
			ConfigManager = new SyncedConfigManager();
			Content.Load();
			ModpackSaveSystem.Initialize();
			CommandManager.Initialize();
			ConfigHelper.Initialize();
			ScrapEaterManager.Initialize();
			NetcodePatcherAwake();
		}

		private void NetcodePatcherAwake()
		{
			try
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Type[] types = executingAssembly.GetTypes();
				Type[] array = types;
				foreach (Type type in array)
				{
					MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
					MethodInfo[] array2 = methods;
					foreach (MethodInfo methodInfo in array2)
					{
						try
						{
							object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
							if (customAttributes.Length != 0)
							{
								try
								{
									methodInfo.Invoke(null, null);
								}
								catch (TargetInvocationException ex)
								{
									Logger.LogWarning((object)("Failed to invoke method " + methodInfo.Name + ": " + ex.Message));
								}
							}
						}
						catch (Exception ex2)
						{
							Logger.LogWarning((object)("Error processing method " + methodInfo.Name + " in type " + type.Name + ": " + ex2.Message));
						}
					}
				}
			}
			catch (Exception ex3)
			{
				Logger.LogError((object)("An error occurred in NetcodePatcherAwake: " + ex3.Message));
			}
		}

		public void OnLocalDisconnect()
		{
			Logger.LogInfo((object)"Local player disconnected. Removing hostConfigData.");
			ConfigManager.SetHostConfigData(null);
			CommandManager.OnLocalDisconnect();
			CancelSellRequest();
		}

		public void OnTerminalQuit()
		{
			CommandManager.OnTerminalQuit();
			CancelSellRequest();
		}

		public ScrapToSell GetScrapToSell(int value, bool onlyAllowedScrap = true, bool withOvertimeBonus = false, bool onlyUseShipInventory = false)
		{
			ScrapToSell = ScrapHelper.GetScrapToSell(value, onlyAllowedScrap, withOvertimeBonus, onlyUseShipInventory);
			return ScrapToSell;
		}

		public ScrapToSell GetScrapToSell(string[] sellList, bool onlyUseShipInventory = false)
		{
			ScrapToSell = ScrapHelper.GetScrapToSell(sellList);
			return ScrapToSell;
		}

		public ScrapToSell SetScrapToSell(List<ItemData> items)
		{
			ScrapToSell = new ScrapToSell(items);
			return ScrapToSell;
		}

		public void CreateSellRequest(SellType sellType, int value, int requestedValue, ConfirmationStatus confirmationType, int scrapEaterIndex = -2, int scrapEaterVariantIndex = -1)
		{
			SellRequest = new SellRequest(sellType, value, requestedValue, confirmationType, scrapEaterIndex, scrapEaterVariantIndex);
			string text = $"Created sell request. {ScrapToSell.ItemCount} items for ${value}.";
			if (scrapEaterIndex >= 0)
			{
				text += $" (ScrapEaterIndex: {scrapEaterIndex}, ScrapEaterVariantIndex: {scrapEaterVariantIndex})";
			}
			Logger.LogInfo((object)text);
		}

		public void ConfirmSellRequest()
		{
			if (ScrapToSell != null && SellRequest != null)
			{
				SellRequest.ConfirmationStatus = ConfirmationStatus.Confirmed;
				Logger.LogInfo((object)$"Attempting to sell {ScrapToSell.ItemCount} items for ${ScrapToSell.TotalScrapValue}.");
				if (NetworkUtils.IsServer)
				{
					ConfirmSellRequestOnServer();
				}
				else
				{
					ConfirmSellRequestOnClient();
				}
				SellRequest = null;
			}
		}

		private void ConfirmSellRequestOnServer()
		{
			((MonoBehaviour)StartOfRound.Instance).StartCoroutine(PerformSellOnServer());
		}

		private void ConfirmSellRequestOnClient()
		{
			//IL_0025: 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)
			PluginNetworkBehaviour.Instance.PerformSellServerRpc(ScrapToSell, SellRequest.SellType, SellRequest.ScrapEaterIndex);
		}

		public void CancelSellRequest()
		{
			SellRequest = null;
			ScrapToSell = null;
		}

		public void PerformSellOnServerFromClient(ScrapToSell scrapToSell, SellType sellType, int scrapEaterIndex = -2, int scrapEaterVariantIndex = -1)
		{
			ScrapToSell = scrapToSell;
			CreateSellRequest(sellType, ScrapToSell.TotalScrapValue, ScrapToSell.TotalScrapValue, ConfirmationStatus.AwaitingConfirmation, scrapEaterIndex, scrapEaterVariantIndex);
			ConfirmSellRequest();
		}

		public IEnumerator PerformSellOnServer()
		{
			if (ScrapToSell == null || SellRequest == null)
			{
				yield return null;
			}
			if (SellRequest.ConfirmationStatus != ConfirmationStatus.Confirmed)
			{
				yield return null;
			}
			if ((Object)(object)DepositItemsDeskPatch.Instance == (Object)null)
			{
				Logger.LogError((object)"Could not find depositItemsDesk. Are you landed at The Company building?");
				yield break;
			}
			int scrapEaterIndex = SellRequest.ScrapEaterIndex;
			int scrapEaterVariantIndex = SellRequest.ScrapEaterVariantIndex;
			List<GrabbableObject> grabbableObjects = ScrapToSell.GrabbableObjects;
			if (ShipInventoryProxy.Enabled && ScrapToSell.ShipInventoryItems.Length != 0)
			{
				ShipInventoryProxy.SpawnItemsOnServer(ScrapToSell.ShipInventoryItems);
				yield return (object)new WaitUntil((Func<bool>)(() => !ShipInventoryProxy.IsSpawning));
				if (ShipInventoryProxy.SpawnItemsStatus == SpawnItemsStatus.Success)
				{
					grabbableObjects.AddRange(ShipInventoryProxy.GetSpawnedGrabbableObjects());
					ShipInventoryProxy.ClearSpawnedGrabbableObjectsCache();
				}
				else
				{
					if (ShipInventoryProxy.SpawnItemsStatus == SpawnItemsStatus.Failed)
					{
						HUDManager.Instance.DisplayTip("SellMyScrap", "Failed to spawn items from ShipInventory!", true, false, "LC_Tip1");
						yield break;
					}
					if (ShipInventoryProxy.SpawnItemsStatus == SpawnItemsStatus.Busy)
					{
						HUDManager.Instance.DisplayTip("SellMyScrap", "Failed to spawn items from ShipInventory! Chute is busy.", true, false, "LC_Tip1");
						yield break;
					}
				}
			}
			if (!StartOfRound.Instance.shipIsLeaving)
			{
				if (scrapEaterIndex == -1)
				{
					ScrapEaterManager.StartRandomScrapEaterOnServer(grabbableObjects, scrapEaterVariantIndex);
					yield break;
				}
				if (scrapEaterIndex > -1 && ScrapEaterManager.HasScrapEater(scrapEaterIndex))
				{
					ScrapEaterManager.StartScrapEaterOnServer(scrapEaterIndex, grabbableObjects, scrapEaterVariantIndex);
					yield break;
				}
				if (ScrapEaterManager.CanUseScrapEater())
				{
					ScrapEaterManager.StartRandomScrapEaterOnServer(grabbableObjects, scrapEaterVariantIndex);
					yield break;
				}
			}
			DepositItemsDeskPatch.PlaceItemsOnCounter(grabbableObjects);
			PluginNetworkBehaviour.Instance.PlaceItemsOnCounterClientRpc(NetworkUtils.GetNetworkObjectReferences(grabbableObjects));
			yield return (object)new WaitForSeconds(0.5f);
			DepositItemsDeskPatch.SellItemsOnServer();
			ScrapToSell = null;
		}

		public void LogInfoExtended(object data)
		{
			if (ConfigManager.ExtendedLogging)
			{
				Logger.LogInfo(data);
			}
		}

		public void LogMessageExtended(object data)
		{
			if (ConfigManager.ExtendedLogging)
			{
				Logger.LogMessage(data);
			}
		}
	}
	internal static class ScrapHelper
	{
		public static Transform HangarShipTransform => StartOfRound.Instance.elevatorTransform;

		private static List<GrabbableObject> GetValidScrap(IEnumerable<GrabbableObject> grabbableObjects, bool onlyAllowedScrap)
		{
			if (grabbableObjects == null)
			{
				return new List<GrabbableObject>();
			}
			return grabbableObjects.Where((GrabbableObject x) => IsValidScrap(x, onlyAllowedScrap)).ToList();
		}

		public static List<GrabbableObject> GetScrapFromShip(bool onlyAllowedScrap = true)
		{
			if ((Object)(object)HangarShipTransform == (Object)null)
			{
				return new List<GrabbableObject>();
			}
			return GetValidScrap(((Component)HangarShipTransform).GetComponentsInChildren<GrabbableObject>(), onlyAllowedScrap);
		}

		public static List<GrabbableObject> GetScrapFromVehicle(bool onlyAllowedScrap = true)
		{
			VehicleController val = Object.FindFirstObjectByType<VehicleController>();
			if ((Object)(object)val == (Object)null)
			{
				return new List<GrabbableObject>();
			}
			return GetValidScrap(((Component)val).GetComponentsInChildren<GrabbableObject>(), onlyAllowedScrap);
		}

		public static List<ItemData> GetItemDataList(List<GrabbableObject> shipGrabbableObjects, List<GrabbableObject> vehicleGrabbableObjects, ShipInventoryItemData[] shipInventoryItems)
		{
			List<ItemData> list = new List<ItemData>();
			foreach (GrabbableObject shipGrabbableObject in shipGrabbableObjects)
			{
				list.Add(new ItemData(shipGrabbableObject, ItemLocation.Ship));
			}
			foreach (GrabbableObject vehicleGrabbableObject in vehicleGrabbableObjects)
			{
				list.Add(new ItemData(vehicleGrabbableObject, ItemLocation.Vehicle));
			}
			foreach (ShipInventoryItemData shipInventoryItemData in shipInventoryItems)
			{
				list.Add(new ItemData(shipInventoryItemData, ItemLocation.ShipInventory));
			}
			return list;
		}

		public static List<ItemData> GetAllScrap(bool onlyAllowedScrap = true, bool onlyUseShipInventory = false)
		{
			ShipInventoryItemData[] shipInventoryItems = Array.Empty<ShipInventoryItemData>();
			if (ShipInventoryProxy.Enabled)
			{
				shipInventoryItems = (from x in ShipInventoryProxy.GetItems()
					where IsValidScrap(x, onlyAllowedScrap)
					select x).ToArray();
				if (onlyUseShipInventory)
				{
					return GetItemDataList(new List<GrabbableObject>(), new List<GrabbableObject>(), shipInventoryItems);
				}
			}
			return GetItemDataList(GetScrapFromShip(onlyAllowedScrap), GetScrapFromVehicle(onlyAllowedScrap), shipInventoryItems);
		}

		public static List<ItemData> GetAllScrapByItemName(string itemName, bool matchCase = false, bool onlyAllowedScrap = false, bool onlyUseShipInventory = false)
		{
			StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture);
			return (from item in GetAllScrap(onlyAllowedScrap, onlyUseShipInventory)
				where item.ItemName.Contains(itemName, comparisonType)
				select item).ToList();
		}

		public static List<ItemData> GetAllScrapByItemNames(string[] itemNames, bool matchCase = false, bool onlyAllowedScrap = false, bool onlyUseShipInventory = false)
		{
			StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture);
			return GetAllScrap(onlyAllowedScrap, onlyUseShipInventory).Where(delegate(ItemData item)
			{
				string[] array = itemNames;
				foreach (string value in array)
				{
					if (item.ItemName.Contains(value, comparisonType))
					{
						return true;
					}
				}
				return false;
			}).ToList();
		}

		public static List<Item> GetAllScrapItems()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return new List<Item>();
			}
			return StartOfRound.Instance.allItemsList.itemsList.Where(IsScrap).ToList();
		}

		public static bool IsScrap(GrabbableObject grabbableObject)
		{
			if ((Object)(object)grabbableObject == (Object)null)
			{
				return false;
			}
			if (!IsScrap(grabbableObject.itemProperties))
			{
				return false;
			}
			if (grabbableObject.isHeld || !grabbableObject.grabbable)
			{
				return false;
			}
			return true;
		}

		public static bool IsScrap(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			return item.isScrap;
		}

		public static bool IsAllowedScrap(GrabbableObject grabbableObject, string[] dontSellList, bool matchCase = false)
		{
			if ((Object)(object)grabbableObject == (Object)null)
			{
				return false;
			}
			return IsAllowedScrap(grabbableObject.itemProperties, dontSellList, matchCase);
		}

		public static bool IsAllowedScrap(Item item, string[] dontSellItemNames, bool matchCase = false)
		{
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			return IsAllowedScrap(item.itemName, dontSellItemNames, matchCase);
		}

		public static bool IsAllowedScrap(ShipInventoryItemData shipInventoryItemData, string[] dontSellItemNames, bool matchCase = false)
		{
			if (shipInventoryItemData == null)
			{
				return false;
			}
			return IsAllowedScrap(shipInventoryItemData.ItemName, dontSellItemNames, matchCase);
		}

		public static bool IsAllowedScrap(string itemName, string[] dontSellItemNames, bool matchCase = false)
		{
			StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture);
			if (itemName.Equals("Gift", comparisonType) && !Plugin.ConfigManager.SellGifts)
			{
				return false;
			}
			if (itemName.Equals("Shotgun", comparisonType) && !Plugin.ConfigManager.SellShotguns)
			{
				return false;
			}
			if (itemName.Equals("Ammo", comparisonType) && !Plugin.ConfigManager.SellAmmo)
			{
				return false;
			}
			if (itemName.Equals("Kitchen knife", comparisonType) && !Plugin.ConfigManager.SellKnives)
			{
				return false;
			}
			if (itemName.Equals("Jar of pickles", comparisonType) && !Plugin.ConfigManager.SellPickles)
			{
				return false;
			}
			foreach (string value in dontSellItemNames)
			{
				if (itemName.Contains(value, comparisonType))
				{
					return false;
				}
			}
			return true;
		}

		public static bool IsValidScrap(GrabbableObject grabbableObject, bool onlyAllowedScrap)
		{
			if ((Object)(object)grabbableObject == (Object)null)
			{
				return false;
			}
			if (!IsScrap(grabbableObject))
			{
				return false;
			}
			if (!Plugin.ConfigManager.SellScrapWorthZero && grabbableObject.scrapValue <= 0)
			{
				return false;
			}
			if (Plugin.ConfigManager.OnlySellScrapOnFloor && !IsScrapOnFloor(grabbableObject))
			{
				return false;
			}
			if (onlyAllowedScrap && !IsAllowedScrap(grabbableObject, Plugin.ConfigManager.DontSellList))
			{
				return false;
			}
			return true;
		}

		public static bool IsValidScrap(ShipInventoryItemData shipInventoryItemData, bool onlyAllowedScrap)
		{
			if (shipInventoryItemData == null)
			{
				return false;
			}
			if (!Plugin.ConfigManager.SellScrapWorthZero && shipInventoryItemData.ScrapValue <= 0)
			{
				return false;
			}
			if (onlyAllowedScrap && !IsAllowedScrap(shipInventoryItemData, Plugin.ConfigManager.DontSellList))
			{
				return false;
			}
			return true;
		}

		public static bool IsScrapOnFloor(GrabbableObject grabbableObject)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)grabbableObject == (Object)null)
			{
				return false;
			}
			BoxCollider component = ((Component)grabbableObject).GetComponent<BoxCollider>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			Bounds bounds = ((Collider)component).bounds;
			float y = HangarShipTransform.position.y;
			float num = ((Bounds)(ref bounds)).center.y - ((Bounds)(ref bounds)).extents.y;
			float num2 = num - y;
			return num2 <= 0.1f;
		}

		public static Item GetItemByName(string itemName, bool matchCase = false)
		{
			StringComparison comparisonType = ((!matchCase) ? StringComparison.OrdinalIgnoreCase : StringComparison.CurrentCulture);
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				if (items.itemName.Equals(itemName, comparisonType))
				{
					return items;
				}
			}
			return null;
		}

		public static ScrapToSell GetScrapToSell(int value, bool onlyAllowedScrap = true, bool withOvertimeBonus = false, bool onlyUseShipInventory = false)
		{
			return GetScrapToSell(GetAllScrap(onlyAllowedScrap, onlyUseShipInventory), value, withOvertimeBonus);
		}

		private static ScrapToSell GetScrapToSell(List<ItemData> items, int value, bool withOvertimeBonus = false)
		{
			if (value == int.MaxValue)
			{
				return new ScrapToSell(items);
			}
			int targetValue = (withOvertimeBonus ? GetSellValueWithOvertime(value) : GetSellValue(value));
			return new ScrapToSell(FindBestMatch(items, targetValue, Plugin.ConfigManager.PrioritySellList));
		}

		public static List<ItemData> FindBestMatch(List<ItemData> items, int targetValue, string[] priorityList)
		{
			HashSet<string> hashSet = new HashSet<string>(priorityList, StringComparer.OrdinalIgnoreCase);
			if (items.Count == 0 || targetValue == int.MaxValue)
			{
				return items;
			}
			ItemData itemData = items.OrderBy((ItemData item) => item.ScrapValue).First();
			if (targetValue <= itemData.ScrapValue)
			{
				return new List<ItemData>(1) { itemData };
			}
			int num = items.Sum((ItemData item) => item.ScrapValue);
			if (num < targetValue)
			{
				return items;
			}
			int num2 = num;
			int[] array = new int[num2 + 1];
			List<ItemData>[] array2 = new List<ItemData>[num2 + 1];
			int[] array3 = new int[num2 + 1];
			for (int i = 0; i <= num2; i++)
			{
				array[i] = int.MaxValue;
				array2[i] = new List<ItemData>();
				array3[i] = 0;
			}
			array[0] = 0;
			foreach (ItemData item in items)
			{
				int num3 = (hashSet.Contains(item.ItemName) ? 1 : 0);
				for (int num4 = num2; num4 >= item.ScrapValue; num4--)
				{
					int num5 = num4 - item.ScrapValue;
					if (array[num5] != int.MaxValue)
					{
						int num6 = array[num5] + item.ScrapValue;
						int num7 = array3[num5] + num3;
						if (num6 < array[num4] || (num6 == array[num4] && num7 > array3[num4]))
						{
							array[num4] = num6;
							array2[num4] = new List<ItemData>(array2[num5]) { item };
							array3[num4] = num7;
						}
					}
				}
			}
			if (array[targetValue] != int.MaxValue)
			{
				return array2[targetValue];
			}
			for (int j = targetValue + 1; j <= num2; j++)
			{
				if (array[j] != int.MaxValue)
				{
					return array2[j];
				}
			}
			return items;
		}

		public static ScrapToSell GetScrapToSell(string[] sellList, bool onlyAllowedScrap = false, bool onlyUseShipInventory = false)
		{
			return new ScrapToSell(GetAllScrapByItemNames(sellList, onlyAllowedScrap, onlyUseShipInventory));
		}

		private static int GetSellValue(int value)
		{
			if (value == int.MaxValue)
			{
				return value;
			}
			return Mathf.CeilToInt((float)value / StartOfRound.Instance.companyBuyingRate);
		}

		private static int GetSellValueWithOvertime(int value)
		{
			int profitQuota = TimeOfDay.Instance.profitQuota;
			int quotaFulfilled = TimeOfDay.Instance.quotaFulfilled;
			int num = quotaFulfilled + value - profitQuota;
			if (num <= 0)
			{
				return GetSellValue(value);
			}
			int num2 = Mathf.Max(profitQuota - quotaFulfilled, 0);
			value -= (TimeOfDayPatch.GetDaysUntilDeadline() + 1) * 15;
			int value2 = Mathf.CeilToInt((float)(5 * value + num2 + 75) / 6f);
			return GetSellValue(value2);
		}

		public static int GetRealValue(int value)
		{
			return (int)((float)value * StartOfRound.Instance.companyBuyingRate);
		}

		public static string GetScrapMessage(List<ItemData> items)
		{
			return GetScrapMessage(items, Plugin.ConfigManager.SortFoundItemsPrice, Plugin.ConfigManager.AlignFoundItemsPrice);
		}

		public static string GetScrapMessage(List<ItemData> items, bool sortFoundItemsPrice, bool alignFoundItemsPrice)
		{
			string[] itemNames = items.Select((ItemData x) => x.ItemName).ToArray();
			int[] scrapValues = items.Select((ItemData x) => x.ScrapValue).ToArray();
			ItemLocation[] itemLocations = items.Select((ItemData x) => x.ItemLocation).ToArray();
			return GetScrapMessage(itemNames, scrapValues, itemLocations, sortFoundItemsPrice, alignFoundItemsPrice, "#007f00");
		}

		public static string GetScrapMessage(List<GrabbableObject> grabbableObjects)
		{
			return GetScrapMessage(grabbableObjects, Plugin.ConfigManager.SortFoundItemsPrice, Plugin.ConfigManager.AlignFoundItemsPrice);
		}

		public static string GetScrapMessage(List<GrabbableObject> grabbableObjects, bool sortFoundItemsPrice, bool alignFoundItemsPrice)
		{
			string[] array = grabbableObjects.Select((GrabbableObject x) => x.itemProperties.itemName).ToArray();
			int[] scrapValues = grabbableObjects.Select((GrabbableObject x) => x.scrapValue).ToArray();
			ItemLocation[] itemLocations = Enumerable.Repeat(ItemLocation.Ship, array.Length).ToArray();
			return GetScrapMessage(array, scrapValues, itemLocations, sortFoundItemsPrice, alignFoundItemsPrice, string.Empty);
		}

		public static string GetScrapMessage(string[] itemNames, int[] scrapValues, ItemLocation[] itemLocations, bool sortFoundItemsPrice, bool alignFoundItemsPrice, string color2)
		{
			var list = (from i in itemNames.Select((string item, int index) => new
				{
					Item = item,
					Value = scrapValues[index],
					Location = itemLocations[index]
				})
				group i by new { i.Item, i.Location } into g
				select new
				{
					ItemName = g.Key.Item,
					Count = g.Count(),
					TotalValue = g.Sum(i => i.Value),
					Location = g.Key.Location
				}).ToList();
			if (sortFoundItemsPrice)
			{
				list = list.OrderByDescending(item => item.TotalValue).ToList();
			}
			int totalWidth = list.Select(item => GetFormattedItemName(item.ItemName, item.Count, color2).Length).Max();
			int maxPriceLength = list.Select(item => $"${item.TotalValue}").Max((string p) => p.Length);
			StringBuilder stringBuilder = new StringBuilder();
			foreach (var item in list)
			{
				string formattedItemName = GetFormattedItemName(item.ItemName, item.Count, color2);
				string formattedPriceWithLocation = GetFormattedPriceWithLocation(item.TotalValue, item.Location, maxPriceLength);
				if (alignFoundItemsPrice)
				{
					string text = formattedItemName.PadRight(totalWidth);
					stringBuilder.AppendLine(text + " " + formattedPriceWithLocation);
				}
				else
				{
					stringBuilder.AppendLine(formattedItemName + " " + formattedPriceWithLocation);
				}
			}
			return stringBuilder.ToString().Trim();
		}

		private static string GetFormattedItemName(string itemName, int count, string color)
		{
			if (string.IsNullOrWhiteSpace(color))
			{
				return $"{itemName} (x{count}) :";
			}
			return $"{itemName} <color={color}>(x{count})</color>";
		}

		private static string GetLocationText(ItemLocation location)
		{
			if (1 == 0)
			{
			}
			string result = location switch
			{
				ItemLocation.Vehicle => " <color=#7f7f7f>(Vehicle)</color>", 
				ItemLocation.ShipInventory => " <color=#7f7f7f>(ShipInventory)</color>", 
				_ => string.Empty, 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static string GetFormattedPriceWithLocation(int totalValue, ItemLocation location, int maxPriceLength)
		{
			string text = $"${totalValue}";
			string locationText = GetLocationText(location);
			return text.PadRight(maxPriceLength) + (string.IsNullOrWhiteSpace(locationText) ? "" : locationText);
		}

		public static string GetScrapItemMessage(List<Item> scrapItems, int columns = 1, int padding = 25)
		{
			if (scrapItems == null || scrapItems.Count == 0)
			{
				return string.Empty;
			}
			int num = Mathf.CeilToInt((float)scrapItems.Count / (float)columns);
			StringBuilder[] array = new StringBuilder[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = new StringBuilder();
			}
			for (int j = 0; j < columns; j++)
			{
				for (int k = 0; k < num; k++)
				{
					int num2 = num * j + k;
					if (num2 >= scrapItems.Count)
					{
						break;
					}
					string text = scrapItems[num2]?.itemName;
					if (!string.IsNullOrEmpty(text))
					{
						array[k].Append(text.PadRight(padding));
					}
				}
			}
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder[] array2 = array;
			foreach (StringBuilder stringBuilder2 in array2)
			{
				stringBuilder.AppendLine(stringBuilder2.ToString().Trim());
			}
			return stringBuilder.ToString().Trim();
		}
	}
	internal enum PlayerName
	{
		Takerst,
		ZombiesAteMyChannel,
		Insym,
		Thorlar,
		PsychoHypnotic,
		Magoroku,
		IElucian
	}
	internal static class SteamUtils
	{
		public static List<PlayerData> PlayersData { get; private set; } = new List<PlayerData>();


		public static void Initialize()
		{
			PlayersData = new List<PlayerData>(7)
			{
				new PlayerData(PlayerName.Takerst, "Takerst", 76561197980238122uL),
				new PlayerData(PlayerName.ZombiesAteMyChannel, "ZombieAteMyChannel", 76561197990822861uL),
				new PlayerData(PlayerName.Insym, "Insym", 76561198008109303uL),
				new PlayerData(PlayerName.Thorlar, "Thorlar", 76561197964616102uL),
				new PlayerData(PlayerName.PsychoHypnotic, "PsychoHypnotic", 76561197970440803uL),
				new PlayerData(PlayerName.Magoroku, "Magoroku", 76561197982837475uL),
				new PlayerData(PlayerName.IElucian, "iElucian", 76561197962979730uL)
			};
		}

		public static bool IsPlayer(PlayerName playerName, string username, ulong steamId)
		{
			return GetPlayerData(playerName)?.IsPlayer(username, steamId) ?? false;
		}

		public static PlayerData GetLocalClientPlayerData()
		{
			foreach (PlayerData playersDatum in PlayersData)
			{
				if (playersDatum.IsLocalClient())
				{
					return playersDatum;
				}
			}
			return null;
		}

		public static PlayerData GetPlayerData(PlayerName playerName)
		{
			foreach (PlayerData playersDatum in PlayersData)
			{
				if (playersDatum.PlayerName == playerName)
				{
					return playersDatum;
				}
			}
			return null;
		}

		public static bool IsLocalClient(PlayerName playerName)
		{
			return GetPlayerData(playerName)?.IsLocalClient() ?? false;
		}

		public static bool IsLocalClient(string username, ulong steamId)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!SteamClient.IsValid)
			{
				return false;
			}
			if (!SteamClient.IsLoggedOn)
			{
				return false;
			}
			if (SteamClient.Name.Equals(username, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (SteamId.op_Implicit(SteamClient.SteamId) == steamId)
			{
				return true;
			}
			return false;
		}
	}
	internal class PlayerData
	{
		public PlayerName PlayerName { get; private set; }

		public string[] Username { get; private set; }

		public ulong[] SteamId { get; private set; }

		public PlayerData(PlayerName playerName, string username, ulong steamId)
		{
			PlayerName = playerName;
			Username = new string[1] { username };
			SteamId = new ulong[1] { steamId };
		}

		public PlayerData(PlayerName playerName, string[] username, ulong[] steamId)
		{
			PlayerName = playerName;
			Username = username;
			SteamId = steamId;
		}

		public bool IsLocalClient()
		{
			for (int i = 0; i < Username.Length; i++)
			{
				if (SteamUtils.IsLocalClient(Username[i], SteamId[i]))
				{
					return true;
				}
			}
			return false;
		}

		public bool IsPlayer(string username, ulong steamId)
		{
			for (int i = 0; i < Username.Length; i++)
			{
				if (Username[i].Equals(username, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				if (SteamId[i] == steamId)
				{
					return true;
				}
			}
			return false;
		}
	}
	public class SyncedConfigManager
	{
		private SyncedConfigData _hostConfigData;

		private ConfigEntry<bool> ExtendedLoggingCfg;

		private ConfigEntry<bool> SellGiftsCfg;

		private ConfigEntry<bool> SellShotgunsCfg;

		private ConfigEntry<bool> SellAmmoCfg;

		private ConfigEntry<bool> SellKnivesCfg;

		private ConfigEntry<bool> SellPicklesCfg;

		private ConfigEntry<bool> SellScrapWorthZeroCfg;

		private ConfigEntry<bool> OnlySellScrapOnFloorCfg;

		private ConfigEntry<string> PrioritySellListCfg;

		private ConfigEntry<string> DontSellListCfg;

		private ConfigEntry<string> SellListCfg;

		private ConfigEntry<bool> OverrideWelcomeMessageCfg;

		private ConfigEntry<bool> OverrideHelpMessageCfg;

		private ConfigEntry<bool> ShowFoundItemsCfg;

		private ConfigEntry<bool> SortFoundItemsPriceCfg;

		private ConfigEntry<bool> AlignFoundItemsPriceCfg;

		private ConfigEntry<bool> SpeakInShipCfg;

		private ConfigEntry<float> RareVoiceLineChanceCfg;

		private ConfigEntry<bool> ShowQuotaWarningCfg;

		private ConfigEntry<int> ScrapEaterChanceCfg;

		private ConfigEntry<int> OctolarSpawnWeightCfg;

		private ConfigEntry<int> TakeySpawnWeightCfg;

		private ConfigEntry<int> MaxwellSpawnWeightCfg;

		private ConfigEntry<int> YippeeSpawnWeightCfg;

		private ConfigEntry<int> CookieFumoSpawnWeightCfg;

		private ConfigEntry<int> PsychoSpawnWeightCfg;

		private ConfigEntry<int> ZombiesSpawnWeightCfg;

		private ConfigEntry<int> WolfySpawnWeightCfg;

		internal bool ExtendedLogging
		{
			get
			{
				return ExtendedLoggingCfg.Value;
			}
			set
			{
				ExtendedLoggingCfg.Value = value;
			}
		}

		internal bool SellGifts
		{
			get
			{
				return (_hostConfigData == null) ? SellGiftsCfg.Value : _hostConfigData.SellGifts;
			}
			set
			{
				SellGiftsCfg.Value = value;
				SyncedConfigsChanged();
			}
		}

		internal bool SellShotguns
		{
			get
			{
				return (_hostConfigData == null) ? SellShotgunsCfg.Value : _hostConfigData.SellShotguns;
			}
			set
			{
				SellShotgunsCfg.Value = value;
				SyncedConfigsChanged();
			}
		}

		internal bool SellAmmo
		{
			get
			{
				return (_hostConfigData == null) ? SellAmmoCfg.Value : _hostConfigData.SellAmmo;
			}
			set
			{
				SellAmmoCfg.Value = value;
				SyncedConfigsChanged();
			}
		}

		internal bool SellKnives
		{
			get
			{
				return (_hostConfigData == null) ? SellKnivesCfg.Value : _hostConfigData.SellKnives;
			}
			set
			{
				SellKnivesCfg.Value = value;
				SyncedConfigsChanged();
			}
		}

		internal bool SellPickles
		{
			get
			{
				return (_hostConfigData == null) ? SellPicklesCfg.Value : _hostConfigData.SellPickles;
			}
			set
			{
				SellPicklesCfg.Value = value;
				SyncedConfigsChanged();
			}
		}

		internal bool SellScrapWorthZero
		{
			get
			{
				return (_hostConfigData == null) ? SellScrapWorthZeroCfg.Value : _hostConfigData.SellScrapWorthZero;
			}
			set
			{
				SellScrapWorthZeroCfg.Value = value;
				SyncedConfigsChanged();
			}
		}

		internal bool OnlySellScrapOnFloor
		{
			get
			{
				return (_hostConfigData == null) ? OnlySellScrapOnFloorCfg.Value : _hostConfigData.OnlySellScrapOnFloor;
			}
			set
			{
				OnlySellScrapOnFloorCfg.Value = value;
				SyncedConfigsChanged();
			}
		}

		internal string[] PrioritySellList
		{
			get
			{
				string text = ((_hostConfigData == null) ? PrioritySellListCfg.Value : _hostConfigData.PrioritySellList);
				return (from x in text.Split(",", StringSplitOptions.RemoveEmptyEntries)
					select x.Trim()).ToArray();
			}
			set
			{
				PrioritySellListCfg.Value = string.Join(", ", value);
				SyncedConfigsChanged();
			}
		}

		internal string[] DontSellList
		{
			get
			{
				string text = ((_hostConfigData == null) ? DontSellListCfg.Value : _hostConfigData.DontSellList);
				return (from x in text.Split(",", StringSplitOptions.RemoveEmptyEntries)
					select x.Trim()).ToArray();
			}
			set
			{
				DontSellListCfg.Value = string.Join(", ", value);
				SyncedConfigsChanged();
			}
		}

		internal string[] SellList
		{
			get
			{
				string text = ((_hostConfigData == null) ? SellListCfg.Value : _hostConfigData.SellList);
				return (from x in text.Split(",", StringSplitOptions.RemoveEmptyEntries)
					select x.Trim()).ToArray();
			}
			set
			{
				SellListCfg.Value = string.Join(", ", value);
				SyncedConfigsChanged();
			}
		}

		internal bool OverrideWelcomeMessage
		{
			get
			{
				return OverrideWelcomeMessageCfg.Value;
			}
			set
			{
				OverrideWelcomeMessageCfg.Value = value;
			}
		}

		internal bool OverrideHelpMessage
		{
			get
			{
				return OverrideHelpMessageCfg.Value;
			}
			set
			{
				OverrideHelpMessageCfg.Value = value;
			}
		}

		internal bool ShowFoundItems
		{
			get
			{
				return ShowFoundItemsCfg.Value;
			}
			set
			{
				ShowFoundItemsCfg.Value = value;
			}
		}

		internal bool SortFoundItemsPrice
		{
			get
			{
				return SortFoundItemsPriceCfg.Value;
			}
			set
			{
				SortFoundItemsPriceCfg.Value = value;
			}
		}

		internal bool AlignFoundItemsPrice
		{
			get
			{
				return AlignFoundItemsPriceCfg.Value;
			}
			set
			{
				AlignFoundItemsPriceCfg.Value = value;
			}
		}

		internal bool SpeakInShip
		{
			get
			{
				return SpeakInShipCfg.Value;
			}
			set
			{
				SpeakInShipCfg.Value = value;
			}
		}

		internal float RareVoiceLineChance
		{
			get
			{
				return RareVoiceLineChanceCfg.Value;
			}
			set
			{
				RareVoiceLineChanceCfg.Value = value;
			}
		}

		internal bool ShowQuotaWarning
		{
			get
			{
				return ShowQuotaWarningCfg.Value;
			}
			set
			{
				ShowQuotaWarningCfg.Value = value;
			}
		}

		internal int ScrapEaterChance
		{
			get
			{
				return ScrapEaterChanceCfg.Value;
			}
			set
			{
				ScrapEaterChanceCfg.Value = value;
			}
		}

		internal int OctolarSpawnWeight
		{
			get
			{
				return OctolarSpawnWeightCfg.Value;
			}
			set
			{
				OctolarSpawnWeightCfg.Value = value;
			}
		}

		internal int TakeySpawnWeight
		{
			get
			{
				return TakeySpawnWeightCfg.Value;
			}
			set
			{
				TakeySpawnWeightCfg.Value = value;
			}
		}

		internal int MaxwellSpawnWeight
		{
			get
			{
				return MaxwellSpawnWeightCfg.Value;
			}
			set
			{
				MaxwellSpawnWeightCfg.Value = value;
			}
		}

		internal int YippeeSpawnWeight
		{
			get
			{
				return YippeeSpawnWeightCfg.Value;
			}
			set
			{
				YippeeSpawnWeightCfg.Value = value;
			}
		}

		internal int CookieFumoSpawnWeight
		{
			get
			{
				return CookieFumoSpawnWeightCfg.Value;
			}
			set
			{
				CookieFumoSpawnWeightCfg.Value = value;
			}
		}

		internal int PsychoSpawnWeight
		{
			get
			{
				return PsychoSpawnWeightCfg.Value;
			}
			set
			{
				PsychoSpawnWeightCfg.Value = value;
			}
		}

		internal int ZombiesSpawnWeight
		{
			get
			{
				return ZombiesSpawnWeightCfg.Value;
			}
			set
			{
				ZombiesSpawnWeightCfg.Value = value;
			}
		}

		internal int WolfySpawnWeight
		{
			get
			{
				return WolfySpawnWeightCfg.Value;
			}
			set
			{
				WolfySpawnWeightCfg.Value = value;
			}
		}

		public SyncedConfigManager()
		{
			BindConfigs();
			MigrateOldConfigSettings();
			ConfigHelper.ClearUnusedEntries();
		}

		private void BindConfigs()
		{
			ConfigHelper.SkipAutoGen();
			ExtendedLoggingCfg = ConfigHelper.Bind("General Settings", "ExtendedLogging", defaultValue: false, requiresRestart: false, "Enable extended logging.");
			SellGiftsCfg = ConfigHelper.Bind("Sell Settings", "SellGifts", defaultValue: false, requiresRestart: false, "Do you want to sell Gifts?");
			SellShotgunsCfg = ConfigHelper.Bind("Sell Settings", "SellShotguns", defaultValue: false, requiresRestart: false, "Do you want to sell Shotguns?");
			SellAmmoCfg = ConfigHelper.Bind("Sell Settings", "SellAmmo", defaultValue: false, requiresRestart: false, "Do you want to sell Ammo?");
			SellKnivesCfg = ConfigHelper.Bind("Sell Settings", "SellKnives", defaultValue: false, requiresRestart: false, "Do you want to sell Kitchen knives?");
			SellPicklesCfg = ConfigHelper.Bind("Sell Settings", "SellPickles", defaultValue: true, requiresRestart: false, "Do you want to sell Jar of pickles?");
			SellScrapWorthZeroCfg = ConfigHelper.Bind("Advanced Sell Settings", "SellScrapWorthZero", defaultValue: false, requiresRestart: false, "Do you want to sell scrap worth zero?");
			OnlySellScrapOnFloorCfg = ConfigHelper.Bind("Advanced Sell Settings", "OnlySellScrapOnFloor", defaultValue: false, requiresRestart: false, "Do you want to sell scrap that is only on the floor?");
			PrioritySellListCfg = ConfigHelper.Bind("Advanced Sell Settings", "PrioritySellList", "Tragedy, Comedy, Whoopie cushion, Easter egg, Clock, Soccer ball", requiresRestart: false, GetPrioritySellListDescription());
			DontSellListCfg = ConfigHelper.Bind("Advanced Sell Settings", "DontSellList", "", requiresRestart: false, GetDontSellListDescription());
			SellListCfg = ConfigHelper.Bind("Advanced Sell Settings", "SellList", "Whoopie cushion, Easter egg, Tragedy, Comedy", requiresRestart: false, GetSellListDescription());
			OverrideWelcomeMessageCfg = ConfigHelper.Bind("Terminal Settings", "OverrideWelcomeMessage", defaultValue: true, requiresRestart: false, "Overrides the terminal welcome message to add additional info.");
			OverrideHelpMessageCfg = ConfigHelper.Bind("Terminal Settings", "OverrideHelpMessage", defaultValue: true, requiresRestart: false, "Overrides the terminal help message to add additional info.");
			ShowFoundItemsCfg = ConfigHelper.Bind("Terminal Settings", "ShowFoundItems", defaultValue: true, requiresRestart: false, "Show found items on the confirmation screen.");
			SortFoundItemsPriceCfg = ConfigHelper.Bind("Terminal Settings", "SortFoundItemsPrice", defaultValue: true, requiresRestart: false, "Sorts found items from most to least expensive.");
			AlignFoundItemsPriceCfg = ConfigHelper.Bind("Terminal Settings", "AlignFoundItemsPrice", defaultValue: true, requiresRestart: false, "Align all prices of found items.");
			SpeakInShipCfg = ConfigHelper.Bind("Misc Settings", "SpeakInShip", defaultValue: true, requiresRestart: false, "The Company will speak inside your ship after selling from the terminal.");
			RareVoiceLineChanceCfg = ConfigHelper.Bind("Misc Settings", "RareVoiceLineChance", 5f, requiresRestart: false, "The percent chance the Company will say a rare microphone voice line after selling.");
			ShowQuotaWarningCfg = ConfigHelper.Bind("Misc Settings", "ShowQuotaWarning", defaultValue: true, requiresRestart: false, "If enabled, will show a warning when you try to pull the ship's lever when the quota hasn't been fulfilled at the Company building with 0 days left.");
			ScrapEaterChanceCfg = ConfigHelper.Bind("Scrap Eater Settings", "ScrapEaterChance", 75, requiresRestart: false, "The percent chance a scrap eater will spawn?!", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			OctolarSpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "OctolarSpawnWeight", 1, requiresRestart: false, "The spawn chance weight Octolar will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			TakeySpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "TakeySpawnWeight", 1, requiresRestart: false, "The spawn chance weight Takey will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			MaxwellSpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "MaxwellSpawnWeight", 1, requiresRestart: false, "The spawn chance weight Maxwell will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			YippeeSpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "YippeeSpawnWeight", 1, requiresRestart: false, "The spawn chance weight Yippee will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			CookieFumoSpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "CookieFumoSpawnWeight", 1, requiresRestart: false, "The spawn chance weight Cookie Fumo will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			PsychoSpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "PsychoSpawnWeight", 1, requiresRestart: false, "The spawn chance weight Psycho will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			ZombiesSpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "ZombiesSpawnWeight", 1, requiresRestart: false, "The spawn chance weight Zombies will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
			WolfySpawnWeightCfg = ConfigHelper.Bind("Scrap Eater Settings", "WolfySpawnWeight", 1, requiresRestart: false, "The spawn chance weight Wolfy will spawn?! (scrap eater)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100));
		}

		private string GetPrioritySellListDescription()
		{
			string text = "Array of item names to prioritize when selling.\n";
			text += "Use the `edit config` command to easily edit the `PrioritySellList` config setting from the terminal.\n";
			text += "Use the `view scrap` or `view all scrap` command to see the correct item names to use.\n";
			text += "Each entry should be separated by a comma.\n";
			return text + "Item names are not case-sensitive but, spaces do matter.";
		}

		private string GetDontSellListDescription()
		{
			string text = "Array of item names to not sell.\n";
			text += "Use the `edit config` command to easily edit the `DontSellList` config setting from the terminal.\n";
			text += "Use the `view scrap` or `view all scrap` command to see the correct item names to use.\n";
			text += "Each entry should be separated by a comma.\n";
			return text + "Item names are not case-sensitive but, spaces do matter.";
		}

		private string GetSellListDescription()
		{
			string text = "Array of item names to sell when using the `sell list` command.\n";
			text += "Use the `edit config` command to easily edit the `SellList` config setting from the terminal.\n";
			text += "Use the `view scrap` or `view all scrap` command to see the correct item names to use.\n";
			text += "Each entry should be separated by a comma.\n";
			return text + "Item names are not case-sensitive but, spaces do matter.";
		}

		private void MigrateOldConfigSettings()
		{
			foreach (KeyValuePair<ConfigDefinition, string> orphanedConfigEntry in ConfigHelper.GetOrphanedConfigEntries())
			{
				MigrateOldConfigSetting(orphanedConfigEntry.Key.Section, orphanedConfigEntry.Key.Key, orphanedConfigEntry.Value);
			}
		}

		private void MigrateOldConfigSetting(string section, string key, string value)
		{
			if (section == "Sell Settings")
			{
				switch (key)
				{
				case "sellGifts":
					ConfigHelper.SetConfigEntryValue<bool>(SellGiftsCfg, value);
					return;
				case "sellShotguns":
					ConfigHelper.SetConfigEntryValue<bool>(SellShotgunsCfg, value);
					return;
				case "sellAmmo":
					ConfigHelper.SetConfigEntryValue<bool>(SellAmmoCfg, value);
					return;
				case "sellKnives":
					ConfigHelper.SetConfigEntryValue<bool>(SellKnivesCfg, value);
					return;
				case "sellPickles":
					ConfigHelper.SetConfigEntryValue<bool>(SellPicklesCfg, value);
					return;
				}
			}
			if (section == "Advanced Sell Settings")
			{
				if (key == "sellScrapWorthZero")
				{
					ConfigHelper.SetConfigEntryValue<bool>(SellScrapWorthZeroCfg, value);
					return;
				}
				if (key == "onlySellScrapOnFloor")
				{
					ConfigHelper.SetConfigEntryValue<bool>(OnlySellScrapOnFloorCfg, value);
					return;
				}
				try
				{
					if (key.Equals("DontSellListJson", StringComparison.OrdinalIgnoreCase))
					{
						ConfigHelper.SetConfigEntryValue<string>(DontSellListCfg, string.Join(", ", JsonConvert.DeserializeObject<string[]>(value.Replace("\\", ""))));
					}
					if (key.Equals("SellListJson", StringComparison.OrdinalIgnoreCase))
					{
						ConfigHelper.SetConfigEntryValue<string>(SellListCfg, string.Join(", ", JsonConvert.DeserializeObject<string[]>(value.Replace("\\", ""))));
					}
				}
				catch (Exception ex)
				{
					Plugin.Logger.LogError((object)ex);
				}
			}
			if (section == "Terminal Settings")
			{
				switch (key)
				{
				case "overrideWelcomeMessage":
					ConfigHelper.SetConfigEntryValue<bool>(OverrideWelcomeMessageCfg, value);
					return;
				case "overrideHelpMessage":
					ConfigHelper.SetConfigEntryValue<bool>(OverrideHelpMessageCfg, value);
					return;
				case "showFoundItems":
					ConfigHelper.SetConfigEntryValue<bool>(ShowFoundItemsCfg, value);
					return;
				case "sortFoundItemsPrice":
					ConfigHelper.SetConfigEntryValue<bool>(SortFoundItemsPriceCfg, value);
					return;
				case "alignFoundItemsPrice":
					ConfigHelper.SetConfigEntryValue<bool>(AlignFoundItemsPriceCfg, value);
					return;
				}
			}
			if (section == "Misc Settings")
			{
				if (key == "speakInShip")
				{
					ConfigHelper.SetConfigEntryValue<bool>(SpeakInShipCfg, value);
					return;
				}
				if (key == "rareVoiceLineChance")
				{
					ConfigHelper.SetConfigEntryValue<float>(RareVoiceLineChanceCfg, value);
					return;
				}
			}
			if (section == "Scrap Eater Settings")
			{
				switch (key)
				{
				case "scrapEaterChance":
					ConfigHelper.SetConfigEntryValue<int>(ScrapEaterChanceCfg, value);
					break;
				case "octolarSpawnWeight":
					ConfigHelper.SetConfigEntryValue<int>(OctolarSpawnWeightCfg, value);
					break;
				case "takeySpawnWeight":
					ConfigHelper.SetConfigEntryValue<int>(TakeySpawnWeightCfg, value);
					break;
				case "maxwellSpawnWeight":
					ConfigHelper.SetConfigEntryValue<int>(MaxwellSpawnWeightCfg, value);
					break;
				case "yippeeSpawnWeight":
					ConfigHelper.SetConfigEntryValue<int>(YippeeSpawnWeightCfg, value);
					break;
				case "cookieFumoSpawnWeight":
					ConfigHelper.SetConfigEntryValue<int>(CookieFumoSpawnWeightCfg, value);
					break;
				case "psychoSpawnWeight":
					ConfigHelper.SetConfigEntryValue<int>(PsychoSpawnWeightCfg, value);
					break;
				case "zombiesSpawnWeight":
					ConfigHelper.SetConfigEntryValue<int>(ZombiesSpawnWeightCfg, value);
					break;
				}
			}
		}

		internal void ResetToDefault()
		{
			FieldInfo[] fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			FieldInfo[] array = fields;
			foreach (FieldInfo fieldInfo in array)
			{
				if (!fieldInfo.FieldType.IsGenericType || !(fieldInfo.FieldType.GetGenericTypeDefinition() == typeof(ConfigEntry<>)))
				{
					continue;
				}
				object value = fieldInfo.GetValue(this);
				if (value != null)
				{
					PropertyInfo property = fieldInfo.FieldType.GetProperty("Value");
					PropertyInfo property2 = fieldInfo.FieldType.GetProperty("DefaultValue");
					if (property != null && property2 != null)
					{
						object value2 = property2.GetValue(value);
						property.SetValue(value, value2);
					}
				}
			}
			Plugin.Logger.LogInfo((object)"Reset all config settings to their default value.");
			SyncedConfigsChanged();
		}

		internal void TrySetCustomValues()
		{
			if (!SteamUtils.IsLocalClient(PlayerName.Insym))
			{
				TrySetCustomValuesForThorlar();
				TrySetCustomValuesForTakerst();
				if (ScrapEaterChance == 0 && DontSellList.Length == 1 && DontSellList[0].Equals("gold bar", StringComparison.OrdinalIgnoreCase) && !ModpackSaveSystem.ReadValue("ResetScrapEaterChance", defaultValue: false))
				{
					ScrapEaterChance = (int)((ConfigEntryBase)ScrapEaterChanceCfg).DefaultValue;
					ModpackSaveSystem.WriteValue("ResetScrapEaterChance", value: true);
				}
			}
		}

		private void TrySetCustomValuesForThorlar()
		{
			if (SteamUtils.IsLocalClient(PlayerName.Thorlar) && TakeySpawnWeight == 1 && !ModpackSaveSystem.ReadValue("RemovedTakeyScrapEaterSpawnWeight", defaultValue: false))
			{
				TakeySpawnWeight = 0;
				ModpackSaveSystem.WriteValue("RemovedTakeyScrapEaterSpawnWeight", value: true);
			}
		}

		private void TrySetCustomValuesForTakerst()
		{
			if (SteamUtils.IsLocalClient(PlayerName.Takerst))
			{
				if (!Utils.ArrayContains(DontSellList, "Smol Takey"))
				{
					List<string> list = DontSellList.ToList();
					list.Add("Smol Takey");
					DontSellListCfg.Value = JsonConvert.SerializeObject((object)list);
				}
				if (!Utils.ArrayContains(DontSellList, "Takey Box"))
				{
					List<string> list2 = DontSellList.ToList();
					list2.Add("Takey Box");
					DontSellListCfg.Value = JsonConvert.SerializeObject((object)list2);
				}
				if (!Utils.ArrayContains(DontSellList, "Takey Mug"))
				{
					List<string> list3 = DontSellList.ToList();
					list3.Add("Takey Mug");
					DontSellListCfg.Value = JsonConvert.SerializeObject((object)list3);
				}
			}
		}

		internal void SetHostConfigData(SyncedConfigData syncedConfigData)
		{
			_hostConfigData = syncedConfigData;
		}

		private void SyncedConfigsChanged()
		{
			//IL_001c: 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)
			if (NetworkUtils.IsServer)
			{
				PluginNetworkBehaviour.Instance.SendConfigToPlayerClientRpc(new SyncedConfigData(this));
			}
		}
	}
	internal static class Utils
	{
		public static bool RandomPercent(float percent)
		{
			if (percent <= 0f)
			{
				return false;
			}
			if (percent >= 100f)
			{
				return true;
			}
			return Random.value <= percent * 0.01f;
		}

		public static string GetStringWithSpacingInBetween(string a, string b, int maxLength)
		{
			return a + new string(' ', maxLength - a.Length) + " " + b;
		}

		public static string GetLongestStringFromArray(string[] array)
		{
			string text = string.Empty;
			foreach (string text2 in array)
			{
				if (text2.Length > text.Length)
				{
					text = text2;
				}
			}
			return text;
		}

		public static string[] GetArrayToLower(string[] array)
		{
			List<string> list = new List<string>();
			foreach (string text in array)
			{
				list.Add(text.ToLower());
			}
			return list.ToArray();
		}

		public static string GetItemFromList(List<string> list, string item)
		{
			foreach (string item2 in list)
			{
				if (item2.ToLower() == item.ToLower())
				{
					return item2;
				}
			}
			return string.Empty;
		}

		public static bool ArrayContains(string[] array, string value)
		{
			foreach (string text in array)
			{
				if (text.Equals(value, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		public static int GetOvertimeBonus(int value)
		{
			int profitQuota = TimeOfDay.Instance.profitQuota;
			int num = TimeOfDay.Instance.quotaFulfilled + value;
			if (num <= profitQuota)
			{
				return 0;
			}
			int num2 = num - profitQuota;
			int num3 = num2 / 5 + 15 * TimeOfDayPatch.GetDaysUntilDeadline();
			return Mathf.Max(num3, 0);
		}

		public static void CreateExplosion(Vector3 explosionPosition, bool spawnExplosionEffect = true, int damage = 100, float minDamageRange = 0f, float maxDamageRange = 6.4f, int enemyHitForce = 6, CauseOfDeath causeOfDeath = 3, PlayerControllerB attacker = null)
		{
			//IL_000b: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_013f: 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_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Logger.LogInfo((object)$"Spawning explosion at pos: {explosionPosition}");
			Transform val = null;
			if ((Object)(object)RoundManager.Instance != (Object)null && (Object)(object)RoundManager.Instance.mapPropsContainer != (Object)null && (Object)(object)RoundManager.Instance.mapPropsContainer.transform != (Object)null)
			{
				val = RoundManager.Instance.mapPropsContainer.transform;
			}
			if (spawnExplosionEffect)
			{
				Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, explosionPosition, Quaternion.Euler(-90f, 0f, 0f), val).SetActive(true);
			}
			float num = Vector3.Distance(((Component)GameNetworkManager.Instance.localPlayerController).transform.position, explosionPosition);
			if (num < 14f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
			}
			else if (num < 25f)
			{
				HUDManager.Instance.ShakeCamera((ScreenShakeType)0);
			}
			Collider[] array = Physics.OverlapSphere(explosionPosition, maxDamageRange, 2621448, (QueryTriggerInteraction)2);
			PlayerControllerB val2 = null;
			for (int i = 0; i < array.Length; i++)
			{
				float num2 = Vector3.Distance(explosionPosition, ((Component)array[i]).transform.position);
				if (num2 > 4f && Physics.Linecast(explosionPosition, ((Component)array[i]).transform.position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1))
				{
					continue;
				}
				if (((Component)array[i]).gameObject.layer == 3)
				{
					val2 = ((Component)array[i]).gameObject.GetComponent<PlayerControllerB>();
					if ((Object)(object)val2 != (Object)null && ((NetworkBehaviour)val2).IsOwner)
					{
						float num3 = 1f - Mathf.Clamp01((num2 - minDamageRange) / (maxDamageRange - minDamageRange));
						val2.DamagePlayer((int)((float)damage * num3), true, true, causeOfDeath, 0, false, default(Vector3));
					}
				}
				else if (((Component)array[i]).gameObject.layer == 21)
				{
					Landmine componentInChildren = ((Component)array[i]).gameObject.GetComponentInChildren<Landmine>();
					if ((Object)(object)componentInChildren != (Object)null && !componentInChildren.hasExploded && num2 < 6f)
					{
						Plugin.Logger.LogInfo((object)"Setting off other mine");
						((MonoBehaviour)StartOfRound.Instance).StartCoroutine(TriggerOtherMineDelayed(componentInChildren));
					}
				}
				else if (((Component)array[i]).gameObject.layer == 19)
				{
					EnemyAICollisionDetect componentInChildren2 = ((Component)array[i]).gameObject.GetComponentInChildren<EnemyAICollisionDetect>();
					if ((Object)(object)componentInChildren2 != (Object)null && ((NetworkBehaviour)componentInChildren2.mainScript).IsOwner && num2 < 4.5f)
					{
						componentInChildren2.mainScript.HitEnemyOnLocalClient(enemyHitForce, default(Vector3), attacker, false, -1);
					}
				}
			}
			int num4 = ~LayerMask.GetMask(new string[1] { "Room" });
			num4 = ~LayerMask.GetMask(new string[1] { "Colliders" });
			array = Physics.OverlapSphere(explosionPosition, 10f, num4);
			for (int j = 0; j < array.Length; j++)
			{
				Rigidbody component = ((Component)array[j]).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.AddExplosionForce(70f, explosionPosition, 10f);
				}
			}
		}

		private static IEnumerator TriggerOtherMineDelayed(Landmine mine)
		{
			if (!mine.hasExploded)
			{
				mine.mineAudio.pitch = Random.Range(0.75f, 1.07f);
				mine.hasExploded = true;
				yield return (object)new WaitForSeconds(0.2f);
				mine.SetOffMineAnimation();
			}
		}

		public static int GetRandomIndexFromWeightList(List<int> weightList)
		{
			List<(int, int)> list = new List<(int, int)>();
			for (int i = 0; i < weightList.Count; i++)
			{
				int num = weightList[i];
				if (num > 0)
				{
					list.Add((i, num));
				}
			}
			int num2 = 0;
			foreach (var item4 in list)
			{
				int item = item4.Item2;
				num2 += item;
			}
			if (num2 == 0)
			{
				return -1;
			}
			int num3 = Random.Range(0, num2);
			int num4 = 0;
			foreach (var item5 in list)
			{
				int item2 = item5.Item1;
				int item3 = item5.Item2;
				num4 += item3;
				if (num3 < num4)
				{
					return item2;
				}
			}
			throw new InvalidOperationException("Weights are not properly specified.");
		}

		public static List<List<T>> SplitList<T>(List<T> items, int numberOfLists)
		{
			List<List<T>> list = new List<List<T>>();
			int count = items.Count;
			int num = Mathf.CeilToInt((float)count / (float)numberOfLists);
			for (int i = 0; i < numberOfLists; i++)
			{
				List<T> range = items.GetRange(i * num, Mathf.Min(num, count - i * num));
				list.Add(range);
			}
			return list;
		}

		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				return ((MonoBehaviour)Plugin.Instance).StartCoroutine(routine);
			}
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				return ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(routine);
			}
			Plugin.Logger.LogError((object)("Failed to start coroutine. " + routine));
			return null;
		}

		public static string GetStringWithColor(string text, string colorHex)
		{
			return "<color=" + colorHex + ">" + text + "</color>";
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.zehsteam.SellMyScrap";

		public const string PLUGIN_NAME = "SellMyScrap";

		public const string PLUGIN_VERSION = "1.8.0";
	}
}
namespace com.github.zehsteam.SellMyScrap.ScrapEaters
{
	public class ScrapEater
	{
		public GameObject SpawnPrefab;

		public Func<int> GetSpawnWeight;

		public ScrapEater(GameObject spawnPrefab, Func<int> getSpawnWeight)
		{
			SpawnPrefab = spawnPrefab;
			GetSpawnWeight = getSpawnWeight;
		}
	}
	public static class ScrapEaterManager
	{
		public static List<ScrapEater> ScrapEaters { get; private set; } = new List<ScrapEater>();


		internal static void Initialize()
		{
			SyncedConfigManager configManager = Plugin.ConfigManager;
			ScrapEaters = new List<ScrapEater>(8)
			{
				new ScrapEater(Content.OctolarScrapEaterPrefab, () => configManager.OctolarSpawnWeight),
				new ScrapEater(Content.TakeyScrapEaterPrefab, () => configManager.TakeySpawnWeight),
				new ScrapEater(Content.MaxwellScrapEaterPrefab, () => configManager.MaxwellSpawnWeight),
				new ScrapEater(Content.YippeeScrapEaterPrefab, () => configManager.YippeeSpawnWeight),
				new ScrapEater(Content.CookieFumoScrapEaterPrefab, () => configManager.CookieFumoSpawnWeight),
				new ScrapEater(Content.PsychoScrapEaterPrefab, () => configManager.PsychoSpawnWeight),
				new ScrapEater(Content.ZombiesScrapEaterPrefab, () => configManager.ZombiesSpawnWeight),
				new ScrapEater(Content.WolfyScrapEaterPrefab, () => configManager.WolfySpawnWeight)
			};
		}

		internal static bool CanUseScrapEater()
		{
			int scrapEaterChance = Plugin.ConfigManager.ScrapEaterChance;
			return Utils.RandomPercent(scrapEaterChance);
		}

		internal static bool HasScrapEater(int index)
		{
			if (ScrapEaters.Count == 0)
			{
				return false;
			}
			if (index < 0 || index > ScrapEaters.Count - 1)
			{
				return false;
			}
			return true;
		}

		public static void AddScrapEater(GameObject spawnPrefab, Func<int> GetSpawnWeight)
		{
			ScrapEaters.Add(new ScrapEater(spawnPrefab, GetSpawnWeight));
		}

		internal static void StartRandomScrapEaterOnServer(List<GrabbableObject> scrap, int variantIndex = -1)
		{
			if (NetworkUtils.IsServer)
			{
				int randomScrapEaterIndex = GetRandomScrapEaterIndex();
				if (randomScrapEaterIndex != -1)
				{
					StartScrapEaterOnServer(randomScrapEaterIndex, scrap, variantIndex);
				}
			}
		}

		internal static void StartScrapEaterOnServer(int index, List<GrabbableObject> scrap, int variantIndex = -1)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkUtils.IsServer)
			{
				GameObject spawnPrefab = ScrapEaters[index].SpawnPrefab;
				GameObject val = Object.Instantiate<GameObject>(spawnPrefab, Vector3.zero, Quaternion.identity);
				NetworkObject component = val.GetComponent<NetworkObject>();
				component.Spawn(true);
				ScrapEaterBehaviour component2 = val.GetComponent<ScrapEaterBehaviour>();
				component2.SetData(scrap, variantIndex);
				Plugin.Logger.LogInfo((object)$"Spawned scrap eater #{index + 1}");
			}
		}

		private static int GetRandomScrapEaterIndex()
		{
			return Utils.GetRandomIndexFromWeightList(ScrapEaters.Select((ScrapEater x) => x.GetSpawnWeight()).ToList());
		}
	}
}
namespace com.github.zehsteam.SellMyScrap.Patches
{
	[HarmonyPatch(typeof(DepositItemsDesk))]
	internal static class DepositItemsDeskPatch
	{
		private static DepositItemsDesk _instance;

		private static int _clipIndex = -1;

		private static bool _speakInShip = false;

		public static DepositItemsDesk Instance
		{
			get
			{
				if ((Object)(object)_instance == (Object)null)
				{
					_instance = Object.FindFirstObjectByType<DepositItemsDesk>();
				}
				return _instance;
			}
		}

		[HarmonyPatch("SellItemsOnServer")]
		[HarmonyPrefix]
		private static bool SellItemsOnServerPatch(ref DepositItemsDesk __instance)
		{
			if (__instance.itemsOnCounter.Count == 0)
			{
				return false;
			}
			if (NetworkUtils.IsServer)
			{
				SetMicrophoneSpeakDataOnServer(_speakInShip);
			}
			return true;
		}

		[HarmonyPatch("MicrophoneSpeak")]
		[HarmonyPrefix]
		private static bool MicrophoneSpeakPatch(ref DepositItemsDesk __instance)
		{
			AudioClip[] microphoneAudios = __instance.microphoneAudios;
			AudioClip[] rareMicrophoneAudios = __instance.rareMicrophoneAudios;
			List<AudioClip> list = new List<AudioClip>(microphoneAudios.Length + rareMicrophoneAudios.Length);
			list.AddRange(microphoneAudios);
			list.AddRange(rareMicrophoneAudios);
			List<AudioClip> list2 = list;
			if (_clipIndex == -1)
			{
				_clipIndex = GetRandomAudioClipIndex();
			}
			AudioClip val = list2[_clipIndex];
			__instance.speakerAudio.PlayOneShot(val, 1f);
			if (Plugin.ConfigManager.SpeakInShip && _speakInShip)
			{
				StartOfRound.Instance.speakerAudioSource.PlayOneShot(val, 1f);
			}
			_speakInShip = false;
			_clipIndex = -1;
			return false;
		}

		private static int GetRandomAudioClipIndex()
		{
			if (Utils.RandomPercent(Plugin.ConfigManager.RareVoiceLineChance))
			{
				return Random.Range(0, Instance.rareMicrophoneAudios.Length) + Instance.microphoneAudios.Length;
			}
			return Random.Range(0, Instance.microphoneAudios.Length);
		}

		public static void SetMicrophoneSpeakDataOnClient(bool speakInShip, int clipIndex)
		{
			_speakInShip = speakInShip;
			_clipIndex = clipIndex;
		}

		private static void SetMicrophoneSpeakDataOnServer(bool speakInShip)
		{
			_speakInShip = speakInShip;
			_clipIndex = GetRandomAudioClipIndex();
			PluginNetworkBehaviour.Instance.SetMicrophoneSpeakDataClientRpc(speakInShip, _clipIndex);
		}

		public static void SellItemsOnServer()
		{
			_speakInShip = true;
			Instance.SellItemsOnServer();
		}

		public static void PlaceItemsOnCounter(List<GrabbableObject> grabbableObjects)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				grabbableObjects.ForEach(PlaceItemOnCounter);
			}
		}

		public static void PlaceItemOnCounter(GrabbableObject grabbableObject)
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)grabbableObject == (Object)null) && !((Object)(object)Instance == (Object)null) && !Instance.itemsOnCounter.Contains(grabbableObject))
			{
				Instance.itemsOnCounter.Add(grabbableObject);
				NetworkObject component = ((Component)grabbableObject).gameObject.GetComponent<NetworkObject>();
				Instance.itemsOnCounterNetworkObjects.Add(component);
				grabbableObject.EnablePhysics(false);
				grabbableObject.EnableItemMeshes(false);
				((Component)grabbableObject).transform.SetParent(((Component)Instance.deskObjectsContainer).transform);
				((Component)grabbableObject).transform.localPosition = Vector3.zero;
			}
		}

		public static void PlaceRagdollOnCounter(RagdollGrabbableObject ragdollGrabbableObject)
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ragdollGrabbableObject == (Object)null) && !((Object)(object)Instance == (Object)null) && !Instance.itemsOnCounter.Contains((GrabbableObject)(object)ragdollGrabbableObject))
			{
				Instance.itemsOnCounter.Add((GrabbableObject)(object)ragdollGrabbableObject);
				NetworkObject component = ((Component)ragdollGrabbableObject).gameObject.GetComponent<NetworkObject>();
				Instance.itemsOnCounterNetworkObjects.Add(component);
				((GrabbableObject)ragdollGrabbableObject).EnablePhysics(false);
				((GrabbableObject)ragdollGrabbableObject).EnableItemMeshes(false);
				Transform transform = ((Component)ragdollGrabbableObject.ragdoll).transform;
				MeshRenderer[] componentsInChildren = ((Component)transform).GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val in componentsInChildren)
				{
					((Renderer)val).enabled = false;
				}
				SkinnedMeshRenderer[] componentsInChildren2 = ((Component)transform).GetComponentsInChildren<SkinnedMeshRenderer>();
				foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
				{
					((Renderer)val2).enabled = false;
				}
				transform.SetParent(((Component)Instance.deskObjectsContainer).transform);
				transform.localPosition = Vector3.zero;
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal static class GameNetworkManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch()
		{
			AddNetworkPrefabs();
		}

		private static void AddNetworkPrefabs()
		{
			AddNetworkPrefab(Content.NetworkHandlerPrefab);
			ScrapEaterManager.ScrapEaters.ForEach(delegate(ScrapEater scrapEater)
			{
				AddNetworkPrefab(scrapEater.SpawnPrefab);
			});
		}

		private static void AddNetworkPrefab(GameObject prefab)
		{
			if (!((Object)(object)prefab == (Object)null))
			{
				NetworkManager.Singleton.AddNetworkPrefab(prefab);
				Plugin.Logger.LogInfo((object)("Registered \"" + ((Object)prefab).name + "\" network prefab."));
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	internal static class HUDManagerPatch
	{
		[HarmonyPatch("DisplayCreditsEarning")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static bool DisplayCreditsEarningPatch(ref HUDManager __instance, int creditsEarned, GrabbableObject[] objectsSold, int newGroupCredits, ref Coroutine ___scrollRewardTextCoroutine)
		{
			Plugin.Logger.LogInfo((object)$"Earned ${creditsEarned}; sold {objectsSold.Length} items; new credits amount: ${newGroupCredits}");
			string text = ScrapHelper.GetScrapMessage(objectsSold.ToList());
			int num = text.Split('\n').Length;
			int num2 = ((num < 8) ? (8 - num) : 0);
			for (int i = 0; i < num2; i++)
			{
				text += "\n\t";
			}
			((TMP_Text)__instance.moneyRewardsListText).text = text;
			((TMP_Text)__instance.moneyRewardsTotalText).text = $"TOTAL: ${creditsEarned}";
			__instance.moneyRewardsAnimator.SetTrigger("showRewards");
			__instance.rewardsScrollbar.value = 1f;
			if (num >= 9)
			{
				if (___scrollRewardTextCoroutine != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(___scrollRewardTextCoroutine);
				}
				___scrollRewardTextCoroutine = ((MonoBehaviour)__instance).StartCoroutine(ScrollRewardsListText(__instance.rewardsScrollbar));
			}
			return false;
		}

		private static IEnumerator ScrollRewardsListText(Scrollbar rewardsScrollbar, float duration = 3f)
		{
			yield return (object)new WaitForSeconds(1.5f);
			float timer = 0f;
			rewardsScrollbar.value = 1f;
			for (; timer < duration; timer += Time.deltaTime)
			{
				if (timer > duration)
				{
					timer = duration;
				}
				float percent = 1f / duration * timer;
				rewardsScrollbar.value = 1f - percent;
				yield return null;
			}
			rewardsScrollbar.value = 0f;
		}
	}
	[HarmonyPatch(typeof(InteractTrigger))]
	internal static class InteractTriggerPatch
	{
		[HarmonyPatch("StopInteraction")]
		[HarmonyPostfix]
		private static void StopInteractionPatch(ref InteractTrigger __instance)
		{
			if ((Object)(object)StartMatchLeverPatch.InteractTrigger == (Object)(object)__instance)
			{
				StartMatchLeverPatch.DisplayedSellWarning = false;
			}
		}
	}
	[HarmonyPatch(typeof(StartMatchLever))]
	internal static class StartMatchLeverPatch
	{
		public static InteractTrigger InteractTrigger;

		public static bool DisplayedSellWarning;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(ref StartMatchLever __instance)
		{
			InteractTrigger = ((Component)__instance).GetComponent<InteractTrigger>();
			DisplayedSellWarning = false;
		}

		[HarmonyPatch("BeginHoldingInteractOnLever")]
		[HarmonyPostfix]
		private static void BeginHoldingInteractOnLeverPatch(ref StartMatchLever __instance)
		{
			if (TimeOfDay.Instance.daysUntilDeadline > 0 || !Plugin.ConfigManager.ShowQuotaWarning)
			{
				if (__instance.triggerScript.timeToHold == 4.01f)
				{
					__instance.triggerScript.timeToHold = 0.7f;
				}
			}
			else if (StartOfRound.Instance.currentLevelID == 3 && StartOfRound.Instance.shipHasLanded)
			{
				if (TimeOfDay.Instance.quotaFulfilled >= TimeOfDay.Instance.profitQuota)
				{
					__instance.triggerScript.timeToHold = 0.7f;
				}
				else if (!DisplayedSellWarning)
				{
					DisplayedSellWarning = true;
					__instance.triggerScript.timeToHold = 4.01f;
					HUDManager.Instance.DisplayTip("HALT!", "You did not sell enough scrap to fulfill the profit quota.", true, false, "LC_Tip1");
				}
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePatch()
		{
			SpawnNetworkHandler();
		}

		private static void SpawnNetworkHandler()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkUtils.IsServer)
			{
				GameObject val = Object.Instantiate<GameObject>(Content.NetworkHandlerPrefab, Vector3.zero, Quaternion.identity);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch()
		{
			Plugin.ConfigManager.TrySetCustomValues();
			RemoveMapPropsContainerForTesting();
		}

		private static void RemoveMapPropsContainerForTesting()
		{
			GameObject val = GameObject.Find("Environment/MapPropsContainerForTesting");
			if (!((Object)(object)val == (Object)null))
			{
				val.SetActive(false);
			}
		}

		[HarmonyPatch("OnClientConnect")]
		[HarmonyPrefix]
		private static void OnClientConnectPatch(ref ulong clientId)
		{
			SendConfigToNewConnectedPlayer(clientId);
		}

		private static void SendConfigToNewConnectedPlayer(ulong clientId)
		{
			//IL_0011: 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_002e: 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_0034: Unknown result type (might be due to invalid IL or missing refe