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; }
// // 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); }
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(); }
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; } }
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); } }
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 }