Иконка ресурса

FREE Notifications : 1.0.1 1.0.1

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using WebSocketSharp;

namespace Oxide.Plugins
{
	[Info("Notifications", "Mevent", "1.0.1")]
	[Description("Adds an notification system")]
	public class Notifications : RustPlugin
	{
		#region Fields

		[PluginReference] private Plugin ImageLibrary;

		private static Notifications _instance;

		private const string Layer = "Com.Mevent.Notification";

		#endregion

		#region Config

		private static Configuration _config;

		private class Configuration
		{
			[JsonProperty(PropertyName = "Настройка интерфейса | Interface Settings")]
			public IBackground Background = new IBackground
			{
				AnchorMin = "1 0",
				AnchorMax = "1 0",
				Height = 105,
				Width = 300,
				Margin = 5,
				Color = new IColor("#28253C", 98),
				Icon = new InterfacePosition
				{
					AnchorMin = "0 1", AnchorMax = "0 1",
					OffsetMin = "10 -30", OffsetMax = "30 -10"
				},
				Title = new IText
				{
					AnchorMin = "0.5 1", AnchorMax = "0.5 1",
					OffsetMin = "-100 -35", OffsetMax = "100 -5",
					FontSize = 18,
					Font = "robotocondensed-bold.ttf",
					Align = TextAnchor.MiddleCenter,
					Color = new IColor("#FFFFFF", 100)
				},
				Description = new IText
				{
					AnchorMin = "0.5 0", AnchorMax = "0.5 0",
					OffsetMin = "-140 20", OffsetMax = "140 75",
					FontSize = 16,
					Font = "robotocondensed-regular.ttf",
					Align = TextAnchor.MiddleCenter,
					Color = new IColor("#4D4A62", 100)
				},
				Close = new IText
				{
					AnchorMin = "1 1", AnchorMax = "1 1",
					OffsetMin = "-25 -25", OffsetMax = "-5 -5",
					FontSize = 16,
					Font = "robotocondensed-bold.ttf",
					Align = TextAnchor.MiddleCenter,
					Color = new IColor("#4D4A62", 100)
				}
			};
		}

		private class IText : InterfacePosition
		{
			[JsonProperty(PropertyName = "Font Size")]
			public int FontSize;

			[JsonProperty(PropertyName = "Font")] public string Font;

			[JsonProperty(PropertyName = "Align")] [JsonConverter(typeof(StringEnumConverter))]
			public TextAnchor Align;

			[JsonProperty(PropertyName = "Text Color")]
			public IColor Color;

			public void Get(ref CuiElementContainer container, string parent = "Hud", string name = null,
				string text = "")
			{
				if (string.IsNullOrEmpty(name))
					name = CuiHelper.GetGuid();

				container.Add(new CuiLabel
				{
					RectTransform =
						{AnchorMin = AnchorMin, AnchorMax = AnchorMax, OffsetMin = OffsetMin, OffsetMax = OffsetMax},
					Text =
					{
						Text = text, Align = Align, FontSize = FontSize, Color = Color.Get(),
						Font = Font
					}
				}, parent, name);
			}
		}


		private abstract class IAnchors
		{
			public string AnchorMin;

			public string AnchorMax;
		}

		private class IBackground : IAnchors
		{
			[JsonProperty(PropertyName = "Высота | Height")]
			public float Height;

			[JsonProperty(PropertyName = "Ширина | Width")]
			public float Width;

			[JsonProperty(PropertyName = "Отступ | Margin")]
			public float Margin;

			[JsonProperty(PropertyName = "Цвет | Color")]
			public IColor Color;

			[JsonProperty(PropertyName = "Иконка | Icon")]
			public InterfacePosition Icon;

			[JsonProperty(PropertyName = "Заглавие | Title")]
			public IText Title;

			[JsonProperty(PropertyName = "Описание | Description")]
			public IText Description;

			[JsonProperty(PropertyName = "Закрыть | Close")]
			public IText Close;
		}

		private class InterfacePosition : IAnchors
		{
			public string OffsetMin;

			public string OffsetMax;
		}

		private class IColor
		{
			[JsonProperty(PropertyName = "HEX")] public string HEX;

			[JsonProperty(PropertyName = "Непрозрачность | Opacity (0 - 100)")]
			public float Alpha;

			public string Get()
			{
				if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF";

				var str = HEX.Trim('#');
				if (str.Length != 6) throw new Exception(HEX);
				var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
				var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
				var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);

				return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
			}

			public IColor(string hex, float alpha)
			{
				HEX = hex;
				Alpha = alpha;
			}
		}

		protected override void LoadConfig()
		{
			base.LoadConfig();
			try
			{
				_config = Config.ReadObject<Configuration>();
				if (_config == null) throw new Exception();
				SaveConfig();
			}
			catch
			{
				PrintError("Your configuration file contains an error.Using default configuration values.");
				LoadDefaultConfig();
			}
		}

		protected override void SaveConfig()
		{
			Config.WriteObject(_config);
		}

		protected override void LoadDefaultConfig()
		{
			_config = new Configuration();
		}

		#endregion

		#region Data

		private PluginData _data;

		private void SaveData()
		{
			Interface.Oxide.DataFileSystem.WriteObject(Name, _data);
		}

		private void LoadData()
		{
			try
			{
				_data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
			}
			catch (Exception e)
			{
				PrintError(e.ToString());
			}

			if (_data == null) _data = new PluginData();
		}

		private class PluginData
		{
			[JsonProperty(PropertyName = "Image List", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public Dictionary<string, string> Images = new Dictionary<string, string>
			{
				["warning"] = "https://i.imgur.com/p3tKXJV.png"
			};
		}

		#endregion

		#region Hooks

		private void Init()
		{
			_instance = this;
			LoadData();
		}

		private void OnServerInitialized()
		{
			if (!ImageLibrary)
				PrintWarning("IMAGE LIBRARY IS NOT INSTALLED.");
			else
				foreach (var image in _data.Images)
					ImageLibrary.Call("AddImage", image.Value, image.Key);
		}

		private void Unload()
		{
			foreach (var player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, Layer);

			SaveData();

			_instance = null;
			_config = null;
		}

		#endregion

		#region Commands

		[ConsoleCommand("UI_Notifications")]
		private void CmdConsoleNotify(ConsoleSystem.Arg arg)
		{
			var player = arg?.Player();
			if (player == null || !arg.HasArgs()) return;

			switch (arg.Args[0])
			{
				case "remove":
				{
					int index;
					if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out index)) return;
					
					player.GetComponent<NotifyComponent>()?.RemoveByIndex(index);
					break;
				}
			}
		}

		#endregion

		#region Component

		private class UiNotify
		{
			public readonly string GUID;
			
			public float TimeLeft;

			public readonly string Title;

			public readonly string Description;

			public readonly string Image;

			public readonly CuiElementContainer Container;

			public UiNotify(string guid, float delay, string title, string description, string image, CuiElementContainer cont = null)
			{
				GUID = guid;
				TimeLeft = delay;
				Title = title;
				Description = description;
				Image = image;
				
				Container = cont ?? new CuiElementContainer();
			}
		}

		private class NotifyComponent : FacepunchBehaviour
		{
			private BasePlayer _player;

			private readonly List<UiNotify> _notifies = new List<UiNotify>();

			private const float _timer = 0.1f;

			private void Awake()
			{
				_player = GetComponent<BasePlayer>();

				Invoke(TimeHandle, _timer);
			}

			private void TimeHandle()
			{
				CancelInvoke();
				if (_player == null)
				{
					Kill();
					return;
				}

				var toRemove = new List<UiNotify>();

				_notifies.ForEach(notify =>
				{
					notify.TimeLeft -= _timer;
					if (notify.TimeLeft <= 0) toRemove.Add(notify);
				});

				if (toRemove.Count > 0)
				{
					toRemove.ForEach(notify =>
					{
						Interface.Oxide.CallHook("OnNotifyRemove", _player, notify.GUID);
						_notifies.Remove(notify);
					});

					if (_notifies.Count <= 0)
						Kill();
					else
						RefreshUi();
				}

				if (_notifies.Count > 0)
				{
					Invoke(TimeHandle, _timer);
				}
			}

			private void RefreshUi()
			{
				if (_player == null)
				{
					Kill();
					return;
				}

				var container = new CuiElementContainer();

				container.Add(new CuiPanel
				{
					RectTransform =
					{
						AnchorMin = _config.Background.AnchorMin,
						AnchorMax = _config.Background.AnchorMax
					},
					Image = {Color = "0 0 0 0"}
				}, "Overlay", Layer);

				var ySwitch = _config.Background.Margin;
				for (var i = 0; i < _notifies.Count; i++)
				{
					var notify = _notifies[i];

					container.Add(new CuiPanel
					{
						RectTransform =
						{
							AnchorMin = "0 0",
							AnchorMax = "1 1",
							OffsetMin =
								$"-{_config.Background.Width + _config.Background.Margin} {ySwitch}",
							OffsetMax =
								$"-{_config.Background.Margin} {ySwitch + _config.Background.Height}"
						},
						Image =
						{
							Color = _config.Background.Color.Get()
						}
					}, Layer, Layer + $".Notify.{i}");

					if (!notify.Image.IsNullOrEmpty() && _instance._data.Images.ContainsKey(notify.Image))
					{
						container.Add(new CuiElement
						{
							Parent = Layer + $".Notify.{i}",
							Components =
							{
								new CuiRawImageComponent
								{
									Png = _instance.ImageLibrary.Call<string>("GetImage", notify.Image)
								},
								new CuiRectTransformComponent
								{
									AnchorMin = _config.Background.Icon.AnchorMin,
									AnchorMax = _config.Background.Icon.AnchorMax,
									OffsetMin = _config.Background.Icon.OffsetMin,
									OffsetMax = _config.Background.Icon.OffsetMax
								}
							}
						});}

					_config.Background.Title.Get(ref container, Layer + $".Notify.{i}", null, notify.Title);

					_config.Background.Description.Get(ref container, Layer + $".Notify.{i}", null, notify.Description);

					_config.Background.Close.Get(ref container, Layer + $".Notify.{i}", Layer + $".Notify.{i}.Close",
						"✕");

					container.Add(new CuiButton
					{
						RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
						Text = {Text = ""},
						Button =
						{
							Color = "0 0 0 0",
							Command = $"UI_Notifications remove {_notifies.IndexOf(notify)}"
						}
					}, Layer + $".Notify.{i}.Close");
					
					foreach (var element in notify.Container)
					{
						if (element.Parent.IsNullOrEmpty()) 
							element.Parent = Layer + $".Notify.{i}";
						
						container.Add(element);
					}
					
					ySwitch += _config.Background.Height + _config.Background.Margin;
				}
				
				
				CuiHelper.DestroyUi(_player, Layer);
				CuiHelper.AddUi(_player, container);
			}

			public void RemoveByGuid(string guid)
			{
				_notifies.ToList().ForEach(notify =>
				{
					if (notify.GUID == guid && Interface.Oxide.CallHook("OnNotifyRemove", _player, notify.GUID) == null)
					{
						_notifies.Remove(notify);
					}
				});
				
				RefreshUi();
			}
			
			public void RemoveByIndex(int index)
			{
				if (index < 0 || _notifies.Count <= index) return;

				var notify = _notifies[index];

				if (Interface.Oxide.CallHook("OnNotifyRemove", _player, notify.GUID) == null) 
					_notifies.Remove(notify);

				RefreshUi();
			}

			public void AddNotify(UiNotify notyify)
			{
				_notifies.Add(notyify);

				if (!IsInvoking(TimeHandle))
					Invoke(TimeHandle, _timer);
				
				RefreshUi();
			}

			private void OnDestroy()
			{
				CancelInvoke();

				if (_player != null)
					CuiHelper.DestroyUi(_player, Layer);

				Destroy(this);
			}

			public void Kill()
			{
				Destroy(this);
			}
		}

		#endregion

		#region API

		private void AddImage(string image, string url)
		{
			if (_data.Images.ContainsKey(image))
				_data.Images[image] = url;
			else
				_data.Images.Add(image, url);

			ImageLibrary.Call("AddImage", url, image);
		}

		private void ShowNotify(ulong user, float delay, string title, string description, string image, CuiElementContainer container = null)
		{
			ShowNotify(BasePlayer.FindByID(user), delay, title, description, image, container);
		}

		private void RemoveNotify(BasePlayer player, string guid)
		{
			if (player == null) return;
			
			var notify = player.GetComponent<NotifyComponent>() ?? player.gameObject.AddComponent<NotifyComponent>();
			if (notify == null) return;

			notify.RemoveByGuid(guid);
		}
		
		private string ShowNotify(BasePlayer player, float delay, string title, string description, string image, CuiElementContainer container = null)
		{
			if (player == null) return string.Empty; 
			
			var notify = player.GetComponent<NotifyComponent>() ?? player.gameObject.AddComponent<NotifyComponent>();
			if (notify == null) return string.Empty;

			var uiNotify = new UiNotify(CuiHelper.GetGuid(), delay, title, description, image, container);
			notify.AddNotify(uiNotify);
			return uiNotify.GUID;
		}
		
		#endregion
	}
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху