Decompiled source of MistVale v0.6.4

plugins/MistVale.dll

Decompiled 11 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DezzyCode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("DezzyCode")]
[assembly: AssemblyDescription("Companion mod for MistVale, a German Valheim server. Made for this one server only.")]
[assembly: AssemblyFileVersion("0.6.4.0")]
[assembly: AssemblyInformationalVersion("0.6.4+a45091877b7a6836f86c0630b66f7efaea587bb4")]
[assembly: AssemblyProduct("MistVale")]
[assembly: AssemblyTitle("MistVale")]
[assembly: AssemblyVersion("0.6.4.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MistVale
{
	internal static class Images
	{
		private static Sprite _loadingScreen;

		private static Sprite _logo;

		private static bool _loadingScreenTried;

		private static bool _logoTried;

		public static Sprite LoadingScreen => Load("loadingscreen.png", required: true, ref _loadingScreen, ref _loadingScreenTried);

		public static Sprite Logo => Load("logo.png", required: false, ref _logo, ref _logoTried);

		private static Sprite Load(string fileName, bool required, ref Sprite sprite, ref bool tried)
		{
			if (tried)
			{
				return sprite;
			}
			tried = true;
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location), fileName);
			if (!File.Exists(text))
			{
				if (required)
				{
					Plugin.Log.LogWarning((object)(fileName + " not found next to the DLL; keeping the vanilla image."));
				}
				return null;
			}
			sprite = AssetUtils.LoadSpriteFromFile(text);
			if ((Object)(object)sprite == (Object)null)
			{
				Plugin.Log.LogWarning((object)(fileName + " could not be read as an image."));
			}
			return sprite;
		}
	}
	[HarmonyPatch(typeof(Hud))]
	internal static class LoadingScreen
	{
		private const string TipText = "by DezzyCode";

		private static Image[] _vanillaLogos;

		private static Hud _setUpFor;

		private static ConfigEntry<float> _logoScale;

		private static ConfigEntry<float> _logoTopMargin;

		private static readonly Dictionary<RectTransform, Vector2> OriginalPositions = new Dictionary<RectTransform, Vector2>();

		public static void BindConfig(ConfigFile config)
		{
			_logoScale = config.Bind<float>("Loading screen", "Logo scale", 1.5f, "Size of the logo relative to the vanilla Valheim logo.");
			_logoTopMargin = config.Bind<float>("Loading screen", "Logo top margin", 40f, "How far the top edge of the logo sits below the vanilla one, in UI units.");
			if (Mathf.Approximately(_logoScale.Value, 1.35f))
			{
				_logoScale.Value = 1.5f;
			}
			if (Mathf.Approximately(_logoTopMargin.Value, 25f))
			{
				_logoTopMargin.Value = 40f;
			}
		}

		private static void SetUp(Hud hud)
		{
			_setUpFor = hud;
			Image[] componentsInChildren = ((Component)hud.m_loadingScreen).GetComponentsInChildren<Image>(true);
			Image[] array = componentsInChildren;
			foreach (Image val in array)
			{
				Plugin.Log.LogInfo((object)("Loading screen image: " + ((Object)val).name + " (sprite " + (((Object)(object)val.sprite != (Object)null) ? ((Object)val.sprite).name : "none") + ")"));
			}
			_vanillaLogos = componentsInChildren.Where((Image val2) => (Object)(object)val2 != (Object)(object)hud.m_loadingImage && IsLogo(val2)).ToArray();
			if (_vanillaLogos.Length == 0)
			{
				Plugin.Log.LogWarning((object)"No Valheim logo found in the loading screen.");
			}
		}

		private static bool IsLogo(Image image)
		{
			if (!((Object)image).name.ToLowerInvariant().Contains("logo"))
			{
				if ((Object)(object)image.sprite != (Object)null)
				{
					return ((Object)image.sprite).name.ToLowerInvariant().Contains("logo");
				}
				return false;
			}
			return true;
		}

		private static void Apply(Hud hud)
		{
			if ((Object)(object)hud.m_loadingScreen == (Object)null || (Object)(object)hud.m_loadingImage == (Object)null)
			{
				return;
			}
			if ((Object)(object)_setUpFor != (Object)(object)hud)
			{
				SetUp(hud);
			}
			Sprite loadingScreen = Images.LoadingScreen;
			Sprite logo = Images.Logo;
			if ((Object)(object)loadingScreen != (Object)null && (Object)(object)hud.m_loadingImage.sprite != (Object)(object)loadingScreen)
			{
				hud.m_loadingImage.sprite = loadingScreen;
			}
			Image[] vanillaLogos = _vanillaLogos;
			foreach (Image val in vanillaLogos)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if ((Object)(object)logo == (Object)null)
				{
					if (((Behaviour)val).enabled)
					{
						((Behaviour)val).enabled = false;
					}
					continue;
				}
				if ((Object)(object)val.sprite != (Object)(object)logo)
				{
					val.sprite = logo;
					val.preserveAspect = true;
				}
				PlaceLogo(((Graphic)val).rectTransform);
			}
			if ((Object)(object)hud.m_loadingTip != (Object)null && hud.m_loadingTip.text != "by DezzyCode")
			{
				hud.m_loadingTip.text = "by DezzyCode";
			}
		}

		private static void PlaceLogo(RectTransform rect)
		{
			//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_003d: 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_007a: 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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (!OriginalPositions.TryGetValue(rect, out var value))
			{
				value = rect.anchoredPosition;
				OriginalPositions[rect] = value;
			}
			float value2 = _logoScale.Value;
			Rect rect2 = rect.rect;
			float height = ((Rect)(ref rect2)).height;
			float num = value.y + (1f - rect.pivot.y) * height * (1f - value2) - _logoTopMargin.Value;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(value2, value2, 1f);
			if (((Transform)rect).localScale != val)
			{
				((Transform)rect).localScale = val;
			}
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(value.x, num);
			if (rect.anchoredPosition != val2)
			{
				rect.anchoredPosition = val2;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix(Hud __instance)
		{
			Apply(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdateBlackScreen")]
		private static void UpdateBlackScreenPostfix(Hud __instance)
		{
			Apply(__instance);
		}
	}
	internal static class MinimapLogo
	{
		[HarmonyPatch(typeof(Minimap), "Start")]
		private static class MinimapStartPatch
		{
			private static void Postfix(Minimap __instance)
			{
				Build(__instance);
			}
		}

		private const float Width = 180f;

		private const float Gap = 6f;

		private const float ScanInterval = 1f;

		private static ConfigEntry<bool> _enabled;

		private static Minimap _map;

		private static GameObject _logo;

		private static float _nextScan;

		private static readonly HashSet<Graphic> Hidden = new HashSet<Graphic>();

		private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4];

		public static void BindConfig(ConfigFile config)
		{
			//IL_001a: 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_0027: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			_enabled = config.Bind<bool>("Minimap", "Logo", true, new ConfigDescription("Shows the MistVale logo below the minimap and hides whatever else is shown there. Set on the server.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
			_enabled.SettingChanged += delegate
			{
				Refresh();
			};
		}

		private static void Build(Minimap map)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			if ((Object)(object)map == (Object)null || (Object)(object)map.m_smallRoot == (Object)null)
			{
				return;
			}
			if ((Object)(object)_logo != (Object)null)
			{
				Object.Destroy((Object)(object)_logo);
			}
			_logo = null;
			_map = map;
			Hidden.Clear();
			Sprite logo = Images.Logo;
			if (!((Object)(object)logo == (Object)null))
			{
				Rect rect = logo.rect;
				if (!(((Rect)(ref rect)).width <= 0f))
				{
					GameObject val = new GameObject("MistVale_MinimapLogo", new Type[3]
					{
						typeof(RectTransform),
						typeof(CanvasRenderer),
						typeof(Image)
					});
					val.transform.SetParent(map.m_smallRoot.transform, false);
					RectTransform val2 = (RectTransform)val.transform;
					Vector2 val3 = default(Vector2);
					((Vector2)(ref val3))..ctor(0.5f, 0f);
					val2.anchorMax = val3;
					val2.anchorMin = val3;
					val2.pivot = new Vector2(0.5f, 1f);
					val2.anchoredPosition = new Vector2(0f, -6f);
					rect = logo.rect;
					float num = 180f * ((Rect)(ref rect)).height;
					rect = logo.rect;
					val2.sizeDelta = new Vector2(180f, num / ((Rect)(ref rect)).width);
					Image component = val.GetComponent<Image>();
					component.sprite = logo;
					component.preserveAspect = true;
					((Graphic)component).raycastTarget = false;
					_logo = val;
					Refresh();
				}
			}
		}

		private static void Refresh()
		{
			if ((Object)(object)_logo == (Object)null)
			{
				return;
			}
			_logo.SetActive(_enabled.Value);
			if (!_enabled.Value)
			{
				foreach (Graphic item in Hidden)
				{
					if ((Object)(object)item != (Object)null)
					{
						((Behaviour)item).enabled = true;
					}
				}
				Hidden.Clear();
			}
			_nextScan = 0f;
		}

		public static void Update()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_logo == (Object)null || (Object)(object)_map == (Object)null || !_logo.activeInHierarchy || Time.unscaledTime < _nextScan)
			{
				return;
			}
			_nextScan = Time.unscaledTime + 1f;
			if (Menu.IsVisible() || InventoryGui.IsVisible() || StoreGui.IsVisible() || TextInput.IsVisible() || Minimap.IsOpen())
			{
				return;
			}
			Canvas componentInParent = _logo.GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return;
			}
			((RectTransform)_map.m_smallRoot.transform).GetWorldCorners(Corners);
			float y = Corners[0].y;
			((RectTransform)_logo.transform).GetWorldCorners(Corners);
			Rect val = Rect.MinMaxRect(Corners[0].x, Corners[0].y, Corners[2].x, Corners[2].y);
			Graphic[] componentsInChildren = ((Component)componentInParent.rootCanvas).GetComponentsInChildren<Graphic>(false);
			foreach (Graphic val2 in componentsInChildren)
			{
				if (!((Behaviour)val2).enabled || ((Component)val2).transform.IsChildOf(_logo.transform) || IsCustomGui(val2))
				{
					continue;
				}
				val2.rectTransform.GetWorldCorners(Corners);
				Rect val3 = Rect.MinMaxRect(Corners[0].x, Corners[0].y, Corners[2].x, Corners[2].y);
				if (!(((Rect)(ref val3)).yMax > y + 1f) && ((Rect)(ref val3)).Overlaps(val))
				{
					((Behaviour)val2).enabled = false;
					if (Hidden.Add(val2))
					{
						Plugin.Log.LogInfo((object)("Hid '" + Path(((Component)val2).transform) + "' below the minimap."));
					}
				}
			}
		}

		private static bool IsCustomGui(Graphic graphic)
		{
			if (!((Object)(object)GUIManager.CustomGUIFront != (Object)null) || !((Component)graphic).transform.IsChildOf(GUIManager.CustomGUIFront.transform))
			{
				if ((Object)(object)GUIManager.CustomGUIBack != (Object)null)
				{
					return ((Component)graphic).transform.IsChildOf(GUIManager.CustomGUIBack.transform);
				}
				return false;
			}
			return true;
		}

		private static string Path(Transform t)
		{
			string text = ((Object)t).name;
			Transform parent = t.parent;
			while ((Object)(object)parent != (Object)null && (Object)(object)((Component)parent).GetComponent<Canvas>() == (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}
	}
	[BepInPlugin("dezzycode.valheim.mistvale", "MistVale", "0.6.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "dezzycode.valheim.mistvale";

		public const string Name = "MistVale";

		public const string Version = "0.6.4";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			LoadingScreen.BindConfig(((BaseUnityPlugin)this).Config);
			SpawnPoint.BindConfig(((BaseUnityPlugin)this).Config);
			Rules.BindConfig(((BaseUnityPlugin)this).Config);
			MinimapLogo.BindConfig(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("dezzycode.valheim.mistvale");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"MistVale 0.6.4 loaded.");
		}

		private void Update()
		{
			Rules.Update();
			MinimapLogo.Update();
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class Rules
	{
		[HarmonyPatch(typeof(Game), "Start")]
		private static class RegisterRpcs
		{
			private static void Postfix()
			{
				ZRoutedRpc.instance.Register<ZPackage>("MistVale_RulesRequest", (Action<long, ZPackage>)RPC_Request);
				ZRoutedRpc.instance.Register<ZPackage>("MistVale_Rules", (Action<long, ZPackage>)RPC_Rules);
				ZRoutedRpc.instance.Register<string>("MistVale_RulesAccept", (Action<long, string>)RPC_Accept);
			}
		}

		public const int RuleCount = 5;

		private const string RpcRequest = "MistVale_RulesRequest";

		private const string RpcRules = "MistVale_Rules";

		private const string RpcAccept = "MistVale_RulesAccept";

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<string> _title;

		private static ConfigEntry<string> _welcome;

		private static readonly ConfigEntry<string>[] _rules = new ConfigEntry<string>[5];

		private static readonly string[] DefaultRules = new string[5] { "Respekt: Keine Beleidigungen, Hetze oder Belästigung – weder im Chat noch im Voice.", "Kein Griefing oder Diebstahl: Fremde Bauten, Kisten, Tiere und Portale sind tabu.", "Kein Cheaten: Keine Hacks, Exploits, Item-Duplizierung oder nicht erlaubten Mods.", "Baue mit Rücksicht: Halte Abstand zu fremden Basen und lass Wege, Portale und den Spawn frei.", "Die Admins haben das letzte Wort. Probleme meldest du ihnen, statt sie selbst zu regeln." };

		private static Dictionary<string, string> _accepted;

		private static bool _requested;

		private static string AcceptedFile => Path.Combine(Paths.ConfigPath, "MistVale.accepted_rules.txt");

		public static void BindConfig(ConfigFile config)
		{
			_enabled = config.Bind<bool>("Rules", "Enabled", true, "Players have to accept the rules below before they can play. Set on the server.");
			_title = config.Bind<string>("Rules", "Title", "Willkommen auf MistVale!", "Heading of the rules window.");
			_welcome = config.Bind<string>("Rules", "Welcome", "Schön, dass du da bist, Wikinger! Bevor dein Abenteuer beginnt, lies bitte unsere Regeln und bestätige jede einzelne.", "Text above the rules. \\n starts a new line.");
			for (int i = 0; i < 5; i++)
			{
				_rules[i] = config.Bind<string>("Rules", $"Rule {i + 1}", DefaultRules[i], "Changing any rule makes every player accept the rules again.");
			}
		}

		public static void Update()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				_requested = false;
				RulesWindow.Close();
			}
			else if (!_requested && !ZNet.instance.IsServer() && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Character)Player.m_localPlayer).InIntro())
			{
				ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
				if (serverPeer != null && ZRoutedRpc.instance != null)
				{
					_requested = true;
					ZRoutedRpc.instance.InvokeRoutedRPC(serverPeer.m_uid, "MistVale_RulesRequest", new object[1] { (object)new ZPackage() });
				}
			}
		}

		private static void RPC_Rules(long sender, ZPackage pkg)
		{
			if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer() || pkg.ReadBool())
			{
				return;
			}
			string version = pkg.ReadString();
			string title = pkg.ReadString();
			string welcome = pkg.ReadString();
			string[] array = new string[pkg.ReadInt()];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = pkg.ReadString();
			}
			RulesWindow.Show(title, welcome, array, delegate
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "MistVale_RulesAccept", new object[1] { version });
			}, delegate
			{
				Game instance = Game.instance;
				if (instance != null)
				{
					instance.Logout(true, true);
				}
			});
		}

		private static void RPC_Request(long sender, ZPackage _)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			if (!ZNet.instance.IsServer())
			{
				return;
			}
			ZPackage val = new ZPackage();
			string text = AccountOf(sender);
			string text2 = Version();
			if (!_enabled.Value || text == null || IsAccepted(text, text2))
			{
				val.Write(true);
			}
			else
			{
				val.Write(false);
				val.Write(text2);
				val.Write(_title.Value);
				val.Write(_welcome.Value.Replace("\\n", "\n"));
				val.Write(5);
				ConfigEntry<string>[] rules = _rules;
				foreach (ConfigEntry<string> val2 in rules)
				{
					val.Write(val2.Value);
				}
				Plugin.Log.LogInfo((object)("Asking " + text + " to accept the rules."));
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(sender, "MistVale_Rules", new object[1] { val });
		}

		private static void RPC_Accept(long sender, string version)
		{
			if (ZNet.instance.IsServer())
			{
				string text = AccountOf(sender);
				if (text != null && !(version != Version()))
				{
					Load();
					_accepted[text] = version;
					Save();
					ZNetPeer peer = ZNet.instance.GetPeer(sender);
					Plugin.Log.LogInfo((object)((peer?.m_playerName ?? text) + " (" + text + ") accepted the rules."));
				}
			}
		}

		private static string AccountOf(long uid)
		{
			ZNetPeer peer = ZNet.instance.GetPeer(uid);
			if (peer == null)
			{
				return null;
			}
			ISocket socket = peer.m_socket;
			if (socket == null)
			{
				return null;
			}
			return socket.GetHostName();
		}

		private static bool IsAccepted(string account, string version)
		{
			Load();
			if (_accepted.TryGetValue(account, out var value))
			{
				return value == version;
			}
			return false;
		}

		private static string Version()
		{
			string s = _title.Value + "\n" + _welcome.Value + "\n" + string.Join("\n", _rules.Select((ConfigEntry<string> r) => r.Value));
			uint num = 2166136261u;
			byte[] bytes = Encoding.UTF8.GetBytes(s);
			foreach (byte b in bytes)
			{
				num ^= b;
				num *= 16777619;
			}
			return num.ToString("x8");
		}

		private static void Load()
		{
			if (_accepted != null)
			{
				return;
			}
			_accepted = new Dictionary<string, string>();
			if (!File.Exists(AcceptedFile))
			{
				return;
			}
			string[] array = File.ReadAllLines(AcceptedFile);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ' ' });
				if (array2.Length == 2)
				{
					_accepted[array2[0]] = array2[1];
				}
			}
		}

		private static void Save()
		{
			try
			{
				File.WriteAllLines(AcceptedFile, _accepted.Select((KeyValuePair<string, string> kv) => kv.Key + " " + kv.Value).ToArray());
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not save " + AcceptedFile + ": " + ex.Message));
			}
		}
	}
	internal static class RulesWindow
	{
		private const float Width = 760f;

		private const float RuleHeight = 64f;

		private static readonly Color Orange = new Color(1f, 0.631f, 0.235f);

		private static GameObject _panel;

		private static bool _blocking;

		public static void Show(string title, string welcome, string[] rules, Action onAccept, Action onDecline)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_00a4: 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)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_010e: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Expected O, but got Unknown
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			if (GUIManager.IsHeadless() || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				return;
			}
			Close();
			GUIManager instance = GUIManager.Instance;
			float num = 250f + (float)rules.Length * 64f + 90f;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			_panel = instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, val, val, Vector2.zero, 760f, num, false);
			((Object)_panel).name = "MistVale_Rules";
			float num2 = num / 2f;
			instance.CreateText(title, _panel.transform, val, val, new Vector2(0f, num2 - 60f), instance.Norse, 44, Orange, true, Color.black, 700f, 60f, false).GetComponent<Text>().alignment = (TextAnchor)4;
			instance.CreateText(welcome, _panel.transform, val, val, new Vector2(0f, num2 - 145f), instance.AveriaSerifBold, 18, Color.white, true, Color.black, 680f, 90f, false).GetComponent<Text>().alignment = (TextAnchor)4;
			Toggle[] toggles = (Toggle[])(object)new Toggle[rules.Length];
			for (int i = 0; i < rules.Length; i++)
			{
				float num3 = num2 - 230f - (float)i * 64f;
				GameObject obj = instance.CreateToggle(_panel.transform, 28f, 28f);
				RectTransform val2 = (RectTransform)obj.transform;
				Vector2 anchorMin = (val2.anchorMax = val);
				val2.anchorMin = anchorMin;
				val2.anchoredPosition = new Vector2(-320f, num3);
				Toggle component = obj.GetComponent<Toggle>();
				component.isOn = false;
				toggles[i] = component;
				instance.CreateText($"{i + 1}. {rules[i]}", _panel.transform, val, val, new Vector2(30f, num3), instance.AveriaSerifBold, 17, Color.white, true, Color.black, 610f, 58f, false).GetComponent<Text>().alignment = (TextAnchor)3;
			}
			float num4 = 0f - num2 + 55f;
			GameObject val4 = instance.CreateButton("Regeln annehmen", _panel.transform, val, val, new Vector2(130f, num4), 220f, 45f);
			Button acceptButton = val4.GetComponent<Button>();
			((Selectable)acceptButton).interactable = false;
			((UnityEvent)acceptButton.onClick).AddListener((UnityAction)delegate
			{
				Close();
				onAccept();
			});
			Toggle[] array = toggles;
			for (int num5 = 0; num5 < array.Length; num5++)
			{
				((UnityEvent<bool>)(object)array[num5].onValueChanged).AddListener((UnityAction<bool>)delegate
				{
					((Selectable)acceptButton).interactable = toggles.All((Toggle t) => t.isOn);
				});
			}
			((UnityEvent)instance.CreateButton("Ablehnen & verlassen", _panel.transform, val, val, new Vector2(-130f, num4), 220f, 45f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				Close();
				onDecline();
			});
			GUIManager.BlockInput(true);
			_blocking = true;
		}

		public static void Close()
		{
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
			}
			_panel = null;
			if (_blocking)
			{
				GUIManager.BlockInput(false);
				_blocking = false;
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem))]
	internal static class SpawnPoint
	{
		private const string DefaultStartLocation = "StartTemple";

		private static ConfigEntry<bool> _enabled;

		private static ConfigEntry<float> _x;

		private static ConfigEntry<float> _z;

		private static ConfigEntry<float> _height;

		private static Vector3 Position => new Vector3(_x.Value, _height.Value, _z.Value);

		private static string StartLocation
		{
			get
			{
				if (!((Object)(object)Game.instance != (Object)null) || string.IsNullOrEmpty(Game.instance.m_StartLocation))
				{
					return "StartTemple";
				}
				return Game.instance.m_StartLocation;
			}
		}

		private static bool Active
		{
			get
			{
				if (_enabled.Value && (Object)(object)ZNet.instance != (Object)null)
				{
					return ZNet.instance.IsServer();
				}
				return false;
			}
		}

		public static void BindConfig(ConfigFile config)
		{
			_enabled = config.Bind<bool>("Spawn", "Enabled", true, "New characters and players without a bed spawn at the position below instead of the start temple.");
			_x = config.Bind<float>("Spawn", "X", -4216f, "East-west coordinate of the spawn.");
			_z = config.Bind<float>("Spawn", "Z", -5568f, "North-south coordinate of the spawn.");
			_height = config.Bind<float>("Spawn", "Height", 34f, "Height (Unity Y) of the spawn. The game drops players a little above it.");
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetLocationIcons")]
		private static void GetLocationIconsPostfix(Dictionary<Vector3, string> icons)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			if (!Active)
			{
				return;
			}
			string start = StartLocation;
			foreach (Vector3 item in (from kv in icons
				where kv.Value == start
				select kv.Key).ToList())
			{
				icons.Remove(item);
			}
			icons[Position] = start;
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetLocationIcon")]
		private static void GetLocationIconPostfix(string name, ref Vector3 pos, ref bool __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (Active && !(name != StartLocation))
			{
				pos = Position;
				__result = true;
			}
		}
	}
}