Due to update 2.4.3, some mods may no longer function. FixedConfig may be necessary.
Decompiled source of BoplSixPlayers v1.0.0
BepInEx\plugins\BoplSixPlayers.dll
Decompiled 10 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BoplFixedMath; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks; using Steamworks.Data; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.LowLevel; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BoplSixPlayers")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BoplSixPlayers")] [assembly: AssemblyTitle("BoplSixPlayers")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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 BoplSixPlayers { internal static class ColorExpander { private static readonly float[] ExtraTeamHues = new float[4] { 0.135f, 0.5f, 0.76f, 0.255f }; private static readonly HashSet<int> ExpandedTeamAssets = new HashSet<int>(); private static readonly HashSet<int> ExpandedColorAssets = new HashSet<int>(); private static readonly string[] KnownColorProps = new string[8] { "_Color", "_MainColor", "_BaseColor", "_Colour", "_Tint", "_TintColor", "_PlayerColor", "_FillColor" }; internal static void EnsureExpanded() { int max = Plugin.Max; ExpandTeams(max); ExpandPlayerColors(max); } private static void ExpandTeams(int max) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00d0: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00e9: 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) TeamColors[] array = Resources.FindObjectsOfTypeAll<TeamColors>(); foreach (TeamColors val in array) { if (!((Object)(object)val == (Object)null) && val.teamColors != null && val.teamColors.Length < max && ExpandedTeamAssets.Add(((Object)val).GetInstanceID())) { int num = val.teamColors.Length; TeamColor[] array2 = (TeamColor[])(object)new TeamColor[max]; Array.Copy(val.teamColors, array2, num); for (int j = num; j < max; j++) { float num2 = ExtraTeamHues[(j - num) % ExtraTeamHues.Length]; Color fill = Color.HSVToRGB(num2, 0.62f, 0.95f); Color border = Color.HSVToRGB(num2, 0.8f, 0.62f); Color saturated = Color.HSVToRGB(num2, 0.95f, 1f); array2[j] = new TeamColor { team = j, fill = fill, border = border, saturated = saturated }; } val.teamColors = array2; Plugin.Log.LogInfo((object)("TeamColors '" + ((Object)val).name + "': " + num + " -> " + max + " drużyn")); } } } private static float Frac(float v) { v -= Mathf.Floor(v); if (!(v < 0f)) { return v; } return v + 1f; } private static void ExpandPlayerColors(int max) { //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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: 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) PlayerColors[] array = Resources.FindObjectsOfTypeAll<PlayerColors>(); foreach (PlayerColors val in array) { if ((Object)(object)val == (Object)null || val.playerColors == null || val.playerColors.Length == 0) { continue; } if (val.playerColors.Length >= max) { if (ExpandedColorAssets.Add(((Object)val).GetInstanceID())) { Plugin.Log.LogInfo((object)("PlayerColors '" + ((Object)val).name + "': " + val.playerColors.Length + " kolorów – wystarczy dla " + max + " graczy, nie ruszam.")); } } else { if (!ExpandedColorAssets.Add(((Object)val).GetInstanceID())) { continue; } int num = val.playerColors.Length; PlayerColor[] array2 = (PlayerColor[])(object)new PlayerColor[max]; Array.Copy(val.playerColors, array2, num); int num2 = 0; for (int j = 0; j < num; j++) { if (val.playerColors[j].colorIndex > num2) { num2 = val.playerColors[j].colorIndex; } } for (int k = num; k < max; k++) { PlayerColor val2 = val.playerColors[k % num]; Color tint = Color.HSVToRGB(Frac(0.13f + 0.381966f * (float)(k + 1)), 0.75f, 1f); int num3 = k; PlayerColor val3 = default(PlayerColor); num2 = (val3.colorIndex = num2 + 1); val3.uiMaterial = TintedCopy(val2.uiMaterial, tint, "ui_" + k); val3.playerMaterial = TintedCopy(val2.playerMaterial, tint, "player_" + k); array2[num3] = val3; } val.playerColors = array2; Plugin.Log.LogInfo((object)("PlayerColors '" + ((Object)val).name + "': " + num + " -> " + max + " kolorów (dorobione materiały)")); } } } private static Material TintedCopy(Material src, Color tint, string suffix) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)src == (Object)null) { return null; } Material val = new Material(src); ((Object)val).name = ((Object)src).name + "_" + suffix; ((Object)val).hideFlags = (HideFlags)61; bool flag = false; string[] knownColorProps = KnownColorProps; foreach (string text in knownColorProps) { if (val.HasProperty(text)) { val.SetColor(text, tint); flag = true; } } if (!flag) { Plugin.Log.LogWarning((object)("materiał '" + ((Object)src).name + "' nie ma znanej właściwości koloru – nowy kolor może wyglądać identycznie")); } return val; } } [HarmonyPatch] internal static class CoreLimits { private static readonly FieldInfo KillsThisFrame = AccessTools.Field(typeof(AchievementHandler), "killsThisFrame"); internal static void ApplyStaticLimits() { int max = Plugin.Max; if (Constants.MAX_PLAYERS != max) { Constants.MAX_PLAYERS = max; Plugin.Log.LogInfo((object)("Constants.MAX_PLAYERS -> " + max)); } CharacterSelectBox.occupiedRectangles = Grow(CharacterSelectBox.occupiedRectangles, max + 1); CharacterSelectBox.deviceIds = Grow(CharacterSelectBox.deviceIds, max + 1); if (KillsThisFrame != null) { int[] array = KillsThisFrame.GetValue(null) as int[]; if (array == null || array.Length < max) { KillsThisFrame.SetValue(null, Grow(array, max)); } } } private static T[] Grow<T>(T[] src, int len) { if (src != null && src.Length >= len) { return src; } T[] array = new T[len]; if (src != null) { Array.Copy(src, array, src.Length); } return array; } [HarmonyPatch(typeof(GameSessionHandler), "Awake")] [HarmonyPostfix] [HarmonyPriority(0)] private static void ExpandSpawns(GameSessionHandler __instance) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) try { int max = Plugin.Max; Vec2[] teamSpawns = __instance.teamSpawns; if (teamSpawns != null && teamSpawns.Length != 0 && teamSpawns.Length < max) { Vec2[] array = (GameSessionHandler.playerSpawns_readonly = (__instance.teamSpawns = BuildSpawns(teamSpawns, max))); StringBuilder stringBuilder = new StringBuilder("punkty startowe rozszerzone do " + max + ": "); for (int i = 0; i < array.Length; i++) { string[] obj = new string[5] { "[", i.ToString(), "]", null, null }; Vector2 val = (Vector2)array[i]; obj[3] = ((Vector2)(ref val)).ToString("F1"); obj[4] = " "; stringBuilder.Append(string.Concat(obj)); } Plugin.Log.LogInfo((object)stringBuilder.ToString()); } } catch (Exception ex) { Plugin.Log.LogError((object)("ExpandSpawns: " + ex)); } } internal static Vec2[] BuildSpawns(Vec2[] original, int count) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0075: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) Vec2[] array = (Vec2[])(object)new Vec2[count]; for (int i = 0; i < original.Length && i < count; i++) { array[i] = original[i]; } Fix val = (Fix)0.5f; for (int j = original.Length; j < count; j++) { int num = j - original.Length; int num2 = num % original.Length; int num3 = (num2 + 1) % original.Length; int num4 = num / original.Length; Vec2 val2 = (original[num2] + original[num3]) * val; val2.y = val2.y + (Fix)2L + (Fix)(long)(3 * num4); array[j] = val2; } return array; } [HarmonyPatch(typeof(GameSessionHandler), "SpawnPlayers")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> SpawnPlayers_Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = 0; for (int i = 0; i < list.Count - 1; i++) { if (!(list[i + 1].opcode != OpCodes.Newarr) && !(list[i + 1].operand as Type != typeof(int)) && IsLdcI4(list[i], 4)) { list[i].opcode = OpCodes.Ldc_I4; list[i].operand = Plugin.Max; num++; } } Plugin.Log.LogInfo((object)("SpawnPlayers: podmieniono " + num + "x 'new int[4]' na 'new int[" + Plugin.Max + "]'")); return list; } internal static bool IsLdcI4(CodeInstruction ci, int value) { if (ci.opcode == OpCodes.Ldc_I4) { if (ci.operand is int) { return (int)ci.operand == value; } return false; } if (ci.opcode == OpCodes.Ldc_I4_S) { return Convert.ToInt32(ci.operand) == value; } return value switch { 0 => ci.opcode == OpCodes.Ldc_I4_0, 1 => ci.opcode == OpCodes.Ldc_I4_1, 2 => ci.opcode == OpCodes.Ldc_I4_2, 3 => ci.opcode == OpCodes.Ldc_I4_3, 4 => ci.opcode == OpCodes.Ldc_I4_4, 5 => ci.opcode == OpCodes.Ldc_I4_5, 6 => ci.opcode == OpCodes.Ldc_I4_6, 7 => ci.opcode == OpCodes.Ldc_I4_7, 8 => ci.opcode == OpCodes.Ldc_I4_8, _ => false, }; } [HarmonyPatch(typeof(PlayerAverageCamera), "Start")] [HarmonyPostfix] private static void Camera_Start(PlayerAverageCamera __instance) { try { if (Plugin.EnableExtraCamera.Value) { int num = PlayerHandler.Get().NumberOfPlayers(); if (num <= 0) { num = Plugin.Max; } if (num > 4) { float num2 = 1f + Plugin.CameraZoomPerExtraPlayer.Value * (float)(num - 4); float mAX_ZOOM = __instance.MAX_ZOOM; __instance.MAX_ZOOM = mAX_ZOOM * num2; __instance.extraZoomRoom *= num2; Plugin.Log.LogInfo((object)("kamera: MAX_ZOOM " + mAX_ZOOM.ToString("F1") + " -> " + __instance.MAX_ZOOM.ToString("F1") + " (" + num + " graczy)")); } } } catch (Exception ex) { Plugin.Log.LogError((object)("Camera_Start: " + ex)); } } } internal static class DebugMatch { private static int _phase = -1; private static float _timer; private static float _xAtStart; private static float _xAfterRight; internal static void StartLocalTestMatch(int count, bool firstPlayerOnKeyboard = true) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) try { PlayerColors[] array = Resources.FindObjectsOfTypeAll<PlayerColors>(); if (array.Length == 0 || (Object)(object)SteamManager.instance == (Object)null) { Plugin.Log.LogError((object)"mecz testowy: brak PlayerColors albo SteamManagera"); return; } PlayerColors val = array[0]; NamedSpriteList abilityIcons = SteamManager.instance.abilityIcons; if ((Object)(object)abilityIcons == (Object)null || abilityIcons.sprites == null || abilityIcons.sprites.Count < 2) { Plugin.Log.LogError((object)"mecz testowy: brak listy zdolności"); return; } GameLobby.isOnlineGame = false; GameLobby.isPlayingAReplay = false; List<Player> list = PlayerHandler.Get().PlayerList(); list.Clear(); for (int i = 0; i < count; i++) { Player val2 = new Player(i + 1, i); val2.Color = val.playerColors[i % val.playerColors.Length].playerMaterial; val2.UsesKeyboardAndMouse = firstPlayerOnKeyboard && i == 0; val2.CanUseAbilities = true; val2.inputDevice = null; val2.CustomKeyBinding = null; val2.Abilities = new List<GameObject>(3); val2.AbilityIcons = new List<Sprite>(3); int num = (((Object)(object)Settings.Get() == (Object)null) ? 3 : Settings.Get().NumberOfAbilities); for (int j = 0; j < num; j++) { int index = 1 + (i + j) % (abilityIcons.sprites.Count - 1); val2.Abilities.Add(abilityIcons.sprites[index].associatedGameObject); val2.AbilityIcons.Add(abilityIcons.sprites[index].sprite); } list.Add(val2); } GameSession.Init(); SceneManager.LoadScene("Level1"); if (!WinnerTriangleCanvas.HasBeenSpawned) { SceneManager.LoadScene("winnerTriangle", (LoadSceneMode)1); } Plugin.Log.LogInfo((object)("mecz testowy: wystartowano z " + list.Count + " graczami, gracz 1 na klawiaturze=" + (firstPlayerOnKeyboard ? "tak" : "nie"))); _phase = -1; _timer = 0f; } catch (Exception ex) { Plugin.Log.LogError((object)("StartLocalTestMatch: " + ex)); } } internal static void RunInputCheck() { _phase = 0; _timer = 0f; } internal static void Tick(float dt) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) if (_phase < 0) { return; } _timer += dt; List<Player> list = PlayerHandler.Get().PlayerList(); if (list == null || list.Count == 0) { return; } Player val = list[0]; switch (_phase) { case 0: if (_timer > 7f) { _xAtStart = (float)val.Position.x; Plugin.Log.LogInfo((object)("[test sterowania] start, x=" + _xAtStart.ToString("F2") + " – wciskam D")); _phase = 1; _timer = 0f; } break; case 1: PressKey((Key)18); if (_timer > 2f) { _xAfterRight = (float)val.Position.x; Plugin.Log.LogInfo((object)("[test sterowania] po 2s w prawo x=" + _xAfterRight.ToString("F2") + " (delta " + (_xAfterRight - _xAtStart).ToString("F2") + ")")); _phase = 2; _timer = 0f; } break; case 2: PressKey((Key)15); if (_timer > 2f) { float num = (float)val.Position.x; Plugin.Log.LogInfo((object)("[test sterowania] po 2s w lewo x=" + num.ToString("F2") + " (delta " + (num - _xAfterRight).ToString("F2") + ")")); bool flag = _xAfterRight - _xAtStart > 0.5f; bool flag2 = num - _xAfterRight < -0.5f; Plugin.Log.LogInfo((object)("[test sterowania] WYNIK: w prawo=" + (flag ? "DZIALA" : "NIE DZIALA") + ", w lewo=" + (flag2 ? "DZIALA" : "NIE DZIALA"))); _phase = 3; _timer = 0f; } break; case 3: ReleaseKeys(); if (_timer > 0.5f) { _phase = -1; } break; } } private static void PressKey(Key key) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected I4, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current != null) { InputSystem.QueueStateEvent<KeyboardState>((InputDevice)(object)current, new KeyboardState((Key[])(object)new Key[1] { (Key)(int)key }), -1.0); } } private static void ReleaseKeys() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current != null) { InputSystem.QueueStateEvent<KeyboardState>((InputDevice)(object)current, default(KeyboardState), -1.0); } } } internal static class Diagnostics { private static readonly HashSet<string> DumpedScenes = new HashSet<string>(); private static string _path; private static float _pending = -1f; private static string _pendingReason; private static readonly FieldInfo OriginalHeightsField = AccessTools.Field(typeof(AnimateInOutUI), "originalHeights"); internal static string DumpPath { get { if (_path == null) { _path = Path.Combine(Paths.BepInExRootPath, "BoplSixPlayers_dump.txt"); } return _path; } } internal unsafe static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { Plugin.Log.LogInfo((object)("[scene] zaladowano '" + ((Scene)(ref scene)).name + "' (" + ((object)(*(LoadSceneMode*)(&mode))/*cast due to .constrained prefix*/).ToString() + ")")); if (Plugin.DebugDump.Value) { _pending = 1.5f; _pendingReason = "scene-loaded: " + ((Scene)(ref scene)).name; } } internal static void Tick(float dt) { if (_pending < 0f) { return; } _pending -= dt; if (_pending > 0f) { return; } _pending = -1f; try { Dump(_pendingReason); } catch (Exception ex) { Plugin.Log.LogError((object)("diagnostics failed: " + ex)); } } internal static void Dump(string reason) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("================================================================"); stringBuilder.AppendLine("BoplSixPlayers dump (" + reason + ") " + DateTime.Now.ToString("HH:mm:ss")); string[] obj = new string[6] { "active scene: ", null, null, null, null, null }; Scene activeScene = SceneManager.GetActiveScene(); obj[1] = ((Scene)(ref activeScene)).name; obj[2] = " Constants.MAX_PLAYERS="; obj[3] = Constants.MAX_PLAYERS.ToString(); obj[4] = " isOnlineGame="; obj[5] = GameLobby.isOnlineGame.ToString(); stringBuilder.AppendLine(string.Concat(obj)); stringBuilder.AppendLine("================================================================"); DumpPlayerColors(stringBuilder); DumpTeamColors(stringBuilder); DumpCharacterSelect(stringBuilder); DumpCharacterSelectOnline(stringBuilder); DumpSpawns(stringBuilder); DumpCamera(stringBuilder); DumpStaticArrays(stringBuilder); DumpCanvases(stringBuilder); string text = stringBuilder.ToString(); Plugin.Log.LogInfo((object)text); try { File.AppendAllText(DumpPath, text + Environment.NewLine); } catch (Exception ex) { Plugin.Log.LogWarning((object)("could not write dump file: " + ex.Message)); } if (Plugin.AutoProbe == null || !Plugin.AutoProbe.Value) { return; } try { string bepInExRootPath = Paths.BepInExRootPath; activeScene = SceneManager.GetActiveScene(); string text2 = Path.Combine(bepInExRootPath, "shot_" + ((Scene)(ref activeScene)).name + ".png"); if (File.Exists(text2)) { File.Delete(text2); } ScreenCapture.CaptureScreenshot(text2); Plugin.Log.LogInfo((object)("zrzut ekranu -> " + text2)); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("screenshot: " + ex2.Message)); } } private static void DumpPlayerColors(StringBuilder sb) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00e3: Unknown result type (might be due to invalid IL or missing references) sb.AppendLine("--- PlayerColors assets ---"); PlayerColors[] array = Resources.FindObjectsOfTypeAll<PlayerColors>(); sb.AppendLine("instances: " + array.Length); PlayerColors[] array2 = array; foreach (PlayerColors val in array2) { sb.AppendLine(" asset '" + ((Object)val).name + "' length=" + ((val.playerColors == null) ? (-1) : val.playerColors.Length)); if (val.playerColors == null) { continue; } for (int j = 0; j < val.playerColors.Length; j++) { PlayerColor val2 = val.playerColors[j]; sb.AppendLine(" [" + j + "] colorIndex=" + val2.colorIndex + " ui=" + MatName(val2.uiMaterial) + " player=" + MatName(val2.playerMaterial)); } if (val.playerColors.Length != 0) { DumpMaterialProps(sb, " ", val.playerColors[0].playerMaterial, "playerMaterial[0]"); DumpMaterialProps(sb, " ", val.playerColors[0].uiMaterial, "uiMaterial[0]"); if (val.playerColors.Length > 1) { DumpMaterialProps(sb, " ", val.playerColors[1].playerMaterial, "playerMaterial[1]"); } } } } private static string MatName(Material m) { if (!((Object)(object)m == (Object)null)) { return ((Object)m).name + " [" + (((Object)(object)m.shader == (Object)null) ? "?" : ((Object)m.shader).name) + "]"; } return "<null>"; } private static void DumpMaterialProps(StringBuilder sb, string indent, Material m, string label) { //IL_00c0: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m == (Object)null) { sb.AppendLine(indent + label + ": <null>"); return; } sb.AppendLine(indent + label + ": " + ((Object)m).name + " shader=" + (((Object)(object)m.shader == (Object)null) ? "?" : ((Object)m.shader).name)); Shader shader = m.shader; if ((Object)(object)shader == (Object)null) { return; } try { int propertyCount = UnityEditorlessShaderUtil.GetPropertyCount(shader); for (int i = 0; i < propertyCount; i++) { string propertyName = UnityEditorlessShaderUtil.GetPropertyName(shader, i); string propertyType = UnityEditorlessShaderUtil.GetPropertyType(shader, i); string text = ""; switch (propertyType) { case "Color": text = " = " + ((object)m.GetColor(propertyName)/*cast due to .constrained prefix*/).ToString(); break; case "Float": case "Range": text = " = " + m.GetFloat(propertyName); break; case "Vector": text = " = " + ((object)m.GetVector(propertyName)/*cast due to .constrained prefix*/).ToString(); break; } sb.AppendLine(indent + " prop " + i + ": " + propertyName + " (" + propertyType + ")" + text); } } catch (Exception ex) { sb.AppendLine(indent + " <could not enumerate shader props: " + ex.Message + ">"); } } private unsafe static void DumpTeamColors(StringBuilder sb) { //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_00d0: 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_00d7: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) sb.AppendLine("--- TeamColors assets ---"); TeamColors[] array = Resources.FindObjectsOfTypeAll<TeamColors>(); sb.AppendLine("instances: " + array.Length); TeamColors[] array2 = array; foreach (TeamColors val in array2) { sb.AppendLine(" asset '" + ((Object)val).name + "' length=" + ((val.teamColors == null) ? (-1) : val.teamColors.Length)); if (val.teamColors != null) { for (int j = 0; j < val.teamColors.Length; j++) { TeamColor val2 = val.teamColors[j]; string[] obj = new string[10] { " [", j.ToString(), "] team=", val2.team.ToString(), " fill=", null, null, null, null, null }; Color fill = val2.fill; obj[5] = ((object)(*(Color*)(&fill))/*cast due to .constrained prefix*/).ToString(); obj[6] = " border="; fill = val2.border; obj[7] = ((object)(*(Color*)(&fill))/*cast due to .constrained prefix*/).ToString(); obj[8] = " sat="; fill = val2.saturated; obj[9] = ((object)(*(Color*)(&fill))/*cast due to .constrained prefix*/).ToString(); sb.AppendLine(string.Concat(obj)); } } } } private unsafe static void DumpCharacterSelect(StringBuilder sb) { //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: 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_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) CharacterSelectHandler val = Object.FindObjectOfType<CharacterSelectHandler>(); if ((Object)(object)val == (Object)null) { sb.AppendLine("--- CharacterSelectHandler: not in scene ---"); return; } sb.AppendLine("--- CharacterSelectHandler (local) ---"); CharacterSelectBox[] characterSelectBoxes = val.characterSelectBoxes; sb.AppendLine(" boxes: " + ((characterSelectBoxes == null) ? (-1) : characterSelectBoxes.Length)); Vector2 val3; if (characterSelectBoxes != null) { for (int i = 0; i < characterSelectBoxes.Length; i++) { CharacterSelectBox val2 = characterSelectBoxes[i]; if ((Object)(object)val2 == (Object)null) { sb.AppendLine(" [" + i + "] <null>"); continue; } RectTransform component = ((Component)val2).GetComponent<RectTransform>(); string[] obj = new string[25] { " [", i.ToString(), "] name='", ((Object)val2).name, "' rectIndex=", val2.RectangleIndex.ToString(), " parent='", ((Object)(object)((Component)val2).transform.parent == (Object)null) ? "<none>" : ((Object)((Component)val2).transform.parent).name, "' anchoredPos=", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; object obj2; if (!((Object)(object)component == (Object)null)) { val3 = component.anchoredPosition; obj2 = ((Vector2)(ref val3)).ToString("F1"); } else { obj2 = "?"; } obj[9] = (string)obj2; obj[10] = " sizeDelta="; object obj3; if (!((Object)(object)component == (Object)null)) { val3 = component.sizeDelta; obj3 = ((Vector2)(ref val3)).ToString("F1"); } else { obj3 = "?"; } obj[11] = (string)obj3; obj[12] = " scale="; Vector3 localScale = ((Component)val2).transform.localScale; obj[13] = ((Vector3)(ref localScale)).ToString("F2"); obj[14] = " anchorMin="; object obj4; if (!((Object)(object)component == (Object)null)) { val3 = component.anchorMin; obj4 = ((Vector2)(ref val3)).ToString("F2"); } else { obj4 = "?"; } obj[15] = (string)obj4; obj[16] = " anchorMax="; object obj5; if (!((Object)(object)component == (Object)null)) { val3 = component.anchorMax; obj5 = ((Vector2)(ref val3)).ToString("F2"); } else { obj5 = "?"; } obj[17] = (string)obj5; obj[18] = " pivot="; object obj6; if (!((Object)(object)component == (Object)null)) { val3 = component.pivot; obj6 = ((Vector2)(ref val3)).ToString("F2"); } else { obj6 = "?"; } obj[19] = (string)obj6; obj[20] = " selectables="; obj[21] = ((val2.selectables == null) ? (-1) : val2.selectables.Count).ToString(); obj[22] = " abilityGrid='"; obj[23] = (((Object)(object)val2.abilityGrid == (Object)null) ? "<null>" : FullPath(((Component)val2.abilityGrid).transform)); obj[24] = "'"; sb.AppendLine(string.Concat(obj)); } if (characterSelectBoxes.Length != 0 && (Object)(object)characterSelectBoxes[0] != (Object)null) { DumpAnimators(sb, ((Component)characterSelectBoxes[0]).gameObject, "box[0]"); sb.AppendLine(" box[0] full path: " + FullPath(((Component)characterSelectBoxes[0]).transform)); sb.AppendLine(" box[0] children:"); foreach (Transform item in ((Component)characterSelectBoxes[0]).transform) { Transform val4 = item; sb.AppendLine(" - " + ((Object)val4).name); } sb.AppendLine(" box[0] selectables:"); if (characterSelectBoxes[0].selectables != null) { for (int j = 0; j < characterSelectBoxes[0].selectables.Count; j++) { sb.AppendLine(" [" + j + "] " + (((Object)(object)characterSelectBoxes[0].selectables[j] == (Object)null) ? "<null>" : (((object)characterSelectBoxes[0].selectables[j]).GetType().Name + " '" + ((Object)characterSelectBoxes[0].selectables[j]).name + "'"))); } } } } FieldInfo fieldInfo = AccessTools.Field(typeof(CharacterSelectHandler), "animateOutDelays"); if (fieldInfo != null) { float[] array = fieldInfo.GetValue(val) as float[]; sb.AppendLine(" animateOutDelays: " + ((array == null) ? "null" : string.Join(",", array.Select((float x) => x.ToString("F2")).ToArray()))); } val3 = val.center; sb.AppendLine(" center=" + ((object)(*(Vector2*)(&val3))/*cast due to .constrained prefix*/).ToString()); } private static void DumpCharacterSelectOnline(StringBuilder sb) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_01b5: 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_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) CharacterSelectHandler_online val = Object.FindObjectOfType<CharacterSelectHandler_online>(); if ((Object)(object)val == (Object)null) { sb.AppendLine("--- CharacterSelectHandler_online: not in scene ---"); return; } sb.AppendLine("--- CharacterSelectHandler_online ---"); CharacterSelectBox characterSelectBox = val.characterSelectBox; Vector2 val2; if ((Object)(object)characterSelectBox != (Object)null) { RectTransform component = ((Component)characterSelectBox).GetComponent<RectTransform>(); string[] obj = new string[8] { " local box '", ((Object)characterSelectBox).name, "' path=", FullPath(((Component)characterSelectBox).transform), " anchoredPos=", null, null, null }; object obj2; if (!((Object)(object)component == (Object)null)) { val2 = component.anchoredPosition; obj2 = ((Vector2)(ref val2)).ToString("F1"); } else { obj2 = "?"; } obj[5] = (string)obj2; obj[6] = " sizeDelta="; object obj3; if (!((Object)(object)component == (Object)null)) { val2 = component.sizeDelta; obj3 = ((Vector2)(ref val2)).ToString("F1"); } else { obj3 = "?"; } obj[7] = (string)obj3; sb.AppendLine(string.Concat(obj)); } sb.AppendLine(" networkPlayerBoxes: " + ((val.networkPlayerBoxes == null) ? (-1) : val.networkPlayerBoxes.Length)); if (val.networkPlayerBoxes != null) { for (int i = 0; i < val.networkPlayerBoxes.Length; i++) { CSBox_online val3 = val.networkPlayerBoxes[i]; if ((Object)(object)val3 == (Object)null) { sb.AppendLine(" [" + i + "] <null>"); continue; } RectTransform component2 = ((Component)val3).GetComponent<RectTransform>(); string[] obj4 = new string[12] { " [", i.ToString(), "] '", ((Object)val3).name, "' path=", FullPath(((Component)val3).transform), " anchoredPos=", null, null, null, null, null }; object obj5; if (!((Object)(object)component2 == (Object)null)) { val2 = component2.anchoredPosition; obj5 = ((Vector2)(ref val2)).ToString("F1"); } else { obj5 = "?"; } obj4[7] = (string)obj5; obj4[8] = " sizeDelta="; object obj6; if (!((Object)(object)component2 == (Object)null)) { val2 = component2.sizeDelta; obj6 = ((Vector2)(ref val2)).ToString("F1"); } else { obj6 = "?"; } obj4[9] = (string)obj6; obj4[10] = " scale="; Vector3 localScale = ((Component)val3).transform.localScale; obj4[11] = ((Vector3)(ref localScale)).ToString("F2"); sb.AppendLine(string.Concat(obj4)); } } if (val.networkPlayerBoxes != null && val.networkPlayerBoxes.Length != 0 && (Object)(object)val.networkPlayerBoxes[0] != (Object)null) { DumpAnimators(sb, ((Component)val.networkPlayerBoxes[0]).gameObject, "networkPlayerBoxes[0]"); } if ((Object)(object)characterSelectBox != (Object)null) { DumpAnimators(sb, ((Component)characterSelectBox).gameObject, "localBox"); } sb.AppendLine(" loadingCircles: " + ((val.loadingCircles == null) ? (-1) : val.loadingCircles.Length)); if (val.loadingCircles == null) { return; } for (int j = 0; j < val.loadingCircles.Length; j++) { Image val4 = val.loadingCircles[j]; if ((Object)(object)val4 == (Object)null) { sb.AppendLine(" [" + j + "] <null>"); continue; } string[] obj7 = new string[8] { " [", j.ToString(), "] '", ((Object)val4).name, "' path=", FullPath(((Component)val4).transform), " anchoredPos=", null }; val2 = ((Graphic)val4).rectTransform.anchoredPosition; obj7[7] = ((Vector2)(ref val2)).ToString("F1"); sb.AppendLine(string.Concat(obj7)); } } private static void DumpSpawns(StringBuilder sb) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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) GameSessionHandler val = Object.FindObjectOfType<GameSessionHandler>(); if ((Object)(object)val == (Object)null) { sb.AppendLine("--- GameSessionHandler: not in scene ---"); return; } sb.AppendLine("--- GameSessionHandler ---"); sb.AppendLine(" levelType=" + ((object)Unsafe.As<LevelType, LevelType>(ref val.levelType)/*cast due to .constrained prefix*/).ToString() + " teammateSpawnSpacing=" + (float)val.teammateSpawnSpacing); Vec2[] teamSpawns = val.teamSpawns; sb.AppendLine(" teamSpawns: " + ((teamSpawns == null) ? (-1) : teamSpawns.Length)); if (teamSpawns != null) { for (int i = 0; i < teamSpawns.Length; i++) { string text = i.ToString(); Vector2 val2 = (Vector2)teamSpawns[i]; sb.AppendLine(" [" + text + "] " + ((Vector2)(ref val2)).ToString("F3")); } } sb.AppendLine(" SceneBounds: XMin=" + (float)SceneBounds.Camera_XMin + " XMax=" + (float)SceneBounds.Camera_XMax + " YMax=" + (float)SceneBounds.Camera_YMax + " Water=" + (float)SceneBounds.WaterHeight); } private static void DumpCamera(StringBuilder sb) { PlayerAverageCamera[] array = Object.FindObjectsOfType<PlayerAverageCamera>(); sb.AppendLine("--- PlayerAverageCamera: " + array.Length + " ---"); PlayerAverageCamera[] array2 = array; foreach (PlayerAverageCamera val in array2) { sb.AppendLine(" '" + FullPath(((Component)val).transform) + "' MIN_ZOOM=" + val.MIN_ZOOM + " MAX_ZOOM=" + val.MAX_ZOOM + " extraZoomRoom=" + val.extraZoomRoom + " zoomWeight=" + val.zoomWeight + " weight=" + val.weight + " outsideLevelX=" + val.outsideLevelX + " MinHeightAboveFloor=" + val.MinHeightAboveFloor + " useMinMaxForCameraX=" + val.useMinMaxForCameraX + " UpdateX=" + val.UpdateX + " UpdateY=" + val.UpdateY); } } private static void DumpStaticArrays(StringBuilder sb) { sb.AppendLine("--- static arrays ---"); sb.AppendLine(" CharacterSelectBox.occupiedRectangles.Length=" + ((CharacterSelectBox.occupiedRectangles == null) ? (-1) : CharacterSelectBox.occupiedRectangles.Length)); sb.AppendLine(" CharacterSelectBox.deviceIds.Length=" + ((CharacterSelectBox.deviceIds == null) ? (-1) : CharacterSelectBox.deviceIds.Length)); FieldInfo fieldInfo = AccessTools.Field(typeof(AchievementHandler), "killsThisFrame"); int[] array = ((fieldInfo == null) ? null : (fieldInfo.GetValue(null) as int[])); sb.AppendLine(" AchievementHandler.killsThisFrame.Length=" + ((array == null) ? (-1) : array.Length)); sb.AppendLine(" PlayerHandler players=" + PlayerHandler.Get().NumberOfPlayers()); } internal unsafe static void DumpCanvases(StringBuilder sb) { //IL_0055: 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_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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0165: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) sb.AppendLine("--- Canvases ---"); Canvas[] array = Object.FindObjectsOfType<Canvas>(); foreach (Canvas val in array) { RectTransform component = ((Component)val).GetComponent<RectTransform>(); CanvasScaler component2 = ((Component)val).GetComponent<CanvasScaler>(); string[] obj = new string[9] { " '", FullPath(((Component)val).transform), "' renderMode=", ((object)val.renderMode/*cast due to .constrained prefix*/).ToString(), " rect=", ((Object)(object)component == (Object)null) ? "?" : ((object)component.rect/*cast due to .constrained prefix*/).ToString(), " scale=", null, null }; Vector3 localScale = ((Component)val).transform.localScale; obj[7] = ((Vector3)(ref localScale)).ToString("F3"); Vector2 val2; object obj3; if (!((Object)(object)component2 == (Object)null)) { string[] obj2 = new string[6] { " scaler=", ((object)component2.uiScaleMode/*cast due to .constrained prefix*/).ToString(), " ref=", null, null, null }; val2 = component2.referenceResolution; obj2[3] = ((object)(*(Vector2*)(&val2))/*cast due to .constrained prefix*/).ToString(); obj2[4] = " match="; obj2[5] = component2.matchWidthOrHeight.ToString(); obj3 = string.Concat(obj2); } else { obj3 = ""; } obj[8] = (string)obj3; sb.AppendLine(string.Concat(obj)); foreach (Transform item in ((Component)val).transform) { Transform val3 = item; RectTransform val4 = (RectTransform)(object)((val3 is RectTransform) ? val3 : null); string[] obj4 = new string[10] { " child '", ((Object)val3).name, "' anchoredPos=", null, null, null, null, null, null, null }; object obj5; if (!((Object)(object)val4 == (Object)null)) { val2 = val4.anchoredPosition; obj5 = ((Vector2)(ref val2)).ToString("F1"); } else { obj5 = "?"; } obj4[3] = (string)obj5; obj4[4] = " sizeDelta="; object obj6; if (!((Object)(object)val4 == (Object)null)) { val2 = val4.sizeDelta; obj6 = ((Vector2)(ref val2)).ToString("F1"); } else { obj6 = "?"; } obj4[5] = (string)obj6; obj4[6] = " scale="; localScale = val3.localScale; obj4[7] = ((Vector3)(ref localScale)).ToString("F3"); obj4[8] = " children="; obj4[9] = val3.childCount.ToString(); sb.AppendLine(string.Concat(obj4)); } } } internal static void DumpAnimators(StringBuilder sb, GameObject root, string label) { //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) sb.AppendLine(" AnimateInOutUI w '" + label + "':"); AnimateInOutUI[] componentsInChildren = root.GetComponentsInChildren<AnimateInOutUI>(true); foreach (AnimateInOutUI val in componentsInChildren) { float[] array = ((OriginalHeightsField == null) ? null : (OriginalHeightsField.GetValue(val) as float[])); sb.Append(" '" + FullPath(((Component)val).transform) + "' start=" + val.startHeight + " end=" + val.endHeight + " horiz=" + val.horizontalInstead + " delay=" + val.delay + " auto=" + val.autoCallAnimateInOnStart + " transforms=" + ((val.animatedTransforms != null) ? val.animatedTransforms.Length : 0) + " originalHeights=["); if (array != null) { for (int j = 0; j < array.Length; j++) { sb.Append(array[j].ToString("F1") + ((j + 1 < array.Length) ? "," : "")); } } sb.AppendLine("]"); if (val.animatedTransforms == null) { continue; } for (int k = 0; k < val.animatedTransforms.Length; k++) { if ((Object)(object)val.animatedTransforms[k] != (Object)null) { string[] obj = new string[6] { " t[", k.ToString(), "] '", ((Object)val.animatedTransforms[k]).name, "' pos=", null }; Vector2 anchoredPosition = val.animatedTransforms[k].anchoredPosition; obj[5] = ((Vector2)(ref anchoredPosition)).ToString("F1"); sb.AppendLine(string.Concat(obj)); } } } } internal static string FullPath(Transform t) { List<string> list = new List<string>(); while ((Object)(object)t != (Object)null) { list.Add(((Object)t).name); t = t.parent; } list.Reverse(); return string.Join("/", list.ToArray()); } } internal static class UnityEditorlessShaderUtil { private static readonly MethodInfo GetCount = typeof(Shader).GetMethod("GetPropertyCount", BindingFlags.Instance | BindingFlags.Public); private static readonly MethodInfo GetName = typeof(Shader).GetMethod("GetPropertyName", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null); private static readonly MethodInfo GetTypeM = typeof(Shader).GetMethod("GetPropertyType", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null); internal static int GetPropertyCount(Shader s) { if (GetCount == null) { return 0; } return (int)GetCount.Invoke(s, new object[0]); } internal static string GetPropertyName(Shader s, int i) { if (GetName == null) { return "?"; } return (string)GetName.Invoke(s, new object[1] { i }); } internal static string GetPropertyType(Shader s, int i) { if (GetTypeM == null) { return "?"; } return GetTypeM.Invoke(s, new object[1] { i }).ToString(); } } internal struct ExtraPlayerInit { internal ulong steamId; internal byte color; internal byte team; internal byte ability1; internal byte ability2; internal byte ability3; } internal static class ExtraPlayers { internal const int PacketSize = 96; internal const byte Magic = 182; internal const byte LobbyPingId = 200; internal const byte LobbyAckId = 201; internal const int MaxExtra = 4; private const int EntrySize = 13; internal static ExtraPlayerInit[] Data = new ExtraPlayerInit[0]; internal static void Clear() { Data = new ExtraPlayerInit[0]; } internal static byte[] Encode() { byte[] array = new byte[96]; array[0] = 182; int num = Math.Min(Data.Length, 4); array[1] = (byte)num; int num2 = 2; for (int i = 0; i < num; i++) { ulong steamId = Data[i].steamId; for (int j = 0; j < 8; j++) { array[num2++] = (byte)((steamId >> 8 * j) & 0xFF); } array[num2++] = Data[i].color; array[num2++] = Data[i].team; array[num2++] = Data[i].ability1; array[num2++] = Data[i].ability2; array[num2++] = Data[i].ability3; } return array; } internal static bool Decode(byte[] buf) { if (buf == null || buf.Length < 96 || buf[0] != 182) { return false; } int num = buf[1]; if (num > 4) { num = 4; } if (2 + num * 13 > 96) { return false; } ExtraPlayerInit[] array = new ExtraPlayerInit[num]; int num2 = 2; for (int i = 0; i < num; i++) { ulong num3 = 0uL; for (int j = 0; j < 8; j++) { num3 |= (ulong)buf[num2++] << 8 * j; } array[i].steamId = num3; array[i].color = buf[num2++]; array[i].team = buf[num2++]; array[i].ability1 = buf[num2++]; array[i].ability2 = buf[num2++]; array[i].ability3 = buf[num2++]; } Data = array; return true; } internal static ulong SteamIdOf(int playerId, StartRequestPacket sp) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) switch (playerId) { case 1: return sp.p1_id; case 2: return sp.p2_id; case 3: return sp.p3_id; case 4: return sp.p4_id; default: { int num = playerId - 5; if (num >= 0 && num < Data.Length) { return Data[num].steamId; } return 0uL; } } } internal static int TotalKnownPlayers(StartRequestPacket sp) { return 4 + Data.Length; } } internal static class ExtraInput { private class Ring { internal readonly uint[] seq = new uint[256]; internal readonly InputPacket[] packet = (InputPacket[])(object)new InputPacket[256]; internal readonly bool[] used = new bool[256]; } private const int Slots = 256; private static readonly Ring[] Rings = new Ring[16]; internal static void Reset() { for (int i = 0; i < Rings.Length; i++) { Rings[i] = null; } } internal static void Store(int playerId, InputPacket p) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (playerId >= 0 && playerId < Rings.Length) { Ring ring = Rings[playerId]; if (ring == null) { ring = new Ring(); Rings[playerId] = ring; } int num = (int)(p.seqNumber % 256); ring.seq[num] = p.seqNumber; ring.packet[num] = p; ring.used[num] = true; } } internal static bool TryGet(int playerId, uint seqNumber, out InputPacket p) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) p = default(InputPacket); if (playerId < 0 || playerId >= Rings.Length) { return false; } Ring ring = Rings[playerId]; if (ring == null) { return false; } int num = (int)(seqNumber % 256); if (!ring.used[num] || ring.seq[num] != seqNumber) { return false; } p = ring.packet[num]; return true; } } [HarmonyPatch] internal static class LobbyPatches { [HarmonyPatch(typeof(SteamMatchmaking), "CreateLobbyAsync")] [HarmonyPrefix] private static void CreateLobbyAsync_Prefix(ref int maxMembers) { if (Plugin.EnableOnline.Value && maxMembers < Plugin.Max) { Plugin.Log.LogInfo((object)("CreateLobbyAsync: " + maxMembers + " -> " + Plugin.Max)); maxMembers = Plugin.Max; } } [HarmonyPatch(typeof(SteamManager), "OnLobbyEnteredCallback")] [HarmonyPostfix] private static void OnLobbyEntered_Postfix(SteamManager __instance) { RaiseLimit(__instance); } [HarmonyPatch(typeof(SteamManager), "OnLobbyMemberJoinedCallback")] [HarmonyPostfix] private static void OnLobbyMemberJoined_Postfix(SteamManager __instance) { RaiseLimit(__instance); } private static void RaiseLimit(SteamManager mgr) { //IL_0029: 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) if (!Plugin.EnableOnline.Value || (Object)(object)mgr == (Object)null) { return; } try { if (SteamClient.IsValid && SteamId.op_Implicit(((Lobby)(ref mgr.currentLobby)).Id) != 0L && ((Lobby)(ref mgr.currentLobby)).IsOwnedBy(SteamClient.SteamId) && ((Lobby)(ref mgr.currentLobby)).MaxMembers != Plugin.Max) { ((Lobby)(ref mgr.currentLobby)).MaxMembers = Plugin.Max; Plugin.Log.LogInfo((object)("lobby: limit miejsc ustawiony na " + Plugin.Max)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("nie udało się podnieść limitu lobby: " + ex.Message)); } } [HarmonyPatch(typeof(CharacterSelectHandler_online), "CheckForMods")] [HarmonyPostfix] private static void CheckForMods_Postfix() { CharacterSelectHandler_online.hasMods = true; } } [HarmonyPatch] internal static class NetPatches { private static readonly byte[] RecvBuffer = new byte[2048]; private static byte[] AckBuffer = new byte[6]; private static readonly FieldRef<Host, int> HostLocalPlayerId = AccessTools.FieldRefAccess<Host, int>("localPlayerId"); private static readonly FieldRef<Host, Queue<InputPacket>> HostSentPacketHistory = AccessTools.FieldRefAccess<Host, Queue<InputPacket>>("sentPacketHistory"); private static readonly FieldRef<Host, InputPacketQuad> HostPreviousQuad = AccessTools.FieldRefAccess<Host, InputPacketQuad>("previousInputQuad"); private static readonly FieldInfo OnlineSelfRef = AccessTools.Field(typeof(CharacterSelectHandler_online), "selfRef"); private static byte[] ScratchUint = new byte[4]; private static bool Online => Plugin.EnableOnline.Value; [HarmonyPatch(typeof(SteamManager), "HostGame")] [HarmonyPrefix] private static void HostGame_Prefix(SteamManager __instance) { if (!Online) { return; } try { List<SteamConnection> connectedPlayers = __instance.connectedPlayers; int num = connectedPlayers.Count - 3; if (num < 0) { num = 0; } if (num > 4) { num = 4; } ExtraPlayerInit[] array = new ExtraPlayerInit[num]; for (int i = 0; i < num; i++) { SteamConnection val = connectedPlayers[i + 3]; array[i].steamId = val.id.Value; array[i].color = (byte)val.lobby_color; array[i].team = val.lobby_team; array[i].ability1 = val.lobby_ability1; array[i].ability2 = val.lobby_ability2; array[i].ability3 = val.lobby_ability3; } ExtraPlayers.Data = array; BroadcastExtras(__instance, "HostGame"); } catch (Exception ex) { Plugin.Log.LogError((object)("HostGame_Prefix: " + ex)); } } [HarmonyPatch(typeof(SteamManager), "HostNextLevel")] [HarmonyPrefix] private static void HostNextLevel_Prefix(SteamManager __instance) { if (!Online) { return; } try { ExtraPlayerInit[] data = ExtraPlayers.Data; if (data.Length == 0) { return; } List<SteamConnection> connectedPlayers = __instance.connectedPlayers; for (int i = 0; i < data.Length; i++) { for (int j = 0; j < connectedPlayers.Count; j++) { if (connectedPlayers[j].id.Value == data[i].steamId) { data[i].ability1 = connectedPlayers[j].lobby_ability1; data[i].ability2 = connectedPlayers[j].lobby_ability2; data[i].ability3 = connectedPlayers[j].lobby_ability3; break; } } } ExtraPlayers.Data = data; BroadcastExtras(__instance, "HostNextLevel"); } catch (Exception ex) { Plugin.Log.LogError((object)("HostNextLevel_Prefix: " + ex)); } } private static void BroadcastExtras(SteamManager mgr, string why) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) byte[] array = ExtraPlayers.Encode(); List<SteamConnection> connectedPlayers = mgr.connectedPlayers; for (int i = 0; i < connectedPlayers.Count; i++) { if (((ConnectionManager)connectedPlayers[i]).Connected) { ((Connection)(ref ((ConnectionManager)connectedPlayers[i]).Connection)).SendMessage(array, (SendType)8); } } Plugin.Log.LogInfo((object)(why + ": rozesłano dane " + ExtraPlayers.Data.Length + " dodatkowych graczy")); } [HarmonyPatch(typeof(SteamSocket), "OnMessage")] [HarmonyPrefix] private static bool OnMessage_Prefix(Connection connection, NetIdentity identity, IntPtr data, int size) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) if (!Online) { return true; } if (size != 6 && size != 96) { return true; } try { SteamId steamId = ((NetIdentity)(ref identity)).SteamId; if (!((SteamId)(ref steamId)).IsValid) { return true; } if ((Object)(object)SteamManager.instance == (Object)null) { return true; } Friend val = new Friend(((NetIdentity)(ref identity)).SteamId); if (!((Friend)(ref val)).IsIn(((Lobby)(ref SteamManager.instance.currentLobby)).Id)) { return true; } Marshal.Copy(data, RecvBuffer, 0, size); if (size == 96) { if (RecvBuffer[0] != 182) { return true; } if (((Lobby)(ref SteamManager.instance.currentLobby)).IsOwnedBy(((NetIdentity)(ref identity)).SteamId) && ExtraPlayers.Decode(RecvBuffer)) { Plugin.Log.LogInfo((object)("odebrano dane " + ExtraPlayers.Data.Length + " dodatkowych graczy od hosta")); } return false; } switch (RecvBuffer[0]) { case 200: { Ack val3 = NetworkTools.ReadAck(RecvBuffer, ref ScratchUint); ReplyToLobbyPing(identity, val3.seqNumber); return false; } case 201: { Ack val2 = NetworkTools.ReadAck(RecvBuffer, ref ScratchUint); List<SteamConnection> connectedPlayers = SteamManager.instance.connectedPlayers; for (int i = 0; i < connectedPlayers.Count; i++) { if (connectedPlayers[i].id.Value == SteamId.op_Implicit(((NetIdentity)(ref identity)).SteamId)) { connectedPlayers[i].ReceiveAck(val2, Time.timeSinceLevelLoad); break; } } return false; } default: { Host networkClientHandle = SteamManager.networkClientHandle; if ((Object)(object)networkClientHandle != (Object)null && networkClientHandle.hasBeenInitialized) { networkClientHandle.ReadPacket(RecvBuffer, size); } return false; } } } catch (Exception ex) { Plugin.Log.LogError((object)("OnMessage_Prefix: " + ex)); return true; } } private static void ReplyToLobbyPing(NetIdentity identity, uint seqNumber) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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) NetworkTools.EncodeAckForNetwork(ref AckBuffer, new Ack { playerId = 201, seqNumber = seqNumber }); List<SteamConnection> connectedPlayers = SteamManager.instance.connectedPlayers; for (int i = 0; i < connectedPlayers.Count; i++) { if (connectedPlayers[i].id.Value == SteamId.op_Implicit(((NetIdentity)(ref identity)).SteamId)) { ((Connection)(ref ((ConnectionManager)connectedPlayers[i]).Connection)).SendMessage(AckBuffer, (SendType)1); break; } } } [HarmonyPatch(typeof(SteamConnection), "SendPing")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> SendPing_Transpiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = 0; for (int i = 0; i < list.Count - 1; i++) { if (CoreLimits.IsLdcI4(list[i], 5) && !(list[i + 1].opcode != OpCodes.Stfld)) { FieldInfo fieldInfo = list[i + 1].operand as FieldInfo; if (!(fieldInfo == null) && !(fieldInfo.Name != "playerId")) { list[i].opcode = OpCodes.Ldc_I4; list[i].operand = 200; num++; } } } Plugin.Log.LogInfo((object)("SendPing: przenumerowano ping lobby na " + (byte)200 + " (" + num + "x)")); return list; } [HarmonyPatch(typeof(CharacterSelectHandler_online), "ForceStartGame")] [HarmonyPrefix] private static bool ForceStartGame_Prefix(PlayerColors pcs) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0096: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00c1: 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_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) //IL_00d9: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0146: 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) //IL_01c5: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) if (!Online) { return true; } try { CharacterSelectHandler_online val = (CharacterSelectHandler_online)((OnlineSelfRef == null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)pcs == (Object)null) { pcs = (((Object)(object)val != (Object)null) ? val.playerColors : null); } if ((Object)(object)pcs == (Object)null || pcs.playerColors == null) { Plugin.Log.LogWarning((object)"ForceStartGame: brak PlayerColors, oddaję sterowanie wanilii"); return true; } StartRequestPacket startParameters = SteamManager.startParameters; Updater.ReInit(); Updater.InitSeed(startParameters.seed); ExtraInput.Reset(); List<Player> list = new List<Player>(); int added = 0; AddIfPresent(list, ref added, startParameters, 1, startParameters.p1_color, startParameters.p1_team, startParameters.p1_ability1, startParameters.p1_ability2, startParameters.p1_ability3, pcs); AddIfPresent(list, ref added, startParameters, 2, startParameters.p2_color, startParameters.p2_team, startParameters.p2_ability1, startParameters.p2_ability2, startParameters.p2_ability3, pcs); AddIfPresent(list, ref added, startParameters, 3, startParameters.p3_color, startParameters.p3_team, startParameters.p3_ability1, startParameters.p3_ability2, startParameters.p3_ability3, pcs); AddIfPresent(list, ref added, startParameters, 4, startParameters.p4_color, startParameters.p4_team, startParameters.p4_ability1, startParameters.p4_ability2, startParameters.p4_ability3, pcs); ExtraPlayerInit[] data = ExtraPlayers.Data; for (int i = 0; i < data.Length; i++) { AddIfPresent(list, ref added, startParameters, 5 + i, data[i].color, data[i].team, data[i].ability1, data[i].ability2, data[i].ability3, pcs); } for (int j = 0; j < list.Count; j++) { list[j].steamId = SteamId.op_Implicit(ExtraPlayers.SteamIdOf(list[j].Id, startParameters)); } Player val2 = null; if (GameLobby.isPlayingAReplay) { if (list.Count > 0) { val2 = list[0]; } } else { ulong value = SteamClient.SteamId.Value; for (int k = 0; k < list.Count; k++) { if (SteamId.op_Implicit(list[k].steamId) == value) { val2 = list[k]; break; } } } if (val2 == null) { Plugin.Log.LogError((object)("ForceStartGame: nie znalazłem lokalnego gracza (graczy=" + list.Count + ", dodatkowych=" + data.Length + ") – przerywam start")); return false; } val2.IsLocalPlayer = true; val2.inputDevice = CharacterSelectHandler_online.localPlayerInit.inputDevice; val2.UsesKeyboardAndMouse = CharacterSelectHandler_online.localPlayerInit.usesKeyboardMouse; val2.CustomKeyBinding = CharacterSelectHandler_online.localPlayerInit.keybindOverride; CharacterSelectHandler_online.startButtonAvailable = false; PlayerHandler.Get().SetPlayerList(list); SteamManager.instance.StartHostedGame(); AudioManager val3 = AudioManager.Get(); if ((Object)(object)val3 != (Object)null) { val3.Play("startGame"); } GameSession.Init(); Plugin.Log.LogInfo((object)("start meczu: " + list.Count + " graczy, lokalny = nr " + val2.Id)); if (GameLobby.isPlayingAReplay) { SceneManager.LoadScene(startParameters.currentLevel + 6); } else { SceneManager.LoadScene("Level1"); } if (!WinnerTriangleCanvas.HasBeenSpawned) { SceneManager.LoadScene("winnerTriangle", (LoadSceneMode)1); } return false; } catch (Exception ex) { Plugin.Log.LogError((object)("ForceStartGame_Prefix: " + ex)); return true; } } private static void AddIfPresent(List<Player> list, ref int added, StartRequestPacket sp, int id, byte color, byte team, byte a1, byte a2, byte a3, PlayerColors pcs) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (a1 != 0 && sp.nrOfPlayers > added) { list.Add(MakePlayer(id, color, team, a1, a2, a3, sp.nrOfAbilites, pcs)); added++; } } private static Player MakePlayer(int id, byte color, byte team, byte a1, byte a2, byte a3, int nrOfAbilities, PlayerColors pcs) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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) NamedSpriteList abilityIcons = SteamManager.instance.abilityIcons; Player val = new Player(); val.Id = id; if (color < pcs.playerColors.Length) { val.Color = pcs.playerColors[color].playerMaterial; } else { val.Color = pcs.playerColors[0].playerMaterial; } val.Team = team; if (nrOfAbilities > 0) { val.Abilities.Add(abilityIcons.sprites[a1].associatedGameObject); val.AbilityIcons.Add(abilityIcons.sprites[a1].sprite); } if (nrOfAbilities > 1) { val.Abilities.Add(abilityIcons.sprites[a2].associatedGameObject); val.AbilityIcons.Add(abilityIcons.sprites[a2].sprite); } if (nrOfAbilities > 2) { val.Abilities.Add(abilityIcons.sprites[a3].associatedGameObject); val.AbilityIcons.Add(abilityIcons.sprites[a3].sprite); } val.IsLocalPlayer = false; return val; } [HarmonyPatch(typeof(SteamManager), "InitNetworkClient")] [HarmonyPrefix] private static bool InitNetworkClient_Prefix(SteamManager __instance) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown if (!Online) { return true; } try { StartRequestPacket startParameters = SteamManager.startParameters; int num = 4 + ExtraPlayers.Data.Length; ulong value = SteamClient.SteamId.Value; int num2 = 0; for (int i = 1; i <= num; i++) { if (ExtraPlayers.SteamIdOf(i, startParameters) == value) { num2 = i; break; } } List<Client> list = new List<Client>(); List<SteamConnection> connectedPlayers = __instance.connectedPlayers; for (int j = 0; j < connectedPlayers.Count; j++) { for (int k = 1; k <= num; k++) { ulong num3 = ExtraPlayers.SteamIdOf(k, startParameters); if (num3 != 0L && connectedPlayers[j].id.Value == num3 && startParameters.nrOfPlayers >= k) { list.Add(new Client(k, connectedPlayers[j])); break; } } } __instance.networkClient.Init(list, num2, startParameters.currentLevel, __instance.startFrameBuffer, __instance.checkForDesyncs); SteamManager.networkClientHandle = __instance.networkClient; Plugin.Log.LogInfo((object)("sieć: " + list.Count + " klientów, lokalny gracz = nr " + num2)); return false; } catch (Exception ex) { Plugin.Log.LogError((object)("InitNetworkClient_Prefix: " + ex)); return true; } } [HarmonyPatch(typeof(SteamManager), "ForceLoadNextLevel")] [HarmonyPrefix] private static void ForceLoadNextLevel_Prefix() { //IL_00a4: 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_00fa: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if (!Online) { return; } try { ExtraPlayerInit[] data = ExtraPlayers.Data; if (data.Length == 0) { return; } int nrOfAbilites = SteamManager.startParameters.nrOfAbilites; NamedSpriteList abilityIcons = SteamManager.instance.abilityIcons; List<Player> list = PlayerHandler.Get().PlayerList(); for (int i = 0; i < list.Count; i++) { int num = list[i].Id - 5; if (num >= 0 && num < data.Length) { Player val = list[i]; val.Abilities.Clear(); val.AbilityIcons.Clear(); if (nrOfAbilites > 0) { val.Abilities.Add(abilityIcons.sprites[data[num].ability1].associatedGameObject); val.AbilityIcons.Add(abilityIcons.sprites[data[num].ability1].sprite); } if (nrOfAbilites > 1) { val.Abilities.Add(abilityIcons.sprites[data[num].ability2].associatedGameObject); val.AbilityIcons.Add(abilityIcons.sprites[data[num].ability2].sprite); } if (nrOfAbilites > 2) { val.Abilities.Add(abilityIcons.sprites[data[num].ability3].associatedGameObject); val.AbilityIcons.Add(abilityIcons.sprites[data[num].ability3].sprite); } } } } catch (Exception ex) { Plugin.Log.LogError((object)("ForceLoadNextLevel_Prefix: " + ex)); } } [HarmonyPatch(typeof(Host), "Init")] [HarmonyPostfix] private static void Host_Init_Postfix() { ExtraInput.Reset(); } [HarmonyPatch(typeof(Client), "ProcessNetworkPackets")] [HarmonyPostfix] private static void Client_ProcessNetworkPackets_Postfix(Client __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!Online) { return; } int playerId = __instance.PlayerId; if (playerId <= 4) { return; } Queue<InputPacket> inputHistory = __instance.inputHistory; if (inputHistory == null || inputHistory.Count == 0) { return; } foreach (InputPacket item in inputHistory) { ExtraInput.Store(playerId, item); } } [HarmonyPatch(typeof(Host), "UpdateLocalInputHistory")] [HarmonyPostfix] private static void Host_UpdateLocalInputHistory_Postfix(Host __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (!Online) { return; } int num = HostLocalPlayerId.Invoke(__instance); if (num <= 4) { return; } Queue<InputPacket> queue = HostSentPacketHistory.Invoke(__instance); if (queue == null || queue.Count == 0) { return; } foreach (InputPacket item in queue) { ExtraInput.Store(num, item); } } [HarmonyPatch(typeof(Updater), "TickSimulation")] [HarmonyPrefix] private static void TickSimulation_Prefix() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if (!Online || !GameLobby.isOnlineGame || GameLobby.isPlayingAReplay) { return; } try { Host networkClientHandle = SteamManager.networkClientHandle; if ((Object)(object)networkClientHandle == (Object)null || !networkClientHandle.hasBeenInitialized) { return; } List<Player> list = PlayerHandler.Get().PlayerList(); if (list == null) { return; } bool flag = false; for (int i = 0; i < list.Count; i++) { if (list[i].Id > 4) { flag = true; break; } } if (!flag) { return; } InputPacketQuad val = HostPreviousQuad.Invoke(networkClientHandle); uint seqNumber = val.p1.seqNumber; if (val.p2.seqNumber > seqNumber) { seqNumber = val.p2.seqNumber; } if (val.p3.seqNumber > seqNumber) { seqNumber = val.p3.seqNumber; } if (val.p4.seqNumber > seqNumber) { seqNumber = val.p4.seqNumber; } for (int j = 0; j < list.Count; j++) { if (list[j].Id > 4) { if (!ExtraInput.TryGet(list[j].Id, seqNumber, out var p)) { p = default(InputPacket); } list[j].OverrideInputWithNetworkInput(p); } } } catch (Exception ex) { Plugin.Log.LogError((object)("TickSimulation_Prefix: " + ex)); } } [HarmonyPatch(typeof(CSBox_online), "Init")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> CSBoxOnline_Init_Transpiler(IEnumerable<CodeInstruction> instructions) { return RaiseTeamLoopBound(instructions, "CSBox_online.Init"); } [HarmonyPatch(typeof(CharacterSelectHandler_online), "Start")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> ChSelectOnline_Start_Transpiler(IEnumerable<CodeInstruction> instructions) { return RaiseTeamLoopBound(instructions, "CharacterSelectHandler_online.Start"); } private static IEnumerable<CodeInstruction> RaiseTeamLoopBound(IEnumerable<CodeInstruction> instructions, string where) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = 0; for (int i = 0; i < list.Count - 1; i++) { if (CoreLimits.IsLdcI4(list[i], 4)) { OpCode opcode = list[i + 1].opcode; if (!(opcode != OpCodes.Blt) || !(opcode != OpCodes.Blt_S) || !(opcode != OpCodes.Bge) || !(opcode != OpCodes.Bge_S) || !(opcode != OpCodes.Clt)) { list[i].opcode = OpCodes.Ldc_I4; list[i].operand = Plugin.Max; num++; } } } Plugin.Log.LogInfo((object)(where + ": granica wyboru drużyny 4 -> " + Plugin.Max + " (" + num + "x)")); return list; } } [BepInPlugin("com.mateusz.boplsixplayers", "Bopl Six Players", "1.0.0")] [BepInProcess("BoplBattle.exe")] public class Plugin : BaseUnityPlugin { public const string GUID = "com.mateusz.boplsixplayers"; internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigEntry<int> MaxPlayers; internal static ConfigEntry<bool> EnableOnline; internal static ConfigEntry<bool> EnableExtraCamera; internal static ConfigEntry<float> CameraZoomPerExtraPlayer; internal static ConfigEntry<bool> DebugDump; internal static ConfigEntry<bool> AutoProbe; private Harmony _harmony; private int _probeStep; private float _probeTimer; internal static int Max => Mathf.Clamp((MaxPlayers == null) ? 6 : MaxPlayers.Value, 4, 8); private void Awake() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; MaxPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxPlayers", 6, new ConfigDescription("Maksymalna liczba graczy (4-8). Domyślnie 6. WSZYSCY gracze w lobby online muszą mieć tę samą wartość!", (AcceptableValueBase)(object)new AcceptableValueRange<int>(4, 8), Array.Empty<object>())); EnableOnline = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableOnline", true, "Czy łatać także grę online (lobby Steam, netcode). Wyłącz, jeśli chcesz tylko couch/local."); EnableExtraCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "EnableExtraZoom", true, "Czy kamera ma się bardziej oddalać przy większej liczbie graczy."); CameraZoomPerExtraPlayer = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "ZoomPerExtraPlayer", 0.1f, new ConfigDescription("O ile procent (0.10 = 10%) zwiększyć maksymalne oddalenie kamery na każdego gracza powyżej 4.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); DebugDump = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DumpGameData", false, "Zrzuca do BepInEx/LogOutput.log oraz BoplSixPlayers_dump.txt dane o kolorach/drużynach/UI. Klawisz F8 = zrzut na żądanie."); AutoProbe = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "AutoProbeScenes", false, "Tylko do diagnostyki: gra sama wchodzi w ekrany wyboru postaci i zrzuca ich układ. Zostaw false."); Log.LogInfo((object)("BoplSixPlayers " + ((BaseUnityPlugin)this).Info.Metadata.Version?.ToString() + " startuje. MaxPlayers=" + Max + " online=" + EnableOnline.Value)); try { CoreLimits.ApplyStaticLimits(); } catch (Exception ex) { Log.LogError((object)("nie udało się podnieść statycznych limitów: " + ex)); } _harmony = new Harmony("com.mateusz.boplsixplayers"); try { _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)("Harmony: załatano " + _harmony.GetPatchedMethods().Count() + " metod.")); } catch (Exception ex2) { Log.LogError((object)("Harmony PatchAll padło: " + ex2)); } SceneManager.sceneLoaded += OnSceneLoaded; if (DebugDump.Value) { int sceneCountInBuildSettings = SceneManager.sceneCountInBuildSettings; StringBuilder stringBuilder = new StringBuilder("sceny w grze (" + sceneCountInBuildSettings + "): "); for (int i = 0; i < sceneCountInBuildSettings; i++) { stringBuilder.Append("[" + i + "]" + SceneUtility.GetScenePathByBuildIndex(i) + " "); } Log.LogInfo((object)stringBuilder.ToString()); } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; if (_harmony != null) { _harmony.UnpatchSelf(); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) try { CoreLimits.ApplyStaticLimits(); } catch (Exception ex) { Log.LogError((object)("ApplyStaticLimits (scene): " + ex)); } try { ColorExpander.EnsureExpanded(); } catch (Exception ex2) { Log.LogError((object)("ColorExpander: " + ex2)); } try { Diagnostics.OnSceneLoaded(scene, mode); } catch (Exception ex3) { Log.LogError((object)("Diagnostics: " + ex3)); } } private void Update() { try { Diagnostics.Tick(Time.unscaledDeltaTime); Keyboard current = Keyboard.current; if (current != null) { if (((ButtonControl)current.f8Key).wasPressedThisFrame) { Diagnostics.Dump("F8"); } if (((ButtonControl)current.f9Key).wasPressedThisFrame) { Log.LogInfo((object)"F9 -> CharacterSelect"); SceneManager.LoadScene("CharacterSelect"); } if (((ButtonControl)current.f10Key).wasPressedThisFrame) { Log.LogInfo((object)"F10 -> ChSelect_online"); SceneManager.LoadScene("ChSelect_online"); } if (((ButtonControl)current.f11Key).wasPressedThisFrame) { Log.LogInfo((object)("F11 -> testowy mecz z " + Max + " graczami (gracz 1 na klawiaturze)")); DebugMatch.StartLocalTestMatch(Max); } } DebugMatch.Tick(Time.unscaledDeltaTime); if (AutoProbe != null && AutoProbe.Value) { TickProbe(); } } catch (Exception ex) { Log.LogError((object)("Update: " + ex)); } } private void TickProbe() { _probeTimer += Time.unscaledDeltaTime; if (_probeStep == 0 && _probeTimer > 8f) { _probeStep = 1; _probeTimer = 0f; Log.LogInfo((object)"[probe] ladowanie CharacterSelect"); SceneManager.LoadScene("CharacterSelect"); } else if (_probeStep == 1 && _probeTimer > 8f) { _probeStep = 2; _probeTimer = 0f; Log.LogInfo((object)"[probe] ladowanie ChSelect_online"); SceneManager.LoadScene("ChSelect_online"); } else if (_probeStep == 2 && _probeTimer > 8f) { _probeStep = 3; _probeTimer = 0f; Log.LogInfo((object)("[probe] start meczu testowego z " + Max + " graczami")); DebugMatch.StartLocalTestMatch(Max); DebugMatch.RunInputCheck(); } else if (_probeStep == 3 && _probeTimer > 20f) { _probeStep = 4; Log.LogInfo((object)"[probe] koniec"); try { Diagnostics.Dump("mecz testowy"); } catch (Exception ex) { Log.LogError((object)("dump: " + ex)); } } } } internal static class LinqShim { internal static int Count<T>(this IEnumerable<T> src) { int num = 0; foreach (T item in src) { _ = item; num++; } return num; } } [HarmonyPatch] internal static class UiExpander { private static readonly FieldInfo OriginalHeightsField = AccessTools.Field(typeof(AnimateInOutUI), "originalHeights"); private static readonly FieldInfo AnimateOutDelaysField = AccessTools.Field(typeof(CharacterSelectHandler), "animateOutDelays"); private static MonoBehaviour _host; [HarmonyPatch(typeof(CharacterSelectHandler), "Start")] [HarmonyPostfix] private static void LocalCharacterSelect_Start(CharacterSelectHandler __instance) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) try { int max = Plugin.Max; CharacterSelectBox[] characterSelectBoxes = __instance.characterSelectBoxes; if (characterSelectBoxes == null || characterSelectBoxes.Length == 0 || characterSelectBoxes.Length >= max) { return; } int num = characterSelectBoxes.Length; CharacterSelectBox[] array = (CharacterSelectBox[])(object)new CharacterSelectBox[max]; Array.Copy(characterSelectBoxes, array, num); float num2 = SpacingOf(((Component)characterSelectBoxes[0]).transform, (num > 1) ? ((Component)characterSelectBoxes[1]).transform : null); XRange<CharacterSelectBox>(characterSelectBoxes, out float min, out float max2); for (int i = num; i < max; i++) { GameObject val = CloneUi(((Component)characterSelectBoxes[0]).gameObject); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)("nie udało się sklonować slotu " + i)); return; } CharacterSelectBox component = val.GetComponent<CharacterSelectBox>(); RectTransform component2 = val.GetComponent<RectTransform>(); ((Object)val).name = "CharacterSelectBox_mod" + i; component.RectangleIndex = i; component.UseskeyboardMouse = false; component.currentGamePad = null; component2.anchoredPosition = new Vector2(max2 + num2 * (float)(i - num + 1), component2.anchoredPosition.y); array[i] = component; } __instance.characterSelectBoxes = array; GrowDelays(__instance, max); _host = (MonoBehaviour)(object)__instance; FitRow(((Component)characterSelectBoxes[0]).transform.parent, min, max2, max2 + num2 * (float)(max - num)); Plugin.Log.LogInfo((object)("wybór postaci (lokalnie): " + num + " -> " + max + " slotów")); } catch (Exception ex) { Plugin.Log.LogError((object)("LocalCharacterSelect_Start: " + ex)); } } private static void GrowDelays(CharacterSelectHandler handler, int need) { if (AnimateOutDelaysField == null) { return; } float[] array = AnimateOutDelaysField.GetValue(handler) as float[]; if (array != null && array.Length >= need) { return; } float[] array2 = new float[need]; float num = 0f; for (int i = 0; i < need; i++) { if (array != null && i < array.Length) { num = array[i]; } array2[i] = num; } AnimateOutDelaysField.SetValue(handler, array2); } [HarmonyPatch(typeof(CharacterSelectHandler_online), "Start")] [HarmonyPostfix] private static void OnlineCharacterSelect_Start(CharacterSelectHandler_online __instance) { //IL_00a1: 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_0168: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.EnableOnline.Value) { return; } try { int num = Plugin.Max - 1; CSBox_online[] networkPlayerBoxes = __instance.networkPlayerBoxes; if (networkPlayerBoxes == null || networkPlayerBoxes.Length == 0 || networkPlayerBoxes.Length >= num) { return; } int num2 = networkPlayerBoxes.Length; float num3 = SpacingOf(((Component)networkPlayerBoxes[0]).transform, (num2 > 1) ? ((Component)networkPlayerBoxes[1]).transform : null); XRange<CSBox_online>(networkPlayerBoxes, out float min, out float max); if ((Object)(object)__instance.characterSelectBox != (Object)null) { RectTransform component = ((Component)__instance.characterSelectBox).GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null && (Object)(object)((Transform)component).parent == (Object)(object)((Component)networkPlayerBoxes[0]).transform.parent) { if (component.anchoredPosition.x < min) { min = component.anchoredPosition.x; } if (component.anchoredPosition.x > max) { max = component.anchoredPosition.x; } } } CSBox_online[] array = (CSBox_online[])(object)new CSBox_online[num]; Array.Copy(networkPlayerBoxes, array, num2); for (int i = num2; i < num; i++) { GameObject val = CloneUi(((Component)networkPlayerBoxes[0]).gameObject); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)("nie udało się sklonować slotu online " + i)); return; } ((Object)val).name = "OnlinePlayerBox_mod" + i; RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchoredPosition = new Vector2(max + num3 * (float)(i - num2 + 1), component2.anchoredPosition.y); array[i] = val.GetComponent<CSBox_online>(); } __instance.networkPlayerBoxes = array; _host = (MonoBehaviour)(object)__instance; Image[] loadingCircles = __instance.loadingCircles; if (loadingCircles != null && loadingCircles.Length != 0 && loadingCircles.Length < num) { int num4 = loadingCircles.Length; float num5 = SpacingOf(((Component)loadingCircles[0]).transform, (num4 > 1) ? ((Component)loadingCircles[1]).transform : null); XRange<Image>(loadingCircles, out float _, out float max2); Image[] array2 = (Image[])(object)new Image[num]; Array.Copy(loadingCircles, array2, num4); for (int j = num4; j < num; j++) { GameObject val2 = CloneUi(((Component)loadingCircles[0]).gameObject); if ((Object)(object)val2 == (Object)null) { break; } ((Object)val2).name = "waitCircle_mod" + j; RectTransform component3 = val2.GetComponent<RectTransform>(); component3.anchoredPosition = new Vector2(max2 + num5 * (float)(j - num4 + 1), component3.anchoredPosition.y); array2[j] = val2.GetComponent<Image>(); } for (int k = 0; k < num; k++) { if ((Object)(object)array2[k] == (Object)null) { array2[k] = loadingCircles[0]; } } __instance.loadingCircles = array2; } FitRow(((Component)networkPlayerBoxes[0]).transform.parent, min, max, max + num3 * (float)(num - num2)); Plugin.Log.LogInfo((object)("wybór postaci (online): " + num2 + " -> " + num + " slotów dla innych graczy")); } catch (Exception ex) { Plugin.Log.LogError((object)("OnlineCharacterSelect_Start: " + ex)); } } private static float SpacingOf(Transform a, Transform b) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)(object)((a is RectTransform) ? a : null); RectTransform val2 = (RectTransform)(object)((b is RectTransform) ? b : null); if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null) { float num = val2.anchoredPosition.x - val.anchoredPosition.x; if (Mathf.Abs(num) > 1f) { return num; } } if ((Object)(object)val != (Object)null && val.sizeDelta.x > 1f) { return val.sizeDelta.x * 1.1f; } return 600f; } private static void XRange<T>(T[] items, out float min, out float max) where T : Component { //IL_0040: Unknown result type (might be due to invalid IL or missing references) min = float.MaxValue; max = float.MinValue; foreach (T val in items) { if ((Object)(object)val == (Object)null) { continue; } RectTransform component = ((Component)val).GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { float x = component.anchoredPosition.x; if (x < min) { min = x; } if (x > max) { max = x; } } } if (min > max) { min = 0f; max = 0f; } } private static void FitRow(Transform parent, float oldMin, float oldMax, float newMax) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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 refer