Files
Tower-Defense/include/game/server/Server.h

102 lines
2.5 KiB
C++

#pragma once
#include <cstdint>
#include <map>
#include <thread>
#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<std::uint8_t, ServerConnexion> 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