All pastes #806657 Raw Edit

Stuff

public text v1 · immutable
·published 2007-12-05 20:22 UTC
rendered paste body
MVDSV:
/*
==================
Cmd_PreSpawn_f
==================
*/
static void Cmd_PreSpawn_f (void)
{
	unsigned int buf;
	unsigned int check;

	if (sv_client->state != cs_connected)
	{
		Con_Printf ("prespawn not valid -- already spawned\n");
		return;
	}

	// handle the case of a level changing while a client was connecting
	if (Q_atoi(Cmd_Argv(1)) != svs.spawncount)
	{
		SV_ClearReliable (sv_client);
		Con_Printf ("SV_PreSpawn_f from different level\n");
		Cmd_New_f ();
		return;
	}

	buf = Q_atoi(Cmd_Argv(2));
	if (buf >= sv.num_signon_buffers)
		buf = 0;

	if (!buf)
	{
		// should be three numbers following containing checksums
		check = Q_atoi(Cmd_Argv(3));

		//		Con_DPrintf("Client check = %d\n", check);

		if ((int)sv_mapcheck.value && check != sv.map_checksum &&
			check != sv.map_checksum2)
		{
			SV_ClientPrintf (sv_client, PRINT_HIGH,
			                 "Map model file does not match (%s), %i != %i/%i.\n"
			                 "You may need a new version of the map, or the proper install files.\n",
					 sv.modelname, check, sv.map_checksum, sv.map_checksum2);
			SV_DropClient (sv_client);
			return;
		}
		sv_client->checksum = check;
	}

	//NOTE:  This doesn't go through ClientReliableWrite since it's before the user
	//spawns.  These functions are written to not overflow
	if (sv_client->num_backbuf)
	{
		Con_Printf("WARNING %s: [SV_PreSpawn] Back buffered (%d0), clearing\n", sv_client->name, sv_client->netchan.message.cursize);
		sv_client->num_backbuf = 0;
		SZ_Clear(&sv_client->netchan.message);
	}

	SZ_Write (&sv_client->netchan.message,
	          sv.signon_buffers[buf],
	          sv.signon_buffer_size[buf]);

	buf++;
	if (buf == sv.num_signon_buffers)
	{	// all done prespawning
		MSG_WriteByte (&sv_client->netchan.message, svc_stufftext);
		MSG_WriteString (&sv_client->netchan.message, va("cmd spawn %i 0\n",svs.spawncount) );
	}
	else
	{	// need to prespawn more
		MSG_WriteByte (&sv_client->netchan.message, svc_stufftext);
		MSG_WriteString (&sv_client->netchan.message,
		                 va("cmd prespawn %i %i\n", svs.spawncount, buf) );
	}
}

FTE:
void SV_PreSpawn_f (void)
{
	unsigned	buf, bufs;
	unsigned	check;

	unsigned statics;

	if (host_client->state != cs_connected)
	{
		Con_Printf ("prespawn not valid -- already spawned\n");
		return;
	}

	// handle the case of a level changing while a client was connecting
	if ( atoi(Cmd_Argv(1)) != svs.spawncount && !sv.msgfromdemo)
	{
		Con_Printf ("SV_PreSpawn_f from different level\n");
		SV_New_f ();
		return;
	}

	if (sv.democausesreconnect)
		bufs = sv.num_demosignon_buffers;
	else
		bufs = sv.num_signon_buffers;
	statics = sv.numextrastatics;
	buf = atoi(Cmd_Argv(2));

	if (buf >= bufs+statics+sv.num_edicts+255)
	{
		SV_EndRedirect();
		Con_Printf ("SV_Modellist_f: %s send an invalid index\n", host_client->name);
		SV_DropClient(host_client);
		return;
	}

	if (!buf)
	{
		// should be three numbers following containing checksums
		check = atoi(Cmd_Argv(3));

//		Con_DPrintf("Client check = %d\n", check);

		if (sv_mapcheck.value && check != sv.worldmodel->checksum &&
			check != LittleLong(sv.worldmodel->checksum2))
		if (!sv.demofile || (sv.demofile && !sv.democausesreconnect))	//demo playing causes no check. If it's the return level, check anyway to avoid that loophole.
		{
			SV_ClientTPrintf (host_client, PRINT_HIGH,
				STL_MAPCHEAT,
				sv.modelname, check, sv.worldmodel->checksum, sv.worldmodel->checksum2);
			SV_DropClient (host_client);
			return;
		}
		host_client->checksum = check;
	}

//NOTE:  This doesn't go through ClientReliableWrite since it's before the user
//spawns.  These functions are written to not overflow
	if (host_client->num_backbuf) {
		Con_Printf("WARNING %s: [SV_PreSpawn] Back buffered (%d), clearing", host_client->name, host_client->netchan.message.cursize);
		host_client->num_backbuf = 0;
		SZ_Clear(&host_client->netchan.message);
	}

	if (buf >= bufs && !sv.democausesreconnect)
	{
		int i;
		entity_state_t from;
		entity_state_t *state;
		edict_t *ent;
		svcustomtents_t *ctent;


		memset(&from, 0, sizeof(from));
		while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))	//static entities
		{
			if (buf - bufs >= sv.numextrastatics)
				break;

			state = &sv.extendedstatics[buf - bufs];

			if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2)
			{
				MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic2);
				SV_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions);
			}
			else if (state->modelindex < 256)
			{
				MSG_WriteByte(&host_client->netchan.message, svc_spawnstatic);

				MSG_WriteByte (&host_client->netchan.message, state->modelindex&255);

				MSG_WriteByte (&host_client->netchan.message, state->frame);
				MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
				MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum);
				for (i=0 ; i<3 ; i++)
				{
					MSG_WriteCoord(&host_client->netchan.message, state->origin[i]);
					MSG_WriteAngle(&host_client->netchan.message, state->angles[i]);
				}
			}
			buf++;
		}
		while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))	//baselines
		{
			if (buf - bufs - sv.numextrastatics >= sv.num_edicts)
				break;

			ent = EDICT_NUM(svprogfuncs, buf - bufs - sv.numextrastatics);

			state = &ent->baseline;
			if (!state->number || !state->modelindex)
			{	//ent doesn't have a baseline
				buf++;
				continue;
			}

			if (!ent)
			{
				MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);

				MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.numextrastatics);

				MSG_WriteByte (&host_client->netchan.message, 0);

				MSG_WriteByte (&host_client->netchan.message, 0);
				MSG_WriteByte (&host_client->netchan.message, 0);
				MSG_WriteByte (&host_client->netchan.message, 0);
				for (i=0 ; i<3 ; i++)
				{
					MSG_WriteCoord(&host_client->netchan.message, 0);
					MSG_WriteAngle(&host_client->netchan.message, 0);
				}
			}
			else if (host_client->fteprotocolextensions & PEXT_SPAWNSTATIC2)
			{
				MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline2);
				SV_WriteDelta(&from, state, &host_client->netchan.message, true, host_client->fteprotocolextensions);
			}
			else if (state->modelindex < 256)
			{
				MSG_WriteByte(&host_client->netchan.message, svc_spawnbaseline);

				MSG_WriteShort (&host_client->netchan.message, buf - bufs - sv.numextrastatics);

				MSG_WriteByte (&host_client->netchan.message, state->modelindex);

				MSG_WriteByte (&host_client->netchan.message, state->frame);
				MSG_WriteByte (&host_client->netchan.message, (int)state->colormap);
				MSG_WriteByte (&host_client->netchan.message, (int)state->skinnum);
				for (i=0 ; i<3 ; i++)
				{
					MSG_WriteCoord(&host_client->netchan.message, state->origin[i]);
					MSG_WriteAngle(&host_client->netchan.message, state->angles[i]);
				}
			}

			buf++;
		}
		while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2))
		{
			i = buf - bufs - sv.numextrastatics - sv.num_edicts;
			if (i >= 255)
				break;

			ctent = &sv.customtents[i];

			buf++;
			if (!*ctent->particleeffecttype)
			{	//effect isn't registered.
				continue;
			}

			if (host_client->fteprotocolextensions & PEXT_CUSTOMTEMPEFFECTS)
			{
				MSG_WriteByte(&host_client->netchan.message, svc_customtempent);
				MSG_WriteByte(&host_client->netchan.message, 255);
				MSG_WriteByte(&host_client->netchan.message, i);
				MSG_WriteByte(&host_client->netchan.message, ctent->netstyle);
				MSG_WriteString(&host_client->netchan.message, ctent->particleeffecttype);
				if (ctent->netstyle & CTE_STAINS)
				{
					MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
					MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
					MSG_WriteChar(&host_client->netchan.message, ctent->stain[0]);
					MSG_WriteByte(&host_client->netchan.message, ctent->radius);
				}
				if (ctent->netstyle & CTE_GLOWS)
				{
					MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[0]);
					MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[1]);
					MSG_WriteByte(&host_client->netchan.message, ctent->dlightrgb[2]);
					MSG_WriteByte(&host_client->netchan.message, ctent->dlightradius);
					MSG_WriteByte(&host_client->netchan.message, ctent->dlighttime);
				}
			}
		}
	}
	else if (buf >= bufs)
	{
		buf = bufs+sv.numextrastatics+sv.num_edicts+255;
	}
	else
	{
		if (sv.democausesreconnect)
		{
			if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf]+30 < host_client->netchan.message.maxsize)
			{
				SZ_Write (&host_client->netchan.message,
					sv.demosignon_buffers[buf],
					sv.demosignon_buffer_size[buf]);
				buf++;
			}
		}
		else
		{
			if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf]+30 < host_client->netchan.message.maxsize)
			{
				SZ_Write (&host_client->netchan.message,
					sv.signon_buffers[buf],
					sv.signon_buffer_size[buf]);
					buf++;
			}
		}
	}
	if (buf == bufs+sv.numextrastatics+sv.num_edicts+255)
	{	// all done prespawning
		MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
		MSG_WriteString (&host_client->netchan.message, va("cmd spawn %i\n",svs.spawncount) );
	}
	else
	{	// need to prespawn more
		MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
		MSG_WriteString (&host_client->netchan.message,
			va("cmd prespawn %i %i\n", svs.spawncount, buf) );
	}
}