Skip to content

Commit cc50bb2

Browse files
committed
fix user lobby creation loop
Fix user lobby creation/deletion. Delete user lobby when last player leaves. Enforce lobby max capacity. Don't add twice the same user name. Add symbols for server opcodes. Use std::find/find_if
1 parent 853a693 commit cc50bb2

File tree

3 files changed

+187
-129
lines changed

3 files changed

+187
-129
lines changed

models.cpp

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,21 @@
55

66
std::vector<LobbyServer *> LobbyServer::servers;
77

8-
void Lobby::addPlayer(std::shared_ptr<Player> player)
8+
void Lobby::addPlayer(Player::Ptr player)
99
{
10-
members.push_back(player);
10+
if (members.size() == capacity) {
11+
player->send(S_LOBBY_FULL);
12+
return;
13+
}
14+
// Only add player if not already there
15+
auto it = std::find_if(members.begin(), members.end(), [&player](const Player::Ptr& member) {
16+
return member->name == player->name;
17+
});
18+
if (it == members.end())
19+
members.push_back(player);
1120

1221
// Confirm Join Lobby
13-
player->send(0x13, player->fromUtf8(name) + " " + player->fromUtf8(player->name));
22+
player->send(S_JOIN_LOBBY_ACK, player->fromUtf8(name) + " " + player->fromUtf8(player->name));
1423

1524
std::vector<std::string> playerNames;
1625
// Send player info to all members
@@ -19,38 +28,39 @@ void Lobby::addPlayer(std::shared_ptr<Player> player)
1928
playerNames.push_back(p->name);
2029
if (p == player)
2130
continue;
22-
p->send(0x30, player->getSendDataPacket());
31+
p->send(S_PLAYER_LIST_ITEM, player->getSendDataPacket());
2332
}
2433
discordLobbyJoined(player->gameId, player->name, name, playerNames);
2534
}
2635

27-
void Lobby::removePlayer(std::shared_ptr<Player> player)
36+
void Lobby::removePlayer(Player::Ptr player)
2837
{
29-
for (auto it = members.begin(); it != members.end(); ++it)
38+
auto it = std::find(members.begin(), members.end(), player);
39+
if (it != members.end())
3040
{
31-
if ((*it) == player)
32-
{
33-
// Remove player from list
34-
members.erase(it);
35-
36-
// Confirm Leave Lobby
37-
player->send(0xCB);
38-
39-
// Tell all members to remove the player
40-
for (auto& p : members)
41-
p->send(0x2C, p->fromUtf8(player->name));
42-
return;
43-
}
41+
// Remove player from list
42+
members.erase(it);
43+
44+
// Confirm Leave Lobby
45+
player->send(S_LEAVE_LOBBY_ACK);
46+
47+
// Tell all members to remove the player
48+
for (auto& p : members)
49+
p->send(S_LOBBY_LEFT, p->fromUtf8(player->name));
50+
if (!permanent && members.empty())
51+
parent.deleteLobby(name);
52+
}
53+
else {
54+
fprintf(stderr, "Player %s not found in lobby %s\n", player->name.c_str(), name.c_str());
4455
}
45-
fprintf(stderr, "Player %s not found in lobby %s\n", player->name.c_str(), name.c_str());
4656
}
4757

4858
void Lobby::sendChat(const std::string& from, const std::string& message) {
4959
for (auto& player : members)
50-
player->send(0x2D, player->fromUtf8(from) + " " + player->fromUtf8(message));
60+
player->send(S_LOBBY_CHAT, player->fromUtf8(from) + " " + player->fromUtf8(message));
5161
}
5262

53-
std::shared_ptr<Team> Lobby::createTeam(std::shared_ptr<Player> creator, const std::string& name, unsigned capacity, const std::string& type)
63+
Team::Ptr Lobby::createTeam(Player::Ptr creator, const std::string& name, unsigned capacity, const std::string& type)
5464
{
5565
Team::Ptr team = Team::create(shared_from_this(), name, capacity, creator);
5666
teams.push_back(team);
@@ -60,36 +70,32 @@ std::shared_ptr<Team> Lobby::createTeam(std::shared_ptr<Player> creator, const s
6070
ss << creator->fromUtf8(name) << ' ' << creator->fromUtf8(creator->name) << ' ' << capacity << " 0 " << gameName;
6171
std::vector<std::string> playerNames;
6272
for (auto& p : members) {
63-
p->send(0x28, ss.str());
73+
p->send(S_NEW_TEAM, ss.str());
6474
playerNames.push_back(p->name);
6575
}
6676
discordGameCreated(creator->gameId, creator->name, name, playerNames);
6777

6878
return team;
6979
}
70-
void Lobby::deleteTeam(std::shared_ptr<Team> team)
80+
void Lobby::deleteTeam(Team::Ptr team)
7181
{
72-
for (auto it = teams.begin(); it != teams.end(); ++it)
73-
{
74-
if ((*it) == team) {
75-
teams.erase(it);
76-
break;
77-
}
78-
}
82+
auto it = std::find(teams.begin(), teams.end(), team);
83+
if (it != teams.end())
84+
teams.erase(it);
7985
// Tell all members to remove team
8086
for (auto& p : members)
81-
p->send(0x3A, p->fromUtf8(team->name));
87+
p->send(S_TEAM_DELETED, p->fromUtf8(team->name));
8288
}
8389

84-
std::shared_ptr<Team> Lobby::getTeam(const std::string& name)
90+
Team::Ptr Lobby::getTeam(const std::string& name)
8591
{
8692
for (auto& team : teams)
8793
if (team->name == name)
8894
return team;
8995
return nullptr;
9096
}
9197

92-
Player::Player(std::shared_ptr<LobbyConnection> connection, LobbyServer& server)
98+
Player::Player(LobbyConnection::Ptr connection, LobbyServer& server)
9399
: sharedMem(0x1e), gameId(server.getGameId()), server(server), connection(connection)
94100
{
95101
}
@@ -133,7 +139,7 @@ void Player::disconnect(bool sendDCPacket)
133139

134140
// Tell client to d/c if actually still connected
135141
if (sendDCPacket)
136-
send(0x17);
142+
send(S_DO_DISCONNECT);
137143

138144
// Remove player from everything
139145
if (team) {
@@ -195,17 +201,16 @@ std::vector<uint8_t> Player::getSendDataPacket()
195201

196202
void Player::createTeam(const std::string& name, unsigned capacity, const std::string& type)
197203
{
198-
if (lobby != nullptr)
199-
{
200-
if (lobby->getTeam(name) == nullptr)
201-
{
202-
Team::Ptr newTeam = lobby->createTeam(shared_from_this(), name, capacity, type);
203-
team = newTeam;
204-
return;
205-
}
204+
if (lobby == nullptr)
205+
return;
206+
if (lobby->getTeam(name) == nullptr) {
207+
Team::Ptr newTeam = lobby->createTeam(shared_from_this(), name, capacity, type);
208+
team = newTeam;
209+
}
210+
else {
211+
fprintf(stderr, "WARN: createTeam: team %s already exists\n", name.c_str());
212+
send(S_TEAM_NAME_EXISTS);
206213
}
207-
fprintf(stderr, "WARN: createTeam: team %s already exists\n", name.c_str());
208-
send(0x03); // Name already in use
209214
}
210215
void Player::joinTeam(const std::string& name)
211216
{
@@ -246,7 +251,7 @@ void Player::getExtraMem(const std::string& playerName, int offset, int length)
246251
}
247252
if ((int)player->extraUserMem.size() < offset + length)
248253
player->extraUserMem.resize(offset + length);
249-
send(0x50);
254+
send(S_EXTUSER_MEM_START);
250255
for (uint16_t i = 0; length > 0 && offset < (int)player->extraUserMem.size(); i++)
251256
{
252257
int chunksz = std::min(length, 200);
@@ -255,9 +260,9 @@ void Player::getExtraMem(const std::string& playerName, int offset, int length)
255260
memcpy(&payload[2], &player->extraUserMem[offset], chunksz);
256261
length -= chunksz;
257262
offset += chunksz;
258-
send(0x51, payload);
263+
send(S_EXTUSER_MEM_CHUNK, payload);
259264
}
260-
send(0x52);
265+
send(S_EXTUSER_MEM_END);
261266
}
262267

263268
void Player::startExtraMem(int offset, int length)
@@ -269,7 +274,7 @@ void Player::startExtraMem(int offset, int length)
269274
extraMemEnd = offset + length;
270275
if (extraMemEnd >= (int)extraUserMem.size())
271276
extraUserMem.resize(extraMemEnd);
272-
send(0x4F);
277+
send(S_EXTUSER_MEM_ACK);
273278
}
274279
void Player::setExtraMem(int index, const uint8_t *data, int size)
275280
{
@@ -280,12 +285,12 @@ void Player::setExtraMem(int index, const uint8_t *data, int size)
280285
extraMemOffset += size;
281286
if (extraMemOffset >= extraMemEnd)
282287
extraMemEnd = 0;
283-
send(0x4F);
288+
send(S_EXTUSER_MEM_ACK);
284289
}
285290
void Player::endExtraMem()
286291
{
287292
extraMemEnd = 0;
288-
send(0x4F);
293+
send(S_EXTUSER_MEM_ACK);
289294
}
290295

291296
int Player::send(uint16_t opcode, const uint8_t *payload, unsigned length)

0 commit comments

Comments
 (0)