Decompiled source of SleeperAlert v1.4.2

SleeperAlert\SleeperAlert.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Enemies;
using GameData;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Player;
using SNetwork;
using UnityEngine;

[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("SleeperAlert")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SleeperAlert")]
[assembly: AssemblyTitle("SleeperAlert")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SleeperAlert;

[HarmonyPatch(typeof(PlayerChatManager), "PostChatMessageLocaly")]
internal static class ChatMessagePatch
{
	private static void Postfix(SNet_Player fromPlayer, string message, SNet_Player toPlayer)
	{
		try
		{
			WakeReporter.OnChatMessageDisplayed(message);
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 处理聊天消息时出错: " + ex));
			}
		}
	}
}
internal struct DamageSnapshot
{
	public float HealthBefore;
}
internal static class FriendlyFireUtil
{
	public static float SafeHealth(Dam_PlayerDamageBase damageBase)
	{
		try
		{
			return ((Dam_SyncedDamageBase)damageBase).Health;
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 读取血量失败: " + ex.Message));
			}
			return 0f;
		}
	}
}
[HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveBulletDamage")]
internal static class BulletFriendlyFirePatch
{
	private static void Prefix(Dam_PlayerDamageBase __instance, ref DamageSnapshot __state)
	{
		__state = new DamageSnapshot
		{
			HealthBefore = FriendlyFireUtil.SafeHealth(__instance)
		};
	}

	private static void Postfix(Dam_PlayerDamageBase __instance, pBulletDamageData data, DamageSnapshot __state)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		FriendlyFireReporter.OnPlayerDamaged(__instance, data.source, __state);
	}
}
[HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveMeleeDamage")]
internal static class MeleeFriendlyFirePatch
{
	private static void Prefix(Dam_PlayerDamageBase __instance, ref DamageSnapshot __state)
	{
		__state = new DamageSnapshot
		{
			HealthBefore = FriendlyFireUtil.SafeHealth(__instance)
		};
	}

	private static void Postfix(Dam_PlayerDamageBase __instance, pFullDamageData data, DamageSnapshot __state)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		FriendlyFireReporter.OnPlayerDamaged(__instance, data.source, __state);
	}
}
[HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveFireDamage")]
internal static class FireFriendlyFirePatch
{
	private static void Prefix(Dam_PlayerDamageBase __instance, ref DamageSnapshot __state)
	{
		__state = new DamageSnapshot
		{
			HealthBefore = FriendlyFireUtil.SafeHealth(__instance)
		};
	}

	private static void Postfix(Dam_PlayerDamageBase __instance, pSmallDamageData data, DamageSnapshot __state)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		FriendlyFireReporter.OnPlayerDamaged(__instance, data.source, __state);
	}
}
internal static class FriendlyFireReporter
{
	private sealed class FfBatch
	{
		public string AttackerName;

		public string VictimName;

		public float Damage;

		public float VictimHealthMax;

		public float LastEventTime;
	}

	private const float MinDamage = 0.01f;

	private static readonly Dictionary<string, FfBatch> Batches = new Dictionary<string, FfBatch>();

	public static void OnPlayerDamaged(Dam_PlayerDamageBase victimDamage, pAgent source, DamageSnapshot snapshot)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (!SleeperAlertPlugin.FriendlyFireEnabled.Value)
		{
			return;
		}
		try
		{
			float time = Time.time;
			Agent val = default(Agent);
			if (!((pAgent)(ref source)).TryGet(ref val) || (Object)(object)val == (Object)null || (int)val.Type != 0)
			{
				return;
			}
			PlayerAgent val2 = ((Il2CppObjectBase)val).TryCast<PlayerAgent>();
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Agent baseAgent = ((Dam_SyncedDamageBase)victimDamage).GetBaseAgent();
			if ((Object)(object)baseAgent == (Object)null || (int)baseAgent.Type != 0)
			{
				return;
			}
			PlayerAgent val3 = ((Il2CppObjectBase)baseAgent).TryCast<PlayerAgent>();
			if ((Object)(object)val3 == (Object)null)
			{
				return;
			}
			ulong stablePlayerKey = WakeReporter.GetStablePlayerKey(val2);
			ulong stablePlayerKey2 = WakeReporter.GetStablePlayerKey(val3);
			if (stablePlayerKey == stablePlayerKey2)
			{
				return;
			}
			float num = Math.Max(0f, snapshot.HealthBefore - ((Dam_SyncedDamageBase)victimDamage).Health);
			if (!(num < 0.01f))
			{
				string key = stablePlayerKey + "|" + stablePlayerKey2;
				if (!Batches.TryGetValue(key, out var value))
				{
					value = new FfBatch();
					Batches[key] = value;
				}
				value.AttackerName = WakeReporter.ResolvePlayerName(val2);
				value.VictimName = WakeReporter.ResolvePlayerName(val3);
				value.Damage += num;
				value.VictimHealthMax = ((Dam_SyncedDamageBase)victimDamage).HealthMax;
				value.LastEventTime = time;
				FlushExpiredBatches(time);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 友伤检测出错: " + ex.Message));
			}
		}
	}

	public static void Tick()
	{
		if (SleeperAlertPlugin.FriendlyFireEnabled.Value)
		{
			FlushExpiredBatches(Time.time);
		}
	}

	private static void FlushExpiredBatches(float now)
	{
		List<KeyValuePair<string, FfBatch>> list = null;
		foreach (KeyValuePair<string, FfBatch> batch in Batches)
		{
			if (now - batch.Value.LastEventTime >= SleeperAlertPlugin.BatchWindow.Value)
			{
				if (list == null)
				{
					list = new List<KeyValuePair<string, FfBatch>>();
				}
				list.Add(batch);
			}
		}
		if (list == null)
		{
			return;
		}
		foreach (KeyValuePair<string, FfBatch> item in list)
		{
			Batches.Remove(item.Key);
			FlushBatch(item.Value);
		}
	}

	private static void FlushBatch(FfBatch batch)
	{
		try
		{
			float num = ((batch.VictimHealthMax > 0f) ? (batch.Damage / batch.VictimHealthMax * 100f) : batch.Damage);
			string text = SleeperAlertPlugin.FriendlyFireFormat.Value.Replace("{attacker}", batch.AttackerName).Replace("{victim}", batch.VictimName).Replace("{percent}", num.ToString("0.#"))
				.Replace("{damage}", batch.Damage.ToString("0.#"));
			if (!string.IsNullOrWhiteSpace(text))
			{
				WakeReporter.Publish(text);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 友伤播报失败: " + ex.Message));
			}
		}
	}
}
[BepInPlugin("com.gtfo.sleeperalert", "SleeperAlert", "1.4.2")]
[BepInProcess("GTFO.exe")]
public class SleeperAlertPlugin : BasePlugin
{
	internal static ConfigFile ModConfig;

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<bool> ShowBanner;

	internal static ConfigEntry<bool> ShowChat;

	internal static ConfigEntry<float> BannerDuration;

	internal static ConfigEntry<bool> SkipPropagatedWakes;

	internal static ConfigEntry<float> NearestFallbackDistance;

	internal static ConfigEntry<float> BatchWindow;

	internal static ConfigEntry<string> MessageFormat;

	internal static ConfigEntry<bool> FriendlyFireEnabled;

	internal static ConfigEntry<string> FriendlyFireFormat;

	private Harmony _harmony;

	internal static SleeperAlertPlugin Instance { get; private set; }

	internal static ManualLogSource PluginLog
	{
		get
		{
			if (Instance == null)
			{
				return null;
			}
			return ((BasePlugin)Instance).Log;
		}
	}

	public override void Load()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Expected O, but got Unknown
		Instance = this;
		ModConfig = new ConfigFile(Path.Combine(Paths.ConfigPath, "SleeperAlert.cfg"), true);
		Enabled = ModConfig.Bind<bool>("General", "Enabled", true, "是否启用本插件(总开关,修改后重启游戏生效)");
		ShowBanner = ModConfig.Bind<bool>("Display", "ShowBanner", true, "在屏幕中央显示黄色横幅播报");
		ShowChat = ModConfig.Bind<bool>("Display", "ShowChat", true, "在聊天框发一条文字播报");
		BannerDuration = ModConfig.Bind<float>("Display", "BannerDuration", 5f, "横幅显示时长(秒)");
		SkipPropagatedWakes = ModConfig.Bind<bool>("Behavior", "SkipPropagatedWakes", false, "是否跳过连锁惊醒(如 Scout 尖叫引发的后续惊醒)。默认 false=播报连锁惊醒,和聚合计数配合不会刷屏");
		NearestFallbackDistance = ModConfig.Bind<float>("Behavior", "NearestFallbackDistance", 15f, "无法确定元凶时,归因给距离怪物该范围内的最近玩家(米)");
		BatchWindow = ModConfig.Bind<float>("Behavior", "BatchWindow", 2.5f, "聚合窗口(秒):同一玩家在该时间内惊醒的多只怪会合并成一条播报,同名怪物显示只数");
		MessageFormat = ModConfig.Bind<string>("Display", "MessageFormat", "⚠ {player} 惊醒了{enemy}!", "播报文本模板,{player}=玩家名,{enemy}=怪物名(多只时会自动变成\"2只前锋、1只射手\"这种形式)");
		FriendlyFireEnabled = ModConfig.Bind<bool>("General", "FriendlyFireEnabled", true, "友伤播报开关(玩家对玩家造成伤害时播报)");
		FriendlyFireFormat = ModConfig.Bind<string>("Display", "FriendlyFireFormat", "⚠ {attacker} 对 {victim} 造成了 {percent}% 友伤!", "友伤播报模板,{attacker}=攻击者,{victim}=受害者,{percent}=占受害者血量的百分比,{damage}=伤害点数");
		_harmony = new Harmony("com.gtfo.sleeperalert");
		_harmony.PatchAll(typeof(WakeUpPatch));
		_harmony.PatchAll(typeof(ChatMessagePatch));
		_harmony.PatchAll(typeof(UpdateTickPatch));
		_harmony.PatchAll(typeof(BulletFriendlyFirePatch));
		_harmony.PatchAll(typeof(MeleeFriendlyFirePatch));
		_harmony.PatchAll(typeof(FireFriendlyFirePatch));
		_harmony.PatchAll(typeof(ScoutScreamPatch));
		((BasePlugin)this).Log.LogInfo((object)"SleeperAlert v1.4.2 已加载。");
	}
}
internal static class MyPluginInfo
{
	public const string PLUGIN_GUID = "com.gtfo.sleeperalert";

	public const string PLUGIN_NAME = "SleeperAlert";

	public const string PLUGIN_VERSION = "1.4.2";
}
[HarmonyPatch(typeof(ES_ScoutScream), "DoStartScream")]
internal static class ScoutScreamPatch
{
	private static void Postfix(ES_ScoutScream __instance)
	{
		try
		{
			WakeReporter.OnScoutScream(__instance);
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 处理哨兵尖叫出错: " + ex));
			}
		}
	}
}
[HarmonyPatch(typeof(PlayerChatManager), "Update")]
internal static class UpdateTickPatch
{
	private static void Postfix()
	{
		try
		{
			WakeReporter.Tick();
			FriendlyFireReporter.Tick();
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 批次冲刷检查出错: " + ex));
			}
		}
	}
}
internal static class WakeReporter
{
	private sealed class PendingBatch
	{
		public ulong PlayerKey;

		public string PlayerName;

		public readonly List<string> EnemyNames = new List<string>();

		public float LastEventTime;
	}

	private const string Marker = "\u200b";

	private static readonly Dictionary<ushort, float> ReportedAt = new Dictionary<ushort, float>();

	private static float _lastFlushTime = -100f;

	private static readonly Dictionary<ulong, PendingBatch> Batches = new Dictionary<ulong, PendingBatch>();

	private static readonly (string Prefix, string Name)[] EnemyNameTable = new(string, string)[34]
	{
		("Striker_Big_Bullrush", "冲撞大前锋"),
		("Striker_Big_Shadow", "暗影大前锋"),
		("Striker_Big_nightmare", "梦魇大前锋"),
		("Striker_Big", "大前锋"),
		("Striker_Boss", "前锋首领"),
		("Striker_Child_Nightmare", "梦魇幼体前锋"),
		("Striker_Child", "幼体前锋"),
		("Striker_Bullrush", "冲撞前锋"),
		("Striker_Wave_Fast", "疾速前锋"),
		("Striker_Berserk", "狂暴前锋"),
		("Striker", "前锋"),
		("Shooter_Big_RapidFire", "速射巨型射手"),
		("Shooter_Big_Infection", "感染巨型射手"),
		("Shooter_Big", "巨型射手"),
		("Shooter", "射手"),
		("Scout_Bullrush", "冲撞侦察兵"),
		("Scout_zoomer", "疾行侦察兵"),
		("Scout_nightmare", "梦魇侦察兵"),
		("Scout_Shadow", "暗影侦察兵"),
		("Scout", "侦察兵"),
		("Birther_Boss", "母体首领"),
		("Birther", "母体"),
		("MegaMother", "巨母体"),
		("Cocoon", "虫茧"),
		("Shadow", "暗影"),
		("Tank_Boss", "坦克首领"),
		("Tank", "坦克"),
		("Flyer_Big", "巨型飞虫"),
		("Flyer", "飞虫"),
		("SquidBoss_Big_Complex", "巨型触手怪"),
		("SquidBoss_Big", "巨型触手怪"),
		("SquidBoss_VS", "触手怪"),
		("Squidward", "触手怪"),
		("Pouncer", "扑袭者")
	};

	public static void OnSleeperWakeUp(ES_HibernateWakeUp state, bool isPropagatedWakeup)
	{
		if (!SleeperAlertPlugin.Enabled.Value || (isPropagatedWakeup && SleeperAlertPlugin.SkipPropagatedWakes.Value))
		{
			return;
		}
		float time = Time.time;
		EnemyAI ai = ((ES_Base)state).m_ai;
		if (!((Object)(object)ai == (Object)null))
		{
			Agent agent = ((AgentAI)ai).Agent;
			if (!((Object)(object)agent == (Object)null))
			{
				HandleWake(ai, agent, time);
			}
		}
	}

	public static void OnScoutScream(ES_ScoutScream state)
	{
		if (!SleeperAlertPlugin.Enabled.Value)
		{
			return;
		}
		float time = Time.time;
		EnemyAI ai = ((ES_Base)state).m_ai;
		if (!((Object)(object)ai == (Object)null))
		{
			Agent agent = ((AgentAI)ai).Agent;
			if (!((Object)(object)agent == (Object)null))
			{
				HandleWake(ai, agent, time);
			}
		}
	}

	private static void HandleWake(EnemyAI ai, Agent agent, float now)
	{
		ushort globalID = agent.GlobalID;
		if (ReportedAt.TryGetValue(globalID, out var value) && now - value < 60f)
		{
			return;
		}
		ReportedAt[globalID] = now;
		if (ReportedAt.Count > 1024)
		{
			ReportedAt.Clear();
		}
		PlayerAgent val = ResolveCulprit(ai, agent);
		if (!((Object)(object)val == (Object)null))
		{
			string text = ResolvePlayerName(val);
			string text2 = ResolveEnemyName(agent);
			if (!string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(text2))
			{
				AddToBatch(GetStablePlayerKey(val), text, text2, now);
				FlushExpiredBatches(now);
			}
		}
	}

	public static void Tick()
	{
		if (SleeperAlertPlugin.Enabled.Value)
		{
			FlushExpiredBatches(Time.time);
		}
	}

	internal static ulong GetStablePlayerKey(PlayerAgent player)
	{
		try
		{
			if ((Object)(object)player.Owner != (Object)null && player.Owner.Lookup != 0L)
			{
				return player.Owner.Lookup;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 获取玩家标识失败: " + ex.Message));
			}
		}
		return ((Agent)player).GlobalID;
	}

	private static void AddToBatch(ulong key, string playerName, string enemyName, float now)
	{
		if (!Batches.TryGetValue(key, out var value))
		{
			value = new PendingBatch
			{
				PlayerKey = key,
				PlayerName = playerName
			};
			Batches[key] = value;
		}
		value.EnemyNames.Add(enemyName);
		value.PlayerName = playerName;
		value.LastEventTime = now;
	}

	private static void FlushExpiredBatches(float now)
	{
		List<PendingBatch> list = null;
		foreach (KeyValuePair<ulong, PendingBatch> batch in Batches)
		{
			if (now - batch.Value.LastEventTime >= SleeperAlertPlugin.BatchWindow.Value)
			{
				if (list == null)
				{
					list = new List<PendingBatch>();
				}
				list.Add(batch.Value);
			}
		}
		if (list == null)
		{
			return;
		}
		foreach (PendingBatch item in list)
		{
			Batches.Remove(item.PlayerKey);
			FlushBatch(item);
		}
	}

	private static void FlushBatch(PendingBatch batch)
	{
		string text = BuildSummary(batch.EnemyNames);
		if (!string.IsNullOrWhiteSpace(text))
		{
			string text2 = SleeperAlertPlugin.MessageFormat.Value.Replace("{player}", batch.PlayerName).Replace("{enemy}", text);
			if (!string.IsNullOrWhiteSpace(text2))
			{
				Publish(text2);
			}
		}
	}

	internal static void Publish(string message)
	{
		_lastFlushTime = Time.time;
		ShowBanner(message);
		SendChatBroadcast(message);
		ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
		if (pluginLog != null)
		{
			pluginLog.LogDebug((object)("[SleeperAlert] " + message));
		}
	}

	private static string BuildSummary(List<string> enemyNames)
	{
		if (enemyNames.Count == 0)
		{
			return null;
		}
		List<string> list = new List<string>();
		Dictionary<string, int> dictionary = new Dictionary<string, int>();
		foreach (string enemyName in enemyNames)
		{
			if (!dictionary.ContainsKey(enemyName))
			{
				dictionary[enemyName] = 0;
				list.Add(enemyName);
			}
			dictionary[enemyName]++;
		}
		List<string> list2 = new List<string>();
		foreach (string item in list)
		{
			int num = dictionary[item];
			list2.Add((num > 1) ? (num + "只" + item) : item);
		}
		return string.Join("、", list2);
	}

	private static PlayerAgent ResolveCulprit(EnemyAI ai, Agent agent)
	{
		//IL_0016: 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)
		try
		{
			Agent agent2 = ((AgentAI)ai).Target.m_agent;
			if ((Object)(object)agent2 != (Object)null && (int)agent2.Type == 0)
			{
				PlayerAgent val = ((Il2CppObjectBase)agent2).TryCast<PlayerAgent>();
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 读取 AI 目标失败,改用最近玩家: " + ex.Message));
			}
		}
		PlayerAgent result = default(PlayerAgent);
		if (PlayerManager.TryGetCloseEnoughPlayerAgent(agent.Position, SleeperAlertPlugin.NearestFallbackDistance.Value, ref result))
		{
			return result;
		}
		return null;
	}

	private static string ResolveEnemyName(Agent agent)
	{
		try
		{
			EnemyAgent val = ((Il2CppObjectBase)agent).TryCast<EnemyAgent>();
			if ((Object)(object)val == (Object)null)
			{
				return "沉睡者";
			}
			EnemyDataBlock enemyData = val.EnemyData;
			string text = ((GameDataBlockBase<EnemyDataBlock>)(object)enemyData)?.name;
			if (!string.IsNullOrWhiteSpace(text))
			{
				(string, string)[] enemyNameTable = EnemyNameTable;
				for (int i = 0; i < enemyNameTable.Length; i++)
				{
					var (value, result) = enemyNameTable[i];
					if (text.StartsWith(value, StringComparison.OrdinalIgnoreCase))
					{
						return result;
					}
				}
				ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
				if (pluginLog != null)
				{
					pluginLog.LogDebug((object)("[SleeperAlert] 未收录的敌人数据块名: " + text + " (pid=" + ((enemyData != null) ? ((GameDataBlockBase<EnemyDataBlock>)(object)enemyData).persistentID.ToString() : "?") + "),请反馈给作者"));
				}
				return text;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog2 = SleeperAlertPlugin.PluginLog;
			if (pluginLog2 != null)
			{
				pluginLog2.LogWarning((object)("[SleeperAlert] 获取怪物名失败: " + ex.Message));
			}
		}
		return "沉睡者";
	}

	internal static string ResolvePlayerName(PlayerAgent player)
	{
		try
		{
			if ((Object)(object)player.Owner != (Object)null && !string.IsNullOrWhiteSpace(player.Owner.NickName))
			{
				return player.Owner.NickName;
			}
			if ((Object)(object)player.Owner != (Object)null && !string.IsNullOrWhiteSpace(player.Owner.GetName()))
			{
				return player.Owner.GetName();
			}
			if (!string.IsNullOrWhiteSpace(player.PlayerName))
			{
				return player.PlayerName;
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 获取玩家名失败: " + ex.Message));
			}
		}
		return "Player_" + ((Agent)player).GlobalID;
	}

	private static void ShowBanner(string message)
	{
		if (!SleeperAlertPlugin.ShowBanner.Value)
		{
			return;
		}
		try
		{
			InteractionGuiLayer interactionLayer = GuiManager.InteractionLayer;
			if (interactionLayer != null)
			{
				interactionLayer.SetTimedMessage(message, SleeperAlertPlugin.BannerDuration.Value, (ePUIMessageStyle)3, 10);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 横幅显示失败: " + ex.Message));
			}
		}
	}

	private static void SendChatBroadcast(string message)
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Expected O, but got Unknown
		if (!SleeperAlertPlugin.ShowChat.Value)
		{
			return;
		}
		try
		{
			if (!SNet.IsMaster)
			{
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			if ((Object)(object)localPlayerAgent == (Object)null)
			{
				return;
			}
			PlayerChatManager current = PlayerChatManager.Current;
			if ((Object)(object)current == (Object)null)
			{
				return;
			}
			string text = "\u200b" + message;
			int num = 50;
			try
			{
				int cHAT_MESSAGE_MAX_LENGTH = PlayerChatManager.CHAT_MESSAGE_MAX_LENGTH;
				if (cHAT_MESSAGE_MAX_LENGTH > 0 && cHAT_MESSAGE_MAX_LENGTH < 512)
				{
					num = cHAT_MESSAGE_MAX_LENGTH;
				}
			}
			catch (Exception)
			{
			}
			if (text.Length > num)
			{
				text = text.Substring(0, num);
			}
			pChatMessage val = new pChatMessage();
			val.fromPlayer = new pPlayer
			{
				lookup = localPlayerAgent.Owner.Lookup,
				IsBot = localPlayerAgent.Owner.IsBot
			};
			val.toPlayer = default(pPlayer);
			val.message = new pString50
			{
				data = text
			};
			try
			{
				current.m_sendChatMessage.Ask(val);
				return;
			}
			catch (Exception ex2)
			{
				ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
				if (pluginLog != null)
				{
					pluginLog.LogWarning((object)("[SleeperAlert] 联网聊天发送失败,退化为本地显示: " + ex2.Message));
				}
			}
			PlayerChatManager.PostChatMessageLocaly(localPlayerAgent.Owner, text, (SNet_Player)null);
		}
		catch (Exception ex3)
		{
			ManualLogSource pluginLog2 = SleeperAlertPlugin.PluginLog;
			if (pluginLog2 != null)
			{
				pluginLog2.LogWarning((object)("[SleeperAlert] 聊天消息发送失败: " + ex3.Message));
			}
		}
	}

	public static void OnChatMessageDisplayed(string message)
	{
		try
		{
			if (!string.IsNullOrEmpty(message) && SleeperAlertPlugin.ShowBanner.Value && message.StartsWith("\u200b", StringComparison.Ordinal) && !(Time.time - _lastFlushTime < 3f))
			{
				ShowBanner(message.Substring("\u200b".Length));
			}
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 处理联网横幅失败: " + ex.Message));
			}
		}
	}
}
[HarmonyPatch(typeof(ES_HibernateWakeUp), "DoWakeup")]
internal static class WakeUpPatch
{
	private static void Postfix(ES_HibernateWakeUp __instance, bool turn, int index, float delay, bool isPropagatedWakeup)
	{
		try
		{
			WakeReporter.OnSleeperWakeUp(__instance, isPropagatedWakeup);
		}
		catch (Exception ex)
		{
			ManualLogSource pluginLog = SleeperAlertPlugin.PluginLog;
			if (pluginLog != null)
			{
				pluginLog.LogWarning((object)("[SleeperAlert] 处理惊醒事件时出错: " + ex));
			}
		}
	}
}