Decompiled source of Lethal Company Enhancer v1.0.2

plugins/Lethal_Company_Enhancer.dll

Decompiled 3 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using HarmonyLib;
using Lethal_Company_Enhancer.Config;
using Lethal_Company_Enhancer.Enums;
using Lethal_Company_Enhancer.Patches;
using Lethal_Company_Enhancer.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("Mom_Llama")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A tweaks mod to enhance small group or solo play")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+ae252e6ff2141a28cae4066365bd43bc39ca5294")]
[assembly: AssemblyProduct("Lethal_Company_Enhancer")]
[assembly: AssemblyTitle("mom.llama.enhancer")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/LethalCompanyModding/Enhancer")]
[assembly: AssemblyVersion("1.0.2.0")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
[BepInDependency("com.sigurd.csync", "5.0.1")]
[BepInPlugin("mom.llama.enhancer", "Lethal_Company_Enhancer", "1.0.2")]
public class Plugin : BaseUnityPlugin
{
	public static ManualLogSource Log;

	public static PluginConfig Cfg;

	private void Awake()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
		Cfg = new PluginConfig(((BaseUnityPlugin)this).Config);
		((BaseUnityPlugin)this).Config.Save();
		Harmony val = new Harmony("mom.llama.enhancer");
		Log.LogInfo((object)"Patching now");
		val.PatchAll(typeof(HangarShipDoorPatches));
		val.PatchAll(typeof(RoundManagerPatches));
		val.PatchAll(typeof(StartOfRoundPatches));
		val.PatchAll(typeof(TerminalPatches));
		val.PatchAll(typeof(TimeOfDayPatches));
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Attaching a sync listener");
		((SyncedConfig2<PluginConfig>)(object)Cfg).InitialSyncCompleted += SyncCompleted.SyncCompletedCallback;
	}
}
internal static class LCMPluginInfo
{
	public const string PLUGIN_GUID = "mom.llama.enhancer";

	public const string PLUGIN_NAME = "Lethal_Company_Enhancer";

	public const string PLUGIN_VERSION = "1.0.2";
}
namespace Readme
{
	internal class DecompilerMessage
	{
		private const string Hello = "The source code for this project is freely available on request, btw. https://github.com/LethalCompanyModding/Enhancer/";

		internal DecompilerMessage()
		{
			_ = "The source code for this project is freely available on request, btw. https://github.com/LethalCompanyModding/Enhancer/".Length;
			_ = 69;
		}
	}
}
namespace Lethal_Company_Enhancer.Utils
{
	public static class PriceRandomizer
	{
		public static void Randomize()
		{
			Plugin.Log.LogInfo((object)"Randomizing Prices");
			if (TimeOfDay.Instance.daysUntilDeadline < 1)
			{
				StartOfRound.Instance.companyBuyingRate = 1f;
				return;
			}
			float moodFactor = GetMoodFactor();
			Plugin.Log.LogInfo((object)"Got mood factor");
			float num = (float)(1.0 + (double)(0.05f * (float)(SyncedEntry<int>.op_Implicit(Plugin.Cfg.DaysPerQuota) - TimeOfDay.Instance.daysUntilDeadline)));
			num = Mathf.Clamp(num, 1f, 2f);
			Random random = new Random(StartOfRound.Instance.randomMapSeed + 77);
			float companyBuyingRate = (float)random.NextDouble() * (1f - moodFactor * num) + moodFactor;
			Plugin.Log.LogInfo((object)("New prices set at" + companyBuyingRate));
			Plugin.Log.LogInfo((object)("    factors " + moodFactor + " : " + num + " : " + (StartOfRound.Instance.randomMapSeed + 77)));
			StartOfRound.Instance.companyBuyingRate = companyBuyingRate;
		}

		private static bool IsCompanyAvailable()
		{
			if (TimeOfDay.Instance == null)
			{
				return false;
			}
			if (TimeOfDay.Instance.currentCompanyMood == null)
			{
				return false;
			}
			if (((Object)TimeOfDay.Instance.currentCompanyMood).name == null)
			{
				return false;
			}
			return true;
		}

		private static float GetMoodFactor()
		{
			Plugin.Log.LogInfo((object)"Get mood factor");
			float num = 0.4f;
			if (!IsCompanyAvailable())
			{
				return num;
			}
			return ((Object)TimeOfDay.Instance.currentCompanyMood).name switch
			{
				"SilentCalm" => 0.35f, 
				"SnoringGiant" => 0.45f, 
				"Agitated" => 0.25f, 
				_ => num, 
			};
		}
	}
	public static class SyncCompleted
	{
		internal static bool Completed;

		public static void SyncCompletedCallback(object Sender, EventArgs e)
		{
			Plugin.Log.LogInfo((object)"Config sync'd");
			Completed = true;
		}
	}
}
namespace Lethal_Company_Enhancer.Patches
{
	public class HangarShipDoorPatches
	{
		[HarmonyPatch(typeof(HangarShipDoor), "Start")]
		[HarmonyPostfix]
		public static void HangarShipDoorPost(HangarShipDoor __instance)
		{
			Plugin.Log.LogInfo((object)"HangarShipDoor Start");
			__instance.doorPowerDuration = SyncedEntry<float>.op_Implicit(Plugin.Cfg.DoorTimer);
		}
	}
	public class RoundManagerPatches
	{
		[HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")]
		[HarmonyPrefix]
		public static bool ProtectionPrefix(RoundManager __instance, bool despawnAllItems)
		{
			RoundManager __instance2 = __instance;
			if (SyncedEntry<ProtectionType>.op_Implicit(Plugin.Cfg.ScrapProtection) == ProtectionType.SAVE_NONE || despawnAllItems)
			{
				return true;
			}
			Random rng;
			if (((NetworkBehaviour)__instance2).IsHost || ((NetworkBehaviour)__instance2).IsServer)
			{
				Plugin.Log.LogInfo((object)("ProtectionPatch -> " + despawnAllItems + " : " + StartOfRound.Instance.allPlayersDead));
				if (StartOfRound.Instance.allPlayersDead)
				{
					GrabbableObject[] array = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0);
					rng = new Random(StartOfRound.Instance.randomMapSeed + 83);
					GrabbableObject[] array2 = array;
					foreach (GrabbableObject val in array2)
					{
						ProtectionType pType2 = SyncedEntry<ProtectionType>.op_Implicit(Plugin.Cfg.ScrapProtection);
						if (val.isInShipRoom)
						{
							if (!val.itemProperties.isScrap || ShouldSaveScrap(pType2))
							{
								Plugin.Log.LogInfo((object)("Preserving ship item: " + ((Object)val).name));
							}
							else
							{
								DeleteItem(val);
							}
						}
						else
						{
							DeleteItem(val);
						}
					}
					GameObject[] array3 = GameObject.FindGameObjectsWithTag("TemporaryEffect");
					for (int j = 0; j < array3.Length; j++)
					{
						Object.Destroy((Object)(object)array3[j]);
					}
					return false;
				}
			}
			return true;
			void DeleteItem(GrabbableObject item)
			{
				Plugin.Log.LogInfo((object)("Despawning item: " + ((Object)item).name + " in ship: " + item.isInShipRoom));
				((Component)item).gameObject.GetComponent<NetworkObject>().Despawn(true);
				if (__instance2.spawnedSyncedObjects.Contains(((Component)item).gameObject))
				{
					__instance2.spawnedSyncedObjects.Remove(((Component)item).gameObject);
				}
			}
			bool ShouldSaveScrap(ProtectionType pType)
			{
				return pType switch
				{
					ProtectionType.SAVE_ALL => true, 
					ProtectionType.SAVE_COINFLIP => rng.NextDouble() > 0.49, 
					_ => false, 
				};
			}
		}
	}
	public class StartOfRoundPatches
	{
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPrefix]
		public static bool StartOfRoundShipStartPre()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			Plugin.Log.LogInfo((object)"StartOfRound Start");
			if (!NetworkManager.Singleton.IsServer && !SyncCompleted.Completed)
			{
				Plugin.Log.LogError((object)"Client joined without receiving sync");
				Plugin.Cfg.Enabled.LocalValue = false;
				Harmony val = new Harmony("mom.llama.enhancer");
				val.UnpatchSelf();
				return true;
			}
			TimeOfDay.Instance.quotaVariables.deadlineDaysAmount = SyncedEntry<int>.op_Implicit(Plugin.Cfg.DaysPerQuota);
			return true;
		}
	}
	public class TerminalPatches
	{
		[HarmonyPatch(typeof(Terminal), "Update")]
		[HarmonyPostfix]
		public static void TerminalUpdatePost(Terminal __instance)
		{
			if (!((Component)__instance.terminalUIScreen).gameObject.activeSelf && SyncedEntry<bool>.op_Implicit(Plugin.Cfg.KeepConsoleEnabled))
			{
				((Component)__instance.terminalUIScreen).gameObject.SetActive(true);
			}
		}

		[HarmonyPatch(typeof(Terminal), "LoadNewNode")]
		[HarmonyPostfix]
		public static void TerminalLoadHackPost(Terminal __instance, TerminalNode node)
		{
			if (!(((Object)node).name == "ScanInfo") || SyncedEntry<int>.op_Implicit(Plugin.Cfg.ThreatScannerType) == 0 || !RoundManager.Instance.currentLevel.spawnEnemiesAndScrap)
			{
				return;
			}
			float currentEnemyPower = RoundManager.Instance.currentEnemyPower;
			int maxEnemyPowerCount = RoundManager.Instance.currentLevel.maxEnemyPowerCount;
			string text = "\nThreat Level: ";
			switch (SyncedEntry<int>.op_Implicit(Plugin.Cfg.ThreatScannerType))
			{
			case 1:
			{
				int numberOfEnemiesInScene = RoundManager.Instance.numberOfEnemiesInScene;
				text = "\nHostile Contacts: " + numberOfEnemiesInScene;
				break;
			}
			case 2:
				text = text + (currentEnemyPower / (float)maxEnemyPowerCount * 100f).ToString("N1") + "%";
				break;
			case 3:
			{
				string text2 = "CLEAR";
				float num = currentEnemyPower / (float)maxEnemyPowerCount;
				if (num > 0.99f)
				{
					text2 = "OMEGA";
				}
				else if (num > 0.69f)
				{
					text2 = "RED";
				}
				else if ((double)num > 0.49)
				{
					text2 = "ORANGE";
				}
				else if ((double)num > 0.24)
				{
					text2 = "YELLOW";
				}
				else if (num > 0f)
				{
					text2 = "GREEN";
				}
				text += text2;
				break;
			}
			}
			text += "\n";
			TMP_InputField screenText = __instance.screenText;
			screenText.text += text;
			__instance.currentText = __instance.screenText.text;
			__instance.textAdded = 0;
		}
	}
	public class TimeOfDayPatches
	{
		[HarmonyPatch(typeof(TimeOfDay), "SetBuyingRateForDay")]
		[HarmonyPostfix]
		public static void BuyingRatePost(TimeOfDay __instance)
		{
			Plugin.Log.LogInfo((object)"TimeOfDay SetBuyingRateForDay");
			if (SyncedEntry<bool>.op_Implicit(Plugin.Cfg.UseRandomPrices))
			{
				PriceRandomizer.Randomize();
			}
			if (StartOfRound.Instance.companyBuyingRate < SyncedEntry<float>.op_Implicit(Plugin.Cfg.MinimumBuyRate))
			{
				StartOfRound.Instance.companyBuyingRate = SyncedEntry<float>.op_Implicit(Plugin.Cfg.MinimumBuyRate);
			}
			StartOfRound.Instance.SyncCompanyBuyingRateServerRpc();
		}

		[HarmonyPatch(typeof(TimeOfDay), "Start")]
		[HarmonyPostfix]
		public static void TimeOfDayOnStartPost(TimeOfDay __instance)
		{
			Plugin.Log.LogInfo((object)"TimeOfDay Start");
			__instance.globalTimeSpeedMultiplier = SyncedEntry<float>.op_Implicit(Plugin.Cfg.TimeScale);
		}
	}
}
namespace Lethal_Company_Enhancer.Enums
{
	public enum ProtectionType
	{
		SAVE_NONE,
		SAVE_ALL,
		SAVE_COINFLIP
	}
}
namespace Lethal_Company_Enhancer.Config
{
	public class PluginConfig : SyncedConfig2<PluginConfig>
	{
		[field: SyncedEntryField]
		public SyncedEntry<bool> Enabled { get; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> KeepConsoleEnabled { get; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> UseRandomPrices { get; }

		[field: SyncedEntryField]
		public SyncedEntry<float> TimeScale { get; }

		[field: SyncedEntryField]
		public SyncedEntry<float> MinimumBuyRate { get; }

		[field: SyncedEntryField]
		public SyncedEntry<float> DoorTimer { get; }

		[field: SyncedEntryField]
		public SyncedEntry<int> DaysPerQuota { get; }

		[field: SyncedEntryField]
		public SyncedEntry<int> ThreatScannerType { get; }

		[field: SyncedEntryField]
		public SyncedEntry<ProtectionType> ScrapProtection { get; }

		public PluginConfig(ConfigFile Config)
			: base("mom.llama.enhancer")
		{
			Enabled = SyncedBindingExtensions.BindSyncedEntry<bool>(Config, "mom.llama.enhancer", "bEnabled", true, "Globally enable/disable the plugin");
			KeepConsoleEnabled = SyncedBindingExtensions.BindSyncedEntry<bool>(Config, "mom.llama.enhancer", "bAlwaysShowTerminal", true, "Whether to keep the terminal enabled after a player stops using it\nHost Required: No");
			UseRandomPrices = SyncedBindingExtensions.BindSyncedEntry<bool>(Config, "mom.llama.enhancer", "bUseRandomPrices", false, "Enables the random prices setting. Great if you're using longer quota deadlines.\nThis uses a variety of things to randomize prices such as the company mood, time passed in the quota, etc.\nRespects the minimum sale value, too.\nHost Required: Yes");
			TimeScale = SyncedBindingExtensions.BindSyncedEntry<float>(Config, "mom.llama.enhancer", "fTimeScale", 1.5f, "How fast time passes on moons. Lower values mean time passes more slowly.\nRecommended value for single play: 1.15\nHost Required: Yes");
			MinimumBuyRate = SyncedBindingExtensions.BindSyncedEntry<float>(Config, "mom.llama.enhancer", "fMinCompanyBuyPCT", 0f, "The default formula for selling items to the company doesn't allow days remaining above 3.\nAlways keep this set to at least 0.0 but you probably want something higher if you have more days set for the quota.\nRecommended values for games above 3 days: 0.3 - 0.5\nHost Required: Yes");
			DoorTimer = SyncedBindingExtensions.BindSyncedEntry<float>(Config, "mom.llama.enhancer", "fDoorTimer", 30f, "How long the hangar door can be kept shut at a time (in seconds)\nRecommended values: 60.0 - 180.0\nHost Required: All players should use the same setting here");
			DaysPerQuota = SyncedBindingExtensions.BindSyncedEntry<int>(Config, "mom.llama.enhancer", "iQuotaDays", 3, "How long you have to meet each quota (in days)\nRecommended values: 3 - 7\nHost Required: Yes");
			ThreatScannerType = SyncedBindingExtensions.BindSyncedEntry<int>(Config, "mom.llama.enhancer", "eThreatScannerType", 0, "How the threat scanner functions. Valid types:\n0 - Disabled\n1 - Number of Enemies on level\n2 - Percentage of max enemies on level\n3 - Vague Text description (In order of threat level) [Clear -> Green -> Yellow -> Orange - Red]\nHost Required: No");
			ScrapProtection = SyncedBindingExtensions.BindSyncedEntry<ProtectionType>(Config, "mom.llama.enhancer", "eScrapProtection", ProtectionType.SAVE_NONE, "Sets how scrap will be handled when all players die in a round.\nSAVE_NONE: Default all scrap is deleted\nSAVE_ALL: No scrap is removed\nSAVE_COINFLIP: Each piece of scrap has a 50/50 of being removed\nHost Required: Yes");
			ConfigManager.Register<PluginConfig>((SyncedConfig2<PluginConfig>)(object)this);
		}
	}
}