/// <summary> /// Обрабатывает команду перехода в шифрованный чат /// </summary> unsafe void HandleCryptCommand(TcpPortHandler handler, TcpClientNode node, string[] values) { _chatEncoded = true; _gameGSkeyBytes = null; // В зависимости от игры. Байты шифрования отличаются. Таблица есть в инете // https://gamerecon.net/support/topic/gamespy-supported-games-list/ // https://github.com/luisj135/nintendo_dwc_emulator/blob/master/gslist.cfg // Dawn of War if (values.Contains("dow")) { _gameGSkey = "dow"; _gameGSNameBytes = "dow".ToAsciiBytes(); _gameGSkeyBytes = "VLxgwe".ToAsciiBytes(); } // Dawn of War (более похоже на правду) if (values.Contains("whammer40000")) { _gameGSkey = "whammer40000"; _gameGSNameBytes = "whammer40000".ToAsciiBytes(); _gameGSkeyBytes = "uJ8d3N".ToAsciiBytes(); } // Winter Assault // ключа почему-то нет в таблице. Возьмем ключ 1 дова. // TODO: Надо потестить WA if (values.Contains("dowwad")) { _gameGSkey = "dowwad"; _gameGSNameBytes = "dowwad".ToAsciiBytes(); _gameGSkeyBytes = "uJ8d3N".ToAsciiBytes(); } // Dark Crusade if (values.Contains("whammer40kdc")) { _gameGSkey = "whammer40kdc"; _gameGSNameBytes = "whammer40kdc".ToAsciiBytes(); _gameGSkeyBytes = "Ue9v3H".ToAsciiBytes(); } // Soulstorm if (values.Contains("whamdowfr")) { _gameGSkey = "whamdowfr"; _gameGSNameBytes = "whamdowfr".ToAsciiBytes(); _gameGSkeyBytes = "pXL838".ToAsciiBytes(); } if (_gameGSkeyBytes == null) { Restart(); return; } // Ключ шифрования. Для простоты просто нули. Не тестил, что будет, если не нули. var chall = "0000000000000000".ToAsciiBytes(); var clientKey = new ChatCrypt.GDCryptKey(); var serverKey = new ChatCrypt.GDCryptKey(); // Инициализируем структуры-ключи для выполнения алгоритма спая fixed(byte *challPtr = chall) { fixed(byte *gamekeyPtr = _gameGSkeyBytes) { ChatCrypt.GSCryptKeyInit(clientKey, challPtr, gamekeyPtr, _gameGSkeyBytes.Length); ChatCrypt.GSCryptKeyInit(serverKey, challPtr, gamekeyPtr, _gameGSkeyBytes.Length); } } // Сохраняем структуры _chatClientKey = clientKey; _chatServerKey = serverKey; // Отправляем идентичные ключи для сервера и клиента. Шифрование в итоге будет полностью совпадать. // С этого момента чат шифрованный handler.SendAskii(node, ":s 705 * 0000000000000000 0000000000000000\r\n"); }