コード例 #1
0
ファイル: d_main.cpp プロジェクト: JohnnyonFlame/odamex
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;
}
コード例 #2
0
ファイル: d_main.cpp プロジェクト: JohnnyonFlame/odamex
//
// denis - BaseFileSearchDir
// Check single paths for a given file with a possible extension
// Case insensitive, but returns actual file name
//
std::string BaseFileSearchDir(std::string dir, std::string file, std::string ext, std::string hash = "")
{
	std::string found;

	if(dir[dir.length() - 1] != PATHSEPCHAR)
		dir += PATHSEP;

	std::transform(hash.begin(), hash.end(), hash.begin(), toupper);
	std::string dothash = ".";
	if(hash.length())
		dothash += hash;
	else
		dothash = "";

	// denis - list files in the directory of interest, case-desensitize
	// then see if wanted wad is listed
#ifdef UNIX
	// denis - todo -find a way to deal with dir="./" and file="DIR/DIR/FILE.WAD"
	struct dirent **namelist = 0;
	int n = scandir(dir.c_str(), &namelist, 0, alphasort);

	for(int i = 0; i < n && namelist[i]; i++)
	{
		std::string d_name = namelist[i]->d_name;

		M_Free(namelist[i]);

		if(!found.length())
		{
			if(d_name == "." || d_name == "..")
				continue;

			std::string tmp = d_name;
			std::transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);

			if(file == tmp || (file + ext) == tmp || (file + dothash) == tmp || (file + ext + dothash) == tmp)
			{
				std::string local_file = (dir + d_name).c_str();
				std::string local_hash = W_MD5(local_file.c_str());

				if(!hash.length() || hash == local_hash)
				{
					found = d_name;
				}
				else if(hash.length())
				{
					Printf (PRINT_HIGH, "WAD at %s does not match required copy\n", local_file.c_str());
					Printf (PRINT_HIGH, "Local MD5: %s\n", local_hash.c_str());
					Printf (PRINT_HIGH, "Required MD5: %s\n\n", hash.c_str());
				}
			}
		}
	}

	M_Free(namelist);
#else
	if(dir[dir.length() - 1] != PATHSEPCHAR)
		dir += PATHSEP;

	std::string all_ext = dir + "*";
	//all_ext += ext;

	WIN32_FIND_DATA FindFileData;
	HANDLE hFind = FindFirstFile(all_ext.c_str(), &FindFileData);
	DWORD dwError = GetLastError();

	if (hFind == INVALID_HANDLE_VALUE)
	{
		Printf (PRINT_HIGH, "FindFirstFile failed for %s\n", all_ext.c_str());
		Printf (PRINT_HIGH, "GetLastError: %d\n", dwError);
		return "";
	}

	while (true)
	{
		if(!FindNextFile(hFind, &FindFileData))
		{
			dwError = GetLastError();

			if(dwError != ERROR_NO_MORE_FILES)
				Printf (PRINT_HIGH, "FindNextFile failed. GetLastError: %d\n", dwError);

			break;
		}

		if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			continue;

		std::string tmp = FindFileData.cFileName;
		std::transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);

		if(file == tmp || (file + ext) == tmp || (file + dothash) == tmp || (file + ext + dothash) == tmp)
		{
			std::string local_file = (dir + FindFileData.cFileName).c_str();
			std::string local_hash = W_MD5(local_file.c_str());

			if(!hash.length() || hash == local_hash)
			{
				found = FindFileData.cFileName;
				break;
			}
			else if(hash.length())
			{
				Printf (PRINT_HIGH, "WAD at %s does not match required copy\n", local_file.c_str());
				Printf (PRINT_HIGH, "Local MD5: %s\n", local_hash.c_str());
				Printf (PRINT_HIGH, "Required MD5: %s\n\n", hash.c_str());
			}
		}
	}

	FindClose(hFind);
#endif

	return found;
}
コード例 #3
0
ファイル: w_wad.cpp プロジェクト: JohnnyonFlame/odamex
std::string W_AddFile (std::string filename)
{
    wadinfo_t		header;
    lumpinfo_t*		lump_p;
    size_t			i;
    FILE			*handle;
    size_t			length;
    size_t			startlump;
    size_t          res;
    filelump_t*		fileinfo;
    filelump_t		singleinfo;

    FixPathSeparator (filename);
    std::string name = filename;
    M_AppendExtension (name, ".wad");

    // open the file
    if ( (handle = fopen (filename.c_str(), "rb")) == NULL)
    {
        Printf (PRINT_HIGH, " couldn't open %s\n", filename.c_str());
        return "";
    }

    Printf (PRINT_HIGH, "adding %s\n", filename.c_str());

    startlump = numlumps;

    res = fread (&header, sizeof(header), 1, handle);
    header.identification = LELONG(header.identification);

    if (header.identification != IWAD_ID && header.identification != PWAD_ID)
    {
        // raw lump file
        fileinfo = &singleinfo;
        singleinfo.filepos = 0;
        singleinfo.size = M_FileLength(handle);
        M_ExtractFileBase (filename, name);
        numlumps++;
        Printf (PRINT_HIGH, " (single lump)\n", header.numlumps);
    }
    else
    {
        // WAD file
        header.numlumps = LELONG(header.numlumps);
        header.infotableofs = LELONG(header.infotableofs);
        length = header.numlumps*sizeof(filelump_t);

        if(length > (unsigned)M_FileLength(handle))
        {
            Printf (PRINT_HIGH, " bad number of lumps for %s\n", filename.c_str());
            fclose(handle);
            return "";
        }

        fileinfo = (filelump_t *)Z_Malloc (length, PU_STATIC, 0);
        fseek (handle, header.infotableofs, SEEK_SET);
        res = fread (fileinfo, length, 1, handle);
        numlumps += header.numlumps;
        Printf (PRINT_HIGH, " (%d lumps)\n", header.numlumps);
    }

    // Fill in lumpinfo
    lumpinfo = (lumpinfo_t *)Realloc (lumpinfo, numlumps*sizeof(lumpinfo_t));

    if (!lumpinfo)
        I_Error ("Couldn't realloc lumpinfo");

    lump_p = &lumpinfo[startlump];

    for (i=startlump ; i<numlumps ; i++,lump_p++, fileinfo++)
    {
        lump_p->handle = handle;
        lump_p->position = LELONG(fileinfo->filepos);
        lump_p->size = LELONG(fileinfo->size);
        strncpy (lump_p->name, fileinfo->name, 8);

        // W_CheckNumForName needs all lump names in upper case
        std::transform(lump_p->name, lump_p->name+8, lump_p->name, toupper);
    }

    return W_MD5(filename);
}
コード例 #4
0
ファイル: d_main.cpp プロジェクト: JohnnyonFlame/odamex
//
// denis - BaseFileSearchDir
// Check single paths for a given file with a possible extension
// Case insensitive, but returns actual file name
//
std::string BaseFileSearchDir(std::string dir, std::string file, std::string ext, std::string hash = "")
{
    std::string found;

    if(dir[dir.length() - 1] != PATHSEPCHAR)
        dir += PATHSEP;

    std::transform(hash.begin(), hash.end(), hash.begin(), toupper);
    std::string dothash = ".";
    if(hash.length())
        dothash += hash;
    else
        dothash = "";

    // denis - list files in the directory of interest, case-desensitize
    // then see if wanted wad is listed
#ifdef UNIX
    struct dirent **namelist = 0;
    int n = scandir(dir.c_str(), &namelist, 0, alphasort);

    for(int i = 0; i < n && namelist[i]; i++)
    {
        std::string d_name = namelist[i]->d_name;

        M_Free(namelist[i]);

        if(!found.length())
        {
            if(d_name == "." || d_name == "..")
                continue;

            std::string tmp = d_name;
            std::transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);

            if(file == tmp || (file + ext) == tmp || (file + dothash) == tmp || (file + ext + dothash) == tmp)
            {
                std::string local_file = (dir + d_name).c_str();
                std::string local_hash = W_MD5(local_file.c_str());

                if(!hash.length() || hash == local_hash)
                {
                    found = d_name;
                }
                else if(hash.length())
                {
                    Printf (PRINT_HIGH, "WAD at %s does not match required copy\n", local_file.c_str());
                    Printf (PRINT_HIGH, "Local MD5: %s\n", local_hash.c_str());
                    Printf (PRINT_HIGH, "Required MD5: %s\n\n", hash.c_str());
                }
            }
        }
    }

    M_Free(namelist);
#else
    std::string all_ext = dir + "*";
    //all_ext += ext;

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = FindFirstFile(all_ext.c_str(), &FindFileData);
    DWORD dwError = GetLastError();

    if (hFind == INVALID_HANDLE_VALUE)
    {
        Printf (PRINT_HIGH, "FindFirstFile failed for %s\n", all_ext.c_str());
        Printf (PRINT_HIGH, "GetLastError: %d\n", dwError);
        return "";
    }

    do
    {
        if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            continue;

        std::string tmp = FindFileData.cFileName;
        std::transform(tmp.begin(), tmp.end(), tmp.begin(), toupper);

        if(file == tmp || (file + ext) == tmp || (file + dothash) == tmp || (file + ext + dothash) == tmp)
        {
            std::string local_file = (dir + FindFileData.cFileName).c_str();
            std::string local_hash = W_MD5(local_file.c_str());

            if(!hash.length() || hash == local_hash)
            {
                found = FindFileData.cFileName;
                break;
            }
            else if(hash.length())
            {
                Printf (PRINT_HIGH, "WAD at %s does not match required copy\n", local_file.c_str());
                Printf (PRINT_HIGH, "Local MD5: %s\n", local_hash.c_str());
                Printf (PRINT_HIGH, "Required MD5: %s\n\n", hash.c_str());
            }
        }
    } while(FindNextFile(hFind, &FindFileData));

    dwError = GetLastError();

    // Note: As documented, FindNextFile sets ERROR_NO_MORE_FILES as the error
    // code, but when this function "fails" it does not set it we have to assume
    // that it completed successfully (this is actually  bad practice, because
    // it says in the docs that it does not set ERROR_SUCCESS, even though
    // GetLastError returns 0) WTF DO WE DO?!
    if(dwError != ERROR_SUCCESS && dwError != ERROR_NO_MORE_FILES)
        Printf (PRINT_HIGH, "FindNextFile failed. GetLastError: %d\n", dwError);

    FindClose(hFind);
#endif

    return found;
}
コード例 #5
0
ファイル: d_main.cpp プロジェクト: JohnnyonFlame/odamex
std::vector<size_t> D_DoomWadReboot(
    const std::vector<std::string> &wadnames,
    const std::vector<std::string> &patch_files,
    std::vector<std::string> needhashes
)
{
    std::vector<size_t> fails;
    size_t i;


    // already loaded these?
    if (lastWadRebootSuccess &&
            !wadhashes.empty() &&
            needhashes ==
            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 std::vector<size_t>();
    }

    // assume failure
    lastWadRebootSuccess = false;

    if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
        I_Error ("\nYou cannot switch WAD with the shareware version. Register!");

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

    AM_Stop();
    S_Stop();

    DThinker::DestroyAllThinkers();

    // Close all open WAD files
    W_Close();

    // [ML] 9/11/10: Reset custom wad level information from MAPINFO et al.
    // I have never used memset, I hope I am not invoking satan by doing this :(
    if (wadlevelinfos)
    {
        for (i = 0; i < numwadlevelinfos; i++)
            if (wadlevelinfos[i].snapshot)
            {
                delete wadlevelinfos[i].snapshot;
                wadlevelinfos[i].snapshot = NULL;
            }
        memset(wadlevelinfos,0,sizeof(wadlevelinfos));
        numwadlevelinfos = 0;
    }

    if (wadclusterinfos)
    {
        memset(wadclusterinfos,0,sizeof(wadclusterinfos));
        numwadclusterinfos = 0;
    }

    // Restart the memory manager
    Z_Init();

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

    wadfiles.clear();
    modifiedgame = false;

    std::string custwad;
    if(wadnames.empty() == false)
        custwad = wadnames[0];

    D_AddDefWads(custwad);

    for(i = 0; i < wadnames.size(); i++)
    {
        std::string tmp = wadnames[i];

        // strip absolute paths, as they present a security risk
        FixPathSeparator(tmp);
        size_t slash = tmp.find_last_of(PATHSEPCHAR);
        if(slash != std::string::npos)
            tmp = tmp.substr(slash + 1, tmp.length() - slash);

        // [Russell] - Generate a hash if it doesn't exist already
        if (needhashes[i].empty())
            needhashes[i] = W_MD5(tmp);

        std::string file = BaseFileSearch(tmp, ".wad", needhashes[i]);

        if(file.length())
            wadfiles.push_back(file);
        else
        {
            Printf (PRINT_HIGH, "could not find WAD: %s\n", tmp.c_str());
            fails.push_back(i);
        }
    }

    if(wadnames.size() > 1)
        modifiedgame = true;

    wadhashes = W_InitMultipleFiles (wadfiles);

    UndoDehPatch();

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

    D_DoDefDehackedPatch(patch_files);

    //gotconback = false;
    //C_InitConsole(DisplayWidth, DisplayHeight, true);

    HU_Init ();

    if(!(DefaultPalette = InitPalettes("PLAYPAL")))
        I_Error("Could not reinitialize palette");
    V_InitPalette();

    G_SetLevelStrings ();
    G_ParseMapInfo ();
    G_ParseMusInfo ();
    S_ParseSndInfo();

    M_Init();
    R_Init();
    P_InitEffects();	// [ML] Do this here so we don't have to put particle crap in server
    P_Init();

    S_Init (snd_sfxvolume, snd_musicvolume);
    ST_Init();

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

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

    return fails;
}
コード例 #6
0
ファイル: w_wad.cpp プロジェクト: WChrisK/OdaStats
//
// W_AddFile
//
// All files are optional, but at least one file must be found
// (PWAD, if all required lumps are present).
// Files with a .wad extension are wadlink files with multiple lumps.
// Other files are single lumps with the base filename for the lump name.
//
// Map reloads are supported through WAD reload so no need for vanilla tilde
// reload hack here
//
std::string W_AddFile(std::string filename)
{
	FILE*			handle;
	filelump_t*		fileinfo;

	FixPathSeparator(filename);

	if ( (handle = fopen(filename.c_str(), "rb")) == NULL)
	{
		Printf(PRINT_HIGH, "couldn't open %s\n", filename.c_str());
		return "";
	}

	Printf(PRINT_HIGH, "adding %s", filename.c_str());

	size_t newlumps;

	wadinfo_t header;
	fread(&header, sizeof(header), 1, handle);
	header.identification = LELONG(header.identification);

	if (header.identification != IWAD_ID && header.identification != PWAD_ID)
	{
		// raw lump file
		std::string lumpname;
		M_ExtractFileBase(filename, lumpname);

		fileinfo = new filelump_t[1];	
		fileinfo->filepos = 0;
		fileinfo->size = M_FileLength(handle);
		std::transform(lumpname.c_str(), lumpname.c_str() + 8, fileinfo->name, toupper);

		newlumps = 1;
		Printf(PRINT_HIGH, " (single lump)\n");
	}
	else
	{
		// WAD file
		header.numlumps = LELONG(header.numlumps);
		header.infotableofs = LELONG(header.infotableofs);
		size_t length = header.numlumps * sizeof(filelump_t);

		if (length > (unsigned)M_FileLength(handle))
		{
			Printf(PRINT_HIGH, "\nbad number of lumps for %s\n", filename.c_str());
			fclose(handle);
			return "";
		}

		fileinfo = new filelump_t[header.numlumps];
		fseek(handle, header.infotableofs, SEEK_SET);
		fread(fileinfo, length, 1, handle);

		// convert from little-endian to target arch and capitalize lump name
		for (int i = 0; i < header.numlumps; i++)
		{
			fileinfo[i].filepos = LELONG(fileinfo[i].filepos);
			fileinfo[i].size = LELONG(fileinfo[i].size);
			std::transform(fileinfo[i].name, fileinfo[i].name + 8, fileinfo[i].name, toupper);
		}

		newlumps = header.numlumps;	
		Printf(PRINT_HIGH, " (%d lumps)\n", header.numlumps);
	}

	W_AddLumps(handle, fileinfo, newlumps, false);

	delete [] fileinfo;

	return W_MD5(filename);
}
コード例 #7
0
ファイル: d_main.cpp プロジェクト: JohnnyonFlame/odamex
//
// D_DoDefDehackedPatch
//
// [Russell] - Change the meaning, this will load multiple patch files if
//             specified
void D_DoDefDehackedPatch (const std::vector<std::string> &newpatchfiles)
{
    DArgs files;
    BOOL noDef = false;
    BOOL chexLoaded = false;
    QWORD i;

    if (!newpatchfiles.empty())
    {
        std::string f;
        std::string ext;

        // we want the extension of the file
        for (i = 0; i < newpatchfiles.size(); i++)
        {
            if (M_ExtractFileExtension(newpatchfiles[i], ext))
            {
                f = BaseFileSearch(newpatchfiles[i], ext);

                if (f.length())
                {
                    if (DoDehPatch (f.c_str(), false))
                    {
                        std::string Filename;
                        M_ExtractFileName(f, Filename);
                        patchfiles.push_back(Filename);
                    }

                    noDef = true;
                }
            }
        }
    }
    else // [Russell] - Only load if newpatchfiles is empty
    {
        // try .deh files on command line

        files = Args.GatherFiles ("-deh", ".deh", false);

        if (files.NumArgs())
        {
            for (i = 0; i < files.NumArgs(); i++)
            {
                std::string f = BaseFileSearch (files.GetArg (i), ".DEH");

                if (f.length())
                {
                    if (DoDehPatch (f.c_str(), false))
                    {
                        std::string Filename;
                        M_ExtractFileName(f, Filename);
                        patchfiles.push_back(Filename);
                    }

					if (!strncmp(files.GetArg(i),"chex.deh", 8))
						chexLoaded = true;

                }
            }
            noDef = true;
        }

		if (gamemode == retail_chex && !multiplayer && !chexLoaded)
			Printf(PRINT_HIGH,"Warning: chex.deh not loaded, experience may differ from the original!\n");

        // remove the old arguments
        files.FlushArgs();

        // try .bex files on command line
        files = Args.GatherFiles ("-bex", ".bex", false);

        if (files.NumArgs())
        {
            for (i = 0; i < files.NumArgs(); i++)
            {
                std::string f = BaseFileSearch (files.GetArg (i), ".BEX");

                if (f.length())
                {
                    if (DoDehPatch (f.c_str(), false))
                    {
                        std::string Filename;
                        M_ExtractFileName(f, Filename);
                        patchfiles.push_back(Filename);
                    }
                }
            }
            noDef = true;
        }
    }

    // try default patches
    if (!noDef)
        DoDehPatch (NULL, true);	// See if there's a patch in a PWAD

	for (size_t i = 0; i < patchfiles.size(); i++)
		patchhashes.push_back(W_MD5(patchfiles[i]));
}