/** * Main function, initializes and runs server. */ int main(int argc, char *argv[]) { // Parse command line options CommandLineOptions options; parseOptions(argc, argv, options); initializeConfiguration(options.configPath); // General initialization initializeServer(); #ifdef PACKAGE_VERSION LOG_INFO("The Mana Game Server v" << PACKAGE_VERSION); #else LOG_INFO("The Mana Game Server (unknown version)"); #endif LOG_INFO("Manaserv Protocol version " << ManaServ::PROTOCOL_VERSION << ", " << "Enet version " << ENET_VERSION_MAJOR << "." << ENET_VERSION_MINOR << "." << ENET_VERSION_PATCH); if (!options.verbosityChanged) options.verbosity = static_cast<Logger::Level>( Configuration::getValue("log_gameServerLogLevel", options.verbosity) ); Logger::setVerbosity(options.verbosity); // When the gameListenToClientPort is set, we use it. // Otherwise, we use the accountListenToClientPort + 3 if the option is set. // If neither, the DEFAULT_SERVER_PORT + 3 is used. if (!options.portChanged) { // Prepare the fallback value options.port = Configuration::getValue("net_accountListenToClientPort", 0) + 3; if (options.port == 3) options.port = DEFAULT_SERVER_PORT + 3; // Set the actual value of options.port options.port = Configuration::getValue("net_gameListenToClientPort", options.port); } // Make an initial attempt to connect to the account server // Try again after longer and longer intervals when connection fails. bool isConnected = false; int waittime = 0; while (!isConnected && running) { LOG_INFO("Connecting to account server"); isConnected = accountHandler->start(options.port); if (!isConnected) { LOG_INFO("Retrying in " << ++waittime << " seconds"); usleep(waittime * 1000); } } if (!gameHandler->startListen(options.port)) { LOG_FATAL("Unable to create an ENet server host."); return EXIT_NET_EXCEPTION; } // Initialize world timer worldTimer.start(); // Account connection lost flag bool accountServerLost = false; int elapsedWorldTicks = 0; while (running) { elapsedWorldTicks = worldTimer.poll(); if (elapsedWorldTicks == 0) worldTimer.sleep(); while (elapsedWorldTicks > 0) { if (elapsedWorldTicks > WORLD_TICK_SKIP) { LOG_WARN("Skipped "<< elapsedWorldTicks - 1 << " world tick due to insufficient CPU time."); elapsedWorldTicks = 1; } worldTime++; elapsedWorldTicks--; // Print world time at 10 second intervals to show we're alive if (worldTime % 100 == 0) { LOG_INFO("World time: " << worldTime); } if (accountHandler->isConnected()) { accountServerLost = false; // Handle all messages that are in the message queues accountHandler->process(); if (worldTime % 100 == 0) { accountHandler->syncChanges(true); // force sending changes to the account server every 10 secs. } if (worldTime % 300 == 0) { accountHandler->sendStatistics(); LOG_INFO("Total Account Output: " << gBandwidth->totalInterServerOut() << " Bytes"); LOG_INFO("Total Account Input: " << gBandwidth->totalInterServerIn() << " Bytes"); LOG_INFO("Total Client Output: " << gBandwidth->totalClientOut() << " Bytes"); LOG_INFO("Total Client Input: " << gBandwidth->totalClientIn() << " Bytes"); } } else { // If the connection to the account server is lost. // Every players have to be logged out if (!accountServerLost) { LOG_WARN("The connection to the account server was lost."); accountServerLost = true; } // Try to reconnect every 200 ticks if (worldTime % 200 == 0) { accountHandler->start(options.port); } } gameHandler->process(); // Update all active objects/beings GameState::update(worldTime); // Send potentially urgent outgoing messages gameHandler->flush(); } } LOG_INFO("Received: Quit signal, closing down..."); gameHandler->stopListen(); accountHandler->stop(); deinitializeServer(); return EXIT_NORMAL; }
/* Continuous model synthesis main function */ bool continuousModelSynthesis(vector<Edge*> &edges, vector<Vertex*> &vertices, CMSModel3D &input, Grid &grid) { Utils::Timer timer; cout << endl << "---Continuous Model Synthesis Progress---" << std::endl; unsigned int seed = (unsigned int)time(NULL); std::cout<< "Changing seed..." << seed << std::endl; srand(seed); if(firstrun) { for( std::vector<Vertex*>::iterator vertex_itr = vertices.begin(); vertex_itr != vertices.end(); vertex_itr++) { sortEdges(*vertex_itr); } //firstrun = false; } PotentialVertex *currentVertex; std::vector<PotentialVertex*> unassignedVertices; std::vector<PotentialVertex*>::iterator unassignedItr; PotentialVertexState selectedState; if(firstrun) { cout << "Generating states..." << endl; timer.start(); bruteForceGenerate(unassignedVertices, input, grid); timer.stop(); timer.printSeconds(); firstrun = false; } else { while(history.selectedVertexList.size() > 0) { vector<vector<PotentialVertexState>*>::iterator listitr; vector<PotentialVertexState>::iterator stateitr; listitr = history.constrainedVertexList.back().begin(); stateitr = history.removedStatesList.back().begin(); while( listitr != history.constrainedVertexList.back().end() && stateitr != history.removedStatesList.back().end() ) { (*listitr)->push_back(*stateitr); listitr++; stateitr++; } history.constrainedVertexList.pop_back(); history.removedStatesList.pop_back(); unassignedVertices.push_back(history.selectedVertexList.back()); unassignedVertices.back()->states.push_back(history.selectedState.back()); history.selectedVertexList.pop_back(); history.selectedState.pop_back(); } } cout << "Assigning states..." << endl; timer.start(); while(unassignedVertices.size() > 0) { //std::cout << "Assignments Remaining: " << unassignedVertices.size() << std::endl; sort(unassignedVertices.begin(), unassignedVertices.end(), sortVertex); if( (*unassignedVertices.begin())->states.size() == 0) { //unassignedVertices.erase(unassignedVertices.begin()); //continue; //backtrack //std::cout << "BACKTRACK: " << unassignedVertices.size() << std::endl; vector<vector<PotentialVertexState>*>::iterator listitr; vector<PotentialVertexState>::iterator stateitr; listitr = history.constrainedVertexList.back().begin(); stateitr = history.removedStatesList.back().begin(); while( listitr != history.constrainedVertexList.back().end() && stateitr != history.removedStatesList.back().end() ) { (*listitr)->push_back(*stateitr); listitr++; stateitr++; } history.constrainedVertexList.pop_back(); history.removedStatesList.pop_back(); if(history.constrainedVertexList.size() == 0 || history.removedStatesList.size() == 0) { std::cout << "!!!" << std::endl; break; } history.constrainedVertexList.back().push_back(&(history.selectedVertexList.back()->states)); history.removedStatesList.back().push_back(history.selectedState.back()); unassignedVertices.push_back(history.selectedVertexList.back()); history.selectedVertexList.pop_back(); history.selectedState.pop_back(); continue; } unassignedItr = unassignedVertices.begin(); currentVertex = *(unassignedItr); unassignedVertices.erase(unassignedItr); selectedState = currentVertex->getAndRemoveRandomState(); history.selectedVertexList.push_back(currentVertex); history.selectedState.push_back(selectedState); history.constrainedVertexList.push_back(vector<vector<PotentialVertexState>*>()); history.removedStatesList.push_back(vector<PotentialVertexState>()); for(int i = 0; i < NUM_VOLUMES; i++) { if(currentVertex->volumes[i] != NULL) { constrainVolume(currentVertex->volumes[i], selectedState.volumes[i], unassignedVertices, history); } } } for(std::vector<PotentialVertex*>::iterator itr = unassignedVertices.begin(); itr != unassignedVertices.end(); itr++) { delete (*itr); } timer.stop(); timer.printSeconds(); return true; }