The BepInEx console will not appear when launching like it does for other games on Thunderstore. This is normal (and helps prevent crashes during startup). You can turn it back on in your BepInEx.cfg file.
Decompiled source of NoMoreGhost4Real v1.1.0
plugins/nomoreghostv2.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("nomoreghostv2")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("nomoreghostv2")] [assembly: AssemblyTitle("NoMoreGhostV2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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.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 PeakSpectatorGhostInvisible { public static class MyPluginInfo { public const string PLUGIN_GUID = "com.xammen.nomoreghostatall"; public const string PLUGIN_NAME = "NoMoreGhostForReal"; public const string PLUGIN_VERSION = "1.3.0"; } [BepInPlugin("com.xammen.nomoreghostatall", "NoMoreGhostForReal", "1.3.0")] public class PeakSpectatorGhostInvisible : BaseUnityPlugin { private class PlayerGhostPatch { [HarmonyPatch(typeof(PlayerGhost), "RPCA_InitGhost")] [HarmonyPostfix] private static void RPCA_InitGhostPostfix(PlayerGhost __instance, PhotonView character, PhotonView t) { ApplyVisibilitySettings(__instance); ApplySoundSettings(__instance); } } private class AnimatedMouthPatch { [HarmonyPatch(typeof(AnimatedMouth), "ProcessMicData")] [HarmonyPrefix] private static bool ProcessMicDataPrefix(AnimatedMouth __instance) { if ((Object)(object)__instance.character == (Object)null || (Object)(object)__instance.character.Ghost == (Object)null) { return true; } if (__instance.character.IsLocal) { if ((Object)(object)__instance.audioSource != (Object)null) { __instance.audioSource.mute = false; } return true; } if (!ghostSoundEnabled) { if ((Object)(object)__instance.audioSource != (Object)null) { __instance.audioSource.mute = true; } return false; } if ((Object)(object)__instance.audioSource != (Object)null) { __instance.audioSource.mute = false; } return true; } } [CompilerGenerated] private sealed class <ExtractResourceToFile>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string filePath; public string resourceName; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ExtractResourceToFile>d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; if (File.Exists(filePath)) { Logger.LogInfo((object)("La ressource '" + resourceName + "' est déjà extraite vers '" + filePath + "'. Ignoré.")); return false; } Assembly executingAssembly = Assembly.GetExecutingAssembly(); using (Stream stream = executingAssembly.GetManifestResourceStream(resourceName)) { if (stream == null) { Logger.LogError((object)("Impossible de trouver la ressource incorporée : " + resourceName + ". Vérifiez l'orthographe et l'option 'Action de génération' (Ressource incorporée).")); return false; } string directoryName = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } using (FileStream destination = File.Create(filePath)) { stream.CopyTo(destination); } Logger.LogInfo((object)("Ressource '" + resourceName + "' extraite vers '" + filePath + "'.")); } <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadAudioClips>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PeakSpectatorGhostInvisible <>4__this; private string <muteResourceName>5__2; private string <unmuteFilePath>5__3; private string <muteFilePath>5__4; private UnityWebRequest <request>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadAudioClips>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { switch (<>1__state) { case -3: case 3: try { } finally { <>m__Finally1(); } break; case -4: case 4: try { } finally { <>m__Finally2(); } break; } <muteResourceName>5__2 = null; <unmuteFilePath>5__3 = null; <muteFilePath>5__4 = null; <request>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Invalid comparison between Unknown and I4 //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Invalid comparison between Unknown and I4 //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Invalid comparison between Unknown and I4 //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Invalid comparison between Unknown and I4 try { int num = <>1__state; PeakSpectatorGhostInvisible peakSpectatorGhostInvisible = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; string text = Path.Combine(Paths.PluginPath, "com.xammen.nomoreghostatall", "Audio"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } string resourceName = "NoMoreGhostV2.Assets.Sounds.unmute.mp3"; <muteResourceName>5__2 = "NoMoreGhostV2.Assets.Sounds.mute.mp3"; <unmuteFilePath>5__3 = Path.Combine(text, "unmute.mp3"); <muteFilePath>5__4 = Path.Combine(text, "mute.mp3"); <>2__current = peakSpectatorGhostInvisible.ExtractResourceToFile(resourceName, <unmuteFilePath>5__3); <>1__state = 1; return true; } case 1: <>1__state = -1; <>2__current = peakSpectatorGhostInvisible.ExtractResourceToFile(<muteResourceName>5__2, <muteFilePath>5__4); <>1__state = 2; return true; case 2: <>1__state = -1; Logger.LogInfo((object)("Tentative de chargement du son unmute depuis : file:///" + <unmuteFilePath>5__3)); <request>5__5 = UnityWebRequestMultimedia.GetAudioClip("file:///" + <unmuteFilePath>5__3, (AudioType)13); <>1__state = -3; <>2__current = <request>5__5.SendWebRequest(); <>1__state = 3; return true; case 3: <>1__state = -3; if ((int)<request>5__5.result == 2 || (int)<request>5__5.result == 3) { Logger.LogError((object)("Erreur lors du chargement du son unmute : " + <request>5__5.error)); } else { unmuteSound = DownloadHandlerAudioClip.GetContent(<request>5__5); Logger.LogInfo((object)"Son unmute chargé avec succès."); } <>m__Finally1(); <request>5__5 = null; Logger.LogInfo((object)("Tentative de chargement du son mute depuis : file:///" + <muteFilePath>5__4)); <request>5__5 = UnityWebRequestMultimedia.GetAudioClip("file:///" + <muteFilePath>5__4, (AudioType)13); <>1__state = -4; <>2__current = <request>5__5.SendWebRequest(); <>1__state = 4; return true; case 4: <>1__state = -4; if ((int)<request>5__5.result == 2 || (int)<request>5__5.result == 3) { Logger.LogError((object)("Erreur lors du chargement du son mute : " + <request>5__5.error)); } else { muteSound = DownloadHandlerAudioClip.GetContent(<request>5__5); Logger.LogInfo((object)"Son mute chargé avec succès."); } <>m__Finally2(); <request>5__5 = 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 (<request>5__5 != null) { ((IDisposable)<request>5__5).Dispose(); } } private void <>m__Finally2() { <>1__state = -1; if (<request>5__5 != null) { ((IDisposable)<request>5__5).Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static ManualLogSource Logger; private readonly Harmony harmony = new Harmony("com.xammen.nomoreghostatall"); internal static bool ghostVisibilityEnabled; internal static bool ghostSoundEnabled; private static AudioClip muteSound; private static AudioClip unmuteSound; private static AudioSource audioPlayer; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; GameObject val = new GameObject("PeakSpectatorGhostInvisible_AudioPlayer"); Object.DontDestroyOnLoad((Object)(object)val); audioPlayer = val.AddComponent<AudioSource>(); ((MonoBehaviour)this).StartCoroutine(LoadAudioClips()); harmony.PatchAll(typeof(PlayerGhostPatch)); harmony.PatchAll(typeof(AnimatedMouthPatch)); Logger.LogInfo((object)"Plugin NoMoreGhostForReal loaded"); } [IteratorStateMachine(typeof(<LoadAudioClips>d__8))] private IEnumerator LoadAudioClips() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadAudioClips>d__8(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<ExtractResourceToFile>d__9))] private IEnumerator ExtractResourceToFile(string resourceName, string filePath) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ExtractResourceToFile>d__9(0) { resourceName = resourceName, filePath = filePath }; } private void Update() { if (!Input.GetKeyDown((KeyCode)104)) { return; } if (!ghostSoundEnabled) { if ((Object)(object)unmuteSound != (Object)null && (Object)(object)audioPlayer != (Object)null) { audioPlayer.PlayOneShot(unmuteSound); Logger.LogInfo((object)"Lecture du son de 'unmute'."); } else { Logger.LogWarning((object)"Son 'unmute' ou AudioSource non disponible."); } } else if ((Object)(object)muteSound != (Object)null && (Object)(object)audioPlayer != (Object)null) { audioPlayer.PlayOneShot(muteSound); Logger.LogInfo((object)"Lecture du son de 'mute'."); } else { Logger.LogWarning((object)"Son 'mute' ou AudioSource non disponible."); } ghostVisibilityEnabled = !ghostVisibilityEnabled; ghostSoundEnabled = !ghostSoundEnabled; Logger.LogInfo((object)$"Ghost visibility and sound toggled. Visibility: {ghostVisibilityEnabled}, Sound: {ghostSoundEnabled}"); ApplyGhostSettingsToAllCharacters(); } private void ApplyGhostSettingsToAllCharacters() { foreach (Character allCharacter in Character.AllCharacters) { if ((Object)(object)allCharacter.Ghost != (Object)null) { ApplyVisibilitySettings(allCharacter.Ghost); ApplySoundSettings(allCharacter.Ghost); } } } internal static void ApplyVisibilitySettings(PlayerGhost ghost) { bool flag = ghostVisibilityEnabled; if (ghost.PlayerRenderers != null) { Renderer[] playerRenderers = ghost.PlayerRenderers; foreach (Renderer val in playerRenderers) { if ((Object)(object)val != (Object)null) { val.enabled = flag; } } } if (ghost.EyeRenderers != null) { Renderer[] eyeRenderers = ghost.EyeRenderers; foreach (Renderer val2 in eyeRenderers) { if ((Object)(object)val2 != (Object)null) { val2.enabled = flag; } } } if ((Object)(object)ghost.mouthRenderer != (Object)null) { ghost.mouthRenderer.enabled = flag; } if ((Object)(object)ghost.accessoryRenderer != (Object)null) { ghost.accessoryRenderer.enabled = flag; } ManualLogSource logger = Logger; Character owner = ghost.m_owner; logger.LogDebug((object)$"Ghost {((owner != null) ? owner.characterName : null)}'s visibility set to {flag}."); } internal static void ApplySoundSettings(PlayerGhost ghost) { if ((Object)(object)ghost.m_owner != (Object)null && !ghost.m_owner.IsLocal) { if ((Object)(object)ghost.animatedMouth != (Object)null && (Object)(object)ghost.animatedMouth.audioSource != (Object)null) { ghost.animatedMouth.audioSource.mute = !ghostSoundEnabled; Logger.LogDebug((object)$"Ghost {ghost.m_owner.characterName}'s audio muted: {!ghostSoundEnabled}."); } else { ManualLogSource logger = Logger; Character owner = ghost.m_owner; logger.LogWarning((object)("Could not find AnimatedMouth or AudioSource for ghost of " + ((owner != null) ? owner.characterName : null) + ".")); } } else if ((Object)(object)ghost.m_owner != (Object)null && ghost.m_owner.IsLocal && (Object)(object)ghost.animatedMouth != (Object)null && (Object)(object)ghost.animatedMouth.audioSource != (Object)null) { ghost.animatedMouth.audioSource.mute = false; } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }