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 \
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

View File

@ -1,20 +1,14 @@
#include "server.h"
#include <ctime>
#include <cmath>
#include <QTcpServer>
#include <QTcpSocket>
#include <QTimer>
#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; i<clients.size(); ++i)
{
if(clients[i]->isOk())
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; i<clients.size(); ++i)
clients[i]->sendFull(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; i<clients.size(); ++i)
delete clients[i];
for(ServerClient *c : clients)
delete c;
}
void Server::on_newConnection()
{
QTcpSocket* socket = server->nextPendingConnection();
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<Client*> &clients, int id)
void ServerClient::sendFull(const std::vector<InitClientPacket> &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; i<clients.size(); ++i)
socket->write((char*)&(clients[i]->info), sizeof(InitClientPacket));
for(const InitClientPacket &info : worldData)
socket->write((const char*)&info, sizeof(InitClientPacket));
socket->flush();
}

View File

@ -4,11 +4,12 @@
#include <QObject>
#include <vector>
#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<Client*> clients;
Simulation simulation;
std::vector<InitClientPacket>* worldData;
std::vector<ServerClient*> 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<Client*> &clients, int id);
void sendFull(const std::vector<InitClientPacket> &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);
};

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