C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.KitsExtensionMethods;
using UnityEngine;
using Random = UnityEngine.Random;
///Скачано с дискорд сервера Rust Edit [PRO+]
///discord.gg/9vyTXsJyKR
namespace Oxide.Plugins
{
[Info("Kits", "discord.gg/9vyTXsJyKR", "1.2.1")]
public class Kits : RustPlugin
{
#region Fields
[PluginReference] private Plugin
ImageLibrary = null,
CopyPaste = null,
Notify = null,
UINotify = null,
NoEscape = null;
private static Kits _instance;
private const string Layer = "UI.Kits";
private const string InfoLayer = "UI.Kits.Info";
private const string EditingLayer = "UI.Kits.Editing";
private const string ModalLayer = "UI.Kits.Modal";
private bool _enabledImageLibrary;
private readonly Dictionary<BasePlayer, List<Kit>> _openGUI = new Dictionary<BasePlayer, List<Kit>>();
private readonly Dictionary<BasePlayer, Dictionary<string, object>> _kitEditing =
new Dictionary<BasePlayer, Dictionary<string, object>>();
private readonly Dictionary<BasePlayer, Dictionary<string, object>> _itemEditing =
new Dictionary<BasePlayer, Dictionary<string, object>>();
private readonly Dictionary<string, List<KeyValuePair<int, string>>> _itemsCategories =
new Dictionary<string, List<KeyValuePair<int, string>>>();
private readonly List<BasePlayer> _toRemove = new List<BasePlayer>();
private const string PermAdmin = "Kits.admin";
private int _lastKitID;
private string _colorOne;
private string _colorTwo;
private string _colorWhite;
private string _colorThree;
private string _colorFour;
private string _colorRed;
#endregion
#region Config
private Configuration _config;
private class Configuration
{
[JsonProperty(PropertyName = "Automatic wipe on wipe")]
public bool AutoWipe = false;
[JsonProperty(PropertyName = "Default Kit Color")]
public string KitColor = "#A0A935";
[JsonProperty(PropertyName = "Work with Notify?")]
public bool UseNotify = true;
[JsonProperty(PropertyName = "Use NoEscape? (Raid/Combat block)")]
public bool UseNoEscape = false;
[JsonProperty(PropertyName = "Can admins edit? (by flag)")]
public bool FlagAdmin = true;
[JsonProperty(PropertyName = "Whitelist for NoEscape",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<string> NoEscapeWhiteList = new List<string>
{
"kit name 1",
"kit name 2"
};
[JsonProperty(PropertyName = "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly string[] Commands = {"kit", "kits"};
[JsonProperty(PropertyName = "Economy")]
public readonly EconomyConf Economy = new EconomyConf
{
Type = EconomyType.Plugin,
AddHook = "Deposit",
BalanceHook = "Balance",
RemoveHook = "Withdraw",
Plug = "Economics",
ShortName = "scrap",
DisplayName = string.Empty,
Skin = 0
};
[JsonProperty(PropertyName = "Rarity Settings", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<RarityColor> RarityColors = new List<RarityColor>
{
new RarityColor(40, "#A0A935")
};
[JsonProperty(PropertyName = "Auto Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<string> AutoKits = new List<string>
{
"autokit", "autokit_vip", "autokit_premium"
};
[JsonProperty(PropertyName = "Getting an auto kit 1 time?")]
public bool OnceAutoKit = false;
[JsonProperty(PropertyName = "Allow to enable/disable autokit?")]
public bool UseChangeAutoKit = false;
[JsonProperty(PropertyName = "Permission to enable/disable autokit")]
public string ChangeAutoKitPermission = "kits.changeautokit";
[JsonProperty(PropertyName = "Update the kits menu during permissions operations?")]
public bool OnPermissionsUpdate = false;
[JsonProperty(PropertyName = "Logs")] public readonly LogInfo Logs = new LogInfo
{
Console = true,
File = true
};
[JsonProperty(PropertyName = "Color 1")]
public readonly string ColorOne = "#161617";
[JsonProperty(PropertyName = "Color 2")]
public readonly string ColorTwo = "#0E0E10";
[JsonProperty(PropertyName = "Color 3")]
public readonly string ColorThree = "#4B68FF";
[JsonProperty(PropertyName = "Color 4")]
public readonly string ColorFour = "#303030";
[JsonProperty(PropertyName = "Color Red")]
public readonly string ColorRed = "#FF4B4B";
[JsonProperty(PropertyName = "Color White")]
public readonly string ColorWhite = "#FFFFFF";
[JsonProperty(PropertyName = "Show Number?")]
public readonly bool ShowNumber = true;
[JsonProperty(PropertyName = "Show No Permission Description?")]
public readonly bool ShowNoPermDescription = true;
[JsonProperty(PropertyName = "Show All Kits?")]
public bool ShowAllKits = false;
[JsonProperty(PropertyName = "CopyPaste Parameters",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<string> CopyPasteParameters = new List<string>
{
"deployables", "true", "inventories", "true"
};
[JsonProperty(PropertyName = "Block in Building Block?")]
public bool BlockBuilding = false;
[JsonProperty(PropertyName = "NPC Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly Dictionary<string, NpcKitsData> NpcKits = new Dictionary<string, NpcKitsData>
{
["1234567"] = new NpcKitsData
{
Description = "Free Kits",
Kits = new List<string>
{
"kit_one",
"kit_two"
}
},
["7654321"] = new NpcKitsData
{
Description = "VIPs Kits",
Kits = new List<string>
{
"kit_three",
"kit_four"
}
}
};
[JsonProperty(PropertyName = "Description")]
public readonly MenuDescription Description = new MenuDescription
{
AnchorMin = "0 0", AnchorMax = "1 0",
OffsetMin = "0 -55", OffsetMax = "0 -5",
Enabled = true,
Color = new IColor("#0E0E10", 100),
FontSize = 18,
Font = "robotocondensed-bold.ttf",
Align = TextAnchor.MiddleCenter,
TextColor = new IColor("#FFFFFF", 100),
Description = string.Empty
};
[JsonProperty(PropertyName = "Info Kit Description")]
public readonly DescriptionSettings InfoKitDescription = new DescriptionSettings
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-125 -55", OffsetMax = "125 -5",
Enabled = true,
Color = new IColor("#0E0E10", 100),
FontSize = 18,
Font = "robotocondensed-bold.ttf",
Align = TextAnchor.MiddleCenter,
TextColor = new IColor("#FFFFFF", 100)
};
[JsonProperty(PropertyName = "Interface")]
public readonly UserInterface UI = new UserInterface
{
Height = 455,
Width = 640,
KitHeight = 165,
KitWidth = 135f,
Margin = 10f,
KitsOnString = 4,
Strings = 2,
YIndent = -100f,
DisplayName = new DisplayNameSettings
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-45 -75",
OffsetMax = "45 0",
Enabled = true
},
Image = new InterfacePosition
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-32 -75", OffsetMax = "32 -11"
},
KitAvailable = new InterfacePosition
{
AnchorMin = "0 1", AnchorMax = "1 1",
OffsetMin = "0 -100", OffsetMax = "0 -75"
},
KitAmount = new KitAmountSettings
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-125",
OffsetMax = "-120",
Width = 115
},
KitCooldown = new InterfacePosition
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-32.5 -125", OffsetMax = "32.5 -105"
},
KitSale = new InterfacePosition
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-32.5 -115", OffsetMax = "32.5 -95"
},
KitAmountCooldown = new InterfacePosition
{
AnchorMin = "0 1", AnchorMax = "1 1",
OffsetMin = "0 -120",
OffsetMax = "0 -95"
},
NoPermission = new InterfacePosition
{
AnchorMin = "0 1", AnchorMax = "1 1",
OffsetMin = "0 -100", OffsetMax = "0 -75"
}
};
public VersionNumber Version;
}
private enum EconomyType
{
Plugin,
Item
}
private class EconomyConf
{
[JsonProperty(PropertyName = "Type (Plugin/Item)")] [JsonConverter(typeof(StringEnumConverter))]
public EconomyType Type;
[JsonProperty(PropertyName = "Plugin name")]
public string Plug;
[JsonProperty(PropertyName = "Balance add hook")]
public string AddHook;
[JsonProperty(PropertyName = "Balance remove hook")]
public string RemoveHook;
[JsonProperty(PropertyName = "Balance show hook")]
public string BalanceHook;
[JsonProperty(PropertyName = "ShortName")]
public string ShortName;
[JsonProperty(PropertyName = "Display Name (empty - default)")]
public string DisplayName;
[JsonProperty(PropertyName = "Skin")] public ulong Skin;
public double ShowBalance(BasePlayer player)
{
switch (Type)
{
case EconomyType.Plugin:
{
var plugin = _instance?.plugins?.Find(Plug);
if (plugin == null) return 0;
return Math.Round(Convert.ToDouble(plugin.Call(BalanceHook, player.userID)));
}
case EconomyType.Item:
{
return ItemCount(player.inventory.AllItems(), ShortName, Skin);
}
default:
return 0;
}
}
public void AddBalance(BasePlayer player, double amount)
{
switch (Type)
{
case EconomyType.Plugin:
{
var plugin = _instance?.plugins?.Find(Plug);
if (plugin == null) return;
switch (Plug)
{
case "BankSystem":
case "ServerRewards":
plugin.Call(AddHook, player.userID, (int) amount);
break;
default:
plugin.Call(AddHook, player.userID, amount);
break;
}
break;
}
case EconomyType.Item:
{
var am = (int) amount;
var item = ToItem(am);
if (item == null) return;
player.GiveItem(item);
break;
}
}
}
public bool RemoveBalance(BasePlayer player, double amount)
{
switch (Type)
{
case EconomyType.Plugin:
{
if (ShowBalance(player) < amount) return false;
var plugin = _instance?.plugins.Find(Plug);
if (plugin == null) return false;
switch (Plug)
{
case "BankSystem":
case "ServerRewards":
plugin.Call(RemoveHook, player.userID, (int) amount);
break;
default:
plugin.Call(RemoveHook, player.userID, amount);
break;
}
return true;
}
case EconomyType.Item:
{
var playerItems = player.inventory.AllItems();
var am = (int) amount;
if (ItemCount(playerItems, ShortName, Skin) < am) return false;
Take(playerItems, ShortName, Skin, am);
return true;
}
default:
return false;
}
}
private static int ItemCount(Item[] items, string shortname, ulong skin)
{
return items.Where(item =>
item.info.shortname == shortname && !item.isBroken && (skin == 0 || item.skin == skin)).Sum(item => item.amount);
}
private static void Take(IEnumerable<Item> itemList, string shortname, ulong skinId, int iAmount)
{
var num1 = 0;
if (iAmount == 0) return;
var list = Pool.GetList<Item>();
foreach (var item in itemList)
{
if (item.info.shortname != shortname ||
(skinId != 0 && item.skin != skinId) || item.isBroken) continue;
var num2 = iAmount - num1;
if (num2 <= 0) continue;
if (item.amount > num2)
{
item.MarkDirty();
item.amount -= num2;
break;
}
if (item.amount <= num2)
{
num1 += item.amount;
list.Add(item);
}
if (num1 == iAmount)
break;
}
foreach (var obj in list)
obj.RemoveFromContainer();
Pool.FreeList(ref list);
}
private Item ToItem(int amount)
{
var item = ItemManager.CreateByName(ShortName, amount, Skin);
if (item == null)
{
Debug.LogError($"Error creating item with ShortName: '{ShortName}'");
return null;
}
if (!string.IsNullOrEmpty(DisplayName)) item.name = DisplayName;
return item;
}
}
private class UserInterface
{
[JsonProperty(PropertyName = "Height")]
public float Height;
[JsonProperty(PropertyName = "Width")] public float Width;
[JsonProperty(PropertyName = "Kit Height")]
public float KitHeight;
[JsonProperty(PropertyName = "Kit Width")]
public float KitWidth;
[JsonProperty(PropertyName = "Margin")]
public float Margin;
[JsonProperty(PropertyName = "Kits On String")]
public int KitsOnString;
[JsonProperty(PropertyName = "Strings")]
public int Strings;
[JsonProperty(PropertyName = "Y Indent")]
public float YIndent;
[JsonProperty(PropertyName = "Display Name Settings")]
public DisplayNameSettings DisplayName;
[JsonProperty(PropertyName = "Image Settings")]
public InterfacePosition Image;
[JsonProperty(PropertyName = "Kit Available Settings")]
public InterfacePosition KitAvailable;
[JsonProperty(PropertyName = "Kit Amount Settings")]
public KitAmountSettings KitAmount;
[JsonProperty(PropertyName = "Kit Cooldown Settings")]
public InterfacePosition KitCooldown;
[JsonProperty(PropertyName = "Kit Sale Settings")]
public InterfacePosition KitSale;
[JsonProperty(PropertyName = "Kit Cooldown Settings (with amount)")]
public InterfacePosition KitAmountCooldown;
[JsonProperty(PropertyName = "No Permission Settings")]
public InterfacePosition NoPermission;
}
private class DisplayNameSettings : InterfacePosition
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
}
private class KitAmountSettings : InterfacePosition
{
[JsonProperty(PropertyName = "Width")] public float Width;
}
private class NpcKitsData
{
[JsonProperty(PropertyName = "Description")]
public string Description;
[JsonProperty(PropertyName = "Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> Kits;
}
private class InterfacePosition
{
public string AnchorMin;
public string AnchorMax;
public string OffsetMin;
public string OffsetMax;
}
private class DescriptionSettings : InterfacePosition
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Background Color")]
public IColor Color;
[JsonProperty(PropertyName = "Font Size")]
public int FontSize;
[JsonProperty(PropertyName = "Font")] public string Font;
[JsonProperty(PropertyName = "Align")] [JsonConverter(typeof(StringEnumConverter))]
public TextAnchor Align;
[JsonProperty(PropertyName = "Text Color")]
public IColor TextColor;
public void Get(ref CuiElementContainer container, string parent, string name = null,
string description = null)
{
if (!Enabled || string.IsNullOrEmpty(description)) return;
if (string.IsNullOrEmpty(name))
name = CuiHelper.GetGuid();
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = AnchorMin, AnchorMax = AnchorMax,
OffsetMin = OffsetMin, OffsetMax = OffsetMax
},
Image = {Color = Color.Get()}
}, parent, name);
container.Add(new CuiLabel
{
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
Text =
{
Text = $"{description}",
Align = Align,
Font = Font,
FontSize = FontSize,
Color = TextColor.Get()
}
}, name);
}
}
private class MenuDescription : DescriptionSettings
{
[JsonProperty(PropertyName = "Description")]
public string Description;
}
private class IColor
{
[JsonProperty(PropertyName = "HEX")] public string HEX;
[JsonProperty(PropertyName = "Opacity (0 - 100)")]
public readonly float Alpha;
public string Get()
{
if (string.IsNullOrEmpty(HEX)) HEX = "#FFFFFF";
var str = HEX.Trim('#');
if (str.Length != 6) throw new Exception(HEX);
var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
}
public IColor(string hex, float alpha)
{
HEX = hex;
Alpha = alpha;
}
}
private class LogInfo
{
[JsonProperty(PropertyName = "To Console")]
public bool Console;
[JsonProperty(PropertyName = "To File")]
public bool File;
}
private class RarityColor
{
[JsonProperty(PropertyName = "Chance")]
public readonly int Chance;
[JsonProperty(PropertyName = "Color")] public readonly string Color;
public RarityColor(int chance, string color)
{
Chance = chance;
Color = color;
}
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
if (_config.Version < Version)
UpdateConfigValues();
SaveConfig();
}
catch
{
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void SaveConfig()
{
Config.WriteObject(_config);
}
protected override void LoadDefaultConfig()
{
_config = new Configuration();
}
private void UpdateConfigValues()
{
PrintWarning("Config update detected! Updating config values...");
var baseConfig = new Configuration();
if (_config.Version < new VersionNumber(1, 0, 25))
_config.UI.KitSale = baseConfig.UI.KitSale;
if (_config.Version < new VersionNumber(1, 2, 0)) StartConvertOldData();
_config.Version = Version;
PrintWarning("Config update completed!");
}
#endregion
#region Data
private PluginData _data;
private List<ulong> _disablesAutoKits = new List<ulong>();
private void SaveKits()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Kits", _data);
}
private void SaveDisabledAutoKits()
{
if (!_config.UseChangeAutoKit) return;
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/DisabledAutoKits", _disablesAutoKits);
}
private void LoadData()
{
try
{
_data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>($"{Name}/Kits");
if (_config.UseChangeAutoKit)
_disablesAutoKits =
Interface.Oxide.DataFileSystem.ReadObject<List<ulong>>(
$"{Name}/DisabledAutoKits");
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_data == null) _data = new PluginData();
if (_disablesAutoKits == null) _disablesAutoKits = new List<ulong>();
}
private class PluginData
{
[JsonProperty(PropertyName = "Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public readonly List<Kit> Kits = new List<Kit>();
}
private class Kit
{
[JsonIgnore] public int ID;
[JsonProperty(PropertyName = "Name")] public string Name;
[JsonProperty(PropertyName = "Display Name")]
public string DisplayName;
[JsonProperty(PropertyName = "Color")] public string Color;
[JsonProperty(PropertyName = "Permission")]
public string Permission;
[JsonProperty(PropertyName = "Description")]
public string Description;
[JsonProperty(PropertyName = "Image")] public string Image;
[JsonProperty(PropertyName = "Hide")] public bool Hide;
[JsonProperty(PropertyName = "ShowInfo")] [DefaultValue(true)]
public bool ShowInfo;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
[JsonProperty(PropertyName = "Cooldown")]
public double Cooldown;
[JsonProperty(PropertyName = "Wipe Block")]
public double CooldownAfterWipe;
[JsonProperty(PropertyName = "Use Building")]
public bool UseBuilding;
[JsonProperty(PropertyName = "Building")]
public string Building;
[JsonProperty(PropertyName = "Enable sale")]
public bool Sale;
[JsonProperty(PropertyName = "Selling price")]
public int Price;
[JsonProperty(PropertyName = "Items", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<KitItem> Items;
public void Get(BasePlayer player)
{
Items?.ForEach(item => item?.Get(player));
}
[JsonIgnore] public Dictionary<int, KitItem> dictMainItems = new Dictionary<int, KitItem>();
[JsonIgnore] public Dictionary<int, KitItem> dictBeltItems = new Dictionary<int, KitItem>();
[JsonIgnore] public Dictionary<int, KitItem> dictWearItems = new Dictionary<int, KitItem>();
[JsonIgnore] public int beltCount;
[JsonIgnore] public int wearCount;
[JsonIgnore] public int mainCount;
public void LoadContainers()
{
dictWearItems.Clear();
dictBeltItems.Clear();
dictMainItems.Clear();
beltCount = 0;
wearCount = 0;
mainCount = 0;
Items.ForEach(item =>
{
switch (item.Container)
{
case "wear":
dictWearItems[item.Position] = item;
wearCount++;
break;
case "belt":
dictBeltItems[item.Position] = item;
beltCount++;
break;
case "main":
dictMainItems[item.Position] = item;
mainCount++;
break;
}
});
}
public KitItem GetItemByContainerAndPosition(string container, int position)
{
KitItem item;
switch (container)
{
case "wear":
{
return dictWearItems.TryGetValue(position, out item) ? item : null;
}
case "belt":
{
return dictBeltItems.TryGetValue(position, out item) ? item : null;
}
default:
{
return dictMainItems.TryGetValue(position, out item) ? item : null;
}
}
}
}
private enum KitItemType
{
Item,
Command
}
private class KitItem
{
[JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
public KitItemType Type;
[JsonProperty(PropertyName = "Command")]
public string Command;
[JsonProperty(PropertyName = "ShortName")]
public string ShortName;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
[JsonProperty(PropertyName = "Blueprint")]
public int Blueprint;
[JsonProperty(PropertyName = "SkinID")]
public ulong SkinID;
[JsonProperty(PropertyName = "Container")]
public string Container;
[JsonProperty(PropertyName = "Condition")]
public float Condition;
[JsonProperty(PropertyName = "Chance")]
public int Chance;
[JsonProperty(PropertyName = "Position", DefaultValueHandling = DefaultValueHandling.Populate)]
[DefaultValue(-1)]
public int Position;
[JsonProperty(PropertyName = "Image")] public string Image;
[JsonProperty(PropertyName = "Weapon")]
public Weapon Weapon;
[JsonProperty(PropertyName = "Content", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ItemContent> Content;
public void Get(BasePlayer player)
{
if (Chance < 100 && Random.Range(0, 100) > Chance) return;
switch (Type)
{
case KitItemType.Item:
{
GiveItem(player, BuildItem(),
Container == "belt" ? player.inventory.containerBelt :
Container == "wear" ? player.inventory.containerWear : player.inventory.containerMain);
break;
}
case KitItemType.Command:
{
ToCommand(player);
break;
}
}
}
private void ToCommand(BasePlayer player)
{
var command = Command.Replace("\n", "|").Replace("%steamid%", player.UserIDString, StringComparison.OrdinalIgnoreCase).Replace(
"%username%",
player.displayName, StringComparison.OrdinalIgnoreCase);
foreach (var check in command.Split('|')) _instance?.Server.Command(check);
}
private static void GiveItem(BasePlayer player, Item item, ItemContainer cont = null)
{
if (item == null) return;
var inv = player.inventory;
var moved = item.MoveToContainer(cont, item.position) || item.MoveToContainer(cont) ||
item.MoveToContainer(inv.containerMain);
if (!moved)
{
if (cont == inv.containerBelt)
moved = item.MoveToContainer(inv.containerWear);
if (cont == inv.containerWear)
moved = item.MoveToContainer(inv.containerBelt);
}
if (!moved)
item.Drop(player.GetCenter(), player.GetDropVelocity());
}
[JsonIgnore] private ItemDefinition _itemDefinition;
[JsonIgnore]
public ItemDefinition ItemDefinition
{
get
{
if (_itemDefinition == null) _itemDefinition = ItemManager.FindItemDefinition(ShortName);
return _itemDefinition;
}
}
private Item BuildItem()
{
var item = ItemManager.Create(ItemDefinition, Amount > 1 ? Amount : 1, SkinID);
item.condition = Condition;
item.position = Position;
if (Blueprint != 0)
item.blueprintTarget = Blueprint;
if (Weapon != null)
{
var heldEntity = item.GetHeldEntity();
if (heldEntity != null)
{
heldEntity.skinID = SkinID;
var baseProjectile = heldEntity as BaseProjectile;
if (baseProjectile != null && !string.IsNullOrEmpty(Weapon.ammoType))
{
baseProjectile.primaryMagazine.contents = Weapon.ammoAmount;
baseProjectile.primaryMagazine.ammoType =
ItemManager.FindItemDefinition(Weapon.ammoType);
}
heldEntity.SendNetworkUpdate();
}
}
Content?.ForEach(cont =>
{
var newCont = ItemManager.CreateByName(cont.ShortName, cont.Amount);
newCont.condition = cont.Condition;
newCont.MoveToContainer(item.contents);
});
return item;
}
public static KitItem FromOld(ItemData item, string container)
{
var newItem = new KitItem
{
Content =
item.Contents?.Select(x =>
new ItemContent {ShortName = x.Shortname, Condition = x.Condition, Amount = x.Amount}).ToList() ?? new List<ItemContent>(),
Weapon = new Weapon {ammoAmount = item.Ammo, ammoType = item.Ammotype},
Container = container,
SkinID = item.Skin,
Command = string.Empty,
Chance = 100,
Blueprint = string.IsNullOrEmpty(item.BlueprintShortname) ? 0 : 1,
Condition = item.Condition,
Amount = item.Amount,
ShortName = item.Shortname,
Type = KitItemType.Item,
Position = item.Position
};
return newItem;
}
[JsonIgnore] private int _itemId = -1;
[JsonIgnore]
public int itemId
{
get
{
if (_itemId == -1)
_itemId = ItemManager.FindItemDefinition(ShortName)?.itemid ?? -1;
return _itemId;
}
}
[JsonIgnore] private ICuiComponent _image;
public CuiElement GetImage(string aMin, string aMax, string oMin, string oMax, string parent,
string name = null)
{
if (_image == null)
{
if (_instance._enabledImageLibrary && !string.IsNullOrEmpty(Image))
_image = new CuiRawImageComponent
{
Png = _instance.ImageLibrary.Call<string>("GetImage", Image)
};
else
_image = new CuiImageComponent
{
ItemId = itemId,
SkinId = SkinID
};
}
return new CuiElement
{
Name = string.IsNullOrEmpty(name) ? CuiHelper.GetGuid() : name,
Parent = parent,
Components =
{
_image,
new CuiRectTransformComponent
{
AnchorMin = aMin, AnchorMax = aMax,
OffsetMin = oMin, OffsetMax = oMax
}
}
};
}
}
private class Weapon
{
public string ammoType;
public int ammoAmount;
}
private class ItemContent
{
public string ShortName;
public float Condition;
public int Amount;
}
#endregion
#region Hooks
private void Init()
{
_instance = this;
LoadData();
if (!_config.OnPermissionsUpdate)
{
Unsubscribe(nameof(OnUserPermissionGranted));
Unsubscribe(nameof(OnUserPermissionRevoked));
}
}
private void OnServerInitialized()
{
LoadImages();
LoadColors();
LoadKits();
FixItemsPositions();
FillCategories();
RegisterPermissions();
RegisterCommands();
timer.Every(1, HandleUi);
}
private void OnServerSave()
{
timer.In(Random.Range(2, 7), PlayerData.Save);
}
private void Unload()
{
foreach (var player in BasePlayer.activePlayerList)
{
CuiHelper.DestroyUi(player, Layer);
CuiHelper.DestroyUi(player, InfoLayer);
CuiHelper.DestroyUi(player, EditingLayer);
CuiHelper.DestroyUi(player, ModalLayer);
PlayerData.SaveAndUnload(player.UserIDString);
}
_instance = null;
}
private void OnPlayerRespawned(BasePlayer player)
{
if (player == null || (_config.UseChangeAutoKit && _disablesAutoKits.Contains(player.userID))) return;
var kits = GetAutoKits(player);
if (kits.Count == 0)
return;
player.inventory.Strip();
if (_config.OnceAutoKit)
kits.LastOrDefault()?.Get(player);
else
kits.ForEach(kit => kit.Get(player));
}
private void OnPlayerDisconnected(BasePlayer player)
{
_openGUI.Remove(player);
_kitEditing.Remove(player);
_itemEditing.Remove(player);
PlayerData.SaveAndUnload(player.UserIDString);
}
private void OnPlayerDeath(BasePlayer player, HitInfo info)
{
if (player == null) return;
CuiHelper.DestroyUi(player, Layer);
OnPlayerDisconnected(player);
}
private void OnUseNPC(BasePlayer npc, BasePlayer player)
{
if (npc == null || player == null || !_config.NpcKits.ContainsKey(npc.UserIDString)) return;
MainUi(player, npc.userID, first: true);
}
#region Image Library
private void OnPluginLoaded(Plugin plugin)
{
if (plugin.Name == "ImageLibrary") _enabledImageLibrary = true;
}
private void OnPluginUnloaded(Plugin plugin)
{
if (plugin.Name == "ImageLibrary") _enabledImageLibrary = false;
}
#endregion
#region Permissions
private void OnUserPermissionGranted(string id, string permName)
{
UpdateOpenedUI(id, permName);
}
private void OnUserPermissionRevoked(string id, string permName)
{
UpdateOpenedUI(id, permName);
}
#endregion
#endregion
#region Commands
private void CmdOpenKits(IPlayer cov, string command, string[] args)
{
var player = cov?.Object as BasePlayer;
if (player == null) return;
if (args.Length == 0)
{
MainUi(player, first: true);
return;
}
switch (args[0])
{
case "help":
{
Reply(player, KitsHelp, command);
break;
}
case "list":
{
Reply(player, KitsList,
string.Join(", ", GetAvailableKits(player).Select(x => $"'{x.DisplayName}'")));
break;
}
case "remove":
{
if (!IsAdmin(player)) return;
var name = string.Join(" ", args.Skip(1));
if (string.IsNullOrEmpty(name))
{
SendNotify(player, KitNotFound, 1, name);
return;
}
var kit = GetAvailableKits(player)?.Find(x => x.DisplayName == name);
if (kit == null)
{
SendNotify(player, KitNotFound, 1, name);
return;
}
_data.Kits.Remove(kit);
SaveKits();
SendNotify(player, KitRemoved, 0, name);
break;
}
case "autokit":
{
if (!_config.UseChangeAutoKit) return;
if (!string.IsNullOrEmpty(_config.ChangeAutoKitPermission) &&
!cov.HasPermission(_config.ChangeAutoKitPermission))
{
ErrorUi(player, Msg(player, NoPermission));
return;
}
bool enabled;
if (_disablesAutoKits.Contains(player.userID))
{
_disablesAutoKits.Remove(player.userID);
enabled = true;
}
else
{
_disablesAutoKits.Add(player.userID);
enabled = false;
}
if (enabled)
SendNotify(player, ChangeAutoKitOn, 0);
else
SendNotify(player, ChangeAutoKitOff, 1);
SaveDisabledAutoKits();
break;
}
default:
{
var name = string.Join(" ", args);
if (string.IsNullOrEmpty(name))
{
SendNotify(player, KitNotFound, 1, name);
return;
}
var kit = GetAvailableKits(player, checkAmount: false).Find(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(x.DisplayName, name, StringComparison.InvariantCultureIgnoreCase));
if (kit == null)
{
SendNotify(player, KitNotFound, 1, name);
return;
}
GiveKit(player, kit);
break;
}
}
}
[ConsoleCommand("UI_Kits")]
private void CmdKitsConsole(ConsoleSystem.Arg arg)
{
var player = arg?.Player();
if (player == null || !arg.HasArgs()) return;
switch (arg.Args[0])
{
case "close":
{
_openGUI.Remove(player);
StopEditing(player);
break;
}
case "stopedit":
{
StopEditing(player);
break;
}
case "main":
{
var targetId = 0UL;
if (arg.HasArgs(2))
ulong.TryParse(arg.Args[1], out targetId);
var page = 0;
if (arg.HasArgs(3))
int.TryParse(arg.Args[2], out page);
var showAll = false;
if (arg.HasArgs(4))
bool.TryParse(arg.Args[3], out showAll);
MainUi(player, targetId, page, showAll);
break;
}
case "infokit":
{
int kitId;
if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out kitId)) return;
var kit = _data.Kits.Find(x => x.ID == kitId);
if (kit == null) return;
StopEditing(player);
InfoKitUi(player, kit);
break;
}
case "givekit":
{
int kitId;
if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out kitId)) return;
var kit = _data.Kits.Find(x => x.ID == kitId);
if (kit == null) return;
GiveKit(player, kit);
break;
}
case "editkit":
{
if (!IsAdmin(player)) return;
bool creating;
if (!arg.HasArgs(2) || !bool.TryParse(arg.Args[1], out creating)) return;
var kitId = -1;
if (arg.HasArgs(3))
int.TryParse(arg.Args[2], out kitId);
if (arg.HasArgs(4) && (!arg.HasArgs(5) || string.IsNullOrEmpty(arg.Args[4])))
return;
if (arg.HasArgs(5))
{
var key = arg.Args[3];
var value = arg.Args[4];
if (_kitEditing.ContainsKey(player) && _kitEditing[player].ContainsKey(key))
{
object newValue = null;
switch (key)
{
case "ShowInfo":
case "Hide":
case "AutoKit":
case "Sale":
{
bool result;
if (value == "delete")
newValue = default(bool);
else if (bool.TryParse(value, out result)) newValue = result;
break;
}
case "Amount":
case "Price":
{
int result;
if (value == "delete")
newValue = default(int);
else if (int.TryParse(value, out result))
newValue = result;
break;
}
case "Cooldown":
case "CooldownAfterWipe":
{
double result;
if (value == "delete")
newValue = default(double);
else if (double.TryParse(value, out result))
newValue = result;
break;
}
case "DisplayName":
{
newValue = string.Join(" ", arg.Args.Skip(4));
break;
}
default:
{
newValue = value == "delete" ? string.Empty : value;
break;
}
}
if (_kitEditing[player][key].Equals(newValue))
return;
_kitEditing[player][key] = newValue;
}
}
EditingKitUi(player, creating, kitId);
break;
}
case "takeitem":
{
if (!IsAdmin(player)) return;
int kitId, slot;
if (!arg.HasArgs(5) ||
!_itemEditing.ContainsKey(player) ||
!int.TryParse(arg.Args[2], out kitId) ||
!int.TryParse(arg.Args[3], out slot))
return;
var container = arg.Args[1];
_itemEditing[player]["ShortName"] = arg.Args[4];
_itemEditing[player]["SkinID"] = 0UL;
EditingItemUi(player, kitId, slot, container);
break;
}
case "selectitem":
{
if (!IsAdmin(player)) return;
int kitId, slot;
if (!arg.HasArgs(4) ||
!_itemEditing.ContainsKey(player) ||
!int.TryParse(arg.Args[2], out kitId) ||
!int.TryParse(arg.Args[3], out slot))
return;
var container = arg.Args[1];
var selectedCategory = string.Empty;
if (arg.HasArgs(5))
selectedCategory = arg.Args[4];
var page = 0;
if (arg.HasArgs(6))
int.TryParse(arg.Args[5], out page);
var input = string.Empty;
if (arg.HasArgs(7))
input = string.Join(" ", arg.Args.Skip(6));
SelectItem(player, kitId, slot, container, selectedCategory, page, input);
break;
}
case "startedititem":
{
if (!IsAdmin(player)) return;
int kitId, slot;
if (!arg.HasArgs(4) ||
!int.TryParse(arg.Args[2], out kitId) ||
!int.TryParse(arg.Args[3], out slot)) return;
var container = arg.Args[1];
EditingItemUi(player, kitId, slot, container, true);
break;
}
case "edititem":
{
if (!IsAdmin(player)) return;
int kitId, slot;
if (!arg.HasArgs(6) ||
!int.TryParse(arg.Args[2], out kitId) ||
!int.TryParse(arg.Args[3], out slot)) return;
var container = arg.Args[1];
var key = arg.Args[4];
var value = arg.Args[5];
if (_itemEditing.ContainsKey(player) && _itemEditing[player].ContainsKey(key))
{
object newValue = null;
switch (key)
{
case "Type":
{
KitItemType type;
if (value == "delete")
newValue = default(KitItemType);
else if (Enum.TryParse(value, out type))
newValue = type;
break;
}
case "Command":
{
if (value == "delete")
newValue = string.Empty;
else
newValue = string.Join(" ", arg.Args.Skip(5));
break;
}
case "ShortName":
{
if (value == "delete")
{
newValue = string.Empty;
}
else
{
newValue = value;
_itemEditing[player]["SkinID"] = 0UL;
}
break;
}
case "SkinID":
{
ulong result;
if (value == "delete")
newValue = default(ulong);
else if (ulong.TryParse(value, out result))
newValue = result;
break;
}
case "Amount":
case "Blueprint":
case "Chance":
{
int result;
if (value == "delete")
newValue = default(int);
else if (int.TryParse(value, out result))
newValue = result;
break;
}
}
if (_itemEditing[player][key].Equals(newValue))
return;
_itemEditing[player][key] = newValue;
}
EditingItemUi(player, kitId, slot, container);
break;
}
case "saveitem":
{
if (!IsAdmin(player)) return;
int kitId, slot;
if (!arg.HasArgs(4) ||
!int.TryParse(arg.Args[1], out kitId) ||
!int.TryParse(arg.Args[2], out slot)) return;
var container = arg.Args[3];
if (string.IsNullOrEmpty(container)) return;
var editing = _itemEditing[player];
if (editing == null) return;
var kit = _data.Kits.Find(x => x.ID == kitId);
if (kit == null) return;
var item = kit.GetItemByContainerAndPosition(container, slot);
var hasItem = item != null;
var newItem = item == null || editing["ShortName"].ToString() != item.ShortName;
if (item == null)
item = new KitItem();
item.Type = (KitItemType) editing["Type"];
item.Command = editing["Command"].ToString();
item.Container = editing["Container"].ToString();
item.ShortName = editing["ShortName"].ToString();
item.Amount = (int) editing["Amount"];
item.Blueprint = (int) editing["Blueprint"];
item.Chance = (int) editing["Chance"];
item.SkinID = (ulong) editing["SkinID"];
item.Position = (int) editing["Position"];
if (newItem)
{
var info = ItemManager.FindItemDefinition(item.ShortName);
if (info != null)
item.Condition = info.condition.max;
}
if (!hasItem) kit.Items.Add(item);
kit.LoadContainers();
StopEditing(player);
SaveKits();
InfoKitUi(player, kit);
break;
}
case "removeitem":
{
if (!IsAdmin(player)) return;
int kitId, slot;
if (!arg.HasArgs(4) ||
!int.TryParse(arg.Args[1], out kitId) ||
!int.TryParse(arg.Args[2], out slot)) return;
var editing = _itemEditing[player];
if (editing == null) return;
var kit = _data.Kits.Find(x => x.ID == kitId);
if (kit == null) return;
var item = kit.GetItemByContainerAndPosition(arg.Args[3], slot);
if (item != null)
kit.Items.Remove(item);
kit.LoadContainers();
StopEditing(player);
SaveKits();
InfoKitUi(player, kit);
break;
}
case "savekit":
{
if (!IsAdmin(player)) return;
bool creating;
int kitId;
if (!arg.HasArgs(3) || !bool.TryParse(arg.Args[1], out creating) ||
!int.TryParse(arg.Args[2], out kitId)) return;
var editing = _kitEditing[player];
if (editing == null) return;
Kit kit;
if (creating)
{
kit = new Kit
{
ID = ++_lastKitID,
Name = (string) editing["Name"],
DisplayName = (string) editing["DisplayName"],
Color = (string) editing["Color"],
Permission = (string) editing["Permission"],
Image = (string) editing["Image"],
Hide = Convert.ToBoolean(editing["Hide"]),
ShowInfo = Convert.ToBoolean(editing["ShowInfo"]),
Amount = Convert.ToInt32(editing["Amount"]),
Cooldown = Convert.ToDouble(editing["Cooldown"]),
CooldownAfterWipe = Convert.ToDouble(editing["CooldownAfterWipe"]),
Sale = Convert.ToBoolean(editing["Sale"]),
Price = Convert.ToInt32(editing["Price"]),
Items = new List<KitItem>()
};
_data.Kits.Add(kit);
}
else
{
kit = _data.Kits.Find(x => x.ID == kitId);
if (kit == null) return;
kit.Name = (string) editing["Name"];
kit.DisplayName = (string) editing["DisplayName"];
kit.Color = (string) editing["Color"];
kit.Permission = (string) editing["Permission"];
kit.Image = (string) editing["Image"];
kit.Hide = Convert.ToBoolean(editing["Hide"]);
kit.ShowInfo = Convert.ToBoolean(editing["ShowInfo"]);
kit.Amount = Convert.ToInt32(editing["Amount"]);
kit.Cooldown = Convert.ToDouble(editing["Cooldown"]);
kit.CooldownAfterWipe = Convert.ToDouble(editing["CooldownAfterWipe"]);
kit.Sale = Convert.ToBoolean(editing["Sale"]);
kit.Price = Convert.ToInt32(editing["Price"]);
}
var autoKit = Convert.ToBoolean(editing["AutoKit"]);
if (autoKit)
{
if (!_config.AutoKits.Contains(kit.Name))
{
_config.AutoKits.Add(kit.Name);
SaveConfig();
}
}
else
{
_config.AutoKits.Remove(kit.Name);
SaveConfig();
}
StopEditing(player);
var perm = kit.Permission.ToLower();
if (!string.IsNullOrEmpty(perm) && !permission.PermissionExists(perm))
permission.RegisterPermission(perm, this);
if (!string.IsNullOrEmpty(kit.Image))
ImageLibrary?.Call("AddImage", kit.Image, kit.Image);
SaveKits();
MainUi(player);
break;
}
case "removekit":
{
if (!IsAdmin(player)) return;
int kitId;
if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out kitId)) return;
_data.Kits.RemoveAll(x => x.ID == kitId);
SaveKits();
MainUi(player);
break;
}
case "frominv":
{
if (!IsAdmin(player)) return;
int kitId;
if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out kitId)) return;
var kit = _data.Kits.Find(x => x.ID == kitId);
if (kit == null) return;
var kitItems = GetPlayerItems(player);
if (kitItems == null) return;
kit.Items = kitItems;
kit.LoadContainers();
SaveKits();
InfoKitUi(player, kit);
break;
}
}
}
[ConsoleCommand("kits.resetkits")]
private void CmdKitsReset(ConsoleSystem.Arg arg)
{
if (!arg.IsAdmin) return;
_data.Kits.Clear();
SaveKits();
SendReply(arg, "Plugin successfully reset");
}
[ConsoleCommand("kits.give")]
private void CmdKitsGive(ConsoleSystem.Arg arg)
{
if (!arg.IsAdmin) return;
if (!arg.HasArgs(2))
{
SendReply(arg, $"Error syntax! Use: {arg.cmd.FullName} [name/steamid] [kitname]");
return;
}
var target = BasePlayer.Find(arg.Args[0]);
if (target == null)
{
SendReply(arg, $"Player '{arg.Args[0]}' not found!");
return;
}
var kit = _data.Kits.Find(x => x.Name == arg.Args[1]);
if (kit == null)
{
SendReply(arg, $"Kit '{arg.Args[1]}' not found!");
return;
}
kit.Items.ForEach(item => item.Get(target));
SendReply(arg, $"Player '{arg.Args[0]}' successfully received a kit '{arg.Args[1]}'");
Interface.CallHook("OnKitRedeemed", target, kit.Name);
Log(target, kit.Name);
}
[ConsoleCommand("kits.givekit")]
private void CmdKitsGiveKit(ConsoleSystem.Arg arg)
{
if (!arg.IsAdmin) return;
if (!arg.HasArgs(2))
{
SendReply(arg, $"Error syntax! Use: {arg.cmd.FullName} [name/steamid] [kitname] [amount]");
return;
}
var target = BasePlayer.FindAwakeOrSleeping(arg.Args[0]);
if (target == null)
{
SendReply(arg, $"Player '{arg.Args[0]}' not found!");
return;
}
var kit = _data.Kits.Find(x => x.Name == arg.Args[1]);
if (kit == null)
{
SendReply(arg, $"Kit '{arg.Args[1]}' not found!");
return;
}
var amount = 1;
if (arg.HasArgs(3))
int.TryParse(arg.Args[2], out amount);
var playerData = PlayerData.GetOrCreateKitData(target.UserIDString, kit.Name);
if (playerData == null) return;
playerData.HasAmount += amount;
SendReply(arg, $"Player '{arg.Args[0]}' successfully received a kit '{arg.Args[1]}' ({amount} pcs)");
Log(target, kit.Name);
}
#endregion
#region Interface
private void MainUi(BasePlayer player, ulong targetId = 0, int page = 0, bool showAll = false,
bool first = false)
{
#region Fields
var isAdmin = IsAdmin(player);
var totalAmount = _config.UI.KitsOnString * _config.UI.Strings;
var constSwitch = -(_config.UI.KitsOnString * _config.UI.KitWidth +
(_config.UI.KitsOnString - 1) * _config.UI.Margin) / 2f;
var xSwitch = constSwitch;
var ySwitch = _config.UI.YIndent;
var allKits = GetAvailableKits(player, targetId.ToString(), showAll);
var kitsList = allKits.Skip(page * totalAmount).Take(totalAmount);
_openGUI[player] = kitsList;
#endregion
var container = new CuiElementContainer();
#region Background
if (first)
{
CuiHelper.DestroyUi(player, Layer);
container.Add(new CuiPanel
{
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
Image =
{
Color = "0 0 0 0.9",
Material = "assets/content/ui/uibackgroundblur.mat"
},
CursorEnabled = true
}, "Overlay", Layer);
container.Add(new CuiButton
{
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
Text = {Text = ""},
Button =
{
Color = "0 0 0 0",
Close = Layer,
Command = "UI_Kits close"
}
}, Layer);
}
#endregion
#region Main
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5",
OffsetMin =
// ... [Code preview truncated due to length. Full source in attached file] ...