148 lines
3.9 KiB
C++
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()
|
|
{
|
|
timer->stop();
|
|
delete timer;
|
|
for(ServerClient *c : clients)
|
|
delete c;
|
|
if(server->isListening())
|
|
server->close();
|
|
server->deleteLater();
|
|
}
|
|
|
|
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();
|
|
}
|