Exemplo n.º 1
0
/*
==================
CL_ParseServerInfo
==================
*/
void CL_ParseServerInfo (void)
{
	char	*str;
	int		i;
	int		nummodels, numsounds;
	char	model_precache[MAX_MODELS][MAX_QPATH];
	char	sound_precache[MAX_SOUNDS][MAX_QPATH];
	
	Con_DPrintf ("Serverinfo packet received.\n");
//
// wipe the client_state_t struct
//
	CL_ClearState ();

// parse protocol version number
	i = MSG_ReadLong ();
	if (i != PROTOCOL_VERSION)
	{
		Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION);
		return;
	}

// parse maxclients
	cl.maxclients = MSG_ReadByte ();
	if (cl.maxclients < 1 || cl.maxclients > MAX_SCOREBOARD)
	{
		Con_Printf("Bad maxclients (%u) from server\n", cl.maxclients);
		return;
	}
	cl.scores = Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores");

// parse gametype
	cl.gametype = MSG_ReadByte ();

// parse signon message
	str = MSG_ReadString ();
	strncpy (cl.levelname, str, sizeof(cl.levelname)-1);

// seperate the printfs so the server message can have a color
	Con_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
	Con_Printf ("%c%s\n", 2, str);

//
// first we go through and touch all of the precache data that still
// happens to be in the cache, so precaching something else doesn't
// needlessly purge it
//

// precache models
	memset (cl.model_precache, 0, sizeof(cl.model_precache));
	for (nummodels=1 ; ; nummodels++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (nummodels==MAX_MODELS)
		{
			Con_Printf ("Server sent too many model precaches\n");
			return;
		}
		strcpy (model_precache[nummodels], str);
		Mod_TouchModel (str);
	}

// precache sounds
	memset (cl.sound_precache, 0, sizeof(cl.sound_precache));
	for (numsounds=1 ; ; numsounds++)
	{
		str = MSG_ReadString ();
		if (!str[0])
			break;
		if (numsounds==MAX_SOUNDS)
		{
			Con_Printf ("Server sent too many sound precaches\n");
			return;
		}
		strcpy (sound_precache[numsounds], str);
		S_TouchSound (str);
	}

//
// now we try to load everything else until a cache allocation fails
//

	for (i=1 ; i<nummodels ; i++)
	{
		cl.model_precache[i] = Mod_ForName (model_precache[i], false);
		if (cl.model_precache[i] == NULL)
		{
			Con_Printf("Model %s not found\n", model_precache[i]);
			return;
		}
		CL_KeepaliveMessage ();
	}

	S_BeginPrecaching ();
	for (i=1 ; i<numsounds ; i++)
	{
		cl.sound_precache[i] = S_PrecacheSound (sound_precache[i]);
		CL_KeepaliveMessage ();
	}
	S_EndPrecaching ();


// local state
	cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
	
	R_NewMap ();

	Hunk_Check ();		// make sure nothing is hurt
	
	noclip_anglehack = false;		// noclip is turned off at start	
}
Exemplo n.º 2
0
Arquivo: save.c Projeto: jdolan/q2pro
static int read_server_file(void)
{
    char        name[MAX_OSPATH], string[MAX_STRING_CHARS];
    mapcmd_t    cmd;
    size_t      len;

    // errors like missing file, bad version, etc are
    // non-fatal and just return to the command handler
    if (read_binary_file("save/" SAVE_CURRENT "/server.ssv"))
        return -1;

    if (MSG_ReadLong() != SAVE_MAGIC1)
        return -1;

    if (MSG_ReadLong() != SAVE_VERSION)
        return -1;

    memset(&cmd, 0, sizeof(cmd));

    // read the comment field
    MSG_ReadLong();
    MSG_ReadLong();
    if (MSG_ReadByte())
        cmd.loadgame = 2;   // autosave
    else
        cmd.loadgame = 1;   // regular savegame
    MSG_ReadString(NULL, 0);

    // read the mapcmd
    len = MSG_ReadString(cmd.buffer, sizeof(cmd.buffer));
    if (len >= sizeof(cmd.buffer))
        return -1;

    // now try to load the map
    if (!SV_ParseMapCmd(&cmd))
        return -1;

    // save pending CM to be freed later if ERR_DROP is thrown
    Com_AbortFunc(abort_func, &cmd.cm);

    // any error will drop from this point
    SV_Shutdown("Server restarted\n", ERR_RECONNECT);

    // the rest can't underflow
    msg_read.allowunderflow = qfalse;

    // read all CVAR_LATCH cvars
    // these will be things like coop, skill, deathmatch, etc
    while (1) {
        len = MSG_ReadString(name, MAX_QPATH);
        if (!len)
            break;
        if (len >= MAX_QPATH)
            Com_Error(ERR_DROP, "Savegame cvar name too long");

        len = MSG_ReadString(string, sizeof(string));
        if (len >= sizeof(string))
            Com_Error(ERR_DROP, "Savegame cvar value too long");

        Cvar_UserSet(name, string);
    }

    // start a new game fresh with new cvars
    SV_InitGame(MVD_SPAWN_DISABLED);

    // error out immediately if game doesn't support safe savegames
    if (!(g_features->integer & GMF_ENHANCED_SAVEGAMES))
        Com_Error(ERR_DROP, "Game does not support enhanced savegames");

    // read game state
    len = Q_snprintf(name, MAX_OSPATH,
                     "%s/save/" SAVE_CURRENT "/game.ssv", fs_gamedir);
    if (len >= MAX_OSPATH)
        Com_Error(ERR_DROP, "Savegame path too long");

    ge->ReadGame(name);

    // clear pending CM
    Com_AbortFunc(NULL, NULL);

    // go to the map
    SV_SpawnServer(&cmd);
    return 0;
}
Exemplo n.º 3
0
/*
=====================
CL_ParseDownload

A download message has been received from the server
=====================
*/
void CL_ParseDownload ( msg_t *msg ) {
	int		size;
	unsigned char data[MAX_MSGLEN];
	uint16_t block;

	if (!*clc.downloadTempName) {
		Com_Printf("Server sending download, but no download was requested\n");
		CL_AddReliableCommand("stopdl", qfalse);
		return;
	}

	// read the data
	block = MSG_ReadShort ( msg );

	if ( !block && !clc.downloadBlock )
	{
		// block zero is special, contains file size
		clc.downloadSize = MSG_ReadLong ( msg );

		Cvar_SetValue( "cl_downloadSize", clc.downloadSize );

		if (clc.downloadSize < 0)
		{
			Com_Error(ERR_DROP, "%s", MSG_ReadString( msg ) );
			return;
		}
	}

	size = /*(unsigned short)*/MSG_ReadShort ( msg );
	if (size < 0 || size > (int)sizeof(data))
	{
		Com_Error(ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk", size);
		return;
	}

	MSG_ReadData( msg, data, size );

	if((clc.downloadBlock & 0xFFFF) != block)
	{
		Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", (clc.downloadBlock & 0xFFFF), block);
		return;
	}

	// open the file if not opened yet
	if (!clc.download)
	{
		clc.download = FS_SV_FOpenFileWrite( clc.downloadTempName );

		if (!clc.download) {
			Com_Printf( "Could not create %s\n", clc.downloadTempName );
			CL_AddReliableCommand( "stopdl", qfalse );
			CL_NextDownload();
			return;
		}
	}

	if (size)
		FS_Write( data, size, clc.download );

	CL_AddReliableCommand( va("nextdl %d", clc.downloadBlock), qfalse );
	clc.downloadBlock++;

	clc.downloadCount += size;

	// So UI gets access to it
	Cvar_SetValue( "cl_downloadCount", clc.downloadCount );

	if (!size) { // A zero length block means EOF
		if (clc.download) {
			FS_FCloseFile( clc.download );
			clc.download = 0;

			// rename the file
			FS_SV_Rename ( clc.downloadTempName, clc.downloadName, qfalse );
		}

		// send intentions now
		// We need this because without it, we would hold the last nextdl and then start
		// loading right away.  If we take a while to load, the server is happily trying
		// to send us that last block over and over.
		// Write it twice to help make sure we acknowledge the download
		CL_WritePacket();
		CL_WritePacket();

		// get another file if needed
		CL_NextDownload ();
	}
}
Exemplo n.º 4
0
/*
===============
SV_ClientCommand
===============
*/
static bool SV_ClientCommand( client_t *cl, msg_t *msg, bool premaprestart )
{
	int        seq;
	const char *s;
	bool   clientOk = true;
	bool   floodprotect = true;

	seq = MSG_ReadLong( msg );
	s = MSG_ReadString( msg );

	// see if we have already executed it
	if ( cl->lastClientCommand >= seq )
	{
		return true;
	}

	Log::Debug( "clientCommand: %s^7 : %i : %s", cl->name, seq, s );

	// drop the connection if we have somehow lost commands
	if ( seq > cl->lastClientCommand + 1 )
	{
		Log::Notice( "Client %s lost %i clientCommands\n", cl->name, seq - cl->lastClientCommand + 1 );
		SV_DropClient( cl, "Lost reliable commands" );
		return false;
	}

	// Gordon: AHA! Need to steal this for some other stuff BOOKMARK
	// NERVE - SMF - some server game-only commands we cannot have flood protect
	if ( !Q_strncmp( "team", s, 4 ) || !Q_strncmp( "setspawnpt", s, 10 ) || !Q_strncmp( "score", s, 5 ) || !Q_stricmp( "forcetapout", s ) )
	{
//      Log::Debug( "Skipping flood protection for: %s", s );
		floodprotect = false;
	}

	// malicious users may try using too many string commands
	// to lag other players.  If we decide that we want to stall
	// the command, we will stop processing the rest of the packet,
	// including the usercmd.  This causes flooders to lag themselves
	// but not other people
	// We don't do this when the client hasn't been active yet, since it is
	// by protocol to spam a lot of commands when downloading
	if ( !com_cl_running->integer && cl->state >= clientState_t::CS_ACTIVE && // (SA) this was commented out in Wolf.  Did we do that?
	     sv_floodProtect->integer && svs.time < cl->nextReliableTime && floodprotect )
	{
		// ignore any other text messages from this client but let them keep playing
		// TTimo - moved the ignored verbose to the actual processing in SV_ExecuteClientCommand, only printing if the core doesn't intercept
		clientOk = false;
	}

	// don't allow another command for 800 msec
	if ( floodprotect && svs.time >= cl->nextReliableTime )
	{
		cl->nextReliableTime = svs.time + 800;
	}

	SV_ExecuteClientCommand( cl, s, clientOk, premaprestart );

	cl->lastClientCommand = seq;
	Com_sprintf( cl->lastClientCommandString, sizeof( cl->lastClientCommandString ), "%s", s );

	return true; // continue processing
}
Exemplo n.º 5
0
void demoConvert( const char *oldName, const char *newBaseName, qboolean smoothen ) {
	fileHandle_t	oldHandle = 0;
	fileHandle_t	newHandle = 0;
	int				temp;
	int				oldSize;
	int				msgSequence;
	msg_t			oldMsg;
	byte			oldData[ MAX_MSGLEN ];
	int				oldTime, nextTime, fullTime;
	int				clientNum;
	demoFrame_t		*workFrame;
	int				parseEntitiesNum = 0;
	demoConvert_t	*convert;
	char			bigConfigString[BIG_INFO_STRING];
	int				bigConfigNumber;
	const char		*s;
	clSnapshot_t	*oldSnap = 0;
	clSnapshot_t	*newSnap;
	int				levelCount = 0;
	char			newName[MAX_OSPATH];

	oldSize = FS_FOpenFileRead( oldName, &oldHandle, qtrue );
	if (!oldHandle) {
		Com_Printf("Failed to open %s for conversion.", oldName);
		return;
	}
	/* Alloc some memory */
	convert = Z_Malloc( sizeof( demoConvert_t) );
	/* Initialize the first workframe's strings */
	while (oldSize > 0) {
		MSG_Init( &oldMsg, oldData, sizeof( oldData ) );
		/* Read the sequence number */
		if (FS_Read( &convert->messageNum, 4, oldHandle) != 4)
			goto conversionerror;
		convert->messageNum = LittleLong( convert->messageNum );
		oldSize -= 4;
		/* Read the message size */
		if (FS_Read( &oldMsg.cursize,4, oldHandle) != 4)
			goto conversionerror;
		oldSize -= 4;
		oldMsg.cursize = LittleLong( oldMsg.cursize );
		/* Negative size signals end of demo */
		if (oldMsg.cursize < 0)
			break;
		if ( oldMsg.cursize > oldMsg.maxsize ) 
			goto conversionerror;
		/* Read the actual message */
		if (FS_Read( oldMsg.data, oldMsg.cursize, oldHandle ) != oldMsg.cursize)
			goto conversionerror;
		oldSize -= oldMsg.cursize;
		// init the bitstream
		MSG_BeginReading( &oldMsg );
		// Skip the reliable sequence acknowledge number
		MSG_ReadLong( &oldMsg );
		//
		// parse the message
		//
		while ( 1 ) {
			byte cmd;
			if ( oldMsg.readcount > oldMsg.cursize ) {
				Com_Printf ("Demo conversion, read past end of server message.\n");
				goto conversionerror;
			}
            cmd = MSG_ReadByte( &oldMsg );
			if ( cmd == svc_EOF) {
                break;
			}
			workFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES ];
			// other commands
			switch ( cmd ) {
			default:
				Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message\n");
				break;			
			case svc_nop:
				break;
			case svc_serverCommand:
				temp = MSG_ReadLong( &oldMsg );
				s = MSG_ReadString( &oldMsg );
				if (temp<=msgSequence)
					break;
//				Com_Printf( " server command %s\n", s );
				msgSequence = temp;
				Cmd_TokenizeString( s );
	
				if ( !Q_stricmp( Cmd_Argv(0), "bcs0" ) ) {
					bigConfigNumber = atoi( Cmd_Argv(1) );
					Q_strncpyz( bigConfigString, Cmd_Argv(2), sizeof( bigConfigString ));
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "bcs1" ) ) {
					Q_strcat( bigConfigString, sizeof( bigConfigString ), Cmd_Argv(2));
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "bcs2" ) ) {
					Q_strcat( bigConfigString, sizeof( bigConfigString ), Cmd_Argv(2));
					demoFrameAddString( &workFrame->string, bigConfigNumber, bigConfigString );
					break;
				}
				if ( !Q_stricmp( Cmd_Argv(0), "cs" ) ) {
					int num = atoi( Cmd_Argv(1) );
					s = Cmd_ArgsFrom( 2 );
					demoFrameAddString( &workFrame->string, num, Cmd_ArgsFrom( 2 ) );
					break;
				}
				if ( clientNum >= 0 && clientNum < MAX_CLIENTS ) {
					int len = strlen( s ) + 1;
					char *dst;
					if (workFrame->commandUsed + len + 1 > sizeof( workFrame->commandData)) {
						Com_Printf("Overflowed state command data.\n");
						goto conversionerror;
					}
					dst = workFrame->commandData + workFrame->commandUsed;
					*dst = clientNum;
					Com_Memcpy( dst+1, s, len );
					workFrame->commandUsed += len + 1;
				}
				break;
			case svc_gamestate:
				if (newHandle) {
					FS_FCloseFile( newHandle );
					newHandle = 0;
				}
				if (levelCount) {
					Com_sprintf( newName, sizeof( newName ), "%s.%d.mme", newBaseName, levelCount );
				} else {
					Com_sprintf( newName, sizeof( newName ), "%s.mme", newBaseName );
				}
				fullTime = -1;
				clientNum = -1;
				oldTime = -1;
				Com_Memset( convert, 0, sizeof( *convert ));
				convert->frames[0].string.used = 1;
				levelCount++;
				newHandle = FS_FOpenFileWrite( newName );
				if (!newHandle) {
					Com_Printf("Failed to open %s for target conversion target.\n", newName);
					goto conversionerror;
					return;
				} else {
					FS_Write ( demoHeader, strlen( demoHeader ), newHandle );
				}
				Com_sprintf( newName, sizeof( newName ), "%s.txt", newBaseName );
				workFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES ];
				msgSequence = MSG_ReadLong( &oldMsg );
				while( 1 ) {
					cmd = MSG_ReadByte( &oldMsg );
					if (cmd == svc_EOF)
						break;
					if ( cmd == svc_configstring) {
						int		num;
						const char *s;
						num = MSG_ReadShort( &oldMsg );
						s = MSG_ReadBigString( &oldMsg );
						demoFrameAddString( &workFrame->string, num, s );
					} else if ( cmd == svc_baseline ) {
						int num = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
						if ( num < 0 || num >= MAX_GENTITIES ) {
							Com_Printf( "Baseline number out of range: %i.\n", num );
							goto conversionerror;
						}
						MSG_ReadDeltaEntity( &oldMsg, &demoNullEntityState, &convert->entityBaselines[num], num );
					} else {
						Com_Printf( "Unknown block while converting demo gamestate.\n" );
						goto conversionerror;
					}
				}
				clientNum = MSG_ReadLong( &oldMsg );
				/* Skip the checksum feed */
				MSG_ReadLong( &oldMsg );
				break;
			case svc_snapshot:
				nextTime = MSG_ReadLong( &oldMsg );
				/* Delta number, not needed */
				newSnap = &convert->snapshots[convert->messageNum & PACKET_MASK];
				Com_Memset (newSnap, 0, sizeof(*newSnap));
				newSnap->deltaNum = MSG_ReadByte( &oldMsg );
				newSnap->messageNum = convert->messageNum;
				if (!newSnap->deltaNum) {
					newSnap->deltaNum = -1;
					newSnap->valid = qtrue;		// uncompressed frame
					oldSnap  = NULL;
				} else {
					newSnap->deltaNum = newSnap->messageNum - newSnap->deltaNum;
					oldSnap = &convert->snapshots[newSnap->deltaNum & PACKET_MASK];
					if (!oldSnap->valid) {
						Com_Printf( "Delta snapshot without base.\n" );
						goto conversionerror;
					} else if (oldSnap->messageNum != newSnap->deltaNum) {
						// The frame that the server did the delta from
						// is too old, so we can't reconstruct it properly.
						Com_Printf ("Delta frame too old.\n");
					} else if ( parseEntitiesNum - oldSnap->parseEntitiesNum > MAX_PARSE_ENTITIES-128 ) {
						Com_Printf ("Delta parseEntitiesNum too old.\n");
					} else {
						newSnap->valid = qtrue;	// valid delta parse
					}
				}

				/* Snapflags, not needed */
				newSnap->snapFlags = MSG_ReadByte( &oldMsg );
				// read areamask
				workFrame->areaUsed = MSG_ReadByte( &oldMsg );
				MSG_ReadData( &oldMsg, workFrame->areamask, workFrame->areaUsed );
				if (clientNum <0 || clientNum >= MAX_CLIENTS) {
					Com_Printf("Got snapshot with invalid client.\n");
					goto conversionerror;
				}
				MSG_ReadDeltaPlayerstate( &oldMsg, oldSnap ? &oldSnap->ps : &demoNullPlayerState, &newSnap->ps );
				/* Read the individual entities */
				newSnap->parseEntitiesNum = parseEntitiesNum;
				newSnap->numEntities = 0;
				Com_Memset( workFrame->entityData, 0, sizeof( workFrame->entityData ));

				/* The beast that is entity parsing */
				{
				int			newnum;
				entityState_t	*oldstate, *newstate;
				int			oldindex = 0;
				int			oldnum;
				newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
				while ( 1 ) {
					// read the entity index number
					if (oldSnap && oldindex < oldSnap->numEntities) {
						oldstate = &convert->parseEntities[(oldSnap->parseEntitiesNum + oldindex) & (MAX_PARSE_ENTITIES-1)];
						oldnum = oldstate->number;
					} else {
						oldstate = 0;
						oldnum = 99999;
					}
					newstate = &convert->parseEntities[parseEntitiesNum];
					if ( !oldstate && (newnum == (MAX_GENTITIES-1))) {
						break;
					} else if ( oldnum < newnum ) {
						*newstate = *oldstate;
						oldindex++;
					} else if (oldnum == newnum) {
						oldindex++;
						MSG_ReadDeltaEntity( &oldMsg, oldstate, newstate, newnum );
						if ( newstate->number != MAX_GENTITIES-1)
							workFrame->entityData[ newstate->number ] = 1;
						newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
					} else if (oldnum > newnum) {
						MSG_ReadDeltaEntity( &oldMsg, &convert->entityBaselines[newnum], newstate , newnum );
						if ( newstate->number != MAX_GENTITIES-1)
							workFrame->entityData[ newstate->number ] = 1;
						newnum = MSG_ReadBits( &oldMsg, GENTITYNUM_BITS );
					}
					if (newstate->number == MAX_GENTITIES-1)
						continue;
					parseEntitiesNum++;
					parseEntitiesNum &= (MAX_PARSE_ENTITIES-1);
					newSnap->numEntities++;
				}}
				/* Stop processing this further since it's an invalid snap due to lack of delta data */
				if (!newSnap->valid)
					break;

				/* Skipped snapshots will be set invalid in the circular buffer */
				if ( newSnap->messageNum - convert->lastMessageNum >= PACKET_BACKUP ) {
					convert->lastMessageNum = newSnap->messageNum - ( PACKET_BACKUP - 1 );
				}
				for ( ; convert->lastMessageNum < newSnap->messageNum ; convert->lastMessageNum++ ) {
					convert->snapshots[convert->lastMessageNum & PACKET_MASK].valid = qfalse;
				}
				convert->lastMessageNum = newSnap->messageNum + 1;

				/* compress the frame into the new format */
				if (nextTime > oldTime) {
					demoFrame_t *cleanFrame;
					int writeIndex;
					for (temp = 0;temp<newSnap->numEntities;temp++) {
						int p = (newSnap->parseEntitiesNum+temp) & (MAX_PARSE_ENTITIES-1);
						entityState_t *newState = &convert->parseEntities[p];
						workFrame->entities[newState->number] = *newState;
					}
					workFrame->clientData[clientNum] = 1;
					workFrame->clients[clientNum] = newSnap->ps;
					workFrame->serverTime = nextTime;

					/* Which frame from the cache to save */
					writeIndex = convert->frameIndex - (DEMOCONVERTFRAMES/2);
					if (writeIndex >= 0) {
						const demoFrame_t *newFrame;
						msg_t writeMsg;
						// init the message
						MSG_Init( &writeMsg, demoBuffer, sizeof (demoBuffer));
						MSG_Clear( &writeMsg );
						MSG_Bitstream( &writeMsg );
						newFrame = &convert->frames[ writeIndex  % DEMOCONVERTFRAMES];
						if ( smoothen )
							demoFrameInterpolate( convert->frames, DEMOCONVERTFRAMES, writeIndex );
						if ( nextTime > fullTime || writeIndex <= 0 ) {
							/* Plan the next time for a full write */
							fullTime = nextTime + 2000;
							demoFramePack( &writeMsg, newFrame, 0 );
						} else {
							const demoFrame_t *oldFrame = &convert->frames[ ( writeIndex -1 ) % DEMOCONVERTFRAMES];
							demoFramePack( &writeMsg, newFrame, oldFrame );
						}
						/* Write away the new data in the msg queue */
						temp = LittleLong( writeMsg.cursize );
						FS_Write (&temp, 4, newHandle );
						FS_Write ( writeMsg.data , writeMsg.cursize, newHandle );
					}

					/* Clean up the upcoming frame for all new changes */
					convert->frameIndex++;
					cleanFrame = &convert->frames[ convert->frameIndex % DEMOCONVERTFRAMES];
					cleanFrame->serverTime = 0;
					for (temp = 0;temp<MAX_GENTITIES;temp++)
						cleanFrame->entities[temp].number = MAX_GENTITIES-1;
					Com_Memset( cleanFrame->clientData, 0, sizeof ( cleanFrame->clientData ));
					Com_Memcpy( cleanFrame->string.data, workFrame->string.data, workFrame->string.used );
					Com_Memcpy( cleanFrame->string.offsets, workFrame->string.offsets, sizeof( workFrame->string.offsets ));
					cleanFrame->string.used = workFrame->string.used;
					cleanFrame->commandUsed = 0;
					/* keep track of this last frame's time */
					oldTime = nextTime;
				}
				break;
			case svc_download:
				// read block number
				temp = MSG_ReadShort ( &oldMsg );
				if (!temp)	//0 block, read file size
					MSG_ReadLong( &oldMsg );
				// read block size
				temp = MSG_ReadShort ( &oldMsg );
				// read the data block
				for ( ;temp>0;temp--)
					MSG_ReadByte( &oldMsg );
				break;
			}
		}
	}
conversionerror:
	FS_FCloseFile( oldHandle );
	FS_FCloseFile( newHandle );
	Z_Free( convert );
	return;
}
Exemplo n.º 6
0
static qsocket_t *_Datagram_Connect(char *host)
{
    struct qsockaddr sendaddr;
    struct qsockaddr readaddr;
    qsocket_t	*sock;
    int			newsock;
    int			ret;
    int			reps;
    double		start_time;
    int			control;
    char		*reason;

    // see if we can resolve the host name
    if (dfunc.GetAddrFromName(host, &sendaddr) == -1) {
        return NULL;
    }

    newsock = dfunc.OpenSocket(0);
    if (newsock == -1) {
        return NULL;
    }

    sock = NET_NewQSocket();
    if (sock == NULL) {
        goto ErrorReturn2;
    }
    sock->socket = newsock;
    sock->landriver = net_landriverlevel;

    // connect to the host
    if (dfunc.Connect(newsock, &sendaddr) == -1) {
        goto ErrorReturn;
    }

    // send the connection request
    Con_Printf("trying...\n");
    SCR_UpdateScreen();
    start_time = net_time;

    for (reps = 0; reps < 3; reps++) {
        SZ_Clear(&net_message);
        // save space for the header, filled in later
        MSG_WriteLong(&net_message, 0);
        MSG_WriteByte(&net_message, CCREQ_CONNECT);
        MSG_WriteString(&net_message, "QUAKE");
        MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
        dfunc.Write(newsock, net_message.data, net_message.cursize, &sendaddr);
        SZ_Clear(&net_message);
        do {
            ret = dfunc.Read(newsock, net_message.data, net_message.maxsize, &readaddr);
            // if we got something, validate it
            if (ret > 0) {
                // is it from the right place?
                if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0) {
#ifdef DEBUG
                    Con_Printf("wrong reply address\n");
                    Con_Printf("Expected: %s\n", StrAddr(&sendaddr));
                    Con_Printf("Received: %s\n", StrAddr(&readaddr));
                    SCR_UpdateScreen();
#endif
                    ret = 0;
                    continue;
                }

                if (ret < sizeof(int)) {
                    ret = 0;
                    continue;
                }

                net_message.cursize = ret;
                MSG_BeginReading();

                control = BigLong(*((int *)net_message.data));
                MSG_ReadLong();
                if (control == -1) {
                    ret = 0;
                    continue;
                }
                if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL) {
                    ret = 0;
                    continue;
                }
                if ((control & NETFLAG_LENGTH_MASK) != ret) {
                    ret = 0;
                    continue;
                }
            }
        } while (ret == 0 && (SetNetTime() - start_time) < 2.5);
        if (ret) {
            break;
        }
        Con_Printf("still trying...\n");
        SCR_UpdateScreen();
        start_time = SetNetTime();
    }

    if (ret == 0) {
        reason = "No Response";
        Con_Printf("%s\n", reason);
        Q_strcpy(m_return_reason, reason);
        goto ErrorReturn;
    }

    if (ret == -1) {
        reason = "Network Error";
        Con_Printf("%s\n", reason);
        Q_strcpy(m_return_reason, reason);
        goto ErrorReturn;
    }

    ret = MSG_ReadByte();
    if (ret == CCREP_REJECT) {
        reason = MSG_ReadString();
        Con_Printf(reason);
        Q_strncpy(m_return_reason, reason, 31);
        goto ErrorReturn;
    }

    if (ret == CCREP_ACCEPT) {
        Q_memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr));
        dfunc.SetSocketPort(&sock->addr, MSG_ReadLong());
    } else {
        reason = "Bad Response";
        Con_Printf("%s\n", reason);
        Q_strcpy(m_return_reason, reason);
        goto ErrorReturn;
    }

    dfunc.GetNameFromAddr(&sendaddr, sock->address);

    Con_Printf("Connection accepted\n");
    sock->lastMessageTime = SetNetTime();

    // switch the connection to the specified address
    if (dfunc.Connect(newsock, &sock->addr) == -1) {
        reason = "Connect to Game failed";
        Con_Printf("%s\n", reason);
        Q_strcpy(m_return_reason, reason);
        goto ErrorReturn;
    }

    m_return_onerror = false;
    return sock;

ErrorReturn:
    NET_FreeQSocket(sock);
ErrorReturn2:
    dfunc.CloseSocket(newsock);
    if (m_return_onerror) {
        key_dest = key_menu;
        m_state = m_return_state;
        m_return_onerror = false;
    }
    return NULL;
}
Exemplo n.º 7
0
static qsocket_t *_Datagram_CheckNewConnections(void)
{
    struct qsockaddr clientaddr;
    struct qsockaddr newaddr;
    int			newsock;
    int			acceptsock;
    qsocket_t	*sock;
    qsocket_t	*s;
    int			len;
    int			command;
    int			control;
    int			ret;

    acceptsock = dfunc.CheckNewConnections();
    if (acceptsock == -1) {
        return NULL;
    }

    SZ_Clear(&net_message);

    len = dfunc.Read(acceptsock, net_message.data, net_message.maxsize, &clientaddr);
    if (len < sizeof(int)) {
        return NULL;
    }
    net_message.cursize = len;

    MSG_BeginReading();
    control = BigLong(*((int *)net_message.data));
    MSG_ReadLong();
    if (control == -1) {
        return NULL;
    }
    if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL) {
        return NULL;
    }
    if ((control & NETFLAG_LENGTH_MASK) != len) {
        return NULL;
    }

    command = MSG_ReadByte();
    if (command == CCREQ_SERVER_INFO) {
        if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) {
            return NULL;
        }

        SZ_Clear(&net_message);
        // save space for the header, filled in later
        MSG_WriteLong(&net_message, 0);
        MSG_WriteByte(&net_message, CCREP_SERVER_INFO);
        dfunc.GetSocketAddr(acceptsock, &newaddr);
        MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
        MSG_WriteString(&net_message, hostname.string);
        MSG_WriteString(&net_message, sv.name);
        MSG_WriteByte(&net_message, net_activeconnections);
        MSG_WriteByte(&net_message, svs.maxclients);
        MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
        dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
        SZ_Clear(&net_message);
        return NULL;
    }

    if (command == CCREQ_PLAYER_INFO) {
        int			playerNumber;
        int			activeNumber;
        int			clientNumber;
        client_t	*client;

        playerNumber = MSG_ReadByte();
        activeNumber = -1;
        for (clientNumber = 0, client = svs.clients; clientNumber < svs.maxclients; clientNumber++, client++) {
            if (client->active) {
                activeNumber++;
                if (activeNumber == playerNumber) {
                    break;
                }
            }
        }
        if (clientNumber == svs.maxclients) {
            return NULL;
        }

        SZ_Clear(&net_message);
        // save space for the header, filled in later
        MSG_WriteLong(&net_message, 0);
        MSG_WriteByte(&net_message, CCREP_PLAYER_INFO);
        MSG_WriteByte(&net_message, playerNumber);
        MSG_WriteString(&net_message, client->name);
        MSG_WriteLong(&net_message, client->colors);
        MSG_WriteLong(&net_message, (int)client->edict->v.frags);
        MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime));
        MSG_WriteString(&net_message, client->netconnection->address);
        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
        dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
        SZ_Clear(&net_message);

        return NULL;
    }

    if (command == CCREQ_RULE_INFO) {
        char	*prevCvarName;
        cvar_t	*var;

        // find the search start location
        prevCvarName = MSG_ReadString();
        if (*prevCvarName) {
            var = Cvar_FindVar(prevCvarName);
            if (!var) {
                return NULL;
            }
            var = var->next;
        } else {
            var = cvar_vars;
        }

        // search for the next server cvar
        while (var) {
            if (var->server) {
                break;
            }
            var = var->next;
        }

        // send the response

        SZ_Clear(&net_message);
        // save space for the header, filled in later
        MSG_WriteLong(&net_message, 0);
        MSG_WriteByte(&net_message, CCREP_RULE_INFO);
        if (var) {
            MSG_WriteString(&net_message, var->name);
            MSG_WriteString(&net_message, var->string);
        }
        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
        dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
        SZ_Clear(&net_message);

        return NULL;
    }

    if (command != CCREQ_CONNECT) {
        return NULL;
    }

    if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) {
        return NULL;
    }

    if (MSG_ReadByte() != NET_PROTOCOL_VERSION) {
        SZ_Clear(&net_message);
        // save space for the header, filled in later
        MSG_WriteLong(&net_message, 0);
        MSG_WriteByte(&net_message, CCREP_REJECT);
        MSG_WriteString(&net_message, "Incompatible version.\n");
        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
        dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
        SZ_Clear(&net_message);
        return NULL;
    }

#ifdef BAN_TEST
    // check for a ban
    if (clientaddr.sa_family == AF_INET) {
        unsigned long testAddr;
        testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr;
        if ((testAddr & banMask) == banAddr) {
            SZ_Clear(&net_message);
            // save space for the header, filled in later
            MSG_WriteLong(&net_message, 0);
            MSG_WriteByte(&net_message, CCREP_REJECT);
            MSG_WriteString(&net_message, "You have been banned.\n");
            *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
            dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
            SZ_Clear(&net_message);
            return NULL;
        }
    }
#endif

    // see if this guy is already connected
    for (s = net_activeSockets; s; s = s->next) {
        if (s->driver != net_driverlevel) {
            continue;
        }
        ret = dfunc.AddrCompare(&clientaddr, &s->addr);
        if (ret >= 0) {
            // is this a duplicate connection reqeust?
            if (ret == 0 && net_time - s->connecttime < 2.0) {
                // yes, so send a duplicate reply
                SZ_Clear(&net_message);
                // save space for the header, filled in later
                MSG_WriteLong(&net_message, 0);
                MSG_WriteByte(&net_message, CCREP_ACCEPT);
                dfunc.GetSocketAddr(s->socket, &newaddr);
                MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
                *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
                dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
                SZ_Clear(&net_message);
                return NULL;
            }
            // it's somebody coming back in from a crash/disconnect
            // so close the old qsocket and let their retry get them back in
            NET_Close(s);
            return NULL;
        }
    }

    // allocate a QSocket
    sock = NET_NewQSocket();
    if (sock == NULL) {
        // no room; try to let him know
        SZ_Clear(&net_message);
        // save space for the header, filled in later
        MSG_WriteLong(&net_message, 0);
        MSG_WriteByte(&net_message, CCREP_REJECT);
        MSG_WriteString(&net_message, "Server is full.\n");
        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
        dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
        SZ_Clear(&net_message);
        return NULL;
    }

    // allocate a network socket
    newsock = dfunc.OpenSocket(0);
    if (newsock == -1) {
        NET_FreeQSocket(sock);
        return NULL;
    }

    // connect to the client
    if (dfunc.Connect(newsock, &clientaddr) == -1) {
        dfunc.CloseSocket(newsock);
        NET_FreeQSocket(sock);
        return NULL;
    }

    // everything is allocated, just fill in the details
    sock->socket = newsock;
    sock->landriver = net_landriverlevel;
    sock->addr = clientaddr;
    Q_strcpy(sock->address, dfunc.AddrToString(&clientaddr));

    // send him back the info about the server connection he has been allocated
    SZ_Clear(&net_message);
    // save space for the header, filled in later
    MSG_WriteLong(&net_message, 0);
    MSG_WriteByte(&net_message, CCREP_ACCEPT);
    dfunc.GetSocketAddr(newsock, &newaddr);
    MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr));
//	MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr));
    *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
    dfunc.Write(acceptsock, net_message.data, net_message.cursize, &clientaddr);
    SZ_Clear(&net_message);

    return sock;
}
Exemplo n.º 8
0
/*
* CL_ParseServerData
*/
static void CL_ParseServerData( msg_t *msg )
{
	const char *str, *gamedir;
	int i, sv_bitflags, numpure;
	int http_portnum;

	Com_DPrintf( "Serverdata packet received.\n" );

	// wipe the client_state_t struct

	CL_ClearState();
	CL_SetClientState( CA_CONNECTED );

	// parse protocol version number
	i = MSG_ReadLong( msg );

	if( i != APP_PROTOCOL_VERSION && !(cls.demo.playing && i == APP_DEMO_PROTOCOL_VERSION) )
		Com_Error( ERR_DROP, "Server returned version %i, not %i", i, APP_PROTOCOL_VERSION );

	cl.servercount = MSG_ReadLong( msg );
	cl.snapFrameTime = (unsigned int)MSG_ReadShort( msg );
	cl.gamestart = true;

	// set extrapolation time to half snapshot time
	Cvar_ForceSet( "cl_extrapolationTime", va( "%i", (unsigned int)( cl.snapFrameTime * 0.5 ) ) );
	cl_extrapolationTime->modified = false;

	// base game directory
	str = MSG_ReadString( msg );
	if( !str || !str[0] )
		Com_Error( ERR_DROP, "Server sent an empty base game directory" );
	if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) )
		Com_Error( ERR_DROP, "Server sent an invalid base game directory: %s", str );
	if( strcmp( FS_BaseGameDirectory(), str ) )
	{
		Com_Error( ERR_DROP, "Server has different base game directory (%s) than the client (%s)", str,
			FS_BaseGameDirectory() );
	}

	// game directory
	str = MSG_ReadString( msg );
	if( !str || !str[0] )
		Com_Error( ERR_DROP, "Server sent an empty game directory" );
	if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) )
		Com_Error( ERR_DROP, "Server sent an invalid game directory: %s", str );
	gamedir = FS_GameDirectory();
	if( strcmp( str, gamedir ) )
	{
		// shutdown the cgame module first in case it is running for whatever reason
		// (happens on wswtv in lobby), otherwise precaches that are going to follow
		// will probably f**k up (like models trying to load before the world model)
		CL_GameModule_Shutdown();

		if( !FS_SetGameDirectory( str, true ) )
			Com_Error( ERR_DROP, "Failed to load game directory set by server: %s", str );
		ML_Restart( true );
	}

	// parse player entity number
	cl.playernum = MSG_ReadShort( msg );

	// get the full level name
	Q_strncpyz( cl.servermessage, MSG_ReadString( msg ), sizeof( cl.servermessage ) );

	sv_bitflags = MSG_ReadByte( msg );

	if( cls.demo.playing )
	{
		cls.reliable = ( sv_bitflags & SV_BITFLAGS_RELIABLE );
	}
	else
	{
		if( cls.reliable != ( ( sv_bitflags & SV_BITFLAGS_RELIABLE ) != 0 ) )
			Com_Error( ERR_DROP, "Server and client disagree about connection reliability" );
	}

	// builting HTTP server port
	if( cls.httpbaseurl ) {
		Mem_Free( cls.httpbaseurl );
		cls.httpbaseurl = NULL;
	}

	if( ( sv_bitflags & SV_BITFLAGS_HTTP ) != 0 ) {
		if( ( sv_bitflags & SV_BITFLAGS_HTTP_BASEURL ) != 0 ) {
			// read base upstream url
			cls.httpbaseurl = ZoneCopyString( MSG_ReadString( msg ) );
		}
		else {
			http_portnum = MSG_ReadShort( msg ) & 0xffff;
			cls.httpaddress = cls.serveraddress;
			if( cls.httpaddress.type == NA_IP6 ) {
				cls.httpaddress.address.ipv6.port = BigShort( http_portnum );
			} else {
				cls.httpaddress.address.ipv4.port = BigShort( http_portnum );
			}
			if( http_portnum ) {
				if( cls.httpaddress.type == NA_LOOPBACK ) {
					cls.httpbaseurl = ZoneCopyString( va( "http://localhost:%hu/", http_portnum ) );
				}
				else {
					cls.httpbaseurl = ZoneCopyString( va( "http://%s/", NET_AddressToString( &cls.httpaddress ) ) );
				}
			}
		}
	}

	// pure list

	// clean old, if necessary
	Com_FreePureList( &cls.purelist );

	// add new
	numpure = MSG_ReadShort( msg );
	while( numpure > 0 )
	{
		const char *pakname = MSG_ReadString( msg );
		const unsigned checksum = MSG_ReadLong( msg );

		Com_AddPakToPureList( &cls.purelist, pakname, checksum, NULL );

		numpure--;
	}

	//assert( numpure == 0 );

	// get the configstrings request
	CL_AddReliableCommand( va( "configstrings %i 0", cl.servercount ) );

	cls.sv_pure = ( sv_bitflags & SV_BITFLAGS_PURE ) != 0;
	cls.sv_tv = ( sv_bitflags & SV_BITFLAGS_TVSERVER ) != 0;

#ifdef PURE_CHEAT
	cls.sv_pure = false;
#endif

	cls.wakelock = Sys_AcquireWakeLock();

	if( !cls.demo.playing && ( cls.serveraddress.type == NA_IP ) )
		Steam_AdvertiseGame( cls.serveraddress.address.ipv4.ip, NET_GetAddressPort( &cls.serveraddress ) );

	// separate the printfs so the server message can have a color
	Com_Printf( S_COLOR_WHITE "\n" "=====================================\n" );
	Com_Printf( S_COLOR_WHITE "%s\n\n", cl.servermessage );
}
Exemplo n.º 9
0
/* <667f7> ../engine/net_chan.c:1789 */
qboolean Netchan_CopyFileFragments(netchan_t *chan)
{
	fragbuf_t *p;
	int nsize;
	unsigned char *buffer;
	int pos;
	signed int cursize;
	char filename[MAX_PATH];
	char compressor[32];
	fragbuf_s *n;
	qboolean bCompressed;
	unsigned int uncompressedSize;


	if (!chan->incomingready[FRAG_FILE_STREAM])
		return FALSE;

	p = chan->incomingbufs[FRAG_FILE_STREAM];
	if (!p)
	{
		Con_Printf("Netchan_CopyFileFragments:  Called with no fragments readied\n");
		chan->incomingready[FRAG_FILE_STREAM] = FALSE;
		return FALSE;
	}

	bCompressed = FALSE;
	SZ_Clear(&net_message);
	MSG_BeginReading();
	SZ_Write(&net_message, p->frag_message.data, p->frag_message.cursize);
	Q_strncpy(filename, MSG_ReadString(), sizeof(filename) - 1);
	filename[sizeof(filename) - 1] = 0;

	Q_strncpy(compressor, MSG_ReadString(), sizeof(compressor) - 1);
	compressor[sizeof(compressor) - 1] = 0;
	if (!Q_stricmp(compressor, "bz2"))
		bCompressed = TRUE;

	uncompressedSize = (unsigned int)MSG_ReadLong();

#ifdef REHLDS_FIXES
	if (uncompressedSize > 1024 * 64) {
		Con_Printf("Received too large file (size=%u)\nFlushing input queue\n", uncompressedSize);
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}
#endif

	if (Q_strlen(filename) <= 0)
	{
		Con_Printf("File fragment received with no filename\nFlushing input queue\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	if (Q_strstr(filename, ".."))
	{
		Con_Printf("File fragment received with relative path, ignoring\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	if (filename[0] != '!' && !IsSafeFileToDownload(filename))
	{
		Con_Printf("File fragment received with bad path, ignoring\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	if (g_pcls.state != ca_dedicated && filename[0] != '!')
	{
		Con_Printf("File fragment received with bad path, ignoring (2)\n");
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	Q_strncpy(chan->incomingfilename, filename, MAX_PATH - 1);
	chan->incomingfilename[MAX_PATH - 1] = 0;

	if (filename[0] != '!' && FS_FileExists(filename))
	{
		Con_Printf("Can't download %s, already exists\n", filename);
		Netchan_FlushIncoming(chan, 1);
		return TRUE;
	}

	nsize = 0;
	while (p)
	{
		nsize += p->frag_message.cursize;
		if (p == chan->incomingbufs[FRAG_FILE_STREAM])
			nsize -= msg_readcount;
		p = p->next;
	};

	buffer = (unsigned char*)Mem_ZeroMalloc(nsize + 1);
	if (!buffer)
	{
		Con_Printf("Buffer allocation failed on %i bytes\n", nsize + 1);
		Netchan_FlushIncoming(chan, 1);
		return FALSE;
	}

	p = chan->incomingbufs[FRAG_FILE_STREAM];
	pos = 0;
	while (p)
	{
		n = p->next;

		cursize = p->frag_message.cursize;
		// First message has the file name, don't write that into the data stream, just write the rest of the actual data
		if (p == chan->incomingbufs[FRAG_FILE_STREAM])
		{
			// Copy it in
			cursize -= msg_readcount;
			Q_memcpy(&buffer[pos], &p->frag_message.data[msg_readcount], cursize);
			p->frag_message.cursize = cursize;
		}
		else
		{
			Q_memcpy(&buffer[pos], p->frag_message.data, cursize);
		}
		pos += p->frag_message.cursize;
		Mem_Free(p);
		p = n;

	}

	if (bCompressed)
	{
		unsigned char* uncompressedBuffer = (unsigned char*)Mem_Malloc(uncompressedSize);
		Con_DPrintf("Decompressing file %s (%d -> %d)\n", filename, nsize, uncompressedSize);
		BZ2_bzBuffToBuffDecompress((char*)uncompressedBuffer, &uncompressedSize, (char*)buffer, nsize, 1, 0);
		Mem_Free(buffer);
		pos = uncompressedSize;
		buffer = uncompressedBuffer;
	}

	if (filename[0] == '!')
	{
		if (chan->tempbuffer)
		{
			Con_DPrintf("Netchan_CopyFragments:  Freeing holdover tempbuffer\n");
			Mem_Free(chan->tempbuffer);
		}
		chan->tempbuffer = buffer;
		chan->tempbuffersize = pos;
	}
	else
	{

#ifdef REHLDS_FIXES
		//Don't allow to write files to FS on server
		if (chan == &g_pcls.netchan)
#endif // REHLDS_FIXES
		{
			char filedir[MAX_PATH];
			char *pszFileName;
			FileHandle_t handle;

#ifdef REHLDS_CHECKS
			Q_strncpy(filedir, filename, sizeof(filedir) - 1);
			filedir[sizeof(filedir) - 1] = 0;
#else
			Q_strncpy(filedir, filename, sizeof(filedir));
#endif // REHLDS_CHECKS
			COM_FixSlashes(filedir);
			pszFileName = strrchr(filedir, '\\');
			if (pszFileName)
			{
				*pszFileName = 0;

#ifdef REHLDS_FIXES
				FS_CreateDirHierarchy(filedir, "GAMEDOWNLOAD");
#endif
			}

#ifndef REHLDS_FIXES
			FS_CreateDirHierarchy(filedir, "GAMEDOWNLOAD");
#endif
			handle = FS_OpenPathID(filename, "wb", "GAMEDOWNLOAD");
			if (!handle)
			{
				Con_Printf("File open failed %s\n", filename);
				Netchan_FlushIncoming(chan, 1);

#ifdef REHLDS_FIXES
				Mem_Free(buffer);
#endif
				return FALSE;
			}

			Sys_Printf("COM_WriteFile: %s\n", filename);
			FS_Write(buffer, pos, 1, handle);
			FS_Close(handle);
		}

		Mem_Free(buffer);
	}
	SZ_Clear(&net_message);
	chan->incomingbufs[FRAG_FILE_STREAM] = 0;
	chan->incomingready[FRAG_FILE_STREAM] = 0;
	msg_readcount = 0;
	return TRUE;
}
Exemplo n.º 10
0
/*
* CL_ParseServerMessage
*/
void CL_ParseServerMessage( msg_t *msg )
{
	int cmd;

	if( cl_shownet->integer == 1 )
	{
		Com_Printf( "%i ", msg->cursize );
	}
	else if( cl_shownet->integer >= 2 )
	{
		Com_Printf( "------------------\n" );
	}

	// parse the message
	while( 1 )
	{
		if( msg->readcount > msg->cursize )
		{
			Com_Error( ERR_DROP, "CL_ParseServerMessage: Bad server message" );
			break;
		}

		cmd = MSG_ReadByte( msg );
		if( cl_debug_serverCmd->integer & 4 )
		{
			if( cmd == -1 )
				Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, "EOF" );
			else
				Com_Printf( "%3i:CMD %i %s\n", msg->readcount-1, cmd, !svc_strings[cmd] ? "bad" : svc_strings[cmd] );
		}

		if( cmd == -1 )
		{
			SHOWNET( msg, "END OF MESSAGE" );
			break;
		}

		if( cl_shownet->integer >= 2 )
		{
			if( !svc_strings[cmd] )
				Com_Printf( "%3i:BAD CMD %i\n", msg->readcount-1, cmd );
			else
				SHOWNET( msg, svc_strings[cmd] );
		}

		// other commands
		switch( cmd )
		{
		default:
			Com_Error( ERR_DROP, "CL_ParseServerMessage: Illegible server message" );
			break;

		case svc_nop:
			// Com_Printf( "svc_nop\n" );
			break;

		case svc_servercmd:
			if( !cls.reliable )
			{
				int cmdNum = MSG_ReadLong( msg );
				if( cmdNum < 0 )
				{
					Com_Error( ERR_DROP, "CL_ParseServerMessage: Invalid cmdNum value received: %i\n",
						cmdNum );
					return;
				}
				if( cmdNum <= cls.lastExecutedServerCommand )
				{
					MSG_ReadString( msg ); // read but ignore
					break;
				}
				cls.lastExecutedServerCommand = cmdNum;
			}
			// fall through
		case svc_servercs: // configstrings from demo files. they don't have acknowledge
			CL_ParseServerCommand( msg );	
			break;

		case svc_serverdata:
			if( cls.state == CA_HANDSHAKE )
			{
				Cbuf_Execute(); // make sure any stuffed commands are done
				CL_ParseServerData( msg );
			}
			else
			{
				return; // ignore rest of the packet (serverdata is always sent alone)
			}
			break;

		case svc_spawnbaseline:
			CL_ParseBaseline( msg );
			break;

		case svc_download:
			CL_ParseDownload( msg );
			break;

		case svc_clcack:
			if( cls.reliable )
			{
				Com_Error( ERR_DROP, "CL_ParseServerMessage: clack message for reliable client\n" );
				return;
			}
			cls.reliableAcknowledge = (unsigned)MSG_ReadLong( msg );
			cls.ucmdAcknowledged = (unsigned)MSG_ReadLong( msg );
			if( cl_debug_serverCmd->integer & 4 )
				Com_Printf( "svc_clcack:reliable cmd ack:%i ucmdack:%i\n", cls.reliableAcknowledge, cls.ucmdAcknowledged );
			break;

		case svc_frame:
			CL_ParseFrame( msg );
			break;

		case svc_demoinfo:
			assert( cls.demo.playing );
			{
				size_t meta_data_maxsize;

				MSG_ReadLong( msg );
				MSG_ReadLong( msg );
				cls.demo.meta_data_realsize = (size_t)MSG_ReadLong( msg );
				meta_data_maxsize = (size_t)MSG_ReadLong( msg );

				// sanity check
				if( cls.demo.meta_data_realsize > meta_data_maxsize ) {
					cls.demo.meta_data_realsize = meta_data_maxsize;
				}
				if( cls.demo.meta_data_realsize > sizeof( cls.demo.meta_data ) ) {
					cls.demo.meta_data_realsize = sizeof( cls.demo.meta_data );
				}

				MSG_ReadData( msg, cls.demo.meta_data, cls.demo.meta_data_realsize );
				MSG_SkipData( msg, meta_data_maxsize - cls.demo.meta_data_realsize );
			}
			break;

		case svc_playerinfo:
		case svc_packetentities:
		case svc_match:
			Com_Error( ERR_DROP, "Out of place frame data" );
			break;

		case svc_extension:
			if( 1 )
			{
				int ext, len;

				ext = MSG_ReadByte( msg );		// extension id
				MSG_ReadByte( msg );			// version number
				len = MSG_ReadShort( msg );		// command length

				switch( ext )
				{
				default:
					// unsupported
					MSG_SkipData( msg, len );
					break;
				}
			}
			break;
		}
	}

	CL_AddNetgraph();

	//
	// if recording demos, copy the message out
	//
	//
	// we don't know if it is ok to save a demo message until
	// after we have parsed the frame
	//
	if( cls.demo.recording && !cls.demo.waiting )
		CL_WriteDemoMessage( msg );
}
Exemplo n.º 11
0
/*
* CL_ParseDownload
* Handles download message from the server.
* Writes data to the file and requests next download block.
*/
static void CL_ParseDownload( msg_t *msg )
{
	size_t size, offset;
	char *svFilename;

	// read the data
	svFilename = MSG_ReadString( msg );
	offset = MSG_ReadLong( msg );
	size = MSG_ReadLong( msg );

	if( cls.demo.playing )
	{
		// ignore download commands coming from demo files
		return;
	}

	if( msg->readcount + size > msg->cursize )
	{
		Com_Printf( "Error: Download message didn't have as much data as it promised\n" );
		CL_RetryDownload();
		return;
	}

	if( !cls.download.filenum )
	{
		Com_Printf( "Error: Download message while not dowloading\n" );
		msg->readcount += size;
		return;
	}

	if( Q_stricmp( cls.download.name, svFilename ) )
	{
		Com_Printf( "Error: Download message for wrong file\n" );
		msg->readcount += size;
		return;
	}

	if( offset+size > cls.download.size )
	{
		Com_Printf( "Error: Invalid download message\n" );
		msg->readcount += size;
		CL_RetryDownload();
		return;
	}

	if( cls.download.offset != offset )
	{
		Com_Printf( "Error: Download message for wrong position\n" );
		msg->readcount += size;
		CL_RetryDownload();
		return;
	}

	FS_Write( msg->data + msg->readcount, size, cls.download.filenum );
	msg->readcount += size;
	cls.download.offset += size;
	cls.download.percent = (double)cls.download.offset / (double)cls.download.size;
	clamp( cls.download.percent, 0, 1 );

	Cvar_ForceSet( "cl_download_percent", va( "%.1f", cls.download.percent * 100 ) );

	if( cls.download.offset < cls.download.size )
	{
		cls.download.timeout = Sys_Milliseconds() + 3000;
		cls.download.retries = 0;

		CL_AddReliableCommand( va( "nextdl \"%s\" %i", cls.download.name, cls.download.offset ) );
	}
	else
	{
		Com_Printf( "Download complete: %s\n", cls.download.name );

		CL_DownloadComplete();

		// let the server know we're done
		CL_AddReliableCommand( va( "nextdl \"%s\" %i", cls.download.name, -1 ) );

		CL_StopServerDownload();

		CL_DownloadDone();
	}
}
Exemplo n.º 12
0
Arquivo: Dan.cpp Projeto: gthgame/gth
void CDanBattleFunc::RecvCC_SuggestBattle()
{
	if ( !IsGuildMasters( g_curPC ) )		
		return;


	

	REQUEST_RECORD	reqRecord;
	REQUEST_RECORD	sugRecord;

	reqRecord.No		= 0;
	reqRecord.ServerNo	= g_config.gameServerNo;
	reqRecord.ServerID	= g_curPC->idx;
	reqRecord.DanIdx	= g_curPC->guildIdx;
	memcpy(reqRecord.DanName,g_curPC->guildName,GUILDNAMESTRING);
	memcpy(reqRecord.MasterName,g_curPC->name,NAMESTRING);
		

	if ( !g_pDanBattleManager->isSuggester(&reqRecord))			
	{
		SendErrorCode(&g_curPC->sock,GSC_DAN_BATTLE,1,0);		
		return;
	}

	
	
	if ( g_curPC->curChargeSE < g_logic.DanBattlePrice)
	{
		
		SendGSM_SuggestResult(2);
		return;
	}

	sugRecord.DanIdx=MSG_ReadLong();

	sstrncpy( sugRecord.DanName, MSG_ReadString(), GUILDNAMESTRING - 1 );	

	if ( !g_pDanBattleManager->SetSuggester(&sugRecord))
	{
		SendErrorCode(&g_curPC->sock,GSC_DAN_BATTLE,1,0);				
		return;
	}	

	LPREQUEST_RECORD pSuggest=g_pDanBattleManager->GetSuggester();

	MSG_BeginWriting(&netMessage);
	MSG_Clear( &netMessage );
		
	MSG_WriteByte(&netMessage, GSC_EXTEND);
	MSG_WriteByte(&netMessage, GSC_DAN_BATTLE);
	MSG_WriteByte(&netMessage, DANB_SUGGEST_BATTLE);

	
	LPREQUEST_RECORD pSugg=static_cast<LPREQUEST_RECORD>(g_pDanBattleManager->GetRequestPointer(&sugRecord));


	if ( pSuggest->ServerID >= MAX_PCS || pSuggest->ServerID <0)
		return;

	NET_SendUnreliableMessage(&g_pc[pSuggest->ServerID].sock, &netMessage);

	MSG_EndWriting(&netMessage);

}
Exemplo n.º 13
0
/*
================
CL_ParseConfigString
================
*/
void CL_ParseConfigString (void)
{
	int		i;
	char	*s;
	char	olds[MAX_QPATH];

	i = MSG_ReadShort (&net_message);
	if (i < 0 || i >= MAX_CONFIGSTRINGS)
		Com_Error (ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
	s = MSG_ReadString(&net_message);

	strncpy (olds, cl.configstrings[i], sizeof(olds));
	olds[sizeof(olds) - 1] = 0;

	strcpy (cl.configstrings[i], s);

	// do something apropriate 

	// Knightmare- 1/2/2002- BIG UGLY HACK for old demos or
	// connected to server using old protocol
	// Changed config strings require different parsing
	if ( LegacyProtocol())
	{
		if (i >= OLD_CS_LIGHTS && i < OLD_CS_LIGHTS+MAX_LIGHTSTYLES)
			CL_SetLightstyle (i - OLD_CS_LIGHTS);
		else if (i == CS_CDTRACK)
		{
			if (cl.refresh_prepped)
				CL_PlayBackgroundTrack ();
		}
		else if (i >= CS_MODELS && i < CS_MODELS+OLD_MAX_MODELS)
		{
			if (cl.refresh_prepped)
			{
				cl.model_draw[i-CS_MODELS] = R_RegisterModel (cl.configstrings[i]);
				if (cl.configstrings[i][0] == '*')
					cl.model_clip[i-CS_MODELS] = CM_InlineModel (cl.configstrings[i]);
				else
					cl.model_clip[i-CS_MODELS] = NULL;
			}
		}
		else if (i >= OLD_CS_SOUNDS && i < OLD_CS_SOUNDS+OLD_MAX_SOUNDS)
		{
			if (cl.refresh_prepped)
				cl.sound_precache[i-OLD_CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]);
		}
		else if (i >= OLD_CS_IMAGES && i < OLD_CS_IMAGES+OLD_MAX_IMAGES)
		{
			if (cl.refresh_prepped)
				cl.image_precache[i-OLD_CS_IMAGES] = R_DrawFindPic (cl.configstrings[i]);
		}
		else if (i >= OLD_CS_PLAYERSKINS && i < OLD_CS_PLAYERSKINS+MAX_CLIENTS)
		{
			if (cl.refresh_prepped && strcmp(olds, s))
				CL_ParseClientinfo (i-OLD_CS_PLAYERSKINS);
		}
	}
	else // new configstring offsets
	{
		if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES)
			CL_SetLightstyle (i - CS_LIGHTS);
		else if (i == CS_CDTRACK)
		{
			if (cl.refresh_prepped)
				CL_PlayBackgroundTrack ();
		}
		else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS)
		{
			if (cl.refresh_prepped)
			{
				cl.model_draw[i-CS_MODELS] = R_RegisterModel (cl.configstrings[i]);
				if (cl.configstrings[i][0] == '*')
					cl.model_clip[i-CS_MODELS] = CM_InlineModel (cl.configstrings[i]);
				else
					cl.model_clip[i-CS_MODELS] = NULL;
			}
		}
		else if (i >= CS_SOUNDS && i < CS_SOUNDS+MAX_SOUNDS) //Knightmare- was MAX_MODELS
		{
			if (cl.refresh_prepped)
				cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]);
		}
		else if (i >= CS_IMAGES && i < CS_IMAGES+MAX_IMAGES) //Knightmare- was MAX_MODELS
		{
			if (cl.refresh_prepped)
				cl.image_precache[i-CS_IMAGES] = R_DrawFindPic (cl.configstrings[i]);
		}
		else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS)
		{
			if (cl.refresh_prepped && strcmp(olds, s))
				CL_ParseClientinfo (i-CS_PLAYERSKINS);
		}
	}
	//end Knightmare
}
Exemplo n.º 14
0
/*
=====================
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage (void)
{
	int			cmd;
	int			i;
	
//
// if recording demos, copy the message out
//
	if (cl_shownet.value == 1)
		Con_Printf ("%i ",net_message.cursize);
	else if (cl_shownet.value == 2)
		Con_Printf ("------------------\n");
	
	cl.onground = false;	// unless the server says otherwise	
//
// parse the message
//
	MSG_BeginReading ();
	
	while (1)
	{
		if (msg_badread)
			Host_Error ("CL_ParseServerMessage: Bad server message");

		cmd = MSG_ReadByte ();

		if (cmd == -1)
		{
			SHOWNET("END OF MESSAGE");
			return;		// end of message
		}

	// if the high bit of the command byte is set, it is a fast update
		if (cmd & 128)
		{
			SHOWNET("fast update");
			CL_ParseUpdate (cmd&127);
			continue;
		}

		SHOWNET(svc_strings[cmd]);
	
	// other commands
		switch (cmd)
		{
		default:
			Host_Error ("CL_ParseServerMessage: Illegible server message\n");
			break;
			
		case svc_nop:
//			Con_Printf ("svc_nop\n");
			break;
			
		case svc_time:
			cl.mtime[1] = cl.mtime[0];
			cl.mtime[0] = MSG_ReadFloat ();			
			break;
			
		case svc_clientdata:
			i = MSG_ReadShort ();
			CL_ParseClientdata (i);
			break;
		
		case svc_version:
			i = MSG_ReadLong ();
			if (i != PROTOCOL_VERSION)
				Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION);
			break;
			
		case svc_disconnect:
			Host_EndGame ("Server disconnected\n");

		case svc_print:
			Con_Printf ("%s", MSG_ReadString ());
			break;
			
		case svc_centerprint:
			SCR_CenterPrint (MSG_ReadString ());
			break;
			
		case svc_stufftext:
			Cbuf_AddText (MSG_ReadString ());
			break;
			
		case svc_damage:
			V_ParseDamage ();
			break;
			
		case svc_serverinfo:
			CL_ParseServerInfo ();
			vid.recalc_refdef = true;	// leave intermission full screen
			break;
			
		case svc_setangle:
			for (i=0 ; i<3 ; i++)
				cl.viewangles[i] = MSG_ReadAngle ();
			break;
			
		case svc_setview:
			cl.viewentity = MSG_ReadShort ();
			break;
					
		case svc_lightstyle:
			i = MSG_ReadByte ();
			if (i >= MAX_LIGHTSTYLES)
				Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES");
			Q_strcpy (cl_lightstyle[i].map,  MSG_ReadString());
			cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map);
			break;
			
		case svc_sound:
			CL_ParseStartSoundPacket();
			break;
			
		case svc_stopsound:
			i = MSG_ReadShort();
			S_StopSound(i>>3, i&7);
			break;
		
		case svc_updatename:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
			strcpy (cl.scores[i].name, MSG_ReadString ());
			break;
			
		case svc_updatefrags:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD");
			cl.scores[i].frags = MSG_ReadShort ();
			break;			

		case svc_updatecolors:
			Sbar_Changed ();
			i = MSG_ReadByte ();
			if (i >= cl.maxclients)
				Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
			cl.scores[i].colors = MSG_ReadByte ();
			CL_NewTranslation (i);
			break;
			
		case svc_particle:
			R_ParseParticleEffect ();
			break;

		case svc_spawnbaseline:
			i = MSG_ReadShort ();
			// must use CL_EntityNum() to force cl.num_entities up
			CL_ParseBaseline (CL_EntityNum(i));
			break;
		case svc_spawnstatic:
			CL_ParseStatic ();
			break;			
		case svc_temp_entity:
			CL_ParseTEnt ();
			break;

		case svc_setpause:
			{
				cl.paused = MSG_ReadByte ();

				if (cl.paused)
				{
					CDAudio_Pause ();
#ifdef _WIN32
					VID_HandlePause (true);
#endif
				}
				else
				{
					CDAudio_Resume ();
#ifdef _WIN32
					VID_HandlePause (false);
#endif
				}
			}
			break;
			
		case svc_signonnum:
			i = MSG_ReadByte ();
			if (i <= cls.signon)
				Host_Error ("Received signon %i when at %i", i, cls.signon);
			cls.signon = i;
			CL_SignonReply ();
			break;

		case svc_killedmonster:
			cl.stats[STAT_MONSTERS]++;
			break;

		case svc_foundsecret:
			cl.stats[STAT_SECRETS]++;
			break;

		case svc_updatestat:
			i = MSG_ReadByte ();
			if (i < 0 || i >= MAX_CL_STATS)
				Sys_Error ("svc_updatestat: %i is invalid", i);
			cl.stats[i] = MSG_ReadLong ();;
			break;
			
		case svc_spawnstaticsound:
			CL_ParseStaticSound ();
			break;

		case svc_cdtrack:
			cl.cdtrack = MSG_ReadByte ();
			cl.looptrack = MSG_ReadByte ();
			if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) )
				CDAudio_Play ((byte)cls.forcetrack, true);
			else
				CDAudio_Play ((byte)cl.cdtrack, true);
			break;

		case svc_intermission:
			cl.intermission = 1;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			break;

		case svc_finale:
			cl.intermission = 2;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			SCR_CenterPrint (MSG_ReadString ());			
			break;

		case svc_cutscene:
			cl.intermission = 3;
			cl.completed_time = cl.time;
			vid.recalc_refdef = true;	// go to full screen
			SCR_CenterPrint (MSG_ReadString ());			
			break;

		case svc_sellscreen:
			Cmd_ExecuteString ("help", src_command);
			break;
		}
	}
}
Exemplo n.º 15
0
// Do very shallow parse of the demo (could be extended) just to get times and snapshot count
static void CL_ParseDemo(void)
{
	int tstart   = 0;
	int demofile = 0;

	// Reset our demo data
	memset(&di, 0, sizeof(di));

	// Parse start
	di.gameStartTime = -1;
	di.gameEndTime   = -1;
	FS_Seek(clc.demofile, 0, FS_SEEK_SET);
	tstart = Sys_Milliseconds();

	while (qtrue)
	{
		int   r;
		msg_t buf;
		msg_t *msg;
		byte  bufData[MAX_MSGLEN];
		int   s;
		int   cmd;

		di.demoPos = FS_FTell(clc.demofile);

		// get the sequence number
		r = FS_Read(&s, 4, clc.demofile);
		if (r != 4)
		{
			CL_DemoCompleted();
			return;
		}

		clc.serverMessageSequence = LittleLong(s);

		// init the message
		MSG_Init(&buf, bufData, sizeof(bufData));

		// get the length
		r = FS_Read(&buf.cursize, 4, clc.demofile);

		if (r != 4)
		{
			break;
		}

		buf.cursize = LittleLong(buf.cursize);
		if (buf.cursize == -1)
		{
			break;
		}

		if (buf.cursize > buf.maxsize)
		{
			Com_FuncDPrinf("demoMsglen > MAX_MSGLEN");
			break;
		}

		r = FS_Read(buf.data, buf.cursize, clc.demofile);
		if (r != buf.cursize)
		{
			Com_FuncDPrinf("Demo file was truncated.\n");
			break;
		}

		clc.lastPacketTime = cls.realtime;
		buf.readcount      = 0;

		// parse
		msg = &buf;
		MSG_Bitstream(msg);

		// get the reliable sequence acknowledge number
		clc.reliableAcknowledge = MSG_ReadLong(msg);

		if (clc.reliableAcknowledge < clc.reliableSequence - MAX_RELIABLE_COMMANDS)
		{
			clc.reliableAcknowledge = clc.reliableSequence;
		}

		// parse the message
		while (qtrue)
		{
			if (msg->readcount > msg->cursize)
			{
				Com_FuncDrop("read past end of server message");
				break;
			}

			cmd = MSG_ReadByte(msg);

			if (cmd == svc_EOF)
			{
				break;
			}

			// other commands
			switch (cmd)
			{
			default:
				Com_FuncDrop("Illegible server message %d", cmd);
				break;
			case svc_nop:
				break;
			case svc_serverCommand:
				MSG_ReadLong(msg);
				MSG_ReadString(msg);
				break;
			case svc_gamestate:
				clc.serverCommandSequence = MSG_ReadLong(msg);
				cl.gameState.dataCount    = 1;
				while (qtrue)
				{
					int cmd2 = MSG_ReadByte(msg);
					if (cmd2 == svc_EOF)
					{
						break;
					}
					if (cmd2 == svc_configstring)
					{
						MSG_ReadShort(msg);
						MSG_ReadBigString(msg);
					}
					else if (cmd2 == svc_baseline)
					{
						entityState_t s1, s2;
						memset(&s1, 0, sizeof(s1));
						memset(&s2, 0, sizeof(s2));
						MSG_ReadBits(msg, GENTITYNUM_BITS);
						MSG_ReadDeltaEntity(msg, &s1, &s2, 0);
					}
					else
					{
						Com_FuncDrop("bad command byte");
					}
				}
				MSG_ReadLong(msg);
				MSG_ReadLong(msg);
				break;
			case svc_snapshot:
				CL_ParseDemoSnapShotSimple(msg);
				break;
			case svc_download:
				MSG_ReadShort(msg);

				break;
			}
		}

		if (!cl.snap.valid)
		{
			Com_FuncDPrinf("!cl.snap.valid\n");
			continue;
		}

		if (cl.snap.serverTime < cl.oldFrameServerTime)
		{
			// ignore snapshots that don't have entities
			if (cl.snap.snapFlags & SNAPFLAG_NOT_ACTIVE)
			{
				continue;
			}
			cls.state = CA_ACTIVE;

			// set the timedelta so we are exactly on this first frame
			cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
			cl.oldServerTime   = cl.snap.serverTime;

			clc.timeDemoBaseTime = cl.snap.serverTime;
		}
		cl.oldFrameServerTime = cl.snap.serverTime;

		if (cl.newSnapshots)
		{
			CL_AdjustTimeDelta();
		}

		di.lastServerTime = cl.snap.serverTime;
		if (di.firstServerTime == 0)
		{
			di.firstServerTime = cl.snap.serverTime;
			Com_FuncPrinf("firstServerTime %d\n", di.firstServerTime);
		}

		di.snapsInDemo++;
	}

	Com_FuncDPrinf("Snaps in demo: %i\n", di.snapsInDemo);
	Com_FuncDPrinf("last serverTime %d   total %f minutes\n", cl.snap.serverTime, (cl.snap.serverTime - di.firstServerTime) / 1000.0 / 60.0);
	Com_FuncDPrinf("parse time %f seconds\n", (float)(Sys_Milliseconds() - tstart) / 1000.0);
	FS_Seek(clc.demofile, 0, FS_SEEK_SET);
	clc.demoplaying = qfalse;
	demofile        = clc.demofile;
	CL_ClearState();
	Com_Memset(&clc, 0, sizeof(clc));
	clc.demofile             = demofile;
	cls.state                = CA_DISCONNECTED;
	cl_connectedToPureServer = qfalse;

	dpi.firstTime = di.firstServerTime;
	dpi.lastTime  = di.lastServerTime;
}
Exemplo n.º 16
0
void SV_ExecuteClientMessage (client_t *cl)
{
	int		c;
	char	*s;
	usercmd_t	oldest, oldcmd, newcmd;
	client_frame_t	*frame;
	vec3_t o;
	qboolean	move_issued = false; //only allow one move command
	int		checksumIndex;
	byte	checksum, calculatedChecksum;
	int		seq_hash;

	// calc ping time
	frame = &cl->frames[cl->netchan.incoming_acknowledged & UPDATE_MASK];
	frame->ping_time = realtime - frame->senttime;

	// make sure the reply sequence number matches the incoming
	// sequence number 
	if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence)
		cl->netchan.outgoing_sequence = cl->netchan.incoming_sequence;
	else
		cl->send_message = false;	// don't reply, sequences have slipped		

	// save time for ping calculations
	cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].senttime = realtime;
	cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].ping_time = -1;

	host_client = cl;
	sv_player = host_client->edict;

//	seq_hash = (cl->netchan.incoming_sequence & 0xffff) ; // ^ QW_CHECK_HASH;
	seq_hash = cl->netchan.incoming_sequence;
	
	// mark time so clients will know how much to predict
	// other players
 	cl->localtime = sv.time;
	cl->delta_sequence = -1;	// no delta unless requested
	while (1)
	{
		if (msg_badread)
		{
			Con_Printf ("SV_ReadClientMessage: badread\n");
			SV_DropClient (cl);
			return;
		}	

		c = MSG_ReadByte ();
		if (c == -1)
			break;
				
		switch (c)
		{
		default:
			Con_Printf ("SV_ReadClientMessage: unknown command char\n");
			SV_DropClient (cl);
			return;
						
		case clc_nop:
			break;

		case clc_delta:
			cl->delta_sequence = MSG_ReadByte ();
			break;

		case clc_move:
			if (move_issued)
				return;		// someone is trying to cheat...

			move_issued = true;

			checksumIndex = MSG_GetReadCount();
			checksum = (byte)MSG_ReadByte ();

			// read loss percentage
			cl->lossage = MSG_ReadByte();

			MSG_ReadDeltaUsercmd (&nullcmd, &oldest);
			MSG_ReadDeltaUsercmd (&oldest, &oldcmd);
			MSG_ReadDeltaUsercmd (&oldcmd, &newcmd);

			if ( cl->state != cs_spawned )
				break;

			// if the checksum fails, ignore the rest of the packet
			calculatedChecksum = COM_BlockSequenceCRCByte(
				net_message.data + checksumIndex + 1,
				MSG_GetReadCount() - checksumIndex - 1,
				seq_hash);

			if (calculatedChecksum != checksum)
			{
				Con_DPrintf ("Failed command checksum for %s(%d) (%d != %d)\n", 
					cl->name, cl->netchan.incoming_sequence, checksum, calculatedChecksum);
				return;
			}

			if (!sv.paused) {
				SV_PreRunCmd();

				if (net_drop < 20)
				{
					while (net_drop > 2)
					{
						SV_RunCmd (&cl->lastcmd);
						net_drop--;
					}
					if (net_drop > 1)
						SV_RunCmd (&oldest);
					if (net_drop > 0)
						SV_RunCmd (&oldcmd);
				}
				SV_RunCmd (&newcmd);

				SV_PostRunCmd();
			}

			cl->lastcmd = newcmd;
			cl->lastcmd.buttons = 0; // avoid multiple fires on lag
			break;


		case clc_stringcmd:	
			s = MSG_ReadString ();
			SV_ExecuteUserCommand (s);
			break;

		case clc_tmove:
			o[0] = MSG_ReadCoord();
			o[1] = MSG_ReadCoord();
			o[2] = MSG_ReadCoord();
			// only allowed by spectators
			if (host_client->spectator) {
				VectorCopy(o, sv_player->v.origin);
				SV_LinkEdict(sv_player, false);
			}
			break;

		case clc_upload:
			SV_NextUpload();
			break;

		}
	}
}
Exemplo n.º 17
0
static void _Datagram_SearchForHosts(qboolean xmit)
{
    int		ret;
    int		n;
    int		i;
    struct qsockaddr readaddr;
    struct qsockaddr myaddr;
    int		control;

    dfunc.GetSocketAddr(dfunc.controlSock, &myaddr);
    if (xmit) {
        SZ_Clear(&net_message);
        // save space for the header, filled in later
        MSG_WriteLong(&net_message, 0);
        MSG_WriteByte(&net_message, CCREQ_SERVER_INFO);
        MSG_WriteString(&net_message, "QUAKE");
        MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
        *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
        dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize);
        SZ_Clear(&net_message);
    }

    while ((ret = dfunc.Read(dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0) {
        if (ret < sizeof(int)) {
            continue;
        }
        net_message.cursize = ret;

        // don't answer our own query
        if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0) {
            continue;
        }

        // is the cache full?
        if (hostCacheCount == HOSTCACHESIZE) {
            continue;
        }

        MSG_BeginReading();
        control = BigLong(*((int *)net_message.data));
        MSG_ReadLong();
        if (control == -1) {
            continue;
        }
        if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL) {
            continue;
        }
        if ((control & NETFLAG_LENGTH_MASK) != ret) {
            continue;
        }

        if (MSG_ReadByte() != CCREP_SERVER_INFO) {
            continue;
        }

        dfunc.GetAddrFromName(MSG_ReadString(), &readaddr);
        // search the cache for this server
        for (n = 0; n < hostCacheCount; n++)
            if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0) {
                break;
            }

        // is it already there?
        if (n < hostCacheCount) {
            continue;
        }

        // add it
        hostCacheCount++;
        Q_strcpy(hostcache[n].name, MSG_ReadString());
        Q_strcpy(hostcache[n].map, MSG_ReadString());
        hostcache[n].users = MSG_ReadByte();
        hostcache[n].maxusers = MSG_ReadByte();
        if (MSG_ReadByte() != NET_PROTOCOL_VERSION) {
            Q_strcpy(hostcache[n].cname, hostcache[n].name);
            hostcache[n].cname[14] = 0;
            Q_strcpy(hostcache[n].name, "*");
            Q_strcat(hostcache[n].name, hostcache[n].cname);
        }
        Q_memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr));
        hostcache[n].driver = net_driverlevel;
        hostcache[n].ldriver = net_landriverlevel;
        Q_strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr));

        // check for a name conflict
        for (i = 0; i < hostCacheCount; i++) {
            if (i == n) {
                continue;
            }
            if (Q_strcasecmp(hostcache[n].name, hostcache[i].name) == 0) {
                i = Q_strlen(hostcache[n].name);
                if (i < 15 && hostcache[n].name[i-1] > '8') {
                    hostcache[n].name[i] = '0';
                    hostcache[n].name[i+1] = 0;
                } else {
                    hostcache[n].name[i-1]++;
                }
                i = -1;
            }
        }
    }
}
Exemplo n.º 18
0
/*
===================
SV_ReadClientMessage

Returns false if the client should be killed
===================
*/
qboolean SV_ReadClientMessage (void)
{
	int		ret;
	int		cmd;
	char		*s;
	
	do
	{
nextmsg:
		ret = NET_GetMessage (host_client->netconnection);
		if (ret == -1)
		{
			Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
			return false;
		}
		if (!ret)
			return true;
					
		MSG_BeginReading (net_message);
		
		while (1)
		{
			if (!host_client->active)
				return false;	// a command caused an error

			if (net_message->badread)
			{
				Sys_Printf ("SV_ReadClientMessage: badread\n");
				return false;
			}	
	
			cmd = MSG_ReadChar (net_message);
			
			switch (cmd)
			{
			case -1:
				goto nextmsg;		// end of message
				
			default:
				Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
				return false;
							
			case clc_nop:
//				Sys_Printf ("SV_ReadClientMessage: clc_nop\n");
				break;
				
			case clc_stringcmd:	
				s = MSG_ReadString (net_message);

				ret = 0;

				if (nehahra)
				{
					if (strncasecmp(s, "max", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "monster", 7) == 0)
						ret = 1;
					else if (strncasecmp(s, "scrag", 5) == 0)
						ret = 1;
					else if (strncasecmp(s, "wraith", 6) == 0)
						ret = 1;
					else if (strncasecmp(s, "gimme", 5) == 0)
						ret = 1;
				}
				else
				{
					if (strncasecmp(s, "god", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "notarget", 8) == 0)
						ret = 1;
					else if (strncasecmp(s, "fly", 3) == 0)
						ret = 1;
					else if (strncasecmp(s, "noclip", 6) == 0)
						ret = 1;
					else if (strncasecmp(s, "give", 4) == 0)
						ret = 1;
				}

				if (strncasecmp(s, "status", 6) == 0)
					ret = 1;
				else if (strncasecmp(s, "freezeall", 9) == 0)
					ret = 1;
				else if (strncasecmp(s, "name", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "say", 3) == 0)
					ret = 1;
				else if (strncasecmp(s, "say_team", 8) == 0)
					ret = 1;
				else if (strncasecmp(s, "tell", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "color", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "kill", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "pause", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "spawn", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "begin", 5) == 0)
					ret = 1;
				else if (strncasecmp(s, "prespawn", 8) == 0)
					ret = 1;
				else if (strncasecmp(s, "kick", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "ping", 4) == 0)
					ret = 1;
				else if (strncasecmp(s, "ban", 3) == 0)
					ret = 1;
				else if (strncasecmp(s, "qcexec", 6) == 0)
					ret = 1; // qcexec command for qc testing

				if (ret == 1)
					Cmd_ExecuteString (s, src_client);
				else
					Con_DPrintf("%s tried to %s\n", host_client->name, s);
				break;
				
			case clc_disconnect:
//				Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
				return false;
			
			case clc_move:
				SV_ReadClientMove (&host_client->cmd);
				break;
			}
		}
	} while (ret == 1);
	
	return true;
}
Exemplo n.º 19
0
static void Test2_Poll(void)
{
    struct qsockaddr clientaddr;
    int		control;
    int		len;
    char	name[256];
    char	value[256];

    net_landriverlevel = test2Driver;
    name[0] = 0;

    len = dfunc.Read(test2Socket, net_message.data, net_message.maxsize, &clientaddr);
    if (len < sizeof(int)) {
        goto Reschedule;
    }

    net_message.cursize = len;

    MSG_BeginReading();
    control = BigLong(*((int *)net_message.data));
    MSG_ReadLong();
    if (control == -1) {
        goto Error;
    }
    if ((control & (~NETFLAG_LENGTH_MASK)) !=  NETFLAG_CTL) {
        goto Error;
    }
    if ((control & NETFLAG_LENGTH_MASK) != len) {
        goto Error;
    }

    if (MSG_ReadByte() != CCREP_RULE_INFO) {
        goto Error;
    }

    Q_strcpy(name, MSG_ReadString());
    if (name[0] == 0) {
        goto Done;
    }
    Q_strcpy(value, MSG_ReadString());

    Con_Printf("%-16.16s  %-16.16s\n", name, value);

    SZ_Clear(&net_message);
    // save space for the header, filled in later
    MSG_WriteLong(&net_message, 0);
    MSG_WriteByte(&net_message, CCREQ_RULE_INFO);
    MSG_WriteString(&net_message, name);
    *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
    dfunc.Write(test2Socket, net_message.data, net_message.cursize, &clientaddr);
    SZ_Clear(&net_message);

Reschedule:
    SchedulePollProcedure(&test2PollProcedure, 0.05);
    return;

Error:
    Con_Printf("Unexpected repsonse to Rule Info request\n");
Done:
    dfunc.CloseSocket(test2Socket);
    test2InProgress = false;
    return;
}
Exemplo n.º 20
0
void CHelperManager::ProcessMessage_Invite_REQ_fromHELPER(playerCharacter_t* pHelper)
{
	
	if(TRUE == IsBadWritePtr(pHelper,sizeof(playerCharacter_t)) 
		|| TRUE == IsBadReadPtr(pHelper,sizeof(playerCharacter_t)))
	{
	
	
		
		return;
	}


	
	if( tagHelper::tagMemberList::HELPER != pHelper->tHelper.List.mode)
	{
		SendMessage_Invite_Respond_toHelper(
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invalidMode );
			g_logSystem->Write("Fail_RegistrationRequest_invalidMode" );
		return ;
	}



	char cz_tempTakerName[NAMESTRING+1];
	strncpy(cz_tempTakerName,MSG_ReadString(),NAMESTRING);
	cz_tempTakerName[NAMESTRING]=NULL;

	int idx = GTH_FindPCByName(cz_tempTakerName);
	
	playerCharacter_t * pTaker=gcpTools->GetPlayerRecordPointer(idx);

	if(NULL == pTaker){
		SendMessage_Invite_Respond_toHelper(
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invalidUser);
			g_logSystem->Write("Fail_RegistrationRequest_invalidUser" );
		return;
	}
	
	
	if( tagHelper::tagMemberList::TAKER != pTaker->tHelper.List.mode)
	{
		SendMessage_Invite_Respond_toHelper(
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invalidTakerMode );
			g_logSystem->Write("Fail_RegistrationRequest_invalidMode" );
		return ;
	}

	
	if(pTaker->idx == pHelper->idx)
	{
		SendMessage_Invite_Respond_toHelper( 
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invalidUser);
		g_logSystem->Write("Fail_RegistrationRequest_invalidUser" );
		return;
	}


	
	if ( pHelper->tHelper.List.count > tagHelper::MAX_MEMBER)
	{
		SendMessage_Invite_Respond_toHelper( 
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invalidTakersCount);
			g_logSystem->Write("Fail_RegistrationRequest_invalidTakersCount" );
		return;
	}

	
	if(pTaker->tHelper.List.count >= tagHelper::MAX_Accept_HELPERS)
	{
		SendMessage_Invite_Respond_toHelper( 
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invalidHelperCount);
		g_logSystem->Write("Fail_RegistrationRequest_invalidHelperCount" );
		return;
	}

	if ( pHelper->worldIdx != pTaker->worldIdx )
	{
		SendMessage_Invite_Respond_toHelper( 
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invalidWorldIndex);
			g_logSystem->Write("Fail_RegistrationRequest_invalidWorldIndex" );
		return ;
	}

	if(TRUE == isMyChild(pHelper,pTaker->name))
	{
		SendMessage_Invite_Respond_toHelper(
			pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Fail_RegistrationRequest_invaliChild);
			g_logSystem->Write("Fail_RegistrationRequest_invaliChild" );
		return ;
	}



	strncpy(pTaker->HelperAdd.RequestPlayer.Name,pHelper->name,NAMESTRING);
	pTaker->HelperAdd.RequestPlayer.Name[NAMESTRING]=NULL;
	pTaker->HelperAdd.RequestPlayer.pcIdx=pHelper->idx;


	SendMessage_Invite_Respond_toHelper( 
		pHelper,tagHelperPacket_SC_INVITE_RES_toHELPER::Ready_Registration);
	
	ShowLogInfo("Helper_Invite_Suggest: name:%s,level:%d ",pHelper->name,pHelper->level);
	
	SendMessage_Invite_Request_toTaker( pTaker,pHelper->name);
	ShowLogInfo("Helper_Invite_Suggest: name:%s,level:%d ",pTaker->name,pTaker->level);
}
Exemplo n.º 21
0
/*
=====================
CL_ParseDownload

A download message has been received from the server
=====================
*/
void CL_ParseDownload( msg_t *msg )
{
	int           size;
	unsigned char data[ MAX_MSGLEN ];
	int           block;

	if ( !*cls.downloadTempName )
	{
		Com_Printf( "Server sending download, but no download was requested\n" );
        // Eat the packet anyway
	    block = MSG_ReadShort( msg );
        if (block == -1) {
			MSG_ReadString( msg );
			MSG_ReadLong( msg );
			MSG_ReadLong( msg );
        } else if (block != 0) {
            size = MSG_ReadShort( msg );
            if ( size < 0 || size > (int) sizeof( data ) )
            {
                Com_Error( ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk.", size );
            }
	        MSG_ReadData( msg, data, size );
        }

		CL_AddReliableCommand( "stopdl" );
		return;
	}

	// read the data
	block = MSG_ReadShort( msg );

	// TTimo - www dl
	// if we haven't acked the download redirect yet
	if ( block == -1 )
	{
		if ( !clc.bWWWDl )
		{
			// server is sending us a www download
			Q_strncpyz( cls.originalDownloadName, cls.downloadName, sizeof( cls.originalDownloadName ) );
			Q_strncpyz( cls.downloadName, MSG_ReadString( msg ), sizeof( cls.downloadName ) );
			clc.downloadSize = MSG_ReadLong( msg );
			clc.downloadFlags = MSG_ReadLong( msg );

            downloadLogger.Debug("Server sent us a new WWW DL '%s', size %i, flags %i",
                                 cls.downloadName, clc.downloadSize, clc.downloadFlags);

			Cvar_SetValue( "cl_downloadSize", clc.downloadSize );
			clc.bWWWDl = true; // activate wwwdl client loop
			CL_AddReliableCommand( "wwwdl ack" );
			cls.state = CA_DOWNLOADING;

			// make sure the server is not trying to redirect us again on a bad checksum
			if ( strstr( clc.badChecksumList, va( "@%s", cls.originalDownloadName ) ) )
			{
				Com_Printf( "refusing redirect to %s by server (bad checksum)\n", cls.downloadName );
				CL_AddReliableCommand( "wwwdl fail" );
				clc.bWWWDlAborting = true;
				return;
			}

			if ( !DL_BeginDownload( cls.downloadTempName, cls.downloadName ) )
			{
				// setting bWWWDl to false after sending the wwwdl fail doesn't work
				// not sure why, but I suspect we have to eat all remaining block -1 that the server has sent us
				// still leave a flag so that CL_WWWDownload is inactive
				// we count on server sending us a gamestate to start up clean again
				CL_AddReliableCommand( "wwwdl fail" );
				clc.bWWWDlAborting = true;
				Com_Printf( "Failed to initialize download for '%s'\n", cls.downloadName );
			}

			// Check for a disconnected download
			// we'll let the server disconnect us when it gets the bbl8r message
			if ( clc.downloadFlags & ( 1 << DL_FLAG_DISCON ) )
			{
				CL_AddReliableCommand( "wwwdl bbl8r" );
				cls.bWWWDlDisconnected = true;
			}

			return;
		}
		else
		{
			// server keeps sending that message till we ack it, eat and ignore
			//MSG_ReadLong( msg );
			MSG_ReadString( msg );
			MSG_ReadLong( msg );
			MSG_ReadLong( msg );
			return;
		}
	}

	if ( !block )
	{
		// block zero is special, contains file size
		clc.downloadSize = MSG_ReadLong( msg );

        downloadLogger.Debug("Starting new direct download of size %i for '%s'", clc.downloadSize, cls.downloadTempName);
		Cvar_SetValue( "cl_downloadSize", clc.downloadSize );

		if ( clc.downloadSize < 0 )
		{
			Com_Error( ERR_DROP, "%s", MSG_ReadString( msg ) );
		}
	}

	size = MSG_ReadShort( msg );

	if ( size < 0 || size > (int) sizeof( data ) )
	{
		Com_Error( ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk.", size );
	}

    downloadLogger.Debug("Received block of size %i", size);

	MSG_ReadData( msg, data, size );

	if ( clc.downloadBlock != block )
	{
		downloadLogger.Debug( "CL_ParseDownload: Expected block %i, got %i", clc.downloadBlock, block );
		return;
	}

	// open the file if not opened yet
	if ( !clc.download )
	{
		clc.download = FS_SV_FOpenFileWrite( cls.downloadTempName );

		if ( !clc.download )
		{
			Com_Printf( "Could not create %s\n", cls.downloadTempName );
			CL_AddReliableCommand( "stopdl" );
			CL_NextDownload();
			return;
		}
	}

	if ( size )
	{
		FS_Write( data, size, clc.download );
	}

	CL_AddReliableCommand( va( "nextdl %d", clc.downloadBlock ) );
	clc.downloadBlock++;

	clc.downloadCount += size;

	// So UI gets access to it
	Cvar_SetValue( "cl_downloadCount", clc.downloadCount );

	if ( !size )
	{
        downloadLogger.Debug("Received EOF, closing '%s'", cls.downloadTempName);
		// A zero length block means EOF
		if ( clc.download )
		{
			FS_FCloseFile( clc.download );
			clc.download = 0;

			// rename the file
			FS_SV_Rename( cls.downloadTempName, cls.downloadName );
		}

		*cls.downloadTempName = *cls.downloadName = 0;
		Cvar_Set( "cl_downloadName", "" );

		// send intentions now
		// We need this because without it, we would hold the last nextdl and then start
		// loading right away.  If we take a while to load, the server is happily trying
		// to send us that last block over and over.
		// Write it twice to help make sure we acknowledge the download
		CL_WritePacket();
		CL_WritePacket();

		// get another file if needed
		CL_NextDownload();
	}
}
Exemplo n.º 22
0
void CHelperManager::ProcessMessage_SC_REMOVE_NOTIFY_toPlayer()
{
	int  idx=-1;
	char removeName[NAMESTRING+1], playerName[NAMESTRING+1];

	sstrncpy( removeName, MSG_ReadString(), NAMESTRING);
	removeName[NAMESTRING]=NULL;
	sstrncpy( playerName, MSG_ReadString(), NAMESTRING);
	playerName[NAMESTRING]=NULL;

	idx = GTH_FindPCByName(removeName);
	if (0 <= idx ) 
	{
		playerCharacter_t* pRemover=gcpTools->GetPlayerRecordPointer(idx);
		if(NULL == pRemover) return;
		
		MSG_BeginWriting(&netMessage);
		MSG_Clear( &netMessage );
		{
			
			MSG_WriteByte(&netMessage,	 EXTEND_SECOND);
			MSG_WriteShort( &netMessage, HELPER_SYSTEM );
			MSG_WriteShort( &netMessage, SC_REMOVE_NOTIFY_toPlayer );
			MSG_WriteString(&netMessage, playerName);								
		
			NET_SendUnreliableMessage(&pRemover->sock, &netMessage);
		}
		MSG_EndWriting(&netMessage);

		
		GTH_SendMessage_AckMessage(playerName);
	}
	
	else	
	{
		if (TRUE == g_config.isManager )
		{			
			int fromMemberIdx = MSG_ReadByte();											

			MSG_BeginWriting(&netMessage);
			MSG_Clear( &netMessage );
			{
				MSG_WriteByte(&netMessage, EXTEND_SECOND);
				MSG_WriteShort( &netMessage, HELPER_SYSTEM );
				MSG_WriteShort( &netMessage, SS_REMOVE_NOTIFY_toPlayer );
				MSG_WriteString(&netMessage, removeName);							
				MSG_WriteString(&netMessage, playerName);							
				
				
				for (int gameseridx=1; gameseridx < MAX_MEMBER_SERVER; gameseridx++)	
				{
					if ( !g_memberServer[gameseridx].active ) continue;
					if ( gameseridx == fromMemberIdx ) continue;					
					
					NET_SendUnreliableMessage(&g_memberServer[gameseridx].sock, &netMessage);
				}
			}
			MSG_EndWriting(&netMessage);
		}
	}
}
Exemplo n.º 23
0
/*
===================
SV_ReadClientMessage

Returns false if the client should be killed
===================
*/
qboolean SV_ReadClientMessage (void)
{
	int		ret;
	int		cmd;
	char		*s;
	
	do
	{
nextmsg:
		ret = NET_GetMessage (host_client->netconnection);
		if (ret == -1)
		{
			Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n");
			return false;
		}
		if (!ret)
			return true;
					
		MSG_BeginReading ();
		
		while (1)
		{
			if (!host_client->active)
				return false;	// a command caused an error

			if (msg_badread)
			{
				Sys_Printf ("SV_ReadClientMessage: badread\n");
				return false;
			}	
	
			cmd = MSG_ReadChar ();
			
			switch (cmd)
			{
			case -1:
				goto nextmsg;		// end of message
				
			default:
				Sys_Printf ("SV_ReadClientMessage: unknown command char\n");
				return false;
							
			case clc_nop:
//				Sys_Printf ("clc_nop\n");
				break;
				
			case clc_stringcmd:	
				s = MSG_ReadString ();
				if (host_client->privileged)
					ret = 2;
				else
					ret = 0;
				if (Q_strncasecmp(s, "status", 6) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "god", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "notarget", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "fly", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "name", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "noclip", 6) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "say", 3) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "say_team", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "tell", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "color", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "kill", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "pause", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "spawn", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "begin", 5) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "prespawn", 8) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "kick", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "ping", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "give", 4) == 0)
					ret = 1;
				else if (Q_strncasecmp(s, "ban", 3) == 0)
					ret = 1;
				if (ret == 2)
					Cbuf_InsertText (s);
				else if (ret == 1)
					Cmd_ExecuteString (s, src_client);
				else
					Con_DPrintf("%s tried to %s\n", host_client->name, s);
				break;
				
			case clc_disconnect:
//				Sys_Printf ("SV_ReadClientMessage: client disconnected\n");
				return false;
			
			case clc_move:
				SV_ReadClientMove (&host_client->cmd);
				break;
			}
		}
	} while (ret == 1);
	
	return true;
}
Exemplo n.º 24
0
void CHelperManager::ProcessMessage_ServerRequestSummons()
{
	int idx =-1;
	char toName[NAMESTRING+1], summoner[NAMESTRING+1];
	vec3_t position;

	strncpy(toName, MSG_ReadString(),NAMESTRING);
	toName[NAMESTRING]=NULL;
	strncpy(summoner, MSG_ReadString(),NAMESTRING);
	summoner[NAMESTRING]=NULL;

	int worldIdx = MSG_ReadByte();
	MSG_ReadPosition( position );
	

	idx = GTH_FindPCByName(toName);
	if (0 <= idx) 
	{
		playerCharacter_t* pTaker=gcpTools->GetPlayerRecordPointer(idx);
		if(NULL == pTaker) return;
		
		
	
		if( (playerCharacter_t::tagGonryunBattlePractice::MEMBERSHIP_LEADER
			== pTaker->GonryunBattlePractice.MemberShip) ||
			(playerCharacter_t::tagGonryunBattlePractice::MEMBERSHIP_OPENENT
			== pTaker->GonryunBattlePractice.MemberShip)) return;
		
		if( (pTaker->worldIdx == tagGolryunBattle::Golryun_Battle_Map_Index) ||
			(pTaker->worldIdx == DAN_BATTLEMAP_NO)) return;
		
		if(BUSY_STATE_NONE != pTaker->busyState) return;
		
		PC_SetSummonsInfo(pTaker, summoner,worldIdx, position);

		MSG_BeginWriting(&netMessage);
		MSG_Clear( &netMessage );
		{
			MSG_WriteByte(&netMessage, EXTEND_SECOND);
			MSG_WriteShort ( &netMessage, HELPER_SYSTEM);
			MSG_WriteShort(&netMessage, SC_SPAWN_Req_toTaker);
			MSG_WriteString(&netMessage, summoner);	
			NET_SendMessage(&pTaker->sock, &netMessage);
		}
		MSG_EndWriting(&netMessage);
	}
	else	
	{
		if (TRUE == g_config.isManager )
		{
			int fromMemberIdx = MSG_ReadByte(); 

			MSG_BeginWriting(&netMessage);
			MSG_Clear( &netMessage );
			{
				MSG_WriteByte(&netMessage, EXTEND_SECOND);
				MSG_WriteShort ( &netMessage, HELPER_SYSTEM );
				MSG_WriteShort(&netMessage, SS_SPAWN_Req_fromServer);
				MSG_WriteString(&netMessage, toName); 
				MSG_WriteString(&netMessage, summoner);	
				MSG_WriteByte(&netMessage, worldIdx);	
				MSG_WritePosition(&netMessage, position); 
							
				
				for (int serveridx =1; serveridx < MAX_MEMBER_SERVER; serveridx++)	
				{
					if ( !g_memberServer[serveridx].active ) continue;
					if ( serveridx == fromMemberIdx ) continue;	
					
					NET_SendUnreliableMessage(&g_memberServer[serveridx].sock, &netMessage);
				}
			}
			MSG_EndWriting(&netMessage);
		}
	}
}
Exemplo n.º 25
0
/*
=================
CL_ConnectionlessPacket

Responses to broadcasts, etc
=================
*/
void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
	char	*s;
	const char	*c;
	
	MSG_BeginReading( msg );
	MSG_ReadLong( msg );	// skip the -1

	s = MSG_ReadStringLine( msg );

	Cmd_TokenizeString( s );

	c = Cmd_Argv(0);

	Com_DPrintf ("CL packet %s: %s\n", NET_AdrToString(from), c);

	// challenge from the server we are connecting to
	if ( !strcmp(c, "challengeResponse") ) {
		if ( cls.state != CA_CONNECTING ) {
			Com_Printf( "Unwanted challenge response received.  Ignored.\n" );
		} else {
			// start sending challenge repsonse instead of challenge request packets
			clc.challenge = atoi(Cmd_Argv(1));
			cls.state = CA_CHALLENGING;
			clc.connectPacketCount = 0;
			clc.connectTime = -99999;

			// take this address as the new server address.  This allows
			// a server proxy to hand off connections to multiple servers
			clc.serverAddress = from;
		}
		return;
	}

	// server connection
	if ( !strcmp(c, "connectResponse") ) {
		if ( cls.state >= CA_CONNECTED ) {
			Com_Printf ("Dup connect received.  Ignored.\n");
			return;
		}
		if ( cls.state != CA_CHALLENGING ) {
			Com_Printf ("connectResponse packet while not connecting.  Ignored.\n");
			return;
		}
		if ( !NET_CompareBaseAdr( from, clc.serverAddress ) ) {
			Com_Printf( "connectResponse from a different address.  Ignored.\n" );
			Com_Printf( "%s should have been %s\n", NET_AdrToString( from ), 
				NET_AdrToString( clc.serverAddress ) );
			return;
		}
		Netchan_Setup (NS_CLIENT, &clc.netchan, from, Cvar_VariableIntegerValue( "net_qport" ) );
		cls.state = CA_CONNECTED;
		clc.lastPacketSentTime = -9999;		// send first packet immediately
		return;
	}

	// a disconnect message from the server, which will happen if the server
	// dropped the connection but it is still getting packets from us
	if (!strcmp(c, "disconnect")) {
		CL_DisconnectPacket( from );
		return;
	}

	// echo request from server
	if ( !strcmp(c, "echo") ) {
		NET_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv(1) );
		return;
	}

	// print request from server
	if ( !strcmp(c, "print") ) {
		s = MSG_ReadString( msg );
		UI_UpdateConnectionMessageString( s );
		Com_Printf( "%s", s );
		return;
	}


	Com_DPrintf ("Unknown connectionless packet command.\n");
}
Exemplo n.º 26
0
/**
 * @brief A download message has been received from the server
 */
void CL_ParseDownload(msg_t *msg)
{
	int           size;
	unsigned char data[MAX_MSGLEN];
	int           block;

	if (!*cls.download.downloadTempName)
	{
		Com_Printf("Server sending download, but no download was requested\n");
		CL_AddReliableCommand("stopdl");
		return;
	}

	// read the data
	block = MSG_ReadShort(msg);

	// www dl, if we haven't acknowledged the download redirect yet
	if (block == DLTYPE_WWW)
	{
		if (!cls.download.bWWWDl)
		{
			// server is sending us a www download
			Q_strncpyz(cls.download.originalDownloadName, cls.download.downloadName, sizeof(cls.download.originalDownloadName));
			Q_strncpyz(cls.download.downloadName, MSG_ReadString(msg), sizeof(cls.download.downloadName));
			cls.download.downloadSize  = MSG_ReadLong(msg);
			cls.download.downloadFlags = MSG_ReadLong(msg);
			if (cls.download.downloadFlags & (1 << DL_FLAG_URL))
			{
				Sys_OpenURL(cls.download.downloadName, qtrue);
				Cbuf_ExecuteText(EXEC_APPEND, "quit\n");
				CL_AddReliableCommand("wwwdl bbl8r");   // not sure if that's the right msg
				cls.download.bWWWDlAborting = qtrue;
				return;
			}
			Cvar_SetValue("cl_downloadSize", cls.download.downloadSize);
			Com_DPrintf("Server redirected download: %s\n", cls.download.downloadName);
			cls.download.bWWWDl = qtrue; // activate wwwdl client loop
			CL_AddReliableCommand("wwwdl ack");
			// make sure the server is not trying to redirect us again on a bad checksum
			if (strstr(cls.download.badChecksumList, va("@%s", cls.download.originalDownloadName)))
			{
				Com_Printf("refusing redirect to %s by server (bad checksum)\n", cls.download.downloadName);
				CL_AddReliableCommand("wwwdl fail");
				cls.download.bWWWDlAborting = qtrue;
				return;
			}
			// make downloadTempName an OS path
			Q_strncpyz(cls.download.downloadTempName, FS_BuildOSPath(Cvar_VariableString("fs_homepath"), cls.download.downloadTempName, ""), sizeof(cls.download.downloadTempName));
			cls.download.downloadTempName[strlen(cls.download.downloadTempName) - 1] = '\0';
			if (!DL_BeginDownload(cls.download.downloadTempName, cls.download.downloadName))
			{
				// setting bWWWDl to false after sending the wwwdl fail doesn't work
				// not sure why, but I suspect we have to eat all remaining block -1 that the server has sent us
				// still leave a flag so that CL_WWWDownload is inactive
				// we count on server sending us a gamestate to start up clean again
				CL_AddReliableCommand("wwwdl fail");
				cls.download.bWWWDlAborting = qtrue;
				Com_Printf("Failed to initialize download for '%s'\n", cls.download.downloadName);
			}
			// Check for a disconnected download
			// we'll let the server disconnect us when it gets the bbl8r message
			if (cls.download.downloadFlags & (1 << DL_FLAG_DISCON))
			{
				CL_AddReliableCommand("wwwdl bbl8r");
				cls.download.bWWWDlDisconnected = qtrue;
			}
			return;
		}
		else
		{
			// server keeps sending that message till we acknowledge it, eat and ignore
			//MSG_ReadLong( msg );
			MSG_ReadString(msg);
			MSG_ReadLong(msg);
			MSG_ReadLong(msg);
			return;
		}
	}

	if (!block)
	{
		// block zero is special, contains file size
		cls.download.downloadSize = MSG_ReadLong(msg);

		Cvar_SetValue("cl_downloadSize", cls.download.downloadSize);

		if (cls.download.downloadSize < 0)
		{
			Com_Error(ERR_DROP, "%s", MSG_ReadString(msg));
			return;
		}
	}

	size = MSG_ReadShort(msg);
	if (size < 0 || size > sizeof(data))
	{
		Com_Error(ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk.", size);
		return;
	}

	MSG_ReadData(msg, data, size);

	if (cls.download.downloadBlock != block)
	{
		Com_DPrintf("CL_ParseDownload: Expected block %d, got %d\n", cls.download.downloadBlock, block);
		return;
	}

	// open the file if not opened yet
	if (!cls.download.download)
	{
		cls.download.download = FS_SV_FOpenFileWrite(cls.download.downloadTempName);

		if (!cls.download.download)
		{
			Com_Printf("Could not create %s\n", cls.download.downloadTempName);
			CL_AddReliableCommand("stopdl");
			Com_NextDownload();
			return;
		}
	}

	if (size)
	{
		FS_Write(data, size, cls.download.download);
	}

	CL_AddReliableCommand(va("nextdl %d", cls.download.downloadBlock));
	cls.download.downloadBlock++;

	cls.download.downloadCount += size;

	// So UI gets access to it
	Cvar_SetValue("cl_downloadCount", cls.download.downloadCount);

	if (!size)     // A zero length block means EOF
	{
		if (cls.download.download)
		{
			FS_FCloseFile(cls.download.download);
			cls.download.download = 0;

			// rename the file
			FS_SV_Rename(cls.download.downloadTempName, cls.download.downloadName);
		}
		*cls.download.downloadTempName = *cls.download.downloadName = 0;
		Cvar_Set("cl_downloadName", "");

		// send intentions now
		// We need this because without it, we would hold the last nextdl and then start
		// loading right away.  If we take a while to load, the server is happily trying
		// to send us that last block over and over.
		// Write it twice to help make sure we acknowledge the download
		CL_WritePacket();
		CL_WritePacket();

		// get another file if needed
		Com_NextDownload();
	}
}
Exemplo n.º 27
0
void CPostFunc::GTH_ProcessMessage_PostSystem_OpenWindow()
{

	
	int	PostIdx = 0;
	int PostCount = -1;
	

	enum tagGCPacket_POSTSYSTEM_OPEN::enumCode code =
		tagGCPacket_POSTSYSTEM_OPEN::enumCode::fail;
	code = static_cast<enum tagGCPacket_POSTSYSTEM_OPEN::enumCode>(MSG_ReadByte());	
	
	
	switch( code ) 
	{
	case tagGCPacket_POSTSYSTEM_OPEN::enumCode::success:
		{
			PostCount = MSG_ReadLong();	

			g_cgv.myCharacterInfo->m_PostMng.InitPostSystem();		
			
			for ( PostIdx = 0;  PostIdx < PostCount; PostIdx++)
			{
				CPostManager::PostPackage_t PostPackage;
				memset(&PostPackage, 0, sizeof(CPostManager::PostPackage_t) );
				
				PostPackage.iPostIdx		= MSG_ReadLong();
				sstrncpy(PostPackage.szFromName, MSG_ReadString(), NAMESTRING);
				PostPackage.szFromName[NAMESTRING] = NULL;
				CTools::Replace_doubleQUOTATIONmark_by_singleQUOTATIONmark(PostPackage.szFromName);
				
				sstrncpy(PostPackage.szPostTitle,  MSG_ReadString(), CPostManager::POST_TITLESIZE);
				PostPackage.szPostTitle[CPostManager::POST_TITLESIZE] = NULL;
				CTools::Replace_doubleQUOTATIONmark_by_singleQUOTATIONmark(PostPackage.szPostTitle);

				
				sstrncpy(PostPackage.szSendPostTime	, MSG_ReadString(), CPostManager::POST_SENDTIME_INFO_STR_LEN);
				PostPackage.szSendPostTime[CPostManager::POST_SENDTIME_INFO_STR_LEN] = NULL;
				


				sstrncpy(PostPackage.szMailStr, MSG_ReadString(), CPostManager::POST_STRSIZE);
				PostPackage.szMailStr[CPostManager::POST_STRSIZE] = NULL;
				CTools::Replace_doubleQUOTATIONmark_by_singleQUOTATIONmark(PostPackage.szMailStr);
				
				int state = MSG_ReadLong();
				
				if ( state == 0)		
					PostPackage.MailState  =  CPostManager::enumPostPackageState::POSTPACKAGE_UNCHECK;
				else
					PostPackage.MailState  =  CPostManager::enumPostPackageState::POSTPACKAGE_CHECK;
				
				
				
				int nak = MSG_ReadLong();
				PostPackage.Nak = nak;

				int SendType = MSG_ReadLong();				
				
				
				PostPackage.iRemainDays = MSG_ReadLong();	


				if ( SendType == 0)
					PostPackage.PostSendType = CPostManager::enumPostSendType::POST_SENDTYPE_WEB;
				else
					PostPackage.PostSendType = CPostManager::enumPostSendType::POST_SENDTYPE_CHAR;
				
				
				
				g_cgv.myCharacterInfo->m_PostMng.AddPostPackage(PostPackage);				
				
			}					
			
			
				g_ifMng->m_PostWin->InitIFPost();
				g_ifMng->m_PostWin->SetDisplayMode(true);				
				g_ifMng->m_chatWin->Enable( false );

				g_ifMng->m_PostWin->Enable(1);
				g_ifMng->SetFocus( g_ifMng->m_PostWin );				

		}
		break;		

	case tagGCPacket_POSTSYSTEM_OPEN::enumCode::fail:
		g_ifMng->SetMessage( g_LPACK.GetMassage(LPACK_TYPE_NORMAL, 322), 
			g_LPACK.GetMassage(LPACK_TYPE_NORMAL2, 226) );		
		break;

	default:
		break;		
	}	
	

}
Exemplo n.º 28
0
qboolean CL_PeekSnapshot(int snapshotNumber, snapshot_t *snapshot)
{
	clSnapshot_t *clSnap;
	clSnapshot_t csn;
	int          i, count;
	int          origPosition;
	int          cmd;
	//char         *s;
	char     buffer[16];
	qboolean success = qfalse;
	int      r;
	msg_t    buf;
	byte     bufData[MAX_MSGLEN];
	int      j;
	int      lastPacketTimeOrig;
	int      parseEntitiesNumOrig;
	int      currentSnapNum;
	//int      serverMessageSequence;

	clSnap = &csn;

	if (!clc.demoplaying)
	{
		return qfalse;
	}

	if (snapshotNumber <= cl.snap.messageNum)
	{
		success = CL_GetSnapshot(snapshotNumber, snapshot);
		if (!success)
		{
			Com_FuncDPrinf("snapshot number outside of backup buffer\n");
			return qfalse;
		}
		return qtrue;
	}

	if (snapshotNumber > cl.snap.messageNum + 1)
	{
		Com_FuncDPrinf("FIXME CL_PeekSnapshot  %d >  cl.snap.messageNum + 1 (%d)\n", snapshotNumber, cl.snap.messageNum);
		//return qfalse;
	}

	parseEntitiesNumOrig = cl.parseEntitiesNum;
	lastPacketTimeOrig   = clc.lastPacketTime;
	// CL_ReadDemoMessage()
	origPosition = FS_FTell(clc.demofile);

	currentSnapNum = cl.snap.messageNum;

	for (j = 0; j < snapshotNumber - currentSnapNum; j++)
	{
		// get the sequence number
		memset(buffer, 0, sizeof(buffer));
		r = FS_Read(&buffer, 4, clc.demofile);
		if (r != 4)
		{
			Com_FuncDPrinf("couldn't read sequence number\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}
		//serverMessageSequence = LittleLong(*((int *)buffer));

		// init the message
		memset(&buf, 0, sizeof(msg_t));
		MSG_Init(&buf, bufData, sizeof(bufData));

		// get the length
		r = FS_Read(&buf.cursize, 4, clc.demofile);
		if (r != 4)
		{
			Com_FuncDPrinf("couldn't get length\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}

		buf.cursize = LittleLong(buf.cursize);
		if (buf.cursize == -1)
		{
			Com_FuncDPrinf("buf.cursize == -1\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}

		if (buf.cursize > buf.maxsize)
		{
			Com_FuncDrop("demoMsglen > MAX_MSGLEN");
		}

		r = FS_Read(buf.data, buf.cursize, clc.demofile);
		if (r != buf.cursize)
		{
			Com_FuncDPrinf("Demo file was truncated.\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qfalse;
		}

		clc.lastPacketTime = cls.realtime;
		buf.readcount      = 0;

		MSG_Bitstream(&buf);
		// get the reliable sequence acknowledge number
		MSG_ReadLong(&buf);

		// parse the message
		while (qtrue)
		{
			if (buf.readcount > buf.cursize)
			{
				Com_FuncDrop("read past end of server message");
				break;
			}

			cmd = MSG_ReadByte(&buf);

			if (cmd == svc_EOF)
			{
				break;
			}
			success = qfalse;

			switch (cmd)
			{
			default:
				Com_FuncDrop("Illegible server message");
				break;
			case svc_nop:
				break;
			case svc_serverCommand:
				MSG_ReadLong(&buf);  // seq
				//s = MSG_ReadString(&buf);
				MSG_ReadString(&buf);
				break;
			case svc_gamestate:
				Com_FuncDPrinf("FIXME gamestate\n");
				goto alldone;
				break;
			case svc_snapshot:
				// TODO: changed this check if it works
				CL_ParseSnapshot(&buf);
				if (cl.snap.valid)
				{
					success = qtrue;
				}
				break;
			case svc_download:
				Com_FuncDPrinf("FIXME download\n");
				goto alldone;
				break;
			}
		}

alldone:

		if (!success)
		{
			Com_FuncDPrinf("failed\n");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return success;
		}

		// FIXME other ents not supported yet

		// if the entities in the frame have fallen out of their
		// circular buffer, we can't return it
		if (cl.parseEntitiesNum - clSnap->parseEntitiesNum >= MAX_PARSE_ENTITIES)
		{
			Com_FuncDPrinf("cl.parseEntitiesNum - clSnap->parseEntitiesNum >= MAX_PARSE_ENTITIES");
			FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
			clc.lastPacketTime  = lastPacketTimeOrig;
			cl.parseEntitiesNum = parseEntitiesNumOrig;
			return qtrue;  // FIXME if you fix other ents
		}

		// write the snapshot
		snapshot->snapFlags             = clSnap->snapFlags;
		snapshot->serverCommandSequence = clSnap->serverCommandNum;
		snapshot->ping                  = clSnap->ping;
		snapshot->serverTime            = clSnap->serverTime;
		Com_Memcpy(snapshot->areamask, clSnap->areamask, sizeof(snapshot->areamask));
		snapshot->ps = clSnap->ps;
		count        = clSnap->numEntities;

		if (count > MAX_ENTITIES_IN_SNAPSHOT)
		{
			Com_FuncDPrinf("truncated %i entities to %i\n", count, MAX_ENTITIES_IN_SNAPSHOT);
			count = MAX_ENTITIES_IN_SNAPSHOT;
		}

		snapshot->numEntities = count;
		for (i = 0; i < count; i++)
		{
			snapshot->entities[i] = cl.parseEntities[(clSnap->parseEntitiesNum + i) & (MAX_PARSE_ENTITIES - 1)];
		}

	}

	FS_Seek(clc.demofile, origPosition, FS_SEEK_SET);
	clc.lastPacketTime  = lastPacketTimeOrig;
	cl.parseEntitiesNum = parseEntitiesNumOrig;
	// TODO: configstring changes and server commands!!!

	return qtrue;
}
Exemplo n.º 29
0
/*
=====================
CL_ParseCommandString

Command strings are just saved off until cgame asks for them
when it transitions a snapshot
=====================
*/
void CL_ParseCommandString( msg_t *msg ) {
	char	*s;
	int		seq;
	int		index;

#ifdef _DONETPROFILE_
	int startBytes,endBytes;
	startBytes=msg->readcount;
#endif
	seq = MSG_ReadLong( msg );
	s = MSG_ReadString( msg );
#ifdef _DONETPROFILE_
	endBytes=msg->readcount;
	ClReadProf().AddField("svc_serverCommand",endBytes-startBytes);
#endif
	// see if we have already executed stored it off
	if ( clc.serverCommandSequence >= seq ) {
		return;
	}
	clc.serverCommandSequence = seq;

	index = seq & (MAX_RELIABLE_COMMANDS-1);
	/*
	if (s[0] == 'c' && s[1] == 's' && s[2] == ' ' && s[3] == '0' && s[4] == ' ')
	{ //yes.. we seem to have an incoming server info.
		char *f = strstr(s, "g_debugMelee");
		if (f)
		{
			while (*f && *f != '\\')
			{ //find the \ after it
				f++;
			}
			if (*f == '\\')
			{ //got it
				int i = 0;

				f++;
				while (*f && *f != '\\' && i < 128)
				{
					hiddenCvarVal[i] = *f;
					i++;
					f++;
				}
				hiddenCvarVal[i] = 0;

				//don't worry about backing over beginning of string I guess,
				//we already know we successfully strstr'd the initial string
				//which exceeds this length.
				//MSG_ReadString appears to just return a static buffer so I
				//can stomp over its contents safely.
				f--;
				*f = '\"';
				f--;
				*f = ' ';
				f--;
				*f = '0';
				f--;
				*f = ' ';
				f--;
				*f = 's';
				f--;
				*f = 'c';

				//the normal configstring gets to start here...
				s = f;
			}
		}
	}
	*/
	Q_strncpyz( clc.serverCommands[ index ], s, sizeof( clc.serverCommands[ index ] ) );
}
Exemplo n.º 30
0
/*
* SV_ParseClientMessage
* The current message is parsed for the given client
*/
void SV_ParseClientMessage( client_t *client, msg_t *msg )
{
	int c;
	char *s;
	bool move_issued;
	unsigned int cmdNum;

	if( !msg )
		return;

	if (!client->tvclient) {
		SV_UpdateActivity();
	}

	// only allow one move command
	move_issued = false;
	while( 1 )
	{
		if( msg->readcount > msg->cursize )
		{
			Com_Printf( "SV_ParseClientMessage: badread\n" );
			SV_DropClient( client, DROP_TYPE_GENERAL, "%s", "Error: Bad message" );
			return;
		}

		c = MSG_ReadByte( msg );
		if( c == -1 )
			break;

		switch( c )
		{
		default:
			Com_Printf( "SV_ParseClientMessage: unknown command char\n" );
			SV_DropClient( client, DROP_TYPE_GENERAL, "%s", "Error: Unknown command char" );
			return;

		case clc_nop:
			break;

		case clc_move:
			{
				if( move_issued )
					return; // someone is trying to cheat...

				move_issued = true;
				SV_ParseMoveCommand( client, msg );
			}
			break;

		case clc_svcack:
			{
				if( client->reliable )
				{
					Com_Printf( "SV_ParseClientMessage: svack from reliable client\n" );
					SV_DropClient( client, DROP_TYPE_GENERAL, "%s", "Error: svack from reliable client" );
					return;
				}
				cmdNum = MSG_ReadLong( msg );
				if( cmdNum < client->reliableAcknowledge || cmdNum > client->reliableSent )
				{
					//SV_DropClient( client, DROP_TYPE_GENERAL, "%s", "Error: bad server command acknowledged" );
					return;
				}
				client->reliableAcknowledge = cmdNum;
			}
			break;

		case clc_clientcommand:
			if( !client->reliable )
			{
				cmdNum = MSG_ReadLong( msg );
				if( cmdNum <= client->clientCommandExecuted )
				{
					s = MSG_ReadString( msg ); // read but ignore
					continue;
				}
				client->clientCommandExecuted = cmdNum;
			}
			s = MSG_ReadString( msg );
			SV_ExecuteUserCommand( client, s );
			if( client->state == CS_ZOMBIE )
				return; // disconnect command
			break;

		case clc_extension:
			if( 1 )
			{
				int ext, len;

				ext = MSG_ReadByte( msg );		// extension id
				MSG_ReadByte( msg );			// version number
				len = MSG_ReadShort( msg );		// command length

				switch( ext )
				{
				default:
					// unsupported
					MSG_SkipData( msg, len );
					break;
				}
			}
			break;
		}
	}
}