Decompiled source of Always Be Searchin v0.1.1

plugins/AlwaysBeSearchin/AlwaysBeSearchin.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SSSGame;
using SSSGame.Vegetation;
using SSSGame.Weather;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("AlwaysBeSearchin")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+35bcb3c0e2c107c02f6a130e147a0c9fb212ab1d")]
[assembly: AssemblyProduct("AlwaysBeSearchin")]
[assembly: AssemblyTitle("AlwaysBeSearchin")]
[assembly: AssemblyVersion("0.1.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 AlwaysBeSearchin
{
	public class AlwaysOnGlow : MonoBehaviour
	{
		private static readonly int ValueId = Shader.PropertyToID("Global_ResFinderValue");

		private static readonly int RadiusId = Shader.PropertyToID("Global_ResFinderRadius");

		private static readonly int ColorId = Shader.PropertyToID("Global_ResFinderColor");

		internal static bool RoutineActive;

		internal static float RoutineDeadline;

		private PlayerInteractionAgent _agent;

		private float _nextAgentLookup;

		private SettingsManager _settings;

		private bool _wasGameTurn;

		private bool _zeroWritten;

		private string _parsedFrom;

		private bool _hasOurColor;

		private Vector4 _ourColor;

		private MaterialPropertyBlock _mpb;

		private bool _wasExcluding;

		private int _cursor = -1;

		private float _nextCharLog;

		private double _worstFrameMs;

		private double _worstLookupMs;

		private double _worstWriteMs;

		private WeatherSystem _weather;

		private float _nextWeatherLookup;

		private float _nextStrengthLog;

		private bool _weatherFailed;

		private readonly Dictionary<int, (bool overrideOn, float strength)> _plantOriginals = new Dictionary<int, (bool, float)>();

		private float _nextPlantPass;

		private float _lastPlantStrength = float.NaN;

		private string _lastPlantTypes;

		private string _lastBoostTypes;

		private float _lastBoostStrength = float.NaN;

		private bool _plantsLogged;

		private bool _updateFailed;

		private bool _lateFailed;

		private bool _colorFailed;

		private bool _villagerFailed;

		private bool _plantFailed;

		private const int KindCount = 4;

		private const int RendererBudget = 150;

		private const int MaxVisits = 200;

		private const float CacheSeconds = 10f;

		private readonly bool[] _kindOn = new bool[4];

		private readonly Queue<Known> _restore = new Queue<Known>();

		private Known _cur;

		private int _seedStep = -1;

		private long _frameSeedTicks;

		private const int ModeNone = 0;

		private const int ModeZero = 1;

		private const int ModeValue = 2;

		private const int ModeClear = 3;

		public AlwaysOnGlow(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Update()
		{
			try
			{
				if (RoutineActive && Time.time > RoutineDeadline)
				{
					RoutineActive = false;
				}
			}
			catch (Exception ex)
			{
				if (_updateFailed)
				{
					return;
				}
				_updateFailed = true;
				Plugin.Logger.LogWarning((object)("Update failed: " + ex));
			}
			try
			{
				TickPlants();
			}
			catch (Exception ex2)
			{
				if (!_plantFailed)
				{
					_plantFailed = true;
					Plugin.Logger.LogWarning((object)("Plant strength failed: " + ex2));
				}
			}
		}

		private void TickPlants()
		{
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Expected O, but got Unknown
			float time = Time.time;
			float value = Plugin.PlantStrength.Value;
			string value2 = Plugin.PlantTypes.Value;
			string value3 = Plugin.BoostTypes.Value;
			float value4 = Plugin.BoostStrength.Value;
			if (value == _lastPlantStrength && string.Equals(value2, _lastPlantTypes, StringComparison.Ordinal) && string.Equals(value3, _lastBoostTypes, StringComparison.Ordinal) && value4 == _lastBoostStrength && time < _nextPlantPass)
			{
				return;
			}
			_nextPlantPass = time + 5f;
			_lastPlantStrength = value;
			_lastPlantTypes = value2;
			_lastBoostTypes = value3;
			_lastBoostStrength = value4;
			VegetationVFXAddon instance = VegetationVFXAddon.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			List<VFXItemRenderer> vfxRenderers = instance._vfxRenderers;
			if (vfxRenderers == null)
			{
				return;
			}
			HashSet<int> hashSet = new HashSet<int>();
			List<string> list = new List<string>();
			int num = 0;
			HashSet<int> hashSet2 = new HashSet<int>();
			int count = vfxRenderers.Count;
			for (int i = 0; i < count; i++)
			{
				VFXItemRenderer val = vfxRenderers[i];
				VFXVegetationConfig val2 = ((val != null) ? val.Profile : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)val2).GetInstanceID();
				if (!_plantOriginals.TryGetValue(instanceID, out (bool, float) value5))
				{
					value5 = (val2.overrideHighlightStrength, val2.highlightStrength);
					_plantOriginals[instanceID] = value5;
				}
				float num2 = GlowMath.TypeMultiplier(((Object)val2).name, value5.Item2, value2, value, value3, value4);
				bool flag = num2 != value5.Item2;
				bool flag2 = flag || value5.Item1;
				if (hashSet.Add(instanceID) && flag)
				{
					if (num2 > value5.Item2)
					{
						list.Add(((Object)val2).name);
					}
					else
					{
						num++;
					}
				}
				if (val2.overrideHighlightStrength != flag2 || val2.highlightStrength != num2)
				{
					val2.overrideHighlightStrength = flag2;
					val2.highlightStrength = num2;
					hashSet2.Add(instanceID);
				}
				if (hashSet2.Contains(instanceID))
				{
					val._UpdateHighlightStrength();
				}
			}
			if (!_plantsLogged && count > 0)
			{
				_plantsLogged = true;
				ManualLogSource logger = Plugin.Logger;
				bool flag3 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(49, 4, ref flag3);
				if (flag3)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("vegetation types scaled: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" dimmed, ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(list.Count);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" boosted of ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(hashSet.Count);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(string.Join(", ", list.GetRange(0, Math.Min(20, list.Count))));
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(")");
				}
				logger.LogInfo(val3);
			}
		}

		private void LateUpdate()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_agent == (Object)null)
				{
					float time = Time.time;
					if (time < _nextAgentLookup)
					{
						return;
					}
					_nextAgentLookup = time + 2f;
					_agent = Object.FindObjectOfType<PlayerInteractionAgent>();
					if ((Object)(object)_agent == (Object)null)
					{
						return;
					}
					_seedStep = 0;
				}
				if (_seedStep >= 0)
				{
					TickSeed();
				}
				float num = CurrentBaseline();
				float globalFloat = Shader.GetGlobalFloat(ValueId);
				if (GlowMath.GameHasTurn(RoutineActive, globalFloat, num))
				{
					if (!_wasGameTurn)
					{
						Shader.SetGlobalVector(ColorId, PlayerColor());
					}
					_wasGameTurn = true;
					_zeroWritten = false;
				}
				else if (num <= 0f)
				{
					if (_wasGameTurn || !_zeroWritten)
					{
						Shader.SetGlobalFloat(ValueId, 0f);
					}
					_wasGameTurn = false;
					_zeroWritten = true;
				}
				else
				{
					Shader.SetGlobalFloat(ValueId, num);
					Shader.SetGlobalFloat(RadiusId, Plugin.GlowRadius.Value);
					Shader.SetGlobalVector(ColorId, CurrentColor());
					_wasGameTurn = false;
					_zeroWritten = false;
				}
				TickCharacters(GlowMath.ExcludeKindNow(num, Plugin.ExcludeVillagers.Value), GlowMath.ExcludeKindNow(num, Plugin.ExcludeStructures.Value));
			}
			catch (Exception ex)
			{
				if (!_lateFailed)
				{
					_lateFailed = true;
					Plugin.Logger.LogWarning((object)("LateUpdate failed: " + ex));
				}
			}
		}

		private float CurrentBaseline()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			float num = 1f;
			float num2 = float.NaN;
			bool flag = false;
			try
			{
				float time = Time.time;
				if ((Object)(object)_weather == (Object)null && time >= _nextWeatherLookup)
				{
					_nextWeatherLookup = time + 2f;
					_weather = Object.FindObjectOfType<WeatherSystem>();
					flag = (Object)(object)_weather != (Object)null;
				}
				if ((Object)(object)_weather != (Object)null)
				{
					num = _weather.DayNightValue;
					num2 = _weather.narmalizedDayTime;
				}
			}
			catch (Exception ex)
			{
				if (!_weatherFailed)
				{
					_weatherFailed = true;
					Plugin.Logger.LogWarning((object)("Reading the day and night failed: " + ex));
				}
			}
			float num3 = GlowMath.DayNightStrength(Plugin.DayStrength.Value, Plugin.NightStrength.Value, num);
			if ((Object)(object)_weather != (Object)null && (flag || Time.time >= _nextStrengthLog))
			{
				_nextStrengthLog = Time.time + 60f;
				ManualLogSource logger = Plugin.Logger;
				bool flag2 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("daylight ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "0.###");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" time ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num2, "0.###");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" strength ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num3, "0.###");
				}
				logger.LogInfo(val);
			}
			return num3;
		}

		private Vector4 CurrentColor()
		{
			//IL_00a6: 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_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)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			string value = Plugin.GlowColor.Value;
			if (!string.Equals(value, _parsedFrom, StringComparison.Ordinal))
			{
				_parsedFrom = value;
				if (GlowMath.TryParseHexColor(value, out var r, out var g, out var b))
				{
					_ourColor = new Vector4(r, g, b, 1f);
					_hasOurColor = true;
				}
				else
				{
					_hasOurColor = false;
					if (!string.IsNullOrEmpty(value))
					{
						ManualLogSource logger = Plugin.Logger;
						bool flag = default(bool);
						BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(68, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("GlowColor '");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(value);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is not #RRGGBB; using the game's Resource Finder color.");
						}
						logger.LogWarning(val);
					}
				}
			}
			if (!_hasOurColor)
			{
				return PlayerColor();
			}
			return _ourColor;
		}

		private Vector4 PlayerColor()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_003e: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_settings == (Object)null)
				{
					_settings = Object.FindObjectOfType<SettingsManager>();
				}
				if ((Object)(object)_settings != (Object)null)
				{
					Color value = _settings.ResourceFinderColor.Value;
					return new Vector4(value.r, value.g, value.b, 1f);
				}
			}
			catch (Exception ex)
			{
				if (!_colorFailed)
				{
					_colorFailed = true;
					Plugin.Logger.LogWarning((object)("Reading the Resource Finder color failed: " + ex));
				}
			}
			return new Vector4(1f, 1f, 1f, 1f);
		}

		private static bool KindExcluded(int kind, bool characters, bool structures)
		{
			if (kind != 3)
			{
				return characters;
			}
			return structures;
		}

		private static double Ms(long ticks)
		{
			return (double)ticks * 1000.0 / (double)Stopwatch.Frequency;
		}

		private void TickSeed()
		{
			long timestamp = Stopwatch.GetTimestamp();
			int seedStep = _seedStep;
			_seedStep = ((seedStep + 1 >= 4) ? (-1) : (seedStep + 1));
			switch (seedStep)
			{
			case 0:
				foreach (Villager item in Object.FindObjectsOfType<Villager>())
				{
					GlowRegistry.Seed((Component)(object)item, 0);
				}
				break;
			case 1:
				foreach (PlayerCharacter item2 in Object.FindObjectsOfType<PlayerCharacter>())
				{
					GlowRegistry.Seed((Component)(object)item2, 1);
				}
				break;
			case 2:
				foreach (Creature item3 in Object.FindObjectsOfType<Creature>())
				{
					GlowRegistry.Seed((Component)(object)item3, 2);
				}
				break;
			default:
				foreach (Structure item4 in Object.FindObjectsOfType<Structure>())
				{
					GlowRegistry.Seed((Component)(object)item4, 3);
				}
				break;
			}
			_frameSeedTicks += Stopwatch.GetTimestamp() - timestamp;
		}

		private void TickCharacters(bool characters, bool structures)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Expected O, but got Unknown
			bool flag = characters || structures;
			if (!flag && !_wasExcluding && _restore.Count == 0 && _cur == null)
			{
				_frameSeedTicks = 0L;
				return;
			}
			try
			{
				float time = Time.time;
				Stopwatch stopwatch = Stopwatch.StartNew();
				if (_mpb == null)
				{
					_mpb = new MaterialPropertyBlock();
				}
				bool flag2 = !_wasExcluding;
				for (int i = 0; i < 4; i++)
				{
					bool flag3 = KindExcluded(i, characters, structures);
					if (_kindOn[i] && !flag3)
					{
						foreach (Known item in GlowRegistry.List)
						{
							if (item.Kind == i && !item.Removed && (item.Touched || item.Excluded))
							{
								item.Restoring = true;
								_restore.Enqueue(item);
							}
						}
					}
					else if (!_kindOn[i] && flag3)
					{
						foreach (Known item2 in GlowRegistry.List)
						{
							if (item2.Kind == i && !item2.Removed)
							{
								GlowRegistry.Fresh.Enqueue(item2);
							}
						}
					}
					_kindOn[i] = flag3;
				}
				_wasExcluding = flag;
				if (flag2 && flag)
				{
					_nextCharLog = time + 60f;
				}
				long num = _frameSeedTicks + GlowRegistry.TakeTicks();
				long lookupTicks = num;
				long writeTicks = 0L;
				_frameSeedTicks = 0L;
				RunBudget(time, flag, ref lookupTicks, ref writeTicks);
				stopwatch.Stop();
				double val = Ms(lookupTicks);
				double val2 = Ms(writeTicks);
				_worstFrameMs = Math.Max(_worstFrameMs, stopwatch.Elapsed.TotalMilliseconds + Ms(num));
				_worstLookupMs = Math.Max(_worstLookupMs, val);
				_worstWriteMs = Math.Max(_worstWriteMs, val2);
				if (!flag || !(time >= _nextCharLog))
				{
					return;
				}
				_nextCharLog = time + 60f;
				int[] array = new int[4];
				foreach (Known item3 in GlowRegistry.List)
				{
					if (!item3.Removed && _kindOn[item3.Kind])
					{
						array[item3.Kind]++;
					}
				}
				ManualLogSource logger = Plugin.Logger;
				bool flag4 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(131, 10, ref flag4);
				if (flag4)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("excluded from glow: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[0]);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" villagers, ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[1]);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" players, ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[2]);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" creatures, ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(array[3]);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" structures; worst frame ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(_worstFrameMs, "0.00");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" ms (lookup ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(_worstLookupMs, "0.00");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", write ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<double>(_worstWriteMs, "0.00");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("), seeded ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(GlowRegistry.Seeded);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", spawned ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(GlowRegistry.SpawnedCount);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", despawned ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(GlowRegistry.DespawnedCount);
				}
				logger.LogInfo(val3);
				_worstFrameMs = 0.0;
				_worstLookupMs = 0.0;
				_worstWriteMs = 0.0;
			}
			catch (Exception ex)
			{
				_wasExcluding = flag;
				_cur = null;
				for (int j = 0; j < 4; j++)
				{
					_kindOn[j] = KindExcluded(j, characters, structures);
				}
				if (!_villagerFailed)
				{
					_villagerFailed = true;
					Plugin.Logger.LogWarning((object)("Glow exclusion failed: " + ex));
				}
			}
		}

		[HideFromIl2Cpp]
		private void RunBudget(float now, bool anyOn, ref long lookupTicks, ref long writeTicks)
		{
			int num = 150;
			int visits = 0;
			bool flag = false;
			float globalFloat = Shader.GetGlobalFloat(ValueId);
			while (num > 0 && visits < 200)
			{
				if (_cur == null)
				{
					long timestamp = Stopwatch.GetTimestamp();
					_cur = NextKnown(anyOn, ref visits);
					lookupTicks += Stopwatch.GetTimestamp() - timestamp;
					if (_cur == null)
					{
						break;
					}
					_cur.Index = 0;
				}
				Known cur = _cur;
				if (cur.Removed || (Object)(object)cur.Comp == (Object)null)
				{
					GlowRegistry.Drop(cur);
					_cur = null;
					continue;
				}
				if (cur.Index == 0)
				{
					if (cur.Rends == null || now - cur.RendTime > 10f)
					{
						if (flag)
						{
							break;
						}
						flag = true;
						long timestamp2 = Stopwatch.GetTimestamp();
						cur.Rends = Il2CppArrayBase<Renderer>.op_Implicit(cur.Comp.GetComponentsInChildren<Renderer>(true));
						cur.RendTime = now;
						lookupTicks += Stopwatch.GetTimestamp() - timestamp2;
					}
					cur.Mode = ModeFor(cur, globalFloat);
				}
				long timestamp3 = Stopwatch.GetTimestamp();
				Renderer[] rends = cur.Rends;
				int num2 = ((cur.Mode != 0) ? GlowMath.TakeBudget(rends.Length - cur.Index, num) : 0);
				for (int i = 0; i < num2; i++)
				{
					Renderer val = rends[cur.Index + i];
					if (!((Object)(object)val == (Object)null))
					{
						if (cur.Mode == 3)
						{
							val.SetPropertyBlock((MaterialPropertyBlock)null);
							continue;
						}
						val.GetPropertyBlock(_mpb);
						_mpb.SetFloat(ValueId, (cur.Mode == 1) ? 0f : globalFloat);
						val.SetPropertyBlock(_mpb);
					}
				}
				writeTicks += Stopwatch.GetTimestamp() - timestamp3;
				cur.Index += num2;
				num -= num2;
				if (cur.Mode == 0 || cur.Index >= rends.Length)
				{
					cur.Restoring = false;
					cur.Index = 0;
					_cur = null;
				}
			}
		}

		[HideFromIl2Cpp]
		private static int ModeFor(Known k, float global)
		{
			bool flag = !k.Restoring;
			if (k.Kind != 2)
			{
				if (flag)
				{
					k.Touched = true;
					return 1;
				}
				if (!k.Touched)
				{
					return 0;
				}
				k.Touched = false;
				return 2;
			}
			Creature val = ((Il2CppObjectBase)k.Comp).TryCast<Creature>();
			if ((Object)(object)val == (Object)null)
			{
				return 0;
			}
			if (GlowMath.ExcludeCreature(flag, val.IsDead))
			{
				k.Excluded = true;
				return 1;
			}
			if (!k.Excluded)
			{
				return 0;
			}
			k.Excluded = false;
			if (!val.IsDead)
			{
				return 2;
			}
			return 3;
		}

		[HideFromIl2Cpp]
		private Known NextKnown(bool anyOn, ref int visits)
		{
			while (_restore.Count > 0)
			{
				Known known = _restore.Dequeue();
				if (!known.Removed)
				{
					return known;
				}
			}
			if (!anyOn)
			{
				return null;
			}
			Queue<Known> fresh = GlowRegistry.Fresh;
			while (fresh.Count > 0 && visits < 200)
			{
				visits++;
				Known known2 = fresh.Dequeue();
				if (!known2.Removed && _kindOn[known2.Kind])
				{
					return known2;
				}
			}
			List<Known> list = GlowRegistry.List;
			while (list.Count > 0 && visits < 200)
			{
				visits++;
				_cursor = (_cursor + 1) % list.Count;
				Known known3 = list[_cursor];
				if (known3.Removed || (Object)(object)known3.Comp == (Object)null)
				{
					GlowRegistry.Drop(known3);
					list.RemoveAt(_cursor);
					_cursor--;
				}
				else if (_kindOn[known3.Kind])
				{
					return known3;
				}
			}
			return null;
		}
	}
	internal sealed class Known
	{
		public int Kind;

		public int Id;

		public Component Comp;

		public bool Excluded;

		public bool Touched;

		public bool Removed;

		public bool Restoring;

		public Renderer[] Rends;

		public float RendTime;

		public int Index;

		public int Mode;
	}
	internal static class GlowRegistry
	{
		internal static readonly List<Known> List = new List<Known>();

		internal static readonly Queue<Known> Fresh = new Queue<Known>();

		private static readonly Dictionary<int, Known> ById = new Dictionary<int, Known>();

		private static long _ticks;

		internal static int Seeded;

		internal static int SpawnedCount;

		internal static int DespawnedCount;

		internal static long TakeTicks()
		{
			long ticks = _ticks;
			_ticks = 0L;
			return ticks;
		}

		private static bool Add(Component c, int kind)
		{
			if ((Object)(object)c == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)c).GetInstanceID();
			if (ById.ContainsKey(instanceID))
			{
				return false;
			}
			Known known = new Known
			{
				Kind = kind,
				Id = instanceID,
				Comp = c
			};
			List.Add(known);
			ById[instanceID] = known;
			Fresh.Enqueue(known);
			return true;
		}

		internal static void Seed(Component c, int kind)
		{
			if (Add(c, kind))
			{
				Seeded++;
			}
		}

		internal static void Spawned(Component c, int kind)
		{
			long timestamp = Stopwatch.GetTimestamp();
			if (Add(c, kind))
			{
				SpawnedCount++;
			}
			_ticks += Stopwatch.GetTimestamp() - timestamp;
		}

		internal static void Despawned(Component c)
		{
			long timestamp = Stopwatch.GetTimestamp();
			if ((Object)(object)c != (Object)null && ById.TryGetValue(((Object)c).GetInstanceID(), out var value))
			{
				Drop(value);
				DespawnedCount++;
			}
			_ticks += Stopwatch.GetTimestamp() - timestamp;
		}

		internal static void Drop(Known k)
		{
			k.Removed = true;
			if (ById.TryGetValue(k.Id, out var value) && value == k)
			{
				ById.Remove(k.Id);
			}
		}
	}
	[HarmonyPatch]
	internal static class GlowPatches
	{
		private static bool _pressFailed;

		private static bool _routineFailed;

		private static int _spawnedHooks = -1;

		private static int _despawnedHooks = -1;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerInteractionAgent), "ActivateResourceFinder")]
		private static void Press(PlayerInteractionAgent __instance)
		{
			try
			{
				AlwaysOnGlow.RoutineActive = true;
				AlwaysOnGlow.RoutineDeadline = Time.time + __instance.finderActiveTime + __instance.finderFadeOutTime + 1f;
			}
			catch (Exception ex)
			{
				if (!_pressFailed)
				{
					_pressFailed = true;
					Plugin.Logger.LogWarning((object)("ActivateResourceFinder patch failed: " + ex));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(__ResourceFinderRoutine_d__189), "MoveNext")]
		private static void Routine(bool __result)
		{
			try
			{
				if (!__result)
				{
					AlwaysOnGlow.RoutineActive = false;
				}
			}
			catch (Exception ex)
			{
				if (!_routineFailed)
				{
					_routineFailed = true;
					Plugin.Logger.LogWarning((object)("Resource Finder routine patch failed: " + ex));
				}
			}
		}

		internal static int KindOf(Component c)
		{
			if ((Object)(object)((Il2CppObjectBase)c).TryCast<Villager>() != (Object)null)
			{
				return 0;
			}
			if ((Object)(object)((Il2CppObjectBase)c).TryCast<PlayerCharacter>() != (Object)null)
			{
				return 1;
			}
			if ((Object)(object)((Il2CppObjectBase)c).TryCast<Creature>() != (Object)null)
			{
				return 2;
			}
			if (!((Object)(object)((Il2CppObjectBase)c).TryCast<Structure>() != (Object)null))
			{
				return -1;
			}
			return 3;
		}

		internal static IEnumerable<MethodBase> Targets(string method)
		{
			int found = 0;
			Type[] array = new Type[4]
			{
				typeof(Villager),
				typeof(PlayerCharacter),
				typeof(Creature),
				typeof(Structure)
			};
			bool flag = default(bool);
			foreach (Type type in array)
			{
				MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					ManualLogSource logger = Plugin.Logger;
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("spawn hooks: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type.Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(method);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found");
					}
					logger.LogWarning(val);
				}
				else
				{
					found++;
					yield return methodInfo;
				}
			}
			if (method == "Spawned")
			{
				_spawnedHooks = found;
			}
			else
			{
				_despawnedHooks = found;
			}
			if (_spawnedHooks >= 0 && _despawnedHooks >= 0)
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(33, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("spawn hooks: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_spawnedHooks);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Spawned, ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_despawnedHooks);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Despawned");
				}
				logger2.LogInfo(val2);
			}
		}
	}
	[HarmonyPatch]
	internal static class SpawnedPatch
	{
		private static bool _failed;

		private static IEnumerable<MethodBase> TargetMethods()
		{
			return GlowPatches.Targets("Spawned");
		}

		private static void Postfix(object __instance)
		{
			try
			{
				Component val = (Component)((__instance is Component) ? __instance : null);
				if (val != null)
				{
					int num = GlowPatches.KindOf(val);
					if (num >= 0)
					{
						GlowRegistry.Spawned(val, num);
					}
				}
			}
			catch (Exception ex)
			{
				if (!_failed)
				{
					_failed = true;
					Plugin.Logger.LogWarning((object)("Spawned patch failed: " + ex));
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class DespawnedPatch
	{
		private static bool _failed;

		private static IEnumerable<MethodBase> TargetMethods()
		{
			return GlowPatches.Targets("Despawned");
		}

		private static void Postfix(object __instance)
		{
			try
			{
				Component val = (Component)((__instance is Component) ? __instance : null);
				if (val != null)
				{
					GlowRegistry.Despawned(val);
				}
			}
			catch (Exception ex)
			{
				if (!_failed)
				{
					_failed = true;
					Plugin.Logger.LogWarning((object)("Despawned patch failed: " + ex));
				}
			}
		}
	}
	public static class GlowMath
	{
		public static float Clamp01(float v)
		{
			if (float.IsNaN(v))
			{
				return 0f;
			}
			return Math.Clamp(v, 0f, 1f);
		}

		public static float DayNightStrength(float dayStrength, float nightStrength, float daylight)
		{
			float num = Clamp01(dayStrength);
			float num2 = Clamp01(nightStrength);
			float num3 = (float.IsNaN(daylight) ? 1f : Clamp01(daylight));
			return num2 + (num - num2) * num3;
		}

		public static bool GameHasTurn(bool routineActive, float gameValue, float baseline)
		{
			if (routineActive)
			{
				return !(gameValue < Clamp01(baseline));
			}
			return false;
		}

		public static bool ExcludeKindNow(float baseline, bool kindSetting)
		{
			return Clamp01(baseline) > 0f && kindSetting;
		}

		public static bool ExcludeCreature(bool excludeNow, bool isDead)
		{
			if (excludeNow)
			{
				return !isDead;
			}
			return false;
		}

		public static int TakeBudget(int remainingInObject, int budgetLeft)
		{
			return Math.Min(Math.Max(0, remainingInObject), Math.Max(0, budgetLeft));
		}

		public static bool IsPlantType(string configName, string typeList)
		{
			return ContainsAny(configName, typeList);
		}

		private static bool ContainsAny(string configName, string list)
		{
			if (string.IsNullOrEmpty(configName) || string.IsNullOrEmpty(list))
			{
				return false;
			}
			string[] array = list.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length > 0 && configName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		public static float TypeMultiplier(string configName, float original, string plantTypes, float plantStrength, string boostTypes, float boostStrength)
		{
			if (ContainsAny(configName, boostTypes))
			{
				return original * (float.IsNaN(boostStrength) ? 1f : Math.Clamp(boostStrength, 1f, 10f));
			}
			if (IsPlantType(configName, plantTypes))
			{
				return original * Clamp01(plantStrength);
			}
			return original;
		}

		public static bool TryParseHexColor(string s, out float r, out float g, out float b)
		{
			r = (g = (b = 0f));
			if (string.IsNullOrEmpty(s))
			{
				return false;
			}
			if (s[0] == '#')
			{
				s = s.Substring(1);
			}
			if (s.Length != 6)
			{
				return false;
			}
			int num = 0;
			string text = s;
			foreach (char c in text)
			{
				int num2;
				if (c >= '0' && c <= '9')
				{
					num2 = c - 48;
				}
				else if (c >= 'a' && c <= 'f')
				{
					num2 = c - 97 + 10;
				}
				else
				{
					if (c < 'A' || c > 'F')
					{
						return false;
					}
					num2 = c - 65 + 10;
				}
				num = num * 16 + num2;
			}
			r = (float)((num >> 16) & 0xFF) / 255f;
			g = (float)((num >> 8) & 0xFF) / 255f;
			b = (float)(num & 0xFF) / 255f;
			return true;
		}
	}
	[BepInPlugin("solrlabs.aska.alwaysbesearchin", "Always Be Searchin'", "0.1.1")]
	public class Plugin : BasePlugin
	{
		public const string Guid = "solrlabs.aska.alwaysbesearchin";

		public const string Name = "Always Be Searchin'";

		public const string Version = "0.1.1";

		internal static ManualLogSource Logger;

		internal static ConfigEntry<float> DayStrength;

		internal static ConfigEntry<float> NightStrength;

		internal static ConfigEntry<float> GlowRadius;

		internal static ConfigEntry<string> GlowColor;

		internal static ConfigEntry<bool> ExcludeVillagers;

		internal static ConfigEntry<bool> ExcludeStructures;

		internal static ConfigEntry<float> PlantStrength;

		internal static ConfigEntry<string> PlantTypes;

		internal static ConfigEntry<string> BoostTypes;

		internal static ConfigEntry<float> BoostStrength;

		public override void Load()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			DayStrength = ((BasePlugin)this).Config.Bind<float>("General", "DayStrength", 0.17f, new ConfigDescription("Strength of the always-on glow in full daylight, 0 to 1.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			NightStrength = ((BasePlugin)this).Config.Bind<float>("General", "NightStrength", 0.08f, new ConfigDescription("Strength of the always-on glow at night, 0 to 1. The glow blends between the two with the game's day and night. Set both to 0 to turn the always-on glow off; Z then works as in the base game.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			GlowRadius = ((BasePlugin)this).Config.Bind<float>("General", "GlowRadius", 60f, new ConfigDescription("Radius in metres of the always-on glow around the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), Array.Empty<object>()));
			GlowColor = ((BasePlugin)this).Config.Bind<string>("General", "GlowColor", "#FFFF33", "Color of the always-on glow as #RRGGBB. Empty uses the game's Resource Finder color from its settings.");
			ExcludeVillagers = ((BasePlugin)this).Config.Bind<bool>("General", "ExcludeVillagers", true, "Keep villagers, players and live creatures, and what they carry, out of the glow, including during Z.");
			ExcludeStructures = ((BasePlugin)this).Config.Bind<bool>("General", "ExcludeStructures", true, "Keep items stored in or on buildings (storage, cooking pots, racks) out of the glow. Items on the landscape still glow.");
			PlantStrength = ((BasePlugin)this).Config.Bind<float>("General", "PlantStrength", 0.5f, new ConfigDescription("Multiplier on the glow of plants (ferns, bushes, grass and similar), which glow much brighter than rocks. 1 leaves them as the game draws them. Also applies during Z.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			PlantTypes = ((BasePlugin)this).Config.Bind<string>("General", "PlantTypes", "Fern,Bush,Grass,Reed,Flower,Lupin", "Comma-separated name fragments of the vegetation types that PlantStrength applies to.");
			BoostTypes = ((BasePlugin)this).Config.Bind<string>("General", "BoostTypes", "Flax", "Comma-separated name fragments of vegetation types whose glow is multiplied by BoostStrength (never dimmed by PlantStrength).");
			BoostStrength = ((BasePlugin)this).Config.Bind<float>("General", "BoostStrength", 3f, new ConfigDescription("Multiplier on the glow of BoostTypes, for items that are hard to see (1 = as the game draws them).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			new Harmony("solrlabs.aska.alwaysbesearchin").PatchAll(typeof(Plugin).Assembly);
			((BasePlugin)this).AddComponent<AlwaysOnGlow>();
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(79, 6, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Always Be Searchin' ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.1.1");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded (day ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(DayStrength.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", night ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(NightStrength.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", radius ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(GlowRadius.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", color ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(GlowColor.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", exclude villagers ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(ExcludeVillagers.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
			}
			log.LogInfo(val);
		}
	}
}