Decompiled source of SaveOurLoot v1.4.2

SaveOurLoot.dll

Decompiled 10 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SaveOurLoot")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Mod for Lethal Company, that allow adjusting item loss after mission")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0+979f2849e735ed3c95064b823298eff3402ad5be")]
[assembly: AssemblyProduct("SaveOurLoot")]
[assembly: AssemblyTitle("SaveOurLoot")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SaveOurLoot
{
	public class Config
	{
		public static ConfigEntry<float> saveAllChance;

		public static ConfigEntry<float> saveEachChance;

		public static ConfigEntry<int> scrapLossMax;

		public static ConfigEntry<bool> valueSaveEnabled;

		public static ConfigEntry<float> valueSavePercent;

		public static ConfigEntry<bool> equipmentLossEnabled;

		public static ConfigEntry<float> equipmentLossChance;

		public static ConfigEntry<int> equipmentLossMax;

		public static ConfigEntry<bool> hoardingBugInfestationEnabled;

		public static ConfigEntry<float> hoardingBugInfestationChance;

		public static ConfigEntry<float> hoardingBugInfestationLossEachChance;

		public static ConfigEntry<int> hoardingBugInfestationLossMax;

		public static ConfigEntry<bool> hoardingBugInfestationValueLossEnabled;

		public static ConfigEntry<float> hoardingBugInfestationValueLossPercent;

		public static ConfigEntry<bool> hoardingBugInfestationEquipmentLossEnabled;

		public static ConfigEntry<float> hoardingBugInfestationEquipmentLossChance;

		public static ConfigEntry<int> hoardingBugInfestationEquipmentLossMax;

		public static void Load()
		{
			saveAllChance = Plugin.config.Bind<float>("LootSaving", "SaveAllChance", 0.25f, "A chance of all item being saved.\nVanilla value 0. Values between 0-1.");
			saveEachChance = Plugin.config.Bind<float>("LootSaving", "SaveEachChance", 0.5f, "A chance of each item being saved.\nApplied after SaveAllChance\nVanilla value 0. Values between 0-1.");
			scrapLossMax = Plugin.config.Bind<int>("LootSaving", "ScrapLossMax", int.MaxValue, $"The maximum amount of items that can be lost.\nApplied after SaveEachChance\nVanilla value {int.MaxValue}. Values between 0-{int.MaxValue}.");
			valueSaveEnabled = Plugin.config.Bind<bool>("LootSaving", "ValueSaveEnabled", false, "Will it try to save item based on it scrap value?\nApplied after SaveAllChance and prevent SaveEachChance\nVanilla value False.");
			valueSavePercent = Plugin.config.Bind<float>("LootSaving", "ValueSavePercent", 0.25f, "What percentage of total scrap value will be saved among loot.\nVanilla value 0. Values between 0-1.");
			equipmentLossEnabled = Plugin.config.Bind<bool>("EquipmentLoss", "EquipmentLossEnabled", false, "Will it allow equipment to be lost?\nVanilla value False.");
			equipmentLossChance = Plugin.config.Bind<float>("EquipmentLoss", "EquipmentLossChance", 0.1f, "A chance of each equipment being lost.\nApplied after SaveAllChance\nVanilla value 0. Values between 0-1.");
			equipmentLossMax = Plugin.config.Bind<int>("EquipmentLoss", "EquipmentLossMax", int.MaxValue, $"The maximum amount of equipment that can be lost.\nApplied after EquipmentLossChance\nVanilla value 0. Values between 0-{int.MaxValue}.");
			hoardingBugInfestationEnabled = Plugin.config.Bind<bool>("HoardingBugInfestation", "HoardingBugInfestationEnabled", false, "Space is a dangerous place. Bug Mafia will protect you for a little part of your loot.\nYour Ship is infested with Hoarding Bugs, which steal your loot while you sleep between missions.\nEnable all features related to this category?\nVanilla value False.");
			hoardingBugInfestationChance = Plugin.config.Bind<float>("HoardingBugInfestation", "HoardingBugInfestationChance", 1f, "A chance of items being stolen by Hoarding Bugs each night on the Ship.\nValues between 0-1.");
			hoardingBugInfestationLossEachChance = Plugin.config.Bind<float>("HoardingBugInfestation", "HoardingBugInfestationLossEachChance", 0.1f, "A chance of each item being stolen by Hoarding Bugs.\nValues between 0-1.");
			hoardingBugInfestationLossMax = Plugin.config.Bind<int>("HoardingBugInfestation", "HoardingBugInfestationLossMax", int.MaxValue, $"The maximum amount of items that can be lost.\nApplied after HoardingBugInfestationLossEachChance\nVanilla value {int.MaxValue}. Values between 0-{int.MaxValue}.");
			hoardingBugInfestationValueLossEnabled = Plugin.config.Bind<bool>("HoardingBugInfestation", "HoardingBugInfestationValueLossEnabled", true, "Will it try to steal items based on it scrap value?\nPrevent HoardingBugInfestationLossEachChance\nVanilla value False.");
			hoardingBugInfestationValueLossPercent = Plugin.config.Bind<float>("HoardingBugInfestation", "HoardingBugInfestationValueLossPercent", 0.1f, "What percentage of total scrap value will be stolen among loot.\nValues between 0-1.");
			hoardingBugInfestationEquipmentLossEnabled = Plugin.config.Bind<bool>("HoardingBugInfestation", "HoardingBugInfestationEquipmentLossEnabled", true, "Will it allow stealing of equipment?");
			hoardingBugInfestationEquipmentLossChance = Plugin.config.Bind<float>("HoardingBugInfestation", "HoardingBugInfestationEquipmentLossChance", 0.05f, "A chance of each equipment being stollen.\nValues between 0-1.");
			hoardingBugInfestationEquipmentLossMax = Plugin.config.Bind<int>("HoardingBugInfestation", "HoardingBugInfestationEquipmentLossMax", int.MaxValue, $"The maximum amount of equipment that can be stollen.\nApplied after EquipmentLossChance\nValues between 0-{int.MaxValue}.");
		}
	}
	public class HarmonyPatches
	{
		private static readonly Type patchType;

		static HarmonyPatches()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			patchType = typeof(HarmonyPatches);
			new Harmony("LethalCompany.MrHydralisk.SaveOurLoot").Patch((MethodBase)AccessTools.Method(typeof(RoundManager), "DespawnPropsAtEndOfRound", (Type[])null, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(patchType, "RM_DespawnPropsAtEndOfRound_Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
		}

		public static IEnumerable<CodeInstruction> RM_DespawnPropsAtEndOfRound_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			int num = -1;
			int num2 = -1;
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode == OpCodes.Stloc_0))
				{
					continue;
				}
				num = i;
				for (int j = num + 1; j < list.Count; j++)
				{
					if (CodeInstructionExtensions.Is(list[j], OpCodes.Ldstr, (object)"TemporaryEffect"))
					{
						num2 = j;
						break;
					}
				}
				if (num2 > -1)
				{
					break;
				}
			}
			if (num > -1 && num2 > -1)
			{
				Label label = il.DefineLabel();
				list[num2].labels.Add(label);
				List<CodeInstruction> list2 = new List<CodeInstruction>();
				list2.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null));
				list2.Add(new CodeInstruction(OpCodes.Ldloc_0, (object)null));
				list2.Add(new CodeInstruction(OpCodes.Ldarg_1, (object)null));
				list2.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(HarmonyPatches), "CustomDespawnProps", (Type[])null, (Type[])null)));
				list2.Add(new CodeInstruction(OpCodes.Brtrue_S, (object)label));
				list.InsertRange(num + 1, list2);
			}
			return list.AsEnumerable();
		}

		public static bool CustomDespawnProps(RoundManager rManager, GrabbableObject[] gObjects, bool despawnAllItems = false)
		{
			if (despawnAllItems)
			{
				return false;
			}
			Random random = new Random(StartOfRound.Instance.randomMapSeed + 369);
			gObjects.ToList();
			List<GrabbableObject> list = new List<GrabbableObject>();
			foreach (GrabbableObject val in gObjects)
			{
				if ((!val.isInShipRoom && !val.isHeld) || val.deactivated)
				{
					Plugin.MLogS.LogInfo((object)(((Object)val).name + " Lost Outside"));
					DespawnItem(val);
				}
				else
				{
					list.Add(val);
				}
			}
			ILookup<bool, GrabbableObject> lookup = list.ToLookup((GrabbableObject go) => go.itemProperties.isScrap);
			List<GrabbableObject> list2 = lookup[true].ToList();
			List<GrabbableObject> list3 = lookup[false].ToList();
			ConfigEntry<bool> hoardingBugInfestationEnabled = Config.hoardingBugInfestationEnabled;
			if (hoardingBugInfestationEnabled != null && hoardingBugInfestationEnabled.Value && random.NextDouble() >= (double)(1f - (Config.hoardingBugInfestationChance?.Value ?? 1f)))
			{
				ConfigEntry<bool> hoardingBugInfestationValueLossEnabled = Config.hoardingBugInfestationValueLossEnabled;
				if (hoardingBugInfestationValueLossEnabled != null && hoardingBugInfestationValueLossEnabled.Value)
				{
					list2 = list2.OrderByDescending((GrabbableObject go) => go.scrapValue).ToList();
					float num = (float)list2.Sum((GrabbableObject go) => go.scrapValue) * (Config.hoardingBugInfestationValueLossPercent?.Value ?? 0.1f);
					int num2 = 0;
					foreach (GrabbableObject item in list2)
					{
						num2 += item.scrapValue;
						Plugin.MLogS.LogInfo((object)$"{((Object)item).name} Lost Value Mafia {item.scrapValue}");
						DespawnItem(item);
						if ((float)num2 >= num)
						{
							Plugin.MLogS.LogInfo((object)$"{num2} Scrap Value Lost Mafia");
							break;
						}
					}
				}
				else
				{
					int num3 = 0;
					foreach (GrabbableObject item2 in list2)
					{
						if (random.NextDouble() >= (double)(1f - (Config.hoardingBugInfestationLossEachChance?.Value ?? 0.1f)))
						{
							Plugin.MLogS.LogInfo((object)(((Object)item2).name + " Lost Mafia"));
							DespawnItem(item2);
							num3++;
							if (num3 >= (Config.hoardingBugInfestationLossMax?.Value ?? int.MaxValue))
							{
								Plugin.MLogS.LogInfo((object)$"Lost Mafia total {num3}");
								break;
							}
						}
					}
				}
				ConfigEntry<bool> hoardingBugInfestationEquipmentLossEnabled = Config.hoardingBugInfestationEquipmentLossEnabled;
				if (hoardingBugInfestationEquipmentLossEnabled != null && hoardingBugInfestationEquipmentLossEnabled.Value)
				{
					int num4 = 0;
					foreach (GrabbableObject item3 in list3)
					{
						if (random.NextDouble() >= (double)(1f - (Config.hoardingBugInfestationEquipmentLossChance?.Value ?? 0.05f)))
						{
							Plugin.MLogS.LogInfo((object)(((Object)item3).name + " Equipment Lost Mafia"));
							DespawnItem(item3);
							num4++;
							if (num4 >= (Config.hoardingBugInfestationEquipmentLossMax?.Value ?? int.MaxValue))
							{
								Plugin.MLogS.LogInfo((object)$"Equipment Lost Mafia total {num4}");
								break;
							}
						}
					}
				}
			}
			if (StartOfRound.Instance.allPlayersDead)
			{
				if (random.NextDouble() >= (double)(1f - (Config.saveAllChance?.Value ?? 0.25f)))
				{
					Plugin.MLogS.LogInfo((object)"All Saved");
				}
				else
				{
					list2.RemoveAll((GrabbableObject go) => !((NetworkBehaviour)go).IsSpawned);
					ConfigEntry<bool> valueSaveEnabled = Config.valueSaveEnabled;
					if (valueSaveEnabled != null && valueSaveEnabled.Value)
					{
						list2 = list2.OrderByDescending((GrabbableObject go) => go.scrapValue).ToList();
						int num5 = list2.Sum((GrabbableObject go) => go.scrapValue);
						float num6 = (float)num5 * (Config.valueSavePercent?.Value ?? 0.25f);
						foreach (GrabbableObject item4 in list2)
						{
							num5 -= item4.scrapValue;
							Plugin.MLogS.LogInfo((object)$"{((Object)item4).name} Lost Value {item4.scrapValue}");
							DespawnItem(item4);
							if ((float)num5 < num6)
							{
								Plugin.MLogS.LogInfo((object)$"{num5} Scrap Value Saved");
								break;
							}
						}
					}
					else
					{
						int num7 = 0;
						foreach (GrabbableObject item5 in list2)
						{
							if (random.NextDouble() >= (double)(1f - (Config.saveEachChance?.Value ?? 0.5f)))
							{
								Plugin.MLogS.LogInfo((object)(((Object)item5).name + " Saved"));
								continue;
							}
							Plugin.MLogS.LogInfo((object)(((Object)item5).name + " Lost"));
							DespawnItem(item5);
							num7++;
							if (num7 < (Config.scrapLossMax?.Value ?? int.MaxValue))
							{
								continue;
							}
							Plugin.MLogS.LogInfo((object)$"Lost total {num7}");
							break;
						}
					}
					ConfigEntry<bool> equipmentLossEnabled = Config.equipmentLossEnabled;
					if (equipmentLossEnabled != null && equipmentLossEnabled.Value)
					{
						list3.RemoveAll((GrabbableObject go) => !((NetworkBehaviour)go).IsSpawned);
						int num8 = 0;
						foreach (GrabbableObject item6 in list3)
						{
							if (random.NextDouble() >= (double)(1f - (Config.equipmentLossChance?.Value ?? 0.1f)))
							{
								Plugin.MLogS.LogInfo((object)(((Object)item6).name + " Equipment Lost"));
								DespawnItem(item6);
								num8++;
								if (num8 >= (Config.equipmentLossMax?.Value ?? int.MaxValue))
								{
									Plugin.MLogS.LogInfo((object)$"Equipment Lost total {num8}");
									break;
								}
							}
						}
					}
				}
			}
			return true;
			void DespawnItem(GrabbableObject gObject)
			{
				if (gObject.isHeld && (Object)(object)gObject.playerHeldBy != (Object)null)
				{
					gObject.playerHeldBy.DropAllHeldItems(true, false);
				}
				((Component)gObject).gameObject.GetComponent<NetworkObject>().Despawn(true);
				if (rManager.spawnedSyncedObjects.Contains(((Component)gObject).gameObject))
				{
					rManager.spawnedSyncedObjects.Remove(((Component)gObject).gameObject);
				}
			}
		}
	}
	[BepInPlugin("MrHydralisk.SaveOurLoot", "Save Our Loot", "1.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string MOD_GUID = "MrHydralisk.SaveOurLoot";

		private const string MOD_NAME = "Save Our Loot";

		public static Plugin instance;

		public static ManualLogSource MLogS;

		public static ConfigFile config;

		private void Awake()
		{
			MLogS = Logger.CreateLogSource("MrHydralisk.SaveOurLoot");
			config = ((BaseUnityPlugin)this).Config;
			Config.Load();
			instance = this;
			try
			{
				RuntimeHelpers.RunClassConstructor(typeof(HarmonyPatches).TypeHandle);
			}
			catch (Exception ex)
			{
				MLogS.LogError((object)string.Concat("Error in static constructor of ", typeof(HarmonyPatches), ": ", ex));
			}
			MLogS.LogInfo((object)"Plugin is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "SaveOurLoot";

		public const string PLUGIN_NAME = "SaveOurLoot";

		public const string PLUGIN_VERSION = "1.4.0";
	}
}