Decompiled source of SCP500B v1.0.3

BepinEx/plugins/SCP-500-B/ProjectSCP.SCP500.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("ProjectSCP.SCP500")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SCP500")]
[assembly: AssemblyTitle("ProjectSCP.SCP500")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.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;
		}
	}
}
namespace SCP500
{
	[BepInPlugin("ProjectSCP.SCP500", "SCP500", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin PluginInstance;

		public static ManualLogSource LoggerInstance;

		private readonly Harmony harmony = new Harmony("ProjectSCP.SCP500");

		public static AssetBundle? ModAssets;

		public static ConfigEntry<int> config500MinValue;

		public static ConfigEntry<int> config500MaxValue;

		public static ConfigEntry<string> config500LevelRarities;

		public static ConfigEntry<string> config500CustomLevelRarities;

		public static ConfigEntry<int> config500MaxAmount;

		public static ConfigEntry<int> config500MinAmount;

		public static ConfigEntry<float> config500EffectTime;

		public static ConfigEntry<bool> configRemoveDrunkness;

		public static ConfigEntry<bool> configRemoveBleeding;

		public static ConfigEntry<bool> configRemoveMovementHindered;

		public static ConfigEntry<bool> configRemovePlayerAlone;

		public static ConfigEntry<bool> configRemoveInsanity;

		public static ConfigEntry<bool> configRemoveFear;

		public static ConfigEntry<bool> configRemoveMaskEffect;

		public static PlayerControllerB localPlayer => StartOfRound.Instance.localPlayerController;

		private void Awake()
		{
			if ((Object)(object)PluginInstance == (Object)null)
			{
				PluginInstance = this;
			}
			LoggerInstance = ((BaseUnityPlugin)PluginInstance).Logger;
			harmony.PatchAll();
			config500MinValue = ((BaseUnityPlugin)this).Config.Bind<int>("SCP-500", "Min Value", 10, "Minimum scrap value for SCP-500.");
			config500MaxValue = ((BaseUnityPlugin)this).Config.Bind<int>("SCP-500", "Max Value", 100, "Maximum scrap value for SCP-500.");
			config500LevelRarities = ((BaseUnityPlugin)this).Config.Bind<string>("SCP-500 Rarities", "Level Rarities", "ExperimentationLevel:10, AssuranceLevel:10, VowLevel:10, OffenseLevel:15, AdamanceLevel:20, MarchLevel:15, RendLevel:20, DineLevel:20, TitanLevel:20, ArtificeLevel:30, EmbrionLevel:10, All:10, Modded:10", "Rarities for each level. See default for formatting.");
			config500CustomLevelRarities = ((BaseUnityPlugin)this).Config.Bind<string>("SCP-500 Rarities", "Custom Level Rarities", "", "Rarities for modded levels. Same formatting as level rarities.");
			config500MaxAmount = ((BaseUnityPlugin)this).Config.Bind<int>("SCP-500", "Max amount", 15, "Maximum pills for SCP-500. Max is ");
			config500MinAmount = ((BaseUnityPlugin)this).Config.Bind<int>("SCP-500", "Min amount", 2, "Minimum pills for SCP-500");
			config500EffectTime = ((BaseUnityPlugin)this).Config.Bind<float>("SCP-500", "Effect time", 30f, "How long the effect lasts for SCP-500");
			configRemoveDrunkness = ((BaseUnityPlugin)this).Config.Bind<bool>("SCP-500 Effects", "Remove Drunkness", true, "Remove Drunkness");
			configRemoveBleeding = ((BaseUnityPlugin)this).Config.Bind<bool>("SCP-500 Effects", "Remove Bleeding", true, "Remove Bleeding");
			configRemoveMovementHindered = ((BaseUnityPlugin)this).Config.Bind<bool>("SCP-500 Effects", "Remove Movement Hinderance", true, "Remove Movement Hinderance");
			configRemovePlayerAlone = ((BaseUnityPlugin)this).Config.Bind<bool>("SCP-500 Effects", "Remove Player Alone", true, "Remove Player Alone");
			configRemoveInsanity = ((BaseUnityPlugin)this).Config.Bind<bool>("SCP-500 Effects", "Remove Insanity", true, "Remove Insanity");
			configRemoveFear = ((BaseUnityPlugin)this).Config.Bind<bool>("SCP-500 Effects", "Remove Fear", true, "Remove Fear");
			configRemoveMaskEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("SCP-500 Effects", "Remove Mask Effect", true, "Remove Mask Effect");
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "scp500_assets"));
			if ((Object)(object)ModAssets == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Failed to load custom assets.");
				return;
			}
			LoggerInstance.LogDebug((object)("Got AssetBundle at: " + Path.Combine(directoryName, "scp500_assets")));
			Item val = ModAssets.LoadAsset<Item>("Assets/ModAssets/SCP500/SCP500Item.asset");
			if ((Object)(object)val == (Object)null)
			{
				LoggerInstance.LogError((object)"Error: Couldnt get SCP500 from assets");
				return;
			}
			LoggerInstance.LogDebug((object)"Got SCP500 prefab");
			val.minValue = config500MinValue.Value;
			val.maxValue = config500MaxValue.Value;
			NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab);
			Utilities.FixMixerGroups(val.spawnPrefab);
			Items.RegisterScrap(val, GetLevelRarities(config500LevelRarities.Value), GetCustomLevelRarities(config500CustomLevelRarities.Value));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ProjectSCP.SCP500 v1.0.0 has loaded!");
		}

		public Dictionary<LevelTypes, int> GetLevelRarities(string levelsString)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Dictionary<LevelTypes, int> dictionary = new Dictionary<LevelTypes, int>();
				if (levelsString != null && levelsString != "")
				{
					string[] array = levelsString.Split(',');
					string[] array2 = array;
					foreach (string text in array2)
					{
						string[] array3 = text.Split(':');
						if (array3.Length == 2)
						{
							string text2 = array3[0].Trim();
							string text3 = array3[1].Trim();
							if (Enum.TryParse<LevelTypes>(text2, out LevelTypes result) && int.TryParse(text3, out var result2))
							{
								dictionary.Add(result, result2);
							}
							else
							{
								LoggerInstance.LogError((object)("Error: Invalid level rarity: " + text2 + ":" + text3));
							}
						}
					}
				}
				return dictionary;
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Error: {arg}");
				return null;
			}
		}

		public Dictionary<string, int> GetCustomLevelRarities(string levelsString)
		{
			try
			{
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				if (levelsString != null)
				{
					string[] array = levelsString.Split(',');
					string[] array2 = array;
					foreach (string text in array2)
					{
						string[] array3 = text.Split(':');
						if (array3.Length == 2)
						{
							string text2 = array3[0].Trim();
							string text3 = array3[1].Trim();
							if (int.TryParse(text3, out var result))
							{
								dictionary.Add(text2, result);
							}
							else
							{
								LoggerInstance.LogError((object)("Error: Invalid level rarity: " + text2 + ":" + text3));
							}
						}
					}
				}
				return dictionary;
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Error: {arg}");
				return null;
			}
		}

		private static void InitializeNetworkBehaviours()
		{
			Type[] types = Assembly.GetExecutingAssembly().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)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			LoggerInstance.LogDebug((object)"Finished initializing network behaviours");
		}
	}
	internal class SCP500Behavior : PhysicsProp
	{
		private static ManualLogSource logger = Plugin.LoggerInstance;

		public List<GameObject> PillsInBottle;

		public AudioClip PillSwallowSFX;

		public override void Start()
		{
			((GrabbableObject)this).Start();
			int num = Random.Range(Plugin.config500MinAmount.Value, Plugin.config500MaxAmount.Value);
			int num2 = PillsInBottle.Count - num;
			for (int i = 0; i < num2; i++)
			{
				RemovePillFromBottle();
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (buttonDown && !((GrabbableObject)this).itemUsedUp)
			{
				RemovePillFromBottle();
				SCP500Controller.TakePill();
				((GrabbableObject)this).playerHeldBy.statusEffectAudio.PlayOneShot(PillSwallowSFX, 1f);
				if (PillsInBottle.Count == 0)
				{
					((GrabbableObject)this).itemUsedUp = true;
				}
			}
		}

		private void RemovePillFromBottle()
		{
			GameObject val = PillsInBottle.Last();
			PillsInBottle.Remove(val);
			Object.Destroy((Object)(object)val);
		}
	}
	public class SCP500Controller : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <ApplySCP500EffectCoroutine>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public SCP500Controller <>4__this;

			object? IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object? IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplySCP500EffectCoroutine>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					LocalPlayerAffectedBySCP500 = true;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<>4__this.timer > 0f)
				{
					<>4__this.timer -= Time.deltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				LocalPlayerAffectedBySCP500 = false;
				<>4__this.scp500Coroutine = null;
				Instance = null;
				Object.Destroy((Object)(object)((Component)<>4__this).gameObject);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		internal static SCP500Controller? Instance;

		private float timer = 0f;

		public static bool LocalPlayerAffectedBySCP500;

		private Coroutine? scp500Coroutine;

		public void Update()
		{
			if (Plugin.configRemoveDrunkness.Value)
			{
				Plugin.localPlayer.drunkness = 0f;
			}
			if (Plugin.configRemoveMovementHindered.Value)
			{
				Plugin.localPlayer.isMovementHindered = 0;
			}
			if (Plugin.configRemoveInsanity.Value)
			{
				Plugin.localPlayer.insanityLevel = 0f;
			}
			if (Plugin.configRemoveFear.Value)
			{
				Plugin.localPlayer.playersManager.fearLevel = 0f;
			}
			Plugin.localPlayer.bleedingHeavily = !Plugin.configRemoveBleeding.Value;
			Plugin.localPlayer.isPlayerAlone = !Plugin.configRemovePlayerAlone.Value;
		}

		public static void TakePill()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayer = Plugin.localPlayer;
			localPlayer.health += 999;
			Plugin.localPlayer.DamagePlayer(0, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
			HUDManager.Instance.UpdateHealthUI(Plugin.localPlayer.health, false);
			Plugin.localPlayer.MakeCriticallyInjured(false);
			Plugin.localPlayer.hasBeenCriticallyInjured = false;
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = new GameObject("SCP500Controller").AddComponent<SCP500Controller>();
			}
			Instance.timer += Plugin.config500EffectTime.Value;
			if (Instance.scp500Coroutine == null)
			{
				Instance.scp500Coroutine = ((MonoBehaviour)Instance).StartCoroutine(Instance.ApplySCP500EffectCoroutine());
			}
		}

		[IteratorStateMachine(typeof(<ApplySCP500EffectCoroutine>d__6))]
		private IEnumerator ApplySCP500EffectCoroutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplySCP500EffectCoroutine>d__6(0)
			{
				<>4__this = this
			};
		}
	}
	[HarmonyPatch]
	internal class Patches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(HauntedMaskItem), "BeginAttachment")]
		public static bool BeginAttachmentPrefix()
		{
			if (SCP500Controller.LocalPlayerAffectedBySCP500)
			{
				return !Plugin.configRemoveMaskEffect.Value;
			}
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ProjectSCP.SCP500";

		public const string PLUGIN_NAME = "SCP500";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}