示例#1
0
        /*
         * ===============
         * CL_Netchan_Transmit
         * ================
         */
        void CL_Netchan_Transmit(netchan_t *chan, msg_t *msg)
        {
            MSG_WriteByte(msg, clc_EOF);

            CL_Netchan_Encode(msg);
            Netchan_Transmit(chan, msg->cursize, msg->data);
        }
示例#2
0
        /*
         * =================
         * Netchan_SV_Process
         * =================
         */
        bool SV_Netchan_Process(client_t *client, msg_t *msg)
        {
            int ret;

            ret = Netchan_Process(&client->netchan, msg);
            if (!ret)
            {
                return(false);
            }
            SV_Netchan_Decode(client, msg);
            return(true);
        }
示例#3
0
        /*
         * =================
         * CL_Netchan_Process
         * =================
         */
        bool CL_Netchan_Process(netchan_t *chan, msg_t *msg)
        {
            int ret;

            ret = Netchan_Process(chan, msg);
            if (!ret)
            {
                return(false);
            }
            CL_Netchan_Decode(msg);
            newsize += msg->cursize;
            return(true);
        }
示例#4
0
        /*
         * ==================
         * SV_UpdateServerCommandsToClient
         *
         * (re)send all server commands the client hasn't acknowledged yet
         * ==================
         */
        void SV_UpdateServerCommandsToClient(client_t *client, msg_t *msg)
        {
            int i;

            // write any unacknowledged serverCommands
            for (i = client->reliableAcknowledge + 1; i <= client->reliableSequence; i++)
            {
                MSG_WriteByte(msg, svc_serverCommand);
                MSG_WriteLong(msg, i);
                MSG_WriteString(msg, client->reliableCommands[i & (MAX_RELIABLE_COMMANDS - 1)]);
            }
            client->reliableSent = client->reliableSequence;
        }
示例#5
0
        /*
         * ==============
         * CL_Netchan_Encode
         *
         *      // first 12 bytes of the data are always:
         *      long serverId;
         *      long messageAcknowledge;
         *      long reliableAcknowledge;
         *
         * ==============
         */
        static void CL_Netchan_Encode(msg_t *msg)
        {
            int  serverId, messageAcknowledge, reliableAcknowledge;
            int  i, index, srdc, sbit, soob;
            byte key, *string;

            if (msg->cursize <= CL_ENCODE_START)
            {
                return;
            }

            srdc = msg->readcount;
            sbit = msg->bit;
            soob = msg->oob;

            msg->bit       = 0;
            msg->readcount = 0;
            msg->oob       = (bool)0;

            serverId            = MSG_ReadLong(msg);
            messageAcknowledge  = MSG_ReadLong(msg);
            reliableAcknowledge = MSG_ReadLong(msg);

            msg->oob       = (bool)soob;
            msg->bit       = sbit;
            msg->readcount = srdc;

            string = (byte *)clc.serverCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
            index  = 0;
            //
            key = clc.challenge ^ serverId ^ messageAcknowledge;
            for (i = CL_ENCODE_START; i < msg->cursize; i++)
            {
                // modify the key with the last received now acknowledged server command
                if (!string[index])
                {
                    index = 0;
                }
                if (string[index] > 127 || string[index] == '%')
                {
                    key ^= '.' << (i & 1);
                }
                else
                {
                    key ^= string[index] << (i & 1);
                }
                index++;
                // encode the data with this key
                *(msg->data + i) = (*(msg->data + i)) ^ key;
            }
        }
示例#6
0
        /*
         * ==============
         * SV_Netchan_Encode
         *
         *      // first four bytes of the data are always:
         *      long reliableAcknowledge;
         *
         * ==============
         */
        static void SV_Netchan_Encode(client_t *client, msg_t *msg)
        {
            long reliableAcknowledge, i, index;
            byte key, *string;
            int  srdc, sbit, soob;

            if (msg->cursize < SV_ENCODE_START)
            {
                return;
            }

            srdc = msg->readcount;
            sbit = msg->bit;
            soob = msg->oob;

            msg->bit       = 0;
            msg->readcount = 0;
            msg->oob       = (bool)0;

            reliableAcknowledge = MSG_ReadLong(msg);

            msg->oob       = (bool)soob;
            msg->bit       = sbit;
            msg->readcount = srdc;

            string = (byte *)client->lastClientCommandString;
            index  = 0;
            // xor the client challenge with the netchan sequence number
            key = client->challenge ^ client->netchan.outgoingSequence;
            for (i = SV_ENCODE_START; i < msg->cursize; i++)
            {
                // modify the key with the last received and with this message acknowledged client command
                if (!string[index])
                {
                    index = 0;
                }
                if (string[index] > 127 || string[index] == '%')
                {
                    key ^= '.' << (i & 1);
                }
                else
                {
                    key ^= string[index] << (i & 1);
                }
                index++;
                // encode the data with this key
                *(msg->data + i) = *(msg->data + i) ^ key;
            }
        }
示例#7
0
        /*
         * ==============
         * SV_Netchan_Decode
         *
         *      // first 12 bytes of the data are always:
         *      long serverId;
         *      long messageAcknowledge;
         *      long reliableAcknowledge;
         *
         * ==============
         */
        static void SV_Netchan_Decode(client_t *client, msg_t *msg)
        {
            int  serverId, messageAcknowledge, reliableAcknowledge;
            int  i, index, srdc, sbit, soob;
            byte key, *string;

            srdc = msg->readcount;
            sbit = msg->bit;
            soob = msg->oob;

            msg->oob = (bool)0;

            serverId            = MSG_ReadLong(msg);
            messageAcknowledge  = MSG_ReadLong(msg);
            reliableAcknowledge = MSG_ReadLong(msg);

            msg->oob       = (bool)soob;
            msg->bit       = sbit;
            msg->readcount = srdc;

            string = (byte *)client->reliableCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
            index  = 0;
            //
            key = client->challenge ^ serverId ^ messageAcknowledge;
            for (i = msg->readcount + SV_DECODE_START; i < msg->cursize; i++)
            {
                // modify the key with the last sent and acknowledged server command
                if (!string[index])
                {
                    index = 0;
                }
                if (string[index] > 127 || string[index] == '%')
                {
                    key ^= '.' << (i & 1);
                }
                else
                {
                    key ^= string[index] << (i & 1);
                }
                index++;
                // decode the data with this key
                *(msg->data + i) = *(msg->data + i) ^ key;
            }
        }
示例#8
0
        /*
         * ==============
         * CL_Netchan_Decode
         *
         *      // first four bytes of the data are always:
         *      long reliableAcknowledge;
         *
         * ==============
         */
        static void CL_Netchan_Decode(msg_t *msg)
        {
            long reliableAcknowledge, i, index;
            byte key, *string;
            int  srdc, sbit, soob;

            srdc = msg->readcount;
            sbit = msg->bit;
            soob = msg->oob;

            msg->oob = (bool)0;

            reliableAcknowledge = MSG_ReadLong(msg);

            msg->oob       = (bool)soob;
            msg->bit       = sbit;
            msg->readcount = srdc;

            string = (byte *)clc.reliableCommands[reliableAcknowledge & (MAX_RELIABLE_COMMANDS - 1)];
            index  = 0;
            // xor the client challenge with the netchan sequence number (need something that changes every message)
            key = clc.challenge ^ LittleLong(*(unsigned *)msg->data);
            for (i = msg->readcount + CL_DECODE_START; i < msg->cursize; i++)
            {
                // modify the key with the last sent and with this message acknowledged client command
                if (!string[index])
                {
                    index = 0;
                }
                if (string[index] > 127 || string[index] == '%')
                {
                    key ^= '.' << (i & 1);
                }
                else
                {
                    key ^= string[index] << (i & 1);
                }
                index++;
                // decode the data with this key
                *(msg->data + i) = *(msg->data + i) ^ key;
            }
        }
示例#9
0
        /*
         * ===============
         * SV_Netchan_Transmit
         * TTimo
         * https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=462
         * if there are some unsent fragments (which may happen if the snapshots
         * and the gamestate are fragmenting, and collide on send for instance)
         * then buffer them and make sure they get sent in correct order
         * ================
         */

        void SV_Netchan_Transmit(client_t *client, msg_t *msg)                  //int length, const byte *data ) {
        {
            MSG_WriteByte(msg, svc_EOF);
            if (client->netchan.unsentFragments)
            {
                netchan_buffer_t *netbuf;
                Com_DPrintf("#462 SV_Netchan_Transmit: unsent fragments, stacked\n");
                netbuf = (netchan_buffer_t *)Z_Malloc(sizeof(netchan_buffer_t));
                // store the msg, we can't store it encoded, as the encoding depends on stuff we still have to finish sending
                MSG_Copy(&netbuf->msg, netbuf->msgBuffer, sizeof(netbuf->msgBuffer), msg);
                netbuf->next = NULL;
                // insert it in the queue, the message will be encoded and sent later
                *client->netchan_end_queue = netbuf;
                client->netchan_end_queue = &(*client->netchan_end_queue)->next;
                // emit the next fragment of the current message for now
                Netchan_TransmitNextFragment(&client->netchan);
            }
            else
            {
                SV_Netchan_Encode(client, msg);
                Netchan_Transmit(&client->netchan, msg->cursize, msg->data);
            }
        }
示例#10
0
 void Huff_Decompress(msg_t *mbuf, int offset)
 {
     int    ch, cch, i, j, size;
     byte   seq[65536];
示例#11
0
 bool    Sys_GetPacket(netadr_t *net_from, msg_t *net_message);
示例#12
0
        /*
         * =============================================================================
         *
         * Delta encode a client frame onto the network channel
         *
         * A normal server packet will look like:
         *
         * 4	sequence number (high bit set if an oversize fragment)
         * <optional reliable commands>
         * 1	svc_snapshot
         * 4	last client reliable command
         * 4	serverTime
         * 1	lastframe for delta compression
         * 1	snapFlags
         * 1	areaBytes
         * <areabytes>
         * <playerstate>
         * <packetentities>
         *
         * =============================================================================
         */

        /*
         * =============
         * SV_EmitPacketEntities
         *
         * Writes a delta update of an entityState_t list to the message.
         * =============
         */
        static void SV_EmitPacketEntities(clientSnapshot_t *from, clientSnapshot_t *to, msg_t *msg)
        {
            entityState_t *oldent, *newent;
            int            oldindex, newindex;
            int            oldnum, newnum;
            int            from_num_entities;

            // generate the delta update
            if (!from)
            {
                from_num_entities = 0;
            }
            else
            {
                from_num_entities = from->num_entities;
            }

            newent   = NULL;
            oldent   = NULL;
            newindex = 0;
            oldindex = 0;
            while (newindex < to->num_entities || oldindex < from_num_entities)
            {
                if (newindex >= to->num_entities)
                {
                    newnum = 9999;
                }
                else
                {
                    newent = &svs.snapshotEntities[(to->first_entity + newindex) % svs.numSnapshotEntities];
                    newnum = newent->number;
                }

                if (oldindex >= from_num_entities)
                {
                    oldnum = 9999;
                }
                else
                {
                    oldent = &svs.snapshotEntities[(from->first_entity + oldindex) % svs.numSnapshotEntities];
                    oldnum = oldent->number;
                }

                if (newnum == oldnum)
                {
                    // delta update from old position
                    // because the force parm is false, this will not result
                    // in any bytes being emited if the entity has not changed at all
                    MSG_WriteDeltaEntity(msg, oldent, newent, false);
                    oldindex++;
                    newindex++;
                    continue;
                }

                if (newnum < oldnum)
                {
                    // this is a new entity, send it from the baseline
                    MSG_WriteDeltaEntity(msg, &sv.svEntities[newnum].baseline, newent, true);
                    newindex++;
                    continue;
                }

                if (newnum > oldnum)
                {
                    // the old entity isn't present in the new message
                    MSG_WriteDeltaEntity(msg, oldent, NULL, true);
                    oldindex++;
                    continue;
                }
            }

            MSG_WriteBits(msg, (MAX_GENTITIES - 1), GENTITYNUM_BITS);                   // end of packetentities
        }
示例#13
0
        /*
         * ==================
         * SV_WriteSnapshotToClient
         * ==================
         */
        static void SV_WriteSnapshotToClient(client_t *client, msg_t *msg)
        {
            clientSnapshot_t *frame, *oldframe;
            int lastframe;
            int i;
            int snapFlags;

            // this is the snapshot we are creating
            frame = &client->frames[client->netchan.outgoingSequence & PACKET_MASK];

            // try to use a previous frame as the source for delta compressing the snapshot
            if (client->deltaMessage <= 0 || client->state != CS_ACTIVE)
            {
                // client is asking for a retransmit
                oldframe  = NULL;
                lastframe = 0;
            }
            else if (client->netchan.outgoingSequence - client->deltaMessage
                     >= (PACKET_BACKUP - 3))
            {
                // client hasn't gotten a good message through in a long time
                Com_DPrintf("%s: Delta request from out of date packet.\n", client->name);
                oldframe  = NULL;
                lastframe = 0;
            }
            else
            {
                // we have a valid snapshot to delta from
                oldframe  = &client->frames[client->deltaMessage & PACKET_MASK];
                lastframe = client->netchan.outgoingSequence - client->deltaMessage;

                // the snapshot's entities may still have rolled off the buffer, though
                if (oldframe->first_entity <= svs.nextSnapshotEntities - svs.numSnapshotEntities)
                {
                    Com_DPrintf("%s: Delta request from out of date entities.\n", client->name);
                    oldframe  = NULL;
                    lastframe = 0;
                }
            }

            MSG_WriteByte(msg, svc_snapshot);

            // NOTE, MRE: now sent at the start of every message from server to client
            // let the client know which reliable clientCommands we have received
            //MSG_WriteLong( msg, client->lastClientCommand );

            // send over the current server time so the client can drift
            // its view of time to try to match
            MSG_WriteLong(msg, svs.time);

            // what we are delta'ing from
            MSG_WriteByte(msg, lastframe);

            snapFlags = svs.snapFlagServerBit;
            if (client->rateDelayed)
            {
                snapFlags |= SNAPFLAG_RATE_DELAYED;
            }
            if (client->state != CS_ACTIVE)
            {
                snapFlags |= SNAPFLAG_NOT_ACTIVE;
            }

            MSG_WriteByte(msg, snapFlags);

            // send over the areabits
            MSG_WriteByte(msg, frame->areabytes);
            MSG_WriteData(msg, frame->areabits, frame->areabytes);

            // delta encode the playerstate
            if (oldframe)
            {
                MSG_WriteDeltaPlayerstate(msg, &oldframe->ps, &frame->ps);
            }
            else
            {
                MSG_WriteDeltaPlayerstate(msg, NULL, &frame->ps);
            }

            // delta encode the entities
            SV_EmitPacketEntities(oldframe, frame, msg);

            // padding for rate debugging
            if (sv_padPackets->integer)
            {
                for (i = 0; i < sv_padPackets->integer; i++)
                {
                    MSG_WriteByte(msg, svc_nop);
                }
            }
        }