using System; using System.Collections; 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("RevisitStingers")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Replay interior stingers when they are somewhere they shouldn't be")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1+f644f8d4fe8034b037e8e6b067ab8a7c07785bc7")] [assembly: AssemblyProduct("RevisitStingers")] [assembly: AssemblyTitle("RevisitStingers")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RevisitStingers { internal static class LobbyCompatibility { internal static void Init() { PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.revisitstingers", Version.Parse("1.3.1"), (CompatibilityLevel)0, (VersionStrictness)0); } } [BepInPlugin("butterystancakes.lethalcompany.revisitstingers", "Revisit Stingers", "1.3.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.revisitstingers"; internal const string PLUGIN_NAME = "Revisit Stingers"; internal const string PLUGIN_VERSION = "1.3.1"; internal static ConfigEntry configMaxRarity; internal static ConfigEntry configInterruptMusic; internal static ConfigEntry configFallbackChance; internal static ManualLogSource Logger; private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility"; private const string GUID_DAWN_LIB = "com.github.teamxiaolan.dawnlib"; internal static bool TRUST_CHECKED_FOR_FIRST_TIME = true; private void Awake() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility")) { Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected"); LobbyCompatibility.Init(); } if (Chainloader.PluginInfos.ContainsKey("com.github.teamxiaolan.dawnlib")) { Logger.LogInfo((object)"CROSS-COMPATIBILITY - DawnLib detected"); TRUST_CHECKED_FOR_FIRST_TIME = false; } AcceptableValueRange val = new AcceptableValueRange(0f, 1f); string text = " (0 = never, 1 = guaranteed, or anything in between - 0.5 = 50% chance)"; configMaxRarity = ((BaseUnityPlugin)this).Config.Bind("Misc", "MaxRarity", 0.16f, new ConfigDescription("The highest spawn chance (0.16 = 16%) an interior can have on a specific moon for it to be considered \"rare\". Rare interiors will always play the stinger.", (AcceptableValueBase)(object)val, Array.Empty())); configInterruptMusic = ((BaseUnityPlugin)this).Config.Bind("Misc", "InterruptMusic", 0f, new ConfigDescription("The percentage chance for the stinger to play if you enter the building while an ambient music track is playing." + text, (AcceptableValueBase)(object)val, Array.Empty())); configFallbackChance = ((BaseUnityPlugin)this).Config.Bind("Misc", "FallbackChance", 0f, new ConfigDescription("The percentage chance that the stinger will still play, even if you are in a common interior and there is no music playing on the surface." + text, (AcceptableValueBase)(object)val, Array.Empty())); new Harmony("butterystancakes.lethalcompany.revisitstingers").PatchAll(); Logger.LogInfo((object)"Revisit Stingers v1.3.1 loaded"); } } [HarmonyPatch] internal class RevisitStingersPatches { [HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayer")] [HarmonyPrefix] private static void EntranceTeleport_Pre_TeleportPlayer(EntranceTeleport __instance) { if (ReplayStinger.beenInsideThisRound || !__instance.FindExitPoint()) { return; } ReplayStinger.beenInsideThisRound = true; if (!__instance.isEntranceToBuilding || (__instance.checkedForFirstTime && Plugin.TRUST_CHECKED_FOR_FIRST_TIME) || !ES3.Load($"PlayedDungeonEntrance{RoundManager.Instance.currentDungeonType}", "LCGeneralSaveData", false)) { return; } try { AudioClip firstTimeAudio = RoundManager.Instance.dungeonFlowTypes[RoundManager.Instance.currentDungeonType].firstTimeAudio; if ((Object)(object)firstTimeAudio != (Object)null && ReplayStinger.StingerShouldReplay()) { ((MonoBehaviour)__instance).StartCoroutine(ReplayStinger.DelayedStinger(firstTimeAudio)); } } catch (Exception arg) { Plugin.Logger.LogWarning((object)$"Ran into an error attempting to replay stinger - this is likely due to an incompatibility with modded content\n{arg}"); } } [HarmonyPatch(typeof(StartOfRound), "SetShipReadyToLand")] [HarmonyPostfix] private static void StartOfRound_Post_SetShipReadyToLand() { ReplayStinger.beenInsideThisRound = false; } [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] private static void StartOfRound_Post_Awake() { ReplayStinger.beenInsideThisRound = false; } [HarmonyPatch(typeof(ShipTeleporter), "TeleportPlayerOutWithInverseTeleporter")] [HarmonyPostfix] private static void ShipTeleporter_Post_TeleportPlayerOutWithInverseTeleporter(int playerObj) { if ((Object)(object)StartOfRound.Instance.allPlayerScripts[playerObj] != (Object)(object)GameNetworkManager.Instance.localPlayerController || ReplayStinger.beenInsideThisRound) { return; } ReplayStinger.beenInsideThisRound = true; try { AudioClip firstTimeAudio = RoundManager.Instance.dungeonFlowTypes[RoundManager.Instance.currentDungeonType].firstTimeAudio; if ((Object)(object)firstTimeAudio != (Object)null && (ReplayStinger.StingerShouldReplay() || !ES3.Load($"PlayedDungeonEntrance{RoundManager.Instance.currentDungeonType}", "LCGeneralSaveData", false))) { ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(ReplayStinger.DelayedStinger(firstTimeAudio)); if (ReplayStinger.IsVanillaDungeon()) { ES3.Save($"PlayedDungeonEntrance{RoundManager.Instance.currentDungeonType}", true, "LCGeneralSaveData"); } } } catch (Exception arg) { Plugin.Logger.LogWarning((object)$"Ran into an error attempting to replay stinger - this is likely due to an incompatibility with modded content\n{arg}"); } } } internal class ReplayStinger { [CompilerGenerated] private sealed class d__3 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AudioClip stinger; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.6f); <>1__state = 1; return true; case 1: <>1__state = -1; HUDManager.Instance.UIAudio.PlayOneShot(stinger); 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(); } } internal static bool beenInsideThisRound; internal static bool StingerShouldReplay() { if (Plugin.configInterruptMusic.Value > 0f && SoundManager.Instance.musicSource.isPlaying && Random.value <= Plugin.configInterruptMusic.Value) { return true; } IntWithRarity[] dungeonFlowTypes = StartOfRound.Instance.currentLevel.dungeonFlowTypes; if (dungeonFlowTypes != null && dungeonFlowTypes.Length > 1 && (!StartOfRound.Instance.isChallengeFile || !ES3.Load("FinishedChallenge", "LCChallengeFile", false))) { int num = 0; float num2 = 0f; IntWithRarity[] dungeonFlowTypes2 = StartOfRound.Instance.currentLevel.dungeonFlowTypes; foreach (IntWithRarity val in dungeonFlowTypes2) { if (val.id == RoundManager.Instance.currentDungeonType) { num = val.rarity; } num2 += (float)val.rarity; } if (num > 0 && (float)num / num2 <= Plugin.configMaxRarity.Value) { return true; } } if (Plugin.configFallbackChance.Value > 0f) { return Random.value <= Plugin.configFallbackChance.Value; } return false; } internal static bool IsVanillaDungeon() { if (RoundManager.Instance.currentDungeonType != 0 && RoundManager.Instance.currentDungeonType != 1) { return RoundManager.Instance.currentDungeonType == 4; } return true; } [IteratorStateMachine(typeof(d__3))] internal static IEnumerator DelayedStinger(AudioClip stinger) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__3(0) { stinger = stinger }; } } public static class PluginInfo { public const string PLUGIN_GUID = "RevisitStingers"; public const string PLUGIN_NAME = "RevisitStingers"; public const string PLUGIN_VERSION = "1.3.1"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }