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

FREE RItemCompliance : 1.0.4 1.0.4

Нет прав для скачивания
C#:
//1.0.1 Добавлена блокировка одевания одежды
//1.0.2 Добавлена локализация для сообщения об отсутствии скина, добавлена проверка изменения скина ентити через баллончик с разрушением ентити и нанесением урона игроку (20 единиц)
//1.0.3 Плагин переработан с 100% соответствием правилам Facepunch.Все механизмы используют чисто игровую механику без блокировок и упоминаний законов.//1.0.4 Добавлена команда ric add2 с автоматическим определением шортнеймов через Steam API и добавлением скинов в конфигурацию.using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("RItemCompliance", "RobinPlay", "1.0.4")]
    [Description("Система соответствия предметов требованиям")]
    public partial class RItemCompliance : RustPlugin {
#region Configuration
        private ConfigData configData;
        private class ConfigData {
            [JsonProperty("Блокированные скины")]
            public Dictionary<string, List<ulong>> BlockedSkins {
                get;
                set;
            }
            = new Dictionary<string, List<ulong>>();
            [JsonProperty("Интервал урона (секунды)")]
            public float DamageInterval {
                get;
                set;
            }
            = 1.0f;
            [JsonProperty("Урон за интервал")]
            public float DamageAmount {
                get;
                set;
            }
            = 10.0f;
            [JsonProperty("Звук сирены")]
            public string SirenSound {
                get;
                set;
            }
            = "assets/prefabs/locks/keypad/effects/lock.code.denied.prefab";
            [JsonProperty("Steam API Key")]
            public string SteamApiKey {
                get;
                set;
            }
            = "";
        }
        protected override void LoadDefaultConfig() {
            configData = new ConfigData();
            configData.BlockedSkins["sleepingbag"] = new List<ulong> {
                2921636205, 3002450787
            }
            ;
            configData.BlockedSkins["door.hinged.toptier"] = new List<ulong> {
                2799741628, 2911337044, 2885575403, 2830140703, 1999927543, 1376526519,
            }
            ;
            configData.BlockedSkins["wall.frame.garagedoor"] = new List<ulong> {
                3049318629, 2936423837, 2918938368, 2366648978, 2570889432, 2483380380, 2222230165,
            }
            ;
            configData.BlockedSkins["door.hinged.metal"] = new List<ulong> {
                3568372096, 3488341034, 3345036303, 3048905728, 2949621111, 2811788926, 2217374019, 2431554472, 2396828738, 2091097349, 1952448742, 1653322594,
            }
            ;
            configData.BlockedSkins["door.double.hinged.wood"] = new List<ulong> {
                3334342910
            }
            ;
            configData.BlockedSkins["door.double.hinged.metal"] = new List<ulong> {
                3581911522, 3496304344, 3275117030, 1882782756,
            }
            ;
            configData.BlockedSkins["box.wooden.large"] = new List<ulong> {
                1196352289, 1900496901, 2156384652, 2447526502,
            }
            ;
            configData.BlockedSkins["box.wooden"] = new List<ulong> {
                2394650621
            }
            ;
            configData.BlockedSkins["rug"] = new List<ulong> {
                2875313479
            }
            ;
            configData.BlockedSkins["locker"] = new List<ulong> {
                3357525274, 2960258956
            }
            ;
            configData.BlockedSkins["metal.plate.torso"] = new List<ulong> {
                3559835047
            }
            ;
            configData.BlockedSkins["hoodie"] = new List<ulong> {
                3040981952
            }
            ;
            configData.BlockedSkins["attire.hide.pants"] = new List<ulong> {
                3135159428
            }
            ;
            configData.BlockedSkins["explosive.satchel"] = new List<ulong> {
                2894489438
            }
            ;
            configData.SteamApiKey = "";
            SaveConfig();
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                configData = Config.ReadObject<ConfigData>();
                if (configData == null) {
                    LoadDefaultConfig();
                }
                else {
                    SaveConfig();
                }
            }
            catch {
                LoadDefaultConfig();
            }
        }
        protected override void SaveConfig() {
            Config.WriteObject(configData);
        }
#endregion
#region Data
        private Dictionary<ulong, Timer> activeKillTimers = new Dictionary<ulong, Timer>();
        private Dictionary<ulong, Timer> activeClothingTimers = new Dictionary<ulong, Timer>();
        private Dictionary<string, string> _workshopNameToShortname = new Dictionary<string, string> {
            ["bandana"]
            = "mask.bandana", ["balaclava"] = "mask.balaclava", ["beeniehat"] = "hat.beenie", ["burlapshoes"] = "burlap.shoes", ["burlapshirt"] = "burlap.shirt", ["burlappants"] = "burlap.trousers", ["burlapheadwrap"] = "burlap.headwrap", ["buckethelmet"] = "bucket.helmet", ["booniehat"] = "hat.boonie", ["cap"] = "hat.cap", ["collaredshirt"] = "shirt.collared", ["coffeecanhelmet"] = "coffeecan.helmet", ["deerskullmask"] = "deer.skull.mask", ["hideskirt"] = "attire.hide.skirt", ["hideshirt"] = "attire.hide.vest", ["hidepants"] = "attire.hide.pants", ["hideshoes"] = "attire.hide.boots", ["hidehalterneck"] = "attire.hide.helterneck", ["hoodie"] = "hoodie", ["hideponcho"] = "attire.hide.poncho", ["leathergloves"] = "burlap.gloves", ["longtshirt"] = "tshirt.long", ["metalchestplate"] = "metal.plate.torso", ["metalfacemask"] = "metal.facemask", ["minerhat"] = "hat.miner", ["pants"] = "pants", ["roadsignvest"] = "roadsign.jacket", ["roadsignpants"] = "roadsign.kilt", ["riothelmet"] = "riot.helmet", ["snowjacket"] = "jacket.snow", ["shorts"] = "pants.shorts", ["tanktop"] = "shirt.tanktop", ["tshirt"] = "tshirt", ["vagabondjacket"] = "jacket", ["workboots"] = "shoes.boots", ["ak47"] = "rifle.ak", ["boltrifle"] = "rifle.bolt", ["boneclub"] = "bone.club", ["boneknife"] = "knife.bone", ["crossbow"] = "crossbow", ["doublebarrelshotgun"] = "shotgun.double", ["eokapistol"] = "pistol.eoka", ["f1grenade"] = "grenade.f1", ["longsword"] = "longsword", ["mp5"] = "smg.mp5", ["pumpshotgun"] = "shotgun.pump", ["rock"] = "rock", ["salvagedhammer"] = "hammer.salvaged", ["salvagedicepick"] = "icepick.salvaged", ["satchelcharge"] = "explosive.satchel", ["semiautomaticpistol"] = "pistol.semiauto", ["stonehatchet"] = "stonehatchet", ["stonepickaxe"] = "stone.pickaxe", ["largewoodbox"] = "box.wooden.large", ["reactivetarget"] = "target.reactive", ["sandbagbarricade"] = "barricade.sandbags", ["sleepingbag"] = "sleepingbag", ["sheetmetaldoor"] = "door.hinged.metal", ["waterpurifier"] = "water.purifier", ["woodstoragebox"] = "box.wooden", ["woodendoor"] = "door.hinged.wood", ["acousticguitar"] = "fun.guitar", ["pickaxe"] = "pickaxe", ["hatchet"] = "hatchet", ["revolver"] = "pistol.revolver", ["rocketlauncher"] = "rocket.launcher", ["semiautomaticrifle"] = "rifle.semiauto", ["waterpipeshotgun"] = "shotgun.waterpipe", ["customsmg"] = "smg.2", ["python"] = "pistol.python", ["lr300"] = "rifle.lr300", ["combatknife"] = "knife.combat", ["armoreddoor"] = "door.hinged.toptier", ["concretebarricade"] = "barricade.concrete", ["thompson"] = "smg.thompson", ["hammer"] = "hammer", ["sword"] = "salvaged.sword", ["huntingbow"] = "bow.hunting", ["m249"] = "lmg.m249", ["m39"] = "rifle.m39", ["l96"] = "rifle.l96", ["locker"] = "locker", ["vendingmachine"] = "vending.machine", ["fridge"] = "fridge", ["garagedoor"] = "wall.frame.garagedoor", ["armoreddoubledoor"] = "door.double.hinged.toptier", ["sheetmetaldoubledoor"] = "door.double.hinged.metal", ["woodendoubledoor"] = "door.double.hinged.wood", ["furnace"] = "furnace", ["jackhammer"] = "jackhammer", ["table"] = "table", ["roadsigngloves"] = "roadsign.gloves", ["bearrug"] = "rug.bear", ["rug"] = "rug", ["chair"] = "chair", ["spinningwheel"] = "spinner.wheel", ["largebackpack"] = "largebackpack", ["wallpaperwall"] = "wallpaper.wall", ["wallpaperflooring"] = "wallpaper.flooring", ["wallpaperceiling"] = "wallpaper.ceiling", ["bed"] = "bed", ["hmlmg"] = "hmlmg",
        }
        ;
#endregion
#region LanguageFile
        private void Print(BasePlayer player, string message) {
            Player.Message(player, message);
        }
        private string Lang(string key, string? id = null, params object[] args) {
            return args.Length == 0 ? lang.GetMessage(key, this, id) : string.Format(System.Globalization.CultureInfo.InvariantCulture, lang.GetMessage(key, this, id), args );
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["RestrictedItem"]
                = "This item is corrupted by dark forces and causes harm to the player!", ["ItemBlocked"] = "Item blocked: {0} (Skin: {1})", ["SkinRemoved"] = "Skin removed from item: {0}", ["NotLookingAtItem"] = "You are not looking at a valid item.", ["NoSkin"] = "This item has no skin.",
            }
            , this );
            lang.RegisterMessages(new Dictionary<string, string> {
                ["RestrictedItem"]
                = "Этот предмет осквернён тёмными силами и наносит вред игроку!", ["ItemBlocked"] = "Предмет заблокирован: {0} (Скин: {1})", ["SkinRemoved"] = "Скин удалён с предмета: {0}", ["NotLookingAtItem"] = "Вы не смотрите на предмет.", ["NoSkin"] = "Этот предмет не имеет скина.",
            }
            , this, "ru" );
        }
#endregion
#region Hooks
        void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem) {
            if (player == null || newItem == null) {
                StopKillTimer(player);
                return;
            }
            if (IsBlockedSkin(newItem.info.shortname, newItem.skin)) {
                if (newItem.info.shortname == "explosive.satchel") {
                    ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                    PlaySirenSound(player);
                    player.Hurt(configData.DamageAmount, Rust.DamageType.Generic, null, false);
                    NextTick(() => {
                        if (player == null || !player.IsConnected) return;
                        var activeItem = player.GetActiveItem();
                        if (activeItem == null || activeItem.uid != newItem.uid) return;
                        if (IsBlockedSkin(activeItem.info.shortname, activeItem.skin)) {
                            RemoveActiveItem(player, activeItem);
                        }
                    }
                    );
                }
                else {
                    StartKillTimer(player, newItem);
                }
            }
            else {
                StopKillTimer(player);
            }
        }
        void OnItemAddedToContainer(ItemContainer container, Item item) {
            if (container == null || item == null) return;
            var player = container.playerOwner;
            if (player == null) return;
            if (container == player.inventory.containerWear) {
                if (IsBlockedSkin(item.info.shortname, item.skin)) {
                    ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                    PlaySirenSound(player);
                    timer.Once(0.1f, () => {
                        if (item != null && item.parent == container && item.hasCondition) {
                            item.LoseCondition(item.maxCondition);
                        }
                    }
                    );
                }
                CheckWornClothing(player);
            }
        }
        void OnItemRemovedFromContainer(ItemContainer container, Item item) {
            if (container == null || item == null) return;
            var player = container.playerOwner;
            if (player == null) return;
            if (container == player.inventory.containerWear) {
                CheckWornClothing(player);
            }
        }
        void OnPlayerDisconnected(BasePlayer player) {
            if (player != null) {
                StopKillTimer(player);
                StopClothingTimer(player);
            }
        }
        void OnPlayerDeath(BasePlayer player, HitInfo info) {
            if (player != null) {
                StopKillTimer(player);
                StopClothingTimer(player);
            }
        }
        void OnPlayerSleepEnded(BasePlayer player) {
            if (player != null) {
                CheckWornClothing(player);
            }
        }
        void OnPlayerConnected(BasePlayer player) {
            if (player != null) {
                timer.Once(1f, () => CheckWornClothing(player));
            }
        }
        object CanWearItem(PlayerInventory inventory, Item item) {
            return null;
        }
        object CanDeployItem(BasePlayer player, Deployer deployer, NetworkableId entityId) {
            if (player == null) return null;
            Item item = player.GetActiveItem();
            if (item == null) return null;
            if (IsBlockedSkin(item.info.shortname, item.skin)) {
                if (item.info.shortname == "explosive.satchel") {
                    return null;
                }
                ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                PlaySirenSound(player);
                return false;
            }
            return null;
        }
        object OnPlayerInput(BasePlayer player, InputState input) {
            if (player == null || input == null) return null;
            if (!input.WasJustPressed(BUTTON.FIRE_PRIMARY)) return null;
            Item activeItem = player.GetActiveItem();
            if (activeItem == null) return null;
            if (IsBlockedSkin(activeItem.info.shortname, activeItem.skin)) {
                if (activeItem.info.shortname == "explosive.satchel") {
                    return null;
                }
                ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                PlaySirenSound(player);
                return false;
            }
            return null;
        }
        void OnItemDeployed(Deployer deployer, BaseEntity deployedEntity) {
            if (deployedEntity == null) return;
            BasePlayer player = deployer?.GetOwnerPlayer();
            if (player == null && deployedEntity.OwnerID != 0) {
                player = BasePlayer.FindByID(deployedEntity.OwnerID);
            }
            if (player == null) return;
            timer.Once(0.3f, () => {
                if (deployedEntity == null || deployedEntity.IsDestroyed) return;
                ulong entitySkin = deployedEntity.skinID;
                if (entitySkin == 0) return;
                string prefabName = deployedEntity.ShortPrefabName ?? deployedEntity.PrefabName ?? "";
                ItemDefinition itemDef = ItemManager.FindItemDefinition(prefabName);
                if (itemDef == null) {
                    itemDef = GetItemDefinitionByDeployedEntity(deployedEntity);
                }
                if (itemDef == null) return;
                if (IsBlockedSkin(itemDef.shortname, entitySkin)) {
                    deployedEntity.Kill();
                    if (player != null && player.IsConnected) {
                        ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                        PlaySirenSound(player);
                    }
                }
            }
            );
        }
        void OnEntitySpawned(BaseNetworkable networkable) {
            if (networkable == null) return;
            BaseEntity entity = networkable as BaseEntity;
            if (entity == null) return;
            timer.Once(0.3f, () => {
                if (entity == null || entity.IsDestroyed) return;
                ulong entitySkin = entity.skinID;
                if (entitySkin == 0) return;
                string prefabName = entity.ShortPrefabName ?? entity.PrefabName ?? "";
                ItemDefinition itemDef = ItemManager.FindItemDefinition(prefabName);
                if (itemDef == null) {
                    itemDef = GetItemDefinitionByDeployedEntity(entity);
                }
                if (itemDef == null) return;
                if (IsBlockedSkin(itemDef.shortname, entitySkin)) {
                    entity.Kill();
                    BasePlayer player = BasePlayer.FindByID(entity.OwnerID);
                    if (player != null && player.IsConnected) {
                        ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                        PlaySirenSound(player);
                    }
                }
            }
            );
        }
        void OnEntityReskinned(BaseEntity entity, ItemSkinDirectory.Skin skin, BasePlayer player) {
            if (entity == null || player == null) return;
            timer.Once(0.3f, () => {
                if (entity == null || entity.IsDestroyed) return;
                string prefabName = entity.ShortPrefabName ?? entity.PrefabName ?? "";
                ItemDefinition itemDef = ItemManager.FindItemDefinition(prefabName);
                if (itemDef == null) {
                    itemDef = GetItemDefinitionByDeployedEntity(entity);
                }
                if (itemDef == null) return;
                ulong skinId = entity.skinID;
                if (IsBlockedSkin(itemDef.shortname, skinId)) {
                    entity.Kill();
                    if (player != null && player.IsConnected) {
                        player.Hurt(20f, Rust.DamageType.Generic, null, false);
                        ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                        PlaySirenSound(player);
                    }
                }
            }
            );
        }
#endregion
#region Core Logic
        private bool IsBlockedSkin(string shortname, ulong skin) {
            if (string.IsNullOrEmpty(shortname) || skin == 0) return false;
            if (configData.BlockedSkins.TryGetValue(shortname, out var blockedSkins)) {
                return blockedSkins.Contains(skin);
            }
            return false;
        }
        private ItemDefinition GetItemDefinitionByDeployedEntity(BaseEntity deployedEntity) {
            if (deployedEntity == null) return null;
            string entityPrefabPath = deployedEntity.PrefabName;
            if (string.IsNullOrEmpty(entityPrefabPath)) return null;
            foreach (var itemDef in ItemManager.GetItemDefinitions()) {
                var itemModDeployable = itemDef.GetComponent<ItemModDeployable>();
                if (itemModDeployable == null) continue;
                if (itemModDeployable.entityPrefab.resourcePath == entityPrefabPath) {
                    return itemDef;
                }
            }
            return null;
        }
        private void RemoveActiveItem(BasePlayer player, Item item) {
            if (player == null || item == null || !player.IsConnected) return;
            var activeItem = player.GetActiveItem();
            if (activeItem == null || activeItem.uid != item.uid) return;
            activeItem.RemoveFromContainer();
            if (!activeItem.MoveToContainer(player.inventory.containerMain)) {
                if (!player.inventory.GiveItem(activeItem)) {
                    activeItem.Drop(player.eyes.position + player.eyes.HeadForward() * 1.5f, Vector3.zero );
                }
            }
            player.inventory.SendUpdatedInventory(PlayerInventory.Type.Main, player.inventory.containerMain );
        }
        private void StartKillTimer(BasePlayer player, Item item) {
            if (player == null || !player.IsConnected || player.IsDead()) return;
            StopKillTimer(player);
            ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
            PlaySirenSound(player);
            activeKillTimers[player.userID] = timer.Every(configData.DamageInterval, () => {
                if (player == null || !player.IsConnected || player.IsDead()) {
                    StopKillTimer(player);
                    return;
                }
                var activeItem = player.GetActiveItem();
                if (activeItem == null || !IsBlockedSkin(activeItem.info.shortname, activeItem.skin) ) {
                    StopKillTimer(player);
                    return;
                }
                player.Hurt(configData.DamageAmount, Rust.DamageType.Generic, null, false);
                ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                PlaySirenSound(player);
            }
            );
        }
        private void StopKillTimer(BasePlayer player) {
            if (player == null) return;
            if (activeKillTimers.TryGetValue(player.userID, out var timer)) {
                timer?.Destroy();
                activeKillTimers.Remove(player.userID);
            }
        }
        private void CheckWornClothing(BasePlayer player) {
            if (player == null || !player.IsConnected || player.IsDead()) {
                StopClothingTimer(player);
                return;
            }
            bool hasBlockedClothing = false;
            foreach (var item in player.inventory.containerWear.itemList) {
                if (item != null && IsBlockedSkin(item.info.shortname, item.skin)) {
                    hasBlockedClothing = true;
                    break;
                }
            }
            if (hasBlockedClothing) {
                StartClothingTimer(player);
            }
            else {
                StopClothingTimer(player);
            }
        }
        private void StartClothingTimer(BasePlayer player) {
            if (player == null || !player.IsConnected || player.IsDead()) return;
            if (activeClothingTimers.ContainsKey(player.userID)) return;
            ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
            PlaySirenSound(player);
            activeClothingTimers[player.userID] = timer.Every(configData.DamageInterval, () => {
                if (player == null || !player.IsConnected || player.IsDead()) {
                    StopClothingTimer(player);
                    return;
                }
                bool hasBlockedClothing = false;
                foreach (var item in player.inventory.containerWear.itemList) {
                    if (item != null && IsBlockedSkin(item.info.shortname, item.skin)) {
                        hasBlockedClothing = true;
                        break;
                    }
                }
                if (!hasBlockedClothing) {
                    StopClothingTimer(player);
                    return;
                }
                player.Hurt(configData.DamageAmount, Rust.DamageType.Generic, null, false);
                ShowGameTip(player, Lang("RestrictedItem", player.UserIDString));
                PlaySirenSound(player);
            }
            );
        }
        private void StopClothingTimer(BasePlayer player) {
            if (player == null) return;
            if (activeClothingTimers.TryGetValue(player.userID, out var timer)) {
                timer?.Destroy();
                activeClothingTimers.Remove(player.userID);
            }
        }
        private void ShowGameTip(BasePlayer player, string message) {
            if (player?.IsConnected != true) {
                return;
            }
            player.SendConsoleCommand("gametip.showtoast", 0, message);
        }
        private void PlaySirenSound(BasePlayer player) {
            if (player == null || !player.IsConnected) return;
            if (!string.IsNullOrEmpty(configData.SirenSound)) {
                Effect effect = new Effect(configData.SirenSound, player, 0, Vector3.zero, Vector3.forward );
                EffectNetwork.Send(effect, player.Connection);
            }
        }
#endregion
#region Commands
        [ChatCommand("ic")]
        private void BlockItemCommand(BasePlayer player, string command, string[] args) {
            if (player == null || !player.IsAdmin) return;
            string shortname = null;
            ulong skin = 0;
            bool isDeployed = false;
            Item targetItem = null;
            BaseEntity targetEntity = null;
            var activeItem = player.GetActiveItem();
            if (activeItem != null) {
                if (activeItem.skin == 0) {
                    Print(player, Lang("NoSkin", player.UserIDString));
                    return;
                }
                targetItem = activeItem;
                shortname = activeItem.info.shortname;
                skin = activeItem.skin;
            }
            else {
                targetItem = GetTargetItem(player);
                if (targetItem != null) {
                    if (targetItem.skin == 0) {
                        Print(player, Lang("NoSkin", player.UserIDString));
                        return;
                    }
                    shortname = targetItem.info.shortname;
                    skin = targetItem.skin;
                }
                else {
                    targetEntity = GetTargetEntity(player);
                    if (targetEntity != null) {
                        skin = targetEntity.skinID;
                        if (skin == 0) {
                            Print(player, Lang("NoSkin", player.UserIDString));
                            return;
                        }
                        string prefabName = targetEntity.ShortPrefabName ?? targetEntity.PrefabName ?? "";
                        ItemDefinition itemDef = ItemManager.FindItemDefinition(prefabName);
                        if (itemDef == null) {
                            Print(player, Lang("NotLookingAtItem", player.UserIDString));
                            return;
                        }
                        shortname = itemDef.shortname;
                        isDeployed = true;
                    }
                    else {
                        Print(player, Lang("NotLookingAtItem", player.UserIDString));
                        return;
                    }
                }
            }
            if (skin == 0) {
                Print(player, Lang("NoSkin", player.UserIDString));
                return;
            }
            if (!configData.BlockedSkins.ContainsKey(shortname)) {
                configData.BlockedSkins[shortname] = new List<ulong>();
            }
            if (!configData.BlockedSkins[shortname].Contains(skin)) {
                configData.BlockedSkins[shortname].Add(skin);
                SaveConfig();
            }
            if (isDeployed) {
                targetEntity.skinID = 0;
                targetEntity.SendNetworkUpdate();
            }
            else if (targetItem != null) {
                targetItem.skin = 0;
                targetItem.MarkDirty();
                var heldEntity = targetItem.GetHeldEntity();
                if (heldEntity != null) {
                    heldEntity.skinID = 0;
                    heldEntity.SendNetworkUpdate();
                }
            }
            Print(player, Lang("ItemBlocked", player.UserIDString, shortname, skin));
            Print(player, Lang("SkinRemoved", player.UserIDString, shortname));
        }
        private Item GetTargetItem(BasePlayer player) {
            if (player == null) return null;
            RaycastHit hit;
            if (Physics.Raycast(player.eyes.HeadRay(), out hit, 5f, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore ) ) {
                BaseEntity entity = hit.GetEntity();
                if (entity is DroppedItem droppedItem && droppedItem.item != null) {
                    return droppedItem.item;
                }
            }
            return null;
        }
        private BaseEntity GetTargetEntity(BasePlayer player) {
            if (player == null) return null;
            RaycastHit hit;
            if (Physics.Raycast(player.eyes.HeadRay(), out hit, 5f, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore ) ) {
                BaseEntity entity = hit.GetEntity();
                if (entity != null && entity.skinID != 0) {
                    return entity;
                }
            }
            return null;
        }
#endregion
#region Steam API Classes
        public class PublishedFileDetails {
            public string publishedfileid;
            public string title;
            public Tag[] tags;
            public class Tag {
                public string tag;
            }
        }
        public class SkinsResponse {
            public PublishedFileDetails[] publishedfiledetails;
        }
        public class SkinsQueryResponse {
            public SkinsResponse response;
        }
#endregion
#region Console Commands
        [ConsoleCommand("ric")]
        private void ConsoleCommandAddSkins(ConsoleSystem.Arg args) {
            if (args?.Args == null || args.Args.Length < 2) return;
            if (args.Player() != null) return;
            if (args.Args[0] != "add2") return;
            if (string.IsNullOrEmpty(configData.SteamApiKey)) {
                Puts("Steam API Key не настроен в конфигурации!");
                return;
            }
            List<ulong> skinIDs = new List<ulong>();
            int maxSkins = 15;
            for (int i = 1; i < args.Args.Length && skinIDs.Count < maxSkins; i++) {
                if (ulong.TryParse(args.Args[i], out ulong skinID)) {
                    skinIDs.Add(skinID);
                }
                else {
                    Puts($"Неверный SkinID: {args.Args[i]}");
                }
            }
            if (skinIDs.Count == 0) {
                Puts("Не найдено ни одного валидного SkinID!");
                return;
            }
            string details = $"?key={configData.SteamApiKey}&itemcount={skinIDs.Count}";
            for (int i = 0; i < skinIDs.Count; i++) {
                details += $"&publishedfileids[{i}]={skinIDs[i]}";
            }
            webrequest.Enqueue("https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/", details, (code, response) => OnSkinsRequestComplete(code, response, skinIDs.Count), this, RequestMethod.POST );
        }
        private void OnSkinsRequestComplete(int code, string response, int countAll) {
            if (code != 200 || string.IsNullOrEmpty(response)) {
                Puts("Ошибка при запросе к Steam API!");
                return;
            }
            try {
                SkinsQueryResponse sQR = JsonConvert.DeserializeObject<SkinsQueryResponse>(response );
                if (sQR?.response == null || sQR.response.publishedfiledetails == null || sQR.response.publishedfiledetails.Length == 0 ) {
                    Puts("Ошибка при добавлении скинов: неверный ответ от Steam API");
                    return;
                }
                int count = ParseAndAddSkins(sQR);
                Puts($"Успешно добавлено {count}/{countAll} скинов.");
                SaveConfig();
            }
            catch (System.Exception ex) {
                Puts($"Ошибка при обработке ответа Steam API: {ex.Message}");
            }
        }
        private int ParseAndAddSkins(SkinsQueryResponse sQR) {
            int count = 0;
            foreach (PublishedFileDetails publishedFileDetails in sQR.response.publishedfiledetails) {
                if (publishedFileDetails.tags == null) continue;
                foreach (PublishedFileDetails.Tag tag in publishedFileDetails.tags) {
                    string normalizedTag = tag.tag.ToLower().Replace("skin", "").Replace(" ", "").Replace("-", "").Replace(".item", "");
                    if (string.IsNullOrEmpty(normalizedTag)) continue;
                    if (!_workshopNameToShortname.TryGetValue(normalizedTag, out string shortname)) continue;
                    if (!ulong.TryParse(publishedFileDetails.publishedfileid, out ulong skinID)) continue;
                    if (!configData.BlockedSkins.ContainsKey(shortname)) {
                        configData.BlockedSkins[shortname] = new List<ulong>();
                    }
                    if (!configData.BlockedSkins[shortname].Contains(skinID)) {
                        configData.BlockedSkins[shortname].Add(skinID);
                        count++;
                    }
                }
            }
            return count;
        }
#endregion
    }
}

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