C#:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using Color = UnityEngine.Color;
namespace Oxide.Plugins {
[Info("ReportSystem", "Sparkless", "0.0.1")]
public class ReportSystem : RustPlugin {
public class PlayerData {
[JsonProperty("Сколько проверок было сделано всего")]
public int CheckAlert {
get;
set;
}
[JsonProperty("Ник последнего проверяющего")]
public string AlertModerator {
get;
set;
}
[JsonProperty("Всего репортов")]
public int ReportAmount {
get;
set;
}
[JsonProperty("Последний репорт")]
public string LastReport {
get;
set;
}
[JsonProperty("КД")]
public int TimeOut {
get;
set;
}
}
public Dictionary<ulong, PlayerData> PlayerDatas = new Dictionary<ulong, PlayerData>();
ConfigData _config;
private System.Random random = new System.Random();
private string URLEncode(string input) {
if (input.Contains("#")) input = input.Replace("#", "%23");
if (input.Contains("$")) input = input.Replace("$", "%24");
if (input.Contains("+")) input = input.Replace("+", "%2B");
if (input.Contains("/")) input = input.Replace("/", "%2F");
if (input.Contains(":")) input = input.Replace(":", "%3A");
if (input.Contains(";")) input = input.Replace(";", "%3B");
if (input.Contains("?")) input = input.Replace("?", "%3F");
if (input.Contains("@")) input = input.Replace("@", "%40");
return input;
}
class ConfigData {
[JsonProperty("VK токен группы")]
public string VKTOKEN = "b44083cd4d19aab35b4546dcd6bf20d8b04e0892e311076f1d52b7cd5c6175ab3cf23d7fc4ce6389c842b";
[JsonProperty(PropertyName = "VkID администраторов (пример 11111, 22222)")]
public string VkID = "176879279";
[JsonProperty("Пермишенс модераторов")]
public string Moderator = "ReportAdmin.use";
[JsonProperty("Причины репортов")]
public Dictionary<string, string> ReasonBan {
get;
set;
}
[JsonProperty("Сколько давать кд игроку")]
public int KD = 3600;
}
protected override void LoadDefaultConfig() {
_config = new ConfigData {
ReasonBan = new Dictionary<string, string>() {
["1"]
= "2+", ["2"] = "МАКРОС", ["3"] = "ЧИТЫ", ["4"] = "БАГОЮЗ"
}
}
;
}
protected override void LoadConfig() {
base.LoadConfig();
_config = Config.ReadObject<ConfigData>();
}
protected override void SaveConfig() {
Config.WriteObject(_config);
}
void GetCallback(int number, string param, string message) {
}
private string app = "v=5.92";
private string RandomId() => random.Next(Int32.MinValue, Int32.MaxValue).ToString();
private void SendVkMessage(string reciverID, string msg) => webrequest.Enqueue("https://api.vk.com/method/messages.send?user_ids=" + reciverID + "&message=" + URLEncode(msg) + "&"+app + "&random_id=" + RandomId() + "&access_token=" + _config.VKTOKEN, null, (code, response) => GetCallback(code, response, "Сообщение"), this);
public string VKADMIN() => _config.VkID;
[PluginReference]
private Plugin ImageLibrary;
void OnServerInitialized() {
if (!permission.PermissionExists(_config.Moderator)) {
permission.RegisterPermission(_config.Moderator, this);
}
try {
PlayerDatas = Interface.GetMod().DataFileSystem.ReadObject<Dictionary<ulong, PlayerData>>(Name);
}
catch {
PlayerDatas = new Dictionary<ulong, PlayerData>();
}
foreach (var player in BasePlayer.activePlayerList) {
OnPlayerConnected(player);
}
timer.Every(1, () => {
foreach (var playerData in PlayerDatas) {
if (playerData.Value.TimeOut > 0) {
playerData.Value.TimeOut--;
}
}
}
);
}
void Unload() {
if (PlayerDatas != null) {
Interface.Oxide.DataFileSystem.WriteObject(Name, PlayerDatas);
}
BasePlayer.activePlayerList.ToList().ForEach(p => CuiHelper.DestroyUi(p, Info));
}
private List<ulong> ListPlayer = new List<ulong>();
void OnPlayerConnected(BasePlayer player) {
if (!PlayerDatas.ContainsKey(player.userID)) {
PlayerDatas.Add(player.userID, new PlayerData {
CheckAlert = 0, AlertModerator = "", ReportAmount = 0, LastReport = "", TimeOut = 0,
}
);
}
}
public string Layer = "UI_Report";
[ChatCommand("report")]
void ReportUI(BasePlayer player, string command, string[] args) {
CuiHelper.DestroyUi(player, Layer);
var container = new CuiElementContainer();
var Panel = container.Add(new CuiPanel {
Image = {
Color = "0 0 0 0.8"
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, CursorEnabled = true,
}
, "Overlay", Layer);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "-100 -100", AnchorMax = "100 100", OffsetMax = "0 0"
}
, Button = {
FadeIn = 0.5f, Color = "0 0 0 0.5", Close = Layer
}
, Text = {
Text = ""
}
}
, Layer);
container.Add(new CuiElement // ОСНОВА
{
Parent = Layer, Components = {
new CuiImageComponent {
Color = "0.5764706 0.5764706 0.5764706 0.1647059"
}
, new CuiRectTransformComponent {
AnchorMin = "0.2822918 0.3453704", AnchorMax = "0.7145832 0.7157407"
}
}
}
);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.2833334 0.6787039", AnchorMax = "0.7124999 0.7157403"
}
, Button = {
Color = HexToCuiColor("#FFFFFF00"), FadeIn = 0.1f
}
, Text = {
Text = $"ВЫБЕРИТЕ ИГРОКА, ЧТОБЫ ПОЖАЛОВАТЬСЯ НА НЕГО", FontSize = 20, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf"
}
}
, Layer);
container.Add(new CuiElement // ОСНОВА
{
Parent = Layer, Components = {
new CuiImageComponent {
Color = "0 0 0 0"
}
, new CuiRectTransformComponent {
AnchorMin = "0.4307289 0.3518519", AnchorMax = "0.558854 0.3990741"
}
}
}
);
CuiHelper.AddUi(player, container);
UpdatePlayer(player, 1);
}
void UpdatePlayer(BasePlayer player, int page) {
var container = new CuiElementContainer();
CuiHelper.DestroyUi(player, Layer + ".Page");
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.43125 0.3546296", AnchorMax = "0.5567709 0.3953704", OffsetMax = "0 0"
}
, Button = {
FadeIn = 0f, Color = HexToCuiColor("#FFFFFF00")
}
, Text = {
Text = $"{page}", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 25
}
}
, Layer, Layer + ".Page");
CuiHelper.DestroyUi(player, Layer + ".Back");
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.1317708 0.3546296", AnchorMax = "0.4578125 0.3972222", OffsetMax = "0 0"
}
, Button = {
FadeIn = 0f, Color = HexToCuiColor("#FFFFFF00"), Command = $"ReportSystem {page - 1}"
}
, Text = {
Text = "<", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 25
}
}
, Layer, Layer + ".Back");
CuiHelper.DestroyUi(player, Layer + ".Run");
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.5317693 0.3546296", AnchorMax = "0.857811 0.3972222", OffsetMax = "0 0"
}
, Button = {
FadeIn = 0f, Color = HexToCuiColor("#FFFFFF00"), Command = $"ReportSystem {page + 1}"
}
, Text = {
Text = ">", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 25
}
}
, Layer, Layer + ".Run");
for (int i = 0; i < 15; i++) {
CuiHelper.DestroyUi(player, Layer + $".{i}.Img");
CuiHelper.DestroyUi(player, Layer + $".{i}");
}
foreach (var check in BasePlayer.activePlayerList.OrderByDescending(p => PlayerDatas[p.userID].ReportAmount).Select((i, t) => new {
A = i, B = t - (page - 1) * 15
}
).Skip((page - 1) * 15).Take(15)) {
container.Add(new CuiButton {
RectTransform = {
AnchorMin = $"{0.2843751 + check.B * 0.100 - Math.Floor((double) check.B / 5) * 5 * 0.100} {0.6351852 - Math.Floor((double) check.B / 5) * 0.16}", AnchorMax = $"{0.3776042 + check.B * 0.100 - Math.Floor((double) check.B / 5) * 5 * 0.100} {0.6749998 - Math.Floor((double) check.B / 5) * 0.16 }", OffsetMax = "0 0"
}
, Button = {
Color = "0.5764706 0.5764706 0.5764706 0.1647059", Command = $"ReportSystem check {check.A.userID}"
}
, Text = {
Text = $"", Align = TextAnchor.LowerRight, Font = "robotocondensed-regular.ttf", FontSize = 15
}
}
, Layer, Layer + $".{check.B}");
container.Add(new CuiElement {
FadeOut = 0.3f, Parent = Layer + $".{check.B}", Name = Layer + $".{check.B}.Txt", Components = {
new CuiTextComponent {
Text = $"{check.A.displayName}", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 11, Color = "1 1 1 0.6"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 1", OffsetMax = "-5 -1"
}
}
}
);
}
CuiHelper.AddUi(player, container);
}
[ChatCommand("discord")]
void discordaccess(BasePlayer player, string cmd, string[] Args) {
if (Args == null || Args.Length == 0) {
player.ChatMessage("/discord ВАШ ДИСКОРД");
return;
}
if (ListPlayer.Contains(player.userID)) {
var Discord = "";
foreach (var arg in Args) {
Discord += " " + arg;
}
SendVkMessage(VKADMIN(), $"Игрок: {player.displayName}({player.userID})" + $"\nВыдал дискорд для проверки: {Discord}");
SendReply(player, $"Вы успешно отправили дискорд на проверку!\n");
}
}
[ConsoleCommand("ReportSystem")]
void ConsoleCommanding(ConsoleSystem.Arg args) {
BasePlayer player = args.Player();
if (player != null && args.HasArgs(1)) {
int page = 1;
if (int.TryParse(args.Args[0], out page) && page > 0 && (page - 1) * 15 <= BasePlayer.activePlayerList.Count) {
UpdatePlayer(player, page);
}
else if (args.Args[0] == "check") {
BasePlayer target = BasePlayer.Find(args.Args[1]);
if (target == null) {
CuiHelper.DestroyUi(player, Layer);
SendReply(player, "Данный игрок вышел с сервера!");
return;
}
if (target.userID == player.userID) return;
for (int i = 0; i < 25; i++) {
CuiHelper.DestroyUi(player, Layer + $".{i}1");
}
var container = new CuiElementContainer();
CuiHelper.DestroyUi(player, Layer + "1");
if (player.IsAdmin && permission.UserHasPermission(player.UserIDString, _config.Moderator)) {
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.4015626 0.7222222", AnchorMax = "0.5796875 0.7731482"
}
, Button = {
Close = Layer, Command = $"ReportSystem info {target.userID}", Color = "0.1607843 1 0 0.1961727", FadeIn = 0.1f
}
, Text = {
Text = "Полная информация об игроке", FontSize = 14, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf"
}
}
, Layer, Layer + "1");
}
foreach (var check in _config.ReasonBan.Select((i, t) => new {
A = i, B = t
}
)) {
container.Add(new CuiButton {
RectTransform = {
AnchorMin = $"{0.2828125 + check.B * 0.080 - Math.Floor((double) check.B / 5) * 5 * 0.080} {0.2944444 - Math.Floor((double) check.B / 5) * 0.16}", AnchorMax = $"{0.3598959 + check.B * 0.080 - Math.Floor((double) check.B / 5) * 5 * 0.080} {0.3425926 - Math.Floor((double) check.B / 5) * 0.16}", OffsetMax = "0 0"
}
, Button = {
Color = "1 0 0 0.198398", Command = $"ReportSystem report {check.A.Value} {target.userID}"
}
, Text = {
Text = $"{check.A.Value}", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 14
}
}
, Layer, Layer + $".{check.B}1");
}
CuiHelper.AddUi(player, container);
}
else if (args.Args[0] == "report") {
string reason = args.Args[1];
BasePlayer target = BasePlayer.Find(args.Args[2]);
if (target == null) {
CuiHelper.DestroyUi(player, Layer);
SendReply(player, "Данный игрок вышел с сервера!");
return;
}
CuiHelper.DestroyUi(player, Layer);
if (PlayerDatas[player.userID].TimeOut > 0) {
SendReply(player, $"На данный момент у вас откат репорта, подождите {PlayerDatas[player.userID].TimeOut} секунд");
return;
}
PlayerDatas[target.userID].ReportAmount++;
PlayerDatas[target.userID].LastReport = reason;
SendVkMessage(VKADMIN(), $"Игрок: {player.displayName}({player.userID})" + $"\nДанный игрок пожаловался на:{target.displayName}({target.userID})" + $"\nПричина жалобы: {reason}");
SendReply(player, $"Вы успешно отправили репорт на игрока {target.displayName}\nСпасибо за помощь!");
PlayerDatas[player.userID].TimeOut = _config.KD;
}
else if (args.Args[0] == "info") {
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, _config.Moderator)) return;
BasePlayer target = BasePlayer.Find(args.Args[1]);
if (target == null) return;
var container = new CuiElementContainer();
CuiHelper.DestroyUi(player, Info);
CuiHelper.DestroyUi(player, Layer);
var Panel = container.Add(new CuiPanel {
Image = {
Color = "0 0 0 0.8"
}
, RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, CursorEnabled = true,
}
, "Overlay", Info);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "-100 -100", AnchorMax = "100 100", OffsetMax = "0 0"
}
, Button = {
FadeIn = 0.5f, Color = "0 0 0 0.45", Close = Info
}
, Text = {
Text = ""
}
}
, Info);
container.Add(new CuiElement // ОСНОВА
{
Parent = Info, Components = {
new CuiImageComponent {
Color = "0.5764706 0.5764706 0.5764706 0.1647059"
}
, new CuiRectTransformComponent {
AnchorMin = "0.2822918 0.3453704", AnchorMax = "0.7145832 0.7157407"
}
}
}
);
container.Add(new CuiElement {
Parent = Info, Components = {
new CuiRawImageComponent {
Png = (string) ImageLibrary.Call("GetImage", target.UserIDString)
}
, new CuiRectTransformComponent {
AnchorMin = "0.4437498 0.537037", AnchorMax = "0.5500002 0.7046296", OffsetMax = "0 0"
}
}
}
);
string text = PlayerDatas[target.userID].AlertModerator == "" ? "Игрок еще не был проверен" : $"{PlayerDatas[target.userID].AlertModerator}";
container.Add(new CuiElement {
Parent = Info, Components = {
new CuiTextComponent() {
Color = HexToCuiColor("#FFFFFFFF"), FadeIn = 0.25f, Text = $"Ник: {target.displayName}" + $"\nSTEAM64ID: {target.userID}" + $"\nКоличество репортов на данного игрока: {PlayerDatas[target.userID].ReportAmount}" + $"\nПоследняя полученная жалоба на данного игрока: {PlayerDatas[target.userID].LastReport}" + $"\nПоследний проверяющий модератор: {text}", FontSize = 16, Align = TextAnchor.UpperCenter, Font = "robotocondensed-regular.ttf"
}
, new CuiRectTransformComponent {
AnchorMin = "0.2833333 0.3481482", AnchorMax = "0.7135416 0.5324073"
}
,
}
}
);
if (ListPlayer.Contains(target.userID)) {
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.4041668 0.7277777", AnchorMax = "0.5968748 0.8148147"
}
, Button = {
Close = Info, Command = $"ReportSystem unalert {target.userID}", Color = "1 0 0 0.198398", FadeIn = 0.1f
}
, Text = {
Text = "ОСТАНОВИТЬ ПРОВЕРКУ!", FontSize = 14, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf"
}
}
, Info);
}
else {
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0.4041668 0.7277777", AnchorMax = "0.5968748 0.8148147"
}
, Button = {
Close = Info, Command = $"ReportSystem alert {target.userID}", Color = "0.1607843 1 0 0.1961727", FadeIn = 0.1f
}
, Text = {
Text = "НАЧАТЬ ПРОВЕРКУ!", FontSize = 14, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf"
}
}
, Info);
}
CuiHelper.AddUi(player, container);
}
else if (args.Args[0] == "alert") {
var targets = BasePlayer.Find(args.Args[1]);
if (targets == null) {
SendReply(player, "Данного игрока нет на сервере!");
return;
}
if (ListPlayer.Contains(targets.userID)) {
SendReply(player, "Данный игрок уже на проверке!");
return;
}
ListPlayer.Add(targets.userID);
PlayerDatas[targets.userID].AlertModerator = player.displayName;
SendReply(player, $"Вы успешно вызвали {targets.displayName} на проверку!");
AlertPlayerCheck(targets, player);
}
else if (args.Args[0] == "unalert") {
var target = BasePlayer.Find(args.Args[1]);
if (target != null) {
if (ListPlayer.Contains(target.userID)) {
SendReply(player, $"Игрок {target.displayName} был успешно снят с проверки!");
ListPlayer.Remove(target.userID);
CuiHelper.DestroyUi(player, Info);
CuiHelper.DestroyUi(target, PlayerAlert);
PlayerDatas[target.userID].CheckAlert++;
}
}
}
}
}
void OnPlayerDisconnected(BasePlayer player, string reason) {
if (ListPlayer.Contains(player.userID)) {
if (reason == "Disconnected") {
Server.Broadcast($"Игрок {player.displayName} был забанен за выход с проверки!");
PrintWarning($"Игрок {player.displayName} был забанен за выход с проверки! Причина выхода {reason}");
Server.Command("global.ban", player.userID, "Выход с проверки");
ListPlayer.Remove(player.userID);
}
}
}
public static string PlayerAlert = "MAIN_MENU_alert";
private void AlertPlayerCheck(BasePlayer player, BasePlayer moderinformation) {
CuiElementContainer container = new CuiElementContainer();
CuiHelper.DestroyUi(player, PlayerAlert);
container.Add(new CuiPanel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-200 150", OffsetMax = "180 300"
}
, Image = {
Color = "0 0 0 0"
}
}
, "Overlay", PlayerAlert);
container.Add(new CuiElement {
Parent = PlayerAlert, Name = "MainAlert", Components = {
new CuiImageComponent {
Material = "assets/content/ui/uibackgroundblur.mat", Color = "0 0 0 0.5", Sprite = "assets/content/ui/ui.background.transparent.radial.psd"
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1"
}
}
}
);
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0 0.7644448", AnchorMax = "1 1", OffsetMax = "0 0"
}
, Text = {
Text = "Вас вызвали на проверку", FontSize = 19, Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter
}
}
, "MainAlert");
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0 0.6311106", AnchorMax = "1 0.7422219", OffsetMax = "0 0.764444"
}
, Text = {
Text = "Вы обязаны предоставить Discord!", FontSize = 15, Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter
}
}
, "MainAlert");
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.0684208 0.05777803", AnchorMax = "0.9087719 0.6266667", OffsetMax = "0 0"
}
, Text = {
Text = $"Что бы предоставить дискорд, вам необходимо написать в чат /discord ВАШ ДИСКОРД\nВызвавший модератор : {moderinformation.displayName}", FontSize = 17, Font = "robotocondensed-bold.ttf", Align = TextAnchor.MiddleCenter
}
}
, "MainAlert");
CuiHelper.AddUi(player, container);
}
public string Info = "UI_Info";
#region Helpers
private static string HexToCuiColor(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 $"{color.r:F2} {color.g:F2} {color.b:F2} {color.a:F2}";
}
#endregion
}
}