mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-28 16:38:51 -07:00
[rooms] Support 2026 Studio loading of legacy baked bundles (#129)
* [rooms] Preserve legacy Unity bundle save DTOs for the Studio loader * [rooms] Resolve JSON baked bundle requests with exact target and version
This commit is contained in:
@@ -6497,3 +6497,120 @@ describe('sweep cron', () => {
|
||||
expect(await inviterIds()).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
it('2026 room experience retains upstream progression in the native object shape', async () => {
|
||||
await seedRoomWithSubRooms(env.DB, {
|
||||
RoomId: 900092,
|
||||
Name: '2026ExperienceTest',
|
||||
CreatorAccountId: 42,
|
||||
SubRooms: [],
|
||||
})
|
||||
const res = await SELF.fetch(`${ORIGIN}/rooms/900092/experience/player`, {
|
||||
headers: await bearer('42', undefined, '20260323.14'),
|
||||
})
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toEqual({
|
||||
RoomExperienceEnabled: false,
|
||||
Experience: 0,
|
||||
ConcurrencyCode: expect.any(String),
|
||||
})
|
||||
})
|
||||
|
||||
describe('Studio baked Unity asset downloads', () => {
|
||||
const mainId = 'aa0320e1-2e47-4cf5-9129-5366c3c5f824'
|
||||
const childId = 'e6da76fb-f990-4299-8724-d786f5723a5a'
|
||||
const filename = 'imports/test-room/main.SubRoom.Main.0.5.assetbundle'
|
||||
const path = '/unity_assets/baked/bulk'
|
||||
beforeAll(async () => {
|
||||
await seedRoomWithSubRooms(env.DB, {
|
||||
RoomId: 900090,
|
||||
Name: 'StudioDownloadTest',
|
||||
CreatorAccountId: 1,
|
||||
Accessibility: 1,
|
||||
SubRooms: [
|
||||
{
|
||||
SubRoomId: 900090,
|
||||
RoomId: 900090,
|
||||
Name: 'Home',
|
||||
CurrentSave: {
|
||||
UnityAssetId: mainId,
|
||||
UnityAsset: filename,
|
||||
UnityAssetHash: 'main-hash',
|
||||
DataBlob: 'scene.room',
|
||||
UnitySubAssets: [
|
||||
{
|
||||
UnityAssetId: childId,
|
||||
UnityAsset: 'child.SubRoom.SubAsset.0.5.assetbundle',
|
||||
UnityAssetHash: 'child-hash',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
async function bulk(body: unknown, authenticated = true) {
|
||||
return SELF.fetch(ORIGIN + path, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', ...(authenticated ? await bearer('2') : {}) },
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
}
|
||||
it('resolves the main and subasset GUIDs with their exact target and version', async () => {
|
||||
const res = await bulk({
|
||||
UnityAssetIds: [mainId.toUpperCase(), childId, mainId],
|
||||
Target: 0,
|
||||
Version: 5,
|
||||
})
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toEqual([
|
||||
{ UnityAssetId: mainId, Target: 0, Version: 5, Filename: filename, Hash: 'main-hash' },
|
||||
{
|
||||
UnityAssetId: childId,
|
||||
Target: 0,
|
||||
Version: 5,
|
||||
Filename: 'child.SubRoom.SubAsset.0.5.assetbundle',
|
||||
Hash: 'child-hash',
|
||||
},
|
||||
])
|
||||
})
|
||||
it('returns the Studio loader DTO with its main bundle and dependencies', async () => {
|
||||
const row = await env.DB.prepare(
|
||||
'SELECT current_save_id FROM subroom WHERE sub_room_id=900090'
|
||||
).first<{ current_save_id: number }>()
|
||||
const res = await SELF.fetch(
|
||||
`${ORIGIN}/rooms/900090/subrooms/900090/saves/${row!.current_save_id}`,
|
||||
{ headers: await bearer('1') }
|
||||
)
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toMatchObject({
|
||||
UnityAsset: filename,
|
||||
UnityAssetHash: 'main-hash',
|
||||
UnitySubAssets: [
|
||||
{
|
||||
UnityAssetId: childId,
|
||||
UnityAsset: 'child.SubRoom.SubAsset.0.5.assetbundle',
|
||||
UnityAssetHash: 'child-hash',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
it('does not substitute Windows bundles for an unavailable target or version', async () => {
|
||||
for (const options of [
|
||||
{ Target: 2, Version: 5 },
|
||||
{ Target: 0, Version: 6 },
|
||||
]) {
|
||||
expect(await (await bulk({ UnityAssetIds: [mainId], ...options })).json()).toEqual([])
|
||||
}
|
||||
})
|
||||
it('rejects unauthenticated and malformed requests', async () => {
|
||||
expect((await bulk({ UnityAssetIds: [mainId] }, false)).status).toBe(401)
|
||||
expect((await bulk({ UnityAssetIds: ['invalid'] })).status).toBe(400)
|
||||
})
|
||||
it('does not expose private-room assets to an unrelated caller', async () => {
|
||||
await env.DB.prepare(
|
||||
"UPDATE room SET data=json_set(data, '$.Accessibility', 0) WHERE room_id=900090"
|
||||
).run()
|
||||
expect(await (await bulk({ UnityAssetIds: [mainId] })).json()).toEqual([])
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user