C#:
/* Copyright (C) Whispers88 - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited
* Proprietary and confidential
* Written by Whispers88 rustafarian.server@gmail.com, December 2021
*/
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Networking;
namespace Oxide.Plugins
{
[Info("Skinner", "Whispers88", "1.3.7")]
[Description("Brings automation and ease to skinning items")]
public class Skinner : CovalencePlugin
{
static Skinner skinner;
private DynamicConfigFile _defaultSkins;
private const string permdefault = "skinner.default";
private const string permitems = "skinner.items";
private const string permcraft = "skinner.craft";
private const string permskininv = "skinner.skininv";
private const string permskincon = "skinner.skincon";
private const string permbypassauth = "skinner.bypassauth";
private const string permimport = "skinner.import";
private const string permskinbase = "skinner.skinbase";
private const string permskinall = "skinner.skinall";
private static List<string> _registeredhooks = new List<string> { "OnLootEntityEnd", "CanStackItem" };//, "OnMaxStackable" };
private Dictionary<ulong, Dictionary<string, CachedSkin>> _playerDefaultSkins = new Dictionary<ulong, Dictionary<string, CachedSkin>>();
private List<string> permissions = new List<string>() { permdefault, permcraft, permitems, permbypassauth, permskincon, permskininv, permimport, permskinbase, permskinall };
private Dictionary<ulong, CoolDowns> _playercooldowns = new Dictionary<ulong, CoolDowns>();
public class CoolDowns
{
public float skin = 30f;
public float skinitem = 30f;
public float skincraft = 30f;
public float skincon = 30f;
public float skininv = 30f;
public float skinbase = 60f;
public float skinall = 60f;
}
#region Init
private void OnServerInitialized()
{
skinner = this;
foreach (string perm in permissions)
permission.RegisterPermission(perm, this);
foreach (string perm in config.Cooldowns.Keys)
permission.RegisterPermission($"skinner.{perm}", this);
AddCovalenceCommand(config.cmdsskin, "SkinCMD");
AddCovalenceCommand(config.cmdsskincraft, "DefaultSkinsCMD");
AddCovalenceCommand(config.cmdsskinitems, "SkinItemCMD");
AddCovalenceCommand(config.cmdsskininv, "SkinInvCMD");
AddCovalenceCommand(config.cmdsskincon, "SkinConCMD");
AddCovalenceCommand(config.cmdskinimport, "SkinImportCMD");
AddCovalenceCommand(config.cmdskinbase, "SkinBaseCMD");
AddCovalenceCommand(config.cmdskinallitems, "SkinAllItemsCMD");
AddCovalenceCommand(new[] { "sbNextPage" }, "SBNextPageCMD");
AddCovalenceCommand(new[] { "sbBackPage" }, "SBBackPageCMD");
AddCovalenceCommand(new[] { "searchCMD" }, "SearchCMD");
//Convert Old Skins Config
foreach (var oldskin in config.Importedskins)
{
if (!config.ImportedSkinList.ContainsKey(oldskin.Key))
config.ImportedSkinList.Add(oldskin.Key, new ImportedItem());
}
config.Importedskins.Clear();
foreach (var skin in config.ImportedSkinList)
{
if (string.IsNullOrEmpty(skin.Value?.itemDisplayname ?? string.Empty) || string.IsNullOrEmpty(skin.Value?.itemShortname ?? string.Empty))
{
if (!_WorkshopSkinIDCollectionList.Contains(skin.Key.ToString()))
_WorkshopSkinIDCollectionList.Add(skin.Key.ToString());
}
}
//GetSkins();
if (getCollectionscouroutine != null)
{
Puts("getcollections already running!!");
}
else
{
getCollectionscouroutine = GetCollectionSkinIDS();
ServerMgr.Instance.StartCoroutine(getCollectionscouroutine);
}
}
private void Loaded()
{
_defaultSkins = Interface.Oxide.DataFileSystem.GetFile("DefaultCraftSkins");
LoadData();
}
private void Unload()
{
SaveData();
foreach (var player in _viewingcon)
{
BaseEntity baseEntity = player.inventory.loot?.entitySource ?? null;
if (baseEntity != null)
{
BoxController boxController;
if (baseEntity.TryGetComponent<BoxController>(out boxController))
{
UnityEngine.GameObject.Destroy(boxController);
}
}
}
foreach (var player in BasePlayer.activePlayerList)
{
CuiHelper.DestroyUi(player, "SkinPageUI");
CuiHelper.DestroyUi(player, "SkinSearchUI");
SpraycanController spraycanController;
if (player.TryGetComponent<SpraycanController>(out spraycanController))
{
UnityEngine.GameObject.Destroy(spraycanController);
}
}
if (getCollectionscouroutine != null)
ServerMgr.Instance.StopCoroutine(getCollectionscouroutine);
if (getSteamWorkshopSkinData != null)
ServerMgr.Instance.StopCoroutine(getSteamWorkshopSkinData);
}
private class CachedSkin
{
public string shortname = string.Empty;
public string displayName = string.Empty;
public ulong skinid = 0;
public bool redirect = false;
public string redirectshortname = string.Empty;
public ItemCategory category;
}
private Dictionary<string, List<CachedSkin>> _skinsCache = new Dictionary<string, List<CachedSkin>>();
private Dictionary<string, string> _redirectSkins = new Dictionary<string, string>();
private Dictionary<string, CachedSkin> _defaultskins = new Dictionary<string, CachedSkin>();
private void GetSkins()
{
if ((Steamworks.SteamInventory.Definitions?.Length ?? 0) == 0)
{
Puts("Waiting for Steamworks to update skin item definitions");
Steamworks.SteamInventory.OnDefinitionsUpdated += GetSkins;
return;
}
int sk = 0;
Puts("Steamworks Updated, Updating Skins");
Steamworks.SteamInventory.OnDefinitionsUpdated -= GetSkins;
foreach (ItemDefinition itemDef in ItemManager.GetItemDefinitions())
{
List<CachedSkin> skins = new List<CachedSkin>() { new CachedSkin() { skinid = 0uL, shortname = itemDef.shortname } };
foreach (var skin in ItemSkinDirectory.ForItem(itemDef))
{
if (config.blacklistedskins.Contains((ulong)skin.id)) continue;
if (skin.id == 0) continue;
CachedSkin cachedSkin = new CachedSkin { skinid = Convert.ToUInt64(skin.id), shortname = itemDef.shortname, displayName = skin.invItem?.displayName?.english ?? itemDef.displayName.english };
ItemSkin itemSkin = skin.invItem as ItemSkin;
if (itemSkin != null && itemSkin.Redirect != null)
{
cachedSkin.redirect = true;
cachedSkin.redirectshortname = itemSkin.Redirect.shortname;
if (!_redirectSkins.ContainsKey(cachedSkin.redirectshortname))
_redirectSkins.Add(cachedSkin.redirectshortname, itemDef.shortname);
}
skins.Add(cachedSkin);
}
if (skins.Count > 1)
{
_skinsCache.Add(itemDef.shortname, skins);
}
}
foreach (Steamworks.InventoryDef item in Steamworks.SteamInventory.Definitions)
{
string shortname = item.GetProperty("itemshortname") == "lr300.item" ? "rifle.lr300" : item.GetProperty("itemshortname");
if (string.IsNullOrEmpty(shortname) || item.Id < 100)
continue;
ulong skinid;
if (config.blacklistedskins.Contains((ulong)item.Id)) continue;
if (!ulong.TryParse(item.GetProperty("workshopid"), out skinid))
{
skinid = (ulong)item.Id;
}
if (skinid < 100000) continue;
List<CachedSkin> skins;
if (_skinsCache.TryGetValue(shortname, out skins))
{
if (skins.Where(x => x.skinid == skinid || x.skinid == (ulong)item.Id).Count() > 0) continue;
skins.Add(new CachedSkin { skinid = Convert.ToUInt64(skinid), shortname = shortname, displayName = item.Name });
}
else
{
_skinsCache.Add(shortname, new List<CachedSkin>() { new CachedSkin { skinid = 0, shortname = shortname }, new CachedSkin { skinid = Convert.ToUInt64(skinid), shortname = shortname, displayName = item.Name } });
}
}
foreach (var whitelistSkin in config.ImportedSkinList)
{
ItemDefinition itemdef = ItemManager.FindItemDefinition(whitelistSkin.Value.itemShortname);
if (itemdef == null)
{
Puts($"Could not find item definition for {whitelistSkin.Value.itemShortname} {whitelistSkin.Key}");
continue;
}
List<CachedSkin> skins2;
if (_skinsCache.TryGetValue(itemdef.shortname, out skins2))
{
skins2.Add(new CachedSkin { skinid = whitelistSkin.Key, shortname = itemdef.shortname, displayName = whitelistSkin.Value.itemDisplayname });
}
else
{
Puts($"No default skins for {whitelistSkin.Value.itemShortname} trying to apply custom skin{whitelistSkin.Key}");
_skinsCache.Add(itemdef.shortname, new List<CachedSkin>() { new CachedSkin() { shortname = itemdef.shortname, displayName = whitelistSkin.Value.itemDisplayname, skinid = whitelistSkin.Key } });
}
}
foreach (var item2 in _skinsCache.ToList())
{
if (_redirectSkins.ContainsKey(item2.Key))
continue;
int skinsamt = item2.Value.Count;
sk += skinsamt;
if (skinsamt == 1)
{
_skinsCache.Remove(item2.Key);
continue;
}
ItemDefinition itemdef = ItemManager.FindItemDefinition(item2.Key);
if (itemdef == null || itemdef?.Blueprint == null)
{
_skinsCache.Remove(item2.Key);
continue;
}
//if (!itemdef.Blueprint.userCraftable)
// continue;
_defaultskins.Add(item2.Key, new CachedSkin() { shortname = item2.Key, category = itemdef.category });
}
SaveConfig();
//Re-order to look nice
_defaultskins = _defaultskins.OrderBy(key => key.Value.category).ToDictionary(x => x.Key, x => x.Value);
Puts($"{sk} skins were indexed, Skin indexing complete");
if (!config.sprayCanOveride)
Unsubscribe("OnActiveItemChanged");
}
#endregion Init
#region Configuration
private Configuration config;
public class Configuration
{
[JsonProperty("Skin Commands (skin items in you inventory")]
public string[] cmdsskin = new[] { "skin", "s" };
[JsonProperty("Skin Items Commands (skin items you have already placed")]
public string[] cmdsskinitems = new[] { "skinitem", "si" };
[JsonProperty("Set default items to be skinned")]
public string[] cmdsskincraft = new[] { "skincraft", "sc" };
[JsonProperty("Automatically set all items in you inventory to your default skins")]
public string[] cmdsskininv = new[] { "skininv", "sinv" };
[JsonProperty("Automatically set all items a container to your default skins")]
public string[] cmdsskincon = new[] { "skincon", "scon" };
[JsonProperty("Automatically skin all deployables in your base")]
public string[] cmdskinbase = new[] { "skinbase", "skinbuilding" };
[JsonProperty("Automatically skin all items in your base")]
public string[] cmdskinallitems = new[] { "skinall", "sa" };
[JsonProperty("Import Custom Skins")] public string[] cmdskinimport = new[] { "skinimport", "sip" };
[JsonProperty("Custom UI Positon 'min x, min y', 'max x', max y'")]
public string[] uiposition = new[] { "0.66 0.05", "0.82 0.1" };
[JsonProperty("Custom Searchbar UI Positon 'min x, min y', 'max x', max y'")]
public string[] uisearchposition = new[] { "0.70 0.88", "0.82 0.91" };
[JsonProperty("Add Search Bar UI")]
public bool searchbar = true;
[JsonProperty("Override spraycan behaviour")]
public bool sprayCanOveride = false;
[JsonProperty("Use spraycan effect when holding spraycan and skinning deployables")]
public bool sprayCanEffect = true;
[JsonProperty("Blacklisted Skins (skinID)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ulong> blacklistedskins = new List<ulong>();
[JsonProperty("Import Skin collections (steam workshop ID)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ulong> skinCollectionIDs = new List<ulong>();
[JsonProperty("Command based cooldowns ('permission' : 'command' seconds")]
public Dictionary<string, CoolDowns> Cooldowns = new Dictionary<string, CoolDowns>() { { "Default30CD", new CoolDowns() } };
[JsonProperty("Imported Skins List", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<ulong, ImportedItem> ImportedSkinList = new Dictionary<ulong, ImportedItem>();
[JsonProperty("Imported Skins (skinid : 'shortnamestring', skinid2 : 'shortnamestring2'", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<ulong, string> Importedskins = new Dictionary<ulong, string>() { { 861142659, "vending.machine" } };
public string ToJson() => JsonConvert.SerializeObject(this);
public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
}
public class ImportedItem
{
public string itemShortname = string.Empty;
public string itemDisplayname = string.Empty;
}
protected override void LoadDefaultConfig() => config = new Configuration();
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<Configuration>();
if (config == null)
{
throw new JsonException();
}
if (!config.ToDictionary().Keys.SequenceEqual(Config.ToDictionary(x => x.Key, x => x.Value).Keys))
{
Puts("Configuration appears to be outdated; updating and saving");
SaveConfig();
}
}
catch
{
Puts($"Configuration file {Name}.json is invalid; using defaults");
LoadDefaultConfig();
}
}
protected override void SaveConfig()
{
Puts($"Configuration changes saved to {Name}.json");
Config.WriteObject(config, true);
}
#endregion Configuration
#region Data
private void LoadData()
{
try
{
_playerDefaultSkins = _defaultSkins.ReadObject<Dictionary<ulong, Dictionary<string, CachedSkin>>>();
}
catch
{
_playerDefaultSkins = new Dictionary<ulong, Dictionary<string, CachedSkin>>();
}
}
private void SaveData()
{
_defaultSkins.WriteObject(_playerDefaultSkins);
}
#endregion Data
#region Localization
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NoPerms"] = "You don't have permissions to use this command",
["NoBuildingAuth"] = "You must have building auth to use this",
["NoObjectsFound"] = "No object found",
["NoSkins"] = "No skins available",
["ImportSkinArgs"] = "Bad args, Required input skinid",
["SkinIDError"] = "Cannot parse skinid {0}",
["NoShortname"] = "No item found for shortname : {0}",
["DuplicateSkin"] = "Duplicate Skin ID for : {0} {1}",
["SkinImported2"] = "Skin {0} has been imported and saved",
["CommandCooldown"] = "You can not use this command for another {0}",
["CompletedInvSkin"] = "All items in your inventory have been set to your default skins",
["CompletedConSkin"] = "All items in {0} have been set to your default skins",
["CompletedBuildingSkin"] = "All {0} in your base have been set to your default skins",
["CompletedAllSkin"] = "All {0} items in your base have been set to your default skins"
}, this);
}
#endregion Localization
#region Commands
private void SkinImportCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!HasPerm(player.UserIDString, permimport))
{
ChatMessage(iplayer, "NoPerms");
return;
}
if (args.Length < 1)
{
ChatMessage(iplayer, "ImportSkinArgs");
return;
}
ulong skinid = 0ul;
if (!ulong.TryParse(args[0], out skinid))
{
ChatMessage(iplayer, "ImportSkinArgs", args[0]);
return;
}
_WorkshopSkinIDCollectionList.Add(skinid.ToString());
if (getSteamWorkshopSkinData != null)
{
Puts("getSteamWorkshopSkinData already running!!");
}
else
{
getSteamWorkshopSkinData = GetSteamWorkshopSkinData();
ServerMgr.Instance.StartCoroutine(getSteamWorkshopSkinData);
}
ChatMessage(iplayer, "SkinImported2", args[0]);
}
private void SkinCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
player.EndLooting();
if (!HasPerm(player.UserIDString, permdefault))
{
ChatMessage(iplayer, "NoPerms");
return;
}
//Check for cooldown
foreach (var cdperm in config.Cooldowns)
{
if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
CoolDowns coolDowns;
if (!_playercooldowns.TryGetValue(player.userID, out coolDowns))
_playercooldowns.Add(player.userID, new CoolDowns() { skin = Time.time });
else
{
if (coolDowns.skin + cdperm.Value.skin > Time.time)
{
ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skin + cdperm.Value.skin - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
return;
}
coolDowns.skin = Time.time;
}
}
StorageContainer storageContainer = CreateStorageCon(player);
BoxController boxController;
if (!storageContainer.TryGetComponent<BoxController>(out boxController))
{
storageContainer.Kill();
return;
}
boxController.StartItemSkin();
if (!_viewingcon.Contains(player))
_viewingcon.Add(player);
if (_viewingcon.Count == 1)
SubscribeToHooks();
timer.Once(0.3f, () =>
{
StartLooting(player, storageContainer);
});
}
private void DefaultSkinsCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!HasPerm(player.UserIDString, permcraft))
{
ChatMessage(iplayer, "NoPerms");
return;
}
//Check for cooldown
foreach (var cdperm in config.Cooldowns)
{
if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
CoolDowns coolDowns;
if (!_playercooldowns.TryGetValue(player.userID, out coolDowns))
_playercooldowns.Add(player.userID, new CoolDowns() { skincraft = Time.time });
else
{
if (coolDowns.skincraft + cdperm.Value.skincraft > Time.time)
{
ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skincraft + cdperm.Value.skincraft - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
return;
}
coolDowns.skincraft = Time.time;
}
}
if (!_playerDefaultSkins.ContainsKey(player.userID))
_playerDefaultSkins.Add(player.userID, new Dictionary<string, CachedSkin>());
StorageContainer storageContainer = CreateStorageCon(player);
BoxController boxController;
if (!storageContainer.TryGetComponent<BoxController>(out boxController))
{
storageContainer.Kill();
return;
}
boxController.GetDefaultSkins();
if (!_viewingcon.Contains(player))
_viewingcon.Add(player);
if (_viewingcon.Count == 1)
SubscribeToHooks();
timer.Once(0.3f, () =>
{
StartLooting(player, storageContainer);
});
}
private static int Layermask = LayerMask.GetMask("Deployed", "Construction");
private void SkinItemCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!HasPerm(player.UserIDString, permitems))
{
ChatMessage(iplayer, "NoPerms");
return;
}
if (!player.IsBuildingAuthed() && !HasPerm(player.UserIDString, permbypassauth))
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
RaycastHit raycastHit;
if (!Physics.Raycast(player.eyes.HeadRay(), out raycastHit, 5f, Layermask))
{
ChatMessage(iplayer, "NoObjectsFound");
return;
}
BaseCombatEntity entity = raycastHit.GetEntity() as BaseCombatEntity;
if (entity == null || entity?.pickup.itemTarget == null)
{
ChatMessage(iplayer, "NoObjectsFound");
return;
}
if (!_skinsCache.ContainsKey(entity.pickup.itemTarget.shortname))
{
ChatMessage(iplayer, "NoSkins");
return;
}
//Check for cooldown
foreach (var cdperm in config.Cooldowns)
{
if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
CoolDowns coolDowns;
if (!_playercooldowns.TryGetValue(player.userID, out coolDowns))
_playercooldowns.Add(player.userID, new CoolDowns() { skinitem = Time.time });
else
{
if (coolDowns.skinitem + cdperm.Value.skinitem > Time.time)
{
ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skinitem + cdperm.Value.skinitem - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
return;
}
coolDowns.skinitem = Time.time;
}
}
StorageContainer storageContainer = CreateStorageCon(player);
BoxController boxController;
if (!storageContainer.TryGetComponent<BoxController>(out boxController))
{
storageContainer.Kill();
return;
}
boxController.SkinDeplyoables(entity);
if (!_viewingcon.Contains(player))
_viewingcon.Add(player);
if (_viewingcon.Count == 1)
SubscribeToHooks();
timer.Once(0.3f, () =>
{
StartLooting(player, storageContainer);
});
}
private void SkinInvCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
player.EndLooting();
if (!HasPerm(player.UserIDString, permskininv))
{
ChatMessage(iplayer, "NoPerms");
return;
}
Dictionary<string, CachedSkin> cachedskins;
if (!_playerDefaultSkins.TryGetValue(player.userID, out cachedskins))
{
ChatMessage(iplayer, "NoDefaultSkins");
return;
}
if (player.inventory == null)
return;
//Check for cooldown
foreach (var cdperm in config.Cooldowns)
{
if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
CoolDowns coolDowns;
if (!_playercooldowns.TryGetValue(player.userID, out coolDowns))
_playercooldowns.Add(player.userID, new CoolDowns() { skininv = Time.time });
else
{
if (coolDowns.skininv + cdperm.Value.skininv > Time.time)
{
ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skininv + cdperm.Value.skininv - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
return;
}
coolDowns.skininv = Time.time;
}
}
foreach (Item item in player.inventory.AllItems())
{
if (item == null) continue;
CachedSkin cachedSkin;
if (cachedskins.TryGetValue(item.info.shortname, out cachedSkin))
{
if (cachedSkin.redirect) continue;
item.skin = cachedSkin.skinid;
BaseEntity held = item.GetHeldEntity();
if (held != null)
{
held.skinID = cachedSkin.skinid;
held.SendNetworkUpdate();
}
}
}
player.inventory.containerWear.MarkDirty();
player.inventory.containerBelt.MarkDirty();
player.SendNetworkUpdateImmediate();
ChatMessage(iplayer, "CompletedInvSkin");
}
private void SkinConCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
player.EndLooting();
if (!HasPerm(player.UserIDString, permskincon))
{
ChatMessage(iplayer, "NoPerms");
return;
}
if (!player.IsBuildingAuthed() && !HasPerm(player.UserIDString, permbypassauth))
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
Dictionary<string, CachedSkin> cachedskins;
if (!_playerDefaultSkins.TryGetValue(player.userID, out cachedskins))
{
ChatMessage(iplayer, "NoDefaultSkins");
return;
}
RaycastHit raycastHit;
if (!Physics.Raycast(player.eyes.HeadRay(), out raycastHit, 5f, Layermask))
{
ChatMessage(iplayer, "NoObjectsFound");
return;
}
StorageContainer storage = raycastHit.GetEntity() as StorageContainer;
if (storage == null || storage?.inventory == null)
{
ChatMessage(iplayer, "NoObjectsFound");
return;
}
//Check for cooldown
foreach (var cdperm in config.Cooldowns)
{
if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
CoolDowns coolDowns;
if (!_playercooldowns.TryGetValue(player.userID, out coolDowns))
_playercooldowns.Add(player.userID, new CoolDowns() { skincon = Time.time });
else
{
if (coolDowns.skincon + cdperm.Value.skincon > Time.time)
{
ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skincon + cdperm.Value.skincon - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
return;
}
coolDowns.skincon = Time.time;
}
}
foreach (Item item in storage.inventory.itemList)
{
if (item == null) continue;
CachedSkin cachedSkin;
if (cachedskins.TryGetValue(item.info.shortname, out cachedSkin))
{
if (cachedSkin.redirect) continue;
item.skin = cachedSkin.skinid;
BaseEntity held = item.GetHeldEntity();
if (held != null)
{
held.skinID = cachedSkin.skinid;
held.SendNetworkUpdate();
}
}
}
storage.SendNetworkUpdateImmediate();
ChatMessage(iplayer, "CompletedConSkin", storage.ShortPrefabName);
}
private void SkinBaseCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!HasPerm(player.UserIDString, permskinbase))
{
ChatMessage(iplayer, "NoPerms");
return;
}
Dictionary<string, CachedSkin> cachedskins;
if (!_playerDefaultSkins.TryGetValue(player.userID, out cachedskins))
{
ChatMessage(iplayer, "NoDefaultSkins");
return;
}
if (!player.IsBuildingAuthed() && !HasPerm(player.UserIDString, permbypassauth))
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
BuildingPrivlidge buildingPrivlidge = player.GetBuildingPrivilege();
if (buildingPrivlidge == null)
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
BuildingManager.Building buildingManager = buildingPrivlidge.GetBuilding();
if (buildingManager == null)
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
//Check for cooldown
foreach (var cdperm in config.Cooldowns)
{
if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
CoolDowns coolDowns;
if (!_playercooldowns.TryGetValue(player.userID, out coolDowns))
_playercooldowns.Add(player.userID, new CoolDowns() { skinbase = Time.time });
else
{
if (coolDowns.skinbase + cdperm.Value.skinbase > Time.time)
{
ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skinbase + cdperm.Value.skinbase - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
return;
}
coolDowns.skinbase = Time.time;
}
}
string skinned = "all deplyoables";
if (args.Length > 0)
{
skinned = $"{args[0]}s";
}
foreach (var decayent in buildingManager.decayEntities)
{
BaseCombatEntity baseCombatEntity = decayent?.GetEntity() as BaseCombatEntity;
if (baseCombatEntity == null || baseCombatEntity.pickup.itemTarget == null) continue;
CachedSkin cachedSkin;
if (args.Length > 0)
{
if (!baseCombatEntity.pickup.itemTarget.shortname.Contains(args[0]))
continue;
}
if (cachedskins.TryGetValue(baseCombatEntity.pickup.itemTarget.shortname, out cachedSkin))
{
if (baseCombatEntity.skinID == cachedSkin.skinid)
continue;
baseCombatEntity.skinID = cachedSkin.skinid;
if (baseCombatEntity.skinID == 0uL || baseCombatEntity.skinID < 100000)
{
SendNetworkUpdate(baseCombatEntity, player);
}
else
baseCombatEntity.SendNetworkUpdateImmediate();
}
}
ChatMessage(iplayer, "CompletedBuildingSkin", skinned);
}
private void SkinAllItemsCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!HasPerm(player.UserIDString, permskinall))
{
ChatMessage(iplayer, "NoPerms");
return;
}
Dictionary<string, CachedSkin> cachedskins;
if (!_playerDefaultSkins.TryGetValue(player.userID, out cachedskins))
{
ChatMessage(iplayer, "NoDefaultSkins");
return;
}
if (!player.IsBuildingAuthed() && !HasPerm(player.UserIDString, permbypassauth))
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
BuildingPrivlidge buildingPrivlidge = player.GetBuildingPrivilege();
if (buildingPrivlidge == null)
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
BuildingManager.Building buildingManager = buildingPrivlidge.GetBuilding();
if (buildingManager == null)
{
ChatMessage(iplayer, "NoBuildingAuth");
return;
}
//Check for cooldown
foreach (var cdperm in config.Cooldowns)
{
if (!HasPerm(player.UserIDString, $"skinner.{cdperm.Key}")) continue;
CoolDowns coolDowns;
if (!_playercooldowns.TryGetValue(player.userID, out coolDowns))
_playercooldowns.Add(player.userID, new CoolDowns() { skinall = Time.time });
else
{
if (coolDowns.skinall + cdperm.Value.skinall > Time.time)
{
ChatMessage(iplayer, "CommandCooldown", TimeSpan.FromSeconds(coolDowns.skinall + cdperm.Value.skinall - Time.time).ToString("hh' hrs 'mm' mins 'ss' secs'"));
return;
}
coolDowns.skinall = Time.time;
}
}
string skinned = "items";
ItemDefinition itemdef = null;
if (args.Length > 0)
{
itemdef = ItemManager.FindItemDefinition(args[0]);
if (itemdef == null)
{
ChatMessage(iplayer, "NoShortname", args[0]);
return;
}
skinned = itemdef.shortname;
}
foreach (var decayent in buildingManager.decayEntities)
{
StorageContainer storageContainer = decayent?.GetEntity() as StorageContainer;
if (storageContainer == null) continue;
foreach (var item in storageContainer.inventory.itemList)
{
if (itemdef != null)
{
if (item.info.shortname != itemdef.shortname)
continue;
}
CachedSkin cachedSkin;
if (cachedskins.TryGetValue(item.info.shortname, out cachedSkin))
{
if (item.skin == cachedSkin.skinid) continue;
item.skin = cachedSkin.skinid;
var held = item.GetHeldEntity();
if (held != null)
{
held.skinID = cachedSkin.skinid;
held.SendNetworkUpdate();
}
}
}
}
ChatMessage(iplayer, "CompletedAllSkin", skinned);
}
private void SBNextPageCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!_viewingcon.Contains(player)) return;
StorageContainer storagecontainer = player.inventory.loot.entitySource as StorageContainer;
if (storagecontainer == null) return;
BoxController boxController;
if (!storagecontainer.TryGetComponent<BoxController>(out boxController))
return;
if (boxController._fillingbox || boxController._clearingbox)
return;
boxController.NextPage();
}
private void SBBackPageCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!_viewingcon.Contains(player)) return;
StorageContainer storagecontainer = player.inventory.loot.entitySource as StorageContainer;
if (storagecontainer == null) return;
BoxController boxController;
if (!storagecontainer.TryGetComponent<BoxController>(out boxController))
return;
if (boxController._fillingbox || boxController._clearingbox)
return;
boxController.BackPage();
}
private void SearchCMD(IPlayer iplayer, string command, string[] args)
{
BasePlayer player = iplayer.Object as BasePlayer;
if (player == null) return;
if (!_viewingcon.Contains(player)) return;
StorageContainer storagecontainer = player.inventory.loot.entitySource as StorageContainer;
if (storagecontainer == null) return;
BoxController boxController;
if (!storagecontainer.TryGetComponent<BoxController>(out boxController))
return;
if (boxController._fillingbox || boxController._clearingbox)
return;
string searchtxt = string.Join(",", args).Replace(",", " ");
if (searchtxt.Trim().ToLower() == "search id or name")
searchtxt = string.Empty;
if (boxController.searchtxt == searchtxt) return;
boxController.searchtxt = searchtxt;
boxController.SearchUpdate();
}
#endregion Commands
#region Hooks
private object CanStackItem(Item item, Item targetItem) => (targetItem.parent?.entityOwner?._limitedNetworking ?? false) ? false : (object)null;
private List<BasePlayer> _viewingcon = new List<BasePlayer>();
private void OnLootEntityEnd(BasePlayer player, StorageContainer storageContainer)
{
if (!_viewingcon.Contains(player)) return;
_viewingcon.Remove(player);
CuiHelper.DestroyUi(player, "SkinPageUI");
CuiHelper.DestroyUi(player, "SkinSearchUI");
if (_viewingcon.Count < 1)
UnSubscribeFromHooks();
BoxController boxController;
if (storageContainer.TryGetComponent<BoxController>(out boxController))
{
timer.Once(0.2f, () => { UnityEngine.Object.Destroy(boxController); });
}
}
private void OnItemCraftFinished(ItemCraftTask task, Item item)
{
if (task.skinID != 0)
return;
BasePlayer player = task.owner;
if (!HasPerm(player.UserIDString, permdefault))
return;
Dictionary<string, CachedSkin> cached;
if (!_playerDefaultSkins.TryGetValue(player.userID, out cached))
return;
CachedSkin cachedSkin;
if (!cached.TryGetValue(item.info.shortname, out cachedSkin))
return;
if (cachedSkin.redirect)
{
int amt = item.amount;
NextTick(() =>
{
DoRemove(item);
player.GiveItem(ItemManager.CreateByName(cachedSkin.redirectshortname, amt, 0), BaseEntity.GiveItemReason.Crafted);
});
return;
}
item.skin = cachedSkin.skinid;
var held = item.GetHeldEntity();
if (held != null)
{
held.skinID = cachedSkin.skinid;
held.SendNetworkUpdate();
}
}
#endregion Hooks
#region Methods
private StorageContainer CreateStorageCon(BasePlayer player)
{
StorageContainer storage = GameManager.server.CreateEntity(StringPool.Get(4080262419), Vector3.zero) as StorageContainer;
storage.syncPosition = false;
storage.limitNetworking = true;
storage.name = player.displayName;
storage.enableSaving = false;
storage.Spawn();
storage.inventory.playerOwner = player;
DestroyOnGroundMissing bouyancy;
if (storage.TryGetComponent<DestroyOnGroundMissing>(out bouyancy))
{
UnityEngine.Object.Destroy(bouyancy);
}
GroundWatch ridgidbody;
if (storage.TryGetComponent<GroundWatch>(out ridgidbody))
{
UnityEngine.Object.Destroy(ridgidbody);
}
storage.gameObject.AddComponent<BoxController>();
return storage;
}
private void StartLooting(BasePlayer player, StorageContainer storage)
{
if (player == null || storage == null || !player.IsAlive()) return;
_viewingcon.Add(player);
if (_viewingcon.Count == 1)
SubscribeToHooks();
//storage.SendAsSnapshot(player.Connection);
if (player.inventory.loot.IsLooting())
player.EndLooting();
player.inventory.loot.Clear();
player.inventory.loot.AddContainer(storage.inventory);
player.inventory.loot.entitySource = storage;
player.inventory.loot.PositionChecks = false;
player.inventory.loot.MarkDirty();
player.inventory.loot.SendImmediate();
player.ClientRPCPlayer<string>(null, player, "RPC_OpenLootPanel", "generic_resizable");
}
#endregion Methods
#region Spraycan Controller
void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem)
{
if (newItem == null)
{
if (oldItem != null)
{
if (oldItem.info?.itemid == -596876839)
{
SpraycanController spraycanController;
if (player.TryGetComponent<SpraycanController>(out spraycanController))
{
UnityEngine.GameObject.Destroy(spraycanController);
}
}
}
return;
}
if (newItem.info?.itemid == -596876839)
{
SpraycanController spraycanController;
if (!player.TryGetComponent<SpraycanController>(out spraycanController))
{
player.gameObject.AddComponent<SpraycanController>();
return;
}
}
if (oldItem != null)
{
if (oldItem.info.itemid == -596876839)
{
SpraycanController spraycanController;
// ... [Code preview truncated due to length. Full source in attached file] ...