Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
#include <QtCore/QCryptographicHash>
#include <QtCore/QStringList>
#include <QtNetwork/QHostAddress>
#include "client.hpp"
#include <iostream>
using namespace std;
Client::Client(int sd) :
QThread()
{
connected = true;
socket = new QTcpSocket(this);
socket->setSocketDescriptor(sd);
peerAddress = socket->peerAddress().toString();
colourRed = -1;
colourGreen = -1;
colourBlue = -1;
playing = false;
playedGo = false;
}
Client::~Client()
{
cout << ":: Deleted Connection: " << peerAddress.toStdString() << endl;
if (connected)
{
socket->disconnectFromHost();
}
delete socket;
}
bool Client::isConnected()
{
return connected;
}
void Client::run()
{
cout << ":: Running Thread" << endl;
doGo();
}
bool Client::doGo()
{
playedGo = false;
bool p = false;
checkDisconnected();
if (connected)
{
if (playing && !crashed)
{
int start = time(0);
updatePos();
crashed = hasCollided(clients);
sendText("G");
if (socket->waitForReadyRead(2000))
{
p = checkReadyRead();
if (!playedGo)
{
socket->disconnectFromHost();
}
}
else
{
p = true;
socket->disconnectFromHost();
}
int finish = time(0);
int delta = finish - start;
cout << ":: " << name.toStdString() << ": " << delta << endl;
}
else
{
while (socket->canReadLine())
{
checkReadyRead();
}
checkPlayable();
p = true;
}
}
playedGo = p;
return true;
}
void Client::checkDisconnected()
{
if (socket->state() == QAbstractSocket::UnconnectedState)
{
connected = false;
}
else
{
if (socket->waitForDisconnected(10))
{
connected = false;
}
}
}
bool Client::checkReadyRead()
{
bool playedGo = false;
if (socket->canReadLine())
{
QByteArray data = socket->readLine();
QString line = data.trimmed();
cout << ":: " << name.toStdString() << ": " << line.toStdString() << endl;
if (line == "DISCONNECT")
{
socket->disconnectFromHost();
}
else if (line.startsWith("NAME "))
{
name = line.remove(0, 5);
}
else if (line.startsWith("CHAT "))
{
QString text = line.remove(0, 5);
emit chat(name, text);
playedGo = true;
}
else if (line.startsWith("COLOUR "))
{
QStringList list = line.split(" ");
if (list.count() == 4)
{
colourRed = list[1].toInt();
colourGreen = list[2].toInt();
colourBlue = list[3].toInt();
}
}
else if (line == "N")
{
playedGo = true;
}
else if (line == "L")
{
angle -= 90;
playedGo = true;
}
else if (line == "R")
{
angle -= 90;
playedGo = true;
}
else if (line == "A")
{
//if (speed < 2.0)
//{
// speed += 0.1;
//}
playedGo = true;
}
else if (line == "D")
{
//if (speed > 0.2)
//{
// speed -= 0.1;
//}
playedGo = true;
}
}
return playedGo;
}
void Client::checkPlayable()
{
if (!name.isEmpty())
{
if (colourRed != -1)
{
if (colourGreen != -1)
{
if (colourBlue != -1)
{
playing = true;
}
}
}
}
}
void Client::updatePos()
{
if (angle >= 360)
{
angle -= 360;
}
if (angle <= -90)
{
angle += 360;
}
if (angle == 0)
{
y -= speed;
}
else if (angle == 180)
{
y += speed;
}
else if (angle == 90)
{
x += speed;
}
else if (angle == 270)
{
x -= speed;
}
linePoints.append(QPoint(x, y));
}
void Client::reset()
{
x = rand() % 800;
y = rand() % 600;
int a = rand() % 4;
angle = a * 90;
speed = 1.0;
linePoints.clear();
linePoints.append(QPoint(x, y));
crashed = false;
sendText("RESET");
}
bool Client::hasCollided(QList<Client *> clients)
{
int i = linePoints.count() - 1;
if(linePoints[i-1].x() < 0 || linePoints[i-1].x() > 800 || linePoints[i-1].y() < 0 || linePoints[i-1].y() > 600)
return true;
if(linePoints[i].x() < 0 || linePoints[i].x() > 800 || linePoints[i].y() < 0 || linePoints[i].y() > 600)
return true;
int j;
foreach (Client *bike, clients)
{
for(j = 0; j < bike->linePoints.count() - 2; j++)
{
if(!(bike->linePoints[j].x() == bike->linePoints[j+1].x() && linePoints[i].x() == linePoints[i-1].x()) && !(bike->linePoints[j].y() == bike->linePoints[j+1].y() && linePoints[i].y() == linePoints[i-1].y()))
{
// If not parallel
if(bike->linePoints[j].x() == bike->linePoints[j+1].x())
{
// x equal
if (((linePoints[i-1].x() > bike->linePoints[j].x()) && (linePoints[i].x() < bike->linePoints[j].x())) || ((linePoints[i-1].x() < bike->linePoints[j].x()) && (linePoints[i].x() > bike->linePoints[j].x())))
{
if((sign(linePoints[i-1].y() - bike->linePoints[j].y()) != sign(linePoints[i-1].y() - bike->linePoints[j+1].y())))
return true;
}
}
else if(bike->linePoints[j].y() == bike->linePoints[j+1].y())
{
if (((linePoints[i-1].y() > bike->linePoints[j].y()) && (linePoints[i].y() < bike->linePoints[j].y())) || ((linePoints[i-1].y() < bike->linePoints[j].y()) && (linePoints[i].y() > bike->linePoints[j].y())))
{
if((sign(linePoints[i-1].x() - bike->linePoints[j].x()) != sign(linePoints[i-1].x() - bike->linePoints[j+1].x())))
return true;
}
}
}
}
}
return false;
}
void Client::sendText(QByteArray text)
{
if (connected)
{
write(text);
write("\n");
}
}
void Client::write(QByteArray text)
{
if (connected)
{
socket->write(text);
socket->flush();
}
}
int sign(float x)
{
if (x > 0)
{
return 1;
}
if (x < 0)
{
return -1;
}
return 0;
}