예제 #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;
}
예제 #2
0
//
// SV_SendServerInfo
// 
// Sends server info to a launcher
// TODO: Clean up and reinvent.
void SV_SendServerInfo()
{
	size_t i;

	SZ_Clear(&ml_message);
	
	MSG_WriteLong(&ml_message, CHALLENGE);
	MSG_WriteLong(&ml_message, SV_NewToken());

	// if master wants a key to be presented, present it we will
	if(MSG_BytesLeft() == 4)
		MSG_WriteLong(&ml_message, MSG_ReadLong());

	MSG_WriteString(&ml_message, (char *)sv_hostname.cstring());

	byte playersingame = 0;
	for (Players::iterator it = players.begin();it != players.end();++it)
	{
		if (it->ingame())
			playersingame++;
	}

	MSG_WriteByte(&ml_message, playersingame);
	MSG_WriteByte(&ml_message, sv_maxclients.asInt());

	MSG_WriteString(&ml_message, level.mapname);

	size_t numwads = wadfiles.size();
	if(numwads > 0xff)numwads = 0xff;

	MSG_WriteByte(&ml_message, numwads - 1);

	for (i = 1; i < numwads; ++i)
		MSG_WriteString(&ml_message, D_CleanseFileName(wadfiles[i], "wad").c_str());

	MSG_WriteBool(&ml_message, (sv_gametype == GM_DM || sv_gametype == GM_TEAMDM));
	MSG_WriteByte(&ml_message, sv_skill.asInt());
	MSG_WriteBool(&ml_message, (sv_gametype == GM_TEAMDM));
	MSG_WriteBool(&ml_message, (sv_gametype == GM_CTF));

	for (Players::iterator it = players.begin();it != players.end();++it)
	{
		if (it->ingame())
		{
			MSG_WriteString(&ml_message, it->userinfo.netname.c_str());
			MSG_WriteShort(&ml_message, it->fragcount);
			MSG_WriteLong(&ml_message, it->ping);

			if (sv_gametype == GM_TEAMDM || sv_gametype == GM_CTF)
				MSG_WriteByte(&ml_message, it->userinfo.team);
			else
				MSG_WriteByte(&ml_message, TEAM_NONE);
		}
	}

	for (i = 1; i < numwads; ++i)
		MSG_WriteString(&ml_message, wadhashes[i].c_str());

	MSG_WriteString(&ml_message, sv_website.cstring());

	if (sv_gametype == GM_TEAMDM || sv_gametype == GM_CTF)
	{
		MSG_WriteLong(&ml_message, sv_scorelimit.asInt());
		
		for(size_t i = 0; i < NUMTEAMS; i++)
		{
			if ((sv_gametype == GM_CTF && i < 2) || (sv_gametype != GM_CTF && i < sv_teamsinplay)) {
				MSG_WriteByte(&ml_message, 1);
				MSG_WriteLong(&ml_message, TEAMpoints[i]);
			} else {
				MSG_WriteByte(&ml_message, 0);
			}
		}
	}
	
	MSG_WriteShort(&ml_message, VERSION);

//bond===========================
	MSG_WriteString(&ml_message, (char *)sv_email.cstring());

	int timeleft = (int)(sv_timelimit - level.time/(TICRATE*60));
	if (timeleft<0) timeleft=0;

	MSG_WriteShort(&ml_message,sv_timelimit.asInt());
	MSG_WriteShort(&ml_message,timeleft);
	MSG_WriteShort(&ml_message,sv_fraglimit.asInt());

	MSG_WriteBool(&ml_message, (sv_itemsrespawn ? true : false));
	MSG_WriteBool(&ml_message, (sv_weaponstay ? true : false));
	MSG_WriteBool(&ml_message, (sv_friendlyfire ? true : false));
	MSG_WriteBool(&ml_message, (sv_allowexit ? true : false));
	MSG_WriteBool(&ml_message, (sv_infiniteammo ? true : false));
	MSG_WriteBool(&ml_message, (sv_nomonsters ? true : false));
	MSG_WriteBool(&ml_message, (sv_monstersrespawn ? true : false));
	MSG_WriteBool(&ml_message, (sv_fastmonsters ? true : false));
	MSG_WriteBool(&ml_message, (sv_allowjump ? true : false));
	MSG_WriteBool(&ml_message, (sv_freelook ? true : false));
	MSG_WriteBool(&ml_message, (sv_waddownload ? true : false));
	MSG_WriteBool(&ml_message, (sv_emptyreset ? true : false));
	MSG_WriteBool(&ml_message, false);		// used to be sv_cleanmaps
	MSG_WriteBool(&ml_message, (sv_fragexitswitch ? true : false));

	for (Players::iterator it = players.begin();it != players.end();++it)
	{
		if (it->ingame())
		{
			MSG_WriteShort(&ml_message, it->killcount);
			MSG_WriteShort(&ml_message, it->deathcount);
			
			int timeingame = (time(NULL) - it->JoinTime)/60;
			if (timeingame<0) timeingame=0;
				MSG_WriteShort(&ml_message, timeingame);
		}
	}
	
//bond===========================

    MSG_WriteLong(&ml_message, (DWORD)0x01020304);
    MSG_WriteShort(&ml_message, sv_maxplayers.asInt());
    
    for (Players::iterator it = players.begin();it != players.end();++it)
    {
        if (it->ingame())
        {
            MSG_WriteBool(&ml_message, (it->spectator ? true : false));
        }
    }

    MSG_WriteLong(&ml_message, (DWORD)0x01020305);
    MSG_WriteShort(&ml_message, strlen(join_password.cstring()) ? 1 : 0);
    
    // GhostlyDeath -- Send Game Version info
    MSG_WriteLong(&ml_message, GAMEVER);

    MSG_WriteByte(&ml_message, patchfiles.size());
    
    for (size_t i = 0; i < patchfiles.size(); ++i)
        MSG_WriteString(&ml_message, D_CleanseFileName(patchfiles[i]).c_str());

	NET_SendPacket(ml_message, net_from);
}
예제 #3
0
void NetDemo::readSnapshotData(byte *buf, size_t length)
{
	byte cid = consoleplayer_id;
	byte did = displayplayer_id;

	P_ClearAllNetIds();

	// Remove all players	
	players.clear();

	// Remove all actors
	TThinkerIterator<AActor> iterator;
	AActor *mo;
	while ( (mo = iterator.Next() ) )
		mo->Destroy();
	
	gameaction = ga_nothing;
	
	FLZOMemFile memfile;
	
	length = 0;
	memfile.Open(buf);		// open for reading

	FArchive arc(memfile);

	// Read the server cvars
	byte vars[4096], *vars_p;
	vars_p = vars;
	size_t len = arc.ReadCount ();
	arc.Read(vars, len);
	cvar_t::C_ReadCVars(&vars_p);

	// read wad info
	std::vector<std::string> newwadfiles, newpatchfiles;
	byte numwads, numpatches;
	std::string str;

	arc >> numwads;
	for (size_t i = 0; i < numwads; i++)
	{
		arc >> str;
		newwadfiles.push_back(D_CleanseFileName(str));
	}
	arc >> numpatches;
	for (size_t i = 0; i < numpatches; i++)
	{
		arc >> str;
		newpatchfiles.push_back(D_CleanseFileName(str));
	}

	std::string mapname;
	bool intermission;
	arc >> mapname;
	arc >> intermission;

	G_SerializeSnapshots(arc);
	P_SerializeRNGState(arc);
	P_SerializeACSDefereds(arc);

	// Read the status of flags in CTF
	for (int i = 0; i < NUMFLAGS; i++)
		arc >> CTFdata[i];

	// Read team points
	for (int i = 0; i < NUMTEAMS; i++)
		arc >> TEAMpoints[i];	

	arc >> level.time;

	for (int i = 0; i < NUM_WORLDVARS; i++)
		arc >> ACS_WorldVars[i];

	for (int i = 0; i < NUM_GLOBALVARS; i++)
		arc >> ACS_GlobalVars[i];

	netgame = multiplayer = true;

	// load a base level
	savegamerestore = true;     // Use the player actors in the savegame
	serverside = false;

	G_LoadWad(newwadfiles, newpatchfiles);

	G_InitNew(mapname.c_str());
	displayplayer_id = consoleplayer_id = 1;
	savegamerestore = false;

	// read consistancy marker
	byte check;
	arc >> check;

	arc.Close();

	if (check != 0x1d)
		fatalError("Bad snapshot");
	
	consoleplayer_id = cid;
	
	// try to restore display player
	player_t *disp = &idplayer(did);
	if (validplayer(*disp) && disp->ingame() && !disp->spectator)
		displayplayer_id = did;
	else
		displayplayer_id = cid;

	// restore player colors
	for (Players::iterator it = players.begin();it != players.end();++it)
	{
		int color = CL_GetPlayerColor(&*it);
		R_BuildPlayerTranslation(it->id, color);
	}

	R_CopyTranslationRGB (0, consoleplayer_id);

	// Link the CTF flag actors to CTFdata[i].actor
	TThinkerIterator<AActor> flagiterator;
	while ( (mo = flagiterator.Next() ) )
	{
		if (mo->type == MT_BDWN || mo->type == MT_BCAR)
			CTFdata[it_blueflag].actor = mo->ptr();
		if (mo->type == MT_RDWN || mo->type == MT_RCAR)
			CTFdata[it_redflag].actor = mo->ptr();
	}

	// Make sure the status bar is displayed correctly
	ST_Start();
}
예제 #4
0
void NetDemo::writeSnapshotData(byte *buf, size_t &length)
{
	G_SnapshotLevel();

	FLZOMemFile memfile;
	memfile.Open();			// open for writing

	FArchive arc(memfile);

	// Save the server cvars
	byte vars[4096], *vars_p;
	vars_p = vars;

	cvar_t::C_WriteCVars(&vars_p, CVAR_SERVERINFO);
	arc.WriteCount(vars_p - vars);
	arc.Write(vars, vars_p - vars);

	// write wad info
	arc << (byte)(wadfiles.size() - 1);
	for (size_t i = 1; i < wadfiles.size(); i++)
		arc << D_CleanseFileName(wadfiles[i]).c_str();
	arc << (byte)patchfiles.size();
	for (size_t i = 0; i < patchfiles.size(); i++)
		arc << D_CleanseFileName(patchfiles[i]).c_str();
	// write map info
	arc << level.mapname;
	arc << (BYTE)(gamestate == GS_INTERMISSION);

	G_SerializeSnapshots(arc);
	P_SerializeRNGState(arc);
	P_SerializeACSDefereds(arc);

	// Save the status of the flags in CTF
	for (int i = 0; i < NUMFLAGS; i++)
		arc << CTFdata[i];

	// Save team points
	for (int i = 0; i < NUMTEAMS; i++)
		arc << TEAMpoints[i];
	
	arc << level.time;

	for (int i = 0; i < NUM_WORLDVARS; i++)
		arc << ACS_WorldVars[i];

	for (int i = 0; i < NUM_GLOBALVARS; i++)
		arc << ACS_GlobalVars[i];

	byte check = 0x1d;
	arc << check;          // consistancy marker

	gameaction = ga_nothing;

	arc.Close();

	// get the size of the snapshot data	
	length = memfile.Length();
	memfile.WriteToBuffer(buf, NetDemo::MAX_SNAPSHOT_SIZE);
			
    if (level.info->snapshot != NULL)
    {
        delete level.info->snapshot;
        level.info->snapshot = NULL;
    }
}
예제 #5
0
void NetDemo::writeConnectionSequence(buf_t *netbuffer)
{
	// The packet sequence id
	MSG_WriteLong	(netbuffer, 0);
	
	// Server sends our player id and digest
	MSG_WriteMarker	(netbuffer, svc_consoleplayer);
	MSG_WriteByte	(netbuffer, consoleplayer().id);
	MSG_WriteString	(netbuffer, digest.c_str());

	// our userinfo
	MSG_WriteMarker	(netbuffer, svc_userinfo);
	MSG_WriteByte	(netbuffer, consoleplayer().id);
	MSG_WriteString	(netbuffer, consoleplayer().userinfo.netname.c_str());
	MSG_WriteByte	(netbuffer, consoleplayer().userinfo.team);
	MSG_WriteLong	(netbuffer, consoleplayer().userinfo.gender);
	MSG_WriteLong	(netbuffer, consoleplayer().userinfo.color);
	MSG_WriteString	(netbuffer, "");	// [SL] place holder for deprecated skins
	MSG_WriteShort	(netbuffer, consoleplayer().GameTime);
	
	// Server sends its settings
	MSG_WriteMarker	(netbuffer, svc_serversettings);
	cvar_t *var = GetFirstCvar();
	while (var)
	{
		if (var->flags() & CVAR_SERVERINFO)
		{
			MSG_WriteByte	(netbuffer, 1);
			MSG_WriteString	(netbuffer,	var->name());
			MSG_WriteString	(netbuffer,	var->cstring());
		}
		var = var->GetNext();
	}
	MSG_WriteByte	(netbuffer, 2);		// end of server settings marker

	// Server tells everyone if we're a spectator
	MSG_WriteMarker	(netbuffer, svc_spectate);
	MSG_WriteByte	(netbuffer, consoleplayer().id);
	MSG_WriteByte	(netbuffer, consoleplayer().spectator);

	// Server sends wads & map name
	MSG_WriteMarker	(netbuffer, svc_loadmap);

	// send list of wads (skip over wadnames[0] == odamex.wad)  
	MSG_WriteByte(netbuffer, MIN<size_t>(wadfiles.size() - 1, 255));
	for (size_t i = 1; i < MIN<size_t>(wadfiles.size(), 256); i++)
	{
		MSG_WriteString(netbuffer, D_CleanseFileName(wadfiles[i], "wad").c_str());
		MSG_WriteString(netbuffer, wadhashes[i].c_str());
	}

    // send list of DEH/BEX patches
    MSG_WriteByte(netbuffer, MIN<size_t>(patchfiles.size(), 255));
    for (size_t i = 0; i < MIN<size_t>(patchfiles.size(), 255); i++)
    {
        MSG_WriteString(netbuffer, D_CleanseFileName(patchfiles[i]).c_str());
        MSG_WriteString(netbuffer, patchfiles[i].c_str());
    }

	MSG_WriteString(netbuffer, level.mapname);

	// Server spawns the player
	MSG_WriteMarker	(netbuffer, svc_spawnplayer);
	MSG_WriteByte	(netbuffer, consoleplayer().id);
	if (consoleplayer().mo)
	{
		MSG_WriteShort	(netbuffer, consoleplayer().mo->netid);
		MSG_WriteLong	(netbuffer, consoleplayer().mo->angle);
		MSG_WriteLong	(netbuffer, consoleplayer().mo->x);
		MSG_WriteLong	(netbuffer, consoleplayer().mo->y);
		MSG_WriteLong	(netbuffer, consoleplayer().mo->z);
	}
	else
	{
		// The client hasn't yet received his own position from the server
		// This happens with cl_autorecord
		// Just fake a position for now
		MSG_WriteShort	(netbuffer, MAXSHORT);
		MSG_WriteLong	(netbuffer, 0);
		MSG_WriteLong	(netbuffer, 0);
		MSG_WriteLong	(netbuffer, 0);
		MSG_WriteLong	(netbuffer, 0);
	}
}
예제 #6
0
void D_DoomMain (void)
{
	const char *iwad;

	M_ClearRandom();
	// [AM] Init rand() PRNG, needed for non-deterministic maplist shuffling.
	srand(time(NULL));

	gamestate = GS_STARTUP;
	SetLanguageIDs ();
	M_FindResponseFile();		// [ML] 23/1/07 - Add Response file support back in

	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

	// Always log by default
    if (!LOG.is_open())
    	C_DoCommand("logfile");

	Printf (PRINT_HIGH, "Heapsize: %u megabytes\n", got_heapsize);

	M_LoadDefaults ();			// load before initing other systems
	C_ExecCmdLineParams (true, false);	// [RH] do all +set commands on the command line

	if (!RebootInit) {
		iwad = Args.CheckValue("-iwad");
		if(!iwad)
			iwad = "";

		D_AddDefWads(iwad);
		D_AddCmdParameterFiles();

		wadhashes = W_InitMultipleFiles (wadfiles);
		for (size_t i = 0; i < wadfiles.size(); i++)
			wadfiles[i] = D_CleanseFileName(wadfiles[i], "wad");

		// [RH] Initialize localizable strings.
		GStrings.LoadStrings (W_GetNumForName ("LANGUAGE"), STRING_TABLE_SIZE, false);
		GStrings.Compact ();

		//D_InitStrings ();
		D_DoDefDehackedPatch();
	}

	I_Init ();

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

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

	// Nomonsters
	if (Args.CheckParm("-nomonsters"))
		sv_nomonsters = 1;

	// Respawn
	if (Args.CheckParm("-respawn"))
		sv_monstersrespawn = 1;

	// Fast
	if (Args.CheckParm("-fast"))
		sv_fastmonsters = 1;

	// developer mode
	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)
	{
		sv_skill.Set (val[0]-'0');
	}

	if (devparm)
		Printf (PRINT_HIGH, "%s", GStrings(D_DEVSTR));        // 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" : "");
		sv_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");
		sv_timelimit.Set (20);
	}

	// [RH] Now that all text strings are set up,
	// insert them into the level and cluster data.
	G_SetLevelStrings ();
	// [RH] Parse through all loaded mapinfo lumps
	G_ParseMapInfo ();
	// [ML] Parse the musinfo lump
	G_ParseMusInfo ();
	// [RH] Parse any SNDINFO lumps
	S_ParseSndInfo();

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

	Printf (PRINT_HIGH, "R_Init: Init DOOM refresh daemon.\n");
	R_Init ();

	Printf (PRINT_HIGH, "P_Init: Init Playloop state.\n");
	P_Init ();

	Printf (PRINT_HIGH, "SV_InitNetwork: Checking network game status.\n");
    SV_InitNetwork();

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

	// [AM] Initialize banlist
	SV_InitBanlist();

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

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

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

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

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

	//iwad = Args.CheckValue("-iwad");
	//D_DoomWadReboot(start_wads);

	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;
	}

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

	G_ChangeMap ();

	D_DoomLoop (); // never returns
}