using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using I2.Loc; using JetBrains.Annotations; using MPUIKIT; using Microsoft.CodeAnalysis; using MoreMountains.Feedbacks; using NGS.MeshFusionPro; using On; using Pathfinding; using Pathfinding.RVO; using Rewired; using Shapes; using Steamworks; using TMPro; using ThronefallMP.Components; using ThronefallMP.Network; using ThronefallMP.Network.Packets; using ThronefallMP.Network.Packets.Administration; using ThronefallMP.Network.Packets.Game; using ThronefallMP.Network.Packets.PlayerCommand; using ThronefallMP.Network.Packets.Sync; using ThronefallMP.Network.Sync; using ThronefallMP.Patches; using ThronefallMP.UI; using ThronefallMP.UI.Controls; using ThronefallMP.UI.Dialogs; using ThronefallMP.UI.Panels; using ThronefallMP.Utils; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Experimental.Rendering; using UnityEngine.SceneManagement; using UnityEngine.TextCore.LowLevel; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyFileVersion("1.2.2.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsUnmanagedAttribute : Attribute { } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } internal static class PluginInfo { public const string PLUGIN_GUID = "com.badwolf.thronefall_mp"; public const string PLUGIN_NAME = "Thronefall Multiplayer"; public const string PLUGIN_VERSION = "1.2.2"; } namespace ThronefallMP { public class CheatHandler { private delegate bool CheatMessageHandler(string user, string[] parts); private Dictionary _handlers = new Dictionary(); private static bool CheatsEnabled => !Plugin.Instance.Network.Online || (SteamManager.Initialized && SteamMatchmaking.GetLobbyData(Plugin.Instance.Network.Lobby, "cheats_enabled") == "yes"); public CheatHandler() { _handlers.Add("add_coins", AddCoins); Plugin.Instance.Network.AddChatMessageHandler(100, OnMessageReceived); } private bool OnMessageReceived(string user, string message) { if (!CheatsEnabled || !Plugin.Instance.Network.Server || !message.StartsWith("/")) { return false; } message = message.Remove(0, 1); Plugin.Log.LogInfo((object)("Parsing cheat '" + message + "'")); string[] array = message.Split(' '); Plugin.Log.LogInfo((object)("Command '" + array[0] + "'")); if (_handlers.TryGetValue(array[0], out var value)) { return value(user, array.Skip(1).ToArray()); } Plugin.Log.LogInfo((object)"Not found"); return false; } private bool AddCoins(string user, string[] parts) { if (parts.Length != 1) { Plugin.Log.LogInfo((object)"Too many arguments"); return false; } if (!int.TryParse(parts[0], out var result)) { Plugin.Log.LogInfo((object)"Failed to parse coins"); return false; } GlobalData.Balance += result; Plugin.Instance.Network.SendServerMessage($"{user} Cheated in {result} coins."); return true; } } public enum Equipment { Invalid, PerkPoint, LongBow, LightSpear, HeavySword, LightningWand, RoyalMint, ArcaneTowers, HeavyArmor, CastleFortifications, RingOfResurrection, PumpkinFields, ArchitectsCouncil, GodsLotion, CastleBlueprints, GladiatorSchool, WarHorse, GlassCannon, BigHarbours, EliteWarriors, ArcherySkills, FasterResearch, TowerSupport, FortifiedHouses, CommanderMode, HealingSpirits, IceMagic, MeleeResistance, PowerTower, RangedResistance, TreasureHunter, IndestructibleMines, WarriorMode, MeleeDamage, FirewingHero, AntiAirTelescope, RangedDamage, StrongerHeroes, LizardRiderHero, AssassinsTraining, MagicArmor, GodlyCurse, CastleUp, MillScarecrow, MillWindSpirits, TowerHotOil, MeleeFlails, RangedHunters, MeleeBerserkers, RangedFireArchers, WarGods, Turtle, Tiger, Rat, Falcon, Destruction, Wasp, Death, Phoenix, NoWallsPact, NoTowersPact, NoUnitsPact, BattleAxe, BloodWand, CursedBlowpipe, FalchionAndTrap, AgileHorse, AncientShrines, Cobbler, DoubleHealing, EliteTowers, EmergencyRepairs, ExperienceGain, ExplosiveRevival, ExplosiveWalls, HealingGold, HealthPotions, Interest, LastStand, LightMaterials, Loan, Outpost, PotionVials, PristineArchers, PristineWarriors, RelentlessResearch, ResilientResidences, RiskTaker, RoyalProtection, SpellScroll, TimberScaffolding, TowerArmor, TowerBunker, EliteGod, GrowthGod, RangeGod, ChaosGod, AfterlifeGod, ChoiceGod, PacifistPact } public static class Equip { public static readonly HashSet Weapons = new HashSet { Equipment.LongBow, Equipment.LightSpear, Equipment.HeavySword, Equipment.LightningWand, Equipment.BattleAxe, Equipment.BloodWand, Equipment.CursedBlowpipe, Equipment.FalchionAndTrap }; private static readonly Dictionary NameToEquip = new Dictionary { { "", Equipment.Invalid }, { "Perk Point", Equipment.PerkPoint }, { "Long Bow", Equipment.LongBow }, { "Light Spear", Equipment.LightSpear }, { "Heavy Sword", Equipment.HeavySword }, { "Lightning Wand", Equipment.LightningWand }, { "Universal Income", Equipment.RoyalMint }, { "Arcane Towers", Equipment.ArcaneTowers }, { "Heavy Armor", Equipment.HeavyArmor }, { "Castle Fortifications", Equipment.CastleFortifications }, { "Ring of Resurection", Equipment.RingOfResurrection }, { "Pumpkin Fields", Equipment.PumpkinFields }, { "Architect's Council", Equipment.ArchitectsCouncil }, { "Gods Lotion", Equipment.GodsLotion }, { "Castle Blueprints", Equipment.CastleBlueprints }, { "Gladiator School", Equipment.GladiatorSchool }, { "War Horse", Equipment.WarHorse }, { "Glass Canon", Equipment.GlassCannon }, { "Big Harbours", Equipment.BigHarbours }, { "Ellite Warriors", Equipment.EliteWarriors }, { "Archery Skills", Equipment.ArcherySkills }, { "Faster Research", Equipment.FasterResearch }, { "TowerSupport", Equipment.TowerSupport }, { "Fortified Houses", Equipment.FortifiedHouses }, { "Commander Mode", Equipment.CommanderMode }, { "Healing Spirits", Equipment.HealingSpirits }, { "Ice Magic", Equipment.IceMagic }, { "Melee Resistence", Equipment.MeleeResistance }, { "Power Tower", Equipment.PowerTower }, { "Ranged Resistence", Equipment.RangedResistance }, { "Treasure Hunter", Equipment.TreasureHunter }, { "Indestructible Mines", Equipment.IndestructibleMines }, { "Warrior Mode", Equipment.WarriorMode }, { "Melee Damage", Equipment.MeleeDamage }, { "Firewing Hero", Equipment.FirewingHero }, { "Anti Air Telescope", Equipment.AntiAirTelescope }, { "Ranged Damage", Equipment.RangedDamage }, { "Stronger Heros", Equipment.StrongerHeroes }, { "LizzardRider Hero", Equipment.LizardRiderHero }, { "CCAssassinsTraining", Equipment.AssassinsTraining }, { "CCMagicArmor", Equipment.MagicArmor }, { "CCGodlyCurse", Equipment.GodlyCurse }, { "CCCastleUp", Equipment.CastleUp }, { "MillScarecrow", Equipment.MillScarecrow }, { "MillWindSpirits", Equipment.MillWindSpirits }, { "TowerHotOil", Equipment.TowerHotOil }, { "MeleeFlails", Equipment.MeleeFlails }, { "RangedHunters", Equipment.RangedHunters }, { "MeleeBerserks", Equipment.MeleeBerserkers }, { "RangedFireArchers", Equipment.RangedFireArchers }, { "Pray to The God of Strength", Equipment.WarGods }, { "Taunt The Turtle God", Equipment.Turtle }, { "Taunt The Tiger God", Equipment.Tiger }, { "Taunt The Rat God", Equipment.Rat }, { "Taunt The Falcon God", Equipment.Falcon }, { "Taunt God of Destruction", Equipment.Destruction }, { "Taunt The Cheese God", Equipment.Wasp }, { "Taunt The Disease God", Equipment.Death }, { "Taunt the Phoenix God", Equipment.Phoenix }, { "No Walls Pact", Equipment.NoWallsPact }, { "No Towers Pact", Equipment.NoTowersPact }, { "No Units Pact", Equipment.NoUnitsPact }, { "Battle Axe", Equipment.BattleAxe }, { "Blood Wand", Equipment.BloodWand }, { "Cursed Blowpipe", Equipment.CursedBlowpipe }, { "Falchion and Trap", Equipment.FalchionAndTrap }, { "Agile Horse", Equipment.AgileHorse }, { "Ancient Shrines", Equipment.AncientShrines }, { "Cobbler", Equipment.Cobbler }, { "Double Healing", Equipment.DoubleHealing }, { "Elite Towers", Equipment.EliteTowers }, { "Emergency Repairs", Equipment.EmergencyRepairs }, { "Experience Gain", Equipment.ExperienceGain }, { "Explosive Revival", Equipment.ExplosiveRevival }, { "Explosive Walls", Equipment.ExplosiveWalls }, { "Healing Gold", Equipment.HealingGold }, { "Health Potions", Equipment.HealthPotions }, { "Interest", Equipment.Interest }, { "Last Stand", Equipment.LastStand }, { "Light Materials", Equipment.LightMaterials }, { "Loan", Equipment.Loan }, { "Outpost", Equipment.Outpost }, { "Potion Vials", Equipment.PotionVials }, { "Pristine Archers", Equipment.PristineArchers }, { "Pristine Warriors", Equipment.PristineWarriors }, { "Relentless Research", Equipment.RelentlessResearch }, { "Resilient Residences", Equipment.ResilientResidences }, { "Risk Taker", Equipment.RiskTaker }, { "Royal Protection", Equipment.RoyalProtection }, { "Spell Scroll", Equipment.SpellScroll }, { "Timber Scaffolding", Equipment.TimberScaffolding }, { "TowerArmor", Equipment.TowerArmor }, { "TowerBunker", Equipment.TowerBunker }, { "Challenge the Elite God", Equipment.EliteGod }, { "Challenge the Growth God", Equipment.GrowthGod }, { "Challenge the Range God", Equipment.RangeGod }, { "Challenge the God of Chaos", Equipment.ChaosGod }, { "Challenge the God of Afterlife", Equipment.AfterlifeGod }, { "Challenge the God of Choice", Equipment.ChoiceGod }, { "Pacifist Pact", Equipment.PacifistPact } }; private static readonly Dictionary EquipmentToEquippable = new Dictionary(); private static readonly Dictionary EquippableToEquipment = new Dictionary(); private static bool _initialized; private static void InitializeDictionaries() { _initialized = true; Traverse> val = Traverse.Create((object)PerkManager.instance).Field>("metaLevels"); Plugin.Log.LogInfoFiltered("Equipment", "Initializing converter dictionary"); Plugin.Log.LogInfoFiltered("Equipment", "Meta levels"); foreach (MetaLevel item in val.Value) { Equipment equipment = Convert(((Object)item.reward).name); Plugin.Log.LogInfoFiltered("Equipment", $"- {equipment} = {((Object)item.reward).name}"); if (equipment == Equipment.Invalid) { Plugin.Log.LogWarning((object)("Equippable '" + ((Object)item.reward).name + "' is not in the equipment table")); continue; } EquipmentToEquippable[equipment] = item.reward; EquippableToEquipment[item.reward] = equipment; } Plugin.Log.LogInfoFiltered("Equipment", "Currently Unlocked"); foreach (Equippable allEquippable in PerkManager.instance.allEquippables) { Equipment equipment2 = Convert(((Object)allEquippable).name); Plugin.Log.LogInfoFiltered("Equipment", $"- {equipment2} = {((Object)allEquippable).name}"); if (equipment2 == Equipment.Invalid) { Plugin.Log.LogWarning((object)("Equippable '" + ((Object)allEquippable).name + "' is not in the equipment table")); continue; } EquipmentToEquippable[equipment2] = allEquippable; EquippableToEquipment[allEquippable] = equipment2; } } public static void ClearEquipments() { Plugin.Log.LogInfoFiltered("Equipment", "Clearing equipment"); PerkManager.instance.CurrentlyEquipped.Clear(); } public static void EquipEquipment(Equipment equipment) { if (!_initialized) { InitializeDictionaries(); } if (!EquipmentToEquippable.TryGetValue(equipment, out var value)) { Plugin.Log.LogWarning((object)$"Cannot equip unknown equipment '{equipment}', skipping"); return; } Plugin.Log.LogInfoFiltered("Equipment", $"Equipping {equipment} -> {((Object)value).name} (\"{value.displayName}\")"); PerkManager.instance.CurrentlyEquipped.Add(value); } public static Equipment Convert(Equippable equip) { if (!_initialized) { InitializeDictionaries(); } return GeneralExtensions.GetValueSafe(EquippableToEquipment, equip); } public static Equippable Convert(Equipment equip) { if (!_initialized) { InitializeDictionaries(); } return GeneralExtensions.GetValueSafe(EquipmentToEquippable, equip); } public static Equipment Convert(string name) { return GeneralExtensions.GetValueSafe(NameToEquip, name); } } public struct InternalGlobalData { public int Balance; public int NetWorth; } public static class GlobalData { public static InternalGlobalData Internal; public static int LocalBalanceDelta; public static int Balance { get { return Plugin.Instance.Network.Server ? Internal.Balance : (Internal.Balance + LocalBalanceDelta); } set { if (Plugin.Instance.Network.Server) { Internal.Balance = value; } else { LocalBalanceDelta = value - Internal.Balance; } } } public static int NetWorth => Internal.NetWorth; } [BepInPlugin("com.badwolf.thronefall_mp", "Thronefall Multiplayer", "1.2.2")] [BepInProcess("Thronefall.exe")] public class Plugin : BaseUnityPlugin { public delegate void LoadCallback(); public const string VersionString = "thronefall_mp_1.2.2"; public static readonly Random Random = new Random(); [UsedImplicitly] public PingPongSync PingPongSync = new PingPongSync(); [UsedImplicitly] public LevelDataSync LevelDataSync = new LevelDataSync(); [UsedImplicitly] public ResourceSync ResourceSync = new ResourceSync(); [UsedImplicitly] public InputSync InputSync = new InputSync(); [UsedImplicitly] public PositionSync PositionSync = new PositionSync(); [UsedImplicitly] public HpSync HpSync = new HpSync(); [UsedImplicitly] public AllyPathfinderSync AllyPathfinderSync = new AllyPathfinderSync(); [UsedImplicitly] public EnemyPathfinderSync EnemyPathfinderSync = new EnemyPathfinderSync(); private static Dictionary> _loadCallbacks = new Dictionary>(); public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } public ThronefallMP.Network.Network Network { get; private set; } public PlayerManager PlayerManager { get; private set; } public TextureRepository TextureRepository { get; private set; } [UsedImplicitly] public CheatHandler CheatHandler { get; private set; } private void Awake() { ConfigEntry val = ((BaseUnityPlugin)this).Config.Bind("Network", "EnableSimulation", false, "Enable simulation of a bad network for debugging"); Instance = this; TextureRepository = new TextureRepository(); Network = ((Component)Instance).gameObject.AddComponent(); ((Component)this).gameObject.AddComponent(); PlayerManager = new PlayerManager(); CheatHandler = new CheatHandler(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.badwolf.thronefall_mp is loaded!"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"===== Thronefall Multiplayer v1.2.2 ====="); Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)$"Little Endian: {BitConverter.IsLittleEndian}"); if (SteamManager.Initialized) { SetSteamNetworkConfigValues(); if (val.Value) { SetSteamNetworkSimulationValues(); } } Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); BuildingInteractorPatch.Apply(); BuildSlotPatch.Apply(); CameraRigPatch.Apply(); CommandUnitsPatch.Apply(); CostDisplayPatch.Apply(); DayNightCyclePatch.Apply(); EnemySpawnerPatch.Apply(); GateOpenerPatch.Apply(); HpPatch.Apply(); InGameResignUIHelperPatch.Apply(); LevelBorderPatch.Apply(); LevelSelectManagerPatch.Apply(); NightCallPatch.Apply(); PathFinderMovementEnemyPatch.Apply(); PathfindMovementPlayerunitPatch.Apply(); PerkHpModifyerPatch.Apply(); PerkWeaponModifyerPatch.Apply(); PlayerAttackPatch.Apply(); PlayerInteractionPatch.Apply(); PlayerMovementPatch.Apply(); PlayerSceptPatch.Apply(); RevivePanelPatch.Apply(); SceneTransitionManagerPatch.Apply(); SteamManagerPatch.Apply(); TreasuryUIPatch.Apply(); UIFrameManagerPatch.Apply(); UIFramePatch.Apply(); UnitRespawnerForBuildingsPatch.Apply(); UpgradeAssassinsTrainingPatch.Apply(); WeaponEquipperPatch.Apply(); Application.runInBackground = true; SceneManager.sceneLoaded += OnSceneChanged; } private void OnUIInitialized() { UIManager.Initialize(); ConfigEntry val = ((BaseUnityPlugin)this).Config.Bind("Network", "EnableSimulation", false, "Enable simulation of a bad network for debugging"); if (val.Value) { UIManager.CreateMessageDialog("Network Debug Simulation", "Simulation of a bad network is enabled"); } } private void OnSceneChanged(Scene scene, LoadSceneMode mode) { if (((Scene)(ref scene)).name == "_UI") { OnUIInitialized(); } if (!_loadCallbacks.TryGetValue(((Scene)(ref scene)).name, out List<(bool, LoadCallback)> value)) { return; } foreach (var item in value) { if (item.Item1) { CallbackOnFinishTransition(item.Item2); } else { item.Item2(); } } value.Clear(); } public static void CallbackOnLoad(string scene, bool waitForTransition, LoadCallback callback) { if (!_loadCallbacks.TryGetValue(scene, out List<(bool, LoadCallback)> value)) { value = new List<(bool, LoadCallback)>(); _loadCallbacks[scene] = value; } value.Add((waitForTransition, callback)); } private static void CallbackOnFinishTransition(LoadCallback callback) { ((MonoBehaviour)Instance).StartCoroutine(WaitForTransition(callback)); } private static IEnumerator WaitForTransition(LoadCallback callback) { while (SceneTransitionManager.instance.SceneTransitionIsRunning) { yield return null; } callback?.Invoke(); } private void SetSteamNetworkConfigValues() { SetSteamNetworkValue((ESteamNetworkingConfigValue)24, (ESteamNetworkingConfigDataType)1, 1600); SetSteamNetworkValue((ESteamNetworkingConfigValue)25, (ESteamNetworkingConfigDataType)1, 3200); SetSteamNetworkValue((ESteamNetworkingConfigValue)9, (ESteamNetworkingConfigDataType)1, 4194304); } private void SetSteamNetworkSimulationValues() { SetSteamNetworkValue((ESteamNetworkingConfigValue)2, (ESteamNetworkingConfigDataType)3, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketLossSendPercentage", 0.3f, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)3, (ESteamNetworkingConfigDataType)3, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketLossReceivePercentage", 0.3f, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)4, (ESteamNetworkingConfigDataType)1, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketLagSendMs", 80, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)5, (ESteamNetworkingConfigDataType)1, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketLagReceiveMs", 80, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)6, (ESteamNetworkingConfigDataType)3, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketReorderPercentageSend", 0.1f, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)7, (ESteamNetworkingConfigDataType)3, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketReorderPercentageReceive", 0.1f, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)8, (ESteamNetworkingConfigDataType)1, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketReorderTime", 20, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)26, (ESteamNetworkingConfigDataType)3, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketDuplicatePercentSend", 0.1f, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)26, (ESteamNetworkingConfigDataType)3, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketDuplicatePercentReceive", 0.1f, (ConfigDescription)null).Value); SetSteamNetworkValue((ESteamNetworkingConfigValue)28, (ESteamNetworkingConfigDataType)1, ((BaseUnityPlugin)this).Config.Bind("Network", "PacketDuplicateTimeMax", 60, (ConfigDescription)null).Value); } private static void SetSteamNetworkValue(ESteamNetworkingConfigValue name, ESteamNetworkingConfigDataType type, T value) where T : unmanaged { //IL_000e: 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) GCHandle gCHandle = GCHandle.Alloc(value, GCHandleType.Pinned); SteamNetworkingUtils.SetConfigValue(name, (ESteamNetworkingConfigScope)1, IntPtr.Zero, type, gCHandle.AddrOfPinnedObject()); gCHandle.Free(); } } public class PrefabSpawner : MonoBehaviour { public enum EnemyType { Unknown, Archer, Catapult, Crossbow, Exploder, Flyer, Hunterling, Melee, MonsterRider, Ogre, ProjectileBow, Racer, Slime, StrongSlime, Weakling } private readonly Dictionary _enemyNameToType = new Dictionary(); private readonly Dictionary _enemyTypeToName = new Dictionary(); private readonly Dictionary _prefabs = new Dictionary(); private void Awake() { AddEnemyEntries(EnemyType.Unknown, ""); AddEnemyEntries(EnemyType.Archer, "E Archer"); AddEnemyEntries(EnemyType.Catapult, "E Catapult"); AddEnemyEntries(EnemyType.Crossbow, "E Crossbow"); AddEnemyEntries(EnemyType.Exploder, "E Exploder"); AddEnemyEntries(EnemyType.Flyer, "E Flyer"); AddEnemyEntries(EnemyType.Hunterling, "E Hunterling"); AddEnemyEntries(EnemyType.Melee, "E Melee"); AddEnemyEntries(EnemyType.MonsterRider, "E MonsterRider"); AddEnemyEntries(EnemyType.Ogre, "E Ogre"); AddEnemyEntries(EnemyType.ProjectileBow, "E ProjectileBow"); AddEnemyEntries(EnemyType.Racer, "E Racer"); AddEnemyEntries(EnemyType.Slime, "E Slime"); AddEnemyEntries(EnemyType.StrongSlime, "E StrongSlime"); AddEnemyEntries(EnemyType.Weakling, "E Weakling"); } private void AddEnemyEntries(EnemyType type, string enemy) { _enemyTypeToName.Add(type, enemy); _enemyNameToType.Add(enemy, type); } private GameObject GetPrefab(EnemyType type) { if (!_prefabs.TryGetValue(type, out var value) || (Object)(object)value == (Object)null) { value = GameObject.Find(_enemyTypeToName[type]); _prefabs.Add(type, value); } return value; } public EnemyType ToEnemy(string enemy) { EnemyType value; return _enemyNameToType.TryGetValue(enemy, out value) ? value : EnemyType.Unknown; } public GameObject Spawn(ushort id, EnemyType type) { GameObject prefab = GetPrefab(type); if ((Object)(object)prefab == (Object)null) { return null; } GameObject val = Helpers.InstantiateDisabled(prefab, (Transform)null, worldPositionStays: false); Identifier identifier = val.AddComponent(); identifier.SetIdentity(IdentifierType.Enemy, id); return val; } } public class TextureRepository { public readonly Texture2D Crown = LoadTexture("crown.png"); public readonly Texture2D Lock = LoadTexture("lock-icon.png"); public readonly Texture2D Blank = LoadTexture("blank.png"); private static Texture2D LoadTexture(string textureName) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(textureName)); Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name); Texture2D val = new Texture2D(2, 2, (GraphicsFormat)8, 1, (TextureCreationFlags)0); using MemoryStream memoryStream = new MemoryStream(); manifestResourceStream.CopyTo(memoryStream); ImageConversion.LoadImage(val, memoryStream.ToArray()); return val; } } } namespace ThronefallMP.Utils { public static class Ext { public static bool LogErrorFiltered(string section) { return ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowError" + section, true, (ConfigDescription)null).Value; } public static void LogErrorFiltered(this ManualLogSource source, string section, object obj) { ConfigEntry val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowError" + section, true, (ConfigDescription)null); if (val.Value) { source.LogError((object)(section + "> " + obj)); } } public static bool LogWarningFiltered(string section) { return ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowWarning" + section, true, (ConfigDescription)null).Value; } public static void LogWarningFiltered(this ManualLogSource source, string section, object obj) { ConfigEntry val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowWarning" + section, true, (ConfigDescription)null); if (val.Value) { source.LogWarning((object)(section + "> " + obj)); } } public static bool LogInfoFiltered(string section) { return ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowInfo" + section, true, (ConfigDescription)null).Value; } public static void LogInfoFiltered(this ManualLogSource source, string section, object obj) { ConfigEntry val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowInfo" + section, true, (ConfigDescription)null); if (val.Value) { source.LogInfo((object)(section + "> " + obj)); } } public static bool LogDebugFiltered(string section) { return ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowDebug" + section, true, (ConfigDescription)null).Value; } public static void LogDebugFiltered(this ManualLogSource source, string section, object obj) { ConfigEntry val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind("Debug", "ShowDebug" + section, true, (ConfigDescription)null); if (val.Value) { source.LogDebug(obj); } } } [Serializable] public struct Half : IComparable, IFormattable, IConvertible, IComparable, IEquatable { [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal ushort value; public static readonly Half Epsilon = ToHalf(1); public static readonly Half MaxValue = ToHalf(31743); public static readonly Half MinValue = ToHalf(64511); public static readonly Half NaN = ToHalf(65024); public static readonly Half NegativeInfinity = ToHalf(64512); public static readonly Half PositiveInfinity = ToHalf(31744); public Half(float value) { this = HalfHelper.SingleToHalf(value); } public Half(int value) : this((float)value) { } public Half(long value) : this((float)value) { } public Half(double value) : this((float)value) { } public Half(decimal value) : this((float)value) { } public Half(uint value) : this((float)value) { } public Half(ulong value) : this((float)value) { } public static Half Negate(Half half) { return -half; } public static Half Add(Half half1, Half half2) { return half1 + half2; } public static Half Subtract(Half half1, Half half2) { return half1 - half2; } public static Half Multiply(Half half1, Half half2) { return half1 * half2; } public static Half Divide(Half half1, Half half2) { return half1 / half2; } public static Half operator +(Half half) { return half; } public static Half operator -(Half half) { return HalfHelper.Negate(half); } public static Half operator ++(Half half) { return (Half)((float)half + 1f); } public static Half operator --(Half half) { return (Half)((float)half - 1f); } public static Half operator +(Half half1, Half half2) { return (Half)((float)half1 + (float)half2); } public static Half operator -(Half half1, Half half2) { return (Half)((float)half1 - (float)half2); } public static Half operator *(Half half1, Half half2) { return (Half)((float)half1 * (float)half2); } public static Half operator /(Half half1, Half half2) { return (Half)((float)half1 / (float)half2); } public static bool operator ==(Half half1, Half half2) { return !IsNaN(half1) && half1.value == half2.value; } public static bool operator !=(Half half1, Half half2) { return half1.value != half2.value; } public static bool operator <(Half half1, Half half2) { return (float)half1 < (float)half2; } public static bool operator >(Half half1, Half half2) { return (float)half1 > (float)half2; } public static bool operator <=(Half half1, Half half2) { return half1 == half2 || half1 < half2; } public static bool operator >=(Half half1, Half half2) { return half1 == half2 || half1 > half2; } public static implicit operator Half(byte value) { return new Half((float)(int)value); } public static implicit operator Half(short value) { return new Half((float)value); } public static implicit operator Half(char value) { return new Half((float)(int)value); } public static implicit operator Half(int value) { return new Half((float)value); } public static implicit operator Half(long value) { return new Half((float)value); } public static explicit operator Half(float value) { return new Half(value); } public static explicit operator Half(double value) { return new Half((float)value); } public static explicit operator Half(decimal value) { return new Half((float)value); } public static explicit operator byte(Half value) { return (byte)(float)value; } public static explicit operator char(Half value) { return (char)(float)value; } public static explicit operator short(Half value) { return (short)(float)value; } public static explicit operator int(Half value) { return (int)(float)value; } public static explicit operator long(Half value) { return (long)(float)value; } public static implicit operator float(Half value) { return HalfHelper.HalfToSingle(value); } public static implicit operator double(Half value) { return (float)value; } public static explicit operator decimal(Half value) { return (decimal)(float)value; } public static implicit operator Half(sbyte value) { return new Half((float)value); } public static implicit operator Half(ushort value) { return new Half((float)(int)value); } public static implicit operator Half(uint value) { return new Half((float)value); } public static implicit operator Half(ulong value) { return new Half((float)value); } public static explicit operator sbyte(Half value) { return (sbyte)(float)value; } public static explicit operator ushort(Half value) { return (ushort)(float)value; } public static explicit operator uint(Half value) { return (uint)(float)value; } public static explicit operator ulong(Half value) { return (ulong)(float)value; } public int CompareTo(Half other) { int result = 0; if (this < other) { result = -1; } else if (this > other) { result = 1; } else if (this != other) { if (!IsNaN(this)) { result = 1; } else if (!IsNaN(other)) { result = -1; } } return result; } public int CompareTo(object obj) { int num = 0; if (obj == null) { return 1; } if (obj is Half) { return CompareTo((Half)obj); } throw new ArgumentException("Object must be of type Half."); } public bool Equals(Half other) { return other == this || (IsNaN(other) && IsNaN(this)); } public override bool Equals(object obj) { bool result = false; if (obj is Half half && (half == this || (IsNaN(half) && IsNaN(this)))) { result = true; } return result; } public override int GetHashCode() { return value.GetHashCode(); } public TypeCode GetTypeCode() { return (TypeCode)255; } public static byte[] GetBytes(Half value) { return BitConverter.GetBytes(value.value); } public static ushort GetBits(Half value) { return value.value; } public static Half ToHalf(byte[] value, int startIndex) { return ToHalf((ushort)BitConverter.ToInt16(value, startIndex)); } public static Half ToHalf(ushort bits) { return new Half { value = bits }; } public static int Sign(Half value) { if (value < 0) { return -1; } if (value > 0) { return 1; } if (value != 0) { throw new ArithmeticException("Function does not accept floating point Not-a-Number values."); } return 0; } public static Half Abs(Half value) { return HalfHelper.Abs(value); } public static Half Max(Half value1, Half value2) { return (value1 < value2) ? value2 : value1; } public static Half Min(Half value1, Half value2) { return (value1 < value2) ? value1 : value2; } public static bool IsNaN(Half half) { return HalfHelper.IsNaN(half); } public static bool IsInfinity(Half half) { return HalfHelper.IsInfinity(half); } public static bool IsNegativeInfinity(Half half) { return HalfHelper.IsNegativeInfinity(half); } public static bool IsPositiveInfinity(Half half) { return HalfHelper.IsPositiveInfinity(half); } public static Half Parse(string value) { return (Half)float.Parse(value, CultureInfo.InvariantCulture); } public static Half Parse(string value, IFormatProvider provider) { return (Half)float.Parse(value, provider); } public static Half Parse(string value, NumberStyles style) { return (Half)float.Parse(value, style, CultureInfo.InvariantCulture); } public static Half Parse(string value, NumberStyles style, IFormatProvider provider) { return (Half)float.Parse(value, style, provider); } public static bool TryParse(string value, out Half result) { if (float.TryParse(value, out var result2)) { result = (Half)result2; return true; } result = default(Half); return false; } public static bool TryParse(string value, NumberStyles style, IFormatProvider provider, out Half result) { bool result2 = false; if (float.TryParse(value, style, provider, out var result3)) { result = (Half)result3; result2 = true; } else { result = default(Half); } return result2; } public override string ToString() { return ((float)this).ToString(CultureInfo.InvariantCulture); } public string ToString(IFormatProvider formatProvider) { return ((float)this).ToString(formatProvider); } public string ToString(string format) { return ((float)this).ToString(format, CultureInfo.InvariantCulture); } public string ToString(string format, IFormatProvider formatProvider) { return ((float)this).ToString(format, formatProvider); } float IConvertible.ToSingle(IFormatProvider provider) { return this; } TypeCode IConvertible.GetTypeCode() { return GetTypeCode(); } bool IConvertible.ToBoolean(IFormatProvider provider) { return Convert.ToBoolean(this); } byte IConvertible.ToByte(IFormatProvider provider) { return Convert.ToByte(this); } char IConvertible.ToChar(IFormatProvider provider) { throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "Char")); } DateTime IConvertible.ToDateTime(IFormatProvider provider) { throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "DateTime")); } decimal IConvertible.ToDecimal(IFormatProvider provider) { return Convert.ToDecimal(this); } double IConvertible.ToDouble(IFormatProvider provider) { return Convert.ToDouble(this); } short IConvertible.ToInt16(IFormatProvider provider) { return Convert.ToInt16(this); } int IConvertible.ToInt32(IFormatProvider provider) { return Convert.ToInt32(this); } long IConvertible.ToInt64(IFormatProvider provider) { return Convert.ToInt64(this); } sbyte IConvertible.ToSByte(IFormatProvider provider) { return Convert.ToSByte(this); } string IConvertible.ToString(IFormatProvider provider) { return Convert.ToString(this, CultureInfo.InvariantCulture); } object IConvertible.ToType(Type conversionType, IFormatProvider provider) { return ((IConvertible)(float)this).ToType(conversionType, provider); } ushort IConvertible.ToUInt16(IFormatProvider provider) { return Convert.ToUInt16(this); } uint IConvertible.ToUInt32(IFormatProvider provider) { return Convert.ToUInt32(this); } ulong IConvertible.ToUInt64(IFormatProvider provider) { return Convert.ToUInt64(this); } } [ComVisible(false)] internal static class HalfHelper { private static readonly uint[] mantissaTable = GenerateMantissaTable(); private static readonly uint[] exponentTable = GenerateExponentTable(); private static readonly ushort[] offsetTable = GenerateOffsetTable(); private static readonly ushort[] baseTable = GenerateBaseTable(); private static readonly sbyte[] shiftTable = GenerateShiftTable(); private static uint ConvertMantissa(int i) { uint num = (uint)(i << 13); uint num2 = 0u; while ((num & 0x800000) == 0) { num2 -= 8388608; num <<= 1; } num &= 0xFF7FFFFFu; num2 += 947912704; return num | num2; } private static uint[] GenerateMantissaTable() { uint[] array = new uint[2048]; array[0] = 0u; for (int i = 1; i < 1024; i++) { array[i] = ConvertMantissa(i); } for (int j = 1024; j < 2048; j++) { array[j] = (uint)(939524096 + (j - 1024 << 13)); } return array; } private static uint[] GenerateExponentTable() { uint[] array = new uint[64]; array[0] = 0u; for (int i = 1; i < 31; i++) { array[i] = (uint)(i << 23); } array[31] = 1199570944u; array[32] = 2147483648u; for (int j = 33; j < 63; j++) { array[j] = (uint)(2147483648u + (j - 32 << 23)); } array[63] = 3347054592u; return array; } private static ushort[] GenerateOffsetTable() { ushort[] array = new ushort[64]; array[0] = 0; for (int i = 1; i < 32; i++) { array[i] = 1024; } array[32] = 0; for (int j = 33; j < 64; j++) { array[j] = 1024; } return array; } private static ushort[] GenerateBaseTable() { ushort[] array = new ushort[512]; for (int i = 0; i < 256; i++) { sbyte b = (sbyte)(127 - i); if (b > 24) { array[i | 0] = 0; array[i | 0x100] = 32768; } else if (b > 14) { array[i | 0] = (ushort)(1024 >> 18 + b); array[i | 0x100] = (ushort)((1024 >> 18 + b) | 0x8000); } else if (b >= -15) { array[i | 0] = (ushort)(15 - b << 10); array[i | 0x100] = (ushort)((15 - b << 10) | 0x8000); } else if (b > sbyte.MinValue) { array[i | 0] = 31744; array[i | 0x100] = 64512; } else { array[i | 0] = 31744; array[i | 0x100] = 64512; } } return array; } private static sbyte[] GenerateShiftTable() { sbyte[] array = new sbyte[512]; for (int i = 0; i < 256; i++) { sbyte b = (sbyte)(127 - i); if (b > 24) { array[i | 0] = 24; array[i | 0x100] = 24; } else if (b > 14) { array[i | 0] = (sbyte)(b - 1); array[i | 0x100] = (sbyte)(b - 1); } else if (b >= -15) { array[i | 0] = 13; array[i | 0x100] = 13; } else if (b > sbyte.MinValue) { array[i | 0] = 24; array[i | 0x100] = 24; } else { array[i | 0] = 13; array[i | 0x100] = 13; } } return array; } public unsafe static float HalfToSingle(Half half) { uint num = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3FF)] + exponentTable[half.value >> 10]; return *(float*)(&num); } public unsafe static Half SingleToHalf(float single) { uint num = *(uint*)(&single); ushort bits = (ushort)(baseTable[(num >> 23) & 0x1FF] + ((num & 0x7FFFFF) >> (int)shiftTable[num >> 23])); return Half.ToHalf(bits); } public static Half Negate(Half half) { return Half.ToHalf((ushort)(half.value ^ 0x8000)); } public static Half Abs(Half half) { return Half.ToHalf((ushort)(half.value & 0x7FFF)); } public static bool IsNaN(Half half) { return (half.value & 0x7FFF) > 31744; } public static bool IsInfinity(Half half) { return (half.value & 0x7FFF) == 31744; } public static bool IsPositiveInfinity(Half half) { return half.value == 31744; } public static bool IsNegativeInfinity(Half half) { return half.value == 64512; } } public static class Helpers { public const float Epsilon = 1.8E-43f; public const float EpsilonSqr = 9E-44f; public const float PositionEpsilonSqr = 0.0025f; private const float SpawnRadiusIncrement = 5f; private const int SpawnAngleIncrement = 60; private const int SpawnAngleEvenOffset = 30; public static Vector3 GetSpawnLocation(Vector3 position, int playerId) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0065: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (playerId == -1) { return position; } float num = 5f; int num2 = 0; bool flag = false; while (playerId > 0) { num2 += 60; if (num2 >= 360) { num2 = 0; num += 5f; flag = !flag; } playerId--; } Vector3 val = new Vector3 { x = num }; val = Quaternion.AngleAxis((float)(num2 + (flag ? 30 : 0)), Vector3.up) * val; return position + val; } public static string GetPath(Transform tr) { Transform parent = tr.parent; return ((Object)(object)parent == (Object)null) ? ((Object)tr).name : (GetPath(parent) + "/" + ((Object)tr).name); } public static bool UnityNullCheck(object a) { int result; if (a != null) { Object val = (Object)((a is Object) ? a : null); result = ((val == null || val != (Object)null) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } public static PlayerInteraction FindClosest(PlayerInteraction[] players, Vector3 pos) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) float num = float.MaxValue; PlayerInteraction result = null; foreach (PlayerInteraction val in players) { Vector3 val2 = ((Component)val).transform.position - pos; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } return result; } public static T InstantiateDisabled(T original, Transform parent = null, bool worldPositionStays = false) where T : Object { if (!GetActiveState(original)) { return Object.Instantiate(original, parent, worldPositionStays); } (GameObject coreObject, Transform coreObjectTransform) tuple = CreateDisabledCoreObject(parent); GameObject item = tuple.coreObject; Transform item2 = tuple.coreObjectTransform; T val = Object.Instantiate(original, item2, worldPositionStays); SetActiveState(val, state: false); SetParent(val, parent, worldPositionStays); Object.Destroy((Object)(object)item); return val; } public static T InstantiateDisabled(T original, Vector3 position, Quaternion rotation, Transform parent = null) where T : Object { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!GetActiveState(original)) { return Object.Instantiate(original, position, rotation, parent); } (GameObject coreObject, Transform coreObjectTransform) tuple = CreateDisabledCoreObject(parent); GameObject item = tuple.coreObject; Transform item2 = tuple.coreObjectTransform; T val = Object.Instantiate(original, position, rotation, item2); SetActiveState(val, state: false); SetParent(val, parent, worldPositionStays: false); Object.Destroy((Object)(object)item); return val; } private static (GameObject coreObject, Transform coreObjectTransform) CreateDisabledCoreObject(Transform parent = null) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject(string.Empty); val.SetActive(false); Transform transform = val.transform; transform.SetParent(parent); return (coreObject: val, coreObjectTransform: transform); } private static bool GetActiveState(T @object) where T : Object { object obj = @object; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val != null) { return val.activeSelf; } object obj2 = @object; Component val2 = (Component)((obj2 is Component) ? obj2 : null); if (val2 != null) { return val2.gameObject.activeSelf; } return false; } private static void SetActiveState(T @object, bool state) where T : Object { object obj = @object; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val == null) { object obj2 = @object; Component val2 = (Component)((obj2 is Component) ? obj2 : null); if (val2 != null) { val2.gameObject.SetActive(state); } } else { val.SetActive(state); } } private static void SetParent(T @object, Transform parent, bool worldPositionStays) where T : Object { object obj = @object; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val == null) { object obj2 = @object; Component val2 = (Component)((obj2 is Component) ? obj2 : null); if (val2 != null) { val2.transform.SetParent(parent, worldPositionStays); } } else { val.transform.SetParent(parent, worldPositionStays); } } } } namespace ThronefallMP.UI { public abstract class BaseUI : MonoBehaviour { public Canvas Canvas { get; set; } public GameObject PanelRoot { get; set; } public bool Enabled { get { return PanelRoot.activeSelf; } set { PanelRoot.SetActive(value); } } public abstract string Name { get; } public abstract void ConstructPanelContent(); public static T Create(GameObject canvas, GameObject container) where T : BaseUI { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0086: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Temp", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(container.transform, false); T val2 = val.AddComponent(); val2.Canvas = canvas.GetComponent(); val2.PanelRoot = val; ((Object)val2.PanelRoot).name = val2.Name; RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 1f); component.offsetMin = new Vector2(0f, 0f); component.offsetMax = new Vector2(0f, 0f); val2.ConstructPanelContent(); val2.Enabled = false; return val2; } } public static class LoadoutFrames { private static bool _resolved; private static UIFrame _levelSelect; private static readonly List _loadoutHelpers; public static UIFrame PrimaryGridFrame { get { Resolve(); foreach (LoadoutUIHelper loadoutHelper in _loadoutHelpers) { if ((Object)(object)loadoutHelper != (Object)null && (Object)(object)loadoutHelper.frame != (Object)null) { return loadoutHelper.frame; } } return _levelSelect; } } public static UIFrame GridFrame { get { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 Resolve(); foreach (LoadoutUIHelper loadoutHelper in _loadoutHelpers) { if ((Object)(object)loadoutHelper != (Object)null && (Object)(object)loadoutHelper.frame != (Object)null && (int)loadoutHelper.mode == 0) { return loadoutHelper.frame; } } return null; } } public static bool PopupOpen => SceneTransitionManagerPatch.InLevelSelect && (Object)(object)UIFrameManager.instance != (Object)null && IsPopupFrame(UIFrameManager.instance.ActiveFrame); static LoadoutFrames() { _loadoutHelpers = new List(); SceneManager.sceneLoaded += delegate { Invalidate(); }; } public static void Invalidate() { _resolved = false; _levelSelect = null; _loadoutHelpers.Clear(); } private static void Resolve() { if (_resolved || (Object)(object)UIFrameManager.instance == (Object)null) { return; } _levelSelect = Traverse.Create((object)UIFrameManager.instance).Field("levelSelectFrame").Value; LoadoutUIHelper[] array = Object.FindObjectsOfType(true); foreach (LoadoutUIHelper val in array) { if (!val.inMatch && (Object)(object)val.frame != (Object)null) { _loadoutHelpers.Add(val); } } _resolved = true; } public static bool IsPopupFrame(UIFrame frame) { if ((Object)(object)frame == (Object)null) { return false; } Resolve(); if ((Object)(object)frame == (Object)(object)_levelSelect) { return true; } foreach (LoadoutUIHelper loadoutHelper in _loadoutHelpers) { if ((Object)(object)loadoutHelper != (Object)null && (Object)(object)loadoutHelper.frame == (Object)(object)frame) { return true; } } return false; } public static LoadoutUIHelper HelperFor(UIFrame frame) { if ((Object)(object)frame == (Object)null) { return null; } Resolve(); foreach (LoadoutUIHelper loadoutHelper in _loadoutHelpers) { if ((Object)(object)loadoutHelper != (Object)null && (Object)(object)loadoutHelper.frame == (Object)(object)frame) { return loadoutHelper; } } return null; } public static string DebugState() { Resolve(); UIFrame val = (((Object)(object)UIFrameManager.instance != (Object)null) ? UIFrameManager.instance.ActiveFrame : null); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(string.Format("resolved={0} levelSelect={1} ", _resolved, ((Object)(object)_levelSelect != (Object)null) ? ((Object)_levelSelect).name : "null")); stringBuilder.Append(string.Format("helpers={0} activeFrame={1}", _loadoutHelpers.Count, ((Object)(object)val != (Object)null) ? ((Object)val).name : "null")); return stringBuilder.ToString(); } public static void CloseAllPopupFrames() { UIFrameManager instance = UIFrameManager.instance; for (int i = 0; i < 4; i++) { if (!((Object)(object)instance != (Object)null)) { break; } if (!IsPopupFrame(instance.ActiveFrame)) { break; } LoadoutUIHelper val = HelperFor(instance.ActiveFrame); if ((Object)(object)val != (Object)null) { ResetLoadoutOnCancel componentInChildren = ((Component)val).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.LockInLoadout(); } } instance.CloseActiveFrame(); } } } public static class LoadoutStatusStrip { private static GameObject _root; private static TextMeshProUGUI _text; public static void Show() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_0140: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { UIFrame primaryGridFrame = LoadoutFrames.PrimaryGridFrame; if ((Object)(object)primaryGridFrame == (Object)null) { return; } _root = new GameObject("MP Loadout Status", new Type[1] { typeof(RectTransform) }); _root.transform.SetParent(((Component)primaryGridFrame).transform, false); RectTransform val = (RectTransform)_root.transform; val.anchorMin = new Vector2(0.5f, 0f); val.anchorMax = new Vector2(0.5f, 0f); val.pivot = new Vector2(0.5f, 0f); val.anchoredPosition = new Vector2(0f, 24f); val.sizeDelta = new Vector2(1400f, 40f); _text = _root.AddComponent(); TMP_Text componentInChildren = ((Component)primaryGridFrame).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)_text).font = componentInChildren.font; } ((TMP_Text)_text).fontSize = 24f; ((TMP_Text)_text).alignment = (TextAlignmentOptions)514; ((Graphic)_text).color = Color.white; ((Graphic)_text).raycastTarget = false; } _root.SetActive(true); } public static void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } public static void SetText(string value) { if ((Object)(object)_text != (Object)null) { ((TMP_Text)_text).text = value; } } } public static class UIHelper { public static GameObject CreateBox(GameObject root, string name, Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) GameObject val = CreateUIObject(name, root); bool? childControlWidth = true; bool? childControlHeight = true; UIHelper.SetLayoutGroup(val, (bool?)null, (bool?)null, childControlWidth, childControlHeight, (int?)null, (int?)null, (int?)null, (int?)null, (int?)null, (TextAnchor?)null); Image val2 = val.AddComponent(); val2.type = (Type)1; ((Graphic)val2).color = color; return val; } public static TextMeshProUGUI CreateText(GameObject root, string name, string text, TMP_FontAsset font = null) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) GameObject val = CreateUIObject(name, root); TextMeshProUGUI val2 = val.AddComponent(); ((TMP_Text)val2).text = text; ((Graphic)val2).color = UIManager.TextColor; ((TMP_Text)val2).font = (Object.op_Implicit((Object)(object)font) ? font : UIManager.DefaultFont); ((TMP_Text)val2).fontSize = 24f; ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; RectTransform component = val.GetComponent(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; return val2; } public static ButtonControl CreateButton(GameObject root, string name, string text) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0058: 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_009b: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown GameObject val = CreateUIObject(name, root, new Vector2(25f, 25f)); GameObject val2 = CreateUIObject("text", val); Button button = val.AddComponent