Skip to content

Commit aaac37c

Browse files
Add sort and limit support to listing lobbies
Allows sorting the list() result on any property and adds support to limit how many lobbies should be returned.
1 parent 5c987cb commit aaac37c

13 files changed

Lines changed: 101 additions & 38 deletions

File tree

features/custom-data.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ Feature: customData on lobbies can be used for filtering and extra information
8585
"""
8686
And "yellow" receives the network event "lobby" with the argument "19yrzmetd2bn7"
8787

88-
When "blue" requests lobbies with this filter:
88+
When "blue" requests lobbies with:
8989
"""json
9090
{
9191
"status": "open"
@@ -104,7 +104,7 @@ Feature: customData on lobbies can be used for filtering and extra information
104104
}
105105
"""
106106

107-
When "blue" requests lobbies with this filter:
107+
When "blue" requests lobbies with:
108108
"""json
109109
{
110110
"status": "open"

features/lobbies.feature

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@ Feature: Lobby Discovery
66

77
Scenario: List empty lobby set
88
Given "green" is connected as "1u8fw4aph5ypt" and ready for game "f666036d-d9e1-4d70-b0c3-4a68b24a9884"
9-
When "green" requests all lobbies
9+
When "green" requests lobbies with:
10+
"""json
11+
{}
12+
"""
1013
Then "green" should receive 0 lobbies
1114

1215
Scenario: Don't list lobbies from a different game
1316
Given "green" creates a network for game "f666036d-d9e1-4d70-b0c3-4a68b24a9884"
1417
And "blue" is connected as "h5yzwyizlwao" and ready for game "4307bd86-e1df-41b8-b9df-e22afcf084bd"
1518
And "yellow" is connected as "19yrzmetd2bn7" and ready for game "4307bd86-e1df-41b8-b9df-e22afcf084bd"
1619
And "blue,yellow" are joined in a lobby
17-
When "green" requests all lobbies
20+
When "green" requests lobbies with:
21+
"""json
22+
{}
23+
"""
1824
Then "green" should receive 0 lobbies
1925

2026
Scenario: List lobbies that exist
@@ -29,7 +35,10 @@ Feature: Lobby Discovery
2935
"""
3036
And "blue" receives the network event "lobby" with the argument "19yrzmetd2bn7"
3137

32-
When "green" requests all lobbies
38+
When "green" requests lobbies with:
39+
"""json
40+
{}
41+
"""
3342
Then "green" should have received only these lobbies:
3443
| code | playerCount |
3544
| 19yrzmetd2bn7 | 1 |
@@ -54,7 +63,10 @@ Feature: Lobby Discovery
5463
"""
5564
And "yellow" receives the network event "lobby" with the argument "prb67ouj837u"
5665

57-
When "green" requests all lobbies
66+
When "green" requests lobbies with:
67+
"""json
68+
{}
69+
"""
5870
Then "green" should have received only these lobbies:
5971
| code | playerCount | public |
6072
| 3t3cfgcqup9e | 1 | true |
@@ -74,7 +86,7 @@ Feature: Lobby Discovery
7486
| 8qva9vyurwbbl | 54fa57d5-b4bd-401d-981d-2c13de99be27 | 9 | true |
7587
| 9qva9vyurwbbl | f666036d-d9e1-4d70-b0c3-4a68b24a9884 | 10 | true |
7688

77-
When "green" requests lobbies with this filter:
89+
When "green" requests lobbies with:
7890
"""json
7991
{
8092
"playerCount": {
@@ -97,7 +109,7 @@ Feature: Lobby Discovery
97109
| 1qva9vyurwbbl | f666036d-d9e1-4d70-b0c3-4a68b24a9884 | 1 | {"map": "de_dust"} | true | 2020-01-02 |
98110
| 2qva9vyurwbbl | f666036d-d9e1-4d70-b0c3-4a68b24a9884 | 1 | {"map": "de_nuke"} | true | 2020-01-03 |
99111

100-
When "green" requests lobbies with this filter:
112+
When "green" requests lobbies with:
101113
"""json
102114
{
103115
"map": "de_nuke",
@@ -126,7 +138,10 @@ Feature: Lobby Discovery
126138
When "blue" disconnects
127139
Then "blue" receives the network event "close"
128140

129-
When "green" requests all lobbies
141+
When "green" requests lobbies with:
142+
"""json
143+
{}
144+
"""
130145
Then "green" should have received only these lobbies:
131146
| code | playerCount |
132147
| HC6Y | 0 |
@@ -152,7 +167,7 @@ Feature: Lobby Discovery
152167
"""
153168
And "green" receives the network event "lobby" with the argument "19yrzmetd2bn7"
154169

155-
When "blue" requests lobbies with this filter:
170+
When "blue" requests lobbies with:
156171
"""json
157172
{
158173
"map": "de_nuke"
@@ -162,3 +177,20 @@ Feature: Lobby Discovery
162177
| code |
163178
| 19yrzmetd2bn7 |
164179
| 3qva9vyurwbb |
180+
181+
Scenario: Sort lobbies with a custom order
182+
Given "green" is connected as "1u8fw4aph5ypt" and ready for game "f666036d-d9e1-4d70-b0c3-4a68b24a9884"
183+
And these lobbies exist:
184+
| code | game | playerCount | public | created_at |
185+
| 1qva9vyurwbb | f666036d-d9e1-4d70-b0c3-4a68b24a9884 | 1 | true | 2020-01-03 |
186+
| 2qva9vyurwbb | f666036d-d9e1-4d70-b0c3-4a68b24a9884 | 3 | true | 2020-01-02 |
187+
| 3qva9vyurwbb | f666036d-d9e1-4d70-b0c3-4a68b24a9884 | 5 | true | 2020-01-01 |
188+
189+
When "green" requests lobbies with:
190+
| filter | {} |
191+
| sort | { "playerCount": -1 } |
192+
| limit | 2 |
193+
Then "green" should have received only these lobbies:
194+
| code | playerCount |
195+
| 3qva9vyurwbb | 5 |
196+
| 2qva9vyurwbb | 3 |

features/maxPlayers.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Feature: Lobbies can have a maximum number of players
4343
"""
4444
And "yellow" receives the network event "lobby" with the argument "h5yzwyizlwao"
4545

46-
When "yellow" requests lobbies with this filter:
46+
When "yellow" requests lobbies with:
4747
"""json
4848
{}
4949
"""
@@ -58,7 +58,7 @@ Feature: Lobbies can have a maximum number of players
5858
}
5959
"""
6060

61-
When "yellow" requests lobbies with this filter:
61+
When "yellow" requests lobbies with:
6262
"""json
6363
{}
6464
"""

features/password.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Feature: Lobbies can be password protected
6262
"""
6363
And "yellow" receives the network event "lobby" with the argument "h5yzwyizlwao"
6464

65-
When "yellow" requests lobbies with this filter:
65+
When "yellow" requests lobbies with:
6666
"""json
6767
{}
6868
"""
@@ -76,7 +76,7 @@ Feature: Lobbies can be password protected
7676
"password": ""
7777
}
7878
"""
79-
And "yellow" requests lobbies with this filter:
79+
And "yellow" requests lobbies with:
8080
"""json
8181
{}
8282
"""

features/support/steps/network.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -210,21 +210,25 @@ When('{string} leaves the lobby', async function (this: World, playerName: strin
210210
await player.network.leave()
211211
})
212212

213-
When('{string} requests all lobbies', async function (this: World, playerName: string) {
213+
When('{string} requests lobbies with:', async function (this: World, playerName: string, payload: string | DataTable) {
214214
const player = this.players.get(playerName)
215215
if (player == null) {
216216
throw new Error('no such player')
217217
}
218-
const lobbies = await player.network.list()
219-
player.lastReceivedLobbies = lobbies
220-
})
218+
let filter: any
219+
let sort: Record<string, 1 | -1> | undefined
220+
let limit: number | undefined
221221

222-
When('{string} requests lobbies with this filter:', async function (this: World, playerName: string, filter: string) {
223-
const player = this.players.get(playerName)
224-
if (player == null) {
225-
throw new Error('no such player')
222+
if (typeof payload !== 'string') {
223+
const argsHash = payload.rowsHash()
224+
filter = argsHash.filter != null ? JSON.parse(argsHash.filter) : undefined
225+
sort = argsHash.sort != null ? JSON.parse(argsHash.sort) : undefined
226+
limit = argsHash.limit != null ? parseInt(argsHash.limit, 10) : undefined
227+
} else {
228+
filter = JSON.parse(payload)
226229
}
227-
const lobbies = await player.network.list(JSON.parse(filter))
230+
231+
const lobbies = await player.network.list(filter, sort, limit)
228232
player.lastReceivedLobbies = lobbies
229233
})
230234

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/jackc/pgx/v5 v5.7.6
99
github.com/koenbollen/logging v0.0.0-20230520102501-e01d64214504
1010
github.com/ory/dockertest/v3 v3.12.0
11-
github.com/poki/mongodb-filter-to-postgres v1.0.6
11+
github.com/poki/mongodb-filter-to-postgres v1.0.7
1212
github.com/rs/cors v1.11.1
1313
github.com/rs/xid v1.6.0
1414
go.uber.org/zap v1.27.0

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
9898
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
9999
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
100100
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
101-
github.com/poki/mongodb-filter-to-postgres v1.0.6 h1:K33b8bng07GewuyTipTzVY5qjLVC3q+cURDmklzSLdc=
102-
github.com/poki/mongodb-filter-to-postgres v1.0.6/go.mod h1:AccQTAURp16s/pIp9pTuVqY64kyDJ5Dre4fNA1efO6A=
101+
github.com/poki/mongodb-filter-to-postgres v1.0.7 h1:PH6zGVAEptv0nH/eo4Q+ZRLqc/51M3Giihmmq/hY7wE=
102+
github.com/poki/mongodb-filter-to-postgres v1.0.7/go.mod h1:AccQTAURp16s/pIp9pTuVqY64kyDJ5Dre4fNA1efO6A=
103103
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
104104
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
105105
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=

internal/signaling/peer.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ func (p *Peer) HandleListPacket(ctx context.Context, packet ListPacket) error {
352352
if p.ID == "" {
353353
return fmt.Errorf("peer not connected")
354354
}
355-
lobbies, err := p.store.ListLobbies(ctx, p.Game, packet.Filter)
355+
lobbies, err := p.store.ListLobbies(ctx, p.Game, packet.Filter, packet.Sort, packet.Limit)
356356
if err != nil {
357357
return err
358358
}
@@ -462,13 +462,14 @@ func (p *Peer) HandleJoinPacket(ctx context.Context, packet JoinPacket) error {
462462

463463
err := p.store.JoinLobby(ctx, p.Game, packet.Lobby, p.ID, packet.Password)
464464
if err != nil {
465-
if err == stores.ErrNotFound {
465+
switch err {
466+
case stores.ErrNotFound:
466467
util.ReplyError(ctx, p.conn, util.ErrorWithCode(err, "lobby-not-found"))
467468
return nil
468-
} else if err == stores.ErrInvalidPassword {
469+
case stores.ErrInvalidPassword:
469470
util.ReplyError(ctx, p.conn, util.ErrorWithCode(err, "invalid-password"))
470471
return nil
471-
} else if err == stores.ErrLobbyIsFull {
472+
case stores.ErrLobbyIsFull:
472473
util.ReplyError(ctx, p.conn, util.ErrorWithCode(err, "lobby-is-full"))
473474
return nil
474475
}

internal/signaling/stores/postgres.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,19 +312,38 @@ func (s *PostgresStore) GetLobby(ctx context.Context, game, lobbyCode string) (L
312312
return lobby, nil
313313
}
314314

315-
func (s *PostgresStore) ListLobbies(ctx context.Context, game, filter string) ([]Lobby, error) {
315+
func (s *PostgresStore) ListLobbies(ctx context.Context, game, filter, sort string, limit int) ([]Lobby, error) {
316316
// TODO: Remove this.
317317
if filter == "" {
318318
filter = "{}"
319319
}
320320

321-
where, values, err := s.filterConverter.Convert([]byte(filter), 2)
321+
where, values, err := s.filterConverter.Convert([]byte(filter), 3)
322322
if err != nil {
323323
logger := logging.GetLogger(ctx)
324324
logger.Warn("failed to convert filter", zap.String("filter", filter), zap.Error(err))
325325
return nil, fmt.Errorf("invalid filter: %w", err)
326326
}
327327

328+
var order string
329+
if sort != "" {
330+
order, err = s.filterConverter.ConvertOrderBy([]byte(sort))
331+
if err != nil {
332+
logger := logging.GetLogger(ctx)
333+
logger.Warn("failed to convert order", zap.String("sort", sort), zap.Error(err))
334+
return nil, fmt.Errorf("invalid order: %w", err)
335+
}
336+
}
337+
if order == "" {
338+
order = `"createdAt" DESC, "code" ASC`
339+
} else {
340+
order += `, "createdAt" DESC, "code" ASC`
341+
}
342+
343+
if limit <= 0 {
344+
limit = 50
345+
}
346+
328347
var lobbies []Lobby
329348
rows, err := s.DB.Query(ctx, `
330349
WITH lobbies AS (
@@ -348,9 +367,9 @@ func (s *PostgresStore) ListLobbies(ctx context.Context, game, filter string) ([
348367
SELECT *
349368
FROM lobbies
350369
WHERE `+where+`
351-
ORDER BY "createdAt" DESC
352-
LIMIT 50
353-
`, append([]any{game}, values...)...)
370+
ORDER BY `+order+`
371+
LIMIT $2
372+
`, append([]any{game, limit}, values...)...)
354373
if err != nil {
355374
return nil, err
356375
}

internal/signaling/stores/shared.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type Store interface {
2929
JoinLobby(ctx context.Context, game, lobby, id, password string) error
3030
LeaveLobby(ctx context.Context, game, lobby, id string) error
3131
GetLobby(ctx context.Context, game, lobby string) (Lobby, error)
32-
ListLobbies(ctx context.Context, game, filter string) ([]Lobby, error)
32+
ListLobbies(ctx context.Context, game, filter, sort string, limit int) ([]Lobby, error)
3333

3434
Subscribe(ctx context.Context, callback SubscriptionCallback, game, lobby, peerID string)
3535
Publish(ctx context.Context, topic string, data []byte) error

0 commit comments

Comments
 (0)