C#:
using System;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries.Covalence;
using ConVar;
using Newtonsoft.Json.Linq;
using Oxide.Core.Libraries;
using System.Linq;
using Oxide.Core.Plugins;
namespace Oxide.Plugins {
[Info("IQReportSystem", "Mercury", "0.2.3")]
class IQReportSystem : RustPlugin {
/// <summary>
/// - Поправил , когда игроки с меню в режиме оффлайн пропадали
///
/// Обновление 0.2.0 :
/// - Исправлены страницы
/// Обновление 0.2.1
/// - Добавил проверку на игрока, есть ли он на сервере во время проверки на АФК
/// - Полностью изменил проверку на АФК
/// - Изменен метод с отслеживанием движения игрока на проверке
/// - Добавлена проверка на актиность в чате в проверке на АФК
/// - Добавлена проверка на использование команды в проверке на АФК
/// - Добавлена поддержка NoEscape
/// - Добавлена возможность запретить проверку игрока,если у него рейдблок
/// Обновление 0.2.2
/// - Добавил возможность выключить проверку на АФК
/// Обновление 0.2.3
/// - Исправил NRE в выдаче рейтинга игроку
/// </summary>
#region Reference
[PluginReference]
Plugin GameWerAC, ImageLibrary, MultiFighting, IQChat, Friends, IQPersonal, IQFakeActive, NoEscape;
public string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary?.Call("GetImage", shortname, skin);
public bool AddImage(string url, string shortname, ulong skin = 0) => (bool)ImageLibrary?.Call("AddImage", url, shortname, skin);
public void SetCheck(BasePlayer player) => IQPersonal?.CallHook("API_SET_CHECK", player.userID);
public void SetBans(BasePlayer player) => IQPersonal?.CallHook("API_SET_BANS", player.userID);
public void SetScore(ulong UserID, int Amount) => IQPersonal?.CallHook("API_SET_SCORE", UserID, Amount);
public void RemoveScore(ulong UserID, int Amount) => IQPersonal?.CallHook("API_REMOVE_SCORE", UserID, Amount);
public bool IsRaidBlocked(BasePlayer player) {
if (NoEscape) return (bool)NoEscape?.Call("IsRaidBlocked", player);
else return false;
}
#region IQFakeActive
public bool IsFake(ulong userID) {
if (!IQFakeActive) return false;
if (!config.IQFakeActiveSettings.UseIQFakeActive) return false;
return (bool)IQFakeActive?.Call("IsFake", userID);
}
public string FindFakeName(ulong userID) => (string)IQFakeActive?.Call("FindFakeName", userID);
public void StartSysncFakeActive() => IQFakeActive?.Call("SyncReserved");
void SyncReservedFinish(string JSON) {
if (!config.IQFakeActiveSettings.UseIQFakeActive) return;
List<FakePlayer> ContentDeserialize = JsonConvert.DeserializeObject<List<FakePlayer>>(JSON);
PlayerBases = ContentDeserialize;
PrintWarning("IQReportSystem - успешно синхронизирована с IQFakeActive");
PrintWarning("=============SYNC==================");
}
public List<FakePlayer> PlayerBases = new List<FakePlayer>();
public class FakePlayer {
public ulong UserID;
public string DisplayName;
public string IQChatPreifx;
public string IQChatColorChat;
public string IQChatColorNick;
}
#endregion
#endregion
#region Vars
#region Permission
string PermissionModeration = "iqreportsystem.moderation";
string PermissionAdmin = "iqreportsystem.admin";
#endregion
#region Lists
public Dictionary<ulong, int> CooldownPC = new Dictionary<ulong, int>();
public Dictionary<ulong, PlayerSaveCheckClass> PlayerSaveCheck = new Dictionary<ulong, PlayerSaveCheckClass>();
public class PlayerSaveCheckClass {
public string Discord;
public string NickName;
public string StatusNetwork;
public ulong ModeratorID;
}
#endregion
#region JSON
private class Response {
public List<string> last_ip;
public string last_nick;
public List<ulong> another_accs;
public List<last_checks> last_check;
public class last_checks {
public ulong moderSteamID;
public string serverName;
public int time;
}
public List<RustCCBans> bans;
public class RustCCBans {
public int banID;
public string reason;
public string serverName;
public int OVHserverID;
public int banDate;
}
}
#endregion
#endregion
#region Configuration
private static Configuration config = new Configuration();
public class Configuration {
[JsonProperty("Основные настройки")]
public Settings Setting = new Settings();
[JsonProperty("Причины репорта")]
public List<string> ReasonReport = new List<string>();
[JsonProperty("Причины блокировки")]
public List<BanReason> ReasonBan = new List<BanReason>();
[JsonProperty("Настройки RustCheatCheck(Будет при проверке выдавать доступ в чекер и выводить информацию модератору)")]
public RCCSettings RCCSetting = new RCCSettings();
[JsonProperty("Настройка репутации для проверяющих")]
public RaitingSettings RaitingSetting = new RaitingSettings();
[JsonProperty("Настройка совместной работы с IQFakeActive")]
public IQFakeActive IQFakeActiveSettings = new IQFakeActive();
internal class BanReason {
[JsonProperty("Название")]
public string DisplayName;
[JsonProperty("Команда")]
public string Command;
}
internal class RCCSettings {
[JsonProperty("Включить поддержку RCC")]
public bool RCCUse;
[JsonProperty("Ключ от RCC")]
public string Key;
}
internal class RaitingSettings {
[JsonProperty("Сколько репутации снимать за 1-2 звезды(IQPersonal)")]
public int RemoveAmountOneTwo;
[JsonProperty("Сколько репутации давать за 3-4 звезды(IQPersonal)")]
public int GiveAmountThreeFour;
[JsonProperty("Сколько репутации давать за 5 звезд(IQPersonal)")]
public int GiveAmountFive;
}
internal class IQFakeActive {
[JsonProperty("Использовать IQFakeActive")]
public bool UseIQFakeActive;
}
internal class Settings {
[JsonProperty("Настройки IQChat")]
public ChatSettings ChatSetting = new ChatSettings();
[JsonProperty("Настройки интерфейса")]
public InterfaceSetting Interface = new InterfaceSetting();
[JsonProperty("NoEscape: Перенести проверку игрока если у него есть рейдблок")]
public bool NoEscapeCheckStop;
[JsonProperty("Включение проверки на AFK(true - включена/false - выключена)(Если будет выключена - игроку сразу придет уведомление о проверки)")]
public bool AfkUse;
[JsonProperty("Включить/отключить общее оповоещение для всех игроков(если игрока вызвали на проверку или вынесли вердикт,сообщение будет видно всем)")]
public bool UseAlertUsers;
[JsonProperty("Включить/отключить оповещение о максимальном кол-во репортов")]
public bool MaxReportAlert;
[JsonProperty("Максимальное количество репортов")]
public int MaxReport;
[JsonProperty("Перезарядка для отправки репорта(секунды)")]
public int CooldownTime;
[JsonProperty("Запретить друзьям репортить друг друга")]
public bool FriendNoReport;
[JsonProperty("Включить логирование в беседу ВК")]
public bool VKMessage;
[JsonProperty("Включить логирование в Discord")]
public bool DiscrodMessage;
[JsonProperty("Webhooks для дискорда")]
public string WebHook;
[JsonProperty("Настройки ВК")]
public VKSetting VKSettings = new VKSetting();
internal class ChatSettings {
[JsonProperty("IQChat : Кастомный префикс в чате")]
public string CustomPrefix;
[JsonProperty("IQChat : Кастомный аватар в чате(Если требуется)")]
public string CustomAvatar;
}
internal class VKSetting {
[JsonProperty("Токен от группы ВК(От группы будут идти сообщения в беседу.Вам нужно добавить свою группу в беседу!)")]
public string Token;
[JsonProperty("ID беседы для группы")]
public string ChatID;
}
internal class InterfaceSetting {
[JsonProperty("Настройка интерфейса для отправки жалобы")]
public ReasonInterfaceSetting ReasonInterface = new ReasonInterfaceSetting();
[JsonProperty("Настройка интерфейса для уведомления")]
public AlertInterfaceSettings AlertInterface = new AlertInterfaceSettings();
[JsonProperty("Настройка интерфейса для мини-панели модератора")]
public ModeratorPanelInterfaceSettings ModderatorPanel = new ModeratorPanelInterfaceSettings();
[JsonProperty("Настройка интерфейса для рейтинга")]
public RaitingInterfaceSettings RaitingInterface = new RaitingInterfaceSettings();
[JsonProperty("Sprite для рейтинга(звезды)")]
public string SpriteRaiting;
[JsonProperty("Sprite для кнопки жалоб в панели модератора")]
public string SpriteReportModeration;
[JsonProperty("Sprite для иконки жалоб")]
public string SpriteReport;
[JsonProperty("Цвет текста в плагине")]
public string HexLabels;
[JsonProperty("Цвет боковой панели")]
public string HexRightMenu;
[JsonProperty("Цвет кнопок боковой панели")]
public string HexButtonRightMenu;
[JsonProperty("Цвет основной панели")]
public string HexMainPanel;
[JsonProperty("Цвет панели поиска и заднего фона игроков")]
public string HexSearchPanel;
[JsonProperty("Цвет кнопки у игрока для перехода к действию")]
public string HexPlayerButton;
[JsonProperty("Sprite кнопки у игрока для преехода к действию")]
public string SpritePlayerButton;
internal class ReasonInterfaceSetting {
[JsonProperty("Цвет основной панели")]
public string HexMain;
[JsonProperty("Цвет панели с заголовком")]
public string HexTitlePanel;
[JsonProperty("Цвет жалоб")]
public string HexButton;
[JsonProperty("Цвет текста с жалобами")]
public string HexLabel;
[JsonProperty("Sprite кнопки закрыть")]
public string SpriteClose;
[JsonProperty("Sprite панели с заголовком")]
public string SpriteTitlePanel;
[JsonProperty("Цвет кнопки закрыть")]
public string HexClose;
}
internal class AlertInterfaceSettings {
[JsonProperty("Цвет основной панели")]
public string HexMain;
[JsonProperty("Цвет заголовка и полоски")]
public string HexTitle;
[JsonProperty("Цвет текста")]
public string HexLabel;
}
internal class ModeratorPanelInterfaceSettings {
[JsonProperty("Цвет основной панели")]
public string HexMain;
[JsonProperty("Цвет панели с заголовком")]
public string HexTitlePanel;
[JsonProperty("Sprite панели с заголовком")]
public string SpriteTitlePanel;
[JsonProperty("Цвет текста")]
public string HexLabel;
[JsonProperty("Цвет кнопки вердикт и задний фон причин")]
public string HexBanButton;
[JsonProperty("Цвет кнопки окончания проверки")]
public string HexStopButton;
}
internal class RaitingInterfaceSettings {
[JsonProperty("Цвет основной панели")]
public string HexMain;
[JsonProperty("Цвет панели с заголовком")]
public string HexTitlePanel;
[JsonProperty("Sprite панели с заголовком")]
public string SpriteTitlePanel;
[JsonProperty("Цвет текста")]
public string HexLabel;
[JsonProperty("Цвет иконок с рейтингом")]
public string HexRaitingButton;
[JsonProperty("Sprite рейтинга")]
public string SpriteRaiting;
}
}
}
public static Configuration GetNewConfiguration() {
return new Configuration {
Setting = new Settings {
AfkUse = true, NoEscapeCheckStop = false, UseAlertUsers = true, FriendNoReport = false, MaxReport = 3, MaxReportAlert = true, CooldownTime = 600, VKMessage = true, DiscrodMessage = false, WebHook = "", ChatSetting = new Settings.ChatSettings {
CustomAvatar = "", CustomPrefix = ""
}
, VKSettings = new Settings.VKSetting {
Token = "", ChatID = ""
}
, Interface = new Settings.InterfaceSetting {
SpriteRaiting = "assets/icons/favourite_servers.png", SpriteReportModeration = "assets/icons/subtract.png", SpriteReport = "assets/icons/examine.png", SpritePlayerButton = "assets/icons/vote_up.png", HexPlayerButton = "#45542BFF", HexLabels = "#DAD1C7FF", HexButtonRightMenu = "#802A2AFF", HexMainPanel = "#21211AF2", HexRightMenu = "#762424FF", HexSearchPanel = "#3B3D37FF", ReasonInterface = new Settings.InterfaceSetting.ReasonInterfaceSetting {
HexMain = "#585450FF", HexTitlePanel = "#54514DFF", HexButton = "#3E482EFF", HexClose = "#B4371EFF", HexLabel = "#bdd197", SpriteClose = "assets/icons/vote_down.png", SpriteTitlePanel = "assets/icons/connection.png"
}
, AlertInterface = new Settings.InterfaceSetting.AlertInterfaceSettings {
HexMain = "#21211AF2", HexLabel = "#DAD1C7FF", HexTitle = "#B4371EFF",
}
, ModderatorPanel = new Settings.InterfaceSetting.ModeratorPanelInterfaceSettings {
HexMain = "#575450FF", HexTitlePanel = "#54514DFF", HexLabel = "#DAD1C7FF", SpriteTitlePanel = "assets/icons/study.png", HexBanButton = "#B4371EFF", HexStopButton = "#3E482EFF"
}
, RaitingInterface = new Settings.InterfaceSetting.RaitingInterfaceSettings {
HexMain = "#575450FF", HexTitlePanel = "#54514DFF", HexLabel = "#DAD1C7FF", HexRaitingButton = "#cdb980", SpriteTitlePanel = "assets/icons/ignite.png", SpriteRaiting = "assets/icons/favourite_servers.png"
}
}
}
, ReasonReport = new List<string> {
"Использование читов", "Макросы", "Игра 3+",
}
, ReasonBan = new List<BanReason> {
new BanReason {
DisplayName = "Использование читов", Command = "ban {0} soft",
}
, new BanReason {
DisplayName = "Макросы", Command = "ban {0} 30d macros",
}
, new BanReason {
DisplayName = "Игра 3+", Command = "ban {0} 14d 3+",
}
, new BanReason {
DisplayName = "Отказ", Command = "ban {0} 7d otkaz",
}
,
}
, RCCSetting = new RCCSettings {
RCCUse = false, Key = "xxxxxxxxxxxxxxRCCKey",
}
, IQFakeActiveSettings = new IQFakeActive {
UseIQFakeActive = false,
}
, RaitingSetting = new RaitingSettings {
RemoveAmountOneTwo = 4, GiveAmountThreeFour = 3, GiveAmountFive = 5
}
}
;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
}
catch {
PrintWarning($"Ошибка чтения конфигурации #93 'oxide/config/{Name}', создаём новую конфигурацию!!");
LoadDefaultConfig();
}
NextTick(SaveConfig);
}
protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Data
public Dictionary<ulong, PlayerInfo> ReportInformation = new Dictionary<ulong, PlayerInfo>();
public Dictionary<ulong, ModeratorInfo> ModeratorInformation = new Dictionary<ulong, ModeratorInfo>();
public class PlayerInfo {
[JsonProperty("Отображаемое имя")]
public string DisplayName;
[JsonProperty("IP Адреса")]
public List<string> IP;
[JsonProperty("Последняя жалоба")]
public string LastReport;
[JsonProperty("Последний проверяющий модератор")]
public string LastCheckModerator;
[JsonProperty("Количество проверок")]
public int CheckCount;
[JsonProperty("История жалоб")]
public List<string> ReportHistory;
[JsonProperty("Количество жалоб")]
public int ReportCount;
[JsonProperty("Игровой статус")]
public string GameStatus;
}
public class ModeratorInfo {
[JsonProperty("Проверки игроков с вердиктами")]
public Dictionary<string, string> CheckPlayerModerator = new Dictionary<string, string>();
[JsonProperty("Блокировки игроков с вердиктом")]
public Dictionary<string, string> BanPlayerModerator = new Dictionary<string, string>();
[JsonProperty("Общее количество проверок")]
public int CheckCount;
[JsonProperty("История оценок модератора")]
public List<int> Arrayrating;
[JsonProperty("Средняя оценка качества")]
public float AverageRating;
}
#endregion
#region Metods
#region MetodsReport
void Metods_PlayerConnected(BasePlayer player) {
if (player == null) return;
if (!ReportInformation.ContainsKey(player.userID)) {
PlayerInfo pInfo = new PlayerInfo {
DisplayName = player.displayName, IP = new List<string>(), LastReport = "", LastCheckModerator = "", CheckCount = 0, ReportCount = 0, GameStatus = IsSteam(player.UserIDString), ReportHistory = new List<string>(),
}
;
ReportInformation.Add(player.userID, pInfo);
}
else {
var User = ReportInformation[player.userID];
var IP = covalence.Players.FindPlayerById(player.UserIDString).Address;
User.GameStatus = IsSteam(player.UserIDString);
if (!String.IsNullOrWhiteSpace(IP)) if (!User.IP.Contains(IP)) User.IP.Add(IP);
}
if (permission.UserHasPermission(player.UserIDString, PermissionModeration)) {
if (!ModeratorInformation.ContainsKey(player.userID)) {
ModeratorInfo mInfo = new ModeratorInfo {
CheckCount = 0, BanPlayerModerator = new Dictionary<string, string>(), CheckPlayerModerator = new Dictionary<string, string>(), Arrayrating = new List<int>(), AverageRating = 0,
}
;
ModeratorInformation.Add(player.userID, mInfo);
}
}
else {
if (ModeratorInformation.ContainsKey(player.userID)) ModeratorInformation.Remove(player.userID);
}
Metods_StatusNetwork(player, lang.GetMessage("NETWORD_STATUS_ONLINE", this, player.UserIDString));
}
void Metods_Report(BasePlayer target, int ReasonIndex) {
if (permission.UserHasPermission(target.UserIDString, PermissionAdmin)) return;
if (IsSteam(target.UserIDString) == lang.GetMessage("IS_STEAM_STATUS_PIRATE", this, target.UserIDString)) {
if (GameWerAC != null) {
GameWerAC.Call("GetScreenReport", target);
Puts("Выполнен скриншот экрана для пирата");
}
}
string ReasonReport = config.ReasonReport[ReasonIndex];
var User = ReportInformation[target.userID];
User.ReportCount++;
User.LastReport = ReasonReport;
User.ReportHistory.Insert(0, ReasonReport);
if (config.Setting.MaxReportAlert) if (User.ReportCount >= config.Setting.MaxReport) {
foreach (var MList in BasePlayer.activePlayerList) if (permission.UserHasPermission(MList.UserIDString, PermissionModeration)) SendChat(MList, String.Format(lang.GetMessage("METODS_HELP_MODERS", this, MList.UserIDString), target.displayName, User.ReportCount));
VKSendMessage(String.Format(lang.GetMessage("METODS_HELP_MODERS_VK", this), target.displayName, User.ReportCount));
DiscordSendMessage(String.Format(lang.GetMessage("METODS_HELP_MODERS_VK", this), target.displayName, User.ReportCount));
}
}
#endregion
#region MetodsCooldown
void Metods_GiveCooldown(ulong ID, int cooldown) {
CooldownPC[ID] = cooldown + (int)CurrentTime();
}
bool Metods_GetCooldown(ulong ID) {
if (!CooldownPC.ContainsKey(ID) || Math.Max(0, CooldownPC[ID]) < 1 || CooldownPC[ID] <= (int)CurrentTime()) return false;
else return true;
}
#endregion
#region MetodsModeration
void Metods_CheckModeration(BasePlayer Suspect, BasePlayer Moderator) {
if (PlayerSaveCheck.ContainsKey(Suspect.userID)) {
SendChat(Moderator, lang.GetMessage("PLAYER_CHECKED", this));
return;
}
if (config.Setting.NoEscapeCheckStop) if (IsRaidBlocked(Suspect)) {
SendChat(Moderator, lang.GetMessage("RAID_BLOCK_TRUE_STOP", this, Moderator.UserIDString));
return;
}
PlayerSaveCheck.Add(Suspect.userID, new PlayerSaveCheckClass {
Discord = lang.GetMessage("DISCORD_NULL", this), NickName = Suspect.displayName, StatusNetwork = lang.GetMessage("NETWORD_STATUS_ONLINE", this, Suspect.UserIDString), ModeratorID = Moderator.userID,
}
);
SendChat(Moderator, String.Format(lang.GetMessage("METODS_MODER_START_CHECK", this, Moderator.UserIDString), Suspect.displayName));
VKSendMessage(String.Format(lang.GetMessage("METODS_MODER_START_CHECK_VK", this), Moderator.displayName, Moderator.UserIDString, Suspect.displayName, Suspect.UserIDString));
Metods_AFK(Suspect.userID, Moderator);
if(config.Setting.UseAlertUsers) foreach(var p in BasePlayer.activePlayerList) SendChat(p, String.Format(lang.GetMessage("METODS_MODER_START_CHECK_VK", this, p.UserIDString), Moderator.displayName, Moderator.UserIDString, Suspect.displayName, Suspect.UserIDString));
}
void Metods_CheckModerationFinish(BasePlayer moderator, ulong SuspectID) {
IPlayer Suspect = covalence.Players.FindPlayerById(SuspectID.ToString());
if (Suspect.IsConnected) {
BasePlayer SOnline = BasePlayer.FindByID(ulong.Parse(Suspect.Id));
CuiHelper.DestroyUi(SOnline, PARENT_UI_ALERT_SEND);
SendChat(SOnline, lang.GetMessage("MSG_CHECK_CHECK_STOP", this, moderator.UserIDString));
}
CuiHelper.DestroyUi(moderator, PARENT_UI_MODERATOR_MINI_PANEL);
PlayerSaveCheck.Remove(ulong.Parse(Suspect.Id));
var User = ReportInformation[ulong.Parse(Suspect.Id)];
var Moderator = ModeratorInformation[moderator.userID];
Moderator.CheckCount++;
if (!Moderator.CheckPlayerModerator.ContainsKey(Suspect.Name)) Moderator.CheckPlayerModerator.Add(Suspect.Name, User.LastReport);
User.ReportCount = 0;
User.ReportHistory.Clear();
User.LastReport = lang.GetMessage("NON_REPORT", this);
User.CheckCount++;
User.LastCheckModerator = moderator.displayName;
SendChat(moderator, lang.GetMessage("METODS_MODER_STOP_CHECK", this, moderator.UserIDString));
VKSendMessage(String.Format(lang.GetMessage("METODS_MODER_STOP_CHECK_VK", this), moderator.displayName));
DiscordSendMessage(String.Format(lang.GetMessage("METODS_MODER_STOP_CHECK_VK", this), moderator.displayName));
SetCheck(moderator);
if (config.Setting.UseAlertUsers) foreach (var p in BasePlayer.activePlayerList) SendChat(p, String.Format(lang.GetMessage("METODS_MODER_STOP_CHECK_ALERT", this, p.UserIDString), moderator.displayName, Suspect.Name));
}
void Metods_StatusNetwork(BasePlayer Suspect, string Reason) {
if (Suspect == null) return;
if (PlayerSaveCheck.ContainsKey(Suspect.userID)) {
if (Suspect.IsConnected) if (Suspect.IsReceivingSnapshot) {
timer.Once(3, () => Metods_StatusNetwork(Suspect, lang.GetMessage("NETWORD_STATUS_ONLINE", this, Suspect.UserIDString)));
return;
}
PlayerSaveCheck[Suspect.userID].StatusNetwork = Reason;
BasePlayer Moderator = BasePlayer.FindByID(PlayerSaveCheck[Suspect.userID].ModeratorID);
CuiHelper.DestroyUi(Moderator, UI_MODERATION_CHECK_MENU_NETWORK);
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.6782616 0.5478261", AnchorMax = "0.9884076 0.7333333"
}
, Text = {
Text = $"{PlayerSaveCheck[Suspect.userID].StatusNetwork}", FontSize = 12, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperCenter, Color = HexToRustFormat("#FFFFFFFF")
}
}
, PARENT_UI_MODERATOR_MINI_PANEL, UI_MODERATION_CHECK_MENU_NETWORK);
CuiHelper.AddUi(Moderator, container);
UI_AlertSendPlayer(Suspect);
SendChat(Moderator, String.Format(lang.GetMessage("STATUS_CHANGED", this, Moderator.UserIDString), Suspect.displayName, Reason));
VKSendMessage(String.Format(lang.GetMessage("STATUS_CHANGED_VK", this), Suspect.displayName, Reason));
DiscordSendMessage(String.Format(lang.GetMessage("STATUS_CHANGED_VK", this), Suspect.displayName, Reason));
}
}
public Timer ModerTimeOutTimer;
void Metods_ModeratorExitCheck(BasePlayer Moderator) {
foreach (var ModeratorCritical in PlayerSaveCheck) if (ModeratorCritical.Value.ModeratorID == Moderator.userID) {
IPlayer ModeratorOffline = covalence.Players.FindPlayerById(ModeratorCritical.Value.ModeratorID.ToString());
IPlayer Suspect = covalence.Players.FindPlayerById(ModeratorCritical.Key.ToString());
int TimeOutCount = 0;
ModerTimeOutTimer = timer.Repeat(5, 10, () => {
if (ModeratorOffline.IsConnected) {
UI_MiniPanelModerator(Moderator, ModeratorCritical.Key);
SendChat(Moderator, lang.GetMessage("MODERATOR_RETURN_WELCOME", this, Moderator.UserIDString));
if (ModerTimeOutTimer != null) {
ModerTimeOutTimer.Destroy();
ModerTimeOutTimer = null;
}
return;
}
else {
TimeOutCount++;
if (TimeOutCount >= 10) {
PlayerSaveCheck.Remove(ModeratorCritical.Key);
foreach (var OnlineModeration in BasePlayer.activePlayerList) if (permission.UserHasPermission(OnlineModeration.UserIDString, PermissionModeration)) if (Suspect.IsConnected) {
BasePlayer SOnline = BasePlayer.FindByID(ulong.Parse(Suspect.Id));
CuiHelper.DestroyUi(SOnline, PARENT_UI_ALERT_SEND);
SendChat(SOnline, String.Format(lang.GetMessage("MODERATOR_DISCONNECTED_STOP_CHECK", this, Moderator.UserIDString), ModeratorOffline.Name));
SendChat(OnlineModeration, String.Format(lang.GetMessage("MODERATOR_DISCONNECTED_STOP_RESEND", this, Moderator.UserIDString), ModeratorOffline.Name, Suspect.Name));
VKSendMessage(String.Format(lang.GetMessage("MODERATOR_DISCONNECTED_STOP_RESEND", this), ModeratorOffline.Name, Suspect.Name));
DiscordSendMessage(String.Format(lang.GetMessage("MODERATOR_DISCONNECTED_STOP_RESEND", this), ModeratorOffline.Name, Suspect.Name));
if (ModerTimeOutTimer != null) {
ModerTimeOutTimer.Destroy();
ModerTimeOutTimer = null;
}
}
return;
}
}
}
);
}
}
void Metods_ModeratorBanned(BasePlayer Moderator, ulong SuspectID, int i) {
CuiHelper.DestroyUi(Moderator, PARENT_UI_MODERATOR_MINI_PANEL);
IPlayer Suspect = covalence.Players.FindPlayerById(SuspectID.ToString());
string Reason = config.ReasonBan[i].DisplayName;
rust.RunClientCommand(Moderator, String.Format(config.ReasonBan[i].Command, SuspectID));
PlayerSaveCheck.Remove(SuspectID);
var ModeratorInfo = ModeratorInformation[Moderator.userID];
ModeratorInfo.CheckCount++;
if (!ModeratorInfo.CheckPlayerModerator.ContainsKey(Suspect.Name)) ModeratorInfo.CheckPlayerModerator.Add(Suspect.Name, Reason);
if (!ModeratorInfo.BanPlayerModerator.ContainsKey(Suspect.Name)) ModeratorInfo.BanPlayerModerator.Add(Suspect.Name, Reason);
SendChat(Moderator, String.Format(lang.GetMessage("MODERATOR_COMPLETED_CHECK", this, Moderator.UserIDString), Reason));
VKSendMessage(String.Format(lang.GetMessage("MODERATOR_COMPLETED_CHECK_VK", this), Moderator.displayName, Moderator.UserIDString, Suspect.Name, SuspectID, Reason));
DiscordSendMessage(String.Format(lang.GetMessage("MODERATOR_COMPLETED_CHECK_VK", this), Moderator.displayName, Moderator.UserIDString, Suspect.Name, SuspectID, Reason));
SetBans(Moderator);
if (config.Setting.UseAlertUsers) foreach (var p in BasePlayer.activePlayerList) SendChat(p, String.Format(lang.GetMessage("MODERATOR_COMPLETED_CHECK_ALERT", this, p.UserIDString), Moderator.displayName, Suspect.Name, Reason));
}
#endregion
#region MetodsAFK
void Metods_CheckStopInAFK(BasePlayer moderator, string ID) {
IPlayer Suspect = covalence.Players.FindPlayerById(ID);
if (Suspect.IsConnected) {
BasePlayer SOnline = BasePlayer.FindByID(ulong.Parse(Suspect.Id));
CuiHelper.DestroyUi(SOnline, PARENT_UI_ALERT_SEND);
}
CuiHelper.DestroyUi(moderator, PARENT_UI_MODERATOR_MINI_PANEL);
PlayerSaveCheck.Remove(ulong.Parse(Suspect.Id));
SendChat(moderator, lang.GetMessage("PLAYER_AFK_CHECK_STOP", this));
VKSendMessage(String.Format(lang.GetMessage("PLAYER_AFK_CHECK_STOP_VK", this), moderator.displayName, moderator.userID, Suspect.Name));
DiscordSendMessage(String.Format(lang.GetMessage("PLAYER_AFK_CHECK_STOP_VK", this), moderator.displayName, moderator.userID, Suspect.Name));
}
public Dictionary<ulong, GenericPosition> AFKPositionTry = new Dictionary<ulong, GenericPosition>();
public Dictionary<ulong, int> AFKCheckedTry = new Dictionary<ulong, int>();
void Metods_AFK(ulong SuspectID, BasePlayer Moderator) {
if (config.Setting.AfkUse) {
IPlayer Suspect = covalence.Players.FindPlayerById(SuspectID.ToString());
if (!AFKCheckedTry.ContainsKey(SuspectID)) AFKCheckedTry.Add(SuspectID, 0);
else AFKCheckedTry[SuspectID] = 0;
StartAFKCheck(Suspect, Moderator);
}
else {
BasePlayer SuspectOnline = BasePlayer.FindByID(SuspectID);
if (SuspectOnline == null || !SuspectOnline.IsConnected) {
SendChat(Moderator, lang.GetMessage("PLAYER_LEAVE_AFK_METOD", this, Moderator.UserIDString));
CuiHelper.DestroyUi(Moderator, PARENT_UI_MODERATOR_MINI_PANEL);
if (PlayerSaveCheck.ContainsKey(SuspectID)) PlayerSaveCheck.Remove(SuspectID);
return;
}
UI_AlertSendPlayer(SuspectOnline);
PlayerSaveCheck = new Dictionary<ulong, PlayerSaveCheckClass> {
[SuspectOnline.userID]
= new PlayerSaveCheckClass {
Discord = lang.GetMessage("DISCORD_NULL", this), NickName = SuspectOnline.displayName, StatusNetwork = lang.GetMessage("NETWORD_STATUS_ONLINE", this, SuspectOnline.UserIDString), ModeratorID = Moderator.userID,
}
}
;
UI_MiniPanelModerator(Moderator, SuspectOnline.userID);
SendChat(Moderator, lang.GetMessage("PLAYER_NON_AFK", this, Moderator.UserIDString));
if (config.RCCSetting.RCCUse) {
string Key = config.RCCSetting.Key;
if (String.IsNullOrEmpty(Key)) return;
try {
string API = $"https://rustcheatcheck.ru/panel/api?action=addPlayer&key={Key}&player={SuspectID}";
webrequest.Enqueue(API, null, (code, response) => {
}
, this);
}
catch {
}
}
}
}
public void StartAFKCheck(IPlayer Suspect, BasePlayer Moderator) {
ulong SuspectID = ulong.Parse(Suspect.Id);
var Postion = Suspect.Position();
if (!AFKPositionTry.ContainsKey(SuspectID)) AFKPositionTry.Add(SuspectID, Postion);
int Try = 1;
timer.Repeat(5f, 5, () => {
Postion = Suspect.Position();
if (AFKPositionTry[SuspectID] != Postion) {
SendChat(Moderator, String.Format(lang.GetMessage("PLAYER_AFK_CHANGE_POS", this, Moderator.UserIDString), Try));
AFKCheckedTry[SuspectID]++;
}
else SendChat(Moderator, String.Format(lang.GetMessage("PLAYER_AFK_CHANGE_NO_POS", this, Moderator.UserIDString), Try));
AFKPositionTry[SuspectID] = Postion;
Try++;
}
);
timer.Once(30f, () => {
if(AFKCheckedTry[SuspectID] < 3) Metods_CheckStopInAFK(Moderator, Suspect.Id);
else {
BasePlayer SuspectOnline = BasePlayer.FindByID(ulong.Parse(Suspect.Id));
if (SuspectOnline == null || !SuspectOnline.IsConnected) {
SendChat(Moderator, lang.GetMessage("PLAYER_LEAVE_AFK_METOD", this, Moderator.UserIDString));
CuiHelper.DestroyUi(Moderator, PARENT_UI_MODERATOR_MINI_PANEL);
if (PlayerSaveCheck.ContainsKey(SuspectID)) PlayerSaveCheck.Remove(SuspectID);
return;
}
UI_AlertSendPlayer(SuspectOnline);
PlayerSaveCheck = new Dictionary<ulong, PlayerSaveCheckClass> {
[SuspectOnline.userID]
= new PlayerSaveCheckClass {
Discord = lang.GetMessage("DISCORD_NULL", this), NickName = SuspectOnline.displayName, StatusNetwork = lang.GetMessage("NETWORD_STATUS_ONLINE", this, SuspectOnline.UserIDString), ModeratorID = Moderator.userID,
}
}
;
UI_MiniPanelModerator(Moderator, SuspectOnline.userID);
SendChat(Moderator, lang.GetMessage("PLAYER_NON_AFK", this, Moderator.UserIDString));
if (config.RCCSetting.RCCUse) {
string Key = config.RCCSetting.Key;
if (String.IsNullOrEmpty(Key)) return;
try {
string API = $"https://rustcheatcheck.ru/panel/api?action=addPlayer&key={Key}&player={Suspect.Id}";
webrequest.Enqueue(API, null, (code, response) => {
}
, this);
}
catch {
}
}
}
if (AFKCheckedTry.ContainsKey(SuspectID)) AFKCheckedTry.Remove(SuspectID);
}
);
}
#endregion
#endregion
#region Command
#region UseCommand
[ChatCommand("report")]
void ReportChatCommand(BasePlayer player, string command, string[] args) {
if (player == null) return;
if (args == null || args.Length == 0) {
UI_Interface(player);
return;
}
}
[ConsoleCommand("report.list")]
void ReportList(ConsoleSystem.Arg arg) {
PrintError(lang.GetMessage("REPORT_LIST_CONSOLE", this));
foreach (var List in BasePlayer.activePlayerList) if (ReportInformation[List.userID].ReportCount >= config.Setting.MaxReport) PrintError($"{List.displayName} : {ReportInformation[List.userID].ReportCount}");
}
[ChatCommand("discord")]
void SendDiscord(BasePlayer Suspect, string command, string[] args) {
if (!PlayerSaveCheck.ContainsKey(Suspect.userID)) {
SendChat(Suspect, lang.GetMessage("MSG_CHECK_DISCORD", this, Suspect.UserIDString));
return;
}
string Discord = "";
foreach (var arg in args) Discord += " " + arg;
PlayerSaveCheck[Suspect.userID].Discord = Discord;
SendChat(Suspect, String.Format(lang.GetMessage("MSG_DISCORD_SEND", this, Suspect.UserIDString), Discord));
VKSendMessage(String.Format(lang.GetMessage("DISCROD_VK_SEND", this), Suspect.displayName, Suspect.userID, Discord));
DiscordSendMessage(String.Format(lang.GetMessage("DISCROD_VK_SEND", this), Suspect.displayName, Suspect.userID, Discord));
BasePlayer Moderator = BasePlayer.FindByID(PlayerSaveCheck[Suspect.userID].ModeratorID);
CuiHelper.DestroyUi(Moderator, UI_MODERATION_CHECK_MENU_DISCORD);
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.01159436 0.5478261", AnchorMax = "0.7072465 0.7333333"
}
, Text = {
Text = $"Discord : {PlayerSaveCheck[Suspect.userID].Discord}", FontSize = 12, Font = "robotocondensed-regular.ttf", Align = TextAnchor.UpperCenter, Color = HexToRustFormat("#FFFFFFFF")
}
}
, PARENT_UI_MODERATOR_MINI_PANEL, UI_MODERATION_CHECK_MENU_DISCORD);
CuiHelper.AddUi(Moderator, container);
}
[ConsoleCommand("call")]
void CallAdminCheck(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (!player.IsAdmin) return;
ulong SuspectID = ulong.Parse(arg.Args[0]);
if(player == null) {
PrintWarning("Вы должны быть на сервере");
SendChat(player, "Вы должны быть на сервере");
return;
}
BasePlayer Suspect = BasePlayer.FindByID(SuspectID);
if(Suspect == null) {
PrintWarning("Игрока нет");
SendChat(player, "Игрока нет");
return;
}
Metods_CheckModeration(Suspect, player);
Puts("Вы вызвали игрока на проверку");
SendChat(player, "Вы вызвали игрока на проверку");
}
[ConsoleCommand("report")]
void ReportCommand(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
if (arg == null || arg.Args == null || arg.Args.Length == 0) {
if (player == null) return;
UI_Interface(player);
return;
}
switch (arg.Args[0].ToLower()) {
case "give" : {
if (arg.Args.Length != 3) {
PrintWarning("Используйте правильный синтаксис : report give SteamID Amount");
return;
}
if (string.IsNullOrWhiteSpace(arg.Args[1])) {
PrintWarning("Укажите корректный Steam64ID");
return;
}
if (!arg.Args[1].IsSteamId()) {
PrintWarning("Укажите корректный Steam64ID");
return;
}
if (string.IsNullOrWhiteSpace(arg.Args[2])) {
PrintWarning("Укажите корректное количество");
return;
}
ReportInformation[ulong.Parse(arg.Args[1])].ReportCount += Convert.ToInt32(arg.Args[2]);
if (player != null) {
VKSendMessage(String.Format(lang.GetMessage("CONSOLE_REPORT_GIVE", this), arg.Args[1], arg.Args[2], ReportInformation[ulong.Parse(arg.Args[1])].ReportCount));
DiscordSendMessage(String.Format(lang.GetMessage("CONSOLE_REPORT_GIVE", this), arg.Args[1], arg.Args[2], ReportInformation[ulong.Parse(arg.Args[1])].ReportCount));
}
PrintWarning("ACCESS");
return;
}
case "remove" : {
if (arg.Args.Length != 3) {
PrintWarning("Используйте правильный синтаксис : report remove SteamID Amount");
return;
}
if (string.IsNullOrWhiteSpace(arg.Args[1])) {
PrintWarning("Укажите корректный Steam64ID");
return;
}
if (!arg.Args[1].IsSteamId()) {
PrintWarning("Укажите корректный Steam64ID");
return;
}
if (string.IsNullOrWhiteSpace(arg.Args[2])) {
PrintWarning("Укажите корректное количество");
return;
}
ReportInformation[ulong.Parse(arg.Args[1])].ReportCount -= Convert.ToInt32(arg.Args[2]);
if (player != null) {
VKSendMessage(String.Format(lang.GetMessage("CONSOLE_REPORT_REMOVE", this), arg.Args[1], arg.Args[2], ReportInformation[ulong.Parse(arg.Args[1])].ReportCount));
}
PrintWarning("ACCESS");
return;
}
}
}
#endregion
#region FuncCommand
[ConsoleCommand("iqreport")]
void IQReportSystemCommands(ConsoleSystem.Arg arg) {
BasePlayer player = arg.Player();
string Key = arg.Args[0].ToLower();
switch (Key) {
case "page" : {
string PageAction = arg.Args[1];
bool Moderation = Convert.ToBoolean(arg.Args[2]);
int Page = Convert.ToInt32(arg.Args[3]);
switch (PageAction) {
case "next" : {
UI_Player_Loaded(player, Moderation, Page + 1);
break;
}
case "back" : {
UI_Player_Loaded(player, Moderation, Page - 1);
break;
}
}
break;
}
;
case "moderation_menu" : {
UI_PanelReportsPlayer(player, true);
break;
}
;
case "reports_menu" : {
// int BaseID = int.Parse(arg.Args[1]);
ulong UserID = ulong.Parse(arg.Args[1]);
// ... [Code preview truncated due to length. Full source in attached file] ...