Decompiled source of SellMyScrap v1.8.0
com.github.zehsteam.SellMyScrap.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
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