-
Notifications
You must be signed in to change notification settings - Fork 0
/
room.cpp
121 lines (102 loc) · 2.96 KB
/
room.cpp
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
#include "room.h"
#include <QDebug>
#include "client.h"
Room::Room(const QString &name, const QString &pin, QObject *parent)
: Server(parent), name_(name), pin_(pin) {
connect(this, &Room::join, this, &Room::joined);
connect(this, &Server::leave, this, &Room::left);
}
Room::~Room() {
qDebug() << "Room" << name_ << "destroyed";
}
void Room::welcome(Client *client) {
client->registerProtocol(new Talk(this, client));
emit join(client);
}
void Room::joined(Client *client) {
users_[client->name()] = client;
emit client->send(userNameList(client));
QString msg(client->name());
msg.append(" has joined.");
broadcast(QStringList(msg), client);
}
void Room::left(Client *client) {
users_.erase(client->name());
QString msg(client->name());
msg.append(" has left.");
broadcast(QStringList(msg), client);
}
QStringList Room::userNameList(Client* client) {
QStringList list;
for (auto& it : users_) {
Client *user = it.second;
list << " * ";
list.last().append(user->name());
if (user == client) {
list.last().append(" (** this is you)");
}
}
return list;
}
void Room::broadcast(QStringList msg, Client *except) {
for (auto& it : users_) {
Client *user = it.second;
if (user != except) {
emit user->send(msg);
}
}
}
const char *kActionLeave = "/leave";
const char *kActionWho = "/who";
const char *kActionWhisper = "/whisper";
Talk::Talk(Room *room, Client *client) : room_(room), client_(client) {}
Talk::~Talk() {
qDebug() << "Talk protocol destroyed";
}
bool Talk::execute(const QString &input, QStringList *output) {
QString head = Command::ParseHead(input);
if (head == kActionLeave) {
emit room_->leave(client_);
emit client_->leave(room_);
return true;
} else if (head == kActionWhisper) {
Whisper* w = new Whisper(room_, client_);
if (!w->execute(input, output)) {
client_->registerProtocol(w);
} else {
delete w;
}
} else if (head == kActionWho) {
emit client_->send(room_->userNameList(client_));
} else {
QString msg = client_->name();
msg.append(": ").append(input);
room_->broadcast(QStringList(msg));
}
return false;
}
Whisper::Whisper(Room *room, Client *client)
: Command(), room_(room), client_(client) {
AddArgument("name", "the name of the person to whisper")->token = true;
AddArgument("msg", "the message to send");
}
Whisper::~Whisper() {
qDebug() << "Whisper protocol destroyed";
}
bool Whisper::execute(QStringList *output) {
auto it = room_->users_.find(args_[0].value);
if (it == room_->users_.end()) {
*output << "User ";
output->last().append(args_[0].value).append(" is not in the room.");
index_ = 0;
return false;
} else {
QStringList msg;
msg << "From ";
msg.last().append(client_->name()).append(": ").append(args_[1].value);
emit it->second->send(msg);
*output << "To ";
output->last().append(args_[0].value).append(": ").append(args_[1].value);
return true;
}
}