void CPreGame::StartServer(const std::string& setupscript) { assert(!gameServer); ScopedOnceTimer startserver("PreGame::StartServer"); GameData* startupData = new GameData(); CGameSetup* setup = new CGameSetup(); setup->Init(setupscript); startupData->SetRandomSeed(static_cast<unsigned>(gu->usRandInt())); if (setup->mapName.empty()) { throw content_error("No map selected in startscript"); } // We must map the map into VFS this early, because server needs the start positions. // Take care that MapInfo isn't loaded here, as map options aren't available to it yet. vfsHandler->AddArchiveWithDeps(setup->mapName, false); // Loading the start positions executes the map's Lua. // This means start positions can NOT be influenced by map options. // (Which is OK, since unitsync does not have map options available either.) setup->LoadStartPositions(); const std::string& modArchive = archiveScanner->ArchiveFromName(setup->modName); const std::string& mapArchive = archiveScanner->ArchiveFromName(setup->mapName); startupData->SetModChecksum(archiveScanner->GetArchiveCompleteChecksum(modArchive)); startupData->SetMapChecksum(archiveScanner->GetArchiveCompleteChecksum(mapArchive)); good_fpu_control_registers("before CGameServer creation"); startupData->SetSetup(setup->gameSetupText); gameServer = new CGameServer(settings->hostIP, settings->hostPort, startupData, setup); delete startupData; gameServer->AddLocalClient(settings->myPlayerName, SpringVersion::GetFull()); good_fpu_control_registers("after CGameServer creation"); }
void CPreGame::StartServer(const std::string& setupscript) { assert(!gameServer); GameData* startupData = new GameData(); CGameSetup* setup = new CGameSetup(); setup->Init(setupscript); startupData->SetRandomSeed(static_cast<unsigned>(gu->usRandInt())); if (! setup->mapName.empty()) { // would be better to use MapInfo here, but this doesn't work LoadMap(setup->mapName); // map into VFS std::string mapDefFile; const std::string extension = setup->mapName.substr(setup->mapName.length()-3); if (extension == "smf") mapDefFile = std::string("maps/")+setup->mapName.substr(0,setup->mapName.find_last_of('.'))+".smd"; else if(extension == "sm3") mapDefFile = string("maps/")+setup->mapName; else throw std::runtime_error("CPreGame::StartServer(): Unknown extension: " + extension); MapParser mp(setup->mapName); LuaTable mapRoot = mp.GetRoot(); const std::string mapWantedScript = mapRoot.GetString("script", ""); const std::string scriptFile = mapRoot.GetString("scriptFile", ""); if (!mapWantedScript.empty()) { setup->scriptName = mapWantedScript; } } // here we now the name of the script to use CScriptHandler::SelectScript(setup->scriptName); std::string scriptWantedMod; scriptWantedMod = CScriptHandler::Instance().chosenScript->GetModName(); if (!scriptWantedMod.empty()) { setup->modName = archiveScanner->ModArchiveToModName(scriptWantedMod); } LoadMod(setup->modName); std::string modArchive = archiveScanner->ModNameToModArchive(setup->modName); startupData->SetModChecksum(archiveScanner->GetModChecksum(modArchive)); std::string mapFromScript = CScriptHandler::Instance().chosenScript->GetMapName(); if (!mapFromScript.empty() && setup->mapName != mapFromScript) { //TODO unload old map LoadMap(mapFromScript, true); } startupData->SetMapChecksum(archiveScanner->GetMapChecksum(setup->mapName)); setup->LoadStartPositions(); good_fpu_control_registers("before CGameServer creation"); startupData->SetSetup(setup->gameSetupText); gameServer = new CGameServer(settings.get(), false, startupData, setup); gameServer->AddLocalClient(settings->myPlayerName, SpringVersion::GetFull()); good_fpu_control_registers("after CGameServer creation"); }
void CPreGame::StartServer(const std::string& setupscript) { assert(!gameServer); ScopedOnceTimer startserver("Starting GameServer"); GameData* startupData = new GameData(); CGameSetup* setup = new CGameSetup(); setup->Init(setupscript); startupData->SetRandomSeed(static_cast<unsigned>(gu->usRandInt())); if (!setup->mapName.empty()) { // would be better to use MapInfo here, but this doesn't work LoadMap(setup->mapName); // map into VFS const std::string mapWantedScript(mapInfo->GetStringValue("script")); if (!mapWantedScript.empty()) { setup->scriptName = mapWantedScript; } } else { throw content_error("No map selected in startscript"); } CScriptHandler::SelectScript(setup->scriptName); LoadMod(setup->modName); std::string modArchive = archiveScanner->ModNameToModArchive(setup->modName); startupData->SetModChecksum(archiveScanner->GetModChecksum(modArchive)); startupData->SetMapChecksum(archiveScanner->GetMapChecksum(setup->mapName)); setup->LoadStartPositions(); good_fpu_control_registers("before CGameServer creation"); startupData->SetSetup(setup->gameSetupText); gameServer = new CGameServer(settings.get(), false, startupData, setup); delete startupData; gameServer->AddLocalClient(settings->myPlayerName, SpringVersion::GetFull()); good_fpu_control_registers("after CGameServer creation"); }
int main(int argc, char *argv[]) { #ifdef _WIN32 try { #endif SDL_Init(SDL_INIT_TIMER); std::cout << "If you find any errors, report them to mantis or the forums." << std::endl << std::endl; ConfigHandler::Instantiate(); // use the default config file FileSystemHandler::Initialize(false); CGameServer* server = 0; CGameSetup* gameSetup = 0; if (argc == 2) { const std::string script(argv[1]); std::string buf; std::cout << "Loading script from file: " << script << std::endl; ClientSetup settings; CFileHandler fh(argv[1]); if (!fh.FileExists()) throw content_error("script does not exist in given location: " + script); if (!fh.LoadStringData(buf)) throw content_error("script cannot be read: " + script); settings.Init(buf); gameSetup = new CGameSetup(); // to store the gamedata inside if (!gameSetup->Init(buf)) { // read the script provided by cmdline std::cout << "Failed to load script" << std::endl; return 1; } std::cout << "Starting server..." << std::endl; // Create the server, it will run in a separate thread GameData data; UnsyncedRNG rng; rng.Seed(gameSetup->gameSetupText.length()); rng.Seed(script.length()); data.SetRandomSeed(rng.RandInt()); // Use script provided hashes if they exist if (gameSetup->mapHash != 0) { data.SetMapChecksum(gameSetup->mapHash); gameSetup->LoadStartPositions(false); // reduced mode } else { data.SetMapChecksum(archiveScanner->GetArchiveCompleteChecksum(gameSetup->mapName)); CFileHandler f("maps/" + gameSetup->mapName); if (!f.FileExists()) { vfsHandler->AddArchiveWithDeps(gameSetup->mapName, false); } gameSetup->LoadStartPositions(); // full mode } if (gameSetup->modHash != 0) { data.SetModChecksum(gameSetup->modHash); } else { const std::string& modArchive = archiveScanner->ArchiveFromName(gameSetup->modName); const unsigned int modCheckSum = archiveScanner->GetArchiveCompleteChecksum(modArchive); data.SetModChecksum(modCheckSum); } data.SetSetup(gameSetup->gameSetupText); server = new CGameServer(settings.hostIP, settings.hostPort, &data, gameSetup); while (!server->HasFinished()) // check if still running #ifdef _WIN32 Sleep(1000); #else sleep(1); // if so, wait 1 second #endif delete server; // delete the server after usage } else { std::cout << "usage: " << argv[0] << " <full_path_to_script>" << std::endl; } FileSystemHandler::Cleanup(); ConfigHandler::Deallocate(); #ifdef _WIN32 } catch (const std::exception& err) { std::cout << "Exception raised: " << err.what() << std::endl; return 1; } #endif return 0; }
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); }
int main(int argc, char *argv[]) { #ifdef _WIN32 try { #endif std::cout << "If you find any errors, report them to mantis or the forums." << std::endl << std::endl; ConfigHandler::Instantiate(""); FileSystemHandler::Cleanup(); FileSystemHandler::Initialize(false); CGameServer* server = 0; CGameSetup* gameSetup = 0; if (argc > 1) { const std::string script(argv[1]); std::cout << "Loading script from file: " << script << std::endl; ClientSetup settings; CFileHandler fh(argv[1]); if (!fh.FileExists()) throw content_error("Setupscript doesn't exists in given location: "+script); std::string buf; if (!fh.LoadStringData(buf)) throw content_error("Setupscript cannot be read: "+script); settings.Init(buf); gameSetup = new CGameSetup(); // to store the gamedata inside if (!gameSetup->Init(buf)) // read the script provided by cmdline { std::cout << "Failed to load script" << std::endl; return 1; } std::cout << "Starting server..." << std::endl; // Create the server, it will run in a separate thread GameData* data = new GameData(); UnsyncedRNG rng; rng.Seed(gameSetup->gameSetupText.length()); rng.Seed(script.length()); data->SetRandomSeed(rng.RandInt()); // Use script provided hashes if they exist if (gameSetup->mapHash != 0) { data->SetMapChecksum(gameSetup->mapHash); gameSetup->LoadStartPositions(false); // reduced mode } else { data->SetMapChecksum(archiveScanner->GetMapChecksum(gameSetup->mapName)); CFileHandler* f = new CFileHandler("maps/" + gameSetup->mapName); if (!f->FileExists()) { std::vector<std::string> ars = archiveScanner->GetArchivesForMap(gameSetup->mapName); if (ars.empty()) { throw content_error("Couldn't find any archives for map '" + gameSetup->mapName + "'."); } for (std::vector<std::string>::iterator i = ars.begin(); i != ars.end(); ++i) { if (!vfsHandler->AddArchive(*i, false)) { throw content_error("Couldn't load archive '" + *i + "' for map '" + gameSetup->mapName + "'."); } } } delete f; gameSetup->LoadStartPositions(); // full mode } if (gameSetup->modHash != 0) { data->SetModChecksum(gameSetup->modHash); } else { const std::string modArchive = archiveScanner->ModNameToModArchive(gameSetup->modName); data->SetModChecksum(archiveScanner->GetModChecksum(modArchive)); } data->SetSetup(gameSetup->gameSetupText); server = new CGameServer(&settings, false, data, gameSetup); while (!server->HasFinished()) // check if still running #ifdef _WIN32 Sleep(1000); #else sleep(1); // if so, wait 1 second #endif delete server; // delete the server after usage } else { std::cout << "usage: spring-dedicated <full_path_to_script>" << std::endl; } FileSystemHandler::Cleanup(); #ifdef _WIN32 } catch (const std::exception& err) { std::cout << "Exception raised: " << err.what() << std::endl; return 1; } #endif return 0; }