コード例 #1
0
        /// <summary>
        /// Обрабатывает новое сообщение, полученное по TCP чата
        /// </summary>
        unsafe void OnChatReceived(TcpPortHandler handler, TcpClientNode node, byte[] buffer, int count)
        {
            // Дешифруем строку, если чат шифрованный
            if (_chatEncoded)
            {
                byte *bytesPtr = stackalloc byte[count];

                for (int i = 0; i < count; i++)
                {
                    bytesPtr[i] = buffer[i];
                }

                ChatCrypt.GSEncodeDecode(_chatClientKey, bytesPtr, count);

                for (int i = 0; i < count; i++)
                {
                    buffer[i] = bytesPtr[i];
                }
            }

            var str = buffer.ToUtf8(count);

            LogTrace(">>>>> " + str);

            //
            var lines = str.Split(_chatSplitChars, StringSplitOptions.RemoveEmptyEntries);

            for (int i = 0; i < lines.Length; i++)
            {
                HandleChatLine(handler, node, lines[i]);
            }
        }
コード例 #2
0
        unsafe void SendToClientChat(TcpClientNode node, string message)
        {
            LogTrace("<<<<<<<<<<< " + message);

            var bytesToSend = message.ToUTF8Bytes();

            // Шифруем сообщение, если соединение уже с режиме шифрование
            if (_chatEncoded)
                fixed(byte *bytesToSendPtr = bytesToSend)
                ChatCrypt.GSEncodeDecode(_chatServerKey, bytesToSendPtr, bytesToSend.Length);

            _chat.Send(node, bytesToSend);
        }
        /// <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");
        }
コード例 #4
0
        void OnServerRetrieveReceived(TcpPortHandler handler, TcpClientNode node, byte[] buffer, int count)
        {
            var str = buffer.ToASCII(count);

            LogTrace("RETRIEVE " + str);

            var endPoint = node.RemoteEndPoint;

            if (endPoint == null)
            {
                handler.KillClient(node);
                return;
            }

            string[] data = str.Split(new char[] { '\x00' }, StringSplitOptions.RemoveEmptyEntries);

            string validate = data[4];
            string filter   = null;

            bool isAutomatch = false;

            if (validate.Length > 8)
            {
                filter   = validate.Substring(8);
                validate = validate.Substring(0, 8);
            }
            else
            {
                //Log(Category, "ROOMS REQUEST - "+ data[2]);

                isAutomatch = data[2].EndsWith("am");

                if (!isAutomatch)
                {
                    SendChatRooms(handler, node, validate);
                    return;
                }
            }

            var lobbies = _emulationAdapter.GetOpenedLobbies();

            try
            {
                // var currentRating = ServerContext.ChatServer.CurrentRating;

                /*for (int i = 0; i < lobbies.Length; i++)
                 * {
                 *  var server = lobbies[i];
                 *
                 *  //server["score_"] = GetCurrentRating(server.MaxPlayers);
                 * }*/

                var fields = data[5].Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);

                var unencryptedBytes = ParseHelper.PackServerList(endPoint, lobbies, fields, isAutomatch);

                _lastLoadedLobbies.Clear();

                for (int i = 0; i < lobbies.Length; i++)
                {
                    var server      = lobbies[i];
                    var address     = server.HostIP ?? server.LocalIP;
                    var port        = ushort.Parse(server.HostPort ?? server.LocalPort);
                    var channelHash = ChatCrypt.PiStagingRoomHash(address, address, port);

                    Log($"HASHFOR {address}:{port}  {channelHash}");

                    server.RoomHash = channelHash;
                    _lastLoadedLobbies[channelHash] = server;
                }

                Log("SERVERS VALIDATE VALUE ~" + validate + "~");

                var encryptedBytes = GSEncoding.Encode(_gameGSkeyBytes, validate.ToAsciiBytes(), unencryptedBytes, unencryptedBytes.LongLength);

                Log("SERVERS bytes " + encryptedBytes.Length);

                int autoGames   = 0;
                int customGames = 0;
                // TODO вынести в отдельно
                for (int i = 0; i < lobbies.Length; i++)
                {
                    var server = lobbies[i];
                    if (server.Ranked)
                    {
                        autoGames++;
                    }
                    else
                    {
                        customGames++;
                    }
                }

                //CoreContext.ClientServer.SendAsServerMessage(
                //    "Received game list: " + customGames + " - custom; " + autoGames +
                //    " - auto; Mod: "+ CoreContext.ThunderHawkModManager.CurrentModName);

                handler.Send(node, encryptedBytes);
            }
            finally
            {
                handler.KillClient(node);
            }
        }