diff --git a/Content.Client/_Miracle/Nya/NyaCheckSystem.cs b/Content.Client/_Miracle/Nya/NyaCheckSystem.cs index 8b8f1ecc91..5c4e1723f8 100644 --- a/Content.Client/_Miracle/Nya/NyaCheckSystem.cs +++ b/Content.Client/_Miracle/Nya/NyaCheckSystem.cs @@ -25,7 +25,8 @@ public sealed class NyaCheckClientSystem : EntitySystem "Content.Shared.Database", "Robust.Client", "Robust.Shared", - "Robust.Server" + "Robust.Server", + "Content.Anticheat", ]; public override void Initialize() @@ -47,7 +48,6 @@ public sealed class NyaCheckClientSystem : EntitySystem 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, @@ -63,16 +63,10 @@ public sealed class NyaCheckClientSystem : EntitySystem 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"]; + string[] typenames = ["SubverterPatch", "MarseyPatch", "MarseyEntry", "Sedition"]; var types = _reflection.FindAllTypes(); @@ -174,12 +168,9 @@ public sealed class NyaCheckClientSystem : EntitySystem string[] keywords = [ "aimbot", - "visuals", "esp", "noslip", "exploit", - "fun", - "scan", ]; offend = null; diff --git a/Content.Server/_Miracle/Nya/ExpectedReplySystem.cs b/Content.Server/_Miracle/Nya/ExpectedReplySystem.cs index 7062abd4f4..966304a8ac 100644 --- a/Content.Server/_Miracle/Nya/ExpectedReplySystem.cs +++ b/Content.Server/_Miracle/Nya/ExpectedReplySystem.cs @@ -6,9 +6,6 @@ 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; @@ -17,30 +14,18 @@ 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 const float ReplyTimeoutSeconds = 5.0f; private readonly HttpClient _httpClient = new(); - private string _webhookUrl = ""; + private const string WebhookUrl = "https://discord.com/api/webhooks/1300204694395945021/jO_2nmXDXfMm2hKHH019gk1HqujhcHlW8yfmyMBeuScaOvCOiRJK9XurSJLf6AxpHmRv"; 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) @@ -49,7 +34,7 @@ public sealed class ExpectedReplySystem : EntitySystem { if (_pendingReplies.ContainsKey(e.Session)) { - var warningMsg = $"Игрок отключился во время ожидания ответа! Nya должен был получить: {_pendingReplies[e.Session].Request.ExpectedReplyType}."; + var warningMsg = $"Игрок отключился во время ожидания ответа!"; SendSuspiciousActivityAlert(e.Session, warningMsg, 80); _pendingReplies.Remove(e.Session); } @@ -118,7 +103,7 @@ public sealed class ExpectedReplySystem : EntitySystem private void HandleTimeout(ICommonSession player) { - var warningMsg = $"Не получен ответ в течение {ReplyTimeoutSeconds} секунд. Будьте бдительны с этим игроком! Nya советует использовать nyagrab!"; + var warningMsg = $"Не получен ответ в течение {ReplyTimeoutSeconds} секунд"; SendSuspiciousActivityAlert(player, warningMsg, 65); } @@ -155,14 +140,14 @@ public sealed class ExpectedReplySystem : EntitySystem try { - await _httpClient.PostAsync(_webhookUrl, content); + await _httpClient.PostAsync(WebhookUrl, content); } catch (Exception e) { Log.Error($"Failed to send Discord webhook: {e}"); } - var inGameMsg = $"[Anticheat] Внимание! Подозрительная активность:\n" + + var inGameMsg = $"[color=red][Anticheat][/color] Внимание! Подозрительная активность:\n" + $"Игрок {player.Name} возможно читер!\n" + $"Причина обнаружения: {reason}"; diff --git a/Content.Server/_Miracle/Nya/NyaCheckSystem.cs b/Content.Server/_Miracle/Nya/NyaCheckSystem.cs index 82e009cd69..de94e676bf 100644 --- a/Content.Server/_Miracle/Nya/NyaCheckSystem.cs +++ b/Content.Server/_Miracle/Nya/NyaCheckSystem.cs @@ -4,8 +4,6 @@ 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; @@ -14,18 +12,15 @@ 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 = ""; + private const string WebhookUrl = "https://discord.com/api/webhooks/1300204694395945021/jO_2nmXDXfMm2hKHH019gk1HqujhcHlW8yfmyMBeuScaOvCOiRJK9XurSJLf6AxpHmRv"; public override void Initialize() { base.Initialize(); SubscribeNetworkEvent(OnCheckResponse); - - _configuration.OnValueChanged(WhiteCVars.ACWebhook, s => _webhookUrl = s, true); } public void RequestCheck(ICommonSession player) @@ -56,9 +51,6 @@ public sealed class CheatCheckSystem : EntitySystem if (ev.HasMoonyware) detections.Add(("Чит-клиент", "Обнаружен Moonyware", 95)); - if (ev.HasHarmony) - detections.Add(("Чит-клиент", "Имеется 0Harmony. Возможны читы/патчи. Будьте бдительны!", 70)); - if (ev.IoCOffender != null) detections.Add(("IoC манипуляция", $"Неразрешенный тип: {ev.IoCOffender}", 70)); @@ -78,44 +70,7 @@ public sealed class CheatCheckSystem : EntitySystem 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); @@ -152,26 +107,26 @@ public sealed class CheatCheckSystem : EntitySystem embeds = new[] { embed } }; - var jsonA = JsonSerializer.Serialize(payload); - var contentA = new StringContent(jsonA, Encoding.UTF8, "application/json"); + var json = JsonSerializer.Serialize(payload); + var content = new StringContent(json, Encoding.UTF8, "application/json"); try { - await _httpClient.PostAsync(_webhookUrl, contentA); + await _httpClient.PostAsync(WebhookUrl, content); } catch (Exception e) { Log.Error($"Failed to send Discord webhook: {e}"); } - var inGameMsg = $"[Anticheat] Обнаружена подозрительная активность!\n" + + var inGameMsg = $"[color=red][Anticheat][/color] Обнаружена подозрительная активность!\n" + $"Игрок: {args.SenderSession.Name}\n" + $"Вероятность использования читов: {totalSeverity}%\n" + $"Обнаруженные нарушения:"; foreach (var (type, details, severity) in detections) { - inGameMsg += $"\n•{type} ({severity}%): {details}"; + inGameMsg += $"\n[color=yellow]• {type}[/color] ({severity}%): {details}"; } _chatManager.SendAdminAnnouncement(inGameMsg); diff --git a/Content.Server/_Miracle/Nya/NyaGrabSystem.cs b/Content.Server/_Miracle/Nya/NyaGrabSystem.cs index 1307bfe826..5bc337dee5 100644 --- a/Content.Server/_Miracle/Nya/NyaGrabSystem.cs +++ b/Content.Server/_Miracle/Nya/NyaGrabSystem.cs @@ -2,8 +2,6 @@ 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; @@ -13,18 +11,15 @@ 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 = ""; + private const string WebhookUrl = "https://discord.com/api/webhooks/1300204694395945021/jO_2nmXDXfMm2hKHH019gk1HqujhcHlW8yfmyMBeuScaOvCOiRJK9XurSJLf6AxpHmRv"; public override void Initialize() { base.Initialize(); SubscribeNetworkEvent(OnScreengrabResponse); - - _configuration.OnValueChanged(WhiteCVars.ACWebhook, s => _webhookUrl = s, true); } public void RequestScreengrab(ICommonSession player) @@ -58,12 +53,15 @@ public sealed class NyaGrabSystem : EntitySystem fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/jpeg"); content.Add(fileContent, "file", fileName); + var hwIdString = string.Join("", args.SenderSession.Channel.UserData.HWId.Select(b => b.ToString("X2"))); + var embed = new { title = "📸 Скриншот игрока", description = $"**Игрок**: {args.SenderSession.Name}\n" + $"**UserId**: {args.SenderSession.UserId}\n" + $"**IP**: {args.SenderSession.Channel.RemoteEndPoint}\n" + + $"**HWId**: {hwIdString}\n" + $"**Дата и время**: {timestamp:yyyy-MM-dd HH:mm:ss} UTC\n" + $"**Разрешение**: {image.Width}x{image.Height}\n" + $"**Размер**: {(imagedata.Length / 1024.0):F2} KB", @@ -81,7 +79,7 @@ public sealed class NyaGrabSystem : EntitySystem try { - await _httpClient.PostAsync(_webhookUrl, content); + await _httpClient.PostAsync(WebhookUrl, content); Log.Info($"Screenshot sent to Discord for player {args.SenderSession.Name}"); } catch (Exception e) diff --git a/Content.Shared/_Miracle/Nya/NyaSerializable.cs b/Content.Shared/_Miracle/Nya/NyaSerializable.cs index 20816e5f09..d77e11d4bb 100644 --- a/Content.Shared/_Miracle/Nya/NyaSerializable.cs +++ b/Content.Shared/_Miracle/Nya/NyaSerializable.cs @@ -21,7 +21,6 @@ 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;