C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//#define DEBUG
#define MORE_SKIN
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Random Deployables", "Norn/Arainrr", "1.1.0", ResourceId = 2187)]
[Description("Randomize deployable skins")]
public class RandomDeployables : RustPlugin
{
#region Fields
private const string PERMISSION_USE = "randomdeployables.use";
private readonly Hash<string, List<ulong>> itemSkins = new Hash<string, List<ulong>>();
private readonly Dictionary<string, string> deployed2Item = new Dictionary<string, string>();
private readonly Dictionary<string, List<ulong>> approvedSkins = new Dictionary<string, List<ulong>>();
#endregion Fields
#region Oxide Hooks
private void Init() => permission.RegisterPermission(PERMISSION_USE, this);
private void OnServerInitialized()
{
FindApprovedSkins();
bool changed = false;
foreach (var itemDefinition in ItemManager.GetItemDefinitions())
{
var deployablePrefab = itemDefinition.GetComponent<ItemModDeployable>()?.entityPrefab?.resourcePath;
if (!string.IsNullOrEmpty(deployablePrefab) && !deployed2Item.ContainsKey(deployablePrefab))
{
deployed2Item.Add(deployablePrefab, itemDefinition.shortname);
if (!configData.blockItems.Contains(itemDefinition.shortname))
{
var skins = new HashSet<ulong>(GetItemSkins(itemDefinition)).ToList();
if (skins.Count > 0)
{
if (!configData.customSkins.ContainsKey(itemDefinition.shortname))
{
changed = true;
configData.customSkins.Add(itemDefinition.shortname, new List<ulong>());
}
skins.RemoveAll(skin => configData.blockSkins.Contains(skin) || skin == 0);
if (configData.defaultSkin)
{
skins.Add(0);
}
itemSkins[itemDefinition.shortname] = skins;
}
}
}
}
if (changed)
{
SaveConfig();
}
#if DEBUG
Interface.Oxide.DataFileSystem.WriteObject(Name, itemSkins);
#endif
}
private void OnEntityBuilt(Planner planner, GameObject obj)
{
var entity = obj?.ToBaseEntity();
if (entity == null) return;
var player = planner?.GetOwnerPlayer();
if (player == null) return;
if (configData.blockRandom && entity.skinID != 0)
{
return;
}
string shortName;
if (deployed2Item.TryGetValue(entity.PrefabName, out shortName))
{
if (permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
{
List<ulong> skins;
if (itemSkins.TryGetValue(shortName, out skins))
{
entity.skinID = skins.GetRandom();
entity.SendNetworkUpdate();
}
}
}
}
#endregion Oxide Hooks
#region Methods
private void FindApprovedSkins()
{
foreach (var skinInfo in Rust.Workshop.Approved.All.Values)
{
List<ulong> skins;
var shortName = skinInfo.Skinnable.ItemName == "lr300.item" ? "rifle.lr300" : skinInfo.Skinnable.ItemName;
if (!approvedSkins.TryGetValue(shortName, out skins))
{
skins = new List<ulong>();
approvedSkins.Add(shortName, skins);
}
skins.Add(skinInfo.WorkshopdId);
}
}
private IEnumerable<ulong> GetItemSkins(ItemDefinition itemDefinition)
{
if (itemDefinition.skins?.Length > 0)
{
foreach (var skin in itemDefinition.skins)
{
yield return (ulong)skin.id;
}
}
#if MORE_SKIN
if (itemDefinition.skins2?.Length > 0)
{
foreach (var skin in itemDefinition.skins2)
{
yield return skin.WorkshopDownload;
}
}
#endif
List<ulong> skins;
if (approvedSkins.TryGetValue(itemDefinition.shortname, out skins))
{
foreach (var skin in skins)
{
yield return skin;
}
}
if (configData.customSkins.TryGetValue(itemDefinition.shortname, out skins))
{
foreach (var skin in skins)
{
yield return skin;
}
}
}
#endregion Methods
#region Commands
[ConsoleCommand("rd.skins")]
private void CmdOutputSkins()
{
Dictionary<string, HashSet<ulong>> allSkins = new Dictionary<string, HashSet<ulong>>();
foreach (var itemDefinition in ItemManager.GetItemDefinitions())
{
var skins = new HashSet<ulong>(GetItemSkins(itemDefinition));
if (skins.Count > 0)
{
skins.RemoveWhere(x => x == 0);
allSkins.TryAdd(itemDefinition.shortname, skins);
}
}
Interface.Oxide.DataFileSystem.WriteObject(Name, allSkins);
}
#endregion Commands
#region ConfigurationFile
private ConfigData configData;
private class ConfigData
{
[JsonProperty(PropertyName = "Allow default skin")]
public bool defaultSkin = false;
[JsonProperty(PropertyName = "If the item has skin, block random skin")]
public bool blockRandom = true;
[JsonProperty(PropertyName = "Block item list (item short name)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> blockItems = new List<string> { "item short name" };
[JsonProperty(PropertyName = "Block skin list (item skin id)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ulong> blockSkins = new List<ulong> { 492800372 };
[JsonProperty(PropertyName = "Custom skin list", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, List<ulong>> customSkins = new Dictionary<string, List<ulong>> { ["door.hinged.metal"] = new List<ulong> { 2465885372 } };
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
configData = Config.ReadObject<ConfigData>();
if (configData == null)
{
LoadDefaultConfig();
}
}
catch (Exception ex)
{
PrintError($"The configuration file is corrupted.\n{ex}");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig()
{
PrintWarning("Creating a new configuration file");
configData = new ConfigData();
}
protected override void SaveConfig() => Config.WriteObject(configData);
#endregion ConfigurationFile
}
}