08 Oct 2010
This commit is contained in:
parent
d8bf6a1329
commit
d505b7685a
|
@ -307,6 +307,9 @@ void CL_WritePacket( void )
|
|||
|
||||
// deliver the message
|
||||
Netchan_Transmit( &cls.netchan, BF_GetNumBytesWritten( &buf ), BF_GetData( &buf ));
|
||||
|
||||
// update download/upload slider.
|
||||
Netchan_UpdateProgress( &cls.netchan );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -580,6 +583,9 @@ void CL_Disconnect( void )
|
|||
CL_SendDisconnectMessage();
|
||||
CL_ClearState ();
|
||||
|
||||
// clear the network channel, too.
|
||||
Netchan_Clear( &cls.netchan );
|
||||
|
||||
// stop download
|
||||
if( cls.download )
|
||||
{
|
||||
|
@ -717,6 +723,11 @@ void CL_Reconnect_f( void )
|
|||
{
|
||||
cls.demonum = cls.movienum = -1; // not in the demo loop now
|
||||
cls.state = ca_connected;
|
||||
|
||||
// clear channel and stuff
|
||||
Netchan_Clear( &cls.netchan );
|
||||
BF_Clear( &cls.netchan.message );
|
||||
|
||||
BF_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
BF_WriteString( &cls.netchan.message, "new" );
|
||||
return;
|
||||
|
@ -973,23 +984,23 @@ void CL_ReadNetMessage( void )
|
|||
if( BF_GetMaxBytes( &net_message ) >= 4 && *(int *)net_message.pData == -1 )
|
||||
{
|
||||
CL_ConnectionlessPacket( net_from, &net_message );
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// can't be a valid sequenced packet
|
||||
if( cls.state < ca_connected ) return;
|
||||
if( cls.state < ca_connected ) continue;
|
||||
|
||||
if( BF_GetMaxBytes( &net_message ) < 8 )
|
||||
{
|
||||
MsgDev( D_WARN, "%s: runt packet\n", NET_AdrToString( net_from ));
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// packet from server
|
||||
if( !NET_CompareAdr( net_from, cls.netchan.remote_address ))
|
||||
{
|
||||
MsgDev( D_WARN, "CL_ReadPackets: %s:sequenced packet without connection\n", NET_AdrToString( net_from ));
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( Netchan_Process( &cls.netchan, &net_message ))
|
||||
|
@ -1005,6 +1016,32 @@ void CL_ReadNetMessage( void )
|
|||
CL_WriteDemoMessage( &net_message, headerBytes );
|
||||
}
|
||||
}
|
||||
|
||||
// check for fragmentation/reassembly related packets.
|
||||
if( cls.state != ca_disconnected && Netchan_IncomingReady( &cls.netchan ))
|
||||
{
|
||||
// the header is different lengths for reliable and unreliable messages
|
||||
int headerBytes = BF_GetNumBytesRead( &net_message );
|
||||
|
||||
// process the incoming buffer(s)
|
||||
if( Netchan_CopyNormalFragments( &cls.netchan, &net_message ))
|
||||
{
|
||||
CL_ParseServerMessage( &net_message );
|
||||
|
||||
// we don't know if it is ok to save a demo message until
|
||||
// after we have parsed the frame
|
||||
if( cls.demorecording && !cls.demowaiting )
|
||||
CL_WriteDemoMessage( &net_message, headerBytes );
|
||||
}
|
||||
|
||||
if( Netchan_CopyFileFragments( &cls.netchan, &net_message ))
|
||||
{
|
||||
// Remove from resource request stuff.
|
||||
// CL_ProcessFile( true, cls.netchan.incomingfilename );
|
||||
}
|
||||
}
|
||||
|
||||
Netchan_UpdateProgress( &cls.netchan );
|
||||
}
|
||||
|
||||
void CL_ReadPackets( void )
|
||||
|
|
|
@ -361,6 +361,8 @@ void CL_InitClientMove( void )
|
|||
{
|
||||
int i;
|
||||
|
||||
Pmove_Init ();
|
||||
|
||||
clgame.pmove->server = false; // running at client
|
||||
clgame.pmove->movevars = &clgame.movevars;
|
||||
clgame.pmove->runfuncs = false;
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "com_model.h"
|
||||
#include "cm_local.h"
|
||||
#include "pm_defs.h"
|
||||
#include "pm_movevars.h"
|
||||
#include "netchan.h"
|
||||
#include "world.h"
|
||||
|
||||
#define MAX_DEMOS 32
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "vsound_api.h"
|
||||
#include "com_export.h"
|
||||
#include "com_model.h"
|
||||
#include "net_msg.h"
|
||||
|
||||
// PERFORMANCE INFO
|
||||
#define MIN_FPS 0.1 // host minimum fps value for maxfps.
|
||||
|
@ -32,6 +31,28 @@
|
|||
#define CIN_MAIN 0
|
||||
#define CIN_LOGO 1
|
||||
|
||||
// config strings are a general means of communication from
|
||||
// the server to all connected clients.
|
||||
// each config string can be at most CS_SIZE characters.
|
||||
#define CS_SIZE 64 // size of one config string
|
||||
#define CS_TIME 16 // size of time string
|
||||
|
||||
// FIXME: eliminate this. Configstrings must be started from CS_MODELS
|
||||
|
||||
#define CS_NAME 0 // map name
|
||||
#define CS_MAPCHECKSUM 1 // level checksum (for catching cheater maps)
|
||||
#define CS_BACKGROUND_TRACK 3 // basename of background track
|
||||
|
||||
// 8 - 32 it's a reserved strings
|
||||
|
||||
#define CS_MODELS 8 // configstrings starts here
|
||||
#define CS_SOUNDS (CS_MODELS+MAX_MODELS) // sound names
|
||||
#define CS_DECALS (CS_SOUNDS+MAX_SOUNDS) // server decal indexes
|
||||
#define CS_EVENTS (CS_DECALS+MAX_DECALNAMES) // queue events
|
||||
#define CS_GENERICS (CS_EVENTS+MAX_EVENTS) // generic resources (e.g. color decals)
|
||||
#define CS_LIGHTSTYLES (CS_GENERICS+MAX_GENERICS) // lightstyle patterns
|
||||
#define MAX_CONFIGSTRINGS (CS_LIGHTSTYLES+MAX_LIGHTSTYLES) // total count
|
||||
|
||||
#ifdef _DEBUG
|
||||
void DBG_AssertFunction( bool fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage );
|
||||
#define Assert( f ) DBG_AssertFunction( f, #f, __FILE__, __LINE__, NULL )
|
||||
|
@ -41,6 +62,7 @@ void DBG_AssertFunction( bool fExpr, const char* szExpr, const char* szFile, int
|
|||
|
||||
extern cvar_t *scr_width;
|
||||
extern cvar_t *scr_height;
|
||||
extern cvar_t *scr_download;
|
||||
extern cvar_t *allow_download;
|
||||
extern cvar_t *host_maxfps;
|
||||
|
||||
|
|
|
@ -739,4 +739,22 @@ char *BF_ReadStringExt( sizebuf_t *bf, bool bLine )
|
|||
string[l] = 0; // terminator
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
void BF_ExciseBits( sizebuf_t *bf, int startbit, int bitstoremove )
|
||||
{
|
||||
int i, endbit = startbit + bitstoremove;
|
||||
int remaining_to_end = bf->nDataBits - endbit;
|
||||
sizebuf_t temp;
|
||||
|
||||
BF_StartWriting( &temp, bf->pData, bf->nDataBits << 3, startbit, -1 );
|
||||
BF_SeekToBit( bf, endbit );
|
||||
|
||||
for( i = 0; i < remaining_to_end; i++ )
|
||||
{
|
||||
BF_WriteOneBit( &temp, BF_ReadOneBit( bf ));
|
||||
}
|
||||
|
||||
BF_SeekToBit( bf, startbit );
|
||||
bf->nDataBits -= bitstoremove;
|
||||
}
|
|
@ -35,6 +35,7 @@ typedef struct
|
|||
#define BF_WriteUBitLong( bf, data, bits ) BF_WriteUBitLongExt( bf, data, bits, true );
|
||||
#define BF_StartReading BF_StartWriting
|
||||
#define BF_GetNumBytesRead BF_GetNumBytesWritten
|
||||
#define BF_GetNumBitsRead BF_GetNumBitsWritten
|
||||
#define BF_ReadBitAngles BF_ReadBitVec3Coord
|
||||
#define BF_ReadString( bf ) BF_ReadStringExt( bf, false )
|
||||
#define BF_ReadStringLine( bf ) BF_ReadStringExt( bf, true )
|
||||
|
@ -45,6 +46,7 @@ void BF_InitExt( sizebuf_t *bf, const char *pDebugName, void *pData, int nBytes,
|
|||
void BF_InitMasks( void ); // called once at startup engine
|
||||
void BF_SeekToBit( sizebuf_t *bf, int bitPos );
|
||||
void BF_SeekToByte( sizebuf_t *bf, int bytePos );
|
||||
void BF_ExciseBits( sizebuf_t *bf, int startbit, int bitstoremove );
|
||||
bool BF_CheckOverflow( sizebuf_t *bf );
|
||||
|
||||
// init writing
|
||||
|
@ -76,7 +78,7 @@ bool BF_WriteBytes( sizebuf_t *bf, const void *pBuf, int nBytes ); // same as MS
|
|||
bool BF_WriteString( sizebuf_t *bf, const char *pStr ); // returns false if it overflows the buffer.
|
||||
|
||||
// delta-write functions
|
||||
bool BF_WriteDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd );
|
||||
bool BF_WriteDeltaMovevars( sizebuf_t *sb, struct movevars_s *from, struct movevars_s *to );
|
||||
|
||||
// helper functions
|
||||
_inline int BF_GetNumBytesWritten( sizebuf_t *bf ) { return BitByte( bf->iCurBit ); }
|
||||
|
@ -111,6 +113,6 @@ bool BF_ReadBytes( sizebuf_t *bf, void *pOut, int nBytes );
|
|||
char *BF_ReadStringExt( sizebuf_t *bf, bool bLine );
|
||||
|
||||
// delta-read functions
|
||||
void BF_ReadDeltaMovevars( sizebuf_t *sb, movevars_t *from, movevars_t *cmd );
|
||||
void BF_ReadDeltaMovevars( sizebuf_t *sb, struct movevars_s *from, struct movevars_s *to );
|
||||
|
||||
#endif//NET_BUFFER_H
|
File diff suppressed because it is too large
Load Diff
|
@ -4,11 +4,15 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "common.h"
|
||||
#include "netchan.h"
|
||||
#include "byteorder.h"
|
||||
#include "mathlib.h"
|
||||
#include "protocol.h"
|
||||
#include "net_encode.h"
|
||||
#include "event_api.h"
|
||||
#include "usercmd.h"
|
||||
#include "pm_movevars.h"
|
||||
#include "entity_state.h"
|
||||
#include "weaponinfo.h"
|
||||
#include "entity_types.h"
|
||||
|
||||
|
|
|
@ -92,15 +92,15 @@ void Delta_ParseTableField( sizebuf_t *msg );
|
|||
|
||||
|
||||
// encode routines
|
||||
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to );
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to );
|
||||
void MSG_WriteDeltaUsercmd( sizebuf_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *msg, struct usercmd_s *from, struct usercmd_s *to );
|
||||
void MSG_WriteDeltaEvent( sizebuf_t *msg, struct event_args_s *from, struct event_args_s *to );
|
||||
void MSG_ReadDeltaEvent( sizebuf_t *msg, struct event_args_s *from, struct event_args_s *to );
|
||||
bool MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to );
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to );
|
||||
void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
|
||||
void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, int timebase );
|
||||
void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *msg, bool force, int timebase );
|
||||
bool MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state_t *to, int number, int timebase );
|
||||
bool MSG_WriteDeltaMovevars( sizebuf_t *msg, struct movevars_s *from, struct movevars_s *to );
|
||||
void MSG_ReadDeltaMovevars( sizebuf_t *msg, struct movevars_s *from, struct movevars_s *to );
|
||||
void MSG_WriteClientData( sizebuf_t *msg, struct clientdata_s *from, struct clientdata_s *to, int timebase );
|
||||
void MSG_ReadClientData( sizebuf_t *msg, struct clientdata_s *from, struct clientdata_s *to, int timebase );
|
||||
void MSG_WriteDeltaEntity( struct entity_state_s *from, struct entity_state_s *to, sizebuf_t *msg, bool frc, int time );
|
||||
bool MSG_ReadDeltaEntity( sizebuf_t *msg, struct entity_state_s *from, struct entity_state_s *to, int num, int time );
|
||||
|
||||
#endif//NET_ENCODE_H
|
|
@ -4,6 +4,7 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "common.h"
|
||||
#include "netchan.h"
|
||||
|
||||
#define VALUE(a) ((int )(a))
|
||||
#define NODE(a) ((void *)(a))
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// net_msg.h - message io functions
|
||||
//=======================================================================
|
||||
#ifndef NET_MSG_H
|
||||
#define NET_MSG_H
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
|
||||
ELEMENTS COMMUNICATED ACROSS THE NET
|
||||
|
||||
==========================================================
|
||||
*/
|
||||
|
||||
#include "usercmd.h"
|
||||
#include "pm_movevars.h"
|
||||
#include "entity_state.h"
|
||||
#include "net_buffer.h"
|
||||
|
||||
// config strings are a general means of communication from
|
||||
// the server to all connected clients.
|
||||
// each config string can be at most CS_SIZE characters.
|
||||
#define CS_SIZE 64 // size of one config string
|
||||
#define CS_TIME 16 // size of time string
|
||||
|
||||
// FIXME: eliminate this. Configstrings must be started from CS_MODELS
|
||||
|
||||
#define CS_NAME 0 // map name
|
||||
#define CS_MAPCHECKSUM 1 // level checksum (for catching cheater maps)
|
||||
#define CS_BACKGROUND_TRACK 3 // basename of background track
|
||||
|
||||
// 8 - 32 it's a reserved strings
|
||||
|
||||
#define CS_MODELS 8 // configstrings starts here
|
||||
#define CS_SOUNDS (CS_MODELS+MAX_MODELS) // sound names
|
||||
#define CS_DECALS (CS_SOUNDS+MAX_SOUNDS) // server decal indexes
|
||||
#define CS_EVENTS (CS_DECALS+MAX_DECALNAMES) // queue events
|
||||
#define CS_GENERICS (CS_EVENTS+MAX_EVENTS) // generic resources (e.g. color decals)
|
||||
#define CS_LIGHTSTYLES (CS_GENERICS+MAX_GENERICS) // lightstyle patterns
|
||||
#define MAX_CONFIGSTRINGS (CS_LIGHTSTYLES+MAX_LIGHTSTYLES) // total count
|
||||
|
||||
// huffman compression
|
||||
void Huff_Init( void );
|
||||
void Huff_CompressPacket( sizebuf_t *msg, int offset );
|
||||
void Huff_DecompressPacket( sizebuf_t *msg, int offset );
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
NET
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
|
||||
typedef struct netchan_s
|
||||
{
|
||||
bool fatal_error;
|
||||
netsrc_t sock;
|
||||
|
||||
int dropped; // between last packet and previous
|
||||
bool compress; // enable huffman compression
|
||||
|
||||
long last_received; // for timeouts
|
||||
long last_sent; // for retransmits
|
||||
|
||||
int drop_count; // dropped packets, cleared each level
|
||||
int good_count; // cleared each level
|
||||
|
||||
netadr_t remote_address;
|
||||
int qport; // qport value to write when transmitting
|
||||
|
||||
// sequencing variables
|
||||
int incoming_sequence;
|
||||
int incoming_acknowledged;
|
||||
int incoming_reliable_acknowledged; // single bit
|
||||
|
||||
int incoming_reliable_sequence; // single bit, maintained local
|
||||
|
||||
int outgoing_sequence;
|
||||
int reliable_sequence; // single bit
|
||||
int last_reliable_sequence; // sequence number of last send
|
||||
|
||||
// reliable staging and holding areas
|
||||
sizebuf_t message; // writing buffer to send to server
|
||||
byte message_buf[MAX_MSGLEN-16]; // leave space for header
|
||||
|
||||
// message is copied to this buffer when it is first transfered
|
||||
int reliable_length;
|
||||
byte reliable_buf[MAX_MSGLEN-16]; // unacked reliable message
|
||||
|
||||
// added for net_speeds
|
||||
size_t total_sended;
|
||||
size_t total_sended_uncompressed;
|
||||
|
||||
size_t total_received;
|
||||
size_t total_received_uncompressed;
|
||||
} netchan_t;
|
||||
|
||||
extern netadr_t net_from;
|
||||
extern sizebuf_t net_message;
|
||||
extern byte net_message_buffer[MAX_MSGLEN];
|
||||
extern cvar_t *net_speeds;
|
||||
|
||||
#define PORT_MASTER 27900
|
||||
#define PORT_CLIENT 27901
|
||||
#define PORT_SERVER 27910
|
||||
#define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2)
|
||||
#define SINGLEPLAYER_BACKUP 16 // same for single player
|
||||
|
||||
void Netchan_Init( void );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport );
|
||||
bool Netchan_NeedReliable( netchan_t *chan );
|
||||
void Netchan_Transmit( netchan_t *chan, int lengthInBytes, byte *data );
|
||||
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data );
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data );
|
||||
void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... );
|
||||
bool Netchan_Process( netchan_t *chan, sizebuf_t *msg );
|
||||
|
||||
#endif//NET_MSG_H
|
|
@ -0,0 +1,211 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// netchan.h - net channel abstraction layer
|
||||
//=======================================================================
|
||||
#ifndef NET_MSG_H
|
||||
#define NET_MSG_H
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
|
||||
ELEMENTS COMMUNICATED ACROSS THE NET
|
||||
|
||||
==========================================================
|
||||
*/
|
||||
#include "net_buffer.h"
|
||||
|
||||
// 0 == regular, 1 == file stream
|
||||
#define MAX_STREAMS 2
|
||||
|
||||
// flow control bytes per second limits
|
||||
#define MAX_RATE 20000
|
||||
#define MIN_RATE 1000
|
||||
|
||||
// default data rate
|
||||
#define DEFAULT_RATE (9999.0f)
|
||||
|
||||
// NETWORKING INFO
|
||||
|
||||
// This is the packet payload without any header bytes (which are attached for actual sending)
|
||||
#define NET_MAX_PAYLOAD 80000
|
||||
|
||||
// This is the payload plus any header info (excluding UDP header)
|
||||
|
||||
// Packet header is:
|
||||
// 4 bytes of outgoing seq
|
||||
// 4 bytes of incoming seq
|
||||
// and for each stream
|
||||
// {
|
||||
// byte (on/off)
|
||||
// int (fragment id)
|
||||
// short (startpos)
|
||||
// short (length)
|
||||
// }
|
||||
#define HEADER_BYTES ( 8 + MAX_STREAMS * 9 )
|
||||
|
||||
// Pad this to next higher 16 byte boundary
|
||||
// This is the largest packet that can come in/out over the wire, before processing the header
|
||||
// bytes will be stripped by the networking channel layer
|
||||
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
|
||||
|
||||
|
||||
|
||||
#define PORT_MASTER 27900
|
||||
#define PORT_CLIENT 27901
|
||||
#define PORT_SERVER 27910
|
||||
#define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2)
|
||||
#define SINGLEPLAYER_BACKUP 16 // same for single player
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
||||
NET
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
#define MAX_FLOWS 2
|
||||
|
||||
#define FLOW_OUTGOING 0
|
||||
#define FLOW_INCOMING 1
|
||||
#define MAX_LATENT 32
|
||||
|
||||
// size of fragmentation buffer internal buffers
|
||||
#define FRAGMENT_SIZE 1400
|
||||
|
||||
#define FRAG_NORMAL_STREAM 0
|
||||
#define FRAG_FILE_STREAM 1
|
||||
|
||||
// message data
|
||||
typedef struct
|
||||
{
|
||||
int size; // size of message sent/received
|
||||
double time; // time that message was sent/received
|
||||
} flowstats_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
flowstats_t stats[MAX_LATENT]; // data for last MAX_LATENT messages
|
||||
int current; // current message position
|
||||
double nextcompute; // time when we should recompute k/sec data
|
||||
float kbytespersec; // average data
|
||||
float avgkbytespersec;
|
||||
int totalbytes;
|
||||
} flow_t;
|
||||
|
||||
// generic fragment structure
|
||||
typedef struct fragbuf_s
|
||||
{
|
||||
struct fragbuf_s *next; // next buffer in chain
|
||||
int bufferid; // id of this buffer
|
||||
sizebuf_t frag_message; // message buffer where raw data is stored
|
||||
byte frag_message_buf[FRAGMENT_SIZE]; // the actual data sits here
|
||||
bool isfile; // is this a file buffer?
|
||||
bool isbuffer; // is this file buffer from memory ( custom decal, etc. ).
|
||||
char filename[CS_SIZE]; // name of the file to save out on remote host
|
||||
int foffset; // offset in file from which to read data
|
||||
int size; // size of data to read at that offset
|
||||
} fragbuf_t;
|
||||
|
||||
// Waiting list of fragbuf chains
|
||||
typedef struct fragbufwaiting_s
|
||||
{
|
||||
struct fragbufwaiting_s *next; // next chain in waiting list
|
||||
int fragbufcount; // number of buffers in this chain
|
||||
fragbuf_t *fragbufs; // the actual buffers
|
||||
} fragbufwaiting_t;
|
||||
|
||||
// Network Connection Channel
|
||||
typedef struct netchan_s
|
||||
{
|
||||
|
||||
netsrc_t sock; // NS_SERVER or NS_CLIENT, depending on channel.
|
||||
netadr_t remote_address; // address this channel is talking to.
|
||||
int qport; // qport value to write when transmitting
|
||||
|
||||
int dropped; // between last packet and previous
|
||||
bool compress; // enable huffman compression
|
||||
|
||||
long last_received; // for timeouts
|
||||
long last_sent; // for retransmits
|
||||
|
||||
double rate; // bandwidth choke. bytes per second
|
||||
long cleartime; // if realtime > cleartime, free to send next packet
|
||||
|
||||
int drop_count; // dropped packets, cleared each level
|
||||
int good_count; // cleared each level
|
||||
|
||||
// Sequencing variables
|
||||
int incoming_sequence; // increasing count of sequence numbers
|
||||
int incoming_acknowledged; // # of last outgoing message that has been ack'd.
|
||||
int incoming_reliable_acknowledged; // toggles T/F as reliable messages are received.
|
||||
int incoming_reliable_sequence; // single bit, maintained local
|
||||
int outgoing_sequence; // message we are sending to remote
|
||||
int reliable_sequence; // whether the message contains reliable payload, single bit
|
||||
int last_reliable_sequence; // outgoing sequence number of last send that had reliable data
|
||||
|
||||
// staging and holding areas
|
||||
sizebuf_t message;
|
||||
byte message_buf[NET_MAX_PAYLOAD];
|
||||
|
||||
// reliable message buffer.
|
||||
// we keep adding to it until reliable is acknowledged. Then we clear it.
|
||||
int reliable_length;
|
||||
byte reliable_buf[NET_MAX_PAYLOAD]; // unacked reliable message
|
||||
|
||||
// Waiting list of buffered fragments to go onto queue.
|
||||
// Multiple outgoing buffers can be queued in succession
|
||||
fragbufwaiting_t *waitlist[MAX_STREAMS];
|
||||
|
||||
int reliable_fragment[MAX_STREAMS]; // is reliable waiting buf a fragment?
|
||||
uint reliable_fragid[MAX_STREAMS]; // buffer id for each waiting fragment
|
||||
|
||||
fragbuf_t *fragbufs[MAX_STREAMS]; // the current fragment being set
|
||||
int fragbufcount[MAX_STREAMS]; // the total number of fragments in this stream
|
||||
|
||||
short frag_startpos[MAX_STREAMS]; // position in outgoing buffer where frag data starts
|
||||
short frag_length[MAX_STREAMS]; // length of frag data in the buffer
|
||||
|
||||
fragbuf_t *incomingbufs[MAX_STREAMS]; // incoming fragments are stored here
|
||||
bool incomingready[MAX_STREAMS]; // set to true when incoming data is ready
|
||||
|
||||
// Only referenced by the FRAG_FILE_STREAM component
|
||||
char incomingfilename[CS_SIZE]; // Name of file being downloaded
|
||||
|
||||
// incoming and outgoing flow metrics
|
||||
flow_t flow[MAX_FLOWS];
|
||||
|
||||
// added for net_speeds
|
||||
size_t total_sended;
|
||||
size_t total_sended_uncompressed;
|
||||
|
||||
size_t total_received;
|
||||
size_t total_received_uncompressed;
|
||||
} netchan_t;
|
||||
|
||||
extern netadr_t net_from;
|
||||
extern sizebuf_t net_message;
|
||||
extern byte net_message_buffer[MAX_MSGLEN];
|
||||
extern cvar_t *net_speeds;
|
||||
|
||||
void Netchan_Init( void );
|
||||
void Netchan_Shutdown( void );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport );
|
||||
bool Netchan_CopyNormalFragments( netchan_t *chan, sizebuf_t *msg );
|
||||
bool Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg );
|
||||
void Netchan_CreateFragments( bool server, netchan_t *chan, sizebuf_t *msg );
|
||||
void Netchan_Transmit( netchan_t *chan, int lengthInBytes, byte *data );
|
||||
void Netchan_TransmitBits( netchan_t *chan, int lengthInBits, byte *data );
|
||||
void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data );
|
||||
void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... );
|
||||
bool Netchan_Process( netchan_t *chan, sizebuf_t *msg );
|
||||
void Netchan_UpdateProgress( netchan_t *chan );
|
||||
bool Netchan_IncomingReady( netchan_t *chan );
|
||||
void Netchan_Clear( netchan_t *chan );
|
||||
|
||||
// huffman compression
|
||||
void Huff_Init( void );
|
||||
void Huff_CompressPacket( sizebuf_t *msg, int offset );
|
||||
void Huff_DecompressPacket( sizebuf_t *msg, int offset );
|
||||
|
||||
#endif//NET_MSG_H
|
|
@ -254,6 +254,15 @@ loc0:
|
|||
|
||||
// find the point distances
|
||||
node = hull->clipnodes + num;
|
||||
|
||||
if( hull->planes == NULL )
|
||||
{
|
||||
if( hull == &pm_boxhull )
|
||||
com.error( "temp hull without planes\n" );
|
||||
else com.error( "Hull %i without planes\n", hull - worldmodel->hulls );
|
||||
}
|
||||
ASSERT( node != NULL );
|
||||
|
||||
plane = hull->planes + node->planenum;
|
||||
|
||||
if( plane->type < 3 )
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
//=======================================================================
|
||||
|
||||
#include "common.h"
|
||||
#include "netchan.h"
|
||||
#include "cm_local.h"
|
||||
#include "input.h"
|
||||
|
||||
|
@ -710,6 +711,7 @@ void Host_InitCommon( const int argc, const char **argv )
|
|||
void Host_FreeCommon( void )
|
||||
{
|
||||
IN_Shutdown();
|
||||
Netchan_Shutdown();
|
||||
Mem_FreePool( &host.mempool );
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "eiface.h"
|
||||
#include "cm_local.h"
|
||||
#include "pm_defs.h"
|
||||
#include "pm_movevars.h"
|
||||
#include "entity_state.h"
|
||||
#include "netchan.h"
|
||||
#include "world.h"
|
||||
|
||||
//=============================================================================
|
||||
|
|
|
@ -75,8 +75,8 @@ void SV_DirectConnect( netadr_t from )
|
|||
sv_client_t temp, *cl, *newcl;
|
||||
edict_t *ent;
|
||||
int i, edictnum;
|
||||
int version;
|
||||
int qport, count = 0;
|
||||
int qport, version;
|
||||
int count = 0;
|
||||
int challenge;
|
||||
|
||||
version = com.atoi( Cmd_Argv( 1 ));
|
||||
|
@ -96,7 +96,7 @@ void SV_DirectConnect( netadr_t from )
|
|||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
{
|
||||
if( cl->state == cs_free ) continue;
|
||||
if( NET_CompareBaseAdr(from, cl->netchan.remote_address) && (cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port ))
|
||||
if( NET_CompareBaseAdr( from, cl->netchan.remote_address ) && ( cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port ))
|
||||
{
|
||||
if( !NET_IsLocalAddress( from ) && ( svs.realtime - cl->lastconnect ) < sv_reconnect_limit->value * 1000 )
|
||||
{
|
||||
|
@ -139,7 +139,7 @@ void SV_DirectConnect( netadr_t from )
|
|||
for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
{
|
||||
if( cl->state == cs_free ) continue;
|
||||
if( NET_CompareBaseAdr( from, cl->netchan.remote_address ) && (cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port ))
|
||||
if( NET_CompareBaseAdr( from, cl->netchan.remote_address ) && ( cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port ))
|
||||
{
|
||||
MsgDev( D_INFO, "%s:reconnect\n", NET_AdrToString( from ));
|
||||
newcl = cl;
|
||||
|
@ -360,6 +360,9 @@ void SV_DropClient( sv_client_t *drop )
|
|||
drop->state = cs_zombie; // become free in a few seconds
|
||||
drop->name[0] = 0;
|
||||
|
||||
// Throw away any residual garbage in the channel.
|
||||
Netchan_Clear( &drop->netchan );
|
||||
|
||||
SV_RefreshUserinfo(); // refresh userinfo on disconnect
|
||||
|
||||
// if this was the last client on the server, send a heartbeat
|
||||
|
@ -444,9 +447,9 @@ char *SV_StatusString( void )
|
|||
int statusLength;
|
||||
int playerLength;
|
||||
|
||||
com.strcpy( status, Cvar_Serverinfo());
|
||||
com.strcpy( status, Cvar_Serverinfo( ));
|
||||
com.strcat( status, "\n" );
|
||||
statusLength = com.strlen(status);
|
||||
statusLength = com.strlen( status );
|
||||
|
||||
for( i = 0; i < sv_maxclients->integer; i++ )
|
||||
{
|
||||
|
@ -1401,10 +1404,10 @@ void SV_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
else if( !com.strcmp( c, "getchallenge" )) SV_GetChallenge( from );
|
||||
else if( !com.strcmp( c, "connect" )) SV_DirectConnect( from );
|
||||
else if( !com.strcmp( c, "rcon" )) SV_RemoteCommand( from, msg );
|
||||
else if( svgame.dllFuncs.pfnConnectionlessPacket( &net_from, args, buf, &len ))
|
||||
else if( svgame.dllFuncs.pfnConnectionlessPacket( &from, args, buf, &len ))
|
||||
{
|
||||
// user out of band message (must be handled in CL_ConnectionlessPacket)
|
||||
if( len > 0 ) Netchan_OutOfBand( NS_SERVER, net_from, len, buf );
|
||||
if( len > 0 ) Netchan_OutOfBand( NS_SERVER, from, len, buf );
|
||||
}
|
||||
else MsgDev( D_ERROR, "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args );
|
||||
}
|
||||
|
|
|
@ -578,7 +578,7 @@ void SV_Status_f( void )
|
|||
l = 24 - com.strlen( cl->name );
|
||||
for( j = 0; j < l; j++ ) Msg( " " );
|
||||
Msg( "%g ", ( svs.realtime - cl->lastmessage ) * 0.001f );
|
||||
s = NET_AdrToString( cl->netchan.remote_address );
|
||||
s = NET_BaseAdrToString( cl->netchan.remote_address );
|
||||
Msg( "%s", s );
|
||||
l = 22 - com.strlen( s );
|
||||
for( j = 0; j < l; j++ ) Msg( " " );
|
||||
|
|
|
@ -123,6 +123,16 @@ void SV_ActivateServer( void )
|
|||
// create a baseline for more efficient communications
|
||||
SV_CreateBaseline();
|
||||
|
||||
// Send serverinfo to all connected clients
|
||||
for( i = 0; i < sv_maxclients->integer; i++ )
|
||||
{
|
||||
if( svs.clients[i].state >= cs_connected )
|
||||
{
|
||||
Netchan_Clear( &svs.clients[i].netchan );
|
||||
svs.clients[i].lastframe = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// run two frames to allow everything to settle
|
||||
for( i = 0; !sv.loadgame && i < 2; i++ )
|
||||
SV_Physics();
|
||||
|
|
|
@ -331,6 +331,22 @@ void SV_ReadPackets( void )
|
|||
SV_ExecuteClientMessage( cl, &net_message );
|
||||
}
|
||||
}
|
||||
|
||||
// Fragmentation/reassembly sending takes priority over all game messages, want this in the future?
|
||||
if( Netchan_IncomingReady( &cl->netchan ))
|
||||
{
|
||||
if( Netchan_CopyNormalFragments( &cl->netchan, &net_message ))
|
||||
{
|
||||
BF_Clear( &net_message );
|
||||
SV_ExecuteClientMessage( cl, &net_message );
|
||||
}
|
||||
|
||||
if( Netchan_CopyFileFragments( &cl->netchan, &net_message ))
|
||||
{
|
||||
// SV_ProcessFile( cl, cl->netchan.incomingfilename );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -430,7 +430,7 @@ void SV_InitClientMove( void )
|
|||
|
||||
Pmove_Init ();
|
||||
|
||||
svgame.pmove->server = false; // running at client
|
||||
svgame.pmove->server = true;
|
||||
svgame.pmove->movevars = &svgame.movevars;
|
||||
svgame.pmove->runfuncs = false;
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ hull_t *SV_HullForEntity( edict_t *ent, int hullNumber, vec3_t mins, vec3_t maxs
|
|||
|
||||
if( hullNumber == -1 )
|
||||
{
|
||||
#if 1
|
||||
#if 0 // more precision but doesn't matched with HL gameplay
|
||||
float curdiff;
|
||||
float lastdiff = 999;
|
||||
int i;
|
||||
|
@ -139,38 +139,34 @@ hull_t *SV_HullForEntity( edict_t *ent, int hullNumber, vec3_t mins, vec3_t maxs
|
|||
lastdiff = curdiff;
|
||||
}
|
||||
}
|
||||
|
||||
// TraceHull stuff
|
||||
hull = &model->hulls[hullNumber];
|
||||
|
||||
// calculate an offset value to center the origin
|
||||
// NOTE: never get offset of drawing hull
|
||||
if( !hullNumber ) VectorCopy( hull->clip_mins, offset );
|
||||
else VectorSubtract( hull->clip_mins, mins, offset );
|
||||
#else
|
||||
if( size[0] < 3 )
|
||||
if( size[0] <= 8.0f )
|
||||
{
|
||||
// point hull
|
||||
hullNumber = 0;
|
||||
}
|
||||
else if( size[0] <= 36 )
|
||||
{
|
||||
if( size[2] <= 36 )
|
||||
{
|
||||
// head hull (ducked)
|
||||
hullNumber = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// human hull
|
||||
hullNumber = 1;
|
||||
}
|
||||
hull = &model->hulls[0];
|
||||
VectorCopy( hull->clip_mins, offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
// large hull
|
||||
hullNumber = 2;
|
||||
if( size[0] <= 36.0f )
|
||||
{
|
||||
if( size[2] <= 36.0f )
|
||||
hull = &model->hulls[3];
|
||||
else hull = &model->hulls[1];
|
||||
}
|
||||
else hull = &model->hulls[2];
|
||||
|
||||
VectorSubtract( hull->clip_mins, mins, offset );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// TraceHull stuff
|
||||
hull = &model->hulls[hullNumber];
|
||||
|
||||
// calculate an offset value to center the origin
|
||||
VectorSubtract( hull->clip_mins, mins, offset );
|
||||
VectorAdd( offset, ent->v.origin, offset );
|
||||
}
|
||||
else
|
||||
|
|
Reference in New Issue