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 BossNotifier v1.0.7
plugins/BossNotifier/BossNotifier.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [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("BossNotifier")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.7.0")] [assembly: AssemblyInformationalVersion("1.0.7")] [assembly: AssemblyProduct("BossNotifier")] [assembly: AssemblyTitle("BossNotifier")] [assembly: AssemblyVersion("1.0.7.0")] [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 BossNotifier { [HarmonyPatch(typeof(EnemyDirector), "AmountSetup")] [HarmonyWrapSafe] public static class AmountSetupPatch { public static string? PendingMessage; private static bool _hasLoggedNames; [HarmonyPrefix] public static void Prefix(EnemyDirector __instance) { if (!PhotonNetwork.IsMasterClient) { return; } if (!_hasLoggedNames) { _hasLoggedNames = true; LogTier("Tier 1", __instance.enemiesDifficulty1); LogTier("Tier 2", __instance.enemiesDifficulty2); LogTier("Tier 3", __instance.enemiesDifficulty3); } if (Plugin.DisableLoom.Value && __instance.enemiesDifficulty3 != null) { int num = __instance.enemiesDifficulty3.RemoveAll((EnemySetup setup) => (Object)(object)setup != (Object)null && !string.IsNullOrEmpty(((Object)setup).name) && ((Object)setup).name.IndexOf("Shadow", StringComparison.OrdinalIgnoreCase) >= 0); if (num > 0) { Plugin.Log.LogInfo((object)$"Loom Toggle: removed {num} Loom (Shadow) entries from tier-3 pool."); } } } [HarmonyPostfix] public static void Postfix(EnemyDirector __instance) { if (!PhotonNetwork.IsMasterClient || !Plugin.ShowBossBanner.Value) { return; } List<EnemySetup> value = Traverse.Create((object)__instance).Field<List<EnemySetup>>("enemyList").Value; if (value == null || value.Count == 0) { return; } var list = (from e in value where (Object)(object)e != (Object)null && !string.IsNullOrEmpty(((Object)e).name) group e by PrettifyName(((Object)e).name) into g select new { Name = g.Key, Count = g.Count() } into x orderby x.Count descending, x.Name select x).ToList(); if (list.Count == 0) { return; } List<string> values = list.Select(x => (x.Count != 1) ? $"{x.Count} {Pluralize(x.Name)} Spawned" : (x.Name + " Spawned")).ToList(); string text = (PendingMessage = string.Join("\n", values)); Plugin.Log.LogInfo((object)("Spawn message queued (host): " + string.Join(", ", values))); if ((Object)(object)PunManager.instance != (Object)null) { PhotonView component = ((Component)PunManager.instance).GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null) { component.RPC("ReceiveBannerMessage", (RpcTarget)1, new object[1] { text }); Plugin.Log.LogInfo((object)"Banner RPC sent to clients."); } else { Plugin.Log.LogWarning((object)"PunManager has no PhotonView; clients won't receive banner."); } } else { Plugin.Log.LogWarning((object)"PunManager.instance is null; can't broadcast banner."); } } private static void LogTier(string label, List<EnemySetup>? list) { if (list == null) { Plugin.Log.LogInfo((object)(label + ": <null>")); return; } Plugin.Log.LogInfo((object)$"{label} ({list.Count} entries):"); foreach (EnemySetup item in list) { Plugin.Log.LogInfo((object)(" - " + (((Object)(object)item != (Object)null) ? ((Object)item).name : "<null setup>"))); } } private static string PrettifyName(string raw) { if (string.IsNullOrEmpty(raw)) { return "Unknown"; } string text = raw; int num = text.LastIndexOf('-'); if (num >= 0 && num < text.Length - 1) { text = text.Substring(num + 1).Trim(); } if (text.StartsWith("Enemy ", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(6).Trim(); } if (text == "Shadow") { return "Loom"; } return text; } private static string Pluralize(string name) { if (!(name == "Headman")) { if (name == "Huntsman") { return "Huntsmen"; } if (name.EndsWith("man", StringComparison.OrdinalIgnoreCase)) { return name.Substring(0, name.Length - 3) + "men"; } if (name.EndsWith("y", StringComparison.OrdinalIgnoreCase) && name.Length >= 2) { char value = name[name.Length - 2]; if (!"aeiouAEIOU".Contains(value)) { return name.Substring(0, name.Length - 1) + "ies"; } } if (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("z", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase)) { return name + "es"; } return name + "s"; } return "Headmen"; } } public class BannerRpcHandler : MonoBehaviour { public static BannerRpcHandler? Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)this); } else { Instance = this; } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } [PunRPC] public void ReceiveBannerMessage(string message) { Plugin.Log.LogInfo((object)("Received banner message via RPC: " + message.Replace('\n', '|'))); AmountSetupPatch.PendingMessage = message; } } public class BossBanner : MonoBehaviour { private Canvas? _canvas; private Text? _text; private GameObject? _bgGameObject; private float _hideAt; public static BossBanner? Instance { get; private set; } private void Awake() { Instance = this; BuildCanvas(); } private void BuildCanvas() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("BossNotifier_Canvas"); val.transform.SetParent(((Component)this).transform, false); val.layer = 5; _canvas = val.AddComponent<Canvas>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 32767; _canvas.overrideSorting = true; CanvasScaler obj = val.AddComponent<CanvasScaler>(); obj.uiScaleMode = (ScaleMode)0; obj.scaleFactor = 1f; val.AddComponent<GraphicRaycaster>(); _bgGameObject = new GameObject("Background"); _bgGameObject.transform.SetParent(val.transform, false); _bgGameObject.layer = 5; Image obj2 = _bgGameObject.AddComponent<Image>(); ((Graphic)obj2).color = new Color(0f, 0f, 0f, 0.75f); ((Graphic)obj2).raycastTarget = false; RectTransform component = _bgGameObject.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, -80f); component.sizeDelta = new Vector2(600f, 150f); GameObject val2 = new GameObject("Text"); val2.transform.SetParent(_bgGameObject.transform, false); val2.layer = 5; _text = val2.AddComponent<Text>(); _text.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); _text.fontSize = 28; _text.fontStyle = (FontStyle)1; _text.alignment = (TextAnchor)4; ((Graphic)_text).color = Color.white; _text.text = ""; ((Graphic)_text).raycastTarget = false; RectTransform component2 = ((Component)_text).GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = new Vector2(20f, 16f); component2.offsetMax = new Vector2(-20f, -16f); _bgGameObject.SetActive(false); } public void Show(string message, float seconds) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_text == (Object)null) && !((Object)(object)_bgGameObject == (Object)null)) { _text.text = message; int num = message.Split('\n').Length; float num2 = Mathf.Max(80f, 36f * (float)num + 32f); _bgGameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(600f, num2); _hideAt = Time.unscaledTime + seconds; _bgGameObject.SetActive(true); } } private void Update() { if ((Object)(object)_bgGameObject != (Object)null && _bgGameObject.activeSelf && Time.unscaledTime > _hideAt) { _bgGameObject.SetActive(false); } } } [HarmonyPatch(typeof(PlayerAvatar), "LoadingLevelAnimationCompletedRPC")] [HarmonyWrapSafe] public static class LoadingCompletePatch { [HarmonyPostfix] [HarmonyPriority(0)] public static void Postfix(PlayerAvatar __instance) { if ((Object)(object)__instance == (Object)null) { return; } PhotonView photonView = __instance.photonView; if (!((Object)(object)photonView == (Object)null) && photonView.IsMine && !string.IsNullOrEmpty(AmountSetupPatch.PendingMessage)) { string pendingMessage = AmountSetupPatch.PendingMessage; AmountSetupPatch.PendingMessage = null; if (!((Object)(object)BossBanner.Instance == (Object)null)) { BossBanner.Instance.Show(pendingMessage, Plugin.BannerDurationSeconds.Value); } } } } internal static class MyPluginInfo { public const string PLUGIN_GUID = "com.deegamenchill.bossnotifier"; public const string PLUGIN_NAME = "BossNotifier"; public const string PLUGIN_VERSION = "1.0.7"; } [BepInPlugin("com.deegamenchill.bossnotifier", "BossNotifier", "1.0.7")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<bool> DisableLoom; internal static ConfigEntry<bool> ShowBossBanner; internal static ConfigEntry<float> BannerDurationSeconds; private void Awake() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; DisableLoom = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawning", "DisableLoom", false, "If true (and you are the host), Loom will be removed from the spawn pool. Has no effect on non-host clients."); ShowBossBanner = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowSpawnBanner", true, "Show an on-screen banner at the start of each level listing every enemy that will spawn (with counts: e.g. \"2 Ducks Spawned\")."); BannerDurationSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "BannerDurationSeconds", 6f, "How long the spawn banner stays on screen."); new Harmony("com.deegamenchill.bossnotifier").PatchAll(); SceneManager.sceneLoaded += OnSceneLoaded; Log.LogInfo((object)"com.deegamenchill.bossnotifier v1.0.7 loaded."); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)BossBanner.Instance != (Object)null)) { GameObject val = new GameObject("BossNotifier_Host"); Object.DontDestroyOnLoad((Object)val); val.AddComponent<BossBanner>(); } } } [HarmonyPatch(typeof(PunManager), "Start")] [HarmonyWrapSafe] public static class PunManagerInitPatch { [HarmonyPostfix] public static void Postfix(PunManager __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).gameObject.GetComponent<BannerRpcHandler>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<BannerRpcHandler>(); Plugin.Log.LogInfo((object)"BannerRpcHandler attached to PunManager."); } } } }