189 lines
6.6 KiB
C++
189 lines
6.6 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);
|
|
GetDispatcher()->RegisterHandler(protocol::PacketType::PlaceTower, this);
|
|
GetDispatcher()->RegisterHandler(protocol::PacketType::SendMobs, this);
|
|
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, 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::getRandomInt<std::uint64_t>(0, RAND_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(const 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(const 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) {
|
|
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);
|
|
}
|
|
m_Player->setTeamColor(packet->getSelectedTeam());
|
|
protocol::UpdatePlayerTeamPacket updateTeamPacket(m_ID, packet->getSelectedTeam());
|
|
m_Server->broadcastPacket(&updateTeamPacket);
|
|
}
|
|
}
|
|
|
|
void ServerConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
|
|
if (packet->getAliveID() == m_KeepAlive.keepAliveID)
|
|
m_KeepAlive.recievedResponse = true;
|
|
}
|
|
|
|
void ServerConnexion::HandlePacket(const 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);
|
|
}
|
|
}
|
|
|
|
void ServerConnexion::HandlePacket(const protocol::PlaceTowerPacket* packet) {
|
|
game::TowerType towerType = packet->getTowerType();
|
|
const game::TowerInfo& towerInfo = game::getTowerInfo(towerType);
|
|
server::ServerWorld* world = m_Server->getGame().getServerWorld();
|
|
|
|
if (!world->CanPlaceLittleTower({ packet->getTowerX(), packet->getTowerY() }, m_ID))
|
|
return;
|
|
|
|
if (towerInfo.isBigTower())
|
|
if (!world->CanPlaceBigTower({ packet->getTowerX(), packet->getTowerY() }, m_ID))
|
|
return;
|
|
|
|
game::TowerPtr tower = world->placeTowerAt(towerType, packet->getTowerX(), packet->getTowerY(), m_ID);
|
|
|
|
protocol::WorldAddTowerPacket addTowerPacket(tower->getID(), packet->getTowerX(), packet->getTowerY(), packet->getTowerType(), m_ID);
|
|
m_Server->broadcastPacket(&addTowerPacket);
|
|
}
|
|
|
|
void ServerConnexion::HandlePacket(const protocol::SendMobsPacket* packet) {
|
|
const std::vector<protocol::MobSend>& mobSent = packet->getMobSends();
|
|
|
|
//TODO: verify the packet
|
|
|
|
for(protocol::MobSend mobSend : mobSent){
|
|
m_Server->getGame().getServerWorld()->spawnMobs(mobSend.mobType, mobSend.mobLevel, m_ID, mobSend.mobCount);
|
|
}
|
|
}
|
|
|
|
void ServerConnexion::HandlePacket(const protocol::UpgradeTowerPacket* packet){
|
|
//TODO: verify the packet
|
|
|
|
m_Server->broadcastPacket(packet);
|
|
}
|
|
|
|
ServerConnexion::~ServerConnexion() {
|
|
if (GetDispatcher() != nullptr)
|
|
GetDispatcher()->UnregisterHandler(this);
|
|
}
|
|
|
|
} // namespace server
|
|
} // namespace td
|