Decompiled source of PoisonPuffer v1.3.0

PoisonPuffer.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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 GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TestAccountCore;
using UnityEngine;
using UnityEngine.Networking;

[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("TestAccount666.PoisonPuffer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("The spore lizard has evolved to be poisonous!")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+d2a6fd5fbb78a9cac4a8872a93b78ddb59d540cc")]
[assembly: AssemblyProduct("PoisonPuffer")]
[assembly: AssemblyTitle("TestAccount666.PoisonPuffer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.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 PoisonPuffer
{
	[BepInDependency("TestAccount666.TestAccountCore", "1.1.0")]
	[BepInPlugin("TestAccount666.PoisonPuffer", "PoisonPuffer", "1.3.0")]
	public class PoisonPuffer : BaseUnityPlugin
	{
		internal static List<AudioClip>? coughAudioClips;

		internal static ConfigEntry<int> coughVolumeEntry;

		internal static ConfigEntry<int> warningCoolDownEntry;

		public static PoisonPuffer Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		internal static float CoughVolume => (float)coughVolumeEntry.Value / 100f;

		internal static long WarningCoolDown => warningCoolDownEntry.Value * 1000;

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			InitializeConfig();
			Patch();
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			if (directoryName == null)
			{
				Logger.LogError((object)"An error occured while trying to find the assembly directory. Please report this!");
				return;
			}
			coughAudioClips = new List<AudioClip>();
			string text = Path.Combine(directoryName, "coughs");
			text = (Directory.Exists(text) ? text : Path.Combine(directoryName));
			for (int i = 1; i <= 14; i++)
			{
				((MonoBehaviour)this).StartCoroutine(LoadAudioClipFromFile(new Uri(Path.Combine(text, $"cough{i}.wav")), $"cough{i}"));
			}
			Logger.LogInfo((object)"TestAccount666.PoisonPuffer v1.3.0 has loaded!");
		}

		private void InitializeConfig()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			coughVolumeEntry = ((BaseUnityPlugin)this).Config.Bind<int>("Sound", "Cough Sound Volume", 100, new ConfigDescription("The volume for coughing sounds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			warningCoolDownEntry = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "Poison Warning Cooldown", 3, new ConfigDescription("The cooldown for warning you about the poison. A cooldown of 0 disables this.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>()));
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("TestAccount666.PoisonPuffer");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}

		private static IEnumerator LoadAudioClipFromFile(Uri filePath, string name)
		{
			UnityWebRequest unityWebRequest = UnityWebRequestMultimedia.GetAudioClip(filePath, (AudioType)20);
			try
			{
				yield return unityWebRequest.SendWebRequest();
				if ((int)unityWebRequest.result != 1)
				{
					Logger.LogError((object)("Failed to load AudioClip: " + unityWebRequest.error));
					yield break;
				}
				AudioClip clip = DownloadHandlerAudioClip.GetContent(unityWebRequest);
				coughAudioClips?.Add(clip);
				((Object)clip).name = name;
				Logger.LogInfo((object)("Loaded clip '" + name + "'!"));
			}
			finally
			{
				((IDisposable)unityWebRequest)?.Dispose();
			}
		}
	}
	public class PoisonTrigger : MonoBehaviour
	{
		private readonly Random _random = new Random();

		private int? _instanceId;

		private static readonly List<int> _PreviousCoughs = new List<int>(3);

		private long _nextCheck;

		private long _nextWarning;

		private bool _destroy;

		private void OnDestroy()
		{
			_destroy = true;
		}

		private void Update()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (_destroy)
			{
				return;
			}
			long currentTime = UnixTime.GetCurrentTime();
			if (currentTime >= _nextCheck)
			{
				PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
				Vector3 position = ((Component)localPlayerController).transform.position;
				Vector3 position2 = ((Component)this).gameObject.transform.position;
				float num = Vector3.Distance(position2, position);
				if (num > 8f)
				{
					_nextCheck = currentTime + 100;
					return;
				}
				localPlayerController.DamagePlayer(_random.Next(3, 9), true, true, (CauseOfDeath)5, 0, false, default(Vector3));
				_nextCheck = currentTime + 500;
				PlayCoughAudio(currentTime);
				SendPoisonWarning(currentTime);
			}
		}

		private void SendPoisonWarning(long currentTime)
		{
			if (PoisonPuffer.warningCoolDownEntry.Value > 0 && currentTime >= _nextWarning)
			{
				HUDManager.Instance.DisplayTip("WARNING", "Poisonous substance detected!", true, false, "LC_Tip1");
				_nextWarning = currentTime + PoisonPuffer.WarningCoolDown;
			}
		}

		private void PlayCoughAudio(long currentTime)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			if (PoisonPuffer.CoughVolume <= 0f)
			{
				return;
			}
			int? instanceId = _instanceId;
			if (instanceId.HasValue && Object.FindObjectFromInstanceID(_instanceId.Value) != null)
			{
				return;
			}
			GameObject val = new GameObject("TemporaryCoughAudio");
			_instanceId = ((Object)val).GetInstanceID();
			if (PoisonPuffer.coughAudioClips == null)
			{
				_nextCheck = currentTime + 1000;
				return;
			}
			int num = _random.Next(0, PoisonPuffer.coughAudioClips.Count);
			if (_PreviousCoughs.Contains(num))
			{
				_nextCheck = currentTime + 100;
				return;
			}
			if (_PreviousCoughs.Count >= 3)
			{
				_PreviousCoughs.RemoveAt(0);
			}
			_PreviousCoughs.Add(num);
			AudioClip val2 = PoisonPuffer.coughAudioClips[num];
			if (val2 == null)
			{
				_nextCheck = currentTime + 1000;
				return;
			}
			PoisonPuffer.Logger.LogDebug((object)$"Playing clip '{((Object)val2).name}' ({num})");
			AudioSource val3 = val.AddComponent<AudioSource>();
			val3.clip = val2;
			val3.volume = PoisonPuffer.CoughVolume;
			val3.Play();
			Object.Destroy((Object)(object)val, val2.length);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TestAccount666.PoisonPuffer";

		public const string PLUGIN_NAME = "PoisonPuffer";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace PoisonPuffer.Patches
{
	[HarmonyPatch]
	public class PufferAIPatch
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> TranspileShakeTailAnimation(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			PoisonPuffer.Logger.LogDebug((object)"Searching for Instantiate...");
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode != OpCodes.Call) && list[i].operand is MethodInfo methodInfo && methodInfo.Name == "Instantiate")
				{
					PoisonPuffer.Logger.LogDebug((object)"Found!");
					MethodInfo methodInfo2 = AccessTools.Method(typeof(PufferAIPatch), "AddPoisonTrigger", new Type[1] { typeof(GameObject) }, (Type[])null);
					PoisonPuffer.Logger.LogDebug((object)("Injecting method '" + methodInfo2?.ToString() + "'!"));
					list[i + 1] = new CodeInstruction(OpCodes.Call, (object)methodInfo2);
					break;
				}
			}
			return list.AsEnumerable();
		}

		public static void AddPoisonTrigger(GameObject gameObject)
		{
			PoisonPuffer.Logger.LogDebug((object)("Found object: " + (object)gameObject));
			gameObject.AddComponent<PoisonTrigger>();
		}

		[HarmonyPatch(typeof(PufferAI), "DoAIInterval")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> DoAIIntervalTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			FindDistancePattern(ref instructions);
			FindTimeSinceAlertPattern(ref instructions);
			return instructions;
		}

		private static void FindDistancePattern(ref IEnumerable<CodeInstruction> instructions)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			string[] array = new string[3] { "ldloc.2 NULL", "ldc.r4 5", "bge.un Label13" };
			int num = 0;
			for (int i = 0; i < list.Count(); i++)
			{
				CodeInstruction val = list[i];
				if (!((object)val).ToString().Equals(array[num]))
				{
					num = 0;
					continue;
				}
				num++;
				if (num >= 2)
				{
					list[i] = new CodeInstruction(OpCodes.Ldc_R4, (object)10f);
					num = 0;
					PoisonPuffer.Logger.LogDebug((object)"Found distance!");
				}
			}
			instructions = list;
		}

		private static void FindTimeSinceAlertPattern(ref IEnumerable<CodeInstruction> instructions)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			string[] array = new string[3] { "ldfld float PufferAI::timeSinceAlert", "ldc.r4 1.5", "ble.un Label15" };
			int num = 0;
			for (int i = 0; i < list.Count(); i++)
			{
				CodeInstruction val = list[i];
				if (!((object)val).ToString().Equals(array[num]))
				{
					num = 0;
					continue;
				}
				num++;
				if (num >= 2)
				{
					list[i] = new CodeInstruction(OpCodes.Ldc_R4, (object)0.75f);
					num = 0;
					PoisonPuffer.Logger.LogDebug((object)"Found timeSinceAlert!");
				}
			}
			instructions = list;
		}
	}
}