Decompiled source of FehuServerNotice v420.101.1

BepInEx/plugins/FehuServerNotice/FehuServerNotice.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Text;
using System.Xml;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
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("BlackViking")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("420.101.1.0")]
[assembly: AssemblyInformationalVersion("420.101.1")]
[assembly: AssemblyProduct("FehuServerNotice")]
[assembly: AssemblyTitle("FehuServerNotice")]
[assembly: AssemblyVersion("420.101.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FehuServerNotice
{
	public static class EndpointMatcher
	{
		public static bool IsApproved(string host, int port, string approvedEndpoints)
		{
			if (port < 1 || port > 65535 || string.IsNullOrWhiteSpace(host))
			{
				return false;
			}
			string[] array = (approvedEndpoints ?? "").Split(new char[1] { ';' });
			for (int i = 0; i < array.Length; i++)
			{
				if (TryParse(array[i], out var host2, out var port2) && port == port2 && string.Equals(NormalizeHost(host), NormalizeHost(host2), StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static string NormalizeHost(string host)
		{
			return host.Trim().Trim('[', ']').TrimEnd(new char[1] { '.' });
		}

		public static bool TryParse(string endpoint, out string host, out int port)
		{
			host = "";
			port = 0;
			if (string.IsNullOrWhiteSpace(endpoint))
			{
				return false;
			}
			endpoint = endpoint.Trim();
			int num = endpoint.LastIndexOf(':');
			if (num <= 0 || !int.TryParse(endpoint.Substring(num + 1), NumberStyles.None, CultureInfo.InvariantCulture, out port) || port < 1 || port > 65535)
			{
				return false;
			}
			host = endpoint.Substring(0, num);
			if (host.Contains(":") && (!host.StartsWith("[") || !host.EndsWith("]")))
			{
				return false;
			}
			if (host.IndexOfAny(new char[7] { '/', '\\', '@', ' ', '\t', '\r', '\n' }) >= 0)
			{
				return false;
			}
			return NormalizeHost(host).Length > 0;
		}

		public static bool TryGetSafeJoinUrl(string input, out string url)
		{
			url = null;
			if (!Uri.TryCreate(input, UriKind.Absolute, out Uri result) || result.Scheme != Uri.UriSchemeHttps || string.IsNullOrWhiteSpace(result.Host) || !string.IsNullOrEmpty(result.UserInfo))
			{
				return false;
			}
			url = result.AbsoluteUri;
			return true;
		}
	}
	internal static class NoticeContent
	{
		internal const string Body = "This mod is designed primarily for <b>active, populated multiplayer servers</b>, where clans, territories, trade, events and warfare can work as intended.\n\nFor this reason, multiplayer access while using this mod is limited to <b>official Forteca servers</b>.\n\n<b>PLAY WITH US — FREE</b>\n\nYou are welcome to join the <b>Forteca Community</b> and play with us completely free of charge.\n\n<b>Forteca is a 27-year-old gaming community</b> built around long-term worlds, cooperation, competition, playing together, learning and creating together.\n\nThere is no paywall required to play, progress, fight, build or explore.\n\n<b>All supporter perks are cosmetic or community-focused.</b>\n\n<b>No gameplay advantages. No pay-to-win.</b>\n\nCome experience the mod the way it was designed to be played:\n\nactive players • clans • wars • territories • economy • events\n\n<b>Join Forteca. Bring your friends. Build your clan. Create your legacy.</b>";

		internal static readonly string[] Paragraphs = "This mod is designed primarily for <b>active, populated multiplayer servers</b>, where clans, territories, trade, events and warfare can work as intended.\n\nFor this reason, multiplayer access while using this mod is limited to <b>official Forteca servers</b>.\n\n<b>PLAY WITH US — FREE</b>\n\nYou are welcome to join the <b>Forteca Community</b> and play with us completely free of charge.\n\n<b>Forteca is a 27-year-old gaming community</b> built around long-term worlds, cooperation, competition, playing together, learning and creating together.\n\nThere is no paywall required to play, progress, fight, build or explore.\n\n<b>All supporter perks are cosmetic or community-focused.</b>\n\n<b>No gameplay advantages. No pay-to-win.</b>\n\nCome experience the mod the way it was designed to be played:\n\nactive players • clans • wars • territories • economy • events\n\n<b>Join Forteca. Bring your friends. Build your clan. Create your legacy.</b>".Split(new string[1] { "\n\n" }, StringSplitOptions.None);

		internal static NoticeDocument CreateDefault()
		{
			NoticeParagraph[] array = new NoticeParagraph[Paragraphs.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new NoticeParagraph
				{
					Text = Paragraphs[i],
					Style = ((i == 9) ? "feature" : "body")
				};
			}
			return new NoticeDocument
			{
				Title = "MULTIPLAYER NOTICE",
				ButtonText = "CONTINUE",
				Paragraphs = array
			};
		}
	}
	[DataContract]
	internal sealed class NoticeDocument
	{
		[DataMember(Name = "title", Order = 0, IsRequired = true)]
		public string Title { get; set; }

		[DataMember(Name = "buttonText", Order = 1, IsRequired = true)]
		public string ButtonText { get; set; }

		[DataMember(Name = "paragraphs", Order = 2, IsRequired = true)]
		public NoticeParagraph[] Paragraphs { get; set; }
	}
	[DataContract]
	internal sealed class NoticeParagraph
	{
		[DataMember(Name = "text", Order = 0, IsRequired = true)]
		public string Text { get; set; }

		[DataMember(Name = "style", Order = 1)]
		public string Style { get; set; }

		internal bool IsFeature => Style == "feature";
	}
	internal static class NoticeContentFile
	{
		internal const int MaximumFileBytes = 131072;

		internal static NoticeDocument LoadOrCreate(string path, Action<string> warn)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Invalid comparison between Unknown and I4
			try
			{
				if (!File.Exists(path))
				{
					CreateDefaultFile(path);
				}
				using FileStream fileStream = File.OpenRead(path);
				if (fileStream.Length > 131072)
				{
					throw new InvalidDataException("Notice JSON exceeds 128 KiB.");
				}
				if (fileStream.Length >= 3 && (fileStream.ReadByte() != 239 || fileStream.ReadByte() != 187 || fileStream.ReadByte() != 191))
				{
					fileStream.Position = 0L;
				}
				XmlDictionaryReader val = JsonReaderWriterFactory.CreateJsonReader((Stream)fileStream, XmlDictionaryReaderQuotas.Max);
				try
				{
					NoticeDocument noticeDocument = (NoticeDocument)((XmlObjectSerializer)new DataContractJsonSerializer(typeof(NoticeDocument))).ReadObject(val);
					while (((XmlReader)val).Read())
					{
						if ((int)((XmlReader)val).NodeType != 13)
						{
							throw new InvalidDataException("Unexpected data after the notice JSON.");
						}
					}
					Validate(noticeDocument);
					return noticeDocument;
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}
			catch (Exception ex) when (ex is IOException || ex is InvalidDataException || ex is UnauthorizedAccessException || ex is SerializationException || ex is XmlException || ex is FormatException)
			{
				warn?.Invoke("Notice text JSON could not be loaded; using built-in text. " + ex.Message);
				return NoticeContent.CreateDefault();
			}
		}

		private static void Validate(NoticeDocument document)
		{
			if (document == null || string.IsNullOrWhiteSpace(document.Title) || string.IsNullOrWhiteSpace(document.ButtonText))
			{
				throw new InvalidDataException("Notice title and buttonText must be non-empty strings.");
			}
			if (document.Paragraphs == null || document.Paragraphs.Length == 0 || document.Paragraphs.Length > 64)
			{
				throw new InvalidDataException("Notice paragraphs must contain between 1 and 64 entries.");
			}
			NoticeParagraph[] paragraphs = document.Paragraphs;
			foreach (NoticeParagraph noticeParagraph in paragraphs)
			{
				if (noticeParagraph == null || string.IsNullOrWhiteSpace(noticeParagraph.Text))
				{
					throw new InvalidDataException("Each notice paragraph needs non-empty text.");
				}
				if (string.IsNullOrEmpty(noticeParagraph.Style))
				{
					noticeParagraph.Style = "body";
				}
				if (noticeParagraph.Style != "body" && noticeParagraph.Style != "feature")
				{
					throw new InvalidDataException("Paragraph style must be body or feature.");
				}
			}
		}

		private static void CreateDefaultFile(string path)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Directory.CreateDirectory(Path.GetDirectoryName(path));
			string text = path + "." + Guid.NewGuid().ToString("N") + ".tmp";
			try
			{
				using (FileStream fileStream = new FileStream(text, FileMode.CreateNew, FileAccess.Write, FileShare.None))
				{
					XmlDictionaryWriter val = JsonReaderWriterFactory.CreateJsonWriter((Stream)fileStream, (Encoding)new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), false, true, "  ");
					try
					{
						((XmlObjectSerializer)new DataContractJsonSerializer(typeof(NoticeDocument))).WriteObject(val, (object)NoticeContent.CreateDefault());
						((XmlWriter)val).Flush();
					}
					finally
					{
						((IDisposable)val)?.Dispose();
					}
					fileStream.Flush(flushToDisk: true);
				}
				File.Move(text, path);
			}
			finally
			{
				if (File.Exists(text))
				{
					File.Delete(text);
				}
			}
		}
	}
	public static class NoticeLayout
	{
		public const float DesignWidth = 940f;

		public const float DesignHeight = 620f;

		public const float PreviousTopInset = 92f;

		public const float UpwardOffset = 18f;

		public const float TopInset = 74f;

		public const float BottomEdgeInset = 20f;

		public const float BodyTop = 86f;

		public const float ButtonGap = 16f;

		public const float ButtonHeight = 52f;

		public const float ButtonWidth = 230f;

		public const float BottomPadding = 18f;

		public static float ButtonTopForBody(float bodyHeight)
		{
			return 86f + Math.Max(0f, bodyHeight) + 16f;
		}

		public static float HeightForBody(float bodyHeight)
		{
			return ButtonTopForBody(bodyHeight) + 52f + 18f;
		}

		public static float FitScale(float availableWidth, float availableHeight, float userScale, float panelHeight = 620f)
		{
			return Math.Max(0.01f, Math.Min(userScale, Math.Min(Math.Max(1f, availableWidth - 40f) / 940f, Math.Max(1f, availableHeight - 92f - 20f) / Math.Max(1f, panelHeight))));
		}

		public static float SpaceAfterParagraph(int index)
		{
			return index switch
			{
				0 => 14f, 
				1 => 16f, 
				2 => 10f, 
				3 => 10f, 
				4 => 12f, 
				5 => 14f, 
				6 => 9f, 
				7 => 16f, 
				8 => 16f, 
				9 => 16f, 
				_ => 0f, 
			};
		}
	}
	public static class NoticePolicy
	{
		public static bool ShouldShow(bool enabled, bool showOnFirstRun, int version, int reminderDays, NoticeState state, DateTimeOffset now, bool showEveryStart = false)
		{
			if (!enabled)
			{
				return false;
			}
			if (showEveryStart)
			{
				return true;
			}
			if (state == null || !state.HasDisplay)
			{
				return showOnFirstRun;
			}
			if (state.NoticeVersion != version)
			{
				return true;
			}
			return now - state.Timestamp >= TimeSpan.FromDays(Math.Max(1, reminderDays));
		}
	}
	[DataContract]
	public sealed class NoticeState
	{
		[DataMember(Order = 0)]
		public string LastNoticeShown { get; set; } = "";

		[DataMember(Order = 1)]
		public int NoticeVersion { get; set; }

		public DateTimeOffset Timestamp
		{
			get
			{
				if (!DateTimeOffset.TryParse(LastNoticeShown, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var result))
				{
					return DateTimeOffset.MinValue;
				}
				return result;
			}
		}

		public bool HasDisplay => Timestamp != DateTimeOffset.MinValue;

		public static NoticeState Displayed(int version, DateTimeOffset now)
		{
			return new NoticeState
			{
				LastNoticeShown = now.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture),
				NoticeVersion = version
			};
		}
	}
	public sealed class NoticeStateStore
	{
		private readonly string path;

		public NoticeStateStore(string path)
		{
			this.path = path;
		}

		private static NoticeState Read(string file)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			using FileStream fileStream = File.OpenRead(file);
			NoticeState noticeState = (NoticeState)((XmlObjectSerializer)new DataContractJsonSerializer(typeof(NoticeState))).ReadObject((Stream)fileStream);
			if (noticeState == null || !noticeState.HasDisplay || noticeState.NoticeVersion < 1)
			{
				throw new InvalidDataException("Invalid notice timestamp or version.");
			}
			return noticeState;
		}

		public NoticeState Load(Action<string> warn)
		{
			if (!File.Exists(path))
			{
				return new NoticeState();
			}
			try
			{
				return Read(path);
			}
			catch (Exception ex) when (ex is IOException || ex is InvalidDataException || ex is UnauthorizedAccessException || ex is SerializationException || ex is FormatException)
			{
				warn?.Invoke("Notice state could not be read: " + ex.Message);
				try
				{
					if (File.Exists(path + ".bak"))
					{
						return Read(path + ".bak");
					}
				}
				catch (Exception ex2) when (ex2 is IOException || ex2 is InvalidDataException || ex2 is UnauthorizedAccessException || ex2 is SerializationException || ex2 is FormatException)
				{
				}
				return new NoticeState();
			}
		}

		public void Save(NoticeState state)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			Directory.CreateDirectory(Path.GetDirectoryName(path));
			string sourceFileName = path + "." + Guid.NewGuid().ToString("N") + ".tmp";
			try
			{
				using (FileStream fileStream = new FileStream(sourceFileName, FileMode.CreateNew, FileAccess.Write, FileShare.None))
				{
					((XmlObjectSerializer)new DataContractJsonSerializer(typeof(NoticeState))).WriteObject((Stream)fileStream, (object)state);
					fileStream.Flush(flushToDisk: true);
				}
				if (File.Exists(path))
				{
					File.Replace(sourceFileName, path, path + ".bak");
				}
				else
				{
					File.Move(sourceFileName, path);
				}
			}
			finally
			{
				if (File.Exists(sourceFileName))
				{
					File.Delete(sourceFileName);
				}
			}
		}
	}
	internal sealed class NoticeView
	{
		private const int ModalDepth = -10000;

		private const int WindowId = 145901101;

		private GameObject root;

		private RectTransform host;

		private GameObject previousSelection;

		private GUIStyle titleStyle;

		private GUIStyle bodyStyle;

		private GUIStyle featureStyle;

		private GUIStyle buttonStyle;

		private Texture2D runeImage;

		private Action acknowledge;

		private bool focusPrimary;

		private bool bodyMeasured;

		private bool buttonPressed;

		private float drawScale = 1f;

		private float currentUiScale = 1f;

		private float panelHeight = 620f;

		private Rect screenPanel;

		private NoticeDocument content;

		private Rect[] paragraphRects;

		private Rect continueRect;

		internal bool Visible
		{
			get
			{
				if ((Object)(object)root != (Object)null)
				{
					return root.activeInHierarchy;
				}
				return false;
			}
		}

		internal void Show(Action acknowledge, string joinUrl, Action<string> openUrl, float uiScale, NoticeDocument content)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00ae: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			GUIManager instance = GUIManager.Instance;
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			if ((Object)(object)customGUIFront == (Object)null)
			{
				throw new InvalidOperationException("Native GUI is not ready.");
			}
			this.acknowledge = acknowledge;
			this.content = content;
			paragraphRects = (Rect[])(object)new Rect[content.Paragraphs.Length];
			host = customGUIFront.GetComponent<RectTransform>();
			root = new GameObject("FehuServerNoticePointerBlocker", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			root.SetActive(false);
			root.transform.SetParent(customGUIFront.transform, false);
			RectTransform component = root.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			((Graphic)root.GetComponent<Image>()).color = Color.clear;
			((Graphic)root.GetComponent<Image>()).canvasRenderer.cullTransparentMesh = false;
			Font averiaSerif = instance.AveriaSerif;
			titleStyle = TextStyle(averiaSerif, 26, new Color(0.84f, 0.68f, 0.4f), (TextAnchor)4);
			bodyStyle = TextStyle(averiaSerif, 20, new Color(0.94f, 0.91f, 0.84f), (TextAnchor)0);
			featureStyle = TextStyle(averiaSerif, 20, new Color(0.88f, 0.77f, 0.55f), (TextAnchor)4);
			buttonStyle = TextStyle(instance.AveriaSerifBold, 19, new Color(0.94f, 0.82f, 0.6f), (TextAnchor)4);
			buttonStyle.hover.textColor = new Color(1f, 0.89f, 0.66f);
			buttonStyle.active.textColor = new Color(0.86f, 0.72f, 0.46f);
			buttonStyle.focused.textColor = new Color(1f, 0.89f, 0.66f);
			runeImage = CreateRuneImage();
			previousSelection = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
			if ((Object)(object)EventSystem.current != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject((GameObject)null);
			}
			focusPrimary = true;
			bodyMeasured = false;
			root.SetActive(true);
			root.transform.SetAsLastSibling();
			Resize(uiScale);
		}

		internal void Resize(float uiScale)
		{
			//IL_001c: 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)
			//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_0036: 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_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)
			currentUiScale = uiScale;
			if (!((Object)(object)host == (Object)null))
			{
				Rect rect = host.rect;
				Vector2 size = ((Rect)(ref rect)).size;
				float num = Mathf.Min((float)Screen.width / Mathf.Max(1f, size.x), (float)Screen.height / Mathf.Max(1f, size.y));
				num = Mathf.Max(0.01f, num);
				drawScale = num * NoticeLayout.FitScale((float)Screen.width / num, (float)Screen.height / num, uiScale, panelHeight);
				float num2 = 940f * drawScale;
				float num3 = panelHeight * drawScale;
				screenPanel = new Rect(((float)Screen.width - num2) / 2f, 74f * num, num2, num3);
			}
		}

		internal void Draw()
		{
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: 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_0266: 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)
			//IL_0014: 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_001a: 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)
			//IL_0020: 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)
			//IL_0026: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Expected O, but got Unknown
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Invalid comparison between Unknown and I4
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Invalid comparison between Unknown and I4
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_00bc: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if (!Visible)
			{
				return;
			}
			int depth = GUI.depth;
			Matrix4x4 matrix = GUI.matrix;
			Color color = GUI.color;
			Color backgroundColor = GUI.backgroundColor;
			Color contentColor = GUI.contentColor;
			bool enabled = GUI.enabled;
			try
			{
				GUI.depth = -10000;
				GUI.matrix = Matrix4x4.identity;
				GUI.enabled = true;
				GUI.backgroundColor = Color.white;
				GUI.contentColor = Color.white;
				if (!bodyMeasured)
				{
					float num = 86f;
					for (int i = 0; i < content.Paragraphs.Length; i++)
					{
						float num2 = Mathf.Ceil((content.Paragraphs[i].IsFeature ? featureStyle : bodyStyle).CalcHeight(new GUIContent(content.Paragraphs[i].Text), 876f));
						paragraphRects[i] = new Rect(32f, num, 876f, num2);
						num += num2 + NoticeLayout.SpaceAfterParagraph(i);
					}
					float bodyHeight = num - 86f;
					continueRect = new Rect(355f, NoticeLayout.ButtonTopForBody(bodyHeight), 230f, 52f);
					panelHeight = NoticeLayout.HeightForBody(bodyHeight);
					bodyMeasured = true;
					Resize(currentUiScale);
				}
				Solid(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), new Color(0f, 0f, 0f, 0.67f));
				GUI.color = Color.white;
				GUI.matrix = Matrix4x4.TRS(new Vector3(((Rect)(ref screenPanel)).x, ((Rect)(ref screenPanel)).y, 0f), Quaternion.identity, new Vector3(drawScale, drawScale, 1f));
				GUI.ModalWindow(145901101, new Rect(0f, 0f, 940f, panelHeight), new WindowFunction(DrawPanel), GUIContent.none, GUIStyle.none);
				Event current = Event.current;
				if ((int)current.type == 0 || (int)current.type == 1 || (int)current.type == 6)
				{
					current.Use();
				}
			}
			finally
			{
				GUI.depth = depth;
				GUI.matrix = matrix;
				GUI.color = color;
				GUI.enabled = enabled;
				GUI.backgroundColor = backgroundColor;
				GUI.contentColor = contentColor;
			}
		}

		private void DrawPanel(int id)
		{
			//IL_001c: 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_005f: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Invalid comparison between Unknown and I4
			Rect rect = default(Rect);
			((Rect)(ref rect))..ctor(0f, 0f, 940f, panelHeight);
			Solid(rect, new Color(0.38f, 0.29f, 0.17f, 1f));
			Solid(new Rect(2f, 2f, ((Rect)(ref rect)).width - 4f, ((Rect)(ref rect)).height - 4f), new Color(0.075f, 0.06f, 0.04f, 1f));
			GUI.Label(new Rect(30f, 14f, ((Rect)(ref rect)).width - 60f, 32f), content.Title, titleStyle);
			Rect rect2 = default(Rect);
			((Rect)(ref rect2))..ctor((((Rect)(ref rect)).width - 24f) / 2f, 47f, 24f, 20f);
			DrawFehuRune(rect2);
			Solid(new Rect(32f, 74f, ((Rect)(ref rect)).width - 64f, 1f), new Color(0.6f, 0.44f, 0.22f, 0.7f));
			for (int i = 0; i < content.Paragraphs.Length; i++)
			{
				if (content.Paragraphs[i].IsFeature)
				{
					Solid(new Rect(((Rect)(ref rect)).width * 0.2f, ((Rect)(ref paragraphRects[i])).y - 7f, ((Rect)(ref rect)).width * 0.6f, 1f), new Color(0.53f, 0.4f, 0.22f, 0.35f));
				}
				GUI.Label(paragraphRects[i], content.Paragraphs[i].Text, content.Paragraphs[i].IsFeature ? featureStyle : bodyStyle);
			}
			if (DrawButton(continueRect, content.ButtonText, "FehuServerNoticeContinue"))
			{
				acknowledge();
			}
			if (focusPrimary && (int)Event.current.type == 7)
			{
				GUI.FocusControl("FehuServerNoticeContinue");
				focusPrimary = false;
			}
		}

		private bool DrawButton(Rect rect, string text, string controlName)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0142: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: 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)
			bool flag = ((Rect)(ref rect)).Contains(Event.current.mousePosition);
			if ((int)Event.current.type == 0 && Event.current.button == 0 && flag)
			{
				buttonPressed = true;
			}
			if ((int)Event.current.rawType == 1)
			{
				buttonPressed = false;
			}
			bool flag2 = buttonPressed && flag;
			if (flag && !flag2)
			{
				Solid(new Rect(((Rect)(ref rect)).x - 2f, ((Rect)(ref rect)).y - 2f, ((Rect)(ref rect)).width + 4f, ((Rect)(ref rect)).height + 4f), new Color(0.65f, 0.49f, 0.27f, 0.1f));
			}
			Solid(rect, flag2 ? new Color(0.39f, 0.29f, 0.17f, 1f) : (flag ? new Color(0.62f, 0.47f, 0.27f, 1f) : new Color(0.5f, 0.38f, 0.22f, 1f)));
			Solid(new Rect(((Rect)(ref rect)).x + 2f, ((Rect)(ref rect)).y + 2f, ((Rect)(ref rect)).width - 4f, ((Rect)(ref rect)).height - 4f), flag2 ? new Color(0.11f, 0.085f, 0.05f, 1f) : (flag ? new Color(0.23f, 0.18f, 0.11f, 1f) : new Color(0.15f, 0.12f, 0.075f, 1f)));
			GUI.SetNextControlName(controlName);
			return GUI.Button(rect, text, buttonStyle);
		}

		private static GUIStyle TextStyle(Font font, int size, Color color, TextAnchor alignment)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0013: 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)
			//IL_001a: 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)
			//IL_0028: 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_003e: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			GUIStyle val = new GUIStyle
			{
				font = font,
				fontSize = size,
				alignment = alignment,
				fontStyle = (FontStyle)0,
				wordWrap = true,
				richText = true,
				padding = new RectOffset(0, 0, 0, 0)
			};
			val.normal.textColor = color;
			return val;
		}

		private static void Solid(Rect rect, Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Color color2 = GUI.color;
			GUI.color = color;
			GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color2;
		}

		private void DrawFehuRune(Rect rect)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_001a: 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)
			Color color = GUI.color;
			try
			{
				GUI.color = new Color(0.7f, 0.54f, 0.3f, 1f);
				GUI.DrawTexture(rect, (Texture)(object)runeImage);
			}
			finally
			{
				GUI.color = color;
			}
		}

		private static Texture2D CreateRuneImage()
		{
			//IL_0130: 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_0140: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0042: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00a4: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[30720];
			Vector2 point = default(Vector2);
			for (int i = 0; i < 160; i++)
			{
				for (int j = 0; j < 192; j++)
				{
					((Vector2)(ref point))..ctor(((float)j + 0.5f) / 8f, 20f - ((float)i + 0.5f) / 8f);
					float num = Mathf.Min(DistanceToStroke(point, new Vector2(6f, 1f), new Vector2(6f, 19f)), Mathf.Min(DistanceToStroke(point, new Vector2(6f, 7.5f), new Vector2(18f, 1f)), DistanceToStroke(point, new Vector2(6f, 14.5f), new Vector2(18f, 8f))));
					byte b = (byte)Mathf.RoundToInt(255f * Mathf.Clamp01((0.9375f - num) * 8f + 0.5f));
					array[i * 192 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			Texture2D val = new Texture2D(192, 160, (TextureFormat)4, false)
			{
				name = "FehuServerNoticeRune",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			val.SetPixels32(array);
			val.Apply(false, true);
			return val;
		}

		private static float DistanceToStroke(Vector2 point, Vector2 start, Vector2 end)
		{
			//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_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_0009: 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_000f: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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)
			Vector2 val = end - start;
			float num = Mathf.Clamp01(Vector2.Dot(point - start, val) / ((Vector2)(ref val)).sqrMagnitude);
			return Vector2.Distance(point, start + num * val);
		}

		internal void Close()
		{
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)root);
			}
			root = null;
			if ((Object)(object)runeImage != (Object)null)
			{
				Object.Destroy((Object)(object)runeImage);
			}
			runeImage = null;
			if ((Object)(object)EventSystem.current != (Object)null && (Object)(object)previousSelection != (Object)null && previousSelection.activeInHierarchy)
			{
				EventSystem.current.SetSelectedGameObject(previousSelection);
			}
			previousSelection = null;
		}
	}
	internal enum Destination
	{
		None,
		Unknown,
		Official,
		Other
	}
	internal static class OfficialServerDetector
	{
		private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		internal static Destination Read(FejdStartup startup, string endpoints, Action<string> debug)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)startup != (Object)null && startup.HasServerToJoin())
				{
					object obj = startup.GetServerToJoin();
					object obj2 = obj.GetType().GetProperty("Dedicated", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
					if (obj2 == null)
					{
						return Destination.Unknown;
					}
					string text = obj2.GetType().GetMethod("GetHost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(obj2, null) as string;
					object obj3 = obj2.GetType().GetField("m_port", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj2);
					if (text == null || obj3 == null)
					{
						return Destination.Unknown;
					}
					return EndpointMatcher.IsApproved(text, Convert.ToInt32(obj3), endpoints) ? Destination.Official : Destination.Other;
				}
				if (!ZNet.HasServerHost())
				{
					return Destination.None;
				}
				string serverString = ZNet.GetServerString(true);
				if (serverString == null || serverString.StartsWith("playfab/", StringComparison.Ordinal))
				{
					return Destination.Unknown;
				}
				if (!EndpointMatcher.TryParse(serverString.Substring(serverString.LastIndexOf('/') + 1), out var host, out var port))
				{
					return Destination.Unknown;
				}
				return EndpointMatcher.IsApproved(host, port, endpoints) ? Destination.Official : Destination.Other;
			}
			catch (Exception ex)
			{
				debug?.Invoke("Destination unavailable: " + ex.GetType().Name);
				return Destination.Unknown;
			}
		}
	}
	[BepInPlugin("forteca.fehuservernotice", "FehuServerNotice", "420.101.1")]
	[BepInDependency("com.jotunn.jotunn", "2.30.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "forteca.fehuservernotice";

		public const string Name = "FehuServerNotice";

		public const string Version = "420.101.1";

		internal static Plugin Instance;

		private ConfigEntry<bool> noticeEnabled;

		private ConfigEntry<bool> firstRun;

		private ConfigEntry<bool> debugLogging;

		private ConfigEntry<bool> showEveryStart;

		private ConfigEntry<int> noticeVersion;

		private ConfigEntry<int> reminderDays;

		private ConfigEntry<string> joinUrl;

		private ConfigEntry<string> officialEndpoints;

		private ConfigEntry<float> uiScale;

		private readonly NoticeView view = new NoticeView();

		private NoticeStateStore store;

		private NoticeState state;

		private NoticeDocument content;

		private Harmony harmony;

		private bool finishedThisSession;

		private bool warnedSave;

		private bool warnedDestination;

		private bool displayedInTestMode;

		private int displayedVersion;

		private float nextCheck;

		private float readySince = -1f;

		private static readonly FieldInfo MainMenu = typeof(FejdStartup).GetField("m_mainMenu", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		internal static bool NoticeVisible
		{
			get
			{
				if ((Object)(object)Instance != (Object)null)
				{
					return Instance.view.Visible;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			if (GUIManager.IsHeadless())
			{
				((Behaviour)this).enabled = false;
				return;
			}
			try
			{
				noticeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Notice", "Enabled", true, "Enable the informational notice.");
				noticeVersion = ((BaseUnityPlugin)this).Config.Bind<int>("Notice", "NoticeVersion", 1, new ConfigDescription("Increment to show updated notice text again.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, int.MaxValue), Array.Empty<object>()));
				reminderDays = ((BaseUnityPlugin)this).Config.Bind<int>("Notice", "ReminderDays", 7, new ConfigDescription("Minimum days between notices.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3650), Array.Empty<object>()));
				firstRun = ((BaseUnityPlugin)this).Config.Bind<bool>("Notice", "ShowOnFirstRun", true, "Show automatically when there is no local display history.");
				showEveryStart = ((BaseUnityPlugin)this).Config.Bind<bool>("Notice", "ShowEveryStart", false, "Temporary UI test mode: show once on every eligible game start, ignoring display history. Does not overwrite normal notice state. Set false to restore normal reminders.");
				joinUrl = ((BaseUnityPlugin)this).Config.Bind<string>("Notice", "JoinFortecaUrl", "", "Optional absolute HTTPS community URL. Blank or invalid hides JOIN FORTECA.");
				debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Notice", "DebugLogging", false, "Enable detailed DEBUG diagnostics.");
				officialEndpoints = ((BaseUnityPlugin)this).Config.Bind<string>("Notice", "OfficialServerEndpoints", "", "Exact approved host:game-port pairs separated by semicolons. IPv6: [address]:port. Blank disables positive identification. No server-name matching or remote lookup.");
				uiScale = ((BaseUnityPlugin)this).Config.Bind<float>("Notice", "UiScale", 1f, new ConfigDescription("Notice size multiplier; always fitted inside the available screen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.75f, 1.5f), Array.Empty<object>()));
				store = new NoticeStateStore(Path.Combine(Paths.ConfigPath, "FehuServerNotice", "state.json"));
				state = store.Load(delegate(string message)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)message);
				});
				content = NoticeContentFile.LoadOrCreate(Path.Combine(Paths.ConfigPath, "FehuServerNotice", "notice.json"), delegate(string message)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)message);
				});
				Instance = this;
				harmony = new Harmony("forteca.fehuservernotice");
				harmony.PatchAll(typeof(Plugin).Assembly);
				((BaseUnityPlugin)this).Logger.LogInfo((object)($"Loaded. Notice version {noticeVersion.Value}, reminder {reminderDays.Value} days." + (showEveryStart.Value ? " Test mode: every start." : "")));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Notice initialization skipped safely: " + ex.Message));
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				Instance = null;
				((Behaviour)this).enabled = false;
			}
		}

		private void Update()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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)
			if (Time.unscaledTime < nextCheck)
			{
				return;
			}
			nextCheck = Time.unscaledTime + 0.5f;
			try
			{
				Scene activeScene;
				if (view.Visible)
				{
					if (noticeEnabled.Value)
					{
						activeScene = SceneManager.GetActiveScene();
						if (!(((Scene)(ref activeScene)).name != "start"))
						{
							view.Resize(uiScale.Value);
							return;
						}
					}
					view.Close();
				}
				else
				{
					if (finishedThisSession || !NoticePolicy.ShouldShow(noticeEnabled.Value, firstRun.Value, noticeVersion.Value, reminderDays.Value, state, DateTimeOffset.UtcNow, showEveryStart.Value))
					{
						return;
					}
					activeScene = SceneManager.GetActiveScene();
					if (((Scene)(ref activeScene)).name != "start" || (Object)(object)FejdStartup.instance == (Object)null)
					{
						readySince = -1f;
						return;
					}
					FejdStartup instance = FejdStartup.instance;
					switch (OfficialServerDetector.Read(instance, officialEndpoints.Value, delegate(string message)
					{
						if (!warnedDestination)
						{
							Debug(message);
							warnedDestination = true;
						}
					}))
					{
					case Destination.Official:
						finishedThisSession = true;
						Debug("Official destination; notice skipped for this session.");
						break;
					default:
						readySince = -1f;
						break;
					case Destination.None:
					{
						object? obj = MainMenu?.GetValue(instance);
						GameObject val = (GameObject)((obj is GameObject) ? obj : null);
						if ((Object)(object)val == (Object)null || !val.activeInHierarchy || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
						{
							readySince = -1f;
							break;
						}
						if (readySince < 0f)
						{
							readySince = Time.unscaledTime;
						}
						if (!(Time.unscaledTime - readySince < 5f))
						{
							displayedVersion = noticeVersion.Value;
							displayedInTestMode = showEveryStart.Value;
							view.Show(Acknowledge, joinUrl.Value, OpenUrl, uiScale.Value, content);
							finishedThisSession = true;
							if (!displayedInTestMode)
							{
								Persist(displayedVersion);
							}
							Debug("Notice displayed.");
						}
						break;
					}
					}
				}
			}
			catch (Exception ex)
			{
				view.Close();
				finishedThisSession = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Notice skipped safely: " + ex.Message));
			}
		}

		private void OnGUI()
		{
			if (!view.Visible)
			{
				return;
			}
			try
			{
				view.Draw();
			}
			catch (Exception ex)
			{
				view.Close();
				finishedThisSession = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Notice rendering skipped safely: " + ex.Message));
			}
		}

		private void Acknowledge()
		{
			if (!displayedInTestMode)
			{
				Persist(displayedVersion);
			}
			view.Close();
			Debug("Notice acknowledged.");
		}

		private void Persist(int version)
		{
			state = NoticeState.Displayed(version, DateTimeOffset.UtcNow);
			try
			{
				store.Save(state);
			}
			catch (Exception ex)
			{
				if (!warnedSave)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Local notice state could not be saved: " + ex.Message));
					warnedSave = true;
				}
			}
		}

		private void OpenUrl(string url)
		{
			if (!EndpointMatcher.TryGetSafeJoinUrl(url, out var url2))
			{
				return;
			}
			try
			{
				Application.OpenURL(url2);
			}
			catch (Exception ex)
			{
				Debug("Community URL unavailable: " + ex.GetType().Name);
			}
		}

		private void Debug(string message)
		{
			if (debugLogging.Value)
			{
				((BaseUnityPlugin)this).Logger.LogDebug((object)message);
			}
		}

		private void OnDestroy()
		{
			view.Close();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "UpdateKeyboard")]
	internal static class MenuKeyboardPatch
	{
		private static bool Prefix()
		{
			return !Plugin.NoticeVisible;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "UpdateGamepad")]
	internal static class MenuGamepadPatch
	{
		private static bool Prefix()
		{
			return !Plugin.NoticeVisible;
		}
	}
}