C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using Random = UnityEngine.Random;
namespace Oxide.Plugins
{
[Info("Kits", "Mevent", "1.0.18")]
public class Kits : RustPlugin
{
#region Fields
[PluginReference] private Plugin ImageLibrary, CopyPaste, Notify;
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 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<string>> ItemsCategories =
new Dictionary<string, List<string>>();
private const string PERM_ADMIN = "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;
[JsonProperty(PropertyName = "Default Kit Color")]
public string KitColor = "#A0A935";
[JsonProperty(PropertyName = "Work with Notify?")]
public bool UseNotify = true;
[JsonProperty(PropertyName = "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] Commands = { "kit", "kits" };
[JsonProperty(PropertyName = "Rarity Settings", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<RarityColor> RarityColors = new List<RarityColor>
{
new RarityColor(40, "#A0A935")
};
[JsonProperty(PropertyName = "Auto Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> AutoKits = new List<string>
{
"autokit", "autokit_vip", "autokit_premium"
};
[JsonProperty(PropertyName = "Getting an auto kit 1 time?")]
public bool OnceAutoKit;
[JsonProperty(PropertyName = "Logs")]
public LogInfo Logs = new LogInfo
{
Console = true,
File = true
};
[JsonProperty(PropertyName = "Image Settings")]
public ImageSettings ImageSettings = new ImageSettings
{
Enabled = false,
AnchorMin = "0.5 1",
AnchorMax = "0.5 1",
OffsetMin = "-32 -75",
OffsetMax = "32 -11"
};
[JsonProperty(PropertyName = "Color 1")]
public string ColorOne = "#161617";
[JsonProperty(PropertyName = "Color 2")]
public string ColorTwo = "#0E0E10";
[JsonProperty(PropertyName = "Color 3")]
public string ColorThree = "#4B68FF";
[JsonProperty(PropertyName = "Color 4")]
public string ColorFour = "#303030";
[JsonProperty(PropertyName = "Color Red")]
public string ColorRed = "#FF4B4B";
[JsonProperty(PropertyName = "Color White")]
public string ColorWhite = "#FFFFFF";
[JsonProperty(PropertyName = "Show Number?")]
public bool ShowNumber = true;
[JsonProperty(PropertyName = "Show Display Name?")]
public bool ShowName = true;
[JsonProperty(PropertyName = "Show No Permission Description?")]
public bool ShowNoPermDescription = true;
[JsonProperty(PropertyName = "Show All Kits?")]
public bool ShowAllKits;
[JsonProperty(PropertyName = "CopyPaste Parameters",
ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> CopyPasteParameters = new List<string>
{
"deployables", "true", "inventories", "true"
};
[JsonProperty(PropertyName = "Block in Building Block?")]
public bool BlockBuilding;
[JsonProperty(PropertyName = "NPC Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public 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 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 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 = "Self-loading images")]
public ImageData ImageData = new ImageData
{
Enabled = true,
URL = "https://rustlabs.com/img/items180/"
};
[JsonProperty(PropertyName = "Interface")]
public UserInterface UI = new UserInterface
{
Height = 455,
Width = 640,
KitHeight = 165,
KitWidth = 135f,
Margin = 10f,
KitsOnString = 4,
Strings = 2,
YIndent = -100f
};
}
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;
}
private class ImageData
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "URL")] public string URL;
}
private class NpcKitsData
{
[JsonProperty(PropertyName = "Description")]
public string Description;
[JsonProperty(PropertyName = "Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> Kits;
}
private abstract class InterfacePosition
{
public string AnchorMin;
public string AnchorMax;
public string OffsetMin;
public string OffsetMax;
}
private class ImageSettings : InterfacePosition
{
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
}
private class DescriptionSettings : ImageSettings
{
[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 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 int Chance;
[JsonProperty(PropertyName = "Color")] public 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();
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();
}
#endregion
#region Data
private PluginData _data;
private Dictionary<ulong, Dictionary<string, KitData>> PlayerData;
private void SaveData()
{
SaveKits();
SaveUsers();
}
private void SaveKits()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Kits", _data);
}
private void SaveUsers()
{
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Data", PlayerData);
}
private void LoadData()
{
try
{
_data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>($"{Name}/Kits");
PlayerData =
Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, Dictionary<string, KitData>>>(
$"{Name}/Data");
}
catch (Exception e)
{
PrintError(e.ToString());
}
if (_data == null) _data = new PluginData();
if (PlayerData == null) PlayerData = new Dictionary<ulong, Dictionary<string, KitData>>();
}
private class PluginData
{
[JsonProperty(PropertyName = "Kits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<Kit> Kits = new List<Kit>();
}
private KitData GetPlayerData(ulong userID, string name)
{
if (!PlayerData.ContainsKey(userID))
PlayerData[userID] = new Dictionary<string, KitData>();
if (!PlayerData[userID].ContainsKey(name))
PlayerData[userID][name] = new KitData();
return PlayerData[userID][name];
}
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 = "Amount")]
public int Amount;
[JsonProperty(PropertyName = "Cooldown")]
public double Cooldown;
[JsonProperty(PropertyName = "Wipe Block")]
public double CooldownAfterWipe;
[JsonProperty(PropertyName = "Building")]
public string Building;
[JsonProperty(PropertyName = "Items", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<KitItem> Items;
public void Get(BasePlayer player)
{
Items?.ForEach(item => item?.Get(player));
}
}
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());
}
private Item BuildItem()
{
var item = ItemManager.CreateByName(ShortName, Amount > 1 ? Amount : 1, SkinID);
item.condition = Condition;
item.position = Position;
if (Blueprint != 0)
item.blueprintTarget = Blueprint;
if (Weapon != null)
{
var baseProjectile = item.GetHeldEntity() as BaseProjectile;
if (baseProjectile != null && !string.IsNullOrEmpty(Weapon.ammoType))
{
baseProjectile.primaryMagazine.contents = Weapon.ammoAmount;
baseProjectile.primaryMagazine.ammoType =
ItemManager.FindItemDefinition(Weapon.ammoType);
}
}
Content?.ForEach(cont =>
{
var new_cont = ItemManager.CreateByName(cont.ShortName, cont.Amount);
new_cont.condition = cont.Condition;
new_cont.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;
}
}
private class Weapon
{
public string ammoType;
public int ammoAmount;
}
private class ItemContent
{
public string ShortName;
public float Condition;
public int Amount;
}
private class KitData
{
public int Amount;
public double Cooldown;
}
#endregion
#region Hooks
private void Init()
{
_instance = this;
LoadData();
}
private void OnServerInitialized()
{
LoadImages();
#region Colors
ColorOne = HexToCuiColor(_config.ColorOne);
ColorTwo = HexToCuiColor(_config.ColorTwo);
ColorWhite = HexToCuiColor(_config.ColorWhite);
ColorThree = HexToCuiColor(_config.ColorThree);
ColorFour = HexToCuiColor(_config.ColorFour);
ColorRed = HexToCuiColor(_config.ColorRed);
#endregion
#region Set IDs
_data.Kits.ForEach(kit =>
{
kit.ID = LastKitID;
++LastKitID;
if (!string.IsNullOrEmpty(kit.Permission) && !permission.PermissionExists(kit.Permission))
permission.RegisterPermission(kit.Permission, this);
});
#endregion
if (!permission.PermissionExists(PERM_ADMIN))
permission.RegisterPermission(PERM_ADMIN, this);
FixItemsPositions();
FillCategories();
AddCovalenceCommand(_config.Commands, nameof(CmdOpenKits));
timer.Every(1, HandleUi);
}
private void OnServerSave()
{
timer.In(Random.Range(2, 7), SaveData);
}
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);
if (kitEditing.ContainsKey(player) || itemEditing.ContainsKey(player))
player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
}
SaveUsers();
_instance = null;
}
private void OnNewSave(string filename)
{
if (!_config.AutoWipe) return;
LoadData();
PlayerData.Clear();
SaveUsers();
}
private void OnPlayerRespawned(BasePlayer player)
{
if (player == null) 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);
}
private object CanSpectateTarget(BasePlayer player, string filter)
{
return player != null && (itemEditing.ContainsKey(player) || kitEditing.ContainsKey(player))
? (object)true
: null;
}
private void OnUseNPC(BasePlayer npc, BasePlayer player)
{
if (npc == null || player == null || !_config.NpcKits.ContainsKey(npc.UserIDString)) return;
MainUi(player, npc.userID, First: true);
}
#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;
}
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);
itemEditing.Remove(player);
kitEditing.Remove(player);
player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
if (itemEditing.Count == 0 && kitEditing.Count == 0)
Unsubscribe(nameof(CanSpectateTarget));
break;
}
case "stopedit":
{
itemEditing.Remove(player);
kitEditing.Remove(player);
player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
if (itemEditing.Count == 0 && kitEditing.Count == 0)
Unsubscribe(nameof(CanSpectateTarget));
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;
player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
kitEditing.Remove(player);
itemEditing.Remove(player);
if (itemEditing.Count == 0 && kitEditing.Count == 0)
Unsubscribe(nameof(CanSpectateTarget));
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 "Name":
newValue = value;
break;
case "DisplayName":
newValue = string.Join(" ", arg.Args.Skip(4));
break;
case "Color":
newValue = value;
break;
case "Permission":
newValue = value;
break;
case "Hide":
bool hide;
bool.TryParse(value, out hide);
newValue = hide;
break;
case "AutoKit":
bool autoKit;
bool.TryParse(value, out autoKit);
newValue = autoKit;
break;
case "Amount":
int amount;
int.TryParse(value, out amount);
newValue = amount;
break;
case "Cooldown":
double cooldown;
double.TryParse(value, out cooldown);
newValue = cooldown;
break;
}
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];
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 (Enum.TryParse(value, out type))
newValue = type;
break;
}
case "Command":
{
newValue = string.Join(" ", arg.Args.Skip(5));
break;
}
case "ShortName":
{
newValue = value;
break;
}
case "Amount":
{
int Value;
if (int.TryParse(value, out Value))
newValue = Value;
break;
}
case "Blueprint":
{
int Value;
if (int.TryParse(value, out Value))
newValue = Value;
break;
}
case "SkinID":
{
ulong Value;
if (ulong.TryParse(value, out Value))
newValue = Value;
break;
}
case "Chance":
{
int Value;
if (int.TryParse(value, out Value))
newValue = Value;
break;
}
}
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.Items.Find(x => x.Container == container && x.Position == slot);
var hasItem = item != null;
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 (!hasItem)
{
var info = ItemManager.FindItemDefinition(item.ShortName);
if (info != null)
item.Condition = info.condition.max;
kit.Items.Add(item);
}
itemEditing.Remove(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.Items.Find(x => x.Container == arg.Args[3] && x.Position == slot);
if (item != null)
kit.Items.Remove(item);
itemEditing.Remove(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"],
Hide = editing["Hide"] as bool? ?? true,
Amount = (int)editing["Amount"],
Cooldown = (double)editing["Cooldown"],
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.Hide = editing["Hide"] as bool? ?? true;
kit.Amount = (int)editing["Amount"];
kit.Cooldown = (double)editing["Cooldown"];
}
var autoKit = editing["AutoKit"] as bool? ?? false;
if (autoKit)
{
if (!_config.AutoKits.Contains(kit.Name))
{
_config.AutoKits.Add(kit.Name);
SaveConfig();
}
}
else
{
_config.AutoKits.Remove(kit.Name);
SaveConfig();
}
kitEditing.Remove(player);
if (!string.IsNullOrEmpty(kit.Permission) && !permission.PermissionExists(kit.Permission))
permission.RegisterPermission(kit.Permission, this);
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;
SaveKits();
InfoKitUi(player, kit);
break;
}
}
}
[ConsoleCommand("kits.resetkits")]
private void CmdKitsReset(ConsoleSystem.Arg arg)
{
if (!arg.IsAdmin) return;
_data.Kits.Clear();
PlayerData.Clear();
SaveData();
SendReply(arg, "Plugin successfully reset");
}
[ConsoleCommand("kits.resetdata")]
private void CmdKitsResetPlayers(ConsoleSystem.Arg arg)
{
if (!arg.IsAdmin) return;
PlayerData.Clear();
SaveUsers();
SendReply(arg, "Players 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);
}
#endregion
#region Interface
private void MainUi(BasePlayer player, ulong targetId = 0, int page = 0, bool showAll = false,
bool First = false)
{
#region Fields
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 xSwicth = constSwitch;
var ySwitch = _config.UI.YIndent;
var allKits = GetAvailableKits(player, targetId.ToString(), showAll);
var kitsList = allKits.Skip(page * totalAmount).Take(totalAmount).ToList();
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 = $"-{_config.UI.Width / 2f} -{_config.UI.Height / 2f}",
OffsetMax = $"{_config.UI.Width / 2f} {_config.UI.Height / 2f}"
},
Image =
{
Color = ColorTwo
}
}, Layer, Layer + ".Main");
#region Header
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = "0 1", AnchorMax = "1 1",
OffsetMin = "0 -50",
OffsetMax = "0 0"
},
Image = { Color = ColorOne }
}, Layer + ".Main", Layer + ".Header");
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "1 1",
OffsetMin = "10 0",
OffsetMax = "0 0"
},
Text =
{
Text = Msg(player, MainTitle),
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-bold.ttf",
FontSize = 14,
Color = ColorWhite
}
}, Layer + ".Header");
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = "1 1", AnchorMax = "1 1",
OffsetMin = "-35 -37.5",
OffsetMax = "-10 -12.5"
},
Text =
{
Text = Msg(player, Close),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf",
FontSize = 10,
Color = ColorWhite
},
Button =
{
Close = Layer,
Color = ColorThree,
Command = "UI_Kits close"
}
}, Layer + ".Header");
if (IsAdmin(player))
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = "1 1", AnchorMax = "1 1",
OffsetMin = "-140 -37.5",
OffsetMax = "-45 -12.5"
},
Text =
{
Text = Msg(player, CreateKit),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = ColorWhite
},
Button =
{
Color = ColorTwo,
Command = "UI_Kits editkit True"
}
}, Layer + ".Header");
#endregion
#region Second Header
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = "10 -85",
OffsetMax = "110 -60"
},
Text =
{
Text = Msg(player, ListKits),
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = ColorWhite
}
}, Layer + ".Main");
#region Checkbox
if (IsAdmin(player))
CheckBoxUi(ref container,
Layer + ".Main",
Layer + ".ShowAll",
"0 1", "0 1",
"90 -77.5",
"100 -67.5",
showAll,
$"UI_Kits main {targetId} 0 {!showAll}",
Msg(player, ShowAll)
);
#endregion
#region Pages
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = "1 1", AnchorMax = "1 1",
OffsetMin = "-132.5 -82.5",
OffsetMax = "-72.5 -60"
},
Text =
{
Text = Msg(player, Back),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = ColorWhite
},
Button =
{
Color = ColorOne,
Command = page != 0 ? $"UI_Kits main {targetId} {page - 1} {showAll}" : ""
}
}, Layer + ".Main");
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = "1 1", AnchorMax = "1 1",
OffsetMin = "-70 -82.5",
OffsetMax = "-10 -60"
},
Text =
{
Text = Msg(player, Next),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = ColorWhite
},
Button =
{
Color = ColorThree,
Command = allKits.Count > (page + 1) * totalAmount
? $"UI_Kits main {targetId} {page + 1} {showAll}"
: ""
}
}, Layer + ".Main");
#endregion
#endregion
#region Kits
if (allKits.Count == 0)
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "1 1",
OffsetMin = "0 25", OffsetMax = "0 -85"
},
Text =
{
Text = Msg(player, NotAvailableKits),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf",
FontSize = 20,
Color = "1 1 1 0.45"
}
}, Layer + ".Main");
else
for (var i = 0; i < kitsList.Count; i++)
{
var kit = kitsList[i];
var number = page * totalAmount + i + 1;
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = $"{xSwicth} {ySwitch - _config.UI.KitHeight}",
OffsetMax = $"{xSwicth + _config.UI.KitWidth} {ySwitch}"
},
Image =
{
Color = "0 0 0 0"
}
}, Layer + ".Main", Layer + $".Kit.{kit.ID}.Main");
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "1 1",
OffsetMin = "0 30", OffsetMax = "0 0"
},
Image =
{
Color = ColorOne
}
}, Layer + $".Kit.{kit.ID}.Main", Layer + $".Kit.{kit.ID}.Main.Background");
#region Name
if (_config.ShowNumber)
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-45 -75",
OffsetMax = "45 0"
},
Text =
{
Text = $"#{number}",
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf",
FontSize = 60,
Color = ColorFour
}
}, Layer + $".Kit.{kit.ID}.Main");
if (_config.ShowName)
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-45 -75",
OffsetMax = "45 0"
},
Text =
{
Text = $"{kit.DisplayName}",
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf",
FontSize = 16,
Color = "1 1 1 1"
}
}, Layer + $".Kit.{kit.ID}.Main");
#endregion
#region Image
if (_config.ImageSettings.Enabled && !string.IsNullOrEmpty(kit.Image))
container.Add(new CuiElement
{
Parent = Layer + $".Kit.{kit.ID}.Main",
Components =
{
new CuiRawImageComponent {Png = ImageLibrary.Call<string>("GetImage", kit.Image)},
new CuiRectTransformComponent
{
AnchorMin = _config.ImageSettings.AnchorMin,
AnchorMax = _config.ImageSettings.AnchorMax,
OffsetMin = _config.ImageSettings.OffsetMin,
OffsetMax = _config.ImageSettings.OffsetMax
}
}
});
#endregion
#region Line
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = "0 0", AnchorMax = "1 0",
OffsetMin = "0 0", OffsetMax = "0 2"
},
Image = { Color = HexToCuiColor(kit.Color) }
}, Layer + $".Kit.{kit.ID}.Main.Background");
#endregion
#region Give Kit
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = $"0 -{_config.UI.KitHeight}", OffsetMax = $"105 -{_config.UI.KitHeight - 25}"
},
Text =
{
Text = Msg(player, KitTake),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = "1 1 1 1"
},
Button =
{
Color = ColorOne,
Command = $"UI_Kits givekit {kit.ID}"
}
}, Layer + $".Kit.{kit.ID}.Main");
#endregion
#region Info
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = "0 1", AnchorMax = "0 1",
OffsetMin = $"{_config.UI.KitWidth - 25} -{_config.UI.KitHeight}",
OffsetMax = $"{_config.UI.KitWidth} -{_config.UI.KitHeight - 25}"
},
Text =
{
Text = Msg(player, KitInfo),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf",
FontSize = 18,
Color = "1 1 1 1"
},
Button =
{
Color = ColorOne,
Command = $"UI_Kits infokit {kit.ID}"
}
}, Layer + $".Kit.{kit.ID}.Main");
#endregion
RefreshKitUi(ref container, player, kit);
if ((i + 1) % _config.UI.KitsOnString == 0)
{
xSwicth = constSwitch;
ySwitch = ySwitch - _config.UI.KitHeight - _config.UI.Margin;
}
else
{
xSwicth += _config.UI.Margin + _config.UI.KitWidth;
}
}
#endregion
#region Description
NpcKitsData npcKit;
var description = targetId == 0
? _config.Description.Description
: _config.NpcKits.TryGetValue(targetId.ToString(), out npcKit)
? npcKit.Description
: string.Empty;
_config.Description.Get(ref container, Layer + ".Main", null, description);
#endregion
#endregion
CuiHelper.DestroyUi(player, Layer + ".Main");
CuiHelper.AddUi(player, container);
}
private void InfoKitUi(BasePlayer player, Kit kit)
{
var container = new CuiElementContainer();
#region Fields
var Size = 70f;
var Margin = 5f;
var ySwitch = -125f;
var amountOnString = 6;
var constSwitch = -(amountOnString * Size + (amountOnString - 1) * Margin) / 2f;
var total = 0;
#endregion
#region Background
container.Add(new CuiPanel
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Image =
{
Color = HexToCuiColor(_config.ColorTwo, 98)
}
}, "Overlay", InfoLayer);
#endregion
#region Header
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "112.5 -140", OffsetMax = "222.5 -115"
},
Text =
{
Text = Msg(player, ComeBack),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = "1 1 1 1"
},
Button =
{
Color = ColorThree,
Command = "UI_Kits stopedit",
Close = InfoLayer
}
}, InfoLayer);
#region Change Button
if (IsAdmin(player))
{
container.Add(new CuiPanel
{
RectTransform =
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = "-12.5 -140", OffsetMax = "102.5 -115"
},
Image = { Color = "0 0 0 0" }
}, InfoLayer, InfoLayer + ".Btn.Change");
CreateOutLine(ref container, InfoLayer + ".Btn.Change", ColorThree, 1);
container.Add(new CuiButton
{
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text =
{
Text = Msg(player, Edit),
Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf",
FontSize = 10,
Color = "1 1 1 1"
},
Button =
{
Color = "0 0 0 0",
Command = $"UI_Kits editkit {false} {kit.ID}",
Close = InfoLayer
}
}, InfoLayer + ".Btn.Change");
}
#endregion
#endregion
#region Main
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = $"{constSwitch} {ySwitch - 15f}", OffsetMax = $"0 {ySwitch}"
},
Text =
{
Text = Msg(player, ContainerMain),
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-regular.ttf",
FontSize = 12,
Color = "1 1 1 1"
}
}, InfoLayer);
ySwitch -= 20f;
var xSwitch = constSwitch;
var kitItems = kit.Items.FindAll(item => item.Container == "main");
kitItems.Sort((x, y) => y.Chance.CompareTo(x.Chance));
for (var slot = 0; slot < amountOnString * 4; slot++)
{
var kitItem = kitItems.Find(x => x.Position == slot); //kitItems.Count > slot ? kitItems[slot] : null;
InfoItemUi(ref container, player,
slot,
$"{xSwitch} {ySwitch - Size}",
$"{xSwitch + Size} {ySwitch}",
kit,
kitItem,
total,
"main");
if ((slot + 1) % amountOnString == 0)
{
xSwitch = constSwitch;
ySwitch = ySwitch - Size - Margin;
}
else
{
xSwitch += Size + Margin;
}
total++;
}
#endregion
#region Wear
ySwitch -= 5f;
amountOnString = 7;
constSwitch = -(amountOnString * Size + (amountOnString - 1) * Margin) / 2f;
xSwitch = constSwitch;
kitItems = kit.Items.FindAll(item => item.Container == "wear");
kitItems.Sort((x, y) => y.Chance.CompareTo(x.Chance));
container.Add(new CuiLabel
{
RectTransform =
{
AnchorMin = "0.5 1", AnchorMax = "0.5 1",
OffsetMin = $"{constSwitch} {ySwitch - 15f}", OffsetMax = $"0 {ySwitch}"
},
Text =
{
Text = Msg(player, ContaineWear),
Align = TextAnchor.MiddleLeft,
Font = "robotocondensed-
// ... [Code preview truncated due to length. Full source in attached file] ...