#pragma once #include #include #include #include "network/TCPListener.h" #include "protocol/Protocol.h" #include "protocol/PacketDispatcher.h" #include "protocol/PacketHandler.h" #include "ServerGame.h" #include "ServerConnexion.h" #include "Lobby.h" #define SERVER_TPS 20 #define SERVER_TICK 1000 / SERVER_TPS namespace td { namespace server { typedef std::map ConnexionMap; class TickCounter { private: float m_TPS; std::uint64_t m_LastTPSTime; std::uint8_t m_TickCount; public: TickCounter() {} void reset() { m_TPS = SERVER_TPS; m_LastTPSTime = utils::getTime(); m_TickCount = 0; } bool update() { // return true when tps is updated m_TickCount++; if (m_TickCount >= SERVER_TPS) { std::uint64_t timeElapsedSinceLast20Ticks = td::utils::getTime() - m_LastTPSTime; m_TPS = (float)SERVER_TPS / (float)(timeElapsedSinceLast20Ticks / 1000.0f); m_TickCount = 0; m_LastTPSTime = td::utils::getTime(); return true; } return false; } float getTPS() const { return m_TPS; } }; class Server { private: network::TCPListener m_Listener; ConnexionMap m_Connections; ServerGame m_Game{ this }; Lobby m_Lobby{ this }; TickCounter m_TickCounter; std::thread m_Thread; bool m_ServerRunning; public: Server(const std::string& worldFilePath); virtual ~Server(); bool start(std::uint16_t port); void stop(); // force the server to stop void close(); // at the end of a game void removeConnexion(std::uint8_t connexionID); void broadcastPacket(const protocol::Packet* packet); float getTPS() const { return m_TickCounter.getTPS(); } bool isRunning() { return m_ServerRunning; } const ServerGame& getGame() const { return m_Game; } ServerGame& getGame() { return m_Game; } const Lobby& getLobby() const { return m_Lobby; } const ConnexionMap& getConnexions() const { return m_Connections; } ConnexionMap& getConnexions() { return m_Connections; } const game::PlayerList& getPlayers() const { return m_Game.getPlayers(); } game::PlayerList& getPlayers() { return m_Game.getPlayers(); } private: void accept(); void updateSockets(); void clean(); void startThread(); void stopThread(); void tick(std::uint64_t delta); void OnPlayerJoin(std::uint8_t id); void OnPlayerLeave(std::uint8_t id); }; } // namespace server } // namespace td