mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
Networking fixes
This commit is contained in:
parent
3dc4418a93
commit
92a5883243
9 changed files with 246 additions and 90 deletions
|
@ -1826,7 +1826,16 @@ wombat: sending conect here: an example connect string from MOHAA looks like thi
|
|||
port = Cvar_VariableValue ("net_qport");
|
||||
|
||||
Q_strncpyz( info, Cvar_InfoString( CVAR_USERINFO ), sizeof( info ) );
|
||||
Info_SetValueForKey( info, "protocol", va("%i", PROTOCOL_VERSION ) );
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(com_legacyprotocol->integer == com_protocol->integer)
|
||||
clc.compat = qtrue;
|
||||
|
||||
if(clc.compat)
|
||||
Info_SetValueForKey(info, "protocol", va("%i", com_legacyprotocol->integer));
|
||||
else
|
||||
#endif
|
||||
Info_SetValueForKey(info, "protocol", va("%i", com_protocol->integer));
|
||||
Info_SetValueForKey( info, "qport", va("%i", port ) );
|
||||
Info_SetValueForKey(info, "challenge", va("%i", clc.challenge));
|
||||
Info_SetValueForKey(info, "version", TARGET_GAME_VERSION);
|
||||
|
@ -2124,7 +2133,15 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
|
|||
NET_AdrToString( clc.serverAddress ) );
|
||||
return;
|
||||
}
|
||||
Netchan_Setup (NS_CLIENT, &clc.netchan, from, Cvar_VariableValue( "net_qport" ) );
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
Netchan_Setup(NS_CLIENT, &clc.netchan, from, Cvar_VariableValue("net_qport"),
|
||||
clc.challenge, clc.compat);
|
||||
#else
|
||||
Netchan_Setup(NS_CLIENT, &clc.netchan, from, Cvar_VariableValue("net_qport"),
|
||||
clc.challenge, qfalse);
|
||||
#endif
|
||||
|
||||
clc.state = CA_CONNECTED;
|
||||
clc.lastPacketSentTime = -9999; // send first packet immediately
|
||||
return;
|
||||
|
|
|
@ -240,6 +240,10 @@ typedef struct {
|
|||
int timeDemoMaxDuration; // maximum frame duration
|
||||
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat;
|
||||
#endif
|
||||
|
||||
// big stuff at end of structure so most offsets are 15 bits or less
|
||||
netchan_t netchan;
|
||||
|
||||
|
|
|
@ -1455,6 +1455,17 @@ void Com_Init( char *commandLine ) {
|
|||
s = va( "%s %s %s", PRODUCT_VERSION_FULL, PLATFORM_STRING, PRODUCT_DATE );
|
||||
com_version = Cvar_Get( "version", s, CVAR_ROM | CVAR_SERVERINFO );
|
||||
com_shortversion = Cvar_Get( "shortversion", TARGET_GAME_VERSION, CVAR_ROM );
|
||||
com_gamename = Cvar_Get("com_gamename", TARGET_GAME_NAME, CVAR_SERVERINFO | CVAR_INIT);
|
||||
com_protocol = Cvar_Get("com_protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO | CVAR_INIT);
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
com_legacyprotocol = Cvar_Get("com_legacyprotocol", va("%i", PROTOCOL_LEGACY_VERSION), CVAR_INIT);
|
||||
|
||||
// Keep for compatibility with old mods / mods that haven't updated yet.
|
||||
if(com_legacyprotocol->integer > 0)
|
||||
Cvar_Get("protocol", com_legacyprotocol->string, CVAR_ROM);
|
||||
else
|
||||
#endif
|
||||
Cvar_Get("protocol", com_protocol->string, CVAR_ROM);
|
||||
|
||||
Sys_Init();
|
||||
Netchan_Init( Com_Milliseconds() & 0xffff ); // pick a port value that should be nice and random
|
||||
|
|
|
@ -83,7 +83,8 @@ Netchan_Setup
|
|||
called to open a channel to a remote system
|
||||
==============
|
||||
*/
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ) {
|
||||
void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge, qboolean compat)
|
||||
{
|
||||
Com_Memset (chan, 0, sizeof(*chan));
|
||||
|
||||
chan->sock = sock;
|
||||
|
@ -91,6 +92,11 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport ) {
|
|||
chan->qport = qport;
|
||||
chan->incomingSequence = 0;
|
||||
chan->outgoingSequence = 1;
|
||||
chan->challenge = challenge;
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
chan->compat = compat;
|
||||
#endif
|
||||
}
|
||||
|
||||
// TTimo: unused, commenting out to make gcc happy
|
||||
|
|
|
@ -48,6 +48,8 @@ extern "C" {
|
|||
#define PRODUCT_DATE __DATE__
|
||||
|
||||
#define BASEGAME "main"
|
||||
// We're always legacy
|
||||
#define LEGACY_PROTOCOL
|
||||
|
||||
//
|
||||
// The target type specifies which content pack the engine targets.
|
||||
|
|
|
@ -288,10 +288,14 @@ typedef struct {
|
|||
int challenge;
|
||||
int lastSentTime;
|
||||
int lastSentSize;
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat;
|
||||
#endif
|
||||
} netchan_t;
|
||||
|
||||
void Netchan_Init( int qport );
|
||||
void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport );
|
||||
void Netchan_Setup(netsrc_t sock, netchan_t *chan, netadr_t adr, int qport, int challenge, qboolean compat);
|
||||
|
||||
void Netchan_Transmit( netchan_t *chan, size_t length, const byte *data );
|
||||
void Netchan_TransmitNextFragment( netchan_t *chan );
|
||||
|
@ -307,7 +311,8 @@ PROTOCOL
|
|||
==============================================================
|
||||
*/
|
||||
|
||||
#define PROTOCOL_VERSION TARGET_GAME_PROTOCOL
|
||||
#define PROTOCOL_VERSION TARGET_GAME_PROTOCOL
|
||||
#define PROTOCOL_LEGACY_VERSION PROTOCOL_VERSION
|
||||
// su44: MoHAA v 1.00 uses protocol version 6
|
||||
|
||||
// maintain a list of compatible protocols for demo playing
|
||||
|
|
|
@ -119,6 +119,9 @@ typedef enum {
|
|||
typedef struct netchan_buffer_s {
|
||||
msg_t msg;
|
||||
byte msgBuffer[MAX_MSGLEN];
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
char clientCommandString[MAX_STRING_CHARS]; // valid command string for SV_Netchan_Encode
|
||||
#endif
|
||||
struct netchan_buffer_s *next;
|
||||
} netchan_buffer_t;
|
||||
|
||||
|
@ -187,7 +190,11 @@ typedef struct client_s {
|
|||
qboolean locprint;
|
||||
int XOffset;
|
||||
int YOffset;
|
||||
char centerprint[ 256 ];
|
||||
char centerprint[256];
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat;
|
||||
#endif
|
||||
} client_t;
|
||||
|
||||
//=============================================================================
|
||||
|
@ -542,6 +549,7 @@ void SV_ClipToEntity( trace_t *trace, const vec3_t start, const vec3_t mins, con
|
|||
void SV_Netchan_Transmit( client_t *client, msg_t *msg);
|
||||
int SV_Netchan_TransmitNextFragment( client_t *client );
|
||||
qboolean SV_Netchan_Process( client_t *client, msg_t *msg );
|
||||
void SV_Netchan_FreeQueue(client_t *client);
|
||||
|
||||
//
|
||||
// sv_gamespy.c
|
||||
|
|
|
@ -237,16 +237,28 @@ void SV_DirectConnect( netadr_t from ) {
|
|||
const char *denied;
|
||||
int count;
|
||||
char *ip;
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat = qfalse;
|
||||
#endif
|
||||
|
||||
Com_DPrintf( "SVC_DirectConnect ()\n" );
|
||||
|
||||
Q_strncpyz( userinfo, Cmd_Argv( 1 ), sizeof( userinfo ) );
|
||||
|
||||
version = atoi( Info_ValueForKey( userinfo, "protocol" ) );
|
||||
if ( version != PROTOCOL_VERSION ) {
|
||||
NET_OutOfBandPrint( NS_SERVER, from, "print\nServer uses protocol version %i.\n", PROTOCOL_VERSION );
|
||||
Com_DPrintf (" rejected connect from version %i\n", version);
|
||||
return;
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(version > 0 && com_legacyprotocol->integer == version)
|
||||
compat = qtrue;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if(version != com_protocol->integer)
|
||||
{
|
||||
NET_OutOfBandPrint(NS_SERVER, from, "print\nServer uses protocol version %i "
|
||||
"(yours is %i).\n", com_protocol->integer, version);
|
||||
Com_DPrintf(" rejected connect from version %i\n", version);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
challenge = atoi( Info_ValueForKey( userinfo, "challenge" ) );
|
||||
|
@ -416,7 +428,12 @@ gotnewcl:
|
|||
newcl->challenge = challenge;
|
||||
|
||||
// save the address
|
||||
Netchan_Setup (NS_SERVER, &newcl->netchan , from, qport);
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
newcl->compat = compat;
|
||||
Netchan_Setup(NS_SERVER, &newcl->netchan, from, qport, challenge, compat);
|
||||
#else
|
||||
Netchan_Setup(NS_SERVER, &newcl->netchan, from, qport, challenge, qfalse);
|
||||
#endif
|
||||
// init the netchan queue
|
||||
newcl->netchan_end_queue = &newcl->netchan_start_queue;
|
||||
|
||||
|
@ -468,6 +485,31 @@ gotnewcl:
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
SV_FreeClient
|
||||
|
||||
Destructor for data allocated in a client structure
|
||||
=====================
|
||||
*/
|
||||
void SV_FreeClient(client_t* client)
|
||||
{
|
||||
#ifdef USE_VOIP
|
||||
int index;
|
||||
|
||||
for (index = client->queuedVoipIndex; index < client->queuedVoipPackets; index++)
|
||||
{
|
||||
index %= ARRAY_LEN(client->voipPacket);
|
||||
|
||||
Z_Free(client->voipPacket[index]);
|
||||
}
|
||||
|
||||
client->queuedVoipPackets = 0;
|
||||
#endif
|
||||
|
||||
SV_Netchan_FreeQueue(client);
|
||||
SV_CloseDownload(client);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
|
@ -496,10 +538,10 @@ void SV_DropClient( client_t *drop, const char *reason ) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Kill any download
|
||||
SV_CloseDownload( drop );
|
||||
// Free all allocated data on the client structure
|
||||
SV_FreeClient(drop);
|
||||
|
||||
// tell everyone why they got dropped
|
||||
SV_SendServerCommand( NULL, "print \"%s %s\n\"", drop->name, reason );
|
||||
|
|
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/qcommon.h"
|
||||
#include "server.h"
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
/*
|
||||
==============
|
||||
SV_Netchan_Encode
|
||||
|
@ -33,30 +34,32 @@ SV_Netchan_Encode
|
|||
|
||||
==============
|
||||
*/
|
||||
static void SV_Netchan_Encode( client_t *client, msg_t *msg ) {
|
||||
long reliableAcknowledge, i, index;
|
||||
static void SV_Netchan_Encode(client_t *client, msg_t *msg, const char *clientCommandString)
|
||||
{
|
||||
long i, index;
|
||||
byte key, *string;
|
||||
int srdc, sbit, soob;
|
||||
|
||||
int srdc, sbit;
|
||||
qboolean 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 = 0;
|
||||
|
||||
reliableAcknowledge = MSG_ReadLong(msg);
|
||||
srdc = msg->readcount;
|
||||
sbit = msg->bit;
|
||||
soob = msg->oob;
|
||||
|
||||
msg->oob = soob;
|
||||
msg->bit = sbit;
|
||||
msg->readcount = srdc;
|
||||
|
||||
string = (byte *)client->lastClientCommandString;
|
||||
msg->bit = 0;
|
||||
msg->readcount = 0;
|
||||
msg->oob = qfalse;
|
||||
|
||||
/* reliableAcknowledge = */ MSG_ReadLong(msg);
|
||||
|
||||
msg->oob = soob;
|
||||
msg->bit = sbit;
|
||||
msg->readcount = srdc;
|
||||
|
||||
string = (byte *) clientCommandString;
|
||||
index = 0;
|
||||
// xor the client challenge with the netchan sequence number
|
||||
key = client->challenge ^ client->netchan.outgoingSequence;
|
||||
|
@ -89,23 +92,24 @@ SV_Netchan_Decode
|
|||
*/
|
||||
static void SV_Netchan_Decode( client_t *client, msg_t *msg ) {
|
||||
int serverId, messageAcknowledge, reliableAcknowledge;
|
||||
int i, index, srdc, sbit, soob;
|
||||
int i, index, srdc, sbit;
|
||||
qboolean soob;
|
||||
byte key, *string;
|
||||
|
||||
srdc = msg->readcount;
|
||||
sbit = msg->bit;
|
||||
soob = msg->oob;
|
||||
|
||||
msg->oob = 0;
|
||||
|
||||
serverId = MSG_ReadLong(msg);
|
||||
srdc = msg->readcount;
|
||||
sbit = msg->bit;
|
||||
soob = msg->oob;
|
||||
|
||||
msg->oob = qfalse;
|
||||
|
||||
serverId = MSG_ReadLong(msg);
|
||||
messageAcknowledge = MSG_ReadLong(msg);
|
||||
reliableAcknowledge = MSG_ReadLong(msg);
|
||||
|
||||
msg->oob = soob;
|
||||
msg->bit = sbit;
|
||||
msg->readcount = srdc;
|
||||
|
||||
msg->oob = soob;
|
||||
msg->bit = sbit;
|
||||
msg->readcount = srdc;
|
||||
|
||||
string = (byte *)client->reliableCommands[ reliableAcknowledge & (MAX_RELIABLE_COMMANDS-1) ];
|
||||
index = 0;
|
||||
//
|
||||
|
@ -125,45 +129,84 @@ static void SV_Netchan_Decode( client_t *client, msg_t *msg ) {
|
|||
*(msg->data + i) = *(msg->data + i) ^ key;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_Netchan_FreeQueue
|
||||
=================
|
||||
*/
|
||||
void SV_Netchan_FreeQueue(client_t *client)
|
||||
{
|
||||
netchan_buffer_t *netbuf, *next;
|
||||
|
||||
for(netbuf = client->netchan_start_queue; netbuf; netbuf = next)
|
||||
{
|
||||
next = netbuf->next;
|
||||
Z_Free(netbuf);
|
||||
}
|
||||
|
||||
client->netchan_start_queue = NULL;
|
||||
client->netchan_end_queue = &client->netchan_start_queue;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_Netchan_TransmitNextInQueue
|
||||
=================
|
||||
*/
|
||||
void SV_Netchan_TransmitNextInQueue(client_t *client)
|
||||
{
|
||||
netchan_buffer_t *netbuf;
|
||||
|
||||
Com_DPrintf("#462 Netchan_TransmitNextFragment: popping a queued message for transmit\n");
|
||||
netbuf = client->netchan_start_queue;
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(client->compat)
|
||||
SV_Netchan_Encode(client, &netbuf->msg, netbuf->clientCommandString);
|
||||
#endif
|
||||
|
||||
Netchan_Transmit(&client->netchan, netbuf->msg.cursize, netbuf->msg.data);
|
||||
|
||||
// pop from queue
|
||||
client->netchan_start_queue = netbuf->next;
|
||||
if(!client->netchan_start_queue)
|
||||
{
|
||||
Com_DPrintf("#462 Netchan_TransmitNextFragment: emptied queue\n");
|
||||
client->netchan_end_queue = &client->netchan_start_queue;
|
||||
}
|
||||
else
|
||||
Com_DPrintf("#462 Netchan_TransmitNextFragment: remaining queued message\n");
|
||||
|
||||
Z_Free(netbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_Netchan_TransmitNextFragment
|
||||
Transmit the next fragment and the next queued packet
|
||||
Return number of ms until next message can be sent based on throughput given by client rate,
|
||||
-1 if no packet was sent.
|
||||
=================
|
||||
*/
|
||||
int SV_Netchan_TransmitNextFragment( client_t *client ) {
|
||||
Netchan_TransmitNextFragment( &client->netchan );
|
||||
if (!client->netchan.unsentFragments)
|
||||
{
|
||||
// make sure the netchan queue has been properly initialized (you never know)
|
||||
if (!client->netchan_end_queue) {
|
||||
Com_Error(ERR_DROP, "netchan queue is not properly initialized in SV_Netchan_TransmitNextFragment\n");
|
||||
}
|
||||
// the last fragment was transmitted, check wether we have queued messages
|
||||
if (client->netchan_start_queue) {
|
||||
netchan_buffer_t* netbuf;
|
||||
Com_DPrintf("#462 Netchan_TransmitNextFragment: popping a queued message for transmit\n");
|
||||
netbuf = client->netchan_start_queue;
|
||||
SV_Netchan_Encode(client, &netbuf->msg);
|
||||
Netchan_Transmit(&client->netchan, netbuf->msg.cursize, netbuf->msg.data);
|
||||
// pop from queue
|
||||
client->netchan_start_queue = netbuf->next;
|
||||
if (!client->netchan_start_queue) {
|
||||
Com_DPrintf("#462 Netchan_TransmitNextFragment: emptied queue\n");
|
||||
client->netchan_end_queue = &client->netchan_start_queue;
|
||||
}
|
||||
else
|
||||
Com_DPrintf("#462 Netchan_TransmitNextFragment: remaining queued message\n");
|
||||
Z_Free(netbuf);
|
||||
return SV_RateMsec(client);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return SV_RateMsec(client);
|
||||
}
|
||||
|
||||
return -1;
|
||||
int SV_Netchan_TransmitNextFragment(client_t *client)
|
||||
{
|
||||
if(client->netchan.unsentFragments)
|
||||
{
|
||||
Netchan_TransmitNextFragment(&client->netchan);
|
||||
return SV_RateMsec(client);
|
||||
}
|
||||
else if(client->netchan_start_queue)
|
||||
{
|
||||
SV_Netchan_TransmitNextInQueue(client);
|
||||
return SV_RateMsec(client);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -178,22 +221,35 @@ 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 ) {
|
||||
void SV_Netchan_Transmit( client_t *client, msg_t *msg)
|
||||
{
|
||||
MSG_WriteByte( msg, svc_EOF );
|
||||
if (client->netchan.unsentFragments) {
|
||||
|
||||
if(client->netchan.unsentFragments || client->netchan_start_queue)
|
||||
{
|
||||
netchan_buffer_t *netbuf;
|
||||
Com_DPrintf("#462 SV_Netchan_Transmit: unsent fragments, stacked\n");
|
||||
netbuf = (netchan_buffer_t *)Z_Malloc(sizeof(netchan_buffer_t));
|
||||
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);
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(client->compat)
|
||||
{
|
||||
Q_strncpyz(netbuf->clientCommandString, client->lastClientCommandString,
|
||||
sizeof(netbuf->clientCommandString));
|
||||
}
|
||||
#endif
|
||||
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 );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(client->compat)
|
||||
SV_Netchan_Encode(client, msg, client->lastClientCommandString);
|
||||
#endif
|
||||
Netchan_Transmit( &client->netchan, msg->cursize, msg->data );
|
||||
}
|
||||
}
|
||||
|
@ -203,12 +259,17 @@ void SV_Netchan_Transmit( client_t *client, msg_t *msg) { //int length, const by
|
|||
Netchan_SV_Process
|
||||
=================
|
||||
*/
|
||||
qboolean SV_Netchan_Process( client_t *client, msg_t *msg ) {
|
||||
int ret;
|
||||
ret = Netchan_Process( &client->netchan, msg );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
SV_Netchan_Decode( client, msg );
|
||||
return qtrue;
|
||||
qboolean SV_Netchan_Process(client_t* client, msg_t* msg) {
|
||||
int ret;
|
||||
ret = Netchan_Process(&client->netchan, msg);
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if (client->compat)
|
||||
SV_Netchan_Decode(client, msg);
|
||||
#endif
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue