Пример #1
0
void GameDatabase::DeleteGame(const size_t index, const bool reload)
{
	wxString file = FilePath::Data(DataFileGames);
	wxString keyfile = FilePath::Data(DataFileGameKeys);

	size_t size = NumGames();

	// If there's only one game in the file, just delete the files.
	if(1 == size)
	{
		wxRemoveFile(file);
		wxRemoveFile(keyfile);
	}
	else
	{
		// If this is not the last game in the file, we'll have to extricate 
		// it.
		if(index != (size - 1))
		{
			// Get two temp file names to use for the atomic deletion.
			wxString tempfile, tempkeyfile;
			tempfile = wxFileName::CreateTempFileName(swGame);
			tempkeyfile = wxFileName::CreateTempFileName(swKeys);

			wxFileInputStream db(file);
			wxFileOutputStream tempdb(tempfile);
			wxFileOutputStream tempkey(tempkeyfile);

			size_t totalLength = db.GetSize();
			size_t offset = 0;

			// Run through all the games in the db and save them to a temp file, 
			// except for the one being deleted, then copy that temp file to the 
			// desired  file.
			for(size_t i = 0; i < size; i++)
			{
				//calculate the size of this data chunk
				size_t chunk;

				if(i < (size - 1))
				{
					chunk = mOffsets[i + 1] - mOffsets[i];
				}
				else
				{
					chunk = totalLength - mOffsets[i];
				}

				// Just copy raw data instead of loading and adding.
				boost::scoped_array<wxUint8> bytes(new wxUint8[chunk]);
				db.Read(bytes.get(), chunk);

				// Skip the one we're deleting.
				if(i != index) 
				{
					tempdb.Write(bytes.get(), chunk);
					tempkey.Write(&offset, 4);

					offset += chunk;
				}
			}
			// Copy the temp files onto the real files.
			wxCopyFile(tempfile, file);
			wxCopyFile(tempkeyfile, keyfile);
		}
		// Otherwise, we can just truncate the file.
		else
		{
			wxFile in(file, wxFile::read);
			size_t chunk = mOffsets[index];

			boost::scoped_array<wxUint8> bytes(new wxUint8[chunk]);
			in.Read(bytes.get(), chunk);
			in.Close();

			// Now just write them back out.
			wxFile out(file, wxFile::write);
			out.Write(bytes.get(), chunk);
			out.Close();

			// Repeat with the key file.
			in.Open(keyfile, wxFile::read);
			chunk = in.Length() - sizeof(size_t);
			bytes.reset(new wxUint8[chunk]);
			in.Read(bytes.get(), chunk);
			in.Close();

			out.Open(keyfile, wxFile::write);
			out.Write(bytes.get(), chunk);
			out.Close();
		}
	}

	if(true == reload)
	{
		InitializeDatabase();
	}
}
Пример #2
0
/*
==================
Host_Game_f
==================
*/
void Host_Game_f (void)
{
	int i;
	unsigned int path_id;
	searchpath_t *search = com_searchpaths;
	pack_t *pak;
	char   pakfile[MAX_OSPATH]; //FIXME: it's confusing to use this string for two different things

	if (Cmd_Argc() > 1)
	{
		if (!registered.value) //disable command for shareware quake
		{
			Con_Printf("You must have the registered version to use modified games\n");
			return;
		}

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

		q_strlcpy (pakfile, va("%s/%s", host_parms->basedir, Cmd_Argv(1)), sizeof(pakfile));
		if (!Q_strcasecmp(pakfile, com_gamedir)) //no change
		{
			Con_Printf("\"game\" is already \"%s\"\n", COM_SkipPath(com_gamedir));
			return;
		}

		com_modified = true;

		//Kill the server
		CL_Disconnect ();
		Host_ShutdownServer(true);

		//Write config file
		Host_WriteConfiguration ();

		//Kill the extra game if it is loaded
		if (NumGames(com_searchpaths) > 1 + com_nummissionpacks)
			KillGameDir(com_searchpaths);

		q_strlcpy (com_gamedir, pakfile, sizeof(com_gamedir));

		if (Q_strcasecmp(Cmd_Argv(1), GAMENAME)) //game is not id1
		{
			// assign a path_id to this game directory
			if (com_searchpaths)
				path_id = com_searchpaths->path_id << 1;
			else	path_id = 1U;
			search = (searchpath_t *) Z_Malloc(sizeof(searchpath_t));
			search->path_id = path_id;
			q_strlcpy (search->filename, pakfile, sizeof(search->filename));
			search->next = com_searchpaths;
			com_searchpaths = search;

			//Load the paks if any are found:
			for (i = 0; ; i++)
			{
				q_snprintf (pakfile, sizeof(pakfile), "%s/pak%i.pak", com_gamedir, i);
				pak = COM_LoadPackFile (pakfile);
				if (!pak)
					break;
				search = (searchpath_t *) Z_Malloc(sizeof(searchpath_t));
				search->path_id = path_id;
				search->pack = pak;
				search->next = com_searchpaths;
				com_searchpaths = search;
			}
		}

		//clear out and reload appropriate data
		Cache_Flush ();
		if (!isDedicated)
		{
			TexMgr_NewGame ();
			Draw_NewGame ();
			R_NewGame ();
		}
		ExtraMaps_NewGame ();
		//Cbuf_InsertText ("exec quake.rc\n");

		Con_Printf("\"game\" changed to \"%s\"\n", COM_SkipPath(com_gamedir));
	}
	else //Diplay the current gamedir
		Con_Printf("\"game\" is \"%s\"\n", COM_SkipPath(com_gamedir));
}