166 lines
4.3 KiB
C++
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();
|
|
}
|