Files
Tower-Defense/src/game/server/ServerConnexion.cpp
2021-08-21 10:14:47 +02:00

154 lines
5.0 KiB
C++

#include "game/server/ServerConnexion.h"
#include "protocol/PacketDispatcher.h"
#include "protocol/PacketFactory.h"
#include "game/server/Server.h"
#include "misc/Time.h"
#include "misc/Random.h"
#include <chrono>
#define KEEP_ALIVE_TIMEOUT 10 * 1000 // 10s
namespace td{
namespace server{
/*
NEVER TRUST USER INPUT
*/
ServerConnexion::ServerConnexion(): m_Player(0){
}
ServerConnexion::ServerConnexion(network::TCPSocket& socket, std::uint8_t id) : Connexion::Connexion(&m_Dispatcher, socket), m_ID(id), m_Player(0){
Connexion::updateSocket();
}
ServerConnexion::ServerConnexion(ServerConnexion&& move) : Connexion::Connexion(std::move(move)), m_Server(move.m_Server),
m_ID(move.m_ID), m_KeepAlive(move.m_KeepAlive), m_Player(move.m_Player){
move.m_Server = nullptr;
registerHandlers();
}
void ServerConnexion::registerHandlers(){
GetDispatcher()->RegisterHandler(protocol::PacketType::PlayerLogin, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::KeepAlive, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::SelectTeam, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::Disconnect, this);
}
bool ServerConnexion::updateSocket(){
checkKeepAlive();
return Connexion::updateSocket();
}
void ServerConnexion::checkKeepAlive(){
std::uint64_t time = utils::getTime();
if (time - m_KeepAlive.sendTime > KEEP_ALIVE_TIMEOUT){
if (m_KeepAlive.recievedResponse){
sendKeepAlive();
}
else{
protocol::DisconnectPacket packet("Time out");
sendPacket(&packet);
closeConnection();
}
}
}
void ServerConnexion::sendKeepAlive(){
m_KeepAlive.keepAliveID = utils::getRandomNumber(UINT64_MAX);
m_KeepAlive.recievedResponse = false;
protocol::KeepAlivePacket keepAlivePacket(m_KeepAlive.keepAliveID);
sendPacket(&keepAlivePacket);
std::uint64_t time = utils::getTime();
m_KeepAlive.sendTime = time;
}
void ServerConnexion::HandlePacket(protocol::PlayerLoginPacket* packet){
if (m_Player->getName().empty() && !packet->getPlayerName().empty()){
m_Player->setName(packet->getPlayerName());
protocol::PlayerJoinPacket joinPacket(m_ID, m_Player->getName());
m_Server->broadcastPacket(&joinPacket);
std::map<std::uint8_t, protocol::PlayerInfo> playerNames;
for (const auto& pair : m_Server->getPlayers()){
const game::Player& player = pair.second;
if (!player.getName().empty()){
protocol::PlayerInfo playerInfo;
playerInfo.name = player.getName();
playerInfo.team = player.getTeamColor();
playerNames.insert({player.getID(), playerInfo});
}
}
protocol::PlayerListPacket listPacket(playerNames);
sendPacket(&listPacket);
}
}
void ServerConnexion::HandlePacket(protocol::SelectTeamPacket* packet){
if(m_Server->getGame().getGameState() != game::GameState::Lobby)
return;
if((std::int8_t) packet->getSelectedTeam() >= -1 || (std::int8_t) packet->getSelectedTeam() <= 1){
//m_Player->setTeamColor(packet->getSelectedTeam());
if(m_Player->getTeamColor() == game::TeamColor::None){ //join a team
m_Server->getGame().getTeam(packet->getSelectedTeam()).addPlayer(m_Player);
}else if(packet->getSelectedTeam() == game::TeamColor::None){ // leave a team
m_Server->getGame().getTeam(m_Player->getTeamColor()).removePlayer(m_Player);
m_Player->setTeamColor(game::TeamColor::None);
}else{ // change team
m_Server->getGame().getTeam(m_Player->getTeamColor()).removePlayer(m_Player);
m_Server->getGame().getTeam(packet->getSelectedTeam()).addPlayer(m_Player);
}
protocol::UpdatePlayerTeamPacket updateTeamPacket(m_ID, packet->getSelectedTeam());
m_Server->broadcastPacket(&updateTeamPacket);
}
}
void ServerConnexion::HandlePacket(protocol::KeepAlivePacket* packet){
if(packet->getAliveID() == m_KeepAlive.keepAliveID)
m_KeepAlive.recievedResponse = true;
}
void ServerConnexion::HandlePacket(protocol::DisconnectPacket* packet){
closeConnection();
}
void ServerConnexion::setServer(Server* server){
m_Server = server;
m_Player = &m_Server->getPlayers().at(m_ID);
initConnection();
sendKeepAlive();
}
void ServerConnexion::initConnection(){
protocol::UpdateGameStatePacket statePacket(m_Server->getGame().getGameState());
sendPacket(&statePacket);
protocol::ConnexionInfoPacket conPacket(m_ID);
sendPacket(&conPacket);
if (m_Server->getGame().getGameState() == game::GameState::Game){
protocol::WorldBeginDataPacket headerDataPacket(m_Server->getGame().getWorld());
protocol::WorldBeginDataPacket dataPacket(m_Server->getGame().getWorld());
sendPacket(&headerDataPacket);
sendPacket(&dataPacket);
}
}
ServerConnexion::~ServerConnexion(){
if (GetDispatcher() != nullptr)
GetDispatcher()->UnregisterHandler(this);
}
} // namespace server
} // namespace td