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

FREE ReferralsRu : 1.3.3 1.3.3

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

#if CARBON
using Carbon.Base;
using Carbon.Modules;
#endif

// ReSharper disable MemberHidesStaticFromOuterClass

namespace Oxide.Plugins
{
	[Info("Referrals", "Mevent", "1.3.3")]
	public class ReferralsRu : RustPlugin
	{
		#region Fields

		[PluginReference] private Plugin ImageLibrary = null, NoEscape = null, Notify = null, UINotify = null;

		private const string Layer = "UI.Referrals";

		private static ReferralsRu _instance;

#if CARBON
	    private ImageDatabaseModule imageDatabase;
#endif

		private bool _enabledImageLibrary;

		#endregion

		#region Config

		private Configuration _config;

		private class Configuration
		{
			[JsonProperty(PropertyName = "Команды", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public string[] Commands = {"ref", "referal"};

			[JsonProperty(PropertyName = "Команды для активации промокода",
				ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public string[] ActivePromoCommands =
			{
				"promo",
				"code"
			};

			[JsonProperty(PropertyName = "Разрешение (пример: referralsru.use)")]
			public string Permission = string.Empty;

			[JsonProperty(PropertyName = "Включить работу с Notify?")]
			public bool UseNotify = true;

			[JsonProperty(PropertyName = "Включиить авто-вайп?")]
			public bool AutoWipe = false;

			[JsonProperty(PropertyName = "Символы для промокода")]
			public string PromoCodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

			[JsonProperty(PropertyName = "Длина промокода")]
			public int PromoCodeLength = 8;

			[JsonProperty(PropertyName = "Минимальное наигранное время (секунды)")]
			public int MinPlayTime = 3600;

			[JsonProperty(PropertyName = "Награды", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<Award> Awards = new List<Award>
			{
				new Award
				{
					InvitesAmount = 1,
					ID = 1,
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "wood",
					Skin = 0,
					Amount = 20000,
					ShowDescription = false,
					Description = new List<string>()
				},
				new Award
				{
					InvitesAmount = 2,
					ID = 2,
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "stones",
					Skin = 0,
					Amount = 15000,
					ShowDescription = false,
					Description = new List<string>()
				},
				new Award
				{
					InvitesAmount = 5,
					ID = 3,
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "leather",
					Skin = 0,
					Amount = 2400,
					ShowDescription = false,
					Description = new List<string>()
				},
				new Award
				{
					InvitesAmount = 7,
					ID = 4,
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "cloth",
					Skin = 0,
					Amount = 2300,
					ShowDescription = false,
					Description = new List<string>()
				},
				new Award
				{
					InvitesAmount = 10,
					ID = 5,
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "lowgradefuel",
					Skin = 0,
					Amount = 1500,
					ShowDescription = false,
					Description = new List<string>()
				}
			};

			[JsonProperty(PropertyName = "Давать награду игроку, активирующему промокод?")]
			public bool GiveSelfAward = true;

			[JsonProperty(PropertyName = "Награда для игрока, активирующего промокод",
				ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<SelfAward> SelfAwards = new List<SelfAward>
			{
				new SelfAward
				{
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "wood",
					Skin = 0,
					Amount = 20000,
					Chance = 50
				},
				new SelfAward
				{
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "stones",
					Skin = 0,
					Amount = 15000,
					Chance = 50
				},
				new SelfAward
				{
					Type = ItemConf.ItemType.Item,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Kit = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = "leather",
					Skin = 0,
					Amount = 2400,
					Chance = 50
				}
			};

			[JsonProperty(PropertyName = "Блокировки наград")]
			public RewardBlocks RewardBlocks = new()
			{
				UseBlockRewardsAfterWipe = false,
				BlockAfterWipeTime = 7200,
				UseBlockRewardsDuringRaidBlock = false,
				UseBlockRewardsDuringCombatBlock = false
			};

			[JsonProperty(PropertyName = "Интерфейс")]
			public InterfaceSettings UI = new()
			{
				Color1 = new IColor("#0E0E10"),
				Color2 = new IColor("#161617"),
				Color3 = new IColor("#FFFFFF"),
				Color4 = new IColor("#4B68FF"),
				Color5 = new IColor("#FFFFFF", 5),
				Color6 = new IColor("#FFFFFF", 20),
				Color7 = new IColor("#4B68FF", 33),
				Color8 = new IColor("#74884A"),
				UseScrollForAwards = true,
				UseScrollForInvitedPlayers = true,
			};
		}

		private class RewardBlocks
		{
			[JsonProperty(PropertyName = "Использовать блокировку наград после вайпа??")]
			public bool UseBlockRewardsAfterWipe;

			[JsonProperty(PropertyName = "Время наград блокировки после вайпа")]
			public float BlockAfterWipeTime;

			[JsonProperty(PropertyName = "Использовать блокировку наград во вреймя рейд блока?")]
			public bool UseBlockRewardsDuringRaidBlock;

			[JsonProperty(PropertyName = "Использовать блокировку наград во вреймя комбат блока?")]
			public bool UseBlockRewardsDuringCombatBlock;
		}

		private class InterfaceSettings
		{
			[JsonProperty(PropertyName = "Цвет 1")]
			public IColor Color1;

			[JsonProperty(PropertyName = "Цвет 2")]
			public IColor Color2;

			[JsonProperty(PropertyName = "Цвет 3")]
			public IColor Color3;

			[JsonProperty(PropertyName = "Цвет 4")]
			public IColor Color4;

			[JsonProperty(PropertyName = "Цвет 5")]
			public IColor Color5;

			[JsonProperty(PropertyName = "Цвет 6")]
			public IColor Color6;

			[JsonProperty(PropertyName = "Цвет 7")]
			public IColor Color7;

			[JsonProperty(PropertyName = "Цвет 8")]
			public IColor Color8;

			[JsonProperty(PropertyName = "Использовать скролл для наград?")]
			public bool UseScrollForAwards;

			[JsonProperty(PropertyName = "Использовать скролл для приглашенных игроков?")]
			public bool UseScrollForInvitedPlayers;
		}

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

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

			[JsonIgnore] private string _color;

			[JsonIgnore]
			public string Get
			{
				get
				{
					if (string.IsNullOrEmpty(_color))
						_color = GetColor();

					return _color;
				}
			}

			private string GetColor()
			{
				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()
			{
			}

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

		private abstract class ItemConf
		{
			public enum ItemType
			{
				Item,
				Command,
				Plugin,
				Kit
			}

			[JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
			public ItemType Type;

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

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

			[JsonProperty(PropertyName = "Command (%steamid%)")]
			public string Command;

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

			[JsonProperty(PropertyName = "Plugin")]
			public PluginItem Plugin;

			[JsonProperty(PropertyName = "Display Name (empty - default)")]
			public string DisplayName;

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

			[JsonProperty(PropertyName = "Skin")] public ulong Skin;

			[JsonProperty(PropertyName = "Amount")]
			public int Amount;

			[JsonIgnore] private string _publicTitle;

			[JsonIgnore]
			public string PublicTitle
			{
				get
				{
					if (string.IsNullOrEmpty(_publicTitle))
						_publicTitle = GetName();

					return _publicTitle;
				}
			}

			[JsonIgnore] private ItemDefinition _def;

			[JsonIgnore]
			public ItemDefinition Definition
			{
				get
				{
					if (_def == null) _def = ItemManager.FindItemDefinition(ShortName);

					return _def;
				}
			}

			private string GetName()
			{
				if (!string.IsNullOrEmpty(Title))
					return Title;

				if (!string.IsNullOrEmpty(DisplayName))
					return DisplayName;

				var def = Definition;
				if (!string.IsNullOrEmpty(ShortName) && def != null)
					return def.displayName.translated;

				return string.Empty;
			}

			public void Get(BasePlayer player, int count = 1)
			{
				switch (Type)
				{
					case ItemType.Item:
						ToItem(player, count);
						break;
					case ItemType.Command:
						ToCommand(player, count);
						break;
					case ItemType.Plugin:
						Plugin.Get(player, count);
						break;
					case ItemType.Kit:
						ToKit(player, count);
						break;
				}
			}

			private void ToKit(BasePlayer player, int count)
			{
				if (string.IsNullOrEmpty(Kit)) return;

				for (var i = 0; i < count; i++)
					Interface.Oxide.CallHook("GiveKit", player, Kit);
			}

			private void ToItem(BasePlayer player, int count)
			{
				var def = Definition;
				if (def == null)
				{
					Debug.LogError($"Error creating item with ShortName '{ShortName}'");
					return;
				}

				GetStacks(def, Amount * count)?.ForEach(stack =>
				{
					var newItem = ItemManager.Create(def, stack, Skin);
					if (newItem == null)
					{
						_instance?.PrintError($"Error creating item with ShortName '{ShortName}'");
						return;
					}

					if (!string.IsNullOrEmpty(DisplayName)) newItem.name = DisplayName;

					player.GiveItem(newItem, BaseEntity.GiveItemReason.PickedUp);
				});
			}

			private void ToCommand(BasePlayer player, int count)
			{
				for (var i = 0; i < count; i++)
				{
					var command = Command.Replace("\n", "|").Replace("%steamid%", player.UserIDString, StringComparison.OrdinalIgnoreCase).Replace(
							"%username%",
							player.displayName, StringComparison.OrdinalIgnoreCase);

					foreach (var check in command.Split('|')) _instance?.Server.Command(check);
				}
			}

			private static List<int> GetStacks(ItemDefinition item, int amount)
			{
				var list = Pool.GetList<int>();
				var maxStack = item.stackable;

				if (maxStack == 0) maxStack = 1;

				while (amount > maxStack)
				{
					amount -= maxStack;
					list.Add(maxStack);
				}

				list.Add(amount);

				return list;
			}
		}

		private class SelfAward : ItemConf
		{
			[JsonProperty(PropertyName = "Chance")]
			public float Chance;
		}

		private class Award : ItemConf
		{
			[JsonProperty(PropertyName = "Invites Amount")]
			public int InvitesAmount;

			[JsonProperty(PropertyName = "ID")] public int ID;

			[JsonProperty(PropertyName = "Показывать описание")]
			public bool ShowDescription;

			[JsonProperty(PropertyName = "Описание", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<string> Description = new List<string>();

			[JsonIgnore] private string _description = string.Empty;

			public string GetDescription()
			{
				if (string.IsNullOrEmpty(_description) && Description != null)
					_description = string.Join("\n", Description);

				return _description ?? string.Empty;
			}
		}

		private class PluginItem
		{
			[JsonProperty(PropertyName = "Hook")] public string Hook = string.Empty;

			[JsonProperty(PropertyName = "Plugin name")]
			public string Plugin = string.Empty;

			[JsonProperty(PropertyName = "Amount")]
			public int Amount = 1;

			[JsonProperty("(GameStores) Store ID in the service")]
			public readonly string ShopID = "UNDEFINED";

			[JsonProperty("(GameStores) Server ID in the service")]
			public readonly string ServerID = "UNDEFINED";

			[JsonProperty("(GameStores) Secret Key")]
			public readonly string SecretKey = "UNDEFINED";

			public void Get(BasePlayer player, int count = 1)
			{
				var plug = _instance?.plugins.Find(Plugin);
				if (plug == null)
				{
					_instance?.PrintError($"Plugin '{Plugin}' not found !!! ");
					return;
				}

				switch (Plugin)
				{
					case "Economics":
					{
						plug.Call(Hook, player.userID, (double) Amount * count);
						break;
					}
					case "RustStore":
					{
						plug.CallHook(Hook, player.userID, Amount * count, new Action<string>(result =>
						{
							if (result == "SUCCESS")
							{
								Interface.Oxide.LogDebug(
									$"Player {player.displayName} ({player.UserIDString}) received {Amount * count} to the balance in {plug}");
								return;
							}

							Interface.Oxide.LogDebug(
								$"The balance of the player {player.userID}  has not been changed, error: {result}");
						}));
						break;
					}
					case "GameStoresRUST":
					{
						_instance?.webrequest.Enqueue(
							$"https://gamestores.ru/api/?shop_id={ShopID}&secret={SecretKey}&server={ServerID}&action=moneys&type=plus&steam_id={player.UserIDString}&amount={Amount * count}",
							"", (code, response) =>
							{
								switch (code)
								{
									case 0:
									{
										_instance?.PrintError("Api does not responded to a request");
										break;
									}
									case 200:
									{
										Interface.Oxide.LogDebug(
											$"Player {player.displayName} ({player.UserIDString}) received {Amount * count} to the balance in {plug}");
										break;
									}
									case 404:
									{
										_instance?.PrintError("Please check your configuration! [404]");
										break;
									}
								}
							}, _instance);
						break;
					}
					default:
					{
						plug.Call(Hook, player.userID, Amount * count);
						break;
					}
				}
			}
		}

		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 = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public Dictionary<ulong, PlayerData> Players = new Dictionary<ulong, PlayerData>();
		}

		private class PlayerData
		{
			[JsonProperty(PropertyName = "Display Name")]
			public string DisplayName;

			[JsonProperty(PropertyName = "Activated")]
			public bool Activated;

			[JsonProperty(PropertyName = "Promo Code")]
			public string PromoCode;

			[JsonProperty(PropertyName = "Play Time")]
			public int PlayTime;

			[JsonProperty(PropertyName = "Received Awards", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<int> ReceivedAwards = new List<int>();

			[JsonProperty(PropertyName = "Invited Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<ulong> InvitedPlayers = new List<ulong>();
		}

		private PlayerData GetPlayerData(BasePlayer player)
		{
			return GetPlayerData(player.userID);
		}

		private PlayerData GetPlayerData(ulong member)

		{
			if (!_data.Players.ContainsKey(member))
				_data.Players.Add(member, new PlayerData
				{
					PromoCode = GetRandomPromoCode()
				});

			return _data.Players[member];
		}

		#endregion

		#region Hooks

		private void Init()
		{
			_instance = this;

			LoadData();
		}

		private void OnServerInitialized()
		{
			LoadImages();

			if (!string.IsNullOrEmpty(_config.Permission) && !permission.PermissionExists(_config.Permission))
				permission.RegisterPermission(_config.Permission, this);

			AddCovalenceCommand(_config.Commands, nameof(CmdOpenUi));
			AddCovalenceCommand(_config.ActivePromoCommands, nameof(CmdActivePromo));

			foreach (var player in BasePlayer.activePlayerList)
				OnPlayerConnected(player);

			if (_config.MinPlayTime > 0)
				timer.Every(1, DataHandle);
		}

		private void OnServerSave()
		{
			timer.In(Random.Range(2f, 7f), SaveData);
		}

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

			SaveData();

			_instance = null;
		}

		private void OnNewSave(string filename)
		{
			if (!_config.AutoWipe) return;

			if (_data == null)
				LoadData();

			_data?.Players.Clear();

			SaveData();

			PrintWarning($"Wipe detected! {Name} wiped!");
		}

		private void OnPlayerConnected(BasePlayer player)
		{
			if (player == null || !player.userID.IsSteamId()) return;

			GetAvatar(player.userID,
				avatar => AddImage(avatar, $"avatar_{player.UserIDString}"));

			var data = GetPlayerData(player);
			if (data == null || string.IsNullOrEmpty(player.displayName)) return;

			data.DisplayName = player.displayName;
		}

		#region Images

#if !CARBON
		private void OnPluginLoaded(Plugin plugin)
		{
			switch (plugin.Name)
			{
				case "ImageLibrary":
					timer.In(1, LoadImages);
					break;
			}
		}

		private void OnPluginUnloaded(Plugin plugin)
		{
			switch (plugin.Name)
			{
				case "ImageLibrary":
					_enabledImageLibrary = false;
					break;
			}
		}
#endif

		#endregion

		#endregion

		#region Commands

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

			switch (arg.Args[0])
			{
				case "page":
				{
					if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out var page)) return;

					var zPage = 0;
					if (arg.HasArgs(3))
						int.TryParse(arg.Args[2], out zPage);

					MainUi(player, page, zPage);
					break;
				}

				case "infoaward":
				{
					if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out var id)) return;

					var item = _config.Awards.Find(x => x.ID == id);
					if (item == null) return;

					ShowDescription(player, item);
					break;
				}

				case "getaward":
				{
					if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out var id)) return;

					var item = _config.Awards.Find(x => x.ID == id);
					if (item == null) return;

					var data = GetPlayerData(player);
					if (data == null || data.ReceivedAwards.Contains(id)) return;

					if (!CanGetAward(player, out var errorMsg))
					{
						SendNotify(player, errorMsg, 1);
						return;
					}

					data.ReceivedAwards.Add(id);

					item.Get(player);

					SendNotify(player, ReceivedItem, 0, item.PublicTitle);

					UpdateUI(player,
						container => ShowAwardUI(player, ref container, item, data,
							data.InvitedPlayers.Count(CheckInvitedPlayer)));
					break;
				}
			}
		}

		private void CmdOpenUi(IPlayer cov, string command, string[] args)
		{
			var player = cov?.Object as BasePlayer;
			if (player == null) return;

			if (_enabledImageLibrary == false)
			{
				SendNotify(player, NoILError, 1);

				BroadcastILNotInstalled();
				return;
			}

			if (!string.IsNullOrEmpty(_config.Permission) &&
			    !permission.UserHasPermission(player.UserIDString, _config.Permission))
			{
				SendNotify(player, NoPermission, 1);
				return;
			}

			MainUi(player, first: true);
		}

		private void CmdActivePromo(IPlayer cov, string command, string[] args)
		{
			var player = cov?.Object as BasePlayer;
			if (player == null) return;

			if (!string.IsNullOrEmpty(_config.Permission) &&
			    !permission.UserHasPermission(player.UserIDString, _config.Permission))
			{
				SendNotify(player, NoPermission, 1);
				return;
			}

			if (args.Length == 0)
			{
				cov.Reply(Msg(ErrorSyntax, cov.Id, command));
				return;
			}

			var data = GetPlayerData(player);
			if (data == null) return;

			if (data.Activated)
			{
				SendNotify(player, AlreadyActivated, 1);
				return;
			}

			if (_config.MinPlayTime > 0 && data.PlayTime < _config.MinPlayTime)
			{
				SendNotify(player, NotEnoughTime, 1,
					FormatShortTime(player, TimeSpan.FromSeconds(_config.MinPlayTime - data.PlayTime)));
				return;
			}

			var promoCode = string.Join(" ", args);
			if (string.IsNullOrEmpty(promoCode))
				return;

			if (_data.Players.All(x => x.Value.PromoCode != promoCode))
			{
				SendNotify(player, PromoCode, 1, promoCode);
				return;
			}

			var check = _data.Players.FirstOrDefault(x => x.Value.PromoCode == promoCode);
			if (check.Value.InvitedPlayers.Contains(player.userID)) return;

			if (check.Value.PromoCode == data.PromoCode)
			{
				SendNotify(player, CannotActivateSelfPromo, 1);
				return;
			}

			check.Value.InvitedPlayers.Add(player.userID);
			data.Activated = true;

			var target = BasePlayer.FindByID(check.Key);
			if (target != null)
				SendNotify(target, ActivatedPromoCode, 0, player.displayName);

			SendNotify(player, ActivatedSelfPromoCode, 0, promoCode);

			if (_config.GiveSelfAward)
				GetSelfAward()?.Get(player);

			Interface.CallHook("OnPromoCodeActivated", player, promoCode);
		}

		#endregion

		#region Interface

		private void MainUi(BasePlayer player, int page = 0, int rPage = 0, bool first = false)
		{
			var data = GetPlayerData(player);
			if (data == null) return;

			var container = new CuiElementContainer();

			#region Background

			if (first)
			{
				container.Add(new CuiPanel
				{
					RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
					Image =
					{
						Color = "0 0 0 0.9",
						Material = "assets/content/ui/uibackgroundblur.mat"
					},
					CursorEnabled = true
				}, "Overlay", Layer, Layer);

				container.Add(new CuiButton
				{
					RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
					Text = {Text = ""},
					Button =
					{
						Color = "0 0 0 0",
						Close = Layer,
						Command = "UI_Referrals close"
					}
				}, Layer);
			}

			#endregion

			#region Main

			container.Add(new CuiPanel
			{
				RectTransform =
				{
					AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5",
					OffsetMin = "-360 -250", OffsetMax = "360 300"
				},
				Image =
				{
					Color = _config.UI.Color1.Get
				}
			}, Layer, Layer + ".Main", Layer + ".Main");

			#region Header

			container.Add(new CuiPanel
			{
				RectTransform =
				{
					AnchorMin = "0 1", AnchorMax = "1 1",
					OffsetMin = "0 -45",
					OffsetMax = "0 0"
				},
				Image = {Color = _config.UI.Color2.Get}
			}, Layer + ".Main", Layer + ".Header", Layer + ".Header");

			#region Title

			container.Add(new CuiLabel
			{
				RectTransform =
				{
					AnchorMin = "0 0", AnchorMax = "1 1",
					OffsetMin = "30 0",
					OffsetMax = "0 0"
				},
				Text =
				{
					Text = Msg(player, TitleMenu),
					Align = TextAnchor.MiddleLeft,
					Font = "robotocondensed-bold.ttf",
					FontSize = 14,
					Color = _config.UI.Color3.Get
				}
			}, Layer + ".Header");

			#endregion

			#region Close

			container.Add(new CuiButton
			{
				RectTransform =
				{
					AnchorMin = "1 1", AnchorMax = "1 1",
					OffsetMin = "-50 -35",
					OffsetMax = "-25 -10"
				},
				Text =
				{
					Text = Msg(player, CloseButton),
					Align = TextAnchor.MiddleCenter,
					Font = "robotocondensed-bold.ttf",
					FontSize = 10,
					Color = _config.UI.Color3.Get
				},
				Button =
				{
					Close = Layer,
					Color = _config.UI.Color4.Get,
					Command = "UI_Referrals close"
				}
			}, Layer + ".Header");

			#endregion

			#endregion

			#region My PromoCode

			container.Add(new CuiPanel
			{
				RectTransform =
				{
					AnchorMin = "0.5 1", AnchorMax = "0.5 1",
					OffsetMin = "-305 -130",
					OffsetMax = "-85 -85"
				},
				Image =
				{
					Color = _config.UI.Color5.Get
				}
			}, Layer + ".Main", Layer + ".My.PromoCode");

			CreateOutLine(ref container, Layer + ".My.PromoCode", _config.UI.Color6.Get, 1);

			container.Add(new CuiElement
			{
				Parent = Layer + ".My.PromoCode",
				Components =
				{
					new CuiInputFieldComponent
					{
						Align = TextAnchor.MiddleLeft,
						Font = "robotocondensed-bold.ttf",
						FontSize = 12,
						Color = "1 1 1 1",
						Command = $"UI_Referrals page {page} {rPage}",
						CharsLimit = 150,
						Text = $"{data.PromoCode}",
						NeedsKeyboard = true,
						HudMenuInput = true
					},
					new CuiRectTransformComponent
					{
						AnchorMin = "0 0", AnchorMax = "1 1",
						OffsetMin = "20 0", OffsetMax = "-20 0"
					}
				}
			});

			container.Add(new CuiLabel
			{
				RectTransform =
				{
					AnchorMin = "0.5 1", AnchorMax = "0.5 1",
					OffsetMin = "-305 -185",
					OffsetMax = "-45 -145"
				},
				Text =
				{
					Text = Msg(player, YourPromoDescription),
					Align = TextAnchor.UpperLeft,
					Font = "robotocondensed-regular.ttf",
					FontSize = 10,
					Color = "1 1 1 0.3"
				}
			}, Layer + ".Main");

			#endregion

			#region Enter PromoCode

			container.Add(new CuiPanel
			{
				RectTransform =
				{
					AnchorMin = "0.5 1", AnchorMax = "0.5 1",
					OffsetMin = "25 -130",
					OffsetMax = "245 -85"
				},
				Image =
				{
					Color = _config.UI.Color5.Get
				}
			}, Layer + ".Main", Layer + ".Enter.PromoCode");

			CreateOutLine(ref container, Layer + ".Enter.PromoCode", _config.UI.Color6.Get, 1);

			container.Add(new CuiElement
			{
				Parent = Layer + ".Enter.PromoCode",
				Components =
				{
					new CuiInputFieldComponent
					{
						Align = TextAnchor.MiddleLeft,
						Font = "robotocondensed-bold.ttf",
						FontSize = 12,
						Color = "1 1 1 1",
						Command = data.Activated ? "" : $"{_config.ActivePromoCommands[0]} ",
						CharsLimit = 150,
						NeedsKeyboard = true,
						HudMenuInput = true
					},
					new CuiRectTransformComponent
					{
						AnchorMin = "0 0", AnchorMax = "1 1",
						OffsetMin = "20 0", OffsetMax = "-20 0"
					}
				}
			});

			container.Add(new CuiLabel
			{
				RectTransform =
				{
					AnchorMin = "0.5 1", AnchorMax = "0.5 1",
					OffsetMin = "25 -185",
					OffsetMax = "285 -145"
				},
				Text =
				{
					Text = Msg(player, EnterPromoDescription),
					Align = TextAnchor.UpperLeft,
					Font = "robotocondensed-regular.ttf",
					FontSize = 10,
					Color = "1 1 1 0.3"
				}
			}, Layer + ".Main");

			#endregion

			#region Invited Players

			container.Add(new CuiPanel
			{
				RectTransform =
				{
					AnchorMin = "0.5 1", AnchorMax = "0.5 1",
					OffsetMin = "-305 -500",
					OffsetMax = "-85 -205"
				},
				Image =
				{
					Color = "0 0 0 0"
				}
			}, Layer + ".Main", Layer + ".InvitedPlayers");

			CreateOutLine(ref container, Layer + ".InvitedPlayers", _config.UI.Color6.Get, 1);

			container.Add(new CuiLabel
			{
				RectTransform =
				{
					AnchorMin = "0 1", AnchorMax = "1 1",
					OffsetMin = "20 -30", OffsetMax = "0 0"
				},
				Text =
				{
					Text = Msg(player, InvitedPlayersTitle),
					Align = TextAnchor.LowerLeft,
					Font = "robotocondensed-regular.ttf",
					FontSize = 10,
					Color = "1 1 1 0.5"
				}
			}, Layer + ".InvitedPlayers");

			#region List

			var amountOnPage = 10;
			var ySwitch = -40f;
			var height = 20f;
			var margin = 5f;

			var invitedPlayers = data.InvitedPlayers.FindAll(CheckInvitedPlayer);
			var invitedPlayersCount = invitedPlayers.Count;
			var hasInvitedPages = invitedPlayersCount > amountOnPage;
			var invitedPlayersParent = Layer + ".InvitedPlayers";

			if (_config.UI.UseScrollForInvitedPlayers && hasInvitedPages)
			{
				var totalHeight = invitedPlayersCount * height + (invitedPlayersCount - 1) * margin;

				ySwitch = 0;

				container.Add(new CuiPanel()
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "1 1",
						OffsetMin = "0 20",
						OffsetMax = "-20 -40"
					},
					Image =
					{
						Color = "0 0 0 0"
					}
				}, Layer + ".InvitedPlayers", Layer + ".InvitedPlayers.Panel");

				container.Add(new CuiElement()
				{
					Parent = Layer + ".InvitedPlayers.Panel",
					Name = Layer + ".InvitedPlayers.Scroll",
					DestroyUi = Layer + ".InvitedPlayers.Scroll",
					Components =
					{
						new CuiScrollViewComponent
						{
							MovementType = ScrollRect.MovementType.Elastic,
							Vertical = true,
							Inertia = true,
							Horizontal = false,
							Elasticity = 0.25f,
							DecelerationRate = 0.3f,
							ScrollSensitivity = 24f,
							ContentTransform = new CuiRectTransform
							{
								AnchorMin = "0 1",
								AnchorMax = "1 1",
								OffsetMin = $"0 -{totalHeight}",
								OffsetMax = "0 0"
							},
							VerticalScrollbar = new CuiScrollbar()
							{
								Size = 5f, AutoHide = true,
								HighlightColor = new IColor("#FFFFFF", 100).Get,
								HandleColor = new IColor("#FFFFFF", 100).Get,
								PressedColor = new IColor("#FFFFFF", 50).Get,
								TrackColor = new IColor("#C4C4C4", 10).Get
							},
						}
					}
				});

				invitedPlayersParent = Layer + ".InvitedPlayers.Scroll";
			}
			else
				invitedPlayers = invitedPlayers.Skip(page * amountOnPage).Take(amountOnPage).ToList();

			foreach (var member in invitedPlayers)
			{
				container.Add(new CuiPanel
					{
						RectTransform =
						{
							AnchorMin = "0 1", AnchorMax = "1 1",
							OffsetMin = $"20 {ySwitch - height}",
							OffsetMax = $"0 {ySwitch}"
						},
						Image = {Color = "0 0 0 0"}
					}, invitedPlayersParent,
					Layer + $".InvitedPlayers.Player.{member}",
					Layer + $".InvitedPlayers.Player.{member}");

				container.Add(new CuiElement
				{
					Parent = Layer + $".InvitedPlayers.Player.{member}",
					Components =
					{
						new CuiRawImageComponent
						{
							Png = GetImage($"avatar_{member}")
						},
						new CuiRectTransformComponent
						{
							AnchorMin = "0 0", AnchorMax = "0 0",
							OffsetMin = "0 0", OffsetMax = "20 20"
						}
					}
				});

				container.Add(new CuiLabel
					{
						RectTransform =
						{
							AnchorMin = "0 0", AnchorMax = "1 1",
							OffsetMin = "45 0", OffsetMax = "0 0"
						},
						Text =
						{
							Text = GetPlayerData(member)?.DisplayName ?? "UNKNOWN",
							Align = TextAnchor.MiddleLeft,
							Font = "robotocondensed-regular.ttf",
							FontSize = 10,
							Color = "1 1 1 1"
						}
					}, Layer + $".InvitedPlayers.Player.{member}");

				ySwitch = ySwitch - height - margin;
			}

			#endregion

			#region Pages

			if (!_config.UI.UseScrollForInvitedPlayers && hasInvitedPages)
			{
				container.Add(new CuiButton
				{
					RectTransform =
					{
						AnchorMin = "1 0", AnchorMax = "1 0",
						OffsetMin = "-40 30",
						OffsetMax = "-20 50"
					},
					Text =
					{
						Text = Msg(player, NextBtn),
						Align = TextAnchor.MiddleCenter,
						Font = "robotocondensed-regular.ttf",
						FontSize = 10,
						Color = "1 1 1 1"
					},
					Button =
					{
						Color = _config.UI.Color4.Get,
						Command = invitedPlayersCount > (page + 1) * amountOnPage
							? $"UI_Referrals page {page + 1}"
							: ""
					}
				}, Layer + ".InvitedPlayers");

				container.Add(new CuiButton
				{
					RectTransform =
					{
						AnchorMin = "1 0", AnchorMax = "1 0",
						OffsetMin = "-40 55",
						OffsetMax = "-20 75"
					},
					Text =
					{
						Text = Msg(player, BackBtn),
						Align = TextAnchor.MiddleCenter,
						Font = "robotocondensed-regular.ttf",
						FontSize = 10,
						Color = "1 1 1 1"
					},
					Button =
					{
						Color = _config.UI.Color7.Get,
						Command = page != 0 ? $"UI_Referrals page {page - 1}" : ""
					}
				}, Layer + ".InvitedPlayers");
			}

			#endregion

			#endregion

			#region Awards

			amountOnPage = 3;

			ySwitch = -205;
			height = 90;
			margin = 10;

			var awards = GetAwards(player);
			var awardsCount = awards.Count;

			var awardsParent = Layer + ".Main";
			if (_config.UI.UseScrollForAwards)
			{
				var totalHeight = awardsCount * height + (awardsCount - 1) * margin;

				totalHeight += 20f;

				ySwitch = -10;

				container.Add(new CuiPanel()
				{
					RectTransform =
					{
						AnchorMin = "0.5 1", AnchorMax = "0.5 1",
						OffsetMin = $"25 -495",
						OffsetMax = $"315 -205"
					},
					Image =
					{
						Color = "0 0 0 0"
					}
				}, Layer + ".Main", Layer + ".Awards.Panel");

				container.Add(new CuiElement()
				{
					Parent = Layer + ".Awards.Panel",
					Name = Layer + ".Awards.Scroll",
					DestroyUi = Layer + ".Awards.Scroll",
					Components =
					{
						new CuiScrollViewComponent
						{
							MovementType = ScrollRect.MovementType.Elastic,
							Vertical = true,
							Inertia = true,
							Horizontal = false,
							Elasticity = 0.25f,
							DecelerationRate = 0.3f,
							ScrollSensitivity = 24f,
							ContentTransform = new CuiRectTransform
							{
								AnchorMin = "0 1",
								AnchorMax = "1 1",
								OffsetMin = $"0 -{totalHeight}",
								OffsetMax = "0 0"
							},
							VerticalScrollbar = new CuiScrollbar()
							{
								Size = 5f, AutoHide = true,
								HighlightColor = new IColor("#FFFFFF", 100).Get,
								HandleColor = new IColor("#FFFFFF", 100).Get,
								PressedColor = new IColor("#FFFFFF", 50).Get,
								TrackColor = new IColor("#C4C4C4", 10).Get
							},
						}
					}
				});

				awardsParent = Layer + ".Awards.Scroll";
			}
			else
			{
				awards = awards.Skip(rPage * amountOnPage).Take(amountOnPage).ToList();
			}

			foreach (var award in awards)
			{
				container.Add(new CuiPanel
					{
						RectTransform =
						{
							AnchorMin = _config.UI.UseScrollForAwards ? "0 1" : "0.5 1",
							AnchorMax = _config.UI.UseScrollForAwards ? "0 1" : "0.5 1",
							OffsetMin = $"{(_config.UI.UseScrollForAwards ? 0 : 25)} {ySwitch - height}",
							OffsetMax = $"{(_config.UI.UseScrollForAwards ? 280 : 305)} {ySwitch}"
						},
						Image =
						{
							Color = "0 0 0 0"
						}
					}, awardsParent, Layer + $".Award.{award.ID}.Background", Layer + $".Award.{award.ID}.Background");

				ShowAwardUI(player, ref container, award, data, invitedPlayersCount);

				ySwitch = ySwitch - height - margin;
			}

			#region Pages

			if (!_config.UI.UseScrollForAwards)
			{
				container.Add(new CuiButton
				{
					RectTransform =
					{
						AnchorMin = "1 0", AnchorMax = "1 0",
						OffsetMin = "-50 55",
						OffsetMax = "-30 75"
					},
					Text =
					{
						Text = Msg(player, NextBtn),
						Align = TextAnchor.MiddleCenter,
						Font = "robotocondensed-regular.ttf",
						FontSize = 10,
						Color = "1 1 1 1"
					},
					Button =
					{
						Color = _config.UI.Color4.Get,
						Command = awardsCount > (rPage + 1) * amountOnPage
							? $"UI_Referrals page {page} {rPage + 1}"
							: ""
					}
				}, Layer + ".Main");

				container.Add(new CuiButton
				{
					RectTransform =
					{
						AnchorMin = "1 0", AnchorMax = "1 0",
						OffsetMin = "-50 80",
						OffsetMax = "-30 100"
					},
					Text =
					{
						Text = Msg(player, BackBtn),
						Align = TextAnchor.MiddleCenter,
						Font = "robotocondensed-regular.ttf",
						FontSize = 10,
						Color = "1 1 1 1"
					},
					Button =
					{
						Color = _config.UI.Color7.Get,
						Command = rPage != 0 ? $"UI_Referrals page {page} {rPage - 1}" : ""
					}
				}, Layer + ".Main");
			}

			#endregion

			#endregion

			#endregion

			CuiHelper.AddUi(player, container);
		}

		private void ShowAwardUI(BasePlayer player, ref CuiElementContainer container, Award award, PlayerData data,
			int invitedPlayersCount)
		{
			container.Add(new CuiPanel
				{
					RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
					Image =
					{
						Color = "0 0 0 0"
					}
				}, Layer + $".Award.{award.ID}.Background", Layer + $".Award.{award.ID}", Layer + $".Award.{award.ID}");

			CreateOutLine(ref container, Layer + $".Award.{award.ID}",
				data.ReceivedAwards.Contains(award.ID) ? _config.UI.Color8.Get : _config.UI.Color6.Get,
				1);

			if (!string.IsNullOrEmpty(award.Image))
				container.Add(new CuiElement
				{
					Parent = Layer + $".Award.{award.ID}",
					Components =
					{
						new CuiRawImageComponent
						{
							Png = GetImage(award.Image)
						},
						new CuiRectTransformComponent
						{
							AnchorMin = "0 0", AnchorMax = "0 0",
							OffsetMin = "15 15", OffsetMax = "75 75"
						}
					}
				});
			else if (award.Definition != null)
				container.Add(new CuiElement
				{
					Parent = Layer + $".Award.{award.ID}",
					Components =
					{
						new CuiImageComponent
						{
							ItemId = award.Definition.itemid,
							SkinId = award.Skin
						},
						new CuiRectTransformComponent
						{
							AnchorMin = "0 0", AnchorMax = "0 0",
							OffsetMin = "15 15", OffsetMax = "75 75"
						}
					}
				});

			#region Name

			container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0.5", AnchorMax = "1 1",
						OffsetMin = "90 0", OffsetMax = "0 0"
					},
					Text =
					{
						Text = Msg(player, ItemNameTitle),
						Align = TextAnchor.LowerLeft,
						Font = "robotocondensed-regular.ttf",
						FontSize = 8,
						Color = "1 1 1 0.5"
					}
				}, Layer + $".Award.{award.ID}");

			container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "1 0.5",
						OffsetMin = "90 0", OffsetMax = "0 0"
					},
					Text =
					{
						Text = $"{award.PublicTitle}",
						Align = TextAnchor.UpperLeft,
						Font = "robotocondensed-bold.ttf",
						FontSize = 10,
						Color = "1 1 1 1"
					}
				}, Layer + $".Award.{award.ID}");

			#endregion

			#region Invited

			container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0.5", AnchorMax = "1 1",
						OffsetMin = "175 0", OffsetMax = "0 0"
					},
					Text =
					{
						Text = Msg(player, InvitedAmountTitle),
						Align = TextAnchor.LowerLeft,
						Font = "robotocondensed-regular.ttf",
						FontSize = 8,
						Color = "1 1 1 0.5"
					}
				}, Layer + $".Award.{award.ID}");

			container.Add(new CuiLabel
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "1 0.5",
						OffsetMin = "175 0", OffsetMax = "0 0"
					},
					Text =
					{
						Text = $"{Mathf.Min(invitedPlayersCount, award.InvitesAmount)}/{award.InvitesAmount}",
						Align = TextAnchor.UpperLeft,
						Font = "robotocondensed-bold.ttf",
						FontSize = 10,
						Color = "1 1 1 1"
					}
				}, Layer + $".Award.{award.ID}");

			#endregion

			#region Button

			if (data.ReceivedAwards.Contains(award.ID))
				container.Add(new CuiButton
					{
						RectTransform =
						{
							AnchorMin = "1 0.5", AnchorMax = "1 0.5",
							OffsetMin = "-40 -15",
							OffsetMax = "-10 15"
						},
						Text =
						{
							Text = Msg(player, ReceivedItemIcon),
							Align = TextAnchor.MiddleCenter,
							Font = "robotocondensed-bold.ttf",
							FontSize = 18,
							Color = "1 1 1 1"
						},
						Button =
						{
							Color = _config.UI.Color8.Get
						}
					}, Layer + $".Award.{award.ID}");
			else if (invitedPlayersCount >= award.InvitesAmount)
				container.Add(new CuiButton
					{
						RectTransform =
						{
							AnchorMin = "1 0.5", AnchorMax = "1 0.5",
							OffsetMin = "-40 -15",
							OffsetMax = "-10 15"
						},
						Text =
						{
							Text = Msg(player, ReceiveItemIcon),
							Align = TextAnchor.MiddleCenter,
							Font = "robotocondensed-bold.ttf",
							FontSize = 18,
							Color = "1 1 1 1"
						},
						Button =
						{
							Color = _config.UI.Color4.Get,
							Command = $"UI_Referrals getaward {award.ID}"
						}
					}, Layer + $".Award.{award.ID}");

			#endregion

			#region Info

			if (award.ShowDescription)
				container.Add(new CuiButton
					{
						RectTransform =
						{
							AnchorMin = "1 1", AnchorMax = "1 1",
							OffsetMin = "-18 -18", OffsetMax = "-5 -5"
						},
						Text = {Text = ""},
						Button =
						{
							Sprite = "assets/icons/warning.png",
							Color = _config.UI.Color6.Get,
							Command = $"UI_Referrals infoaward {award.ID}"
						}
					}, Layer + $".Award.{award.ID}");

			#endregion
		}

		private void ShowDescription(BasePlayer player, Award award)
		{
			CuiHelper.AddUi(player, new CuiElementContainer
			{
				{
					new CuiLabel
					{
						RectTransform =
						{
							AnchorMin = "0.5 0", AnchorMax = "0.5 0",
							OffsetMin = "-150 -110", OffsetMax = "150 0"
						},
						Text =
						{
							Text = $"{award.GetDescription()}",
							Align = TextAnchor.MiddleCenter,
							Font = "robotocondensed-regular.ttf",
							FontSize = 12,
							Color = "1 1 1 1"
						}
					},
					Layer + ".Main", Layer + ".Notice", Layer + ".Notice"
				}
			});
		}

		private static void UpdateUI(BasePlayer player, Action<CuiElementContainer> callback)
		{
			if (player == null) return;

			var container = new CuiElementContainer();

			callback?.Invoke(container);

			CuiHelper.AddUi(player, container);
		}

		#endregion

		#region Utils

		#region Blocks

		private bool CanGetAward(BasePlayer player, out string msg)
		{
			msg = null;

			if (_config.RewardBlocks.UseBlockRewardsAfterWipe)
			{
				var timeLeft = Mathf.RoundToInt(_config.RewardBlocks.BlockAfterWipeTime - GetSecondsFromWipe());
				if (timeLeft > 0)
				{
					msg = Msg(player, MsgBlockAfterWipeCooldown, FormatShortTime(timeLeft));
					return false;
				}
			}

			if (_config.RewardBlocks.UseBlockRewardsDuringCombatBlock && NE_IsCombatBlocked(player))
			{
				msg = MsgBlockCombat;
				return false;
			}

			if (_config.RewardBlocks.UseBlockRewardsDuringRaidBlock && NE_IsRaidBlocked(player))
			{
				msg = MsgBlockRaid;
				return false;
			}

			return true;
		}

		private int GetSecondsFromWipe()
		{
			return (int) DateTime.UtcNow.Subtract(SaveRestore.SaveCreatedTime.ToUniversalTime()).TotalSeconds;
		}

		private static string FormatShortTime(int seconds)
		{
			return TimeSpan.FromSeconds(seconds).ToShortString();
		}

		private bool NE_IsCombatBlocked(BasePlayer player)
		{
			return Convert.ToBoolean(NoEscape?.Call("IsCombatBlocked", player));
		}

		private bool NE_IsRaidBlocked(BasePlayer player)
		{
			return Convert.ToBoolean(NoEscape?.Call("IsRaidBlocked", player));
		}

		#endregion

		private SelfAward GetSelfAward()
		{
			SelfAward item = null;
			var iteration = 0;
			do
			{
				iteration++;

				var randomItem = _config.SelfAwards.GetRandom();
				if (randomItem.Chance < 1 || randomItem.Chance > 100)
					continue;

				if (Random.Range(0f, 100f) <= randomItem.Chance)
					item = randomItem;
			} while (item == null && iteration < 1000);

			return item;
		}

		private static void CreateOutLine(ref CuiElementContainer container, string parent, string color,
			float size = 2)
		{
			container.Add(new CuiPanel
				{
					RectTransform =
					{
						AnchorMin = "0 0",
						AnchorMax = "1 0",
						OffsetMin = $"{size} 0",
						OffsetMax = $"-{size} {size}"
					},
					Image = {Color = color}
				},
				parent);
			container.Add(new CuiPanel
				{
					RectTransform =
					{
						AnchorMin = "0 1",
						AnchorMax = "1 1",
						OffsetMin = $"{size} -{size}",
						OffsetMax = $"-{size} 0"
					},
					Image = {Color = color}
				},
				parent);
			container.Add(new CuiPanel
				{
					RectTransform =
					{
						AnchorMin = "0 0", AnchorMax = "0 1",
						OffsetMin = "0 0",
						OffsetMax = $"{size} 0"
					},
					Image = {Color = color}
				},
				parent);
			container.Add(new CuiPanel
				{
					RectTransform =
					{
						AnchorMin = "1 0",
						AnchorMax = "1 1",
						OffsetMin = $"-{size} 0",
						OffsetMax = "0 0"
					},
					Image = {Color = color}
				},
				parent);
		}

		#region Avatar

		private readonly Regex _regex = new(@"<avatarFull><!\[CDATA\[(.*)\]\]></avatarFull>");

		private void GetAvatar(ulong userId, Action<string> callback)
		{
			if (callback == null) return;

			webrequest.Enqueue($"http://steamcommunity.com/profiles/{userId}?xml=1", null, (code, response) =>
			{
				if (code != 200 || response == null)
					return;

				var avatar = _regex.Match(response).Groups[1].ToString();
				if (string.IsNullOrEmpty(avatar))
					return;

				callback.Invoke(avatar);
			}, this);
		}

		#endregion

		private List<Award> GetAwards(BasePlayer player)
		{
			var result = new List<Award>();

			var data = GetPlayerData(player);

			var receivedAwards = _config.Awards.FindLast(x => data.ReceivedAwards.Contains(x.ID));
			if (receivedAwards != null)
				result.Add(receivedAwards);

			result.AddRange(_config.Awards.FindAll(x => !data.ReceivedAwards.Contains(x.ID)).OrderBy(x => x.InvitesAmount).ThenByDescending(x => data.InvitedPlayers.Count >= x.InvitesAmount));
			return result;
		}

		private string GetRandomPromoCode()
		{
			string promo;
			do
			{
				promo = new string(
					Enumerable.Repeat(_config.PromoCodeChars, _config.PromoCodeLength).Select(s => s[Random.Range(0, s.Length)]).ToArray());
			} while (_data.Players.Any(x => x.Value.PromoCode == promo));

			return promo;
		}

		private void DataHandle()
		{
			foreach (var check in _data.Players)
				check.Value.PlayTime++;
		}

		private bool CheckInvitedPlayer(ulong target)
		{
			var data = GetPlayerData(target);
			if (data == null) return false;

			return _config.MinPlayTime <= 0 || data.PlayTime >= _config.MinPlayTime;
		}

		private string FormatShortTime(BasePlayer player, TimeSpan time)
		{
			var list = Pool.GetList<string>();

			if (time.Days != 0)
				list.Add(Msg(player, DaysFormat, time.Days));

			if (time.Hours != 0)
				list.Add(Msg(player, HoursFormat, time.Hours));

			if (time.Minutes != 0)
				list.Add(Msg(player, MinutesFormat, time.Minutes));

			if (time.Seconds != 0)
				list.Add(Msg(player, SecondsFormat, time.Seconds));

			var result = string.Join(" ", list);
			Pool.FreeList(ref list);
			return result;
		}

		#region Images

		private void AddImage(string url, string fileName, ulong imageId = 0)
		{
#if CARBON
			imageDatabase.Queue(true, new Dictionary<string, string>
			{
				[fileName] = url
			});
#else
			ImageLibrary?.Call("AddImage", url, fileName, imageId);
#endif
		}

		private string GetImage(string name)
		{
#if CARBON
		return imageDatabase.GetImageString(name);
#else
			return Convert.ToString(ImageLibrary?.Call("G
// ... [Code preview truncated due to length. Full source in attached file] ...

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