C#:
using System;
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using Newtonsoft.Json.Converters;
using Facepunch;
using VLB;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Oxide.Core.Libraries;
using Newtonsoft.Json.Linq;
using Network;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins {
[Info("ReportSystem", "EcoSmile", "1.1.3")]
class ReportSystem : RustPlugin {
[PluginReference]
Plugin ImageLibrary;
static ReportSystem ins;
PluginConfig config;
public class PluginConfig {
[JsonProperty("Время на добавления модератора в Дискорде (в cекундах)")]
public float DsAddTime;
[JsonProperty("Привилегия для доступа к меню модератора")]
public string ModeratorPermis;
[JsonProperty("Привилегия для доступа к меню Администратора")]
public string AdminPermis;
[JsonProperty("Команда используемая для бана (%STEAMID% - место вставки steamid игрока, %REASON% - место вставки причины, %TIME% - вместо вставки времени бана)")]
public string BanCommand;
[JsonProperty("Показывать кнопку репорта после смерти игрока?")]
public bool DeathButton;
[JsonProperty("CD на отправу репортов (в секундах)")]
public float ReportCD;
[JsonProperty("Список причина репорта игрока")]
public List<string> Reasons;
[JsonProperty("Список причина бана игрока")]
public List<string> BanPressets;
[JsonProperty("Список времени бана игрока")]
public List<string> BanTimes;
[JsonProperty("Настройка Vk")]
public VKSettings VKSettings;
[JsonProperty("Настройка Discord")]
public DiscordSetting DiscordSetting;
[JsonProperty("Настройка RCC")]
public RCCSettings RCCSettings;
}
//public class UserRewards
//{
// public bool EnableRewards;
//}
//public class PrizeSetting
//{
// [JsonProperty("Шортнейм предмета")]
// public string ShortName;
// [JsonProperty("Исполняемая команда (%STEAMID% - ключ для вставки SteamID64 игрока)")]
// public string Command;
// [JsonProperty("Кастмоное имя предмета")]
// public string CustomName;
// [JsonProperty("Минимальное количество предмета")]
// public int MinAmount;
// [JsonProperty("Максимальное количество предмета")]
// public int MaxAmount;
// [JsonProperty("SkinID предмета")]
// public ulong SkinID;
// public PrizeSetting Get()
// {
// var prize = new PrizeSetting();
// prize.ShortName = ShortName;
// prize.Command = Command;
// prize.CustomName = CustomName;
// var amount = UnityEngine.Random.Range(MinAmount, MaxAmount);
// prize.MinAmount = amount;
// prize.MaxAmount = amount;
// prize.SkinID = SkinID;
// return prize;
// }
//}
public class RCCSettings {
[JsonProperty("Включить поддержку RCC?")]
public bool Enable;
[JsonProperty("API key к RCC")]
public string APIKey;
[JsonProperty("Кикать игроков с указанными причинами бана?")]
public bool KickPlayers;
[JsonProperty("Список причин бана с которыми НЕ пускать игрока на сервер")]
public List<string> BanReasons;
[JsonProperty("Отправлять логи в ВК о срабатывании RCC?")]
public bool VKLog;
[JsonProperty("Отправлять логи в Discord о срабатывании RCC?")]
public bool DSLog;
}
public class DiscordSetting {
[JsonProperty("Включить поддержку Discord?")]
public bool Enable;
[JsonProperty("ВебХук канала для отправки репортов")]
public string WebHook;
[JsonProperty("ВебХук канала для отправки логов о проверке, бане и RCC")]
public string LogWebHook;
}
public class VKSettings {
[JsonProperty("Включить поддержку ВК?")]
public bool Enable;
[JsonProperty("ID чата для отправки Репортов (чтобы получить ID бесед группы, введите getvkid в консоль сервера)")]
public string ChatID;
[JsonProperty("ID чата для отправки Логов (Проверки, баны, срабатывания RCC, введите getvkid в консоль сервера)")]
public string LogChatID;
[JsonProperty("VK Token группы (для сообщений)")]
public string AccesToken;
}
protected override void LoadDefaultConfig() {
config = new PluginConfig {
DsAddTime = 300.0f, ModeratorPermis = "reportsystem.moderatorpage", AdminPermis = "reportsystem.adminpage", BanCommand = "ban %STEAMID% %REASON%", DeathButton = false, ReportCD = 300, Reasons = new List<string>() {
"Wall Hack", "Aim assist", "No Recoil", "Fly Hack", "Macros", "Team Limit (2+)"
}
, BanPressets = new List<string>() {
"Wall Hack", "Aim assist", "No Recoil", "Fly Hack", "Macros", "Team Limit (2+)"
}
, BanTimes = new List<string>() {
"1d", "3d", "7d", "14d", "30d", "PERMANENT"
}
, VKSettings = new VKSettings() {
AccesToken = "", Enable = false, ChatID = "1", LogChatID = "1"
}
, DiscordSetting = new DiscordSetting() {
Enable = false, LogWebHook = "", WebHook = "",
}
, RCCSettings = new RCCSettings() {
Enable = false, APIKey = "", DSLog = true, VKLog = false, KickPlayers = true, BanReasons = new List<string>() {
"multiacc", "cheat", "macros", "чит", "хак", "макрос", "hack", "wh", "aim"
}
}
}
;
}
protected override void LoadConfig() {
base.LoadConfig();
config = Config.ReadObject<PluginConfig>();
}
protected override void SaveConfig() {
Config.WriteObject(config);
}
public enum ReportStatys {
Open, Process, Closed
}
public class Report {
public ReportStatys status;
public string VictimName;
public string SenderName;
public string ReportReson;
public string ReportID;
public DateTime ReportDate;
public ulong SendreID;
}
public class UserReportData {
public string UserName;
public List<Report> Reports;
}
Dictionary<ulong, UserReportData> PlayerReports = new Dictionary<ulong, UserReportData>();
public class ModeratorInfo {
public string UserName = "";
public int BanCount = 0;
public int CheckCount = 0;
public string DiscordID = "";
}
Dictionary<ulong, ModeratorInfo> moderatorData = new Dictionary<ulong, ModeratorInfo>();
void LoadData() {
if (Interface.Oxide.DataFileSystem.ExistsDatafile(Name + "/Reports")) PlayerReports = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, UserReportData>>(Name + "/Reports");
else Interface.Oxide.DataFileSystem.WriteObject(Name + "/Reports", PlayerReports = new Dictionary<ulong, UserReportData>());
if (Interface.Oxide.DataFileSystem.ExistsDatafile(Name + "/ModeratorBase")) moderatorData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, ModeratorInfo>>(Name + "/ModeratorBase");
else Interface.Oxide.DataFileSystem.WriteObject(Name + "/ModeratorBase", moderatorData = new Dictionary<ulong, ModeratorInfo>());
}
private void OnServerInitialized() {
ins = this;
LoadData();
permission.RegisterPermission(config.ModeratorPermis, this);
PrintWarning($"Registered permission {config.ModeratorPermis}");
permission.RegisterPermission(config.AdminPermis, this);
PrintWarning($"Registered permission {config.AdminPermis}");
//DrawMainUI(BasePlayer.activePlayerList.First());
}
void Unload() {
foreach (var player in BasePlayer.activePlayerList) {
CuiHelper.DestroyUi(player, "MainReport.BG");
CuiHelper.DestroyUi(player, "ReportAlert");
CuiHelper.DestroyUi(player, "UI_Moderator");
CuiHelper.DestroyUi(player, "DeatReport.BTN");
UnityEngine.Object.Destroy(player.GetComponent<ReportPlayer>());
}
foreach (var report in PlayerReports) {
foreach (var rp in report.Value.Reports) if (rp.status == ReportStatys.Process) rp.status = ReportStatys.Open;
}
Interface.Oxide.DataFileSystem.WriteObject(Name + "/ModeratorBase", moderatorData);
Interface.Oxide.DataFileSystem.WriteObject(Name + "/Reports", PlayerReports);
}
void OnServerSave() {
Interface.Oxide.DataFileSystem.WriteObject(Name + "/ModeratorBase", moderatorData);
Interface.Oxide.DataFileSystem.WriteObject(Name + "/Reports", PlayerReports);
}
void OnNewSave() {
}
void OnPlayerConnected(BasePlayer player) {
if (player == null) return;
if (player.IsReceivingSnapshot) {
timer.In(2f, () => OnPlayerConnected(player));
return;
}
if (permission.UserHasPermission(player.UserIDString, config.ModeratorPermis)) {
if (moderatorData.ContainsKey(player.userID) && string.IsNullOrEmpty(moderatorData[player.userID].DiscordID)) SendReply(player, $"Чтобы вести работу с системой репортов, необходимо подключить свой Discrod.\nВведите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds EcoSmile#0001");
else if (!moderatorData.ContainsKey(player.userID)) SendReply(player, $"Чтобы вести работу с системой репортов, необходимо подключить свой Discrod.\nВведите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds EcoSmile#0001");
}
}
void OnPlayerDisconnected(BasePlayer player, string reason) {
if (player.GetComponent<ReportPlayer>() != null) {
player.GetComponent<ReportPlayer>().Disconect();
UnityEngine.Object.Destroy(player.GetComponent<ReportPlayer>());
}
}
[ConsoleCommand("getvkid")]
void GetVkChatID(ConsoleSystem.Arg arg) {
if (!arg.IsAdmin) return;
webrequest.Enqueue("https://api.vk.com/method/messages.getConversations?v=5.90" + $"&access_token={config.VKSettings.AccesToken}", "", (code, res) => {
var responce = JsonConvert.DeserializeObject<Rootobject>(res);
var list = responce.response.items;
string msg = "Список достпуных чатов Группы:\n";
foreach (var a in list) {
if (a.conversation.peer.type == "chat") {
msg += $"Chat Name: {a.conversation.chat_settings.title} [Chat ID: {a.conversation.peer.id - 2000000000}]\n";
}
}
PrintWarning(msg);
}
, this, RequestMethod.GET);
}
[ChatCommand("ds")]
void AddDiscord(BasePlayer player, string command, string[] args) {
if (!permission.UserHasPermission(player.UserIDString, config.ModeratorPermis)) return;
if (args.Length == 0) {
SendReply(player, $"Введите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds WOLF#4002");
return;
}
var id = args[0];
if (moderatorData.ContainsKey(player.userID)) moderatorData[player.userID].DiscordID = id;
else {
moderatorData[player.userID] = new ModeratorInfo();
moderatorData[player.userID].DiscordID = id;
moderatorData[player.userID].UserName = player.displayName;
}
SendReply(player, $"Ваш дискорд: {id} Успешно добавлен.\nЧтобы изменить Discord ID введите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds WOLF#4002");
}
[ConsoleCommand("report")]
void DrawMainUI_Comd(ConsoleSystem.Arg arg) => DrawMainUI(arg.Player());
[ChatCommand("report")]
void DrawMainUI(BasePlayer player) {
var container = new CuiElementContainer();
UI.AddImage(ref container, "WMenu", "MainReport.BG", "0 0 0 0.0", "", "", "0 0", "1 1", "", "");
UI.AddImage(ref container, "MainReport.BG", "MainReportField", "0.36 0.34 0.32 0", "assets/content/ui/ui.background.tiletex.psd", "assets/icons/greyout.mat", "0.5 0.5", $"0.5 0.5", "-380 -250", "380 250");
UI.AddImage(ref container, "MainReportField", "MainReportField.Header", "0.36 0.34 0.32 0", "assets/content/ui/ui.background.tiletex.psd", "assets/icons/greyout.mat", "0.5 1", $"0.5 1", "-380 -0", "380 55");
UI.AddText(ref container, "MainReportField.Header", "Header.text", "0.68 0.63 0.60 1", "СИСТЕМА РЕПОРТОВ", TextAnchor.MiddleCenter, 32, "0.5 0.5", "0.5 0.5", "-250 -25", "250 25", "0 0 0 1", "0.1 0.1", "robotocondensed-bold.ttf", 1f);
/*UI.AddButton(ref container, "MainReportField.Header", "closeBtn", $"", "MainReport.BG", "1 1 1 0", "", "", "1 1", "1 1", "-1300 -40", "500 180");
UI.AddButton(ref container, "MainReportField.Header", "closeBtn", $"", "MainReport.BG", "1 1 1 0", "", "", "1 1", "1 1", "-1300 -800", "-760 180");
UI.AddButton(ref container, "MainReportField.Header", "closeBtn", $"", "MainReport.BG", "1 1 1 0", "", "", "1 1", "1 1", "-1300 -800", "500 -555");
UI.AddButton(ref container, "MainReportField.Header", "closeBtn", $"", "MainReport.BG", "1 1 1 0", "", "", "1 1", "1 1", "0 -550", "500 180");*/
UI.AddCursor(ref container, "MainReport.BG");
if (permission.UserHasPermission(player.UserIDString, config.ModeratorPermis)) {
UI.AddButton(ref container, "MainReportField.Header", "ModerMenu.BTN", "rs.moderatorpanel", "", "0.28 0.32 0.17 1", "", "assets/content/ui/uibackgroundblur-ingamemenu.mat", "0 0.5", "0 0.5", "5 -20", "150 20");
UI.AddText(ref container, "ModerMenu.BTN", "Btn.Text", "0.68 0.63 0.60 1", "РЕПОРТЫ", TextAnchor.MiddleCenter, 28, "0 0", "1 1", "", "", "0 0 0 0.5", "robotocondensed-regular.ttf");
}
if (permission.UserHasPermission(player.UserIDString, config.AdminPermis)) {
UI.AddButton(ref container, "MainReportField.Header", "ModerMenu.BTN", "rs.openadminpanel", "", "0.141 0.137 0.109 0.8", "", "assets/content/ui/uibackgroundblur-ingamemenu.mat", "1 0.5", "1 0.5", "-205 -20", "-50 20");
UI.AddText(ref container, "ModerMenu.BTN", "Btn.Text", "0.68 0.63 0.60 1", "АДМИН РАЗДЕЛ", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "", "0 0 0 0.5", "robotocondensed-regular.ttf");
}
CuiHelper.DestroyUi(player, "MainReport.BG");
CuiHelper.AddUi(player, container);
DrawInputField(player);
DrawPlayerList(player, 0, "");
}
void DrawInputField(BasePlayer player) {
var container = new CuiElementContainer();
UI.AddText(ref container, "MainReportField", "HeaderText", "0.68 0.63 0.60 1", "Введите Ник игрока или SteamID для поиска", TextAnchor.MiddleCenter, 18, "0.5 0.96", "0.5 0.96", "-250 -15", "250 15");
UI.AddImage(ref container, "MainReportField", "InputName.bg", "0.68 0.63 0.60 0.50", "", "", "0.5 0.90", "0.5 0.90", "-250 -15", "250 15");
UI.AddInputField(ref container, "InputName.bg", "InputName", $"rs.search", TextAnchor.MiddleCenter, 18, 30);
CuiHelper.AddUi(player, container);
}
[ConsoleCommand("rs.openadminpanel")]
void AdminPanel_cmd(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (!permission.UserHasPermission(player.UserIDString, config.AdminPermis)) return;
var container = new CuiElementContainer();
UI.AddImage(ref container, "MainReport.BG", "MainReportField", "0.141 0.137 0.109 0.8", "assets/content/ui/ui.background.tiletex.psd", "assets/content/ui/uibackgroundblur-ingamemenu.mat", "0.5 0.5", $"0.5 0.5", "-380 -250", "380 250");
UI.AddImage(ref container, "MainReportField", "MainReportField.Header", "0.36 0.34 0.32 1", "assets/content/ui/ui.background.tiletex.psd", "assets/icons/greyout.mat", "0.5 1", $"0.5 1", "-380 -0", "380 55");
UI.AddText(ref container, "MainReportField.Header", "Header.text", "0.68 0.63 0.60 1", "РАЗДЕЛ АДМИНИСТРАТОРА", TextAnchor.MiddleCenter, 32, "0.5 0.5", "0.5 0.5", "-250 -25", "250 25", "0 0 0 1", "0.1 0.1", "robotocondensed-bold.ttf", 1f);
UI.AddButton(ref container, "MainReportField.Header", "closeBtn", $"report", "", "1 1 1 0.5", "assets/icons/close.png", "", "1 1", "1 1", "-40 -40", "-10 -10");
CuiHelper.DestroyUi(player, "MainReportField");
CuiHelper.AddUi(player, container);
DrawAdminMenu(player);
}
void DrawAdminMenu(BasePlayer player) {
var starthorisontal = 0.10;
var startvertical = 0.82f;
var vertical = startvertical;
var horisontal = starthorisontal;
var container = new CuiElementContainer();
UI.AddImage(ref container, "MainReportField", "PlayerPanel", "1 1 1 0.0", "", "", "0.5 0.5", "0.5 0.5", "-380 -250", "380 250");
int count = 0;
foreach (var moderator in moderatorData) {
var victum = BasePlayer.activePlayerList.FirstOrDefault(x => x.userID == moderator.Key);
string colorStatys = victum != null ? "0.28 0.32 0.17 1" : "0.68 0.63 0.60 0.50";
string color = count % 2 == 0 ? "0 0 0 0.5" : "0.929 0.882 0.847 0.15";
UI.AddImage(ref container, "PlayerPanel", "Victum.Name.BG", color, "", "", $"{horisontal} {vertical}", $"{horisontal} {vertical}", $"-60 -105", "60 75");
UI.AddRawImage(ref container, "Victum.Name.BG", "Avatar", ImageLibrary?.Call<string>("GetImage", moderator.Key.ToString()), "1 1 1 1", "", "", "0.5 1", "0.5 1", "-40 -85", "40 -5");
UI.AddText(ref container, "Victum.Name.BG", "Victim.NameID", "0.68 0.63 0.60 1", $" {moderator.Value.UserName}\n[{moderator.Key}]\nПроверок выполнил: {moderator.Value.CheckCount}\nИгроков забанил: {moderator.Value.BanCount}", TextAnchor.UpperLeft, 10, "0.5 0", "0.5 0", "-59 1", "59 75");
UI.AddText(ref container, "Victum.Name.BG", "Victim.Online", victum == null ? "1 0 0 0.3" : "0 1 0 0.3", $"• ", TextAnchor.UpperRight, 32, "0 0", "1 1", "", "");
horisontal += 0.2f;
if (horisontal > 1) {
vertical -= 0.5f;
horisontal = starthorisontal;
}
count++;
}
CuiHelper.DestroyUi(player, "PlayerPanel");
CuiHelper.AddUi(player, container);
}
[ConsoleCommand("rs.moderatorpanel")]
void ModeratorPanel_cmd(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (!permission.UserHasPermission(player.UserIDString, config.ModeratorPermis)) return;
if (moderatorData.ContainsKey(player.userID) && string.IsNullOrEmpty(moderatorData[player.userID].DiscordID)) {
SendReply(player, $"Чтобы вести работу с системой репортов, необходимо подключить свой Discrod.\nВведите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds EcoSmile#0001");
return;
}
if (!moderatorData.ContainsKey(player.userID)) {
SendReply(player, $"Чтобы вести работу с системой репортов, необходимо подключить свой Discrod.\nВведите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds EcoSmile#0001");
return;
}
var container = new CuiElementContainer();
UI.AddImage(ref container, "MainReport.BG", "MainReportField", "0.141 0.137 0.109 0.8", "assets/content/ui/ui.background.tiletex.psd", "assets/content/ui/uibackgroundblur-ingamemenu.mat", "0.5 0.5", $"0.5 0.5", "-380 -250", "380 250");
UI.AddImage(ref container, "MainReportField", "MainReportField.Header", "0.36 0.34 0.32 1", "assets/content/ui/ui.background.tiletex.psd", "assets/icons/greyout.mat", "0.5 1", $"0.5 1", "-380 -0", "380 55");
UI.AddText(ref container, "MainReportField.Header", "Header.text", "0.68 0.63 0.60 1", "СПИСОК РЕПОРТОВ", TextAnchor.MiddleCenter, 32, "0.5 0.5", "0.5 0.5", "-250 -25", "250 25", "0 0 0 1", "0.1 0.1", "robotocondensed-bold.ttf", 1f);
UI.AddButton(ref container, "MainReportField.Header", "closeBtn", $"report", "", "1 1 1 0.5", "assets/icons/close.png", "", "1 1", "1 1", "-40 -40", "-10 -10");
CuiHelper.DestroyUi(player, "MainReportField");
CuiHelper.AddUi(player, container);
ReportsList(player);
}
void ReportsList(BasePlayer player, int page = 0) {
var starthorisontal = 0.10;
var startvertical = 0.42f;
var vertical = startvertical;
var horisontal = starthorisontal;
var container = new CuiElementContainer();
UI.AddImage(ref container, "MainReportField", "PlayerPanel", "1 1 1 0.0", "", "", "0.5 0.5", "0.5 0.5", "-380 -250", "380 250");
int count = 0;
var reportList = PlayerReports.Where(x => x.Value.Reports.Count() > 0).OrderBy(x => x.Value.Reports.Count);
if (reportList.Count() == 0) UI.AddText(ref container, $"PlayerPanel", "NoPlayer", "0.68 0.63 0.60 1", "РЕПОРТОВ НЕТ", TextAnchor.MiddleCenter, 32, "0.1 0", "0.9 1", "", "");
//var report = reportList.Skip(page * 8).Take(8).FirstOrDefault();
foreach (var report in reportList.Skip(page * 10).Take(10)) {
string color = count % 2 == 0 ? "0 0 0 0.5" : "0.929 0.882 0.847 0.15";
UI.AddImage(ref container, "PlayerPanel", "Victum.Name.BG", color, "", "", $"{horisontal} {vertical}", $"{horisontal} {vertical}", $"-60 -105", "60 75");
UI.AddRawImage(ref container, "Victum.Name.BG", "Avatar", ImageLibrary?.Call<string>("GetImage", report.Key.ToString()), "1 1 1 1", "", "", "0.5 1", "0.5 1", "-40 -85", "40 -5");
UI.AddText(ref container, "Avatar", "Victim.NameID", "0.68 0.63 0.60 1", $" {report.Value.UserName}\n[{report.Key}]\nРепортов: {report.Value.Reports.Count(x => x.status == ReportStatys.Open)} ({report.Value.Reports.Count})", TextAnchor.UpperLeft, 12, "0.5 0", "0.5 0", "-59 -65", "59 -5");
var victum = BasePlayer.activePlayerList.FirstOrDefault(x => x.userID == report.Key);
UI.AddText(ref container, "Avatar", "Victim.Online", victum == null ? "1 0 0 0.3" : "0 1 0 0.3", $"•", TextAnchor.MiddleCenter, 32, "1 1", "1 1", "0 -25", "20 15");
UI.AddButton(ref container, "Avatar", "OpenButton", $"openreportlist {report.Key}", "", "0.341 0.137 0.109 0.8", "", "", "0.5 0", "0.5 0", "-55 -90", "55 -60");
UI.AddText(ref container, "OpenButton", "Title", "1 1 1 0.65", "ПОСМОТРЕТЬ", TextAnchor.MiddleCenter, 14, "0 0", "1 1", "", "");
horisontal += 0.2f;
if (horisontal > 1) {
vertical -= 0.5f;
horisontal = starthorisontal;
}
count++;
}
if (page > 0) {
UI.AddButton(ref container, "PlayerPanel", "BackBtn", $"rs.moderatorpage {page - 1}", "", "0.28 0.32 0.17 1", "", "", "0 0", "0 0", "5 5", "60 30");
UI.AddText(ref container, $"BackBtn", "Text", "0.68 0.63 0.60 0.50", "◄", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
}
if (reportList.Skip(page * 10).Count() > 10) {
UI.AddButton(ref container, "PlayerPanel", "NextBtn", $"rs.moderatorpage {page + 1}", "", "0.28 0.32 0.17 1", "", "", "1 0", "1 0", "-60 5", "-5 30");
UI.AddText(ref container, $"NextBtn", "Text", "0.68 0.63 0.60 0.50", "►", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
}
CuiHelper.DestroyUi(player, "PlayerPanel");
CuiHelper.AddUi(player, container);
}
[ConsoleCommand("openreportlist")]
void OpenReportList(ConsoleSystem.Arg arg) {
var player = arg.Player();
var reportedID = arg.GetUInt64(0);
DrawPersonalReportList(player, reportedID, 0);
}
void DrawPersonalReportList(BasePlayer player, ulong reportedID, int page) {
var reportData = PlayerReports[reportedID].Reports.OrderBy(x => x.status);
var starthorisontal = 0.0;
var startvertical = 1f;
var vertical = startvertical;
var horisontal = starthorisontal;
var container = new CuiElementContainer();
UI.AddImage(ref container, "MainReportField", "PlayerPanel", "1 1 1 0.0", "", "", "0.5 0.5", "0.5 0.5", "-380 -250", "380 100");
UI.AddImage(ref container, "MainReportField", "RCCInfoPanel", "1 1 1 0.1", "", "", "0.5 0.5", "0.5 0.5", "-380 100", "380 250");
UI.AddText(ref container, "RCCInfoPanel", "Reason", "0.68 0.63 0.60 1", $"ЗАПРОС ОТПРАВЛЕН, ОЖИДАЕМ ОТВЕТА ОТ RCC", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "");
int count = 0;
var victum = BasePlayer.activePlayerList.FirstOrDefault(x => x.userID == reportedID);
foreach (var report in reportData.Skip(page * 6).Take(6)) {
string color = count % 2 == 0 ? "0 0 0 0.5" : "0.929 0.882 0.847 0.15";
string colorStatys = report.status == ReportStatys.Open ? "0.28 0.32 0.17 1" : "0.68 0.63 0.60 0.50";
UI.AddImage(ref container, "PlayerPanel", "Victum.Name.BG", color, "", "", $"{horisontal} {vertical}", $"{horisontal} {vertical}", $"5 -55", "205 -5");
UI.AddText(ref container, "Victum.Name.BG", "Victim.NameID", "0.68 0.63 0.60 1", $" {report.VictimName}\n[{reportedID}]", TextAnchor.MiddleLeft, 12, "0 0", "1 1", "", "");
UI.AddText(ref container, "Victum.Name.BG", "Victim.Online", victum == null ? "1 0 0 0.3" : "0 1 0 0.3", $"• ", TextAnchor.UpperRight, 32, "0 0", "1 1", "", "");
UI.AddImage(ref container, "Victum.Name.BG", "ReportReason.BG", color, "", "", $"1 0.5", $"1 0.5", $"5 -25", "125 25");
UI.AddText(ref container, "ReportReason.BG", "Reason", "0.68 0.63 0.60 1", $"{report.ReportReson}", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "");
UI.AddImage(ref container, "ReportReason.BG", $"ReportData.BG", color, "", "", $"1 0.5", $"1 0.5", $"5 -25", "170 25");
UI.AddText(ref container, "ReportData.BG", "ReportData", "0.68 0.63 0.60 1", $"{report.ReportDate.ToString("dd.MM.yyyy")}", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "");
UI.AddImage(ref container, "ReportData.BG", $"ReportStatys.BG", color, "", "", $"1 0.5", $"1 0.5", $"5 -25", "125 25");
UI.AddText(ref container, "ReportStatys.BG", "Statys", colorStatys, $"{report.status.ToString().ToUpper()}", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
UI.AddImage(ref container, "ReportStatys.BG", $"GetReport.BG", color, "", "", $"1 0.5", $"1 0.5", $"5 -25", "125 25");
if (victum != null) {
if (report.status == ReportStatys.Closed) {
UI.AddButton(ref container, "GetReport.BG", "OpenReport.BTN", "", "", "1 1 1 0.05", "", "assets/content/ui/uibackgroundblur-ingamemenu.mat", "0.5 0.5", "0.5 0.5", "-50 -20", "50 20");
UI.AddText(ref container, "OpenReport.BTN", "OpenReport.Text", "0.68 0.63 0.60 1", "ПРОВЕРЕНО", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "", "0 0 0 0.5", "robotocondensed-regular.ttf");
}
else {
UI.AddButton(ref container, "GetReport.BG", "OpenReport.BTN", report.status == ReportStatys.Open ? $"rs.openreport {report.ReportID} {reportedID}" : "", "", report.status == ReportStatys.Open ? "0.28 0.32 0.17 1" : "0.28 0.32 0.17 0.5", "", "assets/content/ui/uibackgroundblur-ingamemenu.mat", "0.5 0.5", "0.5 0.5", "-50 -20", "50 20");
UI.AddText(ref container, "OpenReport.BTN", "OpenReport.Text", "0.68 0.63 0.60 1", "НАЧАТЬ ПРОВЕРКУ", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "", "0 0 0 0.5", "robotocondensed-regular.ttf");
}
}
else {
UI.AddButton(ref container, "GetReport.BG", "OpenReport.BTN", report.status == ReportStatys.Open ? $"rs.banplayer {victum.userID}" : "", "", "0.341 0.137 0.109 0.8", "", "assets/content/ui/uibackgroundblur-ingamemenu.mat", "0.5 0.5", "0.5 0.5", "-50 -20", "50 20");
UI.AddText(ref container, "OpenReport.BTN", "OpenReport.Text", "0.68 0.63 0.60 1", "БАН", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "", "0 0 0 0.5", "robotocondensed-regular.ttf");
}
vertical -= 0.15f;
count++;
}
if (page > 0) {
UI.AddButton(ref container, "PlayerPanel", "BackBtn", $"rs.userreportlist {reportedID} {page - 1}", "", "0.28 0.32 0.17 1", "", "", "0 0", "0 0", "5 5", "60 30");
UI.AddText(ref container, $"BackBtn", "Text", "0.68 0.63 0.60 0.50", "◄", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
}
if (reportData.Skip(page * 6).Count() > 6) {
UI.AddButton(ref container, "PlayerPanel", "NextBtn", $"rs.userreportlist {reportedID} {page + 1}", "", "0.28 0.32 0.17 1", "", "", "1 0", "1 0", "-60 5", "-5 30");
UI.AddText(ref container, $"NextBtn", "Text", "0.68 0.63 0.60 0.50", "►", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
}
CuiHelper.DestroyUi(player, "PlayerPanel");
CuiHelper.AddUi(player, container);
DrawRCCInfo(player, victum.userID);
}
void DrawRCCInfo(BasePlayer player, ulong userID) {
var container = new CuiElementContainer();
UI.AddImage(ref container, "MainReportField", "RCCInfoPanel", "1 1 1 0.1", "", "", "0.5 0.5", "0.5 0.5", "-380 100", "380 250");
webrequest.Enqueue($"https://rustcheatcheck.ru/panel/api?action=getInfo&key={config.RCCSettings.APIKey}&player={userID}", null, (code, data) => {
if (code != 200) {
UI.AddText(ref container, "RCCInfoPanel", "Reason", "0.68 0.63 0.60 1", $"ОШИБКА: {code}\nОбратитесь к администратору", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "");
CuiHelper.DestroyUi(player, "RCCInfoPanel");
CuiHelper.AddUi(player, container);
return;
}
RCCData rcc = JsonConvert.DeserializeObject<RCCData>(data);
if (rcc == null) {
UI.AddText(ref container, "RCCInfoPanel", "Reason", "0.68 0.63 0.60 1", $"ИНФОРМАЦИЯ ОБ ИГРОКЕ ОТСУТСВУЕТ", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "");
CuiHelper.DestroyUi(player, "RCCInfoPanel");
CuiHelper.AddUi(player, container);
return;
}
if (rcc.status == "error") {
UI.AddText(ref container, "RCCInfoPanel", "Reason", "0.68 0.63 0.60 1", $"Игрок не вызывался на проверку и баны отсутствуют", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "");
CuiHelper.DestroyUi(player, "RCCInfoPanel");
CuiHelper.AddUi(player, container);
return;
}
if (rcc.status == "success") {
if (rcc.bans.Count > 0) {
string reason = " Информация о банах игрока на сторонних проектах:\n";
foreach (var info in rcc.bans.OrderByDescending(x => x.banDate)) {
var dTime = new DateTime(1970, 1, 1, 0, 0, 0);
var unbanData = new TimeSpan(0, 0, int.Parse(info.unbanDate));
var endData = dTime.Add(unbanData);
reason += $" [{info.serverName}] Дата бана: {new DateTime(1970, 1, 1, 0, 0, 0, 0).Add(new TimeSpan(0, 0, int.Parse(info.banDate))).ToString("dd.MM.yyyy")}, Дата разбана: {(info.unbanDate == "0" ? "ПЕРМАНЕНТ" : new DateTime(1970, 1, 1, 0, 0, 0, 0).Add(unbanData).ToString("dd.MM.yyyy"))}, Причина: <color=#f44e42>{info.reason}</color>, Статус: {(info.active ? "<color=green>АКТИВЕН</color>" : "Не активен")}\n";
}
UI.AddText(ref container, "RCCInfoPanel", "Reason", "0.68 0.63 0.60 1", $"{reason}", TextAnchor.MiddleLeft, 13, "0 0", "1 1", "", "");
}
else {
UI.AddText(ref container, "RCCInfoPanel", "Reason", "0.68 0.63 0.60 1", $"Баны на сторонних проектах не обнаружены", TextAnchor.MiddleCenter, 16, "0 0", "1 1", "", "");
}
}
CuiHelper.DestroyUi(player, "RCCInfoPanel");
CuiHelper.AddUi(player, container);
}
, this);
}
[PluginReference]
Plugin NoEscape;
[ConsoleCommand("rs.openreport")]
void OpenReport(ConsoleSystem.Arg arg) {
var player = arg.Player();
var reportID = arg.Args[0];
var userID = arg.GetUInt64(1);
var report = PlayerReports[userID].Reports.FirstOrDefault(x => x.ReportID == reportID);
var victim = BasePlayer.activePlayerList.FirstOrDefault(x => x.userID == userID);
if (victim.GetComponent<ReportPlayer>()) {
SendReply(player, "Игрок уже проверяется");
return;
}
if (NoEscape?.Call<bool>("IsRaidBlock", victim.userID) == true) {
SendReply(player, "Игрок находится в Рейде, дождитесь окончания рейда и попробуйте снова.");
return;
}
CuiHelper.DestroyUi(player, "MainReport.BG");
UpdateReportList(victim.userID, ReportStatys.Process);
var component = victim.gameObject.AddComponent<ReportPlayer>();
component.Init(player);
BanProcess[player.IPlayer] = new BanInfo(victim.userID, victim.displayName, report.ReportID);
BanProcess[player.IPlayer].component = component;
DrawAlert(victim, player);
SendReply(player, $"Вы успешно вызвали игрока {victim.displayName} на проверку.\nПожалуйста, ожидайте, пока игрок добавит Вас в Discord.");
SendDiscordMsg($"Модератор {player.displayName} ({player.userID}) вызвал на проверку игрока {victim.displayName} ({victim.userID}).\nReport ID {report.ReportID}", false);
SendVKMsg($"Модератор {player.displayName} ({player.userID}) вызвал на проверку игрока {victim.displayName} ({victim.userID}).\nReport ID {report.ReportID}", config.VKSettings.LogChatID);
PrintToChat($"Игрок {victim.displayName} ({victim.userID}) вызван на проверку Модератором {player.displayName} ({player.userID})");
}
private void DrawAlert(BasePlayer player, BasePlayer moderator) {
var container = new CuiElementContainer();
UI.AddImage(ref container, "Overlay", "ReportAlert", "0.36 0.34 0.32 0.9", "assets/content/ui/ui.background.tiletex.psd", "assets/icons/greyout.mat", "0.5 0.8", "0.5 0.8", "-350 -60", "350 60");
UI.AddText(ref container, "ReportAlert", "ReportText", "1 1 1 0.65", $"Здравствуйте, <b><color=#f44e42>{player.displayName}</color></b>, Администрацией проекта было принято решение проверить Вас на наличие запрещенного ПО в связи с большим количеством жалоб.\n" + $"Выход из сети во время проверки приведет к Бану.\nПожалуйста добавьте проверяющего в Discord: <b><color=#f44e42>{(moderatorData.ContainsKey(moderator.userID) ? moderatorData[moderator.userID].DiscordID : "#err")}</color></b>\nУ Вас есть {config.DsAddTime} сек чтобы добавить Проверяющего.", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
Effect effect = new Effect("ASSETS/BUNDLED/PREFABS/FX/INVITE_NOTICE.PREFAB".ToLower(), player, 0, new Vector3(), new Vector3());
EffectNetwork.Send(effect, player.Connection);
CuiHelper.DestroyUi(player, "ReportAlert");
CuiHelper.AddUi(player, container);
}
void UpdateReportList(ulong userID, ReportStatys status) {
if (!PlayerReports.ContainsKey(userID)) return;
foreach (var report in PlayerReports[userID].Reports.Where(x => x.status != ReportStatys.Closed)) {
report.status = status;
}
}
[ConsoleCommand("rs.userreportlist")]
void UserReportPage(ConsoleSystem.Arg arg) {
var player = arg.Player();
var reportedID = arg.GetUInt64(0);
var page = arg.GetInt(1);
if (page < 0) page = 0;
DrawPersonalReportList(player, reportedID, page);
}
[ConsoleCommand("rs.moderatorpage")]
void ModeratorPages(ConsoleSystem.Arg arg) {
var player = arg.Player();
var page = arg.GetInt(0);
if (page < 0) page = 0;
ReportsList(player, page);
}
[ConsoleCommand("rs.search")]
void SerchPlayer(ConsoleSystem.Arg arg) {
var player = arg.Player();
var NameOrID = string.Join("", arg.Args);
DrawPlayerList(player, 0, NameOrID);
}
void DrawPlayerList(BasePlayer player, int page, string NameOrID) {
var starthorisontal = 0.00;
var startvertical = 0.91f;
var vertical = startvertical;
var horisontal = starthorisontal;
var playerList = BasePlayer.activePlayerList.Where(x => x.userID != player.userID).Skip(page * 15).Take(15).ToList();
var FindUsers = new List<Core.Libraries.Covalence.IPlayer>();
if (!string.IsNullOrEmpty(NameOrID)) FindUsers = covalence.Players.FindPlayers(NameOrID).ToList();
if (FindUsers != null && FindUsers.Count > 0) {
playerList = new List<BasePlayer>();
foreach (var user in FindUsers) {
playerList.Add(user.Object as BasePlayer);
}
}
var navContainer = new CuiElementContainer();
UI.AddImage(ref navContainer, "MainReportField", "PlayerPanel", "1 1 1 0.0", "", "", "0.5 0.5", "0.5 0.5", "-380 -250", "380 180");
if (playerList.Count() == 0 || (playerList.Where(x => x != null).Count() <= 0 && !string.IsNullOrEmpty(NameOrID))) {
if (playerList.Where(x => x != null).Count() <= 0 && !string.IsNullOrEmpty(NameOrID)) {
UI.AddText(ref navContainer, $"PlayerPanel", "NoPlayer", "0.68 0.63 0.60 1", $"Игрок {NameOrID} не найден.", TextAnchor.MiddleCenter, 22, "0 0", "1 1", "", "");
}
else if (playerList.Count() == 0) UI.AddText(ref navContainer, $"PlayerPanel", "NoPlayer", "0.68 0.63 0.60 1", "КРОМЕ ВАС ИГРОКОВ НА СЕРВЕРЕ НЕТ", TextAnchor.MiddleCenter, 22, "0.5 0.5", "0.5 0.5", "-300 -100", "300 200");
}
if (page > 0) {
UI.AddButton(ref navContainer, "PlayerPanel", "BackBtn", $"rs.reportpage {page - 1}", "", "0.28 0.32 0.17 1", "", "", "0 0", "0 0", "5 5", "60 30");
UI.AddText(ref navContainer, $"BackBtn", "Text", "0.68 0.63 0.60 0.50", "◄", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
}
if (BasePlayer.activePlayerList.Where(x => x.userID != player.userID).Skip(page * 18).Count() > 18) {
UI.AddButton(ref navContainer, "PlayerPanel", "NextBtn", $"rs.reportpage {page + 1}", "", "0.28 0.32 0.17 1", "", "", "1 0", "1 0", "-60 5", "-5 30");
UI.AddText(ref navContainer, $"NextBtn", "Text", "0.68 0.63 0.60 0.50", "►", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
}
CuiHelper.DestroyUi(player, "PlayerPanel");
CuiHelper.AddUi(player, navContainer);
foreach (var pl in playerList.Where(x => x != null)) {
var userID = pl.userID;
var container = new CuiElementContainer();
UI.AddImage(ref container, "PlayerPanel", $"Player.container.{userID}", "0.68 0.63 0.60 0.50", "", "", $"{horisontal} {vertical}", $"{horisontal} {vertical}", "0 -35", "210 35");
UI.AddRawImage(ref container, $"Player.container.{userID}", "Avatar", ImageLibrary?.Call<string>("GetImage", userID.ToString()), "1 1 1 1", "", "", "0.0 0.5", "0.0 0.5", "2 -32", "64 32");
UI.AddText(ref container, $"Player.container.{userID}", "Player.Name", "0.68 0.63 0.60 1", $"{pl.displayName}", TextAnchor.MiddleLeft, 18, "0.65 1", "0.65 1", "-70 -25", "70 0");
UI.AddButton(ref container, $"Player.container.{userID}", $"ReportBtn.{userID}", $"rs.openreport.ui {userID} false", "", "0.28 0.32 0.17 0", "", "", "1 0.5", "1 0.5", "-210 -32", "-2 32");
UI.AddText(ref container, $"ReportBtn.{userID}", "Text", "0.68 0.63 0.60 0.50", "", TextAnchor.MiddleCenter, 18, "0 0", "1 1", "", "");
CuiHelper.AddUi(player, container);
horisontal += 0.35f;
if (horisontal >= 0.9f) {
horisontal = starthorisontal;
vertical -= 0.18f;
}
}
}
[ConsoleCommand("rs.reportpage")]
void ReportPage(ConsoleSystem.Arg arg) {
var player = arg.Player();
var page = arg.GetInt(0);
if (page < 0) page = 0;
DrawPlayerList(player, page, "");
}
Dictionary<BasePlayer, DateTime> reportCD = new Dictionary<BasePlayer, DateTime>();
[ChatCommand("stop")]
void StopCommand(BasePlayer player) {
if (!permission.UserHasPermission(player.UserIDString, config.ModeratorPermis)) return;
var process = BanProcess[player.IPlayer];
UncheckPlayer(player, process.userID);
}
[ChatCommand("check")]
void StartManualPlayerCheck(BasePlayer player, string command, string[] arg) {
if (!permission.UserHasPermission(player.UserIDString, config.ModeratorPermis)) return;
if(!moderatorData.ContainsKey(player.userID)) {
if (moderatorData.ContainsKey(player.userID) && string.IsNullOrEmpty(moderatorData[player.userID].DiscordID)) SendReply(player, $"Чтобы вести работу с системой репортов, необходимо подключить свой Discrod.\nВведите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds EcoSmile#0001");
else if (!moderatorData.ContainsKey(player.userID)) SendReply(player, $"Чтобы вести работу с системой репортов, необходимо подключить свой Discrod.\nВведите /ds #ID, где #ID - ID в вашем дискорде.\nНапример: /ds EcoSmile#0001");
return;
}
var targetUserID = string.Join(" ", arg);
var victims = covalence.Players.FindPlayers(targetUserID).ToList();
if(victims == null || victims.Count() <= 0) {
SendReply(player, $"Игрок с именем {targetUserID} не найден");
return;
}
if(victims.Count() > 1) {
SendReply(player, $"Найдено несколько игроков с таким именем:\n{string.Join(" ", victims.Select(x=>x.Name))}");
return;
}
if ((victims[0].Object as BasePlayer).GetComponent<ReportPlayer>()) {
SendReply(player, "Игрок уже проверяется");
return;
}
if (NoEscape?.Call<bool>("IsRaidBlock", (victims[0].Object as BasePlayer).userID) == true) {
SendReply(player, "Игрок находится в Рейде, дождитесь окончания рейда и попробуйте снова.");
return;
}
CuiHelper.DestroyUi(player, "MainReport.BG");
UpdateReportList(player.userID, ReportStatys.Process);
Report report = null;
if(PlayerReports.ContainsKey((victims[0].Object as BasePlayer).userID)) report = PlayerReports[(victims[0].Object as BasePlayer).userID].Reports.FirstOrDefault(x => x.status == ReportStatys.Process);
if (report == null) {
report = new Report() {
ReportDate = DateTime.Now, VictimName = (victims[0].Object as BasePlayer).displayName, ReportID = UnityEngine.Random.Range(1, 9999999).ToString(), SenderName = player.displayName, ReportReson = "ПРОВЕРКА МОДЕРАТОРОМ", status = ReportStatys.Open, SendreID = player.userID,
}
;
}
BanProcess[player.IPlayer] = new BanInfo((victims[0].Object as BasePlayer).userID, (victims[0].Object as BasePlayer).displayName, report.ReportID);
if (PlayerReports.ContainsKey((victims[0].Object as BasePlayer).userID)) PlayerReports[(victims[0].Object as BasePlayer).userID].Reports.Add(report);
else {
PlayerReports[(victims[0].Object as BasePlayer).userID] = new UserReportData();
PlayerReports[(victims[0].Object as BasePlayer).userID].UserName = (victims[0].Object as BasePlayer).displayName;
PlayerReports[(victims[0].Object as BasePlayer).userID].Reports = new List<Report>();
PlayerReports[(victims[0].Object as BasePlayer).userID].Reports.Add(report);
}
var component = (victims[0].Object as BasePlayer).gameObject.AddComponent<ReportPlayer>();
component.Init(player);
BanProcess[player.IPlayer].component = component;
DrawAlert((victims[0].Object as BasePlayer), player);
SendDiscordMsg($"Модератор {player.displayName} ({player.userID}) вызвал на проверку игрока {(victims[0].Object as BasePlayer).displayName} ({(victims[0].Object as BasePlayer).userID}).\nReport ID {report.ReportID}", false);
SendVKMsg($"Модератор {player.displayName} ({player.userID}) вызвал на проверку игрока {(victims[0].Object as BasePlayer).displayName} ({(victims[0].Object as BasePlayer).userID}).\nReport ID {report.ReportID}", config.VKSettings.LogChatID);
PrintToChat($"Игрок {(victims[0].
// ... [Code preview truncated due to length. Full source in attached file] ...