SparrowBot/app/server.cpp
2015-09-21 20:01:02 +02:00

148 lines
3.9 KiB
C++

#include "server.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QTimer>
Server::Server(unsigned short port, QObject *parent) : QObject(parent)
{
worldData = simulation.getWorldData();
server = new QTcpServer();
timer = new QTimer();
connect(server, SIGNAL(newConnection()), this, SLOT(on_newConnection()));
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
if(server->listen(QHostAddress::Any, port))
{
emit outMessage(QString("Listening on port %1").arg(port));
timer->start(25);
}
else
emit errMessage(QString("Can't listen on port %1 : %2").arg(port).arg(server->errorString()));
}
void Server::update()
{
// check if some clients are disconnected or invalid
for(unsigned int i=0; i<clients.size(); ++i)
{
if(!clients[i]->isOk())
{
delete clients[i];
clients[i--] = clients.back();
clients.pop_back();
simulation.removeClient(i);
}
}
// update the simulation
simulation.update();
// send wold data to clients
for(unsigned int i=0; i<clients.size(); ++i)
clients[i]->sendFull(*worldData, i);
}
Server::~Server()
{
if(server->isListening())
server->close();
server->deleteLater();
timer->stop();
delete timer;
for(ServerClient *c : clients)
delete c;
}
void Server::on_newConnection()
{
QTcpSocket* socket = server->nextPendingConnection();
ServerClient* client = new ServerClient(clients.size(), socket);
if(client->isOk())
{
simulation.addClient();
clients.push_back(client);
connect(client, SIGNAL(receivedDelta(int,DeltaClientPacket*)), this, SLOT(onClientDelta(int,DeltaClientPacket*)));
connect(client, SIGNAL(outMessage(QString)), this, SIGNAL(outMessage(QString)));
connect(client, SIGNAL(errMessage(QString)), this, SIGNAL(errMessage(QString)));
}
else
delete client;
}
void Server::onClientDelta(int id, DeltaClientPacket* delta)
{
simulation.clientInput(id, *delta);
}
ServerClient::ServerClient(int id, QTcpSocket* mySocket) :
ok(false),
myId(id),
socket(mySocket)
{
if(socket->state() == QTcpSocket::ConnectedState)
{
ok = true;
emit outMessage(QString("New player connected : %1").arg(socket->peerAddress().toString()));
}
connect(socket, SIGNAL(disconnected()), this, SLOT(on_disconnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
}
ServerClient::~ServerClient()
{
if(socket != NULL)
{
if(socket->isOpen())
socket->close();
socket->deleteLater();
}
}
void ServerClient::on_readyRead()
{
while(socket->bytesAvailable())
{
int type;
socket->read((char*)&type, sizeof(int));
switch(type)
{
case DELTA_CLIENT:
{
DeltaClientPacket* delta = new DeltaClientPacket();
socket->read((char*)delta, sizeof(DeltaClientPacket));
emit receivedDelta(myId, delta);
}
break;
default:
emit errMessage(QString("Incorrect packet received"));
socket->close();
break;
}
}
}
void ServerClient::on_disconnected()
{
emit outMessage(QString("Player disconnected"));
disconnect(socket, SIGNAL(disconnected()));
disconnect(socket, SIGNAL(readyRead()));
ok = false;
}
void ServerClient::sendDelta()
{
// TODO
}
void ServerClient::sendFull(const std::vector<InitClientPacket> &worldData, int id)
{
myId = id;
InitServerPacket packet;
packet.idClient = id;
packet.nbClients = worldData.size();
int type = INIT_SERVER;
socket->write((char*)&type, sizeof(int));
socket->write((char*)&packet, sizeof(InitServerPacket));
for(const InitClientPacket &info : worldData)
socket->write((const char*)&info, sizeof(InitClientPacket));
socket->flush();
}