SparrowBot/app/server.cpp
2015-09-18 20:32:11 +02:00

166 lines
4.3 KiB
C++

#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)
{
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))
{
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()
{
for(unsigned int i=0; i<clients.size(); ++i)
{
if(clients[i]->isOk())
clients[i]->update();
else
{
delete clients[i];
clients[i--] = clients.back();
clients.pop_back();
}
}
for(unsigned int i=0; i<clients.size(); ++i)
clients[i]->sendFull(clients, i);
}
Server::~Server()
{
if(server->isListening())
server->close();
server->deleteLater();
timer->stop();
delete timer;
for(int i=0; i<clients.size(); ++i)
delete clients[i];
}
void Server::on_newConnection()
{
QTcpSocket* socket = server->nextPendingConnection();
Client* client = new Client(socket);
if(client->isOk())
{
clients.push_back(client);
connect(client, SIGNAL(outMessage(QString)), this, SIGNAL(outMessage(QString)));
connect(client, SIGNAL(errMessage(QString)), this, SIGNAL(errMessage(QString)));
}
else
delete client;
}
Client::Client(QTcpSocket* 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()
{
if(socket != NULL)
{
if(socket->isOpen())
socket->close();
socket->deleteLater();
}
}
void Client::on_readyRead()
{
while(socket->bytesAvailable())
{
int type;
socket->read((char*)&type, sizeof(int));
switch(type)
{
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;
}
break;
default:
emit errMessage(QString("Incorrect packet received"));
socket->close();
break;
}
}
}
void Client::on_disconnected()
{
emit outMessage(QString("Player disconnected"));
disconnect(socket, SIGNAL(disconnected()));
disconnect(socket, SIGNAL(readyRead()));
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()
{
// TODO
}
void Client::sendFull(const std::vector<Client*> &clients, int id)
{
InitServerPacket packet;
packet.idClient = id;
packet.nbClients = clients.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));
socket->flush();
}