Decompiled source of Mimic v0.1.1

plugins/com.EMOKaMi.Mimic.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Photon.Voice.PUN;
using Photon.Voice.Unity;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.EMOKaMi.Mimic")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1")]
[assembly: AssemblyProduct("com.EMOKaMi.Mimic")]
[assembly: AssemblyTitle("Mimic")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Mimic
{
	[BepInPlugin("com.EMOKaMi.Mimic", "Mimic", "0.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Id = "com.EMOKaMi.Mimic";

		internal static ManualLogSource Log { get; private set; }

		public static Plugin Instance { get; private set; }

		public static string Name => "Mimic";

		public static string Version => "0.1.1";

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, (string)null);
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
			if (!Object.op_Implicit((Object)(object)((Component)this).gameObject.GetComponent<MimicManager>()))
			{
				((Component)this).gameObject.AddComponent<MimicManager>();
			}
		}
	}
	public class MimicManager : MonoBehaviourPunCallbacks
	{
		public static MimicManager Instance;

		public Dictionary<int, List<AudioClip>> VoiceBank = new Dictionary<int, List<AudioClip>>();

		public int MaxClipsPerPlayer = 10;

		public int Setting_MaxMimics = 2;

		public float Setting_SpawnIntervalMin = 60f;

		public float Setting_SpawnIntervalMax = 120f;

		public float Setting_RecycleDistance = 80f;

		private bool gameStarted;

		private float nextSpawnTime;

		private List<MimicController> activeMimics = new List<MimicController>();

		private bool showSettings;

		private Rect settingsRect = new Rect(50f, 50f, 300f, 350f);

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			if (PhotonNetwork.IsMasterClient && Input.GetKeyDown((KeyCode)292))
			{
				showSettings = !showSettings;
				if (showSettings)
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
				}
			}
			if (!PhotonNetwork.IsMasterClient || !gameStarted)
			{
				return;
			}
			if (Time.time > nextSpawnTime && activeMimics.Count < Setting_MaxMimics)
			{
				SpawnMimic();
				SetNextSpawnTime();
			}
			for (int num = activeMimics.Count - 1; num >= 0; num--)
			{
				MimicController mimicController = activeMimics[num];
				if ((Object)(object)mimicController == (Object)null)
				{
					activeMimics.RemoveAt(num);
				}
				else if (ShouldRecycle(mimicController))
				{
					RecycleMimic(mimicController);
				}
			}
		}

		public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
		{
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"M_Max"))
			{
				Setting_MaxMimics = (int)propertiesThatChanged[(object)"M_Max"];
			}
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"M_MinTime"))
			{
				Setting_SpawnIntervalMin = (float)propertiesThatChanged[(object)"M_MinTime"];
			}
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"M_MaxTime"))
			{
				Setting_SpawnIntervalMax = (float)propertiesThatChanged[(object)"M_MaxTime"];
			}
			if (((Dictionary<object, object>)(object)propertiesThatChanged).ContainsKey((object)"M_Dist"))
			{
				Setting_RecycleDistance = (float)propertiesThatChanged[(object)"M_Dist"];
			}
		}

		private void SyncSettings()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0066: Expected O, but got Unknown
			if (PhotonNetwork.IsMasterClient)
			{
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"M_Max", (object)Setting_MaxMimics);
				((Dictionary<object, object>)val).Add((object)"M_MinTime", (object)Setting_SpawnIntervalMin);
				((Dictionary<object, object>)val).Add((object)"M_MaxTime", (object)Setting_SpawnIntervalMax);
				((Dictionary<object, object>)val).Add((object)"M_Dist", (object)Setting_RecycleDistance);
				Hashtable val2 = val;
				PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
			}
		}

		public void OnReachFirstMountain()
		{
			if (!gameStarted)
			{
				gameStarted = true;
				SetNextSpawnTime();
				Plugin.Log.LogInfo((object)"Mimic Game Started!");
			}
		}

		private void SetNextSpawnTime()
		{
			nextSpawnTime = Time.time + Random.Range(Setting_SpawnIntervalMin, Setting_SpawnIntervalMax);
		}

		private bool ShouldRecycle(MimicController mimic)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character allCharacter in Character.AllCharacters)
			{
				if (Vector3.Distance(((Component)mimic).transform.position, ((Component)allCharacter).transform.position) < Setting_RecycleDistance)
				{
					return false;
				}
			}
			return true;
		}

		private void RecycleMimic(MimicController mimic)
		{
			//IL_002a: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			Player[] playerList = PhotonNetwork.PlayerList;
			if (playerList.Length != 0)
			{
				Player val = playerList[Random.Range(0, playerList.Length)];
				Character playerCharacter = PlayerHandler.GetPlayerCharacter(val);
				if (!((Object)(object)playerCharacter == (Object)null))
				{
					Vector3 hiddenSpawnPosition = GetHiddenSpawnPosition(playerCharacter);
					mimic.ResetMimic(val.ActorNumber, hiddenSpawnPosition);
					((Component)mimic).GetComponent<PhotonView>().RPC("RPC_Arise", (RpcTarget)0, new object[1] { ((MonoBehaviourPun)playerCharacter).photonView.ViewID });
				}
			}
		}

		private void SpawnMimic()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			Player[] playerList = PhotonNetwork.PlayerList;
			if (playerList.Length != 0)
			{
				Player val = playerList[Random.Range(0, playerList.Length)];
				Character playerCharacter = PlayerHandler.GetPlayerCharacter(val);
				if (!((Object)(object)playerCharacter == (Object)null) && !playerCharacter.data.dead)
				{
					Vector3 hiddenSpawnPosition = GetHiddenSpawnPosition(playerCharacter);
					GameObject val2 = PhotonNetwork.Instantiate("MushroomZombie_Player", hiddenSpawnPosition, Quaternion.identity, (byte)0, (object[])null);
					MimicController mimicController = val2.AddComponent<MimicController>();
					mimicController.Init(val.ActorNumber);
					val2.GetComponent<PhotonView>().RPC("RPC_Arise", (RpcTarget)0, new object[1] { ((MonoBehaviourPun)playerCharacter).photonView.ViewID });
					activeMimics.Add(mimicController);
				}
			}
		}

		private Vector3 GetHiddenSpawnPosition(Character target)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_003a: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)target).transform.position - ((Component)target).transform.forward * 25f + Vector3.up * 5f;
			val += Random.insideUnitSphere * 5f;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val + Vector3.up * 20f, Vector3.down, ref val2, 50f, LayerMask.op_Implicit(HelperFunctions.terrainMapMask)))
			{
				return ((RaycastHit)(ref val2)).point + Vector3.up;
			}
			return val;
		}

		public void StoreClip(int actorNumber, AudioClip clip)
		{
			if (!VoiceBank.ContainsKey(actorNumber))
			{
				VoiceBank[actorNumber] = new List<AudioClip>();
			}
			List<AudioClip> list = VoiceBank[actorNumber];
			list.Add(clip);
			if (list.Count > MaxClipsPerPlayer)
			{
				list.RemoveAt(0);
			}
		}

		public AudioClip GetRandomClip(int actorNumber)
		{
			if (VoiceBank.TryGetValue(actorNumber, out List<AudioClip> value) && value.Count > 0)
			{
				return value[Random.Range(0, value.Count)];
			}
			return null;
		}

		private void OnGUI()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0034: 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)
			if (PhotonNetwork.InRoom && showSettings && PhotonNetwork.IsMasterClient)
			{
				settingsRect = GUI.Window(999004, settingsRect, new WindowFunction(DrawSettingsWindow), "Mimic Settings (F11)");
			}
		}

		private void DrawSettingsWindow(int id)
		{
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.Label($"Max Mimics: {Setting_MaxMimics}", Array.Empty<GUILayoutOption>());
			float num = GUILayout.HorizontalSlider((float)Setting_MaxMimics, 1f, 5f, Array.Empty<GUILayoutOption>());
			if ((int)num != Setting_MaxMimics)
			{
				Setting_MaxMimics = (int)num;
				SyncSettings();
			}
			GUILayout.Label($"Spawn Interval: {Setting_SpawnIntervalMin:F0}s - {Setting_SpawnIntervalMax:F0}s", Array.Empty<GUILayoutOption>());
			float num2 = GUILayout.HorizontalSlider(Setting_SpawnIntervalMin, 10f, 300f, Array.Empty<GUILayoutOption>());
			if (num2 != Setting_SpawnIntervalMin)
			{
				Setting_SpawnIntervalMin = num2;
				SyncSettings();
			}
			float num3 = GUILayout.HorizontalSlider(Setting_SpawnIntervalMax, Setting_SpawnIntervalMin, 600f, Array.Empty<GUILayoutOption>());
			if (num3 != Setting_SpawnIntervalMax)
			{
				Setting_SpawnIntervalMax = num3;
				SyncSettings();
			}
			GUILayout.Label($"Recycle Distance: {Setting_RecycleDistance:F0}m", Array.Empty<GUILayoutOption>());
			float num4 = GUILayout.HorizontalSlider(Setting_RecycleDistance, 50f, 300f, Array.Empty<GUILayoutOption>());
			if (num4 != Setting_RecycleDistance)
			{
				Setting_RecycleDistance = num4;
				SyncSettings();
			}
			GUILayout.Space(20f);
			if (GUILayout.Button("Close", Array.Empty<GUILayoutOption>()))
			{
				showSettings = false;
			}
			GUILayout.EndVertical();
			GUI.DragWindow();
		}
	}
	public class MimicController : MonoBehaviourPun
	{
		public int TargetActorNumber;

		private Character character;

		private MushroomZombie zombieAI;

		private AudioSource audioSource;

		private float attackTimer;

		private bool isHostile;

		private float talkCooldown;

		public void Init(int targetActor)
		{
			((MonoBehaviourPun)this).photonView.RPC("RPC_InitMimic", (RpcTarget)0, new object[1] { targetActor });
		}

		[PunRPC]
		private void RPC_InitMimic(int targetActor)
		{
			TargetActorNumber = targetActor;
			character = ((Component)this).GetComponent<Character>();
			zombieAI = ((Component)this).GetComponent<MushroomZombie>();
			if (Object.op_Implicit((Object)(object)zombieAI))
			{
				((Behaviour)zombieAI).enabled = false;
			}
			if (!Object.op_Implicit((Object)(object)audioSource))
			{
				audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
				audioSource.spatialBlend = 1f;
				audioSource.minDistance = 2f;
				audioSource.maxDistance = 30f;
			}
			ResetState();
		}

		public void ResetMimic(int newTarget, Vector3 pos)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)character))
			{
				character.WarpPlayerRPC(pos, false);
			}
			((MonoBehaviourPun)this).photonView.RPC("RPC_InitMimic", (RpcTarget)0, new object[1] { newTarget });
		}

		private void ResetState()
		{
			isHostile = false;
			if (Object.op_Implicit((Object)(object)zombieAI))
			{
				((Behaviour)zombieAI).enabled = false;
			}
			((Behaviour)this).enabled = true;
			if (PhotonNetwork.IsMasterClient)
			{
				attackTimer = Time.time + Random.Range(60f, 120f);
			}
		}

		private void Update()
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			if (!isHostile)
			{
				FollowTarget();
				CheckForTalk();
				if (Time.time > attackTimer)
				{
					TurnHostile();
				}
			}
			else
			{
				ChaseTarget();
			}
		}

		private void FollowTarget()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_007f: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			Character target = GetTarget();
			if (!((Object)(object)target == (Object)null))
			{
				float num = Vector3.Distance(((Component)this).transform.position, ((Component)target).transform.position);
				if (num > 8f)
				{
					MoveTo(((Component)target).transform.position);
				}
				else
				{
					character.input.movementInput = Vector2.zero;
				}
				character.data.lookValues = Vector2.op_Implicit(HelperFunctions.DirectionToLook(target.Head - character.Head));
			}
		}

		private void CheckForTalk()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < talkCooldown)
			{
				return;
			}
			Player[] playerList = PhotonNetwork.PlayerList;
			foreach (Player val in playerList)
			{
				Character playerCharacter = PlayerHandler.GetPlayerCharacter(val);
				if (Object.op_Implicit((Object)(object)playerCharacter) && Vector3.Distance(((Component)playerCharacter).transform.position, ((Component)this).transform.position) < 10f)
				{
					PhotonVoiceView component = ((Component)playerCharacter).GetComponent<PhotonVoiceView>();
					if (Object.op_Implicit((Object)(object)component) && component.IsSpeaking)
					{
						((MonoBehaviourPun)this).photonView.RPC("RPC_MimicTalk", (RpcTarget)0, Array.Empty<object>());
						talkCooldown = Time.time + 5f;
						break;
					}
				}
			}
		}

		[PunRPC]
		private void RPC_MimicTalk()
		{
			AudioClip randomClip = MimicManager.Instance.GetRandomClip(TargetActorNumber);
			if (Object.op_Implicit((Object)(object)randomClip) && Object.op_Implicit((Object)(object)audioSource))
			{
				audioSource.clip = randomClip;
				audioSource.Play();
			}
		}

		private void TurnHostile()
		{
			isHostile = true;
			if (Object.op_Implicit((Object)(object)zombieAI))
			{
				((Behaviour)zombieAI).enabled = true;
				zombieAI.currentState = (State)3;
				((Behaviour)this).enabled = false;
			}
		}

		private void ChaseTarget()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			Character target = GetTarget();
			if (Object.op_Implicit((Object)(object)target))
			{
				MoveTo(((Component)target).transform.position, sprint: true);
			}
		}

		private void MoveTo(Vector3 pos, bool sprint = false)
		{
			//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0026: 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_0038: 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)
			Vector3 val = pos - ((Component)this).transform.position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = ((Component)this).transform.InverseTransformDirection(normalized);
			character.input.movementInput = new Vector2(val2.x, val2.z);
			character.input.sprintIsPressed = sprint;
		}

		private Character GetTarget()
		{
			Player[] playerList = PhotonNetwork.PlayerList;
			foreach (Player val in playerList)
			{
				if (val.ActorNumber == TargetActorNumber)
				{
					return PlayerHandler.GetPlayerCharacter(val);
				}
			}
			return null;
		}
	}
	public class VoiceRecorder : MonoBehaviour
	{
		private Speaker speaker;

		private PhotonView view;

		private List<float> tempBuffer = new List<float>();

		private bool isRecording;

		private float silenceTimer;

		private const float SILENCE_THRESHOLD = 0.5f;

		private const float MIN_CLIP_LENGTH = 1f;

		private void Awake()
		{
			speaker = ((Component)this).GetComponent<Speaker>();
			view = ((Component)this).GetComponentInParent<PhotonView>();
		}

		private void OnAudioFilterRead(float[] data, int channels)
		{
			if (Object.op_Implicit((Object)(object)speaker) && speaker.IsPlaying)
			{
				float num = 0f;
				for (int i = 0; i < data.Length; i++)
				{
					num += Mathf.Abs(data[i]);
				}
				float num2 = num / (float)data.Length;
				if (num2 > 0.01f)
				{
					isRecording = true;
					silenceTimer = 0f;
				}
				if (isRecording)
				{
					tempBuffer.AddRange(data);
				}
			}
		}

		private void Update()
		{
			if (Object.op_Implicit((Object)(object)view) && !view.IsMine && isRecording)
			{
				if (!speaker.IsPlaying)
				{
					silenceTimer += Time.deltaTime;
				}
				if (silenceTimer > 0.5f || tempBuffer.Count > 240000)
				{
					FinishRecording();
				}
			}
		}

		private void FinishRecording()
		{
			isRecording = false;
			silenceTimer = 0f;
			if (tempBuffer.Count != 0)
			{
				int outputSampleRate = AudioSettings.outputSampleRate;
				int num = 2;
				float[] array = tempBuffer.ToArray();
				tempBuffer.Clear();
				if (!((float)array.Length < (float)(outputSampleRate * num) * 1f))
				{
					AudioClip val = AudioClip.Create($"Voice_{view.OwnerActorNr}_{Time.time}", array.Length / num, num, outputSampleRate, false);
					val.SetData(array, 0);
					MimicManager.Instance.StoreClip(view.OwnerActorNr, val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	public static class CharacterRecorderPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Character __instance)
		{
			if (!((MonoBehaviourPun)__instance).photonView.IsMine)
			{
				Speaker componentInChildren = ((Component)__instance).GetComponentInChildren<Speaker>();
				if (Object.op_Implicit((Object)(object)componentInChildren) && !Object.op_Implicit((Object)(object)((Component)componentInChildren).gameObject.GetComponent<VoiceRecorder>()))
				{
					((Component)componentInChildren).gameObject.AddComponent<VoiceRecorder>();
				}
			}
		}
	}
	[HarmonyPatch(typeof(MapHandler), "GoToSegment")]
	public static class MapHandlerPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Segment s)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if ((int)s == 0 && PhotonNetwork.IsMasterClient && Object.op_Implicit((Object)(object)MimicManager.Instance))
			{
				MimicManager.Instance.OnReachFirstMountain();
			}
		}
	}
	[HarmonyPatch(typeof(MushroomZombie), "Update")]
	public static class MimicAIPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(MushroomZombie __instance)
		{
			MimicController component = ((Component)__instance).GetComponent<MimicController>();
			if (Object.op_Implicit((Object)(object)component) && ((Behaviour)component).enabled)
			{
				return false;
			}
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}