Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of FakeFriend v1.1.0
FakeFriend.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.AI.Walker; using EntityStates.Railgunner.Reload; using FakeFriend.AI; using Microsoft.CodeAnalysis; using MonoMod.RuntimeDetour; using RoR2; using RoR2.CharacterAI; using RoR2.Navigation; using RoR2.Skills; using RoR2.UI; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FakeFriend")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("FakeFriend")] [assembly: AssemblyTitle("FakeFriend")] [assembly: AssemblyVersion("1.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FakeFriend { internal static class BotBrain { private static readonly FieldInfo PrimaryField = OverrideField("newPrimarySkill"); private static readonly FieldInfo SecondaryField = OverrideField("newSecondarySkill"); private static readonly FieldInfo UtilityField = OverrideField("newUtilitySkill"); private static readonly FieldInfo SpecialField = OverrideField("newSpecialSkill"); public static void Setup(CharacterMaster master, string bodyName, bool keepOwnAi) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_0136: Invalid comparison between Unknown and I4 master.destroyOnBodyDeath = false; BaseAI component = ((Component)master).GetComponent<BaseAI>(); if (!Object.op_Implicit((Object)(object)component)) { return; } AiSkillHelper aiSkillHelper = AiSkillHelperCatalog.Create(bodyName); if (aiSkillHelper != null) { keepOwnAi = false; } else { master.onBodyStart += ApplyAiSkillOverrides; aiSkillHelper = new DefaultSkillHelper(); } component.fullVision = true; component.neverRetaliateFriendlies = true; component.copyLeaderTarget = true; component.aimVectorDampTime = 0.01f; component.aimVectorMaxSpeed = 180f; component.enemyAttentionDuration = 5f; component.scanState = new SerializableEntityStateType(typeof(Wander)); List<AISkillDriver> list = new List<AISkillDriver>(); AISkillDriver val = ((Component)master).gameObject.AddComponent<AISkillDriver>(); val.customName = "FakeFriend.FarLeash"; val.skillSlot = (SkillSlot)(-1); val.moveTargetType = (TargetType)2; val.minDistance = BotSettings.LeashDistance.Value * 2f; val.movementType = (MovementType)1; val.aimType = (AimType)4; val.buttonPressType = (ButtonPressType)1; val.shouldSprint = true; val.resetCurrentEnemyOnNextDriverSelection = true; val.driverUpdateTimerOverride = 3f; list.Add(val); AISkillDriver[] skillDrivers; if (keepOwnAi) { skillDrivers = component.skillDrivers; foreach (AISkillDriver val2 in skillDrivers) { if (Object.op_Implicit((Object)(object)val2) && (int)val2.moveTargetType != 2) { list.Add(val2); } } } else { skillDrivers = ((Component)master).GetComponents<AISkillDriver>(); foreach (AISkillDriver val3 in skillDrivers) { if ((Object)(object)val3 != (Object)(object)val) { Object.DestroyImmediate((Object)(object)val3); } } } HashSet<AISkillDriver> hashSet = new HashSet<AISkillDriver>(((Component)master).GetComponents<AISkillDriver>()); aiSkillHelper.InjectSkills(((Component)master).gameObject, component); skillDrivers = ((Component)master).GetComponents<AISkillDriver>(); foreach (AISkillDriver item in skillDrivers) { if (!hashSet.Contains(item)) { list.Add(item); } } component.ReplaceSkillDrivers(list.ToArray()); ((Component)master).gameObject.AddComponent<BotController>().Init(aiSkillHelper); } public static void ApplyAiSkillOverrides(CharacterBody body) { DoppelgangerSkillOverride val = (Object.op_Implicit((Object)(object)body) ? ((Component)body).GetComponent<DoppelgangerSkillOverride>() : null); SkillLocator val2 = (Object.op_Implicit((Object)(object)body) ? body.skillLocator : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { Override(val2.primary, val, PrimaryField, body); Override(val2.secondary, val, SecondaryField, body); Override(val2.utility, val, UtilityField, body); Override(val2.special, val, SpecialField, body); } } private static FieldInfo OverrideField(string name) { return typeof(DoppelgangerSkillOverride).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } private static void Override(GenericSkill slot, DoppelgangerSkillOverride overrides, FieldInfo field, CharacterBody body) { if (Object.op_Implicit((Object)(object)slot) && field != null) { object? value = field.GetValue(overrides); SkillDef val = (SkillDef)((value is SkillDef) ? value : null); if (val != null && Object.op_Implicit((Object)(object)val)) { slot.SetSkillOverride((object)((Component)body).gameObject, val, (SkillOverridePriority)3); } } } public static void SetLeader(CharacterMaster master, CharacterBody leader) { GameObject gameObject = (Object.op_Implicit((Object)(object)leader) ? ((Component)leader).gameObject : null); BaseAI[] aiComponents = master.AiComponents; foreach (BaseAI val in aiComponents) { if (Object.op_Implicit((Object)(object)val) && val.leader != null) { val.leader.gameObject = gameObject; } } } } internal sealed class BotItems { private const float SyncInterval = 0.5f; private const float ForgetLossAfter = 5f; private static readonly ItemTier[] RandomTiers; private float timer; private ItemMode lastMode; private readonly Dictionary<ItemTier, int> matched = new Dictionary<ItemTier, int>(); private readonly Dictionary<ItemTier, float> lowerSince = new Dictionary<ItemTier, float>(); private readonly Dictionary<ItemTier, int> hostCounts = new Dictionary<ItemTier, int>(); private readonly List<ItemIndex> pool = new List<ItemIndex>(); public void Reset() { timer = 0f; matched.Clear(); lowerSince.Clear(); lastMode = BotSettings.Items.Value; } public void FixedUpdate(CharacterMaster bot, CharacterMaster host, float deltaTime) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) timer -= deltaTime; if (timer > 0f || !Object.op_Implicit((Object)(object)bot) || !Object.op_Implicit((Object)(object)bot.inventory) || !Object.op_Implicit((Object)(object)host) || !Object.op_Implicit((Object)(object)host.inventory)) { return; } timer = 0.5f; ItemMode value = BotSettings.Items.Value; if (value != lastMode) { matched.Clear(); lowerSince.Clear(); if (value == ItemMode.RandomSameTier && lastMode == ItemMode.CopyHost) { CountTiers(host.inventory); foreach (KeyValuePair<ItemTier, int> hostCount in hostCounts) { matched[hostCount.Key] = hostCount.Value; } } lastMode = value; } switch (value) { case ItemMode.CopyHost: CopyFrom(host.inventory, bot.inventory); break; case ItemMode.RandomSameTier: MatchTiers(host.inventory, bot.inventory); break; default: Clear(bot.inventory); break; } } public static bool IsAllowed(ItemIndex index) { //IL_0000: 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) //IL_001e: Invalid comparison between Unknown and I4 ItemDef itemDef = ItemCatalog.GetItemDef(index); if (!Object.op_Implicit((Object)(object)itemDef) || itemDef.hidden || (int)itemDef.tier == 5) { return false; } if (itemDef.ContainsTag((ItemTag)13) || itemDef.ContainsTag((ItemTag)9) || itemDef.ContainsTag((ItemTag)10) || itemDef.ContainsTag((ItemTag)18) || itemDef.ContainsTag((ItemTag)17) || itemDef.ContainsTag((ItemTag)33)) { return false; } if ((Object)(object)itemDef != (Object)(object)Items.ExtraLife && (Object)(object)itemDef != (Object)(object)Items.ExtraLifeConsumed && (Object)(object)itemDef != (Object)(object)Items.ExtraLifeVoid) { return (Object)(object)itemDef != (Object)(object)Items.ExtraLifeVoidConsumed; } return false; } private static void CopyFrom(Inventory source, Inventory target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0014: 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_002f: Unknown result type (might be due to invalid IL or missing references) for (ItemIndex val = (ItemIndex)0; (int)val < ItemCatalog.itemCount; val = (ItemIndex)(val + 1)) { if (IsAllowed(val)) { int num = source.GetItemCountPermanent(val) - target.GetItemCountPermanent(val); if (num > 0) { target.GiveItemPermanent(val, num); } else if (num < 0) { target.RemoveItemPermanent(val, -num); } } } } private static void Clear(Inventory target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) for (ItemIndex val = (ItemIndex)0; (int)val < ItemCatalog.itemCount; val = (ItemIndex)(val + 1)) { if (IsAllowed(val)) { int itemCountPermanent = target.GetItemCountPermanent(val); if (itemCountPermanent > 0) { target.RemoveItemPermanent(val, itemCountPermanent); } } } } private void CountTiers(Inventory host) { //IL_000c: 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_0057: Invalid comparison between Unknown and I4 //IL_000f: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) hostCounts.Clear(); for (ItemIndex val = (ItemIndex)0; (int)val < ItemCatalog.itemCount; val = (ItemIndex)(val + 1)) { if (IsAllowed(val)) { int itemCountPermanent = host.GetItemCountPermanent(val); if (itemCountPermanent > 0) { ItemTier tier = ItemCatalog.GetItemDef(val).tier; hostCounts.TryGetValue(tier, out var value); hostCounts[tier] = value + itemCountPermanent; } } } } private void MatchTiers(Inventory host, Inventory bot) { //IL_0017: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_00ad: Unknown result type (might be due to invalid IL or missing references) CountTiers(host); ItemTier[] randomTiers = RandomTiers; foreach (ItemTier val in randomTiers) { hostCounts.TryGetValue(val, out var value); matched.TryGetValue(val, out var value2); if (value > value2) { GiveRandom(bot, val, value - value2); matched[val] = value; lowerSince.Remove(val); } else if (value < value2) { if (!lowerSince.TryGetValue(val, out var value3)) { lowerSince[val] = Time.time; } else if (Time.time - value3 > 5f) { matched[val] = value; lowerSince.Remove(val); } } else { lowerSince.Remove(val); } } } private void GiveRandom(Inventory bot, ItemTier tier, int count) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0035: Invalid comparison between Unknown and I4 //IL_0038: 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) pool.Clear(); List<PickupIndex> list = DropList(tier); if (list != null) { foreach (PickupIndex item in list) { PickupDef pickupDef = PickupCatalog.GetPickupDef(item); if (pickupDef != null && (int)pickupDef.itemIndex != -1 && IsAllowed(pickupDef.itemIndex)) { pool.Add(pickupDef.itemIndex); } } } if (pool.Count != 0) { for (int i = 0; i < count; i++) { bot.GiveItemPermanent(pool[Random.Range(0, pool.Count)], 1); } } } private static List<PickupIndex> DropList(ItemTier tier) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown Run instance = Run.instance; return (int)tier switch { 0 => instance.availableTier1DropList, 1 => instance.availableTier2DropList, 2 => instance.availableTier3DropList, 4 => instance.availableBossDropList, 3 => instance.availableLunarItemDropList, 6 => instance.availableVoidTier1DropList, 7 => instance.availableVoidTier2DropList, 8 => instance.availableVoidTier3DropList, 9 => instance.availableVoidBossDropList, _ => null, }; } static BotItems() { ItemTier[] array = new ItemTier[9]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); RandomTiers = (ItemTier[])(object)array; } } internal sealed class BotManager { private const float SpawnDelay = 1f; private const float FarGracePeriod = 3f; private CharacterMaster master; private string spawnedSignature; private string spawnedName; private float readyTimer; private float farTimer; private float deadSince = -1f; private int stageId; private int deathStageId; private bool snapPending; private readonly BotItems items = new BotItems(); public CharacterMaster Master => master; public bool IsOutdated { get { if (Object.op_Implicit((Object)(object)master)) { return spawnedSignature != BotSettings.Signature; } return false; } } public void Hook() { Run.onRunStartGlobal += OnRunStart; Run.onRunDestroyGlobal += OnRunDestroy; Stage.onServerStageBegin += OnStageBegin; } public void Unhook() { Run.onRunStartGlobal -= OnRunStart; Run.onRunDestroyGlobal -= OnRunDestroy; Stage.onServerStageBegin -= OnStageBegin; if (NetworkServer.active) { Despawn(); } } private void OnRunStart(Run run) { master = null; spawnedSignature = null; readyTimer = 0f; deadSince = -1f; items.Reset(); } private void OnRunDestroy(Run run) { master = null; spawnedSignature = null; } private void OnStageBegin(Stage stage) { stageId++; snapPending = true; farTimer = 0f; readyTimer = 0f; } public void FixedUpdate() { if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance) || Run.instance.isGameOverServer) { return; } if (!BotSettings.Enabled.Value) { if (Object.op_Implicit((Object)(object)master)) { Despawn(); } } else { if (!Object.op_Implicit((Object)(object)Stage.instance) || !StageAllowsBot()) { return; } float fixedDeltaTime = Time.fixedDeltaTime; CharacterMaster host = FindHostMaster(); CharacterBody val = (Object.op_Implicit((Object)(object)master) ? master.GetBody() : null); CharacterBody val2 = FindLeader(val); bool flag = Object.op_Implicit((Object)(object)val2) && !Object.op_Implicit((Object)(object)val2.currentVehicle); if (!Object.op_Implicit((Object)(object)master)) { readyTimer = (flag ? (readyTimer + fixedDeltaTime) : 0f); if (readyTimer >= 1f) { readyTimer = 0f; items.Reset(); Spawn(host, val2, null, null); } return; } items.FixedUpdate(master, host, fixedDeltaTime); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.healthComponent) && val.healthComponent.alive) { deadSince = -1f; BotBrain.SetLeader(master, val2); if (flag) { if (snapPending) { snapPending = false; TeleportNear(val, val2); } else { KeepClose(val, val2, fixedDeltaTime); } } } else { if (master.IsExtraLifePendingServer()) { return; } if (master.lostBodyToDeath) { if (deadSince < 0f) { deadSince = Time.time; deathStageId = stageId; Chat.AddMessage("<style=cIsDamage>" + spawnedName + "</style> died. " + ((BotSettings.RespawnDelay.Value > 0f) ? $"Back in {BotSettings.RespawnDelay.Value:0} s." : "Back next stage.")); } bool num = deathStageId != stageId; bool flag2 = BotSettings.RespawnDelay.Value > 0f && Time.time - deadSince >= BotSettings.RespawnDelay.Value; if (!num && !flag2) { return; } } if (flag) { RespawnNear(val2); } } } } public void Apply() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && Object.op_Implicit((Object)(object)master)) { CharacterBody val = FindLeader(master.GetBody()); if (Object.op_Implicit((Object)(object)val)) { CharacterMaster val2 = master; CharacterBody body = val2.GetBody(); Vector3? at = ((Object.op_Implicit((Object)(object)body) && body.healthComponent.alive) ? new Vector3?(body.footPosition) : ((Vector3?)null)); master = null; Spawn(FindHostMaster(), val, val2.inventory, at); Destroy(val2, effect: false); } } } public void BringToMe() { CharacterBody val = (Object.op_Implicit((Object)(object)master) ? master.GetBody() : null); CharacterBody val2 = FindLeader(val); if (Object.op_Implicit((Object)(object)val) && val.healthComponent.alive && Object.op_Implicit((Object)(object)val2)) { TeleportNear(val, val2); } } public void Despawn() { if (Object.op_Implicit((Object)(object)master)) { Destroy(master, effect: true); } master = null; spawnedSignature = null; } private void Spawn(CharacterMaster host, CharacterBody leader, Inventory carryItemsFrom, Vector3? at) { //IL_006d: 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_008f: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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_0158: 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_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) SurvivorDef val = BotSettings.ResolveSurvivor(); if (!val.CheckRequiredExpansionEnabled((NetworkUser)null)) { Chat.AddMessage("FakeFriend: " + Helpers.Lang(val.displayNameToken, val.cachedName) + " needs a DLC that is off in this run, using Commando instead."); val = SurvivorCatalog.FindSurvivorDef("Commando"); } GameObject bodyPrefab = val.bodyPrefab; CharacterBody component = bodyPrefab.GetComponent<CharacterBody>(); string bodyName = BodyCatalog.GetBodyName(component.bodyIndex); GameObject val2 = (AiSkillHelperCatalog.Has(bodyName) ? null : MasterCatalog.GetMasterPrefab(MasterCatalog.FindAiMasterIndexForBody(component.bodyIndex))); bool keepOwnAi = Object.op_Implicit((Object)(object)val2); if (!Object.op_Implicit((Object)(object)val2)) { val2 = MasterCatalog.FindMasterPrefab("CommandoMonsterMaster"); } if (!Object.op_Implicit((Object)(object)val2)) { FakeFriendPlugin.Log.LogError((object)("No AI master found for " + val.cachedName)); return; } Vector3 val3 = (Vector3)(((??)at) ?? FindSpotNear(leader.footPosition, component)); Vector3 val4 = leader.footPosition - val3; val4.y = 0f; Quaternion rotation = ((((Vector3)(ref val4)).sqrMagnitude > 0.01f) ? Quaternion.LookRotation(val4) : Quaternion.identity); MasterSummon val5 = new MasterSummon { masterPrefab = val2, position = val3, rotation = rotation, teamIndexOverride = (TeamIndex)1, ignoreTeamMemberLimit = true, useAmbientLevel = false, loadout = BotSettings.BuildLoadout(val), preSpawnSetupCallback = delegate(CharacterMaster newMaster) { newMaster.bodyPrefab = bodyPrefab; BotBrain.Setup(newMaster, bodyName, keepOwnAi); if (Object.op_Implicit((Object)(object)host)) { newMaster.minionOwnership.SetOwner(host); } ((Component)newMaster).gameObject.AddComponent<SetDontDestroyOnLoad>(); if (Object.op_Implicit((Object)(object)carryItemsFrom)) { newMaster.inventory.AddItemsFrom(carryItemsFrom, (Func<ItemIndex, bool>)((ItemIndex index) => index != Items.MinionLeash.itemIndex)); } } }; master = val5.Perform(); if (Object.op_Implicit((Object)(object)master)) { spawnedSignature = BotSettings.Signature; spawnedName = Helpers.Lang(val.displayNameToken, val.cachedName); snapPending = false; farTimer = 0f; deadSince = -1f; PlayTeleportEffect(master.GetBody(), val3); if ((Object)(object)carryItemsFrom == (Object)null) { Chat.AddMessage("<style=cIsUtility>FakeFriend</style> joined as <style=cIsUtility>" + spawnedName + "</style>."); } } } private void RespawnNear(CharacterBody leader) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0041: 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_0073: Unknown result type (might be due to invalid IL or missing references) CharacterBody body = (Object.op_Implicit((Object)(object)master.bodyPrefab) ? master.bodyPrefab.GetComponent<CharacterBody>() : null); Vector3 val = FindSpotNear(leader.footPosition, body); CharacterBody body2 = master.Respawn(val, Quaternion.LookRotation(Flat(leader.footPosition - val)), false); snapPending = false; farTimer = 0f; deadSince = -1f; PlayTeleportEffect(body2, val); } private void KeepClose(CharacterBody bot, CharacterBody leader, float deltaTime) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (Vector3.Distance(bot.footPosition, leader.footPosition) < BotSettings.TeleportDistance.Value) { farTimer = 0f; return; } farTimer += deltaTime; if (farTimer >= 3f) { TeleportNear(bot, leader); } } private void TeleportNear(CharacterBody bot, CharacterBody leader) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) Vector3 val = FindSpotNear(leader.footPosition, bot); TeleportHelper.TeleportBody(bot, val, true); PlayTeleportEffect(bot, val); farTimer = 0f; } private static void Destroy(CharacterMaster target, bool effect) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) CharacterBody body = target.GetBody(); if (effect && Object.op_Implicit((Object)(object)body)) { PlayTeleportEffect(body, body.footPosition); } target.DestroyBody(); Object.Destroy((Object)(object)((Component)target).gameObject); } private static bool StageAllowsBot() { SceneInfo instance = SceneInfo.instance; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.sceneDef)) { return !instance.sceneDef.suppressPlayerEntry; } return false; } private static CharacterMaster FindHostMaster() { LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); if (firstLocalUser != null && Object.op_Implicit((Object)(object)firstLocalUser.cachedMaster)) { return firstLocalUser.cachedMaster; } foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.master)) { return instance.master; } } return null; } private static CharacterBody FindLeader(CharacterBody bot) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_009c: Unknown result type (might be due to invalid IL or missing references) CharacterMaster val = FindHostMaster(); CharacterBody val2 = (Object.op_Implicit((Object)(object)val) ? val.GetBody() : null); if (IsAlive(val2)) { return val2; } CharacterBody result = null; float num = float.PositiveInfinity; foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { CharacterBody val3 = ((Object.op_Implicit((Object)(object)instance) && instance.isConnected && Object.op_Implicit((Object)(object)instance.master)) ? instance.master.GetBody() : null); if (IsAlive(val3)) { float num2; if (!Object.op_Implicit((Object)(object)bot)) { num2 = 0f; } else { Vector3 val4 = val3.corePosition - bot.corePosition; num2 = ((Vector3)(ref val4)).sqrMagnitude; } float num3 = num2; if (num3 < num) { result = val3; num = num3; } } } return result; } private static bool IsAlive(CharacterBody body) { if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent)) { return body.healthComponent.alive; } return false; } private static Vector3 FindSpotNear(Vector3 center, CharacterBody body) { //IL_0039: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_00b1: 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_00ae: Unknown result type (might be due to invalid IL or missing references) SceneInfo instance = SceneInfo.instance; bool flag = Object.op_Implicit((Object)(object)body) && body.isFlying; NodeGraph val = (Object.op_Implicit((Object)(object)instance) ? instance.GetNodeGraph((GraphType)(flag ? 1 : 0)) : null); if (!Object.op_Implicit((Object)(object)val)) { return center; } HullMask val2 = (HullMask)(1 << (Object.op_Implicit((Object)(object)body) ? ((int)body.hullClassification) : 0)); List<NodeIndex> list = val.FindNodesInRangeWithFlagConditions(center, 3f, 15f, val2, (NodeFlags)0, (NodeFlags)4, false); if (list.Count == 0) { list = val.FindNodesInRange(center, 0f, 40f, val2); } Vector3 result = default(Vector3); if (list.Count > 0 && val.GetNodePosition(list[Random.Range(0, list.Count)], ref result)) { return result; } return center; } private static Vector3 Flat(Vector3 direction) { //IL_0020: 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) direction.y = 0f; if (!(((Vector3)(ref direction)).sqrMagnitude > 0.01f)) { return Vector3.forward; } return direction; } private static void PlayTeleportEffect(CharacterBody body, Vector3 position) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)Run.instance)) { GameObject teleportEffectPrefab = Run.instance.GetTeleportEffectPrefab(((Component)body).gameObject); if (Object.op_Implicit((Object)(object)teleportEffectPrefab)) { EffectManager.SimpleEffect(teleportEffectPrefab, position, Quaternion.identity, true); } } } public string Status() { if (!Object.op_Implicit((Object)(object)Run.instance)) { if (!BotSettings.Enabled.Value) { return "Off."; } return "Joins when the run starts."; } if (!NetworkServer.active) { return "You are a client: the host's FakeFriend settings are used."; } if (!BotSettings.Enabled.Value) { return "Off."; } if (!Object.op_Implicit((Object)(object)master)) { return "Joining..."; } CharacterBody body = master.GetBody(); if (IsAlive(body)) { return $"{spawnedName} is alive, {body.healthComponent.combinedHealthFraction * 100f:0}% health, level {body.level:0}."; } if (deadSince >= 0f && BotSettings.RespawnDelay.Value > 0f) { float num = BotSettings.RespawnDelay.Value - (Time.time - deadSince); return $"{spawnedName} is dead, back in {Mathf.Max(0f, num):0} s."; } if (!(deadSince >= 0f)) { return "Joining..."; } return spawnedName + " is dead, back next stage."; } } internal sealed class BotPanel { private class Icon { public string Name; public string Subtitle; public string Description; public Texture Texture; public Rect Uv = new Rect(0f, 0f, 1f, 1f); public Color Color = new Color(0.55f, 0.6f, 0.7f); public bool Locked; } private sealed class SurvivorIcon : Icon { public SurvivorDef Def; } private sealed class SkillRow { public string Title; public int Slot; public readonly List<Icon> Variants = new List<Icon>(); } private const int WindowId = 17990; private const float WindowWidth = 470f; private const float ContentWidth = 446f; private const float ScrollbarWidth = 14f; private static readonly string[] ItemModeNames = new string[3] { "Copy mine", "Random, same rarity", "None" }; private static readonly string[] ItemModeHelp = new string[3] { "The bot has the same items as you, kept in sync.", "Whenever you get an item, the bot gets a random one of the same rarity.", "The bot gets no items." }; private readonly BotManager bot; private readonly UiBlocker blocker = new UiBlocker(); private readonly List<Action> queued = new List<Action>(); private readonly List<MPEventSystem> cursorHolders = new List<MPEventSystem>(); private readonly List<Image> cursorImages = new List<Image>(); private readonly Vector3[] cursorCorners = (Vector3[])(object)new Vector3[4]; private List<SurvivorIcon> survivors; private string cachedFor; private readonly List<Icon> skins = new List<Icon>(); private readonly List<SkillRow> skillRows = new List<SkillRow>(); private bool openInRun; private bool inLobby; private bool collapsed; private float lobbyCheckTimer; private Rect windowRect; private Rect drawnWindowRect; private bool positioned; private float guiScale = 1f; private Vector2 survivorScroll; private Vector2 skinScroll; private Icon hovered; public static bool CapturesInput { get; private set; } private bool Visible { get { if (!inLobby) { return openInRun; } return true; } } public BotPanel(BotManager bot) { this.bot = bot; } public void OnKey() { if (inLobby) { collapsed = !collapsed; } else if (Object.op_Implicit((Object)(object)Run.instance)) { SetOpenInRun(!openInRun); } } private void SetOpenInRun(bool open) { if (open == openInRun) { return; } openInRun = open; CapturesInput = open; if (open) { foreach (MPEventSystem readOnlyInstances in MPEventSystem.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances)) { int cursorOpenerCount = readOnlyInstances.cursorOpenerCount; readOnlyInstances.cursorOpenerCount = cursorOpenerCount + 1; cursorHolders.Add(readOnlyInstances); } } return; } foreach (MPEventSystem cursorHolder in cursorHolders) { if (Object.op_Implicit((Object)(object)cursorHolder)) { int cursorOpenerCount = cursorHolder.cursorOpenerCount; cursorHolder.cursorOpenerCount = cursorOpenerCount - 1; } } cursorHolders.Clear(); } public void Destroy() { SetOpenInRun(open: false); blocker.Destroy(); } public void Update() { if (openInRun && !Object.op_Implicit((Object)(object)Run.instance)) { SetOpenInRun(open: false); } lobbyCheckTimer -= Time.unscaledDeltaTime; if (lobbyCheckTimer <= 0f) { lobbyCheckTimer = 0.5f; inLobby = !Object.op_Implicit((Object)(object)Run.instance) && (NetworkServer.active || !NetworkClient.active) && Object.op_Implicit((Object)(object)Object.FindObjectOfType<CharacterSelectController>()); } if (queued.Count > 0) { Action[] array = queued.ToArray(); queued.Clear(); Action[] array2 = array; foreach (Action action in array2) { try { action(); } catch (Exception ex) { FakeFriendPlugin.Log.LogError((object)ex); } } } if (Visible) { EnsureCatalog(); } else { blocker.Hide(); } } private void Queue(Action action) { queued.Add(action); } private void EnsureCatalog() { //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_023c: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) if (survivors == null) { survivors = new List<SurvivorIcon>(); foreach (SurvivorDef orderedSurvivorDef in SurvivorCatalog.orderedSurvivorDefs) { if (Object.op_Implicit((Object)(object)orderedSurvivorDef) && !orderedSurvivorDef.hidden && BotSettings.IsUsable(orderedSurvivorDef)) { CharacterBody component = orderedSurvivorDef.bodyPrefab.GetComponent<CharacterBody>(); bool flag = AiSkillHelperCatalog.Has(BodyCatalog.GetBodyName(component.bodyIndex)); bool flag2 = MasterCatalog.FindAiMasterIndexForBody(component.bodyIndex) != MasterIndex.none; bool flag3 = orderedSurvivorDef.CheckLocalUserHasRequiredEntitlement(); survivors.Add(new SurvivorIcon { Def = orderedSurvivorDef, Name = Helpers.Lang(orderedSurvivorDef.displayNameToken, orderedSurvivorDef.cachedName), Subtitle = Helpers.Lang(component.subtitleNameToken, ""), Description = ((!flag3) ? "You don't own the DLC for this survivor." : (flag ? "Hand-tuned AI for this survivor (from PlayerBots)." : (flag2 ? "Uses the AI that came with this survivor's mod." : "No AI made for this survivor: the bot uses a generic one, so it plays simpler."))), Texture = component.portraitIcon, Color = orderedSurvivorDef.primaryColor, Locked = !flag3 }); } } } if (cachedFor == BotSettings.Survivor.Value) { return; } cachedFor = BotSettings.Survivor.Value; skins.Clear(); skillRows.Clear(); SurvivorDef val = BotSettings.ResolveSurvivor(); if (!Object.op_Implicit((Object)(object)val)) { return; } CharacterBody component2 = val.bodyPrefab.GetComponent<CharacterBody>(); BodyIndex bodyIndex = component2.bodyIndex; SkinDef[] bodySkinDefs = SkinCatalog.GetBodySkinDefs(bodyIndex); foreach (SkinDef val2 in bodySkinDefs) { Icon icon = new Icon { Name = Helpers.Lang(Object.op_Implicit((Object)(object)val2) ? val2.nameToken : null, Object.op_Implicit((Object)(object)val2) ? ((Object)val2).name : "?"), Subtitle = "Skin" }; SetSprite(icon, Object.op_Implicit((Object)(object)val2) ? val2.icon : null); skins.Add(icon); } GenericSkill[] array = BodyCatalog.GetBodyPrefabSkillSlots(bodyIndex) ?? Array.Empty<GenericSkill>(); SkillLocator component3 = ((Component)component2).GetComponent<SkillLocator>(); for (int j = 0; j < array.Length; j++) { GenericSkill val3 = array[j]; if (!Object.op_Implicit((Object)(object)val3) || val3.hideInLoadoutSelect || !Object.op_Implicit((Object)(object)val3.skillFamily) || val3.skillFamily.variants.Length <= 1) { continue; } SkillRow skillRow = new SkillRow { Slot = j, Title = SlotTitle(val3, component3) }; Variant[] variants = val3.skillFamily.variants; foreach (Variant val4 in variants) { Icon icon2 = new Icon { Subtitle = skillRow.Title }; if (Object.op_Implicit((Object)(object)val4.skillDef)) { icon2.Name = Helpers.Lang(val4.skillDef.skillNameToken, val4.skillDef.skillName); icon2.Description = Helpers.StripTags(Helpers.Lang(val4.skillDef.skillDescriptionToken, "")); SetSprite(icon2, val4.skillDef.icon); } else { icon2.Name = "?"; } skillRow.Variants.Add(icon2); } skillRows.Add(skillRow); } } private static string SlotTitle(GenericSkill slot, SkillLocator locator) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected I4, but got Unknown if (!string.IsNullOrWhiteSpace(slot.loadoutTitleToken)) { return Helpers.Lang(slot.loadoutTitleToken, "Skill"); } SkillSlot val = (SkillSlot)((!Object.op_Implicit((Object)(object)locator)) ? (-1) : ((int)locator.FindSkillSlot(slot))); return (int)val switch { 0 => Helpers.Lang("LOADOUT_SKILL_PRIMARY", "Primary"), 1 => Helpers.Lang("LOADOUT_SKILL_SECONDARY", "Secondary"), 2 => Helpers.Lang("LOADOUT_SKILL_UTILITY", "Utility"), 3 => Helpers.Lang("LOADOUT_SKILL_SPECIAL", "Special"), _ => Helpers.Lang("LOADOUT_SKILL_MISC", "Misc"), }; } private static void SetSprite(Icon icon, Sprite sprite) { //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) if (Object.op_Implicit((Object)(object)sprite) && Object.op_Implicit((Object)(object)sprite.texture)) { icon.Texture = (Texture)(object)sprite.texture; icon.Uv = Helpers.SpriteUv(sprite); } } public void OnGUI() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_012a: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Invalid comparison between Unknown and I4 //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) if (Visible && survivors != null) { Styles.Init(); float num = (float)Screen.height / 1080f * BotSettings.UiScale.Value; num = Mathf.Max(Mathf.Min(num, (float)Screen.width / 490f), 0.3f); Matrix4x4 matrix = GUI.matrix; GUISkin skin = GUI.skin; GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f)); GUI.skin = Styles.Skin; float num2 = (float)Screen.width / num; float num3 = (float)Screen.height / num; if (!positioned) { windowRect = new Rect(num2 - 470f - 24f, num3 * 0.11f, 470f, 0f); positioned = true; } guiScale = num; drawnWindowRect = windowRect; windowRect = GUILayout.Window(17990, new Rect(((Rect)(ref windowRect)).x, ((Rect)(ref windowRect)).y, 470f, 0f), new WindowFunction(DrawWindow), GUIContent.none, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(470f) }); ((Rect)(ref windowRect)).x = Mathf.Clamp(((Rect)(ref windowRect)).x, 0f, Mathf.Max(0f, num2 - ((Rect)(ref windowRect)).width)); ((Rect)(ref windowRect)).y = Mathf.Clamp(((Rect)(ref windowRect)).y, 0f, Mathf.Max(0f, num3 - ((Rect)(ref windowRect)).height)); if ((int)Event.current.type == 7) { blocker.Show(new Rect(((Rect)(ref windowRect)).x * num, ((Rect)(ref windowRect)).y * num, ((Rect)(ref windowRect)).width * num, ((Rect)(ref windowRect)).height * num)); } GUI.matrix = matrix; GUI.skin = skin; } } private void DrawWindow(int id) { //IL_01d0: Unknown result type (might be due to invalid IL or missing references) hovered = null; bool flag = NetworkServer.active || !NetworkClient.active; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("FakeFriend", Styles.Title, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }); GUILayout.FlexibleSpace(); if (GUILayout.Button(BotSettings.Enabled.Value ? "BOT ON" : "BOT OFF", BotSettings.Enabled.Value ? Styles.SwitchOn : Styles.SwitchOff, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(92f), GUILayout.Height(28f) })) { Queue(delegate { BotSettings.Enabled.Value = !BotSettings.Enabled.Value; }); } if (GUILayout.Button(collapsed ? "Show" : "Hide", Styles.Small, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(60f), GUILayout.Height(28f) })) { Queue(delegate { collapsed = !collapsed; }); } if (openInRun && GUILayout.Button("X", Styles.Small, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(32f), GUILayout.Height(28f) })) { Queue(delegate { SetOpenInRun(open: false); }); } GUILayout.EndHorizontal(); if (!collapsed) { if (!flag) { GUILayout.Label("You are a client: only the host's bot joins the game, so these settings do nothing here.", Styles.Banner, Array.Empty<GUILayoutOption>()); } DrawSurvivors(); DrawSkins(); DrawSkills(); DrawItems(); DrawFooter(); if (openInRun && flag) { DrawRunButtons(); } } DrawGameCursor(); GUI.DragWindow(new Rect(0f, 0f, 470f, 40f)); } private void DrawSurvivors() { SurvivorDef current = BotSettings.ResolveSurvivor(); string text = (Object.op_Implicit((Object)(object)current) ? Helpers.Lang(current.displayNameToken, current.cachedName) : "?"); GUILayout.Label("Character <color=#969ca8>" + text + "</color>", Styles.Header, Array.Empty<GUILayoutOption>()); int num = DrawGrid(survivors.Count, (int i) => survivors[i], (int i) => (Object)(object)survivors[i].Def == (Object)(object)current, 61f, 80f, labels: true, 2.5f, ref survivorScroll); if (num >= 0 && !survivors[num].Locked) { SurvivorDef def = survivors[num].Def; Queue(delegate { BotSettings.SelectSurvivor(def); }); } } private void DrawSkins() { if (skins.Count <= 1) { return; } int selected = ((BotSettings.Skin.Value >= 0 && BotSettings.Skin.Value < skins.Count) ? BotSettings.Skin.Value : 0); GUILayout.Label("Skin <color=#969ca8>" + skins[selected].Name + "</color>", Styles.Header, Array.Empty<GUILayoutOption>()); int index = DrawGrid(skins.Count, (int i) => skins[i], (int i) => i == selected, 48f, 48f, labels: false, 2f, ref skinScroll); if (index >= 0) { Queue(delegate { BotSettings.Skin.Value = index; }); } } private void DrawSkills() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) if (skillRows.Count == 0) { return; } GUILayout.Label("Skills", Styles.Header, Array.Empty<GUILayoutOption>()); foreach (SkillRow row in skillRows) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(row.Title, Styles.Dim, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(96f), GUILayout.Height(40f) }); uint selected = BotSettings.GetSkill(row.Slot); if (selected >= row.Variants.Count) { selected = 0u; } Vector2 scroll = Vector2.zero; int index = DrawGrid(row.Variants.Count, (int i) => row.Variants[i], (int i) => i == selected, 42f, 42f, labels: false, 0f, ref scroll, 346f); GUILayout.EndHorizontal(); if (index >= 0) { int slot = row.Slot; Queue(delegate { BotSettings.SetSkill(slot, (uint)index); }); } } } private void DrawItems() { GUILayout.Label("Items", Styles.Header, Array.Empty<GUILayoutOption>()); int value = (int)BotSettings.Items.Value; int newMode = GUILayout.Toolbar(value, ItemModeNames, Styles.Tab, Array.Empty<GUILayoutOption>()); if (newMode != value) { Queue(delegate { BotSettings.Items.Value = (ItemMode)newMode; }); } GUILayout.Label(ItemModeHelp[Mathf.Clamp(value, 0, ItemModeHelp.Length - 1)], Styles.Dim, Array.Empty<GUILayoutOption>()); } private void DrawFooter() { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) string text2; string text3; if (hovered != null) { string text = (string.IsNullOrEmpty(hovered.Subtitle) ? "" : (" <size=12><color=#7d8494>" + hovered.Subtitle + "</color></size>")); text2 = "<color=#" + ColorUtility.ToHtmlStringRGB(hovered.Color) + ">" + hovered.Name + "</color>" + text; text3 = (string.IsNullOrEmpty(hovered.Description) ? " " : hovered.Description); } else { text2 = bot.Status(); text3 = (Object.op_Implicit((Object)(object)Run.instance) ? $"{BotSettings.PanelKey.Value} shows or hides this panel." : $"The bot joins next to you when the run starts. {BotSettings.PanelKey.Value} opens this panel during the run."); } GUILayout.BeginVertical(Styles.Panel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(70f) }); GUILayout.Label(text2, Styles.FooterTitle, Array.Empty<GUILayoutOption>()); GUILayout.Label(text3, Styles.FooterText, Array.Empty<GUILayoutOption>()); GUILayout.EndVertical(); } private void DrawRunButtons() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUI.enabled = bot.IsOutdated; if (GUILayout.Button(bot.IsOutdated ? "Apply changes (respawns the bot)" : "Bot is up to date", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { Queue(bot.Apply); } CharacterBody val = (Object.op_Implicit((Object)(object)bot.Master) ? bot.Master.GetBody() : null); GUI.enabled = Object.op_Implicit((Object)(object)val) && val.healthComponent.alive; if (GUILayout.Button("Bring to me", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(120f), GUILayout.Height(30f) })) { Queue(bot.BringToMe); } GUI.enabled = true; GUILayout.EndHorizontal(); } private int DrawGrid(int count, Func<int, Icon> iconAt, Func<int, bool> isSelected, float cellWidth, float cellHeight, bool labels, float maxRows, ref Vector2 scroll, float width = 446f) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0089: 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_00e6: 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_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Invalid comparison between Unknown and I4 //IL_0192: 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) Event current = Event.current; int result = -1; int num = Mathf.Max(1, Mathf.FloorToInt((width - 14f) / cellWidth)); int num2 = (count + num - 1) / num; float num3 = Mathf.Max((float)num2 * cellHeight, 1f); bool flag = maxRows > 0f && (float)num2 > maxRows; float num4 = (flag ? (maxRows * cellHeight) : num3); if (flag) { scroll = GUILayout.BeginScrollView(scroll, false, true, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(num4), GUILayout.Width(width) }); } Rect rect = GUILayoutUtility.GetRect((float)num * cellWidth, num3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(false) }); float num5 = (flag ? scroll.y : float.NegativeInfinity); float num6 = (flag ? (scroll.y + num4) : float.PositiveInfinity); bool flag2 = current.mousePosition.y >= num5 && current.mousePosition.y <= num6; Rect rect2 = default(Rect); for (int i = 0; i < count; i++) { int num7 = i / num; int num8 = i % num; ((Rect)(ref rect2))..ctor(((Rect)(ref rect)).x + (float)num8 * cellWidth + 2f, ((Rect)(ref rect)).y + (float)num7 * cellHeight + 2f, cellWidth - 4f, cellHeight - 4f); if (((Rect)(ref rect2)).yMax < num5 || ((Rect)(ref rect2)).y > num6) { continue; } Icon icon = iconAt(i); bool flag3 = flag2 && ((Rect)(ref rect2)).Contains(current.mousePosition); if (flag3) { hovered = icon; if ((int)current.type == 0 && current.button == 0) { result = i; current.Use(); } } if ((int)current.type == 7) { DrawCell(rect2, icon, labels, flag3, isSelected(i)); } } if (flag) { GUILayout.EndScrollView(); } return result; } private static void DrawCell(Rect rect, Icon icon, bool label, bool hover, bool selected) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0015: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_019e: 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) Texture2D whiteTexture = Texture2D.whiteTexture; Color color = GUI.color; Color color2 = icon.Color; GUI.color = (hover ? Styles.CellHover : Styles.CellBg); GUI.DrawTexture(rect, (Texture)(object)whiteTexture); GUI.color = new Color(color2.r, color2.g, color2.b, icon.Locked ? 0.05f : 0.15f); GUI.DrawTexture(rect, (Texture)(object)whiteTexture); GUI.color = (Color)(icon.Locked ? new Color(1f, 1f, 1f, 0.3f) : Color.white); if (label) { float num = Mathf.Min(((Rect)(ref rect)).width - 10f, ((Rect)(ref rect)).height - 28f); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).center.x - num / 2f, ((Rect)(ref rect)).y + 4f, num, num); if (Object.op_Implicit((Object)(object)icon.Texture)) { GUI.DrawTextureWithTexCoords(val, icon.Texture, icon.Uv, true); } GUI.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref val)).yMax + 1f, ((Rect)(ref rect)).width, ((Rect)(ref rect)).yMax - ((Rect)(ref val)).yMax - 2f), icon.Name, Styles.CellLabel); } else if (Object.op_Implicit((Object)(object)icon.Texture)) { GUI.DrawTextureWithTexCoords(Helpers.Inset(rect, 3f), icon.Texture, icon.Uv, true); } else { GUI.Label(rect, icon.Name, Styles.CellLabel); } if (selected) { Helpers.DrawBorder(rect, Styles.Accent, 2f); } else if (hover) { Helpers.DrawBorder(rect, new Color(1f, 1f, 1f, 0.45f), 1f); } GUI.color = color; } private void DrawGameCursor() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_0181: Unknown result type (might be due to invalid IL or missing references) if ((int)Event.current.type != 7) { return; } Color color = GUI.color; foreach (MPEventSystem readOnlyInstances in MPEventSystem.readOnlyInstancesList) { if (!Object.op_Implicit((Object)(object)readOnlyInstances) || !readOnlyInstances.isCursorVisible) { continue; } CursorIndicatorController componentInChildren = ((Component)readOnlyInstances).GetComponentInChildren<CursorIndicatorController>(); if (!Object.op_Implicit((Object)(object)componentInChildren)) { continue; } ((Component)componentInChildren).GetComponentsInChildren<Image>(false, cursorImages); foreach (Image cursorImage in cursorImages) { if (((Behaviour)cursorImage).enabled && Object.op_Implicit((Object)(object)cursorImage.sprite)) { Canvas canvas = ((Graphic)cursorImage).canvas; Camera obj = ((Object.op_Implicit((Object)(object)canvas) && (int)canvas.renderMode != 0) ? canvas.worldCamera : null); ((Graphic)cursorImage).rectTransform.GetWorldCorners(cursorCorners); Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, cursorCorners[0]); Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, cursorCorners[2]); Rect val3 = new Rect(val.x / guiScale - ((Rect)(ref drawnWindowRect)).x, ((float)Screen.height - val2.y) / guiScale - ((Rect)(ref drawnWindowRect)).y, (val2.x - val.x) / guiScale, (val2.y - val.y) / guiScale); GUI.color = ((Graphic)cursorImage).color; GUI.DrawTextureWithTexCoords(val3, (Texture)(object)cursorImage.sprite.texture, Helpers.SpriteUv(cursorImage.sprite), true); } } } GUI.color = color; } } internal enum ItemMode { CopyHost, RandomSameTier, None } internal static class BotSettings { public static ConfigEntry<bool> Enabled; public static ConfigEntry<string> Survivor; public static ConfigEntry<int> Skin; public static ConfigEntry<string> Skills; public static ConfigEntry<ItemMode> Items; public static ConfigEntry<float> RespawnDelay; public static ConfigEntry<float> LeashDistance; public static ConfigEntry<float> TeleportDistance; public static ConfigEntry<KeyboardShortcut> PanelKey; public static ConfigEntry<float> UiScale; public static string Signature => Survivor.Value + "|" + Skin.Value + "|" + Skills.Value; public static void Bind(ConfigFile config) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_014c: 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 Enabled = config.Bind<bool>("Bot", "Enabled", true, "Turns the bot on or off. Can also be switched in the character select screen or in-run panel."); Survivor = config.Bind<string>("Bot", "Survivor", "Commando", "Internal name of the bot's survivor (SurvivorDef name, e.g. Commando, Huntress, Merc)."); Skin = config.Bind<int>("Bot", "Skin", 0, "Skin index of the bot's survivor (0 = default)."); Skills = config.Bind<string>("Bot", "Skills", "", "Skill variant per loadout slot, comma separated (e.g. 0,1,0,0). Empty = defaults."); Items = config.Bind<ItemMode>("Bot", "Items", ItemMode.RandomSameTier, "CopyHost: same items as the host. RandomSameTier: a random item of the same rarity whenever the host gets one. None: no items."); RespawnDelay = config.Bind<float>("Bot", "Respawn delay", 0f, new ConfigDescription("Seconds until a dead bot comes back. 0 = it waits for the next stage, like a real co-op player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), Array.Empty<object>())); LeashDistance = config.Bind<float>("Behaviour", "Leash distance", 60f, new ConfigDescription("If the bot gets further than this from you (meters) and has nothing to shoot, it runs back. At twice this distance it runs back even mid-fight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 200f), Array.Empty<object>())); TeleportDistance = config.Bind<float>("Behaviour", "Teleport distance", 120f, new ConfigDescription("If the bot stays further than this from you for a few seconds, it teleports next to you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 1000f), Array.Empty<object>())); PanelKey = config.Bind<KeyboardShortcut>("General", "Panel key", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Opens the FakeFriend panel during a run (in the character select screen it is always visible)."); UiScale = config.Bind<float>("General", "UI scale", 1f, new ConfigDescription("Panel size. 1 = sized for 1080p and scaled with your resolution.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2.5f), Array.Empty<object>())); } public static SurvivorDef ResolveSurvivor() { SurvivorDef val = SurvivorCatalog.FindSurvivorDef(Survivor.Value); if (IsUsable(val)) { return val; } val = SurvivorCatalog.FindSurvivorDef("Commando"); if (!IsUsable(val)) { return SurvivorCatalog.defaultSurvivor; } return val; } public static bool IsUsable(SurvivorDef def) { if (Object.op_Implicit((Object)(object)def) && Object.op_Implicit((Object)(object)def.bodyPrefab)) { return Object.op_Implicit((Object)(object)def.bodyPrefab.GetComponent<CharacterBody>()); } return false; } public static void SelectSurvivor(SurvivorDef def) { if (IsUsable(def) && !(def.cachedName == Survivor.Value)) { Survivor.Value = def.cachedName; Skin.Value = 0; Skills.Value = ""; } } public static uint[] ParseSkills() { List<uint> list = new List<uint>(); string[] array = (Skills.Value ?? "").Split(','); foreach (string text in array) { list.Add(uint.TryParse(text.Trim(), out var result) ? result : 0u); } return list.ToArray(); } public static void SetSkill(int slot, uint variant) { uint[] array = ParseSkills(); if (array.Length <= slot) { Array.Resize(ref array, slot + 1); } array[slot] = variant; Skills.Value = string.Join(",", Array.ConvertAll(array, (uint v) => v.ToString())); } public static uint GetSkill(int slot) { uint[] array = ParseSkills(); if (slot >= array.Length) { return 0u; } return array[slot]; } public static Loadout BuildLoadout(SurvivorDef def) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0018: 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_003f: 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) Loadout val = new Loadout(); BodyIndex val2 = BodyCatalog.FindBodyIndex(def.bodyPrefab); if ((int)val2 == -1) { return val; } int bodySkinCount = SkinCatalog.GetBodySkinCount(val2); if (Skin.Value > 0 && Skin.Value < bodySkinCount) { val.bodyLoadoutManager.SetSkinIndex(val2, (uint)Skin.Value); } GenericSkill[] array = BodyCatalog.GetBodyPrefabSkillSlots(val2) ?? Array.Empty<GenericSkill>(); uint[] array2 = ParseSkills(); for (int i = 0; i < array.Length && i < array2.Length; i++) { SkillFamily val3 = (Object.op_Implicit((Object)(object)array[i]) ? array[i].skillFamily : null); if (Object.op_Implicit((Object)(object)val3) && array2[i] < val3.variants.Length) { val.bodyLoadoutManager.SetSkillVariant(val2, i, array2[i]); } } return val; } } [BepInPlugin("Jirka.FakeFriend", "FakeFriend", "1.1.0")] public class FakeFriendPlugin : BaseUnityPlugin { public const string PluginGUID = "Jirka.FakeFriend"; public const string PluginName = "FakeFriend"; public const string PluginVersion = "1.1.0"; internal static ManualLogSource Log; private BotManager bot; private BotPanel panel; private Hook isUIFocusedHook; private string lastError; private void Awake() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; BotSettings.Bind(((BaseUnityPlugin)this).Config); bot = new BotManager(); bot.Hook(); panel = new BotPanel(bot); isUIFocusedHook = new Hook((MethodBase)typeof(LocalUser).GetProperty("isUIFocused").GetGetMethod(), typeof(FakeFriendPlugin).GetMethod("LocalUser_get_isUIFocused", BindingFlags.Static | BindingFlags.NonPublic)); } private void OnDestroy() { Hook obj = isUIFocusedHook; if (obj != null) { obj.Dispose(); } bot.Unhook(); panel.Destroy(); } private void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = BotSettings.PanelKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { panel.OnKey(); } panel.Update(); } private void FixedUpdate() { try { bot.FixedUpdate(); } catch (Exception ex) { string text = ex.ToString(); if (text != lastError) { lastError = text; Log.LogError((object)ex); } } } private void OnGUI() { panel.OnGUI(); } private static bool LocalUser_get_isUIFocused(Func<LocalUser, bool> orig, LocalUser self) { if (!BotPanel.CapturesInput) { return orig(self); } return true; } } internal static class Helpers { private static readonly Regex TagRegex = new Regex("<[^>]*>", RegexOptions.Compiled); public static string Lang(string token, string fallback) { if (string.IsNullOrEmpty(token)) { return fallback; } string text = Language.GetString(token); if (!string.IsNullOrEmpty(text) && !(text == token)) { return text; } return fallback; } public static string StripTags(string text) { if (!string.IsNullOrEmpty(text)) { return TagRegex.Replace(text, ""); } return text; } public static Rect SpriteUv(Sprite sprite) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_004a: 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_006f: Unknown result type (might be due to invalid IL or missing references) Texture texture = (Texture)(object)sprite.texture; try { Rect textureRect = sprite.textureRect; return new Rect(((Rect)(ref textureRect)).x / (float)texture.width, ((Rect)(ref textureRect)).y / (float)texture.height, ((Rect)(ref textureRect)).width / (float)texture.width, ((Rect)(ref textureRect)).height / (float)texture.height); } catch (Exception) { return new Rect(0f, 0f, 1f, 1f); } } public static Rect Inset(Rect rect, float amount) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new Rect(((Rect)(ref rect)).x + amount, ((Rect)(ref rect)).y + amount, ((Rect)(ref rect)).width - amount * 2f, ((Rect)(ref rect)).height - amount * 2f); } public static void DrawBorder(Rect rect, Color color, float thickness) { //IL_0006: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) Texture2D whiteTexture = Texture2D.whiteTexture; GUI.color = color; GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, thickness), (Texture)(object)whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - thickness, ((Rect)(ref rect)).width, thickness), (Texture)(object)whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), (Texture)(object)whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - thickness, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), (Texture)(object)whiteTexture); } } internal static class Styles { public static readonly Color Accent = Color32.op_Implicit(new Color32((byte)110, (byte)200, (byte)245, byte.MaxValue)); public static readonly Color Text = Color32.op_Implicit(new Color32((byte)230, (byte)232, (byte)236, byte.MaxValue)); public static readonly Color TextDim = Color32.op_Implicit(new Color32((byte)150, (byte)156, (byte)168, byte.MaxValue)); public static readonly Color TextDark = Color32.op_Implicit(new Color32((byte)16, (byte)22, (byte)28, byte.MaxValue)); public static readonly Color CellBg = Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)13)); public static readonly Color CellHover = Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)34)); public static readonly Color On = Color32.op_Implicit(new Color32((byte)120, (byte)214, (byte)110, byte.MaxValue)); public static readonly Color Off = Color32.op_Implicit(new Color32((byte)210, (byte)90, (byte)80, byte.MaxValue)); public static GUIStyle Title; public static GUIStyle Header; public static GUIStyle Label; public static GUIStyle Dim; public static GUIStyle Panel; public static GUIStyle Tab; public static GUIStyle Small; public static GUIStyle SwitchOn; public static GUIStyle SwitchOff; public static GUIStyle CellLabel; public static GUIStyle FooterTitle; public static GUIStyle FooterText; public static GUIStyle Banner; public static GUISkin Skin { get; private set; } public static void Init() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_0148: 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_015b: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0249: 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_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0276: 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_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Expected O, but got Unknown //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Expected O, but got Unknown //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Expected O, but got Unknown //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Expected O, but got Unknown //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Expected O, but got Unknown //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Expected O, but got Unknown //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Expected O, but got Unknown //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Expected O, but got Unknown //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Expected O, but got Unknown //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Expected O, but got Unknown //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Expected O, but got Unknown //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Expected O, but got Unknown //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Expected O, but got Unknown //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Expected O, but got Unknown //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Expected O, but got Unknown //IL_04ac: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Expected O, but got Unknown //IL_04db: Expected O, but got Unknown //IL_04f4: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Expected O, but got Unknown //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_054c: Expected O, but got Unknown //IL_0556: Unknown result type (might be due to invalid IL or missing references) //IL_055b: Unknown result type (might be due to invalid IL or missing references) //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_0568: Unknown result type (might be due to invalid IL or missing references) //IL_0572: Expected O, but got Unknown //IL_0577: Expected O, but got Unknown //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_059b: Unknown result type (might be due to invalid IL or missing references) //IL_05a0: Unknown result type (might be due to invalid IL or missing references) //IL_05af: Unknown result type (might be due to invalid IL or missing references) //IL_05b5: Unknown result type (might be due to invalid IL or missing references) //IL_05bf: Unknown result type (might be due to invalid IL or missing references) //IL_05d9: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Expected O, but got Unknown //IL_0607: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0614: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_0621: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_0659: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Expected O, but got Unknown //IL_0687: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_0694: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06a2: Unknown result type (might be due to invalid IL or missing references) //IL_06a9: Unknown result type (might be due to invalid IL or missing references) //IL_06ae: Unknown result type (might be due to invalid IL or missing references) //IL_06b8: Expected O, but got Unknown //IL_06b8: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Expected O, but got Unknown //IL_06c8: Expected O, but got Unknown //IL_06d2: Unknown result type (might be due to invalid IL or missing references) //IL_06d7: Unknown result type (might be due to invalid IL or missing references) //IL_06df: Unknown result type (might be due to invalid IL or missing references) //IL_06e6: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_06fc: Expected O, but got Unknown //IL_0701: Expected O, but got Unknown //IL_070b: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0718: Unknown result type (might be due to invalid IL or missing references) //IL_071f: Unknown result type (might be due to invalid IL or missing references) //IL_0726: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Unknown result type (might be due to invalid IL or missing references) //IL_0735: Expected O, but got Unknown //IL_0735: Unknown result type (might be due to invalid IL or missing references) //IL_073b: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Expected O, but got Unknown //IL_0754: Unknown result type (might be due to invalid IL or missing references) //IL_0759: Unknown result type (might be due to invalid IL or missing references) //IL_0761: Unknown result type (might be due to invalid IL or missing references) //IL_0768: Unknown result type (might be due to invalid IL or missing references) //IL_076f: Unknown result type (might be due to invalid IL or missing references) //IL_0774: Unknown result type (might be due to invalid IL or missing references) //IL_077e: Expected O, but got Unknown //IL_077e: Unknown result type (might be due to invalid IL or missing references) //IL_078f: Unknown result type (might be due to invalid IL or missing references) //IL_079f: Unknown result type (might be due to invalid IL or missing references) //IL_07ae: Unknown result type (might be due to invalid IL or missing references) //IL_07c8: Unknown result type (might be due to invalid IL or missing references) //IL_07cd: Unknown result type (might be due to invalid IL or missing references) //IL_07dc: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)Skin)) { Texture2D background = Bordered(new Color32((byte)17, (byte)19, (byte)25, (byte)240), new Color32((byte)52, (byte)57, (byte)72, byte.MaxValue)); Texture2D background2 = Bordered(new Color32((byte)26, (byte)29, (byte)37, byte.MaxValue), new Color32((byte)42, (byte)46, (byte)58, byte.MaxValue)); Texture2D background3 = Bordered(new Color32((byte)40, (byte)44, (byte)56, byte.MaxValue), new Color32((byte)56, (byte)61, (byte)77, byte.MaxValue)); Texture2D background4 = Bordered(new Color32((byte)52, (byte)57, (byte)72, byte.MaxValue), new Color32((byte)80, (byte)86, (byte)104, byte.MaxValue)); Texture2D background5 = Solid(Color32.op_Implicit(Accent)); Texture2D background6 = Solid(new Color32((byte)150, (byte)220, byte.MaxValue, byte.MaxValue)); Texture2D background7 = Solid(new Color32((byte)11, (byte)12, (byte)16, (byte)180)); Texture2D background8 = Solid(new Color32((byte)72, (byte)78, (byte)96, byte.MaxValue)); Skin = Object.Instantiate<GUISkin>(GUI.skin); ((Object)Skin).hideFlags = (HideFlags)61; Skin.customStyles = (GUIStyle[])(object)new GUIStyle[0]; GUISkin skin = Skin; GUIStyle val = new GUIStyle { border = new RectOffset(1, 1, 1, 1), padding = new RectOffset(12, 12, 10, 12) }; val.normal.background = background; val.onNormal.background = background; skin.window = val; GUISkin skin2 = Skin; GUIStyle val2 = new GUIStyle { fontSize = 14, alignment = (TextAnchor)3, padding = new RectOffset(2, 2, 3, 3), margin = new RectOffset(2, 2, 2, 2), richText = true, wordWrap = true }; val2.normal.textColor = Text; skin2.label = val2; GUISkin skin3 = Skin; GUIStyle val3 = new GUIStyle { fontSize = 14, alignment = (TextAnchor)4, border = new RectOffset(1, 1, 1, 1), padding = new RectOffset(10, 10, 6, 6), margin = new RectOffset(2, 2, 2, 2), clipping = (TextClipping)1 }; val3.normal.background = background3; val3.normal.textColor = Text; val3.hover.background = background4; val3.hover.textColor = Color.white; val3.active.background = background5; val3.active.textColor = TextDark; val3.onNormal.background = background5; val3.onNormal.textColor = TextDark; val3.onHover.background = background6; val3.onHover.textColor = TextDark; val3.onActive.background = background5; val3.onActive.textColor = TextDark; skin3.button = val3; GUISkin skin4 = Skin; GUIStyle val4 = new GUIStyle { border = new RectOffset(1, 1, 1, 1), padding = new RectOffset(8, 8, 6, 8), margin = new RectOffset(2, 2, 4, 4) }; val4.normal.background = background2; skin4.box = val4; GUISkin skin5 = Skin; GUIStyle val5 = new GUIStyle { fixedWidth = 8f, margin = new RectOffset(4, 0, 0, 0) }; val5.normal.background = background7; skin5.verticalScrollbar = val5; GUISkin skin6 = Skin; GUIStyle val6 = new GUIStyle { fixedWidth = 8f }; val6.normal.background = background8; val6.hover.background = background5; val6.active.background = background5; skin6.verticalScrollbarThumb = val6; Skin.verticalScrollbarUpButton = new GUIStyle { fixedWidth = 0f, fixedHeight = 0f }; Skin.verticalScrollbarDownButton = new GUIStyle { fixedWidth = 0f, fixedHeight = 0f }; Skin.horizontalScrollbar = new GUIStyle { fixedHeight = 0f }; Skin.horizontalScrollbarThumb = new GUIStyle { fixedHeight = 0f }; Skin.horizontalScrollbarLeftButton = new GUIStyle { fixedWidth = 0f, fixedHeight = 0f }; Skin.horizontalScrollbarRightButton = new GUIStyle { fixedWidth = 0f, fixedHeight = 0f }; Skin.scrollView = new GUIStyle(); GUIStyle val7 = new GUIStyle(Skin.label) { fontSize = 20, fontStyle = (FontStyle)1, wordWrap = false }; val7.normal.textColor = Accent; Title = val7; Header = new GUIStyle(Skin.label) { fontSize = 14, fontStyle = (FontStyle)1, wordWrap = false, margin = new RectOffset(2, 2, 6, 2) }; Label = Skin.label; GUIStyle val8 = new GUIStyle(Skin.label) { fontSize = 13 }; val8.normal.textColor = TextDim; Dim = val8; Panel = Skin.box; Tab = new GUIStyle(Skin.button) { fontSize = 13, fixedHeight = 28f }; Small = new GUIStyle(Skin.button) { fontSize = 13, padding = new RectOffset(8, 8, 4, 4) }; GUIStyle val9 = new GUIStyle(Skin.button) { fontSize = 14, fontStyle = (FontStyle)1 }; val9.normal.background = Solid(Color32.op_Implicit(On)); val9.normal.textColor = TextDark; val9.hover.background = Solid(new Color32((byte)150, (byte)232, (byte)140, byte.MaxValue)); val9.hover.textColor = TextDark; SwitchOn = val9; GUIStyle val10 = new GUIStyle(Skin.button) { fontSize = 14, fontStyle = (FontStyle)1 }; val10.normal.background = Solid(Color32.op_Implicit(Off)); val10.normal.textColor = Color.white; val10.hover.background = Solid(new Color32((byte)232, (byte)116, (byte)104, byte.MaxValue)); val10.hover.textColor = Color.white; SwitchOff = val10; CellLabel = new GUIStyle(Skin.label) { fontSize = 11, alignment = (TextAnchor)1, wordWrap = true, clipping = (TextClipping)1, padding = new RectOffset(2, 2, 0, 0), margin = new RectOffset() }; FooterTitle = new GUIStyle(Skin.label) { fontS