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

FREE SkinBox : 1.12.8 1.12.8

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using UnityEngine;
using Facepunch.Steamworks;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
namespace Oxide.Plugins {
    [Info("SkinBox", "FuJiCuRa", "1.12.8", ResourceId = 17)]
    //  Слив плагинов server-rust by Apolo YouGame
    class SkinBox : RustPlugin {
        [PluginReference]
        Plugin QuickSort, SortItems, ServerRewards, Economics, StacksExtended;
        bool skinsLoaded;
        bool Initialized;
        bool Changed;
        static SkinBox skinBox = null;
        bool isValidated;
        bool activeServerRewards;
        bool activeEconomics;
        bool activePointSystem;
        int maxItemsShown;
        bool _hasStacksExtended;
        bool _stacksExtendedExtrasDisabled;
        Dictionary<string, LinkedList<ulong>> skinsCache = new Dictionary<string, LinkedList<ulong>>();
        Dictionary<string, LinkedList<ulong>> skinsCacheLimited = new Dictionary<string, LinkedList<ulong>>();
        Dictionary<string, int> approvedSkinsCount = new Dictionary<string, int>();
        List<ulong> checkedPlayers = new List<ulong>();
        Dictionary<string, DateTime> cooldownTimes = new Dictionary<string, DateTime>();
        Dictionary<string, string> NameToItemName = new Dictionary<string, string>();
        Dictionary<string, string> ItemNameToName = new Dictionary<string, string>();
        Dictionary<string, object> manualAddedSkinsPre = new Dictionary<string, object>();
        Dictionary<string, List<ulong>> manualAddedSkins = new Dictionary<string, List<ulong>>();
        List<ulong> excludedSkins = new List<ulong>();
        List<object> excludedSkinsPre = new List<object>();
        Dictionary<ulong, Vector3> activeBoxUsers = new Dictionary<ulong, Vector3>();
        Dictionary<ulong, SkinBoxHandler> activeSkinBoxes = new Dictionary<ulong, SkinBoxHandler>();
        Dictionary<ulong, string> skinWorkshopNames = new Dictionary<ulong, string>();
        List<Workshop.Query> getRankedQueries;
        List<Workshop.Query> getApprovedQueries;
        int countQueriedGetRanked;
        int countQueriedGetApproved;
        IEnumerator _getApprovedWorkshopSkins;
        IEnumerator _getRankedWorkshopSkins;
        IEnumerator _validateManualAddedSkins;
        IEnumerator _searchWorkshopSkin;
        string skinBoxCommand;
        string permissionUse;
        bool forceClientPreload;
        bool forceClientAlways;
        bool forceAlsoWearables;
        bool showLoadedSkinCounts;
        int exludedSkinsAuthLevel;
        bool hideQuickSort;
        bool hideSortItems;
        float boxUseDistance;
        string steamApiKey;
        int accessOverrideAuthLevel;
        bool allowStackedItems;
        bool enableCustomPerms;
        string permCustomPlayerwearable;
        string permCustomWeapon;
        string permCustomDeployable;
        bool useInbuiltSkins;
        bool useApprovedSkins;
        int approvedSkinsLimit;
        bool useManualAddedSkins;
        bool useWebskinsRankedByTrend;
        int usedRankedByTrendDays;
        int usedThreadsGetRanked;
        int maxPagesShown;
        bool enableCooldown;
        int cooldownBox;
        bool cooldownOverrideAdmin;
        int cooldownOverrideAuthLevel;
        bool activateAfterSkinTaken;
        bool enableUsageCost;
        bool useServerRewards;
        bool useEconomics;
        int costBoxOpen;
        int costWeapon;
        int costPlayerwearable;
        int costDeployable;
        bool costExcludeAdmins;
        string costExcludePerm;
        bool costExcludePermEnabled;
        object GetConfig(string menu, string datavalue, object defaultValue) {
            var data = Config[menu] as Dictionary<string, object>;
            if (data == null) {
                data = new Dictionary<string, object>();
                Config[menu] = data;
                Changed = true;
            }
            object value;
            if (!data.TryGetValue(datavalue, out value)) {
                value = defaultValue;
                data[datavalue] = value;
                Changed = true;
            }
            return value;
        }
        void LoadVariables() {
            useInbuiltSkins = Convert.ToBoolean(GetConfig("AvailableSkins", "useInbuiltSkins", true));
            useApprovedSkins = Convert.ToBoolean(GetConfig("AvailableSkins", "useApprovedSkins", true));
            approvedSkinsLimit = Convert.ToInt32(GetConfig("AvailableSkins", "approvedSkinsLimit", -1));
            useManualAddedSkins = Convert.ToBoolean(GetConfig("AvailableSkins", "useManualAddedSkins", true));
            useWebskinsRankedByTrend = Convert.ToBoolean(GetConfig("AvailableSkins", "useWebskinsRankedByTrend", false));
            usedRankedByTrendDays = Convert.ToInt32(GetConfig("AvailableSkins", "usedRankedByTrendDays", 30));
            usedThreadsGetRanked = Convert.ToInt32(GetConfig("AvailableSkins", "usedThreadsGetRanked", 3));
            maxPagesShown = Convert.ToInt32(GetConfig("AvailableSkins", "maxPagesShown", 1));
            skinBoxCommand = Convert.ToString(GetConfig("Settings", "skinBoxCommand", "skinbox"));
            permissionUse = Convert.ToString(GetConfig("Settings", "permissionUse", "skinbox.use"));
            forceClientPreload = Convert.ToBoolean(GetConfig("Settings", "forceClientPreload", false));
            forceClientAlways = Convert.ToBoolean(GetConfig("Settings", "forceClientAlways", false));
            forceAlsoWearables = Convert.ToBoolean(GetConfig("Settings", "forceAlsoWearables", true));
            showLoadedSkinCounts = Convert.ToBoolean(GetConfig("Settings", "showLoadedSkinCounts", true));
            exludedSkinsAuthLevel = Convert.ToInt32(GetConfig("Settings", "exludedSkinsAuthLevel", 2));
            accessOverrideAuthLevel = Convert.ToInt32(GetConfig("Settings", "accessOverrideAuthLevel", 2));
            hideQuickSort = Convert.ToBoolean(GetConfig("Settings", "hideQuickSort", true));
            hideSortItems = Convert.ToBoolean(GetConfig("Settings", "hideSortItems", true));
            allowStackedItems = Convert.ToBoolean(GetConfig("Settings", "allowStackedItems", false));
            boxUseDistance = Convert.ToSingle(GetConfig("Settings", "boxUseDistance", 5.0));
            steamApiKey = Convert.ToString(GetConfig("Settings", "steamApiKey", ""));
            enableCustomPerms = Convert.ToBoolean(GetConfig("CustomPermissions", "enableCustomPerms", false));
            permCustomPlayerwearable = Convert.ToString(GetConfig("CustomPermissions", "permCustomPlayerwearable", "skinbox.playerwearable"));
            permCustomWeapon = Convert.ToString(GetConfig("CustomPermissions", "permCustomWeapon", "skinbox.weapon"));
            permCustomDeployable = Convert.ToString(GetConfig("CustomPermissions", "permCustomDeployable", "skinbox.deployable"));
            enableCooldown = Convert.ToBoolean(GetConfig("Cooldown", "enableCooldown", false));
            cooldownBox = Convert.ToInt32(GetConfig("Cooldown", "cooldownBox", 60));
            cooldownOverrideAdmin = Convert.ToBoolean(GetConfig("Cooldown", "cooldownOverrideAdmin", true));
            cooldownOverrideAuthLevel = Convert.ToInt32(GetConfig("Cooldown", "cooldownOverrideAuthLevel", 2));
            activateAfterSkinTaken = Convert.ToBoolean(GetConfig("Cooldown", "activateAfterSkinTaken", true));
            manualAddedSkinsPre = (Dictionary<string, object>)GetConfig("SkinsAdded", "SkinList", new Dictionary<string, object> {
            }
            );
            excludedSkinsPre = (List<object>)GetConfig("SkinsExcluded", "SkinList", new List<object> {
            }
            );
            enableUsageCost = Convert.ToBoolean(GetConfig("UsageCost", "enableUsageCost", false));
            useServerRewards = Convert.ToBoolean(GetConfig("UsageCost", "useServerRewards", true));
            useEconomics = Convert.ToBoolean(GetConfig("UsageCost", "useEconomics", false));
            costBoxOpen = Convert.ToInt32(GetConfig("UsageCost", "costBoxOpen", 5));
            costWeapon = Convert.ToInt32(GetConfig("UsageCost", "costWeapon", 30));
            costPlayerwearable = Convert.ToInt32(GetConfig("UsageCost", "costPlayerwearable", 20));
            costDeployable = Convert.ToInt32(GetConfig("UsageCost", "costDeployable", 10));
            costExcludeAdmins = Convert.ToBoolean(GetConfig("UsageCost", "costExcludeAdmins", true));
            costExcludePerm = Convert.ToString(GetConfig("UsageCost", "costExcludePerm", "skinbox.costexcluded"));
            costExcludePermEnabled = Convert.ToBoolean(GetConfig("UsageCost", "costExcludePermEnabled", false));
            var configremoval = false;
            if ((Config.Get("AvailableSkins") as Dictionary<string, object>).ContainsKey("MissingSkinNames")) {
                (Config.Get("AvailableSkins") as Dictionary<string, object>).Remove("MissingSkinNames");
                configremoval = true;
            }
            if (!Changed & !configremoval) return;
            SaveConfig();
            Changed = false;
            configremoval = false;
        }
        protected override void LoadDefaultConfig() {
            Config.Clear();
            LoadVariables();
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                {
                    "NoPermission", "У вас нет доступа к этой команде!"
                }
                ,  //{"ToNearPlayer", "The SkinBox is currently not usable at this place"},
                {
                    "CooldownTime", "Нельзя так часто использовать команду: /skin.\nПодождите: {0} секунд."
                }
                , {
                    "NotEnoughBalanceOpen", "У вас не хватает «{0} $» что бы воспользоваться командой: /skin"
                }
                , {
                    "NotEnoughBalanceUse", "Вам необходимо «{0} $» что бы поставить '{1}'"
                }
                , {
                    "NotEnoughBalanceTake", "Скин '{0}' не был очищен!\nУ вас не хватило денег!"
                }
                ,
            }
            , this);
        }
        void Loaded() {
            LoadVariables();
            LoadDefaultMessages();
            UnsubscribeAll();
            if (allowStackedItems) SubscribeSplit();
            else UnsubscribeSplit();
            cmd.AddChatCommand(skinBoxCommand, this, "cmdSkinBox");
            if (!permission.PermissionExists(permissionUse)) permission.RegisterPermission(permissionUse, this);
            if (enableCustomPerms) {
                if (!permission.PermissionExists(permCustomPlayerwearable)) permission.RegisterPermission(permCustomPlayerwearable, this);
                if (!permission.PermissionExists(permCustomWeapon)) permission.RegisterPermission(permCustomWeapon, this);
                if (!permission.PermissionExists(permCustomDeployable)) permission.RegisterPermission(permCustomDeployable, this);
            }
            if (costExcludePermEnabled) {
                if (!permission.PermissionExists(costExcludePerm)) permission.RegisterPermission(costExcludePerm, this);
            }
            skinsCache = new Dictionary<string, LinkedList<ulong>>();
            skinsCacheLimited = new Dictionary<string, LinkedList<ulong>>();
            approvedSkinsCount = new Dictionary<string, int>();
            NameToItemName = new Dictionary<string, string>();
            ItemNameToName = new Dictionary<string, string>();
            checkedPlayers = new List<ulong>();
            activeBoxUsers = new Dictionary<ulong, Vector3>();
            skinsLoaded = false;
            skinBox = this;
            if (maxPagesShown < 1) maxPagesShown = 1;
            maxItemsShown = (36 * maxPagesShown);
        }
        void Unload() {
            var objs = UnityEngine.Object.FindObjectsOfType<SkinBoxHandler>().ToList();
            if (objs.Count > 0) foreach (var obj in objs) {
                if (obj.looter == null) continue;
                obj.looter.EndLooting();
                obj.PlayerStoppedLooting(obj.looter);
                GameObject.Destroy(obj);
            }
            if (Interface.Oxide.IsShuttingDown) return;
            if (_getApprovedWorkshopSkins != null) ServerMgr.Instance.StopCoroutine(_getApprovedWorkshopSkins);
            if (_getRankedWorkshopSkins != null) ServerMgr.Instance.StopCoroutine(_getRankedWorkshopSkins);
            if (_searchWorkshopSkin != null) ServerMgr.Instance.StopCoroutine(_searchWorkshopSkin);
            if (_validateManualAddedSkins != null) ServerMgr.Instance.StopCoroutine(_validateManualAddedSkins);
        }
        void OnServerInitialized() {
            if (enableUsageCost) {
                if (ServerRewards && useServerRewards) activeServerRewards = true;
                if (Economics && useEconomics) activeEconomics = true;
                if (activeServerRewards && activeEconomics) activeEconomics = false;
                if (activeServerRewards || activeEconomics) activePointSystem = true;
            }
            if (allowStackedItems && StacksExtended) {
                _hasStacksExtended = true;
                _stacksExtendedExtrasDisabled = (bool)StacksExtended.CallHook("DisableExtraFeatures");
                if (!_stacksExtendedExtrasDisabled) {
                    Unsubscribe(nameof(CanStackItem));
                    Unsubscribe(nameof(OnItemSplit));
                }
                else {
                    Subscribe(nameof(CanStackItem));
                    Subscribe(nameof(OnItemSplit));
                }
            }
            foreach (var skin in Skinnable.All.ToList()) {
                if (skin.Name == null || skin.Name == string.Empty) continue;
                if (skin.ItemName == null || skin.ItemName == string.Empty) continue;
                if (!NameToItemName.ContainsKey(skin.Name.ToLower())) NameToItemName.Add(skin.Name.ToLower(), skin.ItemName.ToLower());
                if (!ItemNameToName.ContainsKey(skin.ItemName.ToLower())) ItemNameToName.Add(skin.ItemName.ToLower(), skin.Name.ToLower());
            }
            foreach (var manual in manualAddedSkinsPre) manualAddedSkins.Add(manual.Key.ToString(), (manual.Value as List<object>).ConvertAll(obj => Convert.ToUInt64(obj)));
            excludedSkins = excludedSkinsPre.ConvertAll(obj => Convert.ToUInt64(obj));
            if (useManualAddedSkins) {
                _validateManualAddedSkins = ValidateManualAddedSkins();
                ServerMgr.Instance.StartCoroutine(_validateManualAddedSkins);
            }
            else {
                isValidated = true;
                GetItemSkins();
            }
            Initialized = true;
        }
        IEnumerator ValidateManualAddedSkins() {
            if (showLoadedSkinCounts) Puts($"Calling workshop to validate '{manualAddedSkins.Values.Sum(list => list.Count)}' manual added skins");
            int removeCount = 0;
            foreach (var pair in manualAddedSkins.ToList()) {
                var wsQuery = Rust.Global.SteamServer.Workshop.CreateQuery();
                wsQuery.Page = 1;
                wsQuery.PerPage = pair.Value.Count;
                wsQuery.FileId = new List<ulong>(pair.Value);
                wsQuery.Run();
                yield return new WaitWhile(new System.Func<bool>(() => wsQuery.IsRunning));
                foreach (var item in wsQuery.Items.ToList()) {
                    if (item.Title == string.Empty || item.Tags.Any(t => t.ToLower() == "version2")) {
                        manualAddedSkins[pair.Key].Remove(item.Id);
                        removeCount++;
                    }
                }
                wsQuery.Dispose();
            }
            if (showLoadedSkinCounts) if (removeCount > 0) {
                Puts($"Removed '{removeCount}' invalids from manual skinlist");
                Config["SkinsAdded", "SkinList"] = manualAddedSkins;
                Config.Save();
            }
            else Puts($"Manual skinlist successful validated");
            isValidated = true;
            GetItemSkins();
            yield return null;
        }
        void GetItemSkins() {
            if (skinsLoaded) return;
            int countInbuilt = 0;
            foreach (var itemDef in ItemManager.GetItemDefinitions()) {
                List<ulong> skins = new List<ulong> {
                    0
                }
                ;
                if (useInbuiltSkins) skins.AddRange(ItemSkinDirectory.ForItem(itemDef).Select(skin => Convert.ToUInt64(skin.id)));
                skinsCache.Add(itemDef.shortname, new LinkedList<ulong>(skins));
                if (skins.Count > 1) countInbuilt += (skins.Count - 1);
            }
            if (showLoadedSkinCounts && useInbuiltSkins) Puts($"Loaded {countInbuilt} inbuilt skins");
            if (useManualAddedSkins) {
                int countManual = 0;
                foreach (var manualskins in manualAddedSkins) {
                    string shortname = manualskins.Key;
                    if (!ItemNameToName.ContainsKey(shortname)) continue;
                    string itemname = ItemNameToName[shortname];
                    List<ulong> fileids = manualskins.Value;
                    foreach (var fileid in fileids) {
                        if (!skinsCache.ContainsKey(shortname)) {
                            skinsCache.Add(shortname, new LinkedList<ulong>());
                            skinsCache[shortname].AddLast(0);
                        }
                        if (!skinsCache[shortname].Contains(fileid)) {
                            skinsCache[shortname].AddLast(fileid);
                            countManual++;
                        }
                    }
                }
                if (showLoadedSkinCounts && countManual > 0) Puts($"Loaded {countManual} manual added skins");
            }
            if (useApprovedSkins) {
                _getApprovedWorkshopSkins = GetApprovedWorkshopSkins();
                ServerMgr.Instance.StartCoroutine(_getApprovedWorkshopSkins);
                return;
            }
            else if (useWebskinsRankedByTrend) {
                _getRankedWorkshopSkins = GetRankedWorkshopSkins();
                ServerMgr.Instance.StartCoroutine(_getRankedWorkshopSkins);
                return;
            }
            else {
                Interface.CallHook("OnSkinCacheUpdate", new Dictionary<string, LinkedList<ulong>>(skinsCache), true);
                skinsLoaded = true;
            }
        }
        object getSkincache() {
            if (skinsLoaded) return skinsCache;
            else return false;
        }
        public IEnumerator GetApprovedWorkshopSkins(bool timed = false) {
            getApprovedQueries = new List<Workshop.Query>();
            countQueriedGetApproved = 0;
            if (usedThreadsGetRanked < 1) usedThreadsGetRanked = 1;
            var waitCounter = new WaitWhile(() => getApprovedQueries.Count > 10);
            if (showLoadedSkinCounts) Puts($"Checking approved skins of '{Skinnable.All.Length}' skinnables");
            foreach (var pair in ItemNameToName.ToList()) {
                Workshop.Query wsQuery = Rust.Global.SteamServer.Workshop.CreateQuery();
                wsQuery.Page = 1;
                wsQuery.PerPage = maxItemsShown;
                wsQuery.RequireTags.Add("version3");
                wsQuery.RequireTags.Add("skin");
                wsQuery.RequireTags.Add(pair.Value.ToString());
                wsQuery.RequireAllTags = true;
                wsQuery.Order = Workshop.Order.AcceptedForGameRankedByAcceptanceDate;
                wsQuery.OnResult = new Action<Workshop.Query>(OnApprovedWorkshopQuery);
                getApprovedQueries.Add(wsQuery);
                wsQuery.Run();
                yield return waitCounter;
            }
            yield return new WaitUntil(() => getApprovedQueries.Count == 0);
            if (showLoadedSkinCounts && countQueriedGetApproved > 0) Puts($"Imported {countQueriedGetApproved} approved skins for '{skinsCache.Where(c => c.Value.Count > 1).ToList().Count}' types");
            if (useWebskinsRankedByTrend) {
                _getRankedWorkshopSkins = GetRankedWorkshopSkins();
                ServerMgr.Instance.StartCoroutine(_getRankedWorkshopSkins);
            }
            else {
                Interface.CallHook("OnSkinCacheUpdate", new Dictionary<string, LinkedList<ulong>>(skinsCache), true);
                skinsLoaded = true;
            }
        }
        void OnApprovedWorkshopQuery(Workshop.Query query) {
            if (query.Items == null) return;
            foreach (var item in query.Items.Where(i => i.Title != string.Empty).ToList()) {
                foreach (var tag in item.Tags.Where(t => t.ToLower() != "version3" && t.ToLower() != "skin")) {
                    if (NameToItemName.ContainsKey(tag)) {
                        skinWorkshopNames[item.Id] = item.Title;
                        string shortname = NameToItemName[tag];
                        if (!approvedSkinsCount.ContainsKey(shortname)) approvedSkinsCount[shortname] = 0;
                        if (approvedSkinsLimit > 0 && approvedSkinsCount[shortname] >= approvedSkinsLimit) {
                            if (!skinsCacheLimited.ContainsKey(shortname)) skinsCacheLimited[shortname] = new LinkedList<ulong>();
                            skinsCacheLimited[shortname].AddLast(item.Id);
                        }
                        if (skinsCacheLimited.ContainsKey(shortname) && skinsCacheLimited[shortname].Contains(item.Id)) continue;
                        if (!skinsCache.ContainsKey(shortname)) skinsCache[shortname] = new LinkedList<ulong>();
                        if (!skinsCache[shortname].Contains(item.Id) && skinsCache[shortname].Count < maxItemsShown) {
                            skinsCache[shortname].AddLast(item.Id);
                            approvedSkinsCount[shortname]++;
                            countQueriedGetApproved++;
                        }
                    }
                }
            }
            getApprovedQueries.Remove(query);
            query.Dispose();
        }
        IEnumerator GetRankedWorkshopSkins() {
            getRankedQueries = new List<Workshop.Query>();
            countQueriedGetRanked = 0;
            if (usedThreadsGetRanked < 1) usedThreadsGetRanked = 1;
            var waitCounter = new WaitWhile(() => getRankedQueries.Count > usedThreadsGetRanked);
            if (showLoadedSkinCounts) Puts($"Filling up the Cache by '{usedThreadsGetRanked}' workshop threads");
            foreach (var pair in ItemNameToName.ToList()) {
                Workshop.Query wsQuery = Rust.Global.SteamServer.Workshop.CreateQuery();
                wsQuery.Page = 1;
                wsQuery.PerPage = maxItemsShown;
                wsQuery.ExcludeTags.Add("version2");
                wsQuery.RequireTags.Add("version3");
                wsQuery.RequireTags.Add("skin");
                wsQuery.RequireTags.Add(pair.Value.ToString());
                wsQuery.RequireAllTags = true;
                wsQuery.Order = Workshop.Order.RankedByTrend;
                wsQuery.RankedByTrendDays = usedRankedByTrendDays;
                wsQuery.OnResult = new Action<Workshop.Query>(OnRankedWorkshopQuery);
                getRankedQueries.Add(wsQuery);
                wsQuery.Run();
                yield return waitCounter;
            }
            yield return new WaitUntil(() => getRankedQueries.Count == 0);
            if (showLoadedSkinCounts && countQueriedGetRanked > 0) Puts($"Cache for {ItemNameToName.Count} Skinnables filled with {countQueriedGetRanked} ranked skins");
            Interface.CallHook("OnSkinCacheUpdate", new Dictionary<string, LinkedList<ulong>>(skinsCache), true);
            skinsLoaded = true;
        }
        void OnRankedWorkshopQuery(Workshop.Query query) {
            if (query.Items == null) return;
            foreach (var item in query.Items.Where(i => i.Title != string.Empty).ToList()) {
                foreach (var tag in item.Tags.Where(t => t.ToLower() != "version3" && t.ToLower() != "skin")) {
                    if (NameToItemName.ContainsKey(tag)) {
                        skinWorkshopNames[item.Id] = item.Title;
                        string shortname = NameToItemName[tag];
                        if (!skinsCache.ContainsKey(shortname)) continue;
                        if (!skinsCache[shortname].Contains(item.Id) && skinsCache[shortname].Count < maxItemsShown) {
                            skinsCache[shortname].AddLast(item.Id);
                            countQueriedGetRanked++;
                        }
                    }
                }
            }
            getRankedQueries.Remove(query);
            query.Dispose();
        }
        [ConsoleCommand("skinbox.addexcluded")]
        void consoleAddExcluded(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2) return;
            if (arg.Args == null || arg.Args.Length < 1) {
                SendReply(arg, "You need to type in one or more Workshop FileId's");
                return;
            }
            List<ulong> fileIds = new List<ulong>();
            for (int i = 0; i < arg.Args.Length; i++) {
                ulong fileId = 0uL;
                if (!ulong.TryParse(arg.Args[i], out fileId)) {
                    SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
                    continue;
                }
                else {
                    if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
                        continue;
                    }
                    fileIds.Add(fileId);
                }
            }
            int countAdded = 0;
            foreach (var fileId in fileIds) if (!excludedSkins.Contains(fileId)) {
                excludedSkins.Add(fileId);
                countAdded++;
            }
            if (countAdded > 0) {
                Config["SkinsExcluded", "SkinList"] = excludedSkins;
                Config.Save();
                SendReply(arg, $"Added {countAdded} skins to exclusion list");
            }
        }
        [ConsoleCommand("skinbox.removeexcluded")]
        void consoleRemoveExcluded(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2) return;
            if (arg.Args == null || arg.Args.Length < 1) {
                SendReply(arg, "You need to type in one or more Workshop FileId's");
                return;
            }
            List<ulong> fileIds = new List<ulong>();
            for (int i = 0; i < arg.Args.Length; i++) {
                ulong fileId = 0uL;
                if (!ulong.TryParse(arg.Args[i], out fileId)) {
                    SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
                    continue;
                }
                else {
                    if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
                        continue;
                    }
                    fileIds.Add(fileId);
                }
            }
            int countRemoved = 0;
            foreach (var fileId in fileIds) if (excludedSkins.Contains(fileId)) {
                excludedSkins.Remove(fileId);
                countRemoved++;
            }
            if (countRemoved > 0) {
                Config["SkinsExcluded", "SkinList"] = excludedSkins;
                Config.Save();
                SendReplyCl(arg, $"Removed {countRemoved} skins from exclusion");
            }
        }
        [ConsoleCommand("skinbox.addskin")]
        void consoleAddSkin(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2) return;
            if (arg.Args == null || arg.Args.Length < 1) {
                SendReply(arg, "You need to type in one or more Workshop FileId's");
                return;
            }
            List<ulong> fileIds = new List<ulong>();
            for (int i = 0; i < arg.Args.Length; i++) {
                ulong fileId = 0uL;
                if (!ulong.TryParse(arg.Args[i], out fileId)) {
                    SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
                    continue;
                }
                else {
                    if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
                        continue;
                    }
                    fileIds.Add(fileId);
                }
            }
            ServerMgr.Instance.StartCoroutine(SearchWorkshopSkin(fileIds, arg));
        }
        [ConsoleCommand("skinbox.removeskin")]
        void consoleRemoveSkin(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2) return;
            if (arg.Args == null || arg.Args.Length < 1) {
                SendReply(arg, "You need to type in one or more Workshop FileId's");
                return;
            }
            List<ulong> fileIds = new List<ulong>();
            for (int i = 0; i < arg.Args.Length; i++) {
                ulong fileId = 0uL;
                if (!ulong.TryParse(arg.Args[i], out fileId)) {
                    SendReply(arg, $"Ignored '{arg.Args[i]}' as of not a number");
                    continue;
                }
                else {
                    if (arg.Args[i].Length < 9 || arg.Args[i].Length > 10) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9/10-Digits");
                        continue;
                    }
                    fileIds.Add(fileId);
                }
            }
            bool doSave = false;
            int removed = 0;
            foreach (var addedSkins in manualAddedSkins) {
                foreach (var fileId in fileIds) {
                    if (addedSkins.Value.Contains(fileId)) {
                        manualAddedSkins[addedSkins.Key].Remove(fileId);
                        skinsCache[addedSkins.Key].Remove(fileId);
                        removed++;
                        doSave = true;
                    }
                }
            }
            if (doSave) {
                Config["SkinsAdded", "SkinList"] = manualAddedSkins;
                Config.Save();
                SendReply(arg, $"Removed {removed} FileId's");
                Interface.CallHook("OnSkinCacheUpdate", new Dictionary<string, LinkedList<ulong>>(skinsCache), true);
            }
        }
        public IEnumerator SearchWorkshopSkin(List<ulong> fileIds, ConsoleSystem.Arg arg = null) {
            var wsQuery = Rust.Global.SteamServer.Workshop.CreateQuery();
            wsQuery.Page = 1;
            wsQuery.PerPage = 1;
            wsQuery.RequireTags.Add("version3");
            wsQuery.RequireTags.Add("version2");
            wsQuery.FileId = new List<ulong>(fileIds);
            SendReplyCl(arg, $"Calling Workshop for '{fileIds.Count}' FileId's");
            wsQuery.Run();
            yield return new WaitWhile(new System.Func<bool>(() => wsQuery.IsRunning));
            bool doSave = false;
            foreach (var item in wsQuery.Items.Where(i => i.Title != string.Empty).ToList()) {
                if (item.Tags.Any(t => t.ToLower() == "version2")) {
                    SendReplyCl(arg, $"Version2 skins are not more supported in the game ({item.Id})'");
                    continue;
                }
                bool matchedAny = false;
                foreach (var tag in item.Tags.Where(t => t.ToLower() != "version3" && t.ToLower() != "skin")) {
                    if (NameToItemName.ContainsKey(tag)) {
                        string shortname = NameToItemName[tag];
                        if (manualAddedSkins.ContainsKey(shortname)) {
                            if (manualAddedSkins[shortname].Contains(item.Id)) {
                                SendReplyCl(arg, $"'{item.Title} ({item.Id})' was already added");
                                matchedAny = true;
                                continue;
                            }
                        }
                        if (skinsCache.ContainsKey(shortname)) if ((skinsCache[shortname] as LinkedList<ulong>).Contains(item.Id)) {
                            SendReplyCl(arg, $"'{item.Title} ({item.Id})' belongs already to approved/ranked");
                            matchedAny = true;
                            continue;
                        }
                        if (!manualAddedSkins.ContainsKey(shortname)) manualAddedSkins.Add(shortname, new List<ulong>());
                        manualAddedSkins[shortname].Add(item.Id);
                        if (!skinsCache.ContainsKey(shortname)) {
                            skinsCache.Add(shortname, new LinkedList<ulong>());
                            skinsCache[shortname].AddLast(0);
                        }
                        skinsCache[shortname].AddAfter(skinsCache[shortname].First, item.Id);
                        skinWorkshopNames[item.Id] = item.Title;
                        SendReplyCl(arg, $"'{item.Title} ({item.Id})' added to the list for '{shortname}'");
                        matchedAny = true;
                        doSave = true;
                    }
                }
                if (!matchedAny) SendReplyCl(arg, $"No shortname found for '{item.Title}|{item.Id}'.Fix it inside 'MissingSkinNames'");
            }
            if (doSave) {
                Config["SkinsAdded", "SkinList"] = manualAddedSkins;
                Config.Save();
                Interface.CallHook("OnSkinCacheUpdate", new Dictionary<string, LinkedList<ulong>>(skinsCache), true);
            }
            wsQuery.Dispose();
        }
        [ConsoleCommand("skinbox.addcollection")]
        void consoleAddCollection(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2) return;
            if (steamApiKey == null || steamApiKey == string.Empty) {
                SendReply(arg, "This functions needs valid defined steam api-key");
                return;
            }
            if (arg.Args == null || arg.Args.Length < 1) {
                SendReply(arg, "You need to type in a valid collection id");
                return;
            }
            ulong collId = 0;
            if (!ulong.TryParse(arg.Args[0], out collId)) {
                SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' is not a number");
                return;
            }
            else {
                if (arg.Args[0].Length < 9 || arg.Args[0].Length > 10) {
                    SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' has not 9/10-Digits");
                    return;
                }
            }
            var url = $"https://api.steampowered.com/ISteamRemoteStorage/GetCollectionDetails/v1/";
            var body = $"?key={steamApiKey}&collectioncount=1&publishedfileids[0]={arg.Args[0]}";
            try {
                webrequest.Enqueue(url, body, (code, response) => PostCallbackAdd(code, response, arg), this, RequestMethod.POST);
            }
            catch {
                SendReplyCl(arg, "Steam webrequest failed!");
            }
        }
        void PostCallbackAdd(int code, string response, ConsoleSystem.Arg arg = null) {
            if (response == null || code != 200) {
                SendReplyCl(arg, "Steam webrequest failed by wrong response!");
                return;
            }
            var col = JsonConvert.DeserializeObject<GetCollectionDetails>(response);
            if (col == null || !(col is GetCollectionDetails)) {
                SendReplyCl(arg, "No Collection data received!");
                return;
            }
            if (col.response.resultcount == 0 || col.response.collectiondetails == null || col.response.collectiondetails.Count == 0 || col.response.collectiondetails[0].result != 1) {
                SendReplyCl(arg, "The Steam collection could not be found!");
                return;
            }
            List<ulong> fileIds = new List<ulong>();
            foreach (var child in col.response.collectiondetails[0].children) {
                try {
                    fileIds.Add(Convert.ToUInt64(child.publishedfileid));
                }
                catch {
                }
            }
            if (fileIds.Count == 0) {
                SendReplyCl(arg, "No skin numbers found.Workshop search cancelled.");
                return;
            }
            if (_searchWorkshopSkin != null) ServerMgr.Instance.StopCoroutine(_searchWorkshopSkin);
            _searchWorkshopSkin = SearchWorkshopSkin(fileIds, arg);
            ServerMgr.Instance.StartCoroutine(_searchWorkshopSkin);
        }
        [ConsoleCommand("skinbox.removecollection")]
        void consoleRemoveCollection(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel < 2) return;
            if (steamApiKey == null || steamApiKey == string.Empty) {
                SendReply(arg, "This functions needs valid defined steam api-key");
                return;
            }
            if (arg.Args == null || arg.Args.Length < 1) {
                SendReply(arg, "You need to type in a valid collection id");
                return;
            }
            ulong collId = 0;
            if (!ulong.TryParse(arg.Args[0], out collId)) {
                SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' is not a number");
                return;
            }
            else {
                if (arg.Args[0].Length < 9 || arg.Args[0].Length > 10) {
                    SendReply(arg, $"Collection ID not correct: '{arg.Args[0]}' has not 9/10-Digits");
                    return;
                }
            }
            var url = $"https://api.steampowered.com/ISteamRemoteStorage/GetCollectionDetails/v1/";
            var body = $"?key={steamApiKey}&collectioncount=1&publishedfileids[0]={arg.Args[0]}";
            try {
                webrequest.Enqueue(url, body, (code, response) => PostCallbackRemove(code, response, arg), this, RequestMethod.POST);
            }
            catch {
                SendReplyCl(arg, "Steam webrequest failed!");
            }
        }
        void PostCallbackRemove(int code, string response, ConsoleSystem.Arg arg = null) {
            if (response == null || code != 200) {
                SendReplyCl(arg, "Steam webrequest failed by wrong response!");
                return;
            }
            var col = JsonConvert.DeserializeObject<GetCollectionDetails>(response);
            if (col == null || !(col is GetCollectionDetails)) {
                SendReplyCl(arg, "No Collection data received!");
                return;
            }
            if (col.response.resultcount == 0 || col.response.collectiondetails == null || col.response.collectiondetails.Count == 0 || col.response.collectiondetails[0].result != 1) {
                SendReplyCl(arg, "The Steam collection could not be found!");
                return;
            }
            List<ulong> fileIds = new List<ulong>();
            foreach (var child in col.response.collectiondetails[0].children) {
                try {
                    fileIds.Add(Convert.ToUInt64(child.publishedfileid));
                }
                catch {
                }
            }
            if (fileIds.Count == 0) {
                SendReplyCl(arg, "No skin numbers found.Workshop search cancelled.");
                return;
            }
            int removed = 0;
            foreach (var addSkins in new Dictionary<string, List<ulong>>(manualAddedSkins)) {
                foreach (var skin in addSkins.Value.ToList()) {
                    if (fileIds.Contains(skin)) {
                        manualAddedSkins[addSkins.Key].Remove(skin);
                        if (skinsCache.ContainsKey(addSkins.Key)) skinsCache[addSkins.Key].Remove(skin);
                        removed++;
                    }
                }
            }
            if (removed > 0) {
                SendReplyCl(arg, $"Removed '{removed}' manual skins by collection remove.");
                Config["SkinsAdded", "SkinList"] = manualAddedSkins;
                Config.Save();
            }
            else SendReplyCl(arg, $"No manual skins to remove by collection remove.");
        }
        public class GetCollectionDetails {
            [JsonProperty("response")]
            public Response response;
            public class Response {
                [JsonProperty("result")]
                public int result;
                [JsonProperty("resultcount")]
                public int resultcount;
                [JsonProperty("collectiondetails")]
                public List<Collectiondetail> collectiondetails;
                public class Collectiondetail {
                    [JsonProperty("publishedfileid")]
                    public string publishedfileid;
                    [JsonProperty("result")]
                    public int result;
                    [JsonProperty("children")]
                    public List<Child> children;
                    public class Child {
                        [JsonProperty("publishedfileid")]
                        public string publishedfileid;
                        [JsonProperty("sortorder")]
                        public int sortorder;
                        [JsonProperty("filetype")]
                        public int filetype;
                    }
                }
            }
        }
        void OnPlayerInit(BasePlayer player) {
            if (player == null) return;
            if (!forceClientPreload || (checkedPlayers.Contains(player.userID) && !forceClientAlways)) return;
            timer.Once(0.1f, () => InitPreload(player));
        }
        void InitPreload(BasePlayer player) {
            ItemContainer beltInv = player.inventory.containerBelt;
            ItemContainer wearInv = player.inventory.containerWear;
            var wearList = new List<Item>();
            if (forceAlsoWearables) {
                foreach (var item in wearInv.itemList.ToList()) {
                    wearList.Add(item);
                    item.RemoveFromContainer();
                }
                player.inventory.SendUpdatedInventory(PlayerInventory.Type.Wear, wearInv, false);
            }
            beltInv.capacity++;
            foreach (var skinCache in skinsCache) {
                if ((skinCache.Value as LinkedList<ulong>).Count <= 1) continue;
                foreach (var skin in (LinkedList<ulong>)skinCache.Value) {
                    if (skin == 0) continue;
                    var itemDef = ItemManager.FindItemDefinition(skinCache.Key);
                    if (itemDef == null) continue;
                    Item item = ItemManager.Create(itemDef, 1, skin);
                    if (item == null || !item.IsValid()) continue;
                    if (item.info.category == ItemCategory.Attire && !forceAlsoWearables) {
                        item.Remove(0f);
                        continue;
                    }
                    if (item.info.category == ItemCategory.Attire && forceAlsoWearables) {
                        item.MoveToContainer(wearInv);
                        player.inventory.SendUpdatedInventory(PlayerInventory.Type.Wear, wearInv, false);
                    }
                    else {
                        item.MoveToContainer(beltInv, 6, false);
                        player.inventory.SendUpdatedInventory(PlayerInventory.Type.Belt, beltInv, false);
                    }
                    item.RemoveFromContainer();
                    item.Remove(0f);
                }
            }
            beltInv.capacity--;
            if (forceAlsoWearables) {
                foreach (var item in wearList) item.MoveToContainer(wearInv);
                player.inventory.SendUpdatedInventory(PlayerInventory.Type.Wear, wearInv, false);
                wearList.Clear();
            }
            if (!checkedPlayers.Contains(player.userID)) checkedPlayers.Add(player.userID);
            ItemManager.DoRemoves();
        }
        [ConsoleCommand("skinbox.open")]
        void consoleSkinboxOpen(ConsoleSystem.Arg arg) {
            if (arg == null || !isValidated) return;
            if (arg.Connection == null) {
                if (arg.Args == null || arg.Args.Length == 0) {
                    SendReply(arg, $"'skinbox.open' cmd needs a passed steamid ");
                    return;
                }
                ulong argId = 0uL;
                if (!ulong.TryParse(arg.Args[0], out argId)) {
                    SendReply(arg, $"'skinbox.open' cmd for '{arg.Args[0]}' failed (no valid number)");
                    return;
                }
                BasePlayer argPlayer = BasePlayer.FindByID(argId);
                if (argPlayer == null) {
                    SendReply(arg, $"'skinbox.open' cmd for userID '{argId}' failed (player not found)");
                    return;
                }
                if (!argPlayer.inventory.loot.IsLooting()) OpenSkinBox(argPlayer);
            }
            else if (arg.Connection != null && arg.Connection.player != null) {
                BasePlayer player = arg.Player();
                if (player.inventory.loot.IsLooting()) return;
                if (!(player.IsAdmin || player.net.connection.authLevel >= accessOverrideAuthLevel) && !permission.UserHasPermission(player.UserIDString, permissionUse)) {
                    player.ChatMessage(lang.GetMessage("NoPermission", this, player.UserIDString));
                    return;
                }
                if (!CheckDistance(player) || !CheckOpenBalance(player)) return;
                if (enableCooldown && !(cooldownOverrideAdmin && (player.IsAdmin || player.net.connection.authLevel >= cooldownOverrideAuthLevel))) {
                    DateTime now = DateTime.UtcNow;
                    DateTime time;
                    var key = player.UserIDString + "-box";
                    if (cooldownTimes.TryGetValue(key, out time)) {
                        if (time > now.AddSeconds(-cooldownBox)) {
                            player.ChatMessage(string.Format(lang.GetMessage("CooldownTime", this, player.UserIDString), (time - now.AddSeconds(-cooldownBox)).Seconds));
                            return;
                        }
                    }
                }
                OpenSkinBox(player);
            }
        }
        void cmdSkinBox(BasePlayer player, string command, string[] args) {
            if (player.inventory.loot.IsLooting() || !isValidated) 
// ... [Code preview truncated due to length. Full source in attached file] ...

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