updated server

This commit is contained in:
Anselme 2015-09-21 20:01:02 +02:00
parent bfd3119beb
commit 7cd9805539
5 changed files with 139 additions and 63 deletions

View File

@ -18,7 +18,8 @@ SOURCES = main.cpp \
riddles.cpp \ riddles.cpp \
todomodule.cpp \ todomodule.cpp \
server.cpp \ server.cpp \
servermodule.cpp servermodule.cpp \
simulation.cpp
HEADERS += \ HEADERS += \
regismodule.h \ regismodule.h \
@ -30,4 +31,5 @@ HEADERS += \
todomodule.h \ todomodule.h \
packet.h \ packet.h \
server.h \ server.h \
servermodule.h servermodule.h \
simulation.h

View File

@ -1,20 +1,14 @@
#include "server.h" #include "server.h"
#include <ctime>
#include <cmath>
#include <QTcpServer> #include <QTcpServer>
#include <QTcpSocket> #include <QTcpSocket>
#include <QTimer> #include <QTimer>
#define PI 3.1416
#define MAX_ANGULAR_SPEED 1
#define MAX_SPEED 3
Server::Server(unsigned short port, QObject *parent) : QObject(parent) Server::Server(unsigned short port, QObject *parent) : QObject(parent)
{ {
worldData = simulation.getWorldData();
server = new QTcpServer(); server = new QTcpServer();
timer = new QTimer(); timer = new QTimer();
timer->setSingleShot(false);
std::srand(std::time(NULL));
connect(server, SIGNAL(newConnection()), this, SLOT(on_newConnection())); connect(server, SIGNAL(newConnection()), this, SLOT(on_newConnection()));
connect(timer, SIGNAL(timeout()), this, SLOT(update())); connect(timer, SIGNAL(timeout()), this, SLOT(update()));
if(server->listen(QHostAddress::Any, port)) if(server->listen(QHostAddress::Any, port))
@ -28,20 +22,22 @@ Server::Server(unsigned short port, QObject *parent) : QObject(parent)
void Server::update() void Server::update()
{ {
// check if some clients are disconnected or invalid
for(unsigned int i=0; i<clients.size(); ++i) for(unsigned int i=0; i<clients.size(); ++i)
{ {
if(clients[i]->isOk()) if(!clients[i]->isOk())
clients[i]->update();
else
{ {
delete clients[i]; delete clients[i];
clients[i--] = clients.back(); clients[i--] = clients.back();
clients.pop_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) for(unsigned int i=0; i<clients.size(); ++i)
clients[i]->sendFull(clients, i); clients[i]->sendFull(*worldData, i);
} }
Server::~Server() Server::~Server()
@ -51,17 +47,19 @@ Server::~Server()
server->deleteLater(); server->deleteLater();
timer->stop(); timer->stop();
delete timer; delete timer;
for(int i=0; i<clients.size(); ++i) for(ServerClient *c : clients)
delete clients[i]; delete c;
} }
void Server::on_newConnection() void Server::on_newConnection()
{ {
QTcpSocket* socket = server->nextPendingConnection(); QTcpSocket* socket = server->nextPendingConnection();
Client* client = new Client(socket); ServerClient* client = new ServerClient(clients.size(), socket);
if(client->isOk()) if(client->isOk())
{ {
simulation.addClient();
clients.push_back(client); 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(outMessage(QString)), this, SIGNAL(outMessage(QString)));
connect(client, SIGNAL(errMessage(QString)), this, SIGNAL(errMessage(QString))); connect(client, SIGNAL(errMessage(QString)), this, SIGNAL(errMessage(QString)));
} }
@ -69,25 +67,26 @@ void Server::on_newConnection()
delete client; 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) if(socket->state() == QTcpSocket::ConnectedState)
{ {
ok = true; ok = true;
emit outMessage(QString("New player connected : %1").arg(socket->peerAddress().toString())); 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(disconnected()), this, SLOT(on_disconnected()));
connect(socket, SIGNAL(readyRead()), this, SLOT(on_readyRead())); connect(socket, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
} }
Client::~Client() ServerClient::~ServerClient()
{ {
if(socket != NULL) if(socket != NULL)
{ {
@ -97,7 +96,7 @@ Client::~Client()
} }
} }
void Client::on_readyRead() void ServerClient::on_readyRead()
{ {
while(socket->bytesAvailable()) while(socket->bytesAvailable())
{ {
@ -107,20 +106,9 @@ void Client::on_readyRead()
{ {
case DELTA_CLIENT: case DELTA_CLIENT:
{ {
DeltaClientPacket delta; DeltaClientPacket* delta = new DeltaClientPacket();
socket->read((char*)&delta, sizeof(DeltaClientPacket)); socket->read((char*)delta, sizeof(DeltaClientPacket));
info.vangle += delta.dvangle; emit receivedDelta(myId, delta);
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;
} }
break; break;
default: default:
@ -131,7 +119,7 @@ void Client::on_readyRead()
} }
} }
void Client::on_disconnected() void ServerClient::on_disconnected()
{ {
emit outMessage(QString("Player disconnected")); emit outMessage(QString("Player disconnected"));
disconnect(socket, SIGNAL(disconnected())); disconnect(socket, SIGNAL(disconnected()));
@ -139,27 +127,21 @@ void Client::on_disconnected()
ok = false; ok = false;
} }
void Client::update() void ServerClient::sendDelta()
{
info.angle += info.vangle;
info.x += std::cos(info.angle)*info.vforward;
info.y += std::sin(info.angle)*info.vforward;
}
void Client::sendDelta()
{ {
// TODO // TODO
} }
void Client::sendFull(const std::vector<Client*> &clients, int id) void ServerClient::sendFull(const std::vector<InitClientPacket> &worldData, int id)
{ {
myId = id;
InitServerPacket packet; InitServerPacket packet;
packet.idClient = id; packet.idClient = id;
packet.nbClients = clients.size(); packet.nbClients = worldData.size();
int type = INIT_SERVER; int type = INIT_SERVER;
socket->write((char*)&type, sizeof(int)); socket->write((char*)&type, sizeof(int));
socket->write((char*)&packet, sizeof(InitServerPacket)); socket->write((char*)&packet, sizeof(InitServerPacket));
for(unsigned int i=0; i<clients.size(); ++i) for(const InitClientPacket &info : worldData)
socket->write((char*)&(clients[i]->info), sizeof(InitClientPacket)); socket->write((const char*)&info, sizeof(InitClientPacket));
socket->flush(); socket->flush();
} }

View File

@ -4,11 +4,12 @@
#include <QObject> #include <QObject>
#include <vector> #include <vector>
#include "packet.h" #include "packet.h"
#include "simulation.h"
class QTimer; class QTimer;
class QTcpServer; class QTcpServer;
class QTcpSocket; class QTcpSocket;
class Client; class ServerClient;
class Server : public QObject class Server : public QObject
{ {
@ -18,7 +19,9 @@ public:
~Server(); ~Server();
QTcpServer* server; QTcpServer* server;
QTimer* timer; QTimer* timer;
std::vector<Client*> clients; Simulation simulation;
std::vector<InitClientPacket>* worldData;
std::vector<ServerClient*> clients;
int currentClient; int currentClient;
signals: signals:
@ -28,30 +31,31 @@ signals:
public slots: public slots:
void update(); void update();
void on_newConnection(); void on_newConnection();
void onClientDelta(int, DeltaClientPacket*);
}; };
class Client : public QObject class ServerClient : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Client(QTcpSocket* mySocket); ServerClient(int id, QTcpSocket* mySocket);
~Client(); ~ServerClient();
bool isOk() {return ok;} bool isOk() {return ok;}
void update();
void sendDelta(); void sendDelta();
void sendFull(const std::vector<Client*> &clients, int id); void sendFull(const std::vector<InitClientPacket> &clients, int id);
private: private:
bool ok; bool ok;
int myId;
QTcpSocket* socket; QTcpSocket* socket;
InitClientPacket info;
public slots: public slots:
void on_disconnected(); void on_disconnected();
void on_readyRead(); void on_readyRead();
signals: signals:
void receivedDelta(int, DeltaClientPacket*);
void outMessage(QString); void outMessage(QString);
void errMessage(QString); void errMessage(QString);
}; };

68
app/simulation.cpp Normal file
View File

@ -0,0 +1,68 @@
#include "simulation.h"
#include <cmath>
#include <ctime>
#include <cstdlib>
#define PI 3.1416
#define MAX_ANGULAR_SPEED 1
#define MAX_SPEED 3
Simulation::Simulation()
{
std::srand(std::time(NULL));
}
std::vector<InitClientPacket>* 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;
}
}

20
app/simulation.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef SIMULATION_H
#define SIMULATION_H
#include "packet.h"
#include <vector>
#include <cstddef>
class Simulation
{
std::vector<InitClientPacket> worldData;
public:
Simulation();
std::vector<InitClientPacket>* getWorldData();
void addClient();
void removeClient(int i);
void clientInput(int i, const DeltaClientPacket &delta);
void update();
};
#endif // SIMULATION_H