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

FREE vDelivery : 0.1.3 0.1.3

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6

/*
*  < ----- End-User License Agreement ----->
*  
*  You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of this software without the developer’s consent.*
*  THIS SOFTWARE IS PROVIDED BY IIIaKa AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
*  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 
*  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
*  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*
*  Developer: IIIaKa
*      https://t.me/iiiaka
*      Discord: @iiiaka
*      https://github.com/IIIaKa
*      https://umod.org/user/IIIaKa
*      https://codefling.com/iiiaka
*      https://www.patreon.com/iiiaka
*      https://boosty.to/iiiaka
*  Codefling plugin page: https://codefling.com/plugins/vdelivery
*  Codefling license: https://codefling.com/plugins/vdelivery?tab=downloads_field_4
*
*  Copyright © 2023-2024 IIIaKa
*/
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.3")]
    [Description("Allows you to add delivery drones to your vending machine through which you can order various items.")]
    class vDelivery : RustPlugin {
        [PluginReference]
        private Plugin ImageLibrary, CustomVendingSetup;
#region ~Variables~
        private const string PERMISSION_ADMIN = "vDelivery.admin", UI_Name = "vDelivery_Popup", MarketplacePrefab = "assets/prefabs/misc/marketplace/marketplace.prefab", MarketplaceTerminalPrefab = "assets/prefabs/misc/marketplace/marketterminal.prefab", ItemDropPrefab = "assets/prefabs/misc/item drop/item_drop.prefab";
        private ulong _skinID = 3074297551uL;
        private Dictionary<ulong, Timer> _playerTimers = new Dictionary<ulong, Timer>();
        private Vector3 _terminalPos = Vector3.zero, _marketPos = new Vector3(0f, -2000f, 0f);
        private string _iconColor, _textColor, _text2Color;
#endregion
#region ~Configuration~
        private static Configuration _config;
        private class Configuration {
            [JsonProperty(PropertyName = "Chat command")]
            public string Command = "vdelivery";
            [JsonProperty(PropertyName = "Is it worth enabling GameTips for messages?")]
            public bool GameTips_Enabled = 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 = "Popup - Duration")]
            public float Popup_Duration = 6f;
            [JsonProperty(PropertyName = "Popup - Position AnchorMin")]
            public string Popup_AnchorMin = "0 0.9";
            [JsonProperty(PropertyName = "Popup - Position AnchorMax")]
            public string Popup_AnchorMax = "0.25 1";
            [JsonProperty(PropertyName = "Popup - Position OffsetMin")]
            public string Popup_OffsetMin = "20 0";
            [JsonProperty(PropertyName = "Popup - Position OffsetMax")]
            public string Popup_OffsetMax = "0 -30";
            [JsonProperty(PropertyName = "Popup - Icon Url")]
            public string Popup_Icon_Url = "https://i.imgur.com/4Adzkb8.png";
            [JsonProperty(PropertyName = "Popup - Icon Color")]
            public string Popup_Icon_Color = "#CCE699";
            [JsonProperty(PropertyName = "Popup - Icon Transparency")]
            public float Popup_Icon_Transparency = 0.8f;
            [JsonProperty(PropertyName = "Popup - Text Font(https://umod.org/guides/rust/basic-concepts-of-gui#fonts)")]
            public string Popup_Text_Font = "RobotoCondensed-Bold.ttf";
            [JsonProperty(PropertyName = "Popup - Text Font Size")]
            public int Popup_Text_Font_Size = 14;
            [JsonProperty(PropertyName = "Popup - Text Font Color")]
            public string Popup_Text_Font_Color = "#FFFFFF";
            [JsonProperty(PropertyName = "Popup - Description Font")]
            public string Popup_Desc_Font = "RobotoCondensed-Regular.ttf";
            [JsonProperty(PropertyName = "Popup - Description Font Size")]
            public int Popup_Desc_Font_Size = 12;
            [JsonProperty(PropertyName = "Popup - Description Font Color")]
            public string Popup_Desc_Font_Color = "#FFFFFF";
            [JsonProperty(PropertyName = "Popup - Text FadeIn")]
            public float Popup_Text_FadeIn = 1f;
            [JsonProperty(PropertyName = "Popup - Sound Prefab Name")]
            public string Popup_Sound_Prefab = "assets/bundled/prefabs/fx/invite_notice.prefab";
            [JsonProperty(PropertyName = "Settings of vending machines for each permission.Leave null or empty to recreate the default")]
            public Dictionary<string, PermissionLimit> PermissionsLimits = new Dictionary<string, PermissionLimit>();
            public Oxide.Core.VersionNumber Version;
        }
        public class PermissionLimit {
            [JsonProperty(PropertyName = "Max ammount")]
            public int Max_Amount;
            [JsonProperty(PropertyName = "Delivery fee item")]
            public string Fee_Item_Definition;
            [JsonProperty(PropertyName = "Delivery fee amount")]
            public int Fee_Item_Amount;
            public PermissionLimit(int limit = 1, string fee_Item_Definition = "scrap", int fee_Item_Amount = 20) {
                Max_Amount = limit;
                Fee_Item_Definition = fee_Item_Definition;
                Fee_Item_Amount = fee_Item_Amount;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
            }
            catch (Exception ex) {
                PrintError($"{ex.Message}\n\n[{Title}] Your configuration file contains an error.");
            }
            if (_config == null || _config.Version == new VersionNumber()) {
                PrintWarning("The configuration file is not found or contains errors.Creating a new one...");
                LoadDefaultConfig();
            }
            else if (_config.Version < Version) {
                PrintWarning($"Your configuration file version({_config.Version}) is outdated.Updating it to {Version}.");
                _config.Version = Version;
                PrintWarning($"The configuration file has been successfully updated to version {_config.Version}!");
            }
            _terminalPos = new Vector3(_config.Display_Pos_Right, _config.Display_Pos_Up, _config.Display_Pos_Forward);
            _iconColor = StringColorFromHex(_config.Popup_Icon_Color, _config.Popup_Icon_Transparency);
            _textColor = StringColorFromHex(_config.Popup_Text_Font_Color);
            _text2Color = StringColorFromHex(_config.Popup_Desc_Font_Color);
            if (_config.PermissionsLimits == null || !_config.PermissionsLimits.Any()) _config.PermissionsLimits = new Dictionary<string, PermissionLimit>() {
                {
                    "vDelivery.default", new PermissionLimit(1)
                }
                , {
                    "vDelivery.vip", new PermissionLimit(3)
                }
                , {
                    "realpve.vip", new PermissionLimit(5)
                }
            }
            ;
            SaveConfig();
        }
        protected override void SaveConfig() => Config.WriteObject(_config);
        protected override void LoadDefaultConfig() => _config = new Configuration() {
            Version = Version
        }
        ;
#endregion
#region ~DataFile~
        private static StoredData _storedData;
        private class StoredData {
            [JsonProperty(PropertyName = "Player's Data")]
            public Dictionary<ulong, PlayerData> PlayersData = new Dictionary<ulong, PlayerData>();
        }
        public class PlayerData {
            public bool AutoModify = true;
            public HashSet<ulong> Vendings = new HashSet<ulong>();
        }
        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}!", ["MsgPopupText"] = "Add a terminal to the vending machine?", ["MsgPopupSubText"] = "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!", ["MsgAutoModifyEntityEnabled"] = "Automatic entity modification is enabled!", ["MsgAutoModifyEntityDisabled"] = "Automatic entity modification is disabled!"
            }
            , this);
            lang.RegisterMessages(new Dictionary<string, string> {
                ["MsgNotAllowed"]
                = "У вас недостаточно прав для использования этой команды!", ["MsgNotOwner"] = "Вы не являетесь владельцем данного торгового автомата!", ["MsgNotAccessible"] = "Торговый автомат не доступен для дронов!", ["MsgNotVending"] = "Вам необходимо смотреть на торговый автомат или указать корректный net ID!", ["MsgNotVendingDelivery"] = "Торговый автомат не имеет терминала!", ["MsgLimitReached"] = "Вы не можете добавить терминал, так как вы превысили свой лимит в {0}!", ["MsgPopupText"] = "Добавить терминал к торговому автомату?", ["MsgPopupSubText"] = "Нажмите на уведомление для подтверждения", ["MsgMyAdded"] = "Терминал успешно добавлен!", ["MsgMyRemoved"] = "Терминал успешно удален!", ["MsgMyAllRemoved"] = "Все ваши терминалы успешно удалены!", ["MsgPlayerAllRemoved"] = "Все терминалы игрока {0} успешно удалены!", ["MsgAllRemoved"] = "Все терминалы успешно удалены!", ["MsgTerminalsNotFound"] = "Терминалы не найдены!", ["MsgPlayerTerminalsNotFound"] = "Терминалы игрока {0} не найдены!", ["MsgNoHaveCustomFee"] = "Для оплаты персональной комиссии вам необходимо иметь :{0}:(x{1}).Использование настроек комиссии по умолчанию!", ["MsgAutoModifyEntityEnabled"] = "Автоматическая модификация сущностей включена!", ["MsgAutoModifyEntityDisabled"] = "Автоматическая модификация сущностей выключена!"
            }
            , this, "ru");
        }
#endregion
#region ~Methods~
        private void LoadImage() => ImageLibrary?.Call("AddImage", _config.Popup_Icon_Url, UI_Name, 0uL);
        private bool CanModifyVending(VendingMachine vending, PlayerData playerData, IPlayer player = null) {
            string ownerID = vending.OwnerID.ToString();
            if (permission.UserHasPermission(ownerID, PERMISSION_ADMIN)) return true;
            bool result = false;
            string replyKey = string.Empty;
            string[] replyArgs = new string[5];
            int limit = GetHighestLimit(ownerID);
            if (limit == int.MinValue) replyKey = "MsgNotAllowed";
            else if (!_config.Ignore_Accessibility && !IsVendingAccessible(vending)) replyKey = "MsgNotAccessible";
            else if (limit != -1 && !playerData.Vendings.Contains(vending.net.ID.Value) && playerData.Vendings.Count >= limit) {
                replyKey = "MsgLimitReached";
                replyArgs[0] = limit.ToString();
            }
            else result = true;
            if (!result) {
                if (player != null) SendMessage(player, string.Format(lang.GetMessage(replyKey, this, player.Id), replyArgs), true);
                playerData.Vendings.Remove(vending.net.ID.Value);
            }
            return result;
        }
        private void ModifyVending(VendingMachine vending, bool sendReply = false) {
            RemoveFromVending(vending, true);
            if (!_storedData.PlayersData.TryGetValue(vending.OwnerID, out var playerData)) return;
            vending.skinID = _skinID;
            var marketEnt = GameManager.server.CreateEntity(MarketplacePrefab) as Marketplace;
            if (marketEnt != null) {
                marketEnt.skinID = _skinID;
                marketEnt.Spawn();
                marketEnt.SetParent(vending, true);
                marketEnt.transform.localPosition = _marketPos;
                marketEnt.transform.localRotation = Quaternion.identity;
                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 terEnt = GameManager.server.CreateEntity(MarketplaceTerminalPrefab) as MarketTerminal;
            if (terEnt != null) {
                terEnt.skinID = _skinID;
                terEnt.Spawn();
                terEnt.SetParent(vending, true);
                terEnt.transform.localPosition = _terminalPos;
                terEnt.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
                terEnt.Setup(marketEnt);
            }
            playerData.Vendings.Add(vending.net.ID.Value);
            if (sendReply && covalence.Players.FindPlayerById(vending.OwnerID.ToString()) is IPlayer player) SendMessage(player, lang.GetMessage("MsgMyAdded", this, player.Id));
        }
        private void RemoveFromVending(VendingMachine vending, bool isUnload = false) {
            if (vending.skinID == _skinID) vending.skinID = 0uL;
            if (IsVendingHasTerminal(vending)) {
                var entitiesToRemove = Pool.Get<List<BaseEntity>>();
                foreach (var vendingChild in vending.children) {
                    if (!vendingChild.IsDestroyed && (vendingChild is MarketTerminal || vendingChild is Marketplace)) entitiesToRemove.Add(vendingChild);
                }
                foreach (var entToRemove in entitiesToRemove) {
                    if (entToRemove is MarketTerminal market) {
                        var inventory = market.inventory;
                        if (inventory != null && inventory.itemList.Any()) inventory.Drop(ItemDropPrefab, vending.dropPosition, vending.transform.rotation, 0f);
                    }
                    entToRemove.Kill();
                }
                Pool.FreeUnmanaged(ref entitiesToRemove);
            }
            if (!isUnload && _storedData.PlayersData.TryGetValue(vending.OwnerID, out var playerData)) playerData.Vendings.Remove(vending.net.ID.Value);
        }
        private void RemoveVendingOnRevoke(ulong userID, PlayerData playerData) {
            int counter = 0, limit = GetHighestLimit(userID.ToString());
            var removeList = Pool.Get<List<VendingMachine>>();
            foreach (var netID in playerData.Vendings) {
                var vending = BaseNetworkable.serverEntities.Find(new NetworkableId(netID)) as VendingMachine;
                if (vending != null) {
                    counter++;
                    if (counter > limit) removeList.Add(vending);
                }
            }
            foreach (var vending in removeList) RemoveFromVending(vending);
            Pool.FreeUnmanaged(ref removeList);
        }
        private void ClearEntities(bool isUnload = false) {
            foreach (var entity in BaseNetworkable.serverEntities) {
                if (entity is VendingMachine vending) RemoveFromVending(vending, isUnload);
            }
        }
        private void InitPlayer(BasePlayer player) {
            if (!_storedData.PlayersData.ContainsKey(player.userID)) _storedData.PlayersData[player.userID] = new PlayerData();
        }
        private bool GetTerminalContainer(VendingMachine vending, out ItemContainer result) {
            result = null;
            if (vending.children != null) {
                foreach (var child in vending.children) {
                    if (child is MarketTerminal terminal) {
                        result = terminal.inventory;
                        break;
                    }
                }
            }
            return result != null && result.itemList.Any();
        }
        private bool IsVendingHasTerminal(VendingMachine vending) => vending.children != null && vending.children.Any(e => e is MarketTerminal);
        private bool IsNPCVendingCustom(VendingMachine vendingMachine) => (bool)(CustomVendingSetup?.Call("API_IsCustomized", vendingMachine as NPCVendingMachine) ?? 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 bool GetVendingFromArgs(BasePlayer player, string[] args, out VendingMachine result) {
            result = null;
            if (args.Length > 1 && ulong.TryParse(args[1], out var entID)) {
                var vendingByID = BaseNetworkable.serverEntities.Find(new NetworkableId(entID)) as VendingMachine;
                if (vendingByID != null) result = vendingByID;
            }
            if (result == null && Physics.Raycast(player.eyes.HeadRay(), out var hit, 10f, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore) && hit.GetEntity() is VendingMachine vending) result = vending;
            return result != null;
        }
        private int GetHighestLimit(string userID) {
            int result = int.MinValue, limit;
            foreach (var kvp in _config.PermissionsLimits) {
                limit = kvp.Value.Max_Amount;
                if (limit == -1) {
                    if (permission.UserHasPermission(userID, kvp.Key)) return limit;
                    continue;
                }
                if (result < limit && permission.UserHasPermission(userID, kvp.Key)) result = limit;
            }
            return result;
        }
        private bool GetDeliveryFee(string userID, out PermissionLimit result) {
            result = null;
            int highestAmount = int.MinValue, lowestFee = int.MaxValue;
            foreach (var kvp in _config.PermissionsLimits) {
                if (!permission.UserHasPermission(userID, kvp.Key)) continue;
                int maxAmount = kvp.Value.Max_Amount, feeAmount = kvp.Value.Fee_Item_Amount;
                if (maxAmount > highestAmount) {
                    highestAmount = maxAmount;
                    lowestFee = feeAmount;
                    result = kvp.Value;
                }
                else if (maxAmount == highestAmount && feeAmount < lowestFee) {
                    lowestFee = feeAmount;
                    result = kvp.Value;
                }
            }
            return result != null;
        }
        private static string StringColorFromHex(string hexColor, double transperent = 1d) {
            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 SendMessage(IPlayer player, string message, bool isWarning = false) {
            if (_config.GameTips_Enabled) player.Command("gametip.showtoast", (int)(isWarning ? GameTip.Styles.Error : GameTip.Styles.Blue_Normal), message, string.Empty);
            else player.Reply(message);
        }
        private void DestroyPopup(BasePlayer player) {
            if (_playerTimers.TryGetValue(player.userID, out var timer)) {
                CuiHelper.DestroyUi(player, UI_Name);
                if (timer != null) timer.Destroy();
                _playerTimers.Remove(player.userID);
            }
        }
#endregion
#region ~Oxide Hooks~
        void OnPlayerConnected(BasePlayer player) => InitPlayer(player);
        void OnEntitySpawned(VendingMachine vending) {
            if (!vending.OwnerID.IsSteamId() || !_storedData.PlayersData.TryGetValue(vending.OwnerID, out var playerData) || !CanModifyVending(vending, playerData)) return;
            if (playerData.AutoModify) ModifyVending(vending, true);
            else ShowPopup(vending);
        }
        object OnEntityKill(VendingMachine vending) {
            if (vending.skinID == _skinID && GetTerminalContainer(vending, out var inventory)) inventory.Drop(ItemDropPrefab, vending.dropPosition, vending.transform.rotation, 0f);
            if (vending.OwnerID.IsSteamId() && _storedData.PlayersData.TryGetValue(vending.OwnerID, out var playerData)) playerData.Vendings.Remove(vending.net.ID.Value);
            return null;
        }
        object OnRotateVendingMachine(VendingMachine vending, BasePlayer player) {
            if (vending.skinID == _skinID && !IsVendingAccessible(vending, new Vector3(0f, 1f, -1.2f))) {
                SendMessage(player.IPlayer, lang.GetMessage("MsgNotAccessible", this, player.UserIDString), true);
                return false;
            }
            return null;
        }
        object OnVendingTransaction(VendingMachine shopVending, BasePlayer buyer, int sellOrderId, int numberOfTransactions, ItemContainer targetContainer) {
            var marketTerminal = targetContainer?.GetEntityOwner() as MarketTerminal;
            var vending = marketTerminal?.GetParentEntity() as VendingMachine;
            if (marketTerminal != null && vending != null && vending.skinID == _skinID && !IsVendingAccessible(vending)) {
                marketTerminal.ClientRPC(RpcTarget.Player("Client_CloseMarketUI", buyer));
                SendMessage(buyer.IPlayer, lang.GetMessage("MsgNotAccessible", this, buyer.UserIDString), true);
                return false;
            }
            return null;
        }
        object CanPurchaseItem(BasePlayer buyer, Item item, Action<BasePlayer, Item> onItemPurchased, VendingMachine shopVending, ItemContainer targetContainer) {
            if (targetContainer != null && targetContainer.GetEntityOwner() is MarketTerminal terminal && terminal.skinID == _skinID && !IsNPCVendingCustom(shopVending) && GetDeliveryFee(buyer.UserIDString, out var feeValue)) {
                int deliveryFeeAmount = feeValue.Fee_Item_Amount;
                var deliveryFeeCurrency = ItemManager.FindItemDefinition(feeValue.Fee_Item_Definition);
                if (deliveryFeeCurrency != null) {
                    if (feeValue.Fee_Item_Definition != "scrap" || feeValue.Fee_Item_Amount != 20) {
                        int takenAmount = buyer.inventory.Take(null, deliveryFeeCurrency.itemid, deliveryFeeAmount);
                        if (takenAmount != deliveryFeeAmount) {
                            if (takenAmount > 0) {
                                var defaultFeeItem = ItemManager.CreateByItemID(deliveryFeeCurrency.itemid, takenAmount, 0uL);
                                if (!buyer.inventory.GiveItem(defaultFeeItem)) defaultFeeItem.Drop(buyer.inventory.containerMain.dropPosition, buyer.inventory.containerMain.dropVelocity);
                            }
                            SendMessage(buyer.IPlayer, string.Format(lang.GetMessage("MsgNoHaveCustomFee", this, buyer.UserIDString), new string[] {
                                feeValue.Fee_Item_Definition, deliveryFeeAmount.ToString()
                            }
                            ), true);
                        }
                        else {
                            var 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.Fee_Item_Definition} for user {buyer.displayName}.Using default fee settings.");
            }
            return null;
        }
        void OnUserPermissionRevoked(string id, string permName) {
            if (_config.PermissionsLimits.ContainsKey(permName) && ulong.TryParse(id, out ulong userID) && _storedData.PlayersData.TryGetValue(userID, out var playerData) && !permission.UserHasPermission(id, PERMISSION_ADMIN)) RemoveVendingOnRevoke(userID, playerData);
        }
        void OnGroupPermissionRevoked(string groupName, string permName) {
            if (!_config.PermissionsLimits.ContainsKey(permName) || !permission.GroupExists(groupName)) return;
            foreach (var userStr in permission.GetUsersInGroup(groupName)) {
                var userIDString = userStr.Substring(0, userStr.IndexOf('(')).Trim();
                if (ulong.TryParse(userIDString, out var userID) && _storedData.PlayersData.TryGetValue(userID, out var playerData) && permission.UserHasPermission(userIDString, PERMISSION_ADMIN) && !permission.UserHasPermission(userIDString, permName)) {
                    RemoveVendingOnRevoke(userID, playerData);
                }
            }
        }
        void Init() {
            Unsubscribe(nameof(OnPlayerConnected));
            Unsubscribe(nameof(OnEntitySpawned));
            Unsubscribe(nameof(OnEntityKill));
            Unsubscribe(nameof(OnRotateVendingMachine));
            Unsubscribe(nameof(OnVendingTransaction));
            Unsubscribe(nameof(CanPurchaseItem));
            Unsubscribe(nameof(OnUserPermissionRevoked));
            Unsubscribe(nameof(OnGroupPermissionRevoked));
            Unsubscribe(nameof(OnServerSave));
            permission.RegisterPermission(PERMISSION_ADMIN, this);
            AddCovalenceCommand(_config.Command, nameof(vDelivery_Command));
            _storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
        }
        void OnServerInitialized() {
            foreach (var perm in _config.PermissionsLimits.Keys) {
                if (perm.StartsWith("vDelivery")) permission.RegisterPermission(perm, this);
            }
            LoadImage();
            var rList = Pool.Get<List<ulong>>();
            foreach (var kvp in _storedData.PlayersData) {
                var playerData = kvp.Value;
                int counter = 0, limit = GetHighestLimit(kvp.Key.ToString());
                foreach (var netID in playerData.Vendings) {
                    var vending = BaseNetworkable.serverEntities.Find(new NetworkableId(netID)) as VendingMachine;
                    if (vending != null && !vending.IsDestroyed) {
                        counter++;
                        if (limit != -1 && counter > limit) {
                            rList.Add(netID);
                            continue;
                        }
                        ModifyVending(vending);
                    }
                    else rList.Add(netID);
                }
                foreach (var netID in rList) playerData.Vendings.Remove(netID);
                rList.Clear();
            }
            Pool.FreeUnmanaged(ref rList);
            foreach (var player in BasePlayer.activePlayerList) {
                if (player.userID.IsSteamId()) InitPlayer(player);
            }
            Subscribe(nameof(OnPlayerConnected));
            Subscribe(nameof(OnEntitySpawned));
            Subscribe(nameof(OnEntityKill));
            if (!_config.Ignore_Accessibility) {
                Subscribe(nameof(OnRotateVendingMachine));
                Subscribe(nameof(OnVendingTransaction));
            }
            Subscribe(nameof(CanPurchaseItem));
            Subscribe(nameof(OnUserPermissionRevoked));
            Subscribe(nameof(OnGroupPermissionRevoked));
            Subscribe(nameof(OnServerSave));
        }
        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 replyKey = string.Empty;
            string[] replyArgs = new string[5];
            bool isWarning = false;
            if (args != null && args.Length > 0) {
                if (player.IsServer && args[0] == "clear") {
                    ClearEntities();
                    player.Reply($"[{Title}] {lang.GetMessage("MsgAllRemoved", this, player.Id)}");
                    return;
                }
                if (player.Object is BasePlayer bPlayer && _storedData.PlayersData.TryGetValue(bPlayer.userID, out var playerData)) {
                    GetVendingFromArgs(bPlayer, args, out var vending);
                    if (args[0] == "add") {
                        if (vending == null) {
                            replyKey = "MsgNotVending";
                            isWarning = true;
                        }
                        else if (!isAdmin && vending.OwnerID != bPlayer.userID) {
                            replyKey = "MsgNotOwner";
                            isWarning = true;
                        }
                        else if (CanModifyVending(vending, playerData, player)) ModifyVending(vending, true);
                    }
                    else if (args[0] == "remove") {
                        if (vending == null) {
                            replyKey = "MsgNotVending";
                            isWarning = true;
                        }
                        else if (!IsVendingHasTerminal(vending)) {
                            replyKey = "MsgNotVendingDelivery";
                            isWarning = true;
                        }
                        else if (!isAdmin && vending.OwnerID != bPlayer.userID) {
                            replyKey = "MsgNotOwner";
                            isWarning = true;
                        }
                        else {
                            RemoveFromVending(vending);
                            replyKey = "MsgMyRemoved";
                        }
                    }
                    else if (args[0] == "clear") {
                        if (isAdmin && args.Length > 1) {
                            if (args[1] == "all") {
                                ClearEntities();
                                replyKey = "MsgAllRemoved";
                            }
                            else if (ulong.TryParse(args[1], out ulong targetID)) {
                                foreach (var baseNet in BaseNetworkable.serverEntities) {
                                    if (baseNet is VendingMachine tVending && tVending.OwnerID == targetID && (tVending.skinID == _skinID || IsVendingHasTerminal(tVending))) RemoveFromVending(tVending);
                                }
                                replyKey = "MsgPlayerAllRemoved";
                                replyArgs[0] = args[1];
                            }
                        }
                        else {
                            foreach (var netID in playerData.Vendings.ToList()) {
                                if (BaseNetworkable.serverEntities.Find(new NetworkableId(netID)) is VendingMachine tVending) RemoveFromVending(tVending);
                                else playerData.Vendings.Remove(netID);
                            }
                            replyKey = "MsgMyAllRemoved";
                        }
                    }
                    else if (args[0] == "auto") {
                        playerData.AutoModify = !playerData.AutoModify;
                        replyKey = playerData.AutoModify ? "MsgAutoModifyEntityEnabled" : "MsgAutoModifyEntityDisabled";
                        isWarning = playerData.AutoModify;
                    }
                }
            }
            if (!string.IsNullOrWhiteSpace(replyKey)) SendMessage(player, string.Format(lang.GetMessage(replyKey, this, player.Id), replyArgs), isWarning);
        }
#endregion
#region ~UI~
        private void ShowPopup(VendingMachine vending) {
            if (BasePlayer.FindByID(vending.OwnerID) is not BasePlayer player) return;
            var container = new CuiElementContainer();
            container.Add(new CuiPanel {
                RectTransform = {
                    AnchorMin = _config.Popup_AnchorMin, AnchorMax = _config.Popup_AnchorMax, OffsetMin = _config.Popup_OffsetMin, OffsetMax = _config.Popup_OffsetMax
                }
                , Image = {
                    Color = "0 0 0 0"
                }
            }
            , "Overlay", UI_Name);
            container.Add(new CuiElement {
                Parent = UI_Name, Components = {
                    new CuiImageComponent {
                        Color = _iconColor, Png = (string)(ImageLibrary?.Call("GetImage", UI_Name) ?? string.Empty)
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "7 -17.5", OffsetMax = "42 17.5"
                    }
                }
            }
            );
            container.Add(new CuiLabel {
                Text = {
                    Text = lang.GetMessage("MsgPopupText", this, player.UserIDString), Font = _config.Popup_Text_Font, FontSize = _config.Popup_Text_Font_Size, Color = _textColor, Align = TextAnchor.UpperLeft, FadeIn = _config.Popup_Text_FadeIn
                }
                , RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "50 7", OffsetMax = "-5 -7"
                }
            }
            , UI_Name);
            container.Add(new CuiLabel {
                Text = {
                    Text = lang.GetMessage("MsgPopupSubText", this, player.UserIDString), Font = _config.Popup_Text_Font, FontSize = _config.Popup_Desc_Font_Size, Color = _text2Color, Align = TextAnchor.LowerLeft, FadeIn = _config.Popup_Text_FadeIn
                }
                , RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "50 7", OffsetMax = "-5 -7"
                }
            }
            , UI_Name);
            container.Add(new CuiButton {
                Button = {
                    Close = UI_Name, Command = $"{_config.Command} add {vending.net.ID.Value}", Color = "0 0 0 0"
                }
                , RectTransform = {
                    AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
                }
            }
            , UI_Name);
            DestroyPopup(player);
            CuiHelper.AddUi(player, container);
            SendEffect(player.transform.position, player.Connection, _config.Popup_Sound_Prefab);
            _playerTimers[player.userID] = timer.Once(_config.Popup_Duration, () => {
                DestroyPopup(player);
            }
            );
        }
#endregion
#region ~Unload~
        void Unload() {
            Unsubscribe(nameof(OnServerSave));
            OnServerSave();
            foreach (var player in BasePlayer.activePlayerList) DestroyPopup(player);
            ClearEntities(true);
            _storedData = null;
            _config = null;
        }
#endregion
    }
}

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