File: lobby.h

package info (click to toggle)
vcmi 1.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: contrib
  • in suites: bookworm
  • size: 14,672 kB
  • sloc: cpp: 181,738; sh: 220; python: 178; ansic: 69; objc: 66; xml: 59; makefile: 34
file content (188 lines) | stat: -rw-r--r-- 4,733 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
 * lobby.h, part of VCMI engine
 *
 * Authors: listed in file AUTHORS in main folder
 *
 * License: GNU General Public License v2.0 or later
 * Full text of license available in license.txt file, in main folder
 *
 */
#pragma once

#include <QTcpSocket>
#include <QAbstractSocket>

const unsigned int ProtocolVersion = 3;
const std::string ProtocolEncoding = "utf8";

class ProtocolError: public std::runtime_error
{
public:
	ProtocolError(const char * w): std::runtime_error(w) {}
};

enum ProtocolConsts
{
	//client consts
	GREETING, USERNAME, MESSAGE, VERSION, CREATE, JOIN, LEAVE, KICK, READY, FORCESTART,

	//server consts
	SESSIONS, CREATED, JOINED, KICKED, SRVERROR, CHAT, START, STATUS, HOST, MODS, CLIENTMODS
};

const QMap<ProtocolConsts, QString> ProtocolStrings
{
	//=== client commands ===
	
	//handshaking with server
	//%1: first byte is protocol_version, then size of encoding string in bytes, then encoding string
	//%2: client name
	//%3: VCMI version
	{GREETING, "%1<GREETINGS>%2<VER>%3"},
	
	//[unsupported] autorization with username
	//%1: username
	{USERNAME, "<USER>%1"},
	
	//sending message to the chat
	//%1: message text
	{MESSAGE, "<MSG>%1"},
	
	//create new room
	//%1: room name
	//%2: password for the room
	//%3: max number of players
	//%4: mods used by host
	// each mod has a format modname&modversion, mods should be separated by ; symbol
	{CREATE, "<NEW>%1<PSWD>%2<COUNT>%3<MODS>%4"},
	
	//join to the room
	//%1: room name
	//%2: password for the room
	//%3: list of mods used by player
	// each mod has a format modname&modversion, mods should be separated by ; symbol
	{JOIN, "<JOIN>%1<PSWD>%2<MODS>%3"},
	
	//leave the room
	//%1: room name
	{LEAVE, "<LEAVE>%1"},
	
	//kick user from the current room
	//%1: player username
	{KICK, "<KICK>%1"},
	
	//signal that player is ready for game
	//%1: room name
	{READY, "<READY>%1"},
	
	//[unsupported] start session immediately
	//%1: room name
	{FORCESTART, "<FORCESTART>%1"},

	//=== server commands ===
	//server commands are started from :>>, arguments are enumerated by : symbol
	
	//new session was created
	//arg[0]: room name
	{CREATED, "CREATED"},
	
	//list of existing sessions
	//arg[0]: amount of sessions, following arguments depending on it
	//arg[x]: session name
	//arg[x+1]: amount of players in the session
	//arg[x+2]: total amount of players allowed
	//arg[x+3]: True if session is protected by password
	{SESSIONS, "SESSIONS"},
	
	//user has joined to the session
	//arg[0]: session name
	//arg[1]: username (who was joined)
	{JOINED, "JOIN"},
	
	//user has left the session
	//arg[0]: session name
	//arg[1]: username (who has left)
	{KICKED, "KICK"},
	
	//session has been started
	//arg[0]: session name
	//arg[1]: uuid to be used for connection
	{START, "START"},
	
	//host ownership for the game session
	//arg[0]: uuid to be used by vcmiserver
	//arg[1]: amount of players (clients) to be connected
	{HOST, "HOST"},
	
	//room status
	//arg[0]: amount of players, following arguments depending on it
	//arg[x]: player username
	//arg[x+1]: True if player is ready
	{STATUS, "STATUS"}, //joined_players:player_name:is_ready
	
	//server error
	//arg[0]: error message
	{SRVERROR, "ERROR"},
	
	//mods used in the session by host player
	//arg[0]: amount of mods, following arguments depending on it
	//arg[x]: mod name
	//arg[x+1]: mod version
	{MODS, "MODS"},
	
	//mods used by user
	//arg[0]: username
	//arg[1]: amount of mods, following arguments depending on it
	//arg[x]: mod name
	//arg[x+1]: mod version
	{CLIENTMODS, "MODSOTHER"},
	
	//received chat message
	//arg[0]: sender username
	//arg[1]: message text
	{CHAT, "MSG"}
};

class ServerCommand
{
public:
	ServerCommand(ProtocolConsts, const QStringList & arguments);

	const ProtocolConsts command;
	const QStringList arguments;
};

class SocketLobby : public QObject
{
	Q_OBJECT
public:
	explicit SocketLobby(QObject *parent = 0);
	void connectServer(const QString & host, int port, const QString & username, int timeout);
	void disconnectServer();
	void requestNewSession(const QString & session, int totalPlayers, const QString & pswd, const QMap<QString, QString> & mods);
	void requestJoinSession(const QString & session, const QString & pswd, const QMap<QString, QString> & mods);
	void requestLeaveSession(const QString & session);
	void requestReadySession(const QString & session);

	void send(const QString &);

signals:

	void text(QString);
	void receive(QString);
	void disconnect();

public slots:

	void connected();
	void disconnected();
	void bytesWritten(qint64 bytes);
	void readyRead();

private:
	QTcpSocket *socket;
	bool isConnected = false;
	QString username;
};

QString prepareModsClientString(const QMap<QString, QString> & mods);