From da481762bded855ffd709114ee3a16ec4dbaaeb6 Mon Sep 17 00:00:00 2001 From: totycro Date: Sun, 10 Apr 2011 00:55:13 +0200 Subject: Tell player about their color minor cleanup --- pacman-c++/client.cpp | 3 +++ pacman-c++/mainwidget.cpp | 50 +++++++++++++++++++++++------------------------ pacman-c++/mainwidget.h | 2 +- pacman-c++/pacman.proto | 4 ++++ pacman-c++/server.cpp | 30 +++++++++++----------------- pacman-c++/util.cpp | 31 ++++++++++++++++++++++++++++- pacman-c++/util.h | 9 +++++++++ 7 files changed, 83 insertions(+), 46 deletions(-) diff --git a/pacman-c++/client.cpp b/pacman-c++/client.cpp index fbcde6d..c35510a 100644 --- a/pacman-c++/client.cpp +++ b/pacman-c++/client.cpp @@ -1,6 +1,7 @@ #include "client.h" #include "clicklabel.h" #include "audioplayer.h" +#include "pacman.pb.h" Client::Client() { @@ -64,6 +65,8 @@ void Client::mutedChanged(bool muted) const int main(int argc, char ** argv) { + GOOGLE_PROTOBUF_VERIFY_VERSION; + QApplication app(argc, argv); app.setOrganizationName("TU Wien FOOP"); app.setApplicationName("Pacman Client"); diff --git a/pacman-c++/mainwidget.cpp b/pacman-c++/mainwidget.cpp index 420ea8f..25f554a 100644 --- a/pacman-c++/mainwidget.cpp +++ b/pacman-c++/mainwidget.cpp @@ -15,16 +15,20 @@ MainWidget::MainWidget(QWidget *parent) //connect(AudioPlayer::self(), SIGNAL(finished()), this, SLOT(startGame())); //AudioPlayer::self()->play(AudioPlayer::Intro); - bool connected = connectToServer(); - if (!connected) { + Color::Color myColor = connectToServer(); + if (myColor == Color::none) { QMessageBox::critical(this, "Error", "Failed to connect to server, falling back to local test mode"); // TODO: quit application here or sth m_socket = NULL; QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(tick())); timer->start(Constants::tick); + } else { + connect(m_socket, SIGNAL(readyRead()), this, SLOT(tick())); } - connect(m_socket, SIGNAL(readyRead()), this, SLOT(tick())); + + // TODO: use mycolor + qDebug() << "myc" << myColor; startGame(); } @@ -146,17 +150,8 @@ void MainWidget::tick() } } } else { - QByteArray data = m_socket->readAll(); - //qDebug() << "read qbytes " << data.length(); - // TODO: normal conversion to std::string won't work, - // probably due to \0-bytes. both those methods will yield - // a 3 char long string - //std::string dataStr = std::string(data.constData()); - //std::string dataStr = QString(data).toStdString(); std::string dataStr; - for (int i = 0; i < data.size(); ++i) { - dataStr += data[i]; - } + Util::QByteArrayToStdString(m_socket->readAll(), dataStr); //qDebug() << "read str " << dataStr.length(); ProtoBuf::MapUpdate packet; @@ -181,7 +176,7 @@ void MainWidget::keyPressEvent(QKeyEvent* event) return; QWidget::keyPressEvent(event); - Transmission::field_t newKey = translateKey(event->key()); + Transmission::field_t newKey = translateKey(event->key(), -1); if (m_currentKey == newKey || newKey == -1) { return; } @@ -191,15 +186,7 @@ void MainWidget::keyPressEvent(QKeyEvent* event) // send to server ProtoBuf::KeyPressUpdate packet; packet.set_newkey(m_currentKey); - std::string dataStr = packet.SerializeAsString(); - unsigned int bytesWritten = m_socket->write(dataStr.c_str(), dataStr.length()); - m_socket->flush(); - if (bytesWritten != dataStr.length()) { - qDebug() << "written: " << bytesWritten; - qDebug() << "strl: " << dataStr.length(); - } - Q_ASSERT(bytesWritten == dataStr.length()); - + Util::sendPacket(packet, m_socket); qDebug() << "send key: " << m_currentKey; } else { @@ -244,10 +231,23 @@ void MainWidget::playerScoreClicked() return; } -bool MainWidget::connectToServer() +Color::Color MainWidget::connectToServer() { m_socket = new QTcpSocket(this); m_socket->connectToHost("127.0.0.1", Constants::port); - return m_socket->waitForConnected(Constants::connection_timeout); + bool worked = m_socket->waitForConnected(Constants::connection_timeout); + if (worked) { + // additional init + // first packet is our color + worked = m_socket->waitForReadyRead(); + if (worked) { + std::string data; + Util::QByteArrayToStdString(m_socket->readAll(), data); + ProtoBuf::WhoAmI packet; + packet.ParseFromString(data); + return static_cast(packet.color() & Transmission::color_mask); + } + } + return Color::none; } diff --git a/pacman-c++/mainwidget.h b/pacman-c++/mainwidget.h index 04beec2..266f329 100644 --- a/pacman-c++/mainwidget.h +++ b/pacman-c++/mainwidget.h @@ -30,7 +30,7 @@ private: void createMenu(); void updateScore(); bool isRunning(); - bool connectToServer(); + Color::Color connectToServer(); private slots: void startGame(); diff --git a/pacman-c++/pacman.proto b/pacman-c++/pacman.proto index 7a582df..ae8f966 100644 --- a/pacman-c++/pacman.proto +++ b/pacman-c++/pacman.proto @@ -7,3 +7,7 @@ message KeyPressUpdate { message MapUpdate { repeated uint32 field = 1 [packed=true]; } + +message WhoAmI { + required uint32 color = 1; +} diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp index bbe4ad6..422f7e0 100644 --- a/pacman-c++/server.cpp +++ b/pacman-c++/server.cpp @@ -77,14 +77,21 @@ void Server::waitForClientConnections() // server must stay alive as long as sockets (qt parent mem mechanism) tcpSrv->listen(QHostAddress::Any, Constants::port); + Color::Color playerColors[3] = { Color::red, Color::blue, Color::green }; //for (unsigned int i=0; iwaitForNewConnection(-1); Q_ASSERT(connectionAvailable); QTcpSocket *socket = tcpSrv->nextPendingConnection(); - // TODO: color assignment - m_clientConnections[Color::red] = socket; connect(socket, SIGNAL(readyRead()), this, SLOT(keyPressUpdate())); + + // assign color + Color::Color color = playerColors[i]; + m_clientConnections[color] = socket; + // notify player of color + ProtoBuf::WhoAmI packet; + packet.set_color(color); + Util::sendPacket(packet, socket); } } @@ -93,16 +100,7 @@ void Server::sendUpdate(QSharedPointer< ProtoBuf::MapUpdate > packet) std::string dataStr = packet->SerializeAsString(); const char *data = dataStr.c_str(); foreach(QTcpSocket *socket, m_clientConnections) { - //qDebug() << "sending str len: " << dataStr.length(); - int bytesWritten = socket->write(data, dataStr.length()); - if (bytesWritten != dataStr.length()) { - qDebug() << "written: " << bytesWritten; - qDebug() << "strl: " << dataStr.length(); - } - Q_ASSERT(bytesWritten == dataStr.length()); - } - foreach(QTcpSocket *socket, m_clientConnections) { - socket->flush(); + Util::sendPacket(data, dataStr.length(), socket); } } @@ -117,12 +115,8 @@ void Server::keyPressUpdate() qDebug() << "data?"; if (socket->bytesAvailable() > 0) { qDebug() << "data!"; - QByteArray data = socket->readAll(); - // see mainwidget.cpp:153 std::string dataStr; - for (int i = 0; i < data.size(); ++i) { - dataStr += data[i]; - } + Util::QByteArrayToStdString(socket->readAll(), dataStr); ProtoBuf::KeyPressUpdate packet; packet.ParseFromString(dataStr); Transmission::field_t direction = packet.newkey(); @@ -130,10 +124,8 @@ void Server::keyPressUpdate() m_actorMovements[ color ] = Util::transmissionMovementToActor(direction); } } - } - int main(int argc, char ** argv) { GOOGLE_PROTOBUF_VERIFY_VERSION; diff --git a/pacman-c++/util.cpp b/pacman-c++/util.cpp index 6b9780b..ceba2b8 100644 --- a/pacman-c++/util.cpp +++ b/pacman-c++/util.cpp @@ -1,5 +1,7 @@ #include "util.h" +#include + namespace Util { Transmission::map_t createUninitialisedMap() { @@ -20,7 +22,7 @@ namespace Util { cur = Transmission::none; } } - return map; + return map; } // temporary Transmission::map_t createDummyMap() @@ -138,4 +140,31 @@ namespace Util { } return Actor::None; // for pleasing the compiler } + + void QByteArrayToStdString(const QByteArray& arr, std::string& str) { + // TODO: normal conversion to std::string won't work, + // probably due to \0-bytes. + //std::string dataStr = std::string(data.constData()); + //std::string dataStr = QString(data).toStdString(); + for (int i=0; iwrite(data, length); + if (bytesWritten != length) { + qDebug() << "written: " << bytesWritten; + qDebug() << "strl: " << length; + } + Q_ASSERT(bytesWritten == length); + socket->flush(); + } + } diff --git a/pacman-c++/util.h b/pacman-c++/util.h index 8bd03bc..4c0ccb0 100644 --- a/pacman-c++/util.h +++ b/pacman-c++/util.h @@ -3,6 +3,9 @@ #include "constants.h" #include "actor.h" +#include "pacman.pb.h" + +class QTcpSocket; namespace Util { Transmission::map_t createUninitialisedMap(); @@ -16,5 +19,11 @@ namespace Util { Transmission::field_t def = -1); Actor::Movement transmissionMovementToActor(Transmission::field_t field, Actor::Movement def = Actor::Movement(-1)); + + void QByteArrayToStdString(const QByteArray& arr, std::string& str); + + // send packet with error check and flush + void sendPacket(const ::google::protobuf::Message& packet, QTcpSocket *socket); + void sendPacket(const char *data, unsigned int length, QTcpSocket *socket); } #endif // UTIL_H -- cgit v1.2.3