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

FREE Skinner : 2.1.9 2.1.9

Нет прав для скачивания
C#:
/* Copyright (C) Whispers88 - All Rights Reserved
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * Proprietary and confidential
 * Written by Whispers88 rustafarian.server@gmail.com, Feb 2025
 * Version 2.1.8
 *
 *You may not copy, modify, merge, publish, distribute, sublicense, or sell copies of This Software without the Developer’s consent

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Pool;
using System.Text;
using Facepunch;
namespace Oxide.Plugins {
    [Info("Skinner", "Whispers88", "2.1.9")]
    [Description("Brings automation and ease to skinning items")]
    public class Skinner : CovalencePlugin {
        static Skinner skinner;
#region Perms
        private const string permdefault = "skinner.default";
        private const string permitems = "skinner.items";
        private const string permcraft = "skinner.craft";
        private const string permskininv = "skinner.skininv";
        private const string permskinteam = "skinner.skinteam";
        private const string permskinteamblock = "skinner.skinteamblock";
        private const string permskincon = "skinner.skincon";
        private const string permbypassauth = "skinner.bypassauth";
        private const string permimport = "skinner.import";
        private const string permskinbase = "skinner.skinbase";
        private const string permskinall = "skinner.skinall";
        private const string permskinauto = "skinner.skinauto";
        private const string permskinautotoggle = "skinner.skinautotoggled";
        private const string permskinrequest = "skinner.skinrequest";
        private const string permskintry = "skinner.permskintry";
        private List<string> permissions = new List<string>() {
            permdefault, permcraft, permitems, permbypassauth, permskincon, permskininv, permimport, permskinbase, permskinall, permskinteam, permskinteamblock, permskinrequest, permskintry, permskinauto, permskinautotoggle
        }
        ;
#endregion Perms
#region Init
        private void OnServerInitialized() {
            skinner = this;
            _skinNames = new Dictionary<ulong, string>();
            _cachedSkins = new Dictionary<int, List<ulong>>();
            _WaitForSecondsMore = CoroutineEx.waitForSeconds(1f);
            foreach (string perm in permissions) permission.RegisterPermission(perm, this);
            foreach (string perm in config.Cooldowns.Keys) permission.RegisterPermission($"skinner.{perm}", this);
            AddCovalenceCommand(config.cmdsskin, "SkinCMD");
            AddCovalenceCommand(config.cmdsskincraft, "DefaultSkinsCMD");
            AddCovalenceCommand(config.cmdsskinitems, "SkinItemCMD");
            AddCovalenceCommand(config.cmdsskininv, "SkinInvCMD");
            AddCovalenceCommand(config.cmdsskincon, "SkinConCMD");
            AddCovalenceCommand(config.cmdtoggleautoskin, "SkinAutoCMD");
            AddCovalenceCommand(config.cmdskinimport, "SkinImportCMD");
            AddCovalenceCommand(config.cmdcollectionimport, "SkinImportCollection");
            AddCovalenceCommand(config.cmdskinbase, "SkinBaseCMD");
            AddCovalenceCommand(config.cmdskinallitems, "SkinAllItemsCMD");
            AddCovalenceCommand(config.cmdskinteam, "SkinTeamCMD");
            AddCovalenceCommand(config.cmdskinrequest, "SkinRequestCMD");
            List<string> tempList = new List<string>(config.cmdskinset);
            tempList.Add("setSelectCMD");
            AddCovalenceCommand(tempList.ToArray(), "SetSelectCMD");
            AddCovalenceCommand(config.cmdskinrequests, "SkinRequestsCMD");
            AddCovalenceCommand(new[] {
                "sbNextPage"
            }
            , "SBNextPageCMD");
            AddCovalenceCommand(new[] {
                "sbBackPage"
            }
            , "SBBackPageCMD");
            AddCovalenceCommand(new[] {
                "searchCMD"
            }
            , "SearchCMD");
            AddCovalenceCommand(new[] {
                "requestSelectCMD"
            }
            , "RequestSelectCMD");
            foreach (var skin in config.ImportedSkinList) {
                if (!string.IsNullOrEmpty(skin.Value.itemDisplayname) && !string.IsNullOrEmpty(skin.Value.itemShortname)) continue;
                if (_WorkshopSkinIDCollectionList.Contains(skin.Key.ToString())) continue;
                _WorkshopSkinIDCollectionList.Add(skin.Key.ToString());
            }
            if (!config.sprayCanOveride) Unsubscribe("OnActiveItemChanged");
            if (!config.useOnItemCraft) Unsubscribe("OnItemCraftFinished");
            //InitUI
            InitUI();
            if (getCollectionscouroutine != null) {
                Puts("getcollections already running!!");
            }
            else {
                getCollectionscouroutine = GetCollectionSkinIDS();
                ServerMgr.Instance.StartCoroutine(getCollectionscouroutine);
            }
        }
        private void Loaded() {
            _defaultSkins = Interface.Oxide.DataFileSystem.GetFile("Skinner/DefaultCraftSkins");
            _playerData = Interface.Oxide.DataFileSystem.GetFile("Skinner/PlayerUsageData");
            _skinRequestsData = Interface.Oxide.DataFileSystem.GetFile("Skinner/SkinsRequestData");
            LoadData();
        }
        private void Unload() {
            if (getCollectionscouroutine != null) ServerMgr.Instance.StopCoroutine(getCollectionscouroutine);
            if (getSteamWorkshopSkinData != null) ServerMgr.Instance.StopCoroutine(getSteamWorkshopSkinData);
            if (getSteamWorkshopRequestData != null) ServerMgr.Instance.StopCoroutine(getSteamWorkshopRequestData);
            if (notifyDiscordCoroutine != null) ServerMgr.Instance.StopCoroutine(notifyDiscordCoroutine);
            foreach (var player in BasePlayer.allPlayerList) {
                UI.DestroyUI(player, BSkinPageUI);
                UI.DestroyUI(player, BSkinSearchUI);
                UI.DestroyUI(player, BSkinSetsSelectUI);
                UI.DestroyUI(player, BSkinRequestsUI);
                if (_playerUsageData.TryGetValue(player.userID, out PlayerData playerData)) playerData.UpdateLastOnline();
            }
            foreach (var player in BasePlayer.allPlayerList) {
                if (player.TryGetComponent<BoxController>(out BoxController boxController)) {
                    UnityEngine.Object.Destroy(boxController);
                }
                if (player.TryGetComponent<InventoryWatcher>(out InventoryWatcher inventoryWatcher)) {
                    UnityEngine.Object.Destroy(inventoryWatcher);
                }
                if (player.TryGetComponent<SpraycanController>(out SpraycanController spraycanController)) {
                    UnityEngine.Object.Destroy(spraycanController);
                }
            }
            SaveData();
            skinner = null;
            _WaitForSecondsMore = null;
        }
        public static Dictionary<ulong, string>? _skinNames;
        public static Dictionary<int, List<ulong>>? _cachedSkins;
        private static ulong maskID = (ulong)1 << 63;
        private static ulong maskID2 = 18860;
        private ulong SetMask(ulong num) {
            return num | maskID;
        }
        private ulong Get2Unmasked(ulong num) {
            return num & ~maskID2;
        }
        public static ulong GetMask(ulong skinID, int itemID, bool redirectSkin = false) {
            return redirectSkin ? (ulong)itemID | maskID : skinID;
        }
        public static bool HasMask(ulong uID) {
            return (uID & maskID) == maskID;
        }
        public static ulong UnsetMask(ulong num) {
            return num & ~maskID;
        }
        private void AddSkin(ulong skinID, int itemID, string displayName, int redirectID = -1) {
            if (config.blacklistedskins.Contains(skinID) || config.blacklisteditems.Contains(itemID) || config.blacklisteditems.Contains(redirectID)) return;
            if (!_cachedSkins.TryGetValue(itemID, out List<ulong> skinsList)) {
                skinsList = new List<ulong>() {
                    0ul
                }
                ;
                _cachedSkins[itemID] = skinsList;
            }
            ulong uID = GetMask(skinID, redirectID, redirectID != -1);
            if (!skinsList.Contains(uID)) skinsList.Add(uID);
            _skinNames[uID] = displayName;
        }
        private int totskins = 0;
        private void GetSkins() {
            if ((Steamworks.SteamInventory.Definitions?.Length ?? 0) == 0) {
                Puts("Waiting for Steamworks to update skin item definitions");
                Steamworks.SteamInventory.OnDefinitionsUpdated += GetSkins;
                return;
            }
            int sk = 0;
            Puts("Steamworks Updated, Updating Skins");
            Steamworks.SteamInventory.OnDefinitionsUpdated -= GetSkins;
            Dictionary<int, ItemCategory> catDefinitions = new Dictionary<int, ItemCategory>();
            foreach (ItemDefinition itemDef in ItemManager.GetItemDefinitions()) {
                if (!catDefinitions.ContainsKey(itemDef.itemid)) {
                    catDefinitions.Add(itemDef.itemid, itemDef.category);
                }
                if (!config.autoImportApproved) break;
                if (itemDef.isRedirectOf != null) {
                    AddSkin(0ul, itemDef.isRedirectOf.itemid, string.Empty, itemDef.itemid);
                    continue;
                }
                foreach (var skin in ItemSkinDirectory.ForItem(itemDef)) {
                    if (skin.id == 0) continue;
                    ItemSkin itemSkin = skin.invItem as ItemSkin;
                    if (itemSkin == null) continue;
                    bool isredirect = itemSkin?.Redirect != null;
                    if (isredirect) AddSkin((ulong)skin.id, itemDef.itemid, skin.invItem?.displayName?.english ?? itemDef.displayName.english, itemSkin.itemDefinition.itemid);
                    else AddSkin((ulong)skin.id, itemDef.itemid, skin.invItem?.displayName?.english ?? itemDef.displayName.english);
                }
            }
            foreach (Steamworks.InventoryDef item in Steamworks.SteamInventory.Definitions) {
                if (!config.autoImportApproved) break;
                string shortname = item.GetProperty("itemshortname") == "lr300.item" ? "rifle.lr300" : item.GetProperty("itemshortname");
                if (string.IsNullOrEmpty(shortname) || item.Id < 100) continue;
                ulong skinid;
                if (!ulong.TryParse(item.GetProperty("workshopid"), out skinid)) {
                    skinid = (ulong)item.Id;
                }
                if (skinid < 1000000) continue;
                ItemDefinition steamitemdef = ItemManager.FindItemDefinition(shortname);
                if (steamitemdef == null) continue;
                if (_cachedSkins.TryGetValue(steamitemdef.itemid, out List<ulong> cachedskinsList)) {
                    if (cachedskinsList.Contains((ulong)item.Id)) continue;
                }
                if (steamitemdef.isRedirectOf != null) AddSkin(skinid, steamitemdef.isRedirectOf.itemid, item.Name, steamitemdef.itemid);
                else AddSkin(skinid, steamitemdef.itemid, item.Name);
            }
            UpdateImportedSkins();
            List<int> skincachekeys = Pool.Get<List<int>>();
            skincachekeys.AddRange(new List<int>(_cachedSkins.Keys));
            for (int i = skincachekeys.Count - 1; i >= 0; i--) {
                var item2 = _cachedSkins[skincachekeys[i]];
                if (item2.Count == 1) {
                    _cachedSkins.Remove(skincachekeys[i]);
                    continue;
                }
                ItemDefinition itemdef = ItemManager.FindItemDefinition(skincachekeys[i]);
                if (itemdef?.Blueprint == null) {
                    _cachedSkins.Remove(skincachekeys[i]);
                    continue;
                }
                sk += item2.Count;
            }
            Pool.FreeUnmanaged(ref skincachekeys);
            SaveConfig();
            //Re-order to look nice
            List<KeyValuePair<int, List<ulong>>> tempList = new List<KeyValuePair<int, List<ulong>>>(_cachedSkins);
            tempList.Sort((pair1, pair2) => catDefinitions[pair1.Key].CompareTo(catDefinitions[pair2.Key]));
            _cachedSkins.Clear();
            foreach (KeyValuePair<int, List<ulong>> pair in tempList) {
                _cachedSkins.Add(pair.Key, pair.Value);
            }
            _cachedSkinKeys = new List<int>(_cachedSkins.Keys);
            Interface.CallHook("OnSkinnerCacheUpdated", _cachedSkins);
            Puts($"{sk} skins were indexed, Skin indexing complete");
        }
        public static List<int>? _cachedSkinKeys;
        private void UpdateImportedSkins() {
            List<ulong> keys = Pool.Get<List<ulong>>();
            keys.AddRange(new List<ulong>(config.ImportedSkinList.Keys));
            for (int i = config.ImportedSkinList.Count - 1; i >= 0; i--) {
                var whitelistSkin = config.ImportedSkinList[keys[i]];
                if (string.IsNullOrEmpty(whitelistSkin.itemDisplayname) || string.IsNullOrEmpty(whitelistSkin.itemShortname)) {
                    config.ImportedSkinList.Remove(keys[i]);
                    continue;
                }
                ItemDefinition itemdef = ItemManager.FindItemDefinition(whitelistSkin.itemShortname);
                if (itemdef == null) {
                    config.ImportedSkinList.Remove(keys[i]);
                    Puts($"Could not find item definition for {whitelistSkin.itemShortname} {keys[i]}");
                    continue;
                }
                AddSkin(keys[i], itemdef.itemid, whitelistSkin.itemDisplayname);
            }
            Pool.FreeUnmanaged(ref keys);
        }
#endregion Init
#region Configuration
        private Configuration config;
        public class Configuration {
            [JsonProperty("Skin Commands (skin items in you inventory")]
            public string[] cmdsskin = new[] {
                "skin", "s", "skinbox", "sb"
            }
            ;
            [JsonProperty("Skin Items Commands (skin items you have already placed")]
            public string[] cmdsskinitems = new[] {
                "skinitem", "si", "skindeployed", "sd"
            }
            ;
            [JsonProperty("Set default items to be skinned")]
            public string[] cmdsskincraft = new[] {
                "skincraft", "sc"
            }
            ;
            [JsonProperty("Automatically set all items in you inventory to your default skins")]
            public string[] cmdsskininv = new[] {
                "skininv", "sinv"
            }
            ;
            [JsonProperty("Automatically set all items a container to your default skins")]
            public string[] cmdsskincon = new[] {
                "skincon", "scon"
            }
            ;
            [JsonProperty("Automatically skin all deployables in your base")]
            public string[] cmdskinbase = new[] {
                "skinbase", "skinbuilding"
            }
            ;
            [JsonProperty("Automatically skin all items in your base")]
            public string[] cmdskinallitems = new[] {
                "skinall", "sa"
            }
            ;
            [JsonProperty("Automatically skin all items that are moved into you inventory")]
            public string[] cmdtoggleautoskin = new[] {
                "skinauto", "sauto"
            }
            ;
            [JsonProperty("Skin your teams inventories with your skin set")]
            public string[] cmdskinteam = new[] {
                "skinteam", "st"
            }
            ;
            [JsonProperty("Request workshop skins via workshop ID")]
            public string[] cmdskinrequest = new[] {
                "skinrequest", "sr"
            }
            ;
            [JsonProperty("Approve workshop skin requests")]
            public string[] cmdskinrequests = new[] {
                "skinrequests", "srs"
            }
            ;
            [JsonProperty("Set your selected skin set")]
            public string[] cmdskinset = new[] {
                "skinset", "ss"
            }
            ;
            [JsonProperty("Import Custom Skins")]
            public string[] cmdskinimport = new[] {
                "skinimport", "sip"
            }
            ;
            [JsonProperty("Import Workshop Collection Command")]
            public string[] cmdcollectionimport = new[] {
                "colimport", "cip"
            }
            ;
            [JsonProperty("Skin Request Notification Discord Webhook")]
            public string DiscordWebhook = "";
            [JsonProperty("Custom Page Change UI Positon anchor/offset 'min x, min y', 'max x', max y'")]
            public string[] uiposition = new[] {
                "0.5 0.0", "0.5 0.0", "198 60", "400 97"
            }
            ;
            [JsonProperty("Custom Searchbar UI Positon anchor/offset 'min x, min y', 'max x', max y'")]
            public string[] uisearchposition = new[] {
                "0.5 0.0", "0.5 0.0", "410 635", "572 660"
            }
            ;
            [JsonProperty("Custom Set Selection UI Positon anchor/offset 'min x, min y', 'max x', max y'")]
            public string[] uisetsposition = new[] {
                "0.5 0.0", "0.5 0.0", "250 610", "573 633"
            }
            ;
            [JsonProperty("Auto import approved skins")]
            public bool autoImportApproved = true;
            [JsonProperty("Remove player data after inactivity (days)")]
            public int removedataTime = 14;
            [JsonProperty("Apply names of skins to skinned items")]
            public bool applySkinNames = true;
            [JsonProperty("Add Search Bar UI")]
            public bool searchbar = true;
            [JsonProperty("Use on itemcraft hook (skin items after crafting - not required when using skinauto)")]
            public bool useOnItemCraft = false;
            [JsonProperty("Override spraycan behaviour")]
            public bool sprayCanOveride = false;
            [JsonProperty("Use spraycan effect when holding spraycan and skinning deployables")]
            public bool sprayCanEffect = true;
            [JsonProperty("Blacklisted Skins (skinID)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ulong> blacklistedskins = new List<ulong>();
            [JsonProperty("Blacklisted Items (itemID)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<int> blacklisteditems = new List<int>();
            [JsonProperty("Import Skin collections (steam workshop ID)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ulong> skinCollectionIDs = new List<ulong>();
            [JsonProperty("Command based cooldowns ('permission' : 'command' seconds")]
            public Dictionary<string, CoolDowns> Cooldowns = new Dictionary<string, CoolDowns>() {
                {
                    "Default30CD", new CoolDowns()
                }
            }
            ;
            [JsonProperty("Imported Skins List", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, ImportedItem> ImportedSkinList = new Dictionary<ulong, ImportedItem>();
            public string ToJson() => JsonConvert.SerializeObject(this);
            public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
        }
        public struct ImportedItem {
            public string itemShortname;
            public string itemDisplayname;
        }
        public struct RequestItem {
            public ulong skinID;
            public int itemID;
            public string itemDisplayname;
        }
        protected override void LoadDefaultConfig() => config = new Configuration();
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) {
                    throw new JsonException();
                }
                var configDict = config.ToDictionary();
                Dictionary<string, object> defaultconObjects = new Dictionary<string, object>();
                foreach (var obj in Config) {
                    defaultconObjects.Add(obj.Key, obj.Value);
                }
                if (configDict.Count != defaultconObjects.Count) {
                    Puts("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
                else {
                    foreach (var key in configDict.Keys) {
                        if (defaultconObjects.ContainsKey(key)) continue;
                        Puts("Configuration appears to be outdated; updating and saving");
                        SaveConfig();
                        break;
                    }
                }
            }
            catch {
                Puts($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
        }
        protected override void SaveConfig() {
            Puts($"Configuration changes saved to {Name}.json");
            Config.WriteObject(config, true);
        }
#endregion Configuration
#region Data
        private DynamicConfigFile _defaultSkins;
        private DynamicConfigFile _playerData;
        private DynamicConfigFile _skinRequestsData;
        private Dictionary<ulong, CoolDowns> _playercooldowns = new Dictionary<ulong, CoolDowns>();
        private Dictionary<ulong, int> _playerSelectedSet = new Dictionary<ulong, int>();
        private void LoadData() {
            List<ulong> skipdata = Pool.Get<List<ulong>>();
            try {
                _playerUsageData = new Dictionary<ulong, PlayerData>();
                long timenow = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
                //need to read as dec and parse to ulong
                var temp = _playerData.ReadObject<Dictionary<ulong, PlayerDataDec>>();
                foreach (var pair in temp) {
                    //Not logged in for two weeks
                    if (timenow - pair.Value.lastonline > config.removedataTime * 86400) {
                        skipdata.Add(pair.Key);
                        continue;
                    }
                    _playerUsageData.Add(pair.Key, new PlayerData() {
                        lastonline = pair.Value.lastonline
                    }
                    );
                    foreach (var innerDict in pair.Value.skinusage) {
                        List<ulong> ulongList = new List<ulong>();
                        foreach (decimal d in innerDict.Value) {
                            ulong id = decimal.ToUInt64(d);
                            if (HasMask(id) && config.blacklisteditems.Contains((int)UnsetMask(id))) continue;
                            ulongList.Add(decimal.ToUInt64(d));
                        }
                        _playerUsageData[pair.Key].skinusage.TryAdd(innerDict.Key, ulongList);
                    }
                }
            }
            catch {
                _playerUsageData = new Dictionary<ulong, PlayerData>();
            }
            try {
                _playerDefaultSkins = new Dictionary<ulong, Dictionary<int, ulong>[]>();
                //need to read as dec and parse to ulong
                var temp = _defaultSkins.ReadObject<Dictionary<ulong, Dictionary<int, decimal>[]>>();
                foreach (var outerPair in temp) {
                    if (skipdata.Contains(outerPair.Key)) continue;
                    var innerDictArray = new Dictionary<int, ulong>[outerPair.Value.Length];
                    for (int i = 0; i < outerPair.Value.Length; i++) {
                        var innerDict = new Dictionary<int, ulong>();
                        foreach (var innerPair in outerPair.Value[i]) {
                            if (HasMask((ulong)innerPair.Value) && config.blacklisteditems.Contains((int)UnsetMask((ulong)innerPair.Value))) continue;
                            innerDict.Add(innerPair.Key, (ulong)innerPair.Value);
                        }
                        innerDictArray[i] = innerDict;
                    }
                    _playerDefaultSkins.Add(outerPair.Key, innerDictArray);
                }
            }
            catch {
                _playerDefaultSkins = new Dictionary<ulong, Dictionary<int, ulong>[]>();
            }
            try {
                _requestsData = _skinRequestsData.ReadObject<List<RequestItem>>();
            }
            catch {
                _requestsData = new List<RequestItem>();
            }
            Pool.FreeUnmanaged(ref skipdata);
        }
        private void SaveData() {
            Puts("DataSaved");
            _defaultSkins.WriteObject(_playerDefaultSkins);
            _playerData.WriteObject(_playerUsageData);
            _skinRequestsData.WriteObject(_requestsData);
        }
        private Dictionary<ulong, Dictionary<int, ulong>[]> _playerDefaultSkins;
        private Dictionary<ulong, PlayerData> _playerUsageData;
        private List<RequestItem> _requestsData;
        public class PlayerDataDec {
            public Dictionary<int, List<decimal>> skinusage = new Dictionary<int, List<decimal>>();
            public long lastonline {
                get;
                set;
            }
            = 0;
        }
        public class PlayerData {
            public Dictionary<int, List<ulong>> skinusage = new Dictionary<int, List<ulong>>();
            public long lastonline {
                get;
                set;
            }
            = 0;
            public void AddSkinUsage(ulong skinID, int itemID, int rItemID = 0) {
                if (skinID == 0 && rItemID == 0) return;
                if (!skinusage.TryGetValue(itemID, out var list)) {
                    list = new List<ulong>(6);
                    skinusage[itemID] = list;
                }
                ulong uID = GetMask(skinID, rItemID, rItemID != 0);
                for (int i = list.Count - 1; i >= 0; i--) {
                    if (list[i] != uID) continue;
                    list.RemoveAt(i);
                }
                if (list.Count >= 6) {
                    list.RemoveAt(0);
                }
                list.Add(uID);
            }
            public List<ulong>? GetSkinUsage(int itemID) {
                if (!skinusage.TryGetValue(itemID, out List<ulong>? usageList)) {
                    return null;
                }
                return usageList;
            }
            public void UpdateLastOnline() {
                lastonline = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            }
        }
        public class CoolDowns {
            public float skin = 30f;
            public float skinitem = 30f;
            public float skincraft = 30f;
            public float skincon = 30f;
            public float skininv = 30f;
            public float skinteam = 30f;
            public float skinbase = 60f;
            public float skinall = 60f;
        }
#endregion Data
#region Localization
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["NoPerms"]
                = "You don't have permissions to use this command", ["NoBuildingAuth"] = "You must have building auth to use this", ["NoObjectsFound"] = "No object found", ["NoSkins"] = "No skins available", ["ImportSkinArgs"] = "Bad args, Required input skinid", ["ImportCollectionArgs"] = "Bad args, Required input collectionID", ["SkinIDError"] = "Cannot parse skinid {0}", ["NoShortname"] = "No item found for shortname : {0}", ["DuplicateSkin"] = "Duplicate Skin ID for : {0} {1}", ["SkinImported2"] = "Skin {0} has been imported and saved", ["SkinRequested"] = "Skin {0} has been requested", ["AlreadyRequesting"] = "Already updating requests data please wait...", ["RequestingData"] = "Updating requests data please wait...", ["CollectionImported2"] = "Steam Skin Collection {0} has been imported and saved", ["CommandCooldown"] = "You can not use this command for another {0}", ["CompletedInvSkin"] = "All items in your inventory have been set to your default skins", ["CompletedConSkin"] = "All items in {0} have been set to your default skins", ["CompletedBuildingSkin"] = "All {0} in your base have been set to your default skins", ["CompletedAllSkin"] = "All {0} items in your base have been set to your default skins", ["SkinSetSelected"] = "Skin set {0} selected", ["SkinSetSelectedArgs"] = "Bad args, Required input set No.1, 2 or 3", ["AutoSkinEnabled"] = "Auto skins enabled", ["AutoSkinDisabled"] = "Auto skins disabled", ["CompletedTeamSkin"] = "All items in your team have been set skin set {0}", ["NoTeam"] = "You need to be in a team to use this feature", ["TeamSkinBlockEnabled"] = "You enabled team skins", ["TeamSkinBlockDisabled"] = "You disabled team skins"
            }
            , this);
        }
#endregion Localization
#region Commands
        private void SkinAutoCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer? player = iplayer.Object as BasePlayer;
            if (player == null) return;
            if (!HasPerm(player.UserIDString, permskinauto)) {
                ChatMessage(iplayer, "NoPerms");
                return;
            }
            if (!player.TryGetComponent<InventoryWatcher>(out InventoryWatcher inventoryWatcher)) {
                player.gameObject.AddComponent<InventoryWatcher>();
                ChatMessage(iplayer, "AutoSkinEnabled");
                permission.GrantUserPermission(player.UserIDString, permskinautotoggle, this);
                return;
            }
            permission.RevokeUserPermission(player.UserIDString, permskinautotoggle);
            UnityEngine.Object.Destroy(inventoryWatcher);
            ChatMessage(iplayer, "AutoSkinDisabled");
        }
        private void SkinImportCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer? player = iplayer.Object as BasePlayer;
            if (player != null) {
                if (!HasPerm(player.UserIDString, permimport)) {
                    ChatMessage(iplayer, "NoPerms");
                    return;
                }
            }
            else if (!iplayer.IsServer) return;
            if (args.Length < 1) {
                ChatMessage(iplayer, "ImportSkinArgs");
                return;
            }
            ulong skinid = 0ul;
            if (!ulong.TryParse(args[0], out skinid)) {
                ChatMessage(iplayer, "ImportSkinArgs", args[0]);
                return;
            }
            _WorkshopSkinIDCollectionList.Add(skinid.ToString());
            if (getSteamWorkshopSkinData != null) {
                Puts("getSteamWorkshopSkinData already running!!");
            }
            else {
                getSteamWorkshopSkinData = GetSteamWorkshopSkinData();
                ServerMgr.Instance.StartCoroutine(getSteamWorkshopSkinData);
            }
            ChatMessage(iplayer, "SkinImported2", args[0]);
        }
        private void SkinImportCollection(IPlayer iplayer, string command, string[] args) {
            BasePlayer player = iplayer.Object as BasePlayer;
            if (player != null) {
                if (!HasPerm(player.UserIDString, permimport)) {
                    ChatMessage(iplayer, "NoPerms");
                    return;
                }
            }
            else if (!iplayer.IsServer) return;
            if (args.Length < 1) {
                ChatMessage(iplayer, "ImportCollectionArgs");
                return;
            }
            ulong collectionid = 0ul;
            if (!ulong.TryParse(args[0], out collectionid)) {
                ChatMessage(iplayer, "ImportCollectionArgs", args[0]);
                return;
            }
            config.skinCollectionIDs.Add(collectionid);
            if (getCollectionscouroutine != null) {
                Puts("getcollections already running!!");
            }
            else {
                getCollectionscouroutine = GetCollectionSkinIDS();
                ServerMgr.Instance.StartCoroutine(getCollectionscouroutine);
            }
            ChatMessage(iplayer, "CollectionImported2", args[0]);
        }
        private void SkinCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer player = iplayer.Object as BasePlayer;
            if (player == null) return;
            if (!HasPerm(player.UserIDString, permdefault)) {
                ChatMessage(iplayer, "NoPerms");
                return;
            }
            if (_viewingcon.TryGetValue(player.userID, out BoxController? boxController)) {
                if (boxController != null) UnityEngine.Object.Destroy(boxController);
                _viewingcon.Remove(player.userID);
                return;
            }
            //Check for cooldown
            float cdtime = 0;
            //Find shortest cd perm
            foreach (var cdperm in config.Cooldowns) {
                if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
                if (cdtime == 0) cdtime = cdperm.Value.skin;
                else if (cdtime > cdperm.Value.skin) cdtime = cdperm.Value.skin;
            }
            if (cdtime > 0) {
                if (!_playercooldowns.TryGetValue(player.userID, out CoolDowns? coolDowns)) _playercooldowns.Add(player.userID, new CoolDowns() {
                    skin = Time.time
                }
                );
                else {
                    if (coolDowns.skin + cdtime > Time.time) {
                        ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skin + cdtime - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
                        return;
                    }
                    coolDowns.skin = Time.time;
                }
            }
            ItemContainer itemContainer = CreateContainer();
            if (itemContainer == null) return;
            boxController = player.gameObject.AddComponent<BoxController>();
            boxController.inventory = itemContainer;
            boxController.StartAwake();
            boxController.StartItemSkin();
            _viewingcon.Add(player.userID, boxController);
            player.Invoke(() => StartLooting(player, itemContainer), 0.3f);
        }
        private void DefaultSkinsCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer player = iplayer.Object as BasePlayer;
            if (player == null) return;
            if (!HasPerm(player.UserIDString, permcraft)) {
                ChatMessage(iplayer, "NoPerms");
                return;
            }
            if (_viewingcon.TryGetValue(player.userID, out BoxController? boxController)) {
                if (boxController != null) UnityEngine.Object.Destroy(boxController);
                _viewingcon.Remove(player.userID);
                return;
            }
            //Check for cooldown
            float cdtime = 0;
            //Find shortest cd perm
            foreach (var cdperm in config.Cooldowns) {
                if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
                if (cdtime == 0) cdtime = cdperm.Value.skincraft;
                else if (cdtime > cdperm.Value.skincraft) cdtime = cdperm.Value.skincraft;
            }
            if (cdtime > 0) {
                if (!_playercooldowns.TryGetValue(player.userID, out CoolDowns? coolDowns)) _playercooldowns.Add(player.userID, new CoolDowns() {
                    skincraft = Time.time
                }
                );
                else {
                    if (coolDowns.skincraft + cdtime > Time.time) {
                        ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skincraft + cdtime - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
                        return;
                    }
                    coolDowns.skincraft = Time.time;
                }
            }
            if (!_playerDefaultSkins.ContainsKey(player.userID)) _playerDefaultSkins.Add(player.userID, new Dictionary<int, ulong>[3] {
                new Dictionary<int, ulong>(), new Dictionary<int, ulong>(), new Dictionary<int, ulong>()
            }
            );
            ItemContainer itemContainer = CreateContainer();
            boxController = player.gameObject.AddComponent<BoxController>();
            boxController.inventory = itemContainer;
            boxController.StartAwake();
            boxController.SkinCraft();
            _viewingcon.TryAdd(player.userID, boxController);
            player.Invoke(() => StartLooting(player, itemContainer), 0.3f);
        }
        private void SkinRequestCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer player = iplayer.Object as BasePlayer;
            if (player == null) return;
            if (!HasPerm(player.UserIDString, permskinrequest)) {
                ChatMessage(iplayer, "NoPerms");
                return;
            }
            if (args.Length < 1) {
                ChatMessage(iplayer, "ImportSkinArgs");
                return;
            }
            if (!ulong.TryParse(args[0], out ulong skinidResult)) {
                ChatMessage(iplayer, "ImportSkinArgs");
                return;
            }
            ChatMessage(iplayer, "SkinRequested", skinidResult);
            foreach (var a in _requestsData) {
                if (a.skinID == skinidResult) return;
            }
            _requestsData.Add(new RequestItem {
                skinID = skinidResult
            }
            );
            if (string.IsNullOrEmpty(config.DiscordWebhook)) return;
            _discordData.Add(new DiscordData() {
                SkinID = skinidResult, player = player
            }
            );
            if (notifyDiscordCoroutine != null) {
                Puts("getcollections already running!!");
            }
            else {
                notifyDiscordCoroutine = NotifyDiscord();
                ServerMgr.Instance.StartCoroutine(notifyDiscordCoroutine);
            }
        }
        private void SkinRequestsCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer player = iplayer.Object as BasePlayer;
            if (player == null) return;
            if (!HasPerm(player.UserIDString, permimport)) {
                ChatMessage(iplayer, "NoPerms");
                return;
            }
            if (_requestsData.Count == 0) {
                ChatMessage(iplayer, "NoRequests");
                return;
            }
            if (getSteamWorkshopRequestData != null) {
                ChatMessage(iplayer, "AlreadyRequesting");
                return;
            }
            else {
                ChatMessage(iplayer, "RequestingData");
                getSteamWorkshopRequestData = GetSteamWorkshopSkinRequests();
                ServerMgr.Instance.StartCoroutine(getSteamWorkshopRequestData);
            }
            if (_viewingcon.TryGetValue(player.userID, out BoxController? boxController)) {
                if (boxController != null) UnityEngine.Object.Destroy(boxController);
                _viewingcon.Remove(player.userID);
                return;
            }
            ItemContainer itemContainer = CreateContainer();
            boxController = player.gameObject.AddComponent<BoxController>();
            boxController.inventory = itemContainer;
            boxController.StartAwake();
            _viewingcon.TryAdd(player.userID, boxController);
            player.StartCoroutine(CheckforRequests(player, itemContainer, boxController));
        }
        private static WaitForSeconds _WaitForSecondsMore;
        private IEnumerator CheckforRequests(BasePlayer player, ItemContainer itemContainer, BoxController boxController) {
            yield return _WaitForSecondsMore;
            int i = 0;
            for (i = 0; i < 15; i++) {
                if (getSteamWorkshopRequestData == null) break;
                ChatMessage(player.IPlayer, "Updating requests data please wait...");
                yield return _WaitForSecondsMore;
            }
            if (i >= 15) {
                ChatMessage(player.IPlayer, "Updating requests timed out try again later");
                UnityEngine.Object.Destroy(boxController);
            }
            else {
                boxController.SkinRequests();
                StartLooting(player, itemContainer);
            }
        }
        private static int Layermask = LayerMask.GetMask("Deployed", "Construction");
        private void SkinItemCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer player = iplayer.Object as BasePlayer;
            if (player == null) return;
            if (!HasPerm(player.UserIDString, permitems)) {
                ChatMessage(iplayer, "NoPerms");
                return;
            }
            if (player.inventory.loot.IsLooting()) {
                player.EndLooting();
                return;
            }
            if (!player.CanBuild() && !HasPerm(player.UserIDString, permbypassauth)) {
                ChatMessage(iplayer, "NoBuildingAuth");
                return;
            }
            RaycastHit raycastHit;
            if (!Physics.Raycast(player.eyes.HeadRay(), out raycastHit, 5f, Layermask)) {
                ChatMessage(iplayer, "NoObjectsFound");
                return;
            }
            BaseCombatEntity entity = raycastHit.GetEntity() as BaseCombatEntity;
            ItemDefinition? itemDefinition = null;
            if (entity.pickup.itemTarget != null) {
                itemDefinition = entity.pickup.itemTarget;
            }
            else if (entity.repair.itemTarget != null) {
                itemDefinition = entity.repair.itemTarget;
            }
            if (itemDefinition == null) {
                ChatMessage(iplayer, "NoObjectsFound");
                return;
            }
            if (!_cachedSkins.ContainsKey(itemDefinition.isRedirectOf != null ? itemDefinition.isRedirectOf.itemid : itemDefinition.itemid)) {
                ChatMessage(iplayer, "NoSkins");
                return;
            }
            if (_viewingcon.TryGetValue(player.userID, out BoxController? boxController)) {
                if (boxController != null) UnityEngine.Object.Destroy(boxController);
                _viewingcon.Remove(player.userID);
                return;
            }
            //Check for cooldown
            float cdtime = 0;
            //Find shortest cd perm
            foreach (var cdperm in config.Cooldowns) {
                if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
                if (cdtime == 0) cdtime = cdperm.Value.skinitem;
                else if (cdtime > cdperm.Value.skinitem) cdtime = cdperm.Value.skinitem;
            }
            if (cdtime > 0) {
                if (!_playercooldowns.TryGetValue(player.userID, out CoolDowns? coolDowns)) _playercooldowns.Add(player.userID, new CoolDowns() {
                    skinitem = Time.time
                }
                );
                else {
                    if (coolDowns.skinitem + cdtime > Time.time) {
                        ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skinitem + cdtime - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
                        return;
                    }
                    coolDowns.skinitem = Time.time;
                }
            }
            if (args.Length > 0 && int.TryParse(args[0], out int setselect)) {
                Dictionary<int, ulong> cachedskins = GetCachedSkins(player, setselect);
                if (cachedskins.Count < 1) return;
                int itemID = itemDefinition.isRedirectOf != null ? itemDefinition.isRedirectOf.itemid : itemDefinition.itemid;
                if (cachedskins.TryGetValue(itemID, out ulong uID)) {
                    SkinDeployable(entity, uID);
                }
                return;
            }
            ItemContainer itemContainer = CreateContainer();
            boxController = player.gameObject.AddComponent<BoxController>();
            boxController.inventory = itemContainer;
            boxController.StartAwake();
            boxController.SkinDeplyoables(entity, itemDefinition);
            _viewingcon.TryAdd(player.userID, boxController);
            player.Invoke(() => StartLooting(player, itemContainer), 0.3f);
        }
        private void SkinInvCMD(IPlayer iplayer, string command, string[] args) {
            BasePlayer player = iplayer.Object as BasePlayer;
            if (player == null) return;
            if (!HasPerm(player.UserIDString, permskininv)) {
                ChatMessage(iplayer, "NoPerms");
                return;
            }
            int setselect = -1;
            if (args.Length > 0 && !int.TryParse(args[0], out setselect)) {
                setselect = -1;
            }
            Dictionary<int, ulong> cachedskins = GetCachedSkins(player, setselect);
            if (cachedskins.Count < 1) return;
            if (player.inventory == null) return;
            //Check for cooldown
            float cdtime = 0;
            //Find shortest cd perm
            foreach (var cdperm in config.Cooldowns) {
                if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
                if (cdtime == 0) cdtime = cdperm.Value.skininv;
                else if (cdtime > cdperm.Value.skininv) cdtime = cdperm.Value.skininv;
            }
            if (cdtime > 0) {
                if (!_playercooldowns.TryGetValue(player.userID, out CoolDowns? coolDowns)) _playercooldowns.Add(player.userID, new CoolDowns() {
                    skininv = Time.time
              
// ... [Code preview truncated due to length. Full source in attached file] ...

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