server console input

This commit is contained in:
2023-08-13 13:44:05 +02:00
parent ddbba997e5
commit d529c79150
4 changed files with 104 additions and 28 deletions

View File

@@ -63,13 +63,16 @@ private:
std::thread m_Thread; std::thread m_Thread;
bool m_ServerRunning; bool m_ServerRunning;
public: public:
Server(const std::string& worldFilePath); Server();
virtual ~Server(); virtual ~Server();
bool Start(std::uint16_t port); bool Start(std::uint16_t port, bool blocking);
void Stop(); // force the server to stop void Stop(); // force the server to stop
void Close(); // at the end of a game void Close(); // at the end of a game
bool LoadMap(const std::string& worldFilePath);
bool IsMapLoaded();
void RemoveConnexion(std::uint8_t connexionID); void RemoveConnexion(std::uint8_t connexionID);
void BroadcastPacket(const protocol::Packet* packet); void BroadcastPacket(const protocol::Packet* packet);
@@ -95,6 +98,7 @@ private:
void Clean(); void Clean();
void StartThread(); void StartThread();
void StopThread(); void StopThread();
void ServerLoop();
void Tick(std::uint64_t delta); void Tick(std::uint64_t delta);
void OnPlayerJoin(std::uint8_t id); void OnPlayerJoin(std::uint8_t id);

View File

@@ -37,11 +37,55 @@ static void DisplayHelp() {
} }
} }
static bool StartServer(const std::string& mapPath, std::uint16_t port) { class ConsoleThread {
td::server::Server server {mapPath}; private:
return !server.Start(port); td::server::Server& m_Server;
std::thread m_Thread;
bool m_Running = true;
public:
ConsoleThread(td::server::Server& server) : m_Server(server) {}
void Start() {
m_Thread = std::thread([this](){
std::string line;
while (m_Running) {
getline(std::cin, line);
if (line == "stop") {
m_Server.Stop();
} else if (line == "help") {
LOG("use \"stop\" to stop the server");
}
}
});
}
void Stop() {
m_Running = false;
m_Thread.join();
}
~ConsoleThread() {}
};
static void StartServer(const std::string& mapPath, std::uint16_t port) {
td::server::Server server;
if (!server.LoadMap(mapPath)) {
exit(EXIT_FAILURE);
}
ConsoleThread consoleThread{ server };
consoleThread.Start();
if (!server.Start(port, true)) {
exit(EXIT_FAILURE);
}
LOG("Press Enter to coninue ...");
consoleThread.Stop();
} }
#ifdef __ANDROID__ #ifdef __ANDROID__
extern "C" extern "C"
#endif #endif
@@ -89,5 +133,7 @@ int main(int argc, const char* args[]) {
mapFilePath = arg; mapFilePath = arg;
} }
return StartServer(mapFilePath, port); StartServer(mapFilePath, port);
return EXIT_SUCCESS;
} }

View File

@@ -80,8 +80,9 @@ void MainMenu::Render() {
bool MainMenu::StartServer() { bool MainMenu::StartServer() {
if (m_WorldFilePath.empty()) if (m_WorldFilePath.empty())
return false; return false;
m_Server = std::make_unique<td::server::Server>(m_WorldFilePath); m_Server = std::make_unique<td::server::Server>();
if (!m_Server->Start(m_ServerPort)) { m_Server->LoadMap(m_WorldFilePath);
if (!m_Server->Start(m_ServerPort, false)) {
return false; return false;
} }
return true; return true;

View File

@@ -10,8 +10,8 @@
namespace td { namespace td {
namespace server { namespace server {
Server::Server(const std::string& worldFilePath) : m_ServerRunning(false) { Server::Server() : m_ServerRunning(false) {
m_Game.GetWorld()->LoadMapFromFile(worldFilePath);
} }
Server::~Server() { Server::~Server() {
@@ -19,24 +19,36 @@ Server::~Server() {
m_Thread.join(); m_Thread.join();
} }
bool Server::LoadMap(const std::string& worldFilePath) {
return m_Game.GetWorld()->LoadMapFromFile(worldFilePath);
}
bool Server::IsMapLoaded() {
return !m_Game.GetWorld()->GetTilePalette().empty();
}
void Server::ServerLoop() {
std::uint64_t lastTime = td::utils::GetTime();
while (m_ServerRunning) {
std::uint64_t time = td::utils::GetTime();
std::uint64_t delta = time - lastTime;
if (delta >= SERVER_TICK) {
Tick(delta);
lastTime = td::utils::GetTime();
m_TickCounter.SetMSPT(lastTime - time);
std::uint64_t sleepTime = SERVER_TICK - (delta - SERVER_TICK);
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
}
}
Clean();
}
void Server::StartThread() { void Server::StartThread() {
m_Thread = std::thread([this]() { m_Thread = std::thread([this]() {
std::uint64_t lastTime = td::utils::GetTime(); ServerLoop();
while (m_ServerRunning) {
std::uint64_t time = td::utils::GetTime();
std::uint64_t delta = time - lastTime;
if (delta >= SERVER_TICK) {
Tick(delta);
lastTime = td::utils::GetTime();
m_TickCounter.SetMSPT(lastTime - time);
std::uint64_t sleepTime = SERVER_TICK - (delta - SERVER_TICK);
std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
}
}
Clean();
}); });
} }
@@ -48,7 +60,11 @@ void Server::StopThread() {
m_ServerRunning = false; m_ServerRunning = false;
} }
bool Server::Start(std::uint16_t port) { bool Server::Start(std::uint16_t port, bool blocking) {
if (!IsMapLoaded()) {
utils::LOGE(utils::format("No map loaded !"));
return false;
}
if (!m_Listener.Listen(port, 10)) { if (!m_Listener.Listen(port, 10)) {
utils::LOGE(utils::format("Failed to bind port %u !", port)); utils::LOGE(utils::format("Failed to bind port %u !", port));
return false; return false;
@@ -60,7 +76,11 @@ bool Server::Start(std::uint16_t port) {
utils::LOG(utils::format("Server started at port %u !", port)); utils::LOG(utils::format("Server started at port %u !", port));
m_TickCounter.Reset(); m_TickCounter.Reset();
m_ServerRunning = true; m_ServerRunning = true;
StartThread(); if (blocking) {
ServerLoop();
} else {
StartThread();
}
return true; return true;
} }
@@ -145,6 +165,11 @@ void Server::OnPlayerJoin(std::uint8_t id) {
void Server::OnPlayerLeave(std::uint8_t id) { void Server::OnPlayerLeave(std::uint8_t id) {
protocol::PlayerLeavePacket packet(id); protocol::PlayerLeavePacket packet(id);
BroadcastPacket(&packet); BroadcastPacket(&packet);
if (GetPlayers().empty()) {
utils::LOG("All players left. Stopping server ...");
Stop();
}
} }
} // namespace server } // namespace server