Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ n.on('ready', () => {
lobbies.forEach(lobby => {
const li = document.createElement('li')
li.id = lobby.code
li.innerHTML = `<a href="javascript:void(0)" class="code">${lobby.code}</a> - <span class="map_name">${lobby.customData?.map as string ?? 'unknown map'}</span> - <span class="players">${lobby.playerCount}</span> players`
li.innerHTML = `<a href="javascript:void(0)" class="code">${lobby.code}</a> - <span class="map_name">${lobby.customData?.map as string ?? 'unknown map'}</span> - <span class="players">${lobby.playerCount}</span> players (${lobby.latency ?? '<unknown>'}ms)`
el.appendChild(li)
if (n.currentLobby === undefined) {
li.querySelector('a.code')?.addEventListener('click', () => {
Expand Down
63 changes: 63 additions & 0 deletions features/latency3.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
Feature: Country/region latency estimates

Background:
Given the "signaling" backend is running
And the "testproxy" backend is running

Scenario: latency is computed from requester to lobby peers
Given these lobbies exist:
| code | game | peers | public |
| 0qva9vyurwbbl | 123e4567-e89b-12d3-a456-426614174000 | {peerA,peerB} | true |
And these peers exist:
| peer | game | country | region |
| peerA | 123e4567-e89b-12d3-a456-426614174000 | US | US-CA |
| peerB | 123e4567-e89b-12d3-a456-426614174000 | US | US-CA |
And "blue" is connected as "1u8fw4aph5ypt" with country,region as "US","US-CA" and ready for game "123e4567-e89b-12d3-a456-426614174000"

When "blue" requests lobbies with:
"""json
{}
"""

Then "blue" should have received only these lobbies:
| code | latency |
| 0qva9vyurwbbl | 47 |


Scenario: latency uses default when a peer has no country pair data
Given these lobbies exist:
| code | game | peers | public |
| 4z4an3whwhgvl | 223e4567-e89b-12d3-a456-426614174000 | {peerC,peerD} | true |
And these peers exist:
| peer | game | country | region |
| peerC | 223e4567-e89b-12d3-a456-426614174000 | US | US-CA |
| peerD | 223e4567-e89b-12d3-a456-426614174000 | ZZ | null |
And "green" is connected as "1u8fw4aph5ypt" with country,region as "US","US-CA" and ready for game "223e4567-e89b-12d3-a456-426614174000"

When "green" requests lobbies with:
"""json
{}
"""

Then "green" should have received only these lobbies:
| code | latency |
| 4z4an3whwhgvl | 148 |


Scenario: latency uses default when requester has no country
Given these lobbies exist:
| code | game | peers | public |
| 3l6t2w7xk6w0y | 323e4567-e89b-12d3-a456-426614174000 | {peerE} | true |
And these peers exist:
| peer | game | country | region |
| peerE | 323e4567-e89b-12d3-a456-426614174000 | US | US-CA |
And "orange" is connected as "1u8fw4aph5ypt" with country,region as "XX","XX" and ready for game "323e4567-e89b-12d3-a456-426614174000"

When "orange" requests lobbies with:
"""json
{}
"""

Then "orange" should have received only these lobbies:
| code | latency |
| 3l6t2w7xk6w0y | 250 |
8 changes: 6 additions & 2 deletions features/support/steps/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ After(async function (this: World) {
this.players.clear()
})

async function playerIsConnectedAndReadyForGame (this: World, playerName: string, peerID: string, gameID: string): Promise<void> {
const player = await this.createPlayer(playerName, gameID)
async function playerIsConnectedAndReadyForGame (this: World, playerName: string, peerID: string, gameID: string, country?: string, region?: string): Promise<void> {
const player = await this.createPlayer(playerName, gameID, country, region)
const event = await player.waitForEvent('ready')
if (event == null) {
throw new Error(`unable to add player ${playerName} to network`)
Expand All @@ -23,6 +23,10 @@ Given('{string} is connected as {string} and ready for game {string}', async fun
await playerIsConnectedAndReadyForGame.call(this, playerName, peerID, gameID)
})

Given('{string} is connected as {string} with country,region as {string},{string} and ready for game {string}', async function (this: World, playerName: string, peerID: string, country: string, region: string, gameID: string) {
await playerIsConnectedAndReadyForGame.call(this, playerName, peerID, gameID, country, region)
})

async function areJoinedInALobby (this: World, playerNamesRaw: string, publc: boolean): Promise<void> {
const playerNames = playerNamesRaw.split(',').map(s => s.trim())
if (playerNames.length < 2) {
Expand Down
10 changes: 8 additions & 2 deletions features/support/world.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,21 @@ export class World extends CucumberWorld {
}
}

public async createPlayer (playerName: string, gameID: string): Promise<Player> {
public async createPlayer (playerName: string, gameID: string, country?: string, region?: string): Promise<Player> {
return await new Promise((resolve) => {
const config: PeerConfiguration = {}
if (this.useTestProxy) {
config.testproxyURL = this.testproxyURL
}
let signalingURL = this.signalingURL
if (signalingURL !== undefined) {
if (signalingURL !== undefined && (country !== undefined || region !== undefined)) {
const url = new URL(signalingURL)
if (country !== undefined) {
url.searchParams.set('country', country)
}
if (region !== undefined) {
url.searchParams.set('region', region)
}
signalingURL = url.toString()
}

Expand Down
12 changes: 11 additions & 1 deletion internal/signaling/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ const peerActiveUpdateInterval = 30 * time.Second
// China
// Russia
// Indonesia
var countriesToTrackStates = []string{"US", "CA", "AU", "BR", "IN", "MX", "AR", "CL", "CN", "RU", "ID"}
// Japan
var countriesToTrackStates = []string{"US", "CA", "AU", "BR", "IN", "MX", "AR", "CL", "CN", "RU", "ID", "JP"}

func Handler(ctx context.Context, store stores.Store, cloudflare *cloudflare.CredentialsClient) (*sync.WaitGroup, http.HandlerFunc) {
manager := &TimeoutManager{
Expand Down Expand Up @@ -83,6 +84,15 @@ func Handler(ctx context.Context, store stores.Store, cloudflare *cloudflare.Cre

country := r.Header.Get("CF-IPCountry")
region := r.Header.Get("X-Geo-Region")
if country == "" || region == "" {
q := r.URL.Query()
if country == "" {
country = q.Get("country")
}
if region == "" {
region = q.Get("region")
}
}

peer := &Peer{
store: store,
Expand Down
Loading