mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-25 21:38:59 +02:00
Implement command parsing
This commit is contained in:
parent
e54c9af24e
commit
75613a947d
@ -32,6 +32,18 @@ void SocketLobby::disconnectServer()
|
||||
socket->disconnectFromHost();
|
||||
}
|
||||
|
||||
void SocketLobby::requestNewSession(const QString & session, int totalPlayers, const QString & pswd)
|
||||
{
|
||||
const QString sessionMessage = ProtocolStrings[CREATE].arg(session, pswd, QString::number(totalPlayers));
|
||||
send(sessionMessage);
|
||||
}
|
||||
|
||||
void SocketLobby::requestJoinSession(const QString & session, const QString & pswd)
|
||||
{
|
||||
const QString sessionMessage = ProtocolStrings[JOIN].arg(session, pswd);
|
||||
send(sessionMessage);
|
||||
}
|
||||
|
||||
void SocketLobby::send(const QString & msg)
|
||||
{
|
||||
socket->write(qPrintable(msg));
|
||||
@ -42,7 +54,7 @@ void SocketLobby::connected()
|
||||
isConnected = true;
|
||||
emit text("Connected!");
|
||||
|
||||
const QString greetingConst = ProtocolStrings[GREETING].arg(username) + ProtocolStrings[VERSION].arg(QString::fromStdString(GameConstants::VCMI_VERSION));
|
||||
const QString greetingConst = ProtocolStrings[GREETING].arg(username, QString::fromStdString(GameConstants::VCMI_VERSION));
|
||||
send(greetingConst);
|
||||
}
|
||||
|
||||
@ -60,11 +72,15 @@ void SocketLobby::bytesWritten(qint64 bytes)
|
||||
void SocketLobby::readyRead()
|
||||
{
|
||||
qDebug() << "Reading...";
|
||||
emit text(socket->readAll());
|
||||
emit receive(socket->readAll());
|
||||
}
|
||||
|
||||
|
||||
|
||||
ServerCommand::ServerCommand(ProtocolConsts cmd, const QStringList & args):
|
||||
command(cmd),
|
||||
arguments(args)
|
||||
{
|
||||
}
|
||||
|
||||
Lobby::Lobby(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
@ -72,7 +88,8 @@ Lobby::Lobby(QWidget *parent) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
connect(&socketLobby, SIGNAL(text(QString)), this, SLOT(text(QString)));
|
||||
connect(&socketLobby, SIGNAL(text(QString)), this, SLOT(chatMessage(QString)));
|
||||
connect(&socketLobby, SIGNAL(receive(QString)), this, SLOT(dispatchMessage(QString)));
|
||||
}
|
||||
|
||||
Lobby::~Lobby()
|
||||
@ -80,24 +97,128 @@ Lobby::~Lobby()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Lobby::serverCommand(const ServerCommand & command) try
|
||||
{
|
||||
//initialize variables outside of switch block
|
||||
const auto & args = command.arguments;
|
||||
int amount, tagPoint;
|
||||
QString joinStr;
|
||||
switch(command.command)
|
||||
{
|
||||
case ERROR:
|
||||
protocolAssert(args.size());
|
||||
chatMessage("System error:" + args[0]);
|
||||
break;
|
||||
|
||||
case CREATED:
|
||||
protocolAssert(args.size());
|
||||
hostSession = args[0];
|
||||
session = args[0];
|
||||
chatMessage("System: new session started");
|
||||
break;
|
||||
|
||||
case SESSIONS:
|
||||
protocolAssert(args.size());
|
||||
amount = args[0].toInt();
|
||||
protocolAssert(amount * 4 == (args.size() - 1));
|
||||
ui->sessionsTable->setRowCount(amount);
|
||||
|
||||
tagPoint = 1;
|
||||
for(int i = 0; i < amount; ++i)
|
||||
{
|
||||
QTableWidgetItem * sessionNameItem = new QTableWidgetItem(args[tagPoint++]);
|
||||
ui->sessionsTable->setItem(i, 0, sessionNameItem);
|
||||
|
||||
int playersJoined = args[tagPoint++].toInt();
|
||||
int playersTotal = args[tagPoint++].toInt();
|
||||
QTableWidgetItem * sessionPlayerItem = new QTableWidgetItem(QString("%1/%2").arg(playersJoined).arg(playersTotal));
|
||||
ui->sessionsTable->setItem(i, 1, sessionPlayerItem);
|
||||
|
||||
QTableWidgetItem * sessionProtectedItem = new QTableWidgetItem(args[tagPoint++]);
|
||||
ui->sessionsTable->setItem(i, 2, sessionProtectedItem);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case JOINED:
|
||||
case KICKED:
|
||||
protocolAssert(args.size() == 2);
|
||||
joinStr = (command.command == JOINED ? "System: %1 joined to the session %2" : "System: %1 left session %2");
|
||||
|
||||
if(args[1] == username)
|
||||
{
|
||||
chatMessage(joinStr.arg("you", args[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
chatMessage(joinStr.arg(args[1], args[0]));
|
||||
}
|
||||
break;
|
||||
|
||||
case CHAT:
|
||||
protocolAssert(args.size() > 1);
|
||||
QString msg;
|
||||
for(int i = 1; i < args.size(); ++i)
|
||||
msg += args[i];
|
||||
chatMessage(QString("%1: %2").arg(args[0], msg));
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(const ProtocolError & e)
|
||||
{
|
||||
chatMessage(QString("System error: %1").arg(e.what()));
|
||||
}
|
||||
|
||||
void Lobby::dispatchMessage(QString txt) try
|
||||
{
|
||||
if(txt.isEmpty())
|
||||
return;
|
||||
|
||||
QStringList parseTags = txt.split(":>>");
|
||||
protocolAssert(parseTags.size() > 1 && parseTags[0].isEmpty() && !parseTags[1].isEmpty());
|
||||
|
||||
for(int c = 1; c < parseTags.size(); ++c)
|
||||
{
|
||||
QStringList parseArgs = parseTags[c].split(":");
|
||||
protocolAssert(parseArgs.size() > 1);
|
||||
|
||||
auto ctype = ProtocolStrings.key(parseArgs[0]);
|
||||
parseArgs.pop_front();
|
||||
ServerCommand cmd(ctype, parseArgs);
|
||||
serverCommand(cmd);
|
||||
}
|
||||
}
|
||||
catch(const ProtocolError & e)
|
||||
{
|
||||
chatMessage(QString("System error: %1").arg(e.what()));
|
||||
}
|
||||
|
||||
|
||||
void Lobby::chatMessage(QString txt)
|
||||
{
|
||||
QTextCursor curs(ui->chat->document());
|
||||
curs.movePosition(QTextCursor::End);
|
||||
curs.insertText(txt + "\n");
|
||||
}
|
||||
|
||||
void Lobby::protocolAssert(bool expr)
|
||||
{
|
||||
if(!expr)
|
||||
throw ProtocolError("Protocol error");
|
||||
}
|
||||
|
||||
void Lobby::on_messageEdit_returnPressed()
|
||||
{
|
||||
socketLobby.send(ProtocolStrings[MESSAGE].arg(ui->messageEdit->text()));
|
||||
ui->messageEdit->clear();
|
||||
}
|
||||
|
||||
void Lobby::text(QString txt)
|
||||
{
|
||||
QTextCursor curs(ui->chat->document());
|
||||
curs.movePosition(QTextCursor::End);
|
||||
curs.insertText(txt + "\n");
|
||||
}
|
||||
|
||||
void Lobby::on_connectButton_toggled(bool checked)
|
||||
{
|
||||
if(checked)
|
||||
{
|
||||
socketLobby.connectServer(ui->hostEdit->text(), ui->portEdit->text().toInt(), ui->userEdit->text());
|
||||
username = ui->userEdit->text();
|
||||
socketLobby.connectServer(ui->hostEdit->text(), ui->portEdit->text().toInt(), username);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -105,3 +226,18 @@ void Lobby::on_connectButton_toggled(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void Lobby::on_newButton_clicked()
|
||||
{
|
||||
bool ok;
|
||||
QString sessionName = QInputDialog::getText(this, tr("New session"), tr("Session name:"), QLineEdit::Normal, "", &ok);
|
||||
if(ok && !sessionName.isEmpty())
|
||||
socketLobby.requestNewSession(sessionName, 2, ui->passwordInput->text());
|
||||
}
|
||||
|
||||
void Lobby::on_joinButton_clicked()
|
||||
{
|
||||
auto * item = ui->sessionsTable->item(ui->sessionsTable->currentRow(), 0);
|
||||
if(item)
|
||||
socketLobby.requestJoinSession(item->text(), ui->passwordInput->text());
|
||||
}
|
||||
|
||||
|
@ -5,17 +5,46 @@
|
||||
#include <QTcpSocket>
|
||||
#include <QAbstractSocket>
|
||||
|
||||
class ProtocolError: public std::runtime_error
|
||||
{
|
||||
public:
|
||||
ProtocolError(const char * w): std::runtime_error(w) {}
|
||||
};
|
||||
|
||||
enum ProtocolConsts
|
||||
{
|
||||
GREETING, USERNAME, MESSAGE, VERSION
|
||||
//client consts
|
||||
GREETING, USERNAME, MESSAGE, VERSION, CREATE, JOIN,
|
||||
|
||||
//server consts
|
||||
SESSIONS, CREATED, JOINED, KICKED, ERROR, CHAT
|
||||
};
|
||||
|
||||
const QMap<ProtocolConsts, QString> ProtocolStrings
|
||||
{
|
||||
{GREETING, "<GREETINGS>%1"},
|
||||
//client consts
|
||||
{GREETING, "<GREETINGS>%1<VER>%2"},
|
||||
{USERNAME, "<USER>%1"},
|
||||
{MESSAGE, "<MSG>%1"},
|
||||
{VERSION, "<VER>%1"}
|
||||
{CREATE, "<NEW>%1<PSWD>%2<COUNT>%3"},
|
||||
{JOIN, "<JOIN>%1<PSWD>%2"},
|
||||
|
||||
//server consts
|
||||
{CREATED, "CREATED"},
|
||||
{SESSIONS, "SESSIONS"}, //amount:session_name:joined_players:total_players:is_protected
|
||||
{JOINED, "JOIN"}, //session_name:username
|
||||
{KICKED, "KICK"}, //session_name:username
|
||||
{ERROR, "ERROR"},
|
||||
{CHAT, "MSG"} //username:message
|
||||
};
|
||||
|
||||
class ServerCommand
|
||||
{
|
||||
public:
|
||||
ServerCommand(ProtocolConsts, const QStringList & arguments);
|
||||
|
||||
const ProtocolConsts command;
|
||||
const QStringList arguments;
|
||||
};
|
||||
|
||||
class SocketLobby : public QObject
|
||||
@ -25,12 +54,15 @@ public:
|
||||
explicit SocketLobby(QObject *parent = 0);
|
||||
void connectServer(const QString & host, int port, const QString & username);
|
||||
void disconnectServer();
|
||||
void requestNewSession(const QString & session, int totalPlayers, const QString & pswd);
|
||||
void requestJoinSession(const QString & session, const QString & pswd);
|
||||
|
||||
void send(const QString &);
|
||||
|
||||
signals:
|
||||
|
||||
void text(QString);
|
||||
void receive(QString);
|
||||
|
||||
public slots:
|
||||
|
||||
@ -61,13 +93,25 @@ public:
|
||||
private slots:
|
||||
void on_messageEdit_returnPressed();
|
||||
|
||||
void text(QString);
|
||||
void chatMessage(QString);
|
||||
void dispatchMessage(QString);
|
||||
void serverCommand(const ServerCommand &);
|
||||
|
||||
void on_connectButton_toggled(bool checked);
|
||||
|
||||
void on_newButton_clicked();
|
||||
|
||||
void on_joinButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::Lobby *ui;
|
||||
SocketLobby socketLobby;
|
||||
QString hostSession;
|
||||
QString session;
|
||||
QString username;
|
||||
|
||||
private:
|
||||
void protocolAssert(bool);
|
||||
};
|
||||
|
||||
#endif // LOBBY_MOC_H
|
||||
|
@ -110,6 +110,15 @@
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QTableWidget" name="sessionsTable">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Session</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user