From 91d34b41356abde1342b088f45d9e4233ee0ff26 Mon Sep 17 00:00:00 2001 From: BIGZi0348 Date: Fri, 10 Jan 2025 19:42:25 +0300 Subject: [PATCH] amogus --- Content.Client/_Miracle/Nya/NyaCheckSystem.cs | 256 ------------------ Content.Client/_Miracle/Nya/NyaGrabSystem.cs | 38 --- Content.Server/_Miracle/Nya/Commands.cs | 82 ------ .../_Miracle/Nya/ExpectedReplySystem.cs | 178 ------------ Content.Server/_Miracle/Nya/NyaCheckSystem.cs | 179 ------------ Content.Server/_Miracle/Nya/NyaGrabSystem.cs | 92 ------- Content.Server/_Miracle/Nya/PendingReply.cs | 13 - .../_Miracle/Nya/NyaSerializable.cs | 45 --- Content.Shared/_White/WhiteCVars.cs | 3 - 9 files changed, 886 deletions(-) delete mode 100644 Content.Client/_Miracle/Nya/NyaCheckSystem.cs delete mode 100644 Content.Client/_Miracle/Nya/NyaGrabSystem.cs delete mode 100644 Content.Server/_Miracle/Nya/Commands.cs delete mode 100644 Content.Server/_Miracle/Nya/ExpectedReplySystem.cs delete mode 100644 Content.Server/_Miracle/Nya/NyaCheckSystem.cs delete mode 100644 Content.Server/_Miracle/Nya/NyaGrabSystem.cs delete mode 100644 Content.Server/_Miracle/Nya/PendingReply.cs delete mode 100644 Content.Shared/_Miracle/Nya/NyaSerializable.cs diff --git a/Content.Client/_Miracle/Nya/NyaCheckSystem.cs b/Content.Client/_Miracle/Nya/NyaCheckSystem.cs deleted file mode 100644 index 8b8f1ecc91..0000000000 --- a/Content.Client/_Miracle/Nya/NyaCheckSystem.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Content.Shared._Miracle.Nya; -using Robust.Client.Player; -using Robust.Client.UserInterface; -using Robust.Shared.Configuration; -using Robust.Shared.Reflection; - -namespace Content.Client._Miracle.Nya; - -public sealed class NyaCheckClientSystem : EntitySystem -{ - [Dependency] private readonly IReflectionManager _reflection = default!; - [Dependency] private readonly IConfigurationManager _configuration = default!; - [Dependency] private readonly IEntitySystemManager _esm = default!; - [Dependency] private readonly IPlayerManager _player = default!; - [Dependency] private readonly IUserInterfaceManager _ui = default!; - - [ViewVariables(VVAccess.ReadOnly)] - private readonly string[] _allowed = - [ - "Content.Client", - "Content.Shared", - "Content.Server", - "Content.Shared.Database", - "Robust.Client", - "Robust.Shared", - "Robust.Server" - ]; - - public override void Initialize() - { - base.Initialize(); - SubscribeNetworkEvent(OnCheckRequest); - } - - private void OnCheckRequest(CheatCheckRequestEvent ev) - { - var response = RunChecks(); - RaiseNetworkEvent(response); - } - - private CheatCheckResponseEvent RunChecks() - { - return new CheatCheckResponseEvent - { - HasPatchMetadata = FoundPatchMetadataTypes(), - ReflectionOffender = FoundExtraTypesIReflection(out var reflectionOffender) ? reflectionOffender : null, - HasMoonyware = FoundMoonywareModuleReflection(), - HasHarmony = CheckForHarmony(), - IoCOffender = TypesNotFromContentIoC(out var iocOffender) ? iocOffender : null, - ExtraModuleOffender = CheckExtraModule(out var moduleOffender) ? moduleOffender : null, - CvarOffender = CheckCommonCheatCvars(out var cvarOffender) ? cvarOffender : null, - SystemOffender = FoundTypesEntitySystemManager(out var systemOffender) ? systemOffender : null, - ComponentOffender = CheckComponents(out var componentOffender) ? componentOffender : null, - WindowOffender = CheckExtraWindows(out var windowOffender) ? windowOffender : null - }; - } - - private bool FoundPatchMetadataTypes() - { - var found = Type.GetType("MarseyPatch") ?? Type.GetType("SubverterPatch"); - return found is not null; - } - - private bool CheckForHarmony() - { - var harmonyType = Type.GetType("HarmonyLib.Harmony, 0Harmony"); - return harmonyType != null; - } - - private bool FoundExtraTypesIReflection([NotNullWhen(true)] out string? offender) - { - offender = null; - string[] typenames = ["SubverterPatch", "MarseyPatch", "MarseyEntry", "Sedition", "Ware"]; - - var types = _reflection.FindAllTypes(); - - foreach (var type in types) - { - foreach (var name in typenames) - { - if (!type.Name.Contains(name)) - continue; - - offender = type.Name; - return true; - } - } - - return false; - } - - private bool FoundMoonywareModuleReflection() - { - var modules = _reflection.Assemblies; - - foreach (var asm in modules) - { - if (asm.FullName!.Contains("Moonyware")) - return true; - } - - return false; - } - - private bool FoundTypesEntitySystemManager([NotNullWhen(true)] out string? offend) - { - offend = null; - - var types = _esm.GetEntitySystemTypes(); - - foreach (var type in types) - { - if (!NotFromGameModule(type)) - continue; - - offend = type.FullName!; - return true; - } - - return false; - } - - private bool TypesNotFromContentIoC([NotNullWhen(true)] out string? offend) - { - offend = null; - - var types = IoCManager.Instance!.GetRegisteredTypes(); - - foreach (var type in types) - { - if (!NotFromGameModule(type)) - continue; - - offend = type.FullName!; - return true; - } - - return false; - } - - private bool CheckExtraModule([NotNullWhen(true)] out string? offend) - { - offend = null; - - var modules = _reflection.Assemblies; - - foreach (var module in modules) - { - var allowed = false; - - foreach (var allow in _allowed) - { - if (module.FullName!.Contains(allow)) - { - allowed = true; - break; - } - } - - if (allowed) - continue; - - offend = module.FullName!; - return true; - } - - return false; - } - - private bool CheckCommonCheatCvars([NotNullWhen(true)] out string? offend) - { - string[] keywords = - [ - "aimbot", - "visuals", - "esp", - "noslip", - "exploit", - "fun", - "scan", - ]; - - offend = null; - - var cvars = _configuration.GetRegisteredCVars(); - - foreach (var cvar in cvars) - { - if (!keywords.Any(kw => cvar.Contains(kw, StringComparison.CurrentCultureIgnoreCase))) - continue; - - offend = cvar; - return true; - } - - return false; - } - - private bool CheckComponents([NotNullWhen(true)] out string? offend) - { - offend = null; - - if (_player.LocalEntity is null) - return false; - - var comps = AllComps(_player.LocalEntity.Value); - - foreach (var comp in comps) - { - var type = comp.GetType(); - - if (!NotFromGameModule(type)) - continue; - - offend = type.FullName!; - return true; - } - - return false; - } - - private bool CheckExtraWindows([NotNullWhen(true)] out string? offend) - { - offend = null; - - var children = _ui.WindowRoot.Children; - - foreach (var child in children) - { - var type = child.GetType(); - - if (!NotFromGameModule(type)) - continue; - - offend = type.FullName!; - return true; - } - - return false; - } - - private bool NotFromGameModule(Type type) - { - var name = type.FullName; - - foreach (var allow in _allowed) - { - if (name!.Contains(allow)) - return false; - } - - return true; - } -} diff --git a/Content.Client/_Miracle/Nya/NyaGrabSystem.cs b/Content.Client/_Miracle/Nya/NyaGrabSystem.cs deleted file mode 100644 index 836b355ee7..0000000000 --- a/Content.Client/_Miracle/Nya/NyaGrabSystem.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.IO; -using Content.Shared._Miracle.Nya; -using Robust.Client.Graphics; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.PixelFormats; - -namespace Content.Client._Miracle.Nya; - -public sealed class NyaGrabSystem : EntitySystem -{ - [Dependency] private readonly IClyde _clyde = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeNetworkEvent(OnScreengrabRequest); - } - - private async void OnScreengrabRequest(ScreengrabRequestEvent ev) - { - var image = await _clyde.ScreenshotAsync(ScreenshotType.Final); - var array = ImageToByteArray(image); - - if (array.Length > 1_500_000) - return; - - var msg = new ScreengrabResponseEvent { Screengrab = array }; - RaiseNetworkEvent(msg); - } - - private byte[] ImageToByteArray(Image image) - { - using var stream = new MemoryStream(); - image.SaveAsJpeg(stream); - return stream.ToArray(); - } -} diff --git a/Content.Server/_Miracle/Nya/Commands.cs b/Content.Server/_Miracle/Nya/Commands.cs deleted file mode 100644 index e3d317e9c7..0000000000 --- a/Content.Server/_Miracle/Nya/Commands.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System.Linq; -using Content.Server.Administration; -using Content.Shared.Administration; -using Robust.Server.Player; -using Robust.Shared.Console; - -namespace Content.Server._Miracle.Nya; - -[AdminCommand(AdminFlags.Admin)] -public sealed class ScreenGrabCommand : IConsoleCommand -{ - [Dependency] private readonly IPlayerManager _players = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; - - public string Command => "nyagrab"; - public string Description => "nyagrab!!"; - public string Help => "nyagrab player"; - - public void Execute(IConsoleShell shell, string argStr, string[] args) - { - var sys = _entityManager.EntitySysManager.GetEntitySystem(); - if (args.Length < 1) - { - var player = shell.Player; - var toKickPlayer = player ?? _players.Sessions.FirstOrDefault(); - if (toKickPlayer == null) - { - shell.WriteLine("You need to provide a player to nyagrab."); - return; - } - - shell.WriteLine( - $"You need to provide a player to nyagrab. Try running 'nyagrab {toKickPlayer.Name}' as an example."); - return; - } - - var name = args[0]; - - if (_players.TryGetSessionByUsername(name, out var target)) - { - sys.RequestScreengrab(target); - } - } -} - -[AdminCommand(AdminFlags.Admin)] -public sealed class NyaCheckCommand : IConsoleCommand -{ - [Dependency] private readonly IPlayerManager _players = default!; - [Dependency] private readonly IEntityManager _entityManager = default!; - - public string Command => "nyacheck"; - public string Description => "nyacheck!!"; - public string Help => "nyacheck player"; - - public void Execute(IConsoleShell shell, string argStr, string[] args) - { - var sys = _entityManager.EntitySysManager.GetEntitySystem(); - - if (args.Length < 1) - { - var player = shell.Player; - var toKickPlayer = player ?? _players.Sessions.FirstOrDefault(); - if (toKickPlayer == null) - { - shell.WriteLine("You need to provide a player to nyacheck."); - return; - } - - shell.WriteLine( - $"You need to provide a player to nyacheck. Try running 'nyacheck {toKickPlayer.Name}' as an example."); - return; - } - - var name = args[0]; - - if (_players.TryGetSessionByUsername(name, out var target)) - { - sys.RequestCheck(target); - } - } -} diff --git a/Content.Server/_Miracle/Nya/ExpectedReplySystem.cs b/Content.Server/_Miracle/Nya/ExpectedReplySystem.cs deleted file mode 100644 index 7062abd4f4..0000000000 --- a/Content.Server/_Miracle/Nya/ExpectedReplySystem.cs +++ /dev/null @@ -1,178 +0,0 @@ -using Content.Server.Chat.Managers; -using Robust.Shared.Player; -using Content.Shared._Miracle.Nya; -using Robust.Shared.Enums; -using Robust.Shared.Timing; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using Content.Server.GameTicking; -using Content.Shared._White; -using Robust.Shared.Configuration; - -namespace Content.Server._Miracle.Nya; - -public sealed class ExpectedReplySystem : EntitySystem -{ - [Dependency] private readonly ISharedPlayerManager _playMan = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly IChatManager _chatManager = default!; - [Dependency] private readonly IConfigurationManager _configuration = default!; - [Dependency] private readonly CheatCheckSystem _cheatCheckSystem = default!; - - private readonly Dictionary _pendingReplies = new(); - - private const float ReplyTimeoutSeconds = 6.0f; - private readonly HttpClient _httpClient = new(); - - private string _webhookUrl = ""; - - public override void Initialize() - { - base.Initialize(); - - _playMan.PlayerStatusChanged += OnPlayerStatusChanged; - - SubscribeLocalEvent(OnPlayerJoinedLobby); - - _configuration.OnValueChanged(WhiteCVars.ACWebhook, s => _webhookUrl = s, true); - } - - private void OnPlayerJoinedLobby(PlayerJoinedLobbyEvent ev) - { - _cheatCheckSystem.RequestCheck(ev.PlayerSession); - } - - private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e) - { - if (e is { OldStatus: SessionStatus.InGame, NewStatus: SessionStatus.Disconnected }) - { - if (_pendingReplies.ContainsKey(e.Session)) - { - var warningMsg = $"Игрок отключился во время ожидания ответа! Nya должен был получить: {_pendingReplies[e.Session].Request.ExpectedReplyType}."; - SendSuspiciousActivityAlert(e.Session, warningMsg, 80); - _pendingReplies.Remove(e.Session); - } - } - } - - public void ExpectReply( - ICommonSession player, - TRequest request, - Action handler) - where TRequest : ExpectedReplyEntityEventArgs - where TResponse : EntityEventArgs - { - var timeout = _timing.CurTime + TimeSpan.FromSeconds(ReplyTimeoutSeconds); - - void WrapHandler(EntityEventArgs ev, EntitySessionEventArgs args) - { - if (ev is TResponse response) - handler(response, args); - } - - _pendingReplies[player] = new PendingReply(request, timeout, WrapHandler); - RaiseNetworkEvent(request, player.Channel); - } - - public bool HandleReply(EntityEventArgs ev, EntitySessionEventArgs args) - { - if (!_pendingReplies.TryGetValue(args.SenderSession, out var pending)) - { - var warningMsg = "Получен неожиданный ответ без запроса"; - SendSuspiciousActivityAlert(args.SenderSession, warningMsg, 70); - return false; - } - - if (pending.Request.ExpectedReplyType != ev.GetType()) - { - var warningMsg = $"Получен ответ неверного типа. Ожидался {pending.Request.ExpectedReplyType}, получен {ev.GetType()}"; - SendSuspiciousActivityAlert(args.SenderSession, warningMsg, 75); - return false; - } - - pending.Handler(ev, args); - _pendingReplies.Remove(args.SenderSession); - return true; - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - var currentTime = _timing.CurTime; - var timeoutPlayers = new List(); - - foreach (var (player, pending) in _pendingReplies) - { - if (currentTime > pending.TimeoutTime) - timeoutPlayers.Add(player); - } - - foreach (var player in timeoutPlayers) - { - HandleTimeout(player); - _pendingReplies.Remove(player); - } - } - - private void HandleTimeout(ICommonSession player) - { - var warningMsg = $"Не получен ответ в течение {ReplyTimeoutSeconds} секунд. Будьте бдительны с этим игроком! Nya советует использовать nyagrab!"; - SendSuspiciousActivityAlert(player, warningMsg, 65); - } - - private async void SendSuspiciousActivityAlert(ICommonSession player, string reason, int severity) - { - var color = severity switch - { - >= 80 => 0xFF0000, // Красный - >= 70 => 0xFFA500, // Оранжевый - _ => 0xFFFF00 // Желтый - }; - - var warningMsg = $"⚠️ **Система ожидаемых ответов обнаружила подозрительную активность!**\n\n" + - $"**Игрок:** {player.Name}\n" + - $"**IP:** {player.Channel.RemoteEndPoint}\n" + - $"**Уровень подозрительности:** {severity}%\n" + - $"**Причина:** {reason}"; - - var embed = new - { - title = "⚠️ Подозрительная активность!", - description = warningMsg, - color = color, - timestamp = DateTime.UtcNow.ToString("o") - }; - - var payload = new - { - embeds = new[] { embed } - }; - - var json = JsonSerializer.Serialize(payload); - var content = new StringContent(json, Encoding.UTF8, "application/json"); - - try - { - await _httpClient.PostAsync(_webhookUrl, content); - } - catch (Exception e) - { - Log.Error($"Failed to send Discord webhook: {e}"); - } - - var inGameMsg = $"[Anticheat] Внимание! Подозрительная активность:\n" + - $"Игрок {player.Name} возможно читер!\n" + - $"Причина обнаружения: {reason}"; - - _chatManager.SendAdminAnnouncement(inGameMsg); - } - - public override void Shutdown() - { - base.Shutdown(); - _playMan.PlayerStatusChanged -= OnPlayerStatusChanged; - _pendingReplies.Clear(); - } -} diff --git a/Content.Server/_Miracle/Nya/NyaCheckSystem.cs b/Content.Server/_Miracle/Nya/NyaCheckSystem.cs deleted file mode 100644 index 82e009cd69..0000000000 --- a/Content.Server/_Miracle/Nya/NyaCheckSystem.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System.Linq; -using System.Net.Http; -using System.Text; -using System.Text.Json; -using Content.Server.Chat.Managers; -using Content.Shared._Miracle.Nya; -using Content.Shared._White; -using Robust.Shared.Configuration; -using Robust.Shared.Player; - -namespace Content.Server._Miracle.Nya; - -public sealed class CheatCheckSystem : EntitySystem -{ - [Dependency] private readonly ExpectedReplySystem _expectedReply = default!; - [Dependency] private readonly IChatManager _chatManager = default!; - [Dependency] private readonly IConfigurationManager _configuration = default!; - - private readonly HttpClient _httpClient = new(); - - private string _webhookUrl = ""; - - public override void Initialize() - { - base.Initialize(); - SubscribeNetworkEvent(OnCheckResponse); - - _configuration.OnValueChanged(WhiteCVars.ACWebhook, s => _webhookUrl = s, true); - } - - public void RequestCheck(ICommonSession player) - { - _expectedReply.ExpectReply( - player, - new CheatCheckRequestEvent(), - ProcessCheckResponse - ); - } - - private void OnCheckResponse(CheatCheckResponseEvent ev, EntitySessionEventArgs args) - { - if (!_expectedReply.HandleReply(ev, args)) - return; - } - - private async void ProcessCheckResponse(CheatCheckResponseEvent ev, EntitySessionEventArgs args) - { - var detections = new List<(string Type, string Details, int Severity)>(); - - if (ev.HasPatchMetadata) - detections.Add(("Инъекция кода", "Обнаружены метаданные патча", 90)); - - if (ev.ReflectionOffender != null) - detections.Add(("Рефлексия", $"Найден подозрительный тип: {ev.ReflectionOffender}", 80)); - - if (ev.HasMoonyware) - detections.Add(("Чит-клиент", "Обнаружен Moonyware", 95)); - - if (ev.HasHarmony) - detections.Add(("Чит-клиент", "Имеется 0Harmony. Возможны читы/патчи. Будьте бдительны!", 70)); - - if (ev.IoCOffender != null) - detections.Add(("IoC манипуляция", $"Неразрешенный тип: {ev.IoCOffender}", 70)); - - if (ev.ExtraModuleOffender != null) - detections.Add(("Внешний модуль", $"Неразрешенный модуль: {ev.ExtraModuleOffender}", 85)); - - if (ev.CvarOffender != null) - detections.Add(("Подозрительный CVar", $"Найден чит-квар: {ev.CvarOffender}", 60)); - - if (ev.SystemOffender != null) - detections.Add(("Системное вмешательство", $"Неразрешенная система: {ev.SystemOffender}", 75)); - - if (ev.ComponentOffender != null) - detections.Add(("Компонентное вмешательство", $"Неразрешенный компонент: {ev.ComponentOffender}", 75)); - - if (ev.WindowOffender != null) - detections.Add(("UI вмешательство", $"Неразрешенное окно: {ev.WindowOffender}", 65)); - - if (detections.Count == 0) - { - var cleanMsg = $"✅ **Античит завершил проверку**\n\n" + - $"**Игрок:** {args.SenderSession.Name}\n" + - $"**IP:** {args.SenderSession.Channel.RemoteEndPoint}\n" + - $"**Результат:** Нарушений не выявлено"; - - var cleanEmbed = new - { - title = "✅ Проверка завершена", - description = cleanMsg, - color = 0x00FF00, // Зеленый - timestamp = DateTime.UtcNow.ToString("o") - }; - - var cleanPayload = new - { - embeds = new[] { cleanEmbed } - }; - - var json = JsonSerializer.Serialize(cleanPayload); - var content = new StringContent(json, Encoding.UTF8, "application/json"); - - try - { - await _httpClient.PostAsync(_webhookUrl, content); - } - catch (Exception e) - { - Log.Error($"Failed to send Discord webhook: {e}"); - } - - var cleanInGameMsg = $"[Anticheat] Проверка завершена\n" + - $"Игрок: {args.SenderSession.Name}\n" + - $"Результат: Нарушений не выявлено"; - - _chatManager.SendAdminAnnouncement(cleanInGameMsg); - return; - } - - var maxSeverity = detections.Max(d => d.Severity); - var avgSeverity = detections.Average(d => d.Severity); - var totalSeverity = (int)((maxSeverity * 0.7) + (avgSeverity * 0.3)); - - var warningMsg = $"🚨 **Античит обнаружил подозрительную активность!**\n\n" + - $"**Игрок:** {args.SenderSession.Name}\n" + - $"**IP:** {args.SenderSession.Channel.RemoteEndPoint}\n" + - $"**Вероятность использования читов:** {totalSeverity}%\n\n" + - $"**Обнаруженные нарушения:**\n"; - - foreach (var (type, details, severity) in detections) - { - warningMsg += $"• **{type}** ({severity}%): {details}\n"; - } - - var color = totalSeverity switch - { - >= 90 => 0xFF0000, // Красный - >= 70 => 0xFFA500, // Оранжевый - _ => 0xFFFF00 // Желтый - }; - - var embed = new - { - title = "🚫 Обнаружен читер!", - description = warningMsg, - color = color, - timestamp = DateTime.UtcNow.ToString("o") - }; - - var payload = new - { - embeds = new[] { embed } - }; - - var jsonA = JsonSerializer.Serialize(payload); - var contentA = new StringContent(jsonA, Encoding.UTF8, "application/json"); - - try - { - await _httpClient.PostAsync(_webhookUrl, contentA); - } - catch (Exception e) - { - Log.Error($"Failed to send Discord webhook: {e}"); - } - - var inGameMsg = $"[Anticheat] Обнаружена подозрительная активность!\n" + - $"Игрок: {args.SenderSession.Name}\n" + - $"Вероятность использования читов: {totalSeverity}%\n" + - $"Обнаруженные нарушения:"; - - foreach (var (type, details, severity) in detections) - { - inGameMsg += $"\n•{type} ({severity}%): {details}"; - } - - _chatManager.SendAdminAnnouncement(inGameMsg); - } -} diff --git a/Content.Server/_Miracle/Nya/NyaGrabSystem.cs b/Content.Server/_Miracle/Nya/NyaGrabSystem.cs deleted file mode 100644 index 1307bfe826..0000000000 --- a/Content.Server/_Miracle/Nya/NyaGrabSystem.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Linq; -using System.Net.Http; -using System.Text.Json; -using Content.Shared._Miracle.Nya; -using Content.Shared._White; -using Robust.Shared.Configuration; -using Robust.Shared.Player; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.PixelFormats; - -namespace Content.Server._Miracle.Nya; - -public sealed class NyaGrabSystem : EntitySystem -{ - [Dependency] private readonly ExpectedReplySystem _expectedReply = default!; - [Dependency] private readonly IConfigurationManager _configuration = default!; - - private readonly HttpClient _httpClient = new(); - - private string _webhookUrl = ""; - - public override void Initialize() - { - base.Initialize(); - SubscribeNetworkEvent(OnScreengrabResponse); - - _configuration.OnValueChanged(WhiteCVars.ACWebhook, s => _webhookUrl = s, true); - } - - public void RequestScreengrab(ICommonSession player) - { - _expectedReply.ExpectReply( - player, - new ScreengrabRequestEvent(), - OnScreengrabReply - ); - } - - private void OnScreengrabResponse(ScreengrabResponseEvent ev, EntitySessionEventArgs args) - { - if (!_expectedReply.HandleReply(ev, args)) - return; - } - - private async void OnScreengrabReply(ScreengrabResponseEvent ev, EntitySessionEventArgs args) - { - if (ev.Screengrab.Length == 0) - return; - - var timestamp = DateTime.UtcNow; - var imagedata = ev.Screengrab; - using var image = Image.Load(imagedata); - - var content = new MultipartFormDataContent(); - - var fileName = $"screengrab_{args.SenderSession.UserId}_{timestamp:yyyy-MM-dd_HH-mm-ss}.jpg"; - var fileContent = new ByteArrayContent(imagedata); - fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg"); - content.Add(fileContent, "file", fileName); - - var embed = new - { - title = "📸 Скриншот игрока", - description = $"**Игрок**: {args.SenderSession.Name}\n" + - $"**UserId**: {args.SenderSession.UserId}\n" + - $"**IP**: {args.SenderSession.Channel.RemoteEndPoint}\n" + - $"**Дата и время**: {timestamp:yyyy-MM-dd HH:mm:ss} UTC\n" + - $"**Разрешение**: {image.Width}x{image.Height}\n" + - $"**Размер**: {(imagedata.Length / 1024.0):F2} KB", - color = 0x00FF00, - timestamp = timestamp.ToString("o") - }; - - var payload = new - { - embeds = new[] { embed } - }; - - var jsonContent = JsonSerializer.Serialize(payload); - content.Add(new StringContent(jsonContent), "payload_json"); - - try - { - await _httpClient.PostAsync(_webhookUrl, content); - Log.Info($"Screenshot sent to Discord for player {args.SenderSession.Name}"); - } - catch (Exception e) - { - Log.Error($"Failed to send screenshot to Discord: {e}"); - } - } -} diff --git a/Content.Server/_Miracle/Nya/PendingReply.cs b/Content.Server/_Miracle/Nya/PendingReply.cs deleted file mode 100644 index 7ed69ad3f0..0000000000 --- a/Content.Server/_Miracle/Nya/PendingReply.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Content.Shared._Miracle.Nya; - -namespace Content.Server._Miracle.Nya; - -public sealed class PendingReply( - ExpectedReplyEntityEventArgs request, - TimeSpan timeout, - Action handler) -{ - public ExpectedReplyEntityEventArgs Request { get; } = request; - public TimeSpan TimeoutTime { get; } = timeout; - public Action Handler { get; } = handler; -} diff --git a/Content.Shared/_Miracle/Nya/NyaSerializable.cs b/Content.Shared/_Miracle/Nya/NyaSerializable.cs deleted file mode 100644 index 20816e5f09..0000000000 --- a/Content.Shared/_Miracle/Nya/NyaSerializable.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Robust.Shared.Serialization; - -namespace Content.Shared._Miracle.Nya; - -[Serializable, NetSerializable] -public sealed class ScreengrabResponseEvent : EntityEventArgs -{ - public byte[] Screengrab = new byte[1500000]; // Limit screengrab size to 1.5mbs -} - -[Serializable, NetSerializable] -public sealed class ScreengrabRequestEvent : ExpectedReplyEntityEventArgs -{ - [field: NonSerialized] - public override Type ExpectedReplyType { get; } = typeof(ScreengrabResponseEvent); -} - -[Serializable, NetSerializable] -public sealed class CheatCheckResponseEvent : EntityEventArgs -{ - public bool HasPatchMetadata; - public string? ReflectionOffender; - public bool HasMoonyware; - public bool HasHarmony; - public string? IoCOffender; - public string? ExtraModuleOffender; - public string? CvarOffender; - public string? SystemOffender; - public string? ComponentOffender; - public string? WindowOffender; -} - -[Serializable, NetSerializable] -public sealed class CheatCheckRequestEvent : ExpectedReplyEntityEventArgs -{ - [field: NonSerialized] - public override Type ExpectedReplyType { get; } = typeof(CheatCheckResponseEvent); -} - -[Serializable, NetSerializable] -public abstract class ExpectedReplyEntityEventArgs : EntityEventArgs -{ - [field: NonSerialized] - public abstract Type ExpectedReplyType { get; } -} diff --git a/Content.Shared/_White/WhiteCVars.cs b/Content.Shared/_White/WhiteCVars.cs index 842b5524d2..a37567be6b 100644 --- a/Content.Shared/_White/WhiteCVars.cs +++ b/Content.Shared/_White/WhiteCVars.cs @@ -420,7 +420,4 @@ public sealed class WhiteCVars public static readonly CVarDef ItemToArtifactRatio = CVarDef.Create("white.random_artifacts_ratio", 0.5f, CVar.SERVERONLY); - public static readonly CVarDef ACWebhook = - CVarDef.Create("ac.webhook", "", CVar.SERVERONLY); - }