Decompiled source of Prop Hunt v1.0.3
PropHuntMod.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using System.Timers; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using InControl; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using NoRepeat; using PropHuntMod.Commands; using PropHuntMod.Networking.Client; using PropHuntMod.Networking.Server; using PropHuntMod.Patches; using PropHuntMod.Players; using PropHuntMod.Props; using PropHuntMod.Utils; using SSMP.Api.Client; using SSMP.Api.Client.Networking; using SSMP.Api.Command; using SSMP.Api.Command.Client; using SSMP.Api.Command.Server; using SSMP.Api.Server; using SSMP.Api.Server.Networking; using SSMP.Game.Settings; using SSMP.Logging; using SSMP.Math; using SSMP.Networking.Packet; using SSMP.Networking.Packet.Data; using TeamCherry.Localization; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PropHuntMod")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PropHuntMod")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ea9e15ba-4504-4c36-baa6-8f85bee1da18")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace NoRepeat { public class NoRepeat<T> { private readonly Random random = new Random(); public List<T> used { get; private set; } public List<T> inputValues { get; private set; } public NoRepeat(List<T> values) { inputValues = values; used = new List<T>(); } public T GetRandom() { if (used.Count == 0 && inputValues.Count <= 1) { if (inputValues.Count == 0) { return default(T); } return inputValues[0]; } int index = random.Next(inputValues.Count); T val = inputValues[index]; inputValues.RemoveAt(index); if (inputValues.Count == 0) { inputValues.AddRange(used); used = new List<T>(); Log.LogDebug("Resetting NoRepeat"); } used.Add(val); return val; } public T GetSpecific(Func<T, bool> func) { T val = inputValues.FirstOrDefault(func); if (val != null) { return val; } return used.FirstOrDefault(func); } } } namespace PropHuntMod { [BepInPlugin("com.bobbythecatfish.prophunt", "Prop Hunt", "1.0.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("Hollow Knight Silksong.exe")] public class PropHuntMod : BaseUnityPlugin { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static HeroSetDelegate <>9__10_0; internal void <Awake>b__10_0(HeroController heroController) { AttackCooldownPatches.ModifySprintFSM(); } } internal static PropHuntMod Instance; internal SelfHornetManager hornet = new SelfHornetManager(); internal SelfCoverManager cover = new SelfCoverManager(); private static PropMovementControls movement; internal static Dictionary<ushort, PlayerManager> playerManager = new Dictionary<ushort, PlayerManager>(); internal static IClientApi client; internal static bool modEnabled = false; internal static bool showHitboxes = false; internal static List<Action> nextFrameActions = new List<Action>(); private static List<Action> _nextFrames = new List<Action>(); private void Awake() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Instance = this; Config.LoadConfig(((BaseUnityPlugin)this).Config); ClientAddon.RegisterAddon((ClientAddon)(object)new Client()); ServerAddon.RegisterAddon((ServerAddon)(object)new Server()); object obj = <>c.<>9__10_0; if (obj == null) { HeroSetDelegate val = delegate { AttackCooldownPatches.ModifySprintFSM(); }; <>c.<>9__10_0 = val; obj = (object)val; } HeroController.OnHeroInstanceSet += (HeroSetDelegate)obj; } public static void Initialize(IClientApi clientApi) { Log.LogInfo("Prop Hunt mod Loaded."); client = clientApi; Harmony.CreateAndPatchAll(typeof(PropHuntMod), "prophunt"); Harmony.CreateAndPatchAll(typeof(NoDamage), "prophunt"); Harmony.CreateAndPatchAll(typeof(BaseCoverManager), "prophunt"); Harmony.CreateAndPatchAll(typeof(AttackCooldownPatches), "prophunt"); Harmony.CreateAndPatchAll(typeof(ScenePatches), "prophunt"); modEnabled = true; movement = new PropMovementControls(); } public static void Unload() { Harmony.UnpatchID("prophunt"); modEnabled = false; } private bool IsInputDisabled() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 HeroController instance = HeroController.instance; if (instance != null && instance.IsInputBlocked() && PropMovementControls.MovementState == MovementState.Normal) { return true; } GameManager silentInstance = GameManager.SilentInstance; if (silentInstance != null && (int)silentInstance.GameState == 1) { return true; } GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject; if ((Object)(object)currentSelectedGameObject != (Object)null) { InputField component = currentSelectedGameObject.GetComponent<InputField>(); if (component != null && ((Component)component).gameObject.activeInHierarchy) { return true; } } return false; } private void Update() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled) { return; } if (_nextFrames.Count > 0) { foreach (Action nextFrame in _nextFrames) { nextFrame(); } _nextFrames.Clear(); } if ((Object)(object)hornet.hornet != (Object)null) { hornet.EnsureHornetHidden(); } if ((Object)(object)hornet.hornet == (Object)null) { return; } movement?.Update(); if (!IsInputDisabled()) { if (Input.GetKeyDown(Config.HideHornetKey)) { hornet.ToggleHornet(); } if (Input.GetKeyDown(Config.SwapPropKey)) { cover.EnableRandomProp(); } if (Input.GetKeyDown(Config.ResetKey)) { cover.DisableProp(hornet); } } } private void LateUpdate() { if (nextFrameActions.Count > 0) { _nextFrames = nextFrameActions.ToList(); nextFrameActions.Clear(); } } } } namespace PropHuntMod.Networking.Server { internal class Server : ServerAddon { public static Server instance; public static GameState GameState = GameState.NotStarted; private static readonly Dictionary<ushort, ServerPlayer> players = new Dictionary<ushort, ServerPlayer>(); internal static IServerApi api = null; protected override string Name => "Prop Hunt"; protected override string Version => "1.0.3"; public override uint ApiVersion => 1u; public override bool NeedsNetwork => true; public SeekerTimer SeekerTimer { get; private set; } public override void Initialize(IServerApi serverApi) { instance = this; api = serverApi; Log.SetLogger(((ServerAddon)this).Logger); Log.LogInfo("Prop Hunt Server Loaded."); Reset(); ServerNetwork.Init(serverApi, (ServerAddon)(object)this); ((ICommandManager<IServerCommand>)(object)serverApi.CommandManager).RegisterCommand((IServerCommand)(object)new ServerCommands()); serverApi.ServerManager.PlayerConnectEvent += delegate(IServerPlayer player) { ServerPlayer player2 = GetPlayer(player.Id); if (GameState == GameState.SeekerWait) { player2.seeker = true; ServerNetwork.SendRoundStart(player.Id, GameState == GameState.Playing); } }; serverApi.ServerManager.PlayerDisconnectEvent += delegate(IServerPlayer player) { players.Remove(player.Id); CheckGameOver(player); }; } public void Reset(bool disconnect = false) { Log.LogInfo("Resetting server"); GameState = GameState.NotStarted; SeekerTimer?.CancelTimer(); SeekerTimer = null; if (disconnect) { foreach (IServerPlayer player in api.ServerManager.Players) { api.ServerManager.DisconnectPlayer(player.Id, (DisconnectReason)0); } } players.Clear(); } internal static ServerPlayer GetPlayer(ushort playerID) { if (!players.TryGetValue(playerID, out var value)) { value = new ServerPlayer(playerID); players.Add(playerID, value); } return value; } public void Announce(string announcement) { Log.LogDebug("Announcement: " + announcement); api.ServerManager.BroadcastMessage(announcement); } public void Message(ushort recipientID, string message) { Log.LogDebug($"Message to {recipientID}: {message}"); api.ServerManager.SendMessage(recipientID, message); } public string DetermineWinner() { string text = null; foreach (ServerPlayer value in players.Values) { if (!string.IsNullOrEmpty(value.propName)) { if (text != null) { return null; } text = value.PlayerAvatar.Username; } } return text; } private void PickSeekers() { int num = Mathf.Clamp(Config.SeekerCount, 1, players.Count - 1); Log.LogDebug($"Choosing {num} seekers"); for (int i = 0; i < num; i++) { List<ServerPlayer> list = players.Values.Where((ServerPlayer p) => !p.seeker).ToList(); if (list.Count == 0) { Log.LogDebug($"Ran out of seekers to choose (Picked {i}/{num})"); break; } ServerPlayer randomElement = Extensions.GetRandomElement<ServerPlayer>(list); randomElement.seeker = true; Log.LogDebug(randomElement.PlayerAvatar.Username + " is a seeker"); } } private void ResetPlayers() { foreach (ServerPlayer value in players.Values) { value.seeker = false; value.hidden = false; value.swapCount = 0; value.ResetProp(); } } public void GameStart() { if (players.Count < 2) { Announce("...Well that's awkward. I can't start a game without two people!"); return; } ResetPlayers(); PickSeekers(); EnsureSettings(); GameState = GameState.SeekerWait; int seekerCountdown = Config.SeekerCountdown; Announce($"The game has begun! Hiders have a {seekerCountdown} second head start. Good luck!"); SeekerTimer = new SeekerTimer(seekerCountdown); ServerNetwork.BroadcastRoundStart(); } public void CheckGameOver(IServerPlayer playerHit, bool canceled = false) { if (GameState != 0 && (players.Values.All((ServerPlayer p) => string.IsNullOrEmpty(p.propName)) || canceled)) { ServerNetwork.BroadcastGameOver(playerHit, canceled); if (canceled) { Announce("The game has been stopped early!"); SeekerTimer?.CancelTimer(); } else { Announce(playerHit.Username + " was the last bug standing! Congrats!"); } GameState = GameState.NotStarted; ResetPlayers(); } } private void EnsureSettings() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown IServerSettings serverSettings = ((ServerAddon)this).ServerApi.ServerManager.ServerSettings; ServerSettings val = new ServerSettings { AllowSkins = serverSettings.AllowSkins, DisplayNames = serverSettings.DisplayNames, OnlyBroadcastMapIconWithCompass = serverSettings.OnlyBroadcastMapIconWithCompass, TeamsEnabled = serverSettings.TeamsEnabled, AlwaysShowMapIcons = false, IsPvpEnabled = false }; ((ServerAddon)this).ServerApi.ServerManager.ApplyServerSettings(val); } } public class SeekerTimer { public int seconds; private Timer timer; private void SetTimer(int seconds) { this.seconds = seconds; timer = new Timer(1000.0); timer.Elapsed += delegate { OnSecond(); }; timer.AutoReset = true; timer.Start(); } private void OnSecond() { seconds--; if (seconds <= 0) { timer.Stop(); timer = null; Server.instance.Announce("[Seekers]: Ready or not, here we come!"); Server.GameState = GameState.Playing; ServerNetwork.BroadcastSeekerStart(); } else if (seconds <= 5) { Server.instance.Announce($"[Seekers]: {seconds}..."); } } public void CancelTimer() { if (timer != null) { timer.Stop(); timer = null; } } public SeekerTimer(int seconds) { SetTimer(seconds); } } internal class ServerPlayer { public ushort id; public bool hidden; public bool seeker; public string propName; public string propPath; public Vector3 propLocation = Consts.DEFAULT_LOCATION; public float propRotation; public float propScale = 1f; public int swapCount; public IServerPlayer PlayerAvatar => Server.api.ServerManager.GetPlayer(id); public ServerPlayer(ushort id) { this.id = id; } public void ResetProp() { propName = ""; propPath = ""; propLocation = Consts.DEFAULT_LOCATION; propRotation = 0f; propScale = 1f; } } internal struct BypassTicket { public int Id; public CorrectiveActions action; public BypassTicket(int Id = -1, CorrectiveActions action = CorrectiveActions.None) { this.Id = Id; this.action = action; } } internal static class ServerNetwork { private static IServerAddonNetworkSender<CustomPackets> sender; private static IServerAddonNetworkReceiver<CustomPackets> receiver; private static readonly Dictionary<ushort, List<BypassTicket>> tickets = new Dictionary<ushort, List<BypassTicket>>(); private static int TicketID = 0; private static BypassTicket GenerateTicket(ushort playerID, CorrectiveActions action) { if (!tickets.ContainsKey(playerID)) { tickets[playerID] = new List<BypassTicket>(); } BypassTicket bypassTicket = default(BypassTicket); bypassTicket.action = action; bypassTicket.Id = TicketID; BypassTicket bypassTicket2 = bypassTicket; tickets[playerID].Add(bypassTicket2); TicketID++; return bypassTicket2; } private static bool IsValidTicket(ushort playerID, int ticketID, params CorrectiveActions[] action) { if (ticketID == -1) { return false; } if (!tickets.ContainsKey(playerID)) { return false; } int num = tickets[playerID].FindIndex((BypassTicket t) => t.Id == ticketID && action.Contains(t.action)); if (num == -1) { return false; } tickets[playerID].RemoveAt(num); return true; } public static void Broadcast(ushort senderID, CustomPackets packetID, Packet data, bool collection) { foreach (IServerPlayer player in Server.api.ServerManager.Players) { if (player.Id != senderID) { if (collection) { sender.SendCollectionData<Packet>(packetID, data, player.Id); } else { sender.SendSingleData(packetID, (IPacketData)(object)data, player.Id); } } } } private static void FailedAction(ushort senderID, ushort affectedID, CustomPackets packetType, CorrectiveActions fix) { int bypassTicketID = -1; if (fix == CorrectiveActions.ToggleHornetFalse || fix == CorrectiveActions.PreviousScene || fix == CorrectiveActions.RestoreLastProp) { bypassTicketID = GenerateTicket(senderID, fix).Id; } sender.SendCollectionData<FailedAction>(CustomPackets.FailedAction, new FailedAction { AffectedID = affectedID, FailedPacket = packetType, FixMethod = fix, BypassTicketID = bypassTicketID }, senderID); } public static void ForwardPropSwap(ushort id, string propName, string propPath) { Log.LogDebug($"Broadcasting prop swap from {id}: {propName}"); Broadcast(id, CustomPackets.PropSwap, new PropSwap { Id = id, propName = propName, propPath = propPath }, collection: true); } public static void BroadcastRoundStart() { Log.LogDebug("Broadcasting round start"); foreach (IServerPlayer player in Server.api.ServerManager.Players) { SendRoundStart(player.Id); } } public static void SendRoundStart(ushort id, bool started = false) { ServerPlayer player = Server.GetPlayer(id); RoundStart roundStart = new RoundStart { IsSeeker = player.seeker, PropSwapLimit = 0, SeekerWaitTime = ((!started) ? Server.instance.SeekerTimer.seconds : 0), SeekerAttackCooldown = Config.AttackCooldown }; sender.SendSingleData(CustomPackets.RoundStart, (IPacketData)(object)roundStart, id); } public static void ForwardPropLocation(ushort id, Vector3 propPosition, float propRotation, float propScale) { Log.LogDebug($"Broadcasting prop location from {id}: {propPosition}, {propRotation}, {propScale}"); BaseCoverManager.ConstrainPropLocation(ref propPosition, ref propRotation, ref propScale); Broadcast(id, CustomPackets.PropLocation, new PropLocation { Id = id, PropPosition = propPosition, PropRotation = propRotation, PropScale = propScale }, collection: true); } public static void ForwardHideStatus(ushort id, bool isHiding) { Log.LogDebug($"Broadcasting hide status from {id}: {isHiding}"); Broadcast(id, CustomPackets.HideStatus, new HideStatus { Id = id, IsHiding = isHiding }, collection: true); } public static void ForwardPropFound(ushort id, ushort propOwnerID) { Log.LogDebug($"Broadcasting prop found from {id}: {propOwnerID}"); foreach (IServerPlayer player in Server.api.ServerManager.Players) { PropFound propFound = new PropFound { IsClientFound = (player.Id == propOwnerID), PropOwnerID = propOwnerID }; sender.SendCollectionData<PropFound>(CustomPackets.PropFound, propFound, player.Id); } } public static void BroadcastGameOver(IServerPlayer winner, bool canceled) { Log.LogDebug("Broadcasting game over"); foreach (IServerPlayer player in Server.api.ServerManager.Players) { GameOver gameOver = new GameOver { IsWinner = (!canceled && ((winner != null) ? new ushort?(winner.Id) : null) == player.Id), WasCanceled = canceled, WinnerUsername = (((winner != null) ? winner.Username : null) ?? "Nobody") }; sender.SendSingleData(CustomPackets.GameOver, (IPacketData)(object)gameOver, player.Id); } } public static void BroadcastSeekerStart() { Log.LogDebug("Broadcasting seeker start"); sender.BroadcastSingleData(CustomPackets.SeekerStart, (IPacketData)(object)new SeekerStart()); } public static void Init(IServerApi serverApi, ServerAddon serverAddon) { sender = serverApi.NetServer.GetNetworkSender<CustomPackets>(serverAddon); receiver = serverApi.NetServer.GetNetworkReceiver<CustomPackets>(serverAddon, (Func<CustomPackets, IPacketData>)global::PropHuntMod.Networking.Client.Packets.Instantiate); receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.PropSwap>(CustomPackets.PropSwap, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.PropSwap>)OnPropSwap); receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.PropLocation>(CustomPackets.PropLocation, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.PropLocation>)OnPropLocation); receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.PropFound>(CustomPackets.PropFound, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.PropFound>)OnPropFound); receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.Sync>(CustomPackets.Sync, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.Sync>)OnSync); if (Config.AllowDebugFeatures) { receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.HideStatus>(CustomPackets.HideStatus, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.HideStatus>)OnHideStatus); } } private static void OnPropSwap(ushort id, global::PropHuntMod.Networking.Client.PropSwap data) { ServerPlayer player = Server.GetPlayer(id); bool flag = string.IsNullOrEmpty(data.propPath); if (player.seeker && Server.GameState != 0 && !flag) { Server.instance.Message(id, "You're a seeker! You can't hide this round."); FailedAction(id, id, CustomPackets.PropSwap, CorrectiveActions.DisableClientProp); return; } bool flag2 = IsValidTicket(id, data.TicketID, CorrectiveActions.RestoreLastProp, CorrectiveActions.PreviousScene); if (flag) { player.propName = ""; player.propPath = ""; } else { player.propName = data.propName; player.propPath = data.propPath; } if (!flag2) { player.swapCount++; } ForwardPropSwap(id, player.propName, player.propPath); } private static void OnPropLocation(ushort id, global::PropHuntMod.Networking.Client.PropLocation data) { ServerPlayer player = Server.GetPlayer(id); if (player.seeker && Server.GameState != 0) { Server.instance.Message(id, "You're a seeker! You can't hide this round."); FailedAction(id, id, CustomPackets.PropSwap, CorrectiveActions.DisableClientProp); return; } player.propLocation = data.PropPosition; player.propRotation = data.PropRotation; player.propScale = data.PropScale; BaseCoverManager.ConstrainPropLocation(ref player.propLocation, ref player.propRotation, ref player.propScale); ForwardPropLocation(id, player.propLocation, player.propRotation, player.propScale); } private static void OnSync(ushort id, global::PropHuntMod.Networking.Client.Sync data) { ServerPlayer player = Server.GetPlayer(id); if (player.seeker) { player.ResetProp(); } else { player.propName = data.PropName ?? ""; player.propPath = data.PropPath ?? ""; player.propLocation = data.PropLocation; player.propRotation = data.PropRotation; player.propScale = data.PropRotation; } BaseCoverManager.ConstrainPropLocation(ref player.propLocation, ref player.propRotation, ref player.propScale); ForwardPropSwap(id, player.propName, player.propPath); ForwardPropLocation(id, player.propLocation, player.propRotation, player.propScale); Server.instance.CheckGameOver(player.PlayerAvatar); } private static void OnHideStatus(ushort id, global::PropHuntMod.Networking.Client.HideStatus data) { ServerPlayer player = Server.GetPlayer(id); if (Server.GameState != 0 && player.seeker && data.IsHiding && !IsValidTicket(id, data.TicketID, CorrectiveActions.ToggleHornetFalse)) { Server.instance.Message(id, "You're a seeker! You can't hide this round."); FailedAction(id, id, CustomPackets.HideStatus, CorrectiveActions.ToggleHornetTrue); } else { player.hidden = data.IsHiding; ForwardHideStatus(id, data.IsHiding); } } private static void OnPropFound(ushort id, global::PropHuntMod.Networking.Client.PropFound data) { ServerPlayer player = Server.GetPlayer(data.PropOwnerID); ServerPlayer player2 = Server.GetPlayer(id); if (Server.GameState == GameState.SeekerWait) { Server.instance.Message(id, "You're still in the waiting period. No seeking yet!"); FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.RestoreTriggerHandler); return; } if (Server.GameState == GameState.Playing) { if (player.seeker) { Server.instance.Message(id, "That player is a seeker!"); FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.DisablePlayerProp); return; } if (!player2.seeker) { Server.instance.Message(id, "You're not a seeker! You can't find people this round."); FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.RestoreTriggerHandler); return; } player.seeker = true; } if (string.IsNullOrEmpty(player.propName)) { Server.instance.Message(id, "That player has already been found. You might be out of sync."); FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.DisablePlayerProp); return; } player.ResetProp(); ForwardPropFound(id, data.PropOwnerID); Server.instance.Announce(player.PlayerAvatar.Username + " was found by " + player2.PlayerAvatar.Username + "!"); if (Server.GameState == GameState.Playing) { Server.instance.CheckGameOver(player.PlayerAvatar); } } } public class PropSwap : global::PropHuntMod.Networking.Client.PropSwap { public override bool DropReliableDataIfNewerExists => false; public ushort Id { get; set; } public override void WriteData(IPacket packet) { packet.Write(Id); base.WriteData(packet); } public override void ReadData(IPacket packet) { Id = packet.ReadUShort(); base.ReadData(packet); } } public class RoundStart : Packet { public bool IsSeeker; public ushort PropSwapLimit; public int SeekerWaitTime; public float SeekerAttackCooldown; public override void WriteData(IPacket packet) { packet.Write(IsSeeker); packet.Write(PropSwapLimit); packet.Write(SeekerWaitTime); packet.Write(SeekerAttackCooldown); } public override void ReadData(IPacket packet) { IsSeeker = packet.ReadBool(); PropSwapLimit = packet.ReadUShort(); SeekerWaitTime = packet.ReadInt(); SeekerAttackCooldown = packet.ReadFloat(); } } public class PropLocation : global::PropHuntMod.Networking.Client.PropLocation { public override bool DropReliableDataIfNewerExists => false; public ushort Id { get; set; } public override void WriteData(IPacket packet) { packet.Write(Id); base.WriteData(packet); } public override void ReadData(IPacket packet) { Id = packet.ReadUShort(); base.ReadData(packet); } } public class HideStatus : global::PropHuntMod.Networking.Client.HideStatus { public override bool DropReliableDataIfNewerExists => false; public ushort Id { get; set; } public override void WriteData(IPacket packet) { packet.Write(Id); base.WriteData(packet); } public override void ReadData(IPacket packet) { Id = packet.ReadUShort(); base.ReadData(packet); } } public class PropFound : global::PropHuntMod.Networking.Client.PropFound { public override bool DropReliableDataIfNewerExists => false; public bool IsClientFound { get; set; } public override void WriteData(IPacket packet) { packet.Write(IsClientFound); base.WriteData(packet); } public override void ReadData(IPacket packet) { IsClientFound = packet.ReadBool(); base.ReadData(packet); } } public class SeekerStart : Packet { } public class GameOver : Packet { public string WinnerUsername { get; set; } public bool IsWinner { get; set; } public bool WasCanceled { get; set; } public override void WriteData(IPacket packet) { packet.Write(WinnerUsername); packet.Write(IsWinner); packet.Write(WasCanceled); } public override void ReadData(IPacket packet) { WinnerUsername = packet.ReadString(); IsWinner = packet.ReadBool(); WasCanceled = packet.ReadBool(); } } public class FailedAction : Packet { public CustomPackets FailedPacket; public CorrectiveActions FixMethod; public ushort AffectedID; public int BypassTicketID; public override void WriteData(IPacket packet) { packet.Write((int)FailedPacket); packet.Write((int)FixMethod); packet.Write(AffectedID); packet.Write(BypassTicketID); } public override void ReadData(IPacket packet) { FailedPacket = (CustomPackets)packet.ReadInt(); FixMethod = (CorrectiveActions)packet.ReadInt(); AffectedID = packet.ReadUShort(); BypassTicketID = packet.ReadUShort(); } } public static class Packets { internal static IPacketData Instantiate(CustomPackets packetID) { return (IPacketData)(packetID switch { CustomPackets.PropSwap => new PacketDataCollection<PropSwap>(), CustomPackets.RoundStart => new RoundStart(), CustomPackets.PropLocation => new PacketDataCollection<PropLocation>(), CustomPackets.HideStatus => new PacketDataCollection<HideStatus>(), CustomPackets.PropFound => new PacketDataCollection<PropFound>(), CustomPackets.GameOver => new GameOver(), CustomPackets.SeekerStart => new SeekerStart(), CustomPackets.FailedAction => new PacketDataCollection<FailedAction>(), _ => throw new NotImplementedException(packetID.ToString()), }); } } } namespace PropHuntMod.Networking.Client { internal enum Teams { Hunter = 4, Seeker = 3 } internal class Client : ClientAddon { public static GameState GameState; public static bool isSeeker; public static ushort propSwaps; public static ushort maxPropSwaps; public static float seekerAttackCooldown; protected override string Name => "Prop Hunt"; protected override string Version => "1.0.3"; public override uint ApiVersion => 1u; public override bool NeedsNetwork => true; public override void Initialize(IClientApi clientApi) { PropHuntMod.Initialize(clientApi); Log.SetLogger(((ClientAddon)this).Logger); Log.LogInfo("Prop Hunt Client Loaded."); ClientNetwork.Init(clientApi, (ClientAddon)(object)this); clientApi.ClientManager.ConnectEvent += delegate { string[] array = new string[5] { "Prop Hunt Commands:", "/ph start: starts a round", "/ph stop: stops a round", "/ph config: configure server settings", "/sync: syncs other player's props" }; for (int i = 0; i < array.Length; i++) { LocalMessage(array[i]); } }; clientApi.ClientManager.DisconnectEvent += delegate { GameState = GameState.NotStarted; isSeeker = false; propSwaps = 0; maxPropSwaps = 0; PropHuntMod.playerManager.Clear(); global::PropHuntMod.Networking.Server.Server.instance.Reset(disconnect: true); }; clientApi.ClientManager.PlayerConnectEvent += delegate(IClientPlayer player) { PlayerManager.GetPlayerManager(player.Id); }; clientApi.ClientManager.PlayerDisconnectEvent += delegate(IClientPlayer player) { PropHuntMod.playerManager.Remove(player.Id); }; clientApi.ClientManager.PlayerEnterSceneEvent += delegate(IClientPlayer player) { PlayerManager playerManager = PlayerManager.GetPlayerManager(player.Id); playerManager.hornetManager.SetHornet(); playerManager.EnsurePropCover(); }; ((ICommandManager<IClientCommand>)(object)clientApi.CommandManager).RegisterCommand((IClientCommand)(object)new ShowHitboxes()); ((ICommandManager<IClientCommand>)(object)clientApi.CommandManager).RegisterCommand((IClientCommand)(object)new global::PropHuntMod.Commands.Sync()); } public static void LocalMessage(string message) { PropHuntMod.client.UiManager.ChatBox.AddMessage(message); } } internal static class ClientErrorCorrection { [CompilerGenerated] private sealed class <PreviousScene>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public FailedAction data; private int <i>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PreviousScene>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <i>5__2 = 0; break; case 1: <>1__state = -1; <i>5__2++; break; } if (<i>5__2 < 5 && string.IsNullOrEmpty(ScenePatches.PreviousScene)) { Log.LogWarning($"Attempt {<i>5__2 + 1} to find previous scene failed"); <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } if (string.IsNullOrEmpty(ScenePatches.PreviousScene)) { PropHuntMod.client.ClientManager.Disconnect(); Client.LocalMessage("Fatal Error: Unable to find previous scene."); return false; } SceneLoadInfo val = new SceneLoadInfo { SceneName = ScenePatches.PreviousScene, PreventCameraFadeOut = true, WaitForSceneTransitionCameraFade = false, Visualization = (SceneLoadVisualizations)0, AlwaysUnloadUnusedAssets = true, IsFirstLevelForPlayer = false }; ScenePatches.SceneTransitionTicket = data.BypassTicketID; GameManager.instance.BeginSceneTransition(val); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void DiagnoseError(FailedAction data) { switch (data.FixMethod) { case CorrectiveActions.DisableClientProp: SelfCoverManager.instance.DisableProp(logOnFail: false, isSceneChange: false, data.BypassTicketID); break; case CorrectiveActions.DisablePlayerProp: DisablePlayerProp(data); break; case CorrectiveActions.PreviousScene: ((MonoBehaviour)PropHuntMod.Instance).StartCoroutine(PreviousScene(data)); break; case CorrectiveActions.ToggleHornetTrue: SelfHornetManager.instance.ToggleHornet(show: true); break; case CorrectiveActions.ToggleHornetFalse: SelfHornetManager.instance.ToggleHornet(show: false, data.BypassTicketID); break; case CorrectiveActions.RestoreLastProp: RestoreLastProp(data); break; case CorrectiveActions.RestoreTriggerHandler: RestoreTriggerHandler(data); break; case CorrectiveActions.BecomeSeeker: BecomeSeeker(); break; default: throw new NotImplementedException(data.FixMethod.ToString()); case CorrectiveActions.None: break; } } private static void DisablePlayerProp(FailedAction data) { PlayerManager.GetPlayerManager(data.AffectedID).SetProp("", ""); } [IteratorStateMachine(typeof(<PreviousScene>d__2))] private static IEnumerator PreviousScene(FailedAction data) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PreviousScene>d__2(0) { data = data }; } public static void RestoreLastProp(FailedAction data) { SelfCoverManager instance = SelfCoverManager.instance; GameObject obj = PropValidation.FindGameObject(instance.PrevCoverPath); Prop prop = PropValidation.PrepareProp(obj); if ((Object)(object)obj == (Object)null || prop == null) { Log.LogFatal("Couldn't restore previous prop " + instance.PrevCoverPath); } else { SelfCoverManager.instance.EnableProp(prop, data.BypassTicketID); } } private static void RestoreTriggerHandler(FailedAction data) { GameObject cover = PlayerManager.GetPlayerManager(data.AffectedID).coverManager.cover; if ((Object)(object)cover != (Object)null) { if ((Object)(object)cover.GetComponent<TriggerHandler>() == (Object)null) { TriggerHandler triggerHandler = cover.AddComponent<TriggerHandler>(); triggerHandler.isRemote = true; triggerHandler.playerID = data.AffectedID; } else { Log.LogDebug($"Player {data.AffectedID} still had their TriggerHandler. Not restoring."); } } else { Log.LogError($"Player {data.AffectedID}'s prop was already destroyed. Can't restore trigger handler"); } } private static void BecomeSeeker() { Client.isSeeker = true; if (Client.GameState == GameState.SeekerWait) { SelfHornetManager.instance.SetSeekerObscure(enabled: true); } } } internal static class ClientNetwork { private static IClientApi api; private static IClientAddonNetworkSender<CustomPackets> sender; private static IClientAddonNetworkReceiver<CustomPackets> receiver; private static void SendData(CustomPackets packetId, IPacketData data) { if (api.NetClient.IsConnected && sender != null) { sender.SendSingleData(packetId, data); } } private static void SendCollectionData(CustomPackets packetId, Packet data) { if (api.NetClient.IsConnected && sender != null) { sender.SendCollectionData<Packet>(packetId, data); } } public static void SendPropSwap(Prop prop, int ticket = -1) { Log.LogDebug("Sending prop swap: " + prop?.name); SendData(CustomPackets.PropSwap, (IPacketData)(object)new PropSwap { propName = (prop?.name ?? ""), propPath = (prop?.path ?? ""), TicketID = ticket }); } public static void SendPropLocation(Vector3 propPosition, float propRotation, float propScale) { Log.LogDebug($"Sending prop location: {propPosition}, {propRotation}, {propScale}"); SendData(CustomPackets.PropLocation, (IPacketData)(object)new PropLocation { PropPosition = propPosition, PropRotation = propRotation, PropScale = propScale }); } public static void SendHideStatus(bool isHiding, int ticket = -1) { Log.LogDebug($"Sending hide status: {isHiding}"); SendData(CustomPackets.HideStatus, (IPacketData)(object)new HideStatus { IsHiding = isHiding, TicketID = ticket }); } public static void SendPropFound(ushort propOwnerID) { Log.LogDebug($"Sending prop found: {propOwnerID}"); SendCollectionData(CustomPackets.PropFound, new PropFound { PropOwnerID = propOwnerID }); } public static void SendSync(string propName, string propPath, Vector3 propPosition, float propRotation, float propScale) { Log.LogDebug($"Sending sync data: {propName}, {propPosition}, {propRotation}, {propScale}"); SendData(CustomPackets.Sync, (IPacketData)(object)new Sync { PropName = propName, PropPath = propPath, PropLocation = propPosition, PropRotation = propRotation, PropScale = propScale }); } public static void Init(IClientApi clientApi, ClientAddon clientAddon) { api = clientApi; sender = clientApi.NetClient.GetNetworkSender<CustomPackets>(clientAddon); receiver = clientApi.NetClient.GetNetworkReceiver<CustomPackets>(clientAddon, (Func<CustomPackets, IPacketData>)global::PropHuntMod.Networking.Server.Packets.Instantiate); receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.PropSwap>(CustomPackets.PropSwap, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.PropSwap>)OnPropSwap); receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.PropLocation>(CustomPackets.PropLocation, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.PropLocation>)OnPropLocation); receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.PropFound>(CustomPackets.PropFound, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.PropFound>)OnPropFound); receiver.RegisterPacketHandler<RoundStart>(CustomPackets.RoundStart, (GenericClientPacketHandler<RoundStart>)OnRoundStart); receiver.RegisterPacketHandler<GameOver>(CustomPackets.GameOver, (GenericClientPacketHandler<GameOver>)OnGameOver); receiver.RegisterPacketHandler<SeekerStart>(CustomPackets.SeekerStart, (GenericClientPacketHandler<SeekerStart>)OnSeekerStart); receiver.RegisterPacketHandler<FailedAction>(CustomPackets.FailedAction, (GenericClientPacketHandler<FailedAction>)ClientErrorCorrection.DiagnoseError); if (Config.AllowDebugFeatures) { receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.HideStatus>(CustomPackets.HideStatus, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.HideStatus>)OnHideStatus); } } private static void OnPropSwap(global::PropHuntMod.Networking.Server.PropSwap data) { PlayerManager.GetPlayerManager(data.Id).SetProp(data.propName, data.propPath); Log.LogDebug($"{data.Id} prop set to {data.propName}"); } private static void OnRoundStart(RoundStart data) { bool flag = data.SeekerWaitTime == 0; if (flag) { Client.GameState = GameState.Playing; } else { Client.GameState = GameState.SeekerWait; } Client.isSeeker = data.IsSeeker; Client.propSwaps = 0; Client.maxPropSwaps = data.PropSwapLimit; Client.seekerAttackCooldown = data.SeekerAttackCooldown; if (data.IsSeeker) { Client.LocalMessage("You're a seeker!"); SelfCoverManager.instance.DisableProp(logOnFail: false); if (!flag) { SelfHornetManager.instance.SetSeekerObscure(enabled: true); EffectsManager.SetTitle("SEEKER", $"Wait time: {data.SeekerWaitTime} seconds", "YOUR ROLE:", large: true, 10f); } else { EffectsManager.SetTitle("SEEKER", "It's go time!", "YOUR ROLE:", large: true, 10f); } } else { EffectsManager.SetTitle("HIDER", "", "YOUR ROLE:"); SelfCoverManager.instance.EnableRandomProp(); Client.LocalMessage("You're hiding this round!"); } } private static void OnPropLocation(global::PropHuntMod.Networking.Server.PropLocation data) { PlayerManager.GetPlayerManager(data.Id).SetPropLocation(data.PropPosition, data.PropRotation, data.PropScale); Log.LogDebug($"{data.Id} prop moved to {data.PropPosition}, {data.PropRotation}, {data.PropScale}"); } private static void OnHideStatus(global::PropHuntMod.Networking.Server.HideStatus data) { PlayerManager.GetPlayerManager(data.Id).SetHideStatus(data.IsHiding); Log.LogDebug($"{data.Id} hiding status set to {data.IsHiding}"); } private static void OnPropFound(global::PropHuntMod.Networking.Server.PropFound data) { if (data.IsClientFound) { Log.LogDebug("I've been found!"); SelfCoverManager.instance.FindProp(SelfHornetManager.instance); if (Client.GameState == GameState.Playing) { Client.isSeeker = true; } } else { PlayerManager playerManager = PlayerManager.GetPlayerManager(data.PropOwnerID); playerManager.coverManager.FindProp(playerManager.hornetManager); playerManager.SetProp("", ""); Log.LogDebug(playerManager.PlayerAvatar.Username + " has been found"); } EffectsManager.PlayFoundSound(data.IsClientFound); } private static void OnGameOver(GameOver data) { Client.GameState = GameState.NotStarted; Client.isSeeker = false; Client.propSwaps = 0; SelfHornetManager.instance.SetSeekerObscure(enabled: false); SelfCoverManager.instance.DisableProp(); EffectsManager.PlayGameOverSound(!data.WasCanceled && data.IsWinner); string main = (data.WasCanceled ? "Round Canceled" : (data.IsWinner ? "You Won!" : "Round Complete")); string sub = ((data.IsWinner || data.WasCanceled) ? "" : (data.WinnerUsername + " won!")); EffectsManager.SetTitle(main, sub); if (data.IsWinner) { EffectsManager.PlayConfetti(); } GameManager.instance.FreezeMoment((FreezeMomentTypes)10, (Action)null); } private static void OnSeekerStart(SeekerStart data) { Client.GameState = GameState.Playing; if (Client.isSeeker) { SelfHornetManager.instance.SetSeekerObscure(enabled: false); } } } public class Packet : IPacketData { public bool IsReliable => true; public virtual bool DropReliableDataIfNewerExists => true; public virtual void ReadData(IPacket packet) { } public virtual void WriteData(IPacket packet) { } } public class PropSwap : Packet { public string propName = ""; public string propPath = ""; public int TicketID = -1; public override void WriteData(IPacket packet) { packet.Write(propName); packet.Write(propPath); packet.Write(TicketID); } public override void ReadData(IPacket packet) { propName = packet.ReadString(); propPath = packet.ReadString(); TicketID = packet.ReadInt(); } } public class PropLocation : Packet { public Vector3 PropPosition { get; set; } public float PropRotation { get; set; } public float PropScale { get; set; } public override void WriteData(IPacket packet) { packet.Write(PropPosition); packet.Write(PropRotation); packet.Write(PropScale); } public override void ReadData(IPacket packet) { PropPosition = packet.ReadVector3(); PropRotation = packet.ReadFloat(); PropScale = packet.ReadFloat(); } } public class HideStatus : Packet { public int TicketID = -1; public bool IsHiding { get; set; } public override void WriteData(IPacket packet) { packet.Write(IsHiding); packet.Write(TicketID); } public override void ReadData(IPacket packet) { IsHiding = packet.ReadBool(); TicketID = packet.ReadInt(); } } public class PropFound : Packet { public override bool DropReliableDataIfNewerExists => false; public ushort PropOwnerID { get; set; } public override void WriteData(IPacket packet) { packet.Write(PropOwnerID); } public override void ReadData(IPacket packet) { PropOwnerID = packet.ReadUShort(); } } public class Sync : Packet { public string PropName { get; set; } public string PropPath { get; set; } public Vector3 PropLocation { get; set; } public float PropRotation { get; set; } public float PropScale { get; set; } public override void WriteData(IPacket packet) { packet.Write(PropName); packet.Write(PropPath); packet.Write(PropLocation); packet.Write(PropRotation); packet.Write(PropScale); } public override void ReadData(IPacket packet) { PropName = packet.ReadString(); PropPath = packet.ReadString(); PropLocation = packet.ReadVector3(); PropRotation = packet.ReadFloat(); PropScale = packet.ReadFloat(); } } public static class Packets { internal static IPacketData Instantiate(CustomPackets packetID) { return (IPacketData)(packetID switch { CustomPackets.PropSwap => new PropSwap(), CustomPackets.PropLocation => new PropLocation(), CustomPackets.HideStatus => new HideStatus(), CustomPackets.PropFound => new PacketDataCollection<PropFound>(), CustomPackets.Sync => new Sync(), _ => throw new NotImplementedException(packetID.ToString()), }); } } } namespace PropHuntMod.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { resourceMan = new ResourceManager("PropHuntMod.Properties.Resources", typeof(Resources).Assembly); } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] bundle => (byte[])ResourceManager.GetObject("bundle", resourceCulture); internal static byte[] icon => (byte[])ResourceManager.GetObject("icon", resourceCulture); internal static byte[] manifest => (byte[])ResourceManager.GetObject("manifest", resourceCulture); internal Resources() { } } } namespace PropHuntMod.Props { internal enum Direction { Left, Right, Up, Down, Front, Back, Reset, RotateLeft, RotateRight, ScaleUp, ScaleDown } internal class SelfCoverManager : BaseCoverManager { public static SelfCoverManager instance; internal bool movedRecently; internal SelfCoverManager() { isRemote = false; instance = this; } public void MoveProp(Direction direction, KeyCode key, ref bool moved, bool onlyOnce = false) { //IL_000d: 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) if (base.IsHiding && (!onlyOnce || Input.GetKeyDown(key)) && (onlyOnce || Input.GetKey(key))) { moved = true; float distance = ((Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307)) ? 0.01f : 0.1f); MoveProp(direction, distance); } } public void MoveProp(Direction direction, float distance = 0.1f) { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown if (!base.IsHiding) { Log.LogError("No cover, can't move"); return; } float num = base.Position.X; float num2 = base.Position.Y; float num3 = base.Position.Z; float num4 = base.Rotation; float num5 = base.Scale; SelfHornetManager selfHornetManager = SelfHornetManager.instance; if (selfHornetManager.HornetExists()) { bool flag = Extensions.GetScaleX(selfHornetManager.hornet.transform) < 1f; switch (direction) { case Direction.Left: num = ((!flag) ? (num - distance) : (num + distance)); break; case Direction.Right: num = ((!flag) ? (num + distance) : (num - distance)); break; case Direction.Up: num2 += distance; break; case Direction.Down: num2 -= distance; break; case Direction.Front: num3 -= distance; break; case Direction.Back: num3 += distance; break; case Direction.ScaleUp: num5 *= 1f + distance / 5f; break; case Direction.ScaleDown: num5 /= 1f + distance / 5f; break; case Direction.RotateLeft: num4 = ((!flag) ? (num4 + distance * 10f) : (num4 - distance * 10f)); break; case Direction.RotateRight: num4 = ((!flag) ? (num4 - distance * 10f) : (num4 + distance * 10f)); break; case Direction.Reset: num = Consts.DEFAULT_LOCATION.X; num2 = Consts.DEFAULT_LOCATION.Y; num3 = Consts.DEFAULT_LOCATION.Z; num4 = 0f; num5 = 1f; break; default: Log.LogError($"Invalid movement direction {direction} ({(int)direction})"); return; } Vector3 location = new Vector3(num, num2, num3); SetPropLocation(location, num4, num5); movedRecently = true; } } public void SendPropPosition() { if (movedRecently) { if (!base.IsHiding) { Log.LogError("No cover, can't send prop position"); } else { movedRecently = false; ClientNetwork.SendPropLocation(base.Position, base.Rotation, base.Scale); } } } public void EnableRandomProp() { if (PropValidation.currentSceneObjects == null) { PropValidation.GetAllProps(); } if (!IsSeeker()) { if (Client.maxPropSwaps > 0 && Client.propSwaps >= Client.maxPropSwaps) { Client.LocalMessage($"You've reached the max number of prop swaps (${Client.maxPropSwaps})."); return; } Prop random = PropValidation.currentSceneObjects.GetRandom(); EnableProp(random); Log.LogDebug(random.path); Log.LogDebug(PropValidation.FindGameObject(random.path)); } } public bool EnableProp(Prop prop, int ticket = -1) { if (IsSeeker()) { return false; } Log.LogDebug("Enabling prop"); bool num = base.EnableProp(SelfHornetManager.instance, prop); if (num) { ClientNetwork.SendPropSwap(prop, ticket); Client.propSwaps++; } return num; } public bool DisableProp(bool logOnFail = true, bool isSceneChange = false, int ticket = -1) { bool num = base.DisableProp(SelfHornetManager.instance, logOnFail); if (num && !isSceneChange) { PropMovementControls.Instance.SetMovementState(MovementState.Normal); ClientNetwork.SendPropSwap(null, ticket); PropHuntMod.showHitboxes = false; } return num; } public override void OnHit(TriggerHandler handler) { Log.LogError("UH OH! ON HIT IS SUPPOSED TO BE A REMOTE PLAYER!"); } private bool IsSeeker() { if (Client.isSeeker) { Client.LocalMessage("You're a seeker! You can't enable props right now."); return true; } return false; } public override bool EnableProp(BaseHornetManager hornet, Prop prop) { return EnableProp(prop); } public override bool DisableProp(BaseHornetManager hornet, bool logOnFail = true) { return DisableProp(logOnFail); } } internal class BaseCoverManager { internal GameObject cover; internal string CoverPath; internal string PrevCoverPath; public ushort playerID; internal bool isRemote = true; internal Vector3 Position { get { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) GameObject obj = cover; Vector3? val = ((obj != null) ? new Vector3?(obj.transform.localPosition) : null); return (val.HasValue ? ((Vector3)val.GetValueOrDefault()) : null) ?? Consts.DEFAULT_LOCATION; } } internal float Rotation { get { GameObject obj = cover; if (obj == null) { return 0f; } return Extensions.GetLocalRotation2D(obj.transform); } } internal float Scale { get; private set; } = 1f; internal Vector2 OriginalScale { get; private set; } = Vector2.one; public bool IsHiding => (Object)(object)cover != (Object)null; public void SetPropLocation(Vector3 location) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!IsHiding) { Log.LogError("No cover, can't set prop position"); } else { cover.transform.localPosition = (Vector3)location; } } public void SetPropRotation(float rotation) { if (!IsHiding) { Log.LogError("No cover, can't set prop rotation"); } else { Extensions.SetLocalRotation2D(cover.transform, rotation); } } public void SetPropScale(float scale) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Scale = scale; if (!IsHiding) { Log.LogError("No cover, can't set prop scale"); } else { Extensions.SetScale2D(cover.transform, OriginalScale * scale); } } public void SetPropLocation(Vector3 location, float rotation, float scale) { if (!IsHiding) { Log.LogError("No cover, can't set any prop location"); return; } ConstrainPropLocation(ref location, ref rotation, ref scale); SetPropLocation(location); SetPropRotation(rotation); SetPropScale(scale); } public static void ConstrainPropLocation(ref Vector3 location, ref float rotation, ref float scale) { location.X = Mathf.Clamp(location.X, -2f, 2f); location.Y = Mathf.Clamp(location.Y, -4f, 4f); location.Z = Mathf.Clamp(location.Z, -8f, 8f); rotation %= 360f; scale = Mathf.Clamp(scale, 0.5f, 2f); } public virtual bool DisableProp(BaseHornetManager manager, bool logOnFail = true) { if (!IsHiding) { if (logOnFail) { Log.LogError("No cover to disable"); } return false; } Log.LogDebug($"Destroying prop {cover}"); Object.Destroy((Object)(object)cover); cover = null; manager.ToggleHornet(show: true); return true; } public void FindProp(BaseHornetManager manager) { if (!IsHiding) { Log.LogError("No cover to disable"); return; } cover.transform.parent = null; manager.ToggleHornet(show: true); GameObject coverCopy = cover.gameObject; cover = null; Object.Destroy((Object)(object)coverCopy.GetComponent<TriggerHandler>()); EffectsManager.SweepGameObject(coverCopy, delegate { Object.Destroy((Object)(object)coverCopy); }); } public virtual bool EnableProp(BaseHornetManager hornet, Prop prop) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (prop == null) { Client.LocalMessage("There isn't any valid cover here. Try another room."); Log.LogError("No valid cover found"); return false; } if (IsHiding) { Log.LogWarning("Destroying cover..."); PrevCoverPath = CoverPath; Object.Destroy((Object)(object)cover); cover = null; } if (!hornet.HornetExists()) { return false; } try { Log.LogDebug("Creating prop"); if (PrevCoverPath == null) { PrevCoverPath = prop.path; } cover = Object.Instantiate<GameObject>(prop.go, hornet.hornet.transform); ((Object)cover).name = prop.name; CoverPath = prop.path; SpriteRenderer component = cover.GetComponent<SpriteRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = true; component.maskInteraction = (SpriteMaskInteraction)0; } OriginalScale = Vector2.op_Implicit(cover.transform.lossyScale); SetPropLocation(Consts.DEFAULT_LOCATION, 0f, 1f); cover.SetActive(true); cover.layer = 20; hornet.ToggleHornet(show: false); TriggerHandler component2 = cover.GetComponent<TriggerHandler>(); component2.playerID = playerID; component2.isRemote = isRemote; } catch (Exception ex) { Log.LogError("Ran into an error instantiating cover."); Log.LogError(ex); } return true; } public virtual void OnHit(TriggerHandler handler) { Log.LogDebug($"Found {playerID}"); Object.Destroy((Object)(object)handler); ClientNetwork.SendPropFound(playerID); } } internal class TriggerHandler : MonoBehaviour { public ushort playerID; public bool isRemote; private void OnTriggerEnter2D(Collider2D other) { if (isRemote && ((Component)other).tag == "Nail Attack" && ((Client.GameState == GameState.Playing) ? Client.isSeeker : (!SelfCoverManager.instance.IsHiding)) && Object.op_Implicit((Object)(object)((Component)other).GetComponentInParent<HeroController>())) { PlayerManager.GetPlayerManager(playerID).coverManager.OnHit(this); } } } internal class PropMovementControls { private static float StickThreshold = 0.02f; private static SpriteRenderer StateIndicator; private static Sprite MoveXY; private static Sprite MoveZ; private static Sprite Rotate; private static Sprite Scale; private bool moved; public static PropMovementControls Instance; internal static MovementState MovementState = MovementState.Normal; private InputBlockingMechanism blocker = new InputBlockingMechanism(); private bool ModeSwitchPressed; public PropMovementControls() { if (Instance == null) { Instance = this; } } private void ChangeModes() { if (!SelfCoverManager.instance.IsHiding) { SetMovementState(MovementState.Normal); } else if (MovementState == MovementState.Normal) { SetMovementState(MovementState.Move2D); } else if (MovementState == MovementState.Move2D) { SetMovementState(MovementState.MoveZ); } else if (MovementState == MovementState.MoveZ) { SetMovementState(MovementState.Scale); } else if (MovementState == MovementState.Scale) { SetMovementState(MovementState.Rotate); } else { SetMovementState(MovementState.Normal); } } private bool ResetPosition() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown(Config.PropPositionReset)) { MoveProp(Direction.Reset); SetMovementState(MovementState.Normal); moved = true; return true; } return false; } private bool CheckStick(OneAxisInputControl input, Direction direction, bool useValue = true) { if (input.IsPressed && input.Value > StickThreshold) { float num = 0.1f; if (useValue) { num = input.Value / 5f; } if (((OneAxisInputControl)ManagerSingleton<InputHandler>.Instance.inputActions.Dash).IsPressed) { num /= 2f; } MoveProp(direction, num); return true; } return false; } private void NonKeypadUpdate(OneAxisInputControl switchModeButton, OneAxisInputControl left, OneAxisInputControl right, OneAxisInputControl up, OneAxisInputControl down, bool useValue) { left.Enabled = true; right.Enabled = true; up.Enabled = true; down.Enabled = true; switchModeButton.Enabled = true; ((OneAxisInputControl)ManagerSingleton<InputHandler>.Instance.inputActions.Dash).Enabled = true; if (switchModeButton.IsPressed && !ModeSwitchPressed) { ChangeModes(); ModeSwitchPressed = true; } else if (!switchModeButton.IsPressed) { ModeSwitchPressed = false; } if (MovementState == MovementState.Move2D) { if (!CheckStick(left, Direction.Left, useValue)) { CheckStick(right, Direction.Right, useValue); } if (!CheckStick(up, Direction.Up, useValue)) { CheckStick(down, Direction.Down, useValue); } } else if (MovementState == MovementState.MoveZ) { if (!CheckStick(left, Direction.Back, useValue)) { CheckStick(right, Direction.Front, useValue); } if (!CheckStick(up, Direction.Back, useValue)) { CheckStick(down, Direction.Front, useValue); } } else if (MovementState == MovementState.Scale) { if (!CheckStick(left, Direction.ScaleUp, useValue)) { CheckStick(right, Direction.ScaleDown, useValue); } if (!CheckStick(up, Direction.ScaleUp, useValue)) { CheckStick(down, Direction.ScaleDown, useValue); } } else if (MovementState == MovementState.Rotate && !CheckStick(left, Direction.RotateLeft, useValue)) { CheckStick(right, Direction.RotateRight, useValue); } } private void ControllerUpdate(bool rightStick = true) { TwoAxisInputControl val = (rightStick ? InputManager.ActiveDevice.RightStick : InputManager.ActiveDevice.LeftStick); if (val != null) { InputControl val2 = (rightStick ? InputManager.ActiveDevice.RightStickButton : InputManager.ActiveDevice.LeftStickButton); if (val2 != null) { NonKeypadUpdate((OneAxisInputControl)(object)val2, val.Left, val.Right, val.Up, val.Down, useValue: true); } } } private void NumpadUpdate() { SelfCoverManager instance = SelfCoverManager.instance; instance.MoveProp(Direction.Left, (KeyCode)260, ref moved); instance.MoveProp(Direction.Right, (KeyCode)262, ref moved); instance.MoveProp(Direction.Up, (KeyCode)264, ref moved); instance.MoveProp(Direction.Down, (KeyCode)258, ref moved); instance.MoveProp(Direction.Front, (KeyCode)263, ref moved); instance.MoveProp(Direction.Back, (KeyCode)265, ref moved); instance.MoveProp(Direction.RotateLeft, (KeyCode)257, ref moved); instance.MoveProp(Direction.RotateRight, (KeyCode)259, ref moved); instance.MoveProp(Direction.ScaleUp, (KeyCode)270, ref moved); instance.MoveProp(Direction.ScaleDown, (KeyCode)269, ref moved); } private void KeyboardUpdate() { HeroActions inputActions = ManagerSingleton<InputHandler>.Instance.inputActions; NonKeypadUpdate((OneAxisInputControl)(object)inputActions.Taunt, (OneAxisInputControl)(object)inputActions.Left, (OneAxisInputControl)(object)inputActions.Right, (OneAxisInputControl)(object)inputActions.Up, (OneAxisInputControl)(object)inputActions.Down, useValue: false); } public void Update() { if (!ResetPosition()) { switch (Config.MovementMethod) { case MovementMethods.ControllerRightStick: ControllerUpdate(); break; case MovementMethods.ControllerLeftStick: ControllerUpdate(rightStick: false); break; case MovementMethods.Numpad: NumpadUpdate(); break; case MovementMethods.KeyboardMovement: KeyboardUpdate(); break; } if (!moved) { SelfCoverManager.instance.SendPropPosition(); } moved = false; } } private void MoveProp(Direction direction, float distance = 0.1f) { moved = true; SelfCoverManager.instance.MoveProp(direction, distance); } public void SetMovementState(MovementState newState) { Log.LogDebug($"Movement State: {MovementState} -> {newState}"); MovementState = newState; switch (newState) { case MovementState.Move2D: HeroController.instance.AddInputBlocker((object)blocker); break; case MovementState.Normal: PropHuntMod.nextFrameActions.Add(delegate { HeroController.instance.RemoveInputBlocker((object)blocker); }); break; } if ((Object)(object)StateIndicator == (Object)null) { CreateMovementIndicator(); } switch (newState) { case MovementState.Normal: StateIndicator.sprite = null; break; case MovementState.Move2D: StateIndicator.sprite = MoveXY; break; case MovementState.MoveZ: StateIndicator.sprite = MoveZ; break; case MovementState.Scale: StateIndicator.sprite = Scale; break; case MovementState.Rotate: StateIndicator.sprite = Rotate; break; } } private void CreateMovementIndicator() { //IL_0105: Unknown result type (might be due to invalid IL or missing references) AssetBundle obj = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "prophunt.bundle")); Sprite[] source = obj.LoadAllAssets<Sprite>(); MoveXY = source.First((Sprite a) => ((Object)a).name == "MoveXY"); MoveZ = source.First((Sprite a) => ((Object)a).name == "MoveZ"); Rotate = source.First((Sprite a) => ((Object)a).name == "Rotate"); Scale = source.First((Sprite a) => ((Object)a).name == "Scale"); obj.Unload(false); Transform val = ((Component)GameCameras.instance.hudCamera).transform.Find("In-game/Anchor TL/Hud Canvas Offset/Hud Canvas"); Transform val2 = val.Find("Delivery Icon/Parent/Delivery Icon Sprite"); Transform obj2 = Object.Instantiate<Transform>(val2, val); ((Component)obj2).transform.position = val2.position; ((Component)obj2).gameObject.SetActive(true); StateIndicator = ((Component)obj2).GetComponent<SpriteRenderer>(); StateIndicator.sprite = null; } } internal class InputBlockingMechanism { } public class Prop { public string name; public string path; public GameObject go; } internal static class PropValidation { private static readonly string[] extraNames = new string[2] { "corpse", "quest_board" }; private static readonly PhysLayers[] invalidLayers = (PhysLayers[])(object)new PhysLayers[2] { (PhysLayers)11, (PhysLayers)17 }; private static GameObject PropParent; private static readonly Type[] allowedTypes = new Type[13] { typeof(Transform), typeof(MeshFilter), typeof(Renderer), typeof(MeshRenderer), typeof(SpriteRenderer), typeof(tk2dSprite), typeof(tk2dSpriteAnimator), typeof(tk2dSpriteAnimation), typeof(tk2dSpriteAnimationClip), typeof(tk2dSpriteAnimationFrame), typeof(tk2dLookAnimNPC), typeof(CurveRotationAnimation), typeof(JitterSelf) }; public static NoRepeat<Prop> currentSceneObjects { get; private set; } private static bool HasScript(GameObject obj) { if (!Object.op_Implicit((Object)(object)obj.GetComponent<Breakable>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<PlayMakerNPC>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<BasicNPC>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<QuestBoardInteractable>())) { return Object.op_Implicit((Object)(object)obj.GetComponent<PushableRubble>()); } return true; } private static void LogSpecificObj(string objectName, string condition) { if (objectName == "Bonechurch_shop") { Log.LogInfo(condition); } } private static bool IsValidProp(string scene, GameObject gameObject) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if (!gameObject.activeInHierarchy) { LogSpecificObj(((Object)gameObject).name, "inactive"); return false; } if (Regex.IsMatch(((Object)gameObject).name, "^pebble$|^junk_push|^Small_bell_push|^weaver_corpse_shrine|^Weaver Corpse Glow", RegexOptions.IgnoreCase)) { return false; } if (((Object)gameObject).name.Contains("(Clone)")) { LogSpecificObj(((Object)gameObject).name, "clone"); return false; } if (invalidLayers.Contains((PhysLayers)gameObject.layer)) { string name2 = ((Object)gameObject).name; PhysLayers val = (PhysLayers)gameObject.layer; LogSpecificObj(name2, "layer " + ((object)(PhysLayers)(ref val)).ToString()); return false; } SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>(); if ((Object)(object)renderer == (Object)null && (Object)(object)gameObject.GetComponent<tk2dSprite>() == (Object)null) { LogSpecificObj(((Object)gameObject).name, "no renderer"); return false; } SpriteRenderer obj = renderer; object obj2; if (obj == null) { obj2 = null; } else { Sprite sprite = obj.sprite; obj2 = ((sprite != null) ? ((Object)sprite).name : null); } if (obj2 != null && ExtraProps.banned.Any((string p) => p == ((Object)renderer.sprite).name)) { LogSpecificObj(((Object)gameObject).name, "black fader"); return false; } SpriteRenderer obj3 = renderer; float num; if (obj3 == null) { num = 1f; } else { Color color = obj3.color; num = ((Color)(ref color)).grayscale; } if (num < 0.75f) { LogSpecificObj(((Object)gameObject).name, "too dark"); return false; } LogSpecificObj(((Object)gameObject).name, "passed negative"); if (HasScript(gameObject)) { return true; } string name = ((Object)gameObject).name.ToLower(); if (extraNames.Any((string n) => name.Contains(n))) { return true; } if (ExtraProps.IsExtraProp(scene, gameObject)) { return true; } return false; } private static bool IsGameObjectDuplicate(SpriteRenderer newObjRenderer, GameObject existingGameObject) { try { SpriteRenderer renderer = GetRenderer(existingGameObject); if ((Object)(object)((renderer != null) ? renderer.sprite : null) == (Object)null || (Object)(object)((newObjRenderer != null) ? newObjRenderer.sprite : null) == (Object)null) { return false; } return ((Object)renderer.sprite).name == ((Object)newObjRenderer.sprite).name; } catch (Exception ex) { Log.LogError(((Object)existingGameObject).name + " failed, no sprite on one of the objects?"); Log.LogError(ex); return true; } } private static SpriteRenderer GetRenderer(GameObject gameObject) { SpriteRenderer val = gameObject.GetComponent<SpriteRenderer>(); if ((Object)(object)((val != null) ? val.sprite : null) == (Object)null) { val = ((IEnumerable<SpriteRenderer>)gameObject.GetComponentsInChildren<SpriteRenderer>()).FirstOrDefault((Func<SpriteRenderer, bool>)((SpriteRenderer s) => (Object)(object)s.sprite != (Object)null)); } return val; } public static void GetAllProps() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; Log.LogDebug("Preparing all props for scene " + name); GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>(); List<GameObject> list = new List<GameObject>(); ExtraProps.Init(); GameObject[] array2 = array; foreach (GameObject val in array2) { if (IsValidProp(name, val)) { LogSpecificObj(((Object)val).name, "valid prop"); SpriteRenderer renderer = GetRenderer(val); if ((Object)(object)renderer == (Object)null) { LogSpecificObj(((Object)val).name, "no renderer"); } else if (list.Any((GameObject o) => IsGameObjectDuplicate(renderer, o))) { LogSpecificObj(((Object)val).name, "duplicate object"); } else { list.Add(val); } } } PrepareAllProps(list); AddPropsToOutput(name); } private static void AddPropsToOutput(string scene) { List<Prop> inputValues = currentSceneObjects.inputValues; string value = string.Format("{0},{1},\"{2}\"", scene, inputValues.Count, string.Join("\n", inputValues.Select((Prop x) => x.name))); StreamWriter streamWriter = File.AppendText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "PropReport.csv")); streamWriter.WriteLine(value); streamWriter.Close(); } private static void RemoveComponents<T>(GameObject gameObject, bool keepOnParent = false) where T : Component { T[] componentsInChildren = gameObject.GetComponentsInChildren<T>(); foreach (T val in componentsInChildren) { if (!keepOnParent || (Object)(object)((Component)val).gameObject != (Object)(object)gameObject.gameObject) { Object.Destroy((Object)(object)val); } } } private static void StripProp(GameObject gameObject) { MonoBehaviour[] componentsInChildren = gameObject.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { Type type = ((object)val).GetType(); if (!allowedTypes.Any((Type t) => type == t)) { Object.Destroy((Object)(object)val); } } RemoveComponents<Collider2D>(gameObject, keepOnParent: false); RemoveComponents<Rigidbody2D>(gameObject, keepOnParent: true); Transform[] componentsInChildren2 = gameObject.GetComponentsInChildren<Transform>(); foreach (Transform val2 in componentsInChildren2) { if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponentInChildren<Renderer>()) && !Object.op_Implicit((Object)(object)((Component)val2).GetComponentInChildren<ParticleSystem>())) { Object.Destroy((Object)(object)((Component)val2).gameObject); } } } private static string GeneratePropPath(GameObject prop) { string text = ((Object)prop).name; _ = prop.transform.parent; while ((Object)(object)prop.transform.parent != (Object)null) { prop = ((Component)prop.transform.parent).gameObject; text = ((Object)prop).name + "/" + text; } return text; } public static Prop PrepareProp(GameObject prop, bool assignParent = true) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prop == (Object)null) { Log.LogError("Unknown prop to prepare"); return null; } GameObject val; try { if (assignParent) { val = Object.Instantiate<GameObject>(prop, PropParent.transform); } else { val = Object.Instantiate<GameObject>(prop); val.SetActive(false); } val.layer = 20; ((Object)val).name = ((Object)prop).name; Breakable component = val.GetComponent<Breakable>(); if ((Object)(object)component != (Object)null && component.IsBroken) { SpriteRenderer component2 = val.GetComponent<SpriteRenderer>(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).enabled = true; } } } catch (Exception ex) { Log.LogError("Ran into an error instantiating cover " + ((Object)prop).name + "."); Log.LogError(ex); return null; } StripProp(val); Quaternion rotation = val.transform.rotation; val.transform.rotation = Quaternion.identity; if (!AddPropHitbox(val)) { Log.LogError("Couldn't add hitbox for " + ((Object)prop).name); Object.Destroy((Object)(object)val); return null; } val.transform.rotation = rotation; return new Prop { name = ((Object)val).name, go = val, path = GeneratePropPath(prop) }; } private static bool AddPropHitbox(GameObject prop) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) Renderer[] array = (from r in prop.GetComponentsInChildren<Renderer>(false) where !(r is LineRenderer) && !(r is ParticleSystemRenderer) select r).ToArray(); if (array.Length == 0) { Log.LogError("No renderers found"); return false; } Bounds bounds = array[0].bounds; Renderer[] array2 = array; foreach (Renderer val in array2) { string text = ((Object)val).name.ToLower(); if (!text.StartsWith("haze") && !text.StartsWith("light") && !text.StartsWith("vignette") && !text.EndsWith("fader") && !text.EndsWith("glow") && !text.EndsWith("cutout") && !(text == "lit")) { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } Vector3 val2 = prop.transform.InverseTransformVector(((Bounds)(ref bounds)).size); BoxCollider2D val3 = prop.AddComponent<BoxCollider2D>(); ((Collider2D)val3).isTrigger = true; ((Collider2D)val3).offset = Vector2.op_Implicit(prop.transform.InverseTransformPoint(((Bounds)(ref bounds)).center)); val3.size = new Vector2(Mathf.Abs(val2.x), Mathf.Abs(val2.y)); if ((val3.size.x > 20f && val3.size.y > 20f) || val3.size.x >= 30f || val3.size.y >= 30f) { Log.LogError($"Prop {((Object)prop).name} was too frickin big (${val3.size})"); return false; } Extensions.AddComponentIfNotPresent<Rigidbody2D>(prop).bodyType = (RigidbodyType2D)1; prop.AddComponent<LineRenderer>(); prop.AddComponent<DebugViewCollider>(); prop.AddComponent<TriggerHandler>(); array2 = array; foreach (Renderer val4 in array2) { if (!((Object)(object)((Component)val4).gameObject == (Object)(object)prop)) { Extensions.AddComponentIfNotPresent<LineRenderer>(((Component)val4).gameObject); ((Component)val4).gameObject.AddComponent<DebugViewBounds>(); } } return true; } private static void PrepareAllProps(List<GameObject> props) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if ((Object)(object)PropParent != (Object)null) { Object.Destroy((Object)(object)PropParent); } PropParent = new GameObject("PROP PARENT"); PropParent.SetActive(false); if (!SelfHornetManager.instance.HornetExists()) { return; } List<Prop> list = new List<Prop>(); foreach (GameObject prop2 in props) { Prop prop = PrepareProp(prop2); if (prop != null) { list.Add(prop); } } currentSceneObjects = new NoRepeat<Prop>(list); } public static void ResetProps() { Log.LogDebug("Resetting props"); currentSceneObjects = null; } public static GameObject FindGameObject(string path) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) string[] names = path.Split(new char[1] { '/' }); Scene activeScene = SceneManager.GetActiveScene(); GameObject val = ((IEnumerable<GameObject>)((Scene)(ref activeScene)).GetRootGameObjects()).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => ((Object)go).name == names[0])); if ((Object)(object)val == (Object)null) { return null; } for (int i = 1; i < names.Length; i++) { GameObject val2 = FindGameObjectLayer(names[i], val); if ((Object)(object)val2 == (Object)null) { return null; } val = val2; } return val; } private static GameObject FindGameObjectLayer(string name, GameObject parent) { int childCount = parent.transform.childCount; for (int i = 0; i < childCount; i++) { Transform child = parent.transform.GetChild(i); if (((Object)child).name == name) { return ((Component)child).gameObject; } } return null; } } internal class DebugViewCollider : MonoBehaviour { private Color borderColor = Color.white; private readonly float lineWidth = 0.05f; private LineRenderer lineRenderer; private BoxCollider2D collider; private bool Show => PropHuntMod.showHitboxes; private void Awake() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) collider = ((Component)this).GetComponent<BoxCollider2D>(); lineRenderer = ((Component)this).GetComponent<LineRenderer>(); lineRenderer.loop = true; lineRenderer.useWorldSpace = true; lineRenderer.startWidth = lineWidth; lineRenderer.endWidth = lineWidth; ((Renderer)lineRenderer).material = new Material(Shader.Find("Sprites/Default")); lineRenderer.startColor = borderColor; lineRenderer.endColor = borderColor; } private void LateUpdate() { if (Show) { DrawBox(collider); } else { lineRenderer.positionCount = 0; } } private void DrawBox(BoxCollider2D box) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_004d: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) Vector2 val = box.size * 0.5f; Vector2 offset = ((Collider2D)box).offset; SetPositions((Vector3[])(object)new Vector3[4] { Vector2.op_Implicit(offset + new Vector2(0f - val.x, 0f - val.y)), Vector2.op_Implicit(offset + new Vector2(val.x, 0f - val.y)), Vector2.op_Implicit(offset + new Vector2(val.x, val.y)), Vector2.op_Implicit(offset + new Vector2(0f - val.x, val.y)) }); } private void SetPositions(Vector3[] localPoints) { //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) lineRenderer.positionCount = localPoints.Length; for (int i = 0; i < localPoints.Length; i++) { lineRenderer.SetPosition(i, ((Component)this).transform.TransformPoint(localPoints[i])); } } } internal class DebugViewBounds : MonoBehaviour { private LineRenderer lineRenderer; private Renderer[] renderers; private Color borderColor = Color.red; private readonly float lineWidth = 0.05f; private bool Show => PropHuntMod.showHitboxes; private void Awake() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) lineRenderer = ((Component)this).GetComponent<LineRenderer>(); lineRenderer.loop = true; lineRenderer.useWorldSpace = true; lineRenderer.startWidth = lineWidth; lineRenderer.endWidth = lineWidth; ((Renderer)lineRenderer).material = new Material(Shader.Find("Sprites/Default")); lineRenderer.startColor = borderColor; lineRenderer.endColor = borderColor; renderers = ((Component)this).GetComponents<Renderer>(); } private void LateUpdate() { if (Show) { Renderer[] array = renderers; foreach (Renderer renderer in array) { DrawBox(renderer); } } } private void DrawBox(Renderer renderer) { //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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) Bounds localBounds = renderer.localBounds; Vector2 val = Vector2.op_Implicit(Extensions.DivideElements(((Bounds)(ref localBounds)).size, (float?)2.1f, (float?)2.1f, (float?)null)); localBounds = renderer.localBounds; Vector2 val2 = Vector2.op_Implicit(((Bounds)(ref localBounds)).center); SetPositions((Vector3[])(object)new Vector3[4] { Vector2.op_Implicit(val2 + new Vector2(0f - val.x, 0f - val.y)), Vector2.op_Implicit(val2 + new Vector2(val.x, 0f - val.y)), Vector2.op_Implicit(val2 + new Vector2(val.x, val.y)), Vector2.op_Implicit(val2 + new Vector2(0f - val.x, val.y)) }); } private void SetPositions(Vector3[] localPoints) { //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) lineRenderer.positionCount = localPoints.Length; for (int i = 0; i < localPoints.Length; i++) { lineRenderer.SetPosition(i, ((Component)this).transform.TransformPoint(localPoints[i])); } } } internal static class ExtraProps { private static string[] sceneProps; private static string[] scenePrefixes; private static string scenePrefix; public static string[] global = new string[0]; public static string[] banned = new string[0]; public static void Init() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string scene = ((Scene)(ref activeScene)).name; if (scenePrefixes != null) { string text = scenePrefixes.FirstOrDefault((string p) => scene.StartsWith(p)); if (string.IsNullOrEmpty(text)) { Log.LogDebug("EPI: Scene not in extra props list"); sceneProps = null; scenePrefix = null; return; } if (text == scenePrefix) { Log.LogDebug("EPI: Scene is same."); return; } } Log.LogDebug("Proceeding with extra prop loading"); Dictionary<string, string[]> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(File.ReadAllText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ExtraProps.json"))); scenePrefixes = dictionary.Keys.ToArray(); string text2 = dictionary.Keys.FirstOrDefault((string s) => scene.StartsWith(s)); global = dictionary["GLOBAL"]; if (string.IsNullOrEmpty(text2)) { Log.LogError("EPI: key not found"); sceneProps = null; scenePrefix = null; } else { sceneProps = dictionary[text2]; scenePrefix = text2; banned = dictionary["BANNED"]; } } public static bool IsExtraProp(string scene, GameObject gameObject) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(scene)) { return false; } if (sceneProps == null) { return false; } SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>(); SpriteRenderer obj = renderer; if ((Object)(object)((obj != null) ? obj.sprite : null) == (Object)null) { return false; } Color color = renderer.color; if (((Color)(ref color)).grayscale < 0.75f) { return false; } bool flag = global.Any((string p) => ((Object)renderer.sprite).name.StartsWith(p)) || sceneProps.Any((string p) => ((Object)renderer.sprite).name.StartsWith(p)); if (flag && banned.Any((string p) => ((Object)renderer.sprite).name == p)) { flag = false; } return flag; } } } namespace PropHuntMod.Players { internal class PlayerManager { public BaseHornetManager hornetManager; public BaseCoverManager coverManager; public string currentCoverObjName = ""; public string currentCoverObjPath = ""; public Vector3 currentCoverObjLocation = Consts.DEFAULT_LOCATION; public float currentCoverObjRotation; public float currentCoverObjScale = 1f; public bool currentHideState; public ushort playerID; public IClientPlayer PlayerAvatar => PropHuntMod.client.ClientManager.GetPlayer(playerID); public PlayerManager(ushort playerID) { hornetManager = new BaseHornetManager(); coverManager = new BaseCoverManager(); this.playerID = playerID; hornetManager.playerID = playerID; coverManager.playerID = playerID; IClientPlayer val = default(IClientPlayer); PropHuntMod.client.ClientManager.TryGetPlayer(playerID, ref val); if (val == null) { Log.LogError($"No remotePlayer for {playerID}. Are they remote?"); } else { PropHuntMod.playerManager.Add(playerID, this); } } public static PlayerManager GetPlayerManager(ushort playerID) { PropHuntMod.playerManager.TryGetValue(playerID, out var value); if (value == null) { return new PlayerManager(playerID); } return value; } public bool IsHostInSameRoom() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (PlayerAvatar == null) { return false; } bool isInLocalScene = PlayerAvatar.IsInLocalScene; if (isInLocalScene) { Log.LogDebug($"{playerID} is in the same room"); } else { object[] array = new object[1]; object arg = playerID; Scene activeScene = SceneManager.GetActiveScene(); array[0] = $"{arg} is in another room, you are in {((Scene)(ref activeScene)).name}"; Log.LogDebug(array); } return isInLocalScene; } public void EnsurePropCover() { if (string.IsNullOrEmpty(currentCoverObjName)) { coverManager.DisableProp(hornetManager); hornetManager.ToggleHornet(show: true); } else if (IsHostInSameRoom()) { GameObject val = PropValidation.FindGameObject(currentCoverObjPath); if ((Object)(object)val == (Object)null) { Log.LogError($"Couldn't find prop {currentCoverObjName} for player {playerID}"); return; } Prop prop = PropValidation.PrepareProp(val, assignParent: false); if (prop == null) { Log.LogError($"Couldn't prepare prop for player {playerID}"); } else { coverManager.EnableProp(hornetManager, prop); coverManager.SetPropLocation(currentCoverObjLocation, currentCoverObjRotation, currentCoverObjScale); Object.Destroy((Object)(object)prop.go); } } else { coverManager.DisableProp(hornetManager, logOnFail: false); } } public void SetProp(string name, string path) { if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(path)) { name = ""; path = ""; } currentCoverObjName = name; currentCoverObjPath = path; ResetCoverPosition(); EnsurePropCover(); } public void SetPropLocation(Vector3 location, float rotation, float scale) { currentCoverObjLocation = location; currentCoverObjRotation = rotation; currentCoverObjScale = scale; if (IsHostInSameRoom()) { coverManager.SetPropLocation(location, rotation, scale); } } public void SetHideStatus(bool hiding) { hornetManager.shouldBeShown = !hiding; if (IsHostInSameRoom()) { hornetManager.ToggleHornet(!hiding); } } public void ResetCoverPosition() { SetPropLocation(Consts.DEFAULT_LOCATION, 0f, 1f); } public static void EnsureAllPropCovers() { Debug.Log((object)$"Ensuring cover for {PropHuntMod.playerManager.Count} players"); foreach (PlayerManager value in PropHuntMod.playerManager.Values) { value.EnsurePropCover(); } } } internal class InputBlocker { } internal class SelfHornetManager : BaseHornetManager { private static InputBlocker blocker = new InputBlocker(); public static SelfHornetManager instance; private SpriteRenderer obscurance; public SelfHornetManager() { isRemote = false; instance = this; } public void ToggleHornet() { if (Config.AllowDebugFeatures || Se