08 Oct 2010

This commit is contained in:
g-cont 2010-10-08 00:00:00 +04:00 committed by Alibek Omarov
parent d8bf6a1329
commit d505b7685a
21 changed files with 1839 additions and 303 deletions

View File

@ -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 )

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -4,6 +4,7 @@
//=======================================================================
#include "common.h"
#include "netchan.h"
#define VALUE(a) ((int )(a))
#define NODE(a) ((void *)(a))

View File

@ -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

211
engine/common/netchan.h Normal file
View File

@ -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

View File

@ -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 )

View File

@ -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 );
}

View File

@ -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"
//=============================================================================

View File

@ -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 );
}

View File

@ -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( " " );

View File

@ -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();

View File

@ -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;
}

View File

@ -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;

View File

@ -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