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

FREE SkinIt : 1.1.0 1.1.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
/*
 * Copyright (C) 2024 Game4Freak.io
 * This mod is provided under the Game4Freak EULA.* Full legal terms can be found at https://game4freak.io/eula/
 */

using Oxide.Core.Plugins;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace Oxide.Plugins
{
    [Info("Skin It", "VisEntities", "1.1.0")]
    [Description("Change item skins directly through chat without needing a repair bench.")]
    public class SkinIt : RustPlugin
    {
        #region 3rd Party Dependencies

        [PluginReference]
        private readonly Plugin PlayerDLCAPI;

        #endregion 3rd Party Dependencies

        #region Fields

        private static SkinIt _plugin;

        #endregion Fields

        #region Oxide Hooks

        private void Init()
        {
            _plugin = this;
            PermissionUtil.RegisterPermissions();
        }

        private void OnServerInitialized(bool isStartup)
        {
            CheckDependencies();
        }

        private void Unload()
        {
            _plugin = null;
        }

        #endregion Oxide Hooks

        #region Permissions

        private static class PermissionUtil
        {
            public const string USE = "skinit.use";
            private static readonly List<string> _permissions = new List<string>
            {
                USE,
            };

            public static void RegisterPermissions()
            {
                foreach (var permission in _permissions)
                {
                    _plugin.permission.RegisterPermission(permission, _plugin);
                }
            }

            public static bool HasPermission(BasePlayer player, string permissionName)
            {
                return _plugin.permission.UserHasPermission(player.UserIDString, permissionName);
            }
        }

        #endregion Permissions

        #region Helper Functions

        private bool CanUseSkin(BasePlayer player, string shortname, ulong skinId)
        {
            if (!PluginLoaded(PlayerDLCAPI))
                return true;

            bool initialized = false;
            try
            {
                initialized = PlayerDLCAPI.Call<bool>("Initialized");
            }
            catch
            {
                initialized = false;
            }

            if (!initialized)
                return true;

            return PlayerDLCAPI.Call<bool>("IsOwnedOrFreeItem", player, shortname, skinId);
        }

        private bool CheckDependencies()
        {
            if (!PluginLoaded(PlayerDLCAPI))
            {
                Puts("Player DLC API is not loaded.Ownership checks are DISABLED.Install it to enforce DLC/skin ownership.");
                return false;
            }

            bool initialized = false;
            try
            {
                initialized = PlayerDLCAPI.Call<bool>("Initialized");
            }
            catch
            {
                initialized = false;
            }

            if (!initialized)
                Puts("Player DLC API is present but not initialized yet.Until it's ready, ownership checks are DISABLED.");

            return true;
        }

        private static bool PluginLoaded(Plugin plugin)
        {
            if (plugin != null && plugin.IsLoaded)
                return true;
            else
                return false;
        }

        #endregion Helper Functions

        #region Commands

        [ChatCommand("skin")]
        private void cmdSkin(BasePlayer player, string command, string[] args)
        {
            if (player == null)
                return;

            if (!PermissionUtil.HasPermission(player, PermissionUtil.USE))
            {
                ReplyToPlayer(player, Lang.NoPermission);
                return;
            }

            if (args == null || args.Length == 0)
            {
                ReplyToPlayer(player, Lang.Usage);
                return;
            }

            if (!ulong.TryParse(args[0], NumberStyles.Any, CultureInfo.InvariantCulture, out ulong newSkinId))
            {
                ReplyToPlayer(player, Lang.InvalidSkinId, args[0]);
                return;
            }

            string partialItemName = null;
            if (args.Length >= 2)
            {
                partialItemName = string.Join(" ", args.Skip(1).ToArray());
            }

            if (string.IsNullOrEmpty(partialItemName))
            {
                var activeItem = player.GetActiveItem();
                if (activeItem == null)
                {
                    ReplyToPlayer(player, Lang.NoActiveItem);
                    return;
                }

                if (!CanUseSkin(player, activeItem.info.shortname, newSkinId))
                {
                    ReplyToPlayer(player, Lang.SkinRestricted);
                    return;
                }

                bool success = ReskinItem(player, activeItem, newSkinId);
                if (success)
                {
                    ReplyToPlayer(player, Lang.SkinSuccess, activeItem.info.displayName.translated, newSkinId.ToString());
                }
                else
                {
                    ReplyToPlayer(player, Lang.SkinFail);
                }

            }
            else
            {
                List<Item> foundItems = FindAllItemsByName(player, partialItemName);
                if (foundItems.Count == 0)
                {
                    ReplyToPlayer(player, Lang.NoItemFound, partialItemName);
                    return;
                }

                if (foundItems.Count == 1)
                {
                    var singleItem = foundItems[0];

                    if (!CanUseSkin(player, singleItem.info.shortname, newSkinId))
                    {
                        ReplyToPlayer(player, Lang.SkinRestricted);
                        return;
                    }

                    bool success = ReskinItem(player, singleItem, newSkinId);
                    if (success)
                    {
                        string itemName;
                        if (singleItem.info.displayName.translated != null)
                            itemName = singleItem.info.displayName.translated;
                        else
                            itemName = singleItem.info.shortname;

                        ReplyToPlayer(player, Lang.SkinSuccess, itemName, newSkinId.ToString());
                    }
                    else
                    {
                        ReplyToPlayer(player, Lang.SkinFail);
                    }
                }
                else
                {
                    int reskinnedCount = 0;
                    int failCount = 0;

                    foreach (Item item in foundItems)
                    {
                        if (!CanUseSkin(player, item.info.shortname, newSkinId))
                        {
                            failCount++;
                            continue;
                        }

                        bool success = ReskinItem(player, item, newSkinId);
                        if (success)
                        {
                            reskinnedCount++;
                        }
                        else
                        {
                            failCount++;
                        }
                    }

                    ReplyToPlayer(player, Lang.SkinSuccessSummary, reskinnedCount, (failCount + reskinnedCount), partialItemName, newSkinId);
                }
            }
        }

        #endregion Commands

        #region Reskin Logic

        private List<Item> FindAllItemsByName(BasePlayer player, string partialName)
        {
            partialName = partialName.ToLowerInvariant();

            List<Item> matched = new List<Item>();
            matched.AddRange(SearchContainerAll(player.inventory.containerBelt, partialName));
            matched.AddRange(SearchContainerAll(player.inventory.containerMain, partialName));
            matched.AddRange(SearchContainerAll(player.inventory.containerWear, partialName));
            return matched;
        }

        private List<Item> SearchContainerAll(ItemContainer container, string partialName)
        {
            List<Item> results = new List<Item>();
            if (container == null)
                return results;

            foreach (Item item in container.itemList)
            {
                string display;
                if (item.info.displayName.translated != null)
                    display = item.info.displayName.translated.ToLowerInvariant();
                else
                    display = "";

                string shortName;
                if (item.info.shortname != null)
                    shortName = item.info.shortname.ToLowerInvariant();
                else
                    shortName = "";

                if (display.Contains(partialName) || shortName.Contains(partialName))
                {
                    results.Add(item);
                }
            }
            return results;
        }

        private bool ReskinItem(BasePlayer player, Item oldItem, ulong newSkinId, string customName = null)
        {
            if (player == null || oldItem == null || oldItem.info == null)
                return false;

            int oldPosition = oldItem.position;
            ItemContainer oldContainer = oldItem.parent as ItemContainer;
            var shortname = oldItem.info.shortname;
            float condition = oldItem.condition;
            float maxCondition = oldItem.maxCondition;
            int amount = oldItem.amount;

            int savedAmmo = 0;
            ItemDefinition ammoDef = null;
            BaseEntity oldHeld = oldItem.GetHeldEntity();
            BaseProjectile oldProj = oldHeld as BaseProjectile;
            if (oldProj != null)
            {
                if (oldProj.primaryMagazine != null)
                {
                    savedAmmo = oldProj.primaryMagazine.contents;
                    ammoDef = oldProj.primaryMagazine.ammoType;
                }
            }

            List<Item> oldSubItems = null;
            if (oldItem.contents != null && oldItem.contents.itemList.Count > 0)
            {
                oldSubItems = oldItem.contents.itemList.ToList();
            }

            Item newItem = ItemManager.CreateByName(shortname, amount, newSkinId);
            if (newItem == null)
                return false;

            newItem.condition = condition;
            newItem.maxCondition = maxCondition;
            if (!string.IsNullOrEmpty(customName))
                newItem.name = customName;

            if (oldSubItems != null && oldSubItems.Count > 0)
            {
                if (newItem.info.itemMods != null)
                {
                    int maxSlotCount = newItem.info.itemMods.Length;

                    if (newItem.contents == null)
                        newItem.contents = new ItemContainer();

                    newItem.contents.ServerInitialize(newItem, maxSlotCount);
                    newItem.contents.SetFlag(ItemContainer.Flag.IsLocked, false);
                }

                foreach (var sub in oldSubItems)
                {
                    var newSub = ItemManager.Create(sub.info, sub.amount, sub.skin);
                    if (newSub == null) continue;

                    newSub.condition = sub.condition;
                    newSub.maxCondition = sub.maxCondition;

                    newSub.MoveToContainer(newItem.contents);
                    newSub.MarkDirty();
                }

                if (newItem.contents != null)
                    newItem.contents.MarkDirty();
            }

            NextTick(() =>
            {
                if (oldItem != null)
                {
                    oldItem.RemoveFromContainer();
                    oldItem.Remove();
                }

                bool placedSuccessfully = false;

                if (oldContainer != null)
                {
                    if (newItem.MoveToContainer(oldContainer, oldPosition, false))
                    {
                        placedSuccessfully = true;
                    }
                    else
                    {
                        if (newItem.MoveToContainer(player.inventory.containerMain, -1, false))
                        {
                            placedSuccessfully = true;
                        }
                    }
                }
                else
                {
                    if (newItem.MoveToContainer(player.inventory.containerMain, -1, false))
                    {
                        placedSuccessfully = true;
                    }
                }

                if (!placedSuccessfully)
                {
                    newItem.Remove();
                    return;
                }

                BaseEntity newHeld = newItem.GetHeldEntity();
                if (newHeld is BaseProjectile newProj && newProj.primaryMagazine != null)
                {
                    newProj.primaryMagazine.contents = savedAmmo;
                    newProj.primaryMagazine.ammoType = ammoDef;
                    newHeld.skinID = newSkinId;
                    newHeld.SendNetworkUpdateImmediate();
                }

                newItem.MarkDirty();
            });

            return true;
        }

        #endregion Reskin Logic

        #region Localization

        private class Lang
        {
            public const string NoPermission = "NoPermission";
            public const string Usage = "Usage";
            public const string InvalidSkinId = "InvalidSkinId";
            public const string NoActiveItem = "NoActiveItem";
            public const string NoItemFound = "NoItemFound";
            public const string SkinSuccess = "SkinSuccess";
            public const string SkinFail = "SkinFail";
            public const string SkinSuccessSummary = "SkinSuccessSummary";
            public const string SkinRestricted = "SkinRestricted";
        }

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                [Lang.NoPermission] = "You do not have permission to use this command.",
                [Lang.Usage] = "Usage:\n/skin <skinId> [partialItemName]\nIf item name isn't provided, it skins your active item.",
                [Lang.InvalidSkinId] = "'{0}' is not a valid skin ID.",
                [Lang.NoActiveItem] = "You have no active item to skin! Please specify an item name or hold the item.",
                [Lang.NoItemFound] = "Couldn't find any item matching '{0}' in your inventory.",
                [Lang.SkinSuccess] = "Skinned your '{0}' to skin ID {1}.",
                [Lang.SkinFail] = "Failed to reskin the item.",
                [Lang.SkinSuccessSummary] = "Reskinned {0} out of {1} items matching '{2}' to skin ID {3}.",
                [Lang.SkinRestricted] = "That skin is restricted (paid DLC or not owned).",

            }, this, "en");
        }

        private static string GetMessage(BasePlayer player, string messageKey, params object[] args)
        {
            string userId;
            if (player != null)
                userId = player.UserIDString;
            else
                userId = null;

            string message = _plugin.lang.GetMessage(messageKey, _plugin, userId);

            if (args.Length > 0)
                message = string.Format(message, args);

            return message;
        }

        public static void ReplyToPlayer(BasePlayer player, string messageKey, params object[] args)
        {
            string message = GetMessage(player, messageKey, args);

            if (!string.IsNullOrWhiteSpace(message))
                _plugin.SendReply(player, message);
        }

        #endregion Localization
    }
}

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