using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using Enemies;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using Player;
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(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("GTFartO")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2b702fd92416c85b3e9aee5eb57f9ac455f122af")]
[assembly: AssemblyProduct("GTFartO")]
[assembly: AssemblyTitle("GTFartO")]
[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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace GTFartO
{
public class PlayerFart : MonoBehaviour
{
[HarmonyPatch(typeof(PUI_GameEventLog), "AddLogItem")]
internal class ChatMsgReceivedEvent
{
private static void Prefix(string log, eGameEventChatLogType type)
{
instance.ChatMsgReceived(log);
}
}
[HarmonyPatch(typeof(PlayerLocomotion), "ChangeState")]
internal class InjectPLOCEvents
{
private static void Postfix(PlayerLocomotion __instance, PLOC_State state, bool wasWarpedIntoState = false)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
if (((Agent)__instance.m_owner).IsLocallyOwned)
{
instance.OnPlayerJumpFarted(state);
instance.OnCrouchInput(state);
}
}
}
[HarmonyPatch(typeof(LocalPlayerAgent), "Update")]
internal class InjectLocalPlayerAgentHeartbeat
{
private static void Postfix(LocalPlayerAgent __instance)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Expected O, but got Unknown
if ((Object)(object)fartobj == (Object)null)
{
fartobj = new GameObject("PlayerFarts");
PlayerFart playerFart = fartobj.AddComponent<PlayerFart>();
playerFart.Setup();
}
}
}
public static PlayerFart instance;
public static GameObject fartobj;
public static float fartDelay = 260f;
public static float wakeUpRange = 12f;
public static int fartDelayRandom = 0;
public static int autoFart = 4;
public static float fartTimer = 0f;
public static bool canFart = false;
public static bool allowAutoFart = true;
public static List<AudioClip> clipsFart;
private PLOC_State m_lastLocState;
private PLOC_State m_lastLocStateCrouch;
public static PlayerChatManager m_chatManager;
private GameObject audioListener;
public static LocalPlayerAgent m_currentPlayerAgentRef;
public static bool inLevel = false;
public static Random rndPlayerFart = new Random();
public PlayerFart(IntPtr value)
: base(value)
{
}
private void LateUpdate()
{
CheckGameState();
if (inLevel)
{
CheckComponents();
FartLogic();
}
}
private void CheckGameState()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Invalid comparison between Unknown and I4
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Invalid comparison between Unknown and I4
eGameStateName currentStateName = GameStateManager.CurrentStateName;
if ((int)currentStateName != 10 && (Object)(object)m_chatManager != (Object)null)
{
ManualDestroy();
inLevel = false;
}
if ((int)currentStateName == 10)
{
inLevel = true;
}
}
public void Setup()
{
if ((Object)(object)instance == (Object)null)
{
instance = this;
}
resetClips();
GetClipsFromFolder("Farts", clipsFart);
canFart = false;
fartTimer = 0f;
}
private void FartLogic()
{
if (fartDelayRandom == 0)
{
fartDelayRandom = rndPlayerFart.Next((int)Math.Ceiling(fartDelay / 2f), (int)fartDelay);
}
if (fartTimer >= (float)fartDelayRandom)
{
canFart = true;
if (allowAutoFart)
{
allowAutoFart = false;
int num = rndPlayerFart.Next(1, autoFart + 1);
if (num == autoFart)
{
SendChatMessage();
}
}
}
else
{
fartTimer += Time.deltaTime;
}
}
private void CheckComponents()
{
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)m_currentPlayerAgentRef == (Object)null)
{
FPSCamera val = Object.FindObjectOfType<FPSCamera>();
if ((Object)(object)val != (Object)null)
{
m_currentPlayerAgentRef = val.m_owner;
}
}
if ((Object)(object)audioListener == (Object)null)
{
audioListener = GameObject.Find("GLOBAL/Managers/Chat/DissonanceSetup");
}
if ((Object)(object)audioListener != (Object)null && (Object)(object)m_currentPlayerAgentRef != (Object)null)
{
audioListener.transform.position = ((Component)((PlayerAgent)m_currentPlayerAgentRef).FPSCamera).transform.position;
}
if (!Object.op_Implicit((Object)(object)m_chatManager))
{
m_chatManager = PlayerChatManager.Current;
}
if (clipsFart.Count <= 0)
{
return;
}
bool flag = false;
foreach (AudioClip item in clipsFart)
{
if ((Object)(object)item == (Object)null)
{
flag = true;
}
}
if (flag)
{
resetClips();
GetClipsFromFolder("Farts", clipsFart);
}
}
private void resetClips()
{
clipsFart = new List<AudioClip>();
}
private void GetClipsFromFolder(string folder, List<AudioClip> clipsList)
{
DirectoryInfo directoryInfo = new DirectoryInfo(Paths.BepInExRootPath + "/Assets/streamingAssets/" + folder);
FileInfo[] files = directoryInfo.GetFiles("*.*");
FileInfo[] array = files;
foreach (FileInfo clipFile in array)
{
CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ConvertFilesToAudioClip(clipFile, clipsList)), (Action)null);
}
}
private IEnumerator ConvertFilesToAudioClip(FileInfo clipFile, List<AudioClip> list)
{
string songName = clipFile.FullName.ToString();
string url = $"file://{songName}";
WWW www = new WWW(url);
yield return www;
list.Add(www.GetAudioClip(false, false));
}
public void PlayFart(Vector3 position, int clipNumber)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
AudioClip val = clipsFart[clipNumber];
AudioSource.PlayClipAtPoint(val, position, 1f);
}
public static void SendChatMessage()
{
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
if (canFart && Object.op_Implicit((Object)(object)m_chatManager) && Object.op_Implicit((Object)(object)m_currentPlayerAgentRef) && Object.op_Implicit((Object)(object)((PlayerAgent)m_currentPlayerAgentRef).FPSCamera))
{
fartTimer = 0f;
canFart = false;
allowAutoFart = true;
fartDelayRandom = rndPlayerFart.Next((int)Math.Ceiling(fartDelay / 3f), (int)fartDelay);
int num = rndPlayerFart.Next(0, clipsFart.Count);
Vector3 position = ((Component)((PlayerAgent)m_currentPlayerAgentRef).FPSCamera).transform.position;
string text = ((object)(Vector3)(ref position)).ToString();
string text2 = string.Join("_", string.Join("", text.Split('(', ' ', ')')).Split(','));
string currentValue = "error_frt_" + text2 + "_" + num;
m_chatManager.m_currentValue = currentValue;
m_chatManager.PostMessage();
((MonoBehaviour)instance).StartCoroutine("wakeUpEnemy");
}
}
public void ChatMsgReceived(string msg)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
string[] array = msg.Split("error_frt_")[1].Split("_");
Vector3 position = default(Vector3);
position.x = Convert.ToSingle(array[0], CultureInfo.InvariantCulture);
position.y = Convert.ToSingle(array[1], CultureInfo.InvariantCulture);
position.z = Convert.ToSingle(array[2], CultureInfo.InvariantCulture);
if (array.Length == 4)
{
PlayFart(position, int.Parse(array[3]));
}
}
public void OnPlayerJumpFarted(PLOC_State state)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Invalid comparison between Unknown and I4
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Invalid comparison between Unknown and I4
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if (((int)m_lastLocState == 4 || (int)m_lastLocState == 3) && ((int)state == 0 || (int)state == 1))
{
SendChatMessage();
}
m_lastLocState = state;
}
private void OnCrouchInput(PLOC_State state)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if (((int)m_lastLocStateCrouch == 0 && (int)state == 1) || ((int)m_lastLocStateCrouch == 1 && (int)state == 0))
{
SendChatMessage();
}
m_lastLocStateCrouch = state;
}
public void wakeUpEnemy()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
EnemyLocomotion val = null;
Il2CppArrayBase<EnemyLocomotion> val2 = Object.FindObjectsOfType<EnemyLocomotion>();
foreach (EnemyLocomotion item in val2)
{
if (((Component)item).gameObject.active && (int)item.CurrentStateEnum != 11 && (int)item.CurrentStateEnum == 14)
{
if ((Object)(object)val == (Object)null)
{
val = item;
}
else if (Vector3.Distance(((Component)item).gameObject.transform.position, ((Component)((PlayerAgent)m_currentPlayerAgentRef).FPSCamera).transform.position) < Vector3.Distance(((Component)val).gameObject.transform.position, ((Component)((PlayerAgent)m_currentPlayerAgentRef).FPSCamera).transform.position))
{
val = item;
}
}
}
if ((Object)(object)val != (Object)null && Vector3.Distance(((Component)val).gameObject.transform.position, ((Component)((PlayerAgent)m_currentPlayerAgentRef).FPSCamera).transform.position) < wakeUpRange)
{
val.HibernateWakeup.ActivateState(((Component)val).gameObject.transform.position, 1f, 0.5f, true);
}
}
public static void ManualDestroy()
{
if ((Object)(object)instance != (Object)null)
{
Debug.LogWarning(Object.op_Implicit("Farts destroyed"));
m_chatManager = null;
m_currentPlayerAgentRef = null;
instance.audioListener = null;
}
}
}
[BepInPlugin("com.astien.dteyn.gtfarto", "GTFartO by Astien and Dteyn", "1.0.0")]
public class Plugin : BasePlugin
{
internal static ManualLogSource Log;
public static ConfigFile config;
public override void Load()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
Log = ((BasePlugin)this).Log;
Log.LogInfo((object)"Plugin com.astien.dteyn.gtfarto is loaded!");
config = ((BasePlugin)this).Config;
ClassInjector.RegisterTypeInIl2Cpp<PlayerFart>();
ConfigFarts.InitConfigVars();
Harmony val = new Harmony("com.astien.dteyn.gtfarto");
val.PatchAll();
}
}
public static class ConfigFarts
{
public static ConfigEntry<float> fartDelay;
public static ConfigEntry<float> wakeUpRange;
public static ConfigEntry<int> autoFart;
public static void InitConfigVars()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
fartDelay = Plugin.config.Bind<float>("General", "fartDelay", 260f, new ConfigDescription("Max interval in seconds between a possible fart, default is 260 seconds", (AcceptableValueBase)null, Array.Empty<object>()));
wakeUpRange = Plugin.config.Bind<float>("General", "wakeUpRange", 15f, new ConfigDescription("Radius for a fart to wake up enemies, in meters, defaut is 15.0", (AcceptableValueBase)null, Array.Empty<object>()));
autoFart = Plugin.config.Bind<int>("General", "autoFart", 4, new ConfigDescription("Farts have one chance out of autoFart to trigger automatically when reaching time limit. Default is 4", (AcceptableValueBase)null, Array.Empty<object>()));
PlayerFart.autoFart = autoFart.Value;
PlayerFart.fartDelay = fartDelay.Value;
PlayerFart.wakeUpRange = wakeUpRange.Value;
}
}
}