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

FREE SkinBox : 1.8.3 1.8.3

Нет прав для скачивания
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 Rust;
using Oxide.Core;
using Oxide.Core.Plugins;
namespace Oxide.Plugins {
    [Info("SkinBox", "Fujikura", "1.8.3", ResourceId=17)]
    class SkinBox : RustPlugin {
        [PluginReference]
        Plugin QuickSort;
        [PluginReference]
        Plugin ServerRewards;
        [PluginReference]
        Plugin Economics;
        bool skinsLoaded;
        bool Changed=false;
        bool _unloaded;
        static SkinBox skinBox=null;
        bool activeServerRewards;
        bool activeEconomics;
        bool activePointSystem;
        Dictionary<string, List<ulong>>skinsCache=new Dictionary<string, List<ulong>>();
        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>();
        static Dictionary<string, object>missingWorkshopNames() {
            var dp=new Dictionary<string, object>();
            dp.Add("rug", "Rug");
            dp.Add("chair", "Chair");
            dp.Add("rug.bear", "Bearskin Rug");
            dp.Add("bandana", "Bandana");
            dp.Add("table", "Table");
            return dp;
        }
        string skinBoxCommand;
        string permissionUse;
        bool forceClientPreload;
        bool forceClientAlways;
        bool forceAlsoWearables;
        bool showLoadedSkinCounts;
        int exludedSkinsAuthLevel;
        bool hideQuickSort;
        float boxUseDistance;
        bool enableCustomPerms;
        string permCustomPlayerwearable;
        string permCustomWeapon;
        string permCustomDeployable;
        bool useInbuiltSkins;
        bool useApprovedSkins;
        bool useManualAddedSkins;
        bool useWebskinsRankedByTrend;
        int usedRankedByTrendDays;
        Dictionary<string, object>missingSkinNames=new Dictionary<string, object>();
        bool enableCooldown;
        int cooldownBox;
        bool cooldownOverrideAdmin;
        bool activateAfterSkinTaken;
        bool useKeyBindLogin;
        string keyToBind;
        bool enableUsageCost;
        bool useServerRewards;
        bool useEconomics;
        int costBoxOpen;
        int costWeapon;
        int costPlayerwearable;
        int costDeployable;
        bool costExcludeAdmins;
        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));
            useManualAddedSkins=Convert.ToBoolean(GetConfig("AvailableSkins", "useManualAddedSkins", true));
            useWebskinsRankedByTrend=Convert.ToBoolean(GetConfig("AvailableSkins", "useWebskinsRankedByTrend", false));
            usedRankedByTrendDays=Convert.ToInt32(GetConfig("AvailableSkins", "usedRankedByTrendDays", 30));
            missingSkinNames=(Dictionary<string, object>)GetConfig("AvailableSkins", "MissingSkinNames", missingWorkshopNames());
            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));
            hideQuickSort=Convert.ToBoolean(GetConfig("Settings", "hideQuickSort", false));
            boxUseDistance=Convert.ToSingle(GetConfig("Settings", "boxUseDistance", 10.0));
            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));
            activateAfterSkinTaken=Convert.ToBoolean(GetConfig("Cooldown", "activateAfterSkinTaken", true));
            useKeyBindLogin=Convert.ToBoolean(GetConfig("KeyBind", "useKeyBindLogin", false));
            keyToBind=Convert.ToString(GetConfig("KeyBind", "keyToBind", "c"));
            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));
            if (!Changed) return;
            SaveConfig();
            Changed=false;
        }
        protected override void LoadDefaultConfig() {
            Config.Clear();
            LoadVariables();
        }
        void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                {
                    "NoPermission", "You don't have permission to use the SkinBox"
                }
                , {
                    "ToNearPlayer", "The SkinBox is currently not usable at this place"
                }
                , {
                    "CooldownTime", "You need to wait {0} seconds to re-open the SkinBox again"
                }
                , {
                    "NotEnoughBalanceOpen", "You need at least '{0}' bucks to open the SkinBox"
                }
                , {
                    "NotEnoughBalanceUse", "You would need at least '{0}' bucks to skin '{1}'"
                }
                , {
                    "NotEnoughBalanceTake", "'{0}' was not skinned.You had not enough bucks"
                }
                ,
            }
            , this);
        }
        void Loaded() {
            LoadVariables();
            LoadDefaultMessages();
            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);
            }
            skinsCache=new Dictionary<string, List<ulong>>();
            NameToItemName=new Dictionary<string, string>();
            ItemNameToName=new Dictionary<string, string>();
            checkedPlayers=new List <ulong>();
            activeBoxUsers=new Dictionary <ulong, Vector3>();
            skinsLoaded=false;
            _unloaded=false;
            skinBox=this;
        }
        void OnServerInitialized() {
            if (enableUsageCost) {
                if (ServerRewards && useServerRewards) activeServerRewards=true;
                if (Economics && useEconomics) activeEconomics=true;
                if (activeServerRewards && activeEconomics) activeEconomics=false;
                if (activeServerRewards || activeEconomics) activePointSystem=true;
            }
            OnServerInit();
        }
        void OnServerInit() {
            foreach (var itemtype in Rust.Workshop.Approved.All.ToList()) {
                if (itemtype.Skinnable.Name==null || itemtype.Skinnable.Name==string.Empty) continue;
                if (itemtype.Skinnable.ItemName==null || itemtype.Skinnable.ItemName==string.Empty) continue;
                if (!NameToItemName.ContainsKey(itemtype.Skinnable.Name.ToLower())) NameToItemName.Add(itemtype.Skinnable.Name.ToLower(), itemtype.Skinnable.ItemName.ToLower());
                if (!ItemNameToName.ContainsKey(itemtype.Skinnable.ItemName.ToLower())) ItemNameToName.Add(itemtype.Skinnable.ItemName.ToLower(), itemtype.Skinnable.Name.ToLower());
            }
            foreach (var skin in missingSkinNames) {
                var itemname=skin.Key.ToLower();
                var itemDef=ItemManager.FindItemDefinition(itemname);
                if (itemDef==null) continue;
                var workshopname=((string)skin.Value).ToLower();
                if (!NameToItemName.ContainsKey(workshopname)) NameToItemName.Add(workshopname, itemname);
                if (!ItemNameToName.ContainsKey(itemname)) ItemNameToName.Add(itemname, workshopname);
            }
            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));
            GetItemSkins();
        }
        void Unload() {
            _unloaded=true;
            ServerMgr.Instance.StopCoroutine("GetRankedWorkshopSkins");
            ServerMgr.Instance.StopCoroutine("GetAcceptedWorkshopSkins");
            ServerMgr.Instance.StopCoroutine("SearchWorkshopSkin");
            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);
            }
        }
        void GetItemSkins() {
            if (skinsLoaded) return;
            int countInbuilt=0;
            foreach (var itemDef in ItemManager.GetItemDefinitions()) {
                List<ulong>skins;
                skins=new List<ulong> {
                    0
                }
                ;
                if (useInbuiltSkins) skins.AddRange(ItemSkinDirectory.ForItem(itemDef).Select(skin=> Convert.ToUInt64(skin.id)));
                skinsCache.Add(itemDef.shortname, skins);
                if (skins.Count > 1) countInbuilt+=(skins.Count -1);
            }
            if (showLoadedSkinCounts && useInbuiltSkins) {
                Puts($"Loaded {countInbuilt} inbuilt skins");
                Interface.CallHook("OnSkinCacheUpdate", skinsCache);
            }
            if (useApprovedSkins) {
                int countApproved=0;
                foreach (var shopskin in Rust.Workshop.Approved.All.Where(skin=> skin.Skinnable.ItemName !=null)) {
                    if (!skinsCache.ContainsKey(shopskin.Skinnable.ItemName)) skinsCache[shopskin.Skinnable.ItemName]=new List<ulong>();
                    if (!skinsCache[shopskin.Skinnable.ItemName].Contains(shopskin.WorkshopdId)) {
                        skinsCache[shopskin.Skinnable.ItemName].Add(shopskin.WorkshopdId);
                        countApproved++;
                    }
                }
                if (showLoadedSkinCounts) Puts($"Loaded {countApproved} inbuilt approved Workshop 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[shortname].Contains(fileid)) {
                            skinsCache[shortname].Add(fileid);
                            countManual++;
                        }
                    }
                }
                if (showLoadedSkinCounts && countManual > 0) {
                    Puts($"Loaded {countManual} manual added skins");
                    Interface.CallHook("OnSkinCacheUpdate", skinsCache);
                }
            }
            skinsLoaded=true;
            if (useApprovedSkins) ServerMgr.Instance.StartCoroutine(GetAcceptedWorkshopSkins());
            else if (useWebskinsRankedByTrend) ServerMgr.Instance.StartCoroutine(GetRankedWorkshopSkins());
        }
        void RunQuery(Facepunch.Steamworks.Workshop.Query query) {
            FieldInfo Callback=typeof(Facepunch.Steamworks.Workshop.Query).GetField("Callback", (BindingFlags.Instance | BindingFlags.NonPublic));
            FieldInfo _resultSkip=typeof(Facepunch.Steamworks.Workshop.Query).GetField("_resultSkip", (BindingFlags.Instance | BindingFlags.NonPublic));
            FieldInfo _resultsRemain=typeof(Facepunch.Steamworks.Workshop.Query).GetField("_resultsRemain", (BindingFlags.Instance | BindingFlags.NonPublic));
            FieldInfo _resultPage=typeof(Facepunch.Steamworks.Workshop.Query).GetField("_resultPage", (BindingFlags.Instance | BindingFlags.NonPublic));
            FieldInfo _results=typeof(Facepunch.Steamworks.Workshop.Query).GetField("_results", (BindingFlags.Instance | BindingFlags.NonPublic));
            MethodInfo runInternal=typeof(Facepunch.Steamworks.Workshop.Query).GetMethod("RunInternal", BindingFlags.NonPublic | BindingFlags.Instance);
            bool flag=Callback.GetValue(query) !=null;
            if (!flag) {
                bool flag2=query.Page <=0;
                if (flag2) {
                    PrintWarning("Page should be 1 or above");
                    return;
                }
                int num=(query.Page - 1) * query.PerPage;
                query.TotalResults=0;
                _resultSkip.SetValue(query, num % 50);
                _resultsRemain.SetValue(query, query.PerPage);
                _resultPage.SetValue(query, (int)Math.Floor((double)((float)num / 50f)));
                _results.SetValue(query, new List<Workshop.Item>());
                runInternal.Invoke(query, null);
            }
        }
        public IEnumerator GetAcceptedWorkshopSkins(bool timed=false) {
            yield return new WaitForSeconds (2);
            var workshopQuery=Global.SteamServer.Workshop.CreateQuery();
            workshopQuery.Page=1;
            workshopQuery.PerPage=500;
            workshopQuery.RequireTags.Add("Version3");
            workshopQuery.RequireTags.Add("Skin");
            workshopQuery.RequireAllTags=true;
            workshopQuery.Order=Workshop.Order.AcceptedForGameRankedByAcceptanceDate;
            if (showLoadedSkinCounts && !timed) Puts($"Checking Workshop for new accepted skins");
            RunQuery(workshopQuery);
            yield return new WaitWhile(new System.Func<bool>(()=> workshopQuery.IsRunning));
            if (_unloaded) {
                workshopQuery.Dispose();
                workshopQuery=null;
                yield return null;
            }
            int countQueried=0;
            foreach (var item in workshopQuery.Items) {
                foreach (var tag in item.Tags.Where(t=> !t.Contains("Version") && !t.Contains("Skin"))) {
                    if (NameToItemName.ContainsKey(tag)) {
                        string shortname=NameToItemName[tag];
                        if (!skinsCache[shortname].Contains(item.Id)) {
                            skinsCache[shortname].Add(item.Id);
                            countQueried++;
                        }
                    }
                }
            }
            workshopQuery.Dispose();
            if (showLoadedSkinCounts && countQueried > 0) {
                Puts($"Loaded {countQueried} new accepted Workshop skins");
                Interface.CallHook("OnSkinCacheUpdate", skinsCache);
            }
            else if (showLoadedSkinCounts && countQueried==0 && !timed) Puts($"No recently accepted Workshop skins found");
            if (useWebskinsRankedByTrend) ServerMgr.Instance.StartCoroutine(GetRankedWorkshopSkins());
        }
        public IEnumerator GetRankedWorkshopSkins() {
            var workshopQuery=Global.SteamServer.Workshop.CreateQuery();
            workshopQuery.Page=1;
            workshopQuery.PerPage=50000;
            workshopQuery.RequireTags.Add("Version3");
            workshopQuery.RequireTags.Add("Skin");
            workshopQuery.RequireAllTags=true;
            workshopQuery.Order=Workshop.Order.RankedByTrend;
            workshopQuery.RankedByTrendDays=usedRankedByTrendDays;
            if (showLoadedSkinCounts) Puts($"Calling Workshop to fill up the SkinCache.This can take a few moments...");
            RunQuery(workshopQuery);
            yield return new WaitWhile(new System.Func<bool>(()=> workshopQuery.IsRunning));
            if (_unloaded) {
                workshopQuery.Dispose();
                yield break;
            }
            int countQueried=0;
            foreach (var item in workshopQuery.Items) {
                foreach (var tag in item.Tags.Where(t=> !t.Contains("Version") && !t.Contains("Skin"))) {
                    if (NameToItemName.ContainsKey(tag)) {
                        string shortname=NameToItemName[tag];
                        if (!skinsCache[shortname].Contains(item.Id) && skinsCache[shortname].Count < 31) {
                            skinsCache[shortname].Add(item.Id);
                            countQueried++;
                        }
                    }
                }
            }
            workshopQuery.Dispose();
            if (showLoadedSkinCounts && countQueried > 0) {
                Puts($"Filled up SkinCache with {countQueried} new Workshop skins");
                Interface.CallHook("OnSkinCacheUpdate", skinsCache);
            }
        }
        [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) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9-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) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9-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"]=manualAddedSkins;
                Config.Save();
                Puts($"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) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9-Digits");
                        continue;
                    }
                    fileIds.Add(fileId);
                }
            }
            ServerMgr.Instance.StartCoroutine(SearchWorkshopSkin(fileIds));
        }
        [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) {
                        SendReply(arg, $"Ignored '{arg.Args[i]}' as of not 9-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();
                Puts($"Removed {removed} FileId's");
            }
        }
        public IEnumerator SearchWorkshopSkin(List<ulong> fileIds) {
            var workshopQuery=Global.SteamServer.Workshop.CreateQuery();
            workshopQuery.Page=1;
            workshopQuery.PerPage=1;
            workshopQuery.RequireTags.Add("Version3");
            workshopQuery.FileId=new List<ulong>(fileIds);
            Puts($"Calling Workshop for '{fileIds.Count}' FileId's");
            RunQuery(workshopQuery);
            yield return new WaitWhile(new System.Func<bool>(()=> workshopQuery.IsRunning));
            bool doSave=false;
            foreach (var item in workshopQuery.Items) {
                bool matchedAny=false;
                foreach (var tag in item.Tags.Where(t=> !t.Contains("Version") && !t.Contains("Skin") && !t.Contains("Weapon") && !t.Contains("Playerwearable") && !t.Contains("Deployable"))) {
                    if (NameToItemName.ContainsKey(tag)) {
                        string shortname=NameToItemName[tag];
                        if (manualAddedSkins.ContainsKey(shortname)) {
                            if (manualAddedSkins[shortname].Contains(item.Id)) {
                                Puts($"The FileId '{item.Id}' was already added");
                                matchedAny=true;
                                continue;
                            }
                        }
                        if (skinsCache.ContainsKey(shortname)) if ((skinsCache[shortname] as List<ulong>).Contains(item.Id)) {
                            Puts($"The FileId '{item.Id}' belongs already to the default loaded skins");
                            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 List<ulong>());
                        skinsCache[shortname].Add(item.Id);
                        Puts($"Added '{item.Title}' to the manual skins list for '{shortname}'");
                        matchedAny=true;
                        doSave=true;
                    }
                }
                if (!matchedAny) Puts($"No matching item shortname found to assign the skin '{item.Id}'");
            }
            if (doSave) {
                Config["SkinsAdded", "SkinList"]=manualAddedSkins;
                Config.Save();
                Interface.CallHook("OnSkinCacheUpdate", skinsCache);
            }
            workshopQuery.Dispose();
        }
        void OnPlayerInit(BasePlayer player) {
            if (player==null) return;
            if(useKeyBindLogin) {
                player.Command($"bind {keyToBind} skinbox.open");
            }
            if (player==null || !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 List<ulong>).Count <=1) continue;
                foreach (var skin in (List<ulong>)skinCache.Value) {
                    if (skin==0) continue;
                    Item item=ItemManager.Create(ItemManager.FindItemDefinition(skinCache.Key), 1, skin);
                    if (item.info.category==ItemCategory.Attire && !forceAlsoWearables) {
                        item.Remove(0f);
                        continue;
                    }
                    if (item !=null) {
                        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 (!useKeyBindLogin) return;
            if(arg !=null && arg.Connection !=null && arg.Connection.player !=null) {
                BasePlayer player=arg.Player();
                if (player.inventory.loot.IsLooting()) return;
                if(!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)) {
                    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()) return;
            if(!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)) {
                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;
                    }
                }
            }
            timer.Once(0.1f, ()=> {
                OpenSkinBox(player);
            }
            );
        }
        Boolean CheckOpenBalance(BasePlayer player) {
            if (!activePointSystem || costBoxOpen <=0 || (player.IsAdmin && costExcludeAdmins)) return true;
            object getMoney=null;
            if (activeServerRewards) getMoney=ServerRewards?.Call("CheckPoints", player.userID);
            if (activeEconomics) getMoney=Economics?.CallHook("GetPlayerMoney", player.userID);
            int playerMoney=0;
            playerMoney=Convert.ToInt32(getMoney);
            if (playerMoney < costBoxOpen) {
                player.ChatMessage(string.Format(lang.GetMessage("NotEnoughBalanceOpen", this, player.UserIDString), costBoxOpen));
                return false;
            }
            if (activeServerRewards) ServerRewards?.Call("TakePoints", player.userID, costBoxOpen);
            if (activeEconomics) Economics?.CallHook("Withdraw", player.userID, Convert.ToDouble(costBoxOpen));
            return true;
        }
        Boolean CheckSkinBalance(BasePlayer player, Item item) {
            if (!activePointSystem) return true;
            object getMoney=null;
            if (activeServerRewards) getMoney=ServerRewards?.Call("CheckPoints", player.userID);
            if (activeEconomics) getMoney=Economics?.CallHook("GetPlayerMoney", player.userID);
            int playerMoney=0;
            playerMoney=Convert.ToInt32(getMoney);
            bool hasBalance=false;
            int getCost=0;
            switch (item.info.category.ToString()) {
                case "Weapon" : case "Tool" : if (costWeapon <=0 || playerMoney > costWeapon) hasBalance=true;
                getCost=costWeapon;
                break;
                case "Attire" : if (costPlayerwearable <=0 || playerMoney > costPlayerwearable) hasBalance=true;
                getCost=costPlayerwearable;
                break;
                case "Items" : case "Construction" : if (costDeployable <=0 || playerMoney > costDeployable) hasBalance=true;
                getCost=costDeployable;
                break;
                default : hasBalance=true;
                break;
            }
            if (!hasBalance) {
                player.ChatMessage(string.Format(lang.GetMessage("NotEnoughBalanceUse", this, player.UserIDString), getCost, item.info.displayName.translated));
                return false;
            }
            return true;
        }
        Boolean WithdrawBalance(BasePlayer player, Item item) {
            if (!activePointSystem) return true;
            int getCost=0;
            switch (item.info.category.ToString()) {
                case "Weapon" : case "Tool" : getCost=costWeapon;
                break;
                case "Attire" : getCost=costPlayerwearable;
                break;
                case "Items" : case "Construction" : getCost=costDeployable;
                break;
                default : break;
            }
            bool hadMoney=false;
            if (activeServerRewards && (bool)ServerRewards?.Call("TakePoints", player.userID, getCost)) hadMoney=true;
            if (activeEconomics && (bool)Economics?.CallHook("Withdraw", player.userID, Convert.ToDouble(getCost))) hadMoney=true;
            if (!hadMoney) {
                player.ChatMessage(string.Format(lang.GetMessage("NotEnoughBalanceTake", this, player.UserIDString), item.info.displayName.translated));
                return false;
            }
            return true;
        }
        sealed class SkinBoxHandler : MonoBehaviour {
            public bool isCreating;
            public bool isBlocked;
            public bool isCleaning;
            public bool isEmptied;
            public int itemId;
            public Item item;
            public BasePlayer looter;
            ItemContainer loot;
            public BaseEntity entityOwner;
            public ulong skinId;
            void Awake() {
                isCreating=false;
                isBlocked=false;
                isCleaning=false;
                isEmptied=false;
                loot=GetComponent<StorageContainer>().inventory;
                entityOwner=loot.entityOwner;
            }
            public void PlayerStoppedLooting(BasePlayer player) {
                skinBox.activeBoxUsers.Remove(player.userID);
                if (!isEmptied && item !=null) {
                    isEmptied=true;
                    player.GiveItem(item);
                }
                if (!GetComponent<BaseEntity>().IsDestroyed) GetComponent<BaseEntity>().Kill(BaseNetworkable.DestroyMode.None);
                if (skinBox.enableCooldown) skinBox.cooldownTimes[player.UserIDString+"-box"]=DateTime.UtcNow;
            }
            void OnDestroy() {
                skinBox.activeBoxUsers.Remove(looter.userID);
                if (!isEmptied && item!=null) {
                    isEmptied=true;
                    looter.GiveItem(item);
                }
                looter.EndLooting();
            }
        }
        Boolean CheckDistance(BasePlayer player) {
            var playerPos=player.transform.position;
            foreach (var id in activeBoxUsers) {
                if (Vector3.Distance(playerPos, id.Value) < boxUseDistance) {
                    player.ChatMessage(lang.GetMessage("ToNearPlayer", this, player.UserIDString));
                    return false;
                }
            }
            return true;
        }
        void OpenSkinBox(BasePlayer player) {
            var skinBox=GameManager.server.CreateEntity("assets/prefabs/deployable/large wood storage/box.wooden.large.prefab", player.transform.position - new Vector3(UnityEngine.Random.Range(-5f, 5f), 200, UnityEngine.Random.Range(-5f, 5f)));
            skinBox.UpdateNetworkGroup();
            skinBox.SendNetworkUpdateImmediate();
            skinBox.globalBroadcast=true;
            (skinBox as BaseNetworkable).limitNetworking=true;
            skinBox.Spawn();
            skinBox.gameObject.AddComponent<SkinBoxHandler>().looter=player;
            var container=skinBox.GetComponent<StorageContainer>();
            container.inventory.capacity=1;
            container.SetFlag(BaseEntity.Flags.Open, true, false);
            if (QuickSort && hideQuickSort) StartLootingEntity(player.inventory.loot, container);
            else player.inventory.loot.StartLootingEntity(container, false);
            player.inventory.loot.AddContainer(container.inventory);
            player.inventory.loot.SendImmediate();
            player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", container.panelName);
            container.DecayTouch();
            container.SendNetworkUpdate();
            activeBoxUsers[player.userID]=player.transform.position;
        }
        public void StartLootingEntity(PlayerLoot loot, BaseEntity targetEntity) {
            FieldInfo _PositionChecks=typeof(PlayerLoot).GetField("PositionChecks", (BindingFlags.Instance | BindingFlags.NonPublic));
            MethodInfo _MarkDirty=typeof(PlayerLoot).GetMethod("MarkDirty", BindingFlags.NonPublic | BindingFlags.Instance);
            loot.Clear();
            if (!targetEntity) return;
            _PositionChecks.SetValue(loot, false);
            loot.entitySource=targetEntity;
            loot.itemSource=null;
            _MarkDirty.Invoke(loot, null);
        }
        void ClearContainer(ItemContainer container) {
            while (container.itemList.Count > 0) {
                var item=container.itemList[0];
                item.RemoveFromContainer();
                item.Remove(0f);
            }
        }
        object CanAcceptItem(ItemContainer container, Item item) {
            if (container==null || item==null || container.entityOwner==null || container.entityOwner.GetComponent<SkinBoxHandler>()==null || container.entityOwner !=container.entityOwner.GetComponent<SkinBoxHandler>().entityOwner || container.entityOwner.GetComponent<SkinBoxHandler>().isCreating) return null;
            if (container.entityOwner.GetComponent<SkinBoxHandler>().isBlocked || (enableCustomPerms && !CheckItemPerms(container.entityOwner.GetComponent<SkinBoxHandler>().looter, item)) || item.amount > 1 || item.isBroken || !skinsCache.ContainsKey(item.info.shortname) || (skinsCache[item.info.shortname] as List <ulong>).Count <=1 || !CheckSkinBalance(container.entityOwner.GetComponent<SkinBoxHandler>().looter, item)) return ItemContainer.CanAcceptResult.CannotAccept;
            return null;
        }
        bool CheckItemPerms(BasePlayer player, Item item) {
            string category=item.info.category.ToString();
            switch (category) {
                case "Weapon" : if (permission.UserHasPermission(player.UserIDString, permCustomWeapon)) return true;
                break;
                case "Tool" : if (permission.UserHasPermission(player.UserIDString, permCustomWeapon)) return true;
                break;
                case "Attire" : if (permission.UserHasPermission(player.UserIDString, permCustomPlayerwearable)) return true;
                break;
                case "Items" : if (permission.UserHasPermission(player.UserIDString, permCustomDeployable)) return true;
                break;
                case "Construction" : if (permission.UserHasPermission(player.UserIDString, permCustomDeployable)) return true;
                break;
                default : return true;
            }
            return false;
        }
        void OnItemAddedToContainer(ItemContainer container, Item item) {
            if (container==null || item==null || container.entityOwner==null || container.entityOwner.GetComponent<SkinBoxHandler>()==null || container.entityOwner !=container.entityOwner.GetComponent<SkinBoxHandler>().entityOwner || container.entityOwner.GetComponent<SkinBoxHandler>().isCreating) return;
            var lootHandler=container.entityOwner.GetComponent<SkinBoxHandler>();
            lootHandler.isCreating=true;
            lootHandler.itemId=item.info.itemid;
            lootHandler.isEmptied=false;
            string shortname=item.info.shortname;
            bool hasCondition=item.hasCondition;
            float condition=item.condition;
            float maxCondition=item.maxCondition;
            bool isWeapon=item.GetHeldEntity() !=null && item.GetHeldEntity() is BaseProjectile;
            bool hasMods=false;
            int contents=0;
            int capacity=0;
            ItemDefinition ammoType=null;
            Dictionary <int, float>itemMods=new Dictionary <int, float>();
            List <ulong>itemSkins=skinsCache[shortname] as List <ulong>;
            if (isWeapon) {
                contents=(item.GetHeldEntity() as BaseProjectile).primaryMagazine.contents;
                capacity=(item.GetHeldEntity() as BaseProjectile).primaryMagazine.capacity;
                ammoType=(item.GetHeldEntity() as BaseProjectile).primaryMagazine.ammoType;
                if (item.contents !=null && item.contents.itemList.Count > 0) {
                    hasMods=true;
                    foreach (var mod in item.contents.itemList) itemMods.Add(mod.info.itemid, mod.condition);
                }
            }
            item.RemoveFromContainer();
            lootHandler.skinId=item.skin;
            lootHandler.item=item;
            container.capacity=itemSkins.Count();
            var itemDef=ItemManager.FindItemDefinition(shortname);
            foreach (var skin in itemSkins) {
                if (container.itemList.Count==30) break;
                if (excludedSkins.Contains(skin) && lootHandler.looter.net.connection.authLevel < exludedSkinsAuthLevel) continue;
                Item newItem=ItemManager.Create(itemDef, 1, skin);
                if (hasCondition) {
                    newItem.condition=condition;
                    newItem.maxCondition=maxCondition;
                }
                if (isWeapon) {
                    (newItem.GetHeldEntity() as BaseProjectile).primaryMagazine.contents=contents;
                    (newItem.GetHeldEntity() as BaseProjectile).primaryMagazine.capacity=capacity;
                    (newItem.GetHeldEntity() as BaseProjectile).primaryMagazine.ammoType=ammoType;
                    if (hasMods) {
                        foreach (var mod in itemMods) {
                            Item newMod=ItemManager.CreateByItemID((int)mod.Key, 1);
                            newMod.condition=Convert.ToSingle(mod.Value);
                            newMod.MoveToContainer(newItem.contents, -1, false);
                        }
                        newItem.contents.SetFlag(ItemContainer.Flag.IsLocked, true);
                        newItem.contents.SetFlag(ItemContainer.Flag.NoItemInput, true);
                    }
                }
                newItem.MoveToContainer(container, -1, false);
            }
            lootHandler.isCreating=false;
            lootHandler.isBlocked=true;
        }
        void OnItemRemovedFromContainer(ItemContainer container, Item item) {
            if (container==null || item==null || container.entityOwner==null || container.entityOwner.GetComponent<SkinBoxHandler>()==null || container.entityOwner !=container.entityOwner.GetComponent<SkinBoxHandler>().entityOwner || container.entityOwner.GetComponent<SkinBoxHandler>().isCreating || container.entityOwner.GetComponent<SkinBoxHandler>().isCleaning) return;
            var loothandler=container.entityOwner.GetComponent<SkinBoxHandler>();
            if (item.GetHeldEntity() !=null && item.GetHeldEntity() is BaseProjectile) {
                if (item.contents !=null) {
                    item.contents.SetF
// ... [Code preview truncated due to length. Full source in attached file] ...

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