using System; using System.Collections.Generic; using System.Diagnostics; 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 Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 REPOJP.LonelyDeath { [BepInPlugin("REPOJP.LonelyDeath", "LonelyDeath", "1.0.0")] public sealed class LonelyDeathPlugin : BaseUnityPlugin { public const string PluginGuid = "REPOJP.LonelyDeath"; public const string PluginName = "LonelyDeath"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static LonelyDeathConfig ModConfig; private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown try { Log = ((BaseUnityPlugin)this).Logger; ModConfig = new LonelyDeathConfig(((BaseUnityPlugin)this).Config); GameObject val = new GameObject("REPOJP_LonelyDeath_Manager"); val.transform.parent = null; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent(); Log.LogInfo((object)"LonelyDeath loaded."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: LonelyDeath Awake\n" + ex)); } } } internal sealed class LonelyDeathConfig { internal readonly ConfigEntry EnableMod; internal readonly ConfigEntry Radius; internal readonly ConfigEntry CheckInterval; internal readonly ConfigEntry KillDelay; internal readonly ConfigEntry DamagePerSecond; internal readonly ConfigEntry DamageStartDelay; internal readonly ConfigEntry TruckSafeZone; internal readonly ConfigEntry OutsideChatMessage; internal readonly ConfigEntry SafeChatMessage; internal readonly ConfigEntry EnableDebugLog; internal LonelyDeathConfig(ConfigFile config) { EnableMod = config.Bind("General", "EnableMod", true, "Enable this mod.このMODを有効化"); Radius = config.Bind("General", "Radius", 25f, "Safe sphere radius from the center point.中心点からの安全球半径"); CheckInterval = config.Bind("General", "CheckInterval", 1f, "Position check interval in seconds.位置判定間隔 秒"); KillDelay = config.Bind("General", "KillDelay", 10f, "Seconds from leaving the safe sphere until death.安全球外に出てから死亡までの秒数"); DamagePerSecond = config.Bind("General", "DamagePerSecond", 1, "Damage applied every second while outside after the delay.猶予後に球外で毎秒受けるダメージ量"); DamageStartDelay = config.Bind("General", "DamageStartDelay", 0f, "Seconds before periodic damage starts after leaving the safe sphere.球外に出てから継続ダメージ開始までの猶予秒数"); TruckSafeZone = config.Bind("General", "TruckSafeZone", true, "Treat the truck as a safe zone.トラック内をセーフティーゾーン扱い"); OutsideChatMessage = config.Bind("Chat", "OutsideChatMessage", "I'm too far away from everyone. I'm lonely. I'm going to die.", "Forced public chat when a player leaves the safe sphere.安全球外に出た時の強制公開チャット"); SafeChatMessage = config.Bind("Chat", "SafeChatMessage", "safe", "Forced public chat when a player returns to safety.安全圏に戻った時の強制公開チャット"); EnableDebugLog = config.Bind("Debug", "EnableDebugLog", false, "Enable debug logs.デバッグログを有効化"); } } internal sealed class LonelyDeathManager : MonoBehaviour { private readonly Dictionary playerStates = new Dictionary(); private float nextCheckTime; private void Update() { try { LonelyDeathConfig modConfig = LonelyDeathPlugin.ModConfig; if (modConfig == null || !modConfig.EnableMod.Value) { ClearAllStates(sendSafeChat: false); return; } float num = Mathf.Max(0.1f, modConfig.CheckInterval.Value); if (!(Time.time < nextCheckTime)) { nextCheckTime = Time.time + num; RunCheck(modConfig); } } catch (Exception ex) { LonelyDeathPlugin.Log.LogError((object)("Failure: LonelyDeath Update\n" + ex)); } } private void RunCheck(LonelyDeathConfig config) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) if (!IsMasterClient()) { ClearAllStates(sendSafeChat: false); return; } if (!IsValidRunState()) { ClearAllStates(sendSafeChat: false); return; } List alivePlayers = GetAlivePlayers(); if (alivePlayers.Count < 2) { ClearAllStates(sendSafeChat: false); return; } List list = new List(); foreach (PlayerAvatar item in alivePlayers) { if (!IsPlayerInTruck(item)) { list.Add(item); } } if (list.Count < 2) { ClearAllStates(sendSafeChat: false); return; } Vector3 val = CalculateCenter(list); float num = Mathf.Max(0.1f, config.Radius.Value); foreach (PlayerAvatar item2 in alivePlayers) { string playerKey = GetPlayerKey(item2); if (string.IsNullOrEmpty(playerKey)) { continue; } bool flag = IsPlayerInTruck(item2); if (config.TruckSafeZone.Value && flag) { SetSafe(item2, playerKey, config, sendSafeChat: true); continue; } float num2 = Vector3.Distance(((Component)item2).transform.position, val); if (num2 > num) { SetOutside(item2, playerKey, config, num2, num); } else { SetSafe(item2, playerKey, config, sendSafeChat: true); } } RemoveInvalidStates(alivePlayers); } private static bool IsMasterClient() { try { if (!SemiFunc.IsMultiplayer()) { return false; } return SemiFunc.IsMasterClient(); } catch { return PhotonNetwork.IsMasterClient; } } private static bool IsValidRunState() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 try { if (!SemiFunc.IsMultiplayer()) { return false; } if (!SemiFunc.RunIsLevel()) { return false; } if (SemiFunc.RunIsShop() || SemiFunc.RunIsLobby() || SemiFunc.RunIsLobbyMenu() || SemiFunc.RunIsTutorial()) { return false; } if ((Object)(object)GameDirector.instance == (Object)null || (int)GameDirector.instance.currentState != 2) { return false; } return true; } catch { return false; } } private static List GetAlivePlayers() { List list = new List(); List list2 = null; try { list2 = SemiFunc.PlayerGetList(); } catch { if ((Object)(object)GameDirector.instance != (Object)null) { list2 = GameDirector.instance.PlayerList; } } if (list2 == null) { return list; } foreach (PlayerAvatar item in list2) { if (IsAlivePlayer(item)) { list.Add(item); } } return list; } private static bool IsAlivePlayer(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { return false; } if (player.isDisabled || player.deadSet) { return false; } if ((Object)(object)player.playerHealth == (Object)null) { return false; } if (player.playerHealth.health <= 0) { return false; } return true; } private static bool IsPlayerInTruck(PlayerAvatar player) { try { return (Object)(object)player != (Object)null && (Object)(object)player.RoomVolumeCheck != (Object)null && player.RoomVolumeCheck.inTruck; } catch { return false; } } private static Vector3 CalculateCenter(List players) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; foreach (PlayerAvatar player in players) { val += ((Component)player).transform.position; } return val / (float)players.Count; } private void SetOutside(PlayerAvatar player, string key, LonelyDeathConfig config, float distance, float radius) { if (!playerStates.TryGetValue(key, out PlayerLonelyState value)) { value = new PlayerLonelyState(); value.OutsideStartTime = Time.time; value.NextDamageTime = Time.time + Mathf.Max(0f, config.DamageStartDelay.Value); value.OutsideChatSent = false; playerStates[key] = value; } if (!value.OutsideChatSent) { SendForcedChat(player, config.OutsideChatMessage.Value); value.OutsideChatSent = true; } ApplyRedEyes(player); int num = Mathf.Max(0, config.DamagePerSecond.Value); if (num > 0 && Time.time >= value.NextDamageTime) { DamagePlayer(player, num); value.NextDamageTime = Time.time + 1f; } float num2 = Mathf.Max(0.1f, config.KillDelay.Value); if (Time.time - value.OutsideStartTime >= num2) { KillPlayer(player); playerStates.Remove(key); } else if (config.EnableDebugLog.Value) { LonelyDeathPlugin.Log.LogInfo((object)("Outside: " + GetPlayerName(player) + " distance=" + distance.ToString("0.00") + " radius=" + radius.ToString("0.00"))); } } private void SetSafe(PlayerAvatar player, string key, LonelyDeathConfig config, bool sendSafeChat) { if (playerStates.ContainsKey(key)) { playerStates.Remove(key); ClearRedEyes(player); if (sendSafeChat && !string.IsNullOrEmpty(config.SafeChatMessage.Value)) { SendForcedChat(player, config.SafeChatMessage.Value); } } } private void ClearAllStates(bool sendSafeChat) { if (playerStates.Count == 0) { return; } List alivePlayers = GetAlivePlayers(); foreach (PlayerAvatar item in alivePlayers) { string playerKey = GetPlayerKey(item); if (!string.IsNullOrEmpty(playerKey) && playerStates.ContainsKey(playerKey)) { ClearRedEyes(item); if (sendSafeChat && LonelyDeathPlugin.ModConfig != null && !string.IsNullOrEmpty(LonelyDeathPlugin.ModConfig.SafeChatMessage.Value)) { SendForcedChat(item, LonelyDeathPlugin.ModConfig.SafeChatMessage.Value); } } } playerStates.Clear(); } private void RemoveInvalidStates(List alivePlayers) { HashSet hashSet = new HashSet(); foreach (PlayerAvatar alivePlayer in alivePlayers) { string playerKey = GetPlayerKey(alivePlayer); if (!string.IsNullOrEmpty(playerKey)) { hashSet.Add(playerKey); } } List list = new List(); foreach (string key in playerStates.Keys) { if (!hashSet.Contains(key)) { list.Add(key); } } foreach (string item in list) { playerStates.Remove(item); } } private static void SendForcedChat(PlayerAvatar player, string message) { if ((Object)(object)player == (Object)null || string.IsNullOrEmpty(message)) { return; } try { player.ChatMessageSend(message); } catch (Exception ex) { LonelyDeathPlugin.Log.LogWarning((object)("Failure: SendForcedChat " + GetPlayerName(player) + "\n" + ex)); } } private static void DamagePlayer(PlayerAvatar player, int damage) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)player.playerHealth == (Object)null || damage <= 0) { return; } try { player.playerHealth.HurtOther(damage, Vector3.zero, false, -1); } catch (Exception ex) { LonelyDeathPlugin.Log.LogWarning((object)("Failure: DamagePlayer " + GetPlayerName(player) + "\n" + ex)); } } private static void KillPlayer(PlayerAvatar player) { if ((Object)(object)player == (Object)null || player.deadSet) { return; } try { player.PlayerDeath(-1); } catch (Exception ex) { LonelyDeathPlugin.Log.LogWarning((object)("Failure: KillPlayer " + GetPlayerName(player) + "\n" + ex)); } } private static void ApplyRedEyes(PlayerAvatar player) { if ((Object)(object)player == (Object)null || (Object)(object)player.playerHealth == (Object)null) { return; } try { if (GameManager.Multiplayer() && (Object)(object)player.playerHealth.photonView != (Object)null) { player.playerHealth.photonView.RPC("EyeMaterialOverrideRPC", (RpcTarget)0, new object[2] { (object)(EyeOverrideState)1, true }); } else { player.playerHealth.EyeMaterialOverride((EyeOverrideState)1, 1.25f, 50); } } catch (Exception ex) { LonelyDeathPlugin.Log.LogWarning((object)("Failure: ApplyRedEyes " + GetPlayerName(player) + "\n" + ex)); } } private static void ClearRedEyes(PlayerAvatar player) { if ((Object)(object)player == (Object)null || (Object)(object)player.playerHealth == (Object)null) { return; } try { if (GameManager.Multiplayer() && (Object)(object)player.playerHealth.photonView != (Object)null) { player.playerHealth.photonView.RPC("EyeMaterialOverrideRPC", (RpcTarget)0, new object[2] { (object)(EyeOverrideState)1, false }); } } catch (Exception ex) { LonelyDeathPlugin.Log.LogWarning((object)("Failure: ClearRedEyes " + GetPlayerName(player) + "\n" + ex)); } } private static string GetPlayerKey(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { return string.Empty; } try { if (!string.IsNullOrEmpty(player.steamID)) { return player.steamID; } } catch { } try { if ((Object)(object)player.photonView != (Object)null && player.photonView.Owner != null) { return player.photonView.Owner.ActorNumber.ToString(); } } catch { } return ((Object)player).GetInstanceID().ToString(); } private static string GetPlayerName(PlayerAvatar player) { if ((Object)(object)player == (Object)null) { return "Unknown"; } try { return SemiFunc.PlayerGetName(player); } catch { return ((Object)player).name; } } } internal sealed class PlayerLonelyState { internal float OutsideStartTime; internal float NextDamageTime; internal bool OutsideChatSent; } }