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