示例#1
0
static edict_t *
KK_Match_Str2 (const char *substr)
{
	int         i, j, count;
	dstring_t  *lstr = dstring_new ();
	dstring_t  *lname = dstring_new ();
	client_t   *cl;
	edict_t    *retedict = 0;

	dstring_copystr (lstr, substr);
	for (j = 0; lstr->str[j]; j++)
		lstr->str[j] = KK_qwchar (lstr->str[j]);

	for (i = count = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
		if (!cl->state)
			continue;
		dstring_copystr (lname, cl->name);
		for (j = 0; lname->str[j]; j++)
			lname->str[j] = KK_qwchar (lname->str[j]);
		if (strstr (lname->str, lstr->str)) {
			retedict = cl->edict;
			count++;
		}
	}
	if (count > 1)
		retedict = 0;
	dstring_delete (lstr);
	dstring_delete (lname);
	return retedict;
}
示例#2
0
VISIBLE void
Cmd_StuffCmds (cbuf_t *cbuf)
{
	int         i, j;
	dstring_t  *build;

	if (!*com_cmdline)
		return;

	build = dstring_newstr ();

	// pull out the commands
	for (i = 0; com_cmdline[i]; i++) {
		if (com_cmdline[i] == '+') {
			i++;

			for (j = i;
				 (com_cmdline[j]
				  && !((j == 0 || isspace((byte) com_cmdline[j - 1]))
					   && ((com_cmdline[j] == '+')
						    || (com_cmdline[j] == '-'))));
				 j++)
				;

			dstring_appendsubstr (build, com_cmdline + i, j - i);
			dstring_appendstr (build, "\n");
			i = j - 1;
		}
	}

	if (build->str[0])
		Cbuf_InsertText (cbuf, build->str);

	dstring_delete (build);
}
示例#3
0
void
glsl_SCR_ScreenShot_f (void)
{
	dstring_t  *name = dstring_new ();

	// find a file name to save it to
	if (!QFS_NextFilename (name,
						   va ("%s/qf", qfs_gamedir->dir.shots), ".png")) {
		Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PNG file\n");
	} else {
		tex_t      *tex;

		tex = glsl_SCR_CaptureBGR ();
		WritePNGqfs (name->str, tex->data, tex->width, tex->height);
		free (tex);
		Sys_Printf ("Wrote %s/%s\n", qfs_userpath, name->str);
	}
	dstring_delete (name);
}
示例#4
0
void
sw32_SCR_ScreenShot_f (void)
{
	dstring_t  *pcxname = dstring_new ();
	pcx_t      *pcx = 0;
	int         pcx_len;

	// find a file name to save it to
	if (!QFS_NextFilename (pcxname,
						   va ("%s/qf", qfs_gamedir->dir.shots), ".pcx")) {
		Sys_Printf ("SCR_ScreenShot_f: Couldn't create a PCX");
	} else {
		// enable direct drawing of console to back buffer
		sw32_D_EnableBackBufferAccess ();

		// save the pcx file
		switch(sw32_r_pixbytes) {
		case 1:
			pcx = EncodePCX (vid.buffer, vid.width, vid.height, vid.rowbytes,
							 vid.basepal, false, &pcx_len);
			break;
		case 2:
			Sys_Printf("SCR_ScreenShot_f: FIXME - add 16bit support\n");
			break;
		case 4:
			Sys_Printf("SCR_ScreenShot_f: FIXME - add 32bit support\n");
			break;
		default:
			Sys_Error("SCR_ScreenShot_f: unsupported r_pixbytes %i", sw32_r_pixbytes);
		}

		// for adapters that can't stay mapped in for linear writes all the time
		sw32_D_DisableBackBufferAccess ();

		if (pcx) {
			QFS_WriteFile (pcxname->str, pcx, pcx_len);
			Sys_Printf ("Wrote %s/%s\n", qfs_userpath, pcxname->str);
		}
	}
	dstring_delete (pcxname);
}
示例#5
0
static void
SV_Fraglogfile_f (void)
{
	dstring_t  *name;

	if (sv_fraglogfile) {
		SV_Printf ("Frag file logging off.\n");
		Qclose (sv_fraglogfile);
		sv_fraglogfile = NULL;
		return;
	}
	name = dstring_new ();
	if (!QFS_NextFilename (name,
						   va ("%s/frag_", qfs_gamedir->dir.def), ".log")) {
		SV_Printf ("Can't open any logfiles.\n");
		sv_fraglogfile = NULL;
	} else {
		SV_Printf ("Logging frags to %s.\n", name->str);
		sv_fraglogfile = QFS_WOpen (name->str, 0);
	}
	dstring_delete (name);
}
示例#6
0
static void
SV_Snap (int uid)
{
	client_t   *cl;
	int         i;

	for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
		if (cl->state < cs_zombie)
			continue;
		if (cl->userid == uid)
			break;
	}
	if (i >= MAX_CLIENTS) {
		SV_Printf ("userid not found\n");
		return;
	}

	if (!cl->uploadfn)
		cl->uploadfn = dstring_new ();

	if (!QFS_NextFilename (cl->uploadfn,
						   va ("%s/snap/%d-", qfs_gamedir->dir.def, uid),
						   ".pcx")) {
		SV_Printf ("Snap: Couldn't create a file, clean some out.\n");
		dstring_delete (cl->uploadfn);
		cl->uploadfn = 0;
		return;
	}

	memcpy (&cl->snap_from, &net_from, sizeof (net_from));
	if (sv_redirected != RD_NONE)
		cl->remote_snap = true;
	else
		cl->remote_snap = false;

	MSG_ReliableWrite_Begin (&cl->backbuf, svc_stufftext, 24);
	MSG_ReliableWrite_String (&cl->backbuf, "cmd snap\n");
	SV_Printf ("Requesting snap from user %d...\n", uid);
}
示例#7
0
/*
	CL_SendConnectPacket

	called by CL_Connect_f and CL_CheckResend
*/
static void
CL_SendConnectPacket (void)
{
	dstring_t  *data;
	double      t1, t2;

// JACK: Fixed bug where DNS lookups would cause two connects real fast
//		 Now, adds lookup time to the connect time.
//		 Should I add it to realtime instead?!?!

	if (cls.state != ca_disconnected)
		return;

	t1 = Sys_DoubleTime ();

	if (!NET_StringToAdr (cls.servername->str, &cls.server_addr)) {
		Sys_Printf ("Bad server address\n");
		connect_time = -1;
		return;
	}

	if (cls.server_addr.port == 0)
		cls.server_addr.port = BigShort (27500);
	t2 = Sys_DoubleTime ();

	connect_time = realtime + t2 - t1;	// for retransmit requests

	cls.qport = qport->int_val;

	data = dstring_new ();
	dsprintf (data, "%c%c%c%cconnect %i %i %i \"%s\"\n",
			  255, 255, 255, 255, PROTOCOL_VERSION, cls.qport, cls.challenge,
			  Info_MakeString (cls.userinfo, 0));
	Netchan_SendPacket (strlen (data->str), data->str, cls.server_addr);
	dstring_delete (data);
}
示例#8
0
VISIBLE tex_t *
LoadImage (const char *imageFile)
{
	int         tmp;
	dstring_t  *tmpFile;
	char       *ext;
	tex_t      *tex = NULL;
	QFile      *fp;

	// Get the file name without extension
	tmpFile = dstring_new ();
	dstring_copystr (tmpFile, imageFile);
	ext = strrchr (tmpFile->str, '.');
	if (ext)
		tmp = ext - tmpFile->str;
	else
		tmp = tmpFile->size - 1;

	// Check for a .png
	dstring_replace (tmpFile, tmp, tmpFile->size, ".png", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadPNG (fp);
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}

	// Check for a .tga
	dstring_replace (tmpFile, tmp, tmpFile->size, ".tga", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadTGA (fp);
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}

/*
	// Check for a .jpg
	dstring_replace (tmpFile, tmp, tmpFile->size, ".jpg", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadJPG (fp);
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}
*/

	// Check for a .pcx
	dstring_replace (tmpFile, tmp, tmpFile->size, ".pcx", 5);
	QFS_FOpenFile (tmpFile->str, &fp);
	if (fp) {
		tex = LoadPCX (fp, 1, NULL); // Convert, some users don't grok paletted
		Qclose (fp);
		dstring_delete (tmpFile);
		return (tex);
	}

	dstring_delete (tmpFile);
	return (tex);
}
示例#9
0
void
gl_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m,
								   int _s, int extra)
{
	dstring_t  *cache, *fullpath;
	unsigned char model_digest[MDFOUR_DIGEST_BYTES];
	unsigned char mesh_digest[MDFOUR_DIGEST_BYTES];
	int         i, j;
	int        *cmds;
	QFile      *f;
	qboolean    remesh = true;
	qboolean    do_cache = false;

	aliasmodel = m;
	paliashdr = hdr;

	cache = dstring_new ();
	fullpath = dstring_new ();

	if (!gl_alias_render_tri->int_val) {

		if (gl_mesh_cache->int_val
			&& gl_mesh_cache->int_val <= paliashdr->mdl.numtris) {
			do_cache = true;

			mdfour (model_digest, (unsigned char *) _m, _s);

			// look for a cached version
			dstring_copystr (cache, "glquake/");
			dstring_appendstr (cache, m->name);
			QFS_StripExtension (m->name + strlen ("progs/"),
							cache->str + strlen ("glquake/"));
			dstring_appendstr (cache, ".qfms");

			QFS_FOpenFile (cache->str, &f);
			if (f) {
				unsigned char d1[MDFOUR_DIGEST_BYTES];
				unsigned char d2[MDFOUR_DIGEST_BYTES];
				struct mdfour md;
				int			len, vers;
				int         nc = 0, no = 0;
				int        *c = 0, *vo = 0;

				memset (d1, 0, sizeof (d1));
				memset (d2, 0, sizeof (d2));

				Qread (f, &vers, sizeof (int));
				Qread (f, &len, sizeof (int));
				Qread (f, &nc, sizeof (int));
				Qread (f, &no, sizeof (int));

				if (vers == 1 && (nc + no) == len) {
					c = malloc (((nc + 1023) & ~1023) * sizeof (c[0]));
					vo = malloc (((no + 1023) & ~1023) * sizeof (vo[0]));
					if (!c || !vo)
						Sys_Error ("gl_mesh.c: out of memory");
					Qread (f, c, nc * sizeof (c[0]));
					Qread (f, vo, no * sizeof (vo[0]));
					Qread (f, d1, MDFOUR_DIGEST_BYTES);
					Qread (f, d2, MDFOUR_DIGEST_BYTES);
					Qclose (f);

					mdfour_begin (&md);
					mdfour_update (&md, (unsigned char *) &vers, sizeof(int));
					mdfour_update (&md, (unsigned char *) &len, sizeof(int));
					mdfour_update (&md, (unsigned char *) &nc, sizeof(int));
					mdfour_update (&md, (unsigned char *) &no, sizeof(int));
					mdfour_update (&md, (unsigned char *) c, nc * sizeof (c[0]));
					mdfour_update (&md, (unsigned char *) vo, no * sizeof (vo[0]));
					mdfour_update (&md, d1, MDFOUR_DIGEST_BYTES);
					mdfour_result (&md, mesh_digest);

					if (memcmp (d2, mesh_digest, MDFOUR_DIGEST_BYTES) == 0
						&& memcmp (d1, model_digest, MDFOUR_DIGEST_BYTES) == 0) {
						remesh = false;
						numcommands = nc;
						numorder = no;
						if (numcommands > commands_size) {
							if (commands)
								free (commands);
							commands_size = (numcommands + 1023) & ~1023;
							commands = c;
						} else {
							memcpy (commands, c, numcommands * sizeof (c[0]));
							free(c);
						}
						if (numorder > vertexorder_size) {
							if (vertexorder)
								free (vertexorder);
							vertexorder_size = (numorder + 1023) & ~1023;
							vertexorder = vo;
						} else {
							memcpy (vertexorder, vo, numorder * sizeof (vo[0]));
							free (vo);
						}
					}
				}
			}
		}
		if (remesh) {
			// build it from scratch
			Sys_MaskPrintf (SYS_DEV, "meshing %s...\n", m->name);

			BuildTris ();					// trifans or lists

			if (do_cache) {
				// save out the cached version
				dsprintf (fullpath, "%s/%s", qfs_gamedir->dir.def, cache->str);
				f = QFS_WOpen (fullpath->str, 9);

				if (f) {
					struct mdfour md;
					int         vers = 1;
					int         len = numcommands + numorder;

					mdfour_begin (&md);
					mdfour_update (&md, (unsigned char *) &vers, sizeof (int));
					mdfour_update (&md, (unsigned char *) &len, sizeof (int));
					mdfour_update (&md, (unsigned char *) &numcommands,
								   sizeof (int));
					mdfour_update (&md, (unsigned char *) &numorder, sizeof (int));
					mdfour_update (&md, (unsigned char *) commands,
								   numcommands * sizeof (commands[0]));
					mdfour_update (&md, (unsigned char *) vertexorder,
								   numorder * sizeof (vertexorder[0]));
					mdfour_update (&md, model_digest, MDFOUR_DIGEST_BYTES);
					mdfour_result (&md, mesh_digest);

					Qwrite (f, &vers, sizeof (int));
					Qwrite (f, &len, sizeof (int));
					Qwrite (f, &numcommands, sizeof (int));
					Qwrite (f, &numorder, sizeof (int));
					Qwrite (f, commands, numcommands * sizeof (commands[0]));
					Qwrite (f, vertexorder, numorder * sizeof (vertexorder[0]));
					Qwrite (f, model_digest, MDFOUR_DIGEST_BYTES);
					Qwrite (f, mesh_digest, MDFOUR_DIGEST_BYTES);
					Qclose (f);
				}
			}
		}

		// save the data out
		paliashdr->poseverts = numorder;

		cmds = Hunk_Alloc (numcommands * sizeof (int));
		paliashdr->commands = (byte *) cmds - (byte *) paliashdr;
		memcpy (cmds, commands, numcommands * sizeof (int));

	} else {
		tex_coord_t *tex_coord;

		numorder = 0;
		for (i=0; i < pheader->mdl.numtris; i++) {
			add_vertex(triangles[i].vertindex[0]);
			add_vertex(triangles[i].vertindex[1]);
			add_vertex(triangles[i].vertindex[2]);
		}
		paliashdr->poseverts = numorder;

		tex_coord = Hunk_Alloc (numorder * sizeof(tex_coord_t));
		paliashdr->tex_coord = (byte *) tex_coord - (byte *) paliashdr;
		for (i=0; i < numorder; i++) {
			float s, t;
			int k;
			k = vertexorder[i];
			s = stverts[k].s;
			t = stverts[k].t;
			if (!triangles[i/3].facesfront && stverts[k].onseam)
				s += pheader->mdl.skinwidth / 2;	// on back side
			s = (s + 0.5) / pheader->mdl.skinwidth;
			t = (t + 0.5) / pheader->mdl.skinheight;
			tex_coord[i].st[0] = s;
			tex_coord[i].st[1] = t;
		}
	}

	if (extra) {
		trivertx16_t *verts;
		verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts
							* sizeof (trivertx16_t));
		paliashdr->posedata = (byte *) verts - (byte *) paliashdr;
		for (i = 0; i < paliashdr->numposes; i++) {
			trivertx_t *pv = poseverts[i];
			for (j = 0; j < numorder; j++) {
				trivertx16_t v;
				// convert MD16's split coordinates into something a little
				// saner. The first chunk of vertices is fully compatible with
				// IDPO alias models (even the scale). The second chunk is the
				// fractional bits of the vertex, giving 8.8. However, it's
				// easier for us to multiply everything by 256 and adjust the
				// model scale appropriately
				VectorMultAdd (pv[vertexorder[j] + hdr->mdl.numverts].v,
							   256, pv[vertexorder[j]].v, v.v);
				v.lightnormalindex =
					poseverts[i][vertexorder[j]].lightnormalindex;
				*verts++ = v;
			}
		}
	} else {
		trivertx_t *verts;
		verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts
							* sizeof (trivertx_t));
		paliashdr->posedata = (byte *) verts - (byte *) paliashdr;
		for (i = 0; i < paliashdr->numposes; i++) {
			for (j = 0; j < numorder; j++)
				*verts++ = poseverts[i][vertexorder[j]];
		}
	}
	dstring_delete (cache);
	dstring_delete (fullpath);
}
示例#10
0
/*
	CF_Open

	cfopen opens a file, either for reading or writing (not both).
	returns a file descriptor >= 0 on success, < 0 on failure.
	mode is either r or w.
*/
int
CF_Open (const char *path, const char *mode)
{
	char *j;
	dstring_t *fullpath = dstring_new ();
	int desc, oldsize, i;
	QFile *file;

	if (cf_openfiles >= CF_MAXFILES) {
		return -1;
	}

	// check for paths with ..
	if (strequal (path, "..")
		|| !strncmp (path, "../", 3)
		|| strstr (path, "/../")
		|| (strlen (path) >= 3
			&& strequal (path + strlen (path) - 3, "/.."))) {
		return -1;
	}

	if (!(strequal(mode, "w") || strequal(mode, "r") || strequal(mode, "a"))) {
		return -1;
	}

	if (mode[0] == 'w' && cf_maxsize < 0) { // can't even delete if quota < 0
		return -1;
	}

	dsprintf (fullpath, "%s/%s/%s", qfs_gamedir->dir.def, CF_DIR, path);

	j = fullpath->str + strlen (fullpath->str) - strlen (path);
	for (i = 0; path[i]; i++, j++) // strcpy, but force lowercase
		*j = tolower ((byte) path[i]);
	*j = '\0';

	if (CF_AlreadyOpen (fullpath->str, mode[0])) {
		dstring_delete (fullpath);
		return -1;
	}

	if (mode[0] == 'w')
		oldsize = CF_GetFileSize (fullpath->str);
	else
		oldsize = 0;

	file = QFS_Open (fullpath->str, mode);
	if (file) {
		if (cf_openfiles >= cf_filepcount) {
			cf_filepcount++;
			cf_filep = realloc (cf_filep, sizeof (cf_file_t) * cf_filepcount);
			if (!cf_filep) {
				Sys_Error ("CF_Open: memory allocation error!");
			}
			cf_filep[cf_filepcount - 1].file = 0;
		}

		for (desc = 0; cf_filep[desc].file; desc++)
			;
		cf_filep[desc].path = fullpath->str;
		cf_filep[desc].file = file;
		cf_filep[desc].buf = 0;
		cf_filep[desc].size = 0;
		cf_filep[desc].writtento = 0;
		cf_filep[desc].mode = mode[0];

		cf_cursize -= oldsize;
		cf_openfiles++;

		return desc;
	}
	return -1;
}
示例#11
0
static void
Host_Loadgame_f (void)
{
	dstring_t  *name = 0;
	QFile      *f;
	char       *mapname = 0;
	script_t   *script = 0;
	plitem_t   *game = 0;
	plitem_t   *list;
	plitem_t   *item;
	char       *script_data = 0;
	int         i;
	int         entnum;
	int         count;
	int         version;
	float       spawn_parms[NUM_SPAWN_PARMS];

	if (cmd_source != src_command)
		goto end;

	if (Cmd_Argc () != 2) {
		Sys_Printf ("load <savename> : load a game\n");
		goto end;
	}

	cls.demonum = -1;					// stop demo loop in case this fails

	name = dstring_newstr ();
	dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1));
	QFS_DefaultExtension (name, ".sav");

	cl.loading = true;
	CL_UpdateScreen (cl.time);

	Sys_Printf ("Loading game from %s...\n", name->str);
	f = QFS_Open (name->str, "rz");
	if (!f) {
		Sys_Printf ("ERROR: couldn't open.\n");
		goto end;
	}
	script_data = malloc (Qfilesize (f) + 1);
	i = Qread (f, script_data, Qfilesize (f));
	script_data[i] = 0;
	Qclose (f);

	script = Script_New ();
	script->single = "";		// disable {}()': lexing
	Script_Start (script, name->str, script_data);

	Script_GetToken (script, 1);
	if (strequal (script->token->str, PACKAGE_NAME)) {
		if (!Script_TokenAvailable (script, 1)) {
			Sys_Printf ("Unexpected EOF reading %s\n", name->str);
			goto end;
		}
		game = PL_GetPropertyList (script->p);
	} else {
		sscanf (script->token->str, "%i", &version);
		if (version != SAVEGAME_VERSION) {
			Sys_Printf ("Savegame is version %i, not %i\n", version,
						SAVEGAME_VERSION);
			goto end;
		}
		game = convert_to_game_dict (script);
	}

	item = PL_ObjectForKey (game, "spawn_parms");
	for (i = 0; i < NUM_SPAWN_PARMS; i++) {
		if (i >= PL_A_NumObjects (item))
			break;
		spawn_parms[i] = atof (PL_String (PL_ObjectAtIndex (item, i)));
	}
	current_skill = atoi (PL_String (PL_ObjectForKey (game, "current_skill")));
	Cvar_SetValue (skill, current_skill);
	mapname = strdup (PL_String (PL_ObjectForKey (game, "name")));

	CL_Disconnect_f ();

	SV_SpawnServer (mapname);
	if (!sv.active) {
		Sys_Printf ("Couldn't load map %s\n", mapname);
		goto end;
	}
	sv.paused = true;					// pause until all clients connect
	sv.loadgame = true;

	list = PL_ObjectForKey (game, "lightstyles");
	for (i = 0; i < MAX_LIGHTSTYLES; i++) {
		const char *style;
		char       *str;
		if (i >= PL_A_NumObjects (list))
			break;
		item = PL_ObjectAtIndex (list, i);
		style = PL_String (item);
		sv.lightstyles[i] = str = Hunk_Alloc (strlen (style) + 1);
		strcpy (str, style);
	}

	ED_InitGlobals (&sv_pr_state, PL_ObjectForKey (game, "globals"));

	list = PL_ObjectForKey (game, "entities");
	entnum = 0;
	count = PL_A_NumObjects (list);
	if (count > sv.max_edicts)
		Host_Error ("too many entities in saved game. adjust max_edicts\n");
	for (entnum = 0; entnum < count; entnum++) {
		plitem_t   *entity = PL_ObjectAtIndex (list, entnum);
		edict_t    *ent = EDICT_NUM (&sv_pr_state, entnum);

		memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
		ent->free = false;
		ED_InitEntity (&sv_pr_state, entity, ent);

		// link it into the bsp tree
		if (!ent->free)
			SV_LinkEdict (ent, false);
	}

	sv.num_edicts = entnum;
	sv.time = atof (PL_String (PL_ObjectForKey (game, "time")));

	for (i = 0; i < NUM_SPAWN_PARMS; i++)
		svs.clients->spawn_parms[i] = spawn_parms[i];

	if (cls.state != ca_dedicated) {
		CL_EstablishConnection ("local");
		Host_Reconnect_f ();
	}
end:
	if (game)
		PL_Free (game);
	if (mapname)
		free (mapname);
	if (script)
		Script_Delete (script);
	if (script_data)
		free (script_data);
	if (name)
		dstring_delete (name);
}
示例#12
0
static void
Host_Savegame_f (void)
{
	dstring_t  *name;
	const char *save_name;
	char       *save_text;
	QFile      *f;
	int         i;
	char       *bup1, *bup2 = 0;


	if (cmd_source != src_command)
		return;

	if (!sv.active) {
		Sys_Printf ("Not playing a local game.\n");
		return;
	}

	if (cl.intermission) {
		Sys_Printf ("Can't save in intermission.\n");
		return;
	}

	if (svs.maxclients != 1) {
		Sys_Printf ("Can't save multiplayer games.\n");
		return;
	}

	if (Cmd_Argc () != 2) {
		Sys_Printf ("save <savename> : save a game\n");
		return;
	}

	if (strstr (Cmd_Argv (1), "..")) {
		Sys_Printf ("Relative pathnames are not allowed.\n");
		return;
	}

	for (i = 0; i < svs.maxclients; i++) {
		if (svs.clients[i].active && (SVfloat (svs.clients[i].edict, health)
									  <= 0)) {
			Sys_Printf ("Can't savegame with a dead player\n");
			return;
		}
	}

	save_name = Cmd_Argv (1);
	name = dstring_newstr ();
	if (strcmp  (save_name, "quick") == 0) {
		bup2 = nva ("%s/%s%d.sav", qfs_gamedir->dir.def, save_name, MAX_QUICK);
		QFS_Remove (bup2);
		for (i = MAX_QUICK - 1; i > 0; i--) {
			bup1 = nva ("%s/%s%d.sav", qfs_gamedir->dir.def, save_name, i);
			QFS_Rename (bup1, bup2);
			free (bup2);
			bup2 = bup1;
		}
	}
	dsprintf (name, "%s/%s", qfs_gamedir->dir.def, save_name);
	QFS_DefaultExtension (name, ".sav");

	if (bup2) {
		QFS_Rename (name->str, bup2);
		free (bup2);
	}
	Sys_Printf ("Saving game to %s...\n", name->str);
	f = QFS_WOpen (name->str, 0);
	dstring_delete (name);
	if (!f) {
		Sys_Printf ("ERROR: couldn't open.\n");
		return;
	}

	save_text = PL_WritePropertyList (game_dict ());
	Qprintf (f, "%s\n%s", PACKAGE_NAME, save_text);
	free (save_text);

	Qclose (f);
	Sys_Printf ("done.\n");
}
示例#13
0
static void
SV_Punish (int mode)
{
	int         i;
	double      mins = 0.5;
	qboolean    all = false, done = false;
	client_t    *cl = 0;
	dstring_t  *text = dstring_new();
	const char *cmd = 0;
	const char *cmd_do = 0;
	//FIXME const char *cmd_undo = 0;
	int         field_offs = 0;

	switch (mode) {
		case 0:
			cmd = "cuff";
			cmd_do = "cuffed";
			//FIXME cmd_undo = "un-cuffed";
			field_offs = field_offset (client_t, cuff_time);
			break;
		case 1:
			cmd = "mute";
			cmd_do = "muted";
			//FIXME cmd_undo = "can speak";
			field_offs = field_offset (client_t, lockedtill);
			break;
	}

	if (Cmd_Argc () != 2 && Cmd_Argc () != 3) {
		SV_Printf ("usage: %s <name/userid/ALL> [minutes]\n"
				   "       (default = 0.5, 0 = cancel cuff).\n", cmd);
		return;
	}

	if (strequal (Cmd_Argv (1), "ALL")) {
		all = true;
	} else {
		cl = SV_Match_User (Cmd_Argv (1));
	}
	if (!all && !cl)
		return;
	if (Cmd_Argc () == 3) {
		mins = atof (Cmd_Argv (2));
		if (mins < 0.0 || mins > MAXPENALTY)
			mins = MAXPENALTY;
	}
	if (cl) {
		*(double *)((char *)cl + field_offs) = realtime + mins * 60.0;
		if (mins) {
			dsprintf (text, "You are %s for %.1f minutes\n\n"
					 "reconnecting won't help...\n", cmd_do, mins);
			MSG_ReliableWrite_Begin (&cl->backbuf, svc_centerprint,
									 2 + strlen (text->str));
			MSG_ReliableWrite_String (&cl->backbuf, text->str);
		}
	}
	if (all) {
		for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
			if (cl->state < cs_zombie)
				continue;
			*(double *)((char *)cl + field_offs) = realtime + mins * 60.0;
			done = true;
			if (mins) {
				dsprintf (text, "You are %s for %.1f minutes\n\n"
						 "reconnecting won't help...\n", cmd_do, mins);
				MSG_ReliableWrite_Begin (&cl->backbuf, svc_centerprint,
										 2 + strlen (text->str));
				MSG_ReliableWrite_String (&cl->backbuf, text->str);
			}
		}
	}
	if (done) {
		if (mins)
			SV_BroadcastPrintf (PRINT_HIGH, "%s %s for %.1f minutes.\n",
								all? "All Users" : cl->name, cmd_do, mins);
		else
			SV_BroadcastPrintf (PRINT_HIGH, "%s %s.\n",
								all? "All Users" : cl->name, cmd_do);
	}
	dstring_delete (text);
}