mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
record deviceclass
This commit is contained in:
@@ -4,6 +4,7 @@ import { useWorkersLogger } from 'workers-tagged-logger'
|
||||
import {
|
||||
createRoomInstance,
|
||||
deleteExpiredPresence,
|
||||
getAccount,
|
||||
getExpiredPresenceInstanceIds,
|
||||
getJoinableInstance,
|
||||
getOrCreateDormRoom,
|
||||
@@ -131,16 +132,27 @@ const GAME_VERSION = '20230302'
|
||||
*/
|
||||
const DEFAULT_GET_PLAYER = [{ ...playerPayload(1), isOnline: true }]
|
||||
|
||||
/** Store the room instance the player just matchmade into, preserving status. */
|
||||
/**
|
||||
* Store the room instance the player just matchmade into, preserving status.
|
||||
*
|
||||
* With no live presence to carry forward (the player's first matchmake after login,
|
||||
* or one after their presence lapsed) the device fields would otherwise default —
|
||||
* writing a screen player into the instance as deviceClass 0 until their next
|
||||
* heartbeat corrects it. Everyone already in the room sees that stale class in the
|
||||
* meantime, so fall back to what the account reported at login (auth stores
|
||||
* `deviceClass`/`platform` from the token request) instead of to 0. The account read
|
||||
* only happens on that no-presence path; a normal matchmake carries `prev` forward.
|
||||
*/
|
||||
async function enterRoom(c: Context<App>, id: number, roomInstance: RoomInstance): Promise<void> {
|
||||
const prev = await getPresence<RoomInstance>(c.env.DB, id)
|
||||
const account = prev ? null : await getAccount(c.env.DB, id)
|
||||
await setPresence(c.env.DB, {
|
||||
accountId: id,
|
||||
roomInstance,
|
||||
statusVisibility: prev?.statusVisibility ?? 0,
|
||||
deviceClass: prev?.deviceClass ?? 0,
|
||||
deviceClass: prev?.deviceClass ?? account?.deviceClass ?? 0,
|
||||
vrMovementMode: prev?.vrMovementMode ?? 1,
|
||||
platform: prev?.platform ?? 0,
|
||||
platform: prev?.platform ?? account?.platform ?? 0,
|
||||
appVersion: prev?.appVersion || GAME_VERSION,
|
||||
})
|
||||
// Keep the destination instance's is_full flag in sync with live presence (the
|
||||
|
||||
@@ -229,6 +229,28 @@ describe('public endpoints', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('POST /matchmake/room/:roomId seeds presence with the account device class', async () => {
|
||||
// A screen player (deviceClass 2, recorded by auth at login) matchmaking with no
|
||||
// live presence: without the account fallback they'd enter the room as deviceClass
|
||||
// 0 (VR) until their next heartbeat, and everyone in the room would see that.
|
||||
await env.DB.prepare('INSERT OR IGNORE INTO account (data) VALUES (?1)')
|
||||
.bind(JSON.stringify({ accountId: 55, username: 'Screenie', deviceClass: 2, platform: 0 }))
|
||||
.run()
|
||||
const headers = await bearer('55')
|
||||
const res = await exports.default.fetch(`${ORIGIN}/matchmake/room/2`, {
|
||||
method: 'POST',
|
||||
headers: { ...headers, 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: new URLSearchParams({ JoinMode: '2' }).toString(),
|
||||
})
|
||||
expect(res.status).toBe(200)
|
||||
|
||||
const row = await env.DB.prepare('SELECT data FROM presence WHERE account_id = ?1')
|
||||
.bind(55)
|
||||
.first<{ data: string }>()
|
||||
const presence = JSON.parse(row!.data) as { deviceClass: number }
|
||||
expect(presence.deviceClass).toBe(2)
|
||||
})
|
||||
|
||||
test('POST /matchmake/room/:roomId/:subRoomId enters that subroom', async () => {
|
||||
type Instance = {
|
||||
roomId: number
|
||||
|
||||
Reference in New Issue
Block a user