C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System.Linq;
using Facepunch;
namespace Oxide.Plugins {
[Info("XSkinMenu", "Forum: https://topplugin.ru Ds: alone_sempai Vk: https://vk.com/rustnastroika", "1.6.3")]
class XSkinMenu : RustPlugin {
private const bool LanguageEnglish = true;
private const string permUse = "xskinmenu.use";
private const string permSetting = "xskinmenu.setting";
private const string permCraft = "xskinmenu.craft";
private const string permEntity = "xskinmenu.entity";
private const string permSkinI = "xskinmenu.item";
private const string permInv = "xskinmenu.inventory";
private const string permGive = "xskinmenu.give";
private const string permPickup = "xskinmenu.pickup";
private const string permSkinC = "xskinmenu.skinchange";
private const string permAdminS = "xskinmenu.adminskins";
private const string permVipS = "xskinmenu.vipskins";
private const string permAdmin = "xskinmenu.admin";
private const string permSprayC = "xskinmenu.spraycan";
private const string permKitsD = "xskinmenu.defaultkits";
private const string permKitsC = "xskinmenu.customkits";
private const string permPlayerAdd = "xskinmenu.playeradd";
private List<ulong> _adminSkins = new List<ulong>();
private List<ulong> _vipSkins = new List<ulong>();
private List<ulong> _adminAndVipSkins = new List<ulong>();
private List<ulong> _adminUiFD = new List<ulong>();
private Dictionary<BasePlayer, DateTime> Cooldowns = new Dictionary<BasePlayer, DateTime>();
private Dictionary<BasePlayer, DateTime> CooldownsAdd = new Dictionary<BasePlayer, DateTime>();
private readonly Dictionary<string, string> _shortnamesEntity = new Dictionary<string, string>();
private Dictionary<string, ulong> _items = new Dictionary<string, ulong>();
private Dictionary<string, int> _itemsId = new Dictionary<string, int>();
private Dictionary<ulong, int> _skinIDsINT = new Dictionary<ulong, int>();
private Dictionary<string, string> _redirectSkins = new Dictionary<string, string>();
private HashSet<ulong> _removeATC = new HashSet<ulong>();
private string BgMainLayer, BgKitsLayer;
#region Reference
[PluginReference]
private Plugin XBuildingSkinMenu;
#endregion
#region Config
private SkinConfig config;
private class SkinConfig {
internal class SteamSetting {
[JsonProperty("Steam API Key")]
public string APIKey;
}
internal class GeneralSetting {
[JsonProperty(LanguageEnglish ? "Generate/Check and add new skins accepted by developers or made for twitch drops" : "Сгенерировать/Проверять и добавлять новые скины принятые разработчиками или сделаные для твич дропсов")]
public bool UpdateSkins;
[JsonProperty(LanguageEnglish ? "Generate/Check and add new skins added by developers [ For example, a skin for hazmatsuit ]" : "Сгенерировать/Проверять и добавлять новые скины добавленные разработчиками [ К примеру скин на хазмат ]")]
public bool UpdateSkinsFacepunch;
[JsonProperty(LanguageEnglish ? "Propagate blacklisted skins to repair bench" : "Распространять черный список скинов на ремонтный верстак")]
public bool RepairBench;
[JsonProperty(LanguageEnglish ? "Forbid changing the skin of an item that is not in the config" : "Запретить менять скин предмета которого нет в конфиге")]
public bool ReskinConfig;
[JsonProperty(LanguageEnglish ? "Change skins to items after player respawns" : "Изменять скины на предметы после респавна игрока")]
public bool ReskinRespawn;
[JsonProperty(LanguageEnglish ? "Enable default skin kits" : "Включить стандартные наборы скинов")]
public bool EnableDefaultKits = true;
[JsonProperty(LanguageEnglish ? "Enable personal skin kits" : "Включить личные наборы скинов")]
public bool EnableCustomKits = true;
[JsonProperty(LanguageEnglish ? "Reissue an active item.[ Visually, the skin will be visible on the item at once ]" : "Перевыдавать активный предмет.[ Визуально скин будет виден на предмете сразу ]")]
public bool ReissueActiveItem = true;
[JsonProperty(LanguageEnglish ? "Shift UI if the above option is enabled" : "Сдвинуть UI если включен параметр выше")]
public bool ShiftUI = true;
[JsonProperty(LanguageEnglish ? "1.1 Reset Admin skins from items if they are used by a player without permission" : "1.1 Сбрасывать Админ скины с предметов если их использует игрок без разрешения")]
public bool DeleteAdminSkins1 = true;
[JsonProperty(LanguageEnglish ? "1.2 Do not reset Admin skin if the player has it in the Steam inventory" : "1.2 Не сбрасывать Админ скин если он есть у игрока в инвентаре Steam")]
public bool DeleteAdminSkins2 = true;
[JsonProperty(LanguageEnglish ? "2.1 Reset Vip skins from items if they are used by a player without permission" : "2.1 Сбрасывать Вип скины с предметов если их использует игрок без разрешения")]
public bool DeleteVipSkins1 = true;
[JsonProperty(LanguageEnglish ? "2.2 Do not reset Vip skin if the player has it in the Steam inventory" : "2.2 Не сбрасывать Вип скин если он есть у игрока в инвентаре Steam")]
public bool DeleteVipSkins2 = true;
[JsonProperty(LanguageEnglish ? "List of commands to open the menu - 1" : "Список команд для открытия меню - 1")]
public List<string> SkinCommandList;
[JsonProperty(LanguageEnglish ? "List of commands to open the menu - 2" : "Список команд для открытия меню - 2")]
public List<string> SkinKitCommandList;
[JsonProperty(LanguageEnglish ? "List of commands to open the menu - 3" : "Список команд для открытия меню - 3")]
public List<string> SkinEntityCommandList;
[JsonProperty(LanguageEnglish ? "List of commands to open the menu - 4" : "Список команд для открытия меню - 4")]
public List<string> SkinItemCommandList;
[JsonProperty(LanguageEnglish ? "Blacklist of skins that cannot be changed.[ For example: fire gloves, fire hatchet ]" : "Черный список скинов которые нельзя изменить.[ Например: огненные перчатки, огненный топор ]]")]
public List<ulong> Blacklist = new List<ulong>();
[JsonProperty(LanguageEnglish ? "List Admin skins" : "Список Админ скинов")]
public Dictionary<string, List<ulong>> AdminSkins = new Dictionary<string, List<ulong>>();
[JsonProperty(LanguageEnglish ? "List Vip skins" : "Список Вип скинов")]
public Dictionary<string, List<ulong>> VipSkins = new Dictionary<string, List<ulong>>();
}
internal class PlayerSetting {
[JsonProperty(LanguageEnglish ? "Change item skin in inventory after selecting skin in menu" : "Изменить скин предмета в инвентаре после выбора скина в меню")]
public bool ChangeSI;
[JsonProperty(LanguageEnglish ? "Change item skin in inventory after removing skin in menu" : "Изменить скин предмета в инвентаре после удаления скина в меню")]
public bool ChangeSCL;
[JsonProperty(LanguageEnglish ? "Change skin on installed items/constructions [ /skinentity ]" : "Изменить скин на установленных предметах/конструкциях [ /skinentity ]")]
public bool ChangeSE;
[JsonProperty(LanguageEnglish ? "Allow friends to change the skin on items/constructions you installed [ /skinentity ]" : "Разрешить друзьям изменить скин на установленных вами предметах/конструкциях [ /skinentity ]")]
public bool ChangeF;
[JsonProperty(LanguageEnglish ? "Change item skin when it is placed in the inventory by any means" : "Изменить скин предмета когда он любым способом попал в инвентарь")]
public bool ChangeSG;
[JsonProperty(LanguageEnglish ? "Change item skin only when pickup" : "Изменить скин предмета только при его подборе")]
public bool ChangeSP;
[JsonProperty(LanguageEnglish ? "Do not reset item skin for which no skin is selected when it enters the inventory" : "Не сбрасывать скин предмета, для которого не выбран скин, когда он попадает в инвентарь")]
public bool ChangeSGN;
[JsonProperty(LanguageEnglish ? "Change item skin when crafting" : "Изменить скин предмета при крафте")]
public bool ChangeSC;
[JsonProperty(LanguageEnglish ? "Use skins with a spray can" : "Использовать скины с помощью баллончика")]
public bool UseSprayC;
[JsonProperty(LanguageEnglish ? "Enable sound effects in the menu [ Clicks ]" : "Включить звуковые эффекты в меню [ Щелчки ]")]
public bool UseSoundE;
[JsonProperty(LanguageEnglish ? "[ True - Comfort menu | False - Default menu ]" : "[ True - Комфортное меню | False - Стандартное меню ]")]
public bool Comfort;
}
internal class GUISetting {
[JsonProperty(LanguageEnglish ? "Layer UI - [ Overlay - above inventory | Hud - under inventory (to view installed skins without closing the menu) ]" : "Слой UI - [ Overlay - поверх инвентаря | Hud - под инвентарем (для просмотра установленных скинов не закрывая меню) ]")]
public string LayerUI = "Overlay";
[JsonProperty(LanguageEnglish ? "Refresh UI page after skin selection" : "Обновлять UI страницу после выбора скина")]
public bool SkinUP;
[JsonProperty(LanguageEnglish ? "Refresh UI page after skin removal" : "Обновлять UI страницу после удаления скина")]
public bool DelSkinUP;
[JsonProperty(LanguageEnglish ? "Display selected skins on homepage" : "Отображать выбранные скины на главной")]
public bool MainSkin;
[JsonProperty(LanguageEnglish ? "Display button to reset, all selected skins" : "Отображать кнопку для сброса всех выбранных скинов")]
public bool ButtonClear;
[JsonProperty(LanguageEnglish ? "Display pages" : "Отображать страницы")]
public bool Page;
[JsonProperty(LanguageEnglish ? "Display the button - Comfort menu [ + ]" : "Отображать кнопку - Комфортное меню [ + ]")]
public bool ButtonComfortPlus = true;
[JsonProperty(LanguageEnglish ? "Close the menu by tapping on an empty area of the screen" : "Закрыть меню нажатием на пустую область экрана")]
public bool CloseUI;
[JsonProperty(LanguageEnglish ? "Icon - Kits" : "Иконка - Наборы")]
public string IconKits = "assets/icons/clothing.png";
[JsonProperty(LanguageEnglish ? "Icon - XBuildingSkinMenu" : "Иконка - XBuildingSkinMenu")]
public string IconBSkin = "assets/icons/construction.png";
[JsonProperty(LanguageEnglish ? "Icon - Zoom" : "Иконка - Увеличение")]
public string IconZoom = "assets/icons/add.png";
[JsonProperty(LanguageEnglish ? "Material_background_0" : "Материал_фон_0")]
public string BMaterial0 = "assets/icons/greyout.mat";
[JsonProperty(LanguageEnglish ? "Color_background_0" : "Цвет_фон_0")]
public string BColor0 = "0 0 0 0";
[JsonProperty(LanguageEnglish ? "Color_background_1" : "Цвет_фон_1")]
public string BColor1;
[JsonProperty(LanguageEnglish ? "Color_background_2" : "Цвет_фон_2")]
public string BColor2;
[JsonProperty(LanguageEnglish ? "Color_background_3" : "Цвет_фон_3")]
public string BColor3 = "0.1 0.1 0.1 0.975";
[JsonProperty(LanguageEnglish ? "Color_background_4" : "Цвет_фон_4")]
public string BColor4 = "0.257 0.261 0.249 1";
[JsonProperty(LanguageEnglish ? "Active category color" : "Цвет активной категории")]
public string ActiveColor;
[JsonProperty(LanguageEnglish ? "Inactive category color" : "Цвет неактивной категории")]
public string InactiveColor;
[JsonProperty(LanguageEnglish ? "Category button color" : "Цвет кнопок категорий")]
public string CategoryColor;
[JsonProperty(LanguageEnglish ? "Settings buttons color" : "Цвет кнопок настроек")]
public string SettingColor;
[JsonProperty(LanguageEnglish ? "Button color (icons)" : "Цвет кнопок (иконки)")]
public string IconColor;
[JsonProperty(LanguageEnglish ? "Item/skin block color" : "Цвет блоков предметов/скинов")]
public string BlockColor;
[JsonProperty(LanguageEnglish ? "Color of skins/buttons block in kits" : "Цвет блоков скинов/кнопок в наборах")]
public string BlockKitColor = "0.667 0.671 0.659 0.5";
[JsonProperty(LanguageEnglish ? "Selected skin block color" : "Цвет блока выбранного скина")]
public string ActiveBlockColor;
[JsonProperty(LanguageEnglish ? "Active next/reset button color" : "Цвет активной кнопки далее/сбросить")]
public string ActiveNextReloadColor;
[JsonProperty(LanguageEnglish ? "Color of inactive next/reset button" : "Цвет неактивной кнопки далее/сбросить")]
public string InactiveNextReloadColor;
[JsonProperty(LanguageEnglish ? "Next/reset active button text color" : "Цвет текста активной кнопки далее/сбросить")]
public string ActiveNextReloadColorText;
[JsonProperty(LanguageEnglish ? "Text color of inactive next/reset button" : "Цвет текста неактивной кнопки далее/сбросить")]
public string InactiveNextReloadColorText;
[JsonProperty(LanguageEnglish ? "Active back button color" : "Цвет активной кнопки назад")]
public string ActiveBackColor;
[JsonProperty(LanguageEnglish ? "Back button color" : "Цвет неактивной кнопки назад")]
public string InactiveBackColor;
[JsonProperty(LanguageEnglish ? "Active back button text color" : "Цвет текста активной кнопки назад")]
public string ActiveBackColorText;
[JsonProperty(LanguageEnglish ? "Back button text color" : "Цвет текста неактивной кнопки назад")]
public string InactiveBackColorText;
}
internal class MenuSSetting {
[JsonProperty(LanguageEnglish ? "Enabled parameter icon" : "Иконка включенного параметра")]
public string TButtonIcon;
[JsonProperty(LanguageEnglish ? "Disabled parameter icon" : "Иконка вылюченного параметра")]
public string FButtonIcon;
[JsonProperty(LanguageEnglish ? "Enabled parameter color" : "Цвет включенного параметра")]
public string CTButton;
[JsonProperty(LanguageEnglish ? "Disabled parameter color" : "Цвет вылюченного параметра")]
public string CFButton;
}
[JsonProperty(LanguageEnglish ? "Steam settings" : "Настройки Steam")]
public SteamSetting Steam = new SteamSetting();
[JsonProperty(LanguageEnglish ? "General settings" : "Общие настройки")]
public GeneralSetting Setting = new GeneralSetting();
[JsonProperty(LanguageEnglish ? "Default player settings" : "Настройки игрока по умолчанию")]
public PlayerSetting PSetting = new PlayerSetting();
[JsonProperty(LanguageEnglish ? "Default skin kits setting" : "Настройка стандартных наборов скинов")]
public Dictionary<string, Dictionary<string, ulong>> KitsSetting = new Dictionary<string, Dictionary<string, ulong>>();
[JsonProperty(LanguageEnglish ? "Permissions settings.Maximum number of personal skin kits" : "Настройка разрешений.Максимальное кол-во личных наборов скинов")]
public Dictionary<string, int> KitsCPSetting = new Dictionary<string, int>();
[JsonProperty(LanguageEnglish ? "GUI settings" : "Настройки GUI")]
public GUISetting GUI = new GUISetting();
[JsonProperty(LanguageEnglish ? "Menu settings" : "Меню настроект")]
public MenuSSetting MenuS = new MenuSSetting();
[JsonProperty(LanguageEnglish ? "Category settings - [ Item shortname | Default item skin ]" : "Настройка категорий - [ Шортнейм предмета | Дефолтный скин предмета ]")]
public Dictionary<string, Dictionary<string, ulong>> Category = new Dictionary<string, Dictionary<string, ulong>>();
public static SkinConfig GetNewConfiguration() {
return new SkinConfig {
Steam = new SteamSetting {
APIKey = ""
}
, Setting = new GeneralSetting {
UpdateSkins = true, UpdateSkinsFacepunch = false, RepairBench = true, ReskinConfig = false, ReskinRespawn = true, EnableDefaultKits = true, EnableCustomKits = true, ReissueActiveItem = true, ShiftUI = true, DeleteAdminSkins1 = true, DeleteAdminSkins2 = true, DeleteVipSkins1 = true, DeleteVipSkins2 = true, SkinCommandList = new List<string> {
"skin"
}
, SkinKitCommandList = new List<string> {
"skinkit"
}
, SkinEntityCommandList = new List<string> {
"skinentity"
}
, SkinItemCommandList = new List<string> {
"skinitem"
}
, Blacklist = new List<ulong> {
1742796979, 841106268
}
, AdminSkins = new Dictionary<string, List<ulong>> {
["rifle.ak"]
= new List<ulong> {
2428514763, 2431899986, 2802928155, 2551895055, 2957212973, 2976404884
}
, ["smg.mp5"] = new List<ulong> {
2468526014, 2966579723, 2590028692, 2354313222, 2558124512, 2432107615, 2351278756
}
, ["metal.facemask"] = new List<ulong> {
2976455803, 2972755707, 2960187815, 2963852242, 2462021937, 1658894467, 1539950759
}
}
, VipSkins = new Dictionary<string, List<ulong>> {
["hatchet"]
= new List<ulong> {
2940068053, 2891473448, 1567848320, 1414450116, 1306286667, 1277610054, 1679923378
}
, ["pickaxe"] = new List<ulong> {
2940068876, 1672711156, 1624825406, 2637131316, 2837147224, 2775081117
}
, ["box.wooden.large"] = new List<ulong> {
1686318599, 1651859603, 1566044873, 1547157690, 1882223552, 2068573115, 2388451898
}
}
}
, PSetting = new PlayerSetting {
ChangeSI = true, ChangeSCL = true, ChangeSE = true, ChangeF = true, ChangeSG = true, ChangeSP = false, ChangeSGN = true, ChangeSC = true, UseSprayC = true, UseSoundE = true, Comfort = false
}
, KitsSetting = new Dictionary<string, Dictionary<string, ulong>> {
["Blackout"]
= new Dictionary<string, ulong> {
["metal.facemask"]
= 2105454370, ["metal.plate.torso"] = 2105505757, ["hoodie"] = 2080975449, ["pants"] = 2080977144, ["shoes.boots"] = 2090776132, ["coffeecan.helmet"] = 2120618167, ["roadsign.jacket"] = 2120615642, ["roadsign.kilt"] = 2120628865, ["roadsign.gloves"] = 2530894213, ["burlap.gloves"] = 2090790324, ["jacket"] = 2137516645, ["rifle.l96"] = 2473291137, ["rifle.ak"] = 2128372674, ["rifle.lr300"] = 2151920583, ["rifle.bolt"] = 2363806432, ["rifle.semiauto"] = 2267956984, ["smg.mp5"] = 2887642987, ["smg.thompson"] = 2393671891, ["smg.2"] = 2879438786, ["crossbow"] = 2178956071, ["bow.hunting"] = 2192571819
}
, ["Whiteout"] = new Dictionary<string, ulong> {
["metal.facemask"]
= 2432948498, ["metal.plate.torso"] = 2432947351, ["hoodie"] = 2416648557, ["pants"] = 2416647256, ["shoes.boots"] = 2752873720, ["coffeecan.helmet"] = 2503956851, ["roadsign.jacket"] = 2503955663, ["roadsign.kilt"] = 2469019097, ["roadsign.gloves"] = 2469031994
}
, ["Forest Raiders"] = new Dictionary<string, ulong> {
["metal.facemask"]
= 2551475709, ["metal.plate.torso"] = 2551474093, ["hoodie"] = 2563940111, ["pants"] = 2563935722, ["shoes.boots"] = 2575506021, ["coffeecan.helmet"] = 2570227850, ["roadsign.jacket"] = 2570233552, ["roadsign.kilt"] = 2570237224, ["roadsign.gloves"] = 2575539874
}
, ["Desert Raiders"] = new Dictionary<string, ulong> {
["metal.facemask"]
= 2475428991, ["metal.plate.torso"] = 2475407123, ["hoodie"] = 2503910428, ["pants"] = 2503903214, ["shoes.boots"] = 2510093391, ["coffeecan.helmet"] = 2496517898, ["roadsign.jacket"] = 2496520042, ["roadsign.kilt"] = 2496523983, ["roadsign.gloves"] = 2510097681, ["rifle.ak"] = 2525948777, ["smg.thompson"] = 2537687634, ["rifle.semiauto"] = 2522121227
}
}
, KitsCPSetting = new Dictionary<string, int> {
["xskinmenu.kit12"]
= 12, ["xskinmenu.kit9"] = 9, ["xskinmenu.kit6"] = 6, ["xskinmenu.kit3"] = 3
}
, GUI = new GUISetting {
LayerUI = "Overlay", SkinUP = true, DelSkinUP = true, MainSkin = false, ButtonClear = true, Page = true, ButtonComfortPlus = true, CloseUI = false, IconKits = "assets/icons/clothing.png", IconBSkin = "assets/icons/construction.png", IconZoom = "assets/icons/add.png", BMaterial0 = "assets/icons/greyout.mat", BColor0 = "0 0 0 0", BColor1 = "0.517 0.521 0.509 0.95", BColor2 = "0.217 0.221 0.209 0.95", BColor3 = "0.1 0.1 0.1 0.975", BColor4 = "0.257 0.261 0.249 1", ActiveColor = "0.53 0.77 0.35 0.8", InactiveColor = "0 0 0 0", CategoryColor = "0.517 0.521 0.509 0.5", SettingColor = "0.517 0.521 0.509 0.5", IconColor = "1 1 1 0.75", BlockColor = "0.517 0.521 0.509 0.5", BlockKitColor = "0.667 0.671 0.659 0.5", ActiveBlockColor = "0.53 0.77 0.35 0.8", ActiveNextReloadColor = "0.35 0.45 0.25 1", InactiveNextReloadColor = "0.35 0.45 0.25 0.4", ActiveNextReloadColorText = "0.75 0.95 0.41 1", InactiveNextReloadColorText = "0.75 0.95 0.41 0.4", ActiveBackColor = "0.65 0.29 0.24 1", InactiveBackColor = "0.65 0.29 0.24 0.4", ActiveBackColorText = "0.92 0.79 0.76 1", InactiveBackColorText = "0.92 0.79 0.76 0.4"
}
, MenuS = new MenuSSetting {
TButtonIcon = "assets/icons/check.png", FButtonIcon = "assets/icons/close.png", CTButton = "0.53 0.77 0.35 0.8", CFButton = "1 0.4 0.35 0.8"
}
, Category = new Dictionary<string, Dictionary<string, ulong>> {
["weapon"]
= new Dictionary<string, ulong> {
["gun.water"]
= 0, ["pistol.revolver"] = 0, ["pistol.semiauto"] = 0, ["pistol.python"] = 0, ["pistol.eoka"] = 0, ["shotgun.waterpipe"] = 0, ["shotgun.double"] = 0, ["shotgun.pump"] = 0, ["bow.hunting"] = 0, ["crossbow"] = 0, ["grenade.f1"] = 0, ["smg.2"] = 0, ["smg.thompson"] = 0, ["smg.mp5"] = 0, ["rifle.ak"] = 0, ["rifle.lr300"] = 0, ["lmg.m249"] = 0, ["rocket.launcher"] = 0, ["rifle.semiauto"] = 0, ["rifle.m39"] = 0, ["rifle.bolt"] = 0, ["rifle.l96"] = 0, ["longsword"] = 0, ["salvaged.sword"] = 0, ["mace"] = 0, ["knife.combat"] = 0, ["bone.club"] = 0, ["knife.bone"] = 0, ["spear.wooden"] = 0
}
, ["construction"] = new Dictionary<string, ulong> {
["wall.frame.garagedoor"]
= 0, ["door.double.hinged.toptier"] = 0, ["door.double.hinged.metal"] = 0, ["door.double.hinged.wood"] = 0, ["door.hinged.toptier"] = 0, ["door.hinged.metal"] = 0, ["door.hinged.wood"] = 0, ["barricade.concrete"] = 0, ["barricade.sandbags"] = 0, ["cupboard.tool"] = 0, ["wall.frame.lunar2025_a"] = 0
}
, ["item"] = new Dictionary<string, ulong> {
["locker"]
= 0, ["vending.machine"] = 0, ["fridge"] = 0, ["furnace"] = 0, ["table"] = 0, ["chair"] = 0, ["rockingchair"] = 0, ["box.wooden.large"] = 0, ["box.wooden"] = 0, ["rug.bear"] = 0, ["rug"] = 0, ["wallpaper"] = 0, ["sleepingbag"] = 0, ["computerstation"] = 0, ["water.purifier"] = 0, ["target.reactive"] = 0, ["sled"] = 0, ["discofloor"] = 0, ["paddlingpool"] = 0, ["innertube"] = 0, ["boogieboard"] = 0, ["beachtowel"] = 0, ["beachparasol"] = 0, ["beachchair"] = 0, ["skull.trophy"] = 0, ["skullspikes"] = 0, ["skylantern"] = 0, ["industrial.wall.light"] = 0, ["wantedposter"] = 0, ["spinner.wheel"] = 0, ["planter.large"] = 0, ["planter.triangle"] = 0
}
, ["attire"] = new Dictionary<string, ulong> {
["metal.facemask"]
= 0, ["coffeecan.helmet"] = 0, ["riot.helmet"] = 0, ["bucket.helmet"] = 0, ["deer.skull.mask"] = 0, ["twitch.headset"] = 0, ["sunglasses"] = 0, ["mask.balaclava"] = 0, ["burlap.headwrap"] = 0, ["hat.miner"] = 0, ["hat.beenie"] = 0, ["hat.boonie"] = 0, ["hat.cap"] = 0, ["mask.bandana"] = 0, ["metal.plate.torso"] = 0, ["roadsign.jacket"] = 0, ["roadsign.kilt"] = 0, ["roadsign.gloves"] = 0, ["burlap.gloves"] = 0, ["attire.hide.poncho"] = 0, ["jacket.snow"] = 0, ["jacket"] = 0, ["tshirt.long"] = 0, ["hazmatsuit"] = 0, ["hoodie"] = 0, ["shirt.collared"] = 0, ["tshirt"] = 0, ["burlap.shirt"] = 0, ["attire.hide.vest"] = 0, ["shirt.tanktop"] = 0, ["attire.hide.helterneck"] = 0, ["pants"] = 0, ["burlap.trousers"] = 0, ["pants.shorts"] = 0, ["attire.hide.pants"] = 0, ["attire.hide.skirt"] = 0, ["shoes.boots"] = 0, ["burlap.shoes"] = 0, ["attire.hide.boots"] = 0, ["largebackpack"] = 0
}
, ["tool"] = new Dictionary<string, ulong> {
["fun.guitar"]
= 0, ["jackhammer"] = 0, ["icepick.salvaged"] = 0, ["pickaxe"] = 0, ["stone.pickaxe"] = 0, ["rock"] = 0, ["hatchet"] = 0, ["stonehatchet"] = 0, ["explosive.satchel"] = 0, ["hammer"] = 0, ["torch"] = 0
}
, ["transport"] = new Dictionary<string, ulong> {
["snowmobile"]
= 0
}
}
}
;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<SkinConfig>();
}
catch {
PrintWarning(LanguageEnglish ? "Configuration read error! Creating a default configuration!" : "Ошибка чтения конфигурации! Создание дефолтной конфигурации!");
LoadDefaultConfig();
}
if(!config.Setting.ReissueActiveItem) config.Setting.ShiftUI = false;
if(config.Setting.SkinCommandList == null) config.Setting.SkinCommandList = new List<string> {
"skin"
}
;
if(config.Setting.SkinKitCommandList == null) config.Setting.SkinKitCommandList = new List<string> {
"skinkit"
}
;
if(config.Setting.SkinEntityCommandList == null) config.Setting.SkinEntityCommandList = new List<string> {
"skinentity"
}
;
if(config.Setting.SkinItemCommandList == null) config.Setting.SkinItemCommandList = new List<string> {
"skinitem"
}
;
config.KitsCPSetting = config.KitsCPSetting.OrderByDescending(x => x.Value).ToDictionary(k => k.Key, v => v.Value);
SaveConfig();
}
protected override void LoadDefaultConfig() => config = SkinConfig.GetNewConfiguration();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Data
internal class Data {
public bool ChangeSI;
public bool ChangeSCL;
public bool ChangeSE;
public bool ChangeSG;
public bool ChangeSP;
public bool ChangeSGN;
public bool ChangeSC;
public bool UseSprayC;
public bool UseSoundE;
public bool Comfort;
public bool ComfortP;
public Dictionary<string, Dictionary<string, ulong>> Kits = new Dictionary<string, Dictionary<string, ulong>>();
public Dictionary<string, ulong> Skins = new Dictionary<string, ulong>();
}
private Dictionary<ulong, Data> StoredData = new Dictionary<ulong, Data>();
private Dictionary<ulong, bool> StoredDataFriends = new Dictionary<ulong, bool>();
private Dictionary<string, List<ulong>> StoredDataSkins = new Dictionary<string, List<ulong>>();
private Dictionary<ulong, string> StoredDataSkinsName = new Dictionary<ulong, string>();
private void LoadData(BasePlayer player) {
ulong userID = player.userID;
if(Interface.Oxide.DataFileSystem.ExistsDatafile($"XDataSystem/XSkinMenu/UserSettings/{userID}")) {
var Data = Interface.Oxide.DataFileSystem.ReadObject<Data>($"XDataSystem/XSkinMenu/UserSettings/{userID}");
StoredData[userID] = Data ?? DATA();
}
else StoredData[userID] = DATA();
if(!StoredDataFriends.ContainsKey(userID)) StoredDataFriends.Add(userID, config.PSetting.ChangeF);
var list = StoredData[userID].Skins;
foreach(var skin in StoredDataSkins) {
string key = skin.Key;
if(!list.ContainsKey(key)) list.Add(key, _items.ContainsKey(key) ? _items[key] : 0);
}
StoredData[userID].Skins = list;
}
private Data DATA() {
Data data = new Data();
data.ChangeSI = config.PSetting.ChangeSI;
data.ChangeSCL = config.PSetting.ChangeSCL;
data.ChangeSE = config.PSetting.ChangeSE;
data.ChangeSG = config.PSetting.ChangeSG;
data.ChangeSP = config.PSetting.ChangeSP;
data.ChangeSGN = config.PSetting.ChangeSGN;
data.ChangeSC = config.PSetting.ChangeSC;
data.UseSprayC = config.PSetting.UseSprayC;
data.UseSoundE = config.PSetting.UseSoundE;
data.Comfort = config.PSetting.Comfort;
return data;
}
private void SaveDataSkins() {
if(StoredDataSkins != null && StoredDataSkins.Count != 0) Interface.Oxide.DataFileSystem.WriteObject("XDataSystem/XSkinMenu/Skins", StoredDataSkins);
}
private void SaveDataSkinsName() {
if(StoredDataSkinsName != null && StoredDataSkinsName.Count != 0) Interface.Oxide.DataFileSystem.WriteObject("XDataSystem/XSkinMenu/SkinsName", StoredDataSkinsName);
}
private void SaveData(BasePlayer player) {
ulong userID = player.userID;
if(StoredData.ContainsKey(userID)) Interface.Oxide.DataFileSystem.WriteObject($"XDataSystem/XSkinMenu/UserSettings/{userID}", StoredData[userID]);
}
private void Unload() {
foreach(BasePlayer player in BasePlayer.activePlayerList) {
SaveData(player);
CuiHelper.DestroyUi(player, BgMainLayer);
CuiHelper.DestroyUi(player, ".SetItem");
CuiHelper.DestroyUi(player, BgKitsLayer);
}
foreach(var coroutine in _coroutineListCollections) if(coroutine.Value != null) ServerMgr.Instance.StopCoroutine(coroutine.Value);
if(StoredDataFriends != null && StoredDataFriends.Count != 0) Interface.Oxide.DataFileSystem.WriteObject("XDataSystem/XSkinMenu/Friends", StoredDataFriends);
}
#endregion
#region Commands
private void cmdOpenGUI(BasePlayer player, string command, string[] args) {
if(!permission.UserHasPermission(player.UserIDString, permUse)) SendReply(player, lang.GetMessage("NOPERM", this, player.UserIDString));
else GUI(player);
}
private void cmdOpenKitsGUI(BasePlayer player, string command, string[] args) {
if(!permission.UserHasPermission(player.UserIDString, permUse)) SendReply(player, lang.GetMessage("NOPERM", this, player.UserIDString));
else {
if(config.Setting.EnableDefaultKits || config.Setting.EnableCustomKits) SkinKitsGUI(player, true);
}
}
private void cmdSetSkinEntity(BasePlayer player, string command, string[] args) {
if(!permission.UserHasPermission(player.UserIDString, permEntity)) {
SendReply(player, lang.GetMessage("NOPERM", this, player.UserIDString));
return;
}
if(StoredData[player.userID].ChangeSE) EntitySkin(player);
}
private void cmdSetSkinItem(BasePlayer player, string command, string[] args) {
if(!permission.UserHasPermission(player.UserIDString, permSkinI)) {
SendReply(player, lang.GetMessage("NOPERM", this, player.UserIDString));
return;
}
Item item = player.GetActiveItem();
if(item != null) {
string shortname = _redirectSkins.ContainsKey(item.info.shortname) ? _redirectSkins[item.info.shortname] : item.info.shortname;
if(config.Setting.Blacklist.Contains(item.skin)) {
EffectNetwork.Send(new Effect("assets/bundled/prefabs/fx/invite_notice.prefab", player, 0, new Vector3(), new Vector3()), player.Connection);
return;
}
if(StoredDataSkins.ContainsKey(shortname) && _items.ContainsKey(shortname)) SetItemGUI(player, shortname);
}
}
[ConsoleCommand("xbuildingskinmenu_open")]
private void ccmdXBuildingSkinMenuOpen(ConsoleSystem.Arg args) {
BasePlayer player = args.Player();
if(player != null) XBuildingSkinMenu?.Call("cmdOpenGUIB", player, null, null);
}
[ConsoleCommand("skin_c")]
private void ccmdCategoryS(ConsoleSystem.Arg args) {
BasePlayer player = args.Player();
if(!permission.UserHasPermission(player.UserIDString, permUse)) {
SendReply(player, lang.GetMessage("NOPERM", this, player.UserIDString));
return;
}
if(Cooldowns.ContainsKey(player)) if(Cooldowns[player].Subtract(DateTime.Now).TotalSeconds >= 0) return;
Effect x = new Effect("assets/bundled/prefabs/fx/notice/loot.drag.grab.fx.prefab", player, 0, new Vector3(), new Vector3());
Effect z = new Effect("assets/bundled/prefabs/fx/weapons/survey_charge/survey_charge_stick.prefab", player, 0, new Vector3(), new Vector3());
Effect y = new Effect("assets/prefabs/deployable/repair bench/effects/skinchange_spraypaint.prefab", player, 0, new Vector3(), new Vector3());
switch(args.Args[0]) {
case "category" : {
CategoryGUI(player, int.Parse(args.Args[2]));
ItemGUI(player, args.Args[1]);
if(StoredData[player.userID].UseSoundE) EffectNetwork.Send(x, player.Connection);
Cooldowns[player] = DateTime.Now.AddSeconds(0.5f);
break;
}
case "skin" : {
if(StoredData[player.userID].Comfort) {
string category = args.Args[2], item = args.Args[1];
int page = int.Parse(args.Args[3]);
ItemGUI(player, category, page, item);
SkinGUI(player, item, 0, category, page);
}
else SkinGUI(player, args.Args[1]);
if(StoredData[player.userID].UseSoundE) EffectNetwork.Send(x, player.Connection);
if(!StoredData[player.userID].Comfort) CuiHelper.DestroyUi(player, ".ItemGUI");
Cooldowns[player] = DateTime.Now.AddSeconds(0.5f);
break;
}
case "searchskin" : {
if(StoredData[player.userID].Comfort) {
if(args.Args.Length >= 5) SkinGUI(player, args.Args[1], 0, args.Args[2], int.Parse(args.Args[3]), string.Join(" ", args.Args.Skip(4)).ToLower());
else if(args.Args.Length >= 4) SkinGUI(player, args.Args[1], 0, args.Args[2], int.Parse(args.Args[3]));
}
else {
if(args.Args.Length >= 4) SkinGUI(player, args.Args[1], 0, args.Args[2], 0, string.Join(" ", args.Args.Skip(3)).ToLower());
else if(args.Args.Length >= 3) SkinGUI(player, args.Args[1], 0, args.Args[2], 0);
}
if(StoredData[player.userID].UseSoundE) EffectNetwork.Send(x, player.Connection);
Cooldowns[player] = DateTime.Now.AddSeconds(0.5f);
break;
}
case "searchskinmini" : {
if(args.Args.Length >= 4) SetItemGUI(player, args.Args[1], 0, bool.Parse(args.Args[2]), string.Join(" ", args.Args.Skip(3)).ToLower());
else if(args.Args.Length >= 3) SetItemGUI(player, args.Args[1], 0, bool.Parse(args.Args[2]));
if(StoredData[player.userID].UseSoundE) EffectNetwork.Send(x, player.Connection);
Cooldowns[player] = DateTime.Now.AddSeconds(0.5f);
break;
}
case "openkit" : {
if(config.Setting.EnableDefaultKits || config.Setting.EnableCustomKits) {
CategoryGUI(player, -1);
SkinKitsGUI(player);
}
break;
}
case "setskinentity" : {
if(player.CanBuild() && (StoredData[player.userID].UseSprayC && permission.UserHasPermission(player.UserIDString, permSprayC) || StoredData[player.userID].ChangeSE && permission.UserHasPermission(player.UserIDString, permEntity))) {
var entity = GetRHitEntity(player);
if(entity == null) return;
if(!(entity is BaseVehicle)) {
string item = args.Args[1];
ulong skin = ulong.Parse(args.Args[2]);
if(entity.OwnerID == player.userID || player.currentTeam != 0 && player.Team.members.Contains(entity.OwnerID) && StoredDataFriends.ContainsKey(entity.OwnerID) && StoredDataFriends[entity.OwnerID]) {
if(_adminSkins.Contains(skin) && !permission.UserHasPermission(player.UserIDString, permAdminS)) return;
if(_vipSkins.Contains(skin) && !permission.UserHasPermission(player.UserIDString, permVipS)) return;
if(entity is BuildingBlock block && block.HasWallpaper()) {
if("wallpaper" == item && StoredDataSkins.ContainsKey("wallpaper") && (StoredDataSkins["wallpaper"].Contains(skin) || _adminAndVipSkins.Contains(skin) || skin == 0)) {
if(block.HasWallpaper(0) && block.CanSeeWallpaperSocket(player, 0)) block.SetWallpaper(skin, 0);
else if(block.HasWallpaper(1) && block.CanSeeWallpaperSocket(player, 1)) block.SetWallpaper(skin, 1);
Effect.server.Run("assets/prefabs/deployable/repair bench/effects/skinchange_spraypaint.prefab", entity.transform.localPosition);
}
}
else if(_shortnamesEntity.ContainsKey(entity.ShortPrefabName)) {
if(config.Setting.Blacklist.Contains(entity.skinID)) {
EffectNetwork.Send(new Effect("assets/bundled/prefabs/fx/invite_notice.prefab", player, 0, new Vector3(), new Vector3()), player.Connection);
return;
}
string shortname = _shortnamesEntity[entity.ShortPrefabName];
if(shortname == item && StoredDataSkins.ContainsKey(shortname) && (StoredDataSkins[shortname].Contains(skin) || _adminAndVipSkins.Contains(skin) || skin == 0)) SetSkinEntity(player, entity, shortname, skin);
}
}
}
}
Cooldowns[player] = DateTime.Now.AddSeconds(1.5f);
break;
}
case "setskinitem" : {
Item item = player.GetActiveItem();
if(item != null && permission.UserHasPermission(player.UserIDString, permSkinI)) {
string shortname = _redirectSkins.ContainsKey(item.info.shortname) ? _redirectSkins[item.info.shortname] : item.info.shortname, sitem = args.Args[1];
ulong skin = ulong.Parse(args.Args[2]);
if(config.Setting.Blacklist.Contains(item.skin)) {
EffectNetwork.Send(new Effect("assets/bundled/prefabs/fx/invite_notice.prefab", player, 0, new Vector3(), new Vector3()), player.Connection);
Cooldowns[player] = DateTime.Now.AddSeconds(0.5f);
return;
}
if(_adminSkins.Contains(skin) && !permission.UserHasPermission(player.UserIDString, permAdminS)) return;
if(_vipSkins.Contains(skin) && !permission.UserHasPermission(player.UserIDString, permVipS)) return;
if(shortname == sitem && StoredDataSkins.ContainsKey(shortname) && (StoredDataSkins[shortname].Contains(skin) || _adminAndVipSkins.Contains(skin) || skin == 0)) {
if(StoredData[player.userID].ChangeSG) {
StoredData[player.userID].ChangeSG = false;
SSI(player, item, skin, shortname, false, config.Setting.ReissueActiveItem);
StoredData[player.userID].ChangeSG = true;
}
else SSI(player, item, skin, shortname, false, config.Setting.ReissueActiveItem);
EffectNetwork.Send(y, player.Connection);
}
}
Cooldowns[player] = DateTime.Now.AddSeconds(1.5f);
// Don't touch here!!! | Здесь не трогать!!! =)
break;
}
case "setskin" : {
string item = args.Args[1];
ulong skin = ulong.Parse(args.Args[2]);
if(!permission.UserHasPermission(player.UserIDString, permSkinC) || !StoredData[player.userID].Skins.ContainsKey(item)) return;
if(_adminSkins.Contains(skin) && !permission.UserHasPermission(player.UserIDString, permAdminS)) return;
if(_vipSkins.Contains(skin) && !permission.UserHasPermission(player.UserIDString, permVipS)) return;
if(!(StoredDataSkins[item].Contains(skin) || _adminAndVipSkins.Contains(skin))) return;
StoredData[player.userID].Skins[item] = skin;
if(!permission.UserHasPermission(player.UserIDString, permInv)) SendReply(player, lang.GetMessage("NOPERM", this, player.UserIDString));
else {
if(StoredData[player.userID].ChangeSI) SetSkinItem(player, item, skin);
if(config.GUI.SkinUP) {
if(StoredData[player.userID].Comfort) {
string category = args.Args[4];
int page = int.Parse(args.Args[5]);
ItemGUI(player, category, page, item);
if(args.Args.Length >= 7) SkinGUI(player, item, int.Parse(args.Args[3]), category, page, string.Join(" ", args.Args.Skip(6)).ToLower());
else SkinGUI(player, item, int.Parse(args.Args[3]), category, page);
}
else {
if(args.Args.Length >= 5) SkinGUI(player, item, int.Parse(args.Args[3]), "null", 0, string.Join(" ", args.Args.Skip(4)).ToLower());
else SkinGUI(player, item, int.Parse(args.Args[3]));
}
}
}
EffectNetwork.Send(y, player.Connection);
Cooldowns[player] = DateTime.Now.AddSeconds(1.5f);
// Don't touch here!!! | Здесь не трогать!!! =)
break;
}
case "clear" : {
if(!permission.UserHasPermission(player.UserIDString, permSkinC)) return;
string item = args.Args[1];
StoredData[player.userID].Skins[item] = 0;
CuiHelper.DestroyUi(player,
// ... [Code preview truncated due to length. Full source in attached file] ...