Decompiled source of ServersideQoL PrefabConfigurator BETA v1.99.7

ServersideQoL.PrefabConfigurator.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ArgusMagnus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("ArgusMagnus")]
[assembly: AssemblyDescription("Configure prefabs to your hearts content.")]
[assembly: AssemblyFileVersion("1.99.7.0")]
[assembly: AssemblyInformationalVersion("1.99.7-beta+c3f968555bade7e3184055ac6214d025d4f009d5")]
[assembly: AssemblyProduct("ServersideQoL.PrefabConfigurator")]
[assembly: AssemblyTitle("ServersideQoL.PrefabConfigurator")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArgusMagnus/ValheimServersideQoL")]
[assembly: AssemblyVersion("1.99.7.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ServersideQoL.PrefabConfigurator
{
	public sealed class Config : ConfigBase<Config>
	{
		public sealed class PrefabsConfig
		{
			public sealed class ComponentConfig
			{
				public required string Component { get; init; }

				public required string[] PrefabNames { get; init; } = Array.Empty<string>();

				public required Dictionary<string, object?> Fields { get; init; }
			}

			public sealed class Vector3Yaml
			{
				public float x { get; init; }

				public float y { get; init; }

				public float z { get; init; }
			}

			[CompilerGenerated]
			private List<ComponentConfig> <Entries>k__BackingField;

			private static readonly Dictionary<string, (Type Type, IReadOnlyDictionary<string, FieldInfo>)> __validComponents = new Dictionary<string, (Type, IReadOnlyDictionary<string, FieldInfo>)>();

			public List<ComponentConfig> Entries
			{
				get
				{
					return <Entries>k__BackingField ?? (<Entries>k__BackingField = GetList());
				}
				[CompilerGenerated]
				init
				{
					<Entries>k__BackingField = value;
				}
			}

			[YamlIgnore]
			public IReadOnlyDictionary<string, (Type Type, IReadOnlyDictionary<string, FieldInfo>)> ValidComponents => __validComponents;

			private static List<ComponentConfig> GetList()
			{
				HashSet<Type> validFieldTypes = new HashSet<Type>
				{
					typeof(int),
					typeof(float),
					typeof(bool),
					typeof(Vector3),
					typeof(string),
					typeof(GameObject),
					typeof(ItemDrop)
				};
				List<ComponentConfig> list = new List<ComponentConfig>();
				foreach (IGrouping<Type, (string, MonoBehaviour)> item in from x in ZNetScene.instance.m_prefabs.SelectMany((GameObject x) => from c in ((Component)x.GetComponent<ZNetView>()).GetComponentsInChildren<MonoBehaviour>()
						select (name: ((Object)x).name, component: c))
					group x by ((object)x.component).GetType() into x
					orderby x.Key.Name
					select x)
				{
					Type key = item.Key;
					List<FieldInfo> list2 = (from x in key.GetFields(BindingFlags.Instance | BindingFlags.Public)
						where validFieldTypes.Contains(x.FieldType)
						select x).ToList();
					if (list2.Count == 0)
					{
						continue;
					}
					if (!__validComponents.ContainsKey(key.Name))
					{
						__validComponents.Add(key.Name, (key, list2.ToDictionary((FieldInfo x) => x.Name)));
					}
					foreach (var item2 in item)
					{
						var (text, component) = item2;
						list.Add(new ComponentConfig
						{
							Component = key.Name,
							PrefabNames = new string[1] { text },
							Fields = list2.ToDictionary((FieldInfo x) => x.Name, (FieldInfo x) => Serialize(x.GetValue(component)))
						});
					}
				}
				return list;
				static object? Serialize(object? value)
				{
					//IL_0013: Unknown result type (might be due to invalid IL or missing references)
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_002a: 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_0042: Unknown result type (might be due to invalid IL or missing references)
					Object val = (Object)((value is Object) ? value : null);
					if (val != null)
					{
						return val.name;
					}
					if (value is Vector3 val2)
					{
						return new Vector3Yaml
						{
							x = val2.x,
							y = val2.y,
							z = val2.z
						};
					}
					return value;
				}
			}
		}

		private const string Section = "PrefabConfigurator";

		public override ConfigEntry<bool> Enabled { get; } = ConfigBase<Config>.BindEx<bool>(cfg, "PrefabConfigurator", true, "Enables/disables the entire mod", (AcceptableValueBase)null, (Deprecated<Config>)null, "Enabled");

		public YamlConfigEntry<PrefabsConfig> Prefabs { get; } = ConfigBase<Config>.BindYaml<PrefabsConfig>(cfg, "Prefabs");

		public Config(ConfigFile cfg, Logger logger)
			: base(cfg, logger)
		{
		}
	}
	[BepInPlugin("ArgusMagnus.ServersideQoL.PrefabConfigurator", "ServersideQoL.PrefabConfigurator", "1.99.7")]
	public sealed class PrefabConfiguratorPlugin : ServersideQoLPluginBase<PrefabConfiguratorPlugin, Config>
	{
		public const string Author = "ArgusMagnus";

		public const string PluginName = "ServersideQoL.PrefabConfigurator";

		public const string PluginGuid = "ArgusMagnus.ServersideQoL.PrefabConfigurator";

		public const string PluginVersion = "1.99.7";

		public const string PluginInformationalVersion = "1.99.7-beta";

		private DateTimeOffset BuildTimestamp { get; } = new DateTimeOffset(639212504813034387L, default(TimeSpan));

		protected override Config CreateConfigSingleton(ConfigFile configFile, Logger logger)
		{
			return new Config(configFile, logger);
		}

		protected override void RegisterProcessors(IProcessorCollection processors)
		{
			processors.Add<PrefabProcessor>();
		}

		private void Awake()
		{
			ServersideQoLPluginBase<PrefabConfiguratorPlugin, Config>.Logger.LogWarning((object)string.Format("You are running a pre-release version: {0} ({1})", "1.99.7-beta", BuildTimestamp.LocalDateTime));
		}
	}
	[Processor("d597c8f7-129e-4c43-901a-20cea6520f14", Priority = int.MinValue)]
	public sealed class PrefabProcessor : Processor<PrefabProcessor.PrefabInfo>
	{
		public sealed record PrefabInfo : ProcessorPrefabInfo
		{
			internal bool Initialized { get; set; }

			internal bool Skip { get; set; }

			internal IReadOnlyList<(int, int, bool)>? IntValues { get; set; }

			internal IReadOnlyList<(int, float, bool)>? FloatValues { get; set; }

			internal IReadOnlyList<(int, Vector3, bool)>? Vector3Values { get; set; }

			internal IReadOnlyList<(int, string, bool)>? StringValues { get; set; }

			[CompilerGenerated]
			public override string ToString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("PrefabInfo");
				stringBuilder.Append(" { ");
				if (((ProcessorPrefabInfo)this).PrintMembers(stringBuilder))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append('}');
				return stringBuilder.ToString();
			}

			[CompilerGenerated]
			protected override bool PrintMembers(StringBuilder builder)
			{
				return ((ProcessorPrefabInfo)this).PrintMembers(builder);
			}

			[CompilerGenerated]
			public override int GetHashCode()
			{
				return (((((((ProcessorPrefabInfo)this).GetHashCode() * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(Initialized)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(Skip)) * -1521134295 + EqualityComparer<IReadOnlyList<(int, int, bool)>>.Default.GetHashCode(IntValues)) * -1521134295 + EqualityComparer<IReadOnlyList<(int, float, bool)>>.Default.GetHashCode(FloatValues)) * -1521134295 + EqualityComparer<IReadOnlyList<(int, Vector3, bool)>>.Default.GetHashCode(Vector3Values)) * -1521134295 + EqualityComparer<IReadOnlyList<(int, string, bool)>>.Default.GetHashCode(StringValues);
			}

			[CompilerGenerated]
			public sealed override bool Equals(ProcessorPrefabInfo? other)
			{
				return ((object)this).Equals((object?)other);
			}

			[CompilerGenerated]
			public bool Equals(PrefabInfo? other)
			{
				if ((object)this != other)
				{
					if (((ProcessorPrefabInfo)this).Equals((ProcessorPrefabInfo)(object)other) && EqualityComparer<bool>.Default.Equals(Initialized, other.Initialized) && EqualityComparer<bool>.Default.Equals(Skip, other.Skip) && EqualityComparer<IReadOnlyList<(int, int, bool)>>.Default.Equals(IntValues, other.IntValues) && EqualityComparer<IReadOnlyList<(int, float, bool)>>.Default.Equals(FloatValues, other.FloatValues) && EqualityComparer<IReadOnlyList<(int, Vector3, bool)>>.Default.Equals(Vector3Values, other.Vector3Values))
					{
						return EqualityComparer<IReadOnlyList<(int, string, bool)>>.Default.Equals(StringValues, other.StringValues);
					}
					return false;
				}
				return true;
			}

			[CompilerGenerated]
			private PrefabInfo(PrefabInfo original)
				: base((ProcessorPrefabInfo)(object)original)
			{
				Initialized = original.Initialized;
				Skip = original.Skip;
				IntValues = original.IntValues;
				FloatValues = original.FloatValues;
				Vector3Values = original.Vector3Values;
				StringValues = original.StringValues;
			}

			public PrefabInfo()
			{
			}
		}

		protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, PrefabInfo prefabInfo)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			if (!prefabInfo.Initialized)
			{
				if (ConfigBase<Config>.Instance.Prefabs.IsDefault)
				{
					return (ProcessResult)2;
				}
				Initialize(zdo, prefabInfo);
			}
			if (prefabInfo.Skip)
			{
				return (ProcessResult)2;
			}
			zdo.SetComponentHasFields();
			ProcessResult val = (ProcessResult)2;
			foreach (var item in prefabInfo.IntValues ?? Array.Empty<(int, int, bool)>())
			{
				var (num, num2, _) = item;
				if (item.Item3 ? zdo.ZDO.RemoveInt(num) : ZDOExtraData.Set(zdo.ZDO.m_uid, num, num2))
				{
					val = (ProcessResult)(val | 8);
				}
			}
			foreach (var item2 in prefabInfo.FloatValues ?? Array.Empty<(int, float, bool)>())
			{
				var (num3, num4, _) = item2;
				if (item2.Item3 ? zdo.ZDO.RemoveFloat(num3) : ZDOExtraData.Set(zdo.ZDO.m_uid, num3, num4))
				{
					val = (ProcessResult)(val | 8);
				}
			}
			foreach (var item3 in prefabInfo.Vector3Values ?? Array.Empty<(int, Vector3, bool)>())
			{
				var (num5, val2, _) = item3;
				if (item3.Item3 ? zdo.ZDO.RemoveVec3(num5) : ZDOExtraData.Set(zdo.ZDO.m_uid, num5, val2))
				{
					val = (ProcessResult)(val | 8);
				}
			}
			foreach (var item4 in prefabInfo.StringValues ?? Array.Empty<(int, string, bool)>())
			{
				var (num6, text, _) = item4;
				if (item4.Item3 ? zdo.ZDO.RemoveString(num6) : ZDOExtraData.Set(zdo.ZDO.m_uid, num6, text))
				{
					val = (ProcessResult)(val | 8);
				}
			}
			return val;
		}

		private void Initialize(ServersideQoLZDO zdo, PrefabInfo prefabInfo)
		{
			//IL_06ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0607: Unknown result type (might be due to invalid IL or missing references)
			prefabInfo.Initialized = true;
			List<(int, int, bool)> list = null;
			List<(int, float, bool)> list2 = null;
			List<(int, Vector3, bool)> list3 = null;
			List<(int, string, bool)> list4 = null;
			Vector3 val3 = default(Vector3);
			foreach (Config.PrefabsConfig.ComponentConfig entry in ConfigBase<Config>.Instance.Prefabs.Value.Entries)
			{
				if (!ConfigBase<Config>.Instance.Prefabs.Value.ValidComponents.TryGetValue(entry.Component, out (Type, IReadOnlyDictionary<string, FieldInfo>) value))
				{
					((Processor)this).Logger.LogWarning((object)("Invalid component: " + entry.Component));
					continue;
				}
				IReadOnlyDictionary<string, FieldInfo> readOnlyDictionary;
				Type key;
				(key, readOnlyDictionary) = value;
				if (!zdo.PrefabInfo.Components.TryGetValue(key, out var value2))
				{
					continue;
				}
				MonoBehaviour val = value2[0];
				key = ((object)val).GetType();
				string[] prefabNames = entry.PrefabNames;
				bool flag = prefabNames == null || prefabNames.Length <= 0;
				if (!flag)
				{
					string[] prefabNames2 = entry.PrefabNames;
					foreach (string text in prefabNames2)
					{
						int stableHashCode = StringExtensionMethods.GetStableHashCode(text.Trim(), true);
						if (stableHashCode != zdo.ZDO.GetPrefab())
						{
							if (ZNetScene.instance.GetPrefab(stableHashCode) == null)
							{
								((Processor)this).Logger.LogWarning((object)("Invalid prefab name '" + text + "' for component '" + entry.Component + "'"));
							}
							continue;
						}
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					continue;
				}
				bool flag2 = false;
				foreach (var (text3, obj2) in entry.Fields)
				{
					if (!readOnlyDictionary.TryGetValue(text3, out var value3))
					{
						((Processor)this).Logger.LogWarning((object)("Invalid field: " + entry.Component + "." + text3));
						continue;
					}
					bool flag3 = false;
					if (value3.FieldType == typeof(int))
					{
						string text4 = (obj2 as string)?.Trim();
						if (!string.IsNullOrEmpty(text4))
						{
							char c = '\0';
							int num = 0;
							bool flag4;
							switch (text4[0])
							{
							case '*':
							case '+':
							case '-':
							case '/':
								flag4 = true;
								break;
							default:
								flag4 = false;
								break;
							}
							if (flag4)
							{
								c = text4[0];
							}
							if (flag3 = int.TryParse(text4.AsSpan((c != '\0') ? 1 : 0), out var result))
							{
								num = (int)value3.GetValue(val);
								result = c switch
								{
									'+' => num + result, 
									'-' => num - result, 
									'*' => num * result, 
									'/' => num / result, 
									_ => result, 
								};
								bool flag5 = result == num;
								if (!flag5)
								{
									flag2 = true;
								}
								(list ?? (list = new List<(int, int, bool)>())).Add((StringExtensionMethods.GetStableHashCode(key.Name + "." + text3, true), result, flag5));
							}
						}
					}
					else if (value3.FieldType == typeof(float))
					{
						string text5 = (obj2 as string)?.Trim();
						if (!string.IsNullOrEmpty(text5))
						{
							char c2 = '\0';
							float num2 = 0f;
							bool flag4;
							switch (text5[0])
							{
							case '*':
							case '+':
							case '-':
							case '/':
								flag4 = true;
								break;
							default:
								flag4 = false;
								break;
							}
							if (flag4)
							{
								c2 = text5[0];
							}
							if (flag3 = float.TryParse(text5.AsSpan((c2 != '\0') ? 1 : 0), out var result2))
							{
								num2 = (float)value3.GetValue(val);
								result2 = c2 switch
								{
									'+' => num2 + result2, 
									'-' => num2 - result2, 
									'*' => num2 * result2, 
									'/' => num2 / result2, 
									_ => result2, 
								};
								bool flag6 = result2 == num2;
								if (!flag6)
								{
									flag2 = true;
								}
								(list2 ?? (list2 = new List<(int, float, bool)>())).Add((StringExtensionMethods.GetStableHashCode(key.Name + "." + text3, true), result2, flag6));
							}
						}
					}
					else if (value3.FieldType == typeof(bool))
					{
						string value4 = (obj2 as string)?.Trim();
						if (flag3 = bool.TryParse(value4, out var result3))
						{
							bool flag7 = (bool)value3.GetValue(val);
							bool flag8 = result3 == flag7;
							if (!flag8)
							{
								flag2 = true;
							}
							(list ?? (list = new List<(int, int, bool)>())).Add((StringExtensionMethods.GetStableHashCode(key.Name + "." + text3, true), result3 ? 1 : 0, flag8));
						}
					}
					else if (value3.FieldType == typeof(Vector3))
					{
						if (obj2 is Dictionary<string, object> dictionary && dictionary.TryGetValue("x", out var value5) && float.TryParse(value5 as string, out var result4) && dictionary.TryGetValue("y", out value5) && float.TryParse(value5 as string, out var result5) && dictionary.TryGetValue("z", out value5) && float.TryParse(value5 as string, out var result6))
						{
							flag3 = true;
							Vector3 val2 = (Vector3)value3.GetValue(val);
							((Vector3)(ref val3))..ctor(result4, result5, result6);
							bool flag9 = val3 == val2;
							if (!flag9)
							{
								flag2 = true;
							}
							(list3 ?? (list3 = new List<(int, Vector3, bool)>())).Add((StringExtensionMethods.GetStableHashCode(key.Name + "." + text3, true), val3, flag9));
						}
					}
					else if (value3.FieldType == typeof(string))
					{
						if (obj2 is string text6)
						{
							flag3 = true;
							string text7 = (string)value3.GetValue(val);
							bool flag10 = text6 == text7;
							if (!flag10)
							{
								flag2 = true;
							}
							(list4 ?? (list4 = new List<(int, string, bool)>())).Add((StringExtensionMethods.GetStableHashCode(key.Name + "." + text3, true), text6, flag10));
						}
					}
					else if (value3.FieldType == typeof(GameObject))
					{
						string text9;
						if (obj2 is string text8 && ZNetScene.instance.GetPrefab(text9 = text8.Trim()) != null)
						{
							flag3 = true;
							GameObject val4 = (GameObject)value3.GetValue(val);
							string text10 = (((int)val4 != 0) ? ((Object)val4).name : null) ?? "";
							bool flag11 = text9 == text10;
							if (!flag11)
							{
								flag2 = true;
							}
							(list4 ?? (list4 = new List<(int, string, bool)>())).Add((StringExtensionMethods.GetStableHashCode(key.Name + "." + text3, true), text9, flag11));
						}
					}
					else if (value3.FieldType == typeof(ItemDrop))
					{
						if (obj2 is string text11)
						{
							string text12;
							GameObject prefab = ZNetScene.instance.GetPrefab(text12 = text11.Trim());
							if (((prefab != null) ? prefab.GetComponent<ItemDrop>() : null) != null)
							{
								flag3 = true;
								ItemDrop val5 = (ItemDrop)value3.GetValue(val);
								string text13 = (((int)val5 != 0) ? ((Object)val5).name : null) ?? "";
								(list4 ?? (list4 = new List<(int, string, bool)>())).Add((StringExtensionMethods.GetStableHashCode(key.Name + "." + text3, true), text12, text12 == text13));
							}
						}
					}
					else
					{
						((Processor)this).Logger.LogWarning((object)("Unsupported field type: " + value3.FieldType.Name + " (" + entry.Component + "." + text3 + ")"));
						flag3 = false;
					}
					if (!flag3)
					{
						((Processor)this).Logger.LogWarning((object)$"Failed to parse field value as {value3.FieldType.Name}: {entry.Component}.{text3} = {obj2}");
					}
				}
				if (flag2)
				{
					if (list == null)
					{
						list = new List<(int, int, bool)>();
					}
					list.Add((StringExtensionMethods.GetStableHashCode("HasFields" + key.Name, true), 1, false));
				}
			}
			prefabInfo.IntValues = list;
			prefabInfo.FloatValues = list2;
			prefabInfo.Vector3Values = list3;
			prefabInfo.StringValues = list4;
			prefabInfo.Skip = list == null && list2 == null && list3 == null && list4 == null;
		}
	}
}