Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BetterLethal v1.0.0
BepInEx/plugins/BetterLethal.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 BetterLethal.Coroutines; using BetterLethal.Manager; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("BetterLethal")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BetterLethal")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("565547ff-0fdf-442d-a994-eeb7af9ec9ab")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] public static class MyPluginInfo { public const string PLUGIN_GUID = "BetterLethal.Restart"; public const string PLUGIN_NAME = "BetterLethal.Restart"; public const string PLUGIN_VERSION = "1.0.0"; } 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 BetterLethal { [HarmonyPatch(typeof(HUDManager), "DisplayTip")] public static class DisplayTipPatch { public static bool Prefix(HUDManager __instance, string headerText, string bodyText, bool isWarning = false, bool useSave = false, string prefsKey = "LC_Tip1") { if (headerText.StartsWith("Mod List")) { return false; } return true; } } [BepInPlugin("BetterLethal", "BetterLethal", "1.0.0")] public class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("BetterLethal"); public static Plugin Instance; public static ManualLogSource mls; private void Awake() { mls = Logger.CreateLogSource("BetterLethal"); Instance = this; harmony.PatchAll(); mls.LogInfo((object)"Plugin BetterLethal (1.0.0) is loaded!"); } } public static class PluginInfo { private const string GUID = "BetterLethal"; private const string NAME = "BetterLethal"; private const string VERSION = "1.0.0"; } } namespace BetterLethal.Manager { internal static class HornManager { public static List<AudioClip> clips = new List<AudioClip>(); public static bool Loaded; public static int clipIndex = 0; private static bool canSwitch = true; public static event Action OnLoaded; public static void Load() { string[] directories = Directory.GetDirectories(Paths.PluginPath); string[] array = directories; foreach (string text in array) { string path = Path.Combine(Paths.PluginPath, "CustomHorn"); if (Directory.Exists(path)) { string[] files = Directory.GetFiles(path); if (files.Length < 1) { Plugin.mls.LogInfo((object)"No Horn Audio Found!"); break; } List<Coroutine> list = new List<Coroutine>(); string[] array2 = files; string[] array3 = array2; foreach (string filePath in array3) { Coroutine item = CorStarter.StartCoroutine(LoadAudioClip(filePath)); list.Add(item); } CorStarter.StartCoroutine(WaitForAllClips(list)); } } } private static IEnumerator WaitForAllClips(List<Coroutine> coroutines) { foreach (Coroutine coroutine in coroutines) { yield return coroutine; } Loaded = true; HornManager.OnLoaded?.Invoke(); } private static IEnumerator LoadAudioClip(string filePath) { Plugin.mls.LogInfo((object)("Loading " + filePath + "!")); if ((int)GetAudioType(filePath) == 0) { Plugin.mls.LogError((object)("Failed to load AudioClip from " + filePath + "\nUnsupported file extension!")); yield break; } UnityWebRequest loader = UnityWebRequestMultimedia.GetAudioClip(filePath, GetAudioType(filePath)); loader.SendWebRequest(); while (!loader.isDone) { yield return null; } if (loader.error != null) { Plugin.mls.LogError((object)("Error loading clip from path: " + filePath + "\n" + loader.error)); Plugin.mls.LogError((object)loader.error); yield break; } AudioClip dlClip = DownloadHandlerAudioClip.GetContent(loader); if (Object.op_Implicit((Object)(object)dlClip) && (int)dlClip.loadState == 2) { Plugin.mls.LogInfo((object)("Loaded " + filePath)); ((Object)dlClip).name = Path.GetFileName(filePath); clips.Add(dlClip); Plugin.mls.LogInfo((object)$"Clips loaded: {clips.Count()}"); } else { Plugin.mls.LogError((object)("Failed to load clip at: " + filePath + "\nThis might be due to an mismatch between the audio codec and the file extension!")); } } public static void ChangeClip(ShipAlarmCord __instance) { __instance.cordPullSFX = clips[0]; __instance.hornClose.clip = null; __instance.hornFar.clip = null; __instance.cordAudio.maxDistance = 155f; } public static void NextClip(ShipAlarmCord __instance) { if (canSwitch) { clipIndex++; if (clipIndex >= clips.Count) { clipIndex = 0; } __instance.cordPullSFX = clips[clipIndex]; Plugin.mls.LogInfo((object)$"Switched Clip to index {clipIndex}"); canSwitch = false; CorStarter.StartCoroutine(WaitToSwitch()); } } private static IEnumerator WaitToSwitch() { yield return (object)new WaitForSeconds(0.25f); canSwitch = true; } private static AudioType GetAudioType(string path) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) string text = Path.GetExtension(path).ToLower(); switch (text) { case ".wav": return (AudioType)20; case ".ogg": return (AudioType)14; case ".mp3": return (AudioType)13; default: Plugin.mls.LogError((object)("Unsupported extension type: " + text)); return (AudioType)0; } } } } namespace BetterLethal.Patches { [HarmonyPatch] public class ShipAlarmCordPatch { [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Awake")] private static void LoadAudio() { HornManager.Load(); } [HarmonyPostfix] [HarmonyPatch(typeof(ShipAlarmCord), "Start")] private static void ChangeShipAlarmCordSFX(ShipAlarmCord __instance) { if (HornManager.Loaded) { HornManager.ChangeClip(__instance); return; } HornManager.OnLoaded += delegate { HornManager.ChangeClip(__instance); }; } [HarmonyPrefix] [HarmonyPatch(typeof(ShipAlarmCord), "StopHorn")] private static void ActuallyStopHorn(ShipAlarmCord __instance) { __instance.cordAudio.Stop(); HornManager.NextClip(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(ShipAlarmCord), "HoldCordDown")] private static void LoopNewHornSFX(ShipAlarmCord __instance) { if (!__instance.cordAudio.isPlaying) { __instance.cordAudio.PlayOneShot(__instance.cordPullSFX); } } [HarmonyPostfix] [HarmonyPatch(typeof(ShipAlarmCord), "PullCordClientRpc")] private static void LoopNewHornSFXClient(ShipAlarmCord __instance) { if (!__instance.cordAudio.isPlaying) { __instance.cordAudio.PlayOneShot(__instance.cordPullSFX); } } [HarmonyPrefix] [HarmonyPatch(typeof(ShipAlarmCord), "StopPullingCordClientRpc")] private static void ActuallyStopHornClient(ShipAlarmCord __instance) { __instance.cordAudio.Stop(); HornManager.NextClip(__instance); } } internal class Patches { private static ManualLogSource Logger { get; set; } public static void Init(ManualLogSource logger) { Logger = logger; } } } namespace BetterLethal.Coroutines { public class CorStarter : MonoBehaviour { private static CorStarter Instance; public static Coroutine StartCoroutine(IEnumerator routine) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Instance == (Object)null) { Instance = new GameObject("Shared Coroutine Starter").AddComponent<CorStarter>(); Object.DontDestroyOnLoad((Object)(object)Instance); } return ((MonoBehaviour)Instance).StartCoroutine(routine); } } } namespace BetterLethal.Restart { [BepInPlugin("BetterLethal.Restart", "BetterLethal.Restart", "1.0.0")] public class Plugin : BaseUnityPlugin { public static bool verifying; private ConfigEntry<bool> overrideConfirmation; public static bool bypassConfirm; private Harmony harmony; private static MethodInfo chat; private void Awake() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown overrideConfirmation = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Override Confirmation", false, "Ignore the confirmation step of restarting."); bypassConfirm = overrideConfirmation.Value; harmony = new Harmony("BetterLethal.Restart"); harmony.PatchAll(); chat = AccessTools.Method(typeof(HUDManager), "AddChatMessage", (Type[])null, (Type[])null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BetterLethal.Restart loaded!"); } public static bool OverrideConfirmation() { return bypassConfirm = true; } public static void SendChatMessage(string message) { chat?.Invoke(HUDManager.Instance, new object[2] { message, "" }); HUDManager.Instance.lastChatMessage = ""; } public static void ConfirmRestart() { verifying = true; SendChatMessage("Are you sure? Type CONFIRM or DENY."); } public static void AcceptRestart(StartOfRound manager) { SendChatMessage("Restart confirmed."); verifying = false; int[] array = new int[4] { manager.gameStats.daysSpent, manager.gameStats.scrapValueCollected, manager.gameStats.deaths, manager.gameStats.allStepsTaken }; manager.FirePlayersAfterDeadlineClientRpc(array, false); } public static void DeclineRestart() { SendChatMessage("Restart aborted."); verifying = false; } } } namespace BetterLethal.Restart.Patches { [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] public class SubmitChat { private static bool Prefix(HUDManager __instance, ref CallbackContext context) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown if (!((CallbackContext)(ref context)).performed) { return true; } if (string.IsNullOrEmpty(__instance.chatTextField.text)) { return true; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; if ((Object)localPlayerController == (Object)null) { return true; } StartOfRound playersManager = localPlayerController.playersManager; if ((Object)playersManager == (Object)null) { return true; } string text = __instance.chatTextField.text; if (Plugin.verifying) { if (text.ToLower() == "confirm") { ResetTextbox(__instance, localPlayerController); if (!localPlayerController.isInHangarShipRoom || !playersManager.inShipPhase || playersManager.travellingToNewLevel) { Plugin.SendChatMessage("Cannot restart, ship must be in orbit."); return false; } Plugin.AcceptRestart(playersManager); return false; } if (text.ToLower() == "deny") { ResetTextbox(__instance, localPlayerController); Plugin.DeclineRestart(); return false; } return true; } if (text == "/restart" && text == "!restart") { ResetTextbox(__instance, localPlayerController); if (!GameNetworkManager.Instance.isHostingGame) { Plugin.SendChatMessage("Only the host can restart."); return false; } if (!localPlayerController.isInHangarShipRoom || !playersManager.inShipPhase || playersManager.travellingToNewLevel) { Plugin.SendChatMessage("Cannot restart, ship must be in orbit."); return false; } if (Plugin.bypassConfirm) { Plugin.AcceptRestart(playersManager); } else { Plugin.ConfirmRestart(); } return false; } return true; } private static void ResetTextbox(HUDManager manager, PlayerControllerB local) { local.isTypingChat = false; manager.chatTextField.text = ""; EventSystem.current.SetSelectedGameObject((GameObject)null); manager.PingHUDElement(manager.Chat, 2f, 1f, 0.2f); ((Behaviour)manager.typingIndicator).enabled = false; } } }