using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HG; using HG.Reflection; using IL.RoR2; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using On.RoR2.Items; using On.RoR2.Networking; using On.RoR2.UI; using On.RoR2.UI.LogBook; using R2API; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Artifacts; using RoR2.ConVar; using RoR2.ExpansionManagement; using RoR2.Items; using RoR2.Navigation; using RoR2.Networking; using RoR2.Orbs; using RoR2.Skills; using RoR2.UI; using RoR2.UI.LogBook; using ShareSuite; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("TILER2")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9444eb382ea4bcecc9e4621588809737e35f3a37")] [assembly: AssemblyProduct("TILER2")] [assembly: AssemblyTitle("TILER2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace TILER2; public static class Compat_RiskOfOptions { public struct OptionIdentityStrings { public string category; public string name; public string description; public string modName; public string modGuid; } private static bool? _enabled; public static bool enabled { get { if (!_enabled.HasValue) { _enabled = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); } return _enabled.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void SetupMod(string modGuid, string modName, string description, Sprite icon = null) { ModSettingsManager.SetModDescription(description, modGuid, modName); if ((Object)(object)icon != (Object)null) { ModSettingsManager.SetModIcon(icon, modGuid, modName); } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_CheckBox(ConfigEntry configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(configEntry, new CheckBoxConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Slider(ConfigEntry configEntry, OptionIdentityStrings ident, float min, float max, string formatString, bool restartRequired, Func isDisabledDelegate) { //IL_0010: 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_0021: 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_0034: 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_0043: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_006e: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new SliderOption(configEntry, new SliderConfig { category = ident.category, name = ident.name, max = max, min = min, formatString = formatString, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_IntSlider(ConfigEntry configEntry, OptionIdentityStrings ident, int min, int max, string formatString, bool restartRequired, Func isDisabledDelegate) { //IL_0010: 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_0021: 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_0034: 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_0043: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_006e: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new IntSliderOption(configEntry, new IntSliderConfig { category = ident.category, name = ident.name, max = max, min = min, formatString = formatString, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Choice(ConfigEntryBase configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new ChoiceOption(configEntry, new ChoiceConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Keybind(ConfigEntry configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new KeyBindOption(configEntry, new KeyBindConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_String(ConfigEntry configEntry, OptionIdentityStrings ident, bool restartRequired, Func isDisabledDelegate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0056: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(configEntry, new InputFieldConfig { category = ident.category, name = ident.name, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_StepSlider(ConfigEntry configEntry, OptionIdentityStrings ident, float min, float max, float step, string formatString, bool restartRequired, Func isDisabledDelegate) { //IL_0010: 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_0021: 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_0034: 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_0043: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0076: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new StepSliderOption(configEntry, new StepSliderConfig { category = ident.category, name = ident.name, min = min, max = max, formatString = formatString, increment = step, restartRequired = restartRequired, description = ident.description, checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate()) }), ident.modGuid, ident.modName); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOption_Button(OptionIdentityStrings ident, string text, UnityAction del) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new GenericButtonOption(ident.name, ident.category, ident.description, text, del), ident.modGuid, ident.modName); } } public static class Compat_ShareSuite { private static bool? _enabled; public static bool enabled { get { if (!_enabled.HasValue) { _enabled = Chainloader.PluginInfos.ContainsKey("com.funkfrog_sipondo.sharesuite"); } return _enabled.Value; } } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void GiveMoney(uint amount) { MoneySharingHooks.AddMoneyExternal((int)amount); } [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static bool MoneySharing() { if (ShareSuite.MoneyIsShared.Value) { return true; } return false; } } [RequireComponent(typeof(Inventory))] public class FakeInventory : NetworkBehaviour { internal class FakeInventoryModule : T2Module { public override void SetupConfig() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown base.SetupConfig(); NetworkingAPI.RegisterMessageType(); Inventory.GetItemCount_ItemIndex += new hook_GetItemCount_ItemIndex(On_InvGetItemCountByIndex); LunarItemOrEquipmentCostTypeHelper.IsAffordable += new hook_IsAffordable(LunarItemOrEquipmentCostTypeHelper_IsAffordable); Inventory.HasAtLeastXTotalItemsOfTier += new hook_HasAtLeastXTotalItemsOfTier(Inventory_HasAtLeastXTotalItemsOfTier); Inventory.GetTotalItemCountOfTier += new hook_GetTotalItemCountOfTier(Inventory_GetTotalItemCountOfTier); StolenInventoryInfo.StealItem += new hook_StealItem(StolenInventoryInfo_StealItem); RunReport.Generate += new hook_Generate(RunReport_Generate); ShrineCleanseBehavior.CleanseInventoryServer += new hook_CleanseInventoryServer(ShrineCleanseBehavior_CleanseInventoryServer); ShrineCleanseBehavior.InventoryIsCleansable += new hook_InventoryIsCleansable(ShrineCleanseBehavior_InventoryIsCleansable); Util.GetItemCountForTeam += new hook_GetItemCountForTeam(Util_GetItemCountForTeam); PickupPickerController.GetGeneratedOptionsFromInteractor += new Manipulator(PickupPickerController_GetGeneratedOptionsFromInteractor); ContagiousItemManager.StepInventoryInfection += new hook_StepInventoryInfection(ContagiousItemManager_StepInventoryInfection); ContagiousItemManager.OnInventoryChangedGlobal += new hook_OnInventoryChangedGlobal(ContagiousItemManager_OnInventoryChangedGlobal); SuppressedItemManager.OnInventoryChangedGlobal += new hook_OnInventoryChangedGlobal(SuppressedItemManager_OnInventoryChangedGlobal); SuppressedItemManager.SuppressItem += new hook_SuppressItem(SuppressedItemManager_SuppressItem); SuppressedItemManager.TransformItem += new hook_TransformItem(SuppressedItemManager_TransformItem); CharacterMaster.TryCloverVoidUpgrades += new hook_TryCloverVoidUpgrades(CharacterMaster_TryCloverVoidUpgrades); ArtifactTrialMissionController.RemoveAllMissionKeys += new hook_RemoveAllMissionKeys(ArtifactTrialMissionController_RemoveAllMissionKeys); StolenInventoryInfo.TakeItemFromLendee += new hook_TakeItemFromLendee(StolenInventoryInfo_TakeItemFromLendee); StolenInventoryInfo.TakeBackItemsFromLendee += new hook_TakeBackItemsFromLendee(StolenInventoryInfo_TakeBackItemsFromLendee); LunarSunBehavior.FixedUpdate += new hook_FixedUpdate(LunarSunBehavior_FixedUpdate); CostTypeDef.IsAffordable += new hook_IsAffordable(CostTypeDef_IsAffordable); Run.FixedUpdate += new hook_FixedUpdate(Run_FixedUpdate); ItemInventoryDisplay.UpdateDisplay += new hook_UpdateDisplay(On_IIDUpdateDisplay); ItemInventoryDisplay.OnInventoryChanged += new hook_OnInventoryChanged(On_IIDInventoryChanged); } } protected struct MsgSyncAll : INetMessage, ISerializableObject { private NetworkInstanceId _ownerNetId; private int[] _itemsToSync; public void Serialize(NetworkWriter writer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) writer.Write(_ownerNetId); NetworkExtensions.WriteItemStacks(writer, _itemsToSync); } public void Deserialize(NetworkReader reader) { //IL_0003: 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) _ownerNetId = reader.ReadNetworkId(); _itemsToSync = new int[ItemCatalog.itemCount]; NetworkExtensions.ReadItemStacks(reader, _itemsToSync); } public void OnReceived() { //IL_0002: 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) GameObject val = Util.FindNetworkObject(_ownerNetId); if (!Object.op_Implicit((Object)(object)val)) { TILER2Plugin._logger.LogWarning((object)$"FakeInventory.MsgSyncAll received for missing NetworkObject with ID {_ownerNetId}"); return; } FakeInventory fakeInventory = val.GetComponent(); if (!Object.op_Implicit((Object)(object)fakeInventory)) { fakeInventory = val.AddComponent(); } fakeInventory._itemStacks = _itemsToSync; if (NetworkServer.active) { ((NetworkBehaviour)fakeInventory.inventory).SetDirtyBit(1u); ((NetworkBehaviour)fakeInventory.inventory).SetDirtyBit(8u); } MulticastDelegate multicastDelegate = (MulticastDelegate)Reflection.GetFieldCached(typeof(Inventory), "onInventoryChanged").GetValue(fakeInventory.inventory); Delegate[] invocationList = multicastDelegate.GetInvocationList(); foreach (Delegate obj in invocationList) { obj.Method.Invoke(obj.Target, null); } } public MsgSyncAll(NetworkInstanceId ownerNetId, int[] itemsToSync) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) _ownerNetId = ownerNetId; _itemsToSync = itemsToSync; } } private int[] _itemStacks = ItemCatalog.RequestItemStackArray(); public readonly ReadOnlyCollection itemStacks; private static Dictionary instancesByInventory = new Dictionary(); public static ReadOnlyDictionary readOnlyInstancesByInventory = new ReadOnlyDictionary(instancesByInventory); internal static ManualLogSource _logger; public static HashSet blacklist = new HashSet(); private bool itemsDirty = false; public static int ignoreFakes = 0; public Inventory inventory { get; private set; } public FakeInventory() { itemStacks = new ReadOnlyCollection(_itemStacks); } private void OnDestroy() { instancesByInventory.Remove(inventory); ItemCatalog.ReturnItemStackArray(_itemStacks); } private void DeltaItem(ItemIndex ind, int count) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) if (!blacklist.Contains(ItemCatalog.GetItemDef(ind))) { _itemStacks[ind] = Mathf.Max(_itemStacks[ind] + count, 0); itemsDirty = true; } } public void GiveItem(ItemIndex ind, int count = 1) { //IL_0030: 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) if (!NetworkServer.active) { return; } if (count <= 0) { if (count < 0) { RemoveItem(ind, -count); } } else { DeltaItem(ind, count); } } public void RemoveItem(ItemIndex ind, int count = 1) { //IL_0030: 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) if (!NetworkServer.active) { return; } if (count <= 0) { if (count < 0) { GiveItem(ind, -count); } } else { DeltaItem(ind, -count); } } public int GetItemCount(ItemIndex ind) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected I4, but got Unknown return ArrayUtils.GetSafe(_itemStacks, (int)ind); } public int GetRealItemCount(ItemIndex ind) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected I4, but got Unknown return ArrayUtils.GetSafe(_itemStacks, (int)ind); } public int GetAdjustedItemCount(ItemIndex ind) { //IL_0007: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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) ItemIndex transformedItemIndex = ContagiousItemManager.GetTransformedItemIndex(ind); IEnumerable source = ((IEnumerable)(object)ContagiousItemManager.transformationInfos).Where((TransformationInfo x) => x.transformedItem == ind); bool flag = (int)transformedItemIndex != -1; bool flag2 = source.Count() > 0; int realItemCount = GetRealItemCount(ind); if (flag && GetRealItemCount(transformedItemIndex) > 0) { return realItemCount; } if (flag2 && realItemCount > 0) { return realItemCount + source.Sum((TransformationInfo x) => GetItemCount(x.originalItem)) + GetItemCount(ind); } return realItemCount + GetItemCount(ind); } private void Awake() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) inventory = ((Component)this).GetComponent(); if (instancesByInventory.ContainsKey(inventory)) { TILER2Plugin._logger.LogError((object)("Inventory on object " + ((Object)((Component)inventory).gameObject).name + " already has a FakeInventory assigned, can't add another!")); Object.Destroy((Object)(object)this); return; } instancesByInventory[inventory] = this; if (NetworkServer.active) { NetworkInstanceId netId = ((NetworkBehaviour)this).netId; if (((NetworkInstanceId)(ref netId)).Value != 0) { NetMessageExtensions.Send((INetMessage)(object)new MsgSyncAll(((NetworkBehaviour)this).netId, _itemStacks), (NetworkDestination)1); } } } private void Update() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (itemsDirty && NetworkServer.active) { NetworkInstanceId netId = ((NetworkBehaviour)this).netId; if (((NetworkInstanceId)(ref netId)).Value != 0) { NetMessageExtensions.Send((INetMessage)(object)new MsgSyncAll(((NetworkBehaviour)this).netId, _itemStacks), (NetworkDestination)1); itemsDirty = false; } } } private static void Run_FixedUpdate(orig_FixedUpdate orig, Run self) { orig.Invoke(self); if (ignoreFakes != 0) { TILER2Plugin._logger.LogError((object)$"FakeInventory ignoreFakes count = {ignoreFakes} on new frame (!= 0, very bad!), clearing"); ignoreFakes = 0; } } private static void StolenInventoryInfo_TakeBackItemsFromLendee(orig_TakeBackItemsFromLendee orig, StolenInventoryInfo self) { ignoreFakes++; orig.Invoke(self); ignoreFakes--; } private static void LunarSunBehavior_FixedUpdate(orig_FixedUpdate orig, LunarSunBehavior self) { ignoreFakes++; orig.Invoke(self); ignoreFakes--; } private static int StolenInventoryInfo_TakeItemFromLendee(orig_TakeItemFromLendee orig, StolenInventoryInfo self, ItemIndex itemIndex, int maxStackToTake) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; int result = orig.Invoke(self, itemIndex, maxStackToTake); ignoreFakes--; return result; } private static void ArtifactTrialMissionController_RemoveAllMissionKeys(orig_RemoveAllMissionKeys orig) { ignoreFakes++; orig.Invoke(); ignoreFakes--; } private static void PickupPickerController_GetGeneratedOptionsFromInteractor(ILContext il) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int locIndex = -1; FieldReference val2 = default(FieldReference); val.GotoNext((MoveType)2, new Func[3] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref locIndex), (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, ref val2) && ((MemberReference)val2).Name == "itemDef", (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "canRemove") }); val.Emit(OpCodes.Ldarg_1); val.Emit(OpCodes.Ldloc_S, (byte)locIndex); val.EmitDelegate>((Func)delegate(bool origDoContinue, Interactor iac, ItemDef def) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) bool result = origDoContinue; ignoreFakes++; if (((Component)iac).GetComponent().inventory.GetItemCountPermanent(def.itemIndex) <= 0) { result = false; } ignoreFakes--; return result; }); } private static bool CostTypeDef_IsAffordable(orig_IsAffordable orig, CostTypeDef self, int cost, Interactor activator) { ignoreFakes++; bool result = orig.Invoke(self, cost, activator); ignoreFakes--; return result; } private static int Util_GetItemCountForTeam(orig_GetItemCountForTeam orig, TeamIndex teamIndex, ItemIndex itemIndex, bool requiresAlive, bool requiresConnected) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; int result = orig.Invoke(teamIndex, itemIndex, requiresAlive, requiresConnected); ignoreFakes--; return result; } private static bool ShrineCleanseBehavior_InventoryIsCleansable(orig_InventoryIsCleansable orig, Inventory inventory) { ignoreFakes++; bool result = orig.Invoke(inventory); ignoreFakes--; return result; } private static int ShrineCleanseBehavior_CleanseInventoryServer(orig_CleanseInventoryServer orig, Inventory inventory) { ignoreFakes++; int result = orig.Invoke(inventory); ignoreFakes--; return result; } private static RunReport RunReport_Generate(orig_Generate orig, Run run, GameEndingDef gameEnding) { ignoreFakes++; RunReport result = orig.Invoke(run, gameEnding); ignoreFakes--; return result; } private static int StolenInventoryInfo_StealItem(orig_StealItem orig, StolenInventoryInfo self, ItemIndex itemIndex, int maxStackToSteal, bool? useOrbOverride) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; int result = orig.Invoke(self, itemIndex, maxStackToSteal, useOrbOverride); ignoreFakes--; return result; } private static int Inventory_GetTotalItemCountOfTier(orig_GetTotalItemCountOfTier orig, Inventory self, ItemTier itemTier) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; int result = orig.Invoke(self, itemTier); ignoreFakes--; return result; } private static bool Inventory_HasAtLeastXTotalItemsOfTier(orig_HasAtLeastXTotalItemsOfTier orig, Inventory self, ItemTier itemTier, int x) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; bool result = orig.Invoke(self, itemTier, x); ignoreFakes--; return result; } private static bool LunarItemOrEquipmentCostTypeHelper_IsAffordable(orig_IsAffordable orig, CostTypeDef costTypeDef, IsAffordableContext context) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; bool result = orig.Invoke(costTypeDef, context); ignoreFakes--; return result; } private static bool ContagiousItemManager_StepInventoryInfection(orig_StepInventoryInfection orig, Inventory inventory, ItemIndex originalItem, int limit, bool isForced) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; bool result = orig.Invoke(inventory, originalItem, limit, isForced); ignoreFakes--; return result; } private static void ContagiousItemManager_OnInventoryChangedGlobal(orig_OnInventoryChangedGlobal orig, Inventory inventory) { ignoreFakes++; orig.Invoke(inventory); ignoreFakes--; } private static void SuppressedItemManager_OnInventoryChangedGlobal(orig_OnInventoryChangedGlobal orig, Inventory inventory) { ignoreFakes++; orig.Invoke(inventory); ignoreFakes--; } private static bool SuppressedItemManager_SuppressItem(orig_SuppressItem orig, ItemIndex suppressedIndex, ItemIndex transformedIndex) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; bool result = orig.Invoke(suppressedIndex, transformedIndex); ignoreFakes--; return result; } private static void SuppressedItemManager_TransformItem(orig_TransformItem orig, Inventory inventory, ItemIndex suppressedIndex, ItemIndex transformedIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) ignoreFakes++; orig.Invoke(inventory, suppressedIndex, transformedIndex); ignoreFakes--; } private static void CharacterMaster_TryCloverVoidUpgrades(orig_TryCloverVoidUpgrades orig, CharacterMaster self) { ignoreFakes++; orig.Invoke(self); ignoreFakes--; } private static int On_InvGetItemCountByIndex(orig_GetItemCount_ItemIndex orig, Inventory self, ItemIndex itemIndex) { //IL_0003: 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) int result = orig.Invoke(self, itemIndex); if (ignoreFakes > 0 || !Object.op_Implicit((Object)(object)self)) { return result; } if (readOnlyInstancesByInventory.TryGetValue(self, out var value)) { return value.GetAdjustedItemCount(itemIndex); } return result; } private static void On_IIDInventoryChanged(orig_OnInventoryChanged orig, ItemInventoryDisplay self) { orig.Invoke(self); if (!Object.op_Implicit((Object)(object)self) || !((Behaviour)self).isActiveAndEnabled || !Object.op_Implicit((Object)(object)self.inventory) || !readOnlyInstancesByInventory.TryGetValue(self.inventory, out var value)) { return; } List list = self.itemOrder.Take(self.itemOrderCount).ToList(); for (int i = 0; i < self.itemStacks.Length; i++) { int adjustedItemCount = value.GetAdjustedItemCount((ItemIndex)i); if (self.itemStacks[i] == 0) { if (adjustedItemCount > 0) { list.Add((ItemIndex)i); } else { list.Remove((ItemIndex)i); } } self.itemStacks[i] = adjustedItemCount; } list = list.Distinct().ToList(); list.CopyTo(0, self.itemOrder, 0, Mathf.Min(self.itemOrder.Length, list.Count)); self.itemOrderCount = list.Count; } private static void On_IIDUpdateDisplay(orig_UpdateDisplay orig, ItemInventoryDisplay self) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_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) orig.Invoke(self); Inventory val = self.inventory; if (!Object.op_Implicit((Object)(object)val) || !readOnlyInstancesByInventory.TryGetValue(self.inventory, out var value)) { return; } foreach (ItemIcon itemIcon in self.itemIcons) { int realItemCount = value.GetRealItemCount(itemIcon.itemIndex); int num = value.GetAdjustedItemCount(itemIcon.itemIndex) - realItemCount; SpriteAsNumberManager spriteAsNumberManager = itemIcon.spriteAsNumberManager; spriteAsNumberManager.SetSpriteColor(Color.white); if (num != 0) { spriteAsNumberManager.TrySetup(); spriteAsNumberManager.isVisible = true; List list = new List(); spriteAsNumberManager.LoadListWithDigitPositions(num, ref list, 0); list.Add(-6666); spriteAsNumberManager.LoadListWithDigitPositions(realItemCount, ref list, 0); list.Add(-6666); spriteAsNumberManager.UpdateSpriteObjectsWithListValues(list, 0); for (int i = 0; i <= spriteAsNumberManager.GetTotalDigitPositions(num); i++) { ((Graphic)spriteAsNumberManager.imageList[i]).color = new Color(0.75686276f, 0.56078434f, 0.8784314f); } } } } } [RequireComponent(typeof(NetworkIdentity))] public class ItemWard : NetworkBehaviour { public enum DisplayPerformanceMode { None, OnePerItemIndex, All } internal class ItemWardModule : T2Module { [AutoConfigRoOChoice(null, null)] [AutoConfig("Controls how many item displays are created on ItemWards.", AutoConfigFlags.DeferUntilEndGame, new object[] { })] public DisplayPerformanceMode displayPerformanceMode { get; private set; } = DisplayPerformanceMode.All; public override void SetupConfig() { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) base.SetupConfig(); NetworkingAPI.RegisterMessageType(); NetworkingAPI.RegisterMessageType(); GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load("prefabs/effects/orbeffects/ItemTransferOrbEffect"), "TILER2TempSetupPrefab", false); ((Behaviour)val.GetComponent()).enabled = false; ((Behaviour)val.GetComponent()).enabled = false; ((Behaviour)val.GetComponent()).enabled = false; displayPrefab = PrefabAPI.InstantiateClone(val, "ItemWardDisplay", false); GameObject val2 = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load("Prefabs/NetworkedObjects/WarbannerWard"), "TILER2TempSetupPrefab", false); GameObject gameObject = ((Component)val2.transform.Find("Indicator")).gameObject; gameObject.transform.SetParent((Transform)null); MeshRenderer component = ((Component)gameObject.transform.Find("IndicatorSphere")).gameObject.GetComponent(); ((Renderer)component).material.SetTexture("_RemapTex", (Texture)(object)Addressables.LoadAssetAsync((object)"RoR2/Base/Common/ColorRamps/texRampDefault.png").WaitForCompletion()); ((Renderer)component).material.SetColor("_CutoffScroll", new Color(0.8f, 0.8f, 0.85f)); ((Renderer)component).material.SetColor("_RimColor", new Color(0.8f, 0.8f, 0.85f)); stockIndicatorPrefab = PrefabAPI.InstantiateClone(gameObject, "ItemWardStockIndicator", false); Object.Destroy((Object)(object)val2); Object.Destroy((Object)(object)gameObject); } } protected struct MsgSyncRadius : INetMessage, ISerializableObject { private ItemWard _targetWard; private float _newRadius; public void Serialize(NetworkWriter writer) { writer.Write(((Component)_targetWard).gameObject); writer.Write(_newRadius); } public void Deserialize(NetworkReader reader) { _targetWard = reader.ReadGameObject().GetComponent(); _newRadius = reader.ReadSingle(); } public void OnReceived() { _targetWard._radius = _newRadius; _targetWard.radSq = _newRadius * _newRadius; } public MsgSyncRadius(ItemWard targetWard, float newRadius) { _targetWard = targetWard; _newRadius = newRadius; } } protected struct MsgDeltaDisplay : INetMessage, ISerializableObject { private NetworkInstanceId _ownerNetId; private ItemIndex _itemIndex; private bool _isAdd; public void Serialize(NetworkWriter writer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected I4, but got Unknown writer.Write(_ownerNetId); writer.Write((int)_itemIndex); writer.Write(_isAdd); } public void Deserialize(NetworkReader reader) { //IL_0003: 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_0014: Unknown result type (might be due to invalid IL or missing references) _ownerNetId = reader.ReadNetworkId(); _itemIndex = (ItemIndex)reader.ReadInt32(); _isAdd = reader.ReadBoolean(); } public void OnReceived() { //IL_0002: 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_001e: Unknown result type (might be due to invalid IL or missing references) ItemWard component = Util.FindNetworkObject(_ownerNetId).GetComponent(); if (_isAdd) { component.ClientAddItemDisplay(_itemIndex); } else { component.ClientRemoveItemDisplay(_itemIndex); } } public MsgDeltaDisplay(NetworkInstanceId ownerNetId, ItemIndex itemIndex, bool isAdd) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) _ownerNetId = ownerNetId; _itemIndex = itemIndex; _isAdd = isAdd; } } public static GameObject stockIndicatorPrefab; public static GameObject displayPrefab; public float displayRadiusFracH = 0.5f; public float displayRadiusFracV = 0.3f; public Vector3 displayIndivScale = Vector3.one; public Vector3 displayRadiusOffset = new Vector3(0f, 0f, 0f); public Transform rangeIndicator; public Dictionary itemcounts = new Dictionary(); private const float updateTickRate = 1f; private float stopwatch = 0f; private TeamFilter teamFilter; private TeamComponent teamComponent; private float rangeIndicatorScaleVelocity; private readonly List displays = new List(); private readonly List displayVelocities = new List(); private readonly List displayItems = new List(); private readonly List trackedInventories = new List(); private float _radius = 10f; public float radius { get { return _radius; } set { _radius = value; radSq = _radius * _radius; if (NetworkServer.active) { NetMessageExtensions.Send((INetMessage)(object)new MsgSyncRadius(this, value), (NetworkDestination)1); } } } public float radSq { get; private set; } = 100f; public TeamIndex currentTeam => (TeamIndex)((!Object.op_Implicit((Object)(object)teamFilter)) ? ((!Object.op_Implicit((Object)(object)teamComponent)) ? (-1) : ((int)teamComponent.teamIndex)) : ((int)teamFilter.teamIndex)); private void Awake() { teamFilter = ((Component)this).GetComponent(); teamComponent = ((Component)this).GetComponent(); } private void OnDestroy() { if (!NetworkServer.active) { return; } foreach (GameObject display in displays) { Object.Destroy((Object)(object)display); } } private void OnEnable() { if (Object.op_Implicit((Object)(object)rangeIndicator)) { ((Component)rangeIndicator).gameObject.SetActive(true); } foreach (GameObject display in displays) { display.SetActive(true); } } private void OnDisable() { if (Object.op_Implicit((Object)(object)rangeIndicator)) { ((Component)rangeIndicator).gameObject.SetActive(false); } foreach (GameObject display in displays) { display.SetActive(false); } trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x) || !Object.op_Implicit((Object)(object)((Component)x).gameObject)); for (int num = trackedInventories.Count - 1; num >= 0; num--) { DeregInv(trackedInventories[num]); } } private void Update() { //IL_002c: 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_00e3: 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_00ee: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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) if (NetworkClient.active) { if (Object.op_Implicit((Object)(object)rangeIndicator)) { float num = Mathf.SmoothDamp(rangeIndicator.localScale.x, radius, ref rangeIndicatorScaleVelocity, 0.2f); rangeIndicator.localScale = new Vector3(num, num, num); } float num2 = -0.125f * (MathF.PI * 2f * Time.time); float num3 = MathF.PI * 2f / (float)displays.Count; float num4 = radius * displayRadiusFracH; float num5 = Mathf.Max(radius * displayRadiusFracV, 1f); for (int num6 = displays.Count - 1; num6 >= 0; num6--) { Vector3 val = new Vector3(Mathf.Cos(num3 * (float)num6 + num2) * num4, num5, Mathf.Sin(num3 * (float)num6 + num2) * num4) + displayRadiusOffset; Vector3 value = displayVelocities[num6]; displays[num6].transform.localPosition = Vector3.SmoothDamp(displays[num6].transform.localPosition, val, ref value, 1f); displays[num6].transform.localScale = displayIndivScale; displayVelocities[num6] = value; } } } private void FixedUpdate() { //IL_005f: 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_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) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) stopwatch += Time.fixedDeltaTime; if (!(stopwatch > 1f)) { return; } stopwatch = 0f; trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x) || !Object.op_Implicit((Object)(object)((Component)x).gameObject)); IEnumerable enumerable = from tc in TeamComponent.GetTeamMembers(currentTeam) select tc.body; foreach (CharacterBody item in enumerable) { if (Object.op_Implicit((Object)(object)item)) { Vector3 val = item.transform.position - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= radSq) { RegBody(item); } else { DeregBody(item); } } } } private void RegBody(CharacterBody cb) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = cb.inventory; if (!Object.op_Implicit((Object)(object)inventory) || trackedInventories.Contains(inventory)) { return; } trackedInventories.Add(inventory); if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(inventory, out var value)) { value = ((Component)inventory).gameObject.AddComponent(); } foreach (KeyValuePair itemcount in itemcounts) { value.GiveItem(itemcount.Key, itemcount.Value); } } private void DeregBody(CharacterBody cb) { Inventory inventory = cb.inventory; if (Object.op_Implicit((Object)(object)inventory)) { DeregInv(inventory); } } private void DeregInv(Inventory inv) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (!trackedInventories.Contains(inv)) { return; } if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(inv, out var value)) { TILER2Plugin._logger.LogError((object)("ItemWard.DeregInv: Inventory on object " + ((Object)((Component)inv).gameObject).name + " had its FakeInventory unexpectedly removed")); return; } foreach (KeyValuePair itemcount in itemcounts) { value.RemoveItem(itemcount.Key, itemcount.Value); } trackedInventories.Remove(inv); } public void ServerAddItem(ItemIndex ind) { //IL_0018: 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_003c: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } if (!itemcounts.ContainsKey(ind)) { itemcounts[ind] = 1; } else { itemcounts[ind]++; } trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x)); foreach (Inventory trackedInventory in trackedInventories) { if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(trackedInventory, out var value)) { TILER2Plugin._logger.LogError((object)("ItemWard.ServerAddItem: Inventory on object " + ((Object)((Component)trackedInventory).gameObject).name + " had its FakeInventory unexpectedly removed")); } else { value.GiveItem(ind); } } NetMessageExtensions.Send((INetMessage)(object)new MsgDeltaDisplay(((NetworkBehaviour)this).netId, ind, isAdd: true), (NetworkDestination)1); } public void ServerRemoveItem(ItemIndex ind) { //IL_0018: 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_0033: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !itemcounts.ContainsKey(ind)) { return; } itemcounts[ind]--; if (itemcounts[ind] == 0) { itemcounts.Remove(ind); } NetMessageExtensions.Send((INetMessage)(object)new MsgDeltaDisplay(((NetworkBehaviour)this).netId, ind, isAdd: false), (NetworkDestination)1); trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x) || !Object.op_Implicit((Object)(object)((Component)x).gameObject)); foreach (Inventory trackedInventory in trackedInventories) { if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(trackedInventory, out var value)) { TILER2Plugin._logger.LogError((object)("ItemWard.ServerRemoveItem: Inventory on object " + ((Object)((Component)trackedInventory).gameObject).name + " had its FakeInventory unexpectedly removed")); } else { value.RemoveItem(ind); } } } internal void ClientAddItemDisplay(ItemIndex ind) { //IL_0014: 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_0038: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { if (!itemcounts.ContainsKey(ind)) { itemcounts[ind] = 1; } else { itemcounts[ind]++; } } if (T2Module.instance.displayPerformanceMode != DisplayPerformanceMode.None && (T2Module.instance.displayPerformanceMode != DisplayPerformanceMode.OnePerItemIndex || !displayItems.Contains(ind))) { GameObject val = Object.Instantiate(displayPrefab, ((Component)this).transform.position, ((Component)this).transform.rotation); ((Component)val.transform.Find("BillboardBase").Find("PickupSprite")).GetComponent().sprite = ItemCatalog.GetItemDef(ind).pickupIconSprite; val.transform.parent = ((Component)this).transform; displays.Add(val); displayItems.Add(ind); displayVelocities.Add(new Vector3(0f, 0f, 0f)); } } internal void ClientRemoveItemDisplay(ItemIndex ind) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00a7: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { if (!itemcounts.ContainsKey(ind)) { return; } itemcounts[ind]--; if (itemcounts[ind] == 0) { itemcounts.Remove(ind); } } if (T2Module.instance.displayPerformanceMode != DisplayPerformanceMode.None && (T2Module.instance.displayPerformanceMode != DisplayPerformanceMode.OnePerItemIndex || itemcounts[ind] == 0)) { int index = displayItems.IndexOf(ind); Object.Destroy((Object)(object)displays[index]); displays.RemoveAt(index); displayItems.RemoveAt(index); displayVelocities.RemoveAt(index); } } } public class AutoConfigBinding { public enum DeferType { UpdateImmediately, WaitForNextStage, WaitForRunEnd, NeverAutoUpdate } internal static readonly List instances = new List(); internal static readonly Dictionary stageDirtyInstances = new Dictionary(); internal static readonly Dictionary runDirtyInstances = new Dictionary(); internal bool isOverridden = false; public AutoConfigContainer owner { get; internal set; } public object target { get; internal set; } public ConfigEntryBase configEntry { get; internal set; } public PropertyInfo boundProperty { get; internal set; } public string modName { get; internal set; } public AutoConfigUpdateActionsAttribute updateEventAttribute { get; internal set; } public MethodInfo propGetter { get; internal set; } public MethodInfo propSetter { get; internal set; } public Type propType { get; internal set; } public object boundKey { get; internal set; } public bool onDict { get; internal set; } public bool allowConCmd { get; internal set; } public bool allowNetMismatch { get; internal set; } public bool netMismatchCritical { get; internal set; } public object cachedValue { get; internal set; } public DeferType deferType { get; internal set; } public string readablePath => modName + "/" + configEntry.Definition.Section + "/" + configEntry.Definition.Key; internal static void CleanupDirty(bool isRunEnd) { TILER2Plugin._logger.LogDebug((object)$"Stage ended; applying {stageDirtyInstances.Count} deferred config changes..."); foreach (AutoConfigBinding key in stageDirtyInstances.Keys) { key.DeferredUpdateProperty(stageDirtyInstances[key].Item1, stageDirtyInstances[key].Item2); } stageDirtyInstances.Clear(); if (!isRunEnd) { return; } TILER2Plugin._logger.LogDebug((object)$"Run ended; applying {runDirtyInstances.Count} deferred config changes..."); foreach (AutoConfigBinding key2 in runDirtyInstances.Keys) { key2.DeferredUpdateProperty(runDirtyInstances[key2], silent: true); } runDirtyInstances.Clear(); } internal AutoConfigBinding() { instances.Add(this); } ~AutoConfigBinding() { if (instances.Contains(this)) { instances.Remove(this); } } internal void OverrideProperty(object newValue, bool silent = false) { if (!isOverridden) { runDirtyInstances[this] = cachedValue; } isOverridden = true; UpdateProperty(newValue, silent); } private void DeferredUpdateProperty(object newValue, bool silent = false) { object oldValue = propGetter.Invoke(target, (!onDict) ? new object[0] : new object[1] { boundKey }); propSetter.Invoke(target, (!onDict) ? new object[1] { newValue } : new object[2] { boundKey, newValue }); AutoConfigUpdateActionTypes autoConfigUpdateActionTypes = updateEventAttribute?.flags ?? AutoConfigUpdateActionTypes.None; AutoConfigUpdateActionsAttribute autoConfigUpdateActionsAttribute = updateEventAttribute; if (autoConfigUpdateActionsAttribute != null && !autoConfigUpdateActionsAttribute.ignoreDefault) { autoConfigUpdateActionTypes |= owner.defaultEnabledUpdateFlags; } cachedValue = newValue; owner.OnConfigChanged(new AutoConfigUpdateActionEventArgs { flags = autoConfigUpdateActionTypes, oldValue = oldValue, newValue = newValue, target = this, silent = silent }); } internal void UpdateProperty(object newValue, bool silent = false) { if (NetworkServer.active && !allowNetMismatch) { NetConfigModule.ServerSyncOneToAll(this, newValue); } if (deferType == DeferType.UpdateImmediately || (Object)(object)Run.instance == (Object)null || !((Behaviour)Run.instance).enabled) { DeferredUpdateProperty(newValue, silent); } else if (deferType == DeferType.WaitForNextStage) { stageDirtyInstances[this] = (newValue, silent); } else if (deferType == DeferType.WaitForRunEnd) { runDirtyInstances[this] = newValue; } else { TILER2Plugin._logger.LogWarning((object)("Something attempted to set the value of an AutoConfigBinding with the DeferForever flag: \"" + readablePath + "\"")); } } public static (List results, string errorMsg) FindFromPath(string path1, string path2, string path3) { string p1u = path1.ToUpper(); string p2u = path2?.ToUpper(); string p3u = path3?.ToUpper(); List matchesLevel1 = new List(); List matchesLevel2 = new List(); List matchesLevel3 = new List(); List matchesLevel4 = new List(); instances.ForEach(delegate(AutoConfigBinding x) { if (x.allowConCmd) { string key = x.configEntry.Definition.Key; string text = key.ToUpper(); string section = x.configEntry.Definition.Section; string text2 = section.ToUpper(); string text3 = x.modName; string text4 = text3.ToUpper(); if (path2 == null) { if (text.Contains(p1u) || text2.Contains(p1u) || text4.Contains(p1u)) { matchesLevel1.Add(x); matchesLevel2.Add(x); if (text == p1u) { matchesLevel3.Add(x); if (key == path1) { matchesLevel4.Add(x); } } } } else if (path3 == null) { bool flag = text4.Contains(p1u); bool flag2 = text2.Contains(p1u); bool flag3 = text2.Contains(p2u); bool flag4 = text.Contains(p2u); if ((flag && flag3) || (flag2 && flag4) || (flag && flag4)) { matchesLevel1.Add(x); if (!(flag && flag4)) { matchesLevel2.Add(x); bool flag5 = text3.Contains(path1); bool flag6 = section.Contains(path1); bool flag7 = section.Contains(path2); bool flag8 = key.Contains(path2); if ((flag5 && flag7) || (flag6 && flag8)) { matchesLevel3.Add(x); bool flag9 = text3 == path1; bool flag10 = section == path1; bool flag11 = section == path2; bool flag12 = key == path2; if ((flag9 && flag11) || (flag10 && flag12)) { matchesLevel4.Add(x); } } } } } else if (text.Contains(p3u) && text2.Contains(p2u) && text4.Contains(p1u)) { matchesLevel1.Add(x); matchesLevel2.Add(x); if (text4 == p3u && text2 == p2u && text == p1u) { matchesLevel3.Add(x); if (text3 == path3 && section == path2 && key == path1) { matchesLevel4.Add(x); } } } } }); if (matchesLevel1.Count == 0) { return (results: null, errorMsg: "no level 1 matches"); } if (matchesLevel1.Count == 1) { return (results: matchesLevel1, errorMsg: null); } if (matchesLevel2.Count == 0) { return (results: matchesLevel1, errorMsg: "multiple level 1 matches, no level 2 matches"); } if (matchesLevel2.Count == 1) { return (results: matchesLevel2, errorMsg: null); } if (matchesLevel3.Count == 0) { return (results: matchesLevel2, errorMsg: "multiple level 2 matches, no level 3 matches"); } if (matchesLevel3.Count == 1) { return (results: matchesLevel3, errorMsg: null); } if (matchesLevel4.Count == 0) { return (results: matchesLevel3, errorMsg: "multiple level 3 matches, no level 4 matches"); } if (matchesLevel4.Count == 1) { return (results: matchesLevel4, errorMsg: null); } Debug.LogError((object)("TILER2 AutoConfig: There are multiple config entries with the path \"" + matchesLevel4[0].readablePath + "\"; this should never happen! Please report this as a bug.")); return (results: matchesLevel4, errorMsg: "multiple level 4 matches"); } } public class AutoConfigContainer { public struct BindSubDictInfo { public object key; public object val; public Type keyType; public int index; } protected internal readonly List bindings = new List(); private static readonly Dictionary observedFiles = new Dictionary(); private const float filePollingRate = 10f; private static float filePollingStopwatch = 0f; protected internal virtual AutoConfigUpdateActionTypes defaultEnabledUpdateFlags => AutoConfigUpdateActionTypes.None; public event EventHandler ConfigEntryChanged; public AutoConfigBinding FindConfig(string propName) { return bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == propName && !x.onDict); } public AutoConfigBinding FindConfig(string propName, object dictKey) { return bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == propName && x.onDict && x.boundKey == dictKey); } internal void OnConfigChanged(AutoConfigUpdateActionEventArgs e) { this.ConfigEntryChanged?.Invoke(this, e); Debug.Log((object)$"{e.target.readablePath}: {e.oldValue} > {e.newValue}"); if ((Object)(object)Run.instance != (Object)null && ((Behaviour)Run.instance).isActiveAndEnabled) { if ((e.flags & AutoConfigUpdateActionTypes.InvalidateStats) == AutoConfigUpdateActionTypes.InvalidateStats) { AutoConfigModule.globalStatsDirty = true; } if ((e.flags & AutoConfigUpdateActionTypes.InvalidateDropTable) == AutoConfigUpdateActionTypes.InvalidateDropTable) { AutoConfigModule.globalDropsDirty = true; } if (!e.silent && (e.flags & AutoConfigUpdateActionTypes.AnnounceToRun) == AutoConfigUpdateActionTypes.AnnounceToRun && NetworkServer.active) { NetUtil.ServerSendGlobalChatMsg(Language.GetStringFormatted("TILER2_AUTOCONFIG_ANNOUNCE_CHANGE", new object[3] { e.target.readablePath, e.oldValue, e.newValue })); } } } internal static void FilePollUpdateHook(orig_Update orig, RoR2Application self) { orig.Invoke(self); filePollingStopwatch += Time.unscaledDeltaTime; if (!(filePollingStopwatch >= 10f)) { return; } filePollingStopwatch = 0f; foreach (ConfigFile item in observedFiles.Keys.ToList()) { DateTime lastWriteTime = File.GetLastWriteTime(item.ConfigFilePath); if (observedFiles[item] < lastWriteTime) { observedFiles[item] = lastWriteTime; TILER2Plugin._logger.LogDebug((object)("A config file tracked by AutoItemConfig has been changed: " + item.ConfigFilePath)); item.Reload(); } } } private string ReplaceTags(string orig, PropertyInfo prop, string categoryName, BindSubDictInfo? subDict = null) { return Regex.Replace(orig, "", delegate(Match m) { string value = m.Groups[0].Value; string[] array = Regex.Split(value.Substring(1, value.Length - 1 - 1), "(?= 2) { string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + ": malformed string param \"" + m.Value + "\" "; switch (array[1]) { case "Prop": { if (array.Length < 3) { TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for Prop tag).")); return m.Value; } PropertyInfo property2 = prop.DeclaringType.GetProperty(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property2 == null) { TILER2Plugin._logger.LogWarning((object)(text + "(could not find Prop \"" + array[2] + "\").")); return m.Value; } return property2.GetValue(this).ToString(); } case "Field": { if (array.Length < 3) { TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for Field tag).")); return m.Value; } FieldInfo field2 = prop.DeclaringType.GetField(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 == null) { TILER2Plugin._logger.LogWarning((object)(text + "(could not find Field \"" + array[2] + "\").")); return m.Value; } return field2.GetValue(this).ToString(); } case "DictKey": if (!subDict.HasValue) { TILER2Plugin._logger.LogWarning((object)(text + "(DictKey tag used on non-BindDict).")); return m.Value; } return subDict.Value.key.ToString(); case "DictInd": if (!subDict.HasValue) { TILER2Plugin._logger.LogWarning((object)(text + "(DictInd tag used on non-BindDict).")); return m.Value; } return subDict.Value.index.ToString(); case "DictKeyProp": { if (!subDict.HasValue) { TILER2Plugin._logger.LogWarning((object)(text + "(DictKeyProp tag used on non-BindDict).")); return m.Value; } if (array.Length < 3) { TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for DictKeyProp tag).")); return m.Value; } PropertyInfo property = subDict.Value.key.GetType().GetProperty(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null) { TILER2Plugin._logger.LogWarning((object)(text + "(could not find DictKeyProp \"" + array[2] + "\").")); return m.Value; } return property.GetValue(subDict.Value.key).ToString(); } case "DictKeyField": { if (!subDict.HasValue) { TILER2Plugin._logger.LogWarning((object)(text + "(DictKeyField tag used on non-BindDict).")); return m.Value; } if (array.Length < 3) { TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for DictKeyField tag).")); return m.Value; } FieldInfo field = subDict.Value.key.GetType().GetField(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { TILER2Plugin._logger.LogWarning((object)(text + "(could not find DictKeyField \"" + array[2] + "\").")); return m.Value; } return field.GetValue(subDict.Value.key).ToString(); } default: TILER2Plugin._logger.LogWarning((object)(text + "(unknown tag \"" + array[1] + "\").")); return m.Value; } } return m.Value; }); } public void Bind(PropertyInfo prop, ConfigFile cfl, string modName, string categoryName, AutoConfigAttribute attrib, AutoConfigUpdateActionsAttribute eiattr = null, BindSubDictInfo? subDict = null) { //IL_06c5: Unknown result type (might be due to invalid IL or missing references) //IL_06cb: Expected O, but got Unknown //IL_06e0: Unknown result type (might be due to invalid IL or missing references) //IL_06e6: Expected O, but got Unknown //IL_06eb: Unknown result type (might be due to invalid IL or missing references) //IL_06f5: Expected O, but got Unknown string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + " failed: "; if (!subDict.HasValue) { if (bindings.Exists((AutoConfigBinding x) => x.boundProperty == prop)) { TILER2Plugin._logger.LogError((object)(text + "this property has already been bound.")); return; } if ((attrib.flags & AutoConfigFlags.BindDict) == AutoConfigFlags.BindDict) { if (!prop.PropertyType.GetInterfaces().Any((Type i) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<, >))) { TILER2Plugin._logger.LogError((object)(text + "BindDict flag cannot be used on property types which don't implement IDictionary.")); return; } Type type = prop.PropertyType.GetGenericArguments()[1]; if (attrib.avb != null && attrib.avbType != type) { TILER2Plugin._logger.LogError((object)(text + "dict value and AcceptableValue types must match (received " + type.Name + " and " + attrib.avbType.Name + ").")); return; } if (!TomlTypeConverter.CanConvert(type)) { TILER2Plugin._logger.LogError((object)(text + "dict value type cannot be converted by BepInEx.Configuration.TomlTypeConverter (received " + type.Name + ").")); return; } IDictionary dictionary = (IDictionary)prop.GetValue(this, null); int num = 0; List list = (from object k in dictionary.Keys select (k)).ToList(); if (list.Count == 0) { TILER2Plugin._logger.LogError((object)(text + "BindDict was used on an empty dictionary. All intended keys must be present at time of binding and cannot be added afterwards.")); } { foreach (object item in list) { Bind(prop, cfl, modName, categoryName, attrib, eiattr, new BindSubDictInfo { key = item, val = dictionary[item], keyType = type, index = num }); num++; } return; } } } if (!subDict.HasValue) { if (attrib.avb != null && attrib.avbType != prop.PropertyType) { TILER2Plugin._logger.LogError((object)(text + "property and AcceptableValue types must match (received " + prop.PropertyType.Name + " and " + attrib.avbType.Name + ").")); return; } if (!TomlTypeConverter.CanConvert(prop.PropertyType)) { TILER2Plugin._logger.LogError((object)(text + "property type cannot be converted by BepInEx.Configuration.TomlTypeConverter (received " + prop.PropertyType.Name + ").")); return; } } object obj = (subDict.HasValue ? prop.GetValue(this) : this); IDictionary dictionary2 = (subDict.HasValue ? ((IDictionary)obj) : null); MethodInfo methodInfo = (subDict.HasValue ? dictionary2.GetType().GetProperty("Item").GetGetMethod(nonPublic: true) : (prop.GetGetMethod(nonPublic: true) ?? prop.DeclaringType.GetProperty(prop.Name)?.GetGetMethod(nonPublic: true))); MethodInfo methodInfo2 = (subDict.HasValue ? dictionary2.GetType().GetProperty("Item").GetSetMethod(nonPublic: true) : (prop.GetSetMethod(nonPublic: true) ?? prop.DeclaringType.GetProperty(prop.Name)?.GetSetMethod(nonPublic: true))); Type type2 = (subDict.HasValue ? subDict.Value.keyType : prop.PropertyType); if (methodInfo == null || methodInfo2 == null) { TILER2Plugin._logger.LogError((object)(text + "property (or IDictionary Item property, if using BindDict flag) must have both a getter and a setter.")); return; } string name = attrib.name; if (name != null) { name = ReplaceTags(name, prop, categoryName, subDict); } else { object arg = char.ToUpperInvariant(prop.Name[0]); string name2 = prop.Name; name = string.Format("{0}{1}{2}", arg, name2.Substring(1, name2.Length - 1), subDict.HasValue ? (":" + subDict.Value.index) : ""); } string desc = attrib.desc; desc = ((desc == null) ? ("Automatically generated from a C# " + (subDict.HasValue ? "dictionary " : "") + "property.") : ReplaceTags(desc, prop, categoryName, subDict)); MethodInfo methodInfo3 = typeof(ConfigFile).GetMethods().First((MethodInfo x) => x.Name == "Bind" && x.GetParameters().Length == 3 && x.GetParameters()[0].ParameterType == typeof(ConfigDefinition) && x.GetParameters()[2].ParameterType == typeof(ConfigDescription)).MakeGenericMethod(type2); object obj2 = (subDict.HasValue ? subDict.Value.val : prop.GetValue(this)); bool flag = (attrib.flags & AutoConfigFlags.PreventNetMismatch) != AutoConfigFlags.PreventNetMismatch; bool flag2 = (attrib.flags & AutoConfigFlags.DeferForever) == AutoConfigFlags.DeferForever; bool flag3 = (attrib.flags & AutoConfigFlags.DeferUntilEndGame) == AutoConfigFlags.DeferUntilEndGame; bool flag4 = (attrib.flags & AutoConfigFlags.DeferUntilNextStage) == AutoConfigFlags.DeferUntilNextStage; bool flag5 = (attrib.flags & AutoConfigFlags.PreventConCmd) != AutoConfigFlags.PreventConCmd; if (flag2 && !flag) { desc += "\nWARNING: THIS SETTING CANNOT BE CHANGED WHILE THE GAME IS RUNNING, AND MUST BE SYNCED MANUALLY FOR MULTIPLAYER!"; } ConfigEntryBase cfe = (ConfigEntryBase)methodInfo3.Invoke(cfl, new object[3] { (object)new ConfigDefinition(categoryName, name), obj2, (object)new ConfigDescription(desc, attrib.avb, Array.Empty()) }); observedFiles[cfl] = File.GetLastWriteTime(cfl.ConfigFilePath); AutoConfigBinding newBinding = new AutoConfigBinding { boundProperty = prop, allowConCmd = (flag5 && !flag2 && !flag3), allowNetMismatch = flag, netMismatchCritical = (!flag && flag2), deferType = (flag2 ? AutoConfigBinding.DeferType.NeverAutoUpdate : (flag3 ? AutoConfigBinding.DeferType.WaitForRunEnd : (flag4 ? AutoConfigBinding.DeferType.WaitForNextStage : AutoConfigBinding.DeferType.UpdateImmediately))), configEntry = cfe, modName = modName, owner = this, propGetter = methodInfo, propSetter = methodInfo2, propType = type2, onDict = subDict.HasValue, boundKey = (subDict.HasValue ? subDict.Value.key : null), updateEventAttribute = eiattr, cachedValue = obj2, target = obj }; bindings.Add(newBinding); if (!flag2) { Type type3 = typeof(ConfigEntry<>).MakeGenericType(type2); EventInfo evt = type3.GetEvent("SettingChanged"); evt.ReflAddEventHandler(cfe, delegate { newBinding.UpdateProperty(cfe.BoxedValue); }); } if ((attrib.flags & AutoConfigFlags.NoInitialRead) != AutoConfigFlags.NoInitialRead) { methodInfo2.Invoke(obj, (!subDict.HasValue) ? new object[1] { cfe.BoxedValue } : new object[2] { subDict.Value.key, cfe.BoxedValue }); newBinding.cachedValue = cfe.BoxedValue; } BindRoO(cfe, prop, type2, categoryName, name, desc, flag2, flag3 || flag2); } public void BindRoO(AutoConfigBinding bind, params Attribute[] entryRoOAttributes) { BindRoO(bind.configEntry, bind.boundProperty, bind.propType, bind.configEntry.Definition.Section, bind.configEntry.Definition.Key, bind.configEntry.Description.Description, bind.deferType >= AutoConfigBinding.DeferType.NeverAutoUpdate, bind.deferType >= AutoConfigBinding.DeferType.WaitForRunEnd, entryRoOAttributes); } public void BindRoO(ConfigEntryBase cfe, PropertyInfo prop, Type propType, string categoryName, string cfgName, string cfgDesc, bool deferForever, bool deferRun, params Attribute[] entryRoOAttributes) { if (!Compat_RiskOfOptions.enabled) { return; } string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + " could not apply Risk of Options compat: "; AutoConfigRoOInfoOverridesAttribute customAttribute = GetType().GetCustomAttribute(); AutoConfigRoOInfoOverridesAttribute customAttribute2 = prop.GetCustomAttribute(); if (entryRoOAttributes.Length == 0) { return; } if ((from x in entryRoOAttributes group x by x.GetType()).Any((IGrouping x) => x.Count() > 1)) { TILER2Plugin._logger.LogWarning((object)("AutoConfigContainer.BindRoO on property " + prop.Name + " in category " + categoryName + " has multiple RoO options of the same type")); } string text2 = null; string text3 = null; bool flag = false; if (customAttribute != null) { text2 = customAttribute.modGuid; text3 = customAttribute.modName; flag = true; } else { Assembly assembly = Assembly.GetAssembly(GetType()); Type[] types; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { types = ex.Types; } Type[] array = types; foreach (Type element in array) { BepInPlugin customAttribute3 = ((MemberInfo)element).GetCustomAttribute(); if (customAttribute3 != null) { text2 = customAttribute3.GUID; text3 = customAttribute3.Name; flag = true; break; } } } if (!flag) { TILER2Plugin._logger.LogError((object)(text + "could not find mod info. Declaring type must be in an assembly with a BepInPlugin, or have an AutoConfigContainerRoOInfoAttribute on it.")); return; } Compat_RiskOfOptions.OptionIdentityStrings identStrings = new Compat_RiskOfOptions.OptionIdentityStrings { category = (customAttribute2?.categoryName ?? customAttribute?.categoryName ?? categoryName), name = (customAttribute2?.entryName ?? customAttribute?.entryName ?? cfgName), description = cfgDesc, modGuid = (customAttribute2?.modGuid ?? text2), modName = (customAttribute2?.modName ?? text3) }; for (int num2 = 0; num2 < entryRoOAttributes.Length; num2++) { BaseAutoConfigRoOAttribute baseAutoConfigRoOAttribute = (BaseAutoConfigRoOAttribute)entryRoOAttributes[num2]; if ((baseAutoConfigRoOAttribute.requiredType == typeof(Enum)) ? (!propType.IsEnum) : (propType != baseAutoConfigRoOAttribute.requiredType)) { TILER2Plugin._logger.LogError((object)(text + baseAutoConfigRoOAttribute.GetType().Name + " may only be applied to " + baseAutoConfigRoOAttribute.requiredType.Name + " properties (got " + propType.Name + ").")); } else { baseAutoConfigRoOAttribute.Apply(cfe, identStrings, deferForever, () => (deferRun && Object.op_Implicit((Object)(object)Run.instance)) ? true : false); } } } internal void BindRoO(ConfigEntryBase cfe, PropertyInfo prop, Type propType, string categoryName, string cfgName, string cfgDesc, bool deferForever, bool deferRun) { if (Compat_RiskOfOptions.enabled) { Attribute[] entryRoOAttributes = prop.GetCustomAttributes().ToArray(); BindRoO(cfe, prop, propType, categoryName, cfgName, cfgDesc, deferForever, deferRun, entryRoOAttributes); } } public void BindAll(ConfigFile cfl, string modName, string categoryName) { PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { AutoConfigAttribute customAttribute = propertyInfo.GetCustomAttribute(inherit: true); if (customAttribute != null) { Bind(propertyInfo, cfl, modName, categoryName, customAttribute, propertyInfo.GetCustomAttribute(inherit: true)); } } } } internal class AutoConfigModule : T2Module { internal static bool globalStatsDirty; internal static bool globalDropsDirty; internal static bool globalLanguageDirty; public override bool managedEnable => false; public override void SetupConfig() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown base.SetupConfig(); RoR2Application.Update += new hook_Update(AutoConfigContainer.FilePollUpdateHook); NetworkManagerSystem.Disconnect += new hook_Disconnect(On_GNMDisconnect); SceneManager.sceneLoaded += Evt_USMSceneLoaded; } internal static void Update() { if (!((Object)(object)Run.instance != (Object)null) || !((Behaviour)Run.instance).isActiveAndEnabled) { globalStatsDirty = false; globalDropsDirty = false; } else { if (globalStatsDirty) { globalStatsDirty = false; MiscUtil.AliveList().ForEach(delegate(CharacterMaster cm) { if (cm.hasBody) { cm.GetBody().RecalculateStats(); } }); } if (globalDropsDirty) { globalDropsDirty = false; Run.instance.OnRuleBookUpdated(Run.instance.networkRuleBookComponent); Run.instance.BuildDropTable(); } } if (globalLanguageDirty) { globalLanguageDirty = false; Language.SetCurrentLanguage(Language.currentLanguageName); } } internal static void On_GNMDisconnect(orig_Disconnect orig, NetworkManagerSystem self) { orig.Invoke(self); AutoConfigBinding.CleanupDirty(isRunEnd: true); } internal static void Evt_USMSceneLoaded(Scene scene, LoadSceneMode mode) { AutoConfigBinding.CleanupDirty(isRunEnd: false); } } [Flags] public enum AutoConfigFlags { None = 0, AVIsList = 1, DeferUntilNextStage = 2, DeferUntilEndGame = 4, DeferForever = 8, PreventConCmd = 0x10, NoInitialRead = 0x20, PreventNetMismatch = 0x40, BindDict = 0x80 } [Flags] public enum AutoConfigUpdateActionTypes { None = 0, InvalidateLanguage = 1, InvalidateModel = 2, InvalidateStats = 4, InvalidateDropTable = 8, AnnounceToRun = 0x10 } public class AutoConfigUpdateActionEventArgs : EventArgs { public AutoConfigUpdateActionTypes flags; public object oldValue; public object newValue; public AutoConfigBinding target; public bool silent; } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigUpdateActionsAttribute : Attribute { public readonly AutoConfigUpdateActionTypes flags; public readonly bool ignoreDefault; public AutoConfigUpdateActionsAttribute(AutoConfigUpdateActionTypes flags, bool ignoreDefault = false) { this.flags = flags; this.ignoreDefault = ignoreDefault; } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigAttribute : Attribute { public readonly string name = null; public readonly string desc = null; public readonly AcceptableValueBase avb = null; public readonly Type avbType = null; public readonly AutoConfigFlags flags; public AutoConfigAttribute(string name, string desc, AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues) : this(desc, flags, acceptableValues) { this.name = name; } public AutoConfigAttribute(string desc, AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues) : this(flags, acceptableValues) { this.desc = desc; } public AutoConfigAttribute(AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues) { //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown if (acceptableValues.Length != 0) { bool flag = (flags & AutoConfigFlags.AVIsList) == AutoConfigFlags.AVIsList; if (!flag && acceptableValues.Length != 2) { throw new ArgumentException("Range mode for acceptableValues (flag AVIsList not set) requires either 0 or 2 params; received " + acceptableValues.Length + ".\nThe description provided was: \"" + desc + "\"."); } Type type = acceptableValues[0].GetType(); for (int i = 1; i < acceptableValues.Length; i++) { if (type != acceptableValues[i].GetType()) { throw new ArgumentException("Types of all acceptableValues must match"); } } avb = (AcceptableValueBase)Activator.CreateInstance(flag ? typeof(AcceptableValueList<>).MakeGenericType(type) : typeof(AcceptableValueRange<>).MakeGenericType(type), acceptableValues); avbType = type; } this.flags = flags; } } public abstract class BaseAutoConfigRoOAttribute : Attribute { public string nameOverride; public string catOverride; public abstract Type requiredType { get; } public BaseAutoConfigRoOAttribute(string nameOverride = null, string catOverride = null) { this.nameOverride = nameOverride; this.catOverride = catOverride; } public abstract void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate); } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOSliderAttribute : BaseAutoConfigRoOAttribute { public string format; public float min; public float max; public override Type requiredType => typeof(float); public AutoConfigRoOSliderAttribute(string format, float min, float max, string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { this.format = format; this.min = min; this.max = max; } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_Slider((ConfigEntry)(object)cfe, identStrings, min, max, format, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOStepSliderAttribute : BaseAutoConfigRoOAttribute { public string format; public float min; public float max; public float step; public override Type requiredType => typeof(float); public AutoConfigRoOStepSliderAttribute(string format, float min, float max, float step, string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { this.format = format; this.min = min; this.max = max; this.step = step; } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_StepSlider((ConfigEntry)(object)cfe, identStrings, min, max, step, format, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOIntSliderAttribute : BaseAutoConfigRoOAttribute { public string format; public int min; public int max; public override Type requiredType => typeof(int); public AutoConfigRoOIntSliderAttribute(string format, int min, int max, string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { this.format = format; this.min = min; this.max = max; } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_IntSlider((ConfigEntry)(object)cfe, identStrings, min, max, format, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOChoiceAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(Enum); public AutoConfigRoOChoiceAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_Choice(cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOKeybindAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(KeyboardShortcut); public AutoConfigRoOKeybindAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_Keybind((ConfigEntry)(object)cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOCheckboxAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(bool); public AutoConfigRoOCheckboxAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_CheckBox((ConfigEntry)(object)cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOStringAttribute : BaseAutoConfigRoOAttribute { public override Type requiredType => typeof(string); public AutoConfigRoOStringAttribute(string nameOverride = null, string catOverride = null) : base(nameOverride, catOverride) { } public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func isDisabledDelegate) { Compat_RiskOfOptions.AddOption_String((ConfigEntry)(object)cfe, identStrings, deferForever, isDisabledDelegate); } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] public class AutoConfigRoOInfoOverridesAttribute : Attribute { public string modGuid; public string modName; public string categoryName; public string entryName; public AutoConfigRoOInfoOverridesAttribute(string guid, string name, string cat = null, string ent = null) { modGuid = guid; modName = name; categoryName = cat; entryName = ent; } public AutoConfigRoOInfoOverridesAttribute(Type ownerPluginType, string cat = null, string ent = null) { BepInPlugin customAttribute = ((MemberInfo)ownerPluginType).GetCustomAttribute(); if (customAttribute == null) { TILER2Plugin._logger.LogError((object)("AutoConfigContainerRoOInfoAttribute received an invalid type " + ownerPluginType.Name + " with no BepInPluginAttribute")); return; } modGuid = customAttribute.GUID; modName = customAttribute.Name; categoryName = cat; entryName = ent; } } public static class AutoConfigPresetExtensions { public static void ApplyPreset(this AutoConfigContainer container, string name) { HashSet hashSet = new HashSet(); foreach (AutoConfigBinding binding in container.bindings) { IEnumerable source = binding.boundProperty.GetCustomAttributes(typeof(AutoConfigPresetAttribute), inherit: true).Cast(); AutoConfigPresetAttribute autoConfigPresetAttribute = source.FirstOrDefault((AutoConfigPresetAttribute p) => p.presetName == name); if (autoConfigPresetAttribute != null) { binding.configEntry.BoxedValue = autoConfigPresetAttribute.boxedValue; if (!binding.configEntry.ConfigFile.SaveOnConfigSet) { hashSet.Add(binding.configEntry.ConfigFile); } } } foreach (ConfigFile item in hashSet) { item.Save(); } } } [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)] public class AutoConfigPresetAttribute : Attribute { public readonly string presetName; public readonly object boxedValue; public AutoConfigPresetAttribute(string name, object value) { presetName = name; boxedValue = value; } } public abstract class CatalogBoilerplate : T2Module { public struct ConsoleStrings { public string className; public string objectName; public string formattedIndex; } public string nameToken { get; private protected set; } public string pickupToken { get; private protected set; } public string descToken { get; private protected set; } public string loreToken { get; private protected set; } public PickupDef pickupDef { get; internal set; } public PickupIndex pickupIndex { get; internal set; } public Entry logbookEntry { get; internal set; } public RuleDef ruleDef { get; internal set; } protected internal override AutoConfigUpdateActionTypes defaultEnabledUpdateFlags => AutoConfigUpdateActionTypes.AnnounceToRun; public override bool managedEnable => true; public override AutoConfigFlags enabledConfigFlags => AutoConfigFlags.DeferUntilNextStage | AutoConfigFlags.PreventNetMismatch; public override AutoConfigUpdateActionTypes enabledConfigUpdateActionTypes => AutoConfigUpdateActionTypes.InvalidateLanguage | AutoConfigUpdateActionTypes.InvalidateStats | AutoConfigUpdateActionTypes.InvalidateDropTable; public GameObject modelResource { get; protected set; } = null; public Sprite iconResource { get; protected set; } = null; [Obsolete("No longer in use. Replaced by LanguageAPI systems: use a language file or similar to define token ModIdent_ClassName_NAME, e.g. MYMOD_MYITEM_NAME.")] public virtual string displayName { get; } = null; protected virtual string[] GetNameStringArgs(string langID = null) { return new string[0]; } protected virtual string[] GetPickupStringArgs(string langID = null) { return new string[0]; } protected virtual string[] GetDescStringArgs(string langID = null) { return new string[0]; } protected virtual string[] GetLoreStringArgs(string langID = null) { return new string[0]; } protected virtual string GetNameString(string langID = null) { try { Language bestLanguage = MiscUtil.GetBestLanguage(langID); object obj; if (bestLanguage == null) { obj = null; } else { string obj2 = nameToken ?? "Language load error! (null token)"; object[] nameStringArgs = GetNameStringArgs(langID); obj = bestLanguage.GetLocalizedFormattedStringByToken(obj2, nameStringArgs); } if (obj == null) { obj = "Language load error!"; } return string.Format((string)obj); } catch (FormatException) { TILER2Plugin._logger.LogError((object)("Argument count mismatch while retrieving string " + nameToken)); return $"Language load error! (argument count mismatch; expected {GetNameStringArgs(langID).Length} total)"; } } protected virtual string GetPickupString(string langID = null) { try { Language bestLanguage = MiscUtil.GetBestLanguage(langID); object obj; if (bestLanguage == null) { obj = null; } else { string obj2 = pickupToken ?? "Language load error! (null token)"; object[] pickupStringArgs = GetPickupStringArgs(langID); obj = bestLanguage.GetLocalizedFormattedStringByToken(obj2, pickupStringArgs); } if (obj == null) { obj = "Language load error!"; } return string.Format((string)obj); } catch (FormatException) { TILER2Plugin._logger.LogError((object)("Argument count mismatch while retrieving string " + pickupToken)); return $"Language load error! (argument count mismatch; expected {GetPickupStringArgs(langID).Length} total)"; } } protected virtual string GetDescString(string langID = null) { try { Language bestLanguage = MiscUtil.GetBestLanguage(langID); object obj; if (bestLanguage == null) { obj = null; } else { string obj2 = descToken ?? "Language load error! (null token)"; object[] descStringArgs = GetDescStringArgs(langID); obj = bestLanguage.GetLocalizedFormattedStringByToken(obj2, descStringArgs); } if (obj == null) { obj = "Language load error!"; } return string.Format((string)obj); } catch (FormatException) { TILER2Plugin._logger.LogError((object)("Argument count mismatch while retrieving string " + descToken)); return $"Language load error! (argument count mismatch; expected {GetDescStringArgs(langID).Length} total)"; } } protected virtual string GetLoreString(string langID = null) { try { Language bestLanguage = MiscUtil.GetBestLanguage(langID); object obj; if (bestLanguage == null) { obj = null; } else { string obj2 = loreToken ?? "Language load error! (null token)"; object[] loreStringArgs = GetLoreStringArgs(langID); obj = bestLanguage.GetLocalizedFormattedStringByToken(obj2, loreStringArgs); } if (obj == null) { obj = "Language load error!"; } return string.Format((string)obj); } catch (FormatException) { TILER2Plugin._logger.LogError((object)("Argument count mismatch while retrieving string " + loreToken)); return $"Language load error! (argument count mismatch; expected {GetLoreStringArgs(langID).Length} total)"; } } protected virtual GameObject GetPickupModel() { return null; } public CatalogBoilerplate() { CatalogBoilerplateModule.allInstances.Add(this); } public override void SetupConfig() { base.SetupConfig(); base.ConfigEntryChanged += delegate(object sender, AutoConfigUpdateActionEventArgs args) { if ((args.flags & AutoConfigUpdateActionTypes.InvalidateModel) == AutoConfigUpdateActionTypes.InvalidateModel) { GameObject pickupModel = GetPickupModel(); if ((Object)(object)pickupModel != (Object)null) { if (pickupDef != null) { pickupDef.displayPrefab = pickupModel; } if (logbookEntry != null) { logbookEntry.modelPrefab = pickupModel; } } } }; } public override void RefreshPermanentLanguage() { string text = Language.GetString("TILER2_CONFIG_DISABLED"); permanentGenericLanguageTokens[nameToken + "_RENDERED"] = (base.enabled ? "" : text) + GetNameString(); permanentGenericLanguageTokens[pickupToken + "_RENDERED"] = (base.enabled ? "" : text) + GetPickupString(); permanentGenericLanguageTokens[descToken + "_RENDERED"] = (base.enabled ? "" : (text + "\n")) + GetDescString(); permanentGenericLanguageTokens[loreToken + "_RENDERED"] = GetLoreString() ?? ""; foreach (string key in Language.languagesByName.Keys) { if (!permanentSpecificLanguageTokens.ContainsKey(key)) { permanentSpecificLanguageTokens.Add(key, new Dictionary()); } Dictionary dictionary = permanentSpecificLanguageTokens[key]; string text2 = Language.GetString("TILER2_CONFIG_DISABLED", key); dictionary[nameToken + "_RENDERED"] = (base.enabled ? "" : text2) + GetNameString(key); dictionary[pickupToken + "_RENDERED"] = (base.enabled ? "" : text2) + GetPickupString(key); dictionary[descToken + "_RENDERED"] = (base.enabled ? "" : (text2 + "\n")) + GetDescString(key); dictionary[loreToken + "_RENDERED"] = GetLoreString(key) ?? ""; } base.RefreshPermanentLanguage(); } public override void SetupAttributes() { base.SetupAttributes(); nameToken = base.modInfo.longIdentifier.ToUpper() + "_" + name.ToUpper() + "_NAME"; descToken = base.modInfo.longIdentifier.ToUpper() + "_" + name.ToUpper() + "_DESC"; pickupToken = base.modInfo.longIdentifier.ToUpper() + "_" + name.ToUpper() + "_PICKUP"; loreToken = base.modInfo.longIdentifier.ToUpper() + "_" + name.ToUpper() + "_LORE"; } public virtual void SetupCatalogReady() { } public override void Install() { base.Install(); if (Object.op_Implicit((Object)(object)PreGameController.instance)) { PreGameController.instance.RecalculateModifierAvailability(); } } public override void Uninstall() { base.Uninstall(); if (Object.op_Implicit((Object)(object)PreGameController.instance)) { PreGameController.instance.RecalculateModifierAvailability(); } } public static void ConsoleDump(ManualLogSource logger, MiscUtil.FilingDictionary instances) { int num = 0; int num2 = 0; List list = new List(); foreach (CatalogBoilerplate instance in instances) { ConsoleStrings consoleStrings = instance.GetConsoleStrings(); list.Add(consoleStrings); num = Mathf.Max(consoleStrings.className.Length, num); num2 = Mathf.Max(consoleStrings.objectName.Length, num2); } logger.LogMessage((object)"Index dump follows (pairs of name / index):"); foreach (ConsoleStrings item in list) { logger.LogMessage((object)(item.className.PadLeft(num) + " " + item.objectName.PadRight(num2) + " / " + item.formattedIndex)); } } public virtual ConsoleStrings GetConsoleStrings() { return new ConsoleStrings { className = "Other", objectName = name, formattedIndex = "N/A" }; } } internal class CatalogBoilerplateModule : T2Module { internal static readonly MiscUtil.FilingDictionary allInstances = new MiscUtil.FilingDictionary(); internal static readonly Dictionary itemInstances = new Dictionary(); internal static readonly Dictionary equipmentInstances = new Dictionary(); internal static readonly Dictionary artifactInstances = new Dictionary(); public override bool managedEnable => false; public static Sprite lockIcon { get; private set; } public override void SetupConfig() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown base.SetupConfig(); lockIcon = LegacyResourcesAPI.Load("Textures/MiscIcons/texUnlockIcon"); LogBookController.BuildPickupEntries += new hook_BuildPickupEntries(On_LogbookBuildPickupEntries); Run.BuildDropTable += new hook_BuildDropTable(On_RunBuildDropTable); LogBookController.CanSelectItemEntry += new hook_CanSelectItemEntry(LogBookController_CanSelectItemEntry); LogBookController.CanSelectEquipmentEntry += new hook_CanSelectEquipmentEntry(LogBookController_CanSelectEquipmentEntry); RuleDef.FromItem += new hook_FromItem(RuleDef_FromItem); RuleDef.FromEquipment += new hook_FromEquipment(RuleDef_FromEquipment); RuleDef.FromArtifact += new hook_FromArtifact(RuleDef_FromArtifact); PreGameController.ResolveChoiceMask += new Manipulator(PreGameController_ResolveChoiceMask); Run.onRunStartGlobal += Run_onRunStartGlobal; } private void Run_onRunStartGlobal(Run obj) { UpdateEnigmaEquipmentTable(); UpdateRandomTriggerEquipmentTable(); } internal void UpdateEnigmaEquipmentTable() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) IEnumerable enumerable = from x in equipmentInstances where !x.Value.enabled select x.Key; IEnumerable enumerable2 = from x in equipmentInstances where x.Value.enabled && x.Value.isEnigmaCompatible select x.Key; foreach (EquipmentIndex item in enumerable) { EquipmentCatalog.enigmaEquipmentList.Remove(item); EnigmaArtifactManager.validEquipment.Remove(item); } foreach (EquipmentIndex item2 in enumerable2) { if (!EquipmentCatalog.enigmaEquipmentList.Contains(item2)) { EquipmentCatalog.enigmaEquipmentList.Add(item2); } if (!EnigmaArtifactManager.validEquipment.Contains(item2)) { EnigmaArtifactManager.validEquipment.Add(item2); } } } internal void UpdateRandomTriggerEquipmentTable() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) IEnumerable enumerable = from x in equipmentInstances where !x.Value.enabled select x.Key; IEnumerable enumerable2 = from x in equipmentInstances where x.Value.enabled && x.Value.canBeRandomlyTriggered select x.Key; foreach (EquipmentIndex item in enumerable) { EquipmentCatalog.randomTriggerEquipmentList.Remove(item); } foreach (EquipmentIndex item2 in enumerable2) { if (!EquipmentCatalog.randomTriggerEquipmentList.Contains(item2)) { EquipmentCatalog.randomTriggerEquipmentList.Add(item2); } } } private void PreGameController_ResolveChoiceMask(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)0, new Func[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "choiceMaskBuffer"), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "SetRuleChoiceMask") })) { int index = val.Index; val.Index = index + 1; val.EmitDelegate>((Func)delegate(RuleChoiceMask origMask) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_001f: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 //IL_0062: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Invalid comparison between Unknown and I4 //IL_00a5: 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) for (int i = 0; i < ((SerializableBitArray)origMask).length; i++) { RuleChoiceDef choiceDef = RuleCatalog.GetChoiceDef(i); if ((int)choiceDef.artifactIndex != -1 && artifactInstances.ContainsKey(choiceDef.artifactIndex) && !artifactInstances[choiceDef.artifactIndex].enabled) { ((SerializableBitArray)origMask)[i] = false; } if ((int)choiceDef.equipmentIndex != -1 && equipmentInstances.ContainsKey(choiceDef.equipmentIndex) && !equipmentInstances[choiceDef.equipmentIndex].enabled) { ((SerializableBitArray)origMask)[i] = false; } if ((int)choiceDef.itemIndex != -1 && itemInstances.ContainsKey(choiceDef.itemIndex) && !itemInstances[choiceDef.itemIndex].enabled) { ((SerializableBitArray)origMask)[i] = false; } } return origMask; }); } else { TILER2Plugin._logger.LogError((object)"CatalogBoilerplateModule: Failed to apply IL hook (PreGameController.ResolveChoiceMask), target instructions not found. Disabled items will be erroneously selectable if using a pregame item rulebook unhider mod."); } } private RuleDef RuleDef_FromArtifact(orig_FromArtifact orig, ArtifactIndex artifactIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) RuleDef val = orig.Invoke(artifactIndex); foreach (CatalogBoilerplate allInstance in allInstances) { if (allInstance is Artifact artifact && artifact.catalogIndex == artifactIndex) { artifactInstances[artifactIndex] = artifact; artifact.ruleDef = val; break; } } return val; } private RuleDef RuleDef_FromEquipment(orig_FromEquipment orig, EquipmentIndex equipmentIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) RuleDef val = orig.Invoke(equipmentIndex); foreach (CatalogBoilerplate allInstance in allInstances) { if (allInstance is Equipment equipment && equipment.catalogIndex == equipmentIndex) { equipmentInstances[equipmentIndex] = equipment; equipment.ruleDef = val; break; } } return val; } private RuleDef RuleDef_FromItem(orig_FromItem orig, ItemIndex itemIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) RuleDef val = orig.Invoke(itemIndex); foreach (CatalogBoilerplate allInstance in allInstances) { if (allInstance is Item item && item.catalogIndex == itemIndex) { itemInstances[itemIndex] = item; item.ruleDef = val; break; } } return val; } private bool LogBookController_CanSelectEquipmentEntry(orig_CanSelectEquipmentEntry orig, EquipmentDef equipmentDef, Dictionary expansionAvailability) { bool result = orig.Invoke(equipmentDef, expansionAvailability); if ((Object)(object)equipmentDef != (Object)null && allInstances.Any((CatalogBoilerplate x) => !x.enabled && x is Equipment equipment && (Object)(object)equipment.equipmentDef == (Object)(object)equipmentDef)) { return false; } return result; } private bool LogBookController_CanSelectItemEntry(orig_CanSelectItemEntry orig, ItemDef itemDef, Dictionary expansionAvailability) { bool result = orig.Invoke(itemDef, expansionAvailability); if ((Object)(object)itemDef != (Object)null && allInstances.Any((CatalogBoilerplate x) => !x.enabled && x is Item item && (Object)(object)item.itemDef == (Object)(object)itemDef)) { return false; } return result; } private Option[] PickupPickerController_GetOptionsFromPickupIndex(orig_GetOptionsFromPickupState orig, PickupIndex pickupIndex) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) Option[] source = orig.Invoke(new UniquePickup(pickupIndex)); HashSet remv = new HashSet(); foreach (CatalogBoilerplate allInstance in allInstances) { if ((allInstance is Item || allInstance is Equipment) && !allInstance.enabled && allInstance.pickupIndex != PickupIndex.none) { remv.Add(allInstance.pickupIndex); } } return source.Where((Option x) => !remv.Contains(((Option)(ref x)).pickupIndex)).ToArray(); } private void On_RunBuildDropTable(orig_BuildDropTable orig, Run self) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) ItemMask availableItems = self.availableItems; EquipmentMask availableEquipment = self.availableEquipment; foreach (CatalogBoilerplate allInstance in allInstances) { if (allInstance is Item { enabled: false } item) { availableItems.Remove(item.catalogIndex); } else if (allInstance is Equipment { enabled: false } equipment) { availableEquipment.Remove(equipment.catalogIndex); } } self.availableItems = availableItems; self.availableEquipment = availableEquipment; orig.Invoke(self); PickupDropTable.RegenerateAll(Run.instance); UpdateEnigmaEquipmentTable(); UpdateRandomTriggerEquipmentTable(); } [SystemInitializer(new Type[] { typeof(PickupCatalog) })] private static void PostCachePickups() { //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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) foreach (CatalogBoilerplate allInstance in allInstances) { PickupIndex val; if (allInstance is Equipment equipment) { val = PickupCatalog.FindPickupIndex(equipment.catalogIndex); } else { if (!(allInstance is Item item)) { continue; } val = PickupCatalog.FindPickupIndex(item.catalogIndex); } PickupDef pickupDef = PickupCatalog.GetPickupDef(val); allInstance.pickupDef = pickupDef; allInstance.pickupIndex = val; } } private Entry[] On_LogbookBuildPickupEntries(orig_BuildPickupEntries orig, Dictionary expansionAvailability) { //IL_005d: 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) Entry[] array = orig.Invoke(expansionAvailability); List list = allInstances.ToList(); Entry[] array2 = array; foreach (Entry val in array2) { if (!(val.extraData is PickupIndex)) { continue; } CatalogBoilerplate catalogBoilerplate = null; foreach (CatalogBoilerplate item in list) { if ((PickupIndex)val.extraData == item.pickupIndex) { catalogBoilerplate = item; break; } } if (catalogBoilerplate != null) { catalogBoilerplate.logbookEntry = val; list.Remove(catalogBoilerplate); } } return array; } } public abstract class Artifact : Artifact where T : Artifact { public static T instance { get; private set; } public Artifact() { if (instance != null) { throw new InvalidOperationException("Singleton class \"" + typeof(T).Name + "\" inheriting CatalogBoilerplate/Artifact was instantiated twice"); } instance = this as T; } } public abstract class Artifact : CatalogBoilerplate { public override string configCategoryPrefix => "Artifacts."; public Sprite iconResourceDisabled { get; protected set; } = null; public ArtifactIndex catalogIndex => artifactDef.artifactIndex; public ArtifactDef artifactDef { get; private set; } [AutoConfigRoOString(null, null)] [AutoConfig("The internal name of this artifact for use in other config entries. No effect if changed; will be reset on game launch.", AutoConfigFlags.None, new object[] { })] public virtual string configNameInternal { get; protected set; } = null; [AutoConfigRoOString(null, null)] [AutoConfig("The name token of this artifact for use in other config entries. No effect if changed; will be reset on game launch.", AutoConfigFlags.None, new object[] { })] public virtual string configNameToken { get; protected set; } = null; protected override string GetLoreString(string langID = null) { return null; } protected override string GetPickupString(string langID = null) { return null; } public override void SetupConfig() { base.SetupConfig(); base.ConfigEntryChanged += delegate(object sender, AutoConfigUpdateActionEventArgs args) { if (args.target.boundProperty.Name == "enabled" && args.oldValue != args.newValue) { if ((bool)args.newValue) { if (Object.op_Implicit((Object)(object)Run.instance) && ((Behaviour)Run.instance).enabled) { Chat.AddMessage(Language.GetStringFormatted("TILER2_CHAT_ARTIFACT_ENABLED", new object[1] { Language.GetString(base.nameToken + "_RENDERED") })); } artifactDef.descriptionToken = base.descToken; artifactDef.smallIconDeselectedSprite = iconResourceDisabled; artifactDef.smallIconSelectedSprite = base.iconResource; } else { if (Object.op_Implicit((Object)(object)Run.instance) && ((Behaviour)Run.instance).enabled) { Chat.AddMessage(Language.GetStringFormatted("TILER2_CHAT_ARTIFACT_DISABLED", new object[1] { Language.GetString(base.nameToken + "_RENDERED") })); } artifactDef.descriptionToken = "TILER2_DISABLED_ARTIFACT"; artifactDef.smallIconDeselectedSprite = LegacyResourcesAPI.Load("textures/miscicons/texUnlockIcon"); artifactDef.smallIconSelectedSprite = LegacyResourcesAPI.Load("textures/miscicons/texUnlockIcon"); } } }; } public override void SetupAttributes() { base.SetupAttributes(); artifactDef = ScriptableObject.CreateInstance(); artifactDef.nameToken = base.nameToken + "_RENDERED"; artifactDef.descriptionToken = base.descToken + "_RENDERED"; artifactDef.smallIconDeselectedSprite = iconResourceDisabled; artifactDef.smallIconSelectedSprite = base.iconResource; SetupModifyArtifactDef(); ContentAddition.AddArtifactDef(artifactDef); ((ResourceAvailability)(ref ArtifactCatalog.availability)).CallWhenAvailable((Action)SetupCatalogReady); } public override void SetupCatalogReady() { base.SetupCatalogReady(); ConfigEntryBase configEntry = bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == "configNameInternal").configEntry; configEntry.BoxedValue = artifactDef.cachedName; if (!configEntry.ConfigFile.SaveOnConfigSet) { configEntry.ConfigFile.Save(); } ConfigEntryBase configEntry2 = bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == "configNameToken").configEntry; configEntry2.BoxedValue = artifactDef.nameToken; if (!configEntry2.ConfigFile.SaveOnConfigSet) { configEntry2.ConfigFile.Save(); } } public virtual void SetupModifyArtifactDef() { } public override void Install() { base.Install(); artifactDef.smallIconDeselectedSprite = iconResourceDisabled; artifactDef.smallIconSelectedSprite = base.iconResource; } public override void Uninstall() { base.Uninstall(); artifactDef.smallIconDeselectedSprite = CatalogBoilerplateModule.lockIcon; artifactDef.smallIconSelectedSprite = CatalogBoilerplateModule.lockIcon; } public bool IsActiveAndEnabled() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) return base.enabled && Object.op_Implicit((Object)(object)RunArtifactManager.instance) && RunArtifactManager.instance.IsArtifactEnabled(catalogIndex); } public override ConsoleStrings GetConsoleStrings() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected I4, but got Unknown return new ConsoleStrings { className = "Artifact", objectName = name, formattedIndex = ((int)catalogIndex).ToString() }; } } public abstract class Equipment : Equipment where T : Equipment { public static T instance { get; private set; } public Equipment() { if (instance != null) { throw new InvalidOperationException("Singleton class \"" + typeof(T).Name + "\" inheriting ItemBoilerplate/Equipment was instantiated twice"); } instance = this as T; } } public abstract class Equipment : CatalogBoilerplate { protected ItemDisplayRuleDict displayRules = new ItemDisplayRuleDict(Array.Empty()); public override string configCategoryPrefix => "Equipments."; public EquipmentIndex catalogIndex { get { //IL_003c: 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_0033: 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) if ((Object)(object)equipmentDef == (Object)null) { TILER2Plugin._logger.LogError((object)("TILER2.Equipment " + name + " has null EquipmentDef! Cannot retrieve EquipmentIndex")); return (EquipmentIndex)(-1); } return equipmentDef.equipmentIndex; } } public EquipmentDef equipmentDef { get; private set; } public CustomEquipment customEquipment { get; private set; } [AutoConfigRoOString(null, null)] [AutoConfig("The internal name of this equipment for use in other config entries. No effect if changed; will be reset on game launch.", AutoConfigFlags.None, new object[] { })] public virtual string configNameInternal { get; protected set; } = null; [AutoConfigRoOString(null, null)] [AutoConfig("The name token of this equipment for use in other config entries. No effect if changed; will be reset on game launch.", AutoConfigFlags.None, new object[] { })] public virtual string configNameToken { get; protected set; } = null; [AutoConfigRoOSlider("{0:N0} s", 0f, 300f, null, null)] [AutoConfig("The base cooldown of the equipment, in seconds.", AutoConfigFlags.DeferUntilNextStage, new object[] { 0f, float.MaxValue })] public virtual float cooldown { get; protected set; } = 45f; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("Whether the equipment can be granted by Artifact of Enigma.", AutoConfigFlags.DeferForever, new object[] { })] public virtual bool isEnigmaCompatible { get; protected set; } = true; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("Whether the equipment can be triggered by Bottled Chaos.", AutoConfigFlags.DeferForever, new object[] { })] public virtual bool canBeRandomlyTriggered { get; protected set; } = true; public virtual bool isLunar => false; public override void SetupConfig() { base.SetupConfig(); base.ConfigEntryChanged += delegate(object sender, AutoConfigUpdateActionEventArgs args) { //IL_00e0: 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) if (args.target.boundProperty.Name == "enabled" && args.oldValue != args.newValue) { if ((bool)args.newValue) { if (Object.op_Implicit((Object)(object)Run.instance) && ((Behaviour)Run.instance).enabled) { Chat.AddMessage(Language.GetStringFormatted("TILER2_CHAT_ITEM_ENABLED", new object[2] { ColorCatalog.GetColorHexString(equipmentDef.colorIndex), Language.GetString(base.nameToken + "_RENDERED") })); } } else if (Object.op_Implicit((Object)(object)Run.instance) && ((Behaviour)Run.instance).enabled) { Chat.AddMessage(Language.GetStringFormatted("TILER2_CHAT_ITEM_DISABLED", new object[2] { ColorCatalog.GetColorHexString(equipmentDef.colorIndex), Language.GetString(base.nameToken + "_RENDERED") })); } } }; } public override void SetupAttributes() { //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) base.SetupAttributes(); equipmentDef = ScriptableObject.CreateInstance(); ((Object)equipmentDef).name = base.modInfo.shortIdentifier + name; equipmentDef.pickupModelPrefab = base.modelResource; equipmentDef.pickupIconSprite = base.iconResource; equipmentDef.nameToken = base.nameToken + "_RENDERED"; equipmentDef.pickupToken = base.pickupToken + "_RENDERED"; equipmentDef.descriptionToken = base.descToken + "_RENDERED"; equipmentDef.loreToken = base.loreToken + "_RENDERED"; equipmentDef.cooldown = cooldown; equipmentDef.enigmaCompatible = isEnigmaCompatible; equipmentDef.canBeRandomlyTriggered = canBeRandomlyTriggered; equipmentDef.isLunar = isLunar; equipmentDef.canDrop = true; if (isLunar) { equipmentDef.colorIndex = (ColorIndex)4; } SetupModifyEquipmentDef(); customEquipment = new CustomEquipment(equipmentDef, displayRules); ItemAPI.Add(customEquipment); ((ResourceAvailability)(ref EquipmentCatalog.availability)).CallWhenAvailable((Action)SetupCatalogReady); } public override void SetupCatalogReady() { base.SetupCatalogReady(); ConfigEntryBase configEntry = bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == "configNameInternal").configEntry; configEntry.BoxedValue = ((Object)equipmentDef).name; if (!configEntry.ConfigFile.SaveOnConfigSet) { configEntry.ConfigFile.Save(); } ConfigEntryBase configEntry2 = bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == "configNameToken").configEntry; configEntry2.BoxedValue = equipmentDef.nameToken; if (!configEntry2.ConfigFile.SaveOnConfigSet) { configEntry2.ConfigFile.Save(); } } public virtual void SetupModifyEquipmentDef() { } public override void Install() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.Install(); EquipmentSlot.PerformEquipmentAction += new hook_PerformEquipmentAction(Evt_ESPerformEquipmentAction); equipmentDef.pickupIconSprite = base.iconResource; } public override void Uninstall() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.Uninstall(); EquipmentSlot.PerformEquipmentAction -= new hook_PerformEquipmentAction(Evt_ESPerformEquipmentAction); equipmentDef.pickupIconSprite = CatalogBoilerplateModule.lockIcon; } private bool Evt_ESPerformEquipmentAction(orig_PerformEquipmentAction orig, EquipmentSlot self, EquipmentDef def) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (base.enabled && def.equipmentIndex == catalogIndex) { return PerformEquipmentAction(self); } return orig.Invoke(self, def); } protected abstract bool PerformEquipmentAction(EquipmentSlot slot); public bool HasEquipment(Inventory inv, bool inMain = true, bool inAlt = false) { //IL_0011: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between I4 and Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between I4 and Unknown return (inMain && ((!((Object)(object)inv != (Object)null)) ? (-1) : ((int)inv.currentEquipmentIndex)) == (int)catalogIndex) || (inAlt && ((!((Object)(object)inv != (Object)null)) ? (-1) : ((int)inv.alternateEquipmentIndex)) == (int)catalogIndex); } public bool HasEquipment(CharacterBody body) { //IL_0002: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) EquipmentIndex val = (EquipmentIndex)(-1); if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.equipmentSlot)) { val = body.equipmentSlot.equipmentIndex; } return val == catalogIndex; } public override ConsoleStrings GetConsoleStrings() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected I4, but got Unknown return new ConsoleStrings { className = "Equipment", objectName = name, formattedIndex = ((int)catalogIndex).ToString() }; } } public abstract class Item : Item where T : Item { public static T instance { get; private set; } public Item() { if (instance != null) { throw new InvalidOperationException("Singleton class \"" + typeof(T).Name + "\" inheriting ItemBoilerplate/Item was instantiated twice"); } instance = this as T; } } public abstract class Item : CatalogBoilerplate { protected ItemDisplayRuleDict displayRules = new ItemDisplayRuleDict(Array.Empty()); public override string configCategoryPrefix => "Items."; public ItemIndex catalogIndex { get { //IL_003c: 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_0033: 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) if ((Object)(object)itemDef == (Object)null) { TILER2Plugin._logger.LogError((object)("TILER2.Item " + name + " has null ItemDef! Cannot retrieve ItemIndex")); return (ItemIndex)(-1); } return itemDef.itemIndex; } } public ItemDef itemDef { get; private set; } public CustomItem customItem { get; private set; } public abstract ItemTier itemTier { get; } [AutoConfigRoOString(null, null)] [AutoConfig("The internal name of this item for use in other config entries. No effect if changed; will be reset on game launch.", AutoConfigFlags.None, new object[] { })] public virtual string configNameInternal { get; protected set; } = null; [AutoConfigRoOString(null, null)] [AutoConfig("The name token of this item for use in other config entries. No effect if changed; will be reset on game launch.", AutoConfigFlags.None, new object[] { })] public virtual string configNameToken { get; protected set; } = null; [AutoConfigRoOCheckbox(null, null)] [AutoConfig("If true, the item will not be given to enemies by Evolution nor in the arena map, and it will not be found by Scavengers.", AutoConfigFlags.None, new object[] { })] public virtual bool itemIsAIBlacklisted { get; protected set; } = false; public virtual ReadOnlyCollection itemTags { get; private set; } public override void SetupConfig() { base.SetupConfig(); base.ConfigEntryChanged += delegate(object sender, AutoConfigUpdateActionEventArgs args) { //IL_006d: 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_0117: 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) if (args.target.boundProperty.Name == "enabled") { if ((Object)(object)Run.instance != (Object)null && ((Behaviour)Run.instance).enabled) { Run.instance.BuildDropTable(); } if (args.oldValue != args.newValue) { ColorIndex colorIndex = ItemTierCatalog.GetItemTierDef(itemDef.tier).colorIndex; if ((bool)args.newValue) { if (Object.op_Implicit((Object)(object)Run.instance) && ((Behaviour)Run.instance).enabled) { Chat.AddMessage(Language.GetStringFormatted("TILER2_CHAT_ITEM_ENABLED", new object[2] { ColorCatalog.GetColorHexString(colorIndex), Language.GetString(base.nameToken + "_RENDERED") })); } } else if (Object.op_Implicit((Object)(object)Run.instance) && ((Behaviour)Run.instance).enabled) { Chat.AddMessage(Language.GetStringFormatted("TILER2_CHAT_ITEM_DISABLED", new object[2] { ColorCatalog.GetColorHexString(colorIndex), Language.GetString(base.nameToken + "_RENDERED") })); } } } else if (args.target.boundProperty.Name == "itemIsAIBlacklisted") { bool flag = itemDef.tags.Contains((ItemTag)4); if (flag && !itemIsAIBlacklisted) { itemDef.tags = itemDef.tags.Where((ItemTag tag) => (int)tag != 4).ToArray(); } else if (!flag && itemIsAIBlacklisted) { List list = itemDef.tags.ToList(); list.Add((ItemTag)4); itemDef.tags = list.ToArray(); } } }; } public override void SetupAttributes() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown base.SetupAttributes(); List list = new List(itemTags); if (itemIsAIBlacklisted) { list.Add((ItemTag)4); } ItemTag[] array = list.ToArray(); itemDef = ScriptableObject.CreateInstance(); ((Object)itemDef).name = base.modInfo.shortIdentifier + name; itemDef.deprecatedTier = itemTier; itemDef.pickupModelPrefab = base.modelResource; itemDef.pickupIconSprite = base.iconResource; itemDef.nameToken = base.nameToken + "_RENDERED"; itemDef.pickupToken = base.pickupToken + "_RENDERED"; itemDef.descriptionToken = base.descToken + "_RENDERED"; itemDef.loreToken = base.loreToken + "_RENDERED"; itemDef.tags = array; SetupModifyItemDef(); itemTags = Array.AsReadOnly(array); customItem = new CustomItem(itemDef, displayRules); ItemAPI.Add(customItem); ((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)SetupCatalogReady); } public override void SetupCatalogReady() { base.SetupCatalogReady(); ConfigEntryBase configEntry = bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == "configNameInternal").configEntry; configEntry.BoxedValue = ((Object)itemDef).name; if (!configEntry.ConfigFile.SaveOnConfigSet) { configEntry.ConfigFile.Save(); } ConfigEntryBase configEntry2 = bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == "configNameToken").configEntry; configEntry2.BoxedValue = itemDef.nameToken; if (!configEntry2.ConfigFile.SaveOnConfigSet) { configEntry2.ConfigFile.Save(); } } public virtual void SetupModifyItemDef() { } public override void Install() { base.Install(); itemDef.pickupIconSprite = base.iconResource; } public override void Uninstall() { base.Uninstall(); itemDef.pickupIconSprite = CatalogBoilerplateModule.lockIcon; } public int GetCount(Inventory inv) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (!((Object)(object)inv == (Object)null)) ? inv.GetItemCount(catalogIndex) : 0; } public int GetCount(CharacterMaster chrm) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)chrm) || !Object.op_Implicit((Object)(object)chrm.inventory)) { return 0; } return chrm.inventory.GetItemCount(catalogIndex); } public int GetCount(CharacterBody body) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.inventory)) { return 0; } return body.inventory.GetItemCount(catalogIndex); } public int GetCountOnDeployables(CharacterMaster master) { //IL_0034: 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_003e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)master == (Object)null) { return 0; } List deployablesList = master.deployablesList; if (deployablesList == null) { return 0; } int num = 0; foreach (DeployableInfo item in deployablesList) { num += GetCount(((Component)item.deployable).gameObject.GetComponent()); } return num; } public override ConsoleStrings GetConsoleStrings() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected I4, but got Unknown return new ConsoleStrings { className = "Item", objectName = name, formattedIndex = ((int)catalogIndex).ToString() }; } } internal static class NetConfigLocalClient { internal struct MsgRequestConfigSyncBegin : INetMessage, ISerializableObject { private int _packageSizeBytes; public void Deserialize(NetworkReader reader) { _packageSizeBytes = reader.ReadInt32(); } public void Serialize(NetworkWriter writer) { writer.Write(_packageSizeBytes); } public void OnReceived() { if (syncReceiveData.Count() != 0) { TILER2Plugin._logger.LogError((object)"MsgRequestConfigSyncBegin received by client with sync already in progress"); return; } syncReceiveBytesMax = _packageSizeBytes; NetMessageExtensions.Send((INetMessage)(object)new NetConfigModule.MsgReplyNetConfig(netId, password, NetConfigModule.ConfigSyncStatus.BeginSync), (NetworkDestination)2); } public MsgRequestConfigSyncBegin(int packageSizeBytes) { _packageSizeBytes = packageSizeBytes; } } internal struct MsgRequestConfigSyncContinue : INetMessage, ISerializableObject { private byte[] _chunk; private int _index; public void Deserialize(NetworkReader reader) { _chunk = reader.ReadBytesAndSize(); _index = reader.ReadInt32(); } public void Serialize(NetworkWriter writer) { writer.WriteBytesAndSize(_chunk, _chunk.Length); writer.Write(_index); } public void OnReceived() { syncReceiveData[_index] = _chunk; syncReceiveBytes += _chunk.Length; if (syncReceiveBytes == syncReceiveBytesMax) { ClientFinalizeConfigSync(); } else if (syncReceiveBytes > syncReceiveBytesMax) { TILER2Plugin._logger.LogError((object)"Received more bytes via MsgRequestConfigSyncContinue than payload size given by MsgRequestConfigSyncBegin"); } } public MsgRequestConfigSyncContinue(byte[] chunk, int index) { _chunk = chunk; _index = index; } } internal struct MsgRequestNetConfigAck : INetMessage, ISerializableObject { private string _password; private int _netId; public void Deserialize(NetworkReader reader) { _netId = reader.ReadInt32(); _password = reader.ReadString(); } public void Serialize(NetworkWriter writer) { writer.Write(_netId); writer.Write(_password); } public void OnReceived() { password = _password; netId = _netId; NetMessageExtensions.Send((INetMessage)(object)new NetConfigModule.MsgReplyNetConfig(_netId, _password, NetConfigModule.ConfigSyncStatus.Connect), (NetworkDestination)2); } public MsgRequestNetConfigAck(NetConfigClientInfo cli) { _netId = cli.connection.connectionId; _password = cli.password; } } private static string password; private static int netId; private static int syncReceiveBytesMax = 0; private static int syncReceiveBytes = 0; private static readonly Dictionary syncReceiveData = new Dictionary(); private static void ClientCleanupConfigSync() { syncReceiveData.Clear(); syncReceiveBytes = 0; syncReceiveBytesMax = 0; } private static void ClientFinalizeConfigSync() { if (!NetworkClient.active) { TILER2Plugin._logger.LogError((object)"NetConfigLocalClient.ClientFinalizeConfigSync called on server"); return; } List list = new List(); for (int i = 0; i < syncReceiveData.Count; i++) { if (!syncReceiveData.ContainsKey(i)) { TILER2Plugin._logger.LogError((object)$"Gap in received MsgRequestConfigSyncContinue data at index {i} of {syncReceiveData.Count}"); ClientCleanupConfigSync(); return; } list.AddRange(syncReceiveData[i]); } if (list.Count != syncReceiveBytesMax) { TILER2Plugin._logger.LogError((object)"Mismatch in received MsgRequestConfigSyncContinue data vs payload size given by MsgRequestConfigSyncBegin"); ClientCleanupConfigSync(); return; } NetConfigModule.ConfigExchangeEntry[] array = new NetConfigModule.ConfigExchange(list.ToArray()).Unpack(); ClientCleanupConfigSync(); TILER2Plugin._logger.LogDebug((object)$"NetConfig.ClientFinalizeConfigSync received payload of {array.Length} entries"); int num = 0; bool flag = false; bool flag2 = false; NetConfigModule.ConfigExchangeEntry[] array2 = array; for (int j = 0; j < array2.Length; j++) { NetConfigModule.ConfigExchangeEntry configExchangeEntry = array2[j]; switch (ClientSyncConfigEntry(configExchangeEntry.modName, configExchangeEntry.configCategory, configExchangeEntry.configName, configExchangeEntry.serializedValue, silent: true)) { case NetConfigModule.ConfigSyncStatus.SyncPassWithChange: num++; break; case NetConfigModule.ConfigSyncStatus.SyncWarn: flag2 = true; break; case NetConfigModule.ConfigSyncStatus.SyncFail: flag = true; break; } } NetConfigModule.ConfigSyncStatus status = NetConfigModule.ConfigSyncStatus.SyncPass; if (flag) { Debug.LogError((object)"TILER2 NetConfig: The above config entries marked with \"UNRESOLVABLE MISMATCH\" are different on the server, must be identical between server and client, and cannot be changed while the game is running. Close the game, change these entries to match the server's, then restart and rejoin the server."); status = NetConfigModule.ConfigSyncStatus.SyncFail; } else if (num > 0) { Chat.AddMessage(Language.GetStringFormatted("TILER2_NETCONFIG_SYNCED", new object[1] { num })); } if (flag2) { status = NetConfigModule.ConfigSyncStatus.SyncWarn; } NetMessageExtensions.Send((INetMessage)(object)new NetConfigModule.MsgReplyNetConfig(netId, password, status), (NetworkDestination)2); } private static NetConfigModule.ConfigSyncStatus ClientSyncConfigEntry(string modname, string category, string cfgname, string value, bool silent) { if (!NetworkClient.active) { TILER2Plugin._logger.LogError((object)"NetConfig.ClientSyncConfigEntry called on server"); return NetConfigModule.ConfigSyncStatus.Invalid; } List list = AutoConfigBinding.instances.FindAll((AutoConfigBinding x) => x.configEntry.Definition.Key == cfgname && x.configEntry.Definition.Section == category && x.modName == modname); if (list.Count > 1) { string stringFormatted = Language.GetStringFormatted("TILER2_NETCONFIG_ERROR_MULTIPATH", new object[3] { modname, category, cfgname }); Debug.LogError((object)stringFormatted); Chat.AddMessage(stringFormatted); return NetConfigModule.ConfigSyncStatus.SyncWarn; } if (list.Count == 0) { Debug.LogError((object)("TILER2 NetConfig: The server requested an update for a nonexistent config entry with the path \"" + modname + "/" + category + "/" + cfgname + "\". Make sure you're using the same mods AND mod versions as the server!")); return NetConfigModule.ConfigSyncStatus.SyncWarn; } object obj = TomlTypeConverter.ConvertToValue(value, list[0].propType); if (!list[0].cachedValue.Equals(obj)) { if (list[0].netMismatchCritical) { Debug.LogError((object)$"TILER2 NetConfig: UNRESOLVABLE MISMATCH on \"{modname}/{category}/{cfgname}\"! Requested {obj} vs current {list[0].cachedValue}"); return NetConfigModule.ConfigSyncStatus.SyncFail; } list[0].OverrideProperty(obj, silent); return NetConfigModule.ConfigSyncStatus.SyncPassWithChange; } return NetConfigModule.ConfigSyncStatus.SyncPass; } } public class NetConfigModule : T2Module { internal enum ConfigSyncStatus : byte { Invalid, Connect, BeginSync, SyncPass, SyncPassWithChange, SyncWarn, SyncFail } internal struct ConfigExchangeEntry { public string modName; public string configCategory; public string configName; public string serializedValue; public ConfigExchangeEntry(string modName, string configCategory, string configName, string serializedValue) { this.modName = modName; this.configCategory = configCategory; this.configName = configName; this.serializedValue = serializedValue; } } internal struct ConfigExchange { public byte[] content; public float timestamp; public ConfigExchange(byte[] packedEntries) { content = packedEntries; timestamp = Time.unscaledTime; } public ConfigExchange(ConfigExchangeEntry[] entries) { List list = new List(); for (int i = 0; i < entries.Length; i++) { ConfigExchangeEntry configExchangeEntry = entries[i]; list.Add(configExchangeEntry.modName); list.Add(configExchangeEntry.configCategory); list.Add(configExchangeEntry.configName); list.Add(configExchangeEntry.serializedValue); } content = NetUtil.PackStringArray(list.ToArray()); timestamp = Time.unscaledTime; } public ConfigExchangeEntry[] Unpack() { string[] array = NetUtil.UnpackStringArray(content); ConfigExchangeEntry[] array2 = new ConfigExchangeEntry[array.Length / 4]; int num = 0; for (int i = 0; i < array.Length; i += 4) { array2[num++] = new ConfigExchangeEntry(array[i], array[i + 1], array[i + 2], array[i + 3]); } return array2; } } internal struct MsgReplyNetConfig : INetMessage, ISerializableObject { private string _password; private int _netId; private ConfigSyncStatus _status; public void Deserialize(NetworkReader reader) { _netId = reader.ReadInt32(); _password = reader.ReadString(); _status = (ConfigSyncStatus)reader.ReadByte(); } public void Serialize(NetworkWriter writer) { writer.Write(_netId); writer.Write(_password); writer.Write((byte)_status); } public void OnReceived() { NetworkConnection conn = null; foreach (NetworkConnection connection in NetworkServer.connections) { if (connection != null && connection.connectionId == _netId) { conn = connection; break; } } if (conn == null) { TILER2Plugin._logger.LogError((object)$"NetConfig received reply from an invalid connectionId {_netId}! Reply has password \"{_password}\", type {_status}"); { foreach (NetConfigClientInfo client in clients) { if (client.password == _password) { TILER2Plugin._logger.LogError((object)$" Password matches user with connectionId {client.connection.connectionId}"); } } return; } } NetConfigClientInfo netConfigClientInfo = clients.Find((NetConfigClientInfo x) => x.connection == conn); if (netConfigClientInfo == null) { TILER2Plugin._logger.LogError((object)$"NetConfig received reply from untracked connectionId {_netId}! Reply has password \"{_password}\", type {_status}"); return; } if (netConfigClientInfo.password != _password) { TILER2Plugin._logger.LogError((object)$"NetConfig received reply from connectionId {_netId} with invalid password! Reply has password \"{_password}\", expected \"{netConfigClientInfo.password}\"; type {_status}"); return; } TILER2Plugin._logger.LogDebug((object)$"NetConfig reply OK! Reply has connectionId {_netId}, password \"{_password}\", type {_status}"); if (_status == ConfigSyncStatus.Connect) { netConfigClientInfo.hasAcked = true; netConfigClientInfo.AdvanceExchangeQueue(); } else if (_status == ConfigSyncStatus.BeginSync) { netConfigClientInfo.BeginExchange(); } else if (_status == ConfigSyncStatus.SyncPass) { TILER2Plugin._logger.LogDebug((object)$"connectionId {_netId} passed config check"); netConfigClientInfo.EndExchange(); } else if (_status == ConfigSyncStatus.SyncWarn) { if (T2Module.instance.badVersionKick) { TILER2Plugin._logger.LogWarning((object)$"connectionId {_netId} failed config check (missing entries), kicking"); NetworkManagerSystem.singleton.ServerKickClient(conn, (BaseKickReason)(object)kickMissingEntry); } else { TILER2Plugin._logger.LogWarning((object)$"connectionId {_netId} failed config check (missing entries)"); netConfigClientInfo.EndExchange(); } } else if (_status == ConfigSyncStatus.SyncFail) { if (T2Module.instance.mismatchKick) { TILER2Plugin._logger.LogWarning((object)$"connectionId {_netId} failed config check (a config with DeferForever and PreventNetMismatch is mismatched), kicking"); NetworkManagerSystem.singleton.ServerKickClient(conn, (BaseKickReason)(object)kickCritMismatch); } else { TILER2Plugin._logger.LogWarning((object)$"connectionId {_netId} failed config check (a config with DeferForever and PreventNetMismatch is mismatched)"); netConfigClientInfo.EndExchange(); } } else { TILER2Plugin._logger.LogError((object)$"NetConfig received reply from connectionId {_netId} with invalid type! Reply has password \"{_password}\", type {_status}"); } } public MsgReplyNetConfig(int netId, string password, ConfigSyncStatus status) { _netId = netId; _password = password; _status = status; } } public static readonly SimpleLocalizedKickReason kickCritMismatch = new SimpleLocalizedKickReason("TILER2_KICKREASON_NCCRITMISMATCH", Array.Empty()); public static readonly SimpleLocalizedKickReason kickTimeout = new SimpleLocalizedKickReason("TILER2_KICKREASON_NCTIMEOUT", Array.Empty()); public static readonly SimpleLocalizedKickReason kickMissingEntry = new SimpleLocalizedKickReason("TILER2_KICKREASON_NCMISSINGENTRY", Array.Empty()); private static readonly BoolConVar allowClientNCFGSet = new BoolConVar("ncfg_allowclientset", (ConVarFlags)0, "false", "If true, clients may use the ConCmds ncfg_set or ncfg_settemp to temporarily set config values on the server. If false, ncfg_set and ncfg_settemp will not work for clients."); private const float CONN_CHECK_WAIT_TIME = 15f; internal const int MAX_MESSAGE_SIZE_BYTES = 1000; private static readonly List clients = new List(); private readonly List _updateKickList = new List(); private const string NCFG_GET_WRONG_ARGS_PRE = "ConCmd ncfg_get was used with bad arguments ("; private const string NCFG_GET_USAGE_POST = ").\nUsage: ncfg_get \"path1\" \"optional path2\" \"optional path3\". Path matches mod name, config category, and config name, in that order."; public override bool managedEnable => false; [AutoConfig("If true, NetConfig will use the server to check for config mismatches.", AutoConfigFlags.None, new object[] { })] public bool enableCheck { get; private set; } = true; [AutoConfig("If true, NetConfig will kick clients that fail config checks (caused by config entries internally marked as both DeferForever and DisallowNetMismatch).", AutoConfigFlags.None, new object[] { })] public bool mismatchKick { get; private set; } = true; [AutoConfig("If true, NetConfig will kick clients that are missing config entries (may be caused by different mod versions on client).", AutoConfigFlags.None, new object[] { })] public bool badVersionKick { get; private set; } = true; [AutoConfig("If true, NetConfig will kick clients that take too long to respond to config checks (may be caused by missing mods on client, or by major network issues).", AutoConfigFlags.None, new object[] { })] public bool timeoutKick { get; private set; } = true; public override void SetupConfig() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown base.SetupConfig(); NetworkManagerSystem.OnServerAddPlayerInternal += (hook_OnServerAddPlayerInternal)delegate(orig_OnServerAddPlayerInternal orig, NetworkManagerSystem self, NetworkConnection conn, short pcid, NetworkReader extraMsg) { orig.Invoke(self, conn, pcid, extraMsg); if (enableCheck && !Util.ConnectionIsLocal(conn) && !clients.Exists((NetConfigClientInfo x) => x.connection == conn)) { string password = Guid.NewGuid().ToString("d"); NetConfigClientInfo netConfigClientInfo = new NetConfigClientInfo { connection = conn, password = password }; clients.Add(netConfigClientInfo); netConfigClientInfo.AddExchangeAll(); NetMessageExtensions.Send((INetMessage)(object)new NetConfigLocalClient.MsgRequestNetConfigAck(netConfigClientInfo), conn); } }; RoR2Application.onUpdate += UpdateConnections; NetworkingAPI.RegisterMessageType(); NetworkingAPI.RegisterMessageType(); NetworkingAPI.RegisterMessageType(); NetworkingAPI.RegisterMessageType(); } private void UpdateConnections() { if (!NetworkServer.active) { return; } foreach (NetConfigClientInfo client in clients) { if ((!client.hasAcked && Time.unscaledTime - client.connectedAt > 15f) || (client.currentExchange.HasValue && Time.unscaledTime - client.currentExchange.Value.timestamp > 15f)) { if (timeoutKick) { TILER2Plugin._logger.LogWarning((object)$"Connection {client.connection.connectionId} took too long to respond to config check request! Kick-on-timeout option is enabled; kicking client."); _updateKickList.Add(client); } else { TILER2Plugin._logger.LogWarning((object)$"Connection {client.connection.connectionId} took too long to respond to config check request! Kick-on-timeout option is disabled."); } } } foreach (NetConfigClientInfo updateKick in _updateKickList) { NetworkManagerSystem.singleton.ServerKickClient(updateKick.connection, (BaseKickReason)(object)kickTimeout); clients.Remove(updateKick); } _updateKickList.Clear(); clients.RemoveAll((NetConfigClientInfo x) => x.connection == null || !x.connection.isConnected); } internal static void ServerSyncAllToOne(NetworkConnection conn) { if (!NetworkServer.active) { TILER2Plugin._logger.LogError((object)"NetConfig.ServerNCFGSyncAllToOne called on client"); return; } clients.Find((NetConfigClientInfo x) => x.connection == conn)?.AddExchangeAll(); } internal static void ServerSyncOneToAll(AutoConfigBinding binding, object newValue) { if (!NetworkServer.active) { TILER2Plugin._logger.LogError((object)"NetConfig.ServerNCFGSyncOneToAll called on client"); return; } foreach (NetConfigClientInfo client in clients) { client.AddExchangeOne(binding, newValue); } } [ConCommand(commandName = "ncfg_get", helpText = "Prints an ingame value managed by TILER2.AutoItemConfig to console.")] public static void ConCmdNCFGGet(ConCommandArgs args) { if (((ConCommandArgs)(ref args)).Count < 1) { Debug.LogWarning((object)"ConCmd ncfg_get was used with bad arguments (not enough arguments).\nUsage: ncfg_get \"path1\" \"optional path2\" \"optional path3\". Path matches mod name, config category, and config name, in that order."); return; } if (((ConCommandArgs)(ref args)).Count > 3) { Debug.LogWarning((object)"ConCmd ncfg_get was used with bad arguments (too many arguments).\nUsage: ncfg_get \"path1\" \"optional path2\" \"optional path3\". Path matches mod name, config category, and config name, in that order."); return; } var (list, text) = AutoConfigBinding.FindFromPath(((ConCommandArgs)(ref args))[0], (((ConCommandArgs)(ref args)).Count > 1) ? ((ConCommandArgs)(ref args))[1] : null, (((ConCommandArgs)(ref args)).Count > 2) ? ((ConCommandArgs)(ref args))[2] : null); if (text != null) { if (list != null) { Debug.Log((object)("The following config settings match that path:\n" + string.Join(", ", list.Select((AutoConfigBinding x) => "\"" + x.readablePath + "\"")))); } else { Debug.Log((object)"There are no config settings with complete nor partial matches for that path."); } return; } List list2 = new List(); string[] obj = new string[6] { "\"", list[0].readablePath, "\" (", list[0].propType.Name, "): ", null }; ConfigDescription description = list[0].configEntry.Description; obj[5] = ((description != null) ? description.Description : null) ?? "[no description]"; list2.Add(string.Concat(obj)); list2.Add($"Current value: {list[0].cachedValue}"); List list3 = list2; if (AutoConfigBinding.stageDirtyInstances.ContainsKey(list[0])) { list3.Add($"Value next stage: {AutoConfigBinding.stageDirtyInstances[list[0]].Item1}"); } if (AutoConfigBinding.runDirtyInstances.ContainsKey(list[0])) { if (AutoConfigBinding.runDirtyInstances[list[0]].Equals(list[0].configEntry.BoxedValue)) { list3.Add($"Temp. override; original value: {AutoConfigBinding.runDirtyInstances[list[0]]}"); } else { list3.Add($"Value after game ends: {AutoConfigBinding.runDirtyInstances[list[0]]}"); } } Debug.Log((object)string.Join("\n", list3)); } private static void NCFGSet(ConCommandArgs args, bool isTemporary) { //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) string text = (isTemporary ? "ncfg_settemp" : "ncfg_set"); string text2 = "ConCmd " + text + " failed ("; string text3 = ").\nUsage: " + text + " \"path1\" \"optional path2\" \"optional path3\" newValue. Path matches mod name, config category, and config name, in that order."; if (((ConCommandArgs)(ref args)).Count < 2) { NetUtil.SendConMsg(args.sender, text2 + "not enough arguments" + text3, (LogLevel)4); return; } if (((ConCommandArgs)(ref args)).Count > 4) { NetUtil.SendConMsg(args.sender, text2 + "too many arguments" + text3, (LogLevel)4); return; } List list; string text4; (list, text4) = AutoConfigBinding.FindFromPath(((ConCommandArgs)(ref args))[0], (((ConCommandArgs)(ref args)).Count > 2) ? ((ConCommandArgs)(ref args))[1] : null, (((ConCommandArgs)(ref args)).Count > 3) ? ((ConCommandArgs)(ref args))[2] : null); if (text4 != null) { text4 += ")."; if (list != null) { text4 = text4 + "\nThe following config settings have a matching path: " + string.Join(", ", list.Select((AutoConfigBinding x) => "\"" + x.readablePath + "\"")); } NetUtil.SendConMsg(args.sender, text2 + text4, (LogLevel)4); return; } string text5 = ((ConCommandArgs)(ref args))[((ConCommandArgs)(ref args)).Count - 1]; object obj; try { obj = TomlTypeConverter.ConvertToValue(text5, list[0].propType); } catch { NetUtil.SendConMsg(args.sender, text2 + "can't convert argument 2 'newValue', \"" + text5 + "\", to the target config type, " + list[0].propType.Name + ").", (LogLevel)4); return; } if (!isTemporary) { list[0].configEntry.BoxedValue = obj; if (!list[0].configEntry.ConfigFile.SaveOnConfigSet) { list[0].configEntry.ConfigFile.Save(); } } else { list[0].OverrideProperty(obj); } if (Object.op_Implicit((Object)(object)args.sender) && !((NetworkBehaviour)args.sender).hasAuthority) { Debug.Log((object)$"TILER2 NetConfig: ConCmd {text} from client {args.sender.userName} passed. Changed config setting {list[0].readablePath} to {obj}."); NetUtil.SendConMsg(args.sender, $"ConCmd {text} successfully updated config entry! Changed config setting {list[0].readablePath} to {obj}.", (LogLevel)8); } else { Debug.Log((object)$"TILER2 NetConfig: {text} successful. Changed config setting {list[0].readablePath} to {obj}."); } } [ConCommand(commandName = "ncfg_set", helpText = "While on the main menu, in singleplayer, or hosting a server: permanently override an ingame value managed by TILER2.AutoItemConfig. While non-host: attempts to call ncfg_settemp on the server instead.")] public static void ConCmdNCFGSet(ConCommandArgs args) { //IL_0001: 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_0047: 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_0034: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)args.sender) && !((NetworkBehaviour)args.sender).isServer) { Console.instance.RunClientCmd(args.sender, "ncfg_settemp", args.userArgs.ToArray()); } else { NCFGSet(args, isTemporary: false); } } [ConCommand(/*Could not decode attribute arguments.*/)] public static void ConCmdNCFGSetTemp(ConCommandArgs args) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) NCFGSet(args, isTemporary: true); } [ConCommand(commandName = "ncfg", helpText = "Routes to other AutoItemConfig commands (ncfg_get, ncfg_set, ncfg_settemp). For when you forget the underscore.")] public static void ConCmdNCFG(ConCommandArgs args) { //IL_00b0: 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) if (((ConCommandArgs)(ref args)).Count == 0) { Debug.LogWarning((object)"ConCmd ncfg was not passed enough arguments (needs at least 1 to determine which command to route to)."); return; } string text; if (((ConCommandArgs)(ref args))[0].ToUpper() == "GET") { text = "ncfg_get"; } else if (((ConCommandArgs)(ref args))[0].ToUpper() == "SET") { text = "ncfg_set"; } else { if (!(((ConCommandArgs)(ref args))[0].ToUpper() == "SETTEMP")) { Debug.LogWarning((object)("ConCmd ncfg_" + ((ConCommandArgs)(ref args))[0] + " does not exist. Valid commands include: ncfg_get, ncfg_set, ncfg_settemp.")); return; } text = "ncfg_settemp"; } Console.instance.RunClientCmd(args.sender, text, args.userArgs.Skip(1).ToArray()); } } internal class NetConfigClientInfo { public NetworkConnection connection; public string password; public bool hasAcked = false; public NetConfigModule.ConfigExchange? currentExchange; public readonly List pendingExchanges = new List(); public readonly float connectedAt = Time.unscaledTime; public void AddExchangeOne(AutoConfigBinding bind) { AddExchange(new NetConfigModule.ConfigExchange(new NetConfigModule.ConfigExchangeEntry[1] { new NetConfigModule.ConfigExchangeEntry(bind.modName, bind.configEntry.Definition.Section, bind.configEntry.Definition.Key, TomlTypeConverter.ConvertToString(bind.cachedValue, bind.propType)) })); } public void AddExchangeOne(AutoConfigBinding bind, object newValue) { AddExchange(new NetConfigModule.ConfigExchange(new NetConfigModule.ConfigExchangeEntry[1] { new NetConfigModule.ConfigExchangeEntry(bind.modName, bind.configEntry.Definition.Section, bind.configEntry.Definition.Key, TomlTypeConverter.ConvertToString(newValue, bind.propType)) })); } public void AddExchangeAll() { IEnumerable enumerable = AutoConfigBinding.instances.Where((AutoConfigBinding x) => !x.allowNetMismatch); List list = new List(); foreach (AutoConfigBinding item in enumerable) { list.Add(new NetConfigModule.ConfigExchangeEntry(item.modName, item.configEntry.Definition.Section, item.configEntry.Definition.Key, TomlTypeConverter.ConvertToString(item.cachedValue, item.propType))); } AddExchange(new NetConfigModule.ConfigExchange(list.ToArray())); } private void AddExchange(NetConfigModule.ConfigExchange exch) { pendingExchanges.Add(exch); if (hasAcked && !currentExchange.HasValue) { AdvanceExchangeQueue(); } } public void AdvanceExchangeQueue() { if (!hasAcked) { TILER2Plugin._logger.LogError((object)"ClientConfigSyncInfo.AdvanceExchangeQueue called before client ack"); } else if (!currentExchange.HasValue) { if (pendingExchanges.Count == 0) { TILER2Plugin._logger.LogDebug((object)"ClientConfigSyncInfo.AdvanceExchangeQueue called with empty queue"); return; } currentExchange = pendingExchanges[0]; pendingExchanges.RemoveAt(0); NetMessageExtensions.Send((INetMessage)(object)new NetConfigLocalClient.MsgRequestConfigSyncBegin(currentExchange.Value.content.Length), connection); } } public void BeginExchange() { if (!hasAcked) { TILER2Plugin._logger.LogError((object)"ClientConfigSyncInfo.BeginExchange called before client ack"); return; } if (!currentExchange.HasValue) { TILER2Plugin._logger.LogWarning((object)"ClientConfigSyncInfo.BeginExchange called with no immediate exchange, attempting to advance queue"); AdvanceExchangeQueue(); if (!currentExchange.HasValue) { TILER2Plugin._logger.LogError((object)"ClientConfigSyncInfo.BeginExchange called with no immediate or pending exchange"); return; } } byte[] content = currentExchange.Value.content; int num = 996; int num2 = 0; for (int i = 0; i < content.Length; i += num) { IEnumerable source = content.Skip(i); NetMessageExtensions.Send((INetMessage)(object)new NetConfigLocalClient.MsgRequestConfigSyncContinue(source.Take(Math.Min(num, source.Count())).ToArray(), num2++), connection); } } public void EndExchange() { if (!hasAcked) { TILER2Plugin._logger.LogError((object)"ClientConfigSyncInfo.EndExchange called before client ack"); return; } currentExchange = null; AdvanceExchangeQueue(); } } public static class CatalogUtil { public static bool TryGetItemDef(PickupIndex pickupIndex, out ItemDef itemDef) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0028: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) itemDef = null; if (pickupIndex == PickupIndex.none) { return false; } PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex); if (pickupDef == null || (int)pickupDef.itemIndex == -1) { return false; } itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex); return (Object)(object)itemDef != (Object)null; } public static bool TryGetItemDef(PickupDef pickupDef, out ItemDef itemDef) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) itemDef = null; if (pickupDef == null || (int)pickupDef.itemIndex == -1) { return false; } itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex); return (Object)(object)itemDef != (Object)null; } public static bool TryGetItemDef(ItemIndex itemIndex, out ItemDef itemDef) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) itemDef = null; if ((int)itemIndex == -1) { return false; } itemDef = ItemCatalog.GetItemDef(itemIndex); return (Object)(object)itemDef != (Object)null; } public static bool TryGetEquipmentDef(PickupIndex pickupIndex, out EquipmentDef equipmentDef) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0028: Invalid comparison between Unknown and I4 //IL_0037: Unknown result type (might be due to invalid IL or missing references) equipmentDef = null; if (pickupIndex == PickupIndex.none) { return false; } PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex); if (pickupDef == null || (int)pickupDef.equipmentIndex == -1) { return false; } equipmentDef = EquipmentCatalog.GetEquipmentDef(pickupDef.equipmentIndex); return (Object)(object)equipmentDef != (Object)null; } public static bool TryGetEquipmentDef(PickupDef pickupDef, out EquipmentDef equipmentDef) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) equipmentDef = null; if (pickupDef == null || (int)pickupDef.equipmentIndex == -1) { return false; } equipmentDef = EquipmentCatalog.GetEquipmentDef(pickupDef.equipmentIndex); return (Object)(object)equipmentDef != (Object)null; } public static bool TryGetEquipmentDef(EquipmentIndex equipmentIndex, out EquipmentDef equipmentDef) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) equipmentDef = null; if ((int)equipmentIndex == -1) { return false; } equipmentDef = EquipmentCatalog.GetEquipmentDef(equipmentIndex); return (Object)(object)equipmentDef != (Object)null; } } internal static class DebugUtil { internal static void Setup() { } [ConCommand(commandName = "goto_itemrender", helpText = "Opens the item rendering scene.")] private static void CCGotoRenderScene(ConCommandArgs args) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)Run.instance)) { Debug.LogError((object)"Cannot goto render scene while a run is active."); } else { Addressables.LoadSceneAsync((object)"RoR2/Dev/renderitem/renderitem.unity", (LoadSceneMode)0, true, 100); } } [ConCommand(commandName = "ir_sim", helpText = "Spawns an item's entire pickup model, for use with the item rendering scene and a runtime inspector.")] private static void CCSpawnItemModel(ConCommandArgs args) { //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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown Scene activeScene = SceneManager.GetActiveScene(); GameObject val = ((IEnumerable)((Scene)(ref activeScene)).GetRootGameObjects()).FirstOrDefault((Func)((GameObject o) => ((Object)o).name == "ITEM GOES HERE (can offset from here)")); if (Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)val)) { Debug.LogError((object)"Cannot spawn an item model outside the item render scene (use concmd goto_itemrender)."); return; } if (((ConCommandArgs)(ref args)).Count < 1) { TILER2Plugin._logger.LogError((object)"ir_sim: missing argument 1 (item ID)!"); return; } string itemSearch = ((ConCommandArgs)(ref args)).TryGetArgString(0); if (itemSearch == null) { TILER2Plugin._logger.LogError((object)"ir_sim: could not read argument 1 (item ID)!"); return; } ItemIndex val2; if (int.TryParse(itemSearch, out var result)) { val2 = (ItemIndex)result; if (!ItemCatalog.IsIndexValid(ref val2)) { TILER2Plugin._logger.LogError((object)"ir_sim: argument 1 (item ID as integer ItemIndex) is out of range; no item with that ID exists!"); return; } } else { IEnumerable source = ((IEnumerable)(object)ItemCatalog.allItems).Where(delegate(ItemIndex ind) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) string name = ((Object)ItemCatalog.GetItemDef(ind)).name; return name.ToUpper().Contains(itemSearch.ToUpper()); }); if (source.Count() < 1) { TILER2Plugin._logger.LogError((object)"ir_sim: argument 1 (item ID as string ItemName) not found in ItemCatalog; no item with a name containing that string exists!"); return; } if (source.Count() > 1) { TILER2Plugin._logger.LogWarning((object)"ir_sim: argument 1 (item ID as string ItemName) matched multiple items; using first."); } val2 = source.First(); } ItemDef itemDef = ItemCatalog.GetItemDef(val2); GameObject pickupModelPrefab = itemDef.pickupModelPrefab; foreach (Transform item in val.transform) { Transform val3 = item; if (Object.op_Implicit((Object)(object)val3)) { ((Component)val3).gameObject.SetActive(false); } } Object.Instantiate(pickupModelPrefab, val.transform); } [ConCommand(commandName = "ir_sqm", helpText = "Spawns an equipment's entire pickup model, for use with the item rendering scene and a runtime inspector.")] private static void CCSpawnEquipmentModel(ConCommandArgs args) { //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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown Scene activeScene = SceneManager.GetActiveScene(); GameObject val = ((IEnumerable)((Scene)(ref activeScene)).GetRootGameObjects()).FirstOrDefault((Func)((GameObject o) => ((Object)o).name == "ITEM GOES HERE (can offset from here)")); if (Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)val)) { Debug.LogError((object)"Cannot spawn an equipment model outside the item render scene (use concmd goto_itemrender)."); return; } if (((ConCommandArgs)(ref args)).Count < 1) { TILER2Plugin._logger.LogError((object)"ir_sqm: missing argument 1 (item ID)!"); return; } string itemSearch = ((ConCommandArgs)(ref args)).TryGetArgString(0); if (itemSearch == null) { TILER2Plugin._logger.LogError((object)"ir_sqm: could not read argument 1 (equipment ID)!"); return; } EquipmentIndex val2; if (int.TryParse(itemSearch, out var result)) { val2 = (EquipmentIndex)result; if (!EquipmentCatalog.IsIndexValid(ref val2)) { TILER2Plugin._logger.LogError((object)"ir_sqm: argument 1 (equipment ID as integer EquipmentIndex) is out of range; no item with that ID exists!"); return; } } else { IEnumerable source = ((IEnumerable)(object)EquipmentCatalog.allEquipment).Where(delegate(EquipmentIndex ind) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) string name = ((Object)EquipmentCatalog.GetEquipmentDef(ind)).name; return name.ToUpper().Contains(itemSearch.ToUpper()); }); if (source.Count() < 1) { TILER2Plugin._logger.LogError((object)"ir_sqm: argument 1 (equipment ID as string EquipmentName) not found in EquipmentCatalog; no equipment with a name containing that string exists!"); return; } if (source.Count() > 1) { TILER2Plugin._logger.LogWarning((object)"ir_sqm: argument 1 (equipment ID as string EquipmentName) matched multiple equipments; using first."); } val2 = source.First(); } EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(val2); GameObject pickupModelPrefab = equipmentDef.pickupModelPrefab; foreach (Transform item in val.transform) { Transform val3 = item; if (Object.op_Implicit((Object)(object)val3)) { ((Component)val3).gameObject.SetActive(false); } } Object.Instantiate(pickupModelPrefab, val.transform); } [ConCommand(/*Could not decode attribute arguments.*/)] private static void CCEvoSetItem(ConCommandArgs args) { //IL_010d: 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_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) if (((ConCommandArgs)(ref args)).Count < 1) { TILER2Plugin._logger.LogError((object)"evo_setitem: missing argument 1 (item ID)!"); return; } int num2; if (((ConCommandArgs)(ref args)).Count > 1) { int? num = ((ConCommandArgs)(ref args)).TryGetArgInt(1); if (!num.HasValue || num < 0) { TILER2Plugin._logger.LogError((object)"evo_setitem: argument 2 (item count) must be a positive integer!"); return; } num2 = num.Value; } else { num2 = 1; } string itemSearch = ((ConCommandArgs)(ref args)).TryGetArgString(0); if (itemSearch == null) { TILER2Plugin._logger.LogError((object)"evo_setitem: could not read argument 1 (item ID)!"); return; } ItemIndex val; if (int.TryParse(itemSearch, out var result)) { val = (ItemIndex)result; if (!ItemCatalog.IsIndexValid(ref val)) { TILER2Plugin._logger.LogError((object)"evo_setitem: argument 1 (item ID as integer ItemIndex) is out of range; no item with that ID exists!"); return; } } else { IEnumerable source = ((IEnumerable)(object)ItemCatalog.allItems).Where(delegate(ItemIndex ind) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) string nameToken = ItemCatalog.GetItemDef(ind).nameToken; string text = Language.GetString(nameToken); return text.ToUpper().Contains(itemSearch.ToUpper()); }); if (source.Count() < 1) { TILER2Plugin._logger.LogError((object)"evo_setitem: argument 1 (item ID as string ItemName) not found in ItemCatalog; no item with a name containing that string exists!"); return; } if (source.Count() > 1) { TILER2Plugin._logger.LogWarning((object)"evo_setitem: argument 1 (item ID as string ItemName) matched multiple items; using first."); } val = source.First(); } Inventory monsterTeamInventory = MonsterTeamGainsItemsArtifactManager.monsterTeamInventory; if ((Object)(object)monsterTeamInventory == (Object)null) { TILER2Plugin._logger.LogError((object)"evo_setitem: Artifact of Evolution must be enabled!"); return; } int num3 = num2 - monsterTeamInventory.GetItemCount(val); monsterTeamInventory.GiveItem(val, num3); TILER2Plugin._logger.LogMessage((object)string.Format("evo_setitem: {0}{1}x {2}", (num3 > 0) ? "added " : "removed ", Mathf.Abs(num3), Language.GetString(ItemCatalog.GetItemDef(val).nameToken))); } } public static class MiscUtil { public class FilingDictionary : IEnumerable, IEnumerable { private readonly Dictionary _dict = new Dictionary(); public int Count => _dict.Count; public void Add(T inst) { _dict.Add(inst.GetType(), inst); } public void Add(subT inst) where subT : T { _dict.Add(typeof(subT), (T)(object)inst); } public void Set(subT inst) where subT : T { _dict[typeof(subT)] = (T)(object)inst; } public subT Get() where subT : T { return (subT)(object)_dict[typeof(subT)]; } public void Remove(T inst) { _dict.Remove(inst.GetType()); } public void RemoveWhere(Func predicate) { foreach (T item in _dict.Values.Where(predicate).ToList()) { _dict.Remove(item.GetType()); } } public IEnumerator GetEnumerator() { return _dict.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public ReadOnlyFilingDictionary AsReadOnly() { return new ReadOnlyFilingDictionary(this); } } public class ReadOnlyFilingDictionary : IReadOnlyCollection, IEnumerable, IEnumerable { private readonly FilingDictionary baseCollection; public int Count => baseCollection.Count; public ReadOnlyFilingDictionary(FilingDictionary baseCollection) { this.baseCollection = baseCollection; } public IEnumerator GetEnumerator() { return baseCollection.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return baseCollection.GetEnumerator(); } } internal static void Setup() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown DirectorCore.TrySpawnObject += new Manipulator(IL_DCTrySpawnObject); OccupyNearbyNodes.OnSceneDirectorPrePopulateSceneServer += new hook_OnSceneDirectorPrePopulateSceneServer(OccupyNearbyNodes_OnSceneDirectorPrePopulateSceneServer); } private static void OccupyNearbyNodes_OnSceneDirectorPrePopulateSceneServer(orig_OnSceneDirectorPrePopulateSceneServer orig, SceneDirector sceneDirector) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) NodeGraph nodeGraph = SceneInfo.instance.GetNodeGraph((GraphType)0); foreach (OccupyNearbyNodes instances in OccupyNearbyNodes.instancesList) { NodeOccupationInfo nodeOccupationInfo = ((Component)instances).GetComponent(); if (!Object.op_Implicit((Object)(object)nodeOccupationInfo)) { nodeOccupationInfo = ((Component)instances).gameObject.AddComponent(); } List list = nodeGraph.FindNodesInRange(((Component)instances).transform.position, 0f, instances.radius, (HullMask)0); foreach (NodeIndex item in list) { nodeOccupationInfo._indices.Add(new KeyValuePair(nodeGraph, item)); DirectorCore.instance.AddOccupiedNode(nodeGraph, item); } } } private static void IL_DCTrySpawnObject(ILContext il) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int graphind = -1; if (!val.TryGotoNext(new Func[2] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "GetNodeGraph"), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref graphind) })) { TILER2Plugin._logger.LogError((object)"MiscUtil: failed to apply IL patch (DCTrySpawnObject => graphind), RemoveAllOccupiedNodes will not work for single objects"); return; } val.Index = 0; int instind = -1; if (!val.TryGotoNext(new Func[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld(x, "spawnedInstance"), (Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref instind) })) { TILER2Plugin._logger.LogError((object)"MiscUtil: failed to apply IL patch (DCTrySpawnObject => instind), RemoveAllOccupiedNodes will not work for single objects"); return; } val.Index = 0; while (val.TryGotoNext(new Func[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "AddOccupiedNode") })) { val.Emit(OpCodes.Dup); val.Emit(OpCodes.Ldloc, graphind); val.Emit(OpCodes.Ldloc, instind); val.EmitDelegate>((Action)delegate(NodeIndex ind, NodeGraph graph, GameObject res) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)res)) { NodeOccupationInfo nodeOccupationInfo = res.gameObject.GetComponent(); if (!Object.op_Implicit((Object)(object)nodeOccupationInfo)) { nodeOccupationInfo = res.gameObject.AddComponent(); } nodeOccupationInfo._indices.Add(new KeyValuePair(graph, ind)); } }); int index = val.Index; val.Index = index + 1; } } public static GameObject ModifyVanillaPrefab(string addressablePath, string newName, bool shouldNetwork, Func modifierCallback) { //IL_0002: 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) GameObject val = PrefabAPI.InstantiateClone(Addressables.LoadAssetAsync((object)addressablePath).WaitForCompletion(), "Temporary Setup Prefab", false); GameObject val2 = modifierCallback(val); GameObject result = PrefabAPI.InstantiateClone(val2, newName, shouldNetwork); Object.Destroy((Object)(object)val); Object.Destroy((Object)(object)val2); return result; } public static float Wrap(float x, float min, float max) { if (x < min) { return max - (min - x) % (max - min); } return min + (x - min) % (max - min); } public static float Remap(float x, float minFrom, float maxFrom, float minTo, float maxTo) { return minTo + (maxTo - minTo) * ((x - minFrom) / (maxFrom - minFrom)); } public static (Vector3 vInitial, float tFinal) CalculateVelocityForFinalPosition(Vector3 source, Vector3 target, float extraPeakHeight) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_0009: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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) Vector3 val = target - source; float y = val.y; float num = Mathf.Max(new float[3] { Mathf.Max(y, 0f) + extraPeakHeight, y, 0f }); float num2 = 0f - Physics.gravity.y; float num3 = Mathf.Sqrt(2f * num2 * num); float num4 = Mathf.Sqrt(2f) / num2 * (Mathf.Sqrt(num2 * (num - y)) + Mathf.Sqrt(num2 * num)); float num5 = val.x / num4; float num6 = val.z / num4; return (vInitial: new Vector3(num5, num3, num6), tFinal: num4); } public static bool TrajectorySphereCast(out RaycastHit hit, Vector3 source, Vector3 vInitial, float tFinal, float radius, int resolution, int layerMask = -5, QueryTriggerInteraction qTI = (QueryTriggerInteraction)0) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Vector3 val = source; for (int i = 0; i < resolution; i++) { Vector3 val2 = val; val = Trajectory.CalculatePositionAtTime(source, vInitial, ((float)i / (float)resolution + 1f) * tFinal); Vector3 val3 = val - val2; if (Physics.SphereCast(new Ray(val2, ((Vector3)(ref val3)).normalized), radius, ref hit, ((Vector3)(ref val3)).magnitude, layerMask, qTI)) { return true; } } hit = default(RaycastHit); return false; } public static List CollectNearestNodeLaunchVelocities(NodeGraph graph, int desiredCount, float minRange, float maxRange, Vector3 source, float extraPeakHeight, float radius, float maxDeviation, int trajectoryResolution, int layerMask = -5, QueryTriggerInteraction qTI = (QueryTriggerInteraction)0, HullMask hullMask = (HullMask)1) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) IOrderedEnumerable orderedEnumerable = graph.FindNodesInRange(source, minRange, maxRange, hullMask).Select(delegate(NodeIndex x) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) Vector3 result = default(Vector3); graph.GetNodePosition(x, ref result); return result; }).OrderBy(delegate(Vector3 x) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 val3 = x - source; return ((Vector3)(ref val3)).sqrMagnitude; }); List list = new List(); float num = maxDeviation * maxDeviation; foreach (Vector3 item in orderedEnumerable) { var (val, tFinal) = CalculateVelocityForFinalPosition(source, item, extraPeakHeight); if (TrajectorySphereCast(out var hit, source, val, tFinal, radius, trajectoryResolution, layerMask, qTI)) { Vector3 val2 = ((RaycastHit)(ref hit)).point - item; if (((Vector3)(ref val2)).sqrMagnitude <= num) { list.Add(val); } } if (list.Count >= desiredCount) { break; } } return list; } public static float SteepSigmoid01(float x, float b) { return 0.5f - (float)Math.Tanh(2f * b * (x - 0.5f)) / (2f * (float)Math.Tanh(0f - b)); } public static void ReflAddEventHandler(this EventInfo evt, object o, Action lam) { ParameterExpression[] array = (from p in evt.EventHandlerType.GetMethod("Invoke").GetParameters() select Expression.Parameter(p.ParameterType)).ToArray(); Delegate handler = Expression.Lambda(evt.EventHandlerType, Expression.Call(Expression.Constant(lam), lam.GetType().GetMethod("Invoke"), array[0], array[1]), array).Compile(); evt.AddEventHandler(o, handler); } public static string Pct(float tgt, uint prec = 0u, float mult = 100f) { return (tgt * mult).ToString("N" + prec) + "%"; } public static string NPlur(float tgt, uint prec = 0u) { if (prec == 0) { return (tgt == 1f || tgt == -1f) ? "" : "s"; } return ((double)Math.Abs(Math.Abs(tgt) - 1f) < Math.Pow(10.0, 0L - (long)prec)) ? "" : "s"; } public static float GetDifficultyCoeffIncreaseAfter(float time, int stages) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(Run.instance.selectedDifficulty); float num = Mathf.Floor((Run.instance.GetRunStopwatch() + time) * (1f / 60f)); float num2 = 0.7f + (float)Run.instance.participatingPlayerCount * 0.3f; float num3 = 0.046f * difficultyDef.scalingValue * Mathf.Pow((float)Run.instance.participatingPlayerCount, 0.2f); float num4 = Mathf.Pow(1.15f, (float)Run.instance.stageClearCount + (float)stages); return (num2 + num3 * num) * num4 - Run.instance.difficultyCoefficient; } public static List AliveList(bool playersOnly = false) { if (playersOnly) { return (from x in PlayerCharacterMasterController.instances where x.isConnected && Object.op_Implicit((Object)(object)x.master) && x.master.hasBody && x.master.GetBody().healthComponent.alive select x.master).ToList(); } return CharacterMaster.readOnlyInstancesList.Where((CharacterMaster x) => x.hasBody && x.GetBody().healthComponent.alive).ToList(); } public static GameObject GetRootWithLocators(GameObject target, int maxSearch = 5) { if (!Object.op_Implicit((Object)(object)target)) { return null; } GameObject val = target; EntityLocator val2 = default(EntityLocator); for (int i = 0; i < maxSearch; i++) { if (val.TryGetComponent(ref val2) && Object.op_Implicit((Object)(object)val2.entity)) { val = val2.entity; continue; } Transform root = val.transform.root; if (Object.op_Implicit((Object)(object)root) && (Object)(object)((Component)root).gameObject != (Object)(object)val) { val = ((Component)root).gameObject; continue; } return val; } return val; } public static Language GetBestLanguage(string langID) { return ((langID == null) ? null : Language.FindLanguageByName(langID)) ?? Language.currentLanguage ?? Language.english; } public static void SpawnItemFromBody(CharacterBody src, int tier, Xoroshiro128Plus rng) { //IL_00d0: 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_0103: Unknown result type (might be due to invalid IL or missing references) if (1 == 0) { } List list = tier switch { 0 => Run.instance.availableTier1DropList, 1 => Run.instance.availableTier2DropList, 2 => Run.instance.availableTier3DropList, 3 => Run.instance.availableLunarItemDropList, 4 => Run.instance.availableEquipmentDropList, 5 => Run.instance.availableLunarEquipmentDropList, 6 => Run.instance.availableVoidTier1DropList, 7 => Run.instance.availableVoidTier2DropList, 8 => Run.instance.availableVoidTier3DropList, _ => throw new ArgumentOutOfRangeException("tier", tier, "spawnItemFromBody: Item tier must be between 0 and 8 inclusive"), }; if (1 == 0) { } List list2 = list; PickupDropletController.CreatePickupDroplet(list2[rng.RangeInt(0, list2.Count)], src.transform.position, new Vector3(Random.Range(-5f, 5f), 20f, Random.Range(-5f, 5f))); } public static List GatherEnemies(TeamIndex allyIndex, params TeamIndex[] ignore) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) List list = new List(); bool flag = (int)FriendlyFireManager.friendlyFireMode > 0; IEnumerable enumerable = ((TeamIndex[])Enum.GetValues(typeof(TeamIndex))).Except(ignore); foreach (TeamIndex item in enumerable) { if (flag || allyIndex != item) { list.AddRange(TeamComponent.GetTeamMembers(item)); } } return list; } public static bool RemoveOccupiedNode(this DirectorCore self, NodeGraph nodeGraph, NodeIndex nodeIndex) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) int num = self.occupiedNodes.Length; self.occupiedNodes = self.occupiedNodes.Where((NodeReference x) => (Object)(object)x.nodeGraph != (Object)(object)nodeGraph || x.nodeIndex != nodeIndex).ToArray(); if (num == self.occupiedNodes.Length) { TILER2Plugin._logger.LogWarning((object)"RemoveOccupiedNode was passed an already-removed or otherwise nonexistent node"); return false; } return true; } public static bool RemoveAllOccupiedNodes(this DirectorCore self, GameObject obj) { NodeOccupationInfo component = obj.GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { return true; } component._indices.RemoveAll((KeyValuePair i) => self.RemoveOccupiedNode(i.Key, i.Value)); return component._indices.Count == 0; } public static void UpdateOccupiedNodesReference(this DirectorCore _, GameObject oldObj, GameObject newObj) { NodeOccupationInfo component = oldObj.GetComponent(); NodeOccupationInfo component2 = newObj.GetComponent(); if (Object.op_Implicit((Object)(object)component) && !Object.op_Implicit((Object)(object)component2)) { component2 = newObj.AddComponent(); component2._indices.AddRange(component._indices); } } } public class NodeOccupationInfo : MonoBehaviour { internal readonly List> _indices; public readonly ReadOnlyCollection> indices; public NodeOccupationInfo() { _indices = new List>(); indices = _indices.AsReadOnly(); } } public static class NetUtil { private struct MsgSendConMsg : INetMessage, ISerializableObject { private string _msg; private LogLevel _severity; public void Serialize(NetworkWriter writer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected I4, but got Unknown writer.Write((int)_severity); writer.Write(_msg); } public void Deserialize(NetworkReader reader) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) _severity = (LogLevel)reader.ReadInt32(); _msg = reader.ReadString(); } public void OnReceived() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) SendConMsgInternal(_msg, _severity); } public MsgSendConMsg(string msg, LogLevel severity = (LogLevel)8) { //IL_0009: 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) _msg = msg; _severity = severity; } } private struct MsgSendChatMsg : INetMessage, ISerializableObject { private string _msg; public void Serialize(NetworkWriter writer) { writer.Write(_msg); } public void Deserialize(NetworkReader reader) { _msg = reader.ReadString(); } public void OnReceived() { Chat.AddMessage(_msg); } public MsgSendChatMsg(string msg) { _msg = msg; } } internal static void Setup() { NetworkingAPI.RegisterMessageType(); NetworkingAPI.RegisterMessageType(); } public static byte[] PackStringArray(string[] strings) { List list = new List { strings.Length }; foreach (string text in strings) { list.Add(text.Length); } byte[] buffer = list.SelectMany(BitConverter.GetBytes).Concat(Encoding.Unicode.GetBytes(string.Join("", strings))).ToArray(); using MemoryStream memoryStream = new MemoryStream(buffer); using MemoryStream memoryStream2 = new MemoryStream(); using (DeflateStream destination = new DeflateStream(memoryStream2, CompressionMode.Compress)) { memoryStream.CopyTo(destination); } return memoryStream2.ToArray(); } public static string[] UnpackStringArray(byte[] packed) { string[] array3; using (MemoryStream stream = new MemoryStream(packed)) { using MemoryStream memoryStream = new MemoryStream(); using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) { deflateStream.CopyTo(memoryStream); } memoryStream.Seek(0L, SeekOrigin.Begin); byte[] array = new byte[4]; memoryStream.Read(array, 0, 4); int[] array2 = new int[BitConverter.ToInt32(array, 0)]; array3 = new string[array2.Length]; for (int i = 0; i < array2.Length; i++) { memoryStream.Read(array, 0, 4); array2[i] = BitConverter.ToInt32(array, 0); } using StreamReader streamReader = new StreamReader(memoryStream, Encoding.Unicode); for (int j = 0; j < array2.Length; j++) { char[] array4 = new char[array2[j]]; streamReader.Read(array4, 0, array2[j]); array3[j] = new string(array4); } } return array3; } public static void SendConMsg(NetworkUser user, string msg, LogLevel severity = (LogLevel)8) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { SendConMsgInternal(msg, severity); } else { ServerSendConMsg(user, msg, severity); } } private static void SendConMsgInternal(string msg, LogLevel severity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if ((int)severity != 2) { if ((int)severity == 4) { Debug.LogWarning((object)msg); } else { Debug.Log((object)msg); } } else { Debug.LogError((object)msg); } } public static void ServerSendConMsg(NetworkUser user, string msg, LogLevel severity = (LogLevel)8) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { TILER2Plugin._logger.LogError((object)"NetUtil.ServerSendConMsg called on client"); } else { NetMessageExtensions.Send((INetMessage)(object)new MsgSendConMsg(msg, severity), ((NetworkBehaviour)user).connectionToClient); } } public static void ServerSendGlobalChatMsg(string msg) { if (!NetworkServer.active) { TILER2Plugin._logger.LogError((object)"NetUtil.ServerSendGlobalChatMsg called on client"); } else { NetMessageExtensions.Send((INetMessage)(object)new MsgSendChatMsg(msg), (NetworkDestination)1); } } public static void ServerSendChatMsg(NetworkUser user, string msg) { if (!NetworkServer.active) { TILER2Plugin._logger.LogError((object)"NetUtil.ServerSendChatMsg called on client"); } else { NetMessageExtensions.Send((INetMessage)(object)new MsgSendChatMsg(msg), ((NetworkBehaviour)user).connectionToClient); } } } public static class SkillUtil { public static void GlobalUpdateSkillDef(SkillDef targetDef) { MiscUtil.AliveList().ForEach(delegate(CharacterMaster cb) { if (cb.hasBody) { SkillLocator skillLocator = cb.GetBody().skillLocator; if (Object.op_Implicit((Object)(object)skillLocator)) { for (int i = 0; i < skillLocator.skillSlotCount; i++) { GenericSkill skillAtIndex = skillLocator.GetSkillAtIndex(i); if ((Object)(object)skillAtIndex.skillDef == (Object)(object)targetDef) { skillAtIndex.RecalculateValues(); } } } } }); } public static SkillFamily FindSkillFamilyFromBody(string bodyName, int slotIndex) { //IL_0002: 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_002b: 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) BodyIndex val = BodyCatalog.FindBodyIndex(bodyName); if ((int)val == -1) { TILER2Plugin._logger.LogError((object)("FindSkillFamilyFromBody: Couldn't find body with name " + bodyName)); return null; } GenericSkill[] bodyPrefabSkillSlots = BodyCatalog.GetBodyPrefabSkillSlots(val); if (slotIndex < 0 || slotIndex > bodyPrefabSkillSlots.Length) { TILER2Plugin._logger.LogError((object)$"FindSkillFamilyFromBody: Skill slot index {slotIndex} is invalid for body with name {bodyName}"); return null; } return BodyCatalog.GetBodyPrefabSkillSlots(val)[slotIndex].skillFamily; } public static SkillFamily FindSkillFamilyFromBody(string bodyName, SkillSlot slot) { //IL_0002: 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00bd: Unknown result type (might be due to invalid IL or missing references) BodyIndex val = BodyCatalog.FindBodyIndex(bodyName); if ((int)val == -1) { TILER2Plugin._logger.LogError((object)("FindSkillFamilyFromBody: Couldn't find body with name " + bodyName)); return null; } GenericSkill[] bodyPrefabSkillSlots = BodyCatalog.GetBodyPrefabSkillSlots(val); SkillLocator componentInChildren = BodyCatalog.GetBodyPrefab(val).GetComponentInChildren(); if (!Object.op_Implicit((Object)(object)componentInChildren)) { TILER2Plugin._logger.LogError((object)("FindSkillFamilyFromBody: Body with name " + bodyName + " has no SkillLocator")); return null; } GenericSkill[] array = bodyPrefabSkillSlots; foreach (GenericSkill val2 in array) { SkillSlot val3 = componentInChildren.FindSkillSlot(val2); if (val3 == slot) { return val2.skillFamily; } } TILER2Plugin._logger.LogError((object)$"FindSkillFamilyFromBody: Body with name {bodyName} has no skill in slot {slot}"); return null; } public static void ReplaceVariant(this SkillFamily targetFamily, SkillDef origDef, SkillDef newDef) { int num = Array.FindIndex(targetFamily.variants, (Variant x) => (Object)(object)x.skillDef == (Object)(object)origDef); if (num < 0) { TILER2Plugin._logger.LogError((object)$"SkillFamily.OverrideVariant: couldn't find target skilldef {origDef} in family {targetFamily}"); } else { targetFamily.variants[num].skillDef = newDef; } } public static void ReplaceVariant(string targetBodyName, int targetSlot, SkillDef origDef, SkillDef newDef) { SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.ReplaceVariant(origDef, newDef); } else { TILER2Plugin._logger.LogError((object)"Failed to OverrideVariant for bodyname+slot (target not found)"); } } public static void ReplaceVariant(string targetBodyName, SkillSlot targetSlot, SkillDef origDef, SkillDef newDef) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.ReplaceVariant(origDef, newDef); } else { TILER2Plugin._logger.LogError((object)"Failed to OverrideVariant for bodyname+slotname (target not found)"); } } public static void AddVariant(this SkillFamily targetFamily, SkillDef newDef, UnlockableDef unlockableDef = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //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) Array.Resize(ref targetFamily.variants, targetFamily.variants.Length + 1); Variant[] variants = targetFamily.variants; int num = variants.Length - 1; Variant val = new Variant { skillDef = newDef }; ((Variant)(ref val)).viewableNode = new Node(newDef.skillNameToken, false, (Node)null); val.unlockableDef = unlockableDef; variants[num] = val; } public static void AddVariant(string targetBodyName, int targetSlot, SkillDef newDef, UnlockableDef unlockableDef = null) { SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.AddVariant(newDef, unlockableDef); } else { TILER2Plugin._logger.LogError((object)"Failed to AddVariant for bodyname+slot (target not found)"); } } public static void AddVariant(string targetBodyName, SkillSlot targetSlot, SkillDef newDef, UnlockableDef unlockableDef = null) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.AddVariant(newDef, unlockableDef); } else { TILER2Plugin._logger.LogError((object)"Failed to AddVariant for bodyname+slotname (target not found)"); } } public static void RemoveVariant(this SkillFamily targetFamily, SkillDef targetDef) { List list = new List(targetFamily.variants); int count = list.Count; list.RemoveAll((Variant x) => (Object)(object)x.skillDef == (Object)(object)targetDef); if (list.Count - count == 0) { TILER2Plugin._logger.LogError((object)$"SkillFamily.RemoveVariant: Couldn't find SkillDef {targetDef} for removal from SkillFamily {targetFamily}"); } targetFamily.variants = list.ToArray(); } public static void RemoveVariant(string targetBodyName, int targetSlot, SkillDef targetDef) { SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.RemoveVariant(targetDef); } else { TILER2Plugin._logger.LogError((object)"Failed to RemoveVariant for bodyname+slot (target not found)"); } } public static void RemoveVariant(string targetBodyName, SkillSlot targetSlot, SkillDef targetDef) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SkillFamily val = FindSkillFamilyFromBody(targetBodyName, targetSlot); if ((Object)(object)val != (Object)null) { val.RemoveVariant(targetDef); } else { TILER2Plugin._logger.LogError((object)"Failed to RemoveVariant for bodyname+slotname (target not found)"); } } public static SkillDef CloneSkillDef(SkillDef oldDef) { //IL_0045: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) SkillDef val = ScriptableObject.CreateInstance(); val.skillName = oldDef.skillName; val.skillNameToken = oldDef.skillNameToken; val.skillDescriptionToken = oldDef.skillDescriptionToken; val.icon = oldDef.icon; val.activationStateMachineName = oldDef.activationStateMachineName; val.activationState = oldDef.activationState; val.interruptPriority = oldDef.interruptPriority; val.baseRechargeInterval = oldDef.baseRechargeInterval; val.baseMaxStock = oldDef.baseMaxStock; val.rechargeStock = oldDef.rechargeStock; val.requiredStock = oldDef.requiredStock; val.stockToConsume = oldDef.stockToConsume; val.beginSkillCooldownOnSkillEnd = oldDef.beginSkillCooldownOnSkillEnd; val.fullRestockOnAssign = oldDef.fullRestockOnAssign; val.dontAllowPastMaxStocks = oldDef.dontAllowPastMaxStocks; val.canceledFromSprinting = oldDef.canceledFromSprinting; val.isCombatSkill = oldDef.isCombatSkill; val.resetCooldownTimerOnUse = oldDef.resetCooldownTimerOnUse; val.cancelSprintingOnActivation = oldDef.cancelSprintingOnActivation; val.canceledFromSprinting = oldDef.canceledFromSprinting; val.forceSprintDuringState = oldDef.forceSprintDuringState; val.mustKeyPress = oldDef.mustKeyPress; val.keywordTokens = oldDef.keywordTokens; return val; } } public abstract class T2Module : T2Module where T : T2Module { public static T instance { get; private set; } protected T2Module() { if (instance != null) { throw new InvalidOperationException("Singleton class \"" + typeof(T).Name + "\" inheriting Module was instantiated twice"); } instance = this as T; } } public abstract class T2Module : AutoConfigContainer { public struct ModInfo { public string displayName; public string longIdentifier; public string shortIdentifier; public ConfigFile mainConfigFile; } private static readonly MiscUtil.FilingDictionary _allModules = new MiscUtil.FilingDictionary(); public static readonly MiscUtil.ReadOnlyFilingDictionary allModules = _allModules.AsReadOnly(); public readonly string name; protected readonly List languageOverlays = new List(); protected readonly List permanentLanguageOverlays = new List(); protected readonly Dictionary genericLanguageTokens = new Dictionary(); protected readonly Dictionary> specificLanguageTokens = new Dictionary>(); protected readonly Dictionary permanentGenericLanguageTokens = new Dictionary(); protected readonly Dictionary> permanentSpecificLanguageTokens = new Dictionary>(); public bool enabled { get; protected internal set; } = true; public virtual bool managedEnable => true; public virtual bool managedEnableRoO => true; public virtual string enabledConfigDescription => null; public virtual AutoConfigFlags enabledConfigFlags => AutoConfigFlags.PreventNetMismatch; public virtual AutoConfigUpdateActionTypes enabledConfigUpdateActionTypes => AutoConfigUpdateActionTypes.InvalidateLanguage; public bool languageInstalled { get; private set; } = false; public bool permanentLanguageInstalled { get; private set; } = false; public Xoroshiro128Plus rng { get; internal set; } public ModInfo modInfo { get; private set; } public virtual string configCategoryPrefix => "Modules."; internal static void SetupModuleClass() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown Run.Start += new hook_Start(On_RunStart); Language.SetCurrentLanguage += new hook_SetCurrentLanguage(Language_SetCurrentLanguage); } private static void On_RunStart(orig_Start orig, Run self) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown orig.Invoke(self); if (!NetworkServer.active) { return; } Xoroshiro128Plus val = new Xoroshiro128Plus(self.seed); foreach (T2Module allModule in _allModules) { allModule.rng = new Xoroshiro128Plus(val.nextUlong); } } private static void Language_SetCurrentLanguage(orig_SetCurrentLanguage orig, string newCurrentLanguageName) { orig.Invoke(newCurrentLanguageName); foreach (T2Module allModule in allModules) { allModule.RefreshPermanentLanguage(); if (allModule.enabled) { if (allModule.languageInstalled) { allModule.UninstallLanguage(); } allModule.InstallLanguage(); } } AutoConfigModule.globalLanguageDirty = false; } public virtual void SetupConfig() { string categoryName = configCategoryPrefix + name; if (managedEnable) { Bind(typeof(T2Module).GetProperty("enabled"), modInfo.mainConfigFile, modInfo.displayName, categoryName, new AutoConfigAttribute(((enabledConfigDescription != null) ? (enabledConfigDescription + "\n") : "") + "Set to False to disable this module, and as much of its content as can be disabled after initial load. Doing so may cause changes in other modules as well.", enabledConfigFlags), (enabledConfigUpdateActionTypes != AutoConfigUpdateActionTypes.None) ? new AutoConfigUpdateActionsAttribute(enabledConfigUpdateActionTypes) : null); if (managedEnableRoO && Compat_RiskOfOptions.enabled) { AutoConfigBinding bind = bindings.First((AutoConfigBinding x) => x.boundProperty == typeof(T2Module).GetProperty("enabled")); BindRoO(bind, new AutoConfigRoOCheckboxAttribute()); } } BindAll(modInfo.mainConfigFile, modInfo.displayName, categoryName); base.ConfigEntryChanged += delegate(object sender, AutoConfigUpdateActionEventArgs args) { if (args.target.boundProperty.Name == "enabled") { if ((bool)args.newValue) { Install(); } else { Uninstall(); if (languageInstalled) { UninstallLanguage(); } } RefreshPermanentLanguage(); } if (args.flags.HasFlag(AutoConfigUpdateActionTypes.InvalidateLanguage)) { if (enabled) { if (languageInstalled) { UninstallLanguage(); } InstallLanguage(); } RefreshPermanentLanguage(); } }; } public virtual void SetupAttributes() { } public virtual void SetupBehavior() { } public virtual void SetupLate() { } public virtual void Install() { } public virtual void Uninstall() { } public virtual void InstallLanguage() { languageOverlays.Add(LanguageAPI.AddOverlay(genericLanguageTokens)); languageOverlays.Add(LanguageAPI.AddOverlay(specificLanguageTokens)); languageInstalled = true; AutoConfigModule.globalLanguageDirty = true; } public virtual void UninstallLanguage() { foreach (LanguageOverlay languageOverlay in languageOverlays) { languageOverlay.Remove(); } languageOverlays.Clear(); languageInstalled = false; AutoConfigModule.globalLanguageDirty = true; } public virtual void RefreshPermanentLanguage() { if (permanentLanguageInstalled) { foreach (LanguageOverlay permanentLanguageOverlay in permanentLanguageOverlays) { permanentLanguageOverlay.Remove(); } } permanentLanguageOverlays.Clear(); permanentLanguageOverlays.Add(LanguageAPI.AddOverlay(permanentGenericLanguageTokens)); permanentLanguageOverlays.Add(LanguageAPI.AddOverlay(permanentSpecificLanguageTokens)); AutoConfigModule.globalLanguageDirty = true; } public static MiscUtil.FilingDictionary InitDirect(ModInfo modInfo) where T : T2Module { return InitAll(modInfo, Assembly.GetCallingAssembly(), (Type t) => (!t.BaseType.IsGenericType) ? (t.BaseType == typeof(T)) : (t.BaseType.GenericTypeArguments[0] == t && t.BaseType.BaseType == typeof(T))); } public static MiscUtil.FilingDictionary InitAll(ModInfo modInfo, Func extraTypeChecks = null) where T : T2Module { return InitAll(modInfo, Assembly.GetCallingAssembly(), extraTypeChecks); } private static MiscUtil.FilingDictionary InitAll(ModInfo modInfo, Assembly callingAssembly, Func extraTypeChecks) where T : T2Module { MiscUtil.FilingDictionary filingDictionary = new MiscUtil.FilingDictionary(); foreach (Type item in from t in callingAssembly.GetTypes() where t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(T)) && (extraTypeChecks?.Invoke(t) ?? true) select t) { T val = (T)Activator.CreateInstance(item, nonPublic: true); val.modInfo = modInfo; filingDictionary.Add(val); } return filingDictionary; } public static MiscUtil.FilingDictionary InitModules(ModInfo modInfo) { return InitAll(modInfo, Assembly.GetCallingAssembly(), (Type t) => (!t.BaseType.IsGenericType) ? (t.BaseType == typeof(T2Module)) : (t.BaseType.GenericTypeArguments[0] == t && t.BaseType.BaseType == typeof(T2Module))); } public static void SetupAll_PluginAwake(IEnumerable modulesToSetup) { foreach (T2Module item in modulesToSetup) { item.SetupConfig(); } foreach (T2Module item2 in modulesToSetup) { item2.SetupAttributes(); } foreach (T2Module item3 in modulesToSetup) { item3.SetupBehavior(); } } public static void SetupAll_PluginStart(IEnumerable modulesToSetup, bool installUnmanaged = false) { foreach (T2Module item in modulesToSetup) { item.SetupLate(); } foreach (T2Module item2 in modulesToSetup) { if ((installUnmanaged || item2.managedEnable) && item2.enabled) { item2.Install(); } } } protected T2Module() { name = GetType().Name; _allModules.Add(this); } } [BepInDependency("com.bepis.r2api", "5.3.0")] [BepInPlugin("com.ThinkInvisible.TILER2", "TILER2", "7.4.3")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class TILER2Plugin : BaseUnityPlugin { public const string ModVer = "7.4.3"; public const string ModName = "TILER2"; public const string ModGuid = "com.ThinkInvisible.TILER2"; internal ConfigFile cfgFile; internal static ManualLogSource _logger; private MiscUtil.FilingDictionary allModules; internal TILER2Plugin() { } public void Awake() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown _logger = ((BaseUnityPlugin)this).Logger; cfgFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "com.ThinkInvisible.TILER2.cfg"), true); T2Module.SetupModuleClass(); allModules = T2Module.InitModules(new T2Module.ModInfo { displayName = "TILER2", mainConfigFile = cfgFile, longIdentifier = "TILER2", shortIdentifier = "TILER2" }); T2Module.SetupAll_PluginAwake(allModules); NetUtil.Setup(); MiscUtil.Setup(); DebugUtil.Setup(); } private void Start() { T2Module.SetupAll_PluginStart(allModules); } private void Update() { if (RoR2Application.loadFinished) { AutoConfigModule.Update(); } } }