C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System;
using Oxide.Game.Rust.Libraries;
namespace Oxide.Plugins {
[Info("RustApp Lite", "RustApp", "1.0.10")]
[Description("Get reports on players in Discord, using a nicely designed interface or F7")]
public class RustAppLite : RustPlugin {
#region Configuration
private class Configuration {
[JsonProperty("[UI] Chat commands")]
public List<string> report_ui_commands = new List<string>();
[JsonProperty("[UI] Report reasons")]
public List<string> report_ui_reasons = new List<string>();
[JsonProperty("[UI] Cooldown between reports (seconds)")]
public int report_ui_cooldown = 300;
[JsonProperty("[UI] Auto-parse reports from F7 (ingame reports)")]
public bool report_ui_auto_parse = true;
[JsonProperty("[Discord] Webhook to send reports")]
public string discord_webhook = "";
[JsonProperty("[Discord-Translations] Nickname field")]
public string discord_translations_nickname = "Nickname";
[JsonProperty("[Discord-Translations] Reason field")]
public string discord_translations_reason = "Reason";
[JsonProperty("[Discord-Translations] Comment field")]
public string discord_translations_comment = "Comment";
[JsonProperty("[Discord-Translations] Report sent text")]
public string discord_translations_report_sent = "Report sent";
public static Configuration Generate() {
return new Configuration {
report_ui_commands = new List<string> {
"report", "reports"
}
, report_ui_reasons = new List<string> {
"Cheat", "Abusive", "Spam"
}
, report_ui_cooldown = 300, report_ui_auto_parse = true, discord_webhook = "", discord_translations_comment = "Comment", discord_translations_nickname = "Nickname", discord_translations_reason = "Reason", discord_translations_report_sent = "Report sent"
}
;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
_Settings = Config.ReadObject<Configuration>();
}
catch {
PrintWarning($"Error reading config, creating one new config!");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void LoadDefaultConfig() => _Settings = Configuration.Generate();
protected override void SaveConfig() => Config.WriteObject(_Settings);
#endregion
#region DiscordEmbedMessage
public class DiscordMessage {
public string content {
get;
set;
}
public DiscordEmbed[] embeds {
get;
set;
}
public DiscordMessage(string Content, DiscordEmbed[] Embeds = null) {
content = Content;
embeds = Embeds;
}
public void Send(string url) {
_RustAppLite.webrequest.Enqueue(url, JsonConvert.SerializeObject(this), (code, response) => {
if (code == 200 || code == 204) {
return;
}
_RustAppLite.Error($"Веб-хук не был отправлен ({response})", $"Webhook was not sent ({response})" );
}
, _RustAppLite, Core.Libraries.RequestMethod.POST, _Headeers, 30f);
}
public static Dictionary<string, string> _Headeers = new Dictionary<string, string> {
["Content-Type"]
= "application/json"
}
;
}
public class DiscordEmbed {
public string title {
get;
set;
}
public string description {
get;
set;
}
public int? color {
get;
set;
}
public DiscordField[] fields {
get;
set;
}
public DiscordFooter footer {
get;
set;
}
public DiscordAuthor author {
get;
set;
}
public DiscordEmbed(string Title, string Description, int? Color = null, DiscordField[] Fields = null, DiscordFooter Footer = null, DiscordAuthor Author = null) {
title = Title;
description = Description;
color = Color;
fields = Fields;
footer = Footer;
author = Author;
}
}
public class DiscordFooter {
public string text {
get;
set;
}
public string icon_url {
get;
set;
}
public string proxy_icon_url {
get;
set;
}
public DiscordFooter(string Text, string Icon_url, string Proxy_icon_url = null) {
text = Text;
icon_url = Icon_url;
proxy_icon_url = Proxy_icon_url;
}
}
public class DiscordAuthor {
public string name {
get;
set;
}
public string url {
get;
set;
}
public string icon_url {
get;
set;
}
public string proxy_icon_url {
get;
set;
}
public DiscordAuthor(string Name, string Url, string Icon_url, string Proxy_icon_url = null) {
name = Name;
url = Url;
icon_url = Icon_url;
proxy_icon_url = Proxy_icon_url;
}
}
public class DiscordField {
public string name {
get;
set;
}
public string value {
get;
set;
}
public bool inline {
get;
set;
}
public DiscordField(string Name, string Value, bool Inline = false) {
name = Name;
value = Value;
inline = Inline;
}
}
#endregion DiscordEmbedMessage
#region Interfaces
private static string ReportLayer = "RAL_CommandHandlerUI";
private void DrawReportInterface(BasePlayer player, int page = 0, string search = "", bool redraw = false, BasePlayer preselect = null) {
var lineAmount = 6;
var lineMargin = 8;
var size = (float)(700 - lineMargin * lineAmount) / lineAmount;
var list = new List<BasePlayer>();
if (preselect != null) {
list.Add(preselect);
}
list.AddRange(BasePlayer.activePlayerList.ToList().Where(v => v.userID != preselect?.userID));
var finalList = list.FindAll(v => v.displayName.ToLower().Contains(search) || v.UserIDString.ToLower().Contains(search) || search == null).Skip(page * 18).Take(18);
if (finalList.Count() == 0) {
if (search == null) {
DrawReportInterface(player, page - 1);
return;
}
}
CuiElementContainer container = new CuiElementContainer();
if (!redraw) {
container.Add(new CuiPanel {
CursorEnabled = true, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
}
, Image = {
Color = "0 0 0 0.8", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
}
, "Overlay", ReportLayer, ReportLayer);
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
}
, Button = {
Color = HexToRustFormat("#343434"), Sprite = "assets/content/ui/ui.background.transparent.radial.psd", Close = ReportLayer
}
, Text = {
Text = ""
}
}
, ReportLayer);
}
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-368 -200", OffsetMax = "368 142"
}
, Image = {
Color = "1 0 0 0"
}
}
, ReportLayer, ReportLayer + ".C", ReportLayer + ".C");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "1 0", AnchorMax = "1 1", OffsetMin = "-36 0", OffsetMax = "0 0"
}
, Image = {
Color = "0 0 1 0"
}
}
, ReportLayer + ".C", ReportLayer + ".R");
//↓ ↑
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 0.5", OffsetMin = "0 0", OffsetMax = "0 -4"
}
, Button = {
Color = HexToRustFormat($"#{(list.Count > 18 && finalList.Count() == 18 ? "D0C6BD4D" : "D0C6BD33")}"), Command = list.Count > 18 && finalList.Count() == 18 ? $"RAL_CommandHandler search {page + 1}" : ""
}
, Text = {
Text = "↓", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 24, Color = HexToRustFormat($"{(list.Count > 18 && finalList.Count() == 18 ? "D0C6BD" : "D0C6BD4D")}")
}
}
, ReportLayer + ".R", ReportLayer + ".RD");
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0 0.5", AnchorMax = "1 1", OffsetMin = "0 4", OffsetMax = "0 0"
}
, Button = {
Color = HexToRustFormat($"#{(page == 0 ? "D0C6BD33" : "D0C6BD4D")}"), Command = page == 0 ? "" : $"RAL_CommandHandler search {page - 1}"
}
, Text = {
Text = "↑", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 24, Color = HexToRustFormat($"{(page == 0 ? "D0C6BD4D" : "D0C6BD")}")
}
}
, ReportLayer + ".R", ReportLayer + ".RU");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-250 8", OffsetMax = "0 43"
}
, Image = {
Color = HexToRustFormat("#D0C6BD33")
}
}
, ReportLayer + ".C", ReportLayer + ".S");
container.Add(new CuiElement {
Parent = ReportLayer + ".S", Components = {
new CuiInputFieldComponent {
Text = $"{lang.GetMessage("Header.Search.Placeholder", this, player.UserIDString)}", FontSize = 14, Font = "robotocondensed-regular.ttf", Color = HexToRustFormat("#D0C6BD80"), Align = TextAnchor.MiddleLeft, Command = "RAL_CommandHandler search 0", NeedsKeyboard = true
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "10 0", OffsetMax = "-85 0"
}
}
}
);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "1 0", AnchorMax = "1 1", OffsetMin = "-75 0", OffsetMax = "0 0"
}
, Button = {
Color = HexToRustFormat("#D0C6BD"), Material = "assets/icons/greyout.mat"
}
, Text = {
Text = $"{lang.GetMessage("Header.Search", this, player.UserIDString)}", Font = "robotocondensed-bold.ttf", Color = HexToRustFormat("#443F3B"), FontSize = 14, Align = TextAnchor.MiddleCenter
}
}
, ReportLayer + ".S", ReportLayer + ".SB");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 1", AnchorMax = "0.5 1", OffsetMin = "0 7", OffsetMax = "0 47"
}
, Image = {
Color = "0.8 0.8 0.8 0"
}
}
, ReportLayer + ".C", ReportLayer + ".LT");
container.Add(new CuiLabel() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
, Text = {
Text = $"{lang.GetMessage("Header.Find", this, player.UserIDString)} {(search != null && search.Length > 0 ? $"- {
(search.Length > 20 ? search.Substring(0, 14).ToUpper() + "..." : search.ToUpper())
}
" : "")}", Font = "robotocondensed-bold.ttf", Color = HexToRustFormat("#D0C6BD"), FontSize = 24, Align = TextAnchor.UpperLeft
}
}
, ReportLayer + ".LT");
container.Add(new CuiLabel() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
, Text = {
Text = search == null || search.Length == 0 ? lang.GetMessage("Header.SubDefault", this, player.UserIDString) : finalList.Count() == 0 ? lang.GetMessage("Header.SubFindEmpty", this, player.UserIDString) : lang.GetMessage("Header.SubFindResults", this, player.UserIDString), Font = "robotocondensed-regular.ttf", Color = HexToRustFormat("#D0C6BD4D"), FontSize = 14, Align = TextAnchor.LowerLeft
}
}
, ReportLayer + ".LT");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "-40 0"
}
, Image = {
Color = "0 1 0 0"
}
}
, ReportLayer + ".C", ReportLayer + ".L");
for (var y = 0; y < 3; y++) {
for (var x = 0; x < 6; x++) {
var target = finalList.ElementAtOrDefault(y * 6 + x);
if (target) {
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"{x * size + lineMargin * x} -{(y + 1) * size + lineMargin * y}", OffsetMax = $"{(x + 1) * size + lineMargin * x} -{y * size + lineMargin * y}"
}
, Image = {
Color = HexToRustFormat("#D0C6BD33")
}
}
, ReportLayer + ".L", ReportLayer + $".{target.UserIDString}");
container.Add(new CuiElement {
Parent = ReportLayer + $".{target.UserIDString}", Components = {
new CuiRawImageComponent {
SteamId = target.UserIDString, Sprite = "assets/icons/loading.png"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
}
}
}
);
container.Add(new CuiPanel() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
, Image = {
Sprite = "assets/content/ui/ui.background.transparent.linear.psd", Color = HexToRustFormat("#282828f2")
}
}
, ReportLayer + $".{target.UserIDString}");
string normaliseName = NormalizeString(target.displayName);
string name = normaliseName.Length > 14 ? normaliseName.Substring(0, 15) + ".." : normaliseName;
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "6 16", OffsetMax = "0 0"
}
, Text = {
Text = name, Align = TextAnchor.LowerLeft, Font = "robotocondensed-bold.ttf", FontSize = 13, Color = HexToRustFormat("#D0C6BD")
}
}
, ReportLayer + $".{target.UserIDString}");
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "6 5", OffsetMax = "0 0"
}
, Text = {
Text = target.UserIDString, Align = TextAnchor.LowerLeft, Font = "robotocondensed-regular.ttf", FontSize = 10, Color = HexToRustFormat("#D0C6BD80")
}
}
, ReportLayer + $".{target.UserIDString}");
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 0", OffsetMax = "0 0"
}
, Button = {
Color = "0 0 0 0", Command = $"RAL_CommandHandler show {target.UserIDString} {x * size + lineMargin * x} -{(y + 1) * size + lineMargin * y} {(x + 1) * size + lineMargin * x} -{y * size + lineMargin * y} {x >= 3}"
}
, Text = {
Text = ""
}
}
, ReportLayer + $".{target.UserIDString}");
}
else {
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"{x * size + lineMargin * x} -{(y + 1) * size + lineMargin * y}", OffsetMax = $"{(x + 1) * size + lineMargin * x} -{y * size + lineMargin * y}"
}
, Image = {
Color = HexToRustFormat("#D0C6BD33")
}
}
, ReportLayer + ".L");
}
}
}
CuiHelper.AddUi(player, container);
if (preselect != null) {
player.SendConsoleCommand($"RAL_CommandHandler show {preselect.UserIDString} 0 -{size} {size} 0 false");
}
}
private static string HexToRustFormat(string hex) {
if (string.IsNullOrEmpty(hex)) {
hex = "#FFFFFFFF";
}
var str = hex.Trim('#');
if (str.Length == 6) str += "FF";
if (str.Length != 8) {
throw new Exception(hex);
throw new InvalidOperationException("Cannot convert a wrong format.");
}
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);
var a = byte.Parse(str.Substring(6, 2), NumberStyles.HexNumber);
Color color = new Color32(r, g, b, a);
return string.Format("{0:F2} {1:F2} {2:F2} {3:F2}", color.r, color.g, color.b, color.a);
}
#endregion
#region Variables
private static RustAppLite _RustAppLite;
private static Configuration _Settings;
private Dictionary<ulong, double> _Cooldowns = new Dictionary<ulong, double>();
#endregion
#region Initialization
private void OnServerInitialized() {
_RustAppLite = this;
if (_Settings.discord_webhook == null || _Settings.discord_webhook.Length < 5) {
Error("Установите discord_webhook в конфигурации плагина, и перезапустите плагин o.reload RustAppLite", "Setup discord_webhook in plugin config, then reload plugin o.reload RustAppLite" );
return;
}
_Settings.report_ui_commands.ForEach(v => {
cmd.AddChatCommand(v, this, nameof(ChatCmdReport));
}
);
Log("\nВы пользуетесь упрощённой версией плагина RustApp!\nВ полной версии есть:\n — статистика игрока\n — система вызова на проверку\n — бан система\n — история чата/команд\n — и многое другое на сайте: https://rustapp.io", "\nYou are using the simplified version of the RustApp plugin!\nThe full version includes:\n — player statistics\n — inspection system\n — ban/mute system\n — chat/team history\n — and much more on the website: https://rustapp.io" );
if (!_Settings.report_ui_auto_parse) {
Unsubscribe(nameof(OnPlayerReported));
}
WriteLiteMarker();
}
private void WriteLiteMarker() {
if (Interface.Oxide.DataFileSystem.ExistsDatafile(Name)) {
return;
}
// Is using in main plugin to detect users, who switched from Lite to main branch
Interface.Oxide.DataFileSystem.WriteObject(Name, CurrentTime());
}
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["Header.Find"]
= "FIND PLAYER", ["Header.SubDefault"] = "Who do you want to report?", ["Header.SubFindResults"] = "Here are players, which we found", ["Header.SubFindEmpty"] = "No players was found", ["Header.Search"] = "Search", ["Header.Search.Placeholder"] = "Enter nickname/steamid", ["Subject.Head"] = "Select the reason for the report", ["Subject.SubHead"] = "For player %PLAYER%", ["Cooldown"] = "Wait %TIME% sec.", ["Sent"] = "Report succesful sent", ["Player.Not.Found"] = "Player with requested ID not found"
}
, this, "en");
lang.RegisterMessages(new Dictionary<string, string> {
["Header.Find"]
= "НАЙТИ ИГРОКА", ["Header.SubDefault"] = "На кого вы хотите пожаловаться?", ["Header.SubFindResults"] = "Вот игроки, которых мы нашли", ["Header.SubFindEmpty"] = "Игроки не найдены", ["Header.Search"] = "Поиск", ["Header.Search.Placeholder"] = "Введите ник/steamid", ["Subject.Head"] = "Выберите причину репорта", ["Subject.SubHead"] = "На игрока %PLAYER%", ["Cooldown"] = "Подожди %TIME% сек.", ["Sent"] = "Жалоба успешно отправлена", ["Player.Not.Found"] = "Игрок с указанным ID не найден"
}
, this, "ru");
}
private void Unload() {
foreach (var player in BasePlayer.activePlayerList) {
CuiHelper.DestroyUi(player, ReportLayer);
}
_RustAppLite = null;
_Settings = null;
}
#endregion
#region Hooks
private void OnPlayerReported(BasePlayer reporter, string targetName, string targetId, string subject, string message, string type) {
// TODO: Unsubscribed, if _Settings.report_ui_auto_parse is setted to false
var target = BasePlayer.Find(targetId) ?? BasePlayer.FindSleeping(targetId);
if (target == null) {
return;
}
RA_ReportSend(reporter.UserIDString, targetId, type, message);
}
#endregion
#region Commands
[ConsoleCommand("RAL_CommandHandler")]
private void CmdConsoleReportPanel(ConsoleSystem.Arg args) {
var player = args.Player();
if (player == null || !args.HasArgs(1)) {
return;
}
switch (args.Args[0].ToLower()) {
case "search" : {
int page = args.HasArgs(2) ? int.Parse(args.Args[1]) : 0;
string search = args.HasArgs(3) ? args.Args[2] : "";
Effect effect = new Effect("assets/prefabs/tools/detonator/effects/unpress.prefab", player, 0, new Vector3(), new Vector3());
EffectNetwork.Send(effect, player.Connection);
DrawReportInterface(player, page, search, true);
break;
}
case "show" : {
string targetId = args.Args[1];
BasePlayer target = BasePlayer.Find(targetId) ?? BasePlayer.FindSleeping(targetId);
Effect effect = new Effect("assets/prefabs/tools/detonator/effects/unpress.prefab", player, 0, new Vector3(), new Vector3());
EffectNetwork.Send(effect, player.Connection);
CuiElementContainer container = new CuiElementContainer();
CuiHelper.DestroyUi(player, ReportLayer + $".T");
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"{args.Args[2]} {args.Args[3]}", OffsetMax = $"{args.Args[4]} {args.Args[5]}"
}
, Image = {
Color = "0 0 0 1"
}
}
, ReportLayer + $".L", ReportLayer + $".T");
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = $"-500 -500", OffsetMax = $"500 500"
}
, Button = {
Close = $"{ReportLayer}.T", Color = "0 0 0 1", Sprite = "assets/content/ui/ui.circlegradient.png"
}
}
, ReportLayer + $".T");
bool leftAlign = bool.Parse(args.Args[6]);
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = $"{(leftAlign ? -1 : 2)} 0", AnchorMax = $"{(leftAlign ? -2 : 3)} 1", OffsetMin = $"-500 -500", OffsetMax = $"500 500"
}
, Button = {
Close = $"{ReportLayer}.T", Color = HexToRustFormat("#343434"), Sprite = "assets/content/ui/ui.circlegradient.png"
}
}
, ReportLayer + $".T");
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = $"-1111111 -1111111", OffsetMax = $"1111111 1111111"
}
, Button = {
Close = $"{ReportLayer}.T", Color = "0 0 0 0.5", Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
}
}
, ReportLayer + $".T");
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = $"{(leftAlign ? "0" : "1")} 0", AnchorMax = $"{(leftAlign ? "0" : "1")} 1", OffsetMin = $"{(leftAlign ? "-350" : "20")} 0", OffsetMax = $"{(leftAlign ? "-20" : "350")} -5"
}
, Text = {
FadeIn = 0.4f, Text = lang.GetMessage("Subject.Head", this, player.UserIDString), Font = "robotocondensed-bold.ttf", Color = HexToRustFormat("#D0C6BD"), FontSize = 24, Align = leftAlign ? TextAnchor.UpperRight : TextAnchor.UpperLeft
}
}
, ReportLayer + ".T");
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = $"{(leftAlign ? "0" : "1")} 0", AnchorMax = $"{(leftAlign ? "0" : "1")} 1", OffsetMin = $"{(leftAlign ? "-250" : "20")} 0", OffsetMax = $"{(leftAlign ? "-20" : "250")} -35"
}
, Text = {
FadeIn = 0.4f, Text = $"{lang.GetMessage("Subject.SubHead", this, player.UserIDString).Replace("%PLAYER%", $"<b> {
target.displayName
}
</b>")}", Font = "robotocondensed-regular.ttf", Color = HexToRustFormat("#D0C6BD80"), FontSize = 14, Align = leftAlign ? TextAnchor.UpperRight : TextAnchor.UpperLeft
}
}
, ReportLayer + ".T");
container.Add(new CuiElement {
Parent = ReportLayer + $".T", Components = {
new CuiRawImageComponent {
SteamId = target.UserIDString, Sprite = "assets/icons/loading.png"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"
}
}
}
);
for (var i = 0; i < _Settings.report_ui_reasons.Count; i++) {
var offXMin = (20 + (i * 5)) + i * 80;
var offXMax = 20 + (i * 5) + (i + 1) * 80;
container.Add(new CuiButton() {
RectTransform = {
AnchorMin = $"{(leftAlign ? 0 : 1)} 0", AnchorMax = $"{(leftAlign ? 0 : 1)} 0", OffsetMin = $"{(leftAlign ? -offXMax : offXMin)} 15", OffsetMax = $"{(leftAlign ? -offXMin : offXMax)} 45"
}
, Button = {
FadeIn = 0.4f + i * 0.2f, Color = HexToRustFormat("#D0C6BD4D"), Command = $"RAL_CommandHandler report {target.UserIDString} {_Settings.report_ui_reasons[i].Replace(" ", "0")}"
}
, Text = {
FadeIn = 0.4f + i * 0.2f, Text = $"{_Settings.report_ui_reasons[i]}", Align = TextAnchor.MiddleCenter, Color = HexToRustFormat("#D0C6BD"), Font = "robotocondensed-bold.ttf", FontSize = 16
}
}
, ReportLayer + $".T");
}
CuiHelper.AddUi(player, container);
break;
}
case "report" : {
if (!_Cooldowns.ContainsKey(player.userID)) {
_Cooldowns.Add(player.userID, 0);
}
if (_Cooldowns[player.userID] > CurrentTime()) {
var msg = lang.GetMessage("Cooldown", this, player.UserIDString).Replace("%TIME%", $"{(_Cooldowns[player.userID] - CurrentTime()).ToString("0")}");
SoundToast(player, msg, 1);
return;
}
string targetId = args.Args[1];
string reason = args.Args[2].Replace("0", "");
BasePlayer target = BasePlayer.Find(targetId) ?? BasePlayer.FindSleeping(targetId);
RA_ReportSend(player.UserIDString, target.UserIDString, reason, "");
CuiHelper.DestroyUi(player, ReportLayer);
SoundToast(player, lang.GetMessage("Sent", this, player.UserIDString), 2);
_Cooldowns[player.userID] = CurrentTime() + _Settings.report_ui_cooldown;
break;
}
}
}
private void ChatCmdReport(BasePlayer player, string command, string[] args) {
var over = Interface.Oxide.CallHook("RustApp_CanOpenReportUI", player);
if (over != null) {
return;
}
if (!_Cooldowns.ContainsKey(player.userID)) {
_Cooldowns.Add(player.userID, 0);
}
if (_Cooldowns[player.userID] > CurrentTime()) {
var msg = lang.GetMessage("Cooldown", this, player.UserIDString).Replace("%TIME%", $"{(_Cooldowns[player.userID] - CurrentTime()).ToString("0")}");
SoundToast(player, msg, 1);
return;
}
if (args != null && args.Length == 1 && args[0].Length == 17) {
var target = BasePlayer.FindAwakeOrSleeping(args[0]);
if (target == null || !target.IsConnected) {
SoundToast(player, lang.GetMessage("Player.Not.Found", this, player.UserIDString), 1);
return;
}
DrawReportInterface(player, 0, "", false, target);
return;
}
DrawReportInterface(player);
}
#endregion
#region User Manipulation
private void SoundInfoToast(BasePlayer player, string text) {
SoundToast(player, text, 2);
}
private void SoundErrorToast(BasePlayer player, string text) {
SoundToast(player, text, 1);
}
private void SoundToast(BasePlayer player, string text, int type) {
Effect effect = new Effect("assets/bundled/prefabs/fx/notice/item.select.fx.prefab", player, 0, new Vector3(), new Vector3());
EffectNetwork.Send(effect, player.Connection);
player.Command("gametip.showtoast", type, text, 1);
}
#endregion
#region Discord
private void RA_ReportSend(string initiator_steam_id, string target_steam_id, string reason, string message = "") {
var author = permission.GetUserData(initiator_steam_id);
var target = permission.GetUserData(target_steam_id);
var list = new DiscordField[4] {
new DiscordField(_Settings.discord_translations_nickname, $"```{target.LastSeenNickname}```", false), new DiscordField($"SteamID", $"```{target_steam_id}```", true), new DiscordField(_Settings.discord_translations_reason, @$"```ansi
[2;31m{reason}[0m
```", true), null
}
;
if (message != null && message.Length > 0) {
list[3] = new DiscordField(_Settings.discord_translations_comment, $"```{message}```", false);
}
DiscordEmbed embed = new DiscordEmbed("", $" ", null, list.Where(v => v != null).ToArray(), new DiscordFooter($"{_Settings.discord_translations_report_sent}: {author.LastSeenNickname} [{initiator_steam_id}]", "", ""));
DiscordMessage req = new DiscordMessage(null, new DiscordEmbed[1] {
embed
}
);
req.Send(_Settings.discord_webhook);
}
#endregion
#region Utils
private double CurrentTime() => DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
private static List<char> Letters = new List<char> {
'☼', 's', 't', 'r', 'e', 'т', 'ы', 'в', 'о', 'ч', 'х', 'а', 'р', 'u', 'c', 'h', 'a', 'n', 'z', 'o', '^', 'm', 'l', 'b', 'i', 'p', 'w', 'f', 'k', 'y', 'v', '$', '+', 'x', '1', '®', 'd', '#', 'г', 'ш', 'к', '.', 'я', 'у', 'с', 'ь', 'ц', 'и', 'б', 'е', 'л', 'й', '_', 'м', 'п', 'н', 'g', 'q', '3', '4', '2', ']', 'j', '[', '8', '{', '}', '_', '!', '@', '#', '$', '%', '&', '?', '-', '+', '=', '~', ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ь', 'ы', 'ъ', 'э', 'ю', 'я'
}
;
private static string NormalizeString(string text) {
string name = "";
foreach (var @char in text) {
if (Letters.Contains(@char.ToString().ToLower().ToCharArray()[0])) name += @char;
}
return name;
}
private long getUnixTime() {
return ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeSeconds();
}
#endregion
#region Messages
public void Log(string ru, string en) {
if (lang.GetServerLanguage() == "ru") {
Puts(ru);
}
else {
Puts(en);
}
}
public void Warning(string ru, string en) {
if (lang.GetServerLanguage() == "ru") {
PrintWarning(ru);
}
else {
PrintWarning(en);
}
}
public void Error(string ru, string en) {
if (lang.GetServerLanguage() == "ru") {
PrintError(ru);
}
else {
PrintError(en);
}
}
#endregion
}
}