123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Doom 3 Source Code is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #ifndef __MSGCHANNEL_H__
- #define __MSGCHANNEL_H__
- /*
- ===============================================================================
- Network channel.
- Handles message fragmentation and out of order / duplicate suppression.
- Unreliable messages are not garrenteed to arrive but when they do, they
- arrive in order and without duplicates. Reliable messages always arrive,
- and they also arrive in order without duplicates. Reliable messages piggy
- back on unreliable messages. As such an unreliable message stream is
- required for the reliable messages to be delivered.
- ===============================================================================
- */
- #define MAX_MESSAGE_SIZE 16384 // max length of a message, which may
- // be fragmented into multiple packets
- #define CONNECTIONLESS_MESSAGE_ID -1 // id for connectionless messages
- #define CONNECTIONLESS_MESSAGE_ID_MASK 0x7FFF // value to mask away connectionless message id
- #define MAX_MSG_QUEUE_SIZE 16384 // must be a power of 2
- class idMsgQueue {
- public:
- idMsgQueue();
- void Init( int sequence );
- bool Add( const byte *data, const int size );
- bool Get( byte *data, int &size );
- int GetTotalSize( void ) const;
- int GetSpaceLeft( void ) const;
- int GetFirst( void ) const { return first; }
- int GetLast( void ) const { return last; }
- void CopyToBuffer( byte *buf ) const;
- private:
- byte buffer[MAX_MSG_QUEUE_SIZE];
- int first; // sequence number of first message in queue
- int last; // sequence number of last message in queue
- int startIndex; // index pointing to the first byte of the first message
- int endIndex; // index pointing to the first byte after the last message
- void WriteByte( byte b );
- byte ReadByte( void );
- void WriteShort( int s );
- int ReadShort( void );
- void WriteLong( int l );
- int ReadLong( void );
- void WriteData( const byte *data, const int size );
- void ReadData( byte *data, const int size );
- };
- class idMsgChannel {
- public:
- idMsgChannel();
- void Init( const netadr_t adr, const int id );
- void Shutdown( void );
- void ResetRate( void );
- // Sets the maximum outgoing rate.
- void SetMaxOutgoingRate( int rate ) { maxRate = rate; }
- // Gets the maximum outgoing rate.
- int GetMaxOutgoingRate( void ) { return maxRate; }
- // Returns the address of the entity at the other side of the channel.
- netadr_t GetRemoteAddress( void ) const { return remoteAddress; }
- // Returns the average outgoing rate over the last second.
- int GetOutgoingRate( void ) const { return outgoingRateBytes; }
- // Returns the average incoming rate over the last second.
- int GetIncomingRate( void ) const { return incomingRateBytes; }
- // Returns the average outgoing compression ratio over the last second.
- float GetOutgoingCompression( void ) const { return outgoingCompression; }
- // Returns the average incoming compression ratio over the last second.
- float GetIncomingCompression( void ) const { return incomingCompression; }
- // Returns the average incoming packet loss over the last 5 seconds.
- float GetIncomingPacketLoss( void ) const;
- // Returns true if the channel is ready to send new data based on the maximum rate.
- bool ReadyToSend( const int time ) const;
- // Sends an unreliable message, in order and without duplicates.
- int SendMessage( idPort &port, const int time, const idBitMsg &msg );
- // Sends the next fragment if the last message was too large to send at once.
- void SendNextFragment( idPort &port, const int time );
- // Returns true if there are unsent fragments left.
- bool UnsentFragmentsLeft( void ) const { return unsentFragments; }
- // Processes the incoming message. Returns true when a complete message
- // is ready for further processing. In that case the read pointer of msg
- // points to the first byte ready for reading, and sequence is set to
- // the sequence number of the message.
- bool Process( const netadr_t from, int time, idBitMsg &msg, int &sequence );
- // Sends a reliable message, in order and without duplicates.
- bool SendReliableMessage( const idBitMsg &msg );
- // Returns true if a new reliable message is available and stores the message.
- bool GetReliableMessage( idBitMsg &msg );
- // Removes any pending outgoing or incoming reliable messages.
- void ClearReliableMessages( void );
- private:
- netadr_t remoteAddress; // address of remote host
- int id; // our identification used instead of port number
- int maxRate; // maximum number of bytes that may go out per second
- idCompressor * compressor; // compressor used for data compression
- // variables to control the outgoing rate
- int lastSendTime; // last time data was sent out
- int lastDataBytes; // bytes left to send at last send time
- // variables to keep track of the rate
- int outgoingRateTime;
- int outgoingRateBytes;
- int incomingRateTime;
- int incomingRateBytes;
- // variables to keep track of the compression ratio
- float outgoingCompression;
- float incomingCompression;
- // variables to keep track of the incoming packet loss
- float incomingReceivedPackets;
- float incomingDroppedPackets;
- int incomingPacketLossTime;
- // sequencing variables
- int outgoingSequence;
- int incomingSequence;
- // outgoing fragment buffer
- bool unsentFragments;
- int unsentFragmentStart;
- byte unsentBuffer[MAX_MESSAGE_SIZE];
- idBitMsg unsentMsg;
- // incoming fragment assembly buffer
- int fragmentSequence;
- int fragmentLength;
- byte fragmentBuffer[MAX_MESSAGE_SIZE];
- // reliable messages
- idMsgQueue reliableSend;
- idMsgQueue reliableReceive;
- private:
- void WriteMessageData( idBitMsg &out, const idBitMsg &msg );
- bool ReadMessageData( idBitMsg &out, const idBitMsg &msg );
- void UpdateOutgoingRate( const int time, const int size );
- void UpdateIncomingRate( const int time, const int size );
- void UpdatePacketLoss( const int time, const int numReceived, const int numDropped );
- };
- #endif /* !__MSGCHANNEL_H__ */
|