154 lines
5.0 KiB
C++
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
|