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

FREE vDelivery : 0.1.1 0.1.1

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

namespace Oxide.Plugins
{
    [Info("vDelivery", "IIIaKa", "0.1.1")]
    [Description("Drones deliver right into your vending machine.")]
    class vDelivery : RustPlugin
    {
        [PluginReference]
        private Plugin ImageLibrary, CustomVendingSetup;
        
        #region ~Variables~
        private bool _serverLoaded = false;
        private int _imgLibCheck = 0;
        private bool _imgLibIsLoaded = false;
        private Dictionary<ulong, string> _playerUI = new Dictionary<ulong, string>();
        private Dictionary<ulong, Timer> _playerTimers = new Dictionary<ulong, Timer>();
        private const string PERMISSION_ONE = "vDelivery.one";
        private const string PERMISSION_TWO = "vDelivery.two";
        private const string PERMISSION_THREE = "vDelivery.three";
        private const string PERMISSION_ADMIN = "vDelivery.admin";
        private const string marketplacePrefab = "assets/prefabs/misc/marketplace/marketplace.prefab";
        private const string marketplaceTerminalPrefab = "assets/prefabs/misc/marketplace/marketterminal.prefab";
        private const string itemDropPrefab = "assets/prefabs/misc/item drop/item_drop.prefab";

        private readonly Dictionary<string, int> DefaultLimitsPerGroup = new Dictionary<string, int>
        {
            { PERMISSION_ONE, 1 },
            { PERMISSION_TWO, 3 },
            { PERMISSION_THREE, 5 }
        };
        private readonly List<FeeGroupConfiguration> DefaultFeesPerGroup = new List<FeeGroupConfiguration> { new FeeGroupConfiguration(PERMISSION_ONE), new FeeGroupConfiguration(PERMISSION_TWO), new FeeGroupConfiguration(PERMISSION_THREE) };
        
        private const string UI_HUD_Name = "vDelivery_HUD";
        #endregion

        #region ~Configuration~
        private static Configuration _config;

        private class Configuration
        {
            [JsonProperty(PropertyName = "ImageLibrary Counter Check")]
            public int ImgLibCounter = 5;
            
            [JsonProperty(PropertyName = "vDelivery command")]
            public string Command = "vdelivery";
            
            [JsonProperty(PropertyName = "Use GameTip for messages?")]
            public bool Use_GameTips = true;
            
            [JsonProperty(PropertyName = "Is it worth ignoring the inaccessibility of drones?")]
            public bool Ignore_Accessibility = false;
            
            [JsonProperty(PropertyName = "Display position - Forward")]
            public float Display_Pos_Forward = -0.35f;

            [JsonProperty(PropertyName = "Display position - Up")]
            public float Display_Pos_Up = 1.8f;

            [JsonProperty(PropertyName = "Display position - Right")]
            public float Display_Pos_Right = 0f;

            [JsonProperty(PropertyName = "Display rotation - x")]
            public float Display_Rot_X = 0f;

            [JsonProperty(PropertyName = "Display rotation - y")]
            public float Display_Rot_Y = 180f;

            [JsonProperty(PropertyName = "Display rotation - z")]
            public float Display_Rot_Z = 0f;
            
            [JsonProperty(PropertyName = "Max ammount of Vending machines with the Terminal")]
            public Dictionary<string, int> LimitPerGroup = new Dictionary<string, int>();
            
            [JsonProperty(PropertyName = "Delivery fee for each permissions")]
            public List<FeeGroupConfiguration> FeePerGroup = new List<FeeGroupConfiguration>();
            
            [JsonProperty(PropertyName = "UI - Duration")]
            public float UI_Duration = 6f;
            
            [JsonProperty(PropertyName = "UI_HUD.Position - AnchorMin")]
            public string UI_HUD_AnchorMin = "0 0.9";

            [JsonProperty(PropertyName = "UI_HUD.Position - AnchorMax")]
            public string UI_HUD_AnchorMax = "0.25 1";

            [JsonProperty(PropertyName = "UI_HUD.Position - OffsetMin")]
            public string UI_HUD_OffsetMin = "20 0";

            [JsonProperty(PropertyName = "UI_HUD.Position - OffsetMax")]
            public string UI_HUD_OffsetMax = "0 -30";
            
            [JsonProperty("UI_HUD.Icon - Url")]
            public string UI_HUD_Icon_Url = "https://i.imgur.com/4Adzkb8.png";
            
            [JsonProperty(PropertyName = "UI_HUD.Icon - Color")]
            public string UI_HUD_Icon_Color = "#CCE699";
            
            [JsonProperty(PropertyName = "UI_HUD.Icon - Transparency")]
            public float UI_HUD_Icon_Transparency = 0.8f;
            
            [JsonProperty("UI.Text - Font")]
            public string UI_HUD_Text_Font = "RobotoCondensed-Bold.ttf";
            
            [JsonProperty(PropertyName = "UI.Text - Font Size")]
            public int UI_HUD_Text_Font_Size = 14;
            
            [JsonProperty(PropertyName = "UI.Text - Font Color")]
            public string UI_HUD_Text_Font_Color = "#FFFFFF";
            
            [JsonProperty("UI.Text description - Font")]
            public string UI_HUD_Text_Desc_Font = "RobotoCondensed-Regular.ttf";
            
            [JsonProperty(PropertyName = "UI.Text description - Font Size")]
            public int UI_HUD_Text_Desc_Font_Size = 12;

            [JsonProperty(PropertyName = "UI.Text description - Font Color")]
            public string UI_HUD_Text_Desc_Font_Color = "#FFFFFF";
            
            [JsonProperty("Show HUD Sound - Prefab Name")]
            public string Sound_ShowHUD_Prefab = "assets/bundled/prefabs/fx/invite_notice.prefab";
            
            public Oxide.Core.VersionNumber Version;
        }

        private class FeeGroupConfiguration
        {
            [JsonProperty(PropertyName = "Permission name")]
            public string Permission_Name;

            [JsonProperty(PropertyName = "Delivery fee item")]
            public string Delivery_Fee_Item_Definition;

            [JsonProperty(PropertyName = "Delivery fee amount")]
            public int Delivery_Fee_Item_Amount;
            
            public FeeGroupConfiguration() { }
            
            public FeeGroupConfiguration(string permission_Name, string delivery_Fee_Item_Definition = "scrap", int delivery_Fee_Item_Amount = 20)
            {
                Permission_Name = permission_Name;
                Delivery_Fee_Item_Definition = delivery_Fee_Item_Definition;
                Delivery_Fee_Item_Amount = delivery_Fee_Item_Amount;
            }
        }
        
        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 { LimitPerGroup = DefaultLimitsPerGroup, FeePerGroup = DefaultFeesPerGroup };
        #endregion
        
        #region ~DataFile~
        private static StoredData _storedData;

        private class StoredData
        {
            [JsonProperty(PropertyName = "vDelivery list")]
            public Dictionary<ulong, List<ulong>> vDeliveryList = new Dictionary<ulong, List<ulong>>();
        }
        
        private void Init()
        {
            _storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
        }
        private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, _storedData);
        #endregion
        
        #region ~Language~
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["MsgNotAllowed"] = "You do not have permission to use this command!",
                ["MsgNotOwner"] = "You are not the owner of this vending machine!",
                ["MsgNotAccessible"] = "The vending machine is not accessible to drones!",
                ["MsgNotVending"] = "You need to look at the vending machine or provide correct net ID!",
                ["MsgNotVendingDelivery"] = "The vending machine does not have a terminal!",
                ["MsgLimitReached"] = "You cannot add a terminal as you have reached your limit of {0}!",
                ["MsgAddBtn"] = "Add a terminal to the vending machine?",
                ["MsgAddBtnDesc"] = "Click on the notification to confirm",
                ["MsgMyAdded"] = "The terminal has been successfully added!",
                ["MsgMyRemoved"] = "The terminal has been successfully removed!",
                ["MsgMyAllRemoved"] = "All your terminals have been successfully removed!",
                ["MsgPlayerAllRemoved"] = "All {0}'s terminals have been successfully removed!",
                ["MsgAllRemoved"] = "All terminals have been successfully removed!",
                ["MsgTerminalsNotFound"] = "No terminals found!",
                ["MsgPlayerTerminalsNotFound"] = "{0}'s terminals not found!",
                ["MsgNoHaveCustomFee"] = "To pay the personal fee, you need to have :{0}:(x{1}).Using default fee settings!"
            }, this);
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["MsgNotAllowed"] = "У вас недостаточно прав для использования этой команды!",
                ["MsgNotOwner"] = "Вы не являетесь владельцем данного торгового автомата!",
                ["MsgNotAccessible"] = "Торговый автомат не доступен для дронов!",
                ["MsgNotVending"] = "Вам необходимо смотреть на торговый автомат или указать корректный net ID!",
                ["MsgNotVendingDelivery"] = "Торговый автомат не имеет терминала!",
                ["MsgLimitReached"] = "Вы не можете добавить терминал, так как вы превысили свой лимит в {0}!",
                ["MsgAddBtn"] = "Добавить терминал к торговому автомату?",
                ["MsgAddBtnDesc"] = "Нажмите на уведомление для подтверждения",
                ["MsgMyAdded"] = "Терминал успешно добавлен!",
                ["MsgMyRemoved"] = "Терминал успешно удален!",
                ["MsgMyAllRemoved"] = "Все ваши терминалы успешно удалены!",
                ["MsgPlayerAllRemoved"] = "Все терминалы игрока {0} успешно удалены!",
                ["MsgAllRemoved"] = "Все терминалы успешно удалены!",
                ["MsgTerminalsNotFound"] = "Терминалы не найдены!",
                ["MsgPlayerTerminalsNotFound"] = "Терминалы игрока {0} не найдены!",
                ["MsgNoHaveCustomFee"] = "Для оплаты персональной комиссии вам необходимо иметь :{0}:(x{1}).Использование настроек комиссии по умолчанию!"
            }, 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.UI_HUD_Icon_Url.StartsWithAny(new string[2] { "http://", "https://" }))
            {
                Dictionary<string, string> imgList = new Dictionary<string, string>() { { $"{Name}_Add", _config.UI_HUD_Icon_Url } };
                ImageLibrary?.Call("ImportImageList", Name, imgList, 0UL, true);
            }
        }
        
        private bool CanAddToVending(VendingMachine vending, string initID = "", bool sendReply = false)
        {
            bool result = false;
            string replyKey = string.Empty;
            string[] replyArgs = new string[10];
            if (vending != null)
            {
                _storedData.vDeliveryList.TryGetValue(vending.OwnerID, out var ownerData);
                if (permission.UserHasPermission(initID, PERMISSION_ADMIN))
                    result = true;
                else
                {
                    var ownerPlayer = covalence.Players.FindPlayerById($"{vending.OwnerID}");
                    if (ownerPlayer != null)
                    {
                        string userPerm = GetHighestPermission(ownerPlayer.Id);
                        if (string.IsNullOrWhiteSpace(userPerm))
                            replyKey = "MsgNotAllowed";
                        else if (!string.IsNullOrWhiteSpace(initID) && ownerPlayer.Id != initID)
                            replyKey = "MsgNotOwner";
                        else if (!_config.Ignore_Accessibility && !IsVendingAccessible(vending))
                            replyKey = "MsgNotAccessible";
                        else if (ownerData != null && !ownerData.Contains(vending.net.ID.Value) && ownerData.Count >= _config.LimitPerGroup[userPerm])
                        {
                            replyKey = "MsgLimitReached";
                            replyArgs[0] = $"{_config.LimitPerGroup[userPerm]}";
                        }    
                        else
                            result = true;

                        if (sendReply && !string.IsNullOrWhiteSpace(replyKey))
                        {
                            if (_config.Use_GameTips)
                                SendTemporaryTip(ownerPlayer, string.Format(lang.GetMessage(replyKey, this, ownerPlayer.Id), replyArgs), true);
                            else
                                ownerPlayer.Reply(lang.GetMessage(replyKey, this, ownerPlayer.Id));
                        }
                    }
                }
                if (!result && ownerData != null && ownerData.Contains(vending.net.ID.Value))
                    _storedData.vDeliveryList[vending.OwnerID].Remove(vending.net.ID.Value);
            }
            return result;
        }
        
        private void AddToVending(VendingMachine vending, bool sendReply = false)
        {
            if (vending == null) return;
            if (vending.children != null) RemoveFromVending(vending);//TODO replace to checking

            var ownerPlayer = covalence.Players.FindPlayerById($"{vending.OwnerID}");
            
            var marketPos = vending.transform.position + vending.transform.up * -2000f;
            var marketEnt = GameManager.server.CreateEntity(marketplacePrefab, marketPos, vending.transform.rotation) as Marketplace;
            if (marketEnt != null)
            {
                marketEnt.Spawn();
                marketEnt.SetParent(vending, true);
                marketEnt.droneLaunchPoint.position = vending.transform.position + vending.transform.forward * 1f + vending.transform.up * 1.5f;
                foreach (var terminal in marketEnt.terminalEntities)
                {
                    terminal.Get(true).Kill();
                }
            }

            var terPos = vending.transform.position + vending.transform.forward * _config.Display_Pos_Forward + vending.transform.up * _config.Display_Pos_Up + vending.transform.right * _config.Display_Pos_Right;
            var terRot = vending.transform.rotation * Quaternion.Euler(_config.Display_Rot_X, _config.Display_Rot_Y, _config.Display_Rot_Z);
            var terEnt = GameManager.server.CreateEntity(marketplaceTerminalPrefab, terPos, terRot) as MarketTerminal;
            if (terEnt != null)
            {
                terEnt.Spawn();
                terEnt.SetParent(vending, true);
                terEnt.Setup(marketEnt);
            }
            if (!_storedData.vDeliveryList.ContainsKey(vending.OwnerID))
                _storedData.vDeliveryList[vending.OwnerID] = new List<ulong>();
            _storedData.vDeliveryList[vending.OwnerID].Add(vending.net.ID.Value);
            if (sendReply)
            {
                if (_config.Use_GameTips)
                    SendTemporaryTip(ownerPlayer, lang.GetMessage("MsgMyAdded", this, ownerPlayer.Id));
                else
                    ownerPlayer.Reply(lang.GetMessage("MsgMyAdded", this, ownerPlayer.Id));
            }
        }
        
        private void RemoveFromVending(VendingMachine vending, bool isUnload = false)
        {
            if (vending != null && !vending.IsDestroyed && vending.children != null && vending.children.Count > 0)
            {
                var entitiesToRemove = Pool.GetList<BaseEntity>();
                foreach (var vendingChild in vending.children)
                {
                    if (vendingChild != null && !vendingChild.IsDestroyed && (vendingChild is MarketTerminal || vendingChild is Marketplace))
                        entitiesToRemove.Add(vendingChild);
                }
                foreach (var entToRemove in entitiesToRemove)
                {
                    if (entToRemove is MarketTerminal)
                    {
                        var inventory = ((MarketTerminal)entToRemove).inventory;
                        if (inventory != null && inventory.itemList.Count > 0)
                        {
                            var invPos = vending.transform.position + vending.transform.forward * -0.6f + vending.transform.up * 1f;
                            inventory.Drop(itemDropPrefab, invPos, vending.transform.rotation, 0f);
                        }
                    }
                    entToRemove.Kill();
                }
                Pool.FreeList(ref entitiesToRemove);
            }
            if (!isUnload && vending != null && _storedData.vDeliveryList.ContainsKey(vending.OwnerID))
                _storedData.vDeliveryList[vending.OwnerID].Remove(vending.net.ID.Value);
        }
        
        private void UpdateEntities()
        {
            var vList = _storedData.vDeliveryList.ToDictionary(entry => entry.Key, entry => new List<ulong>(entry.Value));
            foreach (var kvp in vList)
            {
                ulong key = kvp.Key;
                var vendingList = kvp.Value;
                var vendingsToCreate = Pool.GetList<VendingMachine>();
                foreach (var vendingID in vendingList)
                {
                    var vending = BaseNetworkable.serverEntities.Find(new NetworkableId(vendingID)) as VendingMachine;
                    if (vending != null && !vending.IsDestroyed && CanAddToVending(vending))
                        vendingsToCreate.Add(vending);
                    else if (_storedData.vDeliveryList[key].Contains(vendingID))
                        _storedData.vDeliveryList[key].Remove(vendingID);
                }
                if (vendingsToCreate.Count > 0)
                {
                    string userPerm = GetHighestPermission(key.ToString());
                    int limit = _config.LimitPerGroup[userPerm];
                    int counter = 0;
                    foreach (var vending in vendingsToCreate)
                    {
                        counter++;
                        if (counter <= limit)
                            AddToVending(vending);
                        else
                            _storedData.vDeliveryList[key].Remove(vending.net.ID.Value);
                    }
                }
                Pool.FreeList(ref vendingList);
            }
        }
        
        private void ClearEntities()
        {
            foreach (var vending in BaseNetworkable.serverEntities.OfType<VendingMachine>())
            {
                RemoveFromVending(vending, true);
            }
        }
        
        private FeeGroupConfiguration GetFeeByPermission(string permission)
        {
            if (!string.IsNullOrWhiteSpace(permission))
                return _config.FeePerGroup.FirstOrDefault(config => config.Permission_Name.Equals(permission, StringComparison.OrdinalIgnoreCase));
            return null;
        }

        private ItemContainer GetTerminalContainer(VendingMachine vending)
        {
            if (vending != null && vending.children != null)
            {
                foreach (var child in vending.children.OfType<MarketTerminal>())
                {
                    return child.inventory;
                }
            }
            return null;
        }
        
        private bool IsVendingDelivery(VendingMachine vending)
        {
            if (vending != null && vending.children != null)
                return vending.children.Any(e => e is MarketTerminal);
            return false;
        }
        
        public bool IsVendingAccessible(VendingMachine vending, Vector3 offset = default, Vector3 halfExtents = default, float testHeight = 200f)
        {
            if (offset.Equals(default))
                offset = new Vector3(0f, 1f, 1f);
            if (halfExtents.Equals(default))
                halfExtents = new Vector3(0.5f, 0.5f, 0.5f);
            Vector3 vector = vending.transform.TransformPoint(offset);
            if (Physics.BoxCast(vector + Vector3.up * testHeight, halfExtents, Vector3.down, vending.transform.rotation, testHeight, 161546496))
                return false;

            return vending.IsVisibleAndCanSee(vector);
        }
        
        private VendingMachine GetLookVending(BasePlayer player, float maxDistance = 10f)
        {
            if (Physics.Raycast(player.eyes.HeadRay(), out var hit, maxDistance, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore))
            {
                if (hit.GetEntity() is VendingMachine vending)
                    return vending;
            }
            return null;
        }
        
        private VendingMachine GetVendingFromArgs(BasePlayer player, string[] args)
        {
            if (args.Length > 1 && ulong.TryParse(args[1], out var entID))
            {
                var vendingByID = BaseNetworkable.serverEntities.Find(new NetworkableId(entID)) as VendingMachine;
                if (vendingByID != null)
                    return vendingByID;
            }
            return GetLookVending(player);
        }
        
        private List<VendingMachine> GetAllDeliveryVendings()
        {
            var vendingList = new List<VendingMachine>();
            foreach (var vending in BaseNetworkable.serverEntities.OfType<VendingMachine>())
            {
                if (vending != null && IsVendingDelivery(vending))
                    vendingList.Add(vending);
            }
            return vendingList;
        }
        
        private bool IsNPCVendingCustom(VendingMachine vendingMachine) => CustomVendingSetup?.Call("API_IsCustomized", vendingMachine as NPCVendingMachine) is bool result ? result : false;
        
        private static string StringColorFromHex(string hexColor, double transperent = 1)
        {
            if (hexColor[0] != '#' || hexColor.Length < 7)
                return $"1 1 1 {transperent:F2}";

            int red = Convert.ToInt32(hexColor.Substring(1, 2), 16);
            int green = Convert.ToInt32(hexColor.Substring(3, 2), 16);
            int blue = Convert.ToInt32(hexColor.Substring(5, 2), 16);

            double redPercentage = (double)red / 255;
            double greenPercentage = (double)green / 255;
            double bluePercentage = (double)blue / 255;

            return $"{redPercentage:F2} {greenPercentage:F2} {bluePercentage:F2} {transperent:F2}";
        }
        
        private static void SendEffect(Vector3 position, Network.Connection connection, string prefabName = "")
        {
            if (prefabName.Length < 10)
                prefabName = "assets/bundled/prefabs/fx/invite_notice.prefab";
            var effect = new Effect();
            effect.Init(Effect.Type.Generic, position, Vector3.zero);
            effect.pooledString = prefabName;
            EffectNetwork.Send(effect, connection);
        }
        
        private static void SendTemporaryTip(IPlayer player, string message, bool isWarning = false)
        {
            if (player != null)
                player.Command("gametip.showtoast", isWarning ? 1 : 0, message, null, null);
        }
        
        private string GetHighestPermission(string playerID)
        {
            if (!string.IsNullOrWhiteSpace(playerID))
            {
                if (permission.UserHasPermission(playerID, PERMISSION_THREE))
                    return PERMISSION_THREE;
                else if (permission.UserHasPermission(playerID, PERMISSION_TWO))
                    return PERMISSION_TWO;
                else if (permission.UserHasPermission(playerID, PERMISSION_ONE))
                    return PERMISSION_ONE;
            }
            return string.Empty;
        }
        
        private Dictionary<ulong, string> GetUsersInGroup(string groupName)
        {
            var userList = new Dictionary<ulong, string>();
            var groupData = permission.GetGroupData(groupName);
            if (groupData != null)
            {
                ulong userID;
                foreach (var user in permission.GetUsersInGroup(groupName))
                {
                    var parts = user.Split(new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length > 1)
                    {
                        if (ulong.TryParse(parts[0], out userID))
                            userList[userID] = parts[1];
                    }
                }
            }
            return userList;
        }

        private void RemoveVendingOnRevoke(ulong userID)
        {
            string perm = GetHighestPermission(userID.ToString());
            int counter = 0;
            var removeList = Pool.GetList<VendingMachine>();
            foreach (var netID in _storedData.vDeliveryList[userID])
            {
                var vending = BaseNetworkable.serverEntities.Find(new NetworkableId(netID)) as VendingMachine;
                if (vending != null)
                {
                    counter++;
                    if (string.IsNullOrWhiteSpace(perm) || counter > _config.LimitPerGroup[perm])
                        removeList.Add(vending);
                }
            }
            foreach (var vend in removeList)
            {
                RemoveFromVending(vend);
            }
            Pool.FreeList(ref removeList);
        }
        
        private void DestroyPlayerUI(BasePlayer player)
        {
            if (_playerUI.TryGetValue(player.userID, out var uiName))
            {
                CuiHelper.DestroyUi(player, uiName);
                _playerUI.Remove(player.userID);
            }
            if (_playerTimers.TryGetValue(player.userID, out var timer))
            {
                timer.Destroy();
                _playerTimers.Remove(player.userID);
            }
        }
        
        void DestroyAllUI()
        {
            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                DestroyPlayerUI(player);
            }
        }
        #endregion

        #region ~Hooks~
        void OnEntitySpawned(BaseNetworkable entity)
        {
            if (_serverLoaded && entity is VendingMachine vending)
            {
                if (_storedData.vDeliveryList.ContainsKey(vending.OwnerID) && _storedData.vDeliveryList[vending.OwnerID].Contains(vending.net.ID.Value)) return;
                var ownerPlayer = BasePlayer.FindByID(vending.OwnerID);
                if (ownerPlayer != null && CanAddToVending(vending))
                    ShowHUD(ownerPlayer, vending.net.ID);
            }
        }
        
        object OnEntityKill(BaseNetworkable entity)
        {
            if (entity is VendingMachine vending && IsVendingDelivery(vending))
            {
                var inventory = GetTerminalContainer(vending);
                if (inventory != null && inventory.itemList.Count > 0)
                {
                    var invPos = vending.transform.position + vending.transform.forward * -0.6f + vending.transform.up * 1f;
                    inventory.Drop(itemDropPrefab, invPos, vending.transform.rotation, 0f);
                }
                if (_storedData.vDeliveryList.ContainsKey(vending.OwnerID))
                    _storedData.vDeliveryList[vending.OwnerID].Remove(vending.net.ID.Value);
            }
            return null;
        }
        
        object OnRotateVendingMachine(VendingMachine machine, BasePlayer player)
        {
            if (!_config.Ignore_Accessibility && IsVendingDelivery(machine) && !IsVendingAccessible(machine, new Vector3(0f, 1f, -1.2f)))
            {
                if (_config.Use_GameTips)
                    SendTemporaryTip(player.IPlayer, lang.GetMessage("MsgNotAccessible", this, player.UserIDString));
                else
                    player.ChatMessage(lang.GetMessage("MsgNotAccessible", this, player.UserIDString));
                return false;
            }
            return null;
        }
        
        object OnVendingTransaction(VendingMachine shopVending, BasePlayer buyer, int sellOrderId, int numberOfTransactions, ItemContainer targetContainer)
        {
            if (targetContainer != null)
            {
                var parentVending = targetContainer.GetEntityOwner().GetParentEntity() as VendingMachine;
                if (parentVending != null && !IsVendingAccessible(parentVending))
                {
                    if (_config.Use_GameTips)
                        SendTemporaryTip(buyer.IPlayer, lang.GetMessage("MsgNotAccessible", this, buyer.UserIDString));
                    else
                        buyer.ChatMessage(lang.GetMessage("MsgNotAccessible", this, buyer.UserIDString));
                    return false;
                }
            }
            return null;
        }
        
        object CanPurchaseItem(BasePlayer buyer, Item item, Action<BasePlayer, Item> onItemPurchased, VendingMachine shopVending, ItemContainer targetContainer)
        {
            if (targetContainer != null && shopVending != null && targetContainer.GetEntityOwner() is MarketTerminal terminal && terminal.GetParentEntity() is VendingMachine parentVending)
            {
                string userPerm = GetHighestPermission(buyer.UserIDString);
                var feeValue = GetFeeByPermission(userPerm);
                if (feeValue != null)
                {
                    int deliveryFeeAmount = feeValue.Delivery_Fee_Item_Amount;
                    var deliveryFeeCurrency = ItemManager.FindItemDefinition(feeValue.Delivery_Fee_Item_Definition);

                    if (deliveryFeeCurrency != null)
                    {
                        if ((feeValue.Delivery_Fee_Item_Definition != "scrap" || (feeValue.Delivery_Fee_Item_Definition == "scrap" && feeValue.Delivery_Fee_Item_Amount != 20)) && !IsNPCVendingCustom(shopVending))
                        {
                            int takenAmount = buyer.inventory.Take(null, deliveryFeeCurrency.itemid, deliveryFeeAmount);
                            if (takenAmount != deliveryFeeAmount)
                            {
                                if (takenAmount > 0)
                                {
                                    Item defaultFeeItem = ItemManager.CreateByItemID(deliveryFeeCurrency.itemid, takenAmount, 0uL);
                                    if (!buyer.inventory.GiveItem(defaultFeeItem))
                                    {
                                        defaultFeeItem.Drop(buyer.inventory.containerMain.dropPosition, buyer.inventory.containerMain.dropVelocity);
                                    }
                                }

                                string replyKey = "MsgNoHaveCustomFee";
                                string[] replyArgs = new string[2] { feeValue.Delivery_Fee_Item_Definition, $"{deliveryFeeAmount}" };
                                if (_config.Use_GameTips)
                                    SendTemporaryTip(buyer.IPlayer, string.Format(lang.GetMessage(replyKey, this, buyer.UserIDString), replyArgs));
                                else
                                    buyer.ChatMessage(string.Format(lang.GetMessage(replyKey, this, buyer.UserIDString), replyArgs));
                            }
                            else
                            {
                                Item defaultFeeItem = ItemManager.CreateByItemID(terminal.deliveryFeeCurrency.itemid, terminal.deliveryFeeAmount, 0uL);
                                if (!buyer.inventory.GiveItem(defaultFeeItem))
                                {
                                    defaultFeeItem.Drop(buyer.inventory.containerMain.dropPosition, buyer.inventory.containerMain.dropVelocity);
                                }
                            }

                            Facepunch.Rust.Analytics.Server.VendingMachineTransaction(null, item.info, item.amount);
                            if (!item.MoveToContainer(targetContainer))
                            {
                                item.Drop(targetContainer.dropPosition, targetContainer.dropVelocity);
                            }
                            onItemPurchased?.Invoke(buyer, item);

                            return true;
                        }
                    }
                    else
                        PrintWarning($"Could not find an item with the name {feeValue.Delivery_Fee_Item_Definition} for user {buyer.displayName} with permission {userPerm}.Using default fee settings.");
                }
            }
            return null;
        }
        
        void OnUserPermissionRevoked(string id, string permName)
        {
            if (permName != PERMISSION_ONE && permName != PERMISSION_TWO && permName != PERMISSION_THREE) return;
            
            ulong userID;
            if (ulong.TryParse(id, out userID) && _storedData.vDeliveryList.ContainsKey(userID))
                RemoveVendingOnRevoke(userID);
        }
        
        void OnGroupPermissionRevoked(string name, string permName)
        {
            if (permName != PERMISSION_ONE && permName != PERMISSION_TWO && permName != PERMISSION_THREE) return;
            
            foreach (var userID in GetUsersInGroup(permName).Keys)
            {
                if (_storedData.vDeliveryList.ContainsKey(userID))
                    RemoveVendingOnRevoke(userID);
            }
        }
        
        void OnPluginLoaded(Plugin plugin)
        {
            if (plugin == ImageLibrary)
                ImgLibCheck();
        }
        
        void OnPluginUnloaded(Plugin plugin)
        {
            if (plugin.Name == "ImageLibrary")
                _imgLibIsLoaded = false;
        }
        
        void OnServerInitialized()
        {
            _serverLoaded = true;
            permission.RegisterPermission(PERMISSION_ONE, this);
            permission.RegisterPermission(PERMISSION_TWO, this);
            permission.RegisterPermission(PERMISSION_THREE, this);
            permission.RegisterPermission(PERMISSION_ADMIN, this);
            AddCovalenceCommand(_config.Command, nameof(vDelivery_Command));
            ImgLibCheck();
            UpdateEntities();
        }
        
        void OnServerSave()
        {
            SaveData();
        }
        #endregion

        #region ~Commands~
        private void vDelivery_Command(IPlayer player, string command, string[] args)
        {
            bool isAdmin = permission.UserHasPermission(player.Id, PERMISSION_ADMIN);
            string userPerm = GetHighestPermission(player.Id);
            if (!isAdmin && string.IsNullOrWhiteSpace(userPerm))
            {
                if (player != null)
                {
                    if (_config.Use_GameTips)
                        SendTemporaryTip(player, lang.GetMessage("MsgNotAllowed", this, player.Id), true);
                    else
                        player.Reply(lang.GetMessage("MsgNotAllowed", this, player.Id));
                }
                return;
            }
            string replyKey = string.Empty;
            string[] replyArgs = new string[10];
            
            if (player.Object is BasePlayer bPlayer && args != null && args.Length > 0)
            {
                var vending = GetVendingFromArgs(bPlayer, args);
                
                if (args[0] == "add")
                {
                    if (vending == null)
                        replyKey = "MsgNotVending";
                    else if (CanAddToVending(vending, player.Id, true))
                        AddToVending(vending, true);
                }
                else if (args[0] == "remove")
                {
                    if (vending == null)
                        replyKey = "MsgNotVending";
                    else if (!IsVendingDelivery(vending))
                        replyKey = "MsgNotVendingDelivery";
                    else if (!isAdmin && vending.OwnerID != bPlayer.userID)
                        replyKey = "MsgNotOwner";
                    else
                    {
                        RemoveFromVending(vending);
                        replyKey = "MsgMyRemoved";
                    }
                }
                else if (args[0] == "clear")
                {
                    var removeList = Pool.GetList<VendingMachine>();
                    if (isAdmin && args.Length > 1)
                    {
                        ulong userID;
                        if (ulong.TryParse(args[1], out userID))
                        {
                            if (_storedData.vDeliveryList.ContainsKey(userID))
                            {
                                foreach (var netID in _storedData.vDeliveryList[userID])
                                {
                                    var netVending = BaseNetworkable.serverEntities.Find(new NetworkableId(netID)) as VendingMachine;
                                    if (netVending != null)
                                        removeList.Add(netVending);
                                }
                                replyKey = "MsgPlayerAllRemoved";
                            }
                            if (removeList.Count == 0)
                                replyKey = "MsgPlayerTerminalsNotFound";
                            replyArgs[0] = userID.ToString();
                        }
                        else if (args[1] == "all")
                        {
                            removeList = GetAllDeliveryVendings();
                            replyKey = "MsgAllRemoved";
                        }
                    }
                    if (string.IsNullOrWhiteSpace(replyKey) && _storedData.vDeliveryList.ContainsKey(bPlayer.userID))
                    {
                        foreach (var netID in _storedData.vDeliveryList[bPlayer.userID])
                        {
                            var netVending = BaseNetworkable.serverEntities.Find(new NetworkableId(netID)) as VendingMachine;
                            if (netVending != null)
                                removeList.Add(netVending);
                        }
                        replyKey = "MsgMyAllRemoved";
                    }
                    
                    if (string.IsNullOrWhiteSpace(replyKey) && removeList.Count < 1)
                        replyKey = "MsgTerminalsNotFound";
                    foreach (var vend in removeList)
                    {
                        RemoveFromVending(vend);
                    }
                    Pool.FreeList(ref removeList);
                }
            }
            
            if (!string.IsNullOrWhiteSpace(replyKey))
            {
                if (_config.Use_GameTips)
                    SendTemporaryTip(player, string.Format(lang.GetMessage(replyKey, this, player.Id), replyArgs));
                else
                    player.Reply(string.Format(lang.GetMessage(replyKey, this, player.Id), replyArgs));
            }
        }
        #endregion

        #region ~UI~
        private void ShowHUD(BasePlayer player, NetworkableId entID)
        {
            if (_playerUI.ContainsKey(player.userID))
                DestroyPlayerUI(player);
            
            SendEffect(player.transform.position, player.Connection, _config.Sound_ShowHUD_Prefab);
            CuiElementContainer container = new CuiElementContainer();
            container.Add(new CuiPanel
            {
                RectTransform = { AnchorMin = _config.UI_HUD_AnchorMin, AnchorMax = _config.UI_HUD_AnchorMax, OffsetMin = _config.UI_HUD_OffsetMin, OffsetMax = _config.UI_HUD_OffsetMax },
                Image = { Color = "0 0 0 0" }
            }, "Overlay", UI_HUD_Name);
            ICuiComponent Icon;
            if (!_imgLibIsLoaded)
                Icon = new CuiRawImageComponent { Url = _config.UI_HUD_Icon_Url };
            else
                Icon = new CuiImageComponent { Color = StringColorFromHex(_config.UI_HUD_Icon_Color, _config.UI_HUD_Icon_Transparency), Png = (string)ImageLibrary?.Call("GetImage", $"{Name}_Add") };
            container.Add(new CuiElement
            {
                Parent = UI_HUD_Name,
                Components =
                {
                    Icon,
                    new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "0.15 1", OffsetMin = "5 5", OffsetMax = "-5 -5" }
                }
            });
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = lang.GetMessage("MsgAddBtn", this, player.UserIDString),
                    Font = _config.UI_HUD_Text_Font,
                    FontSize = _config.UI_HUD_Text_Font_Size,
                    Color = StringColorFromHex(_config.UI_HUD_Text_Font_Color),
                    Align = TextAnchor.UpperLeft
                },
                RectTransform = { AnchorMin = "0.15 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "5 -5" }
            }, UI_HUD_Name);
            container.Add(new CuiLabel
            {
                Text =
                {
                    Text = lang.GetMessage("MsgAddBtnDesc", this, player.UserIDString),
                    Font = _config.UI_HUD_Text_Desc_Font,
                    FontSize = _config.UI_HUD_Text_Desc_Font_Size,
                    Color = StringColorFromHex(_config.UI_HUD_Text_Desc_Font_Color),
                    Align = TextAnchor.LowerLeft
                },
                RectTransform = { AnchorMin = "0.15 0", AnchorMax = "1 1", OffsetMin = "0 5", OffsetMax = "5 0" }
            }, UI_HUD_Name);
            container.Add(new CuiButton
            {
                Button =
                {
                    Close = UI_HUD_Name,
                    Command = $"{_config.Command} add {entID}",
                    Color = "0 0 0 0"
                },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0" }
            }, UI_HUD_Name);

            CuiHelper.AddUi(player, container);
            _playerUI[player.userID] = UI_HUD_Name;
            Timer newTimer = timer.Once(_config.UI_Duration, () =>
            {
                DestroyPlayerUI(player);
            });
            _playerTimers[player.userID] = newTimer;
        }
        #endregion

        #region ~Unload~
        void Unload()
        {
            SaveData();
            ClearEntities();
            DestroyAllUI();
            _storedData = null;
            _config = null;
        }
        #endregion
    }
}

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