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

112 lines
2.6 KiB
C++

#pragma once
#include <map>
#include <thread>
#include "td/network/TCPListener.h"
#include "td/protocol/Protocol.h"
#include "td/protocol/PacketDispatcher.h"
#include "td/protocol/PacketHandler.h"
#include "server/game/ServerGame.h"
#include "server/ServerConnexion.h"
#include "server/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;
float m_MSPT;
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 = static_cast<float>(SERVER_TPS) / static_cast<float>(timeElapsedSinceLast20Ticks / 1000.0f);
m_TickCount = 0;
m_LastTPSTime = td::utils::GetTime();
return true;
}
return false;
}
float GetTPS() const { return m_TPS; }
float GetMSPT() const { return m_MSPT; }
void SetMSPT(float mspt) { m_MSPT = mspt; }
};
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();
virtual ~Server();
bool Start(std::uint16_t port, bool blocking);
void Stop(); // force the server to stop
void Close(); // at the end of a game
void Restart(); // go back to lobby state
bool LoadMap(const std::string& worldFilePath);
bool IsMapLoaded();
void RemoveConnexion(std::uint8_t connexionID);
void BroadcastPacket(const protocol::Packet* packet);
float GetMSPT() const { return m_TickCounter.GetMSPT(); }
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 ServerLoop();
void Tick(std::uint64_t delta);
void OnPlayerJoin(std::uint8_t id);
void OnPlayerLeave(std::uint8_t id);
};
} // namespace server
} // namespace td