Decompiled source of BonkCoop v0.2.3
BonkCoop.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using Actors.Enemies; using Assets.Scripts.Actors; using Assets.Scripts.Actors.Enemies; using Assets.Scripts.Actors.Player; using Assets.Scripts.Camera; using Assets.Scripts.Game.Other; using Assets.Scripts.Inventory__Items__Pickups; using Assets.Scripts.Inventory__Items__Pickups.Weapons; using Assets.Scripts.Managers; using Assets.Scripts.Utility; using Assets.Scripts._Data.MapsAndStages; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BonkCoop.Net; using BonkCoop.Patches; using BonkCoop.Run; using BonkCoop.Steam; using BonkCoop.Sync; using BonkCoop.UI; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppSystem.Reflection; using Microsoft.CodeAnalysis; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("BonkCoop")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.3.0")] [assembly: AssemblyInformationalVersion("0.2.3")] [assembly: AssemblyProduct("BonkCoop")] [assembly: AssemblyTitle("BonkCoop")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BonkCoop { public class CoopManager : MonoBehaviour { private const float SendInterval = 0.05f; private static readonly Vector3 SoloGhostOffset = new Vector3(2.5f, 0f, 0f); private static CoopManager _instance; private ITransport _transport; private readonly Dictionary<ulong, RemotePlayer> _remotes = new Dictionary<ulong, RemotePlayer>(); private float _nextSend; private uint _seq; private int _sent; private int _received; private string _lastError; private bool? _bgBefore; private GUIStyle _tagStyle; public static IEnumerable<RemotePlayer> Remotes { get { if (!((Object)(object)_instance != (Object)null)) { return Array.Empty<RemotePlayer>(); } return _instance._remotes.Values; } } public CoopManager(IntPtr ptr) : base(ptr) { } public static void ToggleSoloTest() { _instance?.SetSoloTest(!Plugin.SoloTestMode.Value); } private void Update() { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown _instance = this; try { MultiplayerMenu.Tick(); SteamLobby.Tick(); SeedWatch.Tick(); MultiplayerScreen.Tick(); UiKit.TickHover(); HandleKeys(); EnsureTransport(); if (_transport == null) { CoopNet.Transport = null; EnemySync.Reset(); MinimapMarkers.Clear(); return; } _transport.Tick(); MyPlayer localPlayer = GetLocalPlayer(); if ((Object)(object)localPlayer != (Object)null && Time.unscaledTime >= _nextSend) { _nextSend = Time.unscaledTime + 0.05f; SendLocalState(localPlayer); } ReceiveAll((Object)(object)localPlayer != (Object)null); if ((Object)(object)localPlayer == (Object)null) { ClearRemotes(); } else { PruneRemotes(); foreach (RemotePlayer value in _remotes.Values) { value.Update(); } } MinimapMarkers.Tick(localPlayer); DownedSync.Tick(localPlayer); StageSync.Tick(localPlayer); PartyHud.Tick(localPlayer); EnemySync.Tick(_transport, localPlayer); } catch (Exception ex) { if (_lastError != ex.Message) { _lastError = ex.Message; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("CoopManager error: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } log.LogError(val); } } } private void HandleKeys() { if (Input.GetKeyDown((KeyCode)289)) { SetSoloTest(!Plugin.SoloTestMode.Value); } if (Input.GetKeyDown((KeyCode)288)) { Plugin.ShowOverlay.Value = !Plugin.ShowOverlay.Value; } } private void SetSoloTest(bool on) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Plugin.SoloTestMode.Value = on; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Solo test mode: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(on ? "ON" : "OFF"); } log.LogInfo(val); ShutdownTransport(); } private void EnsureTransport() { bool flag = SteamLobby.InLobby && SteamLobby.Members.Count > 1; bool flag2 = !flag && Plugin.SoloTestMode.Value; if (_transport is SteamTransport && !flag) { ShutdownTransport(); } if (_transport is LoopbackTransport && !flag2) { ShutdownTransport(); } if (_transport == null) { if (flag) { _transport = new SteamTransport(); Plugin.Log.LogInfo((object)"Started Steam transport"); } else if (flag2) { _transport = new LoopbackTransport(); Plugin.Log.LogInfo((object)"Started solo test transport"); } } CoopNet.Transport = _transport; KeepRunningInBackground(flag); if (_transport is LoopbackTransport loopbackTransport) { loopbackTransport.LatencyMs = Math.Max(0, Plugin.FakeLatencyMs.Value); loopbackTransport.LossPercent = Math.Clamp(Plugin.FakePacketLossPercent.Value, 0, 90); } } private void KeepRunningInBackground(bool coop) { try { if (coop && !_bgBefore.HasValue) { _bgBefore = Application.runInBackground; Application.runInBackground = true; } else if (!coop && _bgBefore.HasValue) { Application.runInBackground = _bgBefore.Value; _bgBefore = null; } } catch (Exception ex) { LogOnce.Warn("runInBackground: " + ex.Message); } } private void ShutdownTransport() { _transport?.Dispose(); _transport = null; ClearRemotes(); } private static MyPlayer GetLocalPlayer() { MyPlayer instance = MyPlayer.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerRenderer == (Object)null) { return null; } return instance; } private void SendLocalState(MyPlayer player) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)player.playerRenderer).transform; int value = 0; int value2 = 0; try { PlayerHealth val = ((player.inventory != null) ? player.inventory.playerHealth : null); if (val != null) { value = val.hp; value2 = val.maxHp; } } catch { } PlayerStatePacket playerStatePacket = new PlayerStatePacket { Seq = ++_seq, Position = transform.position, Yaw = transform.eulerAngles.y, Hp = (short)Math.Clamp(value, 0, 32767), MaxHp = (short)Math.Clamp(value2, 0, 32767), Flags = (DownedSync.Downed ? ((byte)1) : ((byte)0)) }; _transport.Send(playerStatePacket.Write()); _sent++; } private void ReceiveAll(bool inRun) { int num = 400; ulong fromPeer; byte[] data; while (num-- > 0 && _transport.TryReceive(out fromPeer, out data)) { _received++; if (data != null && data.Length != 0) { try { HandlePacket(fromPeer, data, inRun); } catch (Exception e) { LogOnce.Error($"Message {((data.Length != 0) ? data[0] : 0)}", e); } } } } private void HandlePacket(ulong from, byte[] data, bool inRun) { //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_007b: 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_00cd: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data)); PacketType packetType = (PacketType)binaryReader.ReadByte(); if (!EnemySync.Handle(packetType, binaryReader, from) && !StageSync.Handle(packetType, binaryReader, from) && !InteractSync.Handle(packetType, binaryReader, from) && !DownedSync.Handle(packetType, binaryReader, from) && packetType == PacketType.PlayerState && inRun) { PlayerStatePacket playerStatePacket = PlayerStatePacket.Read(binaryReader); Vector3 val = playerStatePacket.Position; if (_transport is LoopbackTransport) { val += SoloGhostOffset; } RemotePlayer remote = GetRemote(from); if (string.IsNullOrEmpty(remote.Character) && !(_transport is LoopbackTransport)) { remote.Character = CharacterOf(from); remote.Skin = SkinOf(from); } remote.AddState(playerStatePacket.Seq, val, playerStatePacket.Yaw); remote.Hp = playerStatePacket.Hp; remote.MaxHp = playerStatePacket.MaxHp; remote.Downed = (playerStatePacket.Flags & 1) != 0; } } private void PruneRemotes() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown List<ulong> list = null; bool flag = _transport is SteamTransport; foreach (KeyValuePair<ulong, RemotePlayer> kv in _remotes) { bool num = !flag || SteamLobby.Members.Exists((SteamLobby.Member m) => m.Id == kv.Key); bool flag2 = Time.unscaledTime - kv.Value.LastHeard > 3f; if (!num || flag2) { (list ?? (list = new List<ulong>())).Add(kv.Key); } } if (list == null) { return; } bool flag3 = default(bool); foreach (ulong item in list) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Player "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_remotes[item].DisplayName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" left the run"); } log.LogInfo(val); _remotes[item].Destroy(); _remotes.Remove(item); } } private RemotePlayer GetRemote(ulong peer) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown if (!_remotes.TryGetValue(peer, out var value)) { string text = ((_transport is LoopbackTransport) ? "Ghost (you)" : SteamLobby.NameOf(peer)); value = new RemotePlayer(peer, text); value.Character = ((_transport is LoopbackTransport) ? SteamLobby.MyCharacter : CharacterOf(peer)); value.Skin = ((_transport is LoopbackTransport) ? SteamLobby.MySkin : SkinOf(peer)); _remotes[peer] = value; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("New remote player: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); } log.LogInfo(val); } return value; } private static string SkinOf(ulong peer) { foreach (SteamLobby.Member member in SteamLobby.Members) { if (member.Id == peer) { return member.SkinName; } } return ""; } private static string CharacterOf(ulong peer) { foreach (SteamLobby.Member member in SteamLobby.Members) { if (member.Id == peer) { return member.Character; } } return ""; } private void ClearRemotes() { foreach (RemotePlayer value in _remotes.Values) { value.Destroy(); } _remotes.Clear(); } private void OnGUI() { //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) DrawNameTags(); if (Plugin.ShowOverlay.Value) { string value = _transport?.Name ?? (SteamLobby.InLobby ? "Lobby (waiting for players)" : "Offline"); string value2 = ((_transport is LoopbackTransport) ? $" | fake lag {Plugin.FakeLatencyMs.Value}ms, loss {Plugin.FakePacketLossPercent.Value}%" : ""); string text = $"BonkCoop {"0.2.3"} | {value}{value2}\nplayers: {_remotes.Count} sent: {_sent} recv: {_received}\n" + "F8 solo test on/off F7 hide this"; if (_lastError != null) { text = text + "\nERROR: " + _lastError; } float num = ((_lastError != null) ? 82 : 64); float num2 = (float)Screen.height - num - 10f; GUI.Box(new Rect(10f, num2, 430f, num), ""); GUI.Label(new Rect(18f, num2 + 4f, 420f, 80f), text); } } private void DrawNameTags() { //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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) if (_remotes.Count == 0) { return; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } if (_tagStyle == null) { _tagStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 16 }; _tagStyle.normal.textColor = Color.white; } Rect val2 = default(Rect); foreach (RemotePlayer value in _remotes.Values) { Vector3 val = main.WorldToScreenPoint(value.CurrentPosition + Vector3.up * 2.4f); if (!(val.z <= 0f)) { string text = (value.Downed ? (value.DisplayName + " (DOWN)") : value.DisplayName); ((Rect)(ref val2))..ctor(val.x - 100f, (float)Screen.height - val.y - 12f, 200f, 24f); Rect val3 = new Rect(((Rect)(ref val2)).x + 1f, ((Rect)(ref val2)).y + 1f, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height); Color textColor = _tagStyle.normal.textColor; _tagStyle.normal.textColor = new Color(0f, 0f, 0f, 0.8f); GUI.Label(val3, text, _tagStyle); _tagStyle.normal.textColor = (Color)(value.Downed ? new Color(1f, 0.4f, 0.35f) : textColor); GUI.Label(val2, text, _tagStyle); _tagStyle.normal.textColor = textColor; } } } private void LateUpdate() { try { MultiplayerScreen.LateTick(); } catch (Exception e) { LogOnce.Error("Lobby screen", e); } EnemySync.LateTick(); foreach (RemotePlayer value in _remotes.Values) { try { value.LateUpdate(); } catch (Exception e2) { LogOnce.Error("Remote late", e2); } } try { DownedSync.LateTick(GetLocalPlayer()); } catch (Exception e3) { LogOnce.Error("Downed late", e3); } } private void OnDestroy() { ShutdownTransport(); } } public static class MultiplayerMenu { private static IntPtr _injectedInto; private static float _nextCheck; private static MainMenu _menu; public static bool SuppressAutoOpen; public static void Tick() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown if ((Object)(object)_menu != (Object)null && !SuppressAutoOpen && !MultiplayerScreen.IsOpen && SteamLobby.State != SteamLobby.LobbyState.None) { MultiplayerScreen.Open(_menu); } if (Time.unscaledTime < _nextCheck) { return; } _nextCheck = Time.unscaledTime + 0.5f; MainMenu val = Object.FindObjectOfType<MainMenu>(); if ((Object)(object)val == (Object)null || ((Il2CppObjectBase)val).Pointer == _injectedInto || (Object)(object)val.btnPlay == (Object)null || (Object)(object)val.btnUnlocks == (Object)null) { return; } _injectedInto = ((Il2CppObjectBase)val).Pointer; _menu = val; SuppressAutoOpen = false; try { UiKit.Capture(val); AddButton(val); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Couldn't add Multiplayer button: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex); } log.LogError(val2); } } private static void AddButton(MainMenu menu) { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Expected O, but got Unknown //IL_0234: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)menu.btnPlay).gameObject; GameObject gameObject2 = menu.btnUnlocks.gameObject; Transform parent = gameObject.transform.parent; GameObject val = Object.Instantiate<GameObject>(gameObject, parent); ((Object)val).name = "B_Multiplayer"; UiKit.StripGameScripts(val); RectTransform component = val.GetComponent<RectTransform>(); TMP_Text componentInChildren = gameObject2.GetComponentInChildren<TMP_Text>(true); float num = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.fontSize : 60f); float num2 = 0f; foreach (TMP_Text componentsInChild in val.GetComponentsInChildren<TMP_Text>(true)) { componentsInChild.text = "MULTIPLAYER"; componentsInChild.enableAutoSizing = false; componentsInChild.fontSize = num; componentsInChild.ForceMeshUpdate(false, false); num2 = Mathf.Max(num2, componentsInChild.preferredWidth); RectTransform rectTransform = componentsInChild.rectTransform; if (((Il2CppObjectBase)rectTransform).Pointer != ((Il2CppObjectBase)component).Pointer) { rectTransform.anchorMin = new Vector2(0f, rectTransform.anchorMin.y); rectTransform.anchorMax = new Vector2(1f, rectTransform.anchorMax.y); rectTransform.offsetMin = new Vector2(0f, rectTransform.offsetMin.y); rectTransform.offsetMax = new Vector2(0f, rectTransform.offsetMax.y); componentsInChild.alignment = (TextAlignmentOptions)514; } } if ((Object)(object)component != (Object)null) { float num3 = Mathf.Max(component.sizeDelta.x, num2 + 70f); component.sizeDelta = new Vector2(num3, component.sizeDelta.y); LayoutElement component2 = val.GetComponent<LayoutElement>(); if ((Object)(object)component2 != (Object)null) { component2.preferredWidth = num3; component2.minWidth = num3; } } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(47, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Multiplayer button: font "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", text width "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", button "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Vector2?>((component != null) ? new Vector2?(component.sizeDelta) : ((Vector2?)null)); } log.LogInfo(val2); Button val3 = val.GetComponentInChildren<Button>(true); if ((Object)(object)val3 == (Object)null) { val3 = val.AddComponent<Button>(); } val3.onClick = new ButtonClickedEvent(); ((UnityEvent)val3.onClick).AddListener(UnityAction.op_Implicit((Action)delegate { MultiplayerScreen.Open(_menu); })); val.transform.SetSiblingIndex(gameObject2.transform.GetSiblingIndex()); if ((Object)(object)component != (Object)null) { UiKit.TrackHover(component); } Plugin.Log.LogInfo((object)"Added MULTIPLAYER button to main menu"); } } [BepInPlugin("BonkCoop", "BonkCoop", "0.2.3")] public class Plugin : BasePlugin { internal static ManualLogSource Log; internal static ConfigEntry<bool> SoloTestMode; internal static ConfigEntry<int> FakeLatencyMs; internal static ConfigEntry<int> FakePacketLossPercent; internal static ConfigEntry<bool> ShowOverlay; internal static ConfigEntry<int> DebugSharedSeed; public override void Load() { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Expected O, but got Unknown //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Expected O, but got Unknown //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown Log = ((BasePlugin)this).Log; SoloTestMode = ((BasePlugin)this).Config.Bind<bool>("Testing", "SoloTestMode", false, "Echo your own movement back as a ghost player, to test syncing without a second player. Toggle in-game with F8."); FakeLatencyMs = ((BasePlugin)this).Config.Bind<int>("Testing", "FakeLatencyMs", 100, "Pretend network delay for solo test mode, in milliseconds."); FakePacketLossPercent = ((BasePlugin)this).Config.Bind<int>("Testing", "FakePacketLossPercent", 0, "Pretend percentage of lost packets for solo test mode (0-90)."); DebugSharedSeed = ((BasePlugin)this).Config.Bind<int>("Testing", "DebugSharedSeed", 0, "If not 0, the host always uses this shared seed (for checking that the same seed gives the same map)."); ShowOverlay = ((BasePlugin)this).Config.Bind<bool>("General", "ShowOverlay", false, "Show the BonkCoop status box in the corner. Toggle in-game with F7."); Harmony val = new Harmony("BonkCoop"); SharedCodeCheck.Build(); int num = 0; int num2 = 0; Type[] types = typeof(Plugin).Assembly.GetTypes(); bool flag = default(bool); foreach (Type type in types) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length == 0) { continue; } try { MethodBase methodBase = null; try { HarmonyMethod val2 = HarmonyMethod.Merge(HarmonyMethodExtensions.GetFromType(type)); if (val2.declaringType != null && val2.methodName != null) { methodBase = AccessTools.Method(val2.declaringType, val2.methodName, val2.argumentTypes, (Type[])null); } } catch { } if (methodBase != null && SharedCodeCheck.IsShared(methodBase)) { ManualLogSource log = Log; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(58, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Skipped hook "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(type.Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(methodBase.DeclaringType?.Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(methodBase.Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" shares its code with other game functions"); } log.LogWarning(val3); num2++; } else { val.CreateClassProcessor(type).Patch(); num++; } } catch (Exception ex) { ManualLogSource log2 = Log; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(15, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Patch "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(type.Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message); } log2.LogWarning(val3); } } ManualLogSource log3 = Log; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Hooks: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" added, "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(num2); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" skipped for safety"); } log3.LogInfo(val4); InteractSync.PatchAll(val); ((BasePlugin)this).AddComponent<CoopManager>(); ManualLogSource log4 = Log; val4 = new BepInExInfoLogInterpolatedStringHandler(17, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("BonkCoop "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>("0.2.3"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" loaded!"); } log4.LogInfo(val4); } } public class RemotePlayer { private struct Snapshot { public float Time; public Vector3 Pos; public float Yaw; } private const float InterpDelay = 0.1f; private bool _downed; private GameObject _marker; private readonly List<Renderer> _hiddenRenderers = new List<Renderer>(); private readonly List<Snapshot> _buffer = new List<Snapshot>(); private GameObject _body; private bool _isCapsule; private PlayerRenderer _renderer; private Vector3 _lastPos; private bool _moving; private float _movingSince; private float _stoppedSince; private float _nextModelRetry; public ulong PeerId { get; } public string DisplayName { get; set; } public uint LastSeq { get; private set; } public int Hp { get; set; } public int MaxHp { get; set; } public string Character { get; set; } = ""; public string Skin { get; set; } = ""; public bool Downed { get { return _downed; } set { if (_downed != value) { _downed = value; RefreshDownedLook(); } } } public float LastHeard { get; private set; } public Vector3 CurrentPosition { get { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_body != (Object)null)) { return Vector3.zero; } return _body.transform.position; } } public float CurrentYaw { get; private set; } public Transform Root { get { if (!((Object)(object)_body != (Object)null)) { return null; } return _body.transform; } } public Rigidbody Body { get; private set; } public RemotePlayer(ulong peerId, string name) { PeerId = peerId; DisplayName = name; } public void AddState(uint seq, Vector3 pos, float yaw) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (seq > LastSeq || LastSeq == 0) { LastSeq = seq; LastHeard = Time.unscaledTime; _buffer.Add(new Snapshot { Time = Time.unscaledTime, Pos = pos, Yaw = yaw }); if (_buffer.Count > 30) { _buffer.RemoveAt(0); } } } public void Update() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) if (_buffer.Count != 0) { EnsureBody(); float num = Time.unscaledTime - 0.1f; int num2 = _buffer.Count - 1; while (num2 > 0 && _buffer[num2 - 1].Time > num) { num2--; } Vector3 val; float num3; if (num2 == 0 || _buffer[num2].Time <= num) { Snapshot snapshot = _buffer[_buffer.Count - 1]; val = snapshot.Pos; num3 = snapshot.Yaw; } else { Snapshot snapshot2 = _buffer[num2 - 1]; Snapshot snapshot3 = _buffer[num2]; float num4 = Mathf.InverseLerp(snapshot2.Time, snapshot3.Time, num); val = Vector3.Lerp(snapshot2.Pos, snapshot3.Pos, num4); num3 = Mathf.LerpAngle(snapshot2.Yaw, snapshot3.Yaw, num4); } Transform transform = _body.transform; CurrentYaw = num3; if (_downed) { transform.position = val + Vector3.up * (_isCapsule ? 0.5f : 0.25f); transform.rotation = Quaternion.Euler(0f, num3, 0f) * Quaternion.Euler(-90f, 0f, 0f); return; } transform.position = (_isCapsule ? (val + Vector3.up) : val); transform.rotation = Quaternion.Euler(0f, num3, 0f); Animate(val, num3); RetryRealModel(); } } private void RetryRealModel() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown if (!_isCapsule || Time.unscaledTime < _nextModelRetry) { return; } _nextModelRetry = Time.unscaledTime + 2f; GameObject val = null; try { val = SpawnCharacterModel(); } catch (Exception ex) { LogOnce.Warn("Model retry for " + DisplayName + ": " + ex.Message); } if (!((Object)(object)val == (Object)null)) { GameObject body = _body; _body = val; _body.transform.SetPositionAndRotation(body.transform.position - Vector3.up, body.transform.rotation); Object.Destroy((Object)(object)body); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(38, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Replaced "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(DisplayName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s stand-in with their "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Character); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" model"); } log.LogInfo(val2); AttachBody(); } } private void Animate(Vector3 pos, float yaw) { //IL_003d: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_renderer == (Object)null) { return; } try { if (_renderer.isDamageFlash) { _renderer.ResetMaterial(); } } catch { } float num = Mathf.Max(Time.deltaTime, 0.0001f); Vector3 val = Vector3.ProjectOnPlane(pos - _lastPos, Vector3.up); float num2 = ((Vector3)(ref val)).magnitude / num; _lastPos = pos; bool flag = num2 > 0.6f; if (flag) { _stoppedSince = Time.time; } else { _movingSince = Time.time; } if (flag != _moving && (flag ? (Time.time - _movingSince) : (Time.time - _stoppedSince)) > 0.08f) { _moving = flag; try { _renderer.ForceMoving(_moving); } catch { } } try { _renderer.ForceRotation(Quaternion.Euler(0f, yaw, 0f) * Vector3.forward); } catch { } } private void EnsureBody() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if ((Object)(object)_body != (Object)null) { return; } try { _body = SpawnCharacterModel(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Couldn't build character model for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(DisplayName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } log.LogWarning(val); if ((Object)(object)_body != (Object)null) { Object.Destroy((Object)(object)_body); } _body = null; _renderer = null; } if ((Object)(object)_body == (Object)null) { MakeCapsule(); } AttachBody(); } private void AttachBody() { Body = _body.GetComponent<Rigidbody>(); if ((Object)(object)Body == (Object)null) { Body = _body.AddComponent<Rigidbody>(); } Body.isKinematic = true; Body.useGravity = false; RefreshDownedLook(); } private GameObject SpawnCharacterModel() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown CharacterData val = UiKit.FindCharacter(Character); MyPlayer instance = MyPlayer.Instance; bool flag = default(bool); if ((Object)(object)val == (Object)null) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(35, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("No model for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(DisplayName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": unknown character '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Character); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); } log.LogWarning(val2); return null; } if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerRenderer == (Object)null) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("No model for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(DisplayName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": your own model isn't ready yet"); } log2.LogWarning(val2); return null; } GameObject val3 = new GameObject("BonkCoop_ModelHolder"); val3.SetActive(false); GameObject val4 = Object.Instantiate<GameObject>(((Component)instance.playerRenderer).gameObject, val3.transform); ((Object)val4).name = $"BonkCoop_Remote_{PeerId}"; foreach (Component componentsInChild in val4.GetComponentsInChildren<Component>(true)) { if (!((Object)(object)componentsInChild == (Object)null)) { Type il2CppType = ((Object)componentsInChild).GetIl2CppType(); string text = il2CppType.Namespace ?? ""; string name = ((MemberInfo)il2CppType).Name; bool flag2 = text.StartsWith("UnityEngine") || text.StartsWith("TMPro"); if (!(name == "PlayerRenderer") && !(name == "Outline") && (!flag2 || !((Object)(object)((Il2CppObjectBase)componentsInChild).TryCast<Collider>() == (Object)null) || !((Object)(object)((Il2CppObjectBase)componentsInChild).TryCast<Rigidbody>() == (Object)null))) { Object.DestroyImmediate((Object)(object)componentsInChild); } } } val4.transform.SetParent((Transform)null, true); Object.Destroy((Object)(object)val3); val4.SetActive(true); _renderer = val4.GetComponent<PlayerRenderer>(); if ((Object)(object)_renderer != (Object)null) { _renderer.playerMovement = null; UiKit.DressModel(val4, _renderer, val, UiKit.FindSkin(Skin)); } else { ManualLogSource log3 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Model copy for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(DisplayName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" has no character renderer"); } log3.LogWarning(val2); } _isCapsule = false; ManualLogSource log4 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(17, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Built "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(Character); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" model for "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(DisplayName); } log4.LogInfo(val5); return val4; } private void MakeCapsule() { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown _isCapsule = true; _renderer = null; _body = GameObject.CreatePrimitive((PrimitiveType)1); ((Object)_body).name = $"BonkCoop_Remote_{PeerId}"; Object.DontDestroyOnLoad((Object)(object)_body); Collider component = _body.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = _body.GetComponent<Renderer>(); if ((Object)(object)component2 != (Object)null) { Shader val = Shader.Find("Unlit/Color"); if ((Object)(object)val != (Object)null) { component2.material = new Material(val); } component2.material.color = new Color(0.24f, 0.82f, 0.78f); } GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); Collider component3 = obj.GetComponent<Collider>(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } obj.transform.SetParent(_body.transform, false); obj.transform.localPosition = new Vector3(0f, 0.5f, 0.5f); obj.transform.localScale = new Vector3(0.3f, 0.3f, 0.4f); } private void RefreshDownedLook() { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown if ((Object)(object)_body == (Object)null) { return; } if ((Object)(object)_renderer != (Object)null) { try { ((Behaviour)_renderer).enabled = !_downed; if (_downed) { _renderer.ForceMoving(false); } } catch { } } if (_downed && (Object)(object)_marker == (Object)null) { _marker = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)_marker).name = "BonkCoop_DownedMarker"; Collider component = _marker.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } Renderer component2 = _marker.GetComponent<Renderer>(); Shader val = Shader.Find("Unlit/Color"); if ((Object)(object)val != (Object)null) { component2.material = new Material(val); } component2.material.color = new Color(1f, 0.25f, 0.2f); } if ((Object)(object)_marker != (Object)null) { _marker.SetActive(_downed); } } public void LateUpdate() { //IL_0048: 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_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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_marker == (Object)null) && _downed && !((Object)(object)_body == (Object)null)) { float num = Mathf.Sin(Time.unscaledTime * 3f) * 0.15f; _marker.transform.position = CurrentPosition + Vector3.up * (2.2f + num); _marker.transform.localScale = Vector3.one * 0.45f; } } public void Destroy() { if ((Object)(object)_body != (Object)null) { Object.Destroy((Object)(object)_body); } if ((Object)(object)_marker != (Object)null) { Object.Destroy((Object)(object)_marker); } _body = null; Body = null; _marker = null; _hiddenRenderers.Clear(); _buffer.Clear(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "BonkCoop"; public const string PLUGIN_NAME = "BonkCoop"; public const string PLUGIN_VERSION = "0.2.3"; } } namespace BonkCoop.UI { public static class LobbyLineup { private class Slot { public GameObject Model; public string Character = ""; public string Skin = ""; public TextMeshProUGUI Tag; } private const float Spacing = 1.9f; private static readonly Dictionary<ulong, Slot> _slots = new Dictionary<ulong, Slot>(); private static CharacterDisplay _display; private static GameObject _template; private static Vector3 _basePos; private static Quaternion _baseRot; private static bool _shown; public static void Tick(RectTransform tagParent, Canvas canvas) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) if (!FindTemplate()) { return; } if (!_shown) { _shown = true; _basePos = _template.transform.position; _baseRot = _template.transform.rotation; _template.SetActive(false); } if (_template.activeSelf) { _template.SetActive(false); } HashSet<ulong> hashSet = new HashSet<ulong>(); foreach (SteamLobby.Member member2 in SteamLobby.Members) { hashSet.Add(member2.Id); } List<ulong> list = new List<ulong>(); foreach (KeyValuePair<ulong, Slot> slot2 in _slots) { if (!hashSet.Contains(slot2.Key)) { list.Add(slot2.Key); } } foreach (ulong item in list) { DestroySlot(_slots[item]); _slots.Remove(item); } List<SteamLobby.Member> list2 = new List<SteamLobby.Member>(); foreach (SteamLobby.Member member3 in SteamLobby.Members) { if (member3.Character.Length > 0) { list2.Add(member3); } } Camera main = Camera.main; Vector3 val; if (!((Object)(object)main != (Object)null)) { val = Vector3.right; } else { Vector3 val2 = Vector3.ProjectOnPlane(((Component)main).transform.right, Vector3.up); val = ((Vector3)(ref val2)).normalized; } Vector3 val3 = val; for (int i = 0; i < list2.Count; i++) { SteamLobby.Member member = list2[i]; if (!_slots.TryGetValue(member.Id, out var value)) { value = (_slots[member.Id] = new Slot()); } if ((Object)(object)value.Model == (Object)null || value.Character != member.Character || value.Skin != member.SkinName) { if ((Object)(object)value.Model != (Object)null) { Object.Destroy((Object)(object)value.Model); } value.Model = SpawnModel(member.Character, member.SkinName); value.Character = member.Character; value.Skin = member.SkinName; } if ((Object)(object)value.Model == (Object)null) { continue; } float num = ((float)i - (float)(list2.Count - 1) / 2f) * 1.9f; Vector3 val4 = _basePos + val3 * num; value.Model.transform.position = val4; if ((Object)(object)main != (Object)null) { Vector3 val5 = Vector3.ProjectOnPlane(((Component)main).transform.position - val4, Vector3.up); if (((Vector3)(ref val5)).sqrMagnitude > 0.01f) { value.Model.transform.rotation = Quaternion.LookRotation(val5); } } else { value.Model.transform.rotation = _baseRot; } value.Model.SetActive(true); UpdateTag(value, member, tagParent, canvas, main); } foreach (SteamLobby.Member member4 in SteamLobby.Members) { if (member4.Character.Length == 0 && _slots.TryGetValue(member4.Id, out var value2)) { DestroySlot(value2); _slots.Remove(member4.Id); } } } public static void Hide() { foreach (Slot value in _slots.Values) { DestroySlot(value); } _slots.Clear(); if (_shown && (Object)(object)_template != (Object)null) { _template.SetActive(true); } _shown = false; } private static bool FindTemplate() { if ((Object)(object)_template != (Object)null) { return true; } _display = Object.FindObjectOfType<CharacterDisplay>(); if ((Object)(object)_display == (Object)null || (Object)(object)_display.playerRenderer == (Object)null) { return false; } _template = ((Component)_display.playerRenderer).gameObject; return true; } private static GameObject SpawnModel(string character, string skinName) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown CharacterData val = UiKit.FindCharacter(character); if ((Object)(object)val == (Object)null) { LogOnce.Warn("Unknown character '" + character + "'"); return null; } bool activeSelf = _template.activeSelf; _template.SetActive(true); GameObject val2 = Object.Instantiate<GameObject>(_template, _template.transform.parent); _template.SetActive(activeSelf); ((Object)val2).name = "BonkCoop_Lobby_" + character; foreach (MonoBehaviour componentsInChild in val2.GetComponentsInChildren<MonoBehaviour>(true)) { switch (((MemberInfo)((Object)componentsInChild).GetIl2CppType()).Name) { case "CharacterDisplay": case "CharacterSpin": case "SpinAroundCharacter": Object.DestroyImmediate((Object)(object)componentsInChild); break; } } PlayerRenderer component = val2.GetComponent<PlayerRenderer>(); if ((Object)(object)component != (Object)null) { try { UiKit.DressModel(val2, component, val, UiKit.FindSkin(skinName)); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Couldn't dress lobby model: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message); } log.LogWarning(val3); } } return val2; } private static void UpdateTag(Slot slot, SteamLobby.Member m, RectTransform parent, Canvas canvas, Camera cam) { //IL_00b0: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)slot.Tag == (Object)null) { slot.Tag = UiKit.MakeLabel((Transform)(object)parent, "", 0f, 0f, 320f, 70f, 28f, (TextAlignmentOptions)1026); RectTransform rectTransform = ((TMP_Text)slot.Tag).rectTransform; Vector2 anchorMin = (rectTransform.anchorMax = Vector2.zero); rectTransform.anchorMin = anchorMin; rectTransform.pivot = new Vector2(0.5f, 0f); } Color color; string value = MultiplayerScreen.StatusText(m, out color); ((TMP_Text)slot.Tag).text = $"{m.Name}\n<size=70%><color=#{Hex(color)}>{value}</color></size>"; if (!((Object)(object)cam == (Object)null)) { Vector3 val = cam.WorldToScreenPoint(HeadTop(slot.Model) + Vector3.up * 0.25f); ((Component)slot.Tag).gameObject.SetActive(val.z > 0f); float num = (((Object)(object)canvas != (Object)null) ? canvas.scaleFactor : 1f); ((TMP_Text)slot.Tag).rectTransform.anchoredPosition = new Vector2(val.x / num, val.y / num); } } private static Vector3 HeadTop(GameObject model) { //IL_0004: 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_002b: 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_007b: 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_0093: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) bool flag = false; Bounds val = default(Bounds); foreach (Renderer componentsInChild in model.GetComponentsInChildren<Renderer>()) { if (componentsInChild.enabled) { if (!flag) { val = componentsInChild.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(componentsInChild.bounds); } } } if (!flag) { return model.transform.position + Vector3.up * 2.3f; } return new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).max.y, ((Bounds)(ref val)).center.z); } private static string Hex(Color c) { //IL_000b: 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_0047: Unknown result type (might be due to invalid IL or missing references) return $"{(int)(Mathf.Clamp01(c.r) * 255f):X2}{(int)(Mathf.Clamp01(c.g) * 255f):X2}{(int)(Mathf.Clamp01(c.b) * 255f):X2}"; } private static void DestroySlot(Slot s) { if ((Object)(object)s.Model != (Object)null) { Object.Destroy((Object)(object)s.Model); } if ((Object)(object)s.Tag != (Object)null) { Object.Destroy((Object)(object)((Component)s.Tag).gameObject); } } } public static class MinimapMarkers { private class Marker { public GameObject Root; public Material Fill; public Transform ArrowTarget; } private static readonly Color[] Palette = (Color[])(object)new Color[3] { new Color(0.35f, 1f, 0.45f), new Color(1f, 0.85f, 0.2f), new Color(0.8f, 0.5f, 1f) }; private static readonly Color DownColor = new Color(1f, 0.2f, 0.15f); private static readonly Dictionary<ulong, Marker> _markers = new Dictionary<ulong, Marker>(); private static MinimapCamera _cam; private static float _nextCamLookup; private static Mesh _arrowMesh; private static Shader _shader; public static Color ColorFor(ulong id) { //IL_0061: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (SteamLobby.Member member in SteamLobby.Members) { if (!member.IsMe) { if (member.Id == id) { return Palette[num % Palette.Length]; } num++; } } return Palette[0]; } public static void Tick(MyPlayer player) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { Clear(); return; } try { if ((Object)(object)_cam == (Object)null) { if (Time.unscaledTime < _nextCamLookup) { return; } _nextCamLookup = Time.unscaledTime + 1f; _cam = Object.FindObjectOfType<MinimapCamera>(); if ((Object)(object)_cam == (Object)null) { return; } } Transform playerIcon = _cam.playerIcon; if ((Object)(object)playerIcon == (Object)null) { return; } Renderer componentInChildren = ((Component)playerIcon).GetComponentInChildren<Renderer>(true); int layer = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject.layer : ((Component)playerIcon).gameObject.layer); float num = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform.position.y : playerIcon.position.y) - ((Component)player).transform.position.y; float num2 = 6f; if ((Object)(object)componentInChildren != (Object)null) { Bounds bounds = componentInChildren.bounds; Vector3 size = ((Bounds)(ref bounds)).size; num2 = Mathf.Clamp(Mathf.Max(size.x, size.z), 1f, 60f); } HashSet<ulong> hashSet = new HashSet<ulong>(); foreach (RemotePlayer remote in CoopManager.Remotes) { if (!((Object)(object)remote.Root == (Object)null)) { hashSet.Add(remote.PeerId); if (!_markers.TryGetValue(remote.PeerId, out var value) || (Object)(object)value.Root == (Object)null) { value = Make(layer); _markers[remote.PeerId] = value; } Transform transform = value.Root.transform; Vector3 currentPosition = remote.CurrentPosition; transform.position = new Vector3(currentPosition.x, currentPosition.y + num + 0.05f, currentPosition.z); transform.rotation = Quaternion.Euler(0f, remote.CurrentYaw, 0f); float num3 = num2 / 1.8f; if (remote.Downed) { num3 *= 1f + 0.25f * Mathf.Sin(Time.unscaledTime * 6f); } transform.localScale = Vector3.one * num3; value.Fill.color = (remote.Downed ? DownColor : ColorFor(remote.PeerId)); UpdateEdgeArrow(value, remote.Downed ? remote.Root : null); } } List<ulong> list = null; foreach (ulong key in _markers.Keys) { if (!hashSet.Contains(key)) { (list ?? (list = new List<ulong>())).Add(key); } } if (list == null) { return; } foreach (ulong item in list) { Remove(item); } } catch (Exception e) { LogOnce.Error("Minimap markers", e); } } private static void UpdateEdgeArrow(Marker mk, Transform target) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) IntPtr intPtr = (((Object)(object)mk.ArrowTarget != (Object)null) ? ((Il2CppObjectBase)mk.ArrowTarget).Pointer : IntPtr.Zero); IntPtr intPtr2 = (((Object)(object)target != (Object)null) ? ((Il2CppObjectBase)target).Pointer : IntPtr.Zero); if (intPtr == intPtr2) { return; } try { if ((Object)(object)mk.ArrowTarget != (Object)null && (Object)(object)_cam != (Object)null) { _cam.RemoveArrow(mk.ArrowTarget); } mk.ArrowTarget = null; if ((Object)(object)target != (Object)null && (Object)(object)_cam != (Object)null) { _cam.AddArrow(target, DownColor); mk.ArrowTarget = target; } } catch (Exception ex) { LogOnce.Warn("Minimap edge arrow: " + ex.Message); mk.ArrowTarget = target; } } private static Marker Make(int layer) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00a3: Unknown result type (might be due to invalid IL or missing references) if (_shader == null) { _shader = Shader.Find("Unlit/Color"); } if (_arrowMesh == null) { _arrowMesh = BuildArrowMesh(); } GameObject val = new GameObject("BonkCoop_MinimapTeammate"); val.layer = layer; GameObject obj = MakePart(val.transform, layer, new Color(0f, 0f, 0f, 1f)); obj.transform.localScale = Vector3.one * 1.3f; obj.transform.localPosition = new Vector3(0f, -0.02f, -0.05f); GameObject val2 = MakePart(val.transform, layer, Palette[0]); return new Marker { Root = val, Fill = ((Renderer)val2.GetComponent<MeshRenderer>()).material }; } private static GameObject MakePart(Transform parent, int layer, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown GameObject val = new GameObject("Arrow") { layer = layer }; val.transform.SetParent(parent, false); val.AddComponent<MeshFilter>().sharedMesh = _arrowMesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); Material val3 = (((Object)(object)_shader != (Object)null) ? new Material(_shader) : new Material(((Renderer)val2).sharedMaterial)); val3.color = color; ((Renderer)val2).material = val3; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; return val; } private static Mesh BuildArrowMesh() { //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) //IL_0011: Expected O, but got Unknown //IL_0029: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_007f: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "BonkCoop_Arrow" }; val.vertices = Il2CppStructArray<Vector3>.op_Implicit((Vector3[])(object)new Vector3[4] { new Vector3(0f, 0f, 1f), new Vector3(0.7f, 0f, -0.8f), new Vector3(0f, 0f, -0.35f), new Vector3(-0.7f, 0f, -0.8f) }); val.triangles = Il2CppStructArray<int>.op_Implicit(new int[12] { 0, 1, 2, 0, 2, 3, 0, 2, 1, 0, 3, 2 }); val.RecalculateNormals(); val.RecalculateBounds(); return val; } private static void Remove(ulong id) { if (!_markers.TryGetValue(id, out var value)) { return; } try { if ((Object)(object)value.ArrowTarget != (Object)null && (Object)(object)_cam != (Object)null) { _cam.RemoveArrow(value.ArrowTarget); } } catch { } if ((Object)(object)value.Root != (Object)null) { Object.Destroy((Object)(object)value.Root); } _markers.Remove(id); } public static void Clear() { if (_markers.Count == 0) { return; } foreach (ulong item in new List<ulong>(_markers.Keys)) { Remove(item); } _cam = null; } } public static class MultiplayerScreen { private static GameObject _root; private static RectTransform _content; private static MainMenu _menu; private static string _shownKey; private static List<SteamLobby.FriendLobby> _friendLobbies = new List<SteamLobby.FriendLobby>(); private static float _nextFriendScan; private static bool _open; private static float _pickStarted; private static readonly Color Red = new Color(1f, 0.35f, 0.3f, 1f); private static readonly Color Green = new Color(0.45f, 0.95f, 0.45f, 1f); private static readonly Color Gold = new Color(1f, 0.85f, 0.3f, 1f); private static readonly Color Grey = new Color(0.7f, 0.7f, 0.7f, 1f); private static readonly List<GameObject> _hiddenArrows = new List<GameObject>(); private const float LeftX = 40f; private const float LeftTop = -340f; private const float BtnW = 300f; private const float BtnH = 72f; private const float BtnGap = 86f; private const float PanelX = 1400f; private const float PanelY = -250f; private const float PanelW = 480f; private const float PanelH = 580f; public static bool IsOpen { get { if (_open) { return (Object)(object)_root != (Object)null; } return false; } } public static bool PickingCharacter { get; private set; } public static bool PickingMap { get; private set; } public static void Open(MainMenu menu) { _menu = menu; EnsureRoot(); _open = true; PickingCharacter = false; PickingMap = false; SetMenuHidden(hidden: true); HideSelectionArrows(hide: true); _root.SetActive(true); EnsureEventSystem(); CameraToCharacters(close: true); _shownKey = null; _nextFriendScan = 0f; } public static void Close() { _open = false; PickingCharacter = false; PickingMap = false; LobbyLineup.Hide(); CameraToCharacters(close: false); if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } SetMenuHidden(hidden: false); HideSelectionArrows(hide: false); } private static void StartCharacterPick() { if (!((Object)(object)_menu == (Object)null)) { PickingCharacter = true; _pickStarted = Time.unscaledTime; SteamLobby.SetPicking(picking: true); LobbyLineup.Hide(); _root.SetActive(false); HideSelectionArrows(hide: false); _menu.GoToCharacterSelection(); } } private static void StartMapPick() { if (!((Object)(object)_menu == (Object)null)) { PickingMap = true; _pickStarted = Time.unscaledTime; LobbyLineup.Hide(); _root.SetActive(false); HideSelectionArrows(hide: false); _menu.GoToMapSelection(); } } public static void CloseForRun() { MultiplayerMenu.SuppressAutoOpen = true; PickingMap = false; PickingCharacter = false; _open = false; LobbyLineup.Hide(); if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } SetMenuHidden(hidden: false); HideSelectionArrows(hide: false); } public static void OnCharacterPicked(string character, string skin) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Picked "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(character); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (skin "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(skin); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") for the lobby"); } log.LogInfo(val); SteamLobby.SetCharacter(character, skin); ReturnFromPick(); } private static void ReturnFromPick() { if (PickingCharacter) { SteamLobby.SetPicking(picking: false); } PickingCharacter = false; PickingMap = false; if ((Object)(object)_menu != (Object)null) { _menu.GoToMenu(); } SetMenuHidden(hidden: true); HideSelectionArrows(hide: true); _root.SetActive(true); CameraToCharacters(close: true); _shownKey = null; } private static void CameraToCharacters(bool close) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown try { MenuCamera val = (((Object)(object)_menu != (Object)null) ? _menu.menuCamera : null); if (!((Object)(object)val == (Object)null)) { if (close) { val.GoToCharacters(); } else { val.GoToMain(); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Camera move failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogWarning(val2); } } public static string StatusText(SteamLobby.Member m, out Color color) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) //IL_0038: 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_0027: Unknown result type (might be due to invalid IL or missing references) if (m.Picking) { color = Grey; return "Choosing character"; } if (m.Ready) { color = Green; return "Ready"; } color = Grey; return "In menu"; } private static void CheckPickCancelled() { if (!(Time.unscaledTime - _pickStarted < 0.75f) && !((Object)(object)_menu == (Object)null)) { GameObject currentTab = _menu.currentTab; GameObject val = (PickingMap ? _menu.tabMaps : _menu.tabCharacters); if (!((Object)(object)currentTab != (Object)null) || !((Object)(object)val != (Object)null) || !(((Il2CppObjectBase)currentTab).Pointer == ((Il2CppObjectBase)val).Pointer)) { ReturnFromPick(); } } } private static void HideSelectionArrows(bool hide) { if (hide) { foreach (SelectionArrow item in Object.FindObjectsOfType<SelectionArrow>()) { if (!((Object)(object)item == (Object)null) && ((Component)item).gameObject.activeSelf) { ((Component)item).gameObject.SetActive(false); _hiddenArrows.Add(((Component)item).gameObject); } } return; } foreach (GameObject hiddenArrow in _hiddenArrows) { if ((Object)(object)hiddenArrow != (Object)null) { hiddenArrow.SetActive(true); } } _hiddenArrows.Clear(); } private static void SetMenuHidden(bool hidden) { if (!((Object)(object)_menu == (Object)null) && !((Object)(object)_menu.tabMenu == (Object)null)) { GameObject tabMenu = _menu.tabMenu; CanvasGroup val = tabMenu.GetComponent<CanvasGroup>(); if ((Object)(object)val == (Object)null) { val = tabMenu.AddComponent<CanvasGroup>(); } val.alpha = (hidden ? 0f : 1f); val.interactable = !hidden; val.blocksRaycasts = !hidden; } } private static void EnsureEventSystem() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)EventSystem.current != (Object)null)) { GameObject val = new GameObject("BonkCoop_EventSystem"); val.AddComponent<EventSystem>(); val.AddComponent<StandaloneInputModule>(); Plugin.Log.LogInfo((object)"No EventSystem found, created one"); } } public static void LateTick() { if (IsOpen && !PickingCharacter && !PickingMap) { Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; } } private static void EnsureRoot() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0051: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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) if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("BonkCoop_MultiplayerScreen"); Canvas obj = _root.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 50; CanvasScaler obj2 = _root.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; _root.AddComponent<GraphicRaycaster>(); RectTransform component = _root.GetComponent<RectTransform>(); _content = UiKit.MakeRect("Content", (Transform)(object)component, 0f, 0f, 1920f, 1080f); _content.anchorMin = Vector2.zero; _content.anchorMax = Vector2.one; RectTransform content = _content; Vector2 offsetMin = (_content.offsetMax = Vector2.zero); content.offsetMin = offsetMin; } } public static void Tick() { if (!IsOpen) { return; } if (PickingCharacter || PickingMap) { CheckPickCancelled(); return; } if (Input.GetKeyDown((KeyCode)27) && SteamLobby.State == SteamLobby.LobbyState.None) { Close(); return; } if (SteamLobby.State == SteamLobby.LobbyState.None && Time.unscaledTime >= _nextFriendScan) { _nextFriendScan = Time.unscaledTime + 2f; try { _friendLobbies = SteamLobby.FindFriendLobbies(); } catch (Exception ex) { LogOnce.Warn("Friend scan failed: " + ex.Message); } } string text = StateKey(); if (text != _shownKey) { _shownKey = text; Rebuild(); SelectFirstButton(); } if (SteamLobby.InLobby) { LobbyLineup.Tick(_root.GetComponent<RectTransform>(), _root.GetComponent<Canvas>()); } else { LobbyLineup.Hide(); } } private static void SelectFirstButton() { EventSystem current = EventSystem.current; if (!((Object)(object)current == (Object)null)) { current.SetSelectedGameObject((GameObject)null); } } private static string StateKey() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(SteamLobby.State).Append('|').Append(SteamLobby.Error) .Append('|') .Append(SteamLobby.IsHost); foreach (SteamLobby.Member member in SteamLobby.Members) { stringBuilder.Append('|').Append(member.Id).Append(member.Name) .Append(member.Ready) .Append(member.Character) .Append(member.Picking); } if (SteamLobby.State == SteamLobby.LobbyState.None) { foreach (SteamLobby.FriendLobby friendLobby in _friendLobbies) { stringBuilder.Append('#').Append(friendLobby.LobbyId).Append(friendLobby.FriendName); } } return stringBuilder.ToString(); } private static void Rebuild() { for (int num = ((Transform)_content).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_content).GetChild(num)).gameObject); } switch (SteamLobby.State) { case SteamLobby.LobbyState.None: BuildChoose(); break; case SteamLobby.LobbyState.Creating: case SteamLobby.LobbyState.Joining: BuildChoose(); break; case SteamLobby.LobbyState.InLobby: BuildLobby(); break; } } private static void LeftTitle(string text) { UiKit.MakeLabel((Transform)(object)_content, text, 40f, -240f, 520f, 70f, 54f, (TextAlignmentOptions)513); } private static Button LeftButton(int index, string text, Action onClick, bool enabled = true) { return UiKit.MakeButton((Transform)(object)_content, text, 40f, -340f - (float)index * 86f, 300f, 72f, onClick, 34f, enabled); } private static RectTransform RightPanel(string title) { RectTransform rectTransform = ((Graphic)UiKit.MakePanel((Transform)(object)_content, 1400f, -250f, 480f, 580f)).rectTransform; UiKit.MakeLabel((Transform)(object)rectTransform, title, 20f, -14f, 440f, 60f, 40f, (TextAlignmentOptions)514); return rectTransform; } private static void ErrorLine(RectTransform panel, float y) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(SteamLobby.Error)) { UiKit.MakeLabel((Transform)(object)panel, SteamLobby.Error, 20f, y, 440f, 70f, 22f, (TextAlignmentOptions)514, Red); } } private static void BuildChoose() { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) bool flag = SteamLobby.State == SteamLobby.LobbyState.Creating; bool flag2 = SteamLobby.State == SteamLobby.LobbyState.Joining; bool flag3 = flag || flag2; LeftTitle("Multiplayer"); LeftButton(0, flag ? "Creating lobby..." : "Host game", SteamLobby.Host, !flag3); LeftButton(1, flag3 ? "Cancel" : "Back", flag3 ? new Action(SteamLobby.Leave) : new Action(Close)); RectTransform val = RightPanel(flag2 ? "Joining lobby..." : "Join a friend"); float num = -90f; if (_friendLobbies.Count == 0) { UiKit.MakeLabel((Transform)(object)val, "No friends hosting right now.\nAsk a friend to host, then invite you through Steam.", 24f, num, 432f, 110f, 24f, (TextAlignmentOptions)514, Grey); } else { foreach (SteamLobby.FriendLobby friendLobby in _friendLobbies) { if (num < -420f) { break; } ulong lobby = friendLobby.LobbyId; UiKit.MakeLabel((Transform)(object)val, friendLobby.FriendName, 28f, num - 6f, 270f, 50f, 30f, (TextAlignmentOptions)513); UiKit.MakeButton((Transform)(object)val, "Join", 310f, num, 140f, 56f, delegate { SteamLobby.Join(lobby); }, 28f); num -= 70f; } } UiKit.MakeButton((Transform)(object)val, "Join lobby code from clipboard", 24f, -490f, 432f, 58f, JoinFromClipboard, 24f); ErrorLine(val, -410f); } private static void BuildWaiting(string text) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) LeftTitle("Multiplayer"); LeftButton(0, "Cancel", SteamLobby.Leave); UiKit.MakeLabel((Transform)(object)RightPanel("Please wait"), text, 20f, -120f, 440f, 60f, 32f, (TextAlignmentOptions)514, Grey); } private static void BuildLobby() { //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) LeftTitle(SteamLobby.IsHost ? "Hosting" : "In lobby"); bool myReady = SteamLobby.MyReady; bool flag = SteamLobby.MyCharacter.Length > 0; LeftButton(0, flag ? "Change character" : "Select character", StartCharacterPick, !myReady); LeftButton(1, myReady ? "Not ready" : (flag ? "Ready" : "Ready (pick a character)"), delegate { SteamLobby.SetReady(!SteamLobby.MyReady); }, flag); if (SteamLobby.IsHost) { bool flag2 = true; foreach (SteamLobby.Member member in SteamLobby.Members) { if (!member.IsMe && !member.Ready) { flag2 = false; } } bool enabled = flag && flag2; string text = ((!flag) ? "Start (pick a character)" : ((!flag2) ? "Start (waiting for players)" : "Start")); LeftButton(2, text, StartMapPick, enabled); } else { UiKit.MakeLabel((Transform)(object)_content, myReady ? "Waiting for the host to start..." : "Click Ready when you're set", 40f, -608f, 520f, 40f, 26f, (TextAlignmentOptions)513, Grey); } LeftButton(SteamLobby.IsHost ? 3 : 2, "Leave lobby", SteamLobby.Leave); string text2 = ""; foreach (SteamLobby.Member member2 in SteamLobby.Members) { if (member2.IsOwner) { text2 = member2.Name; } } RectTransform val = RightPanel(text2 + "'s Lobby"); float num = -86f; foreach (SteamLobby.Member member3 in SteamLobby.Members) { UiKit.MakeLabel((Transform)(object)val, member3.Name + (member3.IsMe ? " (you)" : ""), 28f, num, 300f, 38f, 30f, (TextAlignmentOptions)513); if (member3.IsOwner) { UiKit.MakeLabel((Transform)(object)val, "HOST", 350f, num, 100f, 38f, 24f, (TextAlignmentOptions)516, Gold); } UiKit.MakeLabel((Transform)(object)val, (member3.Character.Length > 0) ? member3.Character : "No character yet", 28f, num - 34f, 220f, 28f, 22f, (TextAlignmentOptions)513, Grey); Color color; string text3 = StatusText(member3, out color); UiKit.MakeLabel((Transform)(object)val, text3, 230f, num - 34f, 220f, 28f, 22f, (TextAlignmentOptions)516, color); num -= 76f; } for (int num2 = SteamLobby.Members.Count; num2 < 4; num2++) { UiKit.MakeLabel((Transform)(object)val, "Empty slot", 28f, num, 260f, 40f, 26f, (TextAlignmentOptions)513, (Color?)new Color(1f, 1f, 1f, 0.3f)); num -= 76f; } UiKit.MakeButton((Transform)(object)val, "Invite friends", 24f, -420f, 432f, 58f, SteamLobby.OpenInviteDialog, 26f); UiKit.MakeButton((Transform)(object)val, "Copy lobby code", 24f, -490f, 432f, 58f, CopyLobbyCode, 24f); ErrorLine(val, -340f); } private static void CopyLobbyCode() { GUIUtility.systemCopyBuffer = SteamLobby.LobbyId.ToString(); SteamLobby.Error = ""; Plugin.Log.LogInfo((object)"Lobby code copied"); } private static void JoinFromClipboard() { if (ulong.TryParse((GUIUtility.systemCopyBuffer ?? "").Trim(), out var result)) { SteamLobby.Join(result); return; } SteamLobby.Error = "Clipboard doesn't contain a lobby code."; _shownKey = null; } } public static class PartyHud { private class Frame { public GameObject Root; public RawImage Icon; public TextMeshProUGUI Name; public RectTransform HpFill; public TextMeshProUGUI HpText; public string Character; } private struct Entry { public string Name; public string Character; public int Hp; public int MaxHp; public bool IsMe; public bool Downed; public bool Connecting; public ulong Id; } private static GameObject _canvas; private static RectTransform _framesRoot; private static RectTransform _pauseRoot; private static readonly List<Frame> _frames = new List<Frame>(); private static readonly List<Frame> _pauseRows = new List<Frame>(); private static PauseUi _pauseUi; private static float _nextPauseLookup; private static float _nextRefresh; private const float FrameW = 300f; private const float FrameH = 64f; private const float IconSize = 56f; private const float BarW = 220f; private const float BarH = 16f; private static readonly Color HpRed = new Color(0.86f, 0.05f, 0.05f, 1f); private static readonly Color HpBack = new Color(0f, 0f, 0f, 0.55f); public static string CenterText; public static string CountdownText; private static TextMeshProUGUI _center; private static TextMeshProUGUI _notice; private static TextMeshProUGUI _countdown; private static float _noticeUntil; private static List<Entry> _others = new List<Entry>(); public static void Notice(string text) { EnsureCanvas(); ((TMP_Text)_notice).text = text; _noticeUntil = Time.unscaledTime + 3.5f; } private static List<Entry> Teammates() { List<Entry> list = new List<Entry>(); Dictionary<ulong, RemotePlayer> dictionary = new Dictionary<ulong, RemotePlayer>(); foreach (RemotePlayer remote in CoopManager.Remotes) { dictionary[remote.PeerId] = remote; } if (SteamLobby.InLobby) { foreach (SteamLobby.Member member in SteamLobby.Members) { if (!member.IsMe) { if (dictionary.TryGetValue(member.Id, out var value)) { list.Add(new Entry { Name = member.Name, Character = member.Character, Hp = value.Hp, MaxHp = value.MaxHp, Downed = value.Downed, Id = member.Id }); } else { list.Add(new Entry { Name = member.Name, Character = member.Character, Connecting = true, Id = member.Id }); } } } } else { foreach (RemotePlayer value2 in dictionary.Values) { list.Add(new Entry { Name = value2.DisplayName, Character = value2.Character, Hp = value2.Hp, MaxHp = value2.MaxHp, Downed = value2.Downed, Id = value2.PeerId }); } } return list; } public static void Tick(MyPlayer player) { //IL_020c: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)player != (Object)null; bool flag2 = Time.unscaledTime >= _nextRefresh; if (flag2) { _nextRefresh = Time.unscaledTime + 0.1f; _others = (flag ? Teammates() : new List<Entry>()); } List<Entry> others = _others; bool flag3 = (Object)(object)_notice != (Object)null && Time.unscaledTime < _noticeUntil; bool flag4 = !string.IsNullOrEmpty(CountdownText); if (!flag || (others.Count == 0 && !flag3 && !flag4 && string.IsNullOrEmpty(CenterText))) { if ((Object)(object)_canvas != (Object)null) { _canvas.SetActive(false); } CenterText = null; return; } EnsureCanvas(); _canvas.SetActive(true); ((Component)_notice).gameObject.SetActive(flag3); ((Component)_countdown).gameObject.SetActive(flag4); if (flag4) { ((TMP_Text)_countdown).text = CountdownText; } ((Component)_center).gameObject.SetActive(!string.IsNullOrEmpty(CenterText)); if (!string.IsNullOrEmpty(CenterText)) { ((TMP_Text)_center).text = CenterText; } bool flag5 = IsPaused(); bool flag6 = false; try { flag6 = MyTime.paused && !flag5; } catch { } ((Component)_pauseRoot).gameObject.SetActive(flag5); ((Component)_framesRoot).gameObject.SetActive(!flag5 && !flag6); if (!flag2) { return; } SyncFrames(_frames, _framesRoot, others.Count, 0f, -74f, compact: true); for (int i = 0; i < others.Count; i++) { Fill(_frames[i], others[i]); } if (flag5) { List<Entry> list = new List<Entry>(); list.Add(MyEntry(player)); list.AddRange(others); RectTransform pauseRoot = _pauseRoot; pauseRoot.sizeDelta = new Vector2(360f, 80f + (float)list.Count * 76f); SyncFrames(_pauseRows, pauseRoot, list.Count, -64f, -76f, compact: false); for (int j = 0; j < list.Count; j++) { Fill(_pauseRows[j], list[j]); } } } private static Entry MyEntry(MyPlayer player) { int hp = 0; int maxHp = 0; try { PlayerHealth val = ((player.inventory != null) ? player.inventory.playerHealth : null); if (val != null) { hp = val.hp; maxHp = val.maxHp; } } catch { } string text = (SteamLobby.InLobby ? SteamLobby.NameOf(SteamLobby.MyId) : "You"); return new Entry { Name = text + " (you)", Character = SteamLobby.MyCharacter, Hp = hp, MaxHp = maxHp, IsMe = true, Downed = DownedSync.Downed }; } private static bool IsPaused() { if ((Object)(object)_pauseUi == (Object)null && Time.unscaledTime >= _nextPauseLookup) { _nextPauseLookup = Time.unscaledTime + 1f; _pauseUi = Object.FindObjectOfType<PauseUi>(); } try { if ((Object)(object)_pauseUi == (Object)null) { return false; } GameObject main = _pauseUi.main; return _pauseUi.IsPaused() || ((Object)(object)main != (Object)null && main.activeInHierarchy); } catch { return false; } } private static void EnsureCanvas() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_canvas != (Object)null)) { _canvas = new GameObject("BonkCoop_PartyHud"); Object.DontDestroyOnLoad((Object)(object)_canvas); Canvas obj = _canvas.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 60; CanvasScaler obj2 = _canvas.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; RectTransform component = _canvas.GetComponent<RectTransform>(); _framesRoot = UiKit.MakeRect("Frames", (Transform)(object)component, 0f, -345f, 300f, 400f); RectTransform framesRoot = _framesRoot; RectTransform framesRoot2 = _framesRoot; RectTransform framesRoot3 = _framesRoot; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 1f); framesRoot3.pivot = val; Vector2 anchorMin = (framesRoot2.anchorMax = val); framesRoot.anchorMin = anchorMin; _framesRoot.anchoredPosition = new Vector2(-30f, -395f); Image obj3 = UiKit.MakePanel((Transform)(object)component, 60f, -530f, 360f, 200f); _pauseRoot = ((Graphic)obj3).rectTransform; ((Graphic)obj3).raycastTarget = false; UiKit.MakeLabel((Transform)(object)_pauseRoot, "Players", 20f, -10f, 300f, 46f, 34f, (TextAlignmentOptions)513); _center = UiKit.MakeLabel((Transform)(object)component, "", 0f, 0f, 1000f, 120f, 40f, (TextAlignmentOptions)514); RectTransform rectTransform = ((TMP_Text)_center).rectTransform; ((Vector2)(ref val))..ctor(0.5f, 0.5f); rectTransform.pivot = val; anchorMin = (rectTransform.anchorMax = val); rectTransform.anchorMin = anchorMin; rectTransform.anchoredPosition = new Vector2(0f, -170f); _countdown = UiKit.MakeLabel((Transform)(object)component, "", 0f, 0f, 1100f, 130f, 52f, (TextAlignmentOptions)514, (Color?)new Color(0.55f, 0.85f, 1f)); RectTransform rectTransform2 = ((TMP_Text)_countdown).rectTransform; ((Vector2)(ref val))..ctor(0.5f, 1f); rectTransform2.pivot = val; anchorMin = (rectTransform2.anchorMax = val); rectTransform2.anchorMin = anchorMin; rectTransform2.anchoredPosition = new Vector2(0f, -190f); _notice = UiKit.MakeLabel((Transform)(object)component, "", 0f, 0f, 1000f, 60f, 34f, (TextAlignmentOptions)514, (Color?)new Color(1f, 0.85f, 0.3f)); RectTransform rectTransform3 = ((TMP_Text)_notice).rectTransform; ((Vector2)(ref val))..ctor(0.5f, 1f); rectTransform3.pivot = val; anchorMin = (rectTransform3.anchorMax = val); rectTransform3.anchorMin = anchorMin; rectTransform3.anchoredPosition = new Vector2(0f, -140f); } } private static void SyncFrames(List<Frame> list, RectTransform parent, int count, float startY, float step, bool compact) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) while (list.Count < count) { list.Add(MakeFrame(pare