using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Mirror;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Networking;
using UnityEngine.Playables;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FartMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FartMod")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9955ca6d-c427-470f-80ed-9c0c104267e2")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FartMod;
public static class AssetUtils
{
private static void Log(string message)
{
FartModCore.Log(message);
}
private static bool IsInvalidPath(string path)
{
return path.EndsWith(".txt") || !path.Contains(".");
}
public static T GetWebRequest<T>(Func<UnityWebRequest> webRequest) where T : DownloadHandler
{
try
{
UnityWebRequest val = webRequest();
val.SendWebRequest();
while (!val.isDone)
{
}
if (val != null)
{
DownloadHandler downloadHandler = val.downloadHandler;
if (downloadHandler != null && downloadHandler is T)
{
return (T)(object)downloadHandler;
}
}
else
{
Log("www is null " + val.url);
}
}
catch
{
}
return default(T);
}
public static string GetWebRequestPath(string path)
{
Log("path: " + path);
path = "file:///" + path.Replace("\\", "/");
return path;
}
public static AssetBundle LoadAssetBundleFromWebRequest(string path)
{
if (IsInvalidPath(path))
{
return null;
}
path = GetWebRequestPath(path);
DownloadHandlerAssetBundle webRequest = AssetUtils.GetWebRequest<DownloadHandlerAssetBundle>((Func<UnityWebRequest>)(() => UnityWebRequestAssetBundle.GetAssetBundle(path)));
if (webRequest != null)
{
return webRequest.assetBundle;
}
return null;
}
public static AssetBundle LoadAssetBundle(string bundlePath)
{
string text = Path.Combine(Paths.PluginPath, bundlePath);
if (!File.Exists(text))
{
return null;
}
return AssetBundle.LoadFromFile(text);
}
public static AudioClip LoadAudioFromWebRequest(string path, AudioType audioType)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (IsInvalidPath(path))
{
return null;
}
path = GetWebRequestPath(path);
DownloadHandlerAudioClip webRequest = AssetUtils.GetWebRequest<DownloadHandlerAudioClip>((Func<UnityWebRequest>)(() => UnityWebRequestMultimedia.GetAudioClip(path, audioType)));
if (webRequest != null)
{
return webRequest.audioClip;
}
return null;
}
public static List<AudioClip> PreloadAudioClips(string folderName)
{
List<AudioClip> list = new List<AudioClip>();
Log("Checking Sounds");
string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), folderName);
if (Directory.Exists(text))
{
list.Clear();
CollectAudioFiles(text);
}
else
{
Log("Directory " + text + " does not exist! Creating.");
Directory.CreateDirectory(text);
}
return list;
}
private static List<AudioClip> CollectAudioFiles(string path)
{
List<AudioClip> list = new List<AudioClip>();
Log("checking folder " + Path.GetFileName(path));
string[] files = Directory.GetFiles(path);
string[] array = files;
foreach (string path2 in array)
{
Log("\tchecking single file " + Path.GetFileName(path2));
AudioClip val = LoadAudioFromWebRequest(path2, (AudioType)0);
if (Object.op_Implicit((Object)(object)val))
{
list.Add(val);
}
}
return list;
}
}
internal static class Configuration
{
public static ConfigEntry<float> FartVolume;
public static ConfigEntry<float> FartParticleSize;
public static ConfigEntry<float> JiggleIntensity;
public static ConfigEntry<string> FartParticleStartColors;
public static ConfigEntry<string> FartParticleEndColors;
public static ConfigEntry<float> GlobalFartVolume;
public static ConfigEntry<bool> FartChaos;
internal static void BindConfiguration()
{
FartVolume = FartModCore.GetConfig().Bind<float>("Fart Effects", "FartVolume", 0.08f, "The volume of your character's farts");
FartParticleSize = FartModCore.GetConfig().Bind<float>("Fart Effects", "FartParticleSize", 0.075f, "The size of the fart particle effect.");
JiggleIntensity = FartModCore.GetConfig().Bind<float>("Fart Effects", "JiggleIntensity", 1f, "Multiplier for how intense your butt jiggles from farts.");
string text = "CFFF4E, 77F131, 349300";
FartParticleStartColors = FartModCore.GetConfig().Bind<string>("Fart Effects", "FartParticleStartColors", text, "Start color of fart particles.");
string text2 = "CFFF4E, DCFF40, 92B204";
FartParticleEndColors = FartModCore.GetConfig().Bind<string>("Fart Effects", "FartParticleEndColors", text2, "End color of fart particles.");
FartChaos = FartModCore.GetConfig().Bind<bool>("Global", "FartChaos", false, "Make ALL multiplayer characters fart when they chat.");
GlobalFartVolume = FartModCore.GetConfig().Bind<float>("Global", "GlobalFartVolume", 1f, "Volume of ALL multiplayer character farts.");
}
public static List<Color> GetStartColors()
{
return GetConfigColors(FartParticleStartColors);
}
public static List<Color> GetEndColors()
{
return GetConfigColors(FartParticleEndColors);
}
private static List<Color> GetConfigColors(ConfigEntry<string> config)
{
return GetColors(config.Value);
}
public static List<Color> GetColors(string config)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
config = config.Replace(" ", "");
List<string> list = config.Split(new char[1] { ',' }).ToList();
List<Color> list2 = new List<Color>();
foreach (string item in list)
{
list2.Add(FromHex(item));
}
return list2;
}
public static Color FromHex(string hex)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
if (hex.Length < 6)
{
Debug.LogError((object)"Needs a string with a length of at least 6");
return Color.green;
}
string s = hex.Substring(0, 2);
string s2 = hex.Substring(2, 2);
string s3 = hex.Substring(4, 2);
string s4 = ((hex.Length < 8) ? "FF" : hex.Substring(6, 2));
return new Color((float)int.Parse(s, NumberStyles.HexNumber) / 255f, (float)int.Parse(s2, NumberStyles.HexNumber) / 255f, (float)int.Parse(s3, NumberStyles.HexNumber) / 255f, (float)int.Parse(s4, NumberStyles.HexNumber) / 255f);
}
}
public class FartController : MonoBehaviour
{
public class CurrentAnimationMonitor
{
public Animator animator;
public int layer;
public AnimationClip currentClip;
public List<AnimationClip> clipsToIgnore = new List<AnimationClip>();
public CurrentAnimationMonitor(Animator animator, int layer)
{
this.animator = animator;
this.layer = layer;
currentClip = GetCurrentClip();
}
public AnimationClip GetCurrentClip()
{
AnimatorClipInfo[] currentAnimatorClipInfo = animator.GetCurrentAnimatorClipInfo(layer);
if (currentAnimatorClipInfo.Any())
{
return ((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip;
}
return null;
}
public string Debug()
{
string text = animator.GetLayerName(layer);
AnimationClip val = GetCurrentClip();
if (Object.op_Implicit((Object)(object)val))
{
text = text + " " + ((Object)val).name;
}
return text;
}
public bool IsDifferent()
{
AnimationClip val = GetCurrentClip();
if (clipsToIgnore.Contains(val))
{
return false;
}
return (Object)(object)currentClip != (Object)(object)val;
}
}
public static List<FartController> allFartControllers = new List<FartController>();
[Header("Components")]
public Player owner;
private AssetBundle bundle;
[Header("Fart Effects")]
private FartEffectsManager fartEffectsManager;
[Header("Animation Player")]
private PlayableAnimationPlayer animPlayer;
private void Awake()
{
if (!allFartControllers.Contains(this))
{
allFartControllers.Add(this);
}
}
private void OnDestroy()
{
allFartControllers.Remove(this);
}
private void Log(string message, bool force = false)
{
FartModCore.Log(message, force);
}
private AnimationClip GetAnimationClip(int index)
{
Player player = GetPlayer();
if (Object.op_Implicit((Object)(object)player))
{
Animator raceAnimator = player._pVisual._playerRaceModel._raceAnimator;
if (index < raceAnimator.runtimeAnimatorController.animationClips.Length)
{
return raceAnimator.runtimeAnimatorController.animationClips[index];
}
}
return null;
}
public void FartOneshot()
{
((MonoBehaviour)this).StopAllCoroutines();
Fart();
}
public void FartLoop()
{
PlayAnimation();
((MonoBehaviour)this).StartCoroutine(LoopFartRoutine());
((MonoBehaviour)this).StartCoroutine(StopLoopFartRoutine());
}
private IEnumerator LoopFartRoutine()
{
while (GetAnimationPlayer().currentClip == 0)
{
yield return null;
}
((MonoBehaviour)this).StartCoroutine(FartLoopInfiniteRoutine());
}
private void StopFartLoop()
{
((MonoBehaviour)this).StopAllCoroutines();
((Behaviour)GetAnimationPlayer()).enabled = false;
}
private Animator GetPlayerAnimator()
{
if (Object.op_Implicit((Object)(object)GetPlayer()))
{
return GetPlayer()._pVisual._visualAnimator;
}
return null;
}
private IEnumerator StopLoopFartRoutine()
{
GetPlayerAnimator();
List<CurrentAnimationMonitor> currentAnimationMonitors = new List<CurrentAnimationMonitor>();
if (Object.op_Implicit((Object)(object)GetPlayer()))
{
List<int> clipIndexes = new List<int> { 1 };
List<AnimationClip> clipsToIgnore = new List<AnimationClip>();
foreach (int j in clipIndexes)
{
AnimationClip clip = GetAnimationClip(j);
if (Object.op_Implicit((Object)(object)clip))
{
clipsToIgnore.Add(clip);
}
}
Animator playerAnim = GetPlayer()._pVisual._visualAnimator;
for (int i = 0; i < playerAnim.layerCount; i++)
{
if (i != 2 && i != 6 && i != 4)
{
currentAnimationMonitors.Add(new CurrentAnimationMonitor(playerAnim, i)
{
clipsToIgnore = clipsToIgnore
});
}
}
}
while (true)
{
if (!Object.op_Implicit((Object)(object)GetPlayer()))
{
StopFartLoop();
yield break;
}
if (!currentAnimationMonitors.Any())
{
Log("No monitors");
StopFartLoop();
yield break;
}
CurrentAnimationMonitor monitor = currentAnimationMonitors.Find((CurrentAnimationMonitor x) => x.IsDifferent());
if (monitor != null)
{
break;
}
yield return null;
}
StopFartLoop();
}
public void FartLoopInfinite()
{
((MonoBehaviour)this).StopAllCoroutines();
((MonoBehaviour)this).StartCoroutine(FartLoopInfiniteRoutine());
}
public void StopFarting()
{
((MonoBehaviour)this).StopAllCoroutines();
}
private void Fart()
{
GetFartEffectsManager().StartEffect();
}
private FartEffectsManager GetFartEffectsManager()
{
if (!Object.op_Implicit((Object)(object)fartEffectsManager))
{
fartEffectsManager = FartController.AddAndGetComponent<FartEffectsManager>(((Component)this).gameObject);
fartEffectsManager.owner = GetPlayer();
fartEffectsManager.Initialize(bundle);
}
return fartEffectsManager;
}
private PlayableAnimationPlayer GetAnimationPlayer()
{
if (!Object.op_Implicit((Object)(object)animPlayer))
{
animPlayer = FartController.AddAndGetComponent<PlayableAnimationPlayer>(((Component)this).gameObject);
((Behaviour)animPlayer).enabled = false;
}
return animPlayer;
}
private Player GetPlayer()
{
return owner;
}
private IEnumerator FartLoopInfiniteRoutine()
{
yield return (object)new WaitForSeconds(0.5f);
while (Object.op_Implicit((Object)(object)GetPlayer()))
{
Fart();
float delayTime = Random.Range(2f, 5f);
yield return (object)new WaitForSeconds(delayTime);
}
((MonoBehaviour)this).StopAllCoroutines();
}
private void PlayAnimation()
{
List<AnimationSequence> list = new List<AnimationSequence>();
AnimationClip animationClip = GetAnimationClip(77);
if (Object.op_Implicit((Object)(object)animationClip))
{
list.Add(new AnimationSequence(animationClip, infinite: false));
}
AnimationClip animationClip2 = GetAnimationClip(76);
if (Object.op_Implicit((Object)(object)animationClip2))
{
list.Add(new AnimationSequence(animationClip2, infinite: true));
}
PlayAnimation(list);
}
private void PlayAnimation(AnimationClip clip)
{
List<AnimationSequence> list = new List<AnimationSequence>();
list.Add(new AnimationSequence(clip, infinite: false));
PlayAnimation(list);
}
private void PlayAnimation(List<AnimationSequence> clips)
{
if (!clips.Any())
{
Log("No anim clip!");
return;
}
Player player = GetPlayer();
if (Object.op_Implicit((Object)(object)player))
{
Animator visualAnimator = player._pVisual._visualAnimator;
if (Object.op_Implicit((Object)(object)visualAnimator))
{
PlayableAnimationPlayer animationPlayer = GetAnimationPlayer();
if (Object.op_Implicit((Object)(object)animationPlayer))
{
animationPlayer.StartAnimating(visualAnimator, clips);
return;
}
Log("No anim player!");
}
Log("No animator on character!");
}
Log("No character!");
}
public void Initialize(AssetBundle bundle)
{
this.bundle = bundle;
GetFartEffectsManager();
GetAnimationPlayer();
}
public static T AddAndGetComponent<T>(GameObject gameObject) where T : Component
{
T val = gameObject.GetComponent<T>();
if (!Object.op_Implicit((Object)(object)val))
{
val = gameObject.AddComponent<T>();
}
return val;
}
public void SetOwner(Player owner, AssetBundle bundle)
{
this.owner = owner;
if (Object.op_Implicit((Object)(object)owner))
{
((Object)this).name = ((Object)this).name + " " + ((Object)owner).name;
((Component)this).transform.SetParent(((Component)owner).transform);
GetFartEffectsManager().SetTransform(((Component)this).transform);
}
Initialize(bundle);
}
}
public class FartEffectsManager : MonoBehaviour
{
private static List<AudioClip> sounds = new List<AudioClip>();
private static GameObject particleSystemPrefab;
public Player owner;
private AudioSource audioSource;
private ParticleSystem particleSystem;
private ParticleSystem gasParticle;
private bool effectPlaying;
private AssetBundle bundle;
private float counter;
private FartEffectsConfiguration configuration = new FartEffectsConfiguration();
public void Initialize(AssetBundle bundle)
{
this.bundle = bundle;
configuration = new FartEffectsConfiguration(this);
PreloadAudioClips();
GetParticleSystemPrefab();
GetAudioSource();
GetParticleSystem();
((Behaviour)this).enabled = false;
}
private GameObject GetParticleSystemPrefab()
{
if (!Object.op_Implicit((Object)(object)particleSystemPrefab))
{
particleSystemPrefab = bundle.LoadAsset<GameObject>("FartParticle");
}
return particleSystemPrefab;
}
private void PreloadAudioClips()
{
if (!sounds.Any())
{
Log("Checking Sounds");
string path = "Audio";
string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), path);
if (Directory.Exists(text))
{
sounds.Clear();
CollectAudioFiles(text);
}
else
{
Log("Directory " + text + " does not exist! Creating.");
Directory.CreateDirectory(text);
}
}
}
private void CollectAudioFiles(string path)
{
Log("checking folder " + Path.GetFileName(path));
string[] files = Directory.GetFiles(path);
string[] array = files;
foreach (string path2 in array)
{
Log("\tchecking single file " + Path.GetFileName(path2));
AudioClip val = AssetUtils.LoadAudioFromWebRequest(path2, (AudioType)0);
if (Object.op_Implicit((Object)(object)val))
{
sounds.Add(val);
}
}
}
private AudioSource GetAudioSource()
{
if (!Object.op_Implicit((Object)(object)audioSource))
{
audioSource = FartController.AddAndGetComponent<AudioSource>(((Component)this).gameObject);
}
if (Object.op_Implicit((Object)(object)audioSource))
{
audioSource.volume = configuration.GetVolume();
}
return audioSource;
}
private ParticleSystem GetParticleSystem()
{
if (!Object.op_Implicit((Object)(object)particleSystem))
{
particleSystem = ((Component)this).GetComponentInChildren<ParticleSystem>();
if (!Object.op_Implicit((Object)(object)particleSystem) && Object.op_Implicit((Object)(object)GetParticleSystemPrefab()))
{
particleSystem = Object.Instantiate<GameObject>(GetParticleSystemPrefab(), ((Component)this).transform).GetComponent<ParticleSystem>();
}
}
return particleSystem;
}
public void StartEffect()
{
counter = 0f;
int index = Random.Range(0, sounds.Count);
AudioClip clip = sounds[index];
GetAudioSource().clip = clip;
GetAudioSource().Play();
Player player = GetPlayer();
AudioSource val = GetAudioSource();
AudioSource componentInChildren = ((Component)player).GetComponentInChildren<AudioSource>();
if (Object.op_Implicit((Object)(object)componentInChildren))
{
val.spatialBlend = componentInChildren.spatialBlend;
}
((Behaviour)this).enabled = true;
}
private Vector3 AssDirection(Player player)
{
//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_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: 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_0052: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Vector3.zero;
DynamicBone[] assDynamicBones = player._pVisual._playerRaceModel._assDynamicBones;
foreach (DynamicBone val2 in assDynamicBones)
{
val += val2.m_Root.up;
}
return val / (float)assDynamicBones.Length;
}
private Vector3 AssPosition(Player player)
{
//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_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: 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_0052: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Vector3.zero;
DynamicBone[] assDynamicBones = player._pVisual._playerRaceModel._assDynamicBones;
foreach (DynamicBone val2 in assDynamicBones)
{
val += ((Component)val2).transform.position;
}
return val / (float)assDynamicBones.Length;
}
private Player GetPlayer()
{
return owner;
}
private void Log(string message, bool force = false)
{
FartModCore.Log(message, force);
}
private Gradient GetGradientColorKeys(List<Color> colors, Gradient gradient)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Expected O, but got Unknown
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
List<GradientColorKey> list = new List<GradientColorKey>();
GradientColorKey item = default(GradientColorKey);
for (int i = 0; i < gradient.colorKeys.Length; i++)
{
GradientColorKey val = gradient.colorKeys[i];
Color val2 = val.color;
if (colors.Any())
{
val2 = ((i >= colors.Count) ? colors[0] : colors[i]);
}
((GradientColorKey)(ref item))..ctor(val2, val.time);
list.Add(item);
}
Gradient val3 = new Gradient();
val3.SetKeys(list.ToArray(), gradient.alphaKeys);
return val3;
}
private ParticleSystem GetGasParticle()
{
if (!Object.op_Implicit((Object)(object)gasParticle))
{
gasParticle = ((Component)((Component)GetParticleSystem()).transform.Find("Gas")).GetComponent<ParticleSystem>();
}
return gasParticle;
}
private Gradient GetStartGradient()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
ColorOverLifetimeModule colorOverLifetime = GetGasParticle().colorOverLifetime;
MinMaxGradient color = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
return ((MinMaxGradient)(ref color)).gradientMax;
}
private Gradient GetEndGradient()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
ColorOverLifetimeModule colorOverLifetime = GetGasParticle().colorOverLifetime;
MinMaxGradient color = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
return ((MinMaxGradient)(ref color)).gradientMin;
}
private void SetEffectEnabled(bool b)
{
//IL_0049: 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_0055: Unknown result type (might be due to invalid IL or missing references)
((MonoBehaviour)this).StopAllCoroutines();
if (b)
{
List<Color> startColors = configuration.GetStartColors();
Gradient gradientColorKeys = GetGradientColorKeys(startColors, GetStartGradient());
List<Color> endColors = configuration.GetEndColors();
Gradient gradientColorKeys2 = GetGradientColorKeys(endColors, GetEndGradient());
ColorOverLifetimeModule colorOverLifetime = GetGasParticle().colorOverLifetime;
((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(gradientColorKeys2, gradientColorKeys);
((MonoBehaviour)this).StartCoroutine(EyeConditionRoutine());
((MonoBehaviour)this).StartCoroutine(JiggleRoutine());
}
else
{
GetAudioSource().Stop();
}
SetJiggleForce(0f);
SetParticleEnabled(b);
effectPlaying = b;
}
public void SetTransform(Transform t)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: 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)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
Player player = GetPlayer();
if (Object.op_Implicit((Object)(object)player))
{
t.forward = AssDirection(player);
t.position = AssPosition(player) + t.forward * 0.75f;
}
}
private void Update()
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)GetAudioSource().clip))
{
((Behaviour)this).enabled = false;
return;
}
if (counter >= GetAudioSource().clip.length)
{
((Behaviour)this).enabled = false;
return;
}
Player player = GetPlayer();
if (!Object.op_Implicit((Object)(object)player))
{
((Behaviour)this).enabled = false;
return;
}
audioSource.volume = configuration.GetVolume();
((Component)GetParticleSystem()).transform.localScale = Vector3.one * configuration.GetParticleSize();
SetTransform(((Component)this).transform);
if (true)
{
if (!effectPlaying)
{
SetEffectEnabled(b: true);
}
}
else if (effectPlaying)
{
SetEffectEnabled(b: false);
}
counter += Time.deltaTime;
}
private void SetJiggleForce(float forceMultiplier)
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
Player player = GetPlayer();
if (Object.op_Implicit((Object)(object)player))
{
float num = Random.Range(0.0003f, 0.0006f);
float num2 = num * forceMultiplier;
DynamicBone[] assDynamicBones = player._pVisual._playerRaceModel._assDynamicBones;
for (int i = 0; i < assDynamicBones.Length; i++)
{
DynamicBone val = assDynamicBones[i];
float num3 = (((i + 1) % 2 == 0) ? 1 : (-1));
Vector3 force = ((Component)player).transform.right * num3 * num2;
val.m_Force = force;
}
List<DynamicBone> list = new List<DynamicBone>(((Component)player).gameObject.GetComponentsInChildren<DynamicBone>());
DynamicBone val2 = list.Find((DynamicBone x) => ((Object)x).name.Contains("tail"));
if (Object.op_Implicit((Object)(object)val2))
{
Vector3 force2 = ((Component)player).transform.up * num2;
val2.m_Force = force2;
}
}
}
private IEnumerator JiggleRoutine()
{
while (true)
{
SetJiggleForce(1f * configuration.GetJiggleMultiplier());
yield return (object)new WaitForEndOfFrame();
SetJiggleForce(0f);
yield return (object)new WaitForSeconds(0.15f);
}
}
private void SetParticleEnabled(bool b)
{
ParticleSystem val = GetParticleSystem();
if (Object.op_Implicit((Object)(object)val))
{
if (b)
{
val.Play(true);
}
else
{
val.Stop(true);
}
}
else
{
Log("NO PARTICLE", force: true);
}
}
private void SetEyeConditions()
{
Player player = GetPlayer();
if (Object.op_Implicit((Object)(object)player))
{
player._pVisual._playerRaceModel.Set_EyeCondition((EyeCondition)8, 1f);
player._pVisual._playerRaceModel.Set_MouthCondition((MouthCondition)0, 1f);
}
}
private IEnumerator EyeConditionRoutine()
{
while (true)
{
SetEyeConditions();
yield return (object)new WaitForEndOfFrame();
}
}
private void OnDisable()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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)
SetEffectEnabled(b: false);
Player player = GetPlayer();
if (Object.op_Implicit((Object)(object)player))
{
List<EyeCondition> list = new List<EyeCondition>();
list.Add((EyeCondition)1);
list.Add((EyeCondition)8);
EyeCondition val = list[Random.Range(0, list.Count)];
player._pVisual._playerRaceModel.Set_EyeCondition(val, 1f);
player._pVisual._playerRaceModel.Set_MouthCondition((MouthCondition)1, 1f);
}
}
}
public class FartEffectsConfiguration
{
public FartEffectsManager owner;
public float volume = 1f;
public string startColors;
public string endColors;
public float particleSize;
public float jiggleMultiplier = 1f;
public FartEffectsConfiguration()
{
SetDefaults();
}
public FartEffectsConfiguration(FartEffectsManager owner)
{
this.owner = owner;
SetDefaults();
}
private void SetDefaults()
{
volume = (float)((ConfigEntryBase)Configuration.FartVolume).DefaultValue;
startColors = (string)((ConfigEntryBase)Configuration.FartParticleStartColors).DefaultValue;
endColors = (string)((ConfigEntryBase)Configuration.FartParticleEndColors).DefaultValue;
jiggleMultiplier = (float)((ConfigEntryBase)Configuration.JiggleIntensity).DefaultValue;
particleSize = (float)((ConfigEntryBase)Configuration.FartParticleSize).DefaultValue;
}
private bool IsPlayer()
{
if (Object.op_Implicit((Object)(object)owner))
{
return (Object)(object)owner.owner == (Object)(object)Player._mainPlayer;
}
return false;
}
public float GetVolume()
{
float value = volume;
if (IsPlayer())
{
value = Configuration.FartVolume.Value;
}
return value + (Configuration.GlobalFartVolume.Value - 1f);
}
public float GetJiggleMultiplier()
{
if (IsPlayer())
{
return Configuration.JiggleIntensity.Value;
}
return jiggleMultiplier;
}
public List<Color> GetStartColors()
{
if (IsPlayer())
{
return Configuration.GetStartColors();
}
return Configuration.GetColors(startColors);
}
public List<Color> GetEndColors()
{
if (IsPlayer())
{
return Configuration.GetEndColors();
}
return Configuration.GetColors(endColors);
}
public float GetParticleSize()
{
if (IsPlayer())
{
return Configuration.FartParticleSize.Value;
}
return particleSize;
}
}
[BepInPlugin("TransientGuy.Atlyss.FartMod", "FartMod", "1.2.3.4")]
public class FartModCore : BaseUnityPlugin
{
public class ChatCommand
{
public string commandKey;
public string commandMessage;
public Action<ChatBehaviour, List<string>> action;
public ChatCommand(string commandKey, string commandMessage, Action<ChatBehaviour, List<string>> action)
{
this.commandKey = commandKey;
this.action = action;
}
public void InvokeAction(ChatBehaviour chatBehaviour)
{
InvokeAction(chatBehaviour, new List<string>());
}
public void InvokeAction(ChatBehaviour chatBehaviour, List<string> parameters)
{
action(chatBehaviour, parameters);
if (!string.IsNullOrEmpty(commandMessage))
{
chatBehaviour.New_ChatMessage("<color=#ea8e09> " + commandMessage + "</color>");
}
}
}
public static class FartCommands
{
[HarmonyPatch(typeof(ChatBehaviour), "Send_ChatMessage")]
public static class AddCommandsPatch
{
[HarmonyPrefix]
public static bool Send_ChatMessage_Prefix(ChatBehaviour __instance, string _message)
{
if (CheckHostCommand(__instance, _message))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ChatBehaviour), "InvokeUserCode_Rpc_RecieveChatMessage__String__Boolean__ChatChannel")]
public static class RecieveChatMessagePatch
{
[HarmonyPostfix]
public static void RecieveChatMessage_Prefix(ChatBehaviour __instance, NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient senderConnection)
{
if (!Object.op_Implicit((Object)(object)obj) || !(obj is ChatBehaviour))
{
return;
}
ChatBehaviour playerChat = GetPlayerChat();
if (Object.op_Implicit((Object)(object)playerChat) && playerChat._chatMessages.Any())
{
string message = playerChat._chatMessages[playerChat._chatMessages.Count - 1];
ChatBehaviour val = (ChatBehaviour)(object)((obj is ChatBehaviour) ? obj : null);
bool flag = CheckRPCCommandReceived(val, message);
if (Configuration.FartChaos.Value && !flag && (Object)(object)val != (Object)(object)playerChat)
{
instance.FartLoop(val, new List<string>());
}
}
}
}
public static ChatBehaviour playerChat;
public static List<ChatCommand> allChatCommands = new List<ChatCommand>();
public static List<ChatCommand> hostChatCommands = new List<ChatCommand>();
public static ChatBehaviour GetPlayerChat()
{
if (!Object.op_Implicit((Object)(object)playerChat))
{
Player mainPlayer = Player._mainPlayer;
if (Object.op_Implicit((Object)(object)mainPlayer))
{
playerChat = ((Component)mainPlayer).GetComponentInChildren<ChatBehaviour>();
}
}
return playerChat;
}
public static void AddCommand(string commandKey, string commandMessage, Action<ChatBehaviour, List<string>> action)
{
allChatCommands.Add(new ChatCommand(commandKey, commandMessage, action));
}
public static void AddHostCommand(string commandKey, string commandMessage, Action<ChatBehaviour, List<string>> action)
{
hostChatCommands.Add(new ChatCommand(commandKey, commandMessage, action));
}
private static bool CheckHostCommand(ChatBehaviour __instance, string _message)
{
if (_message == null)
{
return false;
}
if (!_message.Any())
{
return false;
}
if (_message[0] != '/')
{
return false;
}
_message = _message.Substring(1);
List<string> parameters = _message.Split(new char[1] { ' ' }).ToList();
ChatCommand chatCommand = hostChatCommands.Find((ChatCommand x) => parameters[0] == x.commandKey);
if (chatCommand != null)
{
parameters.RemoveAt(0);
parameters = parameters.Where((string x) => !string.IsNullOrEmpty(x)).ToList();
chatCommand.InvokeAction(__instance, parameters);
return true;
}
return false;
}
private static bool CheckRPCCommandReceived(ChatBehaviour __instance, string _message)
{
bool flag = false;
foreach (ChatCommand allChatCommand in allChatCommands)
{
if (_message.Contains(allChatCommand.commandKey))
{
flag = true;
break;
}
}
if (!flag)
{
return false;
}
string[] array = _message.Split(new char[1] { '/' });
string[] array2 = array;
foreach (string text in array2)
{
string text2 = text.Replace("<", "");
foreach (ChatCommand allChatCommand2 in allChatCommands)
{
if (text2 == allChatCommand2.commandKey)
{
allChatCommand2.InvokeAction(__instance);
return true;
}
}
}
return false;
}
}
internal static ManualLogSource Logger;
public static FartModCore instance;
private FartController originalFartController;
private AssetBundle bundle;
internal static ConfigFile GetConfig()
{
return ((BaseUnityPlugin)instance).Config;
}
public static void Log(string message, bool forcePlay = false)
{
Logger.LogInfo((object)message);
}
private void Awake()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
instance = this;
Logger = ((BaseUnityPlugin)this).Logger;
Configuration.BindConfiguration();
Harmony val = new Harmony("FartMod");
try
{
val.PatchAll();
}
catch (Exception ex)
{
Log(ex.ToString());
throw;
}
GetOriginalFartController();
InitCommands();
Log("Fart Mod Initialized!", forcePlay: true);
}
private void InitCommands()
{
FartCommands.AddCommand("fart", "Rippin ass!", FartLoop);
FartCommands.AddCommand("fartoneshot", "Rippin ass!", FartOneshot);
FartCommands.AddCommand("fartinfinite", "Rippin ass!", FartLoopInfinite);
FartCommands.AddCommand("stopfarting", "", StopFarting);
FartCommands.AddHostCommand("rebind", "", Rebind);
FartCommands.AddHostCommand("fartchaos", "", ToggleFartChaos);
FartCommands.AddHostCommand("fartvolume", "", SetFartVolume);
FartCommands.AddHostCommand("globalfartvolume", "", SetGlobalFartVolume);
FartCommands.AddHostCommand("fartsize", "", SetFarticleSize);
FartCommands.AddHostCommand("fartjiggle", "", SetFartJiggle);
Log("Fart Commands loaded");
}
private void Rebind(ChatBehaviour chatBehaviour, List<string> parameters)
{
Log("Config file rebound!");
GetConfig().Reload();
}
private void ToggleFartChaos(ChatBehaviour chatBehaviour, List<string> parameters)
{
Configuration.FartChaos.Value = !Configuration.FartChaos.Value;
string text = (Configuration.FartChaos.Value ? "on" : "off");
Log("Fart chaos " + text + "!");
}
private float GetFloat(List<string> parameters, int index, float defaultValue, out bool success)
{
if (index >= parameters.Count)
{
Log("Not enough parameters given for command");
success = false;
return defaultValue;
}
if (float.TryParse(parameters[index], out var result))
{
success = true;
return result;
}
Log("Given parameter " + parameters[index] + " is of incorrect type");
success = false;
return defaultValue;
}
private void SetFartVolume(ChatBehaviour chatBehaviour, List<string> parameters)
{
Configuration.FartVolume.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
if (success)
{
Log("Set fart volume to " + Configuration.FartVolume.Value + "!");
}
}
private void SetGlobalFartVolume(ChatBehaviour chatBehaviour, List<string> parameters)
{
Configuration.GlobalFartVolume.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
if (success)
{
Log("Set global fart volume to " + Configuration.GlobalFartVolume.Value + "!");
}
}
private void SetFarticleSize(ChatBehaviour chatBehaviour, List<string> parameters)
{
Configuration.FartParticleSize.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
if (success)
{
Log("Set fart particle size to " + Configuration.FartParticleSize.Value + "!");
}
}
private void SetFartJiggle(ChatBehaviour chatBehaviour, List<string> parameters)
{
Configuration.JiggleIntensity.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
if (success)
{
Log("Set fart jiggle intensity to " + Configuration.JiggleIntensity.Value + "!");
}
}
private void AllAnims(ChatBehaviour chatBehaviour)
{
Player mainPlayer = Player._mainPlayer;
if (!Object.op_Implicit((Object)(object)mainPlayer))
{
return;
}
Animator raceAnimator = mainPlayer._pVisual._playerRaceModel._raceAnimator;
for (int i = 0; i < raceAnimator.runtimeAnimatorController.animationClips.Length; i++)
{
AnimationClip val = raceAnimator.runtimeAnimatorController.animationClips[i];
if (Object.op_Implicit((Object)(object)val))
{
Log(((Object)val).name + " " + i);
}
}
}
private void FartLoop(ChatBehaviour chatBehaviour, List<string> parameters)
{
FartController characterFartController = GetCharacterFartController(chatBehaviour);
if (Object.op_Implicit((Object)(object)characterFartController))
{
characterFartController.FartLoop();
}
}
private void FartOneshot(ChatBehaviour chatBehaviour, List<string> parameters)
{
FartController characterFartController = GetCharacterFartController(chatBehaviour);
if (Object.op_Implicit((Object)(object)characterFartController))
{
characterFartController.FartOneshot();
}
}
private void FartLoopInfinite(ChatBehaviour chatBehaviour, List<string> parameters)
{
FartController characterFartController = GetCharacterFartController(chatBehaviour);
if (Object.op_Implicit((Object)(object)characterFartController))
{
characterFartController.FartLoopInfinite();
}
}
private void StopFarting(ChatBehaviour chatBehaviour, List<string> parameters)
{
FartController characterFartController = GetCharacterFartController(chatBehaviour);
if (Object.op_Implicit((Object)(object)characterFartController))
{
characterFartController.StopFarting();
}
}
private FartController GetCharacterFartController(ChatBehaviour chatBehaviour)
{
Player owningPlayer = ((Component)chatBehaviour).GetComponent<Player>();
if (Object.op_Implicit((Object)(object)owningPlayer))
{
FartController fartController = FartController.allFartControllers.Find((FartController x) => (Object)(object)x.owner == (Object)(object)owningPlayer);
if (!Object.op_Implicit((Object)(object)fartController))
{
fartController = Object.Instantiate<FartController>(GetOriginalFartController());
((Component)fartController).gameObject.SetActive(true);
fartController.SetOwner(owningPlayer, GetAssetBundle());
}
return fartController;
}
return null;
}
private FartController GetOriginalFartController()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
if (!Object.op_Implicit((Object)(object)originalFartController))
{
GameObject val = new GameObject("FartController");
val.transform.SetParent(((Component)this).transform);
originalFartController = val.AddComponent<FartController>();
originalFartController.Initialize(GetAssetBundle());
((Component)originalFartController).gameObject.SetActive(false);
}
return originalFartController;
}
private AssetBundle GetAssetBundle()
{
if (!Object.op_Implicit((Object)(object)bundle))
{
string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
bundle = AssetUtils.LoadAssetBundle(Path.Combine(directoryName, "Assets/atlyss"));
}
return bundle;
}
}
public class PlayableAnimationPlayer : MonoBehaviour
{
public Animator animator;
private PlayableGraph playableGraph;
private AnimationClipPlayable anim;
public int currentClip;
private List<AnimationSequence> animationSequence = new List<AnimationSequence>();
private AnimationSequence GetCurrentClip()
{
if (animationSequence.Any())
{
return (currentClip >= animationSequence.Count) ? animationSequence[animationSequence.Count - 1] : animationSequence[currentClip];
}
return null;
}
public void StartAnimating(Animator animator, List<AnimationSequence> animationSequence)
{
currentClip = 0;
this.animator = animator;
this.animationSequence = animationSequence;
if (Object.op_Implicit((Object)(object)animator) && animationSequence.Any())
{
((Behaviour)this).enabled = true;
PlayCurrentClip();
}
else
{
((Behaviour)this).enabled = false;
}
}
private void PlayCurrentClip()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
DestroyGraph();
anim = AnimationPlayableUtilities.PlayClip(animator, GetCurrentClip().animationClip, ref playableGraph);
}
private void Update()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)animator))
{
((Behaviour)this).enabled = false;
return;
}
try
{
if (!(PlayableExtensions.GetTime<AnimationClipPlayable>(anim) >= (double)((AnimationClipPlayable)(ref anim)).GetAnimationClip().length))
{
return;
}
currentClip++;
if (currentClip < this.animationSequence.Count)
{
PlayCurrentClip();
return;
}
AnimationSequence animationSequence = GetCurrentClip();
if (animationSequence == null || !animationSequence.infinite)
{
((Behaviour)this).enabled = false;
}
}
catch
{
FartModCore.Log("Animation playing failed");
((Behaviour)this).enabled = false;
}
}
private void DestroyGraph()
{
if (Object.op_Implicit((Object)(object)animator))
{
animator.Rebind();
animator.Update(0f);
}
if (((PlayableGraph)(ref playableGraph)).IsValid())
{
((PlayableGraph)(ref playableGraph)).Destroy();
}
}
private void OnDisable()
{
DestroyGraph();
}
}
public class AnimationSequence
{
public AnimationClip animationClip;
public bool infinite;
public AnimationSequence(AnimationClip animationClip, bool infinite)
{
this.animationClip = animationClip;
this.infinite = infinite;
}
}