C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Game.Rust.Cui;
using System;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using System.IO;
using Newtonsoft.Json;
using Oxide.Core.Configuration;
using System.Collections;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using System.Threading.Tasks;
using System.Timers;
namespace Oxide.Plugins {
[Info("SkinController", "Amino", "1.4.0")]
[Description("An advanced skin system for Rust")]
public class SkinController : RustPlugin {
[PluginReference]
private Plugin Backpacks, Kits, KitController;
#region Config
public class SkinnerConfig {
[JsonProperty(PropertyName = "Steam API Key (https://steamcommunity.com/dev/apikey)")]
public string SteamApiKey {
get;
set;
}
= "";
public SkinCommands Commands {
get;
set;
}
= new SkinCommands();
[JsonProperty(PropertyName = "Permission: Max outfits")]
public Dictionary<string, int> OutfitPermissions {
get;
set;
}
= new Dictionary<string, int>();
[JsonProperty(PropertyName = "Allow team leaders to skin entire team")]
public bool AllowSkinTeam {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Skin base cooldown (seconds)")]
public int BaseSkinCooldownSeconds {
get;
set;
}
= 60;
[JsonProperty(PropertyName = "Allow skinning items on craft")]
public bool SkinItemsOnCraft {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Allow skinning items on pickup")]
public bool SkinItemsOnPickup {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Allow skinning backpack items")]
public bool SkinItemsInBackpack {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Allow skinning kits on redeemed")]
public bool SkinKitsOnRedeemed {
get;
set;
}
= true;
public string UIImage {
get;
set;
}
= "https://i.ibb.co/3SNBq4W/Adv-Skinner.png";
[JsonProperty(PropertyName = "Settings icon")]
public string SettingsIcon = "https://i.ibb.co/ckPQhd1/Settings-Cog.png";
[JsonProperty(PropertyName = "Background UI color")]
public string UIBackgroundColor {
get;
set;
}
= $"0 0 0.6";
[JsonProperty(PropertyName = "Main UI color")]
public string UIButtonColor {
get;
set;
}
= $"1.4 0";
[JsonProperty(PropertyName = "Secondary UI color")]
public string UISecondaryButtonColor {
get;
set;
}
= ".29.29.29";
[JsonProperty(PropertyName = "Active UI color")]
public string UIActiveButtonColor {
get;
set;
}
= ".29.29.29";
[JsonProperty(PropertyName = "Safe UI color")]
public string UISafeButtonColor {
get;
set;
}
= ".32.89.26";
[JsonProperty(PropertyName = "Danger UI color")]
public string UIDangerButtonColor {
get;
set;
}
= "1.34.34";
[JsonProperty(PropertyName = "Blur UI background")]
public bool BlurUIBackground {
get;
set;
}
= true;
[JsonProperty(PropertyName = "If skin id is listed below, an item with that skinID cannot be skinned")]
public List<string> DissallowedSkinIDs {
get;
set;
}
= new List<string>();
[JsonProperty(PropertyName = "Default Outfit")]
public List<OutfitDetail> DefaultOutfit {
get;
set;
}
= new List<OutfitDetail>();
public static SkinnerConfig DefaultConfig() {
return new SkinnerConfig {
Commands = new SkinCommands {
SkinMenuCommand = new List<string> {
"skin", "sb"
}
, SkinItemCommand = new List<string> {
"skinitem", "skini"
}
, SkinBaseCommand = new List<string> {
"skinbase"
}
, SkinItemsInContainerCommand = new List<string> {
"skincontainer", "skinc"
}
}
, DefaultOutfit = new List<OutfitDetail>() {
new OutfitDetail {
ItemId = -194953424, Shortname = "metal.facemask", SkinId = "0"
}
, new OutfitDetail {
ItemId = 1751045826, Shortname = "hoodie", SkinId = "0"
}
, new OutfitDetail {
ItemId = 1110385766, Shortname = "metal.plate.torso", SkinId = "0"
}
, new OutfitDetail {
ItemId = 1850456855, Shortname = "roadsign.kilt", SkinId = "0"
}
, new OutfitDetail {
ItemId = 237239288, Shortname = "pants", SkinId = "0"
}
, new OutfitDetail {
ItemId = -1549739227, Shortname = "shoes.boots", SkinId = "0"
}
, new OutfitDetail {
ItemId = 1545779598, Shortname = "rifle.ak", SkinId = "0"
}
, new OutfitDetail {
ItemId = 442886268, Shortname = "rocket.launcher", SkinId = "0"
}
}
, OutfitPermissions = new Dictionary<string, int>() {
{
"skincontroller.default", 4
}
, {
"skincontroller.vip", 6
}
, {
"skincontroller.vip+", 10
}
, {
"skincontroller.admin", 100
}
}
, DissallowedSkinIDs = new List<string>() {
"123456"
}
}
;
}
}
public class SkinCommands {
[JsonProperty(PropertyName = "Skin menu command")]
public List<string> SkinMenuCommand {
get;
set;
}
= new List<string>();
[JsonProperty(PropertyName = "Skin item command")]
public List<string> SkinItemCommand {
get;
set;
}
= new List<string>();
[JsonProperty(PropertyName = "Skin base command")]
public List<string> SkinBaseCommand {
get;
set;
}
= new List<string>();
[JsonProperty(PropertyName = "Skin container items command")]
public List<string> SkinItemsInContainerCommand {
get;
set;
}
= new List<string>();
}
private static SkinnerConfig _config;
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<SkinnerConfig>();
if (_config.DissallowedSkinIDs == null) _config.DissallowedSkinIDs = new List<string> {
"123456"
}
;
if (_config == null) LoadDefaultConfig();
SaveConfig();
}
catch (Exception e) {
Debug.LogException(e);
PrintWarning("Creating new config file.");
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig() => _config = SkinnerConfig.DefaultConfig();
protected override void SaveConfig() => Config.WriteObject(_config);
#endregion
#region Data
private SkinManager _skinList = new SkinManager();
private Dictionary<ulong, PlayerSettings> _playerSettings = new Dictionary<ulong, PlayerSettings>();
public class SkinManager {
public List<SkinData> WorkshopSkins = new List<SkinData>();
public List<SkinData> AddedSkins = new List<SkinData>();
public List<string> BlacklistedSkins = new List<string>();
public Dictionary<string, List<int>> CategoryList = new Dictionary<string, List<int>>();
}
public class SkinData {
public string SkinName {
get;
set;
}
public string SkinID {
get;
set;
}
public string ItemShortname {
get;
set;
}
public int ItemID {
get;
set;
}
}
public class PlayerSettings {
public bool SkinOnPickUp {
get;
set;
}
= false;
public bool SkinOnCraft {
get;
set;
}
= false;
public bool SkinOnLoot {
get;
set;
}
= false;
public bool SkinOnKitRedeem {
get;
set;
}
= false;
public bool FavoriteFallback {
get;
set;
}
= true;
public int CategoryItem {
get;
set;
}
= -194953424;
public string SelectedShortName {
get;
set;
}
= "metal.facemask";
public ulong SelectedSkinId {
get;
set;
}
= 0;
public string Category {
get;
set;
}
= "Attire";
public int ItemPage {
get;
set;
}
= 0;
public string SkinsFilter {
get;
set;
}
= null;
public int SkinPage {
get;
set;
}
= 0;
public int AllSkinPage {
get;
set;
}
= 0;
public int OutfitPage {
get;
set;
}
= 0;
public string LoadedItems {
get;
set;
}
= null;
public string ActiveSaveName {
get;
set;
}
public long BaseSkinCooldown {
get;
set;
}
= 0;
public List<OutfitDetail> SavedItems {
get;
set;
}
= new List<OutfitDetail>();
public List<Outfits> Outfits {
get;
set;
}
= new List<Outfits>();
}
public class Outfits {
public string OutfitName {
get;
set;
}
public bool Favorite {
get;
set;
}
= false;
public List<OutfitDetail> OutfitDetails {
get;
set;
}
}
public class OutfitDetail {
public int ItemId {
get;
set;
}
public string SkinId {
get;
set;
}
public string Shortname {
get;
set;
}
}
private List<string> Permissions = new List<string> {
"skincontroller.addskins", "skincontroller.use", "skincontroller.skinoncraft", "skincontroller.skinonpickup", "skincontroller.skinbase", "skincontroller.skinitem", "skincontroller.skincontainer", "skincontroller.skinonkitredeemed"
}
;
#endregion
#region Constructors
private List<string> _hazmatList = new List<string> {
"1266491000", "-470439097", "-797592358", "861513346", "491263800", "-560304835"
}
;
private readonly Dictionary<string, string> _namesToConvert = new Dictionary<string, string> {
{
"woodbox_deployed", "box.wooden"
}
, {
"waterpurifier.deployed", "water.purifier"
}
, {
"vendingmachine.deployed", "vending.machine"
}
, {
"box.wooden.large", "box.wooden.large"
}
, {
"rug.bear.deployed", "rug.bear"
}
, {
"door.hinged.toptier", "door.hinged.toptier"
}
, {
"door.hinged.metal", "door.hinged.metal"
}
, {
"wall.frame.garagedoor", "wall.frame.garagedoor"
}
, {
"rug.deployed", "rug"
}
, {
"locker.deployed", "locker"
}
, {
"door.double.hinged.metal", "door.double.hinged.metal"
}
, {
"door.double.hinged.wood", "door.double.hinged.wood"
}
, {
"barricade.concrete", "barricade.concrete"
}
, {
"sleepingbag_leather_deployed", "sleepingbag"
}
, {
"table.deployed", "table"
}
, {
"door.double.hinged.toptier", "door.double.hinged.toptier"
}
, {
"fridge.deployed", "fridge"
}
, {
"furnace", "furnace"
}
, {
"barricade.sandbags", "barricade.sandbags"
}
, {
"chair.deployed", "chair"
}
, {
"door.hinged.wood", "door.hinged.wood"
}
}
;
public class AddSkinRoot {
public Response response;
}
public class Tag {
public string tag {
get;
set;
}
}
public class Response {
public int result {
get;
set;
}
public int resultcount {
get;
set;
}
public List<PublishedFileDetail> publishedfiledetails {
get;
set;
}
}
public class PublishedFileDetail {
public string publishedfileid {
get;
set;
}
public int result {
get;
set;
}
public string creator {
get;
set;
}
public int creator_app_id {
get;
set;
}
public int consumer_app_id {
get;
set;
}
public string filename {
get;
set;
}
public int file_size {
get;
set;
}
public string preview_url {
get;
set;
}
public string hcontent_preview {
get;
set;
}
public string title {
get;
set;
}
public string description {
get;
set;
}
public int time_created {
get;
set;
}
public int time_updated {
get;
set;
}
public int visibility {
get;
set;
}
public int banned {
get;
set;
}
public string ban_reason {
get;
set;
}
public int subscriptions {
get;
set;
}
public int favorited {
get;
set;
}
public int lifetime_subscriptions {
get;
set;
}
public int lifetime_favorited {
get;
set;
}
public int views {
get;
set;
}
public List<Tag> tags {
get;
set;
}
}
public class CollectionRoot {
public CollectionResponse response {
get;
set;
}
}
public class CollectionResponse {
public int result {
get;
set;
}
public int resultcount {
get;
set;
}
public List<Collectiondetail> collectiondetails {
get;
set;
}
}
public class Collectiondetail {
public string publishedfileid {
get;
set;
}
public int result {
get;
set;
}
public List<Child> children {
get;
set;
}
}
public class Child {
public string publishedfileid {
get;
set;
}
public int sortorder {
get;
set;
}
public int filetype {
get;
set;
}
}
public Queue<ItemTask> itemTasks = new Queue<ItemTask>();
private void ProcessItemQueue() {
while (itemTasks.Count > 0) {
var task = itemTasks.Dequeue();
ItemContainer tempContainer = new ItemContainer();
tempContainer.ServerInitialize(null, 1);
if (!tempContainer.IsFull()) {
task.Item.MoveToContainer(tempContainer);
}
SkinItemContainer(task.Crafter.owner, task.PlayerSettings, tempContainer, true);
task.Item.MoveToContainer(task.Item.GetRootContainer());
}
}
public class ItemTask {
public Item Item {
get;
set;
}
public ItemCrafter Crafter {
get;
set;
}
public PlayerSettings PlayerSettings {
get;
set;
}
}
#endregion
#region Handlers
private void UnsubscribeHooks() {
if (!_config.SkinItemsOnCraft) Unsubscribe(nameof(OnItemCraftFinished));
if (!_config.SkinItemsOnPickup) Unsubscribe(nameof(OnItemPickup));
if (!_config.SkinKitsOnRedeemed) Unsubscribe(nameof(OnKitRedeemed));
}
private void SavePlayerSettings(BasePlayer player) {
if (!_playerSettings.ContainsKey(player.userID)) return;
Interface.GetMod().DataFileSystem.WriteObject($"SkinController{Path.DirectorySeparatorChar}PlayerOptions{Path.DirectorySeparatorChar}{player.userID}", _playerSettings[player.userID]);
}
private void RemoveSkin(string skinId) {
if (_skinList.WorkshopSkins.Any(x => x.SkinID == skinId)) {
_skinList.WorkshopSkins.RemoveAll(x => x.SkinID == skinId);
_skinList.BlacklistedSkins.Add(skinId);
}
if (_skinList.AddedSkins.Any(x => x.SkinID == skinId)) _skinList.AddedSkins.RemoveAll(x => x.SkinID == skinId);
}
private void LoadSavedPlayerSettings(BasePlayer player) {
var playerOptions = Interface.GetMod().DataFileSystem.ReadObject<PlayerSettings>($"SkinController{Path.DirectorySeparatorChar}PlayerOptions{Path.DirectorySeparatorChar}{player.userID}") ?? new PlayerSettings();
if (playerOptions.SkinsFilter != null && playerOptions.SkinsFilter.Any(x => !char.IsLetterOrDigit(x))) playerOptions.SkinsFilter = null;
_playerSettings[player.userID] = playerOptions;
}
private PlayerSettings GetPlayerSettings(BasePlayer player) {
if (!_playerSettings.ContainsKey(player.userID)) {
LoadSavedPlayerSettings(player);
}
if (_playerSettings[player.userID].SavedItems.Count == 0 && _playerSettings[player.userID].LoadedItems == null) _playerSettings[player.userID].SavedItems = new List<OutfitDetail>(_config.DefaultOutfit.Select(item => new OutfitDetail {
ItemId = item.ItemId, Shortname = item.Shortname, SkinId = item.SkinId
}
));
return _playerSettings[player.userID];
}
private void HandleSetItem(BasePlayer player, int itemId, string skinId, string shortname) {
var playerSettings = GetPlayerSettings(player);
var itemIsHazzy = _hazmatList.Contains(itemId.ToString());
if (playerSettings.SavedItems.Any(x => x.ItemId == itemId || (itemIsHazzy && _hazmatList.Contains(x.ItemId.ToString())))) {
var itemPlacement = playerSettings.SavedItems.FindIndex(x => x.ItemId == itemId || (itemIsHazzy && _hazmatList.Contains(x.ItemId.ToString())));
playerSettings.SavedItems[itemPlacement] = new OutfitDetail {
ItemId = itemId, Shortname = shortname, SkinId = skinId
}
;
}
else playerSettings.SavedItems.Add(new OutfitDetail {
ItemId = itemId, SkinId = skinId, Shortname = shortname
}
);
UIMainLoadoutDisplay(player);
}
private void HandleSetItemFull(BasePlayer player, string skinId) {
var playerSettings = GetPlayerSettings(player);
var skinList = new List<SkinData>(_skinList.WorkshopSkins.Select(item => new SkinData {
SkinName = item.SkinName, ItemID = item.ItemID, ItemShortname = item.ItemShortname, SkinID = item.SkinID
}
));
skinList.AddRange(_skinList.AddedSkins);
var skin = skinList.FirstOrDefault(x => x.SkinID == skinId);
if (skin == null || skin.SkinName == null) {
SaveErrorPopup(player, "Could not decipher skin name", true);
return;
}
var nameSplit = skin.SkinName.Split(' ');
var skinName = nameSplit[0];
var foundSkins = skinList.Where(x => x.SkinName?.ToLower().StartsWith(skinName.ToLower()) == true).ToList();
playerSettings.SavedItems.Clear();
foreach (var item in foundSkins) {
if (playerSettings.SavedItems.Any(x => x.ItemId == item.ItemID)) {
var itemPlacement = playerSettings.SavedItems.FindIndex(x => x.ItemId == item.ItemID);
playerSettings.SavedItems[itemPlacement] = new OutfitDetail {
ItemId = item.ItemID, Shortname = item.ItemShortname, SkinId = item.SkinID
}
;
}
else playerSettings.SavedItems.Add(new OutfitDetail {
ItemId = item.ItemID, SkinId = item.SkinID, Shortname = item.ItemShortname
}
);
}
UIMainLoadoutDisplay(player);
}
private void HandleRemoveItem(BasePlayer player, int itemId, bool isMain) {
var playerSettings = GetPlayerSettings(player);
playerSettings.SavedItems.RemoveAll(x => x.ItemId == itemId);
if (isMain) UIMainLoadoutDisplay(player);
else UIOutfitDisplay(player, isMain);
}
private void SaveErrorPopup(BasePlayer player, string errMsg, bool isNotOutfitEditor = false) {
var container = new CuiElementContainer();
var SCErrorPanel = CreatePanel(ref container, isNotOutfitEditor ? ".0.85" : ".676.66", isNotOutfitEditor ? ".25.99" : ".926.8", isNotOutfitEditor ? "0 0 0.9" : "0 0 0.7", "SCMainPanel", "SCErrPanel");
CreatePanel(ref container, "0 0", ".015 1", $"{_config.UIButtonColor} 1", SCErrorPanel);
CreateLabel(ref container, ".03 0", "1 1", "0 0 0 0", "1 1 1 1", errMsg, 15, TextAnchor.MiddleCenter, SCErrorPanel);
CuiHelper.DestroyUi(player, "SCErrPanel");
CuiHelper.AddUi(player, container);
timer.Once(2, () => CuiHelper.DestroyUi(player, SCErrorPanel));
}
private void LoadDefaultOutfit(BasePlayer player, PlayerSettings playerSettings) {
playerSettings.SavedItems = new List<OutfitDetail>(_config.DefaultOutfit.Select(item => new OutfitDetail {
ItemId = item.ItemId, Shortname = item.Shortname, SkinId = item.SkinId
}
));
}
private void GetCollection(BasePlayer player, bool isChat, string[] args, ConsoleSystem.Arg arg = null) {
if (args == null || args.Length == 0) {
DetermineReply(player, isChat, arg, "No collection id provided");
return;
}
try {
webrequest.Enqueue("https://api.steampowered.com/ISteamRemoteStorage/GetCollectionDetails/v1/", $"?key={_config.SteamApiKey}&collectioncount=1&publishedfileids[0]={args[0]}", (code, response) => {
if (code != 200) {
DetermineReply(player, isChat, arg, $"Collection {args[0]} didn't return code 200 on request");
return;
}
if (response == null) {
DetermineReply(player, isChat, arg, $"Collection {args[0]} not found, null reply");
return;
}
else {
var collectionResponse = JsonConvert.DeserializeObject<CollectionRoot>(response);
if (collectionResponse.response.collectiondetails[0].children == null) {
DetermineReply(player, isChat, arg, $"Collection {args[0]} not found");
return;
}
else DetermineReply(player, isChat, arg, $"Importing {collectionResponse.response.collectiondetails[0].children.Count} skins from collection [ {args[0]} ]");
foreach (var item in collectionResponse.response.collectiondetails[0].children) {
webrequest.Enqueue("https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/", $"?key={_config.SteamApiKey}&itemcount=1&publishedfileids[0]={item.publishedfileid}", (skincode, skinresponse) => ServerMgr.Instance.StartCoroutine(AddWorkShopSkin(skincode, skinresponse, item.publishedfileid)), this, RequestMethod.POST);
}
}
}
, this, RequestMethod.POST);
}
catch {
DetermineReply(player, isChat, arg, $"Error getting skin info for {args[0]}");
}
}
private void GetSkin(BasePlayer player, bool isChat, string[] args, ConsoleSystem.Arg arg = null) {
if (args == null || args.Length == 0 || args[0] == string.Empty || args[0] == null) {
DetermineReply(player, isChat, arg, "No skin id provided");
return;
}
var skinId = args[0];
if (_skinList.AddedSkins.Any(x => x.SkinID == skinId) || _skinList.WorkshopSkins.Any(x => x.SkinID == skinId)) {
DetermineReply(player, isChat, arg, "Skin already in skins list");
}
else {
try {
webrequest.Enqueue("https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/", $"?itemcount=1&publishedfileids[0]={skinId}", (code, response) => {
if (code != 200) {
DetermineReply(player, isChat, arg, $"Skin {skinId} didn't return code 200 on request");
return;
}
if (response == null) {
DetermineReply(player, isChat, arg, $"Skin {skinId} not found, null reply");
return;
}
else {
var workshopskin = JsonConvert.DeserializeObject<AddSkinRoot>(response);
if (workshopskin.response.publishedfiledetails[0].tags == null) {
DetermineReply(player, isChat, arg, $"Skin {skinId} not found");
return;
}
else DetermineReply(player, isChat, arg, $"Importing {skinId} - [ {workshopskin.response.publishedfiledetails[0].title} ]");
}
ServerMgr.Instance.StartCoroutine(AddWorkShopSkin(code, response, skinId));
}
, this, RequestMethod.POST);
}
catch {
DetermineReply(player, isChat, arg, $"Error getting skin info for {skinId}");
}
;
}
}
private void DetermineReply(BasePlayer player, bool isChat, ConsoleSystem.Arg arg, string reply) {
if (isChat) {
CreateGameTip(player, 3, 2, reply);
}
else {
if (arg.Connection == null) Interface.Oxide.LogInfo(reply);
else SendReply(arg, reply);
}
}
private IEnumerator AddWorkShopSkin(int code, string response, string skinId) {
if (response != null && code == 200) {
if (_skinList.AddedSkins.Any(x => x.SkinID == skinId) || _skinList.WorkshopSkins.Any(x => x.SkinID == skinId)) yield return null;
var workshopskin = JsonConvert.DeserializeObject<AddSkinRoot>(response);
foreach (var tag in workshopskin.response.publishedfiledetails[0].tags) {
if (_workshopRename.ContainsKey(tag.tag.ToLower().Replace(" ", ""))) {
var itemName = _workshopRename.FirstOrDefault(x => x.Key == tag.tag.ToLower().Replace(" ", ""));
if (!_skinList.AddedSkins.Any(x => x.SkinID == skinId) || _skinList.WorkshopSkins.Any(x => x.SkinID == skinId)) {
_skinList.AddedSkins.Add(new SkinData {
SkinName = workshopskin.response.publishedfiledetails[0].title, SkinID = skinId, ItemID = itemName.Value.itemid, ItemShortname = itemName.Value.shortname
}
);
}
}
}
}
else yield return null;
}
private bool CheckPlayerPermissionSkins(BasePlayer player, bool isChat, ConsoleSystem.Arg arg = null) {
if (isChat) {
if (!permission.UserHasPermission(player.UserIDString, "skincontroller.addskins")) {
CreateGameTip(player, 3, 1, "You do not have permission");
return false;
}
else return true;
}
if (arg.Connection != null) {
if (!permission.UserHasPermission(arg.Player().UserIDString, "skincontroller.addskins")) {
SendReply(arg, "You do not have permission");
return false;
}
else return true;
}
return true;
}
[ChatCommand("addskin")]
void CmdAddSkin(BasePlayer player, string command, string[] args) {
if (player == null) return;
if (CheckPlayerPermissionSkins(player, true)) {
GetSkin(player, true, args);
}
}
[ChatCommand("addcollection")]
void CmdAddCollection(BasePlayer player, string command, string[] args) {
if (player == null) return;
if (CheckPlayerPermissionSkins(player, true)) {
GetCollection(player, true, args);
}
}
private void SkinItemContainer(BasePlayer player, PlayerSettings playerSettings, ItemContainer container, bool playerInv = true, bool isInd = false, string InputSkinID = "0", int InputItemID = 0) {
if (container == null) return;
var itemsToRemove = new List<Item>();
var itemsToAdd = new List<Item>();
var theSkinInfo = new OutfitDetail();
if (isInd) {
var tempItemID = InputItemID;
var tempSkinID = InputSkinID;
if (tempItemID == 1266491000) {
tempItemID = int.Parse(InputSkinID);
tempSkinID = "0";
}
theSkinInfo = new OutfitDetail {
ItemId = tempItemID, Shortname = String.Empty, SkinId = tempSkinID
}
;
}
foreach (Item item in container.itemList) {
if (_config.DissallowedSkinIDs.Contains(item.skin.ToString())) continue;
if (!isInd) theSkinInfo = FindSkin(player, playerSettings, item, true);
if (theSkinInfo == null) continue;
var isHazzy = _hazmatList.Contains(theSkinInfo.ItemId.ToString());
if (isHazzy && _hazmatList.Contains(item.info.itemid.ToString())) {
if (theSkinInfo.ItemId == item.info.itemid) continue;
var theHazmat = ItemManager.CreateByItemID(theSkinInfo.ItemId, item.amount, 0);
theHazmat.name = item.name;
theHazmat.text = item.text;
theHazmat.condition = item.condition;
theHazmat.position = item.position;
itemsToAdd.Add(theHazmat);
itemsToRemove.Add(item);
}
else if (item.info.itemid == theSkinInfo.ItemId) {
if (ulong.Parse(theSkinInfo.SkinId) == item.skin) continue;
if (playerInv) {
Backpacks?.Call("API_MutateBackpackItems", player.userID, new Dictionary<string, object> {
["ItemId"]
= item.info.itemid
}
, new Dictionary<string, object> {
["SkinId"]
= theSkinInfo.SkinId
}
);
}
item.skin = ulong.Parse(theSkinInfo.SkinId);
if (item.GetHeldEntity() != null) {
item.GetHeldEntity().skinID = ulong.Parse(theSkinInfo.SkinId);
item.GetHeldEntity().SendNetworkUpdateImmediate();
}
item.MarkDirty();
}
}
foreach (var tempitem in itemsToRemove) {
tempitem.RemoveFromContainer();
}
foreach (var tempitem in itemsToAdd) {
tempitem.MoveToContainer(container, tempitem.position);
}
container.MarkDirty();
}
private void SkinSignleItem(BasePlayer player, PlayerSettings playerSettings, Item item) {
if (item == null || player == null || _config.DissallowedSkinIDs.Contains(item.skin.ToString())) return;
var theSkinInfo = FindSkin(player, playerSettings, item, true);
if (theSkinInfo == null || _hazmatList.Contains(theSkinInfo.ItemId.ToString())) return;
if (item.info.itemid == theSkinInfo.ItemId) {
if (ulong.Parse(theSkinInfo.SkinId) == item.skin) return;
item.skin = ulong.Parse(theSkinInfo.SkinId);
if (item.GetHeldEntity() != null) {
item.GetHeldEntity().skinID = ulong.Parse(theSkinInfo.SkinId);
item.GetHeldEntity().SendNetworkUpdateImmediate();
}
item.MarkDirty();
}
}
OutfitDetail FindSkin(BasePlayer player, PlayerSettings playerSettings, Item item, bool playerInv, int itemId = 0, string skinId = null) {
if (_hazmatList.Any(x => x == item.info.itemid.ToString())) {
var savedItem = playerSettings.SavedItems.FirstOrDefault(x => _hazmatList.Contains(x.ItemId.ToString()));
if (savedItem != null) return savedItem;
if (playerSettings.Outfits.Count > 0 && playerSettings.FavoriteFallback) {
var favoriteOutfit = playerSettings.Outfits.FirstOrDefault(x => x.Favorite);
if (favoriteOutfit != null) {
var favOutfitItem = favoriteOutfit.OutfitDetails.FirstOrDefault(x => _hazmatList.Contains(x.ItemId.ToString()));
if (favOutfitItem != null) {
return favOutfitItem;
}
}
}
}
else {
if (itemId == 0) {
var savedItem = playerSettings.SavedItems.FirstOrDefault(x => x.ItemId == item.info.itemid || _hazmatList.Contains(item.info.itemid.ToString()));
if (savedItem != null) {
return savedItem;
}
if (playerSettings.Outfits.Count > 0 && playerSettings.FavoriteFallback) {
var favoriteOutfit = playerSettings.Outfits.FirstOrDefault(x => x.Favorite);
if (favoriteOutfit != null) {
var favOutfitItem = favoriteOutfit.OutfitDetails.FirstOrDefault(x => x.ItemId == item.info.itemid || _hazmatList.Contains(item.info.itemid.ToString()));
if (favOutfitItem != null) {
return favOutfitItem;
}
}
}
}
else {
var theItem = ItemManager.FindItemDefinition(itemId);
return new OutfitDetail {
ItemId = theItem.itemid, Shortname = theItem.shortname, SkinId = skinId
}
;
}
}
return null;
}
private void FindBaseSkin(BasePlayer player, PlayerSettings playerSettings, BaseEntity entity) {
if (playerSettings.SavedItems.Any(x => x.Shortname == convertedShortnames(entity.ShortPrefabName))) {
SkinEntity(player, entity, playerSettings.SavedItems);
return;
}
else if (playerSettings.Outfits.Count > 0 && playerSettings.FavoriteFallback) {
var favoriteOutfit = playerSettings.Outfits.FirstOrDefault(x => x.Favorite);
if (favoriteOutfit != null) {
SkinEntity(player, entity, favoriteOutfit.OutfitDetails);
return;
}
}
return;
}
private void SkinEntity(BasePlayer player, BaseEntity entity, List<OutfitDetail> outfit) {
var foundskin = outfit.FirstOrDefault(x => x.Shortname == convertedShortnames(entity.ShortPrefabName));
if (foundskin != null) {
if (entity.skinID != ulong.Parse(foundskin.SkinId)) {
entity.skinID = ulong.Parse(foundskin.SkinId);
entity.SendNetworkUpdateImmediate();
}
return;
}
}
private void SkinContainer(BasePlayer player, string commands, string[] args) {
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, "skincontroller.skincontainer")) CreateGameTip(player, 3, 1, Lang("NoPermission"));
else {
if (player.IsBuildingAuthed()) {
RaycastHit hit;
if (Physics.Raycast(player.eyes.HeadRay(), out hit, 10f, LayerMask.GetMask("Deployed"))) {
BaseEntity entity = hit.GetEntity();
if (entity != null) {
List<string> containerList = new List<string>() {
"box.wooden.large", "woodbox_deployed", "coffinstorage", "locker.deployed"
}
;
if (containerList.Contains(entity.ShortPrefabName)) {
var playerSettings = GetPlayerSettings(player);
StorageContainer container = entity as StorageContainer;
SkinItemContainer(player, playerSettings, container.inventory, false);
CreateGameTip(player, 3, 2, Lang("SkinningContainer"));
}
}
}
}
else CreateGameTip(player, 3, 1, Lang("NotAuthed"));
}
}
private void SkinItemRaycast(BasePlayer player, string commands, string[] args) {
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, "skincontroller.skinitem")) CreateGameTip(player, 3, 1, Lang("NoPermission"));
else {
if (player.IsBuildingAuthed()) {
RaycastHit hit;
if (Physics.Raycast(player.eyes.HeadRay(), out hit, 10f, LayerMask.GetMask("Deployed", "Construction"))) {
BaseEntity entity = hit.GetEntity();
if (entity != null) {
var playerSettings = GetPlayerSettings(player);
FindBaseSkin(player, playerSettings, entity);
}
else CreateGameTip(player, 3, 1, Lang("NotValidDeployable"));
}
}
else CreateGameTip(player, 3, 1, Lang("NotAuthed"));
}
}
private IEnumerator SkinPlayerBase(BasePlayer player, PlayerSettings playerSettings, List<BaseEntity> entities, uint? currentBuilding) {
foreach (var entity in entities.Where(x => x.GetBuildingPrivilege()?.GetBuilding()?.ID == currentBuilding)) {
FindBaseSkin(player, playerSettings, entity);
yield return null;
}
}
private void SkinBase(BasePlayer player, string commands, string[] args) {
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, "skincontroller.skinbase")) CreateGameTip(player, 3, 1, Lang("NoPermission"));
else {
var playerSettings = GetPlayerSettings(player);
if (playerSettings.BaseSkinCooldown - DateTimeOffset.Now.ToUnixTimeSeconds() > 0) CreateGameTip(player, 3, 1, "On cooldown");
else {
if (player.IsBuildingAuthed()) {
playerSettings.BaseSkinCooldown = DateTimeOffset.Now.ToUnixTimeSeconds() + _config.BaseSkinCooldownSeconds;
var entities = Physics.OverlapSphere(player.transform.position, 30, LayerMask.GetMask("Deployed", "Construction")).Select(x => x.ToBaseEntity()).Distinct().ToList();
var currentBuilding = player.GetBuildingPrivilege()?.GetBuilding()?.ID;
CreateGameTip(player, 3, 2, Lang("SkinningBase"));
InvokeHandler.Instance.StartCoroutine(SkinPlayerBase(player, playerSettings, entities, currentBuilding));
}
else CreateGameTip(player, 3, 1, Lang("NotAuthed"));
}
}
}
private string convertedShortnames(string deployedShortname) {
if (_namesToConvert.ContainsKey(deployedShortname)) return _namesToConvert[deployedShortname];
return deployedShortname;
}
private void CreateGameTip(BasePlayer player, float length, int type, string text) {
if (player == null) return;
player.SendConsoleCommand("gametip.hidegametip");
player.SendConsoleCommand("gametip.showtoast", type, text);
timer.Once(length, () => player?.SendConsoleCommand("gametip.hidegametip"));
}
private void SkinTeam(BasePlayer player, PlayerSettings playerSettings) {
foreach (var member in player.Team.members) {
BasePlayer teamMember = BasePlayer.FindByID(member);
if (teamMember == null || !teamMember.IsConnected) continue;
SkinItemContainer(teamMember, playerSettings, teamMember.inventory.containerBelt, true);
SkinItemContainer(teamMember, playerSettings, teamMember.inventory.containerMain, true);
SkinItemContainer(teamMember, playerSettings, teamMember.inventory.containerWear, true);
}
}
#endregion
#region Lang
// ... [Code preview truncated due to length. Full source in attached file] ...