Exemplo n.º 1
0
        private unsafe void OnGameDataReceived(IAsyncResult async)
        {
            SocketState state = (SocketState)async.AsyncState;

            if (state == null || state.GameSocket == null || !state.GameSocket.Connected)
            {
                return;
            }

            try
            {
                // receive data from the socket
                int received = state.GameSocket.EndReceive(async);

                if (received == 0)
                {
                    return;
                }

                var buffer = state.GameBuffer;

                using (var ms = new MemoryStream(buffer, 0, received))
                {
                    if (!state.SendingEncoded)
                    {
                        using (var reader = new StreamReader(ms))
                        {
                            var asciValue = reader.ReadToEnd();

                            Log("CHATDATA", asciValue);

                            ms.Position = 0;

                            var line = reader.ReadLine();

                            if (line.StartsWith("CRYPT"))
                            {
                                state.SendingEncoded = true;

                                /*if (line.Contains("whammer40kdc"))
                                 * {
                                 *  Gamename = "whammer40kdc".ToAssciiBytes();
                                 *  Gamekey = "Ue9v3H".ToAssciiBytes();
                                 * }*/

                                if (line.Contains("whamdowfr"))
                                {
                                    Gamename = "whamdowfr".ToAssciiBytes();
                                    Gamekey  = "pXL838".ToAssciiBytes();
                                }

                                if (Gamekey == null)
                                {
                                    state.Dispose();
                                    return;
                                }

                                var chall = "0000000000000000".ToAssciiBytes();

                                var receivingGameKey   = new ChatCrypt.GDCryptKey();
                                var sendingGameKey     = new ChatCrypt.GDCryptKey();
                                var receivingServerKey = new ChatCrypt.GDCryptKey();
                                var sendingServerKey   = new ChatCrypt.GDCryptKey();

                                fixed(byte *challPtr = chall)
                                {
                                    fixed(byte *gamekeyPtr = Gamekey)
                                    {
                                        ChatCrypt.GSCryptKeyInit(receivingGameKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(sendingGameKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(receivingServerKey, challPtr, gamekeyPtr, Gamekey.Length);
                                        ChatCrypt.GSCryptKeyInit(sendingServerKey, challPtr, gamekeyPtr, Gamekey.Length);
                                    }
                                }

                                state.ReceivingGameKey   = receivingGameKey;
                                state.SendingGameKey     = sendingGameKey;
                                state.ReceivingServerKey = receivingServerKey;
                                state.SendingServerKey   = sendingServerKey;

                                // Send to server without encoding
                                _serverSocket.Send(buffer, received, SocketFlags.None);
                            }
                            else
                            {
                                // Send to server without encoding
                                _serverSocket.Send(buffer, received, SocketFlags.None);
                            }
                        }
                    }
                    else
                    {
                        using (var reader = new BinaryReader(ms, Encoding.ASCII))
                        {
                            var start = ms.Position;

                            var bytes = reader.ReadBytes((int)(ms.Length - ms.Position));

                            if (state.SendingEncoded)
                            {
                                byte *bytesPtr = stackalloc byte[bytes.Length];

                                for (int i = 0; i < bytes.Length; i++)
                                {
                                    bytesPtr[i] = bytes[i];
                                }

                                ChatCrypt.GSEncodeDecode(state.ReceivingGameKey, bytesPtr, bytes.Length);

                                for (int i = 0; i < bytes.Length; i++)
                                {
                                    bytes[i] = bytesPtr[i];
                                }
                            }

                            var utf8value = Encoding.UTF8.GetString(bytes);

                            Log("CHATDATA", utf8value);

                            if (utf8value.StartsWith("LOGIN", StringComparison.OrdinalIgnoreCase))
                            {
                                var nick = utf8value.Split(' ')[2];

                                ChatNick = nick;

                                SendToServerSocket(ref state, bytes);

                                goto CONTINUE;
                            }

                            if (utf8value.StartsWith("USRIP", StringComparison.OrdinalIgnoreCase))
                            {
                                SendToServerSocket(ref state, bytes);

                                goto CONTINUE;
                            }

                            var hostAddressIndex = utf8value.IndexOf(HOST_ADDRESS_TOKEN, StringComparison.OrdinalIgnoreCase);

                            if (hostAddressIndex != -1)
                            {
                                var port = CutPortValue(utf8value, hostAddressIndex + HOST_ADDRESS_TOKEN.Length, out string portString);

                                port = ByteHelpers.ReverseEndian16(port);

                                var hostSteamId = PortBindingManager.GetSteamIdByPort(port);

                                if (!hostSteamId.HasValue)
                                {
                                    port        = ByteHelpers.ReverseEndian16(port);
                                    hostSteamId = PortBindingManager.GetSteamIdByPort(port);
                                }

                                if (hostSteamId.HasValue)
                                {
                                    utf8value = utf8value.Replace(HOST_ADDRESS_TOKEN + portString, HOST_ADDRESS_TOKEN + hostSteamId.Value.m_SteamID);
                                }
                            }

                            var index = utf8value.IndexOf("#GSP!whamdowfr!", StringComparison.OrdinalIgnoreCase);

                            if (index != -1)
                            {
                                var encodedEndPoint = utf8value.Substring(index + 15, 10);

                                CSteamID steamId;

                                if (ServerListReport.CurrentUserRoomHash == encodedEndPoint)
                                {
                                    steamId = SteamUser.GetSteamID();
                                }
                                else
                                {
                                    if (!ServerListRetrieve.IDByChannelCache.TryGetValue(encodedEndPoint, out steamId))
                                    {
                                        ServerListReport.CurrentUserRoomHash = encodedEndPoint;
                                        steamId = SteamUser.GetSteamID();
                                    }
                                }

                                utf8value = utf8value.Replace(encodedEndPoint, steamId.m_SteamID.ToString());

                                SendToServerSocket(ref state, Encoding.UTF8.GetBytes(utf8value));

                                goto CONTINUE;
                            }

                            //  16777343 ~ 1.0.0.127  inversed port 63349 port
                            // :QWEQWE!X44vf1Wf1X|[email protected] PRIVMSG elamaunt :ACTION 7; 16777343; 63349; 16777343; 63349; 1;

                            SendToServerSocket(ref state, bytes);
                        }
                    }
                }
            }
            catch (ObjectDisposedException)
            {
                if (state != null)
                {
                    state.Dispose();
                }
                state = null;
                return;
            }
            catch (SocketException e)
            {
                switch (e.SocketErrorCode)
                {
                case SocketError.ConnectionReset:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                case SocketError.Disconnecting:
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;

                default:
                    LogError(Category, "Error receiving data");
                    LogError(Category, String.Format("{0} {1}", e.SocketErrorCode, e));
                    if (state != null)
                    {
                        state.Dispose();
                    }
                    state = null;
                    return;
                }
            }
            catch (Exception e)
            {
                LogError(Category, "Error receiving data");
                LogError(Category, e.ToString());
            }

            // and we wait for more data...
            CONTINUE : WaitForGameData(state);
        }