mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 22:51:30 -07:00
stub /goto/room
This commit is contained in:
@@ -13,8 +13,9 @@ C# `MatchmakingController`. EF Core (`AppDbContext`) queries are stubbed for now
|
|||||||
(the C# fell back to that file when the account/room instance wasn't found).
|
(the C# fell back to that file when the account/room instance wasn't found).
|
||||||
- **`POST /goto/none`** returns the static offline-dorm instance with a fresh
|
- **`POST /goto/none`** returns the static offline-dorm instance with a fresh
|
||||||
`photonRoomId`.
|
`photonRoomId`.
|
||||||
- **`POST /goto/room/:room`** 404s — without a Rooms binding the room can't be
|
- **`POST /goto/room/:room`** synthesizes the room-instance response (no Rooms
|
||||||
resolved, matching the C# `NotFound` path.
|
binding yet). The dorm gets its known scene id and a private instance; other
|
||||||
|
rooms get an empty `location` and respect the posted `JoinMode` (2 = private).
|
||||||
- **`POST /player/heartbeat`** echoes the posted heartbeat fields; `roomInstance`
|
- **`POST /player/heartbeat`** echoes the posted heartbeat fields; `roomInstance`
|
||||||
is always null and `isOnline` false until there's a DB binding.
|
is always null and `isOnline` false until there's a DB binding.
|
||||||
- **`/player/login`, `/player/statusvisibility`, `/roominstance/:id/reportjoinresult`**
|
- **`/player/login`, `/player/statusvisibility`, `/roominstance/:id/reportjoinresult`**
|
||||||
|
|||||||
@@ -123,9 +123,40 @@ const app = new Hono<App>()
|
|||||||
.post('/goto/room/:room', async (c) => {
|
.post('/goto/room/:room', async (c) => {
|
||||||
const id = await authedId(c)
|
const id = await authedId(c)
|
||||||
if (id === null) return unauthorized(c)
|
if (id === null) return unauthorized(c)
|
||||||
// No Rooms binding → the room can never be found (C# returns NotFound here).
|
|
||||||
// TODO: resolve the Room, upsert a RoomInstance, and return it.
|
const room = c.req.param('room')
|
||||||
return c.text('Room not found', 404)
|
const isDorm = room.toLowerCase() === 'dormroom'
|
||||||
|
|
||||||
|
const body = await c.req.parseBody().catch(() => ({}) as Record<string, unknown>)
|
||||||
|
const joinMode = typeof body.JoinMode === 'string' ? Number.parseInt(body.JoinMode, 10) || 0 : 0
|
||||||
|
const isPrivate = joinMode === 2 || isDorm
|
||||||
|
|
||||||
|
// No Rooms/SubRooms/RoomInstances bindings yet, so synthesize the instance
|
||||||
|
// the C# would build. The dorm scene id is known; other rooms get an empty
|
||||||
|
// location until there's real Room data.
|
||||||
|
// TODO: resolve the Room + SubRoom and upsert a RoomInstance once a DB binding exists.
|
||||||
|
return c.json({
|
||||||
|
errorCode: 0,
|
||||||
|
roomInstance: {
|
||||||
|
roomInstanceId: 1,
|
||||||
|
roomId: isDorm ? 1 : Number.parseInt(room, 10) || 1,
|
||||||
|
subRoomId: isDorm ? 1 : 0,
|
||||||
|
roomInstanceType: 2,
|
||||||
|
location: isDorm ? '76d98498-60a1-430c-ab76-b54a29b7a163' : '',
|
||||||
|
dataBlob: '',
|
||||||
|
eventId: 0,
|
||||||
|
clubId: 0,
|
||||||
|
roomCode: '',
|
||||||
|
photonRegionId: 'us',
|
||||||
|
photonRoomId: crypto.randomUUID(),
|
||||||
|
name: isDorm ? 'DormRoom' : room,
|
||||||
|
maxCapacity: 4,
|
||||||
|
isFull: false,
|
||||||
|
isPrivate,
|
||||||
|
isInProgress: false,
|
||||||
|
EncryptVoiceChat: false,
|
||||||
|
},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
.post('/goto/none', (c) =>
|
.post('/goto/none', (c) =>
|
||||||
|
|||||||
@@ -81,12 +81,34 @@ describe('auth-gated endpoints', () => {
|
|||||||
expect(res.status).toBe(401)
|
expect(res.status).toBe(401)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('POST /goto/room/:room 404s with a valid token (no DB)', async () => {
|
test('POST /goto/room/dormroom returns the dorm instance', async () => {
|
||||||
const res = await exports.default.fetch(`${ORIGIN}/goto/room/dormroom`, {
|
const res = await exports.default.fetch(`${ORIGIN}/goto/room/dormroom`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: await bearer(),
|
headers: await bearer(),
|
||||||
})
|
})
|
||||||
expect(res.status).toBe(404)
|
expect(res.status).toBe(200)
|
||||||
|
const body = (await res.json()) as {
|
||||||
|
errorCode: number
|
||||||
|
roomInstance: { name: string; location: string; isPrivate: boolean; roomId: number }
|
||||||
|
}
|
||||||
|
expect(body.errorCode).toBe(0)
|
||||||
|
expect(body.roomInstance).toMatchObject({
|
||||||
|
name: 'DormRoom',
|
||||||
|
location: '76d98498-60a1-430c-ab76-b54a29b7a163',
|
||||||
|
isPrivate: true,
|
||||||
|
roomId: 1,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('POST /goto/room/:id synthesizes an instance and honors JoinMode', async () => {
|
||||||
|
const res = await exports.default.fetch(`${ORIGIN}/goto/room/42`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { ...(await bearer()), 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||||
|
body: new URLSearchParams({ JoinMode: '2' }).toString(),
|
||||||
|
})
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
const body = (await res.json()) as { roomInstance: { roomId: number; isPrivate: boolean; name: string } }
|
||||||
|
expect(body.roomInstance).toMatchObject({ roomId: 42, isPrivate: true, name: '42' })
|
||||||
})
|
})
|
||||||
|
|
||||||
test('POST /player/heartbeat 401s without a token', async () => {
|
test('POST /player/heartbeat 401s without a token', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user