Decompiled source of ComfySigns v1.8.0

ComfySigns.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using ComfyLib;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ComfySigns")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ComfySigns")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1a56448b-9dac-4352-a528-d9e3f64f992e")]
[assembly: AssemblyFileVersion("1.8.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.8.0.0")]
[module: UnverifiableCode]
namespace ComfySigns
{
	[BepInPlugin("redseiko.valheim.comfysigns", "ComfySigns", "1.8.0")]
	public sealed class ComfySigns : BaseUnityPlugin
	{
		public const string PluginGuid = "redseiko.valheim.comfysigns";

		public const string PluginName = "ComfySigns";

		public const string PluginVersion = "1.8.0";

		private Harmony _harmony;

		private void Awake()
		{
			ComfyConfigUtils.BindConfig(((BaseUnityPlugin)this).Config);
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "redseiko.valheim.comfysigns");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class SignUtils
	{
		public static readonly Regex SizeRegex = new Regex("<size=[^>]*>");

		public static void AddFallbackFont(TMP_FontAsset font, TMP_FontAsset fallbackFont)
		{
			if (Object.op_Implicit((Object)(object)font) && Object.op_Implicit((Object)(object)fallbackFont) && !((Object)(object)fallbackFont == (Object)(object)font))
			{
				if (font.fallbackFontAssetTable == null)
				{
					font.fallbackFontAssetTable = new List<TMP_FontAsset> { fallbackFont };
				}
				else if (!font.fallbackFontAssetTable.Contains(fallbackFont))
				{
					font.fallbackFontAssetTable.Add(fallbackFont);
				}
			}
		}

		public static void AddFallbackFonts(TMP_FontAsset font)
		{
			AddFallbackFont(font, UIFonts.GetFontAsset(UIFonts.ValheimNorse));
			AddFallbackFont(font, UIFonts.GetFontAsset(UIFonts.ValheimNorsebold));
			AddFallbackFont(font, UIFonts.GetFontAsset(UIFonts.FallbackNotoSansNormal));
		}

		public static bool HasSignEffect(TMP_Text textComponent, string effectId)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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)
			if (textComponent.text.Length <= 0 || !textComponent.text.StartsWith("<link"))
			{
				return false;
			}
			TMP_LinkInfo[] linkInfo = textComponent.textInfo.linkInfo;
			for (int i = 0; i < linkInfo.Length; i++)
			{
				TMP_LinkInfo val = linkInfo[i];
				if (val.linkTextfirstCharacterIndex == 0 && val.linkTextLength == textComponent.textInfo.characterCount && ((TMP_LinkInfo)(ref val)).GetLinkID() == effectId)
				{
					return true;
				}
			}
			return false;
		}

		public static void OnSignConfigChanged()
		{
			SetupSignPrefabs(ZNetScene.s_instance);
		}

		public static void OnSignEffectConfigChanged()
		{
			Sign[] array = Resources.FindObjectsOfTypeAll<Sign>();
			foreach (Sign val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.m_nview) && val.m_nview.IsValid() && Object.op_Implicit((Object)(object)val.m_textWidget))
				{
					ProcessSignEffect(val);
				}
			}
		}

		public static void OnSignTextTagsConfigChanged()
		{
			Sign[] array = Resources.FindObjectsOfTypeAll<Sign>();
			foreach (Sign val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.m_nview) && val.m_nview.IsValid() && Object.op_Implicit((Object)(object)val.m_textWidget))
				{
					if (PluginConfig.SignTextIgnoreSizeTags.Value)
					{
						ProcessSignText(val);
					}
					else
					{
						((TMP_Text)val.m_textWidget).text = val.m_currentText;
					}
				}
			}
		}

		public static void ProcessSignEffect(Sign sign)
		{
			VertexColorCycler vertexColorCycler2 = default(VertexColorCycler);
			if (((Behaviour)sign.m_textWidget).enabled && HasSignEffect((TMP_Text)(object)sign.m_textWidget, "party") && ShouldRenderSignEffect(sign))
			{
				VertexColorCycler vertexColorCycler = default(VertexColorCycler);
				if (!((Component)sign.m_textWidget).gameObject.TryGetComponent<VertexColorCycler>(ref vertexColorCycler))
				{
					((Component)sign.m_textWidget).gameObject.AddComponent<VertexColorCycler>();
				}
			}
			else if (((Component)sign.m_textWidget).gameObject.TryGetComponent<VertexColorCycler>(ref vertexColorCycler2))
			{
				Object.Destroy((Object)(object)vertexColorCycler2);
				((TMP_Text)sign.m_textWidget).ForceMeshUpdate(true, false);
			}
		}

		public static void ProcessSignText(Sign sign)
		{
			if (PluginConfig.SignTextIgnoreSizeTags.Value && SizeRegex.IsMatch(((TMP_Text)sign.m_textWidget).text))
			{
				((TMP_Text)sign.m_textWidget).text = SizeRegex.Replace(((TMP_Text)sign.m_textWidget).text, string.Empty);
			}
		}

		public static void SetupSignFont(Sign sign, TMP_FontAsset fontAsset, Color color)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)((TMP_Text)sign.m_textWidget).font) == Object.op_Implicit((Object)(object)fontAsset))
			{
				((TMP_Text)sign.m_textWidget).font = fontAsset;
			}
			if ((Object)(object)((TMP_Text)sign.m_textWidget).fontSharedMaterial != (Object)(object)((TMP_Asset)fontAsset).material)
			{
				((TMP_Text)sign.m_textWidget).fontSharedMaterial = ((TMP_Asset)fontAsset).material;
			}
			((Graphic)sign.m_textWidget).color = color;
		}

		public static void SetupSignPrefabs(ZNetScene netScene)
		{
			//IL_001e: 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_005b: 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)
			if (!Object.op_Implicit((Object)(object)netScene))
			{
				return;
			}
			TMP_FontAsset fontAsset = UIFonts.GetFontAsset(PluginConfig.SignDefaultTextFontAsset.Value);
			Color value = PluginConfig.SignDefaultTextFontColor.Value;
			if (PluginConfig.UseFallbackFonts.Value)
			{
				AddFallbackFonts(fontAsset);
			}
			Sign sign = default(Sign);
			foreach (GameObject value2 in netScene.m_namedPrefabs.Values)
			{
				if (value2.TryGetComponent<Sign>(ref sign))
				{
					SetupSignFont(sign, fontAsset, value);
				}
			}
			Sign sign2 = default(Sign);
			foreach (ZNetView value3 in netScene.m_instances.Values)
			{
				if (((Component)value3).TryGetComponent<Sign>(ref sign2))
				{
					SetupSignFont(sign2, fontAsset, value);
				}
			}
		}

		public static bool ShouldRenderSignText(Sign sign)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return Vector3.Distance(((Component)sign).transform.position, ((Component)Player.m_localPlayer).transform.position) <= PluginConfig.SignTextMaximumRenderDistance.Value;
			}
			return false;
		}

		public static bool ShouldRenderSignEffect(Sign sign)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (PluginConfig.SignEffectEnablePartyEffect.Value && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)sign).transform.position) <= PluginConfig.SignEffectMaximumRenderDistance.Value;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Sign))]
	internal static class SignPatch
	{
		[HarmonyPatch]
		private static class SignUpdateTextPatch
		{
			private static FieldInfo _sign;

			[HarmonyTargetMethod]
			private static MethodBase FindUpdateTextMethod()
			{
				Type type = AccessTools.Inner(typeof(Sign), "<>c__DisplayClass4_0");
				_sign = AccessTools.Field(type, "<>4__this");
				return AccessTools.Method(type, "<UpdateText>b__0", (Type[])null, (Type[])null);
			}

			[HarmonyPostfix]
			private static void UpdateTextPostfix(object __instance)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				if (PluginConfig.IsModEnabled.Value)
				{
					SignUtils.ProcessSignText((Sign)_sign.GetValue(__instance));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix(ref Sign __instance)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (PluginConfig.IsModEnabled.Value)
			{
				__instance.m_characterLimit = 999;
				if (((Component)(object)__instance.m_textWidget).TryGetComponentInParent<Canvas>(out Canvas component))
				{
					((Component)component).transform.localPosition = new Vector3(0f, 0f, 0.1f);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetText")]
		private static void SetTextPostfix(ref Sign __instance)
		{
			if (PluginConfig.IsModEnabled.Value)
			{
				SignUtils.ProcessSignText(__instance);
				SignUtils.ProcessSignEffect(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdateText")]
		private static void UpdateTextPostfix(Sign __instance)
		{
			if (PluginConfig.IsModEnabled.Value)
			{
				((Behaviour)__instance.m_textWidget).enabled = SignUtils.ShouldRenderSignText(__instance);
				SignUtils.ProcessSignEffect(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(TextInput))]
	internal static class TextInputPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix(ref TextInput __instance)
		{
			if (PluginConfig.IsModEnabled.Value && Object.op_Implicit((Object)(object)__instance.m_inputField))
			{
				__instance.m_panel.GetOrAddComponent<TextInputPanelDragger>();
				((TMP_InputField)__instance.m_inputField).richText = false;
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene))]
	internal static class ZNetScenePatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix(ZNetScene __instance)
		{
			if (PluginConfig.IsModEnabled.Value)
			{
				SignUtils.SetupSignPrefabs(__instance);
			}
		}
	}
	public static class PluginConfig
	{
		public static ConfigFile CurrentConfig { get; private set; }

		public static ConfigEntry<bool> IsModEnabled { get; private set; }

		public static ConfigEntry<bool> UseFallbackFonts { get; private set; }

		public static ConfigEntry<bool> SuppressUnicodeNotFoundWarning { get; private set; }

		public static ConfigEntry<string> SignDefaultTextFontAsset { get; private set; }

		public static ConfigEntry<Color> SignDefaultTextFontColor { get; private set; }

		public static ConfigEntry<float> SignTextMaximumRenderDistance { get; private set; }

		public static ConfigEntry<bool> SignTextIgnoreSizeTags { get; private set; }

		public static ConfigEntry<float> SignEffectMaximumRenderDistance { get; private set; }

		public static ConfigEntry<bool> SignEffectEnablePartyEffect { get; private set; }

		[ComfyConfig]
		public static void BindConfig(ConfigFile config)
		{
			CurrentConfig = config;
			IsModEnabled = config.BindInOrder("_Global", "isModEnabled", defaultValue: true, "Globally enable or disable this mod.");
			UseFallbackFonts = config.BindInOrder("Fonts", "useFallbackFonts", defaultValue: true, "Use fallback fonts to support additional characters.");
		}

		[ComfyConfig(typeof(FejdStartup), "Awake")]
		public static void BindLoggingConfig(ConfigFile config)
		{
			SuppressUnicodeNotFoundWarning = config.BindInOrder("Logging", "suppressUnicodeNotFoundWarning", defaultValue: true, "Hide 'The character with Unicode value ... was not found...' log warnings.");
			SuppressUnicodeNotFoundWarning.OnSettingChanged(delegate(bool value)
			{
				TMP_Settings.instance.m_warningsDisabled = value;
			});
			TMP_Settings.instance.m_warningsDisabled = SuppressUnicodeNotFoundWarning.Value;
		}

		[ComfyConfig(typeof(FejdStartup), "Awake")]
		public static void BindSignConfig(ConfigFile config)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			string[] array = (from f in Resources.FindObjectsOfTypeAll<TMP_FontAsset>()
				select ((Object)f).name).Concat(from f in Resources.FindObjectsOfTypeAll<Font>()
				select ((Object)f).name).ToArray();
			SignDefaultTextFontAsset = config.BindInOrder("Sign.Text", "defaultTextFontAsset", "Valheim-Norse", "Sign.m_textWidget.fontAsset (TMP) default value.", (AcceptableValueBase)(object)new AcceptableValueList<string>(array));
			SignDefaultTextFontAsset.OnSettingChanged<string>(SignUtils.OnSignConfigChanged);
			SignDefaultTextFontColor = config.BindInOrder<Color>("Sign.Text", "defaultTextFontColor", Color.white, "Sign.m_textWidget.color default value.");
			SignDefaultTextFontColor.OnSettingChanged<Color>(SignUtils.OnSignConfigChanged);
			SignTextMaximumRenderDistance = config.BindInOrder("Sign.Text.Render", "maximumRenderDistance", 192f, "Maximum distance that signs can be from player to render sign text.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 192f));
			SignTextIgnoreSizeTags = config.Bind<bool>("Sign.Text.Tags", "ignoreSizeTags", false, "if set, ignore any and all <size> tags in sign text when rendered locally.");
			SignTextIgnoreSizeTags.OnSettingChanged<bool>(SignUtils.OnSignTextTagsConfigChanged);
		}

		[ComfyConfig(typeof(FejdStartup), "Awake")]
		public static void BindSignEffectConfig(ConfigFile config)
		{
			SignEffectMaximumRenderDistance = config.BindInOrder("SignEffect", "maximumRenderDistance", 64f, "Maximum distance that signs can be from player to render sign effects.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 128f));
			SignEffectMaximumRenderDistance.OnSettingChanged<float>(SignUtils.OnSignEffectConfigChanged);
			SignEffectEnablePartyEffect = config.BindInOrder("SignEffect.Party", "enablePartyEffect", defaultValue: false, "Enables the 'Party' Sign effect for signs using the party tag.");
			SignEffectEnablePartyEffect.OnSettingChanged<bool>(SignUtils.OnSignEffectConfigChanged);
		}
	}
	public sealed class TextInputPanelDragger : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		private RectTransform _rectTransform;

		private Vector2 _lastMousePosition;

		private void Start()
		{
			_rectTransform = ((Component)this).GetComponent<RectTransform>();
		}

		public void OnBeginDrag(PointerEventData eventData)
		{
			//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)
			_lastMousePosition = eventData.position;
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0001: 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_000c: 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_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_0024: 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_0034: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = eventData.position - _lastMousePosition;
			RectTransform rectTransform = _rectTransform;
			((Transform)rectTransform).position = ((Transform)rectTransform).position + new Vector3(val.x, val.y, 0f);
			_lastMousePosition = eventData.position;
		}

		public void OnEndDrag(PointerEventData eventData)
		{
		}
	}
	public sealed class VertexColorCycler : MonoBehaviour
	{
		private static readonly WaitForSeconds _longWait = new WaitForSeconds(1f);

		private static readonly WaitForSeconds _shortWait = new WaitForSeconds(0.05f);

		private TMP_Text _textComponent;

		private void Awake()
		{
			_textComponent = ((Component)this).GetComponent<TMP_Text>();
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(AnimateVertexColors());
		}

		private IEnumerator AnimateVertexColors()
		{
			TMP_TextInfo textInfo = _textComponent.textInfo;
			int currentCharacter = 0;
			Color32 val = default(Color32);
			while (true)
			{
				int characterCount = textInfo.characterCount;
				if (characterCount == 0)
				{
					yield return _longWait;
					continue;
				}
				int materialReferenceIndex = textInfo.characterInfo[currentCharacter].materialReferenceIndex;
				Color32[] colors = textInfo.meshInfo[materialReferenceIndex].colors32;
				int vertexIndex = textInfo.characterInfo[currentCharacter].vertexIndex;
				if (textInfo.characterInfo[currentCharacter].isVisible)
				{
					((Color32)(ref val))..ctor((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), byte.MaxValue);
					colors[vertexIndex] = val;
					colors[vertexIndex + 1] = val;
					colors[vertexIndex + 2] = val;
					colors[vertexIndex + 3] = val;
					_textComponent.UpdateVertexData((TMP_VertexDataUpdateFlags)16);
				}
				int num = currentCharacter;
				currentCharacter = (currentCharacter + 1) % characterCount;
				yield return (num < currentCharacter) ? _shortWait : _longWait;
			}
		}
	}
}
namespace ComfyLib
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	public sealed class ComfyConfigAttribute : Attribute
	{
		internal readonly MethodBase TargetMethod;

		public ComfyConfigAttribute()
		{
			TargetMethod = null;
		}

		public ComfyConfigAttribute(Type lateBindType, string lateBindMethodName)
		{
			TargetMethod = AccessTools.Method(lateBindType, lateBindMethodName, (Type[])null, (Type[])null);
		}
	}
	[HarmonyPatch]
	public static class ComfyConfigUtils
	{
		private sealed class ConfigBinder
		{
			public readonly ConfigFile ConfigFile;

			public readonly MethodBase TargetMethod;

			public readonly MethodBase BindConfigMethod;

			public ConfigBinder(ConfigFile configFile, MethodBase targetMethod, MethodBase bindConfigMethod)
			{
				ConfigFile = configFile;
				TargetMethod = targetMethod;
				BindConfigMethod = bindConfigMethod;
			}
		}

		private static readonly Dictionary<MethodBase, List<ConfigBinder>> _configBinders = new Dictionary<MethodBase, List<ConfigBinder>>();

		private static IEnumerable<MethodBase> TargetMethods()
		{
			return _configBinders.Keys;
		}

		private static void Postfix(MethodBase __originalMethod)
		{
			if (_configBinders.Count <= 0 || !_configBinders.TryGetValue(__originalMethod, out var value))
			{
				return;
			}
			foreach (ConfigBinder item in value)
			{
				item.BindConfigMethod.Invoke(null, new object[1] { item.ConfigFile });
			}
			value.Clear();
			_configBinders.Remove(__originalMethod);
		}

		public static void BindConfig(ConfigFile config)
		{
			foreach (MethodInfo bindConfigMethod in GetBindConfigMethods(Assembly.GetExecutingAssembly()))
			{
				ComfyConfigAttribute customAttribute = bindConfigMethod.GetCustomAttribute<ComfyConfigAttribute>(inherit: false);
				if (customAttribute.TargetMethod == null)
				{
					bindConfigMethod.Invoke(null, new object[1] { config });
				}
				else
				{
					AddConfigBinder(config, customAttribute.TargetMethod, bindConfigMethod);
				}
			}
		}

		private static void AddConfigBinder(ConfigFile configFile, MethodBase targetMethod, MethodBase bindConfigMethod)
		{
			if (!_configBinders.TryGetValue(targetMethod, out var value))
			{
				value = new List<ConfigBinder>();
				_configBinders[targetMethod] = value;
			}
			value.Add(new ConfigBinder(configFile, targetMethod, bindConfigMethod));
		}

		private static List<MethodInfo> GetBindConfigMethods(Assembly assembly)
		{
			List<MethodInfo> list = new List<MethodInfo>();
			Type[] types = assembly.GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttribute<ComfyConfigAttribute>(inherit: false) != null)
					{
						ParameterInfo[] parameters = methodInfo.GetParameters();
						if (parameters.Length == 1 && parameters[0].ParameterType == typeof(ConfigFile))
						{
							list.Add(methodInfo);
						}
					}
				}
			}
			return list;
		}
	}
	public static class ConfigFileExtensions
	{
		internal sealed class ConfigurationManagerAttributes
		{
			public Action<ConfigEntryBase> CustomDrawer;

			public bool? Browsable;

			public bool? HideDefaultButton;

			public int? Order;
		}

		private static readonly Dictionary<string, int> _sectionToSettingOrder = new Dictionary<string, int>();

		private static int GetSettingOrder(string section)
		{
			if (!_sectionToSettingOrder.TryGetValue(section, out var value))
			{
				value = 0;
			}
			_sectionToSettingOrder[section] = value - 1;
			return value;
		}

		public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = GetSettingOrder(section)
				}
			}));
		}

		public static ConfigEntry<T> BindInOrder<T>(this ConfigFile config, string section, string key, T defaultValue, string description, Action<ConfigEntryBase> customDrawer = null, bool browsable = true, bool hideDefaultButton = false, bool hideSettingName = false)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			return config.Bind<T>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Browsable = browsable,
					CustomDrawer = customDrawer,
					HideDefaultButton = hideDefaultButton,
					Order = GetSettingOrder(section)
				}
			}));
		}

		public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action settingChangedHandler)
		{
			configEntry.SettingChanged += delegate
			{
				settingChangedHandler();
			};
		}

		public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<T> settingChangedHandler)
		{
			configEntry.SettingChanged += delegate(object _, EventArgs eventArgs)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				settingChangedHandler((T)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue);
			};
		}

		public static void OnSettingChanged<T>(this ConfigEntry<T> configEntry, Action<ConfigEntry<T>> settingChangedHandler)
		{
			configEntry.SettingChanged += delegate(object _, EventArgs eventArgs)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				settingChangedHandler((ConfigEntry<T>)((SettingChangedEventArgs)eventArgs).ChangedSetting.BoxedValue);
			};
		}
	}
	public static class ComponentExtensions
	{
		public static bool TryGetComponentInParent<T>(this Component source, out T component) where T : Component
		{
			component = source.GetComponentInParent<T>();
			return Object.op_Implicit((Object)(object)component);
		}
	}
	public static class GameObjectExtensions
	{
		public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
		{
			T result = default(T);
			if (!gameObject.TryGetComponent<T>(ref result))
			{
				return gameObject.AddComponent<T>();
			}
			return result;
		}
	}
	public static class ObjectExtensions
	{
		public static T FirstByNameOrDefault<T>(this IEnumerable<T> unityObjects, string name) where T : Object
		{
			foreach (T unityObject in unityObjects)
			{
				if (((Object)unityObject).name == name)
				{
					return unityObject;
				}
			}
			return default(T);
		}

		public static T FirstByNameOrThrow<T>(this IEnumerable<T> unityObjects, string name) where T : Object
		{
			foreach (T unityObject in unityObjects)
			{
				if (((Object)unityObject).name == name)
				{
					return unityObject;
				}
			}
			throw new InvalidOperationException($"Could not find Unity object of type {typeof(T)} with name: {name}");
		}

		public static T Ref<T>(this T unityObject) where T : Object
		{
			if (!Object.op_Implicit((Object)(object)unityObject))
			{
				return default(T);
			}
			return unityObject;
		}
	}
	public static class RectMask2DExtensions
	{
		public static RectMask2D SetPadding(this RectMask2D rectMask, float left, float top, float right, float bottom)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			rectMask.padding = new Vector4(left, bottom, right, top);
			return rectMask;
		}

		public static RectMask2D SetSoftness(this RectMask2D rectMask, int horizontal, int vertical)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			rectMask.softness = new Vector2Int(horizontal, vertical);
			return rectMask;
		}
	}
	public static class TMPInputFieldExtensions
	{
		public static TMP_InputField SetRichText(this TMP_InputField inputField, bool richText)
		{
			inputField.richText = richText;
			return inputField;
		}

		public static TMP_InputField SetTextViewport(this TMP_InputField inputField, RectTransform viewport)
		{
			inputField.textViewport = viewport;
			return inputField;
		}
	}
	public static class TextMeshProUGUIExtensions
	{
		public static TextMeshProUGUI SetColor(this TextMeshProUGUI text, Color color)
		{
			//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_000f: Unknown result type (might be due to invalid IL or missing references)
			if (((Graphic)text).color != color)
			{
				((Graphic)text).color = color;
			}
			return text;
		}

		public static TextMeshProUGUI SetFont(this TextMeshProUGUI text, TMP_FontAsset font)
		{
			if ((Object)(object)((TMP_Text)text).font != (Object)(object)font)
			{
				((TMP_Text)text).font = font;
			}
			return text;
		}
	}
	public static class UIFonts
	{
		public static readonly Dictionary<string, Font> FontCache = new Dictionary<string, Font>();

		public static readonly string ValheimNorse = "Valheim-Norse";

		public static readonly string ValheimNorsebold = "Valheim-Norsebold";

		public static readonly string FallbackNotoSansNormal = "Fallback-NotoSansNormal";

		public static readonly Dictionary<string, TMP_FontAsset> FontAssetCache = new Dictionary<string, TMP_FontAsset>();

		public static Font GetFont(string fontName)
		{
			if (!FontCache.TryGetValue(fontName, out var value))
			{
				value = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstByNameOrThrow<Font>(fontName);
				FontCache[fontName] = value;
			}
			return value;
		}

		public static TMP_FontAsset GetFontAsset(string fontName)
		{
			if (!FontAssetCache.TryGetValue(fontName, out var value))
			{
				value = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstByNameOrDefault<TMP_FontAsset>(fontName);
				if (!Object.op_Implicit((Object)(object)value))
				{
					value = TMP_FontAsset.CreateFontAsset(GetFont(fontName));
					((Object)value).name = fontName;
				}
				FontAssetCache[fontName] = value;
			}
			return value;
		}
	}
}