Decompiled source of Notiffy v0.1.1

Notiffy.dll

Decompiled a day 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 BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Notiffy.API;
using Notiffy.Server;
using Notiffy.UI;
using Notiffy.Utils;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using PluginConfig.API.Functionals;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Notiffy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+635564bc34e065b2efaf9b79bc2f2f7e3afc0c6a")]
[assembly: AssemblyProduct("Notiffy")]
[assembly: AssemblyTitle("Notiffy")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 Notiffy
{
	public class ConfigManager
	{
		public static PluginConfigurator? config;

		public static readonly FloatField DefaultTimeout;

		public static readonly IntField MaxHistory;

		public static readonly BoolField UseModifierKey;

		public static readonly KeyCodeField ModifierKey;

		public static readonly KeyCodeField NotificationPanelKey;

		public static readonly BoolField ShowDebugOptions;

		public static readonly BoolField FirstRun;

		public static readonly ButtonField SendTestNotificationButton;

		public static readonly ButtonField SendUrgentNotificationButton;

		public static readonly BoolField Silent;

		private static readonly List<uint> ActiveNotifIds;

		public static void Initialize()
		{
		}

		private static void UpdateDebugOptionsVisibility()
		{
			bool value = ShowDebugOptions.value;
			((ConfigField)SendTestNotificationButton).hidden = !value;
			((ConfigField)SendUrgentNotificationButton).hidden = !value;
			((ConfigField)FirstRun).hidden = !value;
		}

		public static string GetFormattedPanelKeybind()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			KeyCode value;
			if (UseModifierKey.value)
			{
				string text2 = text;
				value = ModifierKey.value;
				text = text2 + "<color=#ff8000>" + ((object)(KeyCode)(ref value)).ToString() + "</color>+";
			}
			string text3 = text;
			value = NotificationPanelKey.value;
			return text3 + "<color=#ff8000>" + ((object)(KeyCode)(ref value)).ToString() + "</color>";
		}

		static ConfigManager()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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)
			//IL_00a3: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Expected O, but got Unknown
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			ActiveNotifIds = new List<uint>();
			config = PluginConfigurator.Create("Notiffy", "com.github.end-4.notiffy");
			string iconPath = Path.Combine(NotiffyPlugin.workingDir, "icon.png");
			if (File.Exists(iconPath))
			{
				config.SetIconWithURL(iconPath);
			}
			new ConfigHeader(config.rootPanel, "", 10);
			new ConfigHeader(config.rootPanel, "-- NOTIFICATION SYSTEM --", 24);
			UseModifierKey = new BoolField(config.rootPanel, "Use modifier key", "modifierKey", true);
			UseModifierKey.postValueChangeEvent += (PostBoolValueChangeEvent)delegate(bool newValue)
			{
				if (ModifierKey != null)
				{
					((ConfigField)ModifierKey).interactable = newValue;
				}
			};
			ModifierKey = new KeyCodeField(config.rootPanel, "Modifier key", "notificationPanelModkey", (KeyCode)308);
			ModifierKey.postValueChangeEvent += (PostKeyCodeValueChangeEvent)delegate
			{
				NotificationController.UpdatePanelTitle();
			};
			((ConfigField)ModifierKey).interactable = UseModifierKey.value;
			NotificationPanelKey = new KeyCodeField(config.rootPanel, "Toggle panel keybind", "notificationPanelKey", (KeyCode)110);
			NotificationPanelKey.postValueChangeEvent += (PostKeyCodeValueChangeEvent)delegate
			{
				NotificationController.UpdatePanelTitle();
			};
			DefaultTimeout = new FloatField(config.rootPanel, "Default timeout (secs)", "defaultTimeout", 6f);
			MaxHistory = new IntField(config.rootPanel, "Max history length", "maxHistory", 50);
			new ConfigHeader(config.rootPanel, "", 10);
			new ConfigHeader(config.rootPanel, "-- DEBUG --", 24);
			ShowDebugOptions = new BoolField(config.rootPanel, "Show debug options", "showDebugOptions", false);
			ShowDebugOptions.postValueChangeEvent += (PostBoolValueChangeEvent)delegate
			{
				UpdateDebugOptionsVisibility();
			};
			SendTestNotificationButton = new ButtonField(config.rootPanel, "Send test notification", "testNotification");
			SendTestNotificationButton.onClick += (OnClick)delegate
			{
				uint item = NotificationSystem.NotifySend("Test notification", "The quick blue V1 jumps over the red V2. Sisyphus sells sea shells by the sea shore.", null, iconPath, Urgency.Normal, "NotifySend", 0u, new Dictionary<string, string>
				{
					{ "hellYeah", "Hell yeah!" },
					{ "noThanks", "I'll pass this time..." }
				});
				ActiveNotifIds.Add(item);
			};
			SendUrgentNotificationButton = new ButtonField(config.rootPanel, "Send urgent test notification", "testNotificationUrgent");
			SendUrgentNotificationButton.onClick += (OnClick)delegate
			{
				NotificationSystem.NotifySend("Urgent notification", "This message should not disappear on its own.", null, "", Urgency.Critical);
			};
			FirstRun = new BoolField(config.rootPanel, "First run", "firstRun", true);
			UpdateDebugOptionsVisibility();
			Silent = new BoolField(config.rootPanel, "Silent", "silent", false);
			((ConfigField)Silent).hidden = true;
			NotificationSystem.ActionInvoked += OnActionInvoked;
			NotificationSystem.NotificationClosed += OnNotificationClosed;
			NotificationSystem.NotificationDeleted += OnNotificationDeleted;
		}

		private static void PrintActiveNotifIds()
		{
			NotiffyPlugin.Log.LogInfo((object)"ACTIVE NOTIFS");
			foreach (uint activeNotifId in ActiveNotifIds)
			{
				NotiffyPlugin.Log.LogInfo((object)activeNotifId);
			}
		}

		private static void OnActionInvoked(uint id, string actionIdentifier)
		{
			PrintActiveNotifIds();
			NotiffyPlugin.Log.LogInfo((object)$"Some action invoked: {id}, {actionIdentifier}; current tracked {ActiveNotifIds} -> {ActiveNotifIds.Contains(id)}");
			if (ActiveNotifIds.Contains(id))
			{
				NotificationSystem.NotifySend("Action invoked", $"ID: {id}\nAction ID: {actionIdentifier}");
				NotiffyPlugin.Log.LogInfo((object)$"INVOKED notification with ID {id}, actionIdentifier: {actionIdentifier}");
				ActiveNotifIds.Remove(id);
			}
		}

		private static void OnNotificationClosed(uint id, ClosedReason reason)
		{
			if (ActiveNotifIds.Contains(id))
			{
				NotiffyPlugin.Log.LogInfo((object)$"DISMISSED notification with ID {id}");
			}
		}

		private static void OnNotificationDeleted(uint id)
		{
			if (ActiveNotifIds.Contains(id))
			{
				ActiveNotifIds.Remove(id);
				NotiffyPlugin.Log.LogInfo((object)$"DELETED notification with ID {id}");
			}
		}
	}
	[BepInPlugin("com.github.end-4.notiffy", "Notiffy", "0.1.1")]
	public class NotiffyPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.github.end-4.notiffy";

		public const string PluginName = "Notiffy";

		public const string PluginVersion = "0.1.1";

		public static string workingPath = Assembly.GetExecutingAssembly().Location;

		public static string workingDir = Path.GetDirectoryName(workingPath);

		internal static ManualLogSource Log;

		private void Awake()
		{
			Log = Logger.CreateLogSource("Notiffy");
			Log.LogInfo((object)"Notiffy is waking up...");
			ConfigManager.Initialize();
			NotificationSystem.Initialize();
			NotificationController.Initialize();
			MenuPatcher.Initialize();
			UserHints.Initialize();
			Log.LogInfo((object)"Notiffy Initialized");
		}

		private void Update()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if ((!ConfigManager.UseModifierKey.value || Input.GetKey(ConfigManager.ModifierKey.value)) && Input.GetKeyDown(ConfigManager.NotificationPanelKey.value))
			{
				NotificationController.TogglePanel();
			}
		}
	}
	public static class UserHints
	{
		public static void IssueFirstRunNoticeIfNecessary()
		{
			if (ConfigManager.FirstRun.value)
			{
				ConfigManager.FirstRun.value = false;
				NotificationSystem.NotifySend("<color=#f2ca3a>Notiffy</color>: instructions", "To open notification panel, press [" + ConfigManager.GetFormattedPanelKeybind() + "]. This can be configured in <color=#55c7f6>Options > Plugin Config > Notiffy</color>", null, Path.Combine(NotiffyPlugin.workingDir, "icon.png"), Urgency.Critical);
			}
		}

		public static void Initialize()
		{
		}

		static UserHints()
		{
			NotificationSystem.ReadyForScene += IssueFirstRunNoticeIfNecessary;
		}
	}
}
namespace Notiffy.Utils
{
	public static class Img2Sprite
	{
		public static Sprite LoadNewSprite(string filePath, float pixelsPerUnit = 100f, SpriteMeshType spriteType = 1)
		{
			//IL_0020: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = LoadTexture(filePath);
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0f, 0f), pixelsPerUnit, 0u, spriteType);
		}

		public static Sprite ConvertTextureToSprite(Texture2D texture, float pixelsPerUnit = 100f, SpriteMeshType spriteType = 1)
		{
			//IL_0019: 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)
			return Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0f, 0f), pixelsPerUnit, 0u, spriteType);
		}

		public static Texture2D LoadTexture(string FilePath)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (File.Exists(FilePath))
			{
				byte[] array = File.ReadAllBytes(FilePath);
				Texture2D val = new Texture2D(2, 2);
				if (ImageConversion.LoadImage(val, array))
				{
					return val;
				}
			}
			return null;
		}
	}
}
namespace Notiffy.UI
{
	internal static class MenuPatcher
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__TogglePanel;
		}

		private static string PauseNotifToggleButtonName;

		private static GameObject? FindNestedObject(GameObject baseObject, string path, bool warnings = true)
		{
			Transform val = baseObject.transform;
			string[] array = path.Split("/");
			foreach (string text in array)
			{
				val = ((Component)val).transform.Find(text);
				if ((Object)(object)val == (Object)null)
				{
					if (warnings)
					{
						NotiffyPlugin.Log.LogWarning((object)(text + " not found for object path " + ((Object)baseObject).name + "/" + path));
					}
					return null;
				}
			}
			return ((Component)val).gameObject;
		}

		public static void Initialize()
		{
		}

		static MenuPatcher()
		{
			PauseNotifToggleButtonName = "ToggleNotificationPanel";
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			PatchPauseMenu();
		}

		private static void PatchPauseMenu()
		{
			//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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_017a: 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)
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject baseObject = (from obj in ((Scene)(ref activeScene)).GetRootGameObjects()
				where ((Object)obj).name == "Canvas"
				select obj).FirstOrDefault();
			if (Object.op_Implicit((Object)(object)FindNestedObject(baseObject, "PauseMenu/" + PauseNotifToggleButtonName, warnings: false)))
			{
				return;
			}
			GameObject val = FindNestedObject(baseObject, "PauseMenu");
			GameObject val2 = FindNestedObject(baseObject, "PauseMenu/Resume");
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				GameObject val3 = Object.Instantiate<GameObject>(val2);
				val3.transform.SetParent(val.transform, false);
				((Object)val3).name = PauseNotifToggleButtonName;
				Button component = val3.GetComponent<Button>();
				component.onClick = new ButtonClickedEvent();
				ButtonClickedEvent onClick = component.onClick;
				object obj2 = <>O.<0>__TogglePanel;
				if (obj2 == null)
				{
					UnityAction val4 = NotificationController.TogglePanel;
					<>O.<0>__TogglePanel = val4;
					obj2 = (object)val4;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj2);
				RectTransform component2 = val3.GetComponent<RectTransform>();
				component2.sizeDelta = new Vector2(component2.sizeDelta.y, component2.sizeDelta.y);
				((Transform)component2).localPosition = new Vector3(170f, 90f, 0f);
				GameObject val5 = FindNestedObject(val3, "Text");
				if ((Object)(object)val5 != (Object)null)
				{
					Object.Destroy((Object)(object)val5);
				}
				GameObject obj3 = Object.Instantiate<GameObject>(NotificationController.Bundle.LoadAsset<GameObject>("NotiffyToggleIcon"));
				obj3.transform.SetParent(val3.transform, false);
				RectTransform component3 = obj3.GetComponent<RectTransform>();
				component3.anchorMin = new Vector2(0.33f, 0.33f);
				component3.anchorMax = new Vector2(0.67f, 0.67f);
				obj3.SetActive(true);
				val3.SetActive(true);
			}
		}
	}
	internal static class NotificationController
	{
		private enum NotificationArea
		{
			Popup,
			Panel,
			Both
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__27_0;

			public static UnityAction <>9__27_1;

			public static Func<GameObject, bool> <>9__29_0;

			internal void <LoadPanelFromBundle>b__27_0()
			{
				NotificationSystem.Server.ClearNotifications();
			}

			internal void <LoadPanelFromBundle>b__27_1()
			{
				ConfigManager.Silent.value = !ConfigManager.Silent.value;
				List<int> list = new List<int>();
				foreach (uint key in PopupNotifObjectDict.Keys)
				{
					list.Add((int)key);
				}
				foreach (int item in list)
				{
					OnNotificationClosed((uint)item);
				}
				UpdateSilentButtonFill();
			}

			internal bool <ParentStuffToCanvas>b__29_0(GameObject obj)
			{
				return ((Object)obj).name == "Canvas";
			}
		}

		private static readonly string BundlePath;

		private static GameObject? _notifPanel;

		private static GameObject? _notifPopupPanel;

		private const string PanelObjectName = "NotiffyPanel";

		private const string PopupPanelObjectName = "NotiffyPopupPanel";

		private static readonly NotificationServer Server;

		internal static readonly AssetBundle Bundle;

		private static readonly Dictionary<uint, GameObject> NotifObjectDict;

		private static readonly Dictionary<uint, GameObject> PopupNotifObjectDict;

		private static Sprite _largeBorder;

		private static Sprite _largeFill;

		static NotificationController()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			BundlePath = Path.Combine(NotiffyPlugin.workingDir, "assets", "notiffy_ui");
			Server = NotificationSystem.Server;
			NotifObjectDict = new Dictionary<uint, GameObject>();
			PopupNotifObjectDict = new Dictionary<uint, GameObject>();
			_largeBorder = Addressables.LoadAssetAsync<Sprite>((object)"Assets/Textures/UI/Controls/Round_BorderLarge.png").WaitForCompletion();
			_largeFill = Addressables.LoadAssetAsync<Sprite>((object)"Assets/Textures/UI/Controls/Round_FillLarge.png").WaitForCompletion();
			if (!((Object)(object)Bundle != (Object)null))
			{
				Bundle = AssetBundle.LoadFromFile(BundlePath);
				if ((Object)(object)Bundle == (Object)null)
				{
					NotiffyPlugin.Log.LogError((object)"Could not find asset bundle!");
				}
				SceneManager.sceneLoaded += OnSceneLoaded;
				Server.OnNotificationAdded += OnNotificationAdded;
				Server.OnNotificationUpdated += OnNotificationUpdated;
				Server.OnNotificationClosed += OnNotificationClosed;
				Server.OnNotificationDeleted += OnNotificationDeleted;
			}
		}

		public static void Initialize()
		{
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ParentStuffToCanvas();
			UpdateSilentButtonFill();
			NotificationSystem.SignalReadyForScene();
		}

		private static void OnNotificationAdded(uint id, Notification notif)
		{
			OnNotificationAdded(id, notif, NotificationArea.Both);
		}

		private static void OnNotificationAdded(uint id, Notification notif, NotificationArea area)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			if ((Object)(object)_notifPanel != (Object)null && area != 0)
			{
				Transform val = _notifPanel.transform.Find("Scroll View/Viewport/NotiffyPanelContent");
				GameObject val2 = CreateNotificationGameObject(notif, id);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.transform.SetParent(val, false);
					NotifObjectDict.Add(id, val2);
				}
				LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)val);
			}
			if (!ConfigManager.Silent.value && (Object)(object)_notifPopupPanel != (Object)null && _notifPopupPanel.activeSelf && area != NotificationArea.Panel)
			{
				Transform transform = _notifPopupPanel.transform;
				GameObject val3 = CreateNotificationGameObject(notif, id, isPopup: true);
				if ((Object)(object)val3 != (Object)null)
				{
					val3.transform.SetParent(transform, false);
					PopupNotifObjectDict.Add(id, val3);
				}
				LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)transform);
			}
			UpdatePanelEmptyPlaceholder();
		}

		private static void OnNotificationUpdated(uint id, Notification notif)
		{
			if (NotifObjectDict.TryGetValue(id, out GameObject value))
			{
				UpdateNotificationGameObjectContent(value, notif);
			}
			if (PopupNotifObjectDict.TryGetValue(id, out GameObject value2))
			{
				UpdateNotificationGameObjectContent(value2, notif);
			}
			UpdatePanelEmptyPlaceholder();
		}

		private static void OnNotificationClosed(uint id, ClosedReason reason = ClosedReason.Expired)
		{
			if (PopupNotifObjectDict.TryGetValue(id, out GameObject value))
			{
				Object.Destroy((Object)(object)value);
				PopupNotifObjectDict.Remove(id);
			}
		}

		private static void OnNotificationDeleted(uint id)
		{
			if (NotifObjectDict.TryGetValue(id, out GameObject value))
			{
				Object.Destroy((Object)(object)value);
				NotifObjectDict.Remove(id);
			}
			if (PopupNotifObjectDict.TryGetValue(id, out GameObject value2))
			{
				Object.Destroy((Object)(object)value2);
				PopupNotifObjectDict.Remove(id);
			}
			UpdatePanelEmptyPlaceholder();
		}

		private static void UpdateNotificationGameObjectContent(GameObject notifObj, Notification notif)
		{
			((TMP_Text)((Component)notifObj.transform.Find("NotificationTextLayout/SummaryText")).GetComponent<TextMeshProUGUI>()).text = notif.Summary;
			((TMP_Text)((Component)notifObj.transform.Find("NotificationTextLayout/BodyText")).GetComponent<TextMeshProUGUI>()).text = notif.Body;
			if ((Object)(object)notif.NotificationIcon != (Object)null)
			{
				((Component)notifObj.transform.Find("AppIconMask/Image")).GetComponent<Image>().sprite = notif.NotificationIcon;
			}
		}

		private static GameObject? CreateNotificationGameObject(Notification notif, uint id, bool isPopup = false)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(Bundle.LoadAsset<GameObject>("NotiffyNotification"));
			((UnityEvent)((Component)val.transform.Find("CloseButton")).GetComponent<Button>().onClick).AddListener(isPopup ? ((UnityAction)delegate
			{
				NotificationSystem.Server.CloseNotification(id, ClosedReason.Dismissed);
			}) : ((UnityAction)delegate
			{
				NotificationSystem.Server.DeleteNotification(id);
			}));
			UpdateNotificationGameObjectContent(val, notif);
			Transform val2 = val.transform.Find("NotificationTextLayout/ActionLayout");
			Transform val3 = val.transform.Find("NotificationTextLayout");
			List<string> actions = notif.Actions;
			if (actions != null && actions.Count > 0)
			{
				GameObject val4 = Bundle.LoadAsset<GameObject>("NotiffyActionButton");
				for (int i = 0; i + 1 < notif.Actions.Count; i += 2)
				{
					string identifier = notif.Actions[i];
					string text = notif.Actions[i + 1];
					GameObject obj = Object.Instantiate<GameObject>(val4);
					obj.transform.SetParent(((Component)val2).transform, false);
					((TMP_Text)obj.GetComponentInChildren<TextMeshProUGUI>()).text = text;
					((UnityEvent)obj.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
					{
						NotificationSystem.Server.InvokeAction(id, identifier);
					});
				}
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)val2).GetComponent<RectTransform>());
			LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)val3).GetComponent<RectTransform>());
			LayoutRebuilder.ForceRebuildLayoutImmediate(val.GetComponent<RectTransform>());
			val.SetActive(true);
			return val;
		}

		private static void SyncNotificationObjects()
		{
			NotifObjectDict.Clear();
			IReadOnlyList<NotificationEntry> history = NotificationSystem.Server.History;
			for (int i = 0; i < history.Count; i++)
			{
				OnNotificationAdded(history[i].Id, history[i].Data, NotificationArea.Panel);
			}
		}

		private static void SyncPopupNotificationObjects()
		{
			PopupNotifObjectDict.Clear();
			foreach (NotificationEntry activeNotification in NotificationSystem.Server.ActiveNotifications)
			{
				OnNotificationAdded(activeNotification.Id, activeNotification.Data, NotificationArea.Popup);
			}
		}

		private static void UpdateSilentButtonFill()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_notifPanel == (Object)null))
			{
				bool value = ConfigManager.Silent.value;
				Image component = ((Component)_notifPanel.transform.Find("Header/NotiffyHeaderSilent")).GetComponent<Image>();
				Image component2 = ((Component)_notifPanel.transform.Find("Header/NotiffyHeaderSilent/Image")).GetComponent<Image>();
				component.sprite = (value ? _largeFill : _largeBorder);
				((Graphic)component2).color = (value ? Color.black : Color.white);
			}
		}

		public static void UpdatePanelTitle()
		{
			if (!((Object)(object)_notifPanel == (Object)null))
			{
				string text = "NOTIFICATIONS<size=60%> [" + ConfigManager.GetFormattedPanelKeybind() + "]";
				((TMP_Text)((Component)_notifPanel.transform.Find("Header/NotiffyHeaderText")).GetComponent<TextMeshProUGUI>()).text = text;
			}
		}

		public static void UpdatePanelEmptyPlaceholder()
		{
			if (!((Object)(object)_notifPanel == (Object)null))
			{
				((Component)_notifPanel.transform.Find("Scroll View/EmptyPlaceholder")).gameObject.SetActive(NotifObjectDict.Count == 0);
			}
		}

		private static void LoadPanelFromBundle()
		{
			//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_0085: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			_notifPanel = Object.Instantiate<GameObject>(Bundle.LoadAsset<GameObject>("NotiffyPanel"));
			_notifPanel.SetActive(true);
			_notifPanel.SetActive(false);
			((Object)_notifPanel).name = "NotiffyPanel";
			Object.DontDestroyOnLoad((Object)(object)_notifPanel);
			ButtonClickedEvent onClick = ((Component)_notifPanel.transform.Find("Header/NotiffyHeaderClose")).GetComponent<Button>().onClick;
			object obj = <>c.<>9__27_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					NotificationSystem.Server.ClearNotifications();
				};
				<>c.<>9__27_0 = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			ButtonClickedEvent onClick2 = ((Component)_notifPanel.transform.Find("Header/NotiffyHeaderSilent")).GetComponent<Button>().onClick;
			object obj2 = <>c.<>9__27_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					ConfigManager.Silent.value = !ConfigManager.Silent.value;
					List<int> list = new List<int>();
					foreach (uint key in PopupNotifObjectDict.Keys)
					{
						list.Add((int)key);
					}
					foreach (int item in list)
					{
						OnNotificationClosed((uint)item);
					}
					UpdateSilentButtonFill();
				};
				<>c.<>9__27_1 = val2;
				obj2 = (object)val2;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			UpdatePanelTitle();
			UpdatePanelEmptyPlaceholder();
			SyncNotificationObjects();
		}

		private static void LoadPopupPanelFromBundle()
		{
			_notifPopupPanel = Object.Instantiate<GameObject>(Bundle.LoadAsset<GameObject>("NotiffyPopupContent"));
			_notifPopupPanel.SetActive(true);
			((Object)_notifPopupPanel).name = "NotiffyPopupPanel";
			Object.DontDestroyOnLoad((Object)(object)_notifPopupPanel);
			SyncPopupNotificationObjects();
		}

		private static void ParentStuffToCanvas()
		{
			//IL_004f: 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)
			if ((Object)(object)_notifPanel == (Object)null)
			{
				_notifPanel = GameObject.Find("NotiffyPanel");
				_notifPopupPanel = GameObject.Find("NotiffyPopupPanel");
				if ((Object)(object)_notifPanel == (Object)null)
				{
					LoadPanelFromBundle();
				}
				if ((Object)(object)_notifPopupPanel == (Object)null)
				{
					LoadPopupPanelFromBundle();
				}
			}
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject val = (from obj in ((Scene)(ref activeScene)).GetRootGameObjects()
				where ((Object)obj).name == "Canvas"
				select obj).FirstOrDefault();
			if ((Object)(object)val != (Object)null && (Object)(object)_notifPanel != (Object)null && (Object)(object)_notifPopupPanel != (Object)null)
			{
				Transform transform = _notifPanel.transform;
				Transform transform2 = _notifPopupPanel.transform;
				transform.SetParent(val.transform, false);
				transform2.SetParent(val.transform, false);
				transform.SetAsLastSibling();
				transform2.SetAsLastSibling();
			}
		}

		public static void TogglePanel()
		{
			_notifPanel.SetActive(!_notifPanel.activeSelf);
			_notifPopupPanel.SetActive(!_notifPanel.activeSelf);
			if (_notifPanel.activeSelf)
			{
				NotificationSystem.Server.ClearNotifications(delete: false);
				LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)_notifPanel.transform.Find("Scroll View/Viewport/NotiffyPanelContent")).GetComponent<RectTransform>());
			}
		}
	}
}
namespace Notiffy.Server
{
	internal class NotificationEntry
	{
		public Notification Data;

		public float StartTime;

		public uint Id;

		public NotificationEntry(Notification notification, uint id)
		{
			UpdateNotification(notification);
			Id = id;
		}

		public void UpdateNotification(Notification notification)
		{
			Data = notification;
			StartTime = Time.time;
		}

		public bool IsTimedout()
		{
			return Time.time >= StartTime + (float)Data.ExpirationTimeout;
		}
	}
	internal class NotificationServer : MonoBehaviour, INotificationServer
	{
		private ManualLogSource Log;

		private readonly Dictionary<uint, NotificationEntry> _activeNotifs;

		private uint _nextId = 1u;

		private readonly List<uint> _removalBuffer = new List<uint>();

		private readonly List<NotificationEntry> _history = new List<NotificationEntry>();

		public IReadOnlyList<NotificationEntry> History => _history;

		public IEnumerable<NotificationEntry> ActiveNotifications => _activeNotifs.Values;

		public event Action<uint, Notification>? OnNotificationAdded;

		public event Action<uint, Notification>? OnNotificationUpdated;

		public event Action<uint, ClosedReason>? OnNotificationClosed;

		public event Action<uint>? OnNotificationDeleted;

		public event Action<uint, ClosedReason>? NotificationClosed;

		public event Action<uint>? NotificationDeleted;

		public event Action<uint, string>? ActionInvoked;

		private bool NotificationIsActive(uint id)
		{
			return _activeNotifs.ContainsKey(id);
		}

		public void TrimHistory()
		{
			if (_history.Count <= ConfigManager.MaxHistory.value)
			{
				return;
			}
			_removalBuffer.Clear();
			for (int i = 0; i < _history.Count - ConfigManager.MaxHistory.value; i++)
			{
				NotificationEntry notificationEntry = _history[i];
				_removalBuffer.Add(notificationEntry.Id);
			}
			foreach (uint item in _removalBuffer)
			{
				DeleteNotification(item);
			}
		}

		private void AddToHistory(NotificationEntry notification)
		{
			_history.Add(notification);
			TrimHistory();
		}

		private void RemoveFromHistory(uint id)
		{
			int num = _history.FindIndex((NotificationEntry x) => x.Id == id);
			if (num != -1)
			{
				_history.RemoveAt(num);
			}
		}

		public void DeleteNotification(uint id, ClosedReason reason = ClosedReason.Dismissed, bool notifySenders = true)
		{
			if (NotificationIsActive(id))
			{
				CloseNotification(id, reason, notifySenders);
			}
			if (_history.FindIndex((NotificationEntry x) => x.Id == id) != -1)
			{
				RemoveFromHistory(id);
				if (notifySenders)
				{
					this.NotificationDeleted?.Invoke(id);
				}
				this.OnNotificationDeleted?.Invoke(id);
			}
		}

		public void CloseNotification(uint id, ClosedReason reason, bool notifySenders = true)
		{
			if (NotificationIsActive(id))
			{
				_activeNotifs.Remove(id);
				if (notifySenders)
				{
					this.NotificationClosed?.Invoke(id, reason);
				}
				this.OnNotificationClosed?.Invoke(id, reason);
			}
		}

		public void ClearNotifications(bool delete = true)
		{
			_removalBuffer.Clear();
			foreach (NotificationEntry item in _history)
			{
				_removalBuffer.Add(item.Id);
			}
			foreach (uint item2 in _removalBuffer)
			{
				if (delete)
				{
					DeleteNotification(item2);
				}
				else
				{
					CloseNotification(item2, ClosedReason.Dismissed);
				}
			}
		}

		public void InvokeAction(uint id, string actionIdentifier)
		{
			DeleteNotification(id, ClosedReason.Dismissed, notifySenders: false);
			this.ActionInvoked?.Invoke(id, actionIdentifier);
		}

		public uint Notify(Notification notification)
		{
			uint num;
			if (notification.ReplacesId != 0 && _activeNotifs.TryGetValue(notification.ReplacesId, out NotificationEntry value))
			{
				value.UpdateNotification(notification);
				num = notification.ReplacesId;
				this.OnNotificationUpdated?.Invoke(num, notification);
			}
			else
			{
				num = _nextId++;
				NotificationEntry notificationEntry = new NotificationEntry(notification, num);
				_activeNotifs.Add(num, notificationEntry);
				AddToHistory(notificationEntry);
				this.OnNotificationAdded?.Invoke(num, notification);
			}
			return num;
		}

		public void CloseNotification(uint id)
		{
			CloseNotification(id, ClosedReason.APIClosed);
		}

		public NotificationServer()
		{
			Log = Logger.CreateLogSource("Notiffy.Server");
			_activeNotifs = new Dictionary<uint, NotificationEntry>();
			Log.LogInfo((object)"Initialized");
		}

		private void Update()
		{
			if (_activeNotifs.Count == 0)
			{
				return;
			}
			float time = Time.time;
			_removalBuffer.Clear();
			foreach (NotificationEntry value2 in _activeNotifs.Values)
			{
				float num = ((value2.Data.ExpirationTimeout > 0) ? ((float)(value2.Data.ExpirationTimeout / 1000)) : ConfigManager.DefaultTimeout.value);
				Dictionary<string, object> hints = value2.Data.Hints;
				if (hints != null && hints.TryGetValue("urgency", out object value) && (Urgency)value == Urgency.Critical)
				{
					num = time - value2.StartTime + 1f;
				}
				if (time - value2.StartTime >= num)
				{
					_removalBuffer.Add(value2.Id);
				}
			}
			for (int i = 0; i < _removalBuffer.Count; i++)
			{
				CloseNotification(_removalBuffer[i], ClosedReason.Expired);
			}
		}
	}
}
namespace Notiffy.API
{
	public enum ClosedReason : uint
	{
		Expired = 1u,
		Dismissed,
		APIClosed,
		Undefined
	}
	public interface INotificationServer
	{
		event Action<uint, ClosedReason>? NotificationClosed;

		event Action<uint>? NotificationDeleted;

		event Action<uint, string>? ActionInvoked;

		uint Notify(Notification notification);

		void CloseNotification(uint id);
	}
	public struct Notification
	{
		public string ApplicationName;

		public uint ReplacesId;

		public Sprite NotificationIcon;

		public string Summary;

		public string Body;

		public int ExpirationTimeout;

		public Dictionary<string, object> Hints;

		public List<string> Actions;
	}
	public static class NotificationSystem
	{
		internal static NotificationServer Server;

		public static event Action<uint, ClosedReason> NotificationClosed
		{
			add
			{
				Server.NotificationClosed += value;
			}
			remove
			{
				Server.NotificationClosed -= value;
			}
		}

		public static event Action<uint> NotificationDeleted
		{
			add
			{
				Server.NotificationDeleted += value;
			}
			remove
			{
				Server.NotificationDeleted -= value;
			}
		}

		public static event Action<uint, string> ActionInvoked
		{
			add
			{
				Server.ActionInvoked += value;
			}
			remove
			{
				Server.ActionInvoked -= value;
			}
		}

		[Obsolete]
		public static event Action ReadyForScene;

		public static uint NotifySend(string summary, string body, Sprite iconSprite = null, string iconFilePath = "", Urgency urgency = Urgency.Normal, string appName = "NotifySend", uint replaceId = 0u, Dictionary<string, string> actions = null, int expireTime = -1)
		{
			Notification notification = default(Notification);
			notification.Summary = summary;
			notification.Body = body;
			Notification notification2 = notification;
			notification2.ApplicationName = appName;
			if (iconFilePath != "")
			{
				Sprite notificationIcon = Img2Sprite.LoadNewSprite(iconFilePath, 100f, (SpriteMeshType)1);
				notification2.NotificationIcon = notificationIcon;
			}
			else if ((Object)(object)iconSprite != (Object)null)
			{
				notification2.NotificationIcon = iconSprite;
			}
			notification2.ExpirationTimeout = expireTime;
			if (replaceId != 0)
			{
				notification2.ReplacesId = replaceId;
			}
			if (actions != null)
			{
				notification2.Actions = new List<string>();
				foreach (KeyValuePair<string, string> action in actions)
				{
					notification2.Actions.Add(action.Key);
					notification2.Actions.Add(action.Value);
				}
			}
			if (urgency != Urgency.Normal)
			{
				notification2.Hints = new Dictionary<string, object>();
				if (urgency != Urgency.Normal)
				{
					notification2.Hints.Add("urgency", urgency);
				}
			}
			return Notify(notification2);
		}

		public static uint Notify(Notification notification)
		{
			return Server.Notify(notification);
		}

		public static void CloseNotification(uint id)
		{
			Server.CloseNotification(id);
		}

		internal static void SignalReadyForScene()
		{
			NotificationSystem.ReadyForScene?.Invoke();
		}

		internal static void Initialize()
		{
		}

		static NotificationSystem()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			GameObject val = new GameObject("Notiffy_Server");
			Server = val.AddComponent<NotificationServer>();
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
		}
	}
	public enum Urgency : uint
	{
		Low,
		Normal,
		Critical
	}
}