Decompiled source of DropCleaner v1.1.0

BepInEx/plugins/DropCleaner/DropCleaner.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("DropCleaner")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DropCleaner")]
[assembly: AssemblyTitle("DropCleaner")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 DropCleanerMod
{
	[BepInPlugin("com.yourname.dropcleaner", "DropCleaner", "1.0.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DropCleaner : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <CleanupLoop>d__10 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public DropCleaner <>4__this;

			private int <removed>5__1;

			private int <total>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CleanupLoop>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					<removed>5__1 = <>4__this.PerformCleanup();
					((BaseUnityPlugin)<>4__this).Logger.LogInfo((object)$"[DropCleaner] Removed {<removed>5__1} items");
					<total>5__2 = Object.FindObjectsOfType<ItemDrop>().Length;
					if (<total>5__2 > 300)
					{
						<>4__this.cleanupInterval.Value = Mathf.Max(10f, <>4__this.cleanupInterval.Value - 5f);
					}
					else if (<total>5__2 < 100)
					{
						<>4__this.cleanupInterval.Value = Mathf.Min(120f, <>4__this.cleanupInterval.Value + 5f);
					}
					break;
				}
				<>2__current = (object)new WaitForSeconds(<>4__this.cleanupInterval.Value);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private ConfigEntry<float> cleanupInterval;

		private ConfigEntry<string> minimumRarityToKeep;

		private ConfigEntry<float> arenaRadius;

		private ConfigEntry<bool> filterTrophies;

		private ConfigEntry<bool> filterValuables;

		private ConfigEntry<int> minItemAgeToDelete;

		private static readonly List<string> trophyItems = new List<string>
		{
			"TrophyBoar", "TrophyDeer", "TrophyGreydwarf", "TrophyGreydwarfBrute", "TrophyGreydwarfShaman", "TrophySkeleton", "TrophyDraugr", "TrophyDraugrElite", "TrophyBlob", "TrophyWraith",
			"TrophySurtling", "TrophyWolf", "TrophyHatchling", "TrophyLox", "TrophyGoblin", "TrophyGoblinBrute", "TrophyGoblinShaman", "TrophyDeathsquito", "TrophyEikthyr", "TrophyTheElder",
			"TrophyBonemass", "TrophyModer", "TrophyYagluth", "TrophyQueen"
		};

		private static readonly List<string> valuableItems = new List<string> { "Coins", "Amber", "AmberPearl", "Ruby", "SilverNecklace" };

		private Coroutine cleanupRoutine;

		private void Awake()
		{
			cleanupInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CleanupInterval", 750f, "Seconds between cleanup runs.");
			minimumRarityToKeep = ((BaseUnityPlugin)this).Config.Bind<string>("Filters", "MinimumRarityToKeep", "Magic", "EpicLoot rarity threshold.");
			arenaRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Filters", "ArenaRadius", 60f, "Skip items within X of bosses.");
			filterTrophies = ((BaseUnityPlugin)this).Config.Bind<bool>("Filters", "FilterTrophies", true, "Never delete trophies.");
			filterValuables = ((BaseUnityPlugin)this).Config.Bind<bool>("Filters", "FilterValuables", true, "Never delete valuables.");
			minItemAgeToDelete = ((BaseUnityPlugin)this).Config.Bind<int>("Filters", "MinItemAgeToDelete", 300, "Min seconds since drop before deletion.");
			cleanupRoutine = ((MonoBehaviour)this).StartCoroutine(CleanupLoop());
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[DropCleaner] Loaded. Cleaning every {cleanupInterval.Value}s");
		}

		[IteratorStateMachine(typeof(<CleanupLoop>d__10))]
		private IEnumerator CleanupLoop()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CleanupLoop>d__10(0)
			{
				<>4__this = this
			};
		}

		private int PerformCleanup()
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			ItemDrop[] array = Object.FindObjectsOfType<ItemDrop>();
			long ticks = ZNet.instance.GetTime().Ticks;
			ItemDrop[] array2 = array;
			foreach (ItemDrop val in array2)
			{
				if ((Object)(object)val == (Object)null || val.m_itemData == null || (Object)(object)((Component)val).transform.parent != (Object)null)
				{
					continue;
				}
				GameObject dropPrefab = val.m_itemData.m_dropPrefab;
				string text = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
				if (!string.IsNullOrEmpty(text) && (!filterTrophies.Value || !trophyItems.Contains(text)) && (!filterValuables.Value || !valuableItems.Contains(text)) && !((Object)val).name.Contains("Arrow") && !((Object)val).name.Contains("Projectile") && !IsInsideBossArena(((Component)val).transform.position) && (!val.m_itemData.m_customData.TryGetValue("Rarity", out var value) || IsBelowMinRarity(value)))
				{
					ZNetView component = ((Component)val).GetComponent<ZNetView>();
					long? obj;
					if (component == null)
					{
						obj = null;
					}
					else
					{
						ZDO zDO = component.GetZDO();
						obj = ((zDO != null) ? new long?(zDO.GetLong("created", 0L)) : null);
					}
					long? num2 = obj;
					long valueOrDefault = num2.GetValueOrDefault();
					long num3 = (ticks - valueOrDefault) / 10000000;
					((BaseUnityPlugin)this).Logger.LogDebug((object)$"[DropCleaner] {text} age={num3}s");
					if (num3 >= minItemAgeToDelete.Value)
					{
						ZNetScene.instance.Destroy(((Component)val).gameObject);
						num++;
					}
				}
			}
			return num;
		}

		private bool IsBelowMinRarity(string rarity)
		{
			string[] array = new string[6] { "None", "Magic", "Rare", "Epic", "Legendary", "Unique" };
			int num = Array.IndexOf(array, rarity);
			int num2 = Array.IndexOf(array, minimumRarityToKeep.Value);
			return num < num2;
		}

		private bool IsInsideBossArena(Vector3 pos)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if ((Object)(object)allCharacter != (Object)null && allCharacter.IsBoss() && Vector3.Distance(pos, ((Component)allCharacter).transform.position) < arenaRadius.Value)
				{
					return true;
				}
			}
			return false;
		}
	}
}