Decompiled source of LightColor v1.5.0

BepInEx/plugins/LightColor/LightColor.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Kriona.Shared;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Kriona")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 Kriona Hagen - MIT License")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0")]
[assembly: AssemblyProduct("Light Color")]
[assembly: AssemblyTitle("Light Color")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.0.0")]
[module: UnverifiableCode]
[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 LightColor
{
	public static class AdminSync
	{
		private const string SettingsRpc = "kriona.LightColor.AdminSettings";

		public const string DeniedMessage = "Only admins can change colors on this server";

		private static bool serverAdminOnly;

		private static bool serverAdminOnlyHelmet;

		public static bool CanChangeColors => IsAllowed(serverAdminOnly);

		public static bool CanUseHelmet => IsAllowed(serverAdminOnlyHelmet);

		public static void OnNewConnection(ZNetPeer peer)
		{
			if (!ZNet.instance.IsServer())
			{
				serverAdminOnly = false;
				serverAdminOnlyHelmet = false;
				peer.m_rpc.Register<ZPackage>("kriona.LightColor.AdminSettings", (Action<ZRpc, ZPackage>)RPC_Settings);
			}
		}

		public static void Send(ZRpc rpc)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(Plugin.AdminOnly.Value);
			val.Write(Plugin.AdminOnlyHelmet.Value);
			rpc.Invoke("kriona.LightColor.AdminSettings", new object[1] { val });
		}

		public static void SendToAll()
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || !instance.IsServer())
			{
				return;
			}
			foreach (ZNetPeer peer in instance.GetPeers())
			{
				if (peer.m_rpc != null && peer.m_uid != 0L)
				{
					Send(peer.m_rpc);
				}
			}
		}

		private static bool IsAllowed(bool adminOnly)
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null || instance.IsServer() || !adminOnly)
			{
				return true;
			}
			return instance.LocalPlayerIsAdminOrHost();
		}

		private static void RPC_Settings(ZRpc rpc, ZPackage package)
		{
			serverAdminOnly = package.ReadBool();
			serverAdminOnlyHelmet = package.ReadBool();
		}
	}
	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	public static class ZNetNewConnectionPatch
	{
		private static void Postfix(ZNetPeer peer)
		{
			AdminSync.OnNewConnection(peer);
		}
	}
	[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
	public static class ZNetPeerInfoPatch
	{
		private static void Postfix(ZNet __instance, ZRpc rpc)
		{
			if (__instance.IsServer())
			{
				ZNetPeer peer = __instance.GetPeer(rpc);
				if (peer != null && peer.m_uid != 0L)
				{
					AdminSync.Send(rpc);
				}
			}
		}
	}
	public class HelmetTint : MonoBehaviour
	{
		public static readonly int SettingsHash = StringExtensionMethods.GetStableHashCode("kriona.LightColor.helmet");

		private VisEquipment visEquipment;

		private ZNetView nview;

		private GameObject helmet;

		private Tintable tintable;

		private uint revision;

		private bool checkedRevision;

		private string text = "";

		private string applied;

		public void Init(VisEquipment equipment)
		{
			visEquipment = equipment;
			nview = equipment.m_nview;
		}

		private void Update()
		{
			if (!((Object)(object)nview == (Object)null) && nview.IsValid())
			{
				GameObject helmetItemInstance = visEquipment.m_helmetItemInstance;
				if ((Object)(object)helmetItemInstance != (Object)(object)helmet)
				{
					helmet = helmetItemInstance;
					tintable = (((Object)(object)helmet != (Object)null) ? new Tintable(helmet) : null);
					applied = null;
				}
				ZDO zDO = nview.GetZDO();
				if (!checkedRevision || zDO.DataRevision != revision)
				{
					checkedRevision = true;
					revision = zDO.DataRevision;
					text = zDO.GetString(SettingsHash, "");
				}
				if (tintable != null && !(text == applied))
				{
					applied = text;
					LightSettings.TryParse(text, out var settings, out var _);
					tintable.Apply(settings);
				}
			}
		}
	}
	[HarmonyPatch(typeof(VisEquipment), "Awake")]
	public static class VisEquipmentAwakePatch
	{
		private static void Postfix(VisEquipment __instance)
		{
			if (__instance.m_isPlayer)
			{
				((Component)__instance).gameObject.AddComponent<HelmetTint>().Init(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
	public static class HudUpdateCrosshairPatch
	{
		private unsafe static void Postfix(Hud __instance, Player player)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = Plugin.ColorKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || TextViewer.instance.IsVisible())
			{
				return;
			}
			GameObject hoverObject = ((Humanoid)player).GetHoverObject();
			if ((Object)(object)hoverObject == (Object)null)
			{
				return;
			}
			LightTint componentInParent = hoverObject.GetComponentInParent<LightTint>();
			if (!((Object)(object)componentInParent == (Object)null) && componentInParent.HasEffects && AdminSync.CanChangeColors)
			{
				string text = ((TMP_Text)__instance.m_hoverName).text;
				if (text.Length == 0)
				{
					Piece component = ((Component)componentInParent).GetComponent<Piece>();
					text = (((Object)(object)component != (Object)null) ? component.m_name : "");
				}
				string text2 = (componentInParent.IsSign ? "Set text glow" : "Set light color");
				TextMeshProUGUI hoverName = __instance.m_hoverName;
				Localization instance = Localization.instance;
				string[] obj = new string[5] { text, "\n[<color=yellow><b>", null, null, null };
				KeyboardShortcut val = value;
				obj[2] = ((object)(*(KeyboardShortcut*)(&val))/*cast due to .constrained prefix*/).ToString();
				obj[3] = "</b></color>] ";
				obj[4] = text2;
				((TMP_Text)hoverName).text = instance.Localize(string.Concat(obj));
				((Graphic)__instance.m_crosshair).color = Color.yellow;
			}
		}
	}
	[Flags]
	public enum TextStyle
	{
		None = 0,
		Halo = 1,
		Lit = 2,
		Outline = 4
	}
	public class LightSettings
	{
		public const float MinBrightness = 0f;

		public const float MaxBrightness = 500f;

		public const float MinRange = 1f;

		public const float MaxRange = 50f;

		private const string DefaultText = "default";

		public static readonly LightSettings Default = new LightSettings();

		public bool HasColor { get; private set; }

		public Color Color { get; private set; } = Color.white;

		public float Brightness { get; private set; } = 1f;

		public float Range { get; private set; }

		public TextStyle Styles { get; private set; }

		public static LightSettings ColorOnly(Color color)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return new LightSettings
			{
				HasColor = true,
				Color = color
			};
		}

		public static bool TryParse(string text, out LightSettings settings, out string error)
		{
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			settings = Default;
			error = null;
			LightSettings lightSettings = new LightSettings();
			string[] array = text.Split(new char[2] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
			Color color = default(Color);
			foreach (string text2 in array)
			{
				string text3 = text2.ToLowerInvariant();
				if (text3 == "default")
				{
					continue;
				}
				if (TryParseStyle(text3, out var style))
				{
					lightSettings.Styles |= style;
					continue;
				}
				if (text3.EndsWith("%"))
				{
					if (!TryParseNumber(text3.Substring(0, text3.Length - 1), out var value) || value < 0f || value > 500f)
					{
						error = "Brightness must be from " + 0f + "% to " + 500f + "%";
						return false;
					}
					lightSettings.Brightness = value / 100f;
					continue;
				}
				if (text3.EndsWith("m") && TryParseNumber(text3.Substring(0, text3.Length - 1), out var value2))
				{
					if (value2 < 1f || value2 > 50f)
					{
						error = "Range must be from " + 1f + "m to " + 50f + "m";
						return false;
					}
					lightSettings.Range = value2;
					continue;
				}
				if (lightSettings.HasColor)
				{
					error = "Only one color can be used";
					return false;
				}
				if (!ColorUtility.TryParseHtmlString(text2, ref color))
				{
					error = "Couldn't read the color " + text2;
					return false;
				}
				color.a = 1f;
				lightSettings.HasColor = true;
				lightSettings.Color = color;
			}
			settings = lightSettings;
			return true;
		}

		public bool IsDefault()
		{
			if (!HasColor && Brightness == 1f && Range == 0f)
			{
				return Styles == TextStyle.None;
			}
			return false;
		}

		private static bool TryParseStyle(string token, out TextStyle style)
		{
			switch (token)
			{
			case "halo":
				style = TextStyle.Halo;
				return true;
			case "lit":
				style = TextStyle.Lit;
				return true;
			case "outline":
				style = TextStyle.Outline;
				return true;
			default:
				style = TextStyle.None;
				return false;
			}
		}

		private static bool TryParseNumber(string text, out float value)
		{
			return float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value);
		}
	}
	public class LightTint : MonoBehaviour, TextReceiver
	{
		private static readonly int ColorHash = StringExtensionMethods.GetStableHashCode("kriona.LightColor");

		private const int CharacterLimit = 32;

		private ZNetView nview;

		private Tintable tintable;

		private uint revision;

		private bool checkedRevision;

		private string applied = "";

		public LightSettings Settings { get; private set; } = LightSettings.Default;

		public bool HasEffects => tintable.HasEffects;

		public bool IsSign
		{
			get
			{
				if (tintable.HasSigns)
				{
					return !tintable.HasLights;
				}
				return false;
			}
		}

		public static LightSettings GetStoredSettings(ZDO zdo)
		{
			LightSettings.TryParse(zdo.GetString(ColorHash, ""), out var settings, out var _);
			return settings;
		}

		public void Init(ZNetView view)
		{
			nview = view;
			tintable = new Tintable(((Component)this).gameObject);
			Refresh();
		}

		public void Rescan()
		{
			tintable.Apply(LightSettings.Default);
			tintable = new Tintable(((Component)this).gameObject);
			applied = null;
			checkedRevision = false;
			Refresh();
		}

		private void Update()
		{
			Refresh();
		}

		public void RequestColor()
		{
			if (!((Object)(object)nview == (Object)null) && nview.IsValid() && !((Object)(object)TextInput.instance == (Object)null))
			{
				string text = (IsSign ? "Text glow - a color, brightness % and halo, lit or outline, e.g. blue 150% lit" : "Light - a color, brightness % and range m, e.g. blue 150% 20m");
				TextInput.instance.RequestText((TextReceiver)(object)this, text, 32);
			}
		}

		public string GetText()
		{
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return "";
			}
			return nview.GetZDO().GetString(ColorHash, "");
		}

		public void SetText(string text)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)nview == (Object)null || !nview.IsValid() || !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
			{
				return;
			}
			if (!AdminSync.CanChangeColors)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, "Only admins can change colors on this server", 0, (Sprite)null, false);
				}
				return;
			}
			text = text.Trim();
			if (!LightSettings.TryParse(text, out var settings, out var error))
			{
				Player localPlayer2 = Player.m_localPlayer;
				if (localPlayer2 != null)
				{
					((Character)localPlayer2).Message((MessageType)2, error, 0, (Sprite)null, false);
				}
				return;
			}
			if (settings.Styles != TextStyle.None && !tintable.HasSigns)
			{
				Player localPlayer3 = Player.m_localPlayer;
				if (localPlayer3 != null)
				{
					((Character)localPlayer3).Message((MessageType)2, "Halo, lit and outline only work on signs", 0, (Sprite)null, false);
				}
				return;
			}
			if (settings.Range > 0f && IsSign)
			{
				Player localPlayer4 = Player.m_localPlayer;
				if (localPlayer4 != null)
				{
					((Character)localPlayer4).Message((MessageType)2, "Signs don't have a range", 0, (Sprite)null, false);
				}
				return;
			}
			if (settings.IsDefault())
			{
				text = "";
			}
			nview.ClaimOwnership();
			ZDO zDO = nview.GetZDO();
			zDO.Set(ColorHash, text);
			if (Game.instance.PortalPrefabHash.Contains(zDO.GetPrefab()))
			{
				ZDOMan.instance.SetDirtyPortals();
			}
			Refresh();
		}

		private void Refresh()
		{
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return;
			}
			ZDO zDO = nview.GetZDO();
			if (!checkedRevision || zDO.DataRevision != revision)
			{
				checkedRevision = true;
				revision = zDO.DataRevision;
				string text = zDO.GetString(ColorHash, "");
				if (!(text == applied))
				{
					applied = text;
					LightSettings.TryParse(text, out var settings, out var _);
					Settings = settings;
					tintable.Apply(settings);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Piece), "Awake")]
	public static class PieceAwakePatch
	{
		private static void Postfix(Piece __instance)
		{
			ZNetView nview = __instance.m_nview;
			if (!((Object)(object)nview == (Object)null) && nview.IsValid() && !((Object)(object)((Component)__instance).GetComponent<LightTint>() != (Object)null) && (!((Object)(object)((Component)__instance).GetComponentInChildren<Light>(true) == (Object)null) || !((Object)(object)((Component)__instance).GetComponentInChildren<Sign>(true) == (Object)null)))
			{
				((Component)__instance).gameObject.AddComponent<LightTint>().Init(nview);
			}
		}
	}
	[HarmonyPatch(typeof(ItemStand), "SetVisualItem")]
	public static class ItemStandSetVisualItemPatch
	{
		private static void Prefix(ItemStand __instance, out GameObject __state)
		{
			__state = __instance.m_visualItem;
		}

		private static void Postfix(ItemStand __instance, GameObject __state)
		{
			ZNetView nview = __instance.m_nview;
			if (!((Object)(object)__instance.m_visualItem == (Object)(object)__state) && !((Object)(object)nview == (Object)null) && nview.IsValid())
			{
				LightTint component = ((Component)__instance).GetComponent<LightTint>();
				if ((Object)(object)component == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<LightTint>().Init(nview);
				}
				else
				{
					component.Rescan();
				}
			}
		}
	}
	[BepInPlugin("kriona.LightColor", "Light Color", "1.5.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "kriona.LightColor";

		public const string PluginName = "Light Color";

		public const string PluginVersion = "1.5.0";

		public static ConfigEntry<KeyboardShortcut> ColorKey;

		public static ConfigEntry<string> Helmet;

		public static ConfigEntry<bool> AdminOnly;

		public static ConfigEntry<bool> AdminOnlyHelmet;

		private Harmony harmony;

		private bool dedicated;

		private ConfigWatcher watcher;

		private string helmetText = "";

		private Player storedPlayer;

		private string storedText;

		private bool helmetDenied;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			ColorKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ColorKey", new KeyboardShortcut((KeyCode)108, Array.Empty<KeyCode>()), "Key to press while looking at a light to type its color - a Unity KeyCode name, optionally with modifiers, e.g. L or LeftControl + L");
			Helmet = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Helmet", "", "Color, brightness and range for the light on your equipped helmet, like the Dverger circlet, typed the same way as on a light, e.g. blue 150% 20m - other players with the mod see it too, and blank keeps the helmet's own light");
			Helmet.SettingChanged += delegate
			{
				CheckHelmetText();
			};
			CheckHelmetText();
			AdminOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "AdminOnly", false, "Only admins in the server's adminlist.txt can change colors and text glow");
			AdminOnly.SettingChanged += delegate
			{
				AdminSync.SendToAll();
			};
			AdminOnlyHelmet = ((BaseUnityPlugin)this).Config.Bind<bool>("Server", "AdminOnlyHelmet", false, "Only admins in the server's adminlist.txt can color their equipped helmet with the Helmet setting");
			AdminOnlyHelmet.SettingChanged += delegate
			{
				AdminSync.SendToAll();
			};
			watcher = new ConfigWatcher(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger, "Light Color");
			harmony = new Harmony("kriona.LightColor");
			dedicated = Application.isBatchMode;
			if (dedicated)
			{
				harmony.CreateClassProcessor(typeof(ZNetPeerInfoPatch)).Patch();
			}
			else
			{
				harmony.PatchAll();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Light Color 1.5.0 loaded");
		}

		private void Update()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			watcher.Update();
			if (dedicated)
			{
				return;
			}
			StoreHelmetSettings();
			if (!IsColorKeyDown())
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !((Character)localPlayer).TakeInput())
			{
				return;
			}
			GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
			if ((Object)(object)hoverObject == (Object)null)
			{
				return;
			}
			LightTint componentInParent = hoverObject.GetComponentInParent<LightTint>();
			if (!((Object)(object)componentInParent == (Object)null) && componentInParent.HasEffects)
			{
				if (!AdminSync.CanChangeColors)
				{
					((Character)localPlayer).Message((MessageType)2, "Only admins can change colors on this server", 0, (Sprite)null, false);
				}
				else if (PrivateArea.CheckAccess(((Component)componentInParent).transform.position, 0f, true, false))
				{
					componentInParent.RequestColor();
				}
			}
		}

		private void CheckHelmetText()
		{
			string text = Helmet.Value.Trim();
			if (!LightSettings.TryParse(text, out var settings, out var error))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Couldn't read the Helmet setting \"" + text + "\": " + error));
				text = "";
			}
			else if (settings.Styles != TextStyle.None)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Halo, lit and outline in the Helmet setting \"" + text + "\" only work on signs, so they're ignored"));
			}
			else if (settings.IsDefault())
			{
				text = "";
			}
			helmetText = text;
		}

		private void StoreHelmetSettings()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			bool flag = helmetText.Length > 0 && !AdminSync.CanUseHelmet;
			string text = (flag ? "" : helmetText);
			if ((Object)(object)localPlayer == (Object)(object)storedPlayer && text == storedText)
			{
				return;
			}
			ZNetView nview = ((Character)localPlayer).m_nview;
			if (!((Object)(object)nview == (Object)null) && nview.IsValid())
			{
				nview.GetZDO().Set(HelmetTint.SettingsHash, text);
				storedPlayer = localPlayer;
				storedText = text;
				if (flag && !helmetDenied)
				{
					((Character)localPlayer).Message((MessageType)1, "Only admins can use the Helmet setting on this server", 0, (Sprite)null, false);
				}
				helmetDenied = flag;
			}
		}

		private static bool IsColorKeyDown()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = ColorKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}

		private void OnDestroy()
		{
			watcher?.Dispose();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(TeleportWorld), "Update")]
	public static class TeleportWorldUpdatePatch
	{
		private static readonly int EmissionColorId = Shader.PropertyToID("_EmissionColor");

		private static readonly int EmissiveTexId = Shader.PropertyToID("_EmissiveTex");

		private static void Postfix(TeleportWorld __instance)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance.m_model == (Object)null))
			{
				LightTint component = ((Component)__instance).GetComponent<LightTint>();
				SetGlowTexture(((Renderer)__instance.m_model).material, (Object)(object)component != (Object)null && component.Settings.HasColor);
				if (!((Object)(object)component == (Object)null) && (component.Settings.HasColor || component.Settings.Brightness != 1f))
				{
					Color val = Color.Lerp(__instance.m_colorUnconnected, __instance.m_colorTargetfound, __instance.m_colorAlpha);
					Color val2 = (component.Settings.HasColor ? Recolor.Replace(val, component.Settings.Color) : val);
					float a = val2.a;
					val2 *= component.Settings.Brightness;
					val2.a = a;
					((Renderer)__instance.m_model).material.SetColor(EmissionColorId, val2);
				}
			}
		}

		private static void SetGlowTexture(Material material, bool hasColor)
		{
			if (!material.HasProperty(EmissiveTexId))
			{
				return;
			}
			Texture texture = material.GetTexture(EmissiveTexId);
			if (!((Object)(object)texture == (Object)null))
			{
				Texture originalTexture = Recolor.GetOriginalTexture(texture);
				Texture val = (Texture)(hasColor ? ((object)Recolor.GetGrayTexture(originalTexture)) : ((object)originalTexture));
				if ((Object)(object)val != (Object)(object)texture)
				{
					material.SetTexture(EmissiveTexId, val);
				}
			}
		}
	}
	[HarmonyPatch(typeof(TeleportWorld), "UpdatePortal")]
	public static class TeleportWorldUpdatePortalPatch
	{
		public static bool Active;

		public static Color Color;

		private static void Prefix(TeleportWorld __instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			LightTint component = ((Component)__instance).GetComponent<LightTint>();
			Active = (Object)(object)component != (Object)null && component.Settings.HasColor;
			Color = (((Object)(object)component != (Object)null) ? component.Settings.Color : Color.white);
		}

		private static void Finalizer()
		{
			Active = false;
		}
	}
	[HarmonyPatch(typeof(EffectList), "Create")]
	public static class EffectListCreatePatch
	{
		private static void Postfix(GameObject[] __result)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!TeleportWorldUpdatePortalPatch.Active || __result == null)
			{
				return;
			}
			foreach (GameObject val in __result)
			{
				if ((Object)(object)val != (Object)null)
				{
					new Tintable(val).Apply(LightSettings.ColorOnly(TeleportWorldUpdatePortalPatch.Color));
				}
			}
		}
	}
	[HarmonyPatch(typeof(TeleportWorld), "Teleport")]
	public static class TeleportWorldTeleportPatch
	{
		public static bool Active;

		public static Color? From;

		public static ZDOID Target;

		private static void Prefix(TeleportWorld __instance)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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)
			LightTint component = ((Component)__instance).GetComponent<LightTint>();
			Active = true;
			From = (((Object)(object)component != (Object)null && component.Settings.HasColor) ? new Color?(component.Settings.Color) : ((Color?)null));
			Target = ZDOID.None;
			ZNetView nview = __instance.m_nview;
			if (!((Object)(object)nview == (Object)null) && nview.IsValid())
			{
				Target = nview.GetZDO().GetConnectionZDOID((ConnectionType)1);
				if (Target != ZDOID.None)
				{
					ZDOMan.instance.RequestZDO(Target);
				}
			}
		}

		private static void Finalizer()
		{
			Active = false;
		}
	}
	[HarmonyPatch(typeof(Player), "TeleportTo")]
	public static class PlayerTeleportToPatch
	{
		private static void Postfix(Player __instance, bool __result)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (__result && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				if (TeleportWorldTeleportPatch.Active)
				{
					TeleportSwirl.Begin(TeleportWorldTeleportPatch.From, TeleportWorldTeleportPatch.Target);
				}
				else
				{
					TeleportSwirl.Begin(null, ZDOID.None);
				}
			}
		}
	}
	internal static class Recolor
	{
		private const float MinSaturation = 0.1f;

		private const float MinReplaceStrength = 1f / 3f;

		private const int MaxTextureSize = 512;

		private const string EmissionKeyword = "_EMISSION";

		private static readonly int EmissionColorId = Shader.PropertyToID("_EmissionColor");

		private static readonly int EmissionMapId = Shader.PropertyToID("_EmissionMap");

		private static readonly int BaseColorId = Shader.PropertyToID("_Color");

		private static readonly int TintColorId = Shader.PropertyToID("_TintColor");

		private static readonly int[] ColorIds = new int[3] { BaseColorId, EmissionColorId, TintColorId };

		private static readonly Dictionary<long, Material> materials = new Dictionary<long, Material>();

		private static readonly Dictionary<long, Texture2D> textures = new Dictionary<long, Texture2D>();

		private static readonly Dictionary<int, Texture2D> grayTextures = new Dictionary<int, Texture2D>();

		private static readonly Dictionary<int, Texture> grayOriginals = new Dictionary<int, Texture>();

		private static readonly Dictionary<long, Sprite> sprites = new Dictionary<long, Sprite>();

		public static Color Shift(Color color, Color target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(color, ref num, ref num2, ref num3);
			if (num2 < 0.1f)
			{
				return color;
			}
			float num4 = default(float);
			float num5 = default(float);
			float num6 = default(float);
			Color.RGBToHSV(target, ref num4, ref num5, ref num6);
			Color result = Color.HSVToRGB(num4, num2 * num5, num3 * num6, true);
			result.a = color.a;
			return result;
		}

		public static Color Strengthen(Color target, float minStrength = 1f / 3f)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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)
			float maxColorComponent = ((Color)(ref target)).maxColorComponent;
			Color val = ((maxColorComponent > 0f) ? (target / maxColorComponent) : Color.white);
			float num = minStrength + (1f - minStrength) * Mathf.Clamp01(maxColorComponent);
			Color result = val * num;
			result.a = 1f;
			return result;
		}

		public static Color Replace(Color glow, Color target)
		{
			//IL_0029: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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)
			if (((Color)(ref target)).maxColorComponent <= 0f)
			{
				return new Color(0f, 0f, 0f, glow.a);
			}
			Color result = Strengthen(target) * ((Color)(ref glow)).maxColorComponent;
			result.a = glow.a;
			return result;
		}

		public static MinMaxGradient Shift(MinMaxGradient value, Color target)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return Map(value, (Color color) => Shift(color, target));
		}

		public static MinMaxGradient Copy(MinMaxGradient value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return Map(value, (Color color) => color);
		}

		private static MinMaxGradient Map(MinMaxGradient value, Func<Color, Color> map)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected I4, but got Unknown
			//IL_0025: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			ParticleSystemGradientMode mode = ((MinMaxGradient)(ref value)).mode;
			MinMaxGradient result = default(MinMaxGradient);
			switch ((int)mode)
			{
			case 0:
				((MinMaxGradient)(ref result))..ctor(map(((MinMaxGradient)(ref value)).color));
				break;
			case 2:
				((MinMaxGradient)(ref result))..ctor(map(((MinMaxGradient)(ref value)).colorMin), map(((MinMaxGradient)(ref value)).colorMax));
				break;
			case 3:
				((MinMaxGradient)(ref result))..ctor(Map(((MinMaxGradient)(ref value)).gradientMin, map), Map(((MinMaxGradient)(ref value)).gradientMax, map));
				break;
			default:
				((MinMaxGradient)(ref result))..ctor(Map(((MinMaxGradient)(ref value)).gradient, map));
				break;
			}
			((MinMaxGradient)(ref result)).mode = ((MinMaxGradient)(ref value)).mode;
			return result;
		}

		private static Gradient Map(Gradient gradient, Func<Color, Color> map)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (gradient == null)
			{
				return null;
			}
			GradientColorKey[] colorKeys = gradient.colorKeys;
			for (int i = 0; i < colorKeys.Length; i++)
			{
				colorKeys[i].color = map(colorKeys[i].color);
			}
			Gradient val = new Gradient
			{
				mode = gradient.mode,
				colorSpace = gradient.colorSpace
			};
			val.SetKeys(colorKeys, gradient.alphaKeys);
			return val;
		}

		public static bool ShouldRecolor(Material material, bool particles)
		{
			if ((Object)(object)material == (Object)null)
			{
				return false;
			}
			if (!particles)
			{
				return IsEmissive(material);
			}
			if (!IsTinted(material, BaseColorId) && !IsTinted(material, EmissionColorId))
			{
				return IsTinted(material, TintColorId);
			}
			return true;
		}

		private static bool IsTinted(Material material, int id)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (!material.HasProperty(id))
			{
				return false;
			}
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			Color.RGBToHSV(material.GetColor(id), ref num, ref num2, ref num3);
			if (num2 >= 0.1f)
			{
				return num3 > 0.01f;
			}
			return false;
		}

		public static bool IsEmissive(Material material)
		{
			//IL_002b: 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)
			if ((Object)(object)material == (Object)null || !material.HasProperty(EmissionColorId) || !material.IsKeywordEnabled("_EMISSION"))
			{
				return false;
			}
			Color color = material.GetColor(EmissionColorId);
			return ((Color)(ref color)).maxColorComponent > 0.01f;
		}

		public static Material GetMaterial(Material material, Color target)
		{
			//IL_0001: 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_0029: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			long key = GetKey((Object)(object)material, target);
			if (materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = new Material(material);
			((Object)value).name = ((Object)material).name + " (Light Color)";
			int[] colorIds = ColorIds;
			foreach (int num in colorIds)
			{
				if (material.HasProperty(num))
				{
					value.SetColor(num, Shift(material.GetColor(num), target));
				}
			}
			if (material.HasProperty(EmissionMapId))
			{
				Texture texture = material.GetTexture(EmissionMapId);
				if ((Object)(object)texture != (Object)null)
				{
					value.SetTexture(EmissionMapId, (Texture)(object)GetTexture(texture, target));
				}
			}
			materials[key] = value;
			return value;
		}

		public static Sprite GetSprite(Sprite sprite, Color target)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			long key = GetKey((Object)(object)sprite, target);
			if (sprites.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Texture2D texture = GetTexture((Texture)(object)sprite.texture, target);
			float num = (float)((Texture)texture).width / (float)((Texture)sprite.texture).width;
			Rect textureRect = sprite.textureRect;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref textureRect)).x * num, ((Rect)(ref textureRect)).y * num, ((Rect)(ref textureRect)).width * num, ((Rect)(ref textureRect)).height * num);
			float x = sprite.pivot.x;
			Rect rect = sprite.rect;
			float num2 = x / ((Rect)(ref rect)).width;
			float y = sprite.pivot.y;
			rect = sprite.rect;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(num2, y / ((Rect)(ref rect)).height);
			value = Sprite.Create(texture, val, val2, sprite.pixelsPerUnit * num, 0u, (SpriteMeshType)0, sprite.border * num);
			((Object)value).name = ((Object)sprite).name + " (Light Color)";
			sprites[key] = value;
			return value;
		}

		private static Texture2D GetTexture(Texture texture, Color target)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			long key = GetKey((Object)(object)texture, target);
			if (textures.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = CopyTexture(texture, (Color32 pixel) => Color32.op_Implicit(Shift(Color32.op_Implicit(pixel), target)));
			textures[key] = value;
			return value;
		}

		public static Texture2D GetGrayTexture(Texture texture)
		{
			int instanceID = ((Object)texture).GetInstanceID();
			if (grayTextures.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = CopyTexture(texture, delegate(Color32 pixel)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: 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)
				byte num = (byte)Mathf.Max(new int[3] { pixel.r, pixel.g, pixel.b });
				return new Color32(num, num, num, pixel.a);
			});
			grayTextures[instanceID] = value;
			grayOriginals[((Object)value).GetInstanceID()] = texture;
			return value;
		}

		public static Texture GetOriginalTexture(Texture texture)
		{
			if (!((Object)(object)texture != (Object)null) || !grayOriginals.TryGetValue(((Object)texture).GetInstanceID(), out var value))
			{
				return texture;
			}
			return value;
		}

		private static Texture2D CopyTexture(Texture texture, Func<Color32, Color32> map)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_006d: 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_00a1: 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)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			int num = texture.width;
			int num2 = texture.height;
			while (num > 512 || num2 > 512)
			{
				num = Mathf.Max(1, num / 2);
				num2 = Mathf.Max(1, num2 / 2);
			}
			RenderTexture temporary = RenderTexture.GetTemporary(num, num2, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			RenderTexture active = RenderTexture.active;
			Graphics.Blit(texture, temporary);
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, true);
			val.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0);
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			Color32[] pixels = val.GetPixels32();
			for (int i = 0; i < pixels.Length; i++)
			{
				pixels[i] = map(pixels[i]);
			}
			val.SetPixels32(pixels);
			((Texture)val).wrapMode = texture.wrapMode;
			((Texture)val).filterMode = texture.filterMode;
			((Object)val).name = ((Object)texture).name + " (Light Color)";
			val.Apply(true, true);
			return val;
		}

		public static long GetKey(Object obj, Color target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_0007: 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_001a: 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)
			Color32 val = Color32.op_Implicit(target);
			uint num = (uint)((val.r << 24) | (val.g << 16) | (val.b << 8) | val.a);
			return ((long)obj.GetInstanceID() << 32) | num;
		}
	}
	[HarmonyPatch(typeof(ShieldGenerator), "UpdateShield")]
	public static class ShieldGeneratorUpdateShieldPatch
	{
		private static readonly int EmissionColorId = Shader.PropertyToID("_EmissionColor");

		private static void Postfix(ShieldGenerator __instance)
		{
			//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)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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)
			//IL_0133: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.m_nview.IsValid() || __instance.m_propertyBlock == null)
			{
				return;
			}
			LightTint component = ((Component)__instance).GetComponent<LightTint>();
			if ((Object)(object)component == (Object)null || (!component.Settings.HasColor && component.Settings.Brightness == 1f))
			{
				return;
			}
			Color domeColor = ShieldDomeImageEffect.GetDomeColor(__instance.m_lastFuel);
			if (component.Settings.HasColor)
			{
				Color color = component.Settings.Color;
				Light[] coloredLights = __instance.m_coloredLights;
				for (int i = 0; i < coloredLights.Length; i++)
				{
					coloredLights[i].color = color;
				}
				ParticleSystem[] energyParticles = __instance.m_energyParticles;
				for (int i = 0; i < energyParticles.Length; i++)
				{
					MainModule main = energyParticles[i].main;
					((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Recolor.Shift(domeColor, color));
				}
				if ((Object)(object)__instance.m_energyParticlesFlare != (Object)null)
				{
					Color color2 = domeColor * Mathf.Pow(__instance.m_lastFuel, 0.5f);
					CustomDataModule customData = __instance.m_energyParticlesFlare.customData;
					((CustomDataModule)(ref customData)).SetColor((ParticleSystemCustomData)0, MinMaxGradient.op_Implicit(Recolor.Shift(color2, color)));
				}
			}
			Color val = domeColor * 2f;
			Color val2 = (component.Settings.HasColor ? Recolor.Shift(val, component.Settings.Color) : val);
			float a = val2.a;
			val2 *= component.Settings.Brightness;
			val2.a = a;
			__instance.m_propertyBlock.SetColor(EmissionColorId, val2);
			MeshRenderer[] meshRenderers = __instance.m_meshRenderers;
			for (int i = 0; i < meshRenderers.Length; i++)
			{
				((Renderer)meshRenderers[i]).SetPropertyBlock(__instance.m_propertyBlock);
			}
		}
	}
	[HarmonyPatch(typeof(ShieldDomeImageEffect), "OnRenderImage")]
	public static class ShieldDomeRenderPatch
	{
		private static bool rendering;

		private static readonly Dictionary<long, Texture2D> gradients = new Dictionary<long, Texture2D>();

		private static readonly List<ComputeBuffer> buffers = new List<ComputeBuffer>();

		private static bool Prefix(ShieldDomeImageEffect __instance, RenderTexture src, RenderTexture dest)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			if (rendering || __instance.m_shieldDomes == null || __instance.m_shieldDomes.Length == 0 || (Object)(object)__instance.m_gradientTex == (Object)null)
			{
				return true;
			}
			List<ShieldDome> list = new List<ShieldDome>();
			Dictionary<long, List<ShieldDome>> dictionary = new Dictionary<long, List<ShieldDome>>();
			Dictionary<long, Texture2D> dictionary2 = new Dictionary<long, Texture2D>();
			foreach (KeyValuePair<ShieldGenerator, ShieldDome> shieldDomeDatum in __instance.m_shieldDomeData)
			{
				LightTint lightTint = (((Object)(object)shieldDomeDatum.Key != (Object)null) ? ((Component)shieldDomeDatum.Key).GetComponent<LightTint>() : null);
				if ((Object)(object)lightTint == (Object)null || !lightTint.Settings.HasColor)
				{
					list.Add(shieldDomeDatum.Value);
					continue;
				}
				Color color = lightTint.Settings.Color;
				long key = Recolor.GetKey((Object)(object)__instance.m_gradientTex, color);
				if (!dictionary.TryGetValue(key, out var value))
				{
					value = (dictionary[key] = new List<ShieldDome>());
					dictionary2[key] = GetGradient(__instance.m_gradientTex, color, key);
				}
				value.Add(shieldDomeDatum.Value);
			}
			if (dictionary.Count == 0)
			{
				return true;
			}
			List<ShieldDome[]> list3 = new List<ShieldDome[]>();
			List<Texture2D> list4 = new List<Texture2D>();
			if (list.Count > 0)
			{
				list3.Add(list.ToArray());
				list4.Add(__instance.m_gradientTex);
			}
			foreach (KeyValuePair<long, List<ShieldDome>> item in dictionary)
			{
				list3.Add(item.Value.ToArray());
				list4.Add(dictionary2[item.Key]);
			}
			ShieldDome[] shieldDomes = __instance.m_shieldDomes;
			Texture2D gradientTex = __instance.m_gradientTex;
			ComputeBuffer shieldDomeBuffer = __instance.m_shieldDomeBuffer;
			RenderTexture val = src;
			rendering = true;
			try
			{
				for (int i = 0; i < list3.Count; i++)
				{
					RenderTexture val2 = ((i == list3.Count - 1) ? dest : RenderTexture.GetTemporary(src.descriptor));
					if (buffers.Count <= i)
					{
						buffers.Add(null);
					}
					__instance.m_shieldDomes = list3[i];
					__instance.m_gradientTex = list4[i];
					__instance.m_shieldDomeBuffer = buffers[i];
					__instance.OnRenderImage(val, val2);
					buffers[i] = __instance.m_shieldDomeBuffer;
					if ((Object)(object)val != (Object)(object)src)
					{
						RenderTexture.ReleaseTemporary(val);
					}
					val = val2;
				}
			}
			finally
			{
				__instance.m_shieldDomes = shieldDomes;
				__instance.m_gradientTex = gradientTex;
				__instance.m_shieldDomeBuffer = shieldDomeBuffer;
				rendering = false;
			}
			return false;
		}

		private static Texture2D GetGradient(Texture2D original, Color color, long key)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (gradients.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = new Texture2D(((Texture)original).width, ((Texture)original).height, (TextureFormat)3, false);
			((Object)value).name = ((Object)original).name + " (Light Color)";
			((Texture)value).wrapMode = ((Texture)original).wrapMode;
			Color[] pixels = original.GetPixels();
			for (int i = 0; i < pixels.Length; i++)
			{
				pixels[i] = Recolor.Shift(pixels[i], color);
			}
			value.SetPixels(pixels);
			value.Apply();
			gradients[key] = value;
			return value;
		}
	}
	public class TeleportSwirl : MonoBehaviour
	{
		private class Layer
		{
			public Image Image;

			public Image Overlay;

			public Sprite Original;

			public Color Color;
		}

		private const float BlendStart = 2f;

		private const float LayerDelay = 0.6f;

		private const float LayerFade = 1.5f;

		private const float MinStrength = 7f / 15f;

		private readonly List<Layer> layers = new List<Layer>();

		private Color? from;

		private Color? to;

		private ZDOID target;

		private bool targetRead;

		private float startTime;

		public static void Begin(Color? from, ZDOID target)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			Hud instance = Hud.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_teleportingProgress == (Object)null)
			{
				return;
			}
			TeleportSwirl teleportSwirl = instance.m_teleportingProgress.GetComponent<TeleportSwirl>();
			if ((Object)(object)teleportSwirl == (Object)null)
			{
				teleportSwirl = instance.m_teleportingProgress.AddComponent<TeleportSwirl>();
				teleportSwirl.FindLayers();
			}
			teleportSwirl.from = from;
			teleportSwirl.to = from;
			teleportSwirl.target = target;
			teleportSwirl.targetRead = target == ZDOID.None;
			teleportSwirl.startTime = Time.time;
			foreach (Layer layer in teleportSwirl.layers)
			{
				layer.Image.sprite = GetSprite(layer, from);
				((Graphic)layer.Image).color = layer.Color;
				((Component)layer.Overlay).gameObject.SetActive(false);
			}
			teleportSwirl.UpdateFade();
		}

		private void FindLayers()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)this).transform.Find("Swirl");
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)this).transform;
			}
			Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
			foreach (Image val2 in componentsInChildren)
			{
				if (!((Object)(object)val2.sprite == (Object)null))
				{
					layers.Add(new Layer
					{
						Image = val2,
						Overlay = CreateOverlay(val2),
						Original = val2.sprite,
						Color = ((Graphic)val2).color
					});
				}
			}
		}

		private static Image CreateOverlay(Image image)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Light Color overlay", new Type[1] { typeof(RectTransform) })
			{
				layer = ((Component)image).gameObject.layer
			};
			val.SetActive(false);
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(((Component)image).transform, false);
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image obj = val.AddComponent<Image>();
			obj.type = image.type;
			obj.preserveAspect = image.preserveAspect;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static Sprite GetSprite(Layer layer, Color? color)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!color.HasValue)
			{
				return layer.Original;
			}
			return Recolor.GetSprite(layer.Original, Recolor.Strengthen(color.Value, 7f / 15f));
		}

		private static bool SameColor(Color? a, Color? b)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (a.HasValue != b.HasValue)
			{
				return false;
			}
			if (a.HasValue)
			{
				return a.Value == b.Value;
			}
			return true;
		}

		private void Update()
		{
			UpdateFade();
		}

		private void UpdateFade()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			float num = Time.time - startTime;
			if (!targetRead)
			{
				if (num < 2f)
				{
					return;
				}
				targetRead = true;
				ZDO zDO = ZDOMan.instance.GetZDO(target);
				if (zDO != null)
				{
					LightSettings storedSettings = LightTint.GetStoredSettings(zDO);
					to = (storedSettings.HasColor ? new Color?(storedSettings.Color) : ((Color?)null));
				}
				if (!SameColor(from, to))
				{
					foreach (Layer layer2 in layers)
					{
						layer2.Overlay.sprite = GetSprite(layer2, to);
						((Component)layer2.Overlay).gameObject.SetActive(true);
					}
				}
			}
			if (!SameColor(from, to))
			{
				for (int i = 0; i < layers.Count; i++)
				{
					Layer layer = layers[i];
					float num2 = Mathf.SmoothStep(0f, 1f, (num - 2f - (float)i * 0.6f) / 1.5f);
					Color color = layer.Color;
					color.a *= 1f - num2 * num2 * num2 * num2;
					((Graphic)layer.Image).color = color;
					Color color2 = layer.Color;
					color2.a *= num2;
					((Graphic)layer.Overlay).color = color2;
				}
			}
		}
	}
	internal static class TextGlow
	{
		private const string ShaderName = "TextMeshPro/Distance Field";

		private const string UnderlayKeyword = "UNDERLAY_ON";

		private const float HaloDilate = 0.3f;

		private const float HaloSoftness = 0.6f;

		private const float OutlineWidth = 0.125f;

		private const float BrightnessScale = 0.6f;

		private static readonly int FaceColorId = Shader.PropertyToID("_FaceColor");

		private static readonly int FaceDilateId = Shader.PropertyToID("_FaceDilate");

		private static readonly int OutlineColorId = Shader.PropertyToID("_OutlineColor");

		private static readonly int OutlineWidthId = Shader.PropertyToID("_OutlineWidth");

		private static readonly int OutlineSoftnessId = Shader.PropertyToID("_OutlineSoftness");

		private static readonly int UnderlayColorId = Shader.PropertyToID("_UnderlayColor");

		private static readonly int UnderlayDilateId = Shader.PropertyToID("_UnderlayDilate");

		private static readonly int UnderlaySoftnessId = Shader.PropertyToID("_UnderlaySoftness");

		private static readonly int UnderlayOffsetXId = Shader.PropertyToID("_UnderlayOffsetX");

		private static readonly int UnderlayOffsetYId = Shader.PropertyToID("_UnderlayOffsetY");

		private static readonly Dictionary<string, Material> materials = new Dictionary<string, Material>();

		private static Shader shader;

		private static bool searched;

		public static TextStyle GetStyles(LightSettings settings)
		{
			if (settings.Styles != TextStyle.None)
			{
				return settings.Styles;
			}
			return TextStyle.Halo;
		}

		public static Color GetColor(LightSettings settings)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (!settings.HasColor)
			{
				return Color.white;
			}
			return settings.Color;
		}

		public static Material GetMaterial(Material material, LightSettings settings)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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)
			Shader val = FindShader();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			TextStyle styles = GetStyles(settings);
			Color color = GetColor(settings);
			string[] obj = new string[7]
			{
				((Object)material).GetInstanceID().ToString(),
				" ",
				null,
				null,
				null,
				null,
				null
			};
			int num = (int)styles;
			obj[2] = num.ToString();
			obj[3] = " ";
			obj[4] = ColorUtility.ToHtmlStringRGB(color);
			obj[5] = " ";
			obj[6] = settings.Brightness.ToString();
			string key = string.Concat(obj);
			if (materials.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = new Material(material);
			((Object)value).name = ((Object)material).name + " (Light Color)";
			value.shader = val;
			float num2 = settings.Brightness * 0.6f;
			Color val2 = color * num2;
			val2.a = 1f;
			Color val3 = (((styles & TextStyle.Lit) != TextStyle.None) ? (Color.white * num2) : Color.white);
			val3.a = 1f;
			value.SetColor(FaceColorId, val3);
			bool flag = (styles & TextStyle.Outline) != 0;
			value.SetColor(OutlineColorId, val2);
			value.SetFloat(OutlineWidthId, flag ? 0.125f : 0f);
			value.SetFloat(OutlineSoftnessId, 0f);
			value.SetFloat(FaceDilateId, flag ? 0.125f : 0f);
			if ((styles & TextStyle.Halo) != TextStyle.None)
			{
				value.EnableKeyword("UNDERLAY_ON");
				value.SetColor(UnderlayColorId, val2);
				value.SetFloat(UnderlayDilateId, 0.3f);
				value.SetFloat(UnderlaySoftnessId, 0.6f);
				value.SetFloat(UnderlayOffsetXId, 0f);
				value.SetFloat(UnderlayOffsetYId, 0f);
			}
			else
			{
				value.DisableKeyword("UNDERLAY_ON");
			}
			ShaderUtilities.UpdateShaderRatios(value);
			materials[key] = value;
			return value;
		}

		private static Shader FindShader()
		{
			if (searched)
			{
				return shader;
			}
			searched = true;
			shader = Shader.Find("TextMeshPro/Distance Field");
			if ((Object)(object)shader == (Object)null)
			{
				Shader[] array = Resources.FindObjectsOfTypeAll<Shader>();
				foreach (Shader val in array)
				{
					if (((Object)val).name == "TextMeshPro/Distance Field")
					{
						shader = val;
						break;
					}
				}
			}
			if ((Object)(object)shader == (Object)null)
			{
				Debug.LogWarning((object)"Light Color: couldn't find the TextMeshPro/Distance Field shader, so sign text can't glow");
			}
			return shader;
		}
	}
	public class Tintable
	{
		private class SignText
		{
			public TMP_Text text;

			public Material material;

			public Color color;
		}

		private class ParticleColors
		{
			public ParticleSystem system;

			public MinMaxGradient startColor;

			public MinMaxGradient lifetimeColor;

			public bool hasCustom1;

			public MinMaxGradient custom1;

			public bool hasCustom2;

			public MinMaxGradient custom2;
		}

		private class RendererMaterials
		{
			public Renderer renderer;

			public Material[] materials;

			public bool particles;
		}

		private readonly Light[] lights;

		private readonly Color[] originalColors;

		private readonly float[] originalIntensities;

		private readonly float[] originalRanges;

		private readonly float largestRange;

		private readonly List<ParticleColors> particles = new List<ParticleColors>();

		private readonly List<RendererMaterials> renderers = new List<RendererMaterials>();

		private readonly List<SignText> signs = new List<SignText>();

		public bool HasLights
		{
			get
			{
				Light[] array = lights;
				for (int i = 0; i < array.Length; i++)
				{
					if ((Object)(object)array[i] != (Object)null)
					{
						return true;
					}
				}
				return false;
			}
		}

		public bool HasSigns
		{
			get
			{
				foreach (SignText sign in signs)
				{
					if ((Object)(object)sign.text != (Object)null)
					{
						return true;
					}
				}
				return false;
			}
		}

		public bool HasEffects
		{
			get
			{
				if (HasLights || HasSigns)
				{
					return true;
				}
				foreach (ParticleColors particle in particles)
				{
					if ((Object)(object)particle.system != (Object)null)
					{
						return true;
					}
				}
				foreach (RendererMaterials renderer in renderers)
				{
					if ((Object)(object)renderer.renderer != (Object)null)
					{
						return true;
					}
				}
				return false;
			}
		}

		public Tintable(GameObject root)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Invalid comparison between Unknown and I4
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Invalid comparison between Unknown and I4
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: 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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			lights = root.GetComponentsInChildren<Light>(true);
			originalColors = (Color[])(object)new Color[lights.Length];
			originalIntensities = new float[lights.Length];
			originalRanges = new float[lights.Length];
			for (int i = 0; i < lights.Length; i++)
			{
				originalColors[i] = lights[i].color;
				originalIntensities[i] = GetBaseIntensity(lights[i]);
				originalRanges[i] = GetBaseRange(lights[i]);
				largestRange = Mathf.Max(largestRange, originalRanges[i]);
			}
			ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				ParticleColors particleColors = new ParticleColors
				{
					system = val
				};
				MainModule main = val.main;
				particleColors.startColor = Recolor.Copy(((MainModule)(ref main)).startColor);
				ColorOverLifetimeModule colorOverLifetime = val.colorOverLifetime;
				particleColors.lifetimeColor = Recolor.Copy(((ColorOverLifetimeModule)(ref colorOverLifetime)).color);
				CustomDataModule customData = val.customData;
				particleColors.hasCustom1 = ((CustomDataModule)(ref customData)).enabled && (int)((CustomDataModule)(ref customData)).GetMode((ParticleSystemCustomData)0) == 2;
				particleColors.hasCustom2 = ((CustomDataModule)(ref customData)).enabled && (int)((CustomDataModule)(ref customData)).GetMode((ParticleSystemCustomData)1) == 2;
				if (particleColors.hasCustom1)
				{
					particleColors.custom1 = Recolor.Copy(((CustomDataModule)(ref customData)).GetColor((ParticleSystemCustomData)0));
				}
				if (particleColors.hasCustom2)
				{
					particleColors.custom2 = Recolor.Copy(((CustomDataModule)(ref customData)).GetColor((ParticleSystemCustomData)1));
				}
				particles.Add(particleColors);
			}
			Renderer[] componentsInChildren2 = root.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren2)
			{
				bool flag = val2 is ParticleSystemRenderer;
				if (!flag && !(val2 is MeshRenderer) && !(val2 is SkinnedMeshRenderer))
				{
					continue;
				}
				Material[] sharedMaterials = val2.sharedMaterials;
				Material[] array = sharedMaterials;
				for (int k = 0; k < array.Length; k++)
				{
					if (Recolor.ShouldRecolor(array[k], flag))
					{
						RendererMaterials item = new RendererMaterials
						{
							renderer = val2,
							materials = sharedMaterials,
							particles = flag
						};
						renderers.Add(item);
						break;
					}
				}
			}
			Sign[] componentsInChildren3 = root.GetComponentsInChildren<Sign>(true);
			foreach (Sign val3 in componentsInChildren3)
			{
				if ((Object)(object)val3.m_textWidget != (Object)null)
				{
					SignText item2 = new SignText
					{
						text = (TMP_Text)(object)val3.m_textWidget,
						material = ((TMP_Text)val3.m_textWidget).fontSharedMaterial,
						color = ((Graphic)val3.m_textWidget).color
					};
					signs.Add(item2);
				}
			}
		}

		public void Apply(LightSettings settings)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			bool hasColor = settings.HasColor;
			Color color = settings.Color;
			float num = ((settings.Range > 0f && largestRange > 0f) ? (settings.Range / largestRange) : 1f);
			for (int i = 0; i < lights.Length; i++)
			{
				if ((Object)(object)lights[i] != (Object)null)
				{
					lights[i].color = (hasColor ? color : originalColors[i]);
					SetIntensity(lights[i], originalIntensities[i] * settings.Brightness);
					SetRange(lights[i], originalRanges[i] * num);
				}
			}
			foreach (ParticleColors particle in particles)
			{
				ApplyParticles(particle, hasColor, color);
			}
			foreach (RendererMaterials renderer in renderers)
			{
				ApplyMaterials(renderer, hasColor, color);
			}
			foreach (SignText sign in signs)
			{
				ApplySign(sign, settings);
			}
		}

		private static float GetBaseIntensity(Light light)
		{
			LightFlicker component = ((Component)light).GetComponent<LightFlicker>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_light != (Object)null)
			{
				return component.m_baseIntensity;
			}
			EffectFade fade = GetFade(light);
			if ((Object)(object)fade != (Object)null)
			{
				return fade.m_lightBaseIntensity;
			}
			return light.intensity;
		}

		private static EffectFade GetFade(Light light)
		{
			EffectFade componentInParent = ((Component)light).GetComponentInParent<EffectFade>(true);
			if (!((Object)(object)componentInParent != (Object)null) || !((Object)(object)componentInParent.m_light == (Object)(object)light))
			{
				return null;
			}
			return componentInParent;
		}

		private static float GetBaseRange(Light light)
		{
			LightLod component = ((Component)light).GetComponent<LightLod>();
			if (!((Object)(object)component != (Object)null) || !((Object)(object)component.m_light != (Object)null))
			{
				return light.range;
			}
			return component.m_baseRange;
		}

		private static void SetIntensity(Light light, float intensity)
		{
			LightFlicker component = ((Component)light).GetComponent<LightFlicker>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_light != (Object)null)
			{
				component.m_baseIntensity = intensity;
				return;
			}
			EffectFade fade = GetFade(light);
			if ((Object)(object)fade != (Object)null)
			{
				fade.m_lightBaseIntensity = intensity;
			}
			else
			{
				light.intensity = intensity;
			}
		}

		private static void SetRange(Light light, float range)
		{
			LightLod component = ((Component)light).GetComponent<LightLod>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_light != (Object)null)
			{
				component.m_baseRange = range;
				if (((Behaviour)light).enabled && light.range > 0f)
				{
					light.range = range;
				}
			}
			else
			{
				light.range = range;
			}
		}

		private static void ApplyParticles(ParticleColors colors, bool hasColor, Color color)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)colors.system == (Object)null))
			{
				MainModule main = colors.system.main;
				SetLiveStartColors(startColor: ((MainModule)(ref main)).startColor = (hasColor ? Recolor.Shift(colors.startColor, color) : Recolor.Copy(colors.startColor)), system: colors.system);
				ColorOverLifetimeModule colorOverLifetime = colors.system.colorOverLifetime;
				((ColorOverLifetimeModule)(ref colorOverLifetime)).color = (hasColor ? Recolor.Shift(colors.lifetimeColor, color) : Recolor.Copy(colors.lifetimeColor));
				CustomDataModule customData = colors.system.customData;
				if (colors.hasCustom1)
				{
					((CustomDataModule)(ref customData)).SetColor((ParticleSystemCustomData)0, hasColor ? Recolor.Shift(colors.custom1, color) : Recolor.Copy(colors.custom1));
				}
				if (colors.hasCustom2)
				{
					((CustomDataModule)(ref customData)).SetColor((ParticleSystemCustomData)1, hasColor ? Recolor.Shift(colors.custom2, color) : Recolor.Copy(colors.custom2));
				}
			}
		}

		private static void SetLiveStartColors(ParticleSystem system, MinMaxGradient startColor)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			int particleCount = system.particleCount;
			if (particleCount != 0)
			{
				Particle[] array = (Particle[])(object)new Particle[particleCount];
				particleCount = system.GetParticles(array);
				for (int i = 0; i < particleCount; i++)
				{
					float num = (float)(((Particle)(ref array[i])).randomSeed % 1000) / 1000f;
					((Particle)(ref array[i])).startColor = Color32.op_Implicit(((MinMaxGradient)(ref startColor)).Evaluate(num, num));
				}
				system.SetParticles(array, particleCount);
			}
		}

		private static void ApplyMaterials(RendererMaterials entry, bool hasColor, Color color)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)entry.renderer == (Object)null)
			{
				return;
			}
			if (!hasColor)
			{
				entry.renderer.sharedMaterials = entry.materials;
				return;
			}
			Material[] array = (Material[])(object)new Material[entry.materials.Length];
			for (int i = 0; i < array.Length; i++)
			{
				Material val = entry.materials[i];
				array[i] = (Recolor.ShouldRecolor(val, entry.particles) ? Recolor.GetMaterial(val, color) : val);
			}
			entry.renderer.sharedMaterials = array;
		}

		private static void ApplySign(SignText entry, LightSettings settings)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)entry.text == (Object)null))
			{
				Material val = (settings.IsDefault() ? null : TextGlow.GetMaterial(entry.material, settings));
				if ((Object)(object)val == (Object)null)
				{
					entry.text.fontSharedMaterial = entry.material;
					((Graphic)entry.text).color = entry.color;
				}
				else
				{
					entry.text.fontSharedMaterial = val;
					((Graphic)entry.text).color = (((TextGlow.GetStyles(settings) & TextStyle.Lit) != TextStyle.None) ? TextGlow.GetColor(settings) : entry.color);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace Kriona.Shared
{
	internal class ConfigMirror
	{
		private readonly ConfigFile config;

		private readonly Action changed;

		private bool syncing;

		public ConfigMirror(ConfigFile config, Action changed)
		{
			this.config = config;
			this.changed = changed;
			config.SaveOnConfigSet = false;
			config.SettingChanged += OnSettingChanged;
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues, int? order, string displayName)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes();
			configurationManagerAttributes.Order = order;
			configurationManagerAttributes.DispName = displayName;
			return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1] { configurationManagerAttributes }));
		}

		public void Remove(ConfigEntryBase entry)
		{
			config.Remove(entry.Definition);
		}

		public void Sync(Action apply)
		{
			syncing = true;
			try
			{
				apply();
			}
			finally
			{
				syncing = false;
			}
		}

		public static void SetDisplayName(ConfigEntryBase entry, string displayName)
		{
			object[] tags = entry.Description.Tags;
			for (int i = 0; i < tags.Length; i++)
			{
				if (tags[i] is ConfigurationManagerAttributes configurationManagerAttributes)
				{
					configurationManagerAttributes.DispName = displayName;
				}
			}
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			if (!syncing)
			{
				changed();
			}
		}
	}
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;

		public string DispName;
	}
	internal class ConfigWatcher : IDisposable
	{
		private const float ReloadDelay = 0.5f;

		private readonly string path;

		private readonly Action reload;

		private readonly ManualLogSource log;

		private readonly string pluginName;

		private readonly FileSystemWatcher watcher;

		private string knownContents;

		private volatile bool fileChanged;

		private float reloadTime = -1f;

		public ConfigWatcher(string path, Action reload, ManualLogSource log, string pluginName)
		{
			this.path = path;
			this.reload = reload;
			this.log = log;
			this.pluginName = pluginName;
			Remember();
			try
			{
				watcher = new FileSystemWatcher(Path.GetDirectoryName(path), Path.GetFileName(path));
				watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
				watcher.Changed += delegate
				{
					fileChanged = true;
				};
				watcher.Created += delegate
				{
					fileChanged = true;
				};
				watcher.Renamed += delegate
				{
					fileChanged = true;
				};
				watcher.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				watcher = null;
				log.LogWarning((object)("Couldn't watch " + path + " for changes, so changes made to it while Valheim is running aren't read: " + ex.Message));
			}
		}

		public ConfigWatcher(ConfigFile config, ManualLogSource log, string pluginName)
			: this(config.ConfigFilePath, delegate
			{
				ReloadConfig(config);
			}, log, pluginName)
		{
		}

		private static void ReloadConfig(ConfigFile config)
		{
			bool saveOnConfigSet = config.SaveOnConfigSet;
			config.SaveOnConfigSet = false;
			try
			{
				config.Reload();
			}
			finally
			{
				config.SaveOnConfigSet = saveOnConfigSet;
			}
			if (saveOnConfigSet && !MatchesFile(config))
			{
				config.Save();
			}
		}

		private static bool MatchesFile(ConfigFile config)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			Dictionary<ConfigDefinition, string> dictionary = new Dictionary<ConfigDefinition, string>();
			string text = string.Empty;
			string[] array = File.ReadAllLines(config.ConfigFilePath);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.StartsWith("#"))
				{
					continue;
				}
				if (text2.StartsWith("[") && text2.EndsWith("]"))
				{
					text = text2.Substring(1, text2.Length - 2);
					continue;
				}
				string[] array2 = text2.Split(new char[1] { '=' }, 2);
				if (array2.Length == 2)
				{
					dictionary[new ConfigDefinition(text, array2[0].Trim())] = array2[1].Trim();
				}
			}
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config)
			{
				if (!dictionary.TryGetValue(item.Key, out var value))
				{
					return false;
				}
				try
				{
					if (!object.Equals(TomlTypeConverter.ConvertToValue(value, item.Value.SettingType), item.Value.BoxedValue))
					{
						return false;
					}
				}
				catch (Exception)
				{
					return false;
				}
			}
			return true;
		}

		public void Update()
		{
			if (fileChanged)
			{
				fileChanged = false;
				reloadTime = Time.realtimeSinceStartup + 0.5f;
			}
			if (reloadTime < 0f || Time.realtimeSinceStartup < reloadTime)
			{
				return;
			}
			reloadTime = -1f;
			string text;
			try
			{
				text = File.ReadAllText(path);
			}
			catch (FileNotFoundException)
			{
				return;
			}
			catch (IOException)
			{
				reloadTime = Time.realtimeSinceStartup + 0.5f;
				return;
			}
			if (text == knownContents)
			{
				return;
			}
			reload();
			Remember();
			if (pluginName != null)
			{
				log.LogInfo((object)("Reloaded " + Path.GetFileName(path)));
				MessageHud instance = MessageHud.instance;
				if (instance != null)
				{
					instance.ShowMessage((MessageType)1, pluginName + ": config reloaded", 0, (Sprite)null, false, true);
				}
			}
		}

		public void Remember()
		{
			try
			{
				knownContents = File.ReadAllText(path);
			}
			catch (IOException)
			{
				knownContents = null;
			}
		}

		public void Dispose()
		{
			watcher?.Dispose();
		}
	}
	internal class StateEntries
	{
		public const string Inherit = "inherit";

		private static readonly AcceptableValueList<string> values = new AcceptableValueList<string>(new string[3] { "inherit", "true", "false" });

		private readonly ConfigMirror mirror;

		private readonly string help;

		private readonly Dictionary<string, ConfigEntry<string>> entries = new Dictionary<string, ConfigEntry<string>>(StringComparer.OrdinalIgnoreCase);

		private readonly HashSet<string> set = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		public StateEntries(ConfigMirror mirror, string help)
		{
			this.mirror = mirror;
			this.help = help;
		}

		public void Set(string section, string key, string displayName, bool? state)
		{
			string entryName = GetEntryName(key, displayName);
			if (entries.TryGetValue(key, out var value) && ((ConfigEntryBase)value).Definition.Section != section)
			{
				mirror.Remove((ConfigEntryBase)(object)value);
				entries.Remove(key);
				value = null;
			}
			if (value == null)
			{
				try
				{
					value = mirror.Bind(section, key, "inherit", "Prefab " + key + " - " + help, (AcceptableValueBase)(object)values, null, entryName);
				}
				catch (ArgumentException)
				{
					return;
				}
				entries[key] = value;
			}
			else
			{
				ConfigMirror.SetDisplayName((ConfigEntryBase)(object)value, entryName);
			}
			value.Value = Format(state);
			set.Add(key);
		}

		public void RemoveUnset()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, ConfigEntry<string>> entry in entries)
			{
				if (!set.Contains(entry.Key))
				{
					mirror.Remove((ConfigEntryBase)(object)entry.Value);
					list.Add(entry.Key);
				}
			}
			foreach (string item in list)
			{
				entries.Remove(item);
			}
			set.Clear();
		}

		public bool TryGetState(string key, out bool? state)
		{
			state = null;
			if (!entries.TryGetValue(key, out var value))
			{
				return false;
			}
			if (bool.TryParse(value.Value, out var result))
			{
				state = result;
			}
			return true;
		}

		public static string Format(bool? state)
		{
			if (!state.HasValue)
			{
				return "inherit";
			}
			if (!state.Value)
			{
				return "false";
			}
			return "true";
		}

		private static string GetEntryName(string key, string displayName)
		{
			string text = displayName.Trim();
			if (text.Length == 0 || text.Equals(key, StringComparison.OrdinalIgnoreCase))
			{
				return key;
			}
			return text + " (" + key + ")";
		}
	}
}