Decompiled source of ServersideQoL DropControl v2.0.0

ServersideQoL.DropControl.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using ServersideQoL.Utilities;
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: AssemblyCompany("ArgusMagnus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("ArgusMagnus")]
[assembly: AssemblyDescription("Configure mob drop tables")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+cdafe98fecdc9c33d99ba13f064e37dcaca41712")]
[assembly: AssemblyProduct("ServersideQoL.DropControl")]
[assembly: AssemblyTitle("ServersideQoL.DropControl")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArgusMagnus/ValheimServersideQoL")]
[assembly: AssemblyVersion("2.0.0.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.DropControl
{
	[Processor("4872b51f-6b0d-4f49-94ed-041f6c13fba6")]
	public sealed class CharacterDropAndRagdollProcessor : Processor<CharacterDropAndRagdollProcessor.PrefabInfo>
	{
		public sealed record PrefabInfo : ProcessorPrefabInfo
		{
			public ItemDrop? ItemDrop { get; }

			[MemberNotNullWhen(true, "CharacterDrop")]
			public bool IsCharacterDrop
			{
				[MemberNotNullWhen(true, "CharacterDrop")]
				get;
			}

			public CharacterDrop? CharacterDrop { get; private set; }

			[MemberNotNullWhen(true, new string[] { "Ragdoll", "CharacterDrop" })]
			public bool IsRagdoll
			{
				[MemberNotNullWhen(true, new string[] { "Ragdoll", "CharacterDrop" })]
				get;
			}

			public Ragdoll? Ragdoll { get; private set; }

			public Config.DropsConfig.DropConfig DropConfig { get; private set; }

			public bool RequiresCustomSpawnDrops { get; private set; }

			public IReadOnlyDictionary<int, Drop> OriginalDropsByHash { get; private set; }

			public bool HasRagdoll { get; private set; }

			private static IReadOnlyDictionary<string, Config.DropsConfig.DropConfig> DropsByName => <DropsByName>k__BackingField ?? (<DropsByName>k__BackingField = ConfigBase<Config>.Instance.Drops.Value.Entries.Where((Config.DropsConfig.DropConfig x) => x.Enabled).ToDictionary((Config.DropsConfig.DropConfig x) => x.Name));

			private static IReadOnlyDictionary<Ragdoll, CharacterDrop> CharacterDropByRagdoll => <CharacterDropByRagdoll>k__BackingField ?? (<CharacterDropByRagdoll>k__BackingField = GetCharacterDropByRagdoll());

			public override bool IsValid
			{
				get
				{
					//IL_0197: Unknown result type (might be due to invalid IL or missing references)
					//IL_019c: 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_01af: Unknown result type (might be due to invalid IL or missing references)
					//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
					//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
					//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
					//IL_01df: Unknown result type (might be due to invalid IL or missing references)
					//IL_01f0: Expected O, but got Unknown
					if (ItemDrop != null)
					{
						return true;
					}
					if (CharacterDrop != null)
					{
						Ragdoll = ((ProcessorPrefabInfo)this).PrefabInfo.GetComponent<Character>()?.m_deathEffects.m_effectPrefabs.Select((EffectData x) => x.m_prefab.GetComponent<Ragdoll>()).FirstOrDefault((Func<Ragdoll, bool>)((Ragdoll x) => x != null));
					}
					else if (Ragdoll != null)
					{
						CharacterDrop = CharacterDropByRagdoll.GetValueOrDefault(Ragdoll);
					}
					DropConfig = null;
					if (CharacterDrop == null || !DropsByName.TryGetValue(((Object)((Component)CharacterDrop).gameObject).name, out Config.DropsConfig.DropConfig value))
					{
						return false;
					}
					DropConfig = value;
					OriginalDropsByHash = CharacterDrop.m_drops.Where((Drop x) => x.m_levelMultiplier && !x.m_onePerPlayer).ToDictionary((Drop x) => ZNetScene.instance.GetPrefabHash(x.m_prefab));
					CharacterDrop.m_drops.Clear();
					foreach (Config.DropsConfig.DropConfig.Drop drop in value.Drops)
					{
						GameObject prefab = ZNetScene.instance.GetPrefab(drop.Prefab);
						if (prefab == null)
						{
							((Processor)Processor.Instance<CharacterDropAndRagdollProcessor>()).Logger.LogWarning((object)("Invalid prefab name: " + drop.Prefab));
							continue;
						}
						CharacterDrop.m_drops.Add(new Drop
						{
							m_prefab = prefab,
							m_amountMin = drop.AmountMin,
							m_amountMax = drop.AmountMax,
							m_chance = drop.Chance,
							m_onePerPlayer = drop.OnePerPlayer,
							m_levelMultiplier = drop.DoubleAmountAndChancePerLevel,
							m_dontScale = drop.IgnoreWorldResourceRate
						});
						bool flag = !RequiresCustomSpawnDrops;
						bool flag2 = flag;
						bool flag3;
						if (flag2)
						{
							if (drop != null)
							{
								float qualityIncreaseChance = drop.QualityIncreaseChance;
								if (qualityIncreaseChance > 0f)
								{
									int maxQuality = drop.MaxQuality;
									if (maxQuality > 1 || drop.MultiplyMaxQualityByLevel)
									{
										goto IL_0287;
									}
								}
								if (!drop.MinLevel.HasValue && !drop.MaxLevel.HasValue)
								{
									string requiredGlobalKey = drop.RequiredGlobalKey;
									if (requiredGlobalKey == null || requiredGlobalKey.Length == 0)
									{
										string forbiddenGlobalKey = drop.ForbiddenGlobalKey;
										if (forbiddenGlobalKey == null || forbiddenGlobalKey.Length == 0)
										{
											flag3 = false;
											goto IL_028f;
										}
									}
								}
							}
							goto IL_0287;
						}
						goto IL_0293;
						IL_0287:
						flag3 = true;
						goto IL_028f;
						IL_028f:
						flag2 = flag3;
						goto IL_0293;
						IL_0293:
						if (flag2)
						{
							RequiresCustomSpawnDrops = true;
						}
					}
					return true;
				}
			}

			[CompilerGenerated]
			private static IReadOnlyDictionary<string, Config.DropsConfig.DropConfig> <DropsByName>k__BackingField;

			[CompilerGenerated]
			private static IReadOnlyDictionary<Ragdoll, CharacterDrop> <CharacterDropByRagdoll>k__BackingField;

			public PrefabInfo(ItemDrop? itemDrop, CharacterDrop? characterDrop, Ragdoll? ragdoll)
			{
				ItemDrop = itemDrop;
				CharacterDrop = characterDrop;
				IsCharacterDrop = characterDrop != null;
				Ragdoll = ragdoll;
				IsRagdoll = ragdoll != null;
			}

			private static IReadOnlyDictionary<Ragdoll, CharacterDrop> GetCharacterDropByRagdoll()
			{
				Dictionary<Ragdoll, CharacterDrop> dictionary = new Dictionary<Ragdoll, CharacterDrop>();
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					CharacterDrop component = prefab.GetComponent<CharacterDrop>();
					if (component == null)
					{
						continue;
					}
					Character component2 = prefab.GetComponent<Character>();
					if (component2 == null)
					{
						continue;
					}
					Ragdoll val = component2.m_deathEffects.m_effectPrefabs.Select((EffectData x) => x.m_prefab.GetComponent<Ragdoll>()).FirstOrDefault((Func<Ragdoll, bool>)((Ragdoll x) => x != null));
					if (val != null)
					{
						if (DropsByName.ContainsKey(((Object)((Component)component).gameObject).name))
						{
							dictionary[val] = component;
						}
						else
						{
							dictionary.TryAdd(val, component);
						}
					}
				}
				return dictionary;
			}

			[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)
			{
				if (((ProcessorPrefabInfo)this).PrintMembers(builder))
				{
					builder.Append(", ");
				}
				builder.Append("ItemDrop = ");
				builder.Append(ItemDrop);
				builder.Append(", IsCharacterDrop = ");
				builder.Append(IsCharacterDrop.ToString());
				builder.Append(", CharacterDrop = ");
				builder.Append(CharacterDrop);
				builder.Append(", IsRagdoll = ");
				builder.Append(IsRagdoll.ToString());
				builder.Append(", Ragdoll = ");
				builder.Append(Ragdoll);
				builder.Append(", DropConfig = ");
				builder.Append(DropConfig);
				builder.Append(", RequiresCustomSpawnDrops = ");
				builder.Append(RequiresCustomSpawnDrops.ToString());
				builder.Append(", OriginalDropsByHash = ");
				builder.Append(OriginalDropsByHash);
				builder.Append(", HasRagdoll = ");
				builder.Append(HasRagdoll.ToString());
				return true;
			}

			[CompilerGenerated]
			public override int GetHashCode()
			{
				return ((((((((((ProcessorPrefabInfo)this).GetHashCode() * -1521134295 + EqualityComparer<ItemDrop>.Default.GetHashCode(ItemDrop)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(IsCharacterDrop)) * -1521134295 + EqualityComparer<CharacterDrop>.Default.GetHashCode(CharacterDrop)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(IsRagdoll)) * -1521134295 + EqualityComparer<Ragdoll>.Default.GetHashCode(Ragdoll)) * -1521134295 + EqualityComparer<Config.DropsConfig.DropConfig>.Default.GetHashCode(DropConfig)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(RequiresCustomSpawnDrops)) * -1521134295 + EqualityComparer<IReadOnlyDictionary<int, Drop>>.Default.GetHashCode(OriginalDropsByHash)) * -1521134295 + EqualityComparer<bool>.Default.GetHashCode(HasRagdoll);
			}

			[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<ItemDrop>.Default.Equals(ItemDrop, other.ItemDrop) && EqualityComparer<bool>.Default.Equals(IsCharacterDrop, other.IsCharacterDrop) && EqualityComparer<CharacterDrop>.Default.Equals(CharacterDrop, other.CharacterDrop) && EqualityComparer<bool>.Default.Equals(IsRagdoll, other.IsRagdoll) && EqualityComparer<Ragdoll>.Default.Equals(Ragdoll, other.Ragdoll) && EqualityComparer<Config.DropsConfig.DropConfig>.Default.Equals(DropConfig, other.DropConfig) && EqualityComparer<bool>.Default.Equals(RequiresCustomSpawnDrops, other.RequiresCustomSpawnDrops) && EqualityComparer<IReadOnlyDictionary<int, Drop>>.Default.Equals(OriginalDropsByHash, other.OriginalDropsByHash))
					{
						return EqualityComparer<bool>.Default.Equals(HasRagdoll, other.HasRagdoll);
					}
					return false;
				}
				return true;
			}

			[CompilerGenerated]
			private PrefabInfo(PrefabInfo original)
				: base((ProcessorPrefabInfo)(object)original)
			{
				ItemDrop = original.ItemDrop;
				IsCharacterDrop = original.IsCharacterDrop;
				CharacterDrop = original.CharacterDrop;
				IsRagdoll = original.IsRagdoll;
				Ragdoll = original.Ragdoll;
				DropConfig = original.DropConfig;
				RequiresCustomSpawnDrops = original.RequiresCustomSpawnDrops;
				OriginalDropsByHash = original.OriginalDropsByHash;
				HasRagdoll = original.HasRagdoll;
			}
		}

		public const string Id = "4872b51f-6b0d-4f49-94ed-041f6c13fba6";

		private float _dropArea;

		private Vector3 _ragdollDropOffset;

		private SectorDictionary<Ragdoll, List<(CharacterDrop, int)>> _characterDropsByRagdoll = new SectorDictionary<Ragdoll, List<(CharacterDrop, int)>>(1f);

		protected override void Initialize()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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)
			_dropArea = (float)typeof(CharacterDrop).GetField("m_dropArea", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic).GetRawConstantValue();
			_ragdollDropOffset = Vector3.up * (float)typeof(Ragdoll).GetField("m_dropOffset", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic).GetRawConstantValue();
		}

		protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, PrefabInfo prefabInfo)
		{
			//IL_0001: 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_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: 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)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			ProcessResult val = (ProcessResult)2;
			if (prefabInfo.ItemDrop != null)
			{
				if (zdo.ZDO.GetPosition().y > 90000f)
				{
					val = (ProcessResult)4;
				}
			}
			else if (prefabInfo.IsCharacterDrop)
			{
				if (prefabInfo.Ragdoll != null)
				{
					zdo.Destroyed += OnCharacterDropWithRagdollDestroyed;
				}
				else
				{
					if (zdo.Fields<CharacterDrop>().UpdateValue((Func<Expression<Func<CharacterDrop, Vector3>>>)(() => (CharacterDrop x) => x.m_spawnOffset), new Vector3(0f, 100000f, 0f), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.DropControl\\CharacterDropAndRagdollProcessor.cs", 150))
					{
						val = (ProcessResult)(val | 8);
					}
					zdo.Destroyed += OnCharacterDropDestroyed;
				}
			}
			else if (prefabInfo.IsRagdoll)
			{
				CharacterDrop characterDrop = prefabInfo.CharacterDrop;
				int num = 1;
				(CharacterDrop, int) tuple = default((CharacterDrop, int));
				ZDOVars vars;
				if (SectorDictionary.TryPop<Ragdoll, (CharacterDrop, int)>(_characterDropsByRagdoll, (zdo.ZDO.GetPosition(), prefabInfo.Ragdoll), true, ref tuple))
				{
					(characterDrop, num) = tuple;
				}
				else
				{
					int num2 = 0;
					int num3 = int.MaxValue;
					int num4 = int.MaxValue;
					int num5 = 0;
					while (true)
					{
						int num6 = num5;
						vars = zdo.Vars;
						if (num6 >= ((ZDOVars)(ref vars)).GetDrops(0))
						{
							break;
						}
						vars = zdo.Vars;
						int dropHash = ((ZDOVars)(ref vars)).GetDropHash(num5, 0);
						if (prefabInfo.OriginalDropsByHash.TryGetValue(dropHash, out Drop value))
						{
							vars = zdo.Vars;
							int dropAmount = ((ZDOVars)(ref vars)).GetDropAmount(num5, 0);
							if (value.m_dontScale || Game.m_resourceRate == 1f)
							{
								num2 = Math.Max(num2, dropAmount / value.m_amountMax);
								num3 = Math.Min(num3, dropAmount / value.m_amountMin);
							}
							else
							{
								float num7 = Mathf.Ceil(((float)dropAmount - 0.5f) / Game.m_resourceRate);
								float num8 = Mathf.Floor(((float)dropAmount + 0.5f) / Game.m_resourceRate);
								num2 = Math.Max(num2, Mathf.CeilToInt(num7 / (float)value.m_amountMax));
								num3 = Math.Min(num3, Mathf.FloorToInt(num8 / (float)value.m_amountMin));
							}
							if (dropAmount < 100)
							{
								num4 = Math.Min(num4, num3);
							}
							if (num2 >= num4)
							{
								break;
							}
						}
						num5++;
					}
					if (num4 == int.MaxValue)
					{
						num4 = num3;
					}
					if (num2 > 0)
					{
						num = (int)Mathf.Log((float)num2, 2f) + 1;
					}
				}
				if (prefabInfo.RequiresCustomSpawnDrops)
				{
					if (num > 1)
					{
						vars = zdo.Vars;
						((ZDOVars)(ref vars)).SetLevel(num, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.DropControl\\CharacterDropAndRagdollProcessor.cs", 210);
					}
					vars = zdo.Vars;
					((ZDOVars)(ref vars)).SetDrops(0, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.DropControl\\CharacterDropAndRagdollProcessor.cs", 211);
					zdo.Destroyed += OnCharacterDropDestroyed;
				}
				else
				{
					List<KeyValuePair<GameObject, int>> list = GenerateDropList(characterDrop, num);
					vars = zdo.Vars;
					((ZDOVars)(ref vars)).SetDrops(list.Count, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.DropControl\\CharacterDropAndRagdollProcessor.cs", 218);
					for (int num9 = 0; num9 < list.Count; num9++)
					{
						list[num9].Deconstruct(out var key, out var value2);
						GameObject val2 = key;
						int num10 = value2;
						int prefabHash = ZNetScene.instance.GetPrefabHash(val2);
						vars = zdo.Vars;
						((ZDOVars)(ref vars)).SetDropHash(num9, prefabHash, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.DropControl\\CharacterDropAndRagdollProcessor.cs", 223);
						vars = zdo.Vars;
						((ZDOVars)(ref vars)).SetDropAmount(num9, num10, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.DropControl\\CharacterDropAndRagdollProcessor.cs", 224);
					}
				}
				ZDO zDO = zdo.ZDO;
				zDO.DataRevision += 100;
			}
			return val;
		}

		private void OnCharacterDropWithRagdollDestroyed(ServersideQoLZDO zdo)
		{
			//IL_002b: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			PrefabInfo processorPrefabInfo = Processor<PrefabInfo>.GetProcessorPrefabInfo(zdo);
			if ((object)processorPrefabInfo == null)
			{
				return;
			}
			CharacterDrop characterDrop = processorPrefabInfo.CharacterDrop;
			if (characterDrop != null)
			{
				Ragdoll ragdoll = processorPrefabInfo.Ragdoll;
				if (ragdoll != null)
				{
					SectorDictionary<Ragdoll, List<(CharacterDrop, int)>> characterDropsByRagdoll = _characterDropsByRagdoll;
					(Vector3, Ragdoll) valueTuple = (zdo.ZDO.GetPosition(), ragdoll);
					ZDOVars vars = zdo.Vars;
					SectorDictionary.Add<Ragdoll, List<(CharacterDrop, int)>, (CharacterDrop, int)>(characterDropsByRagdoll, valueTuple, (characterDrop, ((ZDOVars)(ref vars)).GetLevel(1)));
				}
			}
		}

		private static List<KeyValuePair<GameObject, int>> GenerateDropList(CharacterDrop characterDrop, int level)
		{
			Character component = ((Component)characterDrop).GetComponent<Character>();
			int level2 = component.GetLevel();
			component.SetLevel(level);
			try
			{
				return characterDrop.GenerateDropList();
			}
			finally
			{
				component.SetLevel(level2);
			}
		}

		private void OnCharacterDropDestroyed(ServersideQoLZDO zdo)
		{
			//IL_001c: 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_004c: 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_0051: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			PrefabInfo processorPrefabInfo = Processor<PrefabInfo>.GetProcessorPrefabInfo(zdo);
			if ((object)processorPrefabInfo == null || processorPrefabInfo.CharacterDrop == null)
			{
				return;
			}
			ZDOVars vars;
			if (processorPrefabInfo.Ragdoll == null)
			{
				vars = zdo.Vars;
				if (((ZDOVars)(ref vars)).GetHealth(1f) > 0f)
				{
					return;
				}
			}
			Vector3 val = ((processorPrefabInfo.Ragdoll != null) ? _ragdollDropOffset : processorPrefabInfo.CharacterDrop.m_spawnOffset);
			if (processorPrefabInfo.RequiresCustomSpawnDrops)
			{
				SpawnDrops(zdo, processorPrefabInfo.CharacterDrop, processorPrefabInfo.DropConfig, val, _dropArea);
				return;
			}
			CharacterDrop? characterDrop = processorPrefabInfo.CharacterDrop;
			vars = zdo.Vars;
			List<KeyValuePair<GameObject, int>> list = GenerateDropList(characterDrop, ((ZDOVars)(ref vars)).GetLevel(1));
			CharacterDrop.DropItems(list, zdo.ZDO.GetPosition() + val, _dropArea, false);
			static void SpawnDrop(Drop drop, Config.DropsConfig.DropConfig.Drop cfg, int amount, int level, float levelMultiplier, Vector3 centerPos, float dropArea)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0036: 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_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)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0130: Unknown result type (might be due to invalid IL or missing references)
				//IL_0132: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_0158: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				for (int i = 0; i < amount; i++)
				{
					Quaternion val2 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f);
					Vector3 val3 = Random.insideUnitSphere * dropArea;
					GameObject val4 = Object.Instantiate<GameObject>(drop.m_prefab, centerPos + val3, val2);
					ItemDrop component = val4.GetComponent<ItemDrop>();
					Character component2 = val4.GetComponent<Character>();
					if (component != null || component2 != null)
					{
						if (component != null)
						{
							component.m_itemData.m_worldLevel = (byte)Game.m_worldLevel;
						}
						float num = cfg.QualityIncreaseChance;
						if (cfg.DoubleQualityIncreaseChancePerLevel)
						{
							num *= levelMultiplier;
						}
						int num2 = cfg.MaxQuality;
						if (cfg.MultiplyMaxQualityByLevel && level > 1)
						{
							num2 *= level;
							num = Mathf.Pow(num, Mathf.Max(1f, (float)cfg.MaxQuality - 1f) / ((float)num2 - 1f));
						}
						int num3 = 0;
						while (++num3 < num2 && Random.value <= num)
						{
						}
						if (num3 > 1)
						{
							if (component != null)
							{
								component.SetQuality(num3);
								ItemDrop.SaveToZDO(component.m_itemData, ((Component)component).GetComponent<ZNetView>().GetZDO(), -1);
							}
							if (component2 != null)
							{
								component2.SetLevel(level);
							}
						}
					}
					Rigidbody component3 = val4.GetComponent<Rigidbody>();
					if (component3 != null)
					{
						Vector3 insideUnitSphere = Random.insideUnitSphere;
						if (insideUnitSphere.y < 0f)
						{
							insideUnitSphere.y = 0f - insideUnitSphere.y;
						}
						component3.AddForce(insideUnitSphere * 5f, (ForceMode)2);
					}
				}
			}
			static void SpawnDrops(ServersideQoLZDO val2, CharacterDrop val3, Config.DropsConfig.DropConfig dropConfig, Vector3 offset, float dropArea)
			{
				//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_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				ZDOVars vars2 = val2.Vars;
				int level = ((ZDOVars)(ref vars2)).GetLevel(1);
				int num = Mathf.Max(1, (int)Mathf.Pow(2f, (float)(level - 1)));
				for (int i = 0; i < val3.m_drops.Count; i++)
				{
					Drop val4 = val3.m_drops[i];
					if (val4 != null && val4.m_prefab != null)
					{
						Config.DropsConfig.DropConfig.Drop drop = dropConfig.Drops[i];
						if (!(level < drop.MinLevel) && !(level > drop.MaxLevel) && (string.IsNullOrEmpty(drop.RequiredGlobalKey) || ZoneSystem.instance.GetGlobalKey(drop.RequiredGlobalKey)) && (string.IsNullOrEmpty(drop.ForbiddenGlobalKey) || !ZoneSystem.instance.GetGlobalKey(drop.ForbiddenGlobalKey)))
						{
							float num2 = val4.m_chance;
							if (val4.m_levelMultiplier)
							{
								num2 *= (float)num;
							}
							if (!(Random.value > num2))
							{
								int num3 = (val4.m_dontScale ? Random.Range(val4.m_amountMin, val4.m_amountMax) : Game.instance.ScaleDrops(val4.m_prefab, val4.m_amountMin, val4.m_amountMax));
								if (val4.m_levelMultiplier)
								{
									num3 *= num;
								}
								if (val4.m_onePerPlayer)
								{
									num3 = ZNet.instance.GetNrOfPlayers();
								}
								if (num3 > 100)
								{
									num3 = 100;
								}
								if (num3 > 0)
								{
									SpawnDrop(val4, drop, num3, level, num, val2.ZDO.GetPosition() + offset, dropArea);
								}
							}
						}
					}
				}
			}
		}
	}
	public sealed class Config : ConfigBase<Config>
	{
		public sealed class DropsConfig
		{
			public sealed class DropConfig
			{
				public sealed class Drop
				{
					public required string Prefab { get; init; }

					public required int AmountMin { get; init; }

					public required int AmountMax { get; init; }

					public required float Chance { get; init; }

					public required bool OnePerPlayer { get; init; }

					public required bool DoubleAmountAndChancePerLevel { get; init; }

					public required bool IgnoreWorldResourceRate { get; init; }

					public int? MinLevel { get; init; }

					public int? MaxLevel { get; init; }

					public string? RequiredGlobalKey { get; init; }

					public string? ForbiddenGlobalKey { get; init; }

					public float QualityIncreaseChance { get; init; }

					public bool DoubleQualityIncreaseChancePerLevel { get; init; } = true;

					public int MaxQuality { get; init; } = 1;

					public bool MultiplyMaxQualityByLevel { get; init; }
				}

				public required string Name { get; init; }

				public required string? DisplayName { get; init; }

				public bool Enabled { get; init; }

				public required List<Drop> Drops { get; init; }
			}

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

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

			private static List<DropConfig> GetDrops()
			{
				List<DropConfig> list = new List<DropConfig>();
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					CharacterDrop component = prefab.GetComponent<CharacterDrop>();
					if (component != null)
					{
						Character component2 = prefab.GetComponent<Character>();
						list.Add(new DropConfig
						{
							Name = ((Object)((Component)component).gameObject).name,
							DisplayName = ((component2 == null) ? null : StringExtensionMethods.RemoveRichTextTags(Localization.instance.Localize(component2.m_name))),
							Drops = component.m_drops.Select((Drop x) => new DropConfig.Drop
							{
								Prefab = ((Object)x.m_prefab).name,
								AmountMin = x.m_amountMin,
								AmountMax = x.m_amountMax,
								Chance = x.m_chance,
								OnePerPlayer = x.m_onePerPlayer,
								DoubleAmountAndChancePerLevel = x.m_levelMultiplier,
								IgnoreWorldResourceRate = x.m_dontScale
							}).ToList()
						});
					}
				}
				return list;
			}
		}

		private const string Section = "DropControl";

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

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

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

		public const string PluginName = "ServersideQoL.DropControl";

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

		public const string PluginVersion = "2.0.0";

		public const string PluginInformationalVersion = "2.0.0";

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

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

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

		private void Awake()
		{
		}
	}
}