Permalink
Browse files

simple network protocoll

player serialization
  • Loading branch information...
1 parent 62570b0 commit 303669c0e2a55224df9c8a658672353b54c3895f @vos committed May 19, 2012
Showing with 252 additions and 82 deletions.
  1. +1 −1 canvas.cpp
  2. +1 −0 game.cpp
  3. +2 −3 game.h
  4. +91 −24 mainwindow.cpp
  5. +10 −0 mainwindow.h
  6. +32 −24 multiplayerclient.cpp
  7. +6 −1 multiplayerclient.h
  8. +2 −0 multiplayerpacket.cpp
  9. +4 −2 multiplayerpacket.h
  10. +52 −21 multiplayerserver.cpp
  11. +9 −2 multiplayerserver.h
  12. +23 −0 player.cpp
  13. +16 −1 player.h
  14. +3 −3 xmlscenarioserializer.cpp
View
@@ -32,7 +32,7 @@ Canvas::Canvas(QWidget *parent) :
m_factorSelectionActive = false;
m_backgroundImage = QImage("background.jpg");
- m_activePlayer = new HumanPlayer("Alex", Qt::blue, m_game);
+ m_activePlayer = new HumanPlayer("Alex", Qt::blue);
m_game->addPlayer(m_activePlayer);
m_globalAccess = false;
View
@@ -71,6 +71,7 @@ bool Game::addPlayer(Player *player)
qDebug("Game::addPlayer() player already added: %s", qPrintable(player->name()));
return false;
}
+ player->setParent(this);
m_players.insert(player);
connect(player, SIGNAL(changed(Player::ChangeType)), SLOT(player_changed(Player::ChangeType)), Qt::DirectConnection);
emit playerAdded(player);
View
5 game.h
@@ -7,15 +7,14 @@
#include <QElapsedTimer>
#include "gametime.h"
+#include "player.h"
+#include "planet.h"
QT_BEGIN_NAMESPACE
class QScriptEngine;
class QScriptEngineDebugger;
QT_END_NAMESPACE
-#include "player.h"
-#include "planet.h"
-
class Game : public QObject
{
Q_OBJECT
View
@@ -9,6 +9,7 @@
#include <QPushButton>
#include <QMessageBox>
#include <QFileDialog>
+#include <QInputDialog>
#include "canvas.h"
#include "computerplayer.h"
@@ -28,6 +29,7 @@ MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
m_server(NULL),
+ m_client(NULL),
m_selectedObject(NULL)
{
ui->setupUi(this);
@@ -47,6 +49,9 @@ MainWindow::MainWindow(QWidget *parent) :
ui->editorWidget->setLayout(layout);
connect(m_game, SIGNAL(modeChanged(Game::Mode)), SLOT(game_modeChanged(Game::Mode)));
+ connect(m_game, SIGNAL(playerAdded(Player*)), SLOT(game_playerAdded(Player*)));
+ connect(m_game, SIGNAL(playerRemoved(Player*)), SLOT(game_playerRemoved(Player*)));
+
connect(m_canvas, SIGNAL(selectionChanged(QObject*)), SLOT(canvas_selectionChanged(QObject*)));
m_canvas->setFocus();
@@ -57,6 +62,8 @@ MainWindow::MainWindow(QWidget *parent) :
MainWindow::~MainWindow()
{
+ if (m_server != NULL)
+ delete m_server;
qDeleteAll(m_propertyEditorMap.values());
delete m_canvas;
delete ui;
@@ -67,6 +74,29 @@ void MainWindow::game_modeChanged(Game::Mode mode)
ui->modeComboBox->setCurrentIndex(mode);
}
+void MainWindow::game_playerAdded(Player *player)
+{
+ QVariant playerVar;
+ playerVar.setValue(player);
+ ui->playerComboBox->addItem(player->name(), playerVar);
+ connect(player, SIGNAL(nameChanged(QString,QString)), SLOT(player_nameChanged(QString,QString)));
+
+ m_canvas->setActivePlayer(player);
+ ui->playerComboBox->setCurrentIndex(ui->playerComboBox->count()-1);
+ canvas_selectionChanged(player);
+}
+
+void MainWindow::game_playerRemoved(Player *player)
+{
+ QVariant playerVar;
+ playerVar.setValue(player);
+ int index = ui->playerComboBox->findData(playerVar);
+ ui->playerComboBox->removeItem(index);
+ if (m_selectedObject == player) {
+ canvas_selectionChanged(NULL);
+ }
+}
+
void MainWindow::clearPropertyEditor()
{
QVBoxLayout *layout = (QVBoxLayout*)ui->editorWidget->layout();
@@ -194,25 +224,13 @@ void MainWindow::on_removePlayerButton_clicked()
{
int index = ui->playerComboBox->currentIndex();
Player *player = ui->playerComboBox->itemData(index).value<Player*>();
- if (m_selectedObject == player) {
- canvas_selectionChanged(NULL);
- }
- if (m_game->removePlayer(player)) {
- ui->playerComboBox->removeItem(index);
- }
+ m_game->removePlayer(player);
}
void MainWindow::on_addPlayerButton_clicked()
{
- Player *player = new ComputerPlayer("Player", Qt::white, NULL, m_game);
+ Player *player = new ComputerPlayer("Player");
m_game->addPlayer(player);
- m_canvas->setActivePlayer(player);
- QVariant playerVar;
- playerVar.setValue(player);
- ui->playerComboBox->addItem(player->name(), playerVar);
- connect(player, SIGNAL(nameChanged(QString,QString)), SLOT(player_nameChanged(QString,QString)));
- ui->playerComboBox->setCurrentIndex(ui->playerComboBox->count()-1);
- canvas_selectionChanged(player);
}
void MainWindow::on_globalAccessCheckBox_toggled(bool checked)
@@ -297,22 +315,71 @@ void MainWindow::on_action_saveScenarioAs_triggered()
void MainWindow::on_action_createServer_triggered()
{
- m_server = new MultiplayerServer(this);
- if (m_server->listen(QHostAddress::Any, 54321)) {
- qDebug("The server is listening on interface %s, port %i",
- qPrintable(m_server->serverAddress().toString()), m_server->serverPort());
+ if (m_server == NULL) {
+ m_server = new MultiplayerServer(m_game, this);
+ if (m_server->listen(QHostAddress::Any, 54321)) {
+ statusBar()->showMessage(QString("The server is listening on interface %1, port %2")
+ .arg(m_server->serverAddress().toString())
+ .arg(m_server->serverPort()));
+ ui->action_createServer->setText("Close Server");
+ } else {
+ qCritical("Failed to start the server on interface %s, port %i: %s (error code %i)",
+ qPrintable(m_server->serverAddress().toString()), m_server->serverPort(),
+ qPrintable(m_server->errorString()), m_server->serverError());
+ }
} else {
- qCritical("Failed to start the server on interface %s, port %i: %s (error code %i)",
- qPrintable(m_server->serverAddress().toString()), m_server->serverPort(),
- qPrintable(m_server->errorString()), m_server->serverError());
+ if (m_server->isListening()) {
+ m_server->close();
+ delete m_server;
+ statusBar()->showMessage("Multiplayer server closed", 5000);
+ }
+ m_server = NULL;
+ ui->action_createServer->setText("Create Server");
}
}
void MainWindow::on_action_ConnectToServer_triggered()
{
- MultiplayerClient *client = new MultiplayerClient(this);
- connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater()));
- client->connectToHost("127.0.0.1", 54321);
+ if (m_client == NULL) {
+ bool ok;
+ QString hostAddress = QInputDialog::getText(this, "Connect to Server", "Host Address", QLineEdit::Normal, "127.0.0.1", &ok);
+ if (ok) {
+ m_client = new MultiplayerClient(m_game, m_canvas->activePlayer(), this);
+ connect(m_client, SIGNAL(connected()), SLOT(client_connected()));
+ connect(m_client, SIGNAL(disconnected()), SLOT(client_disconnected()));
+ connect(m_client, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(client_error(QAbstractSocket::SocketError)));
+ ui->action_ConnectToServer->setText("Connecting...");
+ ui->action_ConnectToServer->setEnabled(false);
+ m_client->connectToHost(hostAddress, 54321);
+ }
+ } else {
+ if (m_client->isOpen()) {
+ ui->action_ConnectToServer->setText("Disconnecting...");
+ ui->action_ConnectToServer->setEnabled(false);
+ m_client->disconnectFromHost(); // TODO: send proper packet
+ }
+ }
+}
+
+void MainWindow::client_connected()
+{
+ ui->action_ConnectToServer->setText("Disconnect from Server");
+ ui->action_ConnectToServer->setEnabled(true);
+}
+
+void MainWindow::client_disconnected()
+{
+ m_client->deleteLater();
+ m_client = NULL;
+ ui->action_ConnectToServer->setText("Connect to Server");
+ ui->action_ConnectToServer->setEnabled(true);
+}
+
+void MainWindow::client_error(QAbstractSocket::SocketError error)
+{
+ Q_UNUSED(error)
+ QMessageBox::warning(this, "Connect to Server Error", QString("Error while connecting to the multiplayer server:\n%1").arg(m_client->errorString()));
+ client_disconnected();
}
void MainWindow::updateTitle(const QString &subTitle)
View
@@ -3,12 +3,14 @@
#include <QMainWindow>
#include <QHash>
+#include <QAbstractSocket>
#include "game.h"
class Canvas;
class PropertyEditor;
class MultiplayerServer;
+class MultiplayerClient;
namespace Ui {
class MainWindow;
@@ -24,6 +26,9 @@ class MainWindow : public QMainWindow
private slots:
void game_modeChanged(Game::Mode mode);
+ void game_playerAdded(Player *player);
+ void game_playerRemoved(Player *player);
+
void canvas_selectionChanged(QObject *o);
void saveButton_clicked();
void player_nameChanged(const QString &oldName, const QString &newName);
@@ -43,12 +48,17 @@ private slots:
void on_action_createServer_triggered();
void on_action_ConnectToServer_triggered();
+ void client_connected();
+ void client_disconnected();
+ void client_error(QAbstractSocket::SocketError error);
+
private:
Ui::MainWindow *ui;
Canvas *m_canvas;
Game *m_game;
QString m_scenarioFileName;
MultiplayerServer *m_server;
+ MultiplayerClient *m_client;
QObject *m_selectedObject;
QHash<QString, PropertyEditor*> m_propertyEditorMap;
View
@@ -1,9 +1,12 @@
#include "multiplayerclient.h"
#include "multiplayerpacket.h"
+#include "game.h"
-MultiplayerClient::MultiplayerClient(QObject *parent) :
+MultiplayerClient::MultiplayerClient(Game *game, Player *player, QObject *parent) :
QTcpSocket(parent),
+ m_game(game),
+ m_player(player),
m_packetSize(0)
{
connect(this, SIGNAL(connected()), SLOT(socket_connected()));
@@ -34,34 +37,39 @@ void MultiplayerClient::socket_readyRead()
QDataStream in(this);
in.setVersion(QDataStream::Qt_4_8);
- if (m_packetSize == 0) {
- if (bytesAvailable() < (int)sizeof(quint32)) // packet size
+ while (bytesAvailable() > 0) {
+ if (m_packetSize == 0) {
+ if (bytesAvailable() < (int)sizeof(quint32)) // packet size
+ return;
+ in >> m_packetSize;
+ }
+ if (bytesAvailable() < m_packetSize)
return;
- in >> m_packetSize;
- }
- if (bytesAvailable() < m_packetSize)
- return;
- m_packetSize = 0; // reset packet size
+ m_packetSize = 0; // reset packet size
- // read packet type
- qint32 packetType; // MultiplayerPacket::PacketType value
- in >> packetType;
+ // read packet type
+ qint32 packetType; // MultiplayerPacket::PacketType value
+ in >> packetType;
-#ifdef DEBUG
- qDebug("PacketType = %i (%s)", packetType, qPrintable(MultiplayerPacket::typeString((MultiplayerPacket::PacketType)packetType)));
+#ifdef MULTIPLAYERCLIENT_DEBUG
+ qDebug("PacketType %i (%s)", packetType, qPrintable(MultiplayerPacket::typeString((MultiplayerPacket::PacketType)packetType)));
#endif
- // TODO: read packet data
- switch ((MultiplayerPacket::PacketType)packetType) {
- case MultiplayerPacket::ConnectionAccepted:
- // TODO
- disconnectFromHost();
- break;
- case MultiplayerPacket::ConnectionRefused:
- // TODO
- break;
- default:
- qWarning("MultiplayerClient::socket_readyRead(): Illegal PacketType %i", packetType);
+ // read and handle packet data
+ switch ((MultiplayerPacket::PacketType)packetType) {
+ case MultiplayerPacket::ConnectionAccepted: {
+ MultiplayerPacket packet(MultiplayerPacket::PlayerJoin);
+ packet.stream() << *m_player;
+ packet.send(this);
+ break;
+ }
+ case MultiplayerPacket::ConnectionRefused:
+ // TODO
+ break;
+ default:
+ qWarning("MultiplayerClient::socket_readyRead(): Illegal PacketType %i", packetType);
+ return;
+ }
}
}
View
@@ -3,12 +3,15 @@
#include <QTcpSocket>
+class Game;
+class Player;
+
class MultiplayerClient : public QTcpSocket
{
Q_OBJECT
public:
- explicit MultiplayerClient(QObject *parent = NULL);
+ explicit MultiplayerClient(Game *game, Player *player, QObject *parent = NULL);
private slots:
void socket_connected();
@@ -17,6 +20,8 @@ private slots:
void socket_error(QAbstractSocket::SocketError error);
private:
+ Game *m_game;
+ Player *m_player;
quint32 m_packetSize;
};
View
@@ -5,6 +5,8 @@
const char* MultiplayerPacket::PacketTypeNames[] = {
"ConnectionAccepted",
"ConnectionRefused",
+ "PlayerJoin",
+ "PlayerDisconnect",
"IllegalPacketType"
};
View
@@ -10,8 +10,10 @@ class MultiplayerPacket
{
public:
enum PacketType {
- ConnectionAccepted,
- ConnectionRefused,
+ ConnectionAccepted, // server -> client
+ ConnectionRefused, // server -> client
+ PlayerJoin, // client -> server
+ PlayerDisconnect, // client -> server
IllegalPacketType
};
static QString typeString(PacketType type);
Oops, something went wrong.

0 comments on commit 303669c

Please sign in to comment.