Decompiled source of BossRank v1.4.0

BepInEx/plugins/MaoNu.BossRank.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using FishNet.Object;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 BossRank
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "MaoNu.BossRank";

		public const string PLUGIN_NAME = "BossRank";

		public const string PLUGIN_VERSION = "1.4.0";
	}
	[BepInPlugin("MaoNu.BossRank", "BossRank", "1.4.0")]
	public class Plugin : BaseUnityPlugin
	{
		private ConfigEntry<bool> isBossNoticeEnabled;

		private ConfigEntry<bool> isBossRankEnabled;

		private ConfigEntry<bool> debugLogging;

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public bool IsBossNoticeEnabled
		{
			get
			{
				if (isBossNoticeEnabled != null)
				{
					return isBossNoticeEnabled.Value;
				}
				return false;
			}
		}

		public bool IsBossRankEnabled
		{
			get
			{
				if (isBossRankEnabled != null)
				{
					return isBossRankEnabled.Value;
				}
				return false;
			}
		}

		public bool DebugLogging
		{
			get
			{
				if (debugLogging != null)
				{
					return debugLogging.Value;
				}
				return false;
			}
		}

		public void LogInfo(string msg)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)msg);
		}

		public void LogWarning(string msg)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)msg);
		}

		public void LogError(string msg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)msg);
		}

		public void LogDebug(string msg)
		{
			if (DebugLogging)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)msg);
			}
		}

		private void Awake()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			Instance = this;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[BossRank] v1.4.0 loaded!");
			isBossNoticeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("提示设置", "BOSS出现提示", true, "BOSS出现时是否在聊天窗提示");
			isBossRankEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("提示设置", "BOSS战报", true, "BOSS死亡后是否在聊天窗显示伤害战报");
			debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("调试设置", "详细日志", true, "输出详细调试日志(排查问题用)");
			_harmony = new Harmony("MaoNu.BossRank.Patches");
			TryPatch(typeof(BossManager), "InitializeBossFight", null, "BossSpawnPostfix", "BOSS出现提示");
			TryPatch(typeof(Creature), "LocalHit", null, "CreatureLocalHitPostfix", "BOSS伤害统计");
			TryPatch(typeof(BossManager), "OnBossDeath", null, "BossDeathPostfix", "BOSS战报");
			TryPatch(typeof(PlayerManager), "OnPlayerDied", null, "OnPlayerDiedPostfix", "被击倒统计");
			TryPatchWithPrefixPostfix(typeof(PlayerDying), "ResurrectEffect", "ResurrectPrefix", "ResurrectPostfix", "被救统计");
		}

		private void TryPatch(Type targetType, string methodName, string postfixName, string postfixName2, string logTag)
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null) ?? AccessTools.Method(targetType, methodName, Type.EmptyTypes, (Type[])null);
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[" + logTag + "] 找不到 " + targetType.Name + "." + methodName));
					return;
				}
				MethodInfo methodInfo2 = ((postfixName != null) ? AccessTools.Method(typeof(BossRankPatch), postfixName, (Type[])null, (Type[])null) : AccessTools.Method(typeof(BossRankPatch), postfixName2, (Type[])null, (Type[])null));
				if (methodInfo2 == null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("[" + logTag + "] 找不到 " + (postfixName ?? postfixName2) + " 方法"));
				}
				else
				{
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("[" + logTag + "] " + targetType.Name + "." + methodName + " 补丁安装成功"));
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[" + logTag + "] " + ex.Message));
			}
		}

		private void TryPatchWithPrefixPostfix(Type targetType, string methodName, string prefixName, string postfixName, string logTag)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_00ed: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[" + logTag + "] 找不到 " + targetType.Name + "." + methodName));
					return;
				}
				MethodInfo methodInfo2 = AccessTools.Method(typeof(BossRankPatch), prefixName, (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(BossRankPatch), postfixName, (Type[])null, (Type[])null);
				if (methodInfo2 == null || methodInfo3 == null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("[" + logTag + "] 找不到 " + prefixName + "/" + postfixName));
				}
				else
				{
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("[" + logTag + "] " + targetType.Name + "." + methodName + " 补丁安装成功"));
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[" + logTag + "] " + ex.Message));
			}
		}

		private void OnDestroy()
		{
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}
	}
	internal struct PlayerBossStats
	{
		public int TotalDamage;

		public int HitCount;

		public int DownedCount;

		public int RevivedCount;
	}
	internal static class BossStats
	{
		public static readonly Dictionary<ulong, PlayerBossStats> Data = new Dictionary<ulong, PlayerBossStats>();

		public static void Reset()
		{
			Data.Clear();
		}

		public static void AddDamage(ulong steamID, int damage)
		{
			if (steamID != 0L)
			{
				if (!Data.ContainsKey(steamID))
				{
					Data[steamID] = default(PlayerBossStats);
				}
				PlayerBossStats value = Data[steamID];
				value.TotalDamage += damage;
				value.HitCount++;
				Data[steamID] = value;
			}
		}

		public static void AddDowned(ulong steamID)
		{
			if (steamID != 0L)
			{
				if (!Data.ContainsKey(steamID))
				{
					Data[steamID] = default(PlayerBossStats);
				}
				PlayerBossStats value = Data[steamID];
				value.DownedCount++;
				Data[steamID] = value;
			}
		}

		public static void AddRevived(ulong steamID)
		{
			if (steamID != 0L)
			{
				if (!Data.ContainsKey(steamID))
				{
					Data[steamID] = default(PlayerBossStats);
				}
				PlayerBossStats value = Data[steamID];
				value.RevivedCount++;
				Data[steamID] = value;
			}
		}
	}
	internal static class BossRankPatch
	{
		public static void BossSpawnPostfix(Creature creature)
		{
			if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.Instance.IsBossNoticeEnabled || !((Object)(object)Server.Instance != (Object)null) || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				return;
			}
			BossStats.Reset();
			string text = (((Object)(object)creature == (Object)null || string.IsNullOrEmpty(((Item)creature).GetName())) ? "首领" : ((Item)creature).GetName());
			ulong steamID = 0uL;
			try
			{
				if ((Object)(object)creature != (Object)null && (Object)(object)((Item)creature).AttachedRod != (Object)null && (Object)(object)((Item)((Item)creature).AttachedRod).Holder != (Object)null)
				{
					steamID = ((Item)((Item)creature).AttachedRod).Holder.SteamID;
				}
			}
			catch
			{
			}
			SendSystemMessage(steamID, "【BOSS】" + text + " 首领出现,请做好应战准备!");
		}

		public static void CreatureLocalHitPostfix(Creature __instance, Player player, int damage)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsBossRankEnabled && !((Object)(object)__instance == (Object)null) && (int)__instance.BossType != 0 && !__instance.IsDead && !((Object)(object)player == (Object)null))
			{
				ulong num = 0uL;
				try
				{
					num = player.SteamID;
				}
				catch
				{
				}
				if (num != 0L)
				{
					BossStats.AddDamage(num, damage);
					Plugin.Instance.LogDebug($"[BOSS伤害] {player.SteamName} +{damage} (BOSS HP={__instance.Hp})");
				}
			}
		}

		public static void BossDeathPostfix()
		{
			if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.Instance.IsBossRankEnabled || !((Object)(object)Server.Instance != (Object)null) || !((NetworkBehaviour)Server.Instance).IsServerInitialized)
			{
				return;
			}
			if (BossStats.Data.Count == 0)
			{
				SendSystemMessage(0uL, "首领伤害排行榜:无伤害记录");
				return;
			}
			List<KeyValuePair<ulong, PlayerBossStats>> list = BossStats.Data.OrderByDescending((KeyValuePair<ulong, PlayerBossStats> kv) => kv.Value.TotalDamage).ToList();
			ulong steamID = 0uL;
			try
			{
				if ((Object)(object)Player.LocalPlayer != (Object)null)
				{
					steamID = Player.LocalPlayer.SteamID;
				}
			}
			catch
			{
			}
			SendSystemMessage(steamID, "首领伤害排行榜:");
			int num = 1;
			foreach (KeyValuePair<ulong, PlayerBossStats> item in list)
			{
				ulong key = item.Key;
				Player val = FindPlayerBySteamID(key);
				string message = $"#{num} 伤害 {item.Value.TotalDamage}  命中 {item.Value.HitCount}  被击倒 {item.Value.DownedCount}  被救 {item.Value.RevivedCount}";
				if ((Object)(object)val == (Object)null)
				{
					SendSystemMessage(0uL, message);
				}
				else
				{
					SendSystemMessage(key, message);
				}
				num++;
			}
		}

		public static void OnPlayerDiedPostfix(Player player)
		{
			if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Instance.IsBossRankEnabled && !((Object)(object)player == (Object)null) && (Object)(object)Server.Instance != (Object)null && ((NetworkBehaviour)Server.Instance).IsServerInitialized && !((Object)(object)BossManager.Boss == (Object)null))
			{
				ulong num = 0uL;
				try
				{
					num = player.SteamID;
				}
				catch
				{
				}
				if (num != 0L)
				{
					BossStats.AddDowned(num);
					Plugin.Instance.LogDebug("[被击倒] " + player.SteamName + " (BOSS战期间)");
				}
			}
		}

		public static void ResurrectPrefix(PlayerDying __instance, out bool __state)
		{
			__state = (Object)(object)__instance != (Object)null && __instance.IsDead;
		}

		public static void ResurrectPostfix(PlayerDying __instance, bool respawned, bool __state)
		{
			if ((Object)(object)Plugin.Instance == (Object)null || !Plugin.Instance.IsBossRankEnabled || (Object)(object)__instance == (Object)null || !__state || !((Object)(object)Server.Instance != (Object)null) || !((NetworkBehaviour)Server.Instance).IsServerInitialized || (Object)(object)BossManager.Boss == (Object)null)
			{
				return;
			}
			Player val = null;
			try
			{
				val = AccessTools.FieldRefAccess<PlayerDying, Player>("_player").Invoke(__instance);
			}
			catch (Exception ex)
			{
				Plugin.Instance.LogWarning("[被救统计] 获取 _player 失败: " + ex.Message);
				return;
			}
			if (!((Object)(object)val == (Object)null))
			{
				ulong num = 0uL;
				try
				{
					num = val.SteamID;
				}
				catch
				{
				}
				if (num != 0L && !respawned)
				{
					BossStats.AddRevived(num);
					Plugin.Instance.LogDebug("[被救] " + val.SteamName + " (BOSS战期间)");
				}
			}
		}

		private static Player FindPlayerBySteamID(ulong steamID)
		{
			try
			{
				foreach (Player player in PlayerManager.Players)
				{
					if ((Object)(object)player != (Object)null && player.SteamID == steamID)
					{
						return player;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static void SendSystemMessage(ulong steamID, string message)
		{
			if ((Object)(object)Plugin.Instance == (Object)null)
			{
				return;
			}
			try
			{
				OnlineChatManager instance = OnlineChatManager.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SendChatMessage(steamID, message);
					Plugin.Instance.LogDebug($"[系统消息] steamID={steamID} {message}");
				}
				else
				{
					Plugin.Instance.LogWarning("[系统消息] OnlineChatManager.Instance 为 null");
				}
			}
			catch (Exception ex)
			{
				Plugin.Instance.LogWarning("[系统消息] 发送失败: " + ex.Message);
			}
		}
	}
}