using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Net; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using Battle; using Battle.Attacks; using Battle.Attacks.AttackBehaviours; using Battle.Enemies; using Battle.Enemies.Behaviours.SpiritOfRadia; using Battle.Pachinko; using Battle.Pachinko.Obstacles; using Battle.PegBehaviour; using Battle.StatusEffects; using BepInEx; using BepInEx.Logging; using Challenges; using ClassSystem; using Cruciball; using Currency; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options; using Data; using Data.Scenarios; using HarmonyLib; using I2.Loc; using LiteNetLib; using LiteNetLib.Layers; using LiteNetLib.Utils; using Loading; using Loading.Pegboards; using Map; using Microsoft.CodeAnalysis; using Multipeglin.Continue; using Multipeglin.DI; using Multipeglin.Debug; using Multipeglin.Events; using Multipeglin.Events.Handlers; using Multipeglin.Events.Handlers.Ball; using Multipeglin.Events.Handlers.Battle; using Multipeglin.Events.Handlers.Coop; using Multipeglin.Events.Handlers.Currency; using Multipeglin.Events.Handlers.Cursor; using Multipeglin.Events.Handlers.Deck; using Multipeglin.Events.Handlers.Enemy; using Multipeglin.Events.Handlers.Health; using Multipeglin.Events.Handlers.Lobby; using Multipeglin.Events.Handlers.Map; using Multipeglin.Events.Handlers.Peg; using Multipeglin.Events.Handlers.Relic; using Multipeglin.Events.Handlers.Scenarios; using Multipeglin.Events.Handlers.State; using Multipeglin.Events.Handlers.StatusEffect; using Multipeglin.Events.Network; using Multipeglin.Events.Network.Ball; using Multipeglin.Events.Network.Battle; using Multipeglin.Events.Network.Coop; using Multipeglin.Events.Network.Currency; using Multipeglin.Events.Network.Cursor; using Multipeglin.Events.Network.Deck; using Multipeglin.Events.Network.Enemy; using Multipeglin.Events.Network.Health; using Multipeglin.Events.Network.Lobby; using Multipeglin.Events.Network.Map; using Multipeglin.Events.Network.Peg; using Multipeglin.Events.Network.Relic; using Multipeglin.Events.Network.Scenarios; using Multipeglin.Events.Network.StatusEffect; using Multipeglin.Events.Subscriptions; using Multipeglin.Events.Subscriptions.Coop; using Multipeglin.GameState; using Multipeglin.GameState.Appliers; using Multipeglin.GameState.Providers; using Multipeglin.GameState.Snapshots; using Multipeglin.Multiplayer; using Multipeglin.Network; using Multipeglin.Network.Protocol; using Multipeglin.Patches; using Multipeglin.UI; using Multipeglin.Utility; using NLog; using NLog.Config; using NLog.Layouts; using NLog.Targets; using NLog.Targets.Wrappers; using Newtonsoft.Json; using Peglin; using Peglin.ClassSystem; using Peglin.PegMinigame; using PeglinUI; using PeglinUI.ControllerSupport; using PeglinUI.LoadoutManager; using PeglinUI.MainMenu; using PeglinUI.OrbDisplay; using PeglinUI.PostBattle; using PeglinUI.RunSummary; using PeglinUI.UIUtils; using PixelCrushers; using PixelCrushers.DialogueSystem; using RNG.Scenarios; using Relics; using Rewired; using Rewired.Integration.UnityUI; using Scenarios; using Scenarios.Shop; using Stats; using Steamworks; using TMPro; using ToolBox.Serialization; using Tutorial; using UI.OrbDisplay; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.ResourceManagement.ResourceLocations; using UnityEngine.SceneManagement; using UnityEngine.UI; using Worldmap; [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("Multipeglin")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Multiplayer mode for Peglin")] [assembly: AssemblyFileVersion("0.1.10.0")] [assembly: AssemblyInformationalVersion("0.1.10+fa08d30a0345f919382a92e95e02120aab7c2ac1")] [assembly: AssemblyProduct("Multipeglin")] [assembly: AssemblyTitle("Multipeglin")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.10.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Multipeglin { [BepInPlugin("com.multipeglin", "Multipeglin", "0.1.10")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MultiplayerPlugin : BaseUnityPlugin { private Harmony _harmony; private FileLogger _fileLogger; private static GameObject _modObject; public static MultiplayerPlugin Instance { get; private set; } public static IServiceContainer Services { get; private set; } public static ManualLogSource Logger { get; private set; } public static IReadOnlyList MissingPatches { get; private set; } private void Awake() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; try { string logsDirectory = Path.Combine(Paths.BepInExRootPath, "logs"); _fileLogger = new FileLogger(logsDirectory); Logger.Listeners.Add((ILogListener)(object)new FileLogListener(_fileLogger)); Logger.LogInfo((object)("Log file: " + _fileLogger.FilePath)); Services = ServiceRegistration.CreateAndConfigure(Logger); _modObject = new GameObject("Multipeglin") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)_modObject); _modObject.AddComponent().Initialize(Services.Resolve()); MainThreadDispatcher instance = _modObject.AddComponent(); Services.RegisterSingleton(instance); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _modObject.AddComponent(); _harmony = new Harmony("com.multipeglin"); try { _harmony.PatchAll(); } catch (Exception ex) { Logger.LogError((object)$"Harmony PatchAll failed: {ex}"); MissingPatches = new List { "PatchAll failed: " + ex.Message }; } int num = 0; foreach (MethodBase patchedMethod in _harmony.GetPatchedMethods()) { Logger.LogInfo((object)("Harmony patched: " + patchedMethod.DeclaringType?.FullName + "." + patchedMethod.Name)); num++; } Logger.LogInfo((object)$"Harmony total patches applied: {num}"); if (MissingPatches == null) { List list = PatchValidator.FindMissingPatchTargets(Logger); if (list.Count > 0) { Logger.LogWarning((object)$"[PatchValidator] {list.Count} patch target(s) not found:"); foreach (string item in list) { Logger.LogWarning((object)(" Missing: " + item)); } MissingPatches = list; } } Logger.LogInfo((object)"Multipeglin v0.1.10 loaded"); } catch (Exception arg) { Logger.LogError((object)$"Failed to initialize: {arg}"); } } private void OnDestroy() { } } public static class MultiplayerPluginInfo { public const string GUID = "com.multipeglin"; public const string NAME = "Multipeglin"; public const string VERSION = "0.1.10"; public const string COMPILED_GAME_VERSION = "2.0.12"; } } namespace Multipeglin.Utility { public class BallIdentifier { private readonly Dictionary _guidToBall = new Dictionary(); private readonly Dictionary _ballToGuid = new Dictionary(); private static ManualLogSource Log => MultiplayerPlugin.Logger; public int Count => _guidToBall.Count; public string GetOrAssignGuid(PachinkoBall ball) { if ((Object)(object)ball == (Object)null) { return "null"; } if (_ballToGuid.TryGetValue(ball, out var value)) { return value; } string text = Guid.NewGuid().ToString("N").Substring(0, 12); _guidToBall[text] = ball; _ballToGuid[ball] = text; return text; } public string GetGuid(PachinkoBall ball) { if ((Object)(object)ball == (Object)null) { return null; } if (!_ballToGuid.TryGetValue(ball, out var value)) { return null; } return value; } public void Forget(PachinkoBall ball) { if (!((Object)(object)ball == (Object)null) && _ballToGuid.TryGetValue(ball, out var value)) { _guidToBall.Remove(value); _ballToGuid.Remove(ball); } } public void ForgetByGuid(string guid) { if (!string.IsNullOrEmpty(guid) && _guidToBall.TryGetValue(guid, out var value)) { _guidToBall.Remove(guid); if ((Object)(object)value != (Object)null) { _ballToGuid.Remove(value); } } } public List PruneDestroyed() { List list = new List(); List list2 = new List(); foreach (KeyValuePair item in _guidToBall) { if ((Object)(object)item.Value == (Object)null) { list2.Add(item.Key); } } foreach (string item2 in list2) { _guidToBall.Remove(item2); list.Add(item2); } List list3 = new List(); foreach (KeyValuePair item3 in _ballToGuid) { if ((Object)(object)item3.Key == (Object)null) { list3.Add(item3.Key); } } foreach (PachinkoBall item4 in list3) { _ballToGuid.Remove(item4); } return list; } public void Clear() { int count = _guidToBall.Count; _guidToBall.Clear(); _ballToGuid.Clear(); if (count > 0) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[BallGUID] Cleared {count} entries"); } } } } public static class DiagnosticLogger { private static ManualLogSource Log => MultiplayerPlugin.Logger; public static void DumpBattleState(string trigger) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_06fb: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_0684: Unknown result type (might be due to invalid IL or missing references) //IL_069a: Unknown result type (might be due to invalid IL or missing references) //IL_06ab: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("=== DIAG [" + trigger + "] scene=" + name + " ===")); } ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)($" SGD: seed={StaticGameData.currentSeed}, floor={StaticGameData.totalFloorCount}, " + $"class={StaticGameData.chosenClass}, nodeIdx={StaticGameData.chosenNextNodeIndex}, " + string.Format("seedSet={0}, dataToLoad={1}", StaticGameData.seedSet, ((Object)(object)StaticGameData.dataToLoad != (Object)null) ? ((object)StaticGameData.dataToLoad).GetType().Name : "NULL"))); } MapData dataToLoad = StaticGameData.dataToLoad; MapDataBattle val = (MapDataBattle)(object)((dataToLoad is MapDataBattle) ? dataToLoad : null); if (val != null) { ManualLogSource log3 = Log; if (log3 != null) { string[] obj = new string[6] { " MapDataBattle: name=", ((Object)val).name, ", pegLayout=", ((Object)(object)val.pegLayout != (Object)null) ? ((Object)val.pegLayout).name : "NULL", ", ", null }; object arg = val.NumberOfSlots; object arg2 = val.starterSpawns?.Count ?? (-1); WaveGroup[] waveGroups = val.waveGroups; obj[5] = $"slots={arg}, starterSpawns={arg2}, waves={((waveGroups != null) ? waveGroups.Length : (-1))}"; log3.LogInfo((object)string.Concat(obj)); } } try { RelicManager[] array = Resources.FindObjectsOfTypeAll(); RelicManager val2 = ((array.Length != 0) ? array[0] : null); if ((Object)(object)val2 != (Object)null) { IDictionary dictionary = AccessTools.Field(typeof(RelicManager), "_ownedRelics")?.GetValue(val2) as IDictionary; ManualLogSource log4 = Log; if (log4 != null) { log4.LogInfo((object)$" Relics: {dictionary?.Count ?? 0} owned"); } } } catch { } try { List completeDeck = DeckManager.completeDeck; ManualLogSource log5 = Log; if (log5 != null) { log5.LogInfo((object)$" CompleteDeck: {completeDeck?.Count ?? 0} orbs"); } } catch { } try { Dictionary dictionary2 = AssetLoading.Instance?.EnemyPrefabs; ManualLogSource log6 = Log; if (log6 != null) { log6.LogInfo((object)$" EnemyPrefabCache: {dictionary2?.Count ?? (-1)} entries"); } } catch { } if (name != "Battle") { ManualLogSource log7 = Log; if (log7 != null) { log7.LogInfo((object)("=== END DIAG [" + trigger + "] (not Battle) ===")); } return; } EnemyManager val3 = Object.FindObjectOfType(); if ((Object)(object)val3 != (Object)null) { List enemies = val3.Enemies; ManualLogSource log8 = Log; if (log8 != null) { log8.LogInfo((object)$" Enemies ({enemies?.Count ?? 0}):"); } if (enemies != null) { for (int i = 0; i < enemies.Count; i++) { Enemy val4 = enemies[i]; if ((Object)(object)val4 == (Object)null) { ManualLogSource log9 = Log; if (log9 != null) { log9.LogInfo((object)$" [{i}] NULL"); } continue; } ManualLogSource log10 = Log; if (log10 != null) { log10.LogInfo((object)($" [{i}] {val4.locKey} name={((Object)((Component)val4).gameObject).name} hp={val4.CurrentHealth}/{GetMaxHp(val4):F0} " + $"pos=({((Component)val4).transform.position.x:F2},{((Component)val4).transform.position.y:F2}) flying={val4.IsFlying}")); } } } } else { ManualLogSource log11 = Log; if (log11 != null) { log11.LogInfo((object)" EnemyManager: NOT FOUND"); } } BattleController obj5 = Object.FindObjectOfType(); PegManager val5 = ((obj5 != null) ? obj5.pegManager : null); if (val5 != null && val5.allPegs != null) { List list = AccessTools.Field(typeof(BattleController).Assembly.GetType("Battle.PegManager"), "_bombs")?.GetValue(val5) as List; List list2 = new List(val5.allPegs); if (list != null) { foreach (Bomb item in list) { list2.Add((Peg)(object)item); } } Peg[] array2 = list2.Where((Peg p) => (Object)(object)p != (Object)null && ((Component)p).gameObject.activeSelf).ToArray(); IOrderedEnumerable> orderedEnumerable = from p in array2 group p by p.pegType into g orderby g.Count() descending select g; ManualLogSource log12 = Log; if (log12 != null) { log12.LogInfo((object)$" Pegs: {array2.Length} active / {list2.Count} total (allPegs={val5.allPegs.Count}, bombs={list?.Count ?? 0})"); } foreach (IGrouping item2 in orderedEnumerable) { ManualLogSource log13 = Log; if (log13 != null) { log13.LogInfo((object)$" {item2.Key}: {item2.Count()}"); } } IEnumerable enumerable = (from p in array2 orderby ((Component)p).transform.position.y, ((Component)p).transform.position.x select p).Take(10); ManualLogSource log14 = Log; if (log14 != null) { log14.LogInfo((object)" First 10 pegs by pos:"); } foreach (Peg item3 in enumerable) { ManualLogSource log15 = Log; if (log15 != null) { log15.LogInfo((object)$" ({((Component)item3).transform.position.x:F3},{((Component)item3).transform.position.y:F3}) type={item3.pegType}"); } } } else { ManualLogSource log16 = Log; if (log16 != null) { log16.LogInfo((object)" PegManager: NOT FOUND"); } } ManualLogSource log17 = Log; if (log17 != null) { log17.LogInfo((object)$" BattleState: {BattleController.CurrentBattleState}"); } PachinkoBall[] array3 = Object.FindObjectsOfType(); ManualLogSource log18 = Log; if (log18 != null) { log18.LogInfo((object)$" Balls: {array3.Length} (dummy={array3.Count((PachinkoBall b) => b.IsDummy)}, real={array3.Count((PachinkoBall b) => !b.IsDummy)})"); } ManualLogSource log19 = Log; if (log19 != null) { log19.LogInfo((object)("=== END DIAG [" + trigger + "] ===")); } } catch (Exception ex) { ManualLogSource log20 = Log; if (log20 != null) { log20.LogError((object)("DiagnosticLogger.DumpBattleState failed: " + ex.Message)); } } } private static float GetMaxHp(Enemy e) { try { FieldInfo fieldInfo = AccessTools.Field(typeof(Enemy), "_maxHealth"); return (fieldInfo != null) ? ((float)fieldInfo.GetValue(e)) : (-1f); } catch { return -1f; } } } public class EnemyIdentifier { private readonly Dictionary _guidToEnemy = new Dictionary(); private readonly Dictionary _enemyToGuid = new Dictionary(); private static ManualLogSource Log => MultiplayerPlugin.Logger; public string GetOrAssignGuid(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return "null"; } if (_enemyToGuid.TryGetValue(enemy, out var value)) { return value; } string text = Guid.NewGuid().ToString("N").Substring(0, 12); _guidToEnemy[text] = enemy; _enemyToGuid[enemy] = text; return text; } public void Register(Enemy enemy, string guid) { if ((Object)(object)enemy == (Object)null || string.IsNullOrEmpty(guid)) { return; } if (_guidToEnemy.TryGetValue(guid, out var value) && (Object)(object)value != (Object)(object)enemy) { _enemyToGuid.Remove(value); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[EnemyGUID] Replaced stale mapping for " + guid + " (was '" + value?.locKey + "')")); } } if (_enemyToGuid.TryGetValue(enemy, out var value2) && value2 != guid) { _guidToEnemy.Remove(value2); ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("[EnemyGUID] Enemy '" + enemy.locKey + "' had old GUID " + value2 + ", replacing with " + guid)); } } _guidToEnemy[guid] = enemy; _enemyToGuid[enemy] = guid; } public Enemy Find(string guid) { if (string.IsNullOrEmpty(guid)) { return null; } if (_guidToEnemy.TryGetValue(guid, out var value) && (Object)(object)value != (Object)null) { return value; } if ((Object)(object)value == (Object)null && _guidToEnemy.ContainsKey(guid)) { _guidToEnemy.Remove(guid); } return null; } public string GetGuid(Enemy enemy) { if ((Object)(object)enemy == (Object)null) { return null; } if (!_enemyToGuid.TryGetValue(enemy, out var value)) { return null; } return value; } public void Unregister(Enemy enemy) { if (!((Object)(object)enemy == (Object)null) && _enemyToGuid.TryGetValue(enemy, out var value)) { _enemyToGuid.Remove(enemy); _guidToEnemy.Remove(value); } } public void Unregister(string guid) { if (!string.IsNullOrEmpty(guid) && _guidToEnemy.TryGetValue(guid, out var value)) { _guidToEnemy.Remove(guid); if ((Object)(object)value != (Object)null) { _enemyToGuid.Remove(value); } } } public void Clear() { int count = _guidToEnemy.Count; _guidToEnemy.Clear(); _enemyToGuid.Clear(); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[EnemyGUID] Cleared {count} entries"); } } public void DumpState(string trigger) { //IL_00ba: 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) ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[EnemyGUID] === DUMP ({trigger}) {_guidToEnemy.Count} entries ==="); } foreach (KeyValuePair item in _guidToEnemy) { Enemy value = item.Value; if ((Object)(object)value != (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)("[EnemyGUID] " + item.Key + " → '" + value.locKey + "' (" + ((Object)((Component)value).gameObject).name + ") " + $"pos=({((Component)value).transform.position.x:F1},{((Component)value).transform.position.y:F1}) hp={value.CurrentHealth}")); } } else { ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)("[EnemyGUID] " + item.Key + " → DESTROYED")); } } } } public string GetId(Enemy enemy) { return GetOrAssignGuid(enemy); } } public sealed class EventDiscovery { private readonly ManualLogSource _log; public Dictionary AvailableEvents { get; } = new Dictionary(); public HashSet RegisteredTypeIds { get; } = new HashSet(); public EventDiscovery(ManualLogSource log) { _log = log; } public void ScanGameDelegates() { AvailableEvents.Clear(); try { Assembly assembly = Assembly.Load("Assembly-CSharp"); if (assembly == null) { _log.LogWarning((object)"Could not load Assembly-CSharp for event discovery"); return; } Type[] types = assembly.GetTypes(); foreach (Type type in types) { try { FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (typeof(Delegate).IsAssignableFrom(fieldInfo.FieldType)) { string key = type.FullName + "." + fieldInfo.Name; AvailableEvents[key] = fieldInfo; } } } catch { } } _log.LogInfo((object)$"Event discovery: found {AvailableEvents.Count} static delegate fields in game"); } catch (Exception ex) { _log.LogWarning((object)("Event discovery scan failed: " + ex.Message)); } } public void MarkRegistered(string typeId) { RegisteredTypeIds.Add(typeId); } public void LogReport() { _log.LogInfo((object)"=== Event Discovery Report ==="); _log.LogInfo((object)$"Game delegates found: {AvailableEvents.Count}"); _log.LogInfo((object)$"Handlers registered: {RegisteredTypeIds.Count}"); foreach (IGrouping> item in from kv in AvailableEvents group kv by kv.Value.DeclaringType?.Name ?? "Unknown" into g orderby g.Key select g) { IOrderedEnumerable values = from kv in item select kv.Value.Name into n orderby n select n; _log.LogInfo((object)(" [" + item.Key + "] " + string.Join(", ", values))); } _log.LogInfo((object)"--- Registered handler typeIds ---"); foreach (string item2 in RegisteredTypeIds.OrderBy((string s) => s)) { _log.LogInfo((object)(" " + item2)); } } } public sealed class FileLogger : IDisposable { private readonly Logger _nlog; private readonly string _filePath; private static string _roleTag = string.Empty; public string FilePath => _filePath; public static string RoleTag { get { return _roleTag; } set { _roleTag = AnnotateClientTag(value); } } public FileLogger(string logsDirectory) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0083: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00a3: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown Directory.CreateDirectory(logsDirectory); string text = Environment.GetEnvironmentVariable("MULTIPEGLIN_LOGNAME"); if (string.IsNullOrEmpty(text)) { text = "multipeglin_log.log"; } _filePath = Path.Combine(logsDirectory, text); string environmentVariable = Environment.GetEnvironmentVariable("MULTIPEGLIN_INSTANCE"); if (!string.IsNullOrEmpty(environmentVariable)) { RoleTag = environmentVariable; } LoggingConfiguration val = new LoggingConfiguration(); FileTarget val2 = new FileTarget("multipeglinFile") { FileName = Layout.op_Implicit(_filePath), Layout = Layout.op_Implicit("${message}"), KeepFileOpen = true, AutoFlush = false, OpenFileFlushTimeout = 2, BufferSize = 32768 }; AsyncTargetWrapper val3 = new AsyncTargetWrapper("multipeglinFileAsync", (Target)(object)val2) { QueueLimit = 10000, BatchSize = 200, TimeToSleepBetweenBatches = 0, OverflowAction = (AsyncTargetWrapperOverflowAction)1 }; val.AddRule(LogLevel.Trace, LogLevel.Fatal, (Target)(object)val3, "*"); LogManager.Configuration = val; _nlog = LogManager.GetLogger("Multipeglin"); _nlog.Info($"--- Multipeglin [{RoleTag}] log started at {DateTime.Now:O} ---"); } private static string AnnotateClientTag(string baseTag) { if (baseTag != "CLIENT") { return baseTag; } try { string environmentVariable = Environment.GetEnvironmentVariable("MULTIPEGLIN_INSTANCE"); if (string.IsNullOrEmpty(environmentVariable)) { return baseTag; } int num = environmentVariable.Length; while (num > 0 && char.IsDigit(environmentVariable[num - 1])) { num--; } string text = environmentVariable.Substring(num); return string.IsNullOrEmpty(text) ? baseTag : ("CLIENT" + text); } catch { return baseTag; } } public void Log(LogLevel level, string message) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) string text = (string.IsNullOrEmpty(RoleTag) ? string.Empty : ("[" + RoleTag + "] ")); string text2 = $"[{DateTime.Now:HH:mm:ss.fff}] [{level}] {text}{message}"; _nlog.Info(text2); } public void Dispose() { LogManager.Shutdown(); } } public sealed class FileLogListener : ILogListener, IDisposable { private readonly FileLogger _fileLogger; public FileLogListener(FileLogger fileLogger) { _fileLogger = fileLogger; } public void LogEvent(object sender, LogEventArgs eventArgs) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) ILogSource source = eventArgs.Source; if (source != null && (source.SourceName?.StartsWith("Multipeglin")).GetValueOrDefault()) { _fileLogger.Log(eventArgs.Level, $"[{eventArgs.Source.SourceName}] {eventArgs.Data}"); } } public void Dispose() { } } public static class LongPegVisualHelper { public static void ApplyHitVisual(LongPeg peg) { //IL_0184: 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_0192: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)peg == (Object)null) { return; } try { FieldInfo fieldInfo = AccessTools.Field(typeof(LongPeg), "_hit"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(Peg), "_cleared"); FieldInfo fieldInfo3 = AccessTools.Field(typeof(LongPeg), "_renderer"); FieldInfo fieldInfo4 = AccessTools.Field(typeof(LongPeg), "_colors"); FieldInfo fieldInfo5 = AccessTools.Field(typeof(LongPeg), "_activeMaterial"); FieldInfo fieldInfo6 = AccessTools.Field(typeof(LongPeg), "_destroyedMaterial"); FieldInfo fieldInfo7 = AccessTools.Field(typeof(Peg), "_poppedPegTrigger"); fieldInfo?.SetValue(peg, true); fieldInfo2?.SetValue(peg, true); object? obj = fieldInfo3?.GetValue(peg); MeshRenderer val = (MeshRenderer)((obj is MeshRenderer) ? obj : null); if ((Object)(object)val == (Object)null) { return; } object? obj2 = fieldInfo7?.GetValue(peg); Collider2D val2 = (Collider2D)((obj2 is Collider2D) ? obj2 : null); object? obj3 = (((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled) ? fieldInfo6 : fieldInfo5)?.GetValue(peg); Material val3 = (Material)((obj3 is Material) ? obj3 : null); if ((Object)(object)val3 != (Object)null) { ((Renderer)val).material = val3; } object obj4 = fieldInfo4?.GetValue(peg); if (obj4 != null) { FieldInfo field = obj4.GetType().GetField("Hit"); if (field != null && (Object)(object)((Renderer)val).material != (Object)null) { Color color = (Color)field.GetValue(obj4); ((Renderer)val).material.color = color; } } } catch { } } } public class MainThreadDispatcher : MonoBehaviour { private readonly ConcurrentQueue _queue = new ConcurrentQueue(); private float _heartbeatTimer; private int _heartbeatCount; public static MainThreadDispatcher Instance { get; private set; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { ManualLogSource logger = MultiplayerPlugin.Logger; if (logger != null) { logger.LogWarning((object)"[MainThreadDispatcher] Duplicate detected — destroying old instance"); } Object.Destroy((Object)(object)((Component)Instance).gameObject); } Instance = this; _heartbeatCount = 0; ManualLogSource logger2 = MultiplayerPlugin.Logger; if (logger2 != null) { logger2.LogInfo((object)"[MainThreadDispatcher] Awake — Instance set, heartbeat will auto-start"); } } public void Enqueue(Action action) { _queue.Enqueue(action); } private void Update() { Action result; while (_queue.TryDequeue(out result)) { result(); } RunHeartbeat(); } private void RunHeartbeat() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 BattleState currentBattleState = BattleController.CurrentBattleState; bool flag = (int)currentBattleState == 3 || (int)currentBattleState == 9; float num = (flag ? 1f : 2f); _heartbeatTimer += Time.unscaledDeltaTime; if (_heartbeatTimer < num) { return; } _heartbeatTimer = 0f; try { IServiceContainer services = MultiplayerPlugin.Services; if (services != null && services.TryResolve(out var instance) && instance.IsHosting && services.TryResolve(out var instance2)) { _heartbeatCount++; string trigger = (flag ? $"HEARTBEAT#{_heartbeatCount}(shot)" : $"HEARTBEAT#{_heartbeatCount}"); instance2.SyncAll(trigger); } } catch (Exception ex) { ManualLogSource logger = MultiplayerPlugin.Logger; if (logger != null) { logger.LogWarning((object)$"[HEARTBEAT#{_heartbeatCount}] Exception: {ex.Message}"); } } } } public class OrbIdentifier { private readonly Dictionary _guidToOrb = new Dictionary(); private readonly Dictionary _orbToGuid = new Dictionary(); private static ManualLogSource Log => MultiplayerPlugin.Logger; public int Count => _guidToOrb.Count; public string GetOrAssignGuid(GameObject orb) { if ((Object)(object)orb == (Object)null) { return "null"; } if (_orbToGuid.TryGetValue(orb, out var value)) { return value; } string text = Guid.NewGuid().ToString("N").Substring(0, 12); _guidToOrb[text] = orb; _orbToGuid[orb] = text; return text; } public void Register(GameObject orb, string guid) { if (!((Object)(object)orb == (Object)null) && !string.IsNullOrEmpty(guid)) { if (_guidToOrb.TryGetValue(guid, out var value) && (Object)(object)value != (Object)(object)orb) { _orbToGuid.Remove(value); } if (_orbToGuid.TryGetValue(orb, out var value2) && value2 != guid) { _guidToOrb.Remove(value2); } _guidToOrb[guid] = orb; _orbToGuid[orb] = guid; } } public GameObject Find(string guid) { if (string.IsNullOrEmpty(guid)) { return null; } if (_guidToOrb.TryGetValue(guid, out var value) && (Object)(object)value != (Object)null) { return value; } if ((Object)(object)value == (Object)null && _guidToOrb.ContainsKey(guid)) { _guidToOrb.Remove(guid); } return null; } public string GetGuid(GameObject orb) { if ((Object)(object)orb == (Object)null) { return null; } if (!_orbToGuid.TryGetValue(orb, out var value)) { return null; } return value; } public string GetId(GameObject ball) { if ((Object)(object)ball == (Object)null) { return "unknown"; } Attack component = ball.GetComponent(); if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.locNameString)) { return component.locNameString; } return ((Object)ball).name; } public int GetLevel(GameObject ball) { if ((Object)(object)ball == (Object)null) { return 0; } return ball.GetComponent()?.Level ?? 0; } public void Clear() { int count = _guidToOrb.Count; _guidToOrb.Clear(); _orbToGuid.Clear(); if (count > 0) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[OrbGUID] Cleared {count} entries"); } } } } public static class PatchValidator { public static List FindMissingPatchTargets(ManualLogSource log) { List list = new List(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); Type[] array; try { array = executingAssembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { array = ex.Types.Where((Type t) => t != null).ToArray(); foreach (Exception item in ex.LoaderExceptions?.Where((Exception e) => e != null).Distinct() ?? Array.Empty()) { string text = item.Message ?? "Unknown type load error"; if (log != null) { log.LogWarning((object)("[PatchValidator] Type load failed: " + text)); } list.Add(text); } } Type[] array2 = array; foreach (Type type in array2) { try { HarmonyPatch[] array3 = type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Cast().ToArray(); if (array3.Length == 0) { continue; } Type type2 = null; string text2 = null; HarmonyPatch[] array4 = array3; foreach (HarmonyPatch val in array4) { if (((HarmonyAttribute)val).info.declaringType != null) { type2 = ((HarmonyAttribute)val).info.declaringType; } if (((HarmonyAttribute)val).info.methodName != null) { text2 = ((HarmonyAttribute)val).info.methodName; } } if (type2 != null && text2 != null && !HasMember(type2, text2)) { list.Add(type2.Name + "." + text2); } MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); for (int j = 0; j < methods.Length; j++) { HarmonyPatch[] array5 = methods[j].GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Cast().ToArray(); if (array5.Length == 0) { continue; } Type type3 = type2; string text3 = text2; array4 = array5; foreach (HarmonyPatch val2 in array4) { if (((HarmonyAttribute)val2).info.declaringType != null) { type3 = ((HarmonyAttribute)val2).info.declaringType; } if (((HarmonyAttribute)val2).info.methodName != null) { text3 = ((HarmonyAttribute)val2).info.methodName; } } if (type3 != null && text3 != null && !HasMember(type3, text3)) { list.Add(type3.Name + "." + text3); } } } catch { } } return list.Distinct().ToList(); } private static bool HasMember(Type type, string name) { return type.GetMember(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Length != 0; } } public class PegIdentifier { private readonly Dictionary _guidToPeg = new Dictionary(); private readonly Dictionary _pegToGuid = new Dictionary(); private static ManualLogSource Log => MultiplayerPlugin.Logger; public int Count => _guidToPeg.Count; public string GetOrAssignGuid(Peg peg) { if ((Object)(object)peg == (Object)null) { return "null"; } if (_pegToGuid.TryGetValue(peg, out var value)) { return value; } string text = Guid.NewGuid().ToString("N").Substring(0, 12); _guidToPeg[text] = peg; _pegToGuid[peg] = text; return text; } public void Register(Peg peg, string guid) { if (!((Object)(object)peg == (Object)null) && !string.IsNullOrEmpty(guid)) { if (_guidToPeg.TryGetValue(guid, out var value) && (Object)(object)value != (Object)(object)peg) { _pegToGuid.Remove(value); } if (_pegToGuid.TryGetValue(peg, out var value2) && value2 != guid) { _guidToPeg.Remove(value2); } _guidToPeg[guid] = peg; _pegToGuid[peg] = guid; } } public Peg Find(string guid) { if (string.IsNullOrEmpty(guid)) { return null; } if (_guidToPeg.TryGetValue(guid, out var value) && (Object)(object)value != (Object)null) { return value; } if ((Object)(object)value == (Object)null && _guidToPeg.ContainsKey(guid)) { _guidToPeg.Remove(guid); } return null; } public string GetGuid(Peg peg) { if ((Object)(object)peg == (Object)null) { return null; } if (!_pegToGuid.TryGetValue(peg, out var value)) { return null; } return value; } public void Clear() { int count = _guidToPeg.Count; _guidToPeg.Clear(); _pegToGuid.Clear(); if (count > 0) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[PegGUID] Cleared {count} entries"); } } } public void DumpState(string trigger) { //IL_0080: 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_00ab: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[PegGUID] === DUMP ({trigger}) {_guidToPeg.Count} entries ==="); } int num = 0; foreach (KeyValuePair item in _guidToPeg) { Peg value = item.Value; if ((Object)(object)value != (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)$"[PegGUID] {item.Key} → type={value.pegType} pos=({((Component)value).transform.position.x:F2},{((Component)value).transform.position.y:F2}) active={((Component)value).gameObject.activeSelf}"); } } else { ManualLogSource log3 = Log; if (log3 != null) { log3.LogInfo((object)("[PegGUID] " + item.Key + " → DESTROYED")); } } if (++num >= 20) { ManualLogSource log4 = Log; if (log4 != null) { log4.LogInfo((object)$"[PegGUID] ... and {_guidToPeg.Count - num} more"); } break; } } } } public sealed class VersionChecker { private readonly ManualLogSource _log; public string CompiledGameVersion => "2.0.12"; public string ModVersion => "0.1.10"; public string RuntimeGameVersion { get; private set; } public bool IsVersionMatch { get; private set; } public VersionChecker(ManualLogSource log) { _log = log; } public void Check() { RuntimeGameVersion = Application.version ?? "unknown"; IsVersionMatch = RuntimeGameVersion == CompiledGameVersion; _log.LogInfo((object)("Mod version: " + ModVersion)); _log.LogInfo((object)("Compiled against Peglin: " + CompiledGameVersion)); _log.LogInfo((object)("Running Peglin: " + RuntimeGameVersion)); if (!IsVersionMatch) { _log.LogWarning((object)"========================================"); _log.LogWarning((object)"GAME VERSION MISMATCH"); _log.LogWarning((object)(" Mod compiled for: " + CompiledGameVersion)); _log.LogWarning((object)(" Game running: " + RuntimeGameVersion)); _log.LogWarning((object)" Some features may not work correctly."); _log.LogWarning((object)"========================================"); } } } } namespace Multipeglin.UI { public sealed class ClientRelicChoiceApplier : MonoBehaviour { } public static class CoopNavigateSlotPainter { private static readonly Color WinnerColor = new Color(0.25f, 0.85f, 0.25f, 1f); private static readonly Color LoserColor = new Color(0.85f, 0.2f, 0.2f, 1f); private static readonly Color ZeroVoteColor = new Color(0.95f, 0.85f, 0.15f, 1f); private static List _lastTally; private static int _lastChildCount = -1; public static void Tick() { if (!CoopNavigateState.PhaseActive) { _lastTally = null; _lastChildCount = -1; return; } List voteCounts = CoopNavigateState.VoteCounts; if (voteCounts == null || voteCounts.Count == 0 || !TallyChanged(voteCounts, CoopNavigateState.ChildNodeCount)) { return; } _lastTally = new List(voteCounts); _lastChildCount = CoopNavigateState.ChildNodeCount; try { if (CoopNavigateState.Source == "nav_only") { PaintNavOnly(voteCounts, CoopNavigateState.ChildNodeCount); } else { PaintPostBattle(voteCounts, CoopNavigateState.ChildNodeCount); } } catch (Exception ex) { ManualLogSource logger = MultiplayerPlugin.Logger; if (logger != null) { logger.LogWarning((object)("[CoopNavigate] Slot paint failed: " + ex.Message)); } } } private static bool TallyChanged(List votes, int childCount) { if (_lastTally == null || _lastChildCount != childCount || _lastTally.Count != votes.Count) { return true; } for (int i = 0; i < votes.Count; i++) { if (_lastTally[i] != votes[i]) { return true; } } return false; } private static void PaintPostBattle(List votes, int childCount) { //IL_00d4: 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_00dc: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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) PostBattleController[] array = Resources.FindObjectsOfTypeAll(); PostBattleController val = null; PostBattleController[] array2 = array; foreach (PostBattleController val2 in array2) { if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && ((Component)val2).gameObject.activeInHierarchy) { val = val2; break; } } if (!((Object)(object)val == (Object)null)) { object? obj = AccessTools.Field(typeof(PostBattleController), "_leftSlotManager")?.GetValue(val); SlotManager slot = (SlotManager)((obj is SlotManager) ? obj : null); object? obj2 = AccessTools.Field(typeof(PostBattleController), "_centerSlotManager")?.GetValue(val); SlotManager slot2 = (SlotManager)((obj2 is SlotManager) ? obj2 : null); object? obj3 = AccessTools.Field(typeof(PostBattleController), "_rightSlotManager")?.GetValue(val); SlotManager slot3 = (SlotManager)((obj3 is SlotManager) ? obj3 : null); switch (childCount) { case 1: { Color color = ColorFor(votes, 0); ApplyColor(slot, color); ApplyColor(slot2, color); ApplyColor(slot3, color); break; } case 2: ApplyColor(slot, ColorFor(votes, 0)); ApplyColor(slot3, ColorFor(votes, 1)); break; default: ApplyColor(slot, ColorFor(votes, 0)); ApplyColor(slot2, ColorFor(votes, 1)); ApplyColor(slot3, ColorFor(votes, childCount - 1)); break; } } } private static void PaintNavOnly(List votes, int childCount) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00dc: 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_00ec: Unknown result type (might be due to invalid IL or missing references) NavOnlyController[] array = Resources.FindObjectsOfTypeAll(); NavOnlyController val = null; NavOnlyController[] array2 = array; foreach (NavOnlyController val2 in array2) { if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null && ((Component)val2).gameObject.activeInHierarchy) { val = val2; break; } } if (!((Object)(object)val == (Object)null)) { object? obj = AccessTools.Field(typeof(NavOnlyController), "_leftSlotManager")?.GetValue(val); SlotManager slot = (SlotManager)((obj is SlotManager) ? obj : null); object? obj2 = AccessTools.Field(typeof(NavOnlyController), "_centreSlotManager")?.GetValue(val); SlotManager slot2 = (SlotManager)((obj2 is SlotManager) ? obj2 : null); object? obj3 = AccessTools.Field(typeof(NavOnlyController), "_rightSlotManager")?.GetValue(val); SlotManager slot3 = (SlotManager)((obj3 is SlotManager) ? obj3 : null); if (childCount == 1) { Color color = ColorFor(votes, 0); ApplyColor(slot, color); ApplyColor(slot2, color); ApplyColor(slot3, color); } else { ApplyColor(slot, ColorFor(votes, 0)); ApplyColor(slot3, ColorFor(votes, childCount - 1)); } } } private static Color ColorFor(List votes, int childIdx) { //IL_000d: 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_0057: 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) if (childIdx < 0 || childIdx >= votes.Count) { return ZeroVoteColor; } if (votes[childIdx] == 0) { return ZeroVoteColor; } int num = 0; for (int i = 0; i < votes.Count; i++) { if (votes[i] > num) { num = votes[i]; } } if (votes[childIdx] != num) { return LoserColor; } return WinnerColor; } private static void ApplyColor(SlotManager slot, Color color) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bd: 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_006f: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)slot == (Object)null) && ((Component)slot).gameObject.activeInHierarchy) { if ((Object)(object)slot.highlightHalf != (Object)null && ((Component)slot.highlightHalf).gameObject.activeInHierarchy) { Color color2 = slot.highlightHalf.color; slot.highlightHalf.color = new Color(color.r, color.g, color.b, (color2.a > 0f) ? color2.a : 1f); } if ((Object)(object)slot.highlightFull != (Object)null && ((Component)slot.highlightFull).gameObject.activeInHierarchy) { Color color3 = slot.highlightFull.color; slot.highlightFull.color = new Color(color.r, color.g, color.b, (color3.a > 0f) ? color3.a : 1f); } } } } public class CoopPlayerVisuals : MonoBehaviour { private class PlayerVisual { public int SlotIndex; public GameObject SpriteClone; public GameObject NamePanel; public TextMeshProUGUI NameText; public GameObject HpPanel; public TextMeshProUGUI HpText; public GameObject ArrowPanel; public TextMeshProUGUI ArrowText; public GameObject StatusIconContainer; public Dictionary StatusIcons = new Dictionary(); } private class StatusIconEntry { public GameObject Root; public Image IconImage; public TextMeshProUGUI IntensityText; public StatusIconHoverHandler Hover; } internal class StatusIconHoverHandler : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public StatusEffectType EffectType; public Vector3 WorldAnchor; private bool _tooltipShowing; public void OnPointerEnter(PointerEventData eventData) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (_tooltipShowing) { return; } TooltipManager instance = TooltipManager.Instance; if ((Object)(object)instance == (Object)null) { return; } try { instance.ShowTooltipStatusEffect(EffectType, WorldAnchor, new Vector3(1f, -1f), true, false); _tooltipShowing = true; } catch { } } public void OnPointerExit(PointerEventData eventData) { if (!_tooltipShowing) { return; } try { TooltipManager instance = TooltipManager.Instance; if (instance != null) { instance.HideTooltip(); } } catch { } _tooltipShowing = false; } private void OnDisable() { if (!_tooltipShowing) { return; } try { TooltipManager instance = TooltipManager.Instance; if (instance != null) { instance.HideTooltip(); } } catch { } _tooltipShowing = false; } } private static StatusEffectData _statusEffectData; private static bool _statusEffectDataSearched; private readonly List _visuals = new List(); private bool _inBattle; private string _lastScene = string.Empty; private GameObject _playerRef; private PlayerVisual _hostLabel; private bool _updateErrorLogged; private PlayerStatusEffectController _cachedStatusCtrl; private float _lastHeavyTickTime; private const float HeavyTickInterval = 0.2f; private readonly HashSet _activeTypesScratch = new HashSet(); private readonly List _removeScratch = new List(); private static GameObject _overlayCanvasObj; private static Canvas _overlayCanvas; private static RectTransform _overlayCanvasRect; private static TMP_FontAsset _gameFont; private static bool _gameFontSearched; private static TMP_FontAsset _numberFont; private static bool _numberFontSearched; private const int HostSlot = 0; private static readonly Color _nameColorBase = new Color(0.9f, 0.5f, 0.1f); private static readonly Color _nameColorActive = new Color(1f, 0.95f, 0.4f); private static readonly Color _arrowColorDim = new Color(1f, 0.9f, 0.3f, 0.5f); private static readonly Color _arrowColorBright = new Color(1f, 1f, 0.6f, 1f); private static readonly HashSet _loggedMissingClassSprite = new HashSet(); private static Sprite _cachedPeglinSprite; private static Sprite _cachedBalladinSprite; private static Sprite _cachedRoundrelSprite; private static Sprite _cachedSpinventorSprite; private static RuntimeAnimatorController _cachedPeglinCtrl; private static RuntimeAnimatorController _cachedBalladinCtrl; private static RuntimeAnimatorController _cachedRoundrelCtrl; private static RuntimeAnimatorController _cachedSpinventorCtrl; private static readonly HashSet _loggedMissingClassCtrl = new HashSet(); private static readonly HashSet _addressableAttempted = new HashSet(); private static ManualLogSource Log => MultiplayerPlugin.Logger; public static List LatestPlayerSummaries { get; set; } public static int LatestActiveSlot { get; set; } = -1; private void Update() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (name != _lastScene) { _lastScene = name; CleanupVisuals(); _playerRef = null; _inBattle = false; _updateErrorLogged = false; _cachedStatusCtrl = null; _lastHeavyTickTime = 0f; } IServiceContainer services = MultiplayerPlugin.Services; if (services == null || !services.TryResolve(out var instance) || (!instance.IsHosting && !instance.IsSpectating)) { return; } if (name != "Battle") { if (_inBattle) { CleanupVisuals(); _inBattle = false; } return; } _inBattle = true; float unscaledTime = Time.unscaledTime; if (unscaledTime - _lastHeavyTickTime >= 0.2f) { _lastHeavyTickTime = unscaledTime; HideNativeStatusIcons(); if (instance.IsHosting) { BuildHostSummaries(services); } } List latestPlayerSummaries = LatestPlayerSummaries; if (latestPlayerSummaries == null || latestPlayerSummaries.Count <= 1) { return; } if ((Object)(object)_playerRef == (Object)null) { _playerRef = GameObject.FindGameObjectWithTag("Player"); if ((Object)(object)_playerRef == (Object)null) { return; } } if (!((Object)(object)Camera.main == (Object)null)) { EnsureVisuals(latestPlayerSummaries); UpdateVisuals(latestPlayerSummaries); _updateErrorLogged = false; } } catch (Exception arg) { if (!_updateErrorLogged) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[CoopPlayerVisuals] Update error (will suppress repeats): {arg}"); } _updateErrorLogged = true; } } } private void BuildHostSummaries(IServiceContainer services) { //IL_028b: Unknown result type (might be due to invalid IL or missing references) try { if (!services.TryResolve(out var instance) || instance.TotalPlayerCount < 2) { return; } List list = null; try { PlayerStatusEffectController cachedStatusController = GetCachedStatusController(); if ((Object)(object)cachedStatusController != (Object)null && AccessTools.Field(typeof(PlayerStatusEffectController), "_statusEffects")?.GetValue(cachedStatusController) is IList list2 && list2.Count > 0) { list = new List(); foreach (object item in list2) { FieldInfo fieldInfo = AccessTools.Field(item.GetType(), "EffectType"); FieldInfo fieldInfo2 = AccessTools.Field(item.GetType(), "Intensity"); if (!(fieldInfo == null)) { object value = fieldInfo.GetValue(item); int num = (int)(fieldInfo2?.GetValue(item) ?? ((object)0)); if (num > 0) { list.Add(new StatusEffectEntry { EffectType = (int)value, EffectName = value.ToString(), Intensity = num }); } } } } } catch { } float num2 = -1f; float num3 = -1f; try { PlayerHealthController val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null) { num2 = val.CurrentHealth; num3 = val.MaxHealth; } } catch { } List list3 = new List(); foreach (KeyValuePair playerState in instance.PlayerStates) { CoopPlayerState value2 = playerState.Value; bool num4 = value2.SlotIndex == instance.ActivePlayerSlot; float currentHealth = ((num4 && num2 >= 0f) ? num2 : value2.CurrentHealth); float maxHealth = ((num4 && num3 > 0f) ? num3 : value2.MaxHealth); CoopPlayerSummary coopPlayerSummary = new CoopPlayerSummary { SlotIndex = value2.SlotIndex, PlayerName = value2.PlayerName, ChosenClass = value2.ChosenClass, CurrentHealth = currentHealth, MaxHealth = maxHealth, Gold = value2.Gold, HasShotThisRound = value2.HasShotThisRound }; if (num4 && list != null) { coopPlayerSummary.StatusEffects = list; } else if (value2.StatusEffects != null) { foreach (SerializedStatusEffect statusEffect in value2.StatusEffects) { List statusEffects = coopPlayerSummary.StatusEffects; StatusEffectEntry obj3 = new StatusEffectEntry { EffectType = statusEffect.EffectType }; StatusEffectType val2 = (StatusEffectType)statusEffect.EffectType; obj3.EffectName = ((object)(StatusEffectType)(ref val2)).ToString(); obj3.Intensity = statusEffect.Intensity; statusEffects.Add(obj3); } } list3.Add(coopPlayerSummary); } LatestPlayerSummaries = list3; LatestActiveSlot = instance.ActivePlayerSlot; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)("[CoopPlayerVisuals] BuildHostSummaries failed: " + ex.Message)); } } } private void OnDestroy() { CleanupVisuals(); } private void EnsureVisuals(List summaries) { int localSlotIndex = GetLocalSlotIndex(); CoopPlayerSummary coopPlayerSummary = null; foreach (CoopPlayerSummary summary in summaries) { if (summary.SlotIndex == 0) { coopPlayerSummary = summary; break; } } for (int num = _visuals.Count - 1; num >= 0; num--) { PlayerVisual playerVisual = _visuals[num]; bool flag = false; foreach (CoopPlayerSummary summary2 in summaries) { if (summary2.SlotIndex == playerVisual.SlotIndex) { flag = true; break; } } if (!flag || (Object)(object)playerVisual.SpriteClone == (Object)null || playerVisual.SlotIndex == 0) { DestroyVisual(playerVisual); _visuals.RemoveAt(num); } } if (_hostLabel != null && (Object)(object)_hostLabel.NamePanel == (Object)null) { _hostLabel = null; } if (_hostLabel == null && (Object)(object)_playerRef != (Object)null && coopPlayerSummary != null) { _hostLabel = CreatePlayerLabels(coopPlayerSummary, null); } if (localSlotIndex != 0 && coopPlayerSummary != null && (Object)(object)_playerRef != (Object)null) { ApplyHostClassToPlayerRef(coopPlayerSummary.ChosenClass); } foreach (CoopPlayerSummary summary3 in summaries) { if (summary3.SlotIndex == 0) { continue; } bool flag2 = false; foreach (PlayerVisual visual in _visuals) { if (visual.SlotIndex == summary3.SlotIndex) { flag2 = true; break; } } if (!flag2) { PlayerVisual playerVisual2 = CreatePlayerVisual(summary3); if (playerVisual2 != null) { _visuals.Add(playerVisual2); } } } } private static int GetLocalSlotIndex() { try { return CoopSlotHelper.GetLocalSlotIndex(MultiplayerPlugin.Services); } catch { return -1; } } private void EnsureOverlayCanvas() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_overlayCanvasObj != (Object)null)) { _overlayCanvasObj = new GameObject("CoopPlayerLabelsOverlay"); Object.DontDestroyOnLoad((Object)(object)_overlayCanvasObj); _overlayCanvas = _overlayCanvasObj.AddComponent(); _overlayCanvas.renderMode = (RenderMode)0; _overlayCanvas.sortingOrder = 9000; CanvasScaler obj = _overlayCanvasObj.AddComponent(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 0.5f; _overlayCanvasObj.AddComponent(); _overlayCanvasRect = _overlayCanvasObj.GetComponent(); } } private static TMP_FontAsset GetGameFont() { if (_gameFontSearched) { return _gameFont; } _gameFontSearched = true; try { TextMeshProUGUI[] array = Object.FindObjectsOfType(); foreach (TextMeshProUGUI val in array) { if ((Object)(object)((TMP_Text)val).font != (Object)null) { _gameFont = ((TMP_Text)val).font; break; } } } catch { } return _gameFont; } private static TMP_FontAsset GetStatusEffectNumberFont() { if (_numberFontSearched) { return _numberFont ?? GetGameFont(); } _numberFontSearched = true; try { FieldInfo fieldInfo = AccessTools.Field(typeof(StatusEffectIcon), "_intensityText"); if (fieldInfo != null) { StatusEffectIcon[] array = Resources.FindObjectsOfTypeAll(); foreach (StatusEffectIcon val in array) { if (!((Object)(object)val == (Object)null)) { object? value = fieldInfo.GetValue(val); TextMeshProUGUI val2 = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null); if ((Object)(object)((val2 != null) ? ((TMP_Text)val2).font : null) != (Object)null) { _numberFont = ((TMP_Text)val2).font; break; } } } } } catch { } return _numberFont ?? GetGameFont(); } private static string FormatName(string name, int slot) { if (string.IsNullOrEmpty(name)) { name = $"P{slot}"; } if (name.Length > 14) { name = name.Substring(0, 14); } if (name.Length > 7) { name = name.Substring(0, 7) + "\n" + name.Substring(7); } return name; } private GameObject CreateTextPanel(string goName, float width, float height, string text, float fontSize, Color textColor, Color bgColor, out TextMeshProUGUI tmpText) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_00c9: 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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) EnsureOverlayCanvas(); GameObject val = new GameObject(goName); val.transform.SetParent(_overlayCanvasObj.transform, false); RectTransform obj = val.AddComponent(); obj.sizeDelta = new Vector2(width, height); obj.pivot = new Vector2(0.5f, 0.5f); Image obj2 = val.AddComponent(); ((Graphic)obj2).color = bgColor; ((Graphic)obj2).raycastTarget = false; GameObject val2 = new GameObject("Text"); val2.transform.SetParent(val.transform, false); tmpText = val2.AddComponent(); ((TMP_Text)tmpText).text = text; ((TMP_Text)tmpText).fontSize = fontSize; ((TMP_Text)tmpText).fontStyle = (FontStyles)1; TMP_FontAsset gameFont = GetGameFont(); if ((Object)(object)gameFont != (Object)null) { ((TMP_Text)tmpText).font = gameFont; } ((TMP_Text)tmpText).alignment = (TextAlignmentOptions)514; ((Graphic)tmpText).color = textColor; try { ((TMP_Text)tmpText).outlineWidth = 0.3f; } catch { } try { ((TMP_Text)tmpText).outlineColor = Color32.op_Implicit(Color.black); } catch { } ((TMP_Text)tmpText).enableWordWrapping = false; ((TMP_Text)tmpText).overflowMode = (TextOverflowModes)0; ((TMP_Text)tmpText).lineSpacing = -25f; ((Graphic)tmpText).raycastTarget = false; RectTransform rectTransform = ((TMP_Text)tmpText).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; return val; } private PlayerVisual CreatePlayerLabels(CoopPlayerSummary summary, GameObject spriteClone) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) try { Color textColor = default(Color); ((Color)(ref textColor))..ctor(0.9f, 0.5f, 0.1f); Color textColor2 = default(Color); ((Color)(ref textColor2))..ctor(0.6f, 1f, 0.6f); Color textColor3 = default(Color); ((Color)(ref textColor3))..ctor(1f, 0.9f, 0.3f); Color bgColor = default(Color); ((Color)(ref bgColor))..ctor(0f, 0f, 0f, 0.3f); string text = FormatName(summary.PlayerName, summary.SlotIndex); bool flag = text.Contains("\n"); TextMeshProUGUI tmpText; GameObject namePanel = CreateTextPanel($"CoopName_Slot{summary.SlotIndex}", 187f, flag ? 80 : 50, text, 45f, textColor, bgColor, out tmpText); TextMeshProUGUI tmpText2; GameObject hpPanel = CreateTextPanel($"CoopHP_Slot{summary.SlotIndex}", 160f, 45f, $"{summary.CurrentHealth:F0}/{summary.MaxHealth:F0}", 38f, textColor2, bgColor, out tmpText2); TextMeshProUGUI tmpText3; GameObject val = CreateTextPanel($"CoopArrow_Slot{summary.SlotIndex}", 80f, 100f, "◀", 64f, textColor3, new Color(0f, 0f, 0f, 0f), out tmpText3); val.SetActive(false); EnsureOverlayCanvas(); GameObject val2 = new GameObject($"CoopStatusIcons_Slot{summary.SlotIndex}"); val2.transform.SetParent(_overlayCanvasObj.transform, false); RectTransform obj = val2.AddComponent(); obj.sizeDelta = new Vector2(380f, 56f); obj.pivot = new Vector2(0.5f, 0.5f); HorizontalLayoutGroup obj2 = val2.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 6f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; val2.SetActive(false); return new PlayerVisual { SlotIndex = summary.SlotIndex, SpriteClone = spriteClone, NamePanel = namePanel, NameText = tmpText, HpPanel = hpPanel, HpText = tmpText2, ArrowPanel = val, ArrowText = tmpText3, StatusIconContainer = val2 }; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogError((object)$"[CoopPlayerVisuals] CreatePlayerLabels failed for slot {summary.SlotIndex}: {ex.Message}"); } return null; } } private PlayerVisual CreatePlayerVisual(CoopPlayerSummary summary) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_003d: 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) if ((Object)(object)_playerRef == (Object)null) { return null; } try { GameObject val = new GameObject($"CoopPlayer_Slot{summary.SlotIndex}"); val.transform.position = _playerRef.transform.position; val.layer = _playerRef.layer; SpriteRenderer val2 = FindPlayerSpriteRenderer(); if ((Object)(object)val2 != (Object)null) { SpriteRenderer obj = val.AddComponent(); Sprite val3 = (obj.sprite = GetClassBaseSprite(summary.ChosenClass)); if ((Object)(object)val3 == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[CoopPlayerVisuals] GetClassBaseSprite returned null for slot {summary.SlotIndex} class {summary.ChosenClass}"); } } ((Renderer)obj).material = ((Renderer)val2).material; ((Renderer)obj).sortingLayerID = ((Renderer)val2).sortingLayerID; ((Renderer)obj).sortingOrder = ((Renderer)val2).sortingOrder - 1; obj.color = GetSlotColor(summary.SlotIndex); obj.flipX = val2.flipX; obj.flipY = val2.flipY; Animator val4 = val.AddComponent(); RuntimeAnimatorController classAnimationController = GetClassAnimationController(summary.ChosenClass); if ((Object)(object)classAnimationController != (Object)null) { val4.runtimeAnimatorController = classAnimationController; } } else { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)$"[CoopPlayerVisuals] No SpriteRenderer found on _playerRef for slot {summary.SlotIndex}"); } } return CreatePlayerLabels(summary, val); } catch (Exception ex) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogError((object)$"[CoopPlayerVisuals] Failed to create visual for slot {summary.SlotIndex}: {ex.Message}"); } return null; } } private SpriteRenderer FindPlayerSpriteRenderer() { if ((Object)(object)_playerRef == (Object)null) { return null; } SpriteRenderer component = _playerRef.GetComponent(); if ((Object)(object)component != (Object)null) { return component; } return _playerRef.GetComponentInChildren(true); } private void ApplyHostClassToPlayerRef(int hostClass) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected I4, but got Unknown try { SpriteRenderer val = FindPlayerSpriteRenderer(); PeglinClassAnimationSwitcher val2 = FindClassAnimationSwitcher(); if (!((Object)(object)val2 == (Object)null)) { Class val3 = (Class)hostClass; Sprite val4; RuntimeAnimatorController val5; switch (val3 - 1) { case 0: val4 = val2.balladinBaseSprite; val5 = val2.balladinAnimationController; break; case 1: val4 = val2.roundrelBaseSprite; val5 = val2.roundrelAnimationController; break; case 2: val4 = val2.spinventorBaseSprite; val5 = val2.spinventorAnimationController; break; default: val4 = val2.peglinBaseSprite; val5 = val2.peglinAnimationController; break; } Animator component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)val5 != (Object)null && (Object)(object)component.runtimeAnimatorController != (Object)(object)val5) { component.runtimeAnimatorController = val5; } if ((Object)(object)val != (Object)null && (Object)(object)val4 != (Object)null && (Object)(object)val.sprite != (Object)(object)val4) { val.sprite = val4; } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[CoopPlayerVisuals] ApplyHostClassToPlayerRef failed: " + ex.Message)); } } } private static PeglinClassAnimationSwitcher FindClassAnimationSwitcher() { try { GameObject val = GameObject.FindGameObjectWithTag("Player"); if ((Object)(object)val != (Object)null) { PeglinClassAnimationSwitcher val2 = val.GetComponentInChildren(true) ?? val.GetComponentInParent(); if ((Object)(object)val2 != (Object)null) { return val2; } } PeglinClassAnimationSwitcher val3 = Object.FindObjectOfType(); if ((Object)(object)val3 != (Object)null) { return val3; } PeglinClassAnimationSwitcher[] array = Resources.FindObjectsOfTypeAll(); if (array != null && array.Length != 0) { return array[0]; } } catch { } return null; } private void UpdateVisuals(List summaries) { //IL_002a: 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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_playerRef == (Object)null) { return; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } Vector3 position = _playerRef.transform.position; int latestActiveSlot = LatestActiveSlot; try { float num = ((latestActiveSlot == 0) ? 1.15f : 1f); _playerRef.transform.localScale = Vector3.Lerp(_playerRef.transform.localScale, Vector3.one * num, Time.deltaTime * 5f); } catch { } if (_hostLabel != null) { CoopPlayerSummary coopPlayerSummary = null; foreach (CoopPlayerSummary summary in summaries) { if (summary.SlotIndex == 0) { coopPlayerSummary = summary; break; } } if (coopPlayerSummary != null) { UpdatePlayerLabel(_hostLabel, coopPlayerSummary, position, latestActiveSlot, main); } } Vector3 val = default(Vector3); foreach (PlayerVisual visual in _visuals) { if ((Object)(object)visual.SpriteClone == (Object)null) { continue; } CoopPlayerSummary coopPlayerSummary2 = null; foreach (CoopPlayerSummary summary2 in summaries) { if (summary2.SlotIndex == visual.SlotIndex) { coopPlayerSummary2 = summary2; break; } } if (coopPlayerSummary2 == null) { continue; } ((Vector3)(ref val))..ctor(-2.5f * (float)visual.SlotIndex, -0.2f * (float)visual.SlotIndex, 0f); visual.SpriteClone.transform.position = position + val; Vector3 position2 = visual.SpriteClone.transform.position; UpdatePlayerLabel(visual, coopPlayerSummary2, position2, latestActiveSlot, main); float num2 = ((latestActiveSlot == visual.SlotIndex) ? 1.15f : 1f); visual.SpriteClone.transform.localScale = Vector3.Lerp(visual.SpriteClone.transform.localScale, Vector3.one * num2, Time.deltaTime * 5f); SpriteRenderer component = visual.SpriteClone.GetComponent(); if ((Object)(object)component != (Object)null) { if ((Object)(object)component.sprite == (Object)null) { Sprite classBaseSprite = GetClassBaseSprite(coopPlayerSummary2.ChosenClass); if ((Object)(object)classBaseSprite != (Object)null) { component.sprite = classBaseSprite; } } Color slotColor = GetSlotColor(visual.SlotIndex); component.color = ((latestActiveSlot == visual.SlotIndex) ? Color.Lerp(component.color, Color.white, Time.deltaTime * 3f) : Color.Lerp(component.color, slotColor, Time.deltaTime * 3f)); } Animator component2 = visual.SpriteClone.GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.runtimeAnimatorController == (Object)null) { RuntimeAnimatorController classAnimationController = GetClassAnimationController(coopPlayerSummary2.ChosenClass); if ((Object)(object)classAnimationController != (Object)null) { component2.runtimeAnimatorController = classAnimationController; } } } } private void UpdatePlayerLabel(PlayerVisual visual, CoopPlayerSummary summary, Vector3 charPos, int activeSlot, Camera cam) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) if (visual == null || (Object)(object)cam == (Object)null) { return; } if ((Object)(object)visual.HpText != (Object)null) { ((TMP_Text)visual.HpText).text = $"{summary.CurrentHealth:F0}/{summary.MaxHealth:F0}"; } if ((Object)(object)visual.NameText != (Object)null) { ((TMP_Text)visual.NameText).text = FormatName(summary.PlayerName, summary.SlotIndex); } PositionPanelAtWorld(visual.NamePanel, charPos + new Vector3(0f, 2f, 0f), cam); PositionPanelAtWorld(visual.HpPanel, charPos + new Vector3(0f, -0.6f, 0f), cam); bool flag = activeSlot == visual.SlotIndex; if ((Object)(object)visual.NameText != (Object)null) { if (flag) { float num = (Mathf.Sin(Time.unscaledTime * 3f) + 1f) * 0.5f; ((Graphic)visual.NameText).color = Color.Lerp(_nameColorBase, _nameColorActive, num); } else { ((Graphic)visual.NameText).color = _nameColorBase; } } if ((Object)(object)visual.ArrowPanel != (Object)null) { visual.ArrowPanel.SetActive(flag); if (flag) { PositionPanelAtWorld(visual.ArrowPanel, charPos + new Vector3(1f, 0.5f, 0f), cam); float num2 = (Mathf.Sin(Time.unscaledTime * 4f) + 1f) * 0.5f; float num3 = Mathf.Lerp(0.85f, 1.15f, num2); visual.ArrowPanel.transform.localScale = new Vector3(num3, num3, 1f); if ((Object)(object)visual.ArrowText != (Object)null) { ((Graphic)visual.ArrowText).color = Color.Lerp(_arrowColorDim, _arrowColorBright, num2); } } } UpdateStatusIcons(visual, summary.StatusEffects, charPos, cam); } private void UpdateStatusIcons(PlayerVisual visual, List effects, Vector3 charPos, Camera cam) { //IL_024d: 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) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)visual.StatusIconContainer == (Object)null) { return; } bool flag = effects != null && effects.Count > 0; _activeTypesScratch.Clear(); _removeScratch.Clear(); if (flag) { foreach (StatusEffectEntry effect in effects) { if (effect.Intensity > 0) { _activeTypesScratch.Add(effect.EffectType); } } } foreach (KeyValuePair statusIcon in visual.StatusIcons) { if (_activeTypesScratch.Contains(statusIcon.Key)) { continue; } try { if ((Object)(object)statusIcon.Value.Root != (Object)null) { Object.Destroy((Object)(object)statusIcon.Value.Root); } } catch { } _removeScratch.Add(statusIcon.Key); } foreach (int item in _removeScratch) { visual.StatusIcons.Remove(item); } if (!flag) { visual.StatusIconContainer.SetActive(false); return; } foreach (StatusEffectEntry effect2 in effects) { if (effect2.Intensity <= 0) { continue; } if (visual.StatusIcons.TryGetValue(effect2.EffectType, out var value)) { if ((Object)(object)value.IntensityText != (Object)null) { ((TMP_Text)value.IntensityText).text = ((effect2.Intensity > 999) ? (effect2.Intensity / 1000 + "K") : effect2.Intensity.ToString()); } continue; } StatusIconEntry statusIconEntry = CreateStatusIcon(effect2.EffectType, effect2.Intensity, visual.StatusIconContainer.transform); if (statusIconEntry != null) { visual.StatusIcons[effect2.EffectType] = statusIconEntry; } } visual.StatusIconContainer.SetActive(true); PositionPanelAtWorld(visual.StatusIconContainer, charPos + new Vector3(0f, 2.9f, 0f), cam); Vector3 worldAnchor = charPos + new Vector3(0f, 2.2f, 0f); foreach (KeyValuePair statusIcon2 in visual.StatusIcons) { if ((Object)(object)statusIcon2.Value.Hover != (Object)null) { statusIcon2.Value.Hover.WorldAnchor = worldAnchor; } } } private StatusIconEntry CreateStatusIcon(int effectType, int intensity, Transform parent) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject($"StatusIcon_{effectType}", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(50f, 50f); } LayoutElement val2 = val.AddComponent(); if ((Object)(object)val2 != (Object)null) { val2.preferredWidth = 50f; val2.preferredHeight = 50f; } Image val3 = val.AddComponent(); if ((Object)(object)val3 != (Object)null) { Sprite statusEffectSprite = GetStatusEffectSprite(effectType); if ((Object)(object)statusEffectSprite != (Object)null) { val3.sprite = statusEffectSprite; val3.preserveAspect = true; } else { ((Graphic)val3).color = new Color(0.4f, 0.3f, 0.6f, 0.8f); } ((Graphic)val3).raycastTarget = true; } StatusIconHoverHandler statusIconHoverHandler = val.AddComponent(); statusIconHoverHandler.EffectType = (StatusEffectType)effectType; GameObject val4 = new GameObject("Intensity", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(val.transform, false); TextMeshProUGUI val5 = val4.AddComponent(); if ((Object)(object)val5 == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[CoopPlayerVisuals] AddComponent returned null for effect {effectType}"); } return new StatusIconEntry { Root = val, IconImage = val3, IntensityText = null }; } ((TMP_Text)val5).text = ((intensity > 999) ? (intensity / 1000 + "K") : intensity.ToString()); ((TMP_Text)val5).fontSize = 32f; ((TMP_Text)val5).fontStyle = (FontStyles)0; TMP_FontAsset statusEffectNumberFont = GetStatusEffectNumberFont(); if ((Object)(object)statusEffectNumberFont != (Object)null) { ((TMP_Text)val5).font = statusEffectNumberFont; } ((TMP_Text)val5).alignment = (TextAlignmentOptions)1028; ((Graphic)val5).color = Color.white; try { ((TMP_Text)val5).outlineWidth = 0.35f; } catch { } try { ((TMP_Text)val5).outlineColor = Color32.op_Implicit(Color.black); } catch { } ((TMP_Text)val5).enableWordWrapping = false; ((TMP_Text)val5).overflowMode = (TextOverflowModes)0; ((Graphic)val5).raycastTarget = false; RectTransform rectTransform = ((TMP_Text)val5).rectTransform; if ((Object)(object)rectTransform != (Object)null) { rectTransform.anchorMin = new Vector2(1f, 0f); rectTransform.anchorMax = new Vector2(1f, 0f); rectTransform.pivot = new Vector2(1f, 0f); rectTransform.sizeDelta = new Vector2(44f, 30f); rectTransform.anchoredPosition = new Vector2(8f, -6f); } return new StatusIconEntry { Root = val, IconImage = val3, IntensityText = val5, Hover = statusIconHoverHandler }; } catch (Exception arg) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)$"[CoopPlayerVisuals] CreateStatusIcon({effectType}, {intensity}) failed: {arg}"); } return null; } } private void HideNativeStatusIcons() { try { PlayerStatusEffectController cachedStatusController = GetCachedStatusController(); if (!((Object)(object)cachedStatusController == (Object)null)) { object? obj = AccessTools.Field(typeof(PlayerStatusEffectController), "_statusEffectUI")?.GetValue(cachedStatusController); StatusEffectIconManager val = (StatusEffectIconManager)((obj is StatusEffectIconManager) ? obj : null); if (!((Object)(object)val == (Object)null) && (Object)(object)val.horizontalContainer != (Object)null && ((Component)val.horizontalContainer).gameObject.activeSelf) { ((Component)val.horizontalContainer).gameObject.SetActive(false); } } } catch { } } private PlayerStatusEffectController GetCachedStatusController() { if ((Object)(object)_cachedStatusCtrl == (Object)null) { _cachedStatusCtrl = Object.FindObjectOfType(); } return _cachedStatusCtrl; } private static StatusEffectData GetStatusEffectData() { if (_statusEffectDataSearched) { return _statusEffectData; } _statusEffectDataSearched = true; try { StatusEffectData[] array = Resources.FindObjectsOfTypeAll(); if (array.Length != 0) { _statusEffectData = array[0]; } } catch { } return _statusEffectData; } private static Sprite GetStatusEffectSprite(int effectType) { StatusEffectData statusEffectData = GetStatusEffectData(); if ((Object)(object)statusEffectData == (Object)null) { return null; } return statusEffectData.GetStatusEffectIcon((StatusEffectType)effectType); } private void PositionPanelAtWorld(GameObject panel, Vector3 worldPos, Camera cam) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) if ((Object)(object)panel == (Object)null || (Object)(object)cam == (Object)null) { return; } Vector3 val = cam.WorldToScreenPoint(worldPos); if (val.z < 0f) { panel.SetActive(false); return; } if (!panel.activeSelf) { panel.SetActive(true); } RectTransform component = panel.GetComponent(); if (!((Object)(object)component == (Object)null)) { if ((Object)(object)_overlayCanvasRect != (Object)null) { Vector2 val2 = default(Vector2); RectTransformUtility.ScreenPointToLocalPointInRectangle(_overlayCanvasRect, Vector2.op_Implicit(val), (Camera)null, ref val2); ((Transform)component).localPosition = Vector2.op_Implicit(val2); } else { ((Transform)component).position = val; } } } private void CleanupVisuals() { foreach (PlayerVisual visual in _visuals) { DestroyVisual(visual); } _visuals.Clear(); if (_hostLabel != null) { DestroyPanels(_hostLabel); _hostLabel = null; } } private void DestroyVisual(PlayerVisual v) { try { if ((Object)(object)v.SpriteClone != (Object)null) { Object.Destroy((Object)(object)v.SpriteClone); } } catch { } DestroyPanels(v); } private void DestroyPanels(PlayerVisual v) { try { if ((Object)(object)v.NamePanel != (Object)null) { Object.Destroy((Object)(object)v.NamePanel); } } catch { } try { if ((Object)(object)v.HpPanel != (Object)null) { Object.Destroy((Object)(object)v.HpPanel); } } catch { } try { if ((Object)(object)v.ArrowPanel != (Object)null) { Object.Destroy((Object)(object)v.ArrowPanel); } } catch { } try { if ((Object)(object)v.StatusIconContainer != (Object)null) { Object.Destroy((Object)(object)v.StatusIconContainer); } } catch { } v.StatusIcons?.Clear(); } private static Color GetSlotColor(int slot) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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) return (Color)(slot switch { 1 => new Color(0.7f, 0.85f, 1f), 2 => new Color(1f, 0.8f, 0.7f), 3 => new Color(0.8f, 1f, 0.7f), _ => new Color(0.9f, 0.9f, 0.9f), }); } private static RuntimeAnimatorController GetClassAnimationController(int chosenClass) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected I4, but got Unknown try { RuntimeAnimatorController cachedController = GetCachedController(chosenClass); if ((Object)(object)cachedController != (Object)null) { return cachedController; } PeglinClassAnimationSwitcher[] array = Resources.FindObjectsOfTypeAll(); if (array != null) { PeglinClassAnimationSwitcher[] array2 = array; foreach (PeglinClassAnimationSwitcher val in array2) { if (!((Object)(object)val == (Object)null)) { if ((Object)(object)_cachedPeglinCtrl == (Object)null && (Object)(object)val.peglinAnimationController != (Object)null) { _cachedPeglinCtrl = val.peglinAnimationController; } if ((Object)(object)_cachedBalladinCtrl == (Object)null && (Object)(object)val.balladinAnimationController != (Object)null) { _cachedBalladinCtrl = val.balladinAnimationController; } if ((Object)(object)_cachedRoundrelCtrl == (Object)null && (Object)(object)val.roundrelAnimationController != (Object)null) { _cachedRoundrelCtrl = val.roundrelAnimationController; } if ((Object)(object)_cachedSpinventorCtrl == (Object)null && (Object)(object)val.spinventorAnimationController != (Object)null) { _cachedSpinventorCtrl = val.spinventorAnimationController; } } } } cachedController = GetCachedController(chosenClass); if ((Object)(object)cachedController != (Object)null) { return cachedController; } Class val2 = (Class)chosenClass; string value = (val2 - 1) switch { 0 => "balladin", 1 => "roundrel", 2 => "spinventor", _ => "peglin", }; RuntimeAnimatorController[] array3 = Resources.FindObjectsOfTypeAll(); if (array3 != null) { RuntimeAnimatorController[] array4 = array3; foreach (RuntimeAnimatorController val3 in array4) { if (!((Object)(object)val3 == (Object)null) && !string.IsNullOrEmpty(((Object)val3).name)) { string text = ((Object)val3).name.ToLowerInvariant(); if (text.Contains(value) && !text.Contains("peg_") && !text.Contains("bomb") && !text.Contains("slime")) { SetCachedController(chosenClass, val3); return val3; } } } } if (_loggedMissingClassCtrl.Add(chosenClass)) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[CoopPlayerVisuals] No animation controller for class {chosenClass} — clone will show static sprite"); } } return null; } catch { return null; } } private static RuntimeAnimatorController GetCachedController(int chosenClass) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown Class val = (Class)chosenClass; return (RuntimeAnimatorController)((val - 1) switch { 0 => _cachedBalladinCtrl, 1 => _cachedRoundrelCtrl, 2 => _cachedSpinventorCtrl, _ => _cachedPeglinCtrl, }); } private static void SetCachedController(int chosenClass, RuntimeAnimatorController ctrl) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown Class val = (Class)chosenClass; switch (val - 1) { case 0: _cachedBalladinCtrl = ctrl; break; case 1: _cachedRoundrelCtrl = ctrl; break; case 2: _cachedSpinventorCtrl = ctrl; break; default: _cachedPeglinCtrl = ctrl; break; } } private static Sprite GetClassBaseSprite(int chosenClass) { try { Sprite cachedSprite = GetCachedSprite(chosenClass); if ((Object)(object)cachedSprite != (Object)null) { return cachedSprite; } PeglinClassAnimationSwitcher[] array = Resources.FindObjectsOfTypeAll(); if (array != null) { PeglinClassAnimationSwitcher[] array2 = array; foreach (PeglinClassAnimationSwitcher val in array2) { if (!((Object)(object)val == (Object)null)) { if ((Object)(object)_cachedPeglinSprite == (Object)null && (Object)(object)val.peglinBaseSprite != (Object)null) { _cachedPeglinSprite = val.peglinBaseSprite; } if ((Object)(object)_cachedBalladinSprite == (Object)null && (Object)(object)val.balladinBaseSprite != (Object)null) { _cachedBalladinSprite = val.balladinBaseSprite; } if ((Object)(object)_cachedRoundrelSprite == (Object)null && (Object)(object)val.roundrelBaseSprite != (Object)null) { _cachedRoundrelSprite = val.roundrelBaseSprite; } if ((Object)(object)_cachedSpinventorSprite == (Object)null && (Object)(object)val.spinventorBaseSprite != (Object)null) { _cachedSpinventorSprite = val.spinventorBaseSprite; } } } } cachedSprite = GetCachedSprite(chosenClass); if ((Object)(object)cachedSprite != (Object)null) { return cachedSprite; } Sprite classBaseSpriteFromClassInfo = GetClassBaseSpriteFromClassInfo(chosenClass); if ((Object)(object)classBaseSpriteFromClassInfo != (Object)null) { SetCachedSprite(chosenClass, classBaseSpriteFromClassInfo); return classBaseSpriteFromClassInfo; } Sprite classBaseSpriteFromSelectableCharacter = GetClassBaseSpriteFromSelectableCharacter(chosenClass); if ((Object)(object)classBaseSpriteFromSelectableCharacter != (Object)null) { SetCachedSprite(chosenClass, classBaseSpriteFromSelectableCharacter); return classBaseSpriteFromSelectableCharacter; } Sprite classBaseSpriteFromAddressable = GetClassBaseSpriteFromAddressable(chosenClass); if ((Object)(object)classBaseSpriteFromAddressable != (Object)null) { SetCachedSprite(chosenClass, classBaseSpriteFromAddressable); return classBaseSpriteFromAddressable; } if (_loggedMissingClassSprite.Add(chosenClass)) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[CoopPlayerVisuals] No sprite for class {chosenClass} — switchers={((array != null) ? array.Length : 0)}, caches: P={(Object)(object)_cachedPeglinSprite != (Object)null} B={(Object)(object)_cachedBalladinSprite != (Object)null} R={(Object)(object)_cachedRoundrelSprite != (Object)null} S={(Object)(object)_cachedSpinventorSprite != (Object)null}"); } } return null; } catch { return null; } } private static Sprite GetCachedSprite(int chosenClass) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown Class val = (Class)chosenClass; return (Sprite)((val - 1) switch { 0 => _cachedBalladinSprite, 1 => _cachedRoundrelSprite, 2 => _cachedSpinventorSprite, _ => _cachedPeglinSprite, }); } private static void SetCachedSprite(int chosenClass, Sprite sprite) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown Class val = (Class)chosenClass; switch (val - 1) { case 0: _cachedBalladinSprite = sprite; break; case 1: _cachedRoundrelSprite = sprite; break; case 2: _cachedSpinventorSprite = sprite; break; default: _cachedPeglinSprite = sprite; break; } } private static Sprite GetClassBaseSpriteFromClassInfo(int chosenClass) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 try { ClassInfo[] array = Resources.FindObjectsOfTypeAll(); if (array == null) { return null; } ClassInfo[] array2 = array; foreach (ClassInfo val in array2) { if ((Object)(object)val != (Object)null && (int)val.characterClass == chosenClass && (Object)(object)val.classSprite != (Object)null) { return val.classSprite; } } } catch { } return null; } private static Sprite GetClassBaseSpriteFromSelectableCharacter(int chosenClass) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 try { SelectableCharacter[] array = Resources.FindObjectsOfTypeAll(); if (array == null) { return null; } SelectableCharacter[] array2 = array; foreach (SelectableCharacter val in array2) { if ((Object)(object)val != (Object)null && (int)val.characterClass == chosenClass && (Object)(object)val.idleSprite != (Object)null) { return val.idleSprite; } } } catch { } return null; } private static Sprite GetClassBaseSpriteFromAddressable(int chosenClass) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_00ab: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) try { if (!_addressableAttempted.Add(chosenClass)) { return null; } Class val = (Class)chosenClass; string[] array = (((int)val == 2) ? new string[1] { "Assets/Art/Peglin/Roundrel/Sprites/roundrel.png" } : (((int)val != 3) ? new string[0] : new string[1] { "Assets/Art/Peglin/Spinventor/spinventor.png" })); array = array; Rect val4 = default(Rect); foreach (string text in array) { Sprite val2 = null; try { val2 = Addressables.LoadAssetAsync((object)text).WaitForCompletion(); } catch { val2 = null; } if ((Object)(object)val2 != (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[CoopPlayerVisuals] Loaded class {chosenClass} sprite from Addressable '{text}'"); } return val2; } try { Texture2D val3 = Addressables.LoadAssetAsync((object)text).WaitForCompletion(); if (!((Object)(object)val3 != (Object)null)) { continue; } ((Rect)(ref val4))..ctor(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height); Sprite val5 = Sprite.Create(val3, val4, new Vector2(0.5f, 0.5f), 16f); if ((Object)(object)val5 != (Object)null) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)$"[CoopPlayerVisuals] Built class {chosenClass} sprite from Addressable Texture2D '{text}' (size={((Texture)val3).width}x{((Texture)val3).height})"); } return val5; } } catch { } } } catch (Exception ex) { ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)$"[CoopPlayerVisuals] Addressable sprite fallback failed for class {chosenClass}: {ex.Message}"); } } return null; } public static void Reset() { LatestPlayerSummaries = null; LatestActiveSlot = -1; _statusEffectDataSearched = false; _statusEffectData = null; _loggedMissingClassSprite.Clear(); _addressableAttempted.Clear(); _cachedPeglinSprite = (_cachedBalladinSprite = (_cachedRoundrelSprite = (_cachedSpinventorSprite = null))); _cachedPeglinCtrl = (_cachedBalladinCtrl = (_cachedRoundrelCtrl = (_cachedSpinventorCtrl = null))); _loggedMissingClassCtrl.Clear(); } } public class CoopRewardUI : MonoBehaviour { private enum DisplayState { Hidden, RelicChoices, RewardChoices, Waiting } private GameObject _canvasObj; private GameObject _overlayPanel; private TextMeshProUGUI _titleText; private TextMeshProUGUI _statusText; private GameObject _buttonContainer; private readonly List _buttons = new List(); private DisplayState _currentState; private int _displayedRelicCount; private int _displayedRewardCount; private string _lastSceneName; public const int FORCE_SKIP_SECONDS = 45; private float _hostWaitingStartTime = -1f; private string _hostWaitingPhaseKey; private GameObject _forceContinueButton; private GameObject _navForceButton; private float _navPhaseStartedAt = -1f; private GameObject _navWaitBanner; private TextMeshProUGUI _navWaitBannerText; private static ManualLogSource Log => MultiplayerPlugin.Logger; private void Start() { try { CreateUI(); } catch (Exception arg) { ManualLogSource log = Log; if (log != null) { log.LogError((object)$"[CoopRewardUI] Start failed: {arg}"); } } } private void CreateUI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_013d: 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) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) _canvasObj = new GameObject("CoopRewardCanvas"); Object.DontDestroyOnLoad((Object)(object)_canvasObj); Canvas obj = _canvasObj.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 200; CanvasScaler obj2 = _canvasObj.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; _canvasObj.AddComponent(); _overlayPanel = new GameObject("RewardOverlay"); _overlayPanel.transform.SetParent(_canvasObj.transform, false); ((Graphic)_overlayPanel.AddComponent()).color = new Color(0f, 0f, 0f, 0.88f); StretchFill(_overlayPanel.GetComponent()); GameObject val = new GameObject("Title"); val.transform.SetParent(_overlayPanel.transform, false); _titleText = val.AddComponent(); ((TMP_Text)_titleText).text = "Choose a Reward"; ((TMP_Text)_titleText).fontSize = 48f; ((TMP_Text)_titleText).alignment = (TextAlignmentOptions)514; ((Graphic)_titleText).color = Color.white; RectTransform rectTransform = ((TMP_Text)_titleText).rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 1f); rectTransform.anchorMax = new Vector2(0.5f, 1f); rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.anchoredPosition = new Vector2(0f, -40f); rectTransform.sizeDelta = new Vector2(800f, 64f); _buttonContainer = new GameObject("ButtonContainer"); _buttonContainer.transform.SetParent(_overlayPanel.transform, false); RectTransform obj3 = _buttonContainer.AddComponent(); obj3.anchorMin = new Vector2(0.5f, 0.5f); obj3.anchorMax = new Vector2(0.5f, 0.5f); obj3.pivot = new Vector2(0.5f, 0.5f); obj3.anchoredPosition = new Vector2(0f, 0f); obj3.sizeDelta = new Vector2(900f, 400f); GameObject val2 = new GameObject("StatusText"); val2.transform.SetParent(_overlayPanel.transform, false); _statusText = val2.AddComponent(); ((TMP_Text)_statusText).text = string.Empty; ((TMP_Text)_statusText).fontSize = 32f; ((TMP_Text)_statusText).alignment = (TextAlignmentOptions)514; ((Graphic)_statusText).color = new Color(0.8f, 0.8f, 0.3f); RectTransform rectTransform2 = ((TMP_Text)_statusText).rectTransform; rectTransform2.anchorMin = new Vector2(0.5f, 0f); rectTransform2.anchorMax = new Vector2(0.5f, 0f); rectTransform2.pivot = new Vector2(0.5f, 0f); rectTransform2.anchoredPosition = new Vector2(0f, 80f); rectTransform2.sizeDelta = new Vector2(800f, 48f); _overlayPanel.SetActive(false); CreateNavWaitBanner(); } private void CreateNavWaitBanner() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00b1: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_0142: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) _navWaitBanner = new GameObject("NavWaitBanner"); _navWaitBanner.transform.SetParent(_canvasObj.transform, false); Image obj = _navWaitBanner.AddComponent(); ((Graphic)obj).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)obj).raycastTarget = false; RectTransform component = _navWaitBanner.GetComponent(); component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, -24f); component.sizeDelta = new Vector2(720f, 60f); GameObject val = new GameObject("Text"); val.transform.SetParent(_navWaitBanner.transform, false); _navWaitBannerText = val.AddComponent(); ((TMP_Text)_navWaitBannerText).text = "Waiting for other players to navigate..."; ((TMP_Text)_navWaitBannerText).fontSize = 28f; ((TMP_Text)_navWaitBannerText).alignment = (TextAlignmentOptions)514; ((Graphic)_navWaitBannerText).color = new Color(1f, 0.92f, 0.6f); ((Graphic)_navWaitBannerText).raycastTarget = false; RectTransform rectTransform = ((TMP_Text)_navWaitBannerText).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = new Vector2(16f, 4f); rectTransform.offsetMax = new Vector2(-16f, -4f); _navWaitBanner.SetActive(false); } private void Update() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_overlayPanel == (Object)null) { return; } Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (_lastSceneName != null && _lastSceneName != name) { if (!(name == "Battle") && !(_lastSceneName == "Battle")) { switch (name) { case "ForestMap": case "CastleMap": case "MinesMap": goto IL_0094; } if (!(name == "CoreMap")) { goto IL_0103; } } goto IL_0094; } goto IL_0103; IL_0094: if (_currentState != 0) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[CoopRewardUI] Scene change " + _lastSceneName + " -> " + name + ", hiding overlay")); } HideOverlay(); CoopRewardState.Reset(); CoopNavigateState.Reset(); DestroyNavForceButton(); _navPhaseStartedAt = -1f; MultiplayerClientPatches.AllowNavigateLogic = false; } goto IL_0103; IL_0103: _lastSceneName = name; IServiceContainer services = MultiplayerPlugin.Services; if (services == null || !services.TryResolve(out var instance) || (!instance.IsHosting && !instance.IsSpectating)) { return; } TickNavigateStandaloneForce(instance); CoopNavigateResolver.TickWatchdog(); CoopWaitWatchdog.Tick(instance); CoopNavigateSlotPainter.Tick(); bool flag = CoopNavigateState.PhaseActive && CoopNavigateState.LocalVoteCast && !CoopNavigateState.Resolved; if (flag && !CoopRewardState.WaitingForOtherPlayers) { if (_currentState != 0) { HideOverlay(); } ShowNavWaitBanner(); TickHostForceContinue(); return; } HideNavWaitBanner(); if (CoopRewardState.AllChoicesComplete) { if (_currentState != 0) { HideOverlay(); CoopRewardState.Reset(); } return; } if (CoopRewardState.WaitingForOtherPlayers || flag) { if (_currentState != DisplayState.Waiting) { ShowWaiting(); } TickHostForceContinue(); return; } RelicChoicesEvent pendingRelicChoices = CoopRewardState.PendingRelicChoices; if (pendingRelicChoices?.Choices != null && pendingRelicChoices.Choices.Count > 0) { if (_currentState != DisplayState.RelicChoices || _displayedRelicCount != pendingRelicChoices.Choices.Count) { ShowRelicChoices(pendingRelicChoices); } } else if (_currentState != 0) { HideOverlay(); } } catch (Exception ex) { ManualLogSource log2 = Log; if (log2 != null) { log2.LogError((object)("[CoopRewardUI] Update error: " + ex.Message)); } } } private void ShowRelicChoices(RelicChoicesEvent choices) { //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018b: 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_01ba: Expected O, but got Unknown ClearButtons(); ((TMP_Text)_titleText).text = "Choose a Relic"; ((TMP_Text)_statusText).text = string.Empty; _overlayPanel.SetActive(true); _currentState = DisplayState.RelicChoices; _displayedRelicCount = choices.Choices.Count; float num = 340f; float num2 = 20f; float num3 = (0f - ((float)choices.Choices.Count * num + (float)(choices.Choices.Count - 1) * num2)) / 2f + num / 2f; for (int i = 0; i < choices.Choices.Count; i++) { RelicEntry relicEntry = choices.Choices[i]; float num4 = num3 + (float)i * (num + num2); string text = relicEntry.LocKey ?? string.Empty; try { if (!string.IsNullOrEmpty(text) && !text.Contains(" ")) { string translation = LocalizationManager.GetTranslation("Relics/" + text + "_desc", true, 0, true, false, (GameObject)null, (string)null, true); if (string.IsNullOrEmpty(translation)) { translation = LocalizationManager.GetTranslation(text, true, 0, true, false, (GameObject)null, (string)null, true); } if (!string.IsNullOrEmpty(translation)) { text = translation; } } } catch { } Button obj2 = CreateChoiceButton(_buttonContainer.transform, $"RelicBtn_{i}", relicEntry.EffectName ?? $"Relic {relicEntry.Effect}", text, new Color(0.25f, 0.2f, 0.45f), new Vector2(num4, 0f), new Vector2(num, 260f)); int capturedEffect = relicEntry.Effect; ((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate { OnRelicChosen(capturedEffect); }); } ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[CoopRewardUI] Showing {choices.Choices.Count} relic choices"); } } private void ShowRewardChoices(RewardChoicesEvent choices) { //IL_00ba: 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_00ff: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown ClearButtons(); ((TMP_Text)_titleText).text = "Choose a Reward"; ((TMP_Text)_statusText).text = string.Empty; _overlayPanel.SetActive(true); _currentState = DisplayState.RewardChoices; _displayedRewardCount = choices.Options.Count; float num = 240f; float num2 = 16f; float num3 = (0f - ((float)choices.Options.Count * num + (float)(choices.Options.Count - 1) * num2)) / 2f + num / 2f; for (int i = 0; i < choices.Options.Count; i++) { RewardOption rewardOption = choices.Options[i]; float num4 = num3 + (float)i * (num + num2); Color rewardColor = GetRewardColor(rewardOption.Type); Button obj = CreateChoiceButton(_buttonContainer.transform, $"RewardBtn_{i}", rewardOption.DisplayName ?? rewardOption.Type, rewardOption.Description ?? string.Empty, rewardColor, new Vector2(num4, 0f), new Vector2(num, 200f)); int capturedIndex = rewardOption.OptionIndex; ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { OnRewardChosen(capturedIndex); }); } ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"[CoopRewardUI] Showing {choices.Options.Count} reward choices"); } } private void ShowNavWaitBanner() { if (!((Object)(object)_navWaitBanner == (Object)null)) { if (!_navWaitBanner.activeSelf) { _navWaitBanner.SetActive(true); } if (Object.op_Implicit((Object)(object)_navWaitBannerText)) { ((TMP_Text)_navWaitBannerText).text = "Waiting for other players to navigate..."; } } } private void HideNavWaitBanner() { if ((Object)(object)_navWaitBanner != (Object)null && _navWaitBanner.activeSelf) { _navWaitBanner.SetActive(false); } } private void ShowWaiting() { ClearButtons(); IServiceContainer services = MultiplayerPlugin.Services; IMultiplayerMode instance; bool flag = services != null && services.TryResolve(out instance) && instance.IsHosting; if (CoopRewardState.ShopAwaitingHostNavigation || CoopRewardState.TextScenarioAwaitingHostNavigation || CoopRewardState.PegMinigameAwaitingHostNavigation) { ((TMP_Text)_titleText).text = "Waiting for other players to select the next stage..."; } else if (CoopRewardState.TreasureAwaitingHostNavigation) { ((TMP_Text)_titleText).text = "Waiting for other players..."; } else if (CoopRewardState.TextScenarioPhaseActive) { ((TMP_Text)_titleText).text = "Waiting for other players to finish the event..."; } else if (CoopRewardState.ShopPhaseActive) { ((TMP_Text)_titleText).text = "Waiting for other players to finish shopping..."; } else if (CoopRewardState.TreasurePhaseActive) { ((TMP_Text)_titleText).text = "Waiting for other players to choose a relic..."; } else if (CoopRewardState.PegMinigamePhaseActive) { ((TMP_Text)_titleText).text = "Waiting for other players to finish..."; } else if (CoopNavigateState.PhaseActive && CoopNavigateState.LocalVoteCast && !CoopNavigateState.Resolved) { ((TMP_Text)_titleText).text = "Waiting for other players to navigate..."; } else if (CoopRewardState.HostRelicSelectionActive) { ((TMP_Text)_titleText).text = (flag ? "Waiting for all players to choose their initial relic..." : "Other players are choosing their initial relics..."); } else if (CoopRewardState.ClientInNativeRewardPhase || CoopRewardState.HostRewardPhaseActive) { ((TMP_Text)_titleText).text = "Waiting for other players..."; } else { ((TMP_Text)_titleText).text = "Waiting..."; } ((TMP_Text)_statusText).text = string.Empty; _overlayPanel.SetActive(true); _currentState = DisplayState.Waiting; if (flag) { string text = ResolveHostWaitingPhase(); if (text != null) { if (_hostWaitingPhaseKey != text) { _hostWaitingPhaseKey = text; _hostWaitingStartTime = Time.unscaledTime; DestroyForceContinueButton(); } } else { ClearHostWaitingTimer(); } } else { ClearHostWaitingTimer(); } } private void HideOverlay() { ClearButtons(); DestroyForceContinueButton(); ClearHostWaitingTimer(); _overlayPanel.SetActive(false); HideNavWaitBanner(); _currentState = DisplayState.Hidden; _displayedRelicCount = 0; _displayedRewardCount = 0; } private static string ResolveHostWaitingPhase() { if (CoopRewardState.ShopPhaseActive && CoopRewardState.HostShopDone) { return "shop"; } if (CoopRewardState.TreasurePhaseActive && CoopRewardState.HostTreasureDone) { return "treasure"; } if (CoopRewardState.PegMinigamePhaseActive && CoopRewardState.HostPegMinigameDone) { return "peg_minigame"; } if (CoopRewardState.TextScenarioPhaseActive && CoopRewardState.HostTextScenarioDone) { return "text_scenario"; } if (CoopRewardState.HostRewardPhaseActive && CoopRewardState.HostRewardsDone) { return "post_battle"; } if (CoopRewardState.HostRelicSelectionActive && CoopRewardState.HostHasChosenRelic) { return "starting_relic"; } if (CoopNavigateState.PhaseActive && !CoopNavigateState.Resolved) { return "navigate"; } return null; } private void ClearHostWaitingTimer() { _hostWaitingStartTime = -1f; _hostWaitingPhaseKey = null; } private void DestroyForceContinueButton() { if ((Object)(object)_forceContinueButton != (Object)null) { Object.Destroy((Object)(object)_forceContinueButton); _forceContinueButton = null; } } private void TickHostForceContinue() { if (_currentState == DisplayState.Waiting && !(_hostWaitingStartTime < 0f) && _hostWaitingPhaseKey != null) { if (ResolveHostWaitingPhase() != _hostWaitingPhaseKey) { ClearHostWaitingTimer(); DestroyForceContinueButton(); } else if (!((Object)(object)_forceContinueButton != (Object)null) && !(Time.unscaledTime - _hostWaitingStartTime < 45f)) { _forceContinueButton = CreateForceContinueButton(); } } } private GameObject CreateForceContinueButton() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0037: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b1: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0173: 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_0193: Expected O, but got Unknown GameObject val = new GameObject("ForceContinueButton"); val.transform.SetParent(_overlayPanel.transform, false); ((Graphic)val.AddComponent()).color = new Color(0.55f, 0.18f, 0.18f); Button obj = val.AddComponent