Subversion Repositories QTron

Rev

Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <QtNetwork/QHostAddress>

#include "server.hpp"

#include <iostream>

using namespace std;

Server::Server() :
    QObject()
{
    srand(time(NULL));
    server = new QTcpServer(this);
}

Server::~Server()
{
    delete server;
}

void Server::start()
{
    int port = 4567;
   
    cout << ":: Starting server on port " << port << endl;
   
    if (!server->listen(QHostAddress::Any, port))
    {
        cout << "!! Could not start Server: " << server->errorString().toStdString() << endl;
    }
   
    bool running = true;
    while (running)
    {
        checkClients();
        checkConnections();
        doGo();
    }
}

void Server::checkClients()
{
    for (int i = clients.size() - 1; i >= 0; i--)
    {
        Client *client = clients[i];
        if (!client->isConnected())
        {
            delete client;
            clients.removeAt(i);
        }
    }
}

void Server::checkConnections()
{
    while (server->waitForNewConnection(10))
    {
        QTcpSocket *socket = server->nextPendingConnection();
        Client *client = new Client(socket->socketDescriptor());

        connect(client, SIGNAL(chat(QString, QString)), this, SLOT(chat(QString, QString)));
        clients.append(client);
       
        cout << ":: New Connection: " << socket->peerAddress().toString().toStdString() << endl;
       
        reset();
    }
}

void Server::doGo()
{
    for (int i = clients.size() - 1; i >= 0; i--)
    {
        Client *client = clients[i];
        if (client->isConnected())
        {
            if (client->playing)
            {
                sendClientInfo(client);
            }
            client->clients = clients;
            client->start();
        }
    }
   
    bool goDone = false;
    while (!goDone)
    {
        bool turnsDone = true;
       
        for (int i = clients.size() - 1; i >= 0; i--)
        {
            Client *client = clients[i];
            if (client->isConnected() && client->playing)
            {
                if (!client->playedGo)
                {
                    turnsDone = false;
                }
            }
        }
       
        goDone = turnsDone;
    }
   
    bool allCrashed = true;
    for (int i = clients.size() - 1; i >= 0; i--)
    {
        Client *client = clients[i];
        if (client->isConnected())
        {
            if (!client->crashed)
            {
                allCrashed = false;
            }
        }
    }
   
    if (allCrashed)
    {
        reset();
    }
}

void Server::sendClientInfo(Client *client)
{
    foreach (Client *c, clients)
    {
        if (c->isConnected())
        {
            if (c->crashed)
            {
                client->write("DIED ");
                client->write(c->name.toAscii());
                client->write("\n");
            }
            else
            {
                client->write("BIKE ");
                client->write(c->name.toAscii());
                client->write(" ");
                client->write(QByteArray::number(QByteArray::number(c->x).toInt()));
                client->write(" ");
                client->write(QByteArray::number(QByteArray::number(c->y).toInt()));
                client->write(" ");
                client->write(QByteArray::number(c->colourRed));
                client->write(" ");
                client->write(QByteArray::number(c->colourGreen));
                client->write(" ");
                client->write(QByteArray::number(c->colourBlue));
                client->write("\n");
            }
        }
        else
        {
            client->write("DISCO ");
            client->write(c->name.toAscii());
            client->write("\n");
        }
    }
}

void Server::reset()
{
    foreach (Client *c, clients)
    {
        c->reset();
    }
}

void Server::chat(QString name, QString data)
{
    QByteArray array = "CHAT ";
    array.append(name.toAscii());
    array.append(" ");
    array.append(data.toAscii());
    array.append("\n");
   
    foreach (Client *c, clients)
    {
        c->write(array);
    }
}