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 StunDisplay v0.1.0
StunDisplay.dll
Decompiled 6 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CanvasUtil; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using Microsoft.CodeAnalysis; using TeamCherry.Localization; using UnityEngine; 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("StunDisplay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+f897177a31604af2dd50165940e0c61825579d31")] [assembly: AssemblyProduct("StunDisplay")] [assembly: AssemblyTitle("StunDisplay")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Clazex/Silksong.StunDisplay")] [assembly: NeutralResourcesLanguage("EN")] [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 StunDisplay { internal static class Configs { internal static ConfigEntry<TextAnchor> Location { get; private set; } internal static ConfigEntry<int> FontSize { get; private set; } internal static ConfigEntry<float> Padding { get; private set; } internal static void Bind(ConfigFile config) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown Location = config.Bind<TextAnchor>("Style", "Location", (TextAnchor)7, "Location of the text"); FontSize = config.Bind<int>("Style", "FontSize", 24, new ConfigDescription("Font size", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 48), Array.Empty<object>())); Padding = config.Bind<float>("Style", "Padding", 10f, new ConfigDescription("Padding", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 40f), Array.Empty<object>())); } } internal sealed class EnemyStunInfo { private readonly HealthManager hm; private readonly Fsm stunFsm; private bool initialHiding = true; private readonly FsmFloat hit = FsmFloat.op_Implicit(0f); private readonly int max; private readonly int comboMax; private readonly float comboTime; private readonly Wait comboWait; private readonly bool hasComboBonus = true; private readonly LocalisedString? name; private StunState State { get { switch (stunFsm.ActiveStateName) { case "In Combo": case "Continue Combo": return StunState.InCombo; case "Stun End": case "Stun": case "Dazed Effect": case "Stunned": case "Quick End": return StunState.Stunned; case "Stop": case "Stop Daze Effect 2": case "Stop Daze Effect 3": case "Unstun Increment": case "Reset": return StunState.Disabled; default: return StunState.Idle; } } } private float ComboTimeLeft { get { if (State != StunState.InCombo) { return 0f; } return comboTime - comboWait.timer; } } internal bool IsDead { get { if (!((Object)(object)hm == (Object)null)) { return hm.isDead; } return true; } } internal EnemyStunInfo(HealthManager hm) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) this.hm = hm; stunFsm = hm.stunControlFsm.Fsm; FsmVariables variables = stunFsm.Variables; hit = variables.GetFsmFloat("Hits Total"); max = variables.GetFsmInt("Stun Hit Max").Value; comboMax = variables.GetFsmInt("Stun Combo").Value; comboTime = variables.GetFsmFloat("Combo Time").Value; comboWait = (Wait)stunFsm.GetState("In Combo").Actions[4]; hasComboBonus = comboMax != max; if ((Object)(object)hm.enemyDeathEffects != (Object)null && (Object)(object)hm.enemyDeathEffects.journalRecord != (Object)null) { name = hm.enemyDeathEffects.journalRecord.DisplayName; } } internal bool CheckInitialHiding() { if (!initialHiding) { return false; } if (!hm.IsInvincible) { return initialHiding = false; } return true; } internal StringBuilder BuildString(StringBuilder sb, bool includeName = false) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (includeName) { string? value; if (!name.HasValue) { value = ((Object)hm).name; } else { LocalisedString value2 = name.Value; value = ((object)(LocalisedString)(ref value2)).ToString(); } sb.Append(value).Append(' '); } sb.Append(Lang.Stun).Append(Lang.Colon).AppendFormat("{0:F2}", hit) .Append('/') .Append(max); if (hasComboBonus) { sb.Append(' ').Append(Lang.Combo).Append(Lang.Colon) .Append(comboMax) .Append(' ') .AppendFormat("{0:F2}", ComboTimeLeft) .Append('/') .Append(comboTime); } switch (State) { case StunState.Stunned: sb.Append(Lang.StunStateStunned); break; case StunState.Disabled: sb.Append(Lang.StunStateDisabled); break; } return sb; } public override string ToString() { return BuildString(new StringBuilder(), includeName: true).ToString(); } } internal static class Lang { internal static string Colon => Get("Colon"); internal static string Stun => Get("Stun"); internal static string Combo => Get("Combo"); internal static string StunStateStunned => Get("StunStateStunned"); internal static string StunStateDisabled => Get("StunStateDisabled"); private static string Get(string key) { return Language.Get(key, "Mods.dev.clazex.stundisplay"); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("dev.clazex.stundisplay", "StunDisplay", "0.1.0")] public sealed class StunDisplayPlugin : BaseUnityPlugin { public const string Id = "dev.clazex.stundisplay"; public static StunDisplayPlugin Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } private Harmony Harmony { get; } = new Harmony("dev.clazex.stundisplay"); public static string Name => "StunDisplay"; public static string Version => "0.1.0"; private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; Configs.Bind(((BaseUnityPlugin)this).Config); Harmony.PatchAll(typeof(StunDisplayPlugin)); Logger.LogInfo((object)("Plugin " + Name + " (dev.clazex.stundisplay) v" + Version + " has loaded!")); } private void OnDestroy() { Logger.LogWarning((object)"Unloading in release build"); Harmony.UnpatchSelf(); Logger.LogInfo((object)("Plugin " + Name + " (dev.clazex.stundisplay) v" + Version + " has unloaded!")); } [HarmonyPatch(typeof(HeroController), "Start")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Setup() { StunHud.Setup(); } [HarmonyPatch(typeof(HealthManager), "Start")] [HarmonyWrapSafe] [HarmonyPostfix] private static void AddEnemy(HealthManager __instance) { if (!__instance.isDead && Object.op_Implicit((Object)(object)__instance.stunControlFsm)) { StunHud.AddEnemy(__instance); } } } [RequireComponent(typeof(RectTransform), typeof(Text))] internal sealed class StunHud : MonoBehaviour { [CompilerGenerated] private sealed class <>c__DisplayClass8_0 { public GameManager gm; internal bool <AddEnemyCoro>b__0() { return gm.HasFinishedEnteringScene; } } [CompilerGenerated] private sealed class <AddEnemyCoro>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public HealthManager hm; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AddEnemyCoro>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)new <>c__DisplayClass8_0 { gm = GameManager.instance }.<AddEnemyCoro>b__0); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; enemies.Add(new EnemyStunInfo(hm)); StunDisplayPlugin.Logger.LogDebug((object)("Adding enemy: " + ((Object)hm).name)); RemoveDeadEnemy(); 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(); } } private static StunHud? instance = null; private static readonly List<EnemyStunInfo> enemies = new List<EnemyStunInfo>(); private RectTransform rt; private Text text; internal static StunHud Instance { get { if (!((Object)(object)instance != (Object)null)) { throw new InvalidOperationException("instance not present"); } return instance; } } private static bool MultiEnemies => enemies.Count > 1; internal static void Setup() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_006e: Expected O, but got Unknown if ((Object)(object)instance != (Object)null) { StunDisplayPlugin.Logger.LogDebug((object)"HUD already existed"); return; } StunDisplayPlugin.Logger.LogDebug((object)"Creating HUD"); GameObject obj = CanvasUtil.CreateCanvas((RenderMode)0, new Vector2(1920f, 1080f)); ((Object)obj).name = "Stun Display HUD"; Object.DontDestroyOnLoad((Object)(object)obj); GameObject obj2 = CanvasUtil.CreateTextPanel(obj, "", 1, (TextAnchor)7, new RectData(Vector2.zero, Vector2.zero), false); ((Object)obj2).name = "Text Panel"; obj2.AddComponent<StunHud>(); } internal static void AddEnemy(HealthManager hm) { ((MonoBehaviour)Instance).StartCoroutine(AddEnemyCoro(hm)); } [IteratorStateMachine(typeof(<AddEnemyCoro>d__8))] private static IEnumerator AddEnemyCoro(HealthManager hm) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AddEnemyCoro>d__8(0) { hm = hm }; } private static void RemoveDeadEnemy() { enemies.RemoveAll((EnemyStunInfo i) => i.IsDead); } private void Awake() { instance = this; rt = ((Component)this).GetComponent<RectTransform>(); text = ((Component)this).GetComponent<Text>(); UpdateStyles(); } private void Update() { UpdateStyles(); GameManager unsafeInstance = GameManager.UnsafeInstance; if ((Object)(object)unsafeInstance == (Object)null) { enemies.Clear(); } else { if (unsafeInstance.IsGamePaused()) { return; } RemoveDeadEnemy(); StringBuilder stringBuilder = new StringBuilder(); EnemyStunInfo enemyStunInfo = enemies.FirstOrDefault(); if (enemyStunInfo != null && !enemyStunInfo.CheckInitialHiding()) { enemyStunInfo.BuildString(stringBuilder, MultiEnemies); } foreach (EnemyStunInfo item in enemies.Skip(1)) { if (!item.CheckInitialHiding()) { stringBuilder.Append('\t'); item.BuildString(stringBuilder, includeName: true); } } text.text = stringBuilder.ToString(); } } private void UpdateStyles() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) text.alignment = Configs.Location.Value; text.fontSize = Configs.FontSize.Value; Vector2 val = new Vector2((float)Screen.width, (float)Screen.height) * 1920f / (float)Screen.width; rt.sizeDelta = val - 2f * Configs.Padding.Value * Vector2.one; } } internal enum StunState { Idle, InCombo, Stunned, Disabled } }