Esempio n. 1
0
//
// denis - D_AddSearchDir
// Split a new directory string using the separator and append results to the output
//
void D_AddSearchDir(std::vector<std::string> &dirs, const char *dir, const char separator)
{
	if(!dir)
		return;

	// search through dwd
	std::stringstream ss(dir);
	std::string segment;

	while(!ss.eof())
	{
		std::getline(ss, segment, separator);

		if(!segment.length())
			continue;

		FixPathSeparator(segment);
		I_ExpandHomeDir(segment);

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

		dirs.push_back(segment);
	}
}
Esempio n. 2
0
//
// M_AppendExtension
//
// Add an extension onto the end of a filename, returns false if it failed.
// if_needed detects if an extension is not present in path, if it isn't, it is
// added.
// The extension must contain a . at the beginning
BOOL M_AppendExtension (std::string &filename, std::string extension, bool if_needed)
{
    FixPathSeparator(filename);

    size_t l = filename.find_last_of(PATHSEPCHAR);
	if(l == filename.length())
		return false;

    size_t dot = extension.find_first_of('.');
    if (dot == std::string::npos)
        return false;

    if (if_needed)
    {
        size_t dot = filename.find_last_of('.');

        if (dot == std::string::npos)
            filename.append(extension);

        return true;
    }

    filename.append(extension);

    return true;
}
Esempio n. 3
0
//
// M_AppendExtension
//
// Add an extension onto the end of a filename, returns false if it failed.
// if_needed detects if an extension is not present in path, if it isn't, it is
// added.
// The extension must contain a . at the beginning
BOOL M_AppendExtension (std::string &path, std::string extension, bool if_needed)
{
    FixPathSeparator(path);
    
    size_t l = path.find_last_of('/');
	if(l == path.length())
		return false;

    size_t dot = extension.find_first_of('.');
    if (dot == std::string::npos)
        return false;

    if (if_needed)
    {
        size_t pathdot = path.find_last_of('.');
        
        if (pathdot == std::string::npos)
            path.append(extension);
            
        return true;
    }

    path.append(extension);

    return true;
}
Esempio n. 4
0
std::string I_GetBinaryDir()
{
	std::string ret;

#ifdef _XBOX
	// D:\ always corresponds to the binary path whether running from DVD or HDD.
	ret = "D:\\";
#elif defined GEKKO
	ret = "sd:/";
#elif defined WIN32
	char tmp[MAX_PATH]; // denis - todo - make separate function
	GetModuleFileName (NULL, tmp, sizeof(tmp));
	ret = tmp;
#else
	if(!Args[0])
		return "./";

	char realp[PATH_MAX];
	if(realpath(Args[0], realp))
		ret = realp;
	else
	{
		// search through $PATH
		const char *path = getenv("PATH");
		if(path)
		{
			std::stringstream ss(path);
			std::string segment;

			while(ss)
			{
				std::getline(ss, segment, ':');

				if(!segment.length())
					continue;

				if(segment[segment.length() - 1] != PATHSEPCHAR)
					segment += PATHSEP;
				segment += Args[0];

				if(realpath(segment.c_str(), realp))
				{
					ret = realp;
					break;
				}
			}
		}
	}
#endif

	FixPathSeparator(ret);

	size_t slash = ret.find_last_of(PATHSEPCHAR);

	if(slash == std::string::npos)
		return "";
	else
		return ret.substr(0, slash);
}
Esempio n. 5
0
std::string I_GetUserFileName (const char *file)
{
#if defined(UNIX) && !defined(GEKKO)
	// return absolute or explicitly relative pathnames unmodified,
	// so launchers or CLI/console users have control over netdemo placement
	if (file &&
		(file[0] == PATHSEPCHAR || // /path/to/file
		(file[0] == '.' && file[1] == PATHSEPCHAR) || // ./file
		(file[0] == '.' && file[1] == '.' && file[2] == PATHSEPCHAR))) // ../file
		return std::string (file);

	std::string path = I_GetHomeDir();

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

	path += ".odamex";

	struct stat info;
	if (stat (path.c_str(), &info) == -1)
	{
		if (mkdir (path.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) == -1)
		{
			I_FatalError ("Failed to create %s directory:\n%s",
						  path.c_str(), strerror (errno));
		}
	}
	else
	{
		if (!S_ISDIR(info.st_mode))
		{
			I_FatalError ("%s must be a directory", path.c_str());
		}
	}

	path += PATHSEP;
	path += file;
#elif defined(_XBOX)
	std::string path = "T:";

	path += PATHSEP;
	path += file;
#else
	if (!PathIsRelative(file))
		return std::string (file);

	std::string path = I_GetBinaryDir();

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

	path += file;
#endif

	FixPathSeparator(path);

	return path;
}
Esempio n. 6
0
//
// M_ExtractFilePath
//
// Extract the path from a filename that includes one
void M_ExtractFilePath (std::string path, std::string &dest)
{
    FixPathSeparator(path);

	size_t l = path.find_last_of('/');
	if(l == std::string::npos)
		l = path.length();
		
    if(l < path.length())
        dest = path.substr(0, l);
}
Esempio n. 7
0
//
// M_ExtractFilePath
//
// Extract the path from a filename that includes one
void M_ExtractFilePath (std::string filename, std::string &dest)
{
    FixPathSeparator(filename);

	size_t l = filename.find_last_of(PATHSEPCHAR);
	if(l == std::string::npos)
		l = filename.length();

    if(l < filename.length())
        dest = filename.substr(0, l);
}
Esempio n. 8
0
std::string I_GetBinaryDir()
{
	std::string ret;

#ifdef WIN32
	char tmp[MAX_PATH]; // denis - todo - make separate function
	GetModuleFileName (NULL, tmp, sizeof(tmp));
	ret = tmp;
#else
	if(!Args[0])
		return "./";

	char realp[PATH_MAX];
	if(realpath(Args[0], realp))
		ret = realp;
	else
	{
		// search through $PATH
		const char *path = getenv("PATH");
		if(path)
		{
			std::stringstream ss(path);
			std::string segment;

			while(ss)
			{
				std::getline(ss, segment, ':');

				if(!segment.length())
					continue;

				if(segment[segment.length() - 1] != '/')
					segment += "/";
				segment += Args[0];

				if(realpath(segment.c_str(), realp))
				{
					ret = realp;
					break;
				}
			}
		}
	}
#endif

	FixPathSeparator(ret);

	size_t slash = ret.find_last_of('/');
	if(slash == std::string::npos)
		return "";
	else
		return ret.substr(0, slash);
}
Esempio n. 9
0
std::string I_GetCWD()
{
	char tmp[4096] = {0};
	std::string ret = "./";
	
	const char *cwd = getcwd(tmp, sizeof(tmp));
	if(cwd)
		ret = cwd;

	FixPathSeparator(ret);

	return ret;
}
Esempio n. 10
0
//
// M_ExtractFileName
//
// Extract the name of a file from a path (name = filename with extension)
void M_ExtractFileName (std::string filename, std::string &dest)
{
    FixPathSeparator(filename);

	size_t l = filename.find_last_of('/');
	if(l == std::string::npos)
		l = 0;
	else
		l++;

    if(l < filename.length())
        dest = filename.substr(l, filename.length());
}
Esempio n. 11
0
std::string I_GetUserFileName (const char *file)
{
#if defined(UNIX) && !defined(GEKKO)
	std::string path = I_GetHomeDir();

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

	path += ".odamex";

	struct stat info;
	if (stat (path.c_str(), &info) == -1)
	{
		if (mkdir (path.c_str(), S_IRUSR | S_IWUSR | S_IXUSR) == -1)
		{
			I_FatalError ("Failed to create %s directory:\n%s",
						  path.c_str(), strerror (errno));
		}
	}
	else
	{
		if (!S_ISDIR(info.st_mode))
		{
			I_FatalError ("%s must be a directory", path.c_str());
		}
	}

	path += PATHSEP;
	path += file;
#elif defined(_XBOX)
	std::string path = "T:";

	path += PATHSEP;
	path += file;
#else
	std::string path = I_GetBinaryDir();

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

	path += file;
#endif

	FixPathSeparator(path);

	return path;
}
Esempio n. 12
0
//
// M_ExtractFileBase
//
// Extract the base file name from a path string (basefile = filename with no extension)
//
// e.g. /asdf/qwerty.zxc -> qwerty
// 	iuyt.wad -> iuyt
//      hgfd -> hgfd
//
// Note: On windows, text after the last . is considered the extension, so any preceding
// .'s won't be removed
void M_ExtractFileBase (std::string path, std::string &dest)
{
    FixPathSeparator(path);

	size_t l = path.find_last_of('/');
	if(l == std::string::npos)
		l = 0;
	else
		l++;

	size_t e = path.find_last_of('.');
	if(e == std::string::npos)
		e = path.length();

	if(l < path.length())
		dest = path.substr(l, e);
}
Esempio n. 13
0
//
// M_ExtractFileBase
//
// Extract the base file name from a path string (basefile = filename with no extension)
//
// e.g. /asdf/qwerty.zxc -> qwerty
// 	iuyt.wad -> iuyt
//      hgfd -> hgfd
//
// Note: On windows, text after the last . is considered the extension, so any preceding
// .'s won't be removed
void M_ExtractFileBase (std::string filename, std::string &dest)
{
    FixPathSeparator(filename);

	size_t l = filename.find_last_of(PATHSEPCHAR);
	if(l == std::string::npos)
		l = 0;
	else
		l++;

	size_t e = filename.find_last_of('.');
	if(e == std::string::npos)
		e = filename.length();

	if(l < filename.length())
		dest = filename.substr(l, e - l);
}
Esempio n. 14
0
//
// D_CleanseFileName
//
// Strips a file name of path information and transforms it into uppercase
//
std::string D_CleanseFileName(const std::string &filename, const std::string &ext)
{
	std::string newname(filename);

	FixPathSeparator(newname);
	if (ext.length())
		M_AppendExtension(newname, "." + ext);

	size_t slash = newname.find_last_of(PATHSEPCHAR);

	if (slash != std::string::npos)
		newname = newname.substr(slash + 1, newname.length() - slash);

	std::transform(newname.begin(), newname.end(), newname.begin(), toupper);

	return newname;
}
Esempio n. 15
0
void SV_InitMultipleFiles (std::vector<std::string> filenames)
{
	wadnames.clear();

	for(size_t i = 0; i < filenames.size(); i++)
	{
		FixPathSeparator (filenames[i]);
		std::string name = filenames[i];
		M_AppendExtension (filenames[i], ".wad");

		size_t slash = name.find_last_of(PATHSEPCHAR);

		if(slash != std::string::npos)
			name = name.substr(slash + 1, name.length() - slash);

		std::transform(name.begin(), name.end(), name.begin(), toupper);

		wadnames.push_back(name);
	}
}
Esempio n. 16
0
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);
}
Esempio n. 17
0
void NetDemo::writeLauncherSequence(buf_t *netbuffer)
{
    cvar_t *var = NULL, *prev_cvar = NULL;

    // Server sends launcher info
    MSG_WriteLong	(netbuffer, CHALLENGE);
    MSG_WriteLong	(netbuffer, 0);		// server_token

    // get sv_hostname and write it
    var = cvar_t::FindCVar("sv_hostname", &prev_cvar);
    MSG_WriteString (netbuffer, server_host.c_str());

    int playersingame = 0;
    for (size_t i = 0; i < players.size(); i++)
    {
        if (players[i].ingame())
            playersingame++;
    }
    MSG_WriteByte	(netbuffer, playersingame);
    MSG_WriteByte	(netbuffer, 0);				// sv_maxclients
    MSG_WriteString	(netbuffer, level.mapname);

    // names of all the wadfiles on the server
    size_t numwads = wadfiles.size();
    if (numwads > 0xff)
        numwads = 0xff;
    MSG_WriteByte	(netbuffer, numwads - 1);

    for (size_t n = 1; n < numwads; n++)
    {
        std::string tmpname = wadfiles[n];

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

        MSG_WriteString	(netbuffer, tmpname.c_str());
    }

    MSG_WriteBool	(netbuffer, 0);		// deathmatch?
    MSG_WriteByte	(netbuffer, 0);		// sv_skill
    MSG_WriteBool	(netbuffer, (sv_gametype == GM_TEAMDM));
    MSG_WriteBool	(netbuffer, (sv_gametype == GM_CTF));

    for (size_t i = 0; i < players.size(); i++)
    {
        // Notes: client just ignores this data but still expects to parse it
        if (players[i].ingame())
        {
            MSG_WriteString	(netbuffer, "");	// player's netname
            MSG_WriteShort	(netbuffer, 0);		// player's fragcount
            MSG_WriteLong	(netbuffer, 0);		// player's ping
            MSG_WriteByte	(netbuffer, 0);		// player's team
        }
    }

    // MD5 hash sums for all the wadfiles on the server
    for (size_t n = 1; n < numwads; n++)
        MSG_WriteString	(netbuffer, wadhashes[n].c_str());

    MSG_WriteString	(netbuffer, "");	// sv_website.cstring()

    if (sv_gametype == GM_TEAMDM || sv_gametype == GM_CTF)
    {
        MSG_WriteLong	(netbuffer, 0);		// sv_scorelimit
        for (size_t n = 0; n < NUMTEAMS; n++)
        {
            MSG_WriteBool	(netbuffer, false);
        }
    }

    MSG_WriteShort	(netbuffer, VERSION);

    // Note: these are ignored by clients when the client connects anyway
    // so they don't need real data
    MSG_WriteString	(netbuffer, "");	// sv_email.cstring()

    MSG_WriteShort	(netbuffer, 0);		// sv_timelimit
    MSG_WriteShort	(netbuffer, 0);		// timeleft before end of level
    MSG_WriteShort	(netbuffer, 0);		// sv_fraglimit

    MSG_WriteBool	(netbuffer, false);	// sv_itemrespawn
    MSG_WriteBool	(netbuffer, false);	// sv_weaponstay
    MSG_WriteBool	(netbuffer, false);	// sv_friendlyfire
    MSG_WriteBool	(netbuffer, false);	// sv_allowexit
    MSG_WriteBool	(netbuffer, false);	// sv_infiniteammo
    MSG_WriteBool	(netbuffer, false);	// sv_nomonsters
    MSG_WriteBool	(netbuffer, false);	// sv_monstersrespawn
    MSG_WriteBool	(netbuffer, false);	// sv_fastmonsters
    MSG_WriteBool	(netbuffer, false);	// sv_allowjump
    MSG_WriteBool	(netbuffer, false);	// sv_freelook
    MSG_WriteBool	(netbuffer, false);	// sv_waddownload
    MSG_WriteBool	(netbuffer, false);	// sv_emptyreset
    MSG_WriteBool	(netbuffer, false);	// sv_cleanmaps
    MSG_WriteBool	(netbuffer, false);	// sv_fragexitswitch

    for (size_t i = 0; i < players.size(); i++)
    {
        if (players[i].ingame())
        {
            MSG_WriteShort	(netbuffer, players[i].killcount);
            MSG_WriteShort	(netbuffer, players[i].deathcount);

            int timeingame = (time(NULL) - players[i].JoinTime)/60;
            if (timeingame < 0)
                timeingame = 0;
            MSG_WriteShort	(netbuffer, timeingame);
        }
    }

    MSG_WriteLong(netbuffer, (DWORD)0x01020304);
    MSG_WriteShort(netbuffer, sv_maxplayers);

    for (size_t i = 0; i < players.size(); i++)
    {
        if (players[i].ingame())
            MSG_WriteBool	(netbuffer, players[i].spectator);
    }

    MSG_WriteLong	(netbuffer, (DWORD)0x01020305);
    MSG_WriteShort	(netbuffer, 0);	// join_passowrd

    MSG_WriteLong	(netbuffer, GAMEVER);

    // TODO: handle patch files
    MSG_WriteByte	(netbuffer, 0);  // patchfiles.size()
//	MSG_WriteByte	(netbuffer, patchfiles.size());

//	for (size_t n = 0; n < patchfiles.size(); n++)
//		MSG_WriteString(netbuffer, patchfiles[n].c_str());
}
Esempio n. 18
0
void D_DoomMain (void)
{
	M_ClearRandom();

	gamestate = GS_STARTUP;

	if (lzo_init () != LZO_E_OK)	// [RH] Initialize the minilzo package.
		I_FatalError ("Could not initialize LZO routines");

    C_ExecCmdLineParams (false, true);	// [Nes] test for +logfile command

	I_Init ();

	D_CheckNetGame ();

	M_LoadDefaults ();			// load before initing other systems
	M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in
	C_ExecCmdLineParams (true, false);	// [RH] do all +set commands on the command line

	//D_AddDefWads();
	//SV_InitMultipleFiles (wadfiles);
	//wadhashes = W_InitMultipleFiles (wadfiles);

	// Base systems have been inited; enable cvar callbacks
	cvar_t::EnableCallbacks ();

	// [RH] Initialize configurable strings.
	D_InitStrings ();

	// [RH] User-configurable startup strings. Because BOOM does.
	if (STARTUP1[0])	Printf (PRINT_HIGH, "%s\n", STARTUP1);
	if (STARTUP2[0])	Printf (PRINT_HIGH, "%s\n", STARTUP2);
	if (STARTUP3[0])	Printf (PRINT_HIGH, "%s\n", STARTUP3);
	if (STARTUP4[0])	Printf (PRINT_HIGH, "%s\n", STARTUP4);
	if (STARTUP5[0])	Printf (PRINT_HIGH, "%s\n", STARTUP5);

	devparm = Args.CheckParm ("-devparm");

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

	const char *val = Args.CheckValue ("-skill");
	if (val)
	{
		skill.Set (val[0]-'0');
	}

	unsigned p = Args.CheckParm ("-warp");
	if (p && p < Args.NumArgs() - (1+(gameinfo.flags & GI_MAPxx ? 0 : 1)))
	{
		int ep, map;

		if (gameinfo.flags & GI_MAPxx)
		{
			ep = 1;
			map = atoi (Args.GetArg(p+1));
		}
		else
		{
			ep = Args.GetArg(p+1)[0]-'0';
			map = Args.GetArg(p+2)[0]-'0';
		}

		strncpy (startmap, CalcMapName (ep, map), 8);
		autostart = true;
	}

	// [RH] Hack to handle +map
	p = Args.CheckParm ("+map");
	if (p && p < Args.NumArgs()-1)
	{
		strncpy (startmap, Args.GetArg (p+1), 8);
		((char *)Args.GetArg (p))[0] = '-';
		autostart = true;
	}
	if (devparm)
		Printf (PRINT_HIGH, "%s", Strings[0].builtin);	// D_DEVSTR

	const char *v = Args.CheckValue ("-timer");
	if (v)
	{
		double time = atof (v);
		Printf (PRINT_HIGH, "Levels will end after %g minute%s.\n", time, time > 1 ? "s" : "");
		timelimit.Set ((float)time);
	}

	const char *w = Args.CheckValue ("-avg");
	if (w)
	{
		Printf (PRINT_HIGH, "Austin Virtual Gaming: Levels will end after 20 minutes\n");
		timelimit.Set (20);
	}

	// Check for -file in shareware
	if (modifiedgame && (gameinfo.flags & GI_SHAREWARE))
		I_FatalError ("You cannot -file with the shareware version. Register!");

	// [RH] Initialize items. Still only used for the give command. :-(
	InitItems ();

	// [RH] Lock any cvars that should be locked now that we're
	// about to begin the game.
	cvar_t::EnableNoSet ();

	Printf(PRINT_HIGH, "========== Odamex Server Initialized ==========\n");

#ifdef UNIX
	if (Args.CheckParm("-background"))
            daemon_init();
#endif

	// Use wads mentioned on the commandline to start with
	std::vector<std::string> start_wads;

	std::string custwad;
	const char *iwadparm = Args.CheckValue ("-iwad");
	if (iwadparm)
	{
		custwad = iwadparm;
		FixPathSeparator (custwad);
		start_wads.push_back(custwad);
	}

	DArgs files = Args.GatherFiles ("-file", ".wad", true);
	if (files.NumArgs() > 0)
	{
		modifiedgame = true;
		for (size_t i = 0; i < files.NumArgs(); i++)
		{
			start_wads.push_back(files.GetArg (i));
		}
	}

	D_DoomWadReboot(start_wads);

	// [RH] Now that all game subsystems have been initialized,
	// do all commands on the command line other than +set
	C_ExecCmdLineParams (false, false);

	strncpy(level.mapname, startmap, sizeof(level.mapname));

    gamestate = GS_STARTUP;

	G_ChangeMap ();

	D_DoomLoop (); // never returns
}
Esempio n. 19
0
//
// 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);
}
Esempio n. 20
0
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;
}