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 GameNetcodeStuff;
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+0fc2e77a0c8986d2b81c44e82d90b556df48f845")]
[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", "2.0.3")]
public class LethalPresentsPlugin : BaseUnityPlugin
{
private const string GUID = "LethalPresents";
private const string NAME = "LethalPresents";
private const string VERSION = "2.0.3";
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 bool ShouldSpawnSpikeTrap = 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 AllowShipSpawns = 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;
ShouldSpawnSpikeTrap = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShouldSpawnSpikeTrap", true, "Add spike roof traps 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;
AllowShipSpawns = ((BaseUnityPlugin)this).Config.Bind<bool>("Extra", "AllowShipSpawns", false, "Allow spawning enemies when opening presents inside the ship. Unkillable enemies may not be despawnable.").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_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: 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;
}
if (!AllowShipSpawns && (Object)(object)((GrabbableObject)self).playerHeldBy != (Object)null)
{
PlayerControllerB playerHeldBy = ((GrabbableObject)self).playerHeldBy;
mls.LogDebug((object)("Player is in ship: " + playerHeldBy.isInHangarShipRoom));
mls.LogDebug((object)"We will not spawn the enemy or hazard on the ship.");
if (playerHeldBy.isInHangarShipRoom)
{
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_023f: Unknown result type (might be due to invalid IL or missing references)
//IL_0240: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_024f: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Unknown result type (might be due to invalid IL or missing references)
//IL_025d: Unknown result type (might be due to invalid IL or missing references)
//IL_025e: Unknown result type (might be due to invalid IL or missing references)
//IL_0271: Unknown result type (might be due to invalid IL or missing references)
//IL_027f: Unknown result type (might be due to invalid IL or missing references)
//IL_0280: Unknown result type (might be due to invalid IL or missing references)
//IL_0281: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_028a: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_031a: Unknown result type (might be due to invalid IL or missing references)
//IL_031b: Unknown result type (might be due to invalid IL or missing references)
//IL_0325: Unknown result type (might be due to invalid IL or missing references)
//IL_032a: Unknown result type (might be due to invalid IL or missing references)
//IL_032f: Unknown result type (might be due to invalid IL or missing references)
//IL_0338: Unknown result type (might be due to invalid IL or missing references)
//IL_0339: Unknown result type (might be due to invalid IL or missing references)
//IL_034c: Unknown result type (might be due to invalid IL or missing references)
//IL_0369: Unknown result type (might be due to invalid IL or missing references)
//IL_038c: Unknown result type (might be due to invalid IL or missing references)
//IL_038d: Unknown result type (might be due to invalid IL or missing references)
//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0404: Unknown result type (might be due to invalid IL or missing references)
//IL_0409: Unknown result type (might be due to invalid IL or missing references)
//IL_040e: Unknown result type (might be due to invalid IL or missing references)
//IL_0417: Unknown result type (might be due to invalid IL or missing references)
//IL_0418: Unknown result type (might be due to invalid IL or missing references)
//IL_042b: Unknown result type (might be due to invalid IL or missing references)
//IL_0439: Unknown result type (might be due to invalid IL or missing references)
//IL_043a: Unknown result type (might be due to invalid IL or missing references)
//IL_043b: Unknown result type (might be due to invalid IL or missing references)
//IL_0440: Unknown result type (might be due to invalid IL or missing references)
//IL_0444: Unknown result type (might be due to invalid IL or missing references)
//IL_0467: Unknown result type (might be due to invalid IL or missing references)
//IL_0468: Unknown result type (might be due to invalid IL or missing references)
//IL_0547: Unknown result type (might be due to invalid IL or missing references)
//IL_0548: Unknown result type (might be due to invalid IL or missing references)
//IL_0552: Unknown result type (might be due to invalid IL or missing references)
//IL_0557: Unknown result type (might be due to invalid IL or missing references)
//IL_055c: Unknown result type (might be due to invalid IL or missing references)
//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
//IL_0585: Unknown result type (might be due to invalid IL or missing references)
//IL_0586: 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, 3 + (list2.Count + list.Count) / 3);
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++;
}
if (num == 3 && !ShouldSpawnSpikeTrap)
{
num++;
}
if (increasedLogging)
{
SpawnableMapObject[] spawnableMapObjects = currentLevel.spawnableMapObjects;
foreach (SpawnableMapObject val in spawnableMapObjects)
{
mls.LogDebug((object)("SpawnableMapObject: " + ((Object)val.prefabToSpawn).name));
}
}
Vector3 val4;
switch (num)
{
case 1:
{
SpawnableMapObject[] spawnableMapObjects3 = currentLevel.spawnableMapObjects;
foreach (SpawnableMapObject val5 in spawnableMapObjects3)
{
if (!((Object)(object)val5.prefabToSpawn.GetComponentInChildren<Turret>() == (Object)null))
{
pos -= Vector3.up * 1.8f;
GameObject val6 = Object.Instantiate<GameObject>(val5.prefabToSpawn, pos, Quaternion.identity);
val6.transform.position = pos;
Transform transform2 = val6.transform;
val4 = player_pos - pos;
transform2.forward = ((Vector3)(ref val4)).normalized;
val6.GetComponent<NetworkObject>().Spawn(true);
ManualLogSource obj2 = mls;
val4 = pos;
obj2.LogInfo((object)("Tried spawning a turret at " + ((object)(Vector3)(ref val4)).ToString()));
break;
}
}
return;
}
case 2:
{
SpawnableMapObject[] spawnableMapObjects4 = currentLevel.spawnableMapObjects;
foreach (SpawnableMapObject val7 in spawnableMapObjects4)
{
if (!((Object)(object)val7.prefabToSpawn.GetComponentInChildren<Landmine>() == (Object)null))
{
pos -= Vector3.up * 1.8f;
GameObject val8 = Object.Instantiate<GameObject>(val7.prefabToSpawn, pos, Quaternion.identity);
val8.transform.position = pos;
val8.transform.forward = new Vector3(1f, 0f, 0f);
val8.GetComponent<NetworkObject>().Spawn(true);
ManualLogSource obj3 = mls;
val4 = pos;
obj3.LogInfo((object)("Tried spawning a mine at " + ((object)(Vector3)(ref val4)).ToString()));
break;
}
}
return;
}
case 3:
{
SpawnableMapObject[] spawnableMapObjects2 = currentLevel.spawnableMapObjects;
foreach (SpawnableMapObject val2 in spawnableMapObjects2)
{
if (!((Object)(object)val2.prefabToSpawn.GetComponentInChildren<SpikeRoofTrap>() == (Object)null))
{
pos -= Vector3.up * 1.8f;
GameObject val3 = Object.Instantiate<GameObject>(val2.prefabToSpawn, pos, Quaternion.identity);
val3.transform.position = pos;
Transform transform = val3.transform;
val4 = player_pos - pos;
transform.forward = ((Vector3)(ref val4)).normalized;
val3.GetComponent<NetworkObject>().Spawn(true);
ManualLogSource obj = mls;
val4 = pos;
obj.LogInfo((object)("Tried spawning a spike trap at " + ((object)(Vector3)(ref val4)).ToString()));
break;
}
}
return;
}
}
SpawnableEnemyWithRarity val9;
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;
}
val9 = 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;
}
val9 = list2[Random.Range(0, list2.Count - 1)];
}
pos += Vector3.up * 0.25f;
if (increasedLogging)
{
ManualLogSource obj4 = mls;
string enemyName = val9.enemyType.enemyName;
val4 = pos;
obj4.LogInfo((object)("Spawning " + enemyName + " at " + ((object)(Vector3)(ref val4)).ToString()));
}
SpawnEnemy(val9, 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
{
}
}