Decompiled source of F A R T v1.0.3

F_A_R_T_.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using REPOLib.Modules;
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: AssemblyTitle("F_A_R_T_")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("F_A_R_T_")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("cfb62718-d9da-4177-8164-ca1e9fe25982")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.3.0")]
[BepInPlugin("com.HalHally.f_a_r_t_", "F.A.R.T.", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class FartMod : BaseUnityPlugin
{
	public class PlayerStateTracker : MonoBehaviour
	{
		public bool lastSliding;

		public bool lastSprinting;

		public bool lastCrouching;

		public bool lastTumbling;

		public bool lastJumpImpulse;
	}

	[HarmonyPatch(typeof(PlayerController), "Update")]
	public static class JumpMonitorPatch
	{
		private static void Postfix(PlayerController __instance)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance.playerAvatarScript == (Object)null) && __instance.playerAvatarScript.photonView.IsMine)
			{
				bool flag = JumpImpulseRef.Invoke(__instance);
				PlayerStateTracker tracker = GetTracker(__instance);
				if (flag && !tracker.lastJumpImpulse)
				{
					TryFart(((Component)__instance).transform.position, JumpEnabled.Value, JumpChance.Value);
				}
				tracker.lastJumpImpulse = flag;
			}
		}
	}

	[HarmonyPatch(typeof(PlayerController), "ChangeState")]
	public static class ActionMonitorPatch
	{
		private static void Postfix(PlayerController __instance)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance.playerAvatarScript == (Object)null) && __instance.playerAvatarScript.photonView.IsMine)
			{
				PlayerStateTracker tracker = GetTracker(__instance);
				bool flag = IsTumblingRef.Invoke(__instance.playerAvatarScript);
				if (flag && !tracker.lastTumbling)
				{
					TryFart(((Component)__instance).transform.position, TumbleEnabled.Value, TumbleChance.Value);
				}
				if (__instance.Sliding && !tracker.lastSliding)
				{
					TryFart(((Component)__instance).transform.position, SlidingEnabled.Value, SlidingChance.Value);
				}
				if (__instance.sprinting && !tracker.lastSprinting)
				{
					TryFart(((Component)__instance).transform.position, SprintEnabled.Value, SprintChance.Value);
				}
				if (__instance.Crouching && !tracker.lastCrouching)
				{
					TryFart(((Component)__instance).transform.position, CrouchEnabled.Value, CrouchChance.Value);
				}
				tracker.lastTumbling = flag;
				tracker.lastSliding = __instance.Sliding;
				tracker.lastSprinting = __instance.sprinting;
				tracker.lastCrouching = __instance.Crouching;
			}
		}
	}

	[CompilerGenerated]
	private sealed class <LoadFartSound>d__28 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string path;

		public FartMod <>4__this;

		private UnityWebRequest <www>5__1;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			int num = <>1__state;
			if (num == -3 || num == 1)
			{
				try
				{
				}
				finally
				{
					<>m__Finally1();
				}
			}
			<www>5__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			try
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<www>5__1 = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, (AudioType)13);
					<>1__state = -3;
					<>2__current = <www>5__1.SendWebRequest();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -3;
					if ((int)<www>5__1.result == 1)
					{
						FartClips.Add(DownloadHandlerAudioClip.GetContent(<www>5__1));
					}
					<>m__Finally1();
					<www>5__1 = null;
					return false;
				}
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
		}

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

		private void <>m__Finally1()
		{
			<>1__state = -1;
			if (<www>5__1 != null)
			{
				((IDisposable)<www>5__1).Dispose();
			}
		}

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

	public static List<AudioClip> FartClips = new List<AudioClip>();

	private static float _lastFartTime;

	public static ConfigEntry<int> MasterVolume;

	public static ConfigEntry<bool> RandomPitchEnabled;

	public static ConfigEntry<float> PitchVariation;

	public static ConfigEntry<bool> TumbleEnabled;

	public static ConfigEntry<bool> JumpEnabled;

	public static ConfigEntry<bool> SlidingEnabled;

	public static ConfigEntry<bool> SprintEnabled;

	public static ConfigEntry<bool> CrouchEnabled;

	public static ConfigEntry<int> TumbleChance;

	public static ConfigEntry<int> JumpChance;

	public static ConfigEntry<int> SlidingChance;

	public static ConfigEntry<int> SprintChance;

	public static ConfigEntry<int> CrouchChance;

	public static NetworkedEvent FartNetworkEvent;

	internal static ManualLogSource Logger;

	private static readonly FieldRef<PlayerController, bool> JumpImpulseRef = AccessTools.FieldRefAccess<PlayerController, bool>("JumpImpulse");

	private static readonly FieldRef<PlayerAvatar, bool> IsTumblingRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isTumbling");

	private void Awake()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		Logger = ((BaseUnityPlugin)this).Logger;
		InitConfig();
		LoadAudioFiles();
		new Harmony("com.HalHally.f_a_r_t_").PatchAll();
		FartNetworkEvent = new NetworkedEvent("FartEvent_UniqueKey", (Action<EventData>)OnFartReceived);
	}

	public static void TryFart(Vector3 pos, bool enabled, int chance)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		if (enabled && PhotonNetwork.InRoom && !(Time.time - _lastFartTime < 0.1f) && Random.Range(0, 100) < chance)
		{
			_lastFartTime = Time.time;
			FartNetworkEvent.RaiseEvent((object)new object[2]
			{
				pos,
				PhotonNetwork.LocalPlayer.ActorNumber
			}, NetworkingEvents.RaiseAll, SendOptions.SendReliable);
		}
	}

	private static void OnFartReceived(EventData photonEvent)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		object[] array = (object[])photonEvent.CustomData;
		PlayLocalFartSound((Vector3)array[0]);
		AlertNearbyEnemies((Vector3)array[0], (int)array[1]);
	}

	private static void PlayLocalFartSound(Vector3 pos)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		if (FartClips.Count != 0 && !((Object)(object)AudioManager.instance == (Object)null))
		{
			GameObject val = Object.Instantiate<GameObject>(AudioManager.instance.AudioDefault, pos + Vector3.up * 1.2f, Quaternion.identity);
			try
			{
				Utilities.FixAudioMixerGroups(val);
			}
			catch
			{
			}
			AudioSource val2 = val.GetComponent<AudioSource>() ?? val.AddComponent<AudioSource>();
			AudioClip val4 = (val2.clip = FartClips[Random.Range(0, FartClips.Count)]);
			val2.volume = (float)MasterVolume.Value / 100f;
			if (val2.spatialBlend > 0f)
			{
				val2.minDistance = Mathf.Max(val2.minDistance, 3f);
			}
			if (RandomPitchEnabled.Value)
			{
				val2.pitch = Mathf.Clamp(1f + Random.Range(0f - PitchVariation.Value, PitchVariation.Value), 0.2f, 1.8f);
			}
			if ((Object)(object)AudioManager.instance.SoundsParent != (Object)null)
			{
				val.transform.SetParent(AudioManager.instance.SoundsParent);
			}
			val2.Play();
			Object.Destroy((Object)(object)val, val4.length + 0.5f);
		}
	}

	public static void AlertNearbyEnemies(Vector3 fartPosition, int actorNumber)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		if (!SemiFunc.IsMasterClientOrSingleplayer())
		{
			return;
		}
		EnemyHunter[] array = Object.FindObjectsOfType<EnemyHunter>();
		foreach (EnemyHunter val in array)
		{
			if (Vector3.Distance(fartPosition, ((Component)val).transform.position) > 20f)
			{
				continue;
			}
			try
			{
				AccessTools.Field(typeof(EnemyHunter), "shootFast").SetValue(val, true);
				AccessTools.Field(typeof(EnemyHunter), "investigatePoint").SetValue(val, fartPosition);
				AccessTools.Field(typeof(EnemyHunter), "investigatePathfindOnly").SetValue(val, false);
				AccessTools.Method(typeof(EnemyHunter), "InvestigateTransformGet", (Type[])null, (Type[])null).Invoke(val, null);
				PhotonView val2 = (PhotonView)AccessTools.Field(typeof(EnemyHunter), "photonView").GetValue(val);
				if (SemiFunc.IsMultiplayer() && (Object)(object)val2 != (Object)null)
				{
					val2.RPC("UpdateInvestigationPoint", (RpcTarget)1, new object[1] { fartPosition });
				}
				AccessTools.Method(typeof(EnemyHunter), "UpdateState", (Type[])null, (Type[])null).Invoke(val, new object[1] { (object)(State)3 });
			}
			catch (Exception ex)
			{
				Logger.LogError((object)ex.Message);
			}
		}
	}

	private static PlayerStateTracker GetTracker(PlayerController pc)
	{
		PlayerStateTracker component = ((Component)pc).GetComponent<PlayerStateTracker>();
		return Object.op_Implicit((Object)(object)component) ? component : ((Component)pc).gameObject.AddComponent<PlayerStateTracker>();
	}

	private void InitConfig()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Expected O, but got Unknown
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Expected O, but got Unknown
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Expected O, but got Unknown
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Expected O, but got Unknown
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Expected O, but got Unknown
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Expected O, but got Unknown
		MasterVolume = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Volume", 100, new ConfigDescription("Volume", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		TumbleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Tumble", "Enabled", true, (ConfigDescription)null);
		TumbleChance = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble", "FartRate", 20, new ConfigDescription("Chance of farting when tumbling", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		JumpEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Jump", "Enabled", true, (ConfigDescription)null);
		JumpChance = ((BaseUnityPlugin)this).Config.Bind<int>("Jump", "FartRate", 5, new ConfigDescription("Chance of farting when jumping", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		SlidingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Sliding", "Enabled", true, (ConfigDescription)null);
		SlidingChance = ((BaseUnityPlugin)this).Config.Bind<int>("Sliding", "FartRate", 15, new ConfigDescription("Chance of farting when sliding", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		SprintEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Sprint", "Enabled", false, (ConfigDescription)null);
		SprintChance = ((BaseUnityPlugin)this).Config.Bind<int>("Sprint", "FartRate", 5, new ConfigDescription("Chance of farting while sprinting", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		CrouchEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Crouch", "Enabled", true, (ConfigDescription)null);
		CrouchChance = ((BaseUnityPlugin)this).Config.Bind<int>("Crouch", "FartRate", 10, new ConfigDescription("Chance of farting when crouching", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		RandomPitchEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "RandomPitchEnabled", true, (ConfigDescription)null);
		PitchVariation = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "PitchVariation", 0.5f, new ConfigDescription("Pitch variation range", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
	}

	private void LoadAudioFiles()
	{
		string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		string[] files = Directory.GetFiles(directoryName, "*.mp3");
		foreach (string path in files)
		{
			((MonoBehaviour)this).StartCoroutine(LoadFartSound(path));
		}
	}

	[IteratorStateMachine(typeof(<LoadFartSound>d__28))]
	private IEnumerator LoadFartSound(string path)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <LoadFartSound>d__28(0)
		{
			<>4__this = this,
			path = path
		};
	}
}