C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins {
[Info("Kits GUI Normal Servers", "Pho3niX90", "0.0.2")]
[Description("")]
public class KingGraphicalKits : RustPlugin {
#region Vars
private const string elemMain = "KitsGraphical1.Main";
private const string elemInfo = "KitsGraphical1.Info";
#endregion
#region Oxide Hooks
private object CanSeeKits(BasePlayer player) {
CreateKitsUI(player, 1);
return true;
}
private object CanSeeKitsInfo(BasePlayer player, string kitName) {
BuildContentsUI(player, kitName);
return true;
}
private void OnKitUIRefreshRequested(BasePlayer player) {
var obj = CanSeeKits(player);
}
private void OpenKitUIPage(BasePlayer player, int page) {
CreateKitsUI(player, page);
}
#endregion
#region Core
private void CreateKitsUI(BasePlayer player, int currentPage) {
var kits = API_GetPlayerUIKits(player);
var maxPages = (int)Math.Ceiling((double)kits.Length / config.kitsOnPage);
if (currentPage <= 0) {
currentPage = 1;
}
if (currentPage > maxPages) {
currentPage = maxPages;
}
var forUI = new List<KitUI>();
var start = (currentPage - 1) * config.kitsOnPage;
var end = start + config.kitsOnPage;
for (var i = 0; i < kits.Length; i++) {
if (i >= start && i < end) {
forUI.Add(kits[i]);
}
}
var container = new CuiElementContainer();
BuildMainUI(player.UserIDString, container, currentPage, maxPages);
BuildKitsUI(container, forUI.ToArray(), player.UserIDString);
CuiHelper.DestroyUi(player, elemMain);
CuiHelper.AddUi(player, container);
}
private void BuildMainUI(string userID, CuiElementContainer container, int currentPage, int maxPage) {
// Main panel
container.Add(new CuiElement {
Name = elemMain,
Parent = "Overlay",
Components =
{
new CuiImageComponent
{
Color = config.backgroundColor,
Sprite = config.backgroundSprite,
Material = config.backgroundMaterial
},
new CuiRectTransformComponent {AnchorMin = "0 0", AnchorMax = "1 1"},
new CuiNeedsCursorComponent()
}
});
// Header text
container.Add(new CuiElement {
Parent = elemMain,
Components =
{
new CuiTextComponent
{
Text = GetMessage(Message.TextHead, userID), Align = TextAnchor.UpperCenter
},
new CuiOutlineComponent
{
Color = config.outlineColor,
Distance = config.outlineDistance
},
new CuiRectTransformComponent {AnchorMin = "0 0.5", AnchorMax = "1 1"},
}
});
// Text bottom
container.Add(new CuiElement {
Parent = elemMain,
Components =
{
new CuiTextComponent
{
Text = GetMessage(Message.TextBottom, userID), Align = TextAnchor.LowerCenter
},
new CuiOutlineComponent
{
Color = config.outlineColor,
Distance = config.outlineDistance
},
new CuiRectTransformComponent {AnchorMin = "0 0", AnchorMax = "1 0.5"},
}
});
if (currentPage > 1) {
container.Add(
new CuiButton {
Text = { Text = GetMessage(Message.PreviousPage, userID), Align = TextAnchor.MiddleCenter },
Button = { Command = $"kits.core page {currentPage - 1}", Color = "0 0 0 0", },
RectTransform = { AnchorMin = "0 0", AnchorMax = "0.1 1" }
}, elemMain);
}
if (currentPage < maxPage) {
container.Add(
new CuiButton {
Text = { Text = GetMessage(Message.NextPage, userID), Align = TextAnchor.MiddleCenter },
Button = { Command = $"kits.core page {currentPage + 1}", Color = "0 0 0 0", },
RectTransform = { AnchorMin = "0.9 0", AnchorMax = "1 1" }
}, elemMain);
}
container.Add(new CuiButton {
Text = { Text = null },
Button = { Close = elemMain, Color = "1 0 0 0", },
RectTransform = { AnchorMin = "0.1 0", AnchorMax = "0.9 1" }
}, elemMain);
}
private void BuildKitsUI(CuiElementContainer container, KitUI[] kits, string userID) {
var i = 0;
var lines = (int)Math.Ceiling((double)kits.Length / config.kitsPerLine);
var kitsOnLine = config.kitsPerLine > kits.Length ? kits.Length : config.kitsPerLine;
var sizeX = config.KitsizeX;
var sizeY = config.KitsizeY;
var sizePanelX = kitsOnLine * (config.KitsizeX + config.KitoffsetX) - config.KitoffsetX;
var sizePanelY = lines * (config.KitsizeY + config.KitoffsetY) - config.KitoffsetY;
var originalX = -sizePanelX / 2;
var originalY = sizePanelY / 2;
var startX = originalX;
var startY = originalY;
foreach (var kit in kits) {
var panelName = elemMain + "." + kit.name + "." + Core.Random.Range(1000, 9999);
// Panel
container.Add(new CuiElement {
Name = panelName,
Parent = elemMain,
Components =
{
new CuiImageComponent
{
Color = config.kitBackGroundColor
},
new CuiRectTransformComponent
{
AnchorMin = "0.5 0.5",
AnchorMax = "0.5 0.5",
OffsetMin = $"{startX} {startY - sizeY}",
OffsetMax = $"{startX + sizeX} {startY}"
}
}
});
// Icon
if (!string.IsNullOrEmpty(kit.url)) {
container.Add(new CuiElement {
Parent = panelName,
Components =
{
new CuiRawImageComponent
{
Png = GetImage(kit.url),
Color = "1 1 1 1"
},
new CuiRectTransformComponent
{
AnchorMin = "0 0",
AnchorMax = "1 1"
}
}
});
}
GenerateContents(kit, 9, 10, 18, 18, container, panelName,
"0.05 0.7",
"0.05 0.7", 6);
// Kit Name
container.Add(new CuiElement {
Name = panelName + ".name",
Parent = panelName,
Components =
{
new CuiTextComponent
{
Text = kit.displayName,
Align = TextAnchor.UpperCenter
},
new CuiOutlineComponent
{
Color = config.outlineColor,
Distance = config.outlineDistance
},
new CuiRectTransformComponent
{
AnchorMin = "0.05 0.1",
AnchorMax = "0.95 0.9"
}
}
});
// Kit Info
container.Add(new CuiButton {
Button =
{
Color = "0 0 0 0",
Command = $"kits.core info {kit.name}"
},
Text =
{
Text = GetMessage(Message.InfoText, userID),
Align = TextAnchor.UpperRight,
},
RectTransform =
{
AnchorMin = "0.05 0.5",
AnchorMax = "0.95 0.9"
}
}, panelName);
// Kit claim
container.Add(new CuiButton {
Button =
{
Color = "1 1 1 0.5",
Command = $"kits.core {kit.name} ui.refresh"
},
Text =
{
Text = kit.messageOnButton,
Align = TextAnchor.LowerCenter
},
RectTransform =
{
AnchorMin = "0.05 0.05",
AnchorMax = "0.95 0.15"
}
}, panelName);
startX += sizeX + config.KitoffsetX;
i++;
if (i > 0 && i % kitsOnLine == 0) {
startX = originalX;
startY -= sizeY + config.KitoffsetY;
}
}
}
private void BuildContentsUI(BasePlayer player, string kitName) {
var kit = API_GetKitForUI(player, kitName);
var container = new CuiElementContainer
{
new CuiElement
{
Name = elemInfo,
Parent = "Overlay",
Components =
{
new CuiImageComponent
{
Color = config.backgroundColor,
Sprite = config.backgroundSprite,
Material = config.backgroundMaterial
},
new CuiRectTransformComponent {AnchorMin = "0 0", AnchorMax = "1 1"},
new CuiNeedsCursorComponent()
}
}
};
var numBlock = TimeSpan.FromSeconds(kit.block);
var strBlock = string.Empty;
if (numBlock.Days > 0) {
strBlock += $"{numBlock.Days}d ";
}
if (numBlock.Hours > 0) {
strBlock += $"{numBlock.Hours}h ";
}
if (numBlock.Minutes > 0) {
strBlock += $"{numBlock.Minutes}m ";
}
if (numBlock.Seconds > 0) {
strBlock += $"{numBlock.Seconds}s ";
}
var numCooldown = TimeSpan.FromSeconds(kit.cooldown);
var strCooldown = string.Empty;
if (numCooldown.Days > 0) {
strCooldown += $"{numCooldown.Days}d ";
}
if (numCooldown.Hours > 0) {
strCooldown += $"{numCooldown.Hours}h ";
}
if (numCooldown.Minutes > 0) {
strCooldown += $"{numCooldown.Minutes}m ";
}
if (numCooldown.Seconds > 0) {
strCooldown += $"{numCooldown.Seconds}s ";
}
strBlock = string.IsNullOrEmpty(strBlock) ? GetMessage(Message.None, player.UserIDString) : strBlock;
strCooldown = string.IsNullOrEmpty(strCooldown) ? GetMessage(Message.None, player.UserIDString) : strCooldown;
var strUses = kit.uses > 1 ? kit.uses.ToString() : GetMessage(Message.Infinite, player.UserIDString);
var text = GetMessage(Message.KitContents, player.displayName, "{name}", kit.displayName, "{description}", kit.description, "{wipeblock}", strBlock, "{cooldown}", strCooldown, "{uses}", strUses);
container.Add(new CuiElement {
Parent = elemInfo,
Components =
{
new CuiTextComponent
{
Align = TextAnchor.MiddleCenter,
Text = text
},
new CuiRectTransformComponent
{
AnchorMin = "0.05 0.7",
AnchorMax = "0.95 0.995"
}
}
});
container.Add(new CuiElement {
Parent = elemInfo,
Components =
{
new CuiButtonComponent
{
Color = "0 0 0 0",
Close = elemInfo
},
new CuiRectTransformComponent
{
AnchorMin = "0 0",
AnchorMax = "1 1"
}
}
});
GenerateContents(kit, 14, 75, config.ContentsizeX, config.ContentsizeY, container, elemInfo);
CuiHelper.DestroyUi(player, elemInfo);
CuiHelper.AddUi(player, container);
}
void GenerateContents(KitUI kit, float colms, float colSize, float sizeX, float sizeY, CuiElementContainer container, string parent, string AnchorMin = "0.1 0.5", string AnchorMax = "0.1 0.5", int fontS = 0) {
var i = 0;
var itemsOnLine = (colms * colSize) / sizeX;
var originalX = 0f;
var originalY = 0f;
var startX = originalX;
var startY = originalY;
foreach (var pair in kit.items) {
var url = $"https://rustlabs.com/img/items180/{pair.Key}.png";
var amount = pair.Value;
// Icon
container.Add(new CuiElement {
Name = elemInfo + pair.Key,
Parent = parent,
Components =
{
new CuiRawImageComponent
{
Png = GetImage(url),
Color = "1 1 1 1"
},
new CuiRectTransformComponent
{
AnchorMin = AnchorMin,
AnchorMax = AnchorMax,
OffsetMin = $"{startX} {startY - sizeY}",
OffsetMax = $"{startX + sizeX} {startY}"
}
}
});
// Amount
CuiTextComponent cuiTC = new CuiTextComponent {
Text = amount.ToString(),
Align = TextAnchor.LowerRight
};
CuiTextComponent cuiTCF = new CuiTextComponent {
Text = amount.ToString(),
Align = TextAnchor.LowerRight,
FontSize = fontS
};
container.Add(new CuiElement {
Parent = elemInfo + pair.Key,
Components =
{
fontS > 0 ? cuiTCF : cuiTC,
new CuiOutlineComponent
{
Color = config.outlineColor,
Distance = config.outlineDistance
},
new CuiRectTransformComponent
{
AnchorMin = "0 0",
AnchorMax = "1 1"
}
}
});
startX += sizeX + config.ContentoffsetX;
i++;
if (i > 0 && i % colms == 0) {
startX = originalX;
startY -= sizeY + config.ContentoffsetY;
}
}
}
#endregion
#region Configuration | 2.0.0
private static ConfigData config = new ConfigData();
private class ConfigData {
[JsonProperty(PropertyName = "Background color")]
public string backgroundColor = "0.25 0.25 0.25 0.75";
[JsonProperty(PropertyName = "Background material")]
public string backgroundMaterial = "assets/content/ui/uibackgroundblur-ingamemenu.mat";
[JsonProperty(PropertyName = "Background sprite")]
public string backgroundSprite = "";
[JsonProperty(PropertyName = "Maximal kits on one page")]
public int kitsOnPage = 25;
[JsonProperty(PropertyName = "Maximal kits on one line")]
public int kitsPerLine = 5;
[JsonProperty(PropertyName = "Kit image size X")]
public int KitsizeX = 200;
[JsonProperty(PropertyName = "Kit image size Y")]
public int KitsizeY = 200;
[JsonProperty(PropertyName = "Kit image offset X")]
public int KitoffsetX = 5;
[JsonProperty(PropertyName = "Kit image offset Y")]
public int KitoffsetY = 5;
[JsonProperty(PropertyName = "Content image size X")]
public int ContentsizeX = 75;
[JsonProperty(PropertyName = "Content image size Y")]
public int ContentsizeY = 75;
[JsonProperty(PropertyName = "Content image offset X")]
public int ContentoffsetX = 2;
[JsonProperty(PropertyName = "Content image offset Y")]
public int ContentoffsetY = 2;
[JsonProperty(PropertyName = "Kit background color")]
public string kitBackGroundColor = "0 1 0 0.3";
[JsonProperty(PropertyName = "Outline color")]
public string outlineColor = "0 0 0 1";
[JsonProperty(PropertyName = "Outline distance")]
public string outlineDistance = "1.0 -0.5";
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<ConfigData>();
if (config == null) {
LoadDefaultConfig();
}
} catch {
for (var i = 0; i < 3; i++) {
PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
}
LoadDefaultConfig();
return;
}
ValidateConfig();
SaveConfig();
}
private static void ValidateConfig() {
}
protected override void LoadDefaultConfig() {
config = new ConfigData();
}
protected override void SaveConfig() {
Config.WriteObject(config);
}
#endregion
#region Language | 2.0.0
private Dictionary<object, string> langMessages = new Dictionary<object, string>
{
{Message.InfoText, "Info"},
{Message.CloseMark, "x"},
{Message.NextPage, "<size=30> >> </size>"},
{Message.PreviousPage, "<size=30> << </size>"},
{Message.TextHead, "<size=25>\nKits available:</size>"},
{Message.TextBottom, "<size=15><color=#ff0000>Click on a free place to exit!\n</color></size>"},
{Message.None, "None"},
{Message.Infinite, "Unlimited"},
{Message.KitContents, "<size=40><color=#00ffff>{name}</color></size>\n<size=20>Description: {description}\nBlock after wipe: {wipeblock}\nCooldown: {cooldown}\nUses left: {uses}</size>"},
};
private enum Message {
InfoText,
CloseMark,
TextHead,
TextBottom,
NextPage,
PreviousPage,
KitContents,
None,
Infinite,
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(langMessages.ToDictionary(x => x.Key.ToString(), y => y.Value), this);
}
private string GetMessage(Message key, string playerID = null, params object[] args) {
var message = lang.GetMessage(key.ToString(), this, playerID);
var dic = OrganizeArgs(args);
if (dic != null) {
foreach (var pair in dic) {
var s0 = "{" + pair.Key + "}";
var s1 = pair.Key;
var s2 = pair.Value != null ? pair.Value.ToString() : "null";
message = message.Replace(s0, s2, StringComparison.InvariantCultureIgnoreCase);
message = message.Replace(s1, s2, StringComparison.InvariantCultureIgnoreCase);
}
}
return message;
}
private void SendMessage(object receiver, string message) {
if (receiver == null) {
Puts(message);
return;
}
var console = receiver as ConsoleSystem.Arg;
if (console != null) {
SendReply(console, message);
return;
}
var player = receiver as BasePlayer;
if (player != null) {
player.ChatMessage(message);
return;
}
}
private void SendMessage(object receiver, Message key, params object[] args) {
var userID = (receiver as BasePlayer)?.UserIDString;
var message = GetMessage(key, userID, args);
SendMessage(receiver, message);
}
private static Dictionary<string, object> OrganizeArgs(object[] args) {
var dic = new Dictionary<string, object>();
for (var i = 0; i < args.Length; i += 2) {
var value = args[i].ToString();
var nextValue = i + 1 < args.Length ? args[i + 1] : null;
dic.Add(value, nextValue);
}
return dic;
}
#endregion
#region Image Library Support
[PluginReference] private Plugin ImageLibrary;
private string GetImage(string url) {
return ImageLibrary?.Call<string>("GetImage", url);
}
#endregion
#region Kit UI Class 1.2.0
private class KitUI {
public string name = string.Empty;
public string displayName = string.Empty;
public int cooldown = 3600;
public int block = 0;
public string url = string.Empty;
public string description = string.Empty;
public int uses = 0;
public string messageOnButton = string.Empty;
public Dictionary<string, int> items = new Dictionary<string, int>();
}
#endregion
#region API
private static KitUI[] API_GetPlayerUIKits(BasePlayer player) {
var obj = Interface.CallHook(nameof(API_GetPlayerUIKits), player);
return obj == null ? new KitUI[] { } : JsonConvert.DeserializeObject<KitUI[]>(obj.ToString());
}
private static KitUI API_GetKitForUI(BasePlayer player, string kitName) {
var obj = Interface.CallHook(nameof(API_GetKitForUI), player, kitName);
return obj == null ? new KitUI() : JsonConvert.DeserializeObject<KitUI>(obj.ToString());
}
#endregion
}
}