Example #1
0
static bool VerifyFile(
		const std::string &filename,
		std::string &base_filename,
		std::string &full_filename,
		const std::string &hash = "")
{
	std::string ext;
	M_ExtractFileExtension(filename, ext);

	base_filename = D_CleanseFileName(filename);
	if (base_filename.empty())
		return false;

	// is there an exact match for the filename and hash?
	full_filename = BaseFileSearch(base_filename, "." + ext, hash);
	if (!full_filename.empty())
		return true;

	// is there a file with matching name even if the hash is incorrect?
	full_filename = BaseFileSearch(base_filename, "." + ext);
	if (full_filename.empty())
		return false;

	// if it's an IWAD, check if we have a valid alternative hash
	std::string found_hash = W_MD5(full_filename);
	if (W_IsIWAD(base_filename, found_hash))
		return true;

	return false;
}
Example #2
0
void W_InitMultipleFiles(char **filenames)
{
	char  **ptr;
	byte    loaded[64];			// Enough?

	iwadLoaded = false;

	// Open all the files, load headers, and count lumps
	numlumps = 0;
	lumpinfo = malloc(1);		// Will be realloced as lumps are added

	// This'll force the loader NOT the flag new records Runtime. (?)
	loadingForStartup = true;

	memset(loaded, 0, sizeof(loaded));

	// IWAD(s) must be loaded first. Let's see if one has been specified
	// with -iwad or -file options.
	for(ptr = filenames; *ptr; ptr++)
	{
		if(W_IsIWAD(*ptr))
		{
			loaded[ptr - filenames] = true;
			W_AddFile(*ptr, false);
		}
	}
	// Make sure an IWAD gets loaded; if not, display a warning.
	W_CheckIWAD();

	// Load the rest of the WADs.
	for(ptr = filenames; *ptr; ptr++)
		if(!loaded[ptr - filenames])
			W_AddFile(*ptr, false);

	if(!numlumps)
	{
		Con_Error("W_InitMultipleFiles: no files found");
	}
}
Example #3
0
//
// G_LoadWad
//
// Determines if the vectors of wad & patch filenames differs from the currently
// loaded ones and calls D_DoomWadReboot if so.
//
bool G_LoadWad(	const std::vector<std::string> &newwadfiles,
				const std::vector<std::string> &newpatchfiles,
				const std::vector<std::string> &newwadhashes,
				const std::vector<std::string> &newpatchhashes,
				const std::string &mapname)
{
	bool AddedIWAD = false;
	bool Reboot = false;
	size_t i, j;

	// Did we pass an IWAD?
	if (!newwadfiles.empty() && W_IsIWAD(newwadfiles[0]))
		AddedIWAD = true;

	// Check our environment, if the same WADs are used, ignore this command.

	// Did we switch IWAD files?
	if (AddedIWAD && !wadfiles.empty())
	{
		if (StdStringCompare(M_ExtractFileName(newwadfiles[0]), M_ExtractFileName(wadfiles[1]), true) != 0)
			Reboot = true;
	}

	// Do the sizes of the WAD lists not match up?
	if (!Reboot)
	{
		if (wadfiles.size() - 2 != newwadfiles.size() - (AddedIWAD ? 1 : 0))
			Reboot = true;
	}

	// Do our WAD lists match up exactly?
	if (!Reboot)
	{
		for (i = 2, j = (AddedIWAD ? 1 : 0); i < wadfiles.size() && j < newwadfiles.size(); i++, j++)
		{
			if (StdStringCompare(M_ExtractFileName(newwadfiles[j]), M_ExtractFileName(wadfiles[i]), true) != 0)
			{
				Reboot = true;
				break;
			}
		}
	}

	// Do the sizes of the patch lists not match up?
	if (!Reboot)
	{
		if (patchfiles.size() != newpatchfiles.size())
			Reboot = true;
	}

	// Do our patchfile lists match up exactly?
	if (!Reboot)
	{
		for (i = 0, j = 0; i < patchfiles.size() && j < newpatchfiles.size(); i++, j++)
		{
			if (StdStringCompare(M_ExtractFileName(newpatchfiles[j]), M_ExtractFileName(patchfiles[i]), true) != 0)
			{
				Reboot = true;
				break;
			}
		}
	}

	if (Reboot)
	{
		D_DoomWadReboot(newwadfiles, newpatchfiles, newwadhashes, newpatchhashes);
		if (!missingfiles.empty())
			return false;
	}

	unnatural_level_progression = true;
	if (mapname.length())
		G_DeferedInitNew((char *)mapname.c_str());
	else
		G_DeferedInitNew(startmap);

	return true;
}
Example #4
0
//
// D_DoomWadReboot
// [denis] change wads at runtime
// Returns false if there are missing files and fills the missingfiles
// vector
//
// [SL] passing an IWAD as newwadfiles[0] is now optional
// TODO: hash checking for patchfiles
//
bool D_DoomWadReboot(
	const std::vector<std::string> &newwadfiles,
	const std::vector<std::string> &newpatchfiles,
	const std::vector<std::string> &newwadhashes,
	const std::vector<std::string> &newpatchhashes
)
{
	size_t i;

	bool hashcheck = (newwadfiles.size() == newwadhashes.size());

	missingfiles.clear();
	missinghashes.clear();

	// already loaded these?
	if (lastWadRebootSuccess &&	!wadhashes.empty() &&
		newwadhashes == std::vector<std::string>(wadhashes.begin()+1, wadhashes.end()))
	{
		// fast track if files have not been changed // denis - todo - actually check the file timestamps
		Printf (PRINT_HIGH, "Currently loaded WADs match server checksum\n\n");
		return true;
	}

	lastWadRebootSuccess = false;

	if (gamestate == GS_LEVEL)
		G_ExitLevel(0, 0);

	S_Stop();

	DThinker::DestroyAllThinkers();

	// Close all open WAD files
	W_Close();

	// [ML] 9/11/10: Reset custom wad level information from MAPINFO et al.
	for (i = 0; i < wadlevelinfos.size(); i++)
	{
		if (wadlevelinfos[i].snapshot)
		{
			delete wadlevelinfos[i].snapshot;
			wadlevelinfos[i].snapshot = NULL;
		}
	}

	wadlevelinfos.clear();
	wadclusterinfos.clear();

	// Restart the memory manager
	Z_Init();

	SetLanguageIDs ();

	gamestate_t oldgamestate = gamestate;
	gamestate = GS_STARTUP; // prevent console from trying to use nonexistant font

	// [SL] 2012-12-06 - If we weren't provided with a new IWAD filename in
	// newwadfiles, use the previous IWAD.
	std::string iwad_filename, iwad_hash;
	if ((newwadfiles.empty() || !W_IsIWAD(newwadfiles[0])) && (wadfiles.size() >= 2))
	{
		iwad_filename = wadfiles[1];
		iwad_hash = wadhashes[1];
	}
	else if (!newwadfiles.empty())
	{
		iwad_filename = newwadfiles[0];
		iwad_hash = hashcheck ? newwadhashes[0] : "";
	}

	wadfiles.clear();
	D_AddDefWads(iwad_filename);	// add odamex.wad & IWAD

	// check if the wad files exist and if they match the MD5SUM
	std::string base_filename, full_filename;

	if (!VerifyFile(iwad_filename, base_filename, full_filename, iwad_hash))
	{
		Printf(PRINT_HIGH, "could not find WAD: %s\n", base_filename.c_str());
		missingfiles.push_back(base_filename);
		if (hashcheck)
			missinghashes.push_back(iwad_hash);
	}

	for (i = 0; i < newwadfiles.size(); i++)
	{
		std::string hash = hashcheck ? newwadhashes[i] : "";

		// already added the IWAD with D_AddDefWads
		if (W_IsIWAD(newwadfiles[i]))
			continue;

		if (VerifyFile(newwadfiles[i], base_filename, full_filename, hash))
			wadfiles.push_back(full_filename);
		else
		{
			Printf(PRINT_HIGH, "could not find WAD: %s\n", base_filename.c_str());
			missingfiles.push_back(base_filename);
			if (hashcheck)
				missinghashes.push_back(newwadhashes[i]);
		}
	}

	modifiedgame = (wadfiles.size() > 2) || !patchfiles.empty();	// more than odamex.wad and IWAD?
	if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
		I_Error("\nYou cannot load additional WADs with the shareware version. Register!");

	wadhashes = W_InitMultipleFiles (wadfiles);

	// get skill / episode / map from parms
	strcpy(startmap, (gameinfo.flags & GI_MAPxx) ? "MAP01" : "E1M1");

    UndoDehPatch();
    patchfiles.clear();

	// [RH] Initialize localizable strings.
	GStrings.ResetStrings ();
	GStrings.Compact ();

	D_DoDefDehackedPatch(newpatchfiles);

	D_NewWadInit();

	// preserve state
	lastWadRebootSuccess = missingfiles.empty();

	gamestate = oldgamestate; // GS_STARTUP would prevent netcode connecting properly

	return missingfiles.empty();
}