From 7cd9805539147441ffe3a4699914d42a0bb313ab Mon Sep 17 00:00:00 2001 From: Anselme Date: Mon, 21 Sep 2015 20:01:02 +0200 Subject: [PATCH] updated server --- app/app.pro | 6 ++-- app/server.cpp | 88 ++++++++++++++++++---------------------------- app/server.h | 20 ++++++----- app/simulation.cpp | 68 +++++++++++++++++++++++++++++++++++ app/simulation.h | 20 +++++++++++ 5 files changed, 139 insertions(+), 63 deletions(-) create mode 100644 app/simulation.cpp create mode 100644 app/simulation.h diff --git a/app/app.pro b/app/app.pro index 140e5d5..1c853fe 100644 --- a/app/app.pro +++ b/app/app.pro @@ -18,7 +18,8 @@ SOURCES = main.cpp \ riddles.cpp \ todomodule.cpp \ server.cpp \ - servermodule.cpp + servermodule.cpp \ + simulation.cpp HEADERS += \ regismodule.h \ @@ -30,4 +31,5 @@ HEADERS += \ todomodule.h \ packet.h \ server.h \ - servermodule.h + servermodule.h \ + simulation.h diff --git a/app/server.cpp b/app/server.cpp index de51f83..2814cb9 100644 --- a/app/server.cpp +++ b/app/server.cpp @@ -1,20 +1,14 @@ #include "server.h" -#include -#include #include #include #include -#define PI 3.1416 -#define MAX_ANGULAR_SPEED 1 -#define MAX_SPEED 3 - Server::Server(unsigned short port, QObject *parent) : QObject(parent) { + worldData = simulation.getWorldData(); server = new QTcpServer(); timer = new QTimer(); - timer->setSingleShot(false); - std::srand(std::time(NULL)); + connect(server, SIGNAL(newConnection()), this, SLOT(on_newConnection())); connect(timer, SIGNAL(timeout()), this, SLOT(update())); if(server->listen(QHostAddress::Any, port)) @@ -28,20 +22,22 @@ Server::Server(unsigned short port, QObject *parent) : QObject(parent) void Server::update() { + // check if some clients are disconnected or invalid for(unsigned int i=0; iisOk()) - clients[i]->update(); - else + 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; isendFull(clients, i); + clients[i]->sendFull(*worldData, i); } Server::~Server() @@ -51,17 +47,19 @@ Server::~Server() server->deleteLater(); timer->stop(); delete timer; - for(int i=0; inextPendingConnection(); - Client* client = new Client(socket); + 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))); } @@ -69,25 +67,26 @@ void Server::on_newConnection() delete client; } -Client::Client(QTcpSocket* mySocket) +void Server::onClientDelta(int id, DeltaClientPacket* delta) +{ + simulation.clientInput(id, *delta); +} + +ServerClient::ServerClient(int id, QTcpSocket* mySocket) : + ok(false), + myId(id), + socket(mySocket) { - socket = mySocket; - ok = false; if(socket->state() == QTcpSocket::ConnectedState) { ok = true; emit outMessage(QString("New player connected : %1").arg(socket->peerAddress().toString())); } - info.x = std::rand()%50; - info.y = std::rand()%50; - info.angle = ((float)(std::rand()%360)) / PI; - info.vforward = 0; - info.vangle = 0; connect(socket, SIGNAL(disconnected()), this, SLOT(on_disconnected())); connect(socket, SIGNAL(readyRead()), this, SLOT(on_readyRead())); } -Client::~Client() +ServerClient::~ServerClient() { if(socket != NULL) { @@ -97,7 +96,7 @@ Client::~Client() } } -void Client::on_readyRead() +void ServerClient::on_readyRead() { while(socket->bytesAvailable()) { @@ -107,20 +106,9 @@ void Client::on_readyRead() { case DELTA_CLIENT: { - DeltaClientPacket delta; - socket->read((char*)&delta, sizeof(DeltaClientPacket)); - info.vangle += delta.dvangle; - info.vforward += delta.dvforward; - if(info.vforward>3) - info.vforward = MAX_SPEED; - if(info.vforward<0) - info.vforward = 0; - float speed = info.vforward; - float maxAngularSpeed = speed <= 1 ? speed*MAX_ANGULAR_SPEED : MAX_ANGULAR_SPEED/speed; - if(info.vangle > maxAngularSpeed) - info.vangle = maxAngularSpeed; - if(info.vangle < -maxAngularSpeed) - info.vangle = -maxAngularSpeed; + DeltaClientPacket* delta = new DeltaClientPacket(); + socket->read((char*)delta, sizeof(DeltaClientPacket)); + emit receivedDelta(myId, delta); } break; default: @@ -131,7 +119,7 @@ void Client::on_readyRead() } } -void Client::on_disconnected() +void ServerClient::on_disconnected() { emit outMessage(QString("Player disconnected")); disconnect(socket, SIGNAL(disconnected())); @@ -139,27 +127,21 @@ void Client::on_disconnected() ok = false; } -void Client::update() -{ - info.angle += info.vangle; - info.x += std::cos(info.angle)*info.vforward; - info.y += std::sin(info.angle)*info.vforward; -} - -void Client::sendDelta() +void ServerClient::sendDelta() { // TODO } -void Client::sendFull(const std::vector &clients, int id) +void ServerClient::sendFull(const std::vector &worldData, int id) { + myId = id; InitServerPacket packet; packet.idClient = id; - packet.nbClients = clients.size(); + packet.nbClients = worldData.size(); int type = INIT_SERVER; socket->write((char*)&type, sizeof(int)); socket->write((char*)&packet, sizeof(InitServerPacket)); - for(unsigned int i=0; iwrite((char*)&(clients[i]->info), sizeof(InitClientPacket)); + for(const InitClientPacket &info : worldData) + socket->write((const char*)&info, sizeof(InitClientPacket)); socket->flush(); } diff --git a/app/server.h b/app/server.h index de249fa..4afc796 100644 --- a/app/server.h +++ b/app/server.h @@ -4,11 +4,12 @@ #include #include #include "packet.h" +#include "simulation.h" class QTimer; class QTcpServer; class QTcpSocket; -class Client; +class ServerClient; class Server : public QObject { @@ -18,7 +19,9 @@ public: ~Server(); QTcpServer* server; QTimer* timer; - std::vector clients; + Simulation simulation; + std::vector* worldData; + std::vector clients; int currentClient; signals: @@ -28,30 +31,31 @@ signals: public slots: void update(); void on_newConnection(); + void onClientDelta(int, DeltaClientPacket*); }; -class Client : public QObject +class ServerClient : public QObject { Q_OBJECT public: - Client(QTcpSocket* mySocket); - ~Client(); + ServerClient(int id, QTcpSocket* mySocket); + ~ServerClient(); bool isOk() {return ok;} - void update(); void sendDelta(); - void sendFull(const std::vector &clients, int id); + void sendFull(const std::vector &clients, int id); private: bool ok; + int myId; QTcpSocket* socket; - InitClientPacket info; public slots: void on_disconnected(); void on_readyRead(); signals: + void receivedDelta(int, DeltaClientPacket*); void outMessage(QString); void errMessage(QString); }; diff --git a/app/simulation.cpp b/app/simulation.cpp new file mode 100644 index 0000000..af3b85b --- /dev/null +++ b/app/simulation.cpp @@ -0,0 +1,68 @@ +#include "simulation.h" +#include +#include +#include + +#define PI 3.1416 +#define MAX_ANGULAR_SPEED 1 +#define MAX_SPEED 3 + +Simulation::Simulation() +{ + std::srand(std::time(NULL)); +} + +std::vector* Simulation::getWorldData() +{ + return &worldData; +} + +/** + * @brief Simulation::addClient is only called server-side + */ +void Simulation::addClient() +{ + InitClientPacket info; + info.x = std::rand()%50; + info.y = std::rand()%50; + info.angle = ((float)(std::rand()%360)) / PI; + info.vforward = 0; + info.vangle = 0; + worldData.push_back(info); +} + +/** + * @brief Simulation::removeClient is only called server-side + */ +void Simulation::removeClient(int i) +{ + worldData[i] = worldData.back(); + worldData.pop_back(); +} + +void Simulation::clientInput(int i, const DeltaClientPacket &delta) +{ + InitClientPacket *info = &(worldData[i]); + info->vangle += delta.dvangle; + info->vforward += delta.dvforward; + if(info->vforward>3) + info->vforward = MAX_SPEED; + if(info->vforward<0) + info->vforward = 0; + float speed = info->vforward; + float maxAngularSpeed = speed <= 1 ? speed*MAX_ANGULAR_SPEED : MAX_ANGULAR_SPEED/speed; + if(info->vangle > maxAngularSpeed) + info->vangle = maxAngularSpeed; + if(info->vangle < -maxAngularSpeed) + info->vangle = -maxAngularSpeed; +} + +void Simulation::update() +{ + for(InitClientPacket &info : worldData) + { + info.angle += info.vangle; + info.x += std::cos(info.angle)*info.vforward; + info.y += std::sin(info.angle)*info.vforward; + } +} diff --git a/app/simulation.h b/app/simulation.h new file mode 100644 index 0000000..990f905 --- /dev/null +++ b/app/simulation.h @@ -0,0 +1,20 @@ +#ifndef SIMULATION_H +#define SIMULATION_H + +#include "packet.h" +#include +#include + +class Simulation +{ + std::vector worldData; +public: + Simulation(); + std::vector* getWorldData(); + void addClient(); + void removeClient(int i); + void clientInput(int i, const DeltaClientPacket &delta); + void update(); +}; + +#endif // SIMULATION_H