void CPreGame::ReadDataFromDemo(const std::string& demoName) { ScopedOnceTimer startserver("Reading demo data"); assert(!gameServer); logOutput.Print("Pre-scanning demo file for game data..."); CDemoReader scanner(demoName, 0); boost::shared_ptr<const RawPacket> buf(scanner.GetData(static_cast<float>(FLT_MAX ))); while ( buf ) { if (buf->data[0] == NETMSG_GAMEDATA) { GameData *data = new GameData(boost::shared_ptr<const RawPacket>(buf)); CGameSetup* demoScript = new CGameSetup(); if (!demoScript->Init(data->GetSetup())) { throw content_error("Demo contains incorrect script"); } // modify the startscriptscript so it can be used to watch the demo TdfParser script(data->GetSetup().c_str(), data->GetSetup().size()); TdfParser::TdfSection* tgame = script.GetRootSection()->sections["game"]; tgame->AddPair("ScriptName", demoScript->scriptName); tgame->AddPair("MapName", demoScript->mapName); tgame->AddPair("Gametype", demoScript->modName); tgame->AddPair("Demofile", demoName); for (std::map<std::string, TdfParser::TdfSection*>::iterator it = tgame->sections.begin(); it != tgame->sections.end(); ++it) { if (it->first.size() > 6 && it->first.substr(0, 6) == "player") { it->second->AddPair("isfromdemo", 1); } } // add local spectator (and assert we didn't already have MAX_PLAYERS players) int myPlayerNum; string playerStr; for (myPlayerNum = MAX_PLAYERS - 1; myPlayerNum >= 0; --myPlayerNum) { char section[50]; sprintf(section, "game\\player%i", myPlayerNum); string s(section); if (script.SectionExist(s)) { ++myPlayerNum; sprintf(section, "player%i", myPlayerNum); playerStr = std::string(section); break; } } assert(!playerStr.empty()); TdfParser::TdfSection* me = tgame->construct_subsection(playerStr); me->AddPair("name", settings->myPlayerName); me->AddPair("spectator", 1); tgame->AddPair("myplayername", settings->myPlayerName); TdfParser::TdfSection* modopts = tgame->construct_subsection("MODOPTIONS"); modopts->AddPair("MaxSpeed", 20); std::ostringstream buf; script.print(buf); data->SetSetup(buf.str()); CGameSetup* tempSetup = new CGameSetup(); if (!tempSetup->Init(buf.str())) { throw content_error("Demo contains incorrect script"); } logOutput.Print("Starting GameServer"); good_fpu_control_registers("before CGameServer creation"); gameServer = new CGameServer(settings.get(), true, data, tempSetup); gameServer->AddLocalClient(settings->myPlayerName, SpringVersion::GetFull()); delete data; good_fpu_control_registers("after CGameServer creation"); logOutput.Print("GameServer started"); break; } if (scanner.ReachedEnd()) { throw content_error("End of demo reached and no game data found"); } buf.reset(scanner.GetData(FLT_MAX)); } assert(gameServer); }
std::string CreateDefaultSetup(const std::string& map, const std::string& mod, const std::string& script, const std::string& playername) { TdfParser::TdfSection setup; TdfParser::TdfSection* game = setup.construct_subsection("GAME"); game->add_name_value("Mapname", map); game->add_name_value("Gametype", mod); TdfParser::TdfSection* modopts = game->construct_subsection("MODOPTIONS"); modopts->AddPair("MaxSpeed", 20); game->AddPair("IsHost", 1); game->AddPair("OnlyLocal", 1); game->add_name_value("MyPlayerName", playername); game->AddPair("NoHelperAIs", configHandler->Get("NoHelperAIs", 0)); TdfParser::TdfSection* player0 = game->construct_subsection("PLAYER0"); player0->add_name_value("Name", playername); player0->AddPair("Team", 0); const bool isSkirmishAITestScript = CScriptHandler::Instance().IsSkirmishAITestScript(script); if (isSkirmishAITestScript) { SkirmishAIData aiData = CScriptHandler::Instance().GetSkirmishAIData(script); TdfParser::TdfSection* ai = game->construct_subsection("AI0"); ai->add_name_value("Name", "Enemy"); ai->add_name_value("ShortName", aiData.shortName); ai->add_name_value("Version", aiData.version); ai->AddPair("Host", 0); ai->AddPair("Team", 1); } else { TdfParser::TdfSection* player1 = game->construct_subsection("PLAYER1"); player1->add_name_value("Name", "Enemy"); player1->AddPair("Team", 1); } TdfParser::TdfSection* team0 = game->construct_subsection("TEAM0"); team0->AddPair("TeamLeader", 0); team0->AddPair("AllyTeam", 0); TdfParser::TdfSection* team1 = game->construct_subsection("TEAM1"); if (isSkirmishAITestScript) { team1->AddPair("TeamLeader", 0); } else { team1->AddPair("TeamLeader", 1); } team1->AddPair("AllyTeam", 1); TdfParser::TdfSection* ally0 = game->construct_subsection("ALLYTEAM0"); ally0->AddPair("NumAllies", 0); TdfParser::TdfSection* ally1 = game->construct_subsection("ALLYTEAM1"); ally1->AddPair("NumAllies", 0); std::ostringstream str; setup.print(str); return str.str(); }
void CPreGame::StartServerForDemo(const std::string& demoName) { TdfParser script((gameData->GetSetupText()).c_str(), (gameData->GetSetupText()).size()); TdfParser::TdfSection* tgame = script.GetRootSection()->sections["game"]; std::ostringstream moddedDemoScript; std::string playerStr; { // server will always use a modified copy of this assert(gameSetup != NULL); // modify the demo's start-script so it can be used to watch the demo tgame->AddPair("MapName", gameSetup->mapName); tgame->AddPair("Gametype", gameSetup->modName); tgame->AddPair("Demofile", demoName); tgame->remove("OnlyLocal", false); tgame->remove("HostIP", false); tgame->remove("HostPort", false); tgame->remove("AutohostPort", false); tgame->remove("SourcePort", false); //tgame->remove("IsHost", false); for (std::map<std::string, TdfParser::TdfSection*>::iterator it = tgame->sections.begin(); it != tgame->sections.end(); ++it) { if (it->first.size() > 6 && it->first.substr(0, 6) == "player") { it->second->AddPair("isfromdemo", 1); } } // add local spectator (and assert we didn't already have MAX_PLAYERS players) for (int myPlayerNum = MAX_PLAYERS - 1; myPlayerNum >= 0; --myPlayerNum) { string s = IntToString(myPlayerNum, "game\\player%i"); if (script.SectionExist(s)) { playerStr = IntToString(myPlayerNum + 1, "player%i"); break; } } assert(!playerStr.empty()); TdfParser::TdfSection* me = tgame->construct_subsection(playerStr); me->AddPair("name", clientSetup->myPlayerName); me->AddPair("spectator", 1); tgame->AddPair("myplayername", clientSetup->myPlayerName); // is this needed? TdfParser::TdfSection* modopts = tgame->construct_subsection("MODOPTIONS"); modopts->remove("MaxSpeed", false); } script.print(moddedDemoScript); gameData->SetSetupText(moddedDemoScript.str()); // create the server-private demo GameSetup containing the additional player boost::shared_ptr<CGameSetup> demoGameSetup(new CGameSetup()); if (!demoGameSetup->Init(moddedDemoScript.str())) throw content_error("Demo contains incorrect script"); LOG("[%s] starting GameServer", __FUNCTION__); good_fpu_control_registers("before CGameServer creation"); gameServer = new CGameServer(clientSetup, gameData, demoGameSetup); gameServer->AddLocalClient(clientSetup->myPlayerName, SpringVersion::GetFull()); good_fpu_control_registers("after CGameServer creation"); LOG("[%s] started GameServer", __FUNCTION__); }
std::string CreateDefaultSetup(const std::string& map, const std::string& mod, const std::string& script, const std::string& playername) { TdfParser::TdfSection setup; TdfParser::TdfSection* game = setup.construct_subsection("GAME"); game->add_name_value("Mapname", map); game->add_name_value("Gametype", mod); game->add_name_value("Scriptname", script); game->AddPair("IsHost", 1); game->add_name_value("MyPlayerName", playername); game->AddPair("NoHelperAIs", configHandler.Get("NoHelperAIs", 0)); TdfParser::TdfSection* player0 = game->construct_subsection("PLAYER0"); player0->add_name_value("Name", playername); player0->AddPair("Team", 0); TdfParser::TdfSection* player1 = game->construct_subsection("PLAYER1"); player1->add_name_value("Name", "Enemy"); player1->AddPair("Team", 1); TdfParser::TdfSection* team0 = game->construct_subsection("TEAM0"); team0->AddPair("Leader", 0); team0->AddPair("AllyTeam", 0); TdfParser::TdfSection* team1 = game->construct_subsection("TEAM1"); team1->AddPair("AllyTeam", 1); TdfParser::TdfSection* ally0 = game->construct_subsection("ALLYTEAM0"); ally0->AddPair("NumAllies", 0); TdfParser::TdfSection* ally1 = game->construct_subsection("ALLYTEAM1"); ally1->AddPair("NumAllies", 0); std::ostringstream str; setup.print(str); return str.str(); }