Пример #1
0
        /// <summary>
        /// This method parses and handles a CD-Key authorization request from
        /// from a game server.
        /// </summary>
        /// <param name="Parser">Supplies the message parse context.</param>
        /// <param name="Sender">Supplies the game server address.</param>
        /// <param name="Socket">Supplies the associated socket descriptor
        /// upon which the message was received.</param>
        private void OnRecvMstCDKeyAuthorizationRequest(ExoParseBuffer Parser, IPEndPoint Sender, SocketInfo Socket)
        {
            UInt16 DataPort;
            UInt16 EntryCount;
            UInt32 ClientIP;
            UInt16 ClientPort;
            byte[] ServerChallenge;
            UInt16 Length;
            List<CDKeyInfo> CDKeyHashes;
            CDKeyInfo CDKeyHash;
            string AccountName;
            int KeyIndex;
            int PortNumberHbo;

            if (!Parser.ReadWORD(out DataPort))
                return;
            if (!Parser.ReadWORD(out EntryCount))
                return;
            if (EntryCount != 1)
                return;
            if (!Parser.ReadDWORD(out ClientIP))
                return;
            if (!Parser.ReadWORD(out ClientPort))
                return;

            PortNumberHbo = IPAddress.NetworkToHostOrder(ClientPort);

            if ((PortNumberHbo == 0) || ((PortNumberHbo & 0xFFFF) != PortNumberHbo))
                PortNumberHbo = 5120;

            IPEndPoint ClientEndpoint = new IPEndPoint((long)ClientIP, PortNumberHbo);

            if (!Parser.ReadWORD(out Length))
                return;
            if ((ServerChallenge = Parser.ReadBytes(Length)) == null)
                return;
            if (!Parser.ReadWORD(out Length))
                return;

            CDKeyHashes = new List<CDKeyInfo>();
            CDKeyHash = new CDKeyInfo();

            KeyIndex = 0;
            while (Length-- != 0)
            {
                UInt16 HashLength;

                if (!Parser.ReadSmallString(out CDKeyHash.PublicCDKey, 16))
                    return;
                if (!Parser.ReadWORD(out HashLength))
                    return;
                if ((CDKeyHash.CDKeyHash = Parser.ReadBytes(HashLength)) == null)
                    return;

                //
                // N.B.  The following is somewhat of a hack in that we are not
                //       bothering to extract the (real) product type from the
                //       CD-Key.  As a result, it is possible that the wrong
                //       answer could be provided for clients without all of
                //       the expansions; this situation is considered unlikely
                //       in the current state of affairs.
                //
                //       A better fit could be had by examining the expansion
                //       mask required by the server in the data table, but
                //       this does not appear worthwhile at this stage.
                //

                if (KeyIndex == 0)
                    CDKeyHash.Product = 0;
                else
                    CDKeyHash.Product = (UInt16) (1 << (KeyIndex - 1));

                CDKeyHash.AuthStatus = (UInt16)ConnectStatus.CONNECT_ERR_SUCCESS;

                CDKeyHashes.Add(CDKeyHash);
            }

            if (!Parser.ReadSmallString(out AccountName, 16))
                return;

            SendMstCDKeyAuthorization(Sender, CDKeyHashes);
        }