Decompiled source of BetterLethal v1.0.0

BepInEx/plugins/BetterLethal.dll

Decompiled 2 years ago
using 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;
		}
	}
}