示例#1
0
        private bool DoConnectionlessHandshake()
        {
            string command;

            byte [] data;

            this.connState = ConnectionState.Connecting;
            WriteConnectionlessPacket("getchallenge", null, 0, 0);

            if (ReadConnectionlessPacket(out command, out data))
            {
                if (command == "challengeResponse")
                {
                    this.challenge = Convert.ToInt32(Encoding.Default.GetString(data));

                    MemoryStream ms = new MemoryStream();
                    ms.Position = 2;
                    Q3HuffmanStream huff = new Q3HuffmanStream(ms, System.IO.Compression.CompressionMode.Compress);

                    string connStr = string.Format(@"\challenge\{0}\qport\{1}\protocol\{2}{3}",
                                                   this.challenge, this.qport, PROTOCOL_VERSION, userInfo);
                    huff.WriteString(connStr);
                    huff.Flush();
                    ms.Position = 0;
                    ms.Write(ExBitConverter.GetBytes(( short )connStr.Length, false), 0, 2);

                    this.connState = ConnectionState.Challenging;
                    WriteConnectionlessPacket("connect ", ms.GetBuffer(), 0, ( int )ms.Length);

                    if (ReadConnectionlessPacket(out command, out data))
                    {
                        if (command == "connectResponse")
                        {
                            this.connState = ConnectionState.Connected;
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
示例#2
0
        /*
         *      During normal gameplay, a client packet will contain something like:
         *
         *      4	sequence number
         *      2	qport
         *      4	serverid
         *      4	acknowledged sequence number
         *      4	serverCommandSequence
         *      <optional reliable commands>
         *      1	ClientCommands.Move or ClientCommands.MoveNoDelta
         *      1	command count
         *      <count * usercmds>
         */
        private void WritePacket()
        {
            // 'sequence number' and 'qport' fields will be written by underlying
            // Q3NetworkStream to provide these values without compressing and cyphering
            q3HuffCStream.WriteInt32(this.serverId);                            // serverid
            q3HuffCStream.WriteInt32(this.incomingSequence);                    // acknowledged sequence number
            q3HuffCStream.WriteInt32(this.incomingCommandSequence);             // serverCommandSequence

            reliableCommandsEvent.WaitOne();
            //<optional reliable commands>
            for (int i = reliableAcknowledge + 1; i <= reliableSequence; i++)
            {
                q3HuffCStream.WriteByte(( byte )ClientCommandType.ClientCommand);
                q3HuffCStream.WriteInt32(i);
                q3HuffCStream.WriteString(outgoingReliableCommands [i & (MAX_RELIABLE_COMMANDS - 1)]);
            }
            reliableCommandsEvent.Set();

            // we want to send all the usercmds that were generated in the last
            // few packet, so even if a couple packets are dropped in a row,
            // all the cmds will make it to the server
            if (this.packetDup < 0)
            {
                this.packetDup = 0;
            }
            else if (this.packetDup > 5)
            {
                this.packetDup = 5;
            }

            int oldPacketNum = (this.outgoingSequence - 1 - packetDup) & PACKET_MASK;
            int count        = this.cmdNumber - this.outPackets [oldPacketNum].cmdNumber;

            if (count > MAX_PACKET_USERCMDS)
            {
                count = MAX_PACKET_USERCMDS;
            }

            UserCommand oldcmd = new UserCommand();

            if (count >= 1 && this.newSnapshots)
            {
                // begin a client move command
                if (/*cl_nodelta->integer ||*/ !snap.valid ||               /*|| clc.demowaiting*/
                    this.incomingSequence != this.snap.messageNum)
                {
                    q3HuffCStream.WriteByte(( byte )ClientCommandType.MoveNoDelta);
                }
                else
                {
                    q3HuffCStream.WriteByte(( byte )ClientCommandType.Move);
                }

                // write the command count
                q3HuffCStream.WriteByte(( byte )count);

                // use the checksum feed in the key
                int key = this.checksumFeed;
                // also use the message acknowledge
                key ^= this.incomingSequence;
                // also use the last acknowledged server command in the key
                key ^= this.HashKey(this.incomingReliableCommands [this.incomingCommandSequence & (MAX_RELIABLE_COMMANDS - 1)], 32);

                // write all the commands, including the predicted command
                for (int i = 0; i < count; i++)
                {
                    int j = (this.cmdNumber - count + i + 1) & CMD_MASK;
                    WriteDeltaUsercmdKey(key, oldcmd, ref this.cmds [j]);
                    oldcmd = this.cmds [j];
                }

                this.newSnapshots = false;
            }

            int packetNum = this.outgoingSequence & PACKET_MASK;

            this.outPackets[packetNum].realtime   = DateTime.Now.Millisecond;
            this.outPackets[packetNum].serverTime = oldcmd.serverTime;
            this.outPackets[packetNum].cmdNumber  = this.cmdNumber;
            //clc.lastPacketSentTime = cls.realtime;

            q3HuffCStream.WriteByte(( byte )ClientCommandType.EOF);
            q3HuffCStream.Flush();
        }