Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

349 řádky
9.8 KiB

/* 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 <http://www.gnu.org/licenses/>.
*/
#include "findserver.h"
#include <QtNetwork>
#include <QDataStream>
#include <QtDebug>
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("<EFBFBD>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<EFBFBD>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<65>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<65>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<65>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();
}