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 MultipleWeatherEffects v1.1.0
MultipleWeatherEffects.dll
Decompiled 2 years 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.Configuration; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks.Data; using Unity.Netcode; 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("MultipleWeatherEffects")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Allows moons to experience multiple weather effects at once")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MultipleWeatherEffects")] [assembly: AssemblyTitle("MultipleWeatherEffects")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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 MultipleWeatherEffects { [BepInPlugin("MultipleWeatherEffects", "MultipleWeatherEffects", "1.0.0")] public class Plugin : BaseUnityPlugin { private static readonly MethodInfo nextRandomIntMinMax = AccessTools.Method(typeof(Random), "Next", new Type[2] { typeof(int), typeof(int) }, (Type[])null); private static readonly MethodInfo levelListIndexer = AccessTools.PropertyGetter(typeof(List<SelectableLevel>), "Item"); private static readonly ConstructorInfo newRandomWithSeed = AccessTools.Constructor(typeof(Random), new Type[1] { typeof(int) }, false); private static readonly FieldInfo randomWeatherType = AccessTools.Field(typeof(RandomWeatherWithVariables), "weatherType"); private static readonly FieldInfo levelCurrentWeather = AccessTools.Field(typeof(SelectableLevel), "currentWeather"); private static readonly MethodInfo objectToString = AccessTools.Method(typeof(object), "ToString", (Type[])null, (Type[])null); private static readonly FieldInfo weatherEffectPermanentObject = AccessTools.Field(typeof(WeatherEffect), "effectPermanentObject"); private static readonly MethodInfo setGameObjectActive = AccessTools.Method(typeof(GameObject), "SetActive", (Type[])null, (Type[])null); private static readonly FieldInfo currentLevelWeather = AccessTools.Field(typeof(TimeOfDay), "currentLevelWeather"); private static readonly FieldInfo weatherEffectEnabled = AccessTools.Field(typeof(WeatherEffect), "effectEnabled"); private static readonly FieldInfo weatherVariable = AccessTools.Field(typeof(TimeOfDay), "currentWeatherVariable"); private static readonly FieldInfo weatherVariable2 = AccessTools.Field(typeof(TimeOfDay), "currentWeatherVariable2"); private static readonly MethodInfo setAnimatorBool = AccessTools.Method(typeof(Animator), "SetBool", new Type[2] { typeof(string), typeof(bool) }, (Type[])null); private static readonly Harmony harmony = new Harmony("MultipleWeatherEffects"); private static readonly Dictionary<SelectableLevel, List<RandomWeatherWithVariables>> additionalWeatherEffects = new Dictionary<SelectableLevel, List<RandomWeatherWithVariables>>(); private static int maxConcurrentWeatherEffectsLocal; private static int maxConcurrentWeatherEffects; private static double additionalWeatherEffectChanceLocal; private static double additionalWeatherEffectChance; private static bool eclipseOnlyLocal; private static bool eclipseOnly; private static CustomMessagingManager customMessagingManager => NetworkManager.Singleton.CustomMessagingManager; private static Exception patchFailedException => new InvalidOperationException("Failed to find matching instructions."); private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown maxConcurrentWeatherEffectsLocal = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "MaxConcurrentWeatherEffects", 3, new ConfigDescription("How many different weather effects can happen at once", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>())).Value; additionalWeatherEffectChanceLocal = ((BaseUnityPlugin)this).Config.Bind<double>("Settings", "AdditionalWeatherEffectChance", 0.2, new ConfigDescription("How likely a moon with weather is to have an additional weather effect\nThe chance stacks for multiple additional weather effects", (AcceptableValueBase)(object)new AcceptableValueRange<double>(0.0, 1.0), Array.Empty<object>())).Value; eclipseOnlyLocal = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "EclipseOnly", false, "Should eclipsed be added to every moons weather").Value; revertToLocalConfigValues(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Config loaded successfully"); harmony.PatchAll(typeof(Plugin)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Patches completed successfully"); } public static List<RandomWeatherWithVariables> getLevelAdditionalWeatherList(SelectableLevel level) { if ((Object)(object)level == (Object)null) { throw new ArgumentNullException("level", "Level cannot be null."); } if (additionalWeatherEffects.TryGetValue(level, out var value)) { return value; } return null; } public static RandomWeatherWithVariables getLevelAdditionalWeatherByType(SelectableLevel level, LevelWeatherType weatherType) { //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) return getLevelAdditionalWeatherList(level)?.Find((RandomWeatherWithVariables x) => x.weatherType == weatherType); } public static bool currentLevelHasWeatherEffect(LevelWeatherType weatherType) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return levelHasWeatherEffect(TimeOfDay.Instance.currentLevel, weatherType); } public static bool levelHasWeatherEffect(SelectableLevel level, LevelWeatherType weatherType) { //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) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (level.currentWeather == weatherType) { return true; } return getLevelAdditionalWeatherByType(level, weatherType) != null; } public static float getCurrentLevelWeatherVariable(LevelWeatherType weatherType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (TimeOfDay.Instance.currentLevelWeather == weatherType) { return TimeOfDay.Instance.currentWeatherVariable; } return getLevelAdditionalWeatherByType(TimeOfDay.Instance.currentLevel, weatherType).weatherVariable; } public static float getCurrentLevelWeatherVariable2(LevelWeatherType weatherType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (TimeOfDay.Instance.currentLevelWeather == weatherType) { return TimeOfDay.Instance.currentWeatherVariable2; } return getLevelAdditionalWeatherByType(TimeOfDay.Instance.currentLevel, weatherType).weatherVariable2; } private static void randomizeAdditionalWeatherEffects(SelectableLevel level, Random random) { if (StartOfRound.Instance.isChallengeFile) { return; } List<RandomWeatherWithVariables> list = level.randomWeathers.ToList(); list.RemoveAll((RandomWeatherWithVariables x) => x.weatherType == level.currentWeather); for (int i = 1; i < maxConcurrentWeatherEffects; i++) { if (random.NextDouble() > additionalWeatherEffectChance) { break; } if (list.Count == 0) { break; } int index = random.Next(0, list.Count); additionalWeatherEffects[level].Add(list[index]); list.RemoveAt(index); } } private static string getWeatherString(SelectableLevel level) { string text = ((object)(LevelWeatherType)(ref level.currentWeather)).ToString(); List<RandomWeatherWithVariables> levelAdditionalWeatherList = getLevelAdditionalWeatherList(level); if (levelAdditionalWeatherList == null) { return text; } foreach (RandomWeatherWithVariables item in levelAdditionalWeatherList) { text = text + ", " + ((object)(LevelWeatherType)(ref item.weatherType)).ToString(); } return text; } private static void enableAdditionalWeatherEffectPermanentObjects(bool enable) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) foreach (RandomWeatherWithVariables item in additionalWeatherEffects[StartOfRound.Instance.currentLevel]) { GameObject effectPermanentObject = TimeOfDay.Instance.effects[item.weatherType].effectPermanentObject; if (effectPermanentObject != null) { effectPermanentObject.SetActive(enable); } } } private static void tryEnableSunAnimatorBool(Animator sunAnimator, string name) { if (!(name != "eclipse") || !currentLevelHasWeatherEffect((LevelWeatherType)5)) { sunAnimator.SetBool(name, true); } } private static void enableAdditionalWeatherEffects() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) foreach (RandomWeatherWithVariables item in additionalWeatherEffects[StartOfRound.Instance.currentLevel]) { TimeOfDay.Instance.effects[item.weatherType].effectEnabled = true; } } private static void tryEnableWeatherEffectObject(GameObject gameObject) { if (!(((Object)gameObject).name == "RainParticleContainer") || !currentLevelHasWeatherEffect((LevelWeatherType)2)) { gameObject.SetActive(true); } } private static object getStlocTargetIndex(CodeInstruction instruction) { if (instruction.opcode == OpCodes.Stloc || instruction.opcode == OpCodes.Stloc_S) { return instruction.operand; } return instruction.opcode.Value - OpCodes.Stloc_0.Value; } private static bool isOpCodeInRange(CodeInstruction instruction, OpCode start, OpCode end) { if (instruction.opcode.Value >= start.Value) { return instruction.opcode.Value <= end.Value; } return false; } private static OpCode getLdcOpCodeByType(Type type) { return type.FullName switch { "StormyWeather" => OpCodes.Ldc_I4_2, "FloodWeather" => OpCodes.Ldc_I4_4, "EclipseWeather" => OpCodes.Ldc_I4_5, _ => OpCodes.Ldc_I4_M1, }; } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated")] private static void setLobbyConfigData(Lobby lobby) { ((Lobby)(ref lobby)).SetData("MultipleWeatherEffectsConfig", $"{maxConcurrentWeatherEffectsLocal} {additionalWeatherEffectChanceLocal} {eclipseOnlyLocal}"); } [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "JoinLobby")] private static void getLobbyConfigData(Lobby lobby) { string data = ((Lobby)(ref lobby)).GetData("MultipleWeatherEffectsConfig"); if (Utility.IsNullOrWhiteSpace(data)) { Debug.Log((object)"Set config values for vanilla game compatibility"); maxConcurrentWeatherEffects = 1; additionalWeatherEffectChance = 0.0; eclipseOnly = false; } else { string[] array = data.Split(' '); maxConcurrentWeatherEffects = int.Parse(array[0]); additionalWeatherEffectChance = double.Parse(array[1]); eclipseOnly = bool.Parse(array[2]); Debug.Log((object)$"Synced to host's config with values {maxConcurrentWeatherEffects}, {additionalWeatherEffectChance}, {eclipseOnly}"); } } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "LeaveCurrentSteamLobby")] private static void revertToLocalConfigValues() { maxConcurrentWeatherEffects = maxConcurrentWeatherEffectsLocal; additionalWeatherEffectChance = additionalWeatherEffectChanceLocal; eclipseOnly = eclipseOnlyLocal; Debug.Log((object)$"Reverted to local config with values {maxConcurrentWeatherEffects}, {additionalWeatherEffectChance}, {eclipseOnly}"); } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "SetPlanetsWeather")] private static void randomizeWeather() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Invalid comparison between Unknown and I4 //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Invalid comparison between Unknown and I4 //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (StartOfRound.Instance.isChallengeFile) { return; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel level in levels) { if (additionalWeatherEffects.TryGetValue(level, out var value)) { value.Clear(); } else { value = new List<RandomWeatherWithVariables>(); additionalWeatherEffects.Add(level, value); } List<RandomWeatherWithVariables> list = level.randomWeathers.ToList(); bool flag = (int)level.currentWeather == -1; int num = 1; if (eclipseOnly) { if (flag) { level.currentWeather = (LevelWeatherType)5; } else if ((int)level.currentWeather != 5) { int num2 = list.FindIndex((RandomWeatherWithVariables x) => (int)x.weatherType == 5); if (num2 != -1) { value.Add(level.randomWeathers[num2]); list.RemoveAt(num2); num++; } } } if (flag) { continue; } list.RemoveAll((RandomWeatherWithVariables x) => x.weatherType == level.currentWeather); Random random = new Random(~StartOfRound.Instance.randomMapSeed); for (int j = num; j < maxConcurrentWeatherEffects; j++) { if (random.NextDouble() > additionalWeatherEffectChance) { break; } if (list.Count == 0) { break; } int index = random.Next(0, list.Count); additionalWeatherEffects[level].Add(list[index]); list.RemoveAt(index); } } } [HarmonyTranspiler] [HarmonyPatch(typeof(Terminal), "TextPostProcess")] [HarmonyPatch(typeof(StartOfRound), "SetMapScreenInfoToCurrentLevel")] private static IEnumerable<CodeInstruction> displayWeatherTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); for (int i = 2; i < list.Count; i++) { if (CodeInstructionExtensions.LoadsField(list[i - 2], levelCurrentWeather, true) && CodeInstructionExtensions.Is(list[i - 1], OpCodes.Constrained, (MemberInfo)typeof(LevelWeatherType)) && CodeInstructionExtensions.Calls(list[i], objectToString)) { list.Insert(i + 1, CodeInstruction.Call(typeof(Plugin), "getWeatherString", (Type[])null, (Type[])null)); list.RemoveRange(i - 2, 3); return list; } } throw patchFailedException; } [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static IEnumerable<CodeInstruction> enableAdditionalWeatherEffectPermanentObjectsTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); for (int i = 2; i < list.Count; i++) { if (CodeInstructionExtensions.LoadsField(list[i - 2], weatherEffectPermanentObject, false) && isOpCodeInRange(list[i - 1], OpCodes.Ldc_I4_0, OpCodes.Ldc_I4_1) && CodeInstructionExtensions.Calls(list[i], setGameObjectActive)) { list.InsertRange(list.FindLastIndex(i, (CodeInstruction x) => CodeInstructionExtensions.IsStloc(x, (LocalBuilder)null)) + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(list[i - 1].opcode, (object)null), CodeInstruction.Call(typeof(Plugin), "enableAdditionalWeatherEffectPermanentObjects", (Type[])null, (Type[])null) })); return list; } } throw patchFailedException; } [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerControllerB), "SetSpectatedPlayerEffects")] [HarmonyPatch(typeof(AudioReverbTrigger), "ChangeAudioReverbForPlayer")] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static IEnumerable<CodeInstruction> enableAdditionalWeatherEffectsTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); for (int i = 3; i < list.Count; i++) { if (CodeInstructionExtensions.LoadsField(list[i - 3], currentLevelWeather, false) && list[i - 2].opcode == OpCodes.Ldelem_Ref && list[i - 1].opcode == OpCodes.Ldc_I4_1 && CodeInstructionExtensions.StoresField(list[i], weatherEffectEnabled)) { list.Insert(i + 1, CodeInstruction.Call(typeof(Plugin), "enableAdditionalWeatherEffects", (Type[])null, (Type[])null)); return list; } } throw patchFailedException; } [HarmonyTranspiler] [HarmonyPatch(typeof(StormyWeather), "DetermineNextStrikeInterval")] [HarmonyPatch(typeof(StormyWeather), "LightningStrikeRandom")] [HarmonyPatch(typeof(FloodWeather), "OnEnable")] [HarmonyPatch(typeof(FloodWeather), "OnGlobalTimeSync")] [HarmonyPatch(typeof(FloodWeather), "Update")] [HarmonyPatch(typeof(EclipseWeather), "OnEnable")] private static IEnumerable<CodeInstruction> getWeatherVariablesTranspiler(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); bool flag = false; string text = null; bool flag2 = false; for (int i = 1; i < list.Count; i++) { if (CodeInstructionExtensions.LoadsField(list[i], weatherVariable, false)) { flag = true; text = "getCurrentLevelWeatherVariable"; } else if (CodeInstructionExtensions.LoadsField(list[i], weatherVariable2, false)) { flag = true; text = "getCurrentLevelWeatherVariable2"; } if (flag) { list.RemoveRange(i - 1, 2); list.InsertRange(i - 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(getLdcOpCodeByType(__originalMethod.DeclaringType), (object)null), CodeInstruction.Call(typeof(Plugin), text, (Type[])null, (Type[])null) })); flag = false; flag2 = true; } } if (flag2) { return list; } throw patchFailedException; } [HarmonyTranspiler] [HarmonyPatch(typeof(EnemyAI), "CheckLineOfSightForPlayer")] [HarmonyPatch(typeof(EnemyAI), "CheckLineOfSightForClosestPlayer")] [HarmonyPatch(typeof(EnemyAI), "GetAllPlayersInLineOfSight")] [HarmonyPatch(typeof(RoundManager), "SpawnOutsideHazards")] [HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")] private static IEnumerable<CodeInstruction> weatherTypeCheckTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); for (int i = 3; i < list.Count; i++) { if (CodeInstructionExtensions.LoadsField(list[i - 2], currentLevelWeather, false) && isOpCodeInRange(list[i - 1], OpCodes.Ldc_I4_0, OpCodes.Ldc_I4_8) && list[i].opcode == OpCodes.Bne_Un) { list.RemoveRange(i - 3, 2); list.Insert(i - 2, CodeInstruction.Call(typeof(Plugin), "currentLevelHasWeatherEffect", (Type[])null, (Type[])null)); list[i - 1].opcode = OpCodes.Brfalse; return list; } } throw patchFailedException; } [HarmonyTranspiler] [HarmonyPatch(typeof(TimeOfDay), "SetWeatherEffects")] private static IEnumerable<CodeInstruction> sunAnimatorSetBoolTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); for (int i = 1; i < list.Count; i++) { if (list[i - 1].opcode == OpCodes.Ldc_I4_1 && CodeInstructionExtensions.Calls(list[i], setAnimatorBool)) { list.RemoveRange(i - 1, 2); list.Insert(i - 1, CodeInstruction.Call(typeof(Plugin), "tryEnableSunAnimatorBool", (Type[])null, (Type[])null)); return list; } } throw patchFailedException; } [HarmonyTranspiler] [HarmonyPatch(typeof(TimeOfDay), "SetWeatherEffects")] private static IEnumerable<CodeInstruction> enableWeatherEffectObjectTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = instructions.ToList(); for (int i = 1; i < list.Count; i++) { if (list[i - 1].opcode == OpCodes.Ldc_I4_1 && CodeInstructionExtensions.Calls(list[i], setGameObjectActive)) { list.RemoveRange(i - 1, 2); list.Insert(i - 1, CodeInstruction.Call(typeof(Plugin), "tryEnableWeatherEffectObject", (Type[])null, (Type[])null)); return list; } } throw patchFailedException; } } public static class PluginInfo { public const string PLUGIN_GUID = "MultipleWeatherEffects"; public const string PLUGIN_NAME = "MultipleWeatherEffects"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { 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(); } 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(); } }