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 System.Collections;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Facepunch.Extend;
using Facepunch;
using System.Reflection;
namespace Oxide.Plugins {
[Info("SkinController", "Amino", "2.0.10")]
[Description("An advanced skin system for Rust")]
public class SkinController : RustPlugin {
[PluginReference]
private Plugin Backpacks, Kits, KitController, WelcomeController, ImageLibrary;
#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 = "UI Performance mod")]
public bool UIPerformanceMode {
get;
set;
}
= true;
[JsonProperty(PropertyName = "Permission: Max outfits (Recommend to keep to a low amount)")]
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 = "Skin item cooldown (seconds)")]
public int ItemSkinCooldownSeconds {
get;
set;
}
= 1;
[JsonProperty(PropertyName = "Wait time between skinning new item (Skin base command)")]
public float BaseSkinWait {
get;
set;
}
= 0.10f;
[JsonProperty(PropertyName = "Change item name to skin name")]
public bool ChangeItemName = true;
[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;
[JsonProperty(PropertyName = "Play sound on skin")]
public bool SoundOnSkin {
get;
set;
}
= true;
[JsonProperty(PropertyName = "UI Title (UIImage will take priority if present)")]
public string UITitle {
get;
set;
}
= "SKINS";
[JsonProperty(PropertyName = "UI Banner (810 x 88)")]
public string UIImage {
get;
set;
}
= "https://i.ibb.co/0mPRNQD/SkinsP2.png";
[JsonProperty(PropertyName = "Settings icon")]
public string SettingsIcon = "https://i.ibb.co/ckPQhd1/Settings-Cog.png";
[JsonProperty(PropertyName = "Edit icon")]
public string EditIcon = "https://i.ibb.co/YkcgybW/Pencil-Icon.png";
[JsonProperty(PropertyName = "Invalid item icon")]
public string InvalidItemIcon = "https://i.ibb.co/LZXNRth/chk.png";
[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 UIElements UISettings = new UIElements();
[JsonProperty(PropertyName = "Workshop skins (Manually added)")]
public List<SkinData> AddedSkins {
get;
set;
}
= new List<SkinData>();
[JsonProperty(PropertyName = "Blacklisted Skins")]
public List<ulong> BlacklistedSkins {
get;
set;
}
= new List<ulong>();
[JsonProperty(PropertyName = "Disallowed skinning of items with x skin ID (If an item has this skin ID it cannot be skinned)")]
public List<ulong> DisallowedSkinIds {
get;
set;
}
= new List<ulong>();
public static SkinnerConfig DefaultConfig() {
return new SkinnerConfig {
Commands = new SkinCommands {
SkinMenuCommand = new List<string> {
"skin", "sb", "skins", "skinbox"
}
, SkinOutfitCommand = new List<string> {
"outfits", "outfit", "loadout"
}
, 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 UIElements {
public string UIBackgroundColor {
get;
set;
}
= "0 0 0.6";
public string UIPrimaryColor {
get;
set;
}
= "0 0 0.6";
public string UISecondaryColor {
get;
set;
}
= "0 0 0.5";
public string UIItemButtonColor {
get;
set;
}
= "1 1 1.175";
public string UISkinPanelColor {
get;
set;
}
= "1 1 1.175";
public string UISearchPanelColor {
get;
set;
}
= "0 0 0.5";
public string UICloseButtonColor {
get;
set;
}
= "1.4 0.5";
public string UIButtonColor {
get;
set;
}
= "1.4 0.5";
public string UISecondaryButtonColor {
get;
set;
}
= ".29.29.29.5";
public string UIActiveButtonColor {
get;
set;
}
= "1.4 0.5";
public string UIActiveCategoryColor {
get;
set;
}
= ".29.29.29.5";
public string PrimaryButtonTextColor {
get;
set;
}
= ".32.89.26.8";
public string UISafeButtonColor {
get;
set;
}
= "1.34.34.8";
public string UIDangerButtonColor {
get;
set;
}
= "1.34.34.8";
public string UIScrollBarColor {
get;
set;
}
= "1.4 0.5";
public string UIValidItemColor {
get;
set;
}
= "0 0 0.4";
public string UIInvalidItemColor {
get;
set;
}
= "0 0 0.8";
public string UISelectedItemColor {
get;
set;
}
= "1.4 0.5";
public string UISettingsPanelBlurColor {
get;
set;
}
= "0 0 0.5";
public string UISettingsPanelOverlayColor {
get;
set;
}
= "0 0 0.2";
public string UISettingsPanelColor {
get;
set;
}
= "1 1 1.15";
public string UISecondarySettingsPanelColor {
get;
set;
}
= "1 1 1.2";
public string UISelectPanelBlurColor {
get;
set;
}
= "0 0 0.5";
public string UISelectPanelColor {
get;
set;
}
= ".17.17.17.7";
public string UISecondarySelectPanelColor {
get;
set;
}
= "1 1 1.2";
public string UIApplySelectColor {
get;
set;
}
= "1 1 1.3";
public string UIFindSelectColor {
get;
set;
}
= "1 1 1.25";
public string UISkinSelectColor {
get;
set;
}
= "1 1 1.35";
public string UISkinCommandPanelColor {
get;
set;
}
= ".17.17.17 1";
public string UISkinCommandPageButtonColor {
get;
set;
}
= "1 1 1.13";
public string UISkinCommandPagePanelColor {
get;
set;
}
= "1 1 1.1";
public string UISkinCommandCloseButtonColor {
get;
set;
}
= "1 1 1.1";
public string UISkinCommandTitleColor {
get;
set;
}
= "1 1 1.1";
public string UISkinCommandSkinPanelColor {
get;
set;
}
= "1 1 1.1";
public string UISavePanelBlurColor {
get;
set;
}
= "0 0 0.5";
public string UISavePanelColor {
get;
set;
}
= ".17.17.17.7";
public string UISaveTitleColor {
get;
set;
}
= "1 1 1.2";
public string UISaveSecondaryColor {
get;
set;
}
= "1 1 1.15";
public string UISaveCloseColor {
get;
set;
}
= "1 1 1.2";
public string UISaveOverrideColor {
get;
set;
}
= "1 1 1.17";
public string UISaveColor {
get;
set;
}
= "1.4 0.4";
}
public class SkinCommands {
[JsonProperty(PropertyName = "Skin menu command")]
public List<string> SkinMenuCommand {
get;
set;
}
= new List<string>();
[JsonProperty(PropertyName = "Outfit UI command")]
public List<string> SkinOutfitCommand {
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;
private static UIElements _uiColors;
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();
_uiColors = _config.UISettings;
if (_config.UIImage == "https://i.ibb.co/3SNBq4W/Adv-Skinner.png") _config.UIImage = "https://i.ibb.co/0mPRNQD/SkinsP2.png";
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
public Dictionary<int, List<SkinData>> _skinList = new Dictionary<int, List<SkinData>>();
public Dictionary<string, List<int>> _categoryList = new Dictionary<string, List<int>>();
public Dictionary<int, int> _itemRedirects = new Dictionary<int, int>();
public bool usingWC = false;
public Dictionary<ulong, PlayerSettings> _playerSettings = new Dictionary<ulong, PlayerSettings>();
public List<string> _uiCategories = new List<string>() {
"Weapon", "Attire", "Items", "Tool", "Construction"
}
;
public Dictionary<ulong, BaseEntity> _playerSkinItems = new Dictionary<ulong, BaseEntity>();
public bool SkinsGenerated = false;
public List<OptionalSettings> _optionalSettings = new List<OptionalSettings>();
public Dictionary<ulong, DateTime> _cooldowns = new Dictionary<ulong, DateTime>();
public class OptionalSettings {
public string Permission = string.Empty;
public bool CanUse {
get;
set;
}
= true;
public string SettingName {
get;
set;
}
= String.Empty;
public bool Enabled {
get;
set;
}
= true;
}
public class PlayerOptionalSettings {
public string SettingName {
get;
set;
}
= String.Empty;
public bool Enabled {
get;
set;
}
= true;
}
public class SkinData {
public string SkinName {
get;
set;
}
= String.Empty;
public ulong SkinID {
get;
set;
}
= 0;
public string ItemShortname {
get;
set;
}
= String.Empty;
public int ItemID {
get;
set;
}
= 0;
public string SkinPermission {
get;
set;
}
= String.Empty;
public Redir Redirect = new Redir();
}
public class Redir {
public bool IsRedirect {
get;
set;
}
= false;
public string Shortname {
get;
set;
}
= String.Empty;
public int ItemId {
get;
set;
}
= 0;
}
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 ulong SkinId {
get;
set;
}
public string Shortname {
get;
set;
}
}
public class PlayerSettings {
public long LastUsed = 0;
public int SkinPage = 0;
public int ItemPage = 0;
public int LastItemPage = 0;
public int LoadoutPage = 0;
public DateTime ItemSkinCooldown {
get;
set;
}
public List<PlayerOptionalSettings> PlayerOptionalSettings {
get;
set;
}
= new List<PlayerOptionalSettings>();
public bool AdvacedPlacedItemSkinning {
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 string SkinsFilter {
get;
set;
}
= null;
public string LoadedItems {
get;
set;
}
= null;
public string ActiveSaveName {
get;
set;
}
public long BaseSkinCooldown {
get;
set;
}
= 0;
public IndSettings IndSettings {
get;
set;
}
= new IndSettings();
public UIPosition ItemUIPostition = new UIPosition();
public List<OutfitDetail> SavedItems {
get;
set;
}
= new List<OutfitDetail>();
public List<Outfits> Outfits {
get;
set;
}
= new List<Outfits>();
}
public ulong FalseSkinId = 99811111172;
public class IndSettings {
public int ItemID = 0;
public ulong SkinID = 0;
public int ItemPos = -1;
public int SelectedItemId = 0;
public UIPosition SelectedUIPosition = new UIPosition();
public UIPosition LastUIPosition = new UIPosition();
public List<InvItem> InventoryItems = new List<InvItem>();
}
public class InvItem {
public int ItemId = 0;
public ulong SkinId = 0;
public int NewItemId = 0;
public int Position = 0;
public int Category = 0;
public ulong NewSkinId = 99811111172;
}
public class UIPosition {
public string yMin = string.Empty;
public string yMax = string.Empty;
public string xMin = string.Empty;
public string xMax = string.Empty;
}
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 Lang
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["Close"]
= "CLOSE", ["Settings"] = "SETTINGS", ["OutfitText"] = "LOADED OUTFIT: {0}", ["ApplyToInv"] = "APPLY TO INVENTORY", ["ManageOutfits"] = "MANAGE OUTFITS", ["Weapon"] = "WEAPONS", ["Attire"] = "CLOTHING", ["Items"] = "DEPLOYABLES", ["Tool"] = "TOOLS", ["Construction"] = "CONSTRUCTION", ["Search"] = "SEARCH", ["SkinButton"] = "SKIN", ["SetButton"] = "SET", ["Favorite"] = "FAVORITE", ["Favorited"] = "FAVORITED", ["NewSet"] = "+ NEW SET", ["Delete"] = "DELETE", ["Clear"] = "CLEAR", ["Edit"] = "EDIT", ["Save"] = "SAVE", ["SaveNewOutfit"] = "SAVE NEW OUTFIT", ["OutfitName"] = "OUTFIT NAME", ["OutfitEditor"] = "OUTFIT EDITOR", ["NamePlaceholder"] = "SET NAME", ["SkinCount"] = "{0} SKINS", ["NoOutfit"] = "No outfit", ["NoSkinsAvail"] = "NO SKINS AVAILABLE", ["OverrideOutfit"] = "OVERRIDE OUTFIT\n[ {0} ]", ["AutoSkinPickup"] = "Auto skin on item pickup", ["AutoSkinCraft"] = "Auto skin on item crafted", ["AutoSkinKitRedeem"] = "Auto skin on kit redeemed", ["SimpleSkinItemCommand"] = "Simple skin item command", ["FavoriteFallback"] = "Favorite fallback", ["OutfitNameSaved"] = "You already have an outfit with the name {0}", ["NoSkinFound"] = "Could not find a skin!", ["OutfitNameCharLimit"] = "Outfit name cannot be longer than 20 characters", ["OutfitSaveCount"] = "You've exceeded your save limit of {0}", ["NoPermission"] = "No permission to use this command", ["SkinningContainer"] = "Skinning items in container", ["NotAuthed"] = "You can only do this in a building authed zone", ["NotValidDeployable"] = "Not a valid deployable", ["SkinningBase"] = "Skinning base",
}
, this, "en");
}
private string Lang(string key, string id = null, params object[] args) => string.Format(lang.GetMessage(key, this, id), args);
#endregion
#region Import Constructors
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;
}
}
#endregion
#region Import Skins
private void GetCollection(BasePlayer player, string[] args, bool isChat = false, ConsoleSystem.Arg arg = null) {
if (args == null || args.Length == 0) {
DetermineReply(player, isChat, "No collection id provided", arg);
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, $"Collection {args[0]} didn't return code 200 on request", arg);
return;
}
if (response == null) {
DetermineReply(player, isChat, $"Collection {args[0]} not found, null reply", arg);
return;
}
var collectionResponse = JsonConvert.DeserializeObject<CollectionRoot>(response);
if (collectionResponse.response.collectiondetails[0].children == null) {
DetermineReply(player, isChat, $"Collection {args[0]} not found", arg);
return;
}
else DetermineReply(player, isChat, $"Importing {collectionResponse.response.collectiondetails[0].children.Count} skins from collection [ {args[0]} ]", arg);
GetSkin(player, collectionResponse.response.collectiondetails[0].children.Select(x => x.publishedfileid).ToArray(), isChat, arg);
}
, this, RequestMethod.POST);
}
catch {
}
}
void GetSkin(BasePlayer player, string[] args, bool isChat = false, ConsoleSystem.Arg arg = null) {
List<string> strings = new List<string>() {
""
}
;
List<int> amounts = new List<int>() {
0
}
;
int i = 0;
int page = 0;
foreach (var skinid in args) {
if (i == 99) {
strings.Add("");
amounts.Add(0);
page++;
i = 0;
}
strings[page] = strings[page] + $"&publishedfileids[{i}]={skinid}";
i++;
amounts[page] = amounts[page] + 1;
}
i = 0;
foreach (string skin in strings) {
HandleWorkshopPage(player, isChat, skin, amounts[i], arg);
i++;
}
}
private void HandleWorkshopPage(BasePlayer player, bool isChat, string str, int amount, ConsoleSystem.Arg arg = null) {
try {
webrequest.Enqueue("https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/", $"?itemcount={amount}{str}", (code, response) => {
if (code != 200) {
DetermineReply(player, isChat, "Error adding skin, not a 200 response.", arg);
return;
}
if (response == null) {
DetermineReply(player, isChat, "Error adding skin, not a valid response.", arg);
return;
}
var workshopSkin = JsonConvert.DeserializeObject<AddSkinRoot>(response);
DetermineReply(player, isChat, $"Importing {workshopSkin.response.publishedfiledetails.Count} skin(s)!", arg);
int pendingSkins = workshopSkin.response.publishedfiledetails.Count;
foreach (var skin in workshopSkin.response.publishedfiledetails) {
ServerMgr.Instance.StartCoroutine(AddWorkshopSkin(skin, () => {
pendingSkins--;
if (pendingSkins == 0) {
SaveConfig();
}
}
));
}
}
, this, RequestMethod.POST);
}
catch {
DetermineReply(player, isChat, $"Error getting skin info.", arg);
}
}
private IEnumerator AddWorkshopSkin(PublishedFileDetail skin, Action onComplete) {
if (skin == null || skin.tags == null || string.IsNullOrEmpty(skin.publishedfileid) || string.IsNullOrEmpty(skin.title)) yield return null;
var tags = skin.tags;
if (tags == null) yield return null;
ulong skinId = ulong.Parse(skin.publishedfileid);
if (_config.AddedSkins.Any(x => x.SkinID == skinId)) yield return null;
ClassedItem foundItem = null;
if (tags != null) foreach (var tag in tags) {
if (tag == null || tag?.tag == null) continue;
var item = _workshopRename.FirstOrDefault(x => x.Key == tag?.tag?.ToLower().Replace("skin", "").Replace(" ", "").Replace("-", "").Replace(".item", ""));
if (item.Value == null) continue;
else {
if (item.Value.ItemID == 550753330) continue;
foundItem = item.Value;
break;
}
}
else yield return null;
if (foundItem != null) {
bool hasItem = _skinList.ContainsKey(foundItem.ItemID);
if (!hasItem) yield return null;
bool isAlready = _skinList[foundItem.ItemID].Any(x => x.SkinID == skinId);
var skinInfo = new SkinData() {
SkinName = skin.title, ItemID = foundItem.ItemID, ItemShortname = foundItem.Shortname, SkinID = skinId
}
;
_config.AddedSkins.Add(skinInfo);
if (!isAlready) _skinList[foundItem.ItemID]?.Add(skinInfo);
}
onComplete?.Invoke();
}
private void DetermineReply(BasePlayer player, bool isChat, string reply, ConsoleSystem.Arg arg = null) {
if (isChat) SendReply(player, reply);
else {
if (arg.Connection == null) Interface.Oxide.LogInfo(reply);
else SendReply(arg, reply);
}
}
private bool CheckPlayerSkinPermission(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;
}
#endregion
#region Hooks
public static Dictionary<string, string> ConvertToDictionary(UIElements uiElements) {
var dictionary = new Dictionary<string, string>();
foreach (PropertyInfo property in typeof(UIElements).GetProperties()) {
string key = property.Name;
string value = property.GetValue(uiElements)?.ToString();
dictionary[key] = value;
}
return dictionary;
}
void OnWCRequestColors(string pluginName) {
if (!pluginName.Equals("SkinController", StringComparison.OrdinalIgnoreCase)) return;
Interface.CallHook("WCSendColors", ConvertToDictionary(_uiColors), pluginName);
}
void OnWCSentThemeColors(List<string> pluginNames, Dictionary<string, string> themeColors) {
if (!pluginNames.Contains("SkinController")) return;
_config.UISettings.UIBackgroundColor = themeColors["BackgroundColor"];
_config.UISettings.UIPrimaryColor = themeColors["BackgroundColor"];
_config.UISettings.UISecondaryColor = themeColors["SecondaryColor"];
_config.UISettings.UICloseButtonColor = themeColors["PrimaryButtonColor"];
_config.UISettings.UIButtonColor = themeColors["PrimaryButtonColor"];
_config.UISettings.UIActiveButtonColor = themeColors["PrimaryButtonColor"];
_config.UISettings.UIScrollBarColor = themeColors["PrimaryButtonColor"];
_config.UISettings.UISelectedItemColor = themeColors["PrimaryButtonColor"];
_config.UISettings.UISaveColor = themeColors["ThirdButtonColor"];
_config.UISettings.UISafeButtonColor = themeColors["SecondaryButtonColor"];
_config.UISettings.UIDangerButtonColor = themeColors["SecondaryButtonColor"];
SaveConfig();
}
void OnServerInitialized(bool initial) {
var isUsingWC = Interface.Call("IsUsingPlugin", "SkinController");
if (isUsingWC != null && (isUsingWC is bool)) usingWC = (bool)isUsingWC;
else usingWC = false;
_categoryList.Add("Weapon", new List<int> {
1545779598, -1812555177, 1318558775, -2069578888, 1588298435, -778367295, 442886268
}
);
_categoryList.Add("Attire", new List<int> {
-194953424, 1751045826, 1110385766, 1850456855, 237239288, -1549739227, -699558439, -803263829, -2002277461, 1266491000
}
);
_categoryList.Add("Tool", new List<int> {
1488979457
}
);
_categoryList.Add("Construction", new List<int> {
1390353317
}
);
_categoryList.Add("Items", new List<int> {
1534542921
}
);
if (_config.SkinItemsOnCraft) _optionalSettings.Add(new OptionalSettings {
CanUse = true, Enabled = true, SettingName = "AutoSkinCraft", Permission = "skincontroller.skinoncraft"
}
);
if (_config.SkinItemsOnPickup) _optionalSettings.Add(new OptionalSettings {
CanUse = true, Enabled = true, SettingName = "AutoSkinPickup", Permission = "skincontroller.skinonpickup"
}
);
if (_config.SkinKitsOnRedeemed) _optionalSettings.Add(new OptionalSettings {
CanUse = true, Enabled = true, SettingName = "AutoSkinKitRedeem", Permission = "skincontroller.skinonkitredeemed"
}
);
_optionalSettings.Add(new OptionalSettings {
CanUse = true, Enabled = true, SettingName = "FavoriteFallback"
}
);
_optionalSettings.Add(new OptionalSettings {
CanUse = true, Enabled = true, SettingName = "SimpleSkinItemCommand"
}
);
HandleCommands();
HandlePermissions();
ImportImages();
RequestSkins();
StatLastUpdatedCheck();
UnsubscribeHooks();
}
void OnPlayerDisconnected(BasePlayer player, string reason) {
if (player == null || !player.userID.Get().IsSteamId()) return;
SavePlayerSettings(player);
_playerSettings.Remove(player.userID);
}
private void Unload() {
foreach (BasePlayer player in BasePlayer.activePlayerList) {
SavePlayerSettings(player);
CuiHelper.DestroyUi(player, "SCMainPanel");
}
_config = null;
}
void OnServerSave() {
foreach (var player in BasePlayer.activePlayerList) {
if (_playerSettings.ContainsKey(player.userID)) SavePlayerSettings(player);
}
}
void OnWCRequestedUIPanel(BasePlayer player, string panelName, string neededPlugin) {
if (!neededPlugin.Equals("SkinController", StringComparison.OrdinalIgnoreCase)) return;
usingWC = true;
UIMain(player, null, null);
}
void OnPluginLoaded(Plugin plugin) {
if (plugin.Name == "WelcomeController") {
var isUsingWC = Interface.Call("IsUsingPlugin", "SkinController");
if (isUsingWC != null && (isUsingWC is bool)) usingWC = (bool)isUsingWC;
else usingWC = false;
}
}
void OnPluginUnloaded(Plugin plugin) {
if (plugin.Name == "WelcomeController") {
usingWC = false;
HandleCommands();
}
}
private void OnKitRedeemed(BasePlayer player, string kitName) {
var playerSettings = GetOrLoadPlayerSettings(player);
if (!playerSettings.PlayerOptionalSettings.Any(x => x.SettingName == "AutoSkinKitRedeem" && x.Enabled)) return;
if (!permission.UserHasPermission(player.UserIDString, "skincontroller.skinonkitredeemed")) return;
List<Item> itemList = Pool.Get<List<Item>>();
player.inventory.GetAllItems(itemList);
if(itemList != null) SkinContainer(player, itemList, ref playerSettings, true);
Pool.FreeUnmanaged(ref itemList);
}
private void OnItemPickup(Item item, BasePlayer player) {
var playerSettings = GetOrLoadPlayerSettings(player);
if (!playerSettings.PlayerOptionalSettings.Any(x => x.SettingName == "AutoSkinPickup" && x.Enabled)) return;
if (!permission.UserHasPermission(player.UserIDString, "skincontroller.skinonpickup")) return;
SkinData skinInfo = FindSkin(player, ref playerSettings, item);
if (skinInfo == null) return;
if (item.skin == skinInfo.SkinID) return;
bool isOrigional = !skinInfo.Redirect.IsRedirect;
bool wasRedirect = CheckItemRedirect(item.info.itemid) != item.info.itemid;
if (skinInfo.Redirect.IsRedirect || wasRedirect) NextTick(() => RedirectItem(player, item, skinInfo, wasRedirect, isOrigional));
else SkinItem(item, skinInfo);
return;
}
void OnItemCraftFinished(ItemCraftTask task, Item item, ItemCrafter crafter) {
if (task == null || item?.info == null || crafter == null || crafter.owner == null) return;
var playerSettings = GetOrLoadPlayerSettings(crafter.owner);
if (!playerSettings.PlayerOptionalSettings.Any(x => x.SettingName == "AutoSkinCraft" && x.Enabled) || !permission.UserHasPermission(crafter.owner.UserIDString, "skincontroller.skinoncraft")) return;
SkinData skinInfo = FindSkin(crafter.owner, ref playerSettings, item);
if (skinInfo == null) return;
SkinItem(item, skinInfo);
return;
}
#endregion
#region Console Commands
[ConsoleCommand("skincontroller.addskin")]
private void CMDImportSkins(ConsoleSystem.Arg arg) {
var args = arg.Args;
if (args == null || args.Length == 0) {
DetermineReply(arg.Player(), false, "No skins provided.", arg);
return;
}
var hasPermission = CheckPlayerSkinPermission(arg.Player(), false, arg);
if (hasPermission) GetSkin(arg.Player(), arg.Args, false, arg);
}
[ConsoleCommand("skincontroller.addcollection")]
private void CMDImportCollection(ConsoleSystem.Arg arg) {
var hasPermission = CheckPlayerSkinPermission(arg.Player(), false, arg);
if (hasPermission) GetCollection(arg.Player(), arg.Args, false, arg);
}
[ConsoleCommand("sc_main")]
private void CMDMain(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (player == null) return;
if (!CheckCooldown(player.userID)) return;
var playerSettings = GetOrLoadPlayerSettings(player);
switch (arg.Args[0]) {
case "trycollection" : GetCollection(player, arg.Args.Skip(1).ToArray(), false, arg);
break;
case "tryskin" : GetSkin(player, arg.Args.Skip(1).ToArray(), false, arg);
break;
case "close" : if (usingWC) CuiHelper.DestroyUi(player, "WCMainPanel");
else CuiHelper.DestroyUi(player, "SCMainPanel");
break;
case "item" : SelectItem(player, playerSettings, arg.Args);
break;
case "category" : SelectCategory(player, playerSettings, arg.Args);
break;
case "editloadoutitem" : EditLoadoutItem(player, playerSettings, arg.Args);
break;
case "findskins" : FindSkins(player, playerSettings, arg.Args);
CuiHelper.DestroyUi(player, "SCSelectPanel");
break;
case "skinsfilter" : SkinsFilter(player, playerSettings, arg.Args);
break;
case "indfilter" : IndSkinsFilter(player, playerSettings, arg.Args);
break;
case "commandfilter" : CommandSkinsFilter(player, playerSettings, arg.Args);
break;
case "outfits" : playerSettings.LoadoutPage = 0;
UIInit(player, 1);
break;
case "skinitem" : SkinData skinInfo = _skinList[int.Parse(arg.Args[1])].FirstOrDefault(x => x.SkinID == ulong.Parse(arg.Args[2]));
if (skinInfo == null) return;
List<Item> itemList = Pool.Get<List<Item>>();
player.inventory.GetAllItems(itemList);
if(itemList != null) SkinContainer(player, itemList, ref playerSettings, false, skinInfo, isInventory : true);
Pool.FreeUnmanaged(ref itemList);
CuiHelper.DestroyUi(player, "SCSelectPanel");
break;
case "skininventory" : itemList = Pool.Get<List<Item>>();
player.inventor
// ... [Code preview truncated due to length. Full source in attached file] ...