From 3fd1334e6d5339cad07ac4e4e23991a73d960a8e Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 14 Apr 2011 17:29:46 +0200 Subject: add commandline options to server (not fully done yet) fix client crash when sound is not available --- pacman-c++/server.cpp | 146 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 134 insertions(+), 12 deletions(-) (limited to 'pacman-c++/server.cpp') diff --git a/pacman-c++/server.cpp b/pacman-c++/server.cpp index 51dcc24..50ee3b7 100644 --- a/pacman-c++/server.cpp +++ b/pacman-c++/server.cpp @@ -1,18 +1,24 @@ #include "server.h" - -#include -#include #include "util.h" #include "pacman.pb.h" #include "block.h" +#include "anyoption.h" +#include +#include +#include Server::Server(QWidget *parent) - : SceneHolder(parent) + : SceneHolder(parent), m_bindaddress(QHostAddress::Any), + m_port(Constants::Networking::port), m_numbots(0) { + /* determine max players by using order array */ + for(m_maxplayers = 0; Color::order[m_maxplayers] != Color::none; ++m_maxplayers); +} - qDebug() << "[Server] Waiting for clients"; - waitForClientConnections(); - qDebug() << "[Server] All Clients connected"; +bool Server::run() +{ + if (!waitForClientConnections()) + return false; Transmission::map_t map = Util::createDemoMap(); updateMap(map); @@ -22,6 +28,7 @@ Server::Server(QWidget *parent) QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(tick())); timer->start(Constants::tick); + return true; } void Server::tick() @@ -147,12 +154,21 @@ invalid_direction: return map; } -void Server::waitForClientConnections() +bool Server::waitForClientConnections() { - QTcpServer *tcpSrv = new QTcpServer(this); // server must stay alive as long as sockets (qt parent mem mechanism) - tcpSrv->listen(QHostAddress::Any, Constants::Networking::port); + QTcpServer *tcpSrv = new QTcpServer(this); + tcpSrv->listen(m_bindaddress, m_port); + if (!tcpSrv->isListening()) + { + qCritical() << "Error while creating socket:" << qPrintable(tcpSrv->errorString()); + return false; + } + qDebug() << "[Server] Listening on:" + << qPrintable(QString("%1:%2").arg(tcpSrv->serverAddress().toString()) + .arg(tcpSrv->serverPort())); + qDebug() << "[Server] Waiting for clients"; ProtoBuf::WhoAmI packet; #define SINGLE #ifdef SINGLE @@ -177,6 +193,9 @@ void Server::waitForClientConnections() qDebug() << "[Connect] New Player: color=" << color; } + + qDebug() << "[Server] All Clients connected"; + return true; } void Server::sendUpdate(Transmission::map_t map) @@ -229,6 +248,103 @@ void Server::keyPressUpdate() } } +bool Server::parseCommandline() +{ + AnyOption opt; + opt.setVerbose(); + + /* usage strings must remain valid until parsing is done */ + QString exec = QFileInfo(qApp->applicationFilePath()).fileName(); + QByteArray usage; + QTextStream out(&usage, QIODevice::ReadWrite | QIODevice::Text); + out << "Usage: " << exec << " [OPTION]" << endl + << "Usage: " << exec << " -h" << endl + << endl; + out << " -b, --bind " << endl + << " Specifies the ip address on which the server listens for connections" << endl + << " Default: " << m_bindaddress.toString() << endl + << endl; + opt.setOption("bind", 'b'); + out << " -p, --port " << endl + << " Specifies the port on which the server listens for connections" << endl + << " Default: " << m_port << endl + << endl; + opt.setOption("port", 'p'); + out << " -m, --maxplayers [1.." << m_maxplayers << "]" << endl + << " Specifies the maximum number of players/pacmans" << endl + << " Default: " << m_maxplayers << endl + << endl; + opt.setOption("maxplayers", 'm'); + out << " --bots [0..maxplayers-1]" << endl + << " Specifies the number of AI pacmans/bots" << endl + << " Default: " << m_numbots << endl + << endl; + opt.setOption("bots"); + out << " -h, --help" << endl + << " Prints this help message" << endl; + opt.setFlag("help", 'h'); + out.flush(); + opt.addUsage(usage.constData()); + opt.processCommandArgs(qApp->argc(), qApp->argv()); + + if (opt.getFlag("help") || opt.getFlag('h')) + { + opt.printUsage(); + return false; + } + + if (opt.getValue("port") != NULL) + { + bool ok; + m_port = QString(opt.getValue("port")).toUInt(&ok); + if (!ok || m_port < 1 || m_port > 65535) + { + qCritical() << "Invalid port-option:" << opt.getValue("port") << endl + << "Port must be between 1 and 65535"; + return false; + } + } + + if (opt.getValue("bind") != NULL) + { + m_bindaddress = opt.getValue("bind"); + if (m_bindaddress.isNull()) + { + qCritical() << "Invalid bind-option:" << opt.getValue("bind") << endl + << "Bind address must be an ip address"; + return false; + } + } + + if (opt.getValue("maxplayers") != NULL) + { + bool ok; + unsigned int maxplayers = QString(opt.getValue("maxplayers")).toUInt(&ok); + if (!ok || maxplayers < 1 || maxplayers > m_maxplayers) + { + qCritical() << "Invalid maxplayers-option:" << opt.getValue("maxplayers") << endl + << "Maxplayers must be between 1 and" << m_maxplayers; + return false; + } + m_maxplayers = maxplayers; + } + + if (opt.getValue("bots") != NULL) + { + bool ok; + unsigned int numbots = QString(opt.getValue("bots")).toUInt(&ok); + if (!ok || numbots >= m_maxplayers) + { + qCritical() << "Invalid numbots-options:" << opt.getValue("bots") << endl + << "AI pacmans/bots must be between 0 and" << m_maxplayers - 1; + return false; + } + m_numbots = numbots; + } + + return true; +} + bool Constants::server = true; int main(int argc, char ** argv) @@ -244,8 +360,14 @@ int main(int argc, char ** argv) qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime())); - Server Server; - int ret = app.exec(); + int ret = 0; + Server server; + if (!ret && !server.parseCommandline()) + ret = 1; + if (!ret && !server.run()) + ret = 1; + if (!ret) + ret = app.exec(); /* Delete all global objects allocated by libprotobuf */ google::protobuf::ShutdownProtobufLibrary(); -- cgit v1.2.3