int main(int argc, char *argv[]) { try { std::cout << "BIG FAT WARNING: this server is currently under development. If you find any errors (you most likely will)"; std::cout << " report them to mantis or the forums." << std::endl << std::endl; FileSystemHandler::Cleanup(); FileSystemHandler::Initialize(false); CGameServer* server = 0; CGameSetup* gameSetup = 0; if (argc > 1) { std::string script = argv[1]; std::cout << "Loading script: " << script << std::endl; gameSetup = new CGameSetup(); // to store the gamedata inside if (!gameSetup->Init(script)) // 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 const std::string modArchive = archiveScanner->ModNameToModArchive(gameSetup->baseMod); GameData* data = new GameData(); data->SetMap(gameSetup->mapName, archiveScanner->GetMapChecksum(gameSetup->mapName)); data->SetMod(gameSetup->baseMod, archiveScanner->GetModChecksum(modArchive)); data->SetScript(gameSetup->scriptName); server = new CGameServer(gameSetup->hostport, false, data, gameSetup); if (gameSetup->autohostport > 0) server->AddAutohostInterface(gameSetup->autohostport); else { std::cout << "You should specify an AutohostPort in the script" << std::endl; } 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 delete gameSetup; } else { std::cout << "usage: dedicated <full_path_to_script>" << std::endl; } FileSystemHandler::Cleanup(); } catch (const std::exception& err) { std::cout << "Exception raised: " << err.what() << std::endl; } return 0; }
void CSkirmishAIHandler::LoadFromSetup(const CGameSetup& setup) { for (size_t a = 0; a < setup.GetSkirmishAIs().size(); ++a) { const SkirmishAIData& sai = setup.GetSkirmishAIs()[a]; AddSkirmishAI(sai, a); } }
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"); }
/// this just loads the mapname and some other early stuff void CCregLoadSaveHandler::LoadGameStartInfo(const std::string& file) { const std::string file2 = FindSaveFile(file); ifs = new std::ifstream (filesystem.LocateFile(file2).c_str(), std::ios::in|std::ios::binary); // in case these contained values alredy // (this is the case when loading a game through the spring menu eg), // we set them to empty strings, as ReadString() does append, // and we would end up with the correct value but two times // eg: "AbcAbc" instead of "Abc" scriptText = ""; modName = ""; mapName = ""; ReadString(*ifs, scriptText); if (!scriptText.empty() && !gameSetup) { CGameSetup* temp = new CGameSetup(); if (!temp->Init(scriptText)) { delete temp; temp = 0; } else { temp->saveName = file; gameSetup = temp; } } ReadString(*ifs, modName); ReadString(*ifs, mapName); }
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::GameDataReceived(boost::shared_ptr<const netcode::RawPacket> packet) { ScopedOnceTimer startserver("Loading client data"); gameData.reset(new GameData(packet)); CGameSetup* temp = new CGameSetup(); if (temp->Init(gameData->GetSetup())) { if (settings->isHost) { const std::string& setupTextStr = gameData->GetSetup(); std::fstream setupTextFile("_script.txt", std::ios::out); setupTextFile.write(setupTextStr.c_str(), setupTextStr.size()); setupTextFile.close(); } gameSetup = temp; gs->LoadFromSetup(gameSetup); CPlayer::UpdateControlledTeams(); } else { throw content_error("Server sent us incorrect script"); } gs->SetRandSeed(gameData->GetRandomSeed(), true); LogObject() << "Using map " << gameSetup->mapName << "\n"; if (net && net->GetDemoRecorder()) { net->GetDemoRecorder()->SetName(gameSetup->mapName, gameSetup->modName); LogObject() << "Recording demo " << net->GetDemoRecorder()->GetName() << "\n"; } LoadMap(gameSetup->mapName); archiveScanner->CheckArchive(gameSetup->mapName, gameData->GetMapChecksum()); // This MUST be loaded this late, since this executes map Lua code which // may call Spring.GetMapOptions(), which NEEDS gameSetup to be set! if (!mapInfo) { mapInfo = new CMapInfo(gameSetup->MapFile()); } const std::string mapWantedScript(mapInfo->GetStringValue("script")); if (!mapWantedScript.empty()) { temp->scriptName = mapWantedScript; } LogObject() << "Using script " << gameSetup->scriptName << "\n"; CScriptHandler::SelectScript(gameSetup->scriptName); LogObject() << "Using mod " << gameSetup->modName << "\n"; LoadMod(gameSetup->modName); modArchive = archiveScanner->ArchiveFromName(gameSetup->modName); LogObject() << "Using mod archive " << modArchive << "\n"; archiveScanner->CheckArchive(modArchive, gameData->GetModChecksum()); }
bool CGameSetup::LoadSavedScript(const std::string& file, const std::string& script) { if (script.empty()) return false; if (gameSetup != NULL) return false; CGameSetup* tempGameSetup = new CGameSetup(); if (!tempGameSetup->Init(script)) { delete tempGameSetup; return false; } tempGameSetup->saveName = file; // set the global instance gameSetup = tempGameSetup; return true; }
//this just loads the mapname and some other early stuff void CLoadSaveHandler::LoadGameStartInfo(std::string file) { ifs = new std::ifstream (filesystem.LocateFile(file).c_str(), std::ios::in|std::ios::binary); ReadString(*ifs, scriptText); if (!scriptText.empty() && !gameSetup) { CGameSetup* temp = SAFE_NEW CGameSetup(); if (!temp->Init(scriptText)) { delete temp; temp = 0; } else { temp->saveName = file; gameSetup = temp; } } ReadString(*ifs, modName); ReadString(*ifs, mapName); }
void CPreGame::GameDataReceived(boost::shared_ptr<const netcode::RawPacket> packet) { ScopedOnceTimer startserver("Loading client data"); gameData.reset(new GameData(packet)); CGameSetup* temp = new CGameSetup(); if (temp->Init(gameData->GetSetup())) { if (settings->isHost) { const std::string& setupTextStr = gameData->GetSetup(); std::fstream setupTextFile("_script.txt", std::ios::out); setupTextFile.write(setupTextStr.c_str(), setupTextStr.size()); setupTextFile.close(); } gameSetup = const_cast<const CGameSetup*>(temp); gs->LoadFromSetup(gameSetup); CPlayer::UpdateControlledTeams(); } else { throw content_error("Server sent us incorrect script"); } gs->SetRandSeed(gameData->GetRandomSeed(), true); LogObject() << "Using map " << gameSetup->mapName << "\n"; if (net && net->GetDemoRecorder()) { net->GetDemoRecorder()->SetName(gameSetup->mapName); LogObject() << "Recording demo " << net->GetDemoRecorder()->GetName() << "\n"; } LoadMap(gameSetup->mapName); archiveScanner->CheckMap(gameSetup->mapName, gameData->GetMapChecksum()); LogObject() << "Using script " << gameSetup->scriptName << "\n"; CScriptHandler::SelectScript(gameSetup->scriptName); LogObject() << "Using mod " << gameSetup->modName << "\n"; LoadMod(gameSetup->modName); modArchive = archiveScanner->ModNameToModArchive(gameSetup->modName); LogObject() << "Using mod archive " << modArchive << "\n"; archiveScanner->CheckMod(modArchive, gameData->GetModChecksum()); }
bool CGameSetup::LoadReceivedScript(const std::string& script, bool isHost) { CGameSetup* tempGameSetup = new CGameSetup(); if (!tempGameSetup->Init(script)) { delete tempGameSetup; return false; } if (isHost) { std::fstream setupTextFile("_script.txt", std::ios::out); // copy the script to a local file for inspection setupTextFile.write(script.c_str(), script.size()); setupTextFile.close(); } // set the global instance gameSetup = tempGameSetup; return true; }
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"); }
void CPreGame::GameDataReceived(boost::shared_ptr<const netcode::RawPacket> packet) { gameData.reset(new GameData(packet)); CGameSetup* temp = new CGameSetup(); if (temp->Init(gameData->GetSetup())) { temp->scriptName = gameData->GetScript(); temp->mapName = gameData->GetMap(); temp->baseMod = gameData->GetMod(); gameSetup = const_cast<const CGameSetup*>(temp); gs->LoadFromSetup(gameSetup); } else { throw content_error("Server sent us incorrect script"); } gs->SetRandSeed(gameData->GetRandomSeed(), true); LogObject() << "Using map " << gameData->GetMap() << "\n"; stupidGlobalMapname = gameData->GetMap(); if (net && net->GetDemoRecorder()) { net->GetDemoRecorder()->SetName(gameData->GetMap()); LogObject() << "Recording demo " << net->GetDemoRecorder()->GetName() << "\n"; } LoadMap(gameData->GetMap()); archiveScanner->CheckMap(gameData->GetMap(), gameData->GetMapChecksum()); LogObject() << "Using script " << gameData->GetScript() << "\n"; CScriptHandler::SelectScript(gameData->GetScript()); LogObject() << "Using mod " << gameData->GetMod() << "\n"; LoadMod(gameData->GetMod()); modArchive = archiveScanner->ModNameToModArchive(gameData->GetMod()); LogObject() << "Using mod archive " << modArchive << "\n"; archiveScanner->CheckMod(modArchive, gameData->GetModChecksum()); }
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; }
void CPreGame::GameDataReceived(boost::shared_ptr<const netcode::RawPacket> packet) { ScopedOnceTimer startserver("PreGame::GameDataReceived"); try { gameData.reset(new GameData(packet)); } catch (const netcode::UnpackPacketException& ex) { throw content_error(std::string("Server sent us invalid GameData: ") + ex.what()); } CGameSetup* temp = new CGameSetup(); if (temp->Init(gameData->GetSetup())) { if (settings->isHost) { const std::string& setupTextStr = gameData->GetSetup(); std::fstream setupTextFile("_script.txt", std::ios::out); setupTextFile.write(setupTextStr.c_str(), setupTextStr.size()); setupTextFile.close(); } gameSetup = temp; gu->LoadFromSetup(gameSetup); gs->LoadFromSetup(gameSetup); CPlayer::UpdateControlledTeams(); } else { throw content_error("Server sent us incorrect script"); } // some sanity checks for (int p = 0; p < playerHandler->ActivePlayers(); ++p) { const CPlayer* player = playerHandler->Player(p); if (!playerHandler->IsValidPlayer(player->playerNum)) { throw content_error("Invalid player in game data"); } if (!teamHandler->IsValidTeam(player->team)) { throw content_error("Invalid team in game data"); } if (!teamHandler->IsValidAllyTeam(teamHandler->AllyTeam(player->team))) { // TODO: seems not to make sense really throw content_error("Invalid ally team in game data"); } } gs->SetRandSeed(gameData->GetRandomSeed(), true); LOG("Using map: %s", gameSetup->mapName.c_str()); vfsHandler->AddArchiveWithDeps(gameSetup->mapName, false); try { archiveScanner->CheckArchive(gameSetup->mapName, gameData->GetMapChecksum()); } catch (const content_error& ex) { LOG_L(L_WARNING, "Incompatible map-checksum: %s", ex.what()); } LOG("Using game: %s", gameSetup->modName.c_str()); vfsHandler->AddArchiveWithDeps(gameSetup->modName, false); modArchive = archiveScanner->ArchiveFromName(gameSetup->modName); LOG("Using game archive: %s", modArchive.c_str()); try { archiveScanner->CheckArchive(modArchive, gameData->GetModChecksum()); } catch (const content_error& ex) { LOG_L(L_WARNING, "Incompatible game-checksum: %s", ex.what()); } if (net != NULL && wantDemo) { assert(net->GetDemoRecorder() == NULL); CDemoRecorder* recorder = new CDemoRecorder(gameSetup->mapName, gameSetup->modName); recorder->WriteSetupText(gameData->GetSetup()); recorder->SaveToDemo(packet->data, packet->length, net->GetPacketTime(gs->frameNum)); net->SetDemoRecorder(recorder); LOG("recording demo: %s", (recorder->GetName()).c_str()); } }
/** * Initializes instance of GameSetup */ void SpringApp::CreateGameSetup() { ENTER_SYNCED; if (!startscript.empty()) { CGameSetup* temp = SAFE_NEW CGameSetup(); if (!temp->Init(startscript)) { delete temp; temp = 0; } else { gameSetup = const_cast<const CGameSetup*>(temp); gs->LoadFromSetup(gameSetup); gu->LoadFromSetup(gameSetup); } } if (!gameSetup && demofile.empty()) { gs->noHelperAIs = !!configHandler.GetInt("NoHelperAIs", 0); const string luaGaiaStr = configHandler.GetString("LuaGaia", "1"); const string luaRulesStr = configHandler.GetString("LuaRules", "1"); gs->useLuaGaia = CLuaGaia::SetConfigString(luaGaiaStr); gs->useLuaRules = CLuaRules::SetConfigString(luaRulesStr); if (gs->useLuaGaia) { gs->gaiaTeamID = gs->activeTeams; gs->gaiaAllyTeamID = gs->activeAllyTeams; gs->activeTeams++; gs->activeAllyTeams++; CTeam* team = gs->Team(gs->gaiaTeamID); team->color[0] = 255; team->color[1] = 255; team->color[2] = 255; team->color[3] = 255; team->gaia = true; gs->SetAllyTeam(gs->gaiaTeamID, gs->gaiaAllyTeamID); } } ENTER_MIXED; bool server = true; if (!demofile.empty()) { server = false; } else if (gameSetup) { // first real player is demo host server = (gameSetup->myPlayerNum == gameSetup->numDemoPlayers) && !cmdline->result("client"); } else { server = !cmdline->result("client") || cmdline->result("server"); } #ifdef SYNCDEBUG // initialize sync debugger as soon as we know whether we will be server CSyncDebugger::GetInstance()->Initialize(server); #endif if (!demofile.empty()) { pregame = SAFE_NEW CPreGame(false, demofile, ""); } else { pregame = SAFE_NEW CPreGame(server, "", savefile); } }
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::GameDataReceived(boost::shared_ptr<const netcode::RawPacket> packet) { ScopedOnceTimer startserver("PreGame::GameDataReceived"); try { GameData *data = new GameData(packet); gameData.reset(data); } catch (netcode::UnpackPacketException &e) { throw content_error("Server sent us invalid GameData: " + e.err); } CGameSetup* temp = new CGameSetup(); if (temp->Init(gameData->GetSetup())) { if (settings->isHost) { const std::string& setupTextStr = gameData->GetSetup(); std::fstream setupTextFile("_script.txt", std::ios::out); setupTextFile.write(setupTextStr.c_str(), setupTextStr.size()); setupTextFile.close(); } gameSetup = temp; gu->LoadFromSetup(gameSetup); gs->LoadFromSetup(gameSetup); CPlayer::UpdateControlledTeams(); } else { throw content_error("Server sent us incorrect script"); } // some sanity checks for (int p = 0; p < playerHandler->ActivePlayers(); ++p) { const CPlayer* player = playerHandler->Player(p); if (!playerHandler->IsValidPlayer(player->playerNum)) { throw content_error("Invalid player in game data"); } if (!teamHandler->IsValidTeam(player->team)) { throw content_error("Invalid team in game data"); } if (!teamHandler->IsValidAllyTeam(teamHandler->AllyTeam(player->team))) { // TODO: seems not to make sense really throw content_error("Invalid ally team in game data"); } } gs->SetRandSeed(gameData->GetRandomSeed(), true); LogObject() << "Using map: " << gameSetup->mapName << "\n"; vfsHandler->AddArchiveWithDeps(gameSetup->mapName, false); archiveScanner->CheckArchive(gameSetup->mapName, gameData->GetMapChecksum()); LogObject() << "Using game: " << gameSetup->modName << "\n"; vfsHandler->AddArchiveWithDeps(gameSetup->modName, false); modArchive = archiveScanner->ArchiveFromName(gameSetup->modName); LogObject() << "Using game archive: " << modArchive << "\n"; archiveScanner->CheckArchive(modArchive, gameData->GetModChecksum()); if (net && net->GetDemoRecorder()) { net->GetDemoRecorder()->SetName(gameSetup->mapName, gameSetup->modName); LogObject() << "recording demo: " << net->GetDemoRecorder()->GetName() << "\n"; } }