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

FREE WipeStatus : 0.1.5 0.1.5

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using System.Globalization;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;

namespace Oxide.Plugins
{
	[Info("Wipe Status", "IIIaKa", "0.1.5")]
	[Description("The plugin displays the time until the next wipe in the status bar.Depends on AdvancedStatus plugin.")]
	class WipeStatus : RustPlugin
	{
		[PluginReference]
		private Plugin ImageLibrary, AdvancedStatus;

		#region ~Variables~
		private int _imgLibCheck = 0;
		private bool _imgLibIsLoaded = false;
		private bool _statusIsLoaded = false;
		private const string PERMISSION_ADMIN = "wipestatus.admin";
		private const string _barID = "WipeStatus_";
		private double _timeStamp = 0d;
		private Timer _timer;
		#endregion

		#region ~Configuration~
		private static Configuration _config;

		private class Configuration
		{
			[JsonProperty(PropertyName = "ImageLibrary Counter Check")]
			public int ImgLibCounter = 5;
			
			[JsonProperty(PropertyName = "Wipe command")]
			public string Command = "wipe";
			
			[JsonProperty(PropertyName = "Use GameTip for messages?")]
			public bool Use_GameTips = true;
			
			[JsonProperty("Is it worth displaying the wipe timer only when players in the safe zone or building privilege?")]
			public bool Status_InSafeZone = false;
			
			[JsonProperty(PropertyName = "When should it start displaying? Based on how many days are left(0 to display always)")]
			public int Status_Days_Left = 0;
			
			[JsonProperty(PropertyName = "Custom wipe dates list(empty to use default).Format: yyyy-MM-dd HH:mm.Example: 2023-12-10 13:00")]
			public List<string> Custom_Date_List = new List<string>();
			
			[JsonProperty(PropertyName = "Status.Bar - Height")]
			public int Status_Bar_Height = 26;
			
			[JsonProperty(PropertyName = "Status.Bar - Order")]
			public int Status_Bar_Order = 10;
			
			[JsonProperty("Status.Background - Color")]
			public string Status_Background_Color = "#0370A4";
			
			[JsonProperty(PropertyName = "Status.Background - Transparency")]
			public float Status_Background_Transparency = 0.7f;
			
			[JsonProperty(PropertyName = "Status.Background - Material(empty to disable)")]
			public string Status_Background_Material = "";
			
			[JsonProperty("Status.Image - URL")]
			public string Status_Image_Url = "https://i.imgur.com/FKrFYN5.png";
			
			[JsonProperty(PropertyName = "Status.Image - Sprite(empty to use image from URL)")]
			public string Status_Image_Sprite = "";
			
			[JsonProperty("Status.Image - Is raw image")]
			public bool Status_Image_IsRawImage = false;
			
			[JsonProperty("Status.Image - Color")]
			public string Status_Image_Color = "#0370A4";
			
			[JsonProperty(PropertyName = "Status.Text - Size")]
			public int Status_Text_Size = 12;
			
			[JsonProperty("Status.Text - Color")]
			public string Status_Text_Color = "#FFFFFF";
			
			[JsonProperty(PropertyName = "Status.Text - Font(https://umod.org/guides/rust/basic-concepts-of-gui#fonts)")]
			public string Status_Text_Font = "RobotoCondensed-Bold.ttf";
			
			[JsonProperty(PropertyName = "Status.SubText - Size")]
			public int Status_SubText_Size = 12;

			[JsonProperty("Status.SubText - Color")]
			public string Status_SubText_Color = "#FFFFFF";

			[JsonProperty(PropertyName = "Status.SubText - Font(https://umod.org/guides/rust/basic-concepts-of-gui#fonts)")]
			public string Status_SubText_Font = "RobotoCondensed-Bold.ttf";
			
			public Oxide.Core.VersionNumber Version;
		}
		
		protected override void LoadConfig()
		{
			base.LoadConfig();
			try
			{
				_config = Config.ReadObject<Configuration>();
				if (_config == null)
				{
					PrintWarning("Configuration file not found.Creating a new one...");
					LoadDefaultConfig();
				}
				else if (_config.Version < Version)
				{
					PrintWarning($"Your configuration file version({_config.Version}) is outdated.Updating it to {Version}.");
					LoadDefaultConfig();
					_config.Version = Version;
					PrintWarning($"The configuration file has been successfully updated to version {_config.Version}!");
				}
				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 ~DataFile~
		private static StoredData _storedData;

		private class StoredData
		{
			[JsonProperty(PropertyName = "List of players.")]
			public Dictionary<ulong, bool> PlayersList = new Dictionary<ulong, bool>();
		}
		
		private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, _storedData);
		#endregion
		
		#region ~Language~
		protected override void LoadDefaultMessages()
		{
			lang.RegisterMessages(new Dictionary<string, string>
			{
				["MsgText"] = "WIPE IN",
				["MsgNewDateAdded"] = "The new date {0} has been successfully added.",
				["MsgNewDateAddFailed"] = "Invalid format or date is earlier than the current one.Date format: yyyy-MM-dd HH:mm",
				["MsgClearDates"] = "Custom dates list has been successfully cleared!",
				["MsgSetBar"] = "Displaying the bar: {0}"
			}, this);
			lang.RegisterMessages(new Dictionary<string, string>
			{
				["MsgText"] = "ВАЙП ЧЕРЕЗ",
				["MsgNewDateAdded"] = "Новая дата {0} успешно добавлена.",
				["MsgNewDateAddFailed"] = "Не верный формат или дата меньше текущей.Формат даты: yyyy-MM-dd HH:mm",
				["MsgClearDates"] = "Список дат был успешно очищен!",
				["MsgSetBar"] = "Отображение бара: {0}"
			}, this, "ru");
		}
		#endregion
		
		#region ~Methods~
		private void ImgLibCheck()
		{
			if (ImageLibrary == null || !ImageLibrary.IsLoaded)
			{
				_imgLibCheck++;

				if (_imgLibCheck >= _config.ImgLibCounter)
				{
					PrintError("ImageLibrary appears to be missing or occupied by other plugins load orders.For full plugin functionality, it is recommended to load ImageLibrary plugin.", _config.ImgLibCounter, Name);
					return;
				}

				timer.In(60, ImgLibCheck);
				if (ImageLibrary == null)
					PrintWarning("ImageLibrary is NOT loaded! Waiting ImageLibrary...");
				else
					PrintWarning("ImageLibrary appears to be occupied will check again in 1 minute.");
				return;
			}

			_imgLibCheck = 0;
			_imgLibIsLoaded = true;
			LoadImgs();
		}

		private void LoadImgs()
		{
			if (_config.Status_Image_Url.StartsWithAny(new string[2] { "http://", "https://" }))
			{
				Dictionary<string, string> imgList = new Dictionary<string, string>() { { $"{Name}_Wipe", _config.Status_Image_Url } };
				ImageLibrary?.Call("ImportImageList", Name, imgList, 0UL, true);
			}
		}
		
		private void SendBar(BasePlayer player)
		{
			if (!player.IsConnected || (_storedData.PlayersList.TryGetValue(player.userID, out var canShow) && !canShow)) return;
			if (_config.Status_InSafeZone && !player.InSafeZone() && !InBuildingPrivilege(player)) return;
			Dictionary<string, object> parameters = new Dictionary<string, object>
			{
				{ "Id", _barID },
				{ "BarType", "TimeCounter" },
				{ "Plugin", Name },
				{ "Order", _config.Status_Bar_Order },
				{ "Height", _config.Status_Bar_Height },
				{ "Main_Color", _config.Status_Background_Color },
				{ "Main_Transparency", _config.Status_Background_Transparency },
				{ "Main_Material", _config.Status_Background_Material },
				{ "Image", _imgLibIsLoaded && _config.Status_Image_Url.StartsWithAny(new string[2] { "http://", "https://" }) ? $"{Name}_Wipe" : _config.Status_Image_Url },
				{ "Image_Sprite", _config.Status_Image_Sprite },
				{ "Is_RawImage", _config.Status_Image_IsRawImage },
				{ "Image_Color", _config.Status_Image_Color },
				{ "Text", lang.GetMessage("MsgText", this, player.UserIDString) },
				{ "Text_Size", _config.Status_Text_Size },
				{ "Text_Color", _config.Status_Text_Color },
				{ "Text_Font", _config.Status_Text_Font },
				{ "SubText_Size", _config.Status_SubText_Size },
				{ "SubText_Color", _config.Status_SubText_Color },
				{ "SubText_Font", _config.Status_SubText_Font },
				{ "TimeStamp", _timeStamp }
			};
			AdvancedStatus?.Call("CreateBar", player.userID, parameters);
		}
		
		private bool InBuildingPrivilege(BasePlayer player) => (bool)(AdvancedStatus?.Call("InBuildingPrivilege", player) ?? false);
		
		private bool GetSpanUntilWipe(out TimeSpan result)
		{
			if (!GetCustomSpan(out result) && WipeTimer.serverinstance != null)
				result = WipeTimer.serverinstance.GetTimeSpanUntilWipe();
			else
				PrintWarning("The custom date list is empty, and the vanilla wipe date could not be obtained! You need to add the date manually.");
			return result != TimeSpan.Zero;
			
			bool GetCustomSpan(out TimeSpan customSpan)
			{
				customSpan = TimeSpan.Zero;
				if (_config.Custom_Date_List.Any())
				{
					var minDate = DateTime.MaxValue;
					foreach (var dateString in _config.Custom_Date_List)
					{
						if (DateTime.TryParseExact(dateString, "yyyy-MM-dd HH:mm", null, DateTimeStyles.None, out var date) && date > DateTime.Now && date < minDate)
							minDate = date;
					}
					if (minDate != DateTime.MaxValue)
						customSpan = minDate.Subtract(DateTime.Now);
				}
				return customSpan != TimeSpan.Zero;
			}
		}
		
		private void TryDisplay()
		{
			if (!_statusIsLoaded || !GetSpanUntilWipe(out var timeSpan)) return;
			_timeStamp = timeSpan.TotalSeconds + Network.TimeEx.currentTimestamp;
			if (_config.Status_Days_Left == 0 || ((int)Math.Ceiling(timeSpan.TotalDays) <= _config.Status_Days_Left))
			{
				foreach (var player in BasePlayer.activePlayerList)
				{
					if (player.IsNpc) continue;
					SendBar(player);
				}
				Subscribe(nameof(OnPlayerConnected));
				Subscribe(nameof(OnPlayerSetInfo));
				if (_config.Status_InSafeZone)
				{
					Subscribe(nameof(OnEntityEnter));
					Subscribe(nameof(OnEntityLeave));
					Subscribe(nameof(OnPlayerGainedBuildingPrivilege));
					Subscribe(nameof(OnPlayerLostBuildingPrivilege));
				}
				if (_timer != null)
					_timer.Destroy();
				_timer = timer.Once((float)(timeSpan.TotalSeconds + 1), () =>
				{
					Unsubscribe(nameof(OnPlayerConnected));
					Unsubscribe(nameof(OnPlayerSetInfo));
					Unsubscribe(nameof(OnEntityEnter));
					Unsubscribe(nameof(OnEntityLeave));
					Unsubscribe(nameof(OnPlayerGainedBuildingPrivilege));
					Unsubscribe(nameof(OnPlayerLostBuildingPrivilege));
					TryDisplay();
				});
			}
			else
            {
				_timeStamp = 0d;
				_timer = timer.Once((float)(timeSpan.TotalSeconds - TimeSpan.FromDays(_config.Status_Days_Left).TotalSeconds), () => { TryDisplay(); });
			}
		}
		#endregion

		#region ~Hooks~
		void OnPlayerConnected(BasePlayer player) => SendBar(player);
		
		void OnPlayerSetInfo(Network.Connection connection, string key, string value)
		{
			if (key == "global.language" && BasePlayer.FindByID(connection?.userid ?? 0) is BasePlayer player)
            {
				if (_storedData.PlayersList.TryGetValue(player.userID, out var canShow) && !canShow) return;
				if (_config.Status_InSafeZone && !player.InSafeZone() && !InBuildingPrivilege(player)) return;
				AdvancedStatus?.Call("UpdateContent", player.userID, new Dictionary<string, object>
				{
					{ "Id", _barID },
					{ "Plugin", Name },
					{ "Text", lang.GetMessage("MsgText", this, player.UserIDString) }
				});
			}
		}
		
		void OnEntityEnter(TriggerSafeZone trigger, BasePlayer player) => SendBar(player);
		
		void OnEntityLeave(TriggerSafeZone trigger, BasePlayer player)
		{
			if (!player.InSafeZone())
				AdvancedStatus?.Call("DeleteBar", player, _barID, Name);
		}
		
		void OnPlayerGainedBuildingPrivilege(BasePlayer player) => SendBar(player);
		
		void OnPlayerLostBuildingPrivilege(BasePlayer player) => AdvancedStatus?.Call("DeleteBar", player, _barID, Name);
		
		void OnPluginLoaded(Plugin plugin)
		{
			if (plugin == ImageLibrary)
				ImgLibCheck();
			else if (plugin == AdvancedStatus)
			{
				_statusIsLoaded = plugin.IsLoaded;
				TryDisplay();
			}
		}
		
		void OnPluginUnloaded(Plugin plugin)
		{
			if (plugin.Name == "ImageLibrary")
				_imgLibIsLoaded = false;
			if (plugin.Name == "AdvancedStatus")
            {
				_statusIsLoaded = false;
				if (_timer != null)
					_timer.Destroy();
				Unsubscribe(nameof(OnPlayerConnected));
				Unsubscribe(nameof(OnPlayerSetInfo));
				Unsubscribe(nameof(OnEntityEnter));
				Unsubscribe(nameof(OnEntityLeave));
				Unsubscribe(nameof(OnPlayerGainedBuildingPrivilege));
				Unsubscribe(nameof(OnPlayerLostBuildingPrivilege));
				_timeStamp = 0d;
			}
		}
		
		void Init()
		{
			Unsubscribe(nameof(OnPlayerConnected));
			Unsubscribe(nameof(OnPlayerSetInfo));
			Unsubscribe(nameof(OnEntityEnter));
			Unsubscribe(nameof(OnEntityLeave));
			Unsubscribe(nameof(OnPlayerGainedBuildingPrivilege));
			Unsubscribe(nameof(OnPlayerLostBuildingPrivilege));
			permission.RegisterPermission(PERMISSION_ADMIN, this);
			AddCovalenceCommand(_config.Command, nameof(WipeStatus_Command));
			_storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
		}
		
		void OnServerInitialized()
		{
			_statusIsLoaded = AdvancedStatus != null && AdvancedStatus.IsLoaded;
			ImgLibCheck();
			if (_statusIsLoaded)
				TryDisplay();
		}
		#endregion
		
		#region ~Commands~
		private void WipeStatus_Command(IPlayer player, string command, string[] args)
		{
			if (args != null && args.Length > 0)
			{
				string replyKey = string.Empty;
				string[] replyArgs = new string[5];
				bool isWarning = false;
				if (args[0] == "bar")
				{
					if (player.Object is BasePlayer bPlayer)
                    {
						if (!_storedData.PlayersList.ContainsKey(bPlayer.userID))
							_storedData.PlayersList[bPlayer.userID] = true;
						_storedData.PlayersList[bPlayer.userID] = !_storedData.PlayersList[bPlayer.userID];
						if (_timeStamp > 0d)
                        {
							if (_storedData.PlayersList[bPlayer.userID])
								SendBar(bPlayer);
							else
								AdvancedStatus?.Call("DeleteBar", bPlayer.userID, _barID, Name);
						}
						replyKey = "MsgSetBar";
						replyArgs[0] = $"{_storedData.PlayersList[bPlayer.userID]}";
					}
				}
				else if (player.IsServer || permission.UserHasPermission(player.Id, PERMISSION_ADMIN))
				{
					if (args[0] == "add" && args.Length > 1)
					{
						if (DateTime.TryParseExact(args[1], "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out var newDate) && newDate > DateTime.Now)
						{
							_config.Custom_Date_List.Add(args[1]);
							SaveConfig();
							if (_timeStamp == 0d || newDate.Subtract(DateTime.Now).TotalSeconds + DateTimeOffset.UtcNow.ToUnixTimeSeconds() < _timeStamp)
								TryDisplay();
							replyKey = "MsgNewDateAdded";
						}
						else
						{
							replyKey = "MsgNewDateAddFailed";
							isWarning = true;
						}
						replyArgs[0] = args[1];
					}
					else if (args[0] == "clear")
					{
						_config.Custom_Date_List.Clear();
						SaveConfig();
						if (_timeStamp > 0d)
                        {
							AdvancedStatus?.Call("DeleteBar", _barID, Name);
							TryDisplay();
						}
						replyKey = "MsgClearDates";
					}
				}
				
				if (!string.IsNullOrWhiteSpace(replyKey))
                {
					if (!player.IsServer && _config.Use_GameTips)
						player.Command("gametip.showtoast", isWarning ? 1 : 0, string.Format(lang.GetMessage(replyKey, this, player.Id), replyArgs), null, null);
					else
						player.Reply(string.Format(lang.GetMessage(replyKey, this, player.Id), replyArgs));
				}
			}
		}
		#endregion
		
		#region ~Unload~
		void Unload()
		{
			if (_timer != null)
				_timer.Destroy();
			_config = null;
			_storedData = null;
		}
		#endregion
	}
}

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