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);
}
}
}
}