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

FREE NoSkins : 1.0.1 1.0.1

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

namespace Oxide.Plugins
{
    [Info("NoSkins", "Whispers88", "1.0.1")]
    [Description("Allows you to disable other players worn skins")]
    public class NoSkins : RustPlugin
    {
        //public static NoSkins _noSkins;
        private static HashSet<ulong> _HideSkinsPlayers = new HashSet<ulong>();
        private const string PermAllow = "noskins.allow";
        private const string PermHideSkins = "noskins.on";

        #region Config
        private Configuration config;
        class Configuration
        {
            [JsonProperty("Command Aliases")]
            public string[] noskinCMD = new[] { "noskin", "noskins", "ns" };

            public string ToJson() => JsonConvert.SerializeObject(this);

            public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
        }

        protected override void LoadDefaultConfig() => config = new Configuration();
        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<Configuration>();
                if (config == null)
                {
                    throw new JsonException();
                }
                var configDict = config.ToDictionary();
                Dictionary<string, object> defaultconObjects = new Dictionary<string, object>();
                foreach (var obj in Config)
                {
                    defaultconObjects.Add(obj.Key, obj.Value);
                }
                if (configDict.Count != defaultconObjects.Count)
                {
                    Puts("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
                else
                {
                    foreach (var key in configDict.Keys)
                    {
                        if (defaultconObjects.ContainsKey(key))
                            continue;

                        Puts("Configuration appears to be outdated; updating and saving");
                        SaveConfig();
                        break;

                    }
                }
            }
            catch
            {
                Puts($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
        }

        protected override void SaveConfig()
        {
            Puts($"Configuration changes saved to {Name}.json");
            Config.WriteObject(config, true);
        }

        #endregion Config

        #region Initialization
        private void Init()
        {
            //_noSkins = this;
            _cachedContainers = new Dictionary<ulong, ProtoBuf.ItemContainer>();
            _HideSkinsPlayers = new HashSet<ulong>();

            permission.RegisterPermission(PermAllow, this);
            permission.RegisterPermission(PermHideSkins, this);

            AddCovalenceCommand(config.noskinCMD, nameof(NoSkinCMD));

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

        private void Unload()
        {
            foreach (var player in BasePlayer.activePlayerList)
            {
                if (_HideSkinsPlayers.Contains(player.userID))
                    permission.GrantUserPermission(player.UserIDString, PermHideSkins, this);
            }
            _HideSkinsPlayers = null;
            _cachedContainers = null;
            //_noSkins = null;
        }

        #endregion Initialization

        #region Commands
        private void NoSkinCMD(IPlayer iplayer, string command, string[] args)
        {
            BasePlayer player = (BasePlayer)iplayer.Object;
            if (player == null) return;

            if (!HasPerm(player.UserIDString, PermAllow))
            {
                Message(player, "NoPerms");
                return;
            }

            if (_HideSkinsPlayers.Contains(player.userID))
            {
                _HideSkinsPlayers.Remove(player.userID);
                //permission.RevokeUserPermission(player.UserIDString, PermHideSkins);

                UpdateCurrentConnections(player, false);
                Message(player, "SkinsEnabled");
                return;
            }

            //permission.GrantUserPermission(player.UserIDString, PermHideSkins, this);
            _HideSkinsPlayers.Add(player.userID);

            UpdateCurrentConnections(player, true);
            Message(player, "SkinsDisabled");
        }
        #endregion Commands

        #region Localization
        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["SkinsDisabled"] = "Skins: <color=orange> Disabled </color>",
                ["SkinsEnabled"] = "Skins: <color=orange> Enabled </color>",
                ["NoPerms"] = "You do not have permission to do this"
            }, this);
        }

        private string GetLang(string langKey, string playerId) => lang.GetMessage(langKey, this, playerId);

        private void Message(BasePlayer player, string langKey)
        {
            if (player.IsConnected) player.ChatMessage(GetLang(langKey, player.UserIDString));
        }

        #endregion Localization

        #region Hooks
        private void OnPlayerConnected(BasePlayer player)
        {
            if (HasPerm(player.UserIDString, PermHideSkins) && HasPerm(player.UserIDString, PermAllow))
            {
                ServerMgr.Instance.Invoke(() =>
                {
                    _HideSkinsPlayers.Add(player.userID);
                    UpdateCurrentConnections(player, true);
                }, 3f);
            }
        }

        private void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            if (_HideSkinsPlayers.Contains(player.userID))
                permission.GrantUserPermission(player.UserIDString, PermHideSkins, this);
            else
                permission.RevokeUserPermission(player.UserIDString, PermHideSkins);

            _HideSkinsPlayers.Remove(player.userID);
        }

        private object? OnInventoryNetworkUpdate(PlayerInventory instance, ItemContainer container, UpdateItemContainer updateItemContainer, PlayerInventory.Type type, PlayerInventory.NetworkInventoryMode mode)
        {
            if (instance._baseEntity?.IsNpc ?? true)
                return null;

            if (type != PlayerInventory.Type.Wear)
            {
                return null;
            }
            if (mode == PlayerInventory.NetworkInventoryMode.LocalPlayer)
            {
                return null;
            }
            if (mode == PlayerInventory.NetworkInventoryMode.EveryoneButLocal)
            {
                SendUpdates(instance, updateItemContainer, true);
                return false;
            }
            if (mode == PlayerInventory.NetworkInventoryMode.Everyone)
            {
                SendUpdates(instance, updateItemContainer, false);
                return false;
            }
            return null;
        }
        #endregion Hooks

        #region Methods
        private void UpdateCurrentConnections(BasePlayer player, bool disableSkins)
        {
            var subscribers = player.net.@group.subscribers;
            foreach (var connection in subscribers)
            {
                if (connection?.player is BasePlayer current)
                {
                    if (current.userID == player.userID)
                        continue;

                    CreateAndSendUpdateItemContainer(player, current, current.inventory.containerWear, PlayerInventory.Type.Wear, disableSkins);
                }
            }
        }

        private static Dictionary<ulong, ProtoBuf.ItemContainer> _cachedContainers = new Dictionary<ulong, ProtoBuf.ItemContainer>();

        private static void CreateAndSendUpdateItemContainer(BasePlayer player, BasePlayer current, ItemContainer container, PlayerInventory.Type type, bool disableSkins)
        {
            if (container == null)
                return;

            using (var updateItemContainer = Pool.Get<UpdateItemContainer>())
            {
                container.dirty = false;

                updateItemContainer.type = (int)type;
                updateItemContainer.container = Pool.Get<List<ProtoBuf.ItemContainer>>();

                if (!_cachedContainers.TryGetValue(current.userID, out ProtoBuf.ItemContainer? savedContainer) || savedContainer?.contents == null || savedContainer.contents.Count != current.inventory.containerWear.itemList.Count)
                {
                    savedContainer = container.Save(true);
                    _cachedContainers[current.userID] = savedContainer;
                }
                if (disableSkins && savedContainer.contents != null)
                {
                    foreach (var item in savedContainer.contents)
                    {
                        item.skinid = 0;
                    }
                }
                updateItemContainer.container.Add(savedContainer);

                current.ClientRPC<UpdateItemContainer>(RpcTarget.Player("UpdatedItemContainer", player), updateItemContainer);
            }
        }

        private void SendUpdates(PlayerInventory playerInventory, UpdateItemContainer updateItemContainer, bool updateLocal)
        {
            BasePlayer basePlayer = playerInventory._baseEntity;
            if (basePlayer?.net?.group == null)
                return;

            _cachedContainers[basePlayer.userID] = updateItemContainer.container[0];

            var subscribers = basePlayer.net.group.subscribers;

            List<Connection> connectionsSkinned = Pool.Get<List<Connection>>();
            List<Connection> connectionsNoSkin = Pool.Get<List<Connection>>();

            foreach (var connection in subscribers)
            {
                if (connection?.player is BasePlayer current)
                {
                    if (updateLocal && current.userID == basePlayer.userID)
                    {
                        continue;
                    }

                    if (_HideSkinsPlayers.Contains(current.userID))
                    {
                        connectionsNoSkin.Add(connection);
                    }
                    else
                    {
                        connectionsSkinned.Add(connection);
                    }
                }
            }

            if (connectionsSkinned.Count > 0)
            {
                basePlayer.ClientRPC<UpdateItemContainer>(RpcTarget.Players("UpdatedItemContainer", connectionsSkinned), updateItemContainer);
            }

            if (connectionsNoSkin.Count > 0)
            {
                foreach (var con in updateItemContainer.container)
                {
                    foreach (var item in con.contents)
                    {
                        item.skinid = 0;
                    }
                }
                basePlayer.ClientRPC<UpdateItemContainer>(RpcTarget.Players("UpdatedItemContainer", connectionsNoSkin), updateItemContainer);
            }

            Pool.FreeUnmanaged(ref connectionsSkinned);
            Pool.FreeUnmanaged(ref connectionsNoSkin);
        }

        #endregion Methods

        #region Harmony
        [HarmonyPatch(typeof(PlayerCorpse), "Save"), AutoPatch]
        private static class PlayerCorpse_Save_Patch
        {
            [HarmonyPostfix]
            private static void Postfix(PlayerCorpse __instance, BaseNetworkable.SaveInfo info)
            {
                if (info.forConnection == null)
                    return;

                if (!_HideSkinsPlayers.Contains(info.forConnection.userid))
                    return;

                if (info.msg.storageBox == null)
                    return;

                foreach (var item in info.msg.storageBox.contents.contents)
                {
                    item.skinid = 0;
                }
            }
        }

        [HarmonyPatch(typeof(BaseNetworkable), "SendNetworkGroupChange"), AutoPatch] // when a player respawns
        private static class BaseNetworkable_SendNetworkGroupChange_Patch
        {
            [HarmonyPostfix]
            private static void Postfix(BaseNetworkable __instance)
            {
                if (__instance.net.connection == null)
                    return;

                if (__instance.net.connection.player is not BasePlayer basePlayer)
                    return;

                bool hidingSkins = _HideSkinsPlayers.Contains(__instance.net.connection.userid);

                foreach (var subscriber in basePlayer.net.group.subscribers)
                {
                    if (subscriber.userid == __instance.net.connection.userid)
                        continue;

                    if (subscriber.player is not BasePlayer subPlayer || subPlayer.IsNpc)
                        continue;

                    bool hidingSkins2 = _HideSkinsPlayers.Contains(subscriber.userid);

                    if (hidingSkins2)
                    {
                        CreateAndSendUpdateItemContainer(subPlayer, basePlayer, basePlayer.inventory.containerWear, PlayerInventory.Type.Wear, true);
                    }

                    if (hidingSkins)
                    {
                        CreateAndSendUpdateItemContainer(basePlayer, subPlayer, subPlayer.inventory.containerWear, PlayerInventory.Type.Wear, true);
                    }
                }
            }
        }

        [HarmonyPatch(typeof(Networkable), "OnGroupTransition"), AutoPatch] //moving between grids
        private static class BaseNetworkable_OnGroupTransition_Patch
        {
            [HarmonyPostfix]
            private static void Postfix(Networkable __instance, Network.Visibility.Group oldGroup)
            {
                if (__instance.connection == null)
                    return;

                if (__instance.connection.player is not BasePlayer basePlayer)
                    return;

                bool hidingSkins = _HideSkinsPlayers.Contains(__instance.connection.userid);

                foreach (var subscriber in basePlayer.net.group.subscribers)
                {
                    if (subscriber.userid == __instance.connection.userid)
                        continue;

                    if (subscriber.player is not BasePlayer subPlayer || subPlayer.IsNpc)
                        continue;

                    bool hidingSkins2 = _HideSkinsPlayers.Contains(subscriber.userid);

                    if (hidingSkins2)
                    {
                        CreateAndSendUpdateItemContainer(subPlayer, basePlayer, basePlayer.inventory.containerWear, PlayerInventory.Type.Wear, true);
                    }

                    if (hidingSkins)
                    {
                        CreateAndSendUpdateItemContainer(basePlayer, subPlayer, subPlayer.inventory.containerWear, PlayerInventory.Type.Wear, true);
                    }
                }
            }
        }
        #endregion Harmony

        #region Helpers

        private bool HasPerm(string id, string perm) => permission.UserHasPermission(id, perm);

        private void AddLocalizedCommand(string command)
        {
            foreach (string language in lang.GetLanguages(this))
            {
                Dictionary<string, string> messages = lang.GetMessages(language, this);
                foreach (KeyValuePair<string, string> message in messages)
                {
                    if (!message.Key.Equals(command)) continue;

                    if (string.IsNullOrEmpty(message.Value)) continue;

                    AddCovalenceCommand(message.Value, command);
                }
            }
        }
        #endregion Helpers
    }
}

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