using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using MultiplayerPVP.Addons; using MultiplayerPVP.Core; using PvpWhistle; using ScheduleOne.PlayerScripts; using ScheduleOne.PlayerScripts.Health; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonAdditionalDependencies(new string[] { "MultiplayerPVP" })] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: MelonInfo(typeof(PvpWhistleMod), "PvpWhistle", "1.0.2", "Virtunerd", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: AssemblyFileVersion("1.0.2")] [assembly: AssemblyInformationalVersion("1.0.2")] [assembly: AssemblyVersion("1.0.2.0")] [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 PvpWhistle { public class PvpWhistleMod : MelonMod { private WhistleAddon _addon; public override void OnInitializeMelon() { _addon = new WhistleAddon(); if (PvpApi.RegisterAddon((IPvpAddon)(object)_addon)) { MelonLogger.Msg("[PvpWhistle] registered with MultiplayerPVP."); } else { MelonLogger.Warning("[PvpWhistle] registration failed — is MultiplayerPVP loaded?"); } } public override void OnDeinitializeMelon() { try { PvpApi.UnregisterAddon((IPvpAddon)(object)_addon); } catch { } } } internal sealed class WhistleAddon : PvpAddonBase { private sealed class Ping { internal Vector3 Pos; internal string Name; internal float Until; } private MelonPreferences_Entry _intervalSeconds; private MelonPreferences_Entry _pingSeconds; private MelonPreferences_Entry _seekersOnly; private readonly List _pings = new List(); private float _nextWhistle; private bool _show; private static GUIStyle _center; public override string Id => "PvpWhistle"; private float Interval => Mathf.Max(3f, _intervalSeconds.Value); private static GUIStyle CenterStyle { get { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown if (_center == null) { _center = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 14, fontStyle = (FontStyle)1 }; } return _center; } } public override void OnRegistered() { MelonPreferences_Category val = MelonPreferences.CreateCategory("PvpWhistle", "PVP Hider Whistle"); _intervalSeconds = val.CreateEntry("WhistleIntervalSeconds", 10f, "Whistle interval (s)", "Seconds between automatic hider whistles during Hide & Seek (min 3).", false, false, (ValueValidator)null, (string)null); _pingSeconds = val.CreateEntry("PingVisibleSeconds", 4f, "Ping visible (s)", "How long each whistle ping stays on screen (1-15).", false, false, (ValueValidator)null, (string)null); _seekersOnly = val.CreateEntry("SeekersOnlyDisplay", true, "Seekers only", "Only seekers see the pings (hiders just whistle). Off = everyone sees them.", false, false, (ValueValidator)null, (string)null); } public override void OnGo(GameModeType mode) { _pings.Clear(); _nextWhistle = Time.realtimeSinceStartup + Interval; } public override void OnDayEnded(GameModeType mode, int day) { _pings.Clear(); } public override void OnMatchEnded(GameModeType mode) { _pings.Clear(); } public override void OnSceneLoaded(int buildIndex, string sceneName) { _pings.Clear(); } public override void OnDeinit() { _pings.Clear(); } public override void OnUpdate(float dt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if ((int)PvpApi.Mode != 6 || (int)PvpApi.Phase != 2) { if (_pings.Count > 0) { _pings.Clear(); } return; } _show = true; if (_seekersOnly.Value) { _show = false; try { Player localPlayer = PvpApi.LocalPlayer; bool show = default(bool); if ((Object)(object)localPlayer != (Object)null && PvpApi.TryGetHideSeekRole(localPlayer, ref show)) { _show = show; } } catch { } } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup >= _nextWhistle) { _nextWhistle = realtimeSinceStartup + Interval; Whistle(realtimeSinceStartup); } for (int num = _pings.Count - 1; num >= 0; num--) { if (_pings[num].Until <= realtimeSinceStartup) { _pings.RemoveAt(num); } } } private void Whistle(float now) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(_pingSeconds.Value, 1f, 15f); Player localPlayer = PvpApi.LocalPlayer; List players = PvpApi.Players; bool flag = default(bool); for (int i = 0; i < players.Count; i++) { Player val = players[i]; try { if (!((Object)(object)val == (Object)null) && (!((Object)(object)localPlayer != (Object)null) || !((Object)(object)val == (Object)(object)localPlayer)) && !(!PvpApi.TryGetHideSeekRole(val, ref flag) || flag)) { PlayerHealth componentInChildren = ((Component)val).GetComponentInChildren(true); if (!((Object)(object)componentInChildren != (Object)null) || componentInChildren.IsAlive) { _pings.Add(new Ping { Pos = ((Component)val).transform.position, Name = val.PlayerName, Until = now + num }); } } } catch { } } } public override void OnGui() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_023b: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) if (!_show || _pings.Count == 0 || (int)PvpApi.Phase != 2) { return; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } Vector3 val = Vector3.zero; bool flag = false; try { Player localPlayer = PvpApi.LocalPlayer; if ((Object)(object)localPlayer != (Object)null) { val = ((Component)localPlayer).transform.position; flag = true; } } catch { } float realtimeSinceStartup = Time.realtimeSinceStartup; float num = Mathf.Clamp(_pingSeconds.Value, 1f, 15f); Color color = GUI.color; Rect val3 = default(Rect); for (int i = 0; i < _pings.Count; i++) { Ping ping = _pings[i]; Vector3 val2; try { val2 = main.WorldToScreenPoint(ping.Pos + Vector3.up * 1.8f); } catch { continue; } if (!(val2.z <= 0f)) { float num2 = Mathf.Clamp01((ping.Until - realtimeSinceStartup) / num); string text = (flag ? $"♪ {ping.Name} · {Vector3.Distance(val, ping.Pos):0}m" : ("♪ " + ping.Name)); ((Rect)(ref val3))..ctor(val2.x - 80f, (float)Screen.height - val2.y - 12f, 160f, 24f); GUI.color = new Color(0f, 0f, 0f, num2 * 0.8f); GUI.Label(new Rect(((Rect)(ref val3)).x + 1f, ((Rect)(ref val3)).y + 1f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height), text, CenterStyle); GUI.color = new Color(1f, 0.92f, 0.35f, num2); GUI.Label(val3, text, CenterStyle); } } GUI.color = color; } } }