/* VierGewinnt - A simple 4-in-a-row network game * * Copyright (c) 2008 by Sebastian Lohff, seba@seba-geek.de * http://www.seba-geek.de * * This file is part of VierGewinnt. * * VierGewinnt is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * VierGewinnt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VierGewinnt. If not, see . */ #include "findserver.h" #include #include #include FindServerWidget::FindServerWidget(QWidget *parent) : QWidget(parent) { setFixedSize(640, 480); setWindowTitle(tr("Sebas Netzwerk-VierGewinnt Client")+" - "+tr("Serverliste")); masterserver = "1.proj.seba-geek.de"; // srv1.proj.seba-geek.de masterport = 31415; // net stuff mysock = new QTcpSocket; connect(mysock, SIGNAL(connected()), this, SLOT(procNet())); connect(mysock, SIGNAL(readyRead()), this, SLOT(procNet())); connect(mysock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(procNetError(QAbstractSocket::SocketError))); connect(mysock, SIGNAL(disconnected()), this, SLOT(procNetDisconnect())); // dialoge masterdialog = new SelectMasterDialog(this); cgamedialog = new CreateGameDialog(mysock); /* , this */ vwinwid = new VierGewinntWidget(mysock, this); about = new AboutDialog(this); // networkbrowser nettable = new QTreeWidget; nettable->setColumnCount(5); // nettable->setMaximumWidth(400); QStringList header; header << tr("Id") << tr("Spielname") << tr("Spieler") << tr("Spielfeld") << tr("Gewinnt") << ""; nettable->setHeaderLabels(header); // nettable->resizeColumnToContents(0); // nettable->resizeColumnToContents(1); // nettable->resizeColumnToContents(2); // buttonreihe buttonrow = new QHBoxLayout; refresh = new QPushButton(tr("Erneuern")); connect(refresh, SIGNAL(clicked()), this, SLOT(refreshServerList())); create = new QPushButton(tr("Erstellen")); connect(create, SIGNAL(clicked()), this, SLOT(createGame())); join = new QPushButton(tr("Beitreten")); connect(join, SIGNAL(clicked()), this, SLOT(joinGame())); othermaster = new QPushButton(tr("Anderer Masterserver")); connect(othermaster, SIGNAL(clicked()), this, SLOT(changeMaster())); butabout = new QPushButton(tr("Über")); connect(butabout, SIGNAL(clicked()), about, SLOT(exec())); buttonrow->addWidget(refresh); buttonrow->addWidget(create); buttonrow->addWidget(join); buttonrow->addStretch(); buttonrow->addWidget(othermaster); buttonrow->addWidget(butabout); // network drunter status = new QTextEdit; status->setReadOnly(true); status->setMaximumHeight(80); addLog(tr("Drücke Erneuern um eine Serverliste zu erhalten")); // layout stuff layout = new QVBoxLayout; layout->addWidget(nettable); layout->addLayout(buttonrow); layout->addWidget(status); setLayout(layout); loginstate = 0; refreshonconnect = false; ingame = false; } void FindServerWidget::refreshServerList() { if(mysock->state()==QTcpSocket::UnconnectedState) { refreshonconnect = true; startConnect(); } else { QTextStream sockstream(mysock); addLog(tr("Fordere Liste an...")); nettable->clear(); sockstream << "LIST\n"; } } void FindServerWidget::changeMaster() { // this->hide(); masterdialog->setData(masterserver, masterport); masterdialog->show(); if(masterdialog->exec()== QDialog::Accepted) { masterserver = masterdialog->getMasterServer(); masterport = masterdialog->getMasterPort(); mysock->close(); startConnect(); } } void FindServerWidget::createGame() { if(mysock->state()==QTcpSocket::UnconnectedState) startConnect(); // this->setDisabled(true); // this->hide(); // cgamedialog->reset(); cgamedialog->show(); if(cgamedialog->exec()== QDialog::Accepted) { addLog(tr("Spiel erstellt")); vwinwid->init(7, 6); qDebug() << "i am still here!"; } else { // this->setDisabled(false); // mysock->close(); } // this->show(); } void FindServerWidget::joinGame() { QTreeWidgetItem *myitem = nettable->currentItem(); if(myitem==0) { QMessageBox msgbox(this); msgbox.setText(tr("Es wurde kein Spiel zum beitreten ausgewählt")); msgbox.exec(); return; } if(mysock->state()==QTcpSocket::UnconnectedState) startConnect(); // initing the field (here we have the data) vwinwid->init(7, 6); // to be changed when custom fields are allowed // get id int gameid = myitem->text(0).toInt(); addLog(tr("Trete Spiel bei..")); QTextStream mytext(mysock); mytext << "JOIN " << gameid << "\n"; } void FindServerWidget::procNet() { QTextStream sockstream(mysock); QString tmpbuf; switch(loginstate) { case 0:{ sockstream << "VERSION viergewinnt-qt\n"; loginstate++; }break; case 1: tmpbuf = mysock->readLine(); if(tmpbuf.contains("ACK VERSION")) { addLog(tr("Version akzeptiert")); sockstream << "SELECT VierGewinnt\n"; loginstate++; } else { addLog(tr("Version nicht akzeptiert, kein GNS-Server!")); mysock->close(); } break; case 2: tmpbuf = mysock->readLine(); if(tmpbuf.contains("ACK SELECT")) { loginstate++; addLog(tr("Modul ausgewählt")); if(refreshonconnect) { refreshServerList(); refreshonconnect = false; } } else { addLog(tr("VierGewinnt-Modul nicht gefunden!")); mysock->close(); } break; default: // list, join or error // tmpbuf = mysock->readLine(); // addLog("Got INput: "+sockstream.readLine()); do { QTextStream sockstream2(mysock->readLine()); sockstream2 >> tmpbuf; if(tmpbuf=="ERROR") { sockstream2 >> tmpbuf; int myerrno = tmpbuf.toInt(); if(myerrno==121) { addLog(tr("Keine Spiele offen :(")); } else if(myerrno==125) { addLog(tr("Konnte nicht beitreten: Spiel voll")); } else if(myerrno==124) { addLog(tr("Spiel konnte nicht gefunden werden")); } else if(tmpbuf=="Not") { sockstream2 >> tmpbuf; if(tmpbuf=="your") { vwinwid->ackAdd(false); } } else if(tmpbuf=="Row") { vwinwid->ackAdd(false); } else { qDebug() << "Unbekannter Fehler: " << tmpbuf; // addLog(tr("Unbekannter error: ")+tmpbuf); } } else if(tmpbuf=="GAME") { QStringList qstrlst; QString tmpbuf2; sockstream2 >> tmpbuf; // id qstrlst << tmpbuf; sockstream2 >> tmpbuf2; // player in sockstream2 >> tmpbuf; // player max tmpbuf2 += "/"; tmpbuf2 += tmpbuf; sockstream2 >> tmpbuf; // game's name qstrlst << tmpbuf; qstrlst << tmpbuf2; sockstream2 >> tmpbuf2; // x sockstream2 >> tmpbuf; // y tmpbuf2 += "x"; tmpbuf2 += tmpbuf; qstrlst << tmpbuf2; sockstream2 >> tmpbuf; // for the win qstrlst << tmpbuf; nettable->addTopLevelItem(new QTreeWidgetItem(qstrlst)); } else if(tmpbuf=="ACK") { sockstream2 >> tmpbuf; if(tmpbuf=="CREATE") { addLog("Spiel erstellt, warte auf Mitspieler"); vwinwid->clientExited(); this->hide(); vwinwid->show(); } else if(tmpbuf=="JOIN") { // set data to mainwindow goToGameWindow(); } else if(tmpbuf=="ADD") { vwinwid->ackAdd(true); } } else if(tmpbuf=="INFO") { sockstream2 >> tmpbuf; if(tmpbuf=="START") { vwinwid->startGame(); qDebug() << "Game Started!"; } else if(tmpbuf=="TURN") { sockstream2 >> tmpbuf; vwinwid->setTurn(tmpbuf.toInt()==1); } else if(tmpbuf=="ADD") { sockstream2 >> tmpbuf; vwinwid->add(tmpbuf.toInt(), VierGewinntWidget::o); } else if(tmpbuf=="GAME") { sockstream2 >> tmpbuf; if(tmpbuf=="STOP") { vwinwid->clientExited(); } } else if(tmpbuf=="STATUS") { sockstream2 >> tmpbuf; vwinwid->newGame(tmpbuf=="WON"); // REQ NEW GAME Message ignored, handled here } else if(tmpbuf=="CLIENT") { sockstream2 >> tmpbuf; if(tmpbuf=="NEW") { vwinwid->ackNewGame(); } } else if(tmpbuf=="NEW") { sockstream2 >> tmpbuf; if(tmpbuf=="GAME") { vwinwid->startGame(); } } else if(tmpbuf=="SCORE") { QString tmpbuf2; sockstream2 >> tmpbuf; sockstream2 >> tmpbuf2; vwinwid->setScore(tmpbuf.toInt(), tmpbuf2.toInt()); } } else { qDebug() << "Unhandled TMPBUF: " << tmpbuf; } } while(!sockstream.atEnd()); break; } } void FindServerWidget::procNetError(QAbstractSocket::SocketError e) { switch(e) { case QAbstractSocket::HostNotFoundError: addLog(tr("Fehler: Der Master-Server Hostname konnte nicht aufgelöst werden!")); break; case QAbstractSocket::ConnectionRefusedError: addLog(tr("Fehler: Verbindungsversuch zum Master-Server ist fehlgeschlagen!")); break; case QAbstractSocket::RemoteHostClosedError: procNetDisconnect(); break; default: addLog(tr("Netzwerkfehler: '%1'").arg(mysock->errorString())); break; } qDebug() << "Networ error: " << mysock->errorString(); } void FindServerWidget::procNetDisconnect() { vwinwid->hide(); this->show(); nettable->clear(); addLog(tr("Die Verbindung zum Masterserver wurde getrennt.")); } void FindServerWidget::addLog(QString str) { status->append(str); qDebug() << "Log: " << str; } void FindServerWidget::startConnect() { loginstate = 0; ingame = false; addLog((tr("Versuche Verbindung zu ")+masterserver+" ...")); mysock->connectToHost(masterserver, masterport); } void FindServerWidget::goToGameWindow() { qDebug() << "SHOW togamewindow"; this->hide(); vwinwid->startGame(); vwinwid->show(); }