예제 #1
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();
        }