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 Hitmarker v1.2.3
com.github.zehsteam.Hitmarker.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.UI; using com.github.zehsteam.Hitmarker.MonoBehaviours; using com.github.zehsteam.Hitmarker.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.zehsteam.Hitmarker")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Shows a hitmarker when you successfully hit an enemy. With additional features. (Client-side)")] [assembly: AssemblyFileVersion("1.2.3.0")] [assembly: AssemblyInformationalVersion("1.2.3+9f550c00a965039c6c13c3bda8cf3750925b11f7")] [assembly: AssemblyProduct("Hitmarker")] [assembly: AssemblyTitle("com.github.zehsteam.Hitmarker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.3.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 com.github.zehsteam.Hitmarker { internal class ConfigManager { public ConfigEntry<bool> ExtendedLogging { get; private set; } public ConfigEntry<bool> ShowHitmarkerImage { get; private set; } public ConfigEntry<int> HitmarkerImageSize { get; private set; } public ConfigEntry<bool> PlayHitmarkerSound { get; private set; } public ConfigEntry<float> MessageDuration { get; private set; } public ConfigEntry<int> MessageFontSize { get; private set; } public ConfigEntry<bool> ShowDamageMessage { get; private set; } public ConfigEntry<bool> ShowKillMessage { get; private set; } public ConfigEntry<bool> OnlyShowLocalKillMessage { get; private set; } public ConfigManager() { BindConfigs(); ClearUnusedEntries(); } private void BindConfigs() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown ConfigFile config = ((BaseUnityPlugin)Plugin.Instance).Config; ExtendedLogging = config.Bind<bool>("General Settings", "ExtendedLogging", false, "Enable extended logging."); ShowHitmarkerImage = config.Bind<bool>("Hitmarker Settings", "ShowHitmarkerImage", true, "Do you want to show the hitmarker image?"); HitmarkerImageSize = config.Bind<int>("Hitmarker Settings", "HitmarkerImageSize", 40, new ConfigDescription("The size of the hitmarker image in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())); PlayHitmarkerSound = config.Bind<bool>("Hitmarker Settings", "PlayHitmarkerSound", true, "Do you want to play the hitmarker sound?"); MessageDuration = config.Bind<float>("Message Settings", "MessageDuration", 4f, "The message duration in seconds."); MessageFontSize = config.Bind<int>("Message Settings", "MessageFontSize", 35, new ConfigDescription("The message font size in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>())); ShowDamageMessage = config.Bind<bool>("Message Settings", "ShowDamageMessage", true, "Shows a message of how much damage you did to an enemy."); ShowKillMessage = config.Bind<bool>("Message Settings", "ShowKillMessage", true, "Shows a message when an enemy is killed."); OnlyShowLocalKillMessage = config.Bind<bool>("Message Settings", "OnlyShowLocalKillMessage", true, "Will only show your kill messages."); } private void ClearUnusedEntries() { ConfigFile config = ((BaseUnityPlugin)Plugin.Instance).Config; PropertyInfo property = ((object)config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(config, null); dictionary.Clear(); config.Save(); } } internal class Content { public static GameObject HitmarkerCanvasPrefab; public static void Load() { LoadAssetsFromAssetBundle(); } private static void LoadAssetsFromAssetBundle() { try { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location); string text = Path.Combine(directoryName, "hitmarker_assets"); AssetBundle val = AssetBundle.LoadFromFile(text); HitmarkerCanvasPrefab = val.LoadAsset<GameObject>("HitmarkerCanvas"); Plugin.logger.LogInfo((object)"Successfully loaded assets from AssetBundle!"); } catch (Exception arg) { Plugin.logger.LogError((object)$"Error: failed to load assets from AssetBundle.\n\n{arg}"); } } } [BepInPlugin("com.github.zehsteam.Hitmarker", "Hitmarker", "1.2.3")] internal class Plugin : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("com.github.zehsteam.Hitmarker"); internal static Plugin Instance; internal static ManualLogSource logger; internal static ConfigManager ConfigManager; internal static bool IsHostOrServer => NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } logger = Logger.CreateLogSource("com.github.zehsteam.Hitmarker"); logger.LogInfo((object)"Hitmarker has awoken!"); harmony.PatchAll(typeof(HUDManagerPatch)); harmony.PatchAll(typeof(EnemyAIPatch)); ConfigManager = new ConfigManager(); Content.Load(); } public void CreateHitmarkerCanvas() { if (!((Object)(object)HitmarkerCanvasBehaviour.Instance != (Object)null)) { Object.Instantiate<GameObject>(Content.HitmarkerCanvasPrefab); logger.LogInfo((object)"Instantiated Hitmarker canvas."); } } public void LogInfoExtended(object data) { if (ConfigManager.ExtendedLogging.Value) { logger.LogInfo(data); } } } internal class Utils { public static bool IsLocalPlayer(PlayerControllerB playerScript) { return (Object)(object)StartOfRound.Instance.localPlayerController == (Object)(object)playerScript; } public static PlayerControllerB GetPlayerScript(int playerWhoHit) { if (playerWhoHit < 0 || playerWhoHit > StartOfRound.Instance.allPlayerScripts.Length - 1) { return null; } return StartOfRound.Instance.allPlayerScripts[playerWhoHit]; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.Hitmarker"; public const string PLUGIN_NAME = "Hitmarker"; public const string PLUGIN_VERSION = "1.2.3"; } } namespace com.github.zehsteam.Hitmarker.Patches { [HarmonyPatch(typeof(EnemyAI))] internal class EnemyAIPatch { [HarmonyPatch("HitEnemyOnLocalClient")] [HarmonyPrefix] private static void HitEnemyOnLocalClientPatch(ref EnemyAI __instance, int force, PlayerControllerB playerWhoHit = null) { if (!((Object)(object)playerWhoHit == (Object)null) && Utils.IsLocalPlayer(playerWhoHit)) { HitEnemy(__instance, force, playerWhoHit); } } [HarmonyPatch("HitEnemyServerRpc")] [HarmonyPrefix] private static void HitEnemyServerRpcPatch(ref EnemyAI __instance, int force, int playerWhoHit) { if (playerWhoHit != -1) { PlayerControllerB playerScript = Utils.GetPlayerScript(playerWhoHit); if (!Utils.IsLocalPlayer(playerScript)) { HitEnemy(__instance, force, playerScript); } } } [HarmonyPatch("HitEnemyClientRpc")] [HarmonyPrefix] private static void HitEnemyClientRpcPatch(ref EnemyAI __instance, int force, int playerWhoHit) { if (playerWhoHit != -1 && !Plugin.IsHostOrServer) { PlayerControllerB playerScript = Utils.GetPlayerScript(playerWhoHit); if (!Utils.IsLocalPlayer(playerScript)) { HitEnemy(__instance, force, playerScript); } } } private static void HitEnemy(EnemyAI enemyAI, int force, PlayerControllerB playerWhoHit) { if (enemyAI.enemyType.canDie && !enemyAI.isEnemyDead && enemyAI.enemyHP > 0) { bool flag = Utils.IsLocalPlayer(playerWhoHit); string enemyName = enemyAI.enemyType.enemyName; bool flag2 = enemyAI.enemyHP - force <= 0; if (flag) { HitmarkerCanvasBehaviour.Instance.ShowHitmarker(flag2); HitmarkerCanvasBehaviour.Instance.ShowDamageMessage(enemyName, force); } if (flag2) { HitmarkerCanvasBehaviour.Instance.ShowKillMessage(enemyName, flag, playerWhoHit.playerUsername); } LogInfoExtended("HitEnemy();", enemyAI, force, playerWhoHit); } } private static void LogInfoExtended(string functionName, EnemyAI enemyAI, int force, PlayerControllerB playerWhoHit) { NetworkObject component = ((Component)enemyAI).gameObject.GetComponent<NetworkObject>(); string text = (Utils.IsLocalPlayer(playerWhoHit) ? " (LOCAL)" : ""); string text2 = $"{functionName} NetworkObjectId: {component.NetworkObjectId}\n\n"; text2 += $"Player \"{playerWhoHit.playerUsername}\"{text} hit \"{enemyAI.enemyType.enemyName}\" for {force} force.\n"; text2 += $"isEnemyDead: {enemyAI.isEnemyDead}, enemyHP: {enemyAI.enemyHP}, (new enemyHP should be {enemyAI.enemyHP - force})\n"; Plugin.Instance.LogInfoExtended("\n\n" + text2.Trim() + "\n"); } } [HarmonyPatch(typeof(HUDManager))] internal class HUDManagerPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { Plugin.Instance.CreateHitmarkerCanvas(); } } } namespace com.github.zehsteam.Hitmarker.MonoBehaviours { public class HitmarkerCanvasBehaviour : MonoBehaviour { public static HitmarkerCanvasBehaviour Instance; public HitmarkerImageBehaviour HitmarkerImageBehaviour; public AudioClip HitSFX; public RectTransform MessageListTransform; public RectTransform MessageItemPrefab; private Queue<RectTransform> _messageItemPool = new Queue<RectTransform>(); private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } } private void Start() { InitializeMessageItemPool(); } private void InitializeMessageItemPool() { _messageItemPool = new Queue<RectTransform>(); for (int i = 0; i < 20; i++) { RectTransform val = Object.Instantiate<RectTransform>(MessageItemPrefab, (Transform)(object)MessageListTransform); ((Component)val).gameObject.SetActive(false); _messageItemPool.Enqueue(val); } } public void ShowHitmarker(bool killed = false) { ShowHitmarkerImage(killed); PlayHitSFX(); } private void ShowHitmarkerImage(bool killed = false) { if (Plugin.ConfigManager.ShowHitmarkerImage.Value) { HitmarkerImageBehaviour.ShowImage(killed); } } private void PlayHitSFX() { if (Plugin.ConfigManager.PlayHitmarkerSound.Value) { HUDManager.Instance.UIAudio.PlayOneShot(HitSFX); } } public void ShowDamageMessage(string enemyName, int damage = 1) { if (Plugin.ConfigManager.ShowDamageMessage.Value) { ShowMessage($"{enemyName} -{damage} HP"); } } public void ShowKillMessage(string enemyName, bool fromLocalPlayer = true, string fromPlayerName = "") { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (Plugin.ConfigManager.ShowKillMessage.Value && (fromLocalPlayer || !Plugin.ConfigManager.OnlyShowLocalKillMessage.Value)) { if (!fromLocalPlayer) { ShowMessage(fromPlayerName + " Killed " + enemyName, Color.red); } else { ShowMessage("Killed " + enemyName, Color.red); } } } private void ShowMessage(string text) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) ShowMessage(text, Color.white); } private void ShowMessage(string text, Color color) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) SpawnMessageItemFromPool(text, color); } private RectTransform SpawnMessageItemFromPool(string text, Color color) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (_messageItemPool == null || _messageItemPool.Count == 0) { Plugin.logger.LogError((object)"Error: Failed to spawn message item from pool. Message item pool is either null or empty."); return null; } RectTransform val = _messageItemPool.Dequeue(); ((Component)val).gameObject.SetActive(true); ((Transform)val).SetAsLastSibling(); MessageItemBehaviour messageItemBehaviour = default(MessageItemBehaviour); if (((Component)val).TryGetComponent<MessageItemBehaviour>(ref messageItemBehaviour)) { messageItemBehaviour.SetText(text, color); } _messageItemPool.Enqueue(val); return val; } } public class HitmarkerImageBehaviour : MonoBehaviour { public Image Image; public Color32 DefaultColor; public Color32 KilledColor; private Coroutine _fadeOutCoroutine; private void Start() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) int value = Plugin.ConfigManager.HitmarkerImageSize.Value; ((Graphic)Image).rectTransform.sizeDelta = new Vector2((float)value, (float)value); SetAlpha(0f); } public void ShowImage(bool killed = false) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) ((Graphic)Image).color = Color32.op_Implicit(killed ? KilledColor : DefaultColor); if (_fadeOutCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_fadeOutCoroutine); } _fadeOutCoroutine = ((MonoBehaviour)this).StartCoroutine(FadeOut(0.25f)); } private IEnumerator FadeOut(float duration) { SetAlpha(255f); for (float timer = 0f; timer < duration; timer += Time.deltaTime) { float percent = 1f / duration * timer; float alpha = 255f + -255f * percent; SetAlpha(alpha); yield return null; } SetAlpha(0f); } private void SetAlpha(float a) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) a = Mathf.Clamp(a, 0f, 255f); Color32 val = Color32.op_Implicit(((Graphic)Image).color); val.a = (byte)a; ((Graphic)Image).color = Color32.op_Implicit(val); } } public class MessageItemBehaviour : MonoBehaviour { public TextMeshProUGUI TextUGUI; private Coroutine _animationCoroutine; private void Start() { ((TMP_Text)TextUGUI).fontSize = Plugin.ConfigManager.MessageFontSize.Value; } private void OnEnable() { if (_animationCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_animationCoroutine); } _animationCoroutine = ((MonoBehaviour)this).StartCoroutine(PlayAnimation()); } private void OnDisable() { if (_animationCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_animationCoroutine); } } private IEnumerator PlayAnimation() { yield return (object)new WaitForSeconds(Plugin.ConfigManager.MessageDuration.Value); float fadeOutDuration = 1f; SetAlpha(255f); for (float timer = 0f; timer < fadeOutDuration; timer += Time.deltaTime) { float percent = 1f / fadeOutDuration * timer; float alpha = 255f + -255f * percent; SetAlpha(alpha); yield return null; } SetAlpha(0f); yield return null; ((Component)this).gameObject.SetActive(false); } public void SetText(string text) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) SetText(text, Color.white); } public void SetText(string text, Color color) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)TextUGUI).text = text; ((Graphic)TextUGUI).color = color; } private void SetAlpha(float a) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) a = Mathf.Clamp(a, 0f, 255f); Color32 val = Color32.op_Implicit(((Graphic)TextUGUI).color); val.a = (byte)a; ((Graphic)TextUGUI).color = Color32.op_Implicit(val); } } }