Decompiled source of LethalPresents v2.0.1

LethalPresents.dll

Decompiled 10 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using LethalPresents.NetcodePatcher;
using Microsoft.CodeAnalysis;
using On;
using Unity.Netcode;
using UnityEngine;

[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("LethalPresents")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("LethalPresents mod")]
[assembly: AssemblyFileVersion("1.0.9.0")]
[assembly: AssemblyInformationalVersion("1.0.9+26dc1591d278449dc9719a6c0a74b80846c22dad")]
[assembly: AssemblyProduct("LethalPresents")]
[assembly: AssemblyTitle("LethalPresents")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.9.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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 LethalPresents
{
	[BepInPlugin("LethalPresents", "LethalPresents", "1.0.9")]
	public class LethalPresentsPlugin : BaseUnityPlugin
	{
		public static ManualLogSource mls;

		private static int spawnChance = 5;

		private static string[] disabledEnemies = new string[0];

		private static bool CloneWorkaround = false;

		private static bool IsAllowlist = false;

		private static bool ShouldSpawnMines = false;

		private static bool ShouldSpawnTurrets = false;

		private static bool increasedLogging = false;

		private static string MoonsToIgnore = "";

		private static bool MoonListIsAllowlist = false;

		private static bool FateMode = false;

		private static bool AllowInsideSpawnOutside = false;

		private static bool AllowOutsideSpawnInside = false;

		private static bool isHost => ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost;

		private static SelectableLevel currentLevel => RoundManager.Instance.currentLevel;

		internal static T GetPrivateField<T>(object instance, string fieldName)
		{
			FieldInfo field = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
			return (T)field.GetValue(instance);
		}

		private void Awake()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			mls = ((BaseUnityPlugin)this).Logger;
			mls.LogInfo((object)"Plugin LethalPresents is loaded!");
			loadConfig();
			RoundManager.AdvanceHourAndSpawnNewBatchOfEnemies += new hook_AdvanceHourAndSpawnNewBatchOfEnemies(updateCurrentLevelInfo);
			GiftBoxItem.OpenGiftBoxServerRpc += new hook_OpenGiftBoxServerRpc(spawnRandomEntity);
		}

		private void TryLog(object obj)
		{
			try
			{
				mls.LogInfo(obj);
			}
			catch (Exception)
			{
			}
		}

		private void updateCurrentLevelInfo(orig_AdvanceHourAndSpawnNewBatchOfEnemies orig, RoundManager self)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			orig.Invoke(self);
			RoundManager.AdvanceHourAndSpawnNewBatchOfEnemies -= new hook_AdvanceHourAndSpawnNewBatchOfEnemies(updateCurrentLevelInfo);
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				try
				{
					mls.LogInfo((object)("Moon: " + val.PlanetName + " (" + ((Object)val).name + ")"));
					mls.LogInfo((object)"List of spawnable enemies (inside):");
					val.Enemies.ForEach(delegate(SpawnableEnemyWithRarity e)
					{
						TryLog(((Object)e.enemyType).name);
					});
					mls.LogInfo((object)"List of spawnable enemies (outside):");
					val.OutsideEnemies.ForEach(delegate(SpawnableEnemyWithRarity e)
					{
						TryLog(((Object)e.enemyType).name);
					});
					val.DaytimeEnemies.ForEach(delegate(SpawnableEnemyWithRarity e)
					{
						TryLog(((Object)e.enemyType).name);
					});
				}
				catch (Exception)
				{
				}
			}
		}

		private void loadConfig()
		{
			spawnChance = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SpawnChance", 5, "Chance of spawning an enemy when opening a present [0-100]").Value;
			disabledEnemies = ((BaseUnityPlugin)this).Config.Bind<string>("General", "EnemyBlocklist", "", "Enemy blocklist separated by , and without whitespaces").Value.Split(",");
			IsAllowlist = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsAllowlist", false, "Turns blocklist into allowlist, blocklist must contain at least one inside and one outside enemy, use at your own risk").Value;
			ShouldSpawnMines = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShouldSpawnMines", true, "Add mines to the spawn pool").Value;
			ShouldSpawnTurrets = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShouldSpawnTurrets", true, "Add turrets to the spawn pool").Value;
			MoonsToIgnore = ((BaseUnityPlugin)this).Config.Bind<string>("General", "MoonsToIgnore", "", "List of moons to ignore present spawning events on, separated by comma. You can specify the moon with and without its numbers too").Value;
			increasedLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Extra", "IncreasedLogging", true, "Enables increased logging to help with debugging").Value;
			MoonListIsAllowlist = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MoonListIsAllowlist", false, "Turns moon ignore list into allowlist").Value;
			FateMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Extra", "FateMode", false, "If enabled, the spawn chance will be unpredictable and will vary.").Value;
			CloneWorkaround = ((BaseUnityPlugin)this).Config.Bind<bool>("Extra", "CloneWorkaround", false, "Workadound against some mods (if you find such mods - please complain to their authors about it) replacing level.Enemies entries with cloned enemies without updating their names.").Value;
			AllowInsideSpawnOutside = ((BaseUnityPlugin)this).Config.Bind<bool>("Extra", "AllowInsideSpawnOutside", true, "Allow spawning inside enemies when outside the building. CAN CAUSE LAG WITHOUT PROPER AI MOD").Value;
			AllowOutsideSpawnInside = ((BaseUnityPlugin)this).Config.Bind<bool>("Extra", "AllowOutsideSpawnInside", true, "Allow spawning outside enemies when inside the building. CAN CAUSE LAG WITHOUT PROPER AI MOD").Value;
			if (IsAllowlist)
			{
				mls.LogInfo((object)"Only following enemies can spawn from the gift:");
			}
			else
			{
				mls.LogInfo((object)"Following enemies wont be spawned from the gift:");
			}
			string[] array = disabledEnemies;
			foreach (string text in array)
			{
				mls.LogInfo((object)text);
			}
		}

		private void spawnRandomEntity(orig_OpenGiftBoxServerRpc orig, GiftBoxItem self)
		{
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)self).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				orig.Invoke(self);
				return;
			}
			int privateField = GetPrivateField<int>(self, "__rpc_exec_stage");
			mls.LogDebug((object)("IsServer:" + networkManager.IsServer + " IsHost:" + networkManager.IsHost + " __rpc_exec_stage:" + privateField));
			if (privateField != 1 || !isHost)
			{
				orig.Invoke(self);
				return;
			}
			if ((IsIgnoredMoon(currentLevel.PlanetName) && !MoonListIsAllowlist) || (!IsIgnoredMoon(currentLevel.PlanetName) && MoonListIsAllowlist))
			{
				orig.Invoke(self);
				return;
			}
			int num = Random.Range(1, 100);
			mls.LogDebug((object)("Player's fortune 1:" + num));
			if (FateMode)
			{
				spawnChance = Random.Range(0, 101);
				if (increasedLogging)
				{
					mls.LogDebug((object)("Fate mode active, new spawn chance: " + spawnChance));
				}
			}
			if (num >= spawnChance)
			{
				orig.Invoke(self);
				return;
			}
			chooseAndSpawnEnemy(((GrabbableObject)self).isInFactory, ((Component)self).transform.position, ((Component)self.previousPlayerHeldBy).transform.position);
			orig.Invoke(self);
		}

		private static void chooseAndSpawnEnemy(bool inside, Vector3 pos, Vector3 player_pos)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: 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_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			if (increasedLogging)
			{
				mls.LogDebug((object)$"Player pos {player_pos} moon: {currentLevel.PlanetName} ({((Object)currentLevel).name}), IsAllowList: {IsAllowlist}");
			}
			List<SpawnableEnemyWithRarity> list = currentLevel.Enemies.Where(delegate(SpawnableEnemyWithRarity e)
			{
				string text2 = ((Object)e.enemyType).name;
				if (CloneWorkaround)
				{
					text2 = text2.Replace("(Clone)", "").Trim();
				}
				if (disabledEnemies.Contains(text2))
				{
					mls.LogDebug((object)(text2 + " [" + ((Object)e.enemyType).name + "] is in the list"));
					return IsAllowlist;
				}
				mls.LogDebug((object)(text2 + " [" + ((Object)e.enemyType).name + "] is NOT in the list"));
				return !IsAllowlist;
			}).ToList();
			List<SpawnableEnemyWithRarity> list2 = currentLevel.OutsideEnemies.Concat(currentLevel.DaytimeEnemies).Where(delegate(SpawnableEnemyWithRarity e)
			{
				string text = ((Object)e.enemyType).name;
				if (CloneWorkaround)
				{
					text = text.Replace("(Clone)", "").Trim();
				}
				if (disabledEnemies.Contains(text))
				{
					mls.LogDebug((object)(text + " [" + ((Object)e.enemyType).name + "] is in the list"));
					return IsAllowlist;
				}
				mls.LogDebug((object)(text + " [" + ((Object)e.enemyType).name + "] is NOT in the list"));
				return !IsAllowlist;
			}).ToList();
			int num = Random.Range(1, 2 + (list2.Count + list.Count) / 2);
			mls.LogDebug((object)("Choosing what to spawn; fortune 2: " + num + "; OutsideEnemiesCount: " + list2.Count + "; InsideEnemiesCount: " + list.Count));
			if (num == 1 && !ShouldSpawnTurrets)
			{
				num++;
			}
			if (num == 2 && !ShouldSpawnMines)
			{
				num++;
			}
			Vector3 val3;
			switch (num)
			{
			case 1:
			{
				SpawnableMapObject[] spawnableMapObjects2 = currentLevel.spawnableMapObjects;
				foreach (SpawnableMapObject val4 in spawnableMapObjects2)
				{
					if (!((Object)(object)val4.prefabToSpawn.GetComponentInChildren<Turret>() == (Object)null))
					{
						pos -= Vector3.up * 1.8f;
						GameObject val5 = Object.Instantiate<GameObject>(val4.prefabToSpawn, pos, Quaternion.identity);
						val5.transform.position = pos;
						Transform transform = val5.transform;
						val3 = player_pos - pos;
						transform.forward = ((Vector3)(ref val3)).normalized;
						val5.GetComponent<NetworkObject>().Spawn(true);
						ManualLogSource obj2 = mls;
						val3 = pos;
						obj2.LogInfo((object)("Tried spawning a turret at " + ((object)(Vector3)(ref val3)).ToString()));
						break;
					}
				}
				return;
			}
			case 2:
			{
				SpawnableMapObject[] spawnableMapObjects = currentLevel.spawnableMapObjects;
				foreach (SpawnableMapObject val in spawnableMapObjects)
				{
					if (!((Object)(object)val.prefabToSpawn.GetComponentInChildren<Landmine>() == (Object)null))
					{
						pos -= Vector3.up * 1.8f;
						GameObject val2 = Object.Instantiate<GameObject>(val.prefabToSpawn, pos, Quaternion.identity);
						val2.transform.position = pos;
						val2.transform.forward = new Vector3(1f, 0f, 0f);
						val2.GetComponent<NetworkObject>().Spawn(true);
						ManualLogSource obj = mls;
						val3 = pos;
						obj.LogInfo((object)("Tried spawning a mine at " + ((object)(Vector3)(ref val3)).ToString()));
						break;
					}
				}
				return;
			}
			}
			SpawnableEnemyWithRarity val6;
			if (inside)
			{
				if (AllowOutsideSpawnInside)
				{
					list.AddRange(list2);
				}
				if (list.Count < 1)
				{
					mls.LogInfo((object)"Cant spawn enemy - no other enemies present to copy from");
					return;
				}
				val6 = list[Random.Range(0, list.Count - 1)];
			}
			else
			{
				if (AllowInsideSpawnOutside)
				{
					list2.AddRange(list);
				}
				if (list2.Count < 1)
				{
					mls.LogInfo((object)"Cant spawn enemy - no other enemies present to copy from");
					return;
				}
				val6 = list2[Random.Range(0, list2.Count - 1)];
			}
			pos += Vector3.up * 0.25f;
			if (increasedLogging)
			{
				ManualLogSource obj3 = mls;
				string enemyName = val6.enemyType.enemyName;
				val3 = pos;
				obj3.LogInfo((object)("Spawning " + enemyName + " at " + ((object)(Vector3)(ref val3)).ToString()));
			}
			SpawnEnemy(val6, pos, 0f);
		}

		private static void SpawnEnemy(SpawnableEnemyWithRarity enemy, Vector3 pos, float rot)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			RoundManager.Instance.SpawnEnemyGameObject(pos, rot, -1, enemy.enemyType);
		}

		internal static bool IsIgnoredMoon(string moonName)
		{
			string moonsToIgnore = MoonsToIgnore;
			string[] array = (string.IsNullOrEmpty(moonsToIgnore) ? new string[0] : (from moon in moonsToIgnore.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
				select moon.Trim()).ToArray());
			bool result = false;
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = Regex.Replace(moonName, "\\d", string.Empty).Trim();
				string text3 = Regex.Replace(text, "\\d", string.Empty).Trim();
				if (moonName == text || text2 == text3)
				{
					result = true;
					mls.LogInfo((object)"Moon is on list of moons to ignore events. Skipping Events");
					break;
				}
			}
			return result;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalPresents";

		public const string PLUGIN_NAME = "LethalPresents";

		public const string PLUGIN_VERSION = "1.0.9";
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace LethalPresents.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}