commit 497a601c424e8e728ef0a8e61f049982f2d4af16 Author: Persson-dev <sim16.prib@gmail.com> Date: Sat Aug 12 10:32:52 2023 +0200 fix warning commit 1bfd019a1ea00dcdb6323d1f285e2cdd3ebb4020 Author: Persson-dev <sim16.prib@gmail.com> Date: Tue Jul 25 19:05:13 2023 +0200 refactor: update cast commit 5bbc23a7d37e53eb74a885685f18e714f9448fd9 Author: Persson-dev <sim16.prib@gmail.com> Date: Tue Jul 25 19:04:15 2023 +0200 moved GetImguiTeamColor commit fd0e2d2470ea5cca3553acf280aa371de5c06f4c Author: Persson-dev <sim16.prib@gmail.com> Date: Tue Jul 25 19:03:37 2023 +0200 packets forward declaration commit 06eb9b99a96731f4b9a2167c00ed0bcd03702e3b Author: Persson-dev <sim16.prib@gmail.com> Date: Tue Jul 25 18:30:55 2023 +0200 remove Protocol.h includes commit 165f63d2e8b468f3e38992baddc221270010f801 Author: Persson-dev <sim16.prib@gmail.com> Date: Tue Jul 25 18:30:30 2023 +0200 split packets into separate source files commit f247f146c6c1e804a44b86f65cf3059859c07c6c Author: Persson-dev <sim16.prib@gmail.com> Date: Tue Jul 25 17:45:24 2023 +0200 split packets into separate headers
152 lines
3.5 KiB
C++
152 lines
3.5 KiB
C++
#include "game/server/Server.h"
|
|
#include "protocol/PacketFactory.h"
|
|
|
|
#include "protocol/packets/DisconnectPacket.h"
|
|
#include "protocol/packets/ServerTpsPacket.h"
|
|
#include "protocol/packets/PlayerLeavePacket.h"
|
|
|
|
#include "misc/Format.h"
|
|
|
|
namespace td {
|
|
namespace server {
|
|
|
|
Server::Server(const std::string& worldFilePath) : m_ServerRunning(false) {
|
|
m_Game.GetWorld()->LoadMapFromFile(worldFilePath);
|
|
}
|
|
|
|
Server::~Server() {
|
|
if (m_Thread.joinable())
|
|
m_Thread.join();
|
|
}
|
|
|
|
void Server::StartThread() {
|
|
m_Thread = std::thread([this]() {
|
|
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::Close() {
|
|
StopThread();
|
|
}
|
|
|
|
void Server::StopThread() {
|
|
m_ServerRunning = false;
|
|
}
|
|
|
|
bool Server::Start(std::uint16_t port) {
|
|
if (!m_Listener.Listen(port, 10)) {
|
|
utils::LOGE(utils::format("Failed to bind port %u !", port));
|
|
return false;
|
|
}
|
|
if (!m_Listener.SetBlocking(false)) {
|
|
utils::LOGE("Failed to block server socket !");
|
|
return false;
|
|
}
|
|
utils::LOG(utils::format("Server started at port %u !", port));
|
|
m_TickCounter.Reset();
|
|
m_ServerRunning = true;
|
|
StartThread();
|
|
return true;
|
|
}
|
|
|
|
void Server::Clean() {
|
|
m_Listener.Close();
|
|
m_Listener.Destroy();
|
|
|
|
m_Connections.clear();
|
|
GetPlayers().clear();
|
|
|
|
utils::LOG("Server successfully stopped !");
|
|
}
|
|
|
|
void Server::Stop() {
|
|
if (!m_ServerRunning)
|
|
return;
|
|
|
|
protocol::DisconnectPacket packet("Server closed");
|
|
BroadcastPacket(&packet);
|
|
|
|
StopThread();
|
|
}
|
|
|
|
void Server::Tick(std::uint64_t delta) {
|
|
Accept();
|
|
UpdateSockets();
|
|
m_Lobby.Tick();
|
|
m_Game.Tick(delta);
|
|
if (m_TickCounter.Update()) {
|
|
protocol::ServerTpsPacket packet(m_TickCounter.GetTPS(), m_TickCounter.GetMSPT(), utils::GetTime());
|
|
BroadcastPacket(&packet);
|
|
}
|
|
}
|
|
|
|
void Server::Accept() {
|
|
static std::uint8_t newPlayerID = 0;
|
|
network::TCPSocket newSocket;
|
|
if (m_Listener.Accept(newSocket)) {
|
|
ServerConnexion con(newSocket, newPlayerID);
|
|
m_Connections.insert(std::move(ConnexionMap::value_type{ newPlayerID, std::move(con) }));
|
|
OnPlayerJoin(newPlayerID);
|
|
m_Connections[newPlayerID].SetServer(this);
|
|
newPlayerID++;
|
|
}
|
|
}
|
|
|
|
void Server::UpdateSockets() {
|
|
std::int16_t closedConnexionID = -1;
|
|
for (auto& connection : m_Connections) {
|
|
ServerConnexion& con = connection.second;
|
|
if (con.GetSocketStatus() != network::Socket::Status::Connected) {
|
|
closedConnexionID = connection.first;
|
|
} else {
|
|
con.UpdateSocket();
|
|
}
|
|
}
|
|
if (closedConnexionID != -1) {
|
|
RemoveConnexion(closedConnexionID);
|
|
}
|
|
}
|
|
|
|
void Server::BroadcastPacket(const protocol::Packet* packet) {
|
|
for (auto& connection : m_Connections) {
|
|
ServerConnexion& con = connection.second;
|
|
con.SendPacket(packet);
|
|
}
|
|
}
|
|
|
|
void Server::RemoveConnexion(std::uint8_t connexionID) {
|
|
GetPlayers().erase(GetPlayers().find(connexionID));
|
|
m_Connections.erase(connexionID);
|
|
m_Lobby.OnPlayerLeave(connexionID);
|
|
OnPlayerLeave(connexionID);
|
|
}
|
|
|
|
void Server::OnPlayerJoin(std::uint8_t id) {
|
|
m_Lobby.OnPlayerJoin(id);
|
|
|
|
GetPlayers().insert({ id, game::Player{id} });
|
|
}
|
|
|
|
void Server::OnPlayerLeave(std::uint8_t id) {
|
|
protocol::PlayerLeavePacket packet(id);
|
|
BroadcastPacket(&packet);
|
|
}
|
|
|
|
} // namespace server
|
|
} // namespace td
|