Decompiled source of LooseJesterSpring v1.0.5

LooseJesterSpring.dll

Decompiled 2 months ago
#define DEBUG
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 System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LooseJesterSpring.Patches;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
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.LooseJesterSpring")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("The spring that's holding the Jester shut is a little loose")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5")]
[assembly: AssemblyProduct("LooseJesterSpring")]
[assembly: AssemblyTitle("TestAccount666.LooseJesterSpring")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.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 LooseJesterSpring
{
	public class ConfigManager
	{
		internal ConfigEntry<int> popChance = null;

		internal ConfigEntry<int> volume = null;

		internal ConfigEntry<bool> enableSound = null;

		internal void Setup(ConfigFile configFile)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			popChance = configFile.Bind<int>("General", "1. Pop Chance", 100, new ConfigDescription("A chance in percent that the jester will pop upon hit", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			enableSound = configFile.Bind<bool>("Sound", "1. Enable Sound", true, "If true, will play a sound upon hitting the jester (Requires LCSoundTool to be installed)");
			volume = configFile.Bind<int>("Sound", "2. Volume", 100, new ConfigDescription("The volume the sound will be playing", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
		}
	}
	internal class DependencyChecker
	{
		internal static bool IsSoundToolInstalled()
		{
			return Chainloader.PluginInfos.Values.Any((PluginInfo metadata) => metadata.Metadata.GUID.Contains("LCSoundTool"));
		}
	}
	[BepInPlugin("TestAccount666.LooseJesterSpring", "LooseJesterSpring", "1.0.5")]
	public class LooseJesterSpring : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <LoadSound>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private string <assemblyDirectory>5__1;

			private string <filePath>5__2;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<assemblyDirectory>5__1 = null;
				<filePath>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				<assemblyDirectory>5__1 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				Debug.Assert(<assemblyDirectory>5__1 != null, "assemblyDirectory != null");
				<filePath>5__2 = Path.Combine(<assemblyDirectory>5__1, "fool.wav");
				audioClip = LoadAudioClipFromFile(new Uri(<filePath>5__2), "fool.wav");
				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 AudioClip? audioClip;

		internal static ConfigManager configManager = null;

		internal static Random syncedRandom = new Random();

		public static LooseJesterSpring Instance { get; private set; } = null;


		internal static ManualLogSource Logger { get; private set; } = null;


		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			configManager = new ConfigManager();
			configManager.Setup(((BaseUnityPlugin)this).Config);
			if (configManager.enableSound.Value)
			{
				((MonoBehaviour)this).StartCoroutine(LoadSound());
			}
			Patch();
			Logger.LogInfo((object)"TestAccount666.LooseJesterSpring v1.0.5 has loaded!");
		}

		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.LooseJesterSpring");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll(typeof(EnemyAIPatch));
			Harmony.PatchAll(typeof(RoundManagerPatch));
			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!");
		}

		[IteratorStateMachine(typeof(<LoadSound>d__18))]
		private static IEnumerator LoadSound()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadSound>d__18(0);
		}

		private static AudioClip? LoadAudioClipFromFile(Uri filePath, string name)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			UnityWebRequest val = UnityWebRequestMultimedia.GetAudioClip(filePath, (AudioType)20);
			try
			{
				UnityWebRequestAsyncOperation val2 = val.SendWebRequest();
				while (!((AsyncOperation)val2).isDone)
				{
					Thread.Sleep(100);
				}
				if ((int)val.result != 1)
				{
					Logger.LogError((object)("Failed to load AudioClip: " + val.error));
					return null;
				}
				AudioClip content = DownloadHandlerAudioClip.GetContent(val);
				((Object)content).name = name;
				return content;
			}
			finally
			{
				((IDisposable)val)?.Dispose();
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TestAccount666.LooseJesterSpring";

		public const string PLUGIN_NAME = "LooseJesterSpring";

		public const string PLUGIN_VERSION = "1.0.5";
	}
}
namespace LooseJesterSpring.Patches
{
	[HarmonyPatch(typeof(EnemyAI))]
	public static class EnemyAIPatch
	{
		[CompilerGenerated]
		private sealed class <PopJester>d__2 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public EnemyAI enemyAI;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Expected O, but got Unknown
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					EnemyAI obj5 = enemyAI;
					if (obj5 != null && obj5.currentBehaviourStateIndex >= 2)
					{
						return false;
					}
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				case 1:
				{
					<>1__state = -1;
					LooseJesterSpring.Logger.LogDebug((object)"State 1!");
					EnemyAI obj3 = enemyAI;
					if (obj3 != null)
					{
						obj3.SwitchToBehaviourStateOnLocalClient(1);
					}
					EnemyAI obj4 = enemyAI;
					if (obj4 != null)
					{
						obj4.SwitchToBehaviourClientRpc(1);
					}
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 2;
					return true;
				}
				case 2:
				{
					<>1__state = -1;
					LooseJesterSpring.Logger.LogDebug((object)"State 2!");
					EnemyAI obj = enemyAI;
					if (obj != null)
					{
						obj.SwitchToBehaviourStateOnLocalClient(2);
					}
					EnemyAI obj2 = enemyAI;
					if (obj2 != null)
					{
						obj2.SwitchToBehaviourClientRpc(2);
					}
					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();
			}
		}

		[HarmonyPatch("HitEnemyServerRpc")]
		[HarmonyPostfix]
		private static void JesterHitClientPostfix(EnemyAI __instance, int playerWhoHit)
		{
			HandleJesterPop(__instance, playerWhoHit);
		}

		private static void HandleJesterPop(EnemyAI? enemyAI, int playerWhoHit)
		{
			ManualLogSource logger = LooseJesterSpring.Logger;
			object obj;
			if (enemyAI == null)
			{
				obj = null;
			}
			else
			{
				EnemyType enemyType = enemyAI.enemyType;
				obj = ((enemyType != null) ? ((Object)enemyType).name : null);
			}
			logger.LogDebug((object)("Enemy was hit: " + (string?)obj));
			if (playerWhoHit <= -1)
			{
				LooseJesterSpring.Logger.LogDebug((object)"Not hit by a player!");
			}
			else if (enemyAI is JesterAI && ((NetworkBehaviour)enemyAI).IsHost)
			{
				LooseJesterSpring.Logger.LogDebug((object)"Enemy was Jester!");
				int num = LooseJesterSpring.syncedRandom.Next(0, 100);
				LooseJesterSpring.Logger.LogDebug((object)$"Rolled chance '{num}'/'{LooseJesterSpring.configManager.popChance.Value}'!");
				if (num <= LooseJesterSpring.configManager.popChance.Value)
				{
					LooseJesterSpring.Logger.LogDebug((object)"Pop!");
					PlayAudio(((Component)enemyAI).gameObject);
					((MonoBehaviour)enemyAI).StartCoroutine(PopJester(enemyAI));
				}
			}
		}

		[IteratorStateMachine(typeof(<PopJester>d__2))]
		private static IEnumerator PopJester(EnemyAI? enemyAI)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PopJester>d__2(0)
			{
				enemyAI = enemyAI
			};
		}

		private static void PlayAudio(GameObject jesterGameObject)
		{
			if (LooseJesterSpring.audioClip != null)
			{
				AudioSource val = jesterGameObject.AddComponent<AudioSource>();
				val.spatialBlend = 1f;
				val.maxDistance = 100f;
				val.rolloffMode = (AudioRolloffMode)0;
				val.clip = LooseJesterSpring.audioClip;
				val.volume = (float)LooseJesterSpring.configManager.volume.Value / 100f;
				val.Play();
				Object.Destroy((Object)(object)val, LooseJesterSpring.audioClip.length);
			}
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	public static class RoundManagerPatch
	{
		[HarmonyPatch("GenerateNewLevelClientRpc")]
		[HarmonyPostfix]
		public static void AfterGenerateNewLevelClientRpc()
		{
			LooseJesterSpring.syncedRandom = new Random(StartOfRound.Instance.randomMapSeed);
		}
	}
}