Decompiled source of DadsPermadeath v1.0.0

DadsPermadeath.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.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DadsPermadeath")]
[assembly: AssemblyDescription("Delete the active Valheim character and locally hosted world on death")]
[assembly: AssemblyCompany("Dad_Is_Bored")]
[assembly: AssemblyProduct("DadsPermadeath")]
[assembly: AssemblyCopyright("Copyright 2026 Dad_Is_Bored")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DadsPermadeath
{
	[BepInPlugin("com.dadisbored.dadspermadeath", "DadsPermadeath", "1.0.0")]
	public sealed class DadsPermadeathPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.dadisbored.dadspermadeath";

		public const string PluginName = "DadsPermadeath";

		public const string PluginVersion = "1.0.0";

		internal static DadsPermadeathPlugin Instance;

		internal static ConfigEntry<bool> ModEnabled;

		internal static ManualLogSource Log;

		private Harmony? _harmony;

		private void Awake()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "Mod Enabled", true, "Enable DadsPermadeath.");
			_harmony = new Harmony("com.dadisbored.dadspermadeath");
			_harmony.PatchAll(typeof(DadsPermadeathPlugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsPermadeath 1.0.0 loaded for Valheim 1.0.12.");
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDeath")]
	internal static class PlayerDeathPatch
	{
		private static void Prefix(Player __instance)
		{
			PermadeathController.HandleDeath(__instance);
		}
	}
	[HarmonyPatch(typeof(Game), "RequestRespawn")]
	internal static class RespawnPatch
	{
		private static bool Prefix()
		{
			return !PermadeathController.Triggered;
		}
	}
	[HarmonyPatch(typeof(PlayerProfile), "Save")]
	internal static class PlayerProfileSavePatch
	{
		private static bool Prefix()
		{
			return !PermadeathController.Triggered;
		}
	}
	[HarmonyPatch(typeof(Game), "SavePlayerProfile")]
	internal static class GameSavePlayerProfilePatch
	{
		private static bool Prefix()
		{
			return !PermadeathController.Triggered;
		}
	}
	[HarmonyPatch(typeof(ZNet), "Save")]
	internal static class ZNetSavePatch
	{
		private static bool Prefix()
		{
			return !PermadeathController.Triggered;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "Awake")]
	internal static class MainMenuPatch
	{
		private static void Postfix()
		{
			PermadeathController.Reset();
		}
	}
	[HarmonyPatch(typeof(ServerOptionsGUI), "Awake")]
	internal static class ServerOptionsAwakePatch
	{
		private static void Postfix(ServerOptionsGUI __instance)
		{
			PermadeathWorldModifier.CreateButton(__instance);
		}
	}
	[HarmonyPatch(typeof(ServerOptionsGUI), "ReadKeys")]
	internal static class ServerOptionsReadKeysPatch
	{
		private static void Postfix(ServerOptionsGUI __instance, World world)
		{
			PermadeathWorldModifier.ReadWorld(__instance, world);
		}
	}
	[HarmonyPatch(typeof(ServerOptionsGUI), "SetKeys")]
	internal static class ServerOptionsSetKeysPatch
	{
		private static void Postfix(World world)
		{
			PermadeathWorldModifier.WriteWorld(world);
		}
	}
	[HarmonyPatch(typeof(ServerOptionsGUI), "GetWorldModifierSummary")]
	internal static class WorldModifierSummaryPatch
	{
		private static void Prefix(ref IEnumerable<string> __0, out bool __state)
		{
			__state = PermadeathWorldModifier.RemovePermadeathKeyForSummary(ref __0);
		}

		private static void Postfix(bool __1, string __2, bool __state, ref string __result)
		{
			PermadeathWorldModifier.AddPermadeathToSummary(__1, __2, __state, ref __result);
		}
	}
	internal static class PermadeathController
	{
		private static readonly MethodInfo? ShutdownMethod = AccessTools.Method(typeof(Game), "Shutdown", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly MethodInfo? ContinueLogoutMethod = AccessTools.Method(typeof(Game), "ContinueLogout", new Type[3]
		{
			typeof(bool),
			typeof(bool),
			typeof(bool)
		}, (Type[])null);

		internal static bool Triggered { get; private set; }

		internal static void HandleDeath(Player player)
		{
			if (!DadsPermadeathPlugin.ModEnabled.Value || !PermadeathWorldModifier.IsActiveInCurrentWorld() || Triggered || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			Game instance = Game.instance;
			ZNet instance2 = ZNet.instance;
			PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null);
			World worldIfIsHost = ZNet.GetWorldIfIsHost();
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null || val == null)
			{
				DadsPermadeathPlugin.Log.LogError((object)"Permadeath could not identify the active game, network session, or character.");
				return;
			}
			Triggered = true;
			string filename = val.GetFilename();
			if (string.IsNullOrWhiteSpace(filename))
			{
				Triggered = false;
				DadsPermadeathPlugin.Log.LogError((object)"Permadeath could not identify the active character save filename.");
			}
			else
			{
				string worldFilename = worldIfIsHost?.m_name;
				((MonoBehaviour)DadsPermadeathPlugin.Instance).StartCoroutine(DeleteSavesAndExit(instance, instance2, filename, worldFilename));
			}
		}

		internal static void Reset()
		{
			Triggered = false;
		}

		private static IEnumerator DeleteSavesAndExit(Game game, ZNet znet, string characterFilename, string? worldFilename)
		{
			yield return null;
			while ((Object)(object)znet != (Object)null && znet.IsSaving())
			{
				yield return null;
			}
			if (ShutdownMethod == null || ContinueLogoutMethod == null)
			{
				DadsPermadeathPlugin.Log.LogError((object)"Permadeath could not locate Valheim's no-save shutdown methods; saves were not removed.");
				Triggered = false;
				yield break;
			}
			try
			{
				ShutdownMethod.Invoke(game, new object[1] { false });
				int num = DeleteSaveSet(characterFilename, (SaveDataType)1);
				int num2 = ((!string.IsNullOrWhiteSpace(worldFilename)) ? DeleteSaveSet(worldFilename, (SaveDataType)0) : 0);
				SaveSystem.ClearWorldListCache(true);
				DadsPermadeathPlugin.Log.LogInfo((object)$"Permadeath removed {num} character save file(s) and {num2} world save file(s).");
				if (worldFilename == null)
				{
					DadsPermadeathPlugin.Log.LogInfo((object)"The active world is hosted remotely; only its host can remove that world save.");
				}
				ContinueLogoutMethod.Invoke(game, new object[3] { false, true, true });
			}
			catch (Exception arg)
			{
				DadsPermadeathPlugin.Log.LogError((object)$"Permadeath save removal stopped: {arg}");
				Triggered = false;
			}
		}

		private static int DeleteSaveSet(string saveName, SaveDataType dataType)
		{
			//IL_0009: 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)
			SaveWithBackups val = default(SaveWithBackups);
			if (string.IsNullOrWhiteSpace(saveName) || !SaveSystem.TryGetSaveByName(saveName, dataType, ref val) || val == null)
			{
				return 0;
			}
			int num = 0;
			SaveFile[] array = val.AllFiles.ToArray();
			foreach (SaveFile val2 in array)
			{
				if (SaveSystem.Delete(val2))
				{
					num++;
				}
				else
				{
					DadsPermadeathPlugin.Log.LogError((object)$"Permadeath could not remove save file '{val2.Name}' from source '{val2.m_source}'.");
				}
			}
			return num;
		}
	}
	internal static class PermadeathWorldModifier
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__ShowConfirmation;

			public static PopupButtonCallback <1>__ConfirmSelection;

			public static PopupButtonCallback <2>__RejectSelection;
		}

		internal const string GlobalKey = "dadspermadeath";

		private const string ButtonText = "DadsPermadeath";

		private const string TipText = "This mode with test your ability to stay alive. If you die, your world and character will be deleted and you will be sent back to the main menu.";

		private const string PopupText = "You have selected Permadeath, if you die, your selected world and character will be deleted. Are you sure you want to proceed?";

		private static ServerOptionsGUI? _gui;

		private static World? _world;

		private static Button? _button;

		private static KeyButton? _keyButton;

		private static TMP_Text? _buttonLabel;

		private static ColorBlock _normalColors;

		private static bool _selected;

		internal static void CreateButton(ServerOptionsGUI gui)
		{
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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)
			//IL_01b3: Expected O, but got Unknown
			if (!DadsPermadeathPlugin.ModEnabled.Value || (Object)(object)_button != (Object)null)
			{
				return;
			}
			KeyButton? obj = (from button in gui.m_presetsRoot.GetComponentsInChildren<KeyButton>(true)
				where (int)button.m_preset != 0 && (int)button.m_preset != 2 && (int)button.m_preset != 1
				orderby ((Component)button).transform.GetSiblingIndex()
				select button).LastOrDefault();
			Button val = ((obj != null) ? ((Component)obj).GetComponentInParent<Button>() : null);
			if ((Object)(object)obj == (Object)null || (Object)(object)val == (Object)null)
			{
				DadsPermadeathPlugin.Log.LogError((object)"DadsPermadeath could not locate a world preset button template.");
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent, false);
			((Object)val2).name = "DadsPermadeathPreset";
			val2.transform.SetAsLastSibling();
			_gui = gui;
			_button = val2.GetComponent<Button>();
			_keyButton = val2.GetComponentInChildren<KeyButton>(true);
			_buttonLabel = val2.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)_button == (Object)null || (Object)(object)_keyButton == (Object)null || (Object)(object)_buttonLabel == (Object)null)
			{
				DadsPermadeathPlugin.Log.LogError((object)"DadsPermadeath could not initialize its world modifier button.");
				val2.SetActive(false);
				return;
			}
			_buttonLabel.text = "DadsPermadeath";
			_keyButton.m_toolTip = "This mode with test your ability to stay alive. If you die, your world and character will be deleted and you will be sent back to the main menu.";
			_keyButton.m_toolTipLabel = gui.m_toolTipText;
			_keyButton.m_preset = (WorldPresets)1;
			_keyButton.m_keys.Clear();
			_button.onClick = new ButtonClickedEvent();
			ButtonClickedEvent onClick = _button.onClick;
			object obj2 = <>O.<0>__ShowConfirmation;
			if (obj2 == null)
			{
				UnityAction val3 = ShowConfirmation;
				<>O.<0>__ShowConfirmation = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			_normalColors = ((Selectable)_button).colors;
			IntegratePresetRows(gui, val2.GetComponent<RectTransform>(), val);
			UpdateButtonVisual();
		}

		internal static void ReadWorld(ServerOptionsGUI gui, World world)
		{
			_gui = gui;
			_world = world;
			_selected = ContainsKey(world.m_startingGlobalKeys);
			UpdateButtonVisual();
		}

		internal static void WriteWorld(World world)
		{
			RemoveKey(world.m_startingGlobalKeys);
			if (_selected)
			{
				world.m_startingGlobalKeys.Add("dadspermadeath");
			}
			world.m_startingKeysChanged = true;
		}

		internal static bool IsActiveInCurrentWorld()
		{
			ZoneSystem instance = ZoneSystem.instance;
			if ((Object)(object)instance != (Object)null && instance.GetGlobalKey("dadspermadeath"))
			{
				return true;
			}
			ZNet instance2 = ZNet.instance;
			World val = ((instance2 != null) ? instance2.GetWorld() : null);
			if (val != null)
			{
				return ContainsKey(val.m_startingGlobalKeys);
			}
			return false;
		}

		internal static bool RemovePermadeathKeyForSummary(ref IEnumerable<string> keys)
		{
			List<string> list = keys.ToList();
			bool num = ContainsKey(list);
			if (num)
			{
				RemoveKey(list);
				keys = list;
			}
			return num;
		}

		internal static void AddPermadeathToSummary(bool compact, string separator, bool containedPermadeath, ref string summary)
		{
			if (containedPermadeath)
			{
				if (string.IsNullOrEmpty(summary))
				{
					summary = "Permadeath";
				}
				else if (compact)
				{
					summary = "Permadeath+";
				}
				else
				{
					summary = "Permadeath" + separator + summary;
				}
			}
		}

		private static void ShowConfirmation()
		{
			//IL_0059: 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_0064: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if ((Object)(object)_gui == (Object)null || _world == null || !UnifiedPopup.IsAvailable())
			{
				DadsPermadeathPlugin.Log.LogError((object)"DadsPermadeath could not open its confirmation popup.");
				return;
			}
			_gui.m_toolTipText.text = "This mode with test your ability to stay alive. If you die, your world and character will be deleted and you will be sent back to the main menu.";
			object obj = <>O.<1>__ConfirmSelection;
			if (obj == null)
			{
				PopupButtonCallback val = ConfirmSelection;
				<>O.<1>__ConfirmSelection = val;
				obj = (object)val;
			}
			object obj2 = <>O.<2>__RejectSelection;
			if (obj2 == null)
			{
				PopupButtonCallback val2 = RejectSelection;
				<>O.<2>__RejectSelection = val2;
				obj2 = (object)val2;
			}
			UnifiedPopup.Push((PopupBase)new YesNoPopup("DadsPermadeath", "You have selected Permadeath, if you die, your selected world and character will be deleted. Are you sure you want to proceed?", (PopupButtonCallback)obj, (PopupButtonCallback)obj2, false, true));
		}

		private static void ConfirmSelection()
		{
			UnifiedPopup.Pop();
			if (!((Object)(object)_gui == (Object)null) && _world != null)
			{
				_selected = true;
				_gui.m_toolTipText.text = "This mode with test your ability to stay alive. If you die, your world and character will be deleted and you will be sent back to the main menu.";
				UpdateButtonVisual();
			}
		}

		private static void RejectSelection()
		{
			UnifiedPopup.Pop();
			_selected = false;
			if ((Object)(object)_gui != (Object)null && _world != null)
			{
				_gui.SetPreset(_world, (WorldPresets)2);
				SetNormalTooltip(_gui);
			}
			UpdateButtonVisual();
		}

		private static void UpdateButtonVisual()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0031: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_button == (Object)null))
			{
				ColorBlock normalColors = _normalColors;
				if (_selected)
				{
					((ColorBlock)(ref normalColors)).normalColor = new Color(0.55f, 0.14f, 0.14f, 1f);
					((ColorBlock)(ref normalColors)).highlightedColor = new Color(0.68f, 0.2f, 0.2f, 1f);
					((ColorBlock)(ref normalColors)).selectedColor = ((ColorBlock)(ref normalColors)).highlightedColor;
				}
				((Selectable)_button).colors = normalColors;
			}
		}

		private static void SetNormalTooltip(ServerOptionsGUI gui)
		{
			KeyButton val = ((IEnumerable<KeyButton>)gui.m_presetsRoot.GetComponentsInChildren<KeyButton>(true)).FirstOrDefault((Func<KeyButton, bool>)((KeyButton button) => (Object)(object)button != (Object)(object)_keyButton && (int)button.m_preset == 2));
			gui.m_toolTipText.text = (((Object)(object)val == (Object)null) ? string.Empty : Localization.instance.Localize(val.m_toolTip));
		}

		private static void IntegratePresetRows(ServerOptionsGUI gui, RectTransform customRect, Button templateButton)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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_01a1: 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)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			KeyButton? obj = ((IEnumerable<KeyButton>)gui.m_presetsRoot.GetComponentsInChildren<KeyButton>(true)).FirstOrDefault((Func<KeyButton, bool>)((KeyButton button) => (Object)(object)button != (Object)(object)_keyButton && ((int)button.m_preset == 0 || (int)button.m_preset == 2)));
			Button val = ((obj != null) ? ((Component)obj).GetComponentInParent<Button>() : null);
			RectTransform[] array = (from val5 in (from val5 in (from button in gui.m_presetsRoot.GetComponentsInChildren<KeyButton>(true)
						where (Object)(object)button != (Object)(object)_keyButton && (int)button.m_preset != 0 && (int)button.m_preset != 2 && (int)button.m_preset != 1
						select button).Select(delegate(KeyButton button)
					{
						Button componentInParent = ((Component)button).GetComponentInParent<Button>();
						return (componentInParent == null) ? null : ((Component)componentInParent).GetComponent<RectTransform>();
					})
					where (Object)(object)val5 != (Object)null
					select val5).Cast<RectTransform>().Distinct()
				orderby ((Transform)val5).GetSiblingIndex()
				select val5).ToArray();
			if ((Object)(object)val != (Object)null && array.Length >= 4)
			{
				Canvas.ForceUpdateCanvases();
				RectTransform component = ((Component)val).GetComponent<RectTransform>();
				Rect rect = ((Component)templateButton).GetComponent<RectTransform>().rect;
				float width = ((Rect)(ref rect)).width;
				rect = ((Component)templateButton).GetComponent<RectTransform>().rect;
				float height = ((Rect)(ref rect)).height;
				RectTransform[] array2 = (from val5 in array.OrderBy((RectTransform val5) => ((Transform)val5).position.x).Take(2)
					orderby ((Transform)val5).position.y descending
					select val5).ToArray();
				if (array2.Length == 2)
				{
					RectTransform val2 = array2[0];
					RectTransform val3 = array2[1];
					float num = val3.anchoredPosition.y - val2.anchoredPosition.y;
					float num2 = Mathf.Abs(num);
					if (num2 <= 0f)
					{
						num2 = GetPresetRowHeight(array);
						num = 0f - num2;
					}
					Transform obj2 = ((Component)gui).transform.Find("panel");
					RectTransform val4 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
					if ((Object)(object)val4 == (Object)null)
					{
						val4 = ((Component)gui).GetComponent<RectTransform>();
					}
					Vector2 permadeathPosition = default(Vector2);
					((Vector2)(ref permadeathPosition))..ctor(val3.anchoredPosition.x, val3.anchoredPosition.y + num);
					Vector2 resetPosition = default(Vector2);
					((Vector2)(ref resetPosition))..ctor(component.anchoredPosition.x, component.anchoredPosition.y + num);
					((Transform)customRect).SetParent(((Transform)component).parent, false);
					((Transform)customRect).SetSiblingIndex(((Transform)component).GetSiblingIndex());
					customRect.anchorMin = val3.anchorMin;
					customRect.anchorMax = val3.anchorMax;
					customRect.pivot = val3.pivot;
					customRect.SetSizeWithCurrentAnchors((Axis)0, width);
					customRect.SetSizeWithCurrentAnchors((Axis)1, height);
					(((Component)gui).gameObject.GetComponent<PermadeathLayoutController>() ?? ((Component)gui).gameObject.AddComponent<PermadeathLayoutController>()).Configure(val4, customRect, component, permadeathPosition, resetPosition, num2, width, height);
					DadsPermadeathPlugin.Log.LogInfo((object)("Four-row preset layout applied using reset button '" + ((Object)val).name + "'."));
				}
			}
			else
			{
				DadsPermadeathPlugin.Log.LogError((object)"DadsPermadeath could not locate Valheim's Default/Normal reset preset; four-row layout was not applied.");
			}
		}

		private static float GetPresetRowHeight(IReadOnlyList<RectTransform> presetRects)
		{
			//IL_001d: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			float num = float.MaxValue;
			float num2 = 0f;
			for (int i = 0; i < presetRects.Count; i++)
			{
				for (int j = i + 1; j < presetRects.Count; j++)
				{
					Vector3 val = ((Transform)presetRects[j]).position - ((Transform)presetRects[i]).position;
					float num3 = Mathf.Abs(val.y);
					if (!(num3 < 1f))
					{
						float num4 = Mathf.Abs(val.x);
						if (num4 < num || (Mathf.Approximately(num4, num) && (num2 <= 0f || num3 < num2)))
						{
							num = num4;
							num2 = num3;
						}
					}
				}
			}
			return num2;
		}

		private static bool ContainsKey(IEnumerable<string> keys)
		{
			return keys.Any((string key) => string.Equals(key, "dadspermadeath", StringComparison.OrdinalIgnoreCase));
		}

		private static void RemoveKey(List<string> keys)
		{
			keys.RemoveAll((string key) => string.Equals(key, "dadspermadeath", StringComparison.OrdinalIgnoreCase));
		}
	}
	internal sealed class PermadeathLayoutController : MonoBehaviour
	{
		private RectTransform? _panel;

		private RectTransform? _permadeath;

		private RectTransform? _reset;

		private Vector2 _permadeathPosition;

		private Vector2 _resetPosition;

		private Vector2 _panelPosition;

		private float _panelHeight;

		private float _rowHeight;

		private float _buttonWidth;

		private float _buttonHeight;

		internal void Configure(RectTransform? panel, RectTransform permadeath, RectTransform reset, Vector2 permadeathPosition, Vector2 resetPosition, float rowHeight, float buttonWidth, float buttonHeight)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0020: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			_panel = panel;
			_permadeath = permadeath;
			_reset = reset;
			_permadeathPosition = permadeathPosition;
			_resetPosition = resetPosition;
			float panelHeight;
			if (!((Object)(object)panel == (Object)null))
			{
				Rect rect = panel.rect;
				panelHeight = ((Rect)(ref rect)).height;
			}
			else
			{
				panelHeight = 0f;
			}
			_panelHeight = panelHeight;
			_panelPosition = (((Object)(object)panel == (Object)null) ? Vector2.zero : panel.anchoredPosition);
			_rowHeight = rowHeight;
			_buttonWidth = buttonWidth;
			_buttonHeight = buttonHeight;
			ApplyLayout();
		}

		private void LateUpdate()
		{
			ApplyLayout();
		}

		private void ApplyLayout()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_permadeath == (Object)null) && !((Object)(object)_reset == (Object)null) && !(_rowHeight <= 0f))
			{
				if ((Object)(object)_panel != (Object)null)
				{
					_panel.SetSizeWithCurrentAnchors((Axis)1, _panelHeight + _rowHeight);
					_panel.anchoredPosition = _panelPosition + Vector2.down * (_rowHeight * (1f - _panel.pivot.y));
				}
				_permadeath.anchoredPosition = _permadeathPosition;
				_permadeath.SetSizeWithCurrentAnchors((Axis)0, _buttonWidth);
				_permadeath.SetSizeWithCurrentAnchors((Axis)1, _buttonHeight);
				_reset.anchoredPosition = _resetPosition;
			}
		}
	}
}