803 lines · 17.4 KB · C
RawDownload
// cl_parse.c  -- parse a message received from the server #include <u.h>#include <libc.h>#include <stdio.h>#include "dat.h"#include "fns.h" char *svc_strings[256] ={	"svc_bad", 	"svc_muzzleflash",	"svc_muzzlflash2",	"svc_temp_entity",	"svc_layout",	"svc_inventory", 	"svc_nop",	"svc_disconnect",	"svc_reconnect",	"svc_sound",	"svc_print",	"svc_stufftext",	"svc_serverdata",	"svc_configstring",	"svc_spawnbaseline",		"svc_centerprint",	"svc_download",	"svc_playerinfo",	"svc_packetentities",	"svc_deltapacketentities",	"svc_frame"}; //============================================================================= void CL_DownloadFileName(char *dest, int destlen, char *fn){	if (strncmp(fn, "players", 7) == 0)		Com_sprintf (dest, destlen, "%s/%s", BASEDIRNAME, fn);	else		Com_sprintf (dest, destlen, "%s/%s", FS_Gamedir(), fn);} /*===============CL_CheckOrDownloadFile Returns true if the file exists, otherwise it attemptsto start a download from the server.===============*/qboolean	CL_CheckOrDownloadFile (char *filename){	FILE *fp;	char	name[MAX_OSPATH]; 	if (strstr (filename, ".."))	{		Com_Printf ("Refusing to download a path with ..\n");		return true;	} 	if (FS_LoadFile (filename, NULL) != -1)	{	// it exists, no need to download		return true;	} 	strcpy (cls.downloadname, filename); 	// download to a temp name, and only rename	// to the real name when done, so if interrupted	// a runt file wont be left	COM_StripExtension (cls.downloadname, cls.downloadtempname);	strcat (cls.downloadtempname, ".tmp"); //ZOID	// check to see if we already have a tmp for this file, if so, try to resume	// open the file if not opened yet	CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); //	FS_CreatePath (name); 	fp = fopen (name, "r+b");	if (fp) { // it exists		int len;		fseek(fp, 0, SEEK_END);		len = ftell(fp); 		cls.download = fp; 		// give the server an offset to start the download		Com_Printf ("Resuming %s\n", cls.downloadname);		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);		MSG_WriteString (&cls.netchan.message,			va("download %s %i", cls.downloadname, len));	} else {		Com_Printf ("Downloading %s\n", cls.downloadname);		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);		MSG_WriteString (&cls.netchan.message,			va("download %s", cls.downloadname));	} 	cls.downloadnumber++; 	return false;} /*===============CL_Download_f Request a download from the server===============*/void	CL_Download_f (void){	char filename[MAX_OSPATH]; 	if (Cmd_Argc() != 2) {		Com_Printf("Usage: download <filename>\n");		return;	} 	Com_sprintf(filename, sizeof(filename), "%s", Cmd_Argv(1)); 	if (strstr (filename, ".."))	{		Com_Printf ("Refusing to download a path with ..\n");		return;	} 	if (FS_LoadFile (filename, NULL) != -1)	{	// it exists, no need to download		Com_Printf("File already exists.\n");		return;	} 	strcpy (cls.downloadname, filename);	Com_Printf ("Downloading %s\n", cls.downloadname); 	// download to a temp name, and only rename	// to the real name when done, so if interrupted	// a runt file wont be left	COM_StripExtension (cls.downloadname, cls.downloadtempname);	strcat (cls.downloadtempname, ".tmp"); 	MSG_WriteByte (&cls.netchan.message, clc_stringcmd);	MSG_WriteString (&cls.netchan.message,		va("download %s", cls.downloadname)); 	cls.downloadnumber++;} /*======================CL_RegisterSounds======================*/void CL_RegisterSounds (void){	int		i; 	S_BeginRegistration ();	CL_RegisterTEntSounds ();	for (i=1 ; i<MAX_SOUNDS ; i++)	{		if (!cl.configstrings[CS_SOUNDS+i][0])			break;		cl.sound_precache[i] = S_RegisterSound (cl.configstrings[CS_SOUNDS+i]);		Sys_SendKeyEvents ();	// pump message loop	}	S_EndRegistration ();} static voidrename(char *old, char *new){	char *p;	Dir d; 	if((p = strrchr(new, '/')) == nil)		p = new;	else		p++;	nulldir(&d);	d.name = p;	if(dirwstat(old, &d) < 0)		fprint(2, "rename: %r\n");} /*=====================CL_ParseDownload A download message has been received from the server=====================*/void CL_ParseDownload (void){	int		size, percent;	char	name[MAX_OSPATH]; 	// read the data	size = MSG_ReadShort (&net_message);	percent = MSG_ReadByte (&net_message);	if (size == -1)	{		Com_Printf ("Server does not have this file.\n");		if (cls.download)		{			// if here, we tried to resume a file but the server said no			fclose (cls.download);			cls.download = NULL;		}		CL_RequestNextDownload ();		return;	} 	// open the file if not opened yet	if (!cls.download)	{		CL_DownloadFileName(name, sizeof(name), cls.downloadtempname); 		FS_CreatePath (name); 		cls.download = fopen (name, "wb");		if (!cls.download)		{			net_message.readcount += size;			Com_Printf ("Failed to open %s\n", cls.downloadtempname);			CL_RequestNextDownload ();			return;		}	} 	fwrite (net_message.data + net_message.readcount, 1, size, cls.download);	net_message.readcount += size; 	if (percent != 100)	{		// request next block// change display routines by zoid/*		Com_Printf (".");		if (10*(percent/10) != cls.downloadpercent)		{			cls.downloadpercent = 10*(percent/10);			Com_Printf ("%i%%", cls.downloadpercent);		}*/		cls.downloadpercent = percent; 		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);		SZ_Print (&cls.netchan.message, "nextdl");	}	else	{		char	oldn[MAX_OSPATH];		char	newn[MAX_OSPATH]; //		Com_Printf ("100%%\n"); 		fclose (cls.download); 		// rename the temp file to it's final name		CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname);		CL_DownloadFileName(newn, sizeof(newn), cls.downloadname);		rename (oldn, newn);	/* FIXME */ 		cls.download = NULL;		cls.downloadpercent = 0; 		// get another file if needed 		CL_RequestNextDownload ();	}}  /*=====================================================================   SERVER CONNECTING MESSAGES =====================================================================*/ /*==================CL_ParseServerData==================*/void CL_ParseServerData (void){	extern cvar_t	*fs_gamedirvar;	char	*str;	int		i;		Com_DPrintf ("Serverdata packet received.\n");//// wipe the client_state_t struct//	CL_ClearState ();	cls.state = ca_connected; // parse protocol version number	i = MSG_ReadLong (&net_message);	cls.serverProtocol = i; 	// BIG HACK to let demos from release work with the 3.0x patch!!!	if (Com_ServerState() && PROTOCOL_VERSION == 34)	{	}	else if (i != PROTOCOL_VERSION)		Com_Error (ERR_DROP,"Server returned version %i, not %i", i, PROTOCOL_VERSION); 	cl.servercount = MSG_ReadLong (&net_message);	cl.attractloop = MSG_ReadByte (&net_message); 	// game directory	str = MSG_ReadString (&net_message);	strncpy (cl.gamedir, str, sizeof(cl.gamedir)-1); 	// set gamedir	if ((*str && (!fs_gamedirvar->string || !*fs_gamedirvar->string || strcmp(fs_gamedirvar->string, str))) || (!*str && (fs_gamedirvar->string || *fs_gamedirvar->string)))		Cvar_Set("game", str); 	// parse player entity number	cl.playernum = MSG_ReadShort (&net_message); 	// get the full level name	str = MSG_ReadString (&net_message); 	if (cl.playernum == -1)	{	// playing a cinematic or showing a pic, not a level		SCR_PlayCinematic (str);	}	else	{		// seperate the printfs so the server message can have a color		Com_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");		Com_Printf ("%c%s\n", 2, str); 		// need to prep refresh at next oportunity		cl.refresh_prepped = false;	}} /*==================CL_ParseBaseline==================*/void CL_ParseBaseline (void){	entity_state_t	*es;	int				bits;	int				newnum;	entity_state_t	nullstate; 	memset (&nullstate, 0, sizeof(nullstate)); 	newnum = CL_ParseEntityBits (&bits);	es = &cl_entities[newnum].baseline;	CL_ParseDelta (&nullstate, es, newnum, bits);}  /*================CL_LoadClientinfo ================*/void CL_LoadClientinfo (clientinfo_t *ci, char *s){	int i;	char		*t;	char		model_name[MAX_QPATH];	char		skin_name[MAX_QPATH];	char		model_filename[MAX_QPATH];	char		skin_filename[MAX_QPATH];	char		weapon_filename[MAX_QPATH]; 	strncpy(ci->cinfo, s, sizeof(ci->cinfo));	ci->cinfo[sizeof(ci->cinfo)-1] = 0; 	// isolate the player's name	strncpy(ci->name, s, sizeof(ci->name));	ci->name[sizeof(ci->name)-1] = 0;	t = strstr (s, "\\");	if (t)	{		ci->name[t-s] = 0;		s = t+1;	} 	if (cl_noskins->value || *s == 0)	{		Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");		Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/male/weapon.md2");		Com_sprintf (skin_filename, sizeof(skin_filename), "players/male/grunt.pcx");		Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/male/grunt_i.pcx");		ci->model = re.RegisterModel (model_filename);		memset(ci->weaponmodel, 0, sizeof(ci->weaponmodel));		ci->weaponmodel[0] = re.RegisterModel (weapon_filename);		ci->skin = re.RegisterSkin (skin_filename);		ci->icon = re.RegisterPic (ci->iconname);	}	else	{		// isolate the model name		strcpy (model_name, s);		t = strstr(model_name, "/");		if (!t)			t = strstr(model_name, "\\");		if (!t)			t = model_name;		*t = 0; 		// isolate the skin name		strcpy (skin_name, s + strlen(model_name) + 1); 		// model file		Com_sprintf (model_filename, sizeof(model_filename), "players/%s/tris.md2", model_name);		ci->model = re.RegisterModel (model_filename);		if (!ci->model)		{			strcpy(model_name, "male");			Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");			ci->model = re.RegisterModel (model_filename);		} 		// skin file		Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);		ci->skin = re.RegisterSkin (skin_filename); 		// if we don't have the skin and the model wasn't male,		// see if the male has it (this is for CTF's skins) 		if (!ci->skin && cistrcmp(model_name, "male"))		{			// change model to male			strcpy(model_name, "male");			Com_sprintf (model_filename, sizeof(model_filename), "players/male/tris.md2");			ci->model = re.RegisterModel (model_filename); 			// see if the skin exists for the male model			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/%s.pcx", model_name, skin_name);			ci->skin = re.RegisterSkin (skin_filename);		} 		// if we still don't have a skin, it means that the male model didn't have		// it, so default to grunt		if (!ci->skin) {			// see if the skin exists for the male model			Com_sprintf (skin_filename, sizeof(skin_filename), "players/%s/grunt.pcx", model_name, skin_name);			ci->skin = re.RegisterSkin (skin_filename);		} 		// weapon file		for (i = 0; i < num_cl_weaponmodels; i++) {			Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/%s/%s", model_name, cl_weaponmodels[i]);			ci->weaponmodel[i] = re.RegisterModel(weapon_filename);			if (!ci->weaponmodel[i] && strcmp(model_name, "cyborg") == 0) {				// try male				Com_sprintf (weapon_filename, sizeof(weapon_filename), "players/male/%s", cl_weaponmodels[i]);				ci->weaponmodel[i] = re.RegisterModel(weapon_filename);			}			if (!cl_vwep->value)				break; // only one when vwep is off		} 		// icon file		Com_sprintf (ci->iconname, sizeof(ci->iconname), "/players/%s/%s_i.pcx", model_name, skin_name);		ci->icon = re.RegisterPic (ci->iconname);	} 	// must have loaded all data types to be valud	if (!ci->skin || !ci->icon || !ci->model || !ci->weaponmodel[0])	{		ci->skin = NULL;		ci->icon = NULL;		ci->model = NULL;		ci->weaponmodel[0] = NULL;		return;	}} /*================CL_ParseClientinfo Load the skin, icon, and model for a client================*/void CL_ParseClientinfo (int player){	char			*s;

Lines 1–500 of 803.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t