Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of JetpackFixes v1.6.1
JetpackFixes.dll
Decompiled 5 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("JetpackFixes")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Fixes some (lethal) bugs with the jetpack")] [assembly: AssemblyFileVersion("1.6.1.0")] [assembly: AssemblyInformationalVersion("1.6.1+2f200968eb1957a2aefb50da2ecee6b6292a8faa")] [assembly: AssemblyProduct("JetpackFixes")] [assembly: AssemblyTitle("JetpackFixes")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.6.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace JetpackFixes { internal static class LobbyCompatibility { internal static void Init() { PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.jetpackfixes", Version.Parse("1.6.1"), (CompatibilityLevel)0, (VersionStrictness)0); } } internal enum MidAirExplosions { Off = -1, OnlyTooHigh, Always } [BepInPlugin("butterystancakes.lethalcompany.jetpackfixes", "Jetpack Fixes", "1.6.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.jetpackfixes"; internal const string PLUGIN_NAME = "Jetpack Fixes"; internal const string PLUGIN_VERSION = "1.6.1"; internal static ManualLogSource Logger; internal static ConfigEntry<MidAirExplosions> configMidAirExplosions; private const string GUID_JETPACK_WARNING = "JetpackWarning"; private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility"; internal static bool DISABLE_BEEP_PATCH; private void Awake() { //IL_0127: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility")) { Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected"); LobbyCompatibility.Init(); } if (Chainloader.PluginInfos.ContainsKey("JetpackWarning")) { DISABLE_BEEP_PATCH = true; Logger.LogInfo((object)"CROSS-COMPATIBILITY - Jetpack Warning detected"); } configMidAirExplosions = ((BaseUnityPlugin)this).Config.Bind<MidAirExplosions>("Misc", "MidAirExplosions", MidAirExplosions.OnlyTooHigh, "When should high speeds (exceeding 50u/s, vanilla's \"speed limit\") explode the jetpack?\n\"Off\" will only explode when you crash into something solid.\n\"OnlyTooHigh\" will explode if you are flying too fast, while you are also *extremely* high above the terrain.\n\"Always\" will explode any time you are flying too fast. (Most similar to vanilla's behavior)"); if (configMidAirExplosions.Value == MidAirExplosions.OnlyTooHigh) { if (!((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "BecomeFirework", true, "Legacy setting, use \"MidAirExplosions\" instead").Value) { configMidAirExplosions.Value = MidAirExplosions.Off; } ((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Misc", "BecomeFirework"].Definition); } ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "TransferMomentum", false, "Legacy setting, doesn't work"); ((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Misc", "TransferMomentum"].Definition); ((BaseUnityPlugin)this).Config.Save(); new Harmony("butterystancakes.lethalcompany.jetpackfixes").PatchAll(); Logger.LogInfo((object)"Jetpack Fixes v1.6.1 loaded"); } } [HarmonyPatch(typeof(JetpackItem))] internal static class JetpackFixesPatches { private const float SAFE_HEIGHT = 110.55537f; private const float MIN_DEATH_SPEED = 50f; private const float MAX_DEATH_SPEED = 54f; private static EnemyType flowerSnakeEnemy; [HarmonyPatch("Update")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> JetpackItem_Trans_Update(IEnumerable<CodeInstruction> instructions) { //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_026a: Unknown result type (might be due to invalid IL or missing references) List<CodeInstruction> list = instructions.ToList(); LayerMask val = LayerMask.op_Implicit((1 << LayerMask.NameToLayer("Room")) | (1 << LayerMask.NameToLayer("Colliders")) | (1 << LayerMask.NameToLayer("Terrain"))); FieldInfo fieldInfo = AccessTools.Field(typeof(JetpackItem), "jetpackPower"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(JetpackItem), "rayHit"); FieldInfo fieldInfo3 = AccessTools.Field(typeof(StartOfRound), "allPlayersCollideWithMask"); for (int i = 1; i < list.Count - 3; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 10f && list[i - 1].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 1].operand == fieldInfo) { list[i + 1].opcode = OpCodes.Bgt_Un; Plugin.Logger.LogDebug((object)"Transpiler: Reverse jetpackPower comparison on isGrounded check (allows for sliding)"); } else if (list[i].opcode == OpCodes.Ldflda && (FieldInfo)list[i].operand == fieldInfo2) { if (list[i + 1].opcode == OpCodes.Ldc_R4 && (float)list[i + 1].operand == 25f) { list[i + 1].operand = 4f; Plugin.Logger.LogDebug((object)"Transpiler: Reduce raycast range from 25 to 4"); } else if (list[i + 2].opcode == OpCodes.Ldc_R4 && (float)list[i + 2].operand == 4f) { for (int num = i + 3; num >= i - 1; num--) { list.RemoveAt(num); } Plugin.Logger.LogDebug((object)"Transpiler: Remove 4 unit distance check (redundant)"); } } else if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == fieldInfo3) { list[i].opcode = OpCodes.Ldc_I4; list[i].operand = LayerMask.op_Implicit(val); list.RemoveAt(i - 1); Plugin.Logger.LogDebug((object)"Transpiler: Replace layer mask with custom"); } } return list; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void JetpackItem_Post_Update(JetpackItem __instance) { //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null) { return; } if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController && !((GrabbableObject)__instance).playerHeldBy.isPlayerDead) { ((GrabbableObject)__instance).useCooldown = (StartOfRound.Instance.inShipPhase ? 0.3f : 0f); if (__instance.jetpackActivated && ((GrabbableObject)__instance).playerHeldBy.jetpackControls) { if (__instance.jetpackPower > 10f) { float magnitude = ((Vector3)(ref __instance.forces)).magnitude; if (magnitude > 50f) { if (magnitude > 54f && (Plugin.configMidAirExplosions.Value == MidAirExplosions.Always || (Plugin.configMidAirExplosions.Value == MidAirExplosions.OnlyTooHigh && ((Component)__instance).transform.position.y > 110.55537f))) { ((GrabbableObject)__instance).playerHeldBy.KillPlayer(__instance.forces, true, (CauseOfDeath)2, 0, default(Vector3), false); if (Plugin.configMidAirExplosions.Value == MidAirExplosions.Always) { Plugin.Logger.LogDebug((object)"Player killed from flying too fast"); } else { Plugin.Logger.LogDebug((object)$"Player killed from flying too fast while too high (Altitude: {((Component)__instance).transform.position.y} > {110.55537f})"); } } else if (((GrabbableObject)__instance).playerHeldBy.thisController.isGrounded) { ((GrabbableObject)__instance).playerHeldBy.KillPlayer(__instance.forces, true, (CauseOfDeath)2, 0, default(Vector3), false); Plugin.Logger.LogDebug((object)"Player killed from touching ground while flying too fast"); } } } if ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null) { if (((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle >= 0f && ((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle < 360f) { ((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle = float.MaxValue; ((GrabbableObject)__instance).playerHeldBy.jetpackRandomIntensity = 60f; Plugin.Logger.LogDebug((object)"Uncap player rotation (using jetpack while tulip snakes riding)"); } if (((GrabbableObject)__instance).playerHeldBy.isInElevator && (Object)(object)((Component)((GrabbableObject)__instance).playerHeldBy).transform.parent == (Object)(object)StartOfRound.Instance.elevatorTransform && StartOfRound.Instance.shipDoorsEnabled && ((GrabbableObject)__instance).playerHeldBy.parentedToElevatorLastFrame) { Bounds bounds = StartOfRound.Instance.shipBounds.bounds; if (!((Bounds)(ref bounds)).Contains(((Component)__instance).transform.position)) { ((GrabbableObject)__instance).playerHeldBy.parentedToElevatorLastFrame = false; ((GrabbableObject)__instance).playerHeldBy.isInElevator = false; ((GrabbableObject)__instance).playerHeldBy.isInHangarShipRoom = false; ((Component)((GrabbableObject)__instance).playerHeldBy).transform.SetParent(StartOfRound.Instance.playersContainer); Plugin.Logger.LogDebug((object)"Player flew off of ship, change parent off the ship"); } } } } } ((GrabbableObject)__instance).isBeingUsed = __instance.jetpackActivated; if (!((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null)) { return; } if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController || (GameNetworkManager.Instance.localPlayerController.isPlayerDead && (Object)(object)GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript != (Object)null && (Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript)) { if (__instance.jetpackAudio.dopplerLevel != 0f || __instance.jetpackBeepsAudio.dopplerLevel != 0f) { __instance.jetpackAudio.dopplerLevel = 0f; __instance.jetpackBeepsAudio.dopplerLevel = 0f; Plugin.Logger.LogDebug((object)("Jetpack held by " + (((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController) ? "you" : "spectate target") + ", disable doppler effect")); } } else if (__instance.jetpackAudio.dopplerLevel != 1f || __instance.jetpackBeepsAudio.dopplerLevel != 1f) { __instance.jetpackAudio.dopplerLevel = 1f; __instance.jetpackBeepsAudio.dopplerLevel = 1f; Plugin.Logger.LogDebug((object)"Jetpack held by other player, enable doppler effect"); } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")] [HarmonyPrefix] private static void PlayerControllerB_Pre_DamagePlayer(PlayerControllerB __instance, ref int damageNumber, CauseOfDeath causeOfDeath) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)causeOfDeath == 2 && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController && __instance.jetpackControls && __instance.averageVelocity >= 50f) { Plugin.Logger.LogInfo((object)$"Player took {damageNumber} \"Gravity\" damage while flying too fast; should be instant death"); damageNumber = Mathf.Max(100, __instance.health); } } [HarmonyPatch("DeactivateJetpack")] [HarmonyPostfix] private static void JetpackItem_Post_DeactivateJetpack(JetpackItem __instance) { if ((Object)(object)__instance.previousPlayerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController || !__instance.previousPlayerHeldBy.disablingJetpackControls || !((Object)(object)flowerSnakeEnemy != (Object)null) || flowerSnakeEnemy.numberSpawned <= 0) { return; } int num = flowerSnakeEnemy.numberSpawned; foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies) { FlowerSnakeEnemy val = (FlowerSnakeEnemy)(object)((spawnedEnemy is FlowerSnakeEnemy) ? spawnedEnemy : null); if ((Object)(object)val != (Object)null) { num--; if (!((EnemyAI)val).isEnemyDead && (Object)(object)val.clingingToPlayer == (Object)(object)__instance.previousPlayerHeldBy && val.flightPower > 0f) { val.clingingToPlayer.disablingJetpackControls = false; val.clingingToPlayer.maxJetpackAngle = float.MaxValue; val.clingingToPlayer.jetpackRandomIntensity = 60f; Plugin.Logger.LogDebug((object)"Jetpack disabled, but tulip snake is still carrying"); break; } if (num <= 0) { break; } } } } [HarmonyPatch(typeof(FlowerSnakeEnemy), "SetFlappingLocalClient")] [HarmonyPostfix] private static void FlowerSnakeEnemy_Post_SetFlappingLocalClient(FlowerSnakeEnemy __instance, bool isMainSnake) { if (!isMainSnake || (Object)(object)__instance.clingingToPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController || !__instance.clingingToPlayer.disablingJetpackControls) { return; } bool flag = false; JetpackItem val = null; if ((Object)(object)__instance.clingingToPlayer.ItemOnlySlot != (Object)null && !__instance.clingingToPlayer.ItemOnlySlot.isPocketed) { GrabbableObject itemOnlySlot = __instance.clingingToPlayer.ItemOnlySlot; val = (JetpackItem)(object)((itemOnlySlot is JetpackItem) ? itemOnlySlot : null); if ((Object)(object)val != (Object)null && val.jetpackActivated) { flag = true; } } if (!flag) { for (int i = 0; i < __instance.clingingToPlayer.ItemSlots.Length; i++) { if (!((Object)(object)__instance.clingingToPlayer.ItemSlots[i] == (Object)null) && !__instance.clingingToPlayer.ItemSlots[i].isPocketed) { GrabbableObject obj = __instance.clingingToPlayer.ItemSlots[i]; val = (JetpackItem)(object)((obj is JetpackItem) ? obj : null); if ((Object)(object)val != (Object)null && val.jetpackActivated) { flag = true; break; } } } } if (flag) { __instance.clingingToPlayer.disablingJetpackControls = false; __instance.clingingToPlayer.maxJetpackAngle = -1f; __instance.clingingToPlayer.jetpackRandomIntensity = 0f; Plugin.Logger.LogInfo((object)"Player still using jetpack when tulip snake dropped; re-enable flight controls"); } } [HarmonyPatch(typeof(FlowerSnakeEnemy), "Start")] [HarmonyPostfix] private static void FlowerSnakeEnemy_Post_Start(FlowerSnakeEnemy __instance) { if ((Object)(object)flowerSnakeEnemy == (Object)null) { flowerSnakeEnemy = ((EnemyAI)__instance).enemyType; } } [HarmonyPatch(typeof(GameNetworkManager), "Disconnect")] [HarmonyPostfix] private static void GameNetworkManager_Post_Disconnect() { flowerSnakeEnemy = null; } [HarmonyPatch("DiscardItem")] [HarmonyPostfix] private static void JetpackItem_Post_DiscardItem(JetpackItem __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) __instance.forces = Vector3.zero; } [HarmonyPatch("SetJetpackAudios")] [HarmonyPrefix] private static bool JetpackItem_SetJetpackAudios(JetpackItem __instance) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (Plugin.DISABLE_BEEP_PATCH) { return true; } if (__instance.jetpackActivated) { if (__instance.noiseInterval >= 0.5f) { __instance.noiseInterval = 0f; RoundManager.Instance.PlayAudibleNoise(((Component)__instance).transform.position, 25f, 0.85f, 0, ((GrabbableObject)__instance).playerHeldBy.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed, 41); } else { __instance.noiseInterval += Time.deltaTime; } if (((GrabbableObject)__instance).insertedBattery.charge < 0.15f) { if ((Object)(object)__instance.jetpackBeepsAudio.clip != (Object)(object)__instance.jetpackLowBatteriesSFX) { __instance.jetpackBeepsAudio.Stop(); __instance.jetpackBeepsAudio.clip = __instance.jetpackLowBatteriesSFX; } if (!__instance.jetpackBeepsAudio.isPlaying) { __instance.jetpackBeepsAudio.Play(); } } else { if ((Object)(object)__instance.jetpackBeepsAudio.clip != (Object)(object)__instance.jetpackWarningBeepSFX) { __instance.jetpackBeepsAudio.Stop(); __instance.jetpackBeepsAudio.clip = __instance.jetpackWarningBeepSFX; } if (Physics.CheckSphere(((Component)__instance).transform.position, 6f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { if (!__instance.jetpackBeepsAudio.isPlaying) { __instance.jetpackBeepsAudio.Play(); } } else { __instance.jetpackBeepsAudio.Stop(); } } } else { __instance.jetpackBeepsAudio.Stop(); } return false; } [HarmonyPatch("JetpackEffect")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> JetpackItem_Trans_JetpackEffect(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); Label label = generator.DefineLabel(); MethodInfo methodInfo = AccessTools.Method(typeof(HUDManager), "ShakeCamera", (Type[])null, (Type[])null); for (int i = 2; i < list.Count - 1; i++) { if (list[i].opcode == OpCodes.Callvirt && list[i].operand as MethodInfo == methodInfo) { list[i + 1].labels.Add(label); list.InsertRange(i - 2, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldarg_1, (object)null), new CodeInstruction(OpCodes.Brfalse, (object)label) })); Plugin.Logger.LogDebug((object)"Transpiler: No shake when disabling jetpack"); return list; } } return list; } } public static class PluginInfo { public const string PLUGIN_GUID = "JetpackFixes"; public const string PLUGIN_NAME = "JetpackFixes"; public const string PLUGIN_VERSION = "1.6.1"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } [CompilerGenerated] internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Length; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Length; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Length; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyArray(T[] items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return ((ICollection<T>)_items).Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { ((ICollection<T>)_items).CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return ((IList<T>)_items).IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } }