| 86 | } |
| 87 | |
| 88 | bool ODServer::startServer(const std::string& creator, const std::string& levelFilename, ServerMode mode, bool useMasterServer) |
| 89 | { |
| 90 | OD_LOG_INF("Asked to launch server with levelFilename=" + levelFilename); |
| 91 | |
| 92 | mSeatsConfigured = false; |
| 93 | mDisconnectedPlayers.clear(); |
| 94 | mMasterServerGameId.clear(); |
| 95 | mMasterServerGameStatusUpdateTime = 0.0; |
| 96 | mPlayerConfig = nullptr; |
| 97 | |
| 98 | // Start the server socket listener as well as the server socket thread |
| 99 | if (isConnected()) |
| 100 | { |
| 101 | OD_LOG_INF("Couldn't start server: The server is already connected"); |
| 102 | return false; |
| 103 | } |
| 104 | if ((ODClient::getSingletonPtr() != nullptr) && |
| 105 | ODClient::getSingleton().isConnected()) |
| 106 | { |
| 107 | OD_LOG_INF("Couldn't start server: The client is already connected"); |
| 108 | return false; |
| 109 | } |
| 110 | |
| 111 | // Read in the map. The map loading should be happen here and not in the server thread to |
| 112 | // make sure it is valid before launching the server. |
| 113 | mServerMode = mode; |
| 114 | mServerState = ServerState::StateConfiguration; |
| 115 | mUniqueNumberPlayer = 0; |
| 116 | GameMap* gameMap = mGameMap; |
| 117 | if (!gameMap->loadLevel(levelFilename)) |
| 118 | { |
| 119 | mServerMode = ServerMode::ModeNone; |
| 120 | mServerState = ServerState::StateNone; |
| 121 | OD_LOG_INF("Couldn't start server. The level file can't be loaded: " + levelFilename); |
| 122 | stopServer(); |
| 123 | return false; |
| 124 | } |
| 125 | |
| 126 | // Set up the socket to listen on the specified port |
| 127 | int32_t port = getNetworkPort(); |
| 128 | if (!createServer(port)) |
| 129 | { |
| 130 | mServerMode = ServerMode::ModeNone; |
| 131 | mServerState = ServerState::StateNone; |
| 132 | OD_LOG_ERR("Server could not create server socket!"); |
| 133 | stopServer(); |
| 134 | return false; |
| 135 | } |
| 136 | |
| 137 | // We configure what is fixed (fixed AI, faction or team). While iterating seats, we keep in mind if there is |
| 138 | // at least a human only seat. If yes, we configure all player type choosable to AI. If not, we configure all player |
| 139 | // type choosable to AI except the first one. |
| 140 | uint32_t nbSeatsHuman = 0; |
| 141 | const std::vector<std::string>& factions = ConfigManager::getSingleton().getFactions(); |
| 142 | for(Seat* seat : gameMap->getSeats()) |
| 143 | { |
| 144 | if(seat->isRogueSeat()) |
| 145 | continue; |
no test coverage detected