hooray, animated items seem to be working?! ^w^
This commit is contained in:
parent
a4d159381c
commit
d27395bda2
5 changed files with 134 additions and 397 deletions
|
@ -6,6 +6,7 @@ import { CSSTransition, TransitionGroup } from "react-transition-group";
|
|||
|
||||
import OutfitCanvas, {
|
||||
OutfitCanvasImage,
|
||||
OutfitCanvasMovie,
|
||||
loadImage,
|
||||
useEaselDependenciesLoader,
|
||||
} from "./OutfitCanvas";
|
||||
|
@ -152,13 +153,21 @@ export function OutfitLayers({
|
|||
!loadingEasel && (
|
||||
<FullScreenCenter>
|
||||
<OutfitCanvas width={canvasSize} height={canvasSize}>
|
||||
{visibleLayers.map((layer) => (
|
||||
{visibleLayers.map((layer) =>
|
||||
layer.canvasMovieLibraryUrl ? (
|
||||
<OutfitCanvasMovie
|
||||
key={layer.id}
|
||||
librarySrc={layer.canvasMovieLibraryUrl}
|
||||
zIndex={layer.zone.depth}
|
||||
/>
|
||||
) : (
|
||||
<OutfitCanvasImage
|
||||
key={layer.id}
|
||||
src={getBestImageUrlForLayer(layer)}
|
||||
zIndex={layer.zone.depth}
|
||||
/>
|
||||
))}
|
||||
)
|
||||
)}
|
||||
</OutfitCanvas>
|
||||
</FullScreenCenter>
|
||||
)
|
||||
|
|
|
@ -144,6 +144,7 @@ export const itemAppearanceFragment = gql`
|
|||
id
|
||||
remoteId # HACK: This is for Support tools, but other views don't need it
|
||||
svgUrl
|
||||
canvasMovieLibraryUrl
|
||||
imageUrl(size: SIZE_600)
|
||||
swfUrl # HACK: This is for Support tools, but other views don't need it
|
||||
bodyId
|
||||
|
@ -166,6 +167,7 @@ export const petAppearanceFragment = gql`
|
|||
layers {
|
||||
id
|
||||
svgUrl
|
||||
canvasMovieLibraryUrl
|
||||
imageUrl(size: SIZE_600)
|
||||
zone {
|
||||
id
|
||||
|
|
|
@ -65,7 +65,14 @@ describe("Item", () => {
|
|||
const res = await query({
|
||||
query: gql`
|
||||
query {
|
||||
items(ids: ["38912", "38911", "37375"]) {
|
||||
items(
|
||||
ids: [
|
||||
"38912" # Zafara Agent Robe
|
||||
"38911" # Zafara Agent Hood
|
||||
"37375" # Moon and Stars Background
|
||||
"78244" # Bubbles on Water Foreground
|
||||
]
|
||||
) {
|
||||
id
|
||||
name
|
||||
|
||||
|
@ -75,6 +82,7 @@ describe("Item", () => {
|
|||
remoteId
|
||||
imageUrl(size: SIZE_600)
|
||||
svgUrl
|
||||
canvasMovieLibraryUrl
|
||||
zone {
|
||||
id
|
||||
depth
|
||||
|
@ -96,11 +104,12 @@ describe("Item", () => {
|
|||
expect(getDbCalls()).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"SELECT * FROM item_translations WHERE item_id IN (?,?,?) AND locale = \\"en\\"",
|
||||
"SELECT * FROM item_translations WHERE item_id IN (?,?,?,?) AND locale = \\"en\\"",
|
||||
Array [
|
||||
"38912",
|
||||
"38911",
|
||||
"37375",
|
||||
"78244",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
|
@ -115,7 +124,7 @@ describe("Item", () => {
|
|||
INNER JOIN parents_swf_assets rel ON
|
||||
rel.parent_type = \\"Item\\" AND
|
||||
rel.swf_asset_id = sa.id
|
||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0)) OR (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
||||
Array [
|
||||
"38912",
|
||||
"180",
|
||||
|
@ -123,30 +132,35 @@ describe("Item", () => {
|
|||
"180",
|
||||
"37375",
|
||||
"180",
|
||||
"78244",
|
||||
"180",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM items WHERE id IN (?,?,?)",
|
||||
"SELECT * FROM items WHERE id IN (?,?,?,?)",
|
||||
Array [
|
||||
"38912",
|
||||
"38911",
|
||||
"37375",
|
||||
"78244",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM zones WHERE id IN (?,?,?)",
|
||||
"SELECT * FROM zones WHERE id IN (?,?,?,?)",
|
||||
Array [
|
||||
"26",
|
||||
"40",
|
||||
"3",
|
||||
"45",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM zone_translations WHERE zone_id IN (?,?,?) AND locale = \\"en\\"",
|
||||
"SELECT * FROM zone_translations WHERE zone_id IN (?,?,?,?) AND locale = \\"en\\"",
|
||||
Array [
|
||||
"26",
|
||||
"40",
|
||||
"3",
|
||||
"45",
|
||||
],
|
||||
],
|
||||
]
|
||||
|
|
|
@ -7,8 +7,9 @@ Object {
|
|||
"appearanceOn": Object {
|
||||
"layers": Array [
|
||||
Object {
|
||||
"canvasMovieLibraryUrl": null,
|
||||
"id": "37128",
|
||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14856/600x600.png?v2-1587653266000",
|
||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14856/600x600.png?v2-1577836800000",
|
||||
"remoteId": "14856",
|
||||
"svgUrl": null,
|
||||
"zone": Object {
|
||||
|
@ -34,8 +35,9 @@ Object {
|
|||
"appearanceOn": Object {
|
||||
"layers": Array [
|
||||
Object {
|
||||
"canvasMovieLibraryUrl": null,
|
||||
"id": "37129",
|
||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14857/600x600.png?v2-0",
|
||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/014/14857/600x600.png?v2-1577836800000",
|
||||
"remoteId": "14857",
|
||||
"svgUrl": null,
|
||||
"zone": Object {
|
||||
|
@ -61,8 +63,9 @@ Object {
|
|||
"appearanceOn": Object {
|
||||
"layers": Array [
|
||||
Object {
|
||||
"canvasMovieLibraryUrl": null,
|
||||
"id": "30203",
|
||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/006/6829/600x600.png?v2-1598519675000",
|
||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/006/6829/600x600.png?v2-1577836800000",
|
||||
"remoteId": "6829",
|
||||
"svgUrl": null,
|
||||
"zone": Object {
|
||||
|
@ -77,366 +80,28 @@ Object {
|
|||
"id": "37375",
|
||||
"name": "Moon and Stars Background",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for all-species Maraquan item: db 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
||||
FROM items
|
||||
INNER JOIN parents_swf_assets ON
|
||||
items.id = parents_swf_assets.parent_id AND
|
||||
parents_swf_assets.parent_type = \\"Item\\"
|
||||
INNER JOIN swf_assets ON
|
||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
||||
INNER JOIN pet_types ON
|
||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
||||
INNER JOIN colors ON
|
||||
pet_types.color_id = colors.id
|
||||
WHERE items.id IN (?)
|
||||
GROUP BY pet_types.body_id
|
||||
ORDER BY
|
||||
pet_types.species_id,
|
||||
colors.standard DESC",
|
||||
Array [
|
||||
"77530",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
||||
INNER JOIN parents_swf_assets rel ON
|
||||
rel.parent_type = \\"Item\\" AND
|
||||
rel.swf_asset_id = sa.id
|
||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
||||
Array [
|
||||
"77530",
|
||||
"112",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
Object {
|
||||
"nestTables": true,
|
||||
"sql": "
|
||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
||||
WHERE pet_types.body_id = ?
|
||||
ORDER BY
|
||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
||||
pet_states.female = ? DESC, -- Prefer given gender
|
||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
||||
LIMIT 1",
|
||||
"values": Array [
|
||||
"112",
|
||||
false,
|
||||
],
|
||||
},
|
||||
Array [
|
||||
"112",
|
||||
false,
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
||||
INNER JOIN parents_swf_assets rel ON
|
||||
rel.parent_type = \\"PetState\\" AND
|
||||
rel.swf_asset_id = sa.id
|
||||
WHERE rel.parent_id IN (?)",
|
||||
Array [
|
||||
"5233",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM color_translations
|
||||
WHERE color_id IN (?) AND locale = \\"en\\"",
|
||||
Array [
|
||||
"44",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM species_translations
|
||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
||||
Array [
|
||||
"1",
|
||||
],
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for all-species Maraquan item: item layers 1`] = `
|
||||
Array [
|
||||
"appearanceOn": Object {
|
||||
"layers": Array [
|
||||
Object {
|
||||
"id": "442864",
|
||||
"canvasMovieLibraryUrl": "http://images.neopets.com/cp/items/data/000/000/564/564507_fc3216b9b8/all-item_foreground_lower.js",
|
||||
"id": "468155",
|
||||
"imageUrl": "https://impress-asset-images.s3.amazonaws.com/object/000/000/564/564507/600x600.png?v2-1577836800000",
|
||||
"remoteId": "564507",
|
||||
"svgUrl": null,
|
||||
"zone": Object {
|
||||
"depth": 50,
|
||||
"id": "45",
|
||||
"label": "Lower Foreground Item",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for all-species Maraquan item: pet layers 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"id": "2652",
|
||||
},
|
||||
Object {
|
||||
"id": "2653",
|
||||
],
|
||||
"restrictedZones": Array [],
|
||||
},
|
||||
Object {
|
||||
"id": "2654",
|
||||
"id": "78244",
|
||||
"name": "Bubbles on Water Foreground",
|
||||
},
|
||||
Object {
|
||||
"id": "2656",
|
||||
},
|
||||
Object {
|
||||
"id": "2663",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for all-species item: db 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
||||
FROM items
|
||||
INNER JOIN parents_swf_assets ON
|
||||
items.id = parents_swf_assets.parent_id AND
|
||||
parents_swf_assets.parent_type = \\"Item\\"
|
||||
INNER JOIN swf_assets ON
|
||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
||||
INNER JOIN pet_types ON
|
||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
||||
INNER JOIN colors ON
|
||||
pet_types.color_id = colors.id
|
||||
WHERE items.id IN (?)
|
||||
GROUP BY pet_types.body_id
|
||||
ORDER BY
|
||||
pet_types.species_id,
|
||||
colors.standard DESC",
|
||||
Array [
|
||||
"74967",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
||||
INNER JOIN parents_swf_assets rel ON
|
||||
rel.parent_type = \\"Item\\" AND
|
||||
rel.swf_asset_id = sa.id
|
||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
||||
Array [
|
||||
"74967",
|
||||
"93",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM species_translations
|
||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
||||
Array [
|
||||
"1",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
Object {
|
||||
"nestTables": true,
|
||||
"sql": "
|
||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
||||
WHERE pet_types.body_id = ?
|
||||
ORDER BY
|
||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
||||
pet_states.female = ? DESC, -- Prefer given gender
|
||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
||||
LIMIT 1",
|
||||
"values": Array [
|
||||
"93",
|
||||
true,
|
||||
],
|
||||
},
|
||||
Array [
|
||||
"93",
|
||||
true,
|
||||
],
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for all-species item: item layers 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"id": "395679",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for all-species item: pet layers 1`] = `
|
||||
Object {
|
||||
"id": "5161",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for bodyId=0 item: db 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
||||
FROM items
|
||||
INNER JOIN parents_swf_assets ON
|
||||
items.id = parents_swf_assets.parent_id AND
|
||||
parents_swf_assets.parent_type = \\"Item\\"
|
||||
INNER JOIN swf_assets ON
|
||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
||||
INNER JOIN pet_types ON
|
||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
||||
INNER JOIN colors ON
|
||||
pet_types.color_id = colors.id
|
||||
WHERE items.id IN (?)
|
||||
GROUP BY pet_types.body_id
|
||||
ORDER BY
|
||||
pet_types.species_id,
|
||||
colors.standard DESC",
|
||||
Array [
|
||||
"37375",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
||||
INNER JOIN parents_swf_assets rel ON
|
||||
rel.parent_type = \\"Item\\" AND
|
||||
rel.swf_asset_id = sa.id
|
||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
||||
Array [
|
||||
"37375",
|
||||
"93",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM species_translations
|
||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
||||
Array [
|
||||
"1",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
Object {
|
||||
"nestTables": true,
|
||||
"sql": "
|
||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
||||
WHERE pet_types.body_id = ?
|
||||
ORDER BY
|
||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
||||
pet_states.female = ? DESC, -- Prefer given gender
|
||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
||||
LIMIT 1",
|
||||
"values": Array [
|
||||
"93",
|
||||
true,
|
||||
],
|
||||
},
|
||||
Array [
|
||||
"93",
|
||||
true,
|
||||
],
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for bodyId=0 item: item layers 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"id": "30203",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for bodyId=0 item: pet layers 1`] = `
|
||||
Object {
|
||||
"id": "5161",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for single-species item: db 1`] = `
|
||||
Array [
|
||||
Array [
|
||||
"SELECT pet_types.body_id, pet_types.species_id, items.id AS item_id
|
||||
FROM items
|
||||
INNER JOIN parents_swf_assets ON
|
||||
items.id = parents_swf_assets.parent_id AND
|
||||
parents_swf_assets.parent_type = \\"Item\\"
|
||||
INNER JOIN swf_assets ON
|
||||
parents_swf_assets.swf_asset_id = swf_assets.id
|
||||
INNER JOIN pet_types ON
|
||||
pet_types.body_id = swf_assets.body_id OR swf_assets.body_id = 0
|
||||
INNER JOIN colors ON
|
||||
pet_types.color_id = colors.id
|
||||
WHERE items.id IN (?)
|
||||
GROUP BY pet_types.body_id
|
||||
ORDER BY
|
||||
pet_types.species_id,
|
||||
colors.standard DESC",
|
||||
Array [
|
||||
"38911",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT sa.*, rel.parent_id FROM swf_assets sa
|
||||
INNER JOIN parents_swf_assets rel ON
|
||||
rel.parent_type = \\"Item\\" AND
|
||||
rel.swf_asset_id = sa.id
|
||||
WHERE (rel.parent_id = ? AND (sa.body_id = ? OR sa.body_id = 0))",
|
||||
Array [
|
||||
"38911",
|
||||
"180",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
"SELECT * FROM species_translations
|
||||
WHERE species_id IN (?) AND locale = \\"en\\"",
|
||||
Array [
|
||||
"54",
|
||||
],
|
||||
],
|
||||
Array [
|
||||
Object {
|
||||
"nestTables": true,
|
||||
"sql": "
|
||||
SELECT pet_states.*, pet_types.* FROM pet_states
|
||||
INNER JOIN pet_types ON pet_types.id = pet_states.pet_type_id
|
||||
WHERE pet_types.body_id = ?
|
||||
ORDER BY
|
||||
pet_types.color_id = 8 DESC, -- Prefer Blue
|
||||
pet_states.mood_id = 1 DESC, -- Prefer Happy
|
||||
pet_states.female = ? DESC, -- Prefer given gender
|
||||
pet_states.id DESC, -- Prefer recent models (like in the app)
|
||||
pet_states.glitched ASC -- Prefer not glitched (like in the app)
|
||||
LIMIT 1",
|
||||
"values": Array [
|
||||
"180",
|
||||
false,
|
||||
],
|
||||
},
|
||||
Array [
|
||||
"180",
|
||||
false,
|
||||
],
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for single-species item: item layers 1`] = `
|
||||
Array [
|
||||
Object {
|
||||
"id": "37129",
|
||||
},
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Item loads canonical appearance for single-species item: pet layers 1`] = `
|
||||
Object {
|
||||
"id": "17861",
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -38,6 +38,14 @@ const typeDefs = gql`
|
|||
"""
|
||||
swfUrl: String
|
||||
|
||||
"""
|
||||
This layer as an HTML canvas library JS file, if available.
|
||||
|
||||
This will be empty for layers that don't animate, and might also be empty
|
||||
for animated layers not yet converted by Neopets.
|
||||
"""
|
||||
canvasMovieLibraryUrl: String
|
||||
|
||||
"""
|
||||
This layer can fit on PetAppearances with the same bodyId. "0" is a
|
||||
special body ID that indicates it fits all PetAppearances.
|
||||
|
@ -111,30 +119,7 @@ const resolvers = {
|
|||
// When the manifest is specifically null, that means we don't know if
|
||||
// it exists yet. Load it to find out!
|
||||
if (manifest === null) {
|
||||
manifest = await loadAssetManifest(layer.url);
|
||||
|
||||
// Then, write the new manifest. We make sure to write an empty string
|
||||
// if there was no manifest, to signify that it doesn't exist, so we
|
||||
// don't need to bother looking it up again.
|
||||
//
|
||||
// TODO: Someday the manifests will all exist, right? So we'll want to
|
||||
// reload all the missing ones at that time.
|
||||
manifest = manifest || "";
|
||||
const [
|
||||
result,
|
||||
] = await db.execute(
|
||||
`UPDATE swf_assets SET manifest = ? WHERE id = ? LIMIT 1;`,
|
||||
[manifest, layer.id]
|
||||
);
|
||||
if (result.affectedRows !== 1) {
|
||||
throw new Error(
|
||||
`Expected to affect 1 asset, but affected ${result.affectedRows}`
|
||||
);
|
||||
}
|
||||
console.log(
|
||||
`Loaded and saved manifest for ${layer.type} ${layer.remoteId}. ` +
|
||||
`DTI ID: ${layer.id}. Exists?: ${Boolean(manifest)}`
|
||||
);
|
||||
manifest = await loadAndCacheAssetManifest(db, layer);
|
||||
}
|
||||
|
||||
if (!manifest) {
|
||||
|
@ -163,6 +148,39 @@ const resolvers = {
|
|||
const url = new URL(assetDatum.path, "http://images.neopets.com");
|
||||
return url.toString();
|
||||
},
|
||||
canvasMovieLibraryUrl: async ({ id }, _, { db, swfAssetLoader }) => {
|
||||
const layer = await swfAssetLoader.load(id);
|
||||
let manifest = layer.manifest && JSON.parse(layer.manifest);
|
||||
|
||||
// When the manifest is specifically null, that means we don't know if
|
||||
// it exists yet. Load it to find out!
|
||||
if (manifest === null) {
|
||||
manifest = await loadAndCacheAssetManifest(db, layer);
|
||||
}
|
||||
|
||||
if (!manifest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (manifest.assets.length !== 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const asset = manifest.assets[0];
|
||||
if (asset.format !== "lod") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const jsAssetDatum = asset.assetData.find((ad) =>
|
||||
ad.path.endsWith(".js")
|
||||
);
|
||||
if (!jsAssetDatum) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const url = new URL(jsAssetDatum.path, "http://images.neopets.com");
|
||||
return url.toString();
|
||||
},
|
||||
item: async ({ id }, _, { db }) => {
|
||||
// TODO: If this becomes a popular request, we'll definitely need to
|
||||
// loaderize this! I'm cheating for now because it's just Support, one at
|
||||
|
@ -207,6 +225,35 @@ async function loadAssetManifest(swfUrl) {
|
|||
};
|
||||
}
|
||||
|
||||
async function loadAndCacheAssetManifest(db, layer) {
|
||||
let manifest = await loadAssetManifest(layer.url);
|
||||
|
||||
// Then, write the new manifest. We make sure to write an empty string
|
||||
// if there was no manifest, to signify that it doesn't exist, so we
|
||||
// don't need to bother looking it up again.
|
||||
//
|
||||
// TODO: Someday the manifests will all exist, right? So we'll want to
|
||||
// reload all the missing ones at that time.
|
||||
manifest = manifest || "";
|
||||
const [
|
||||
result,
|
||||
] = await db.execute(
|
||||
`UPDATE swf_assets SET manifest = ? WHERE id = ? LIMIT 1;`,
|
||||
[manifest, layer.id]
|
||||
);
|
||||
if (result.affectedRows !== 1) {
|
||||
throw new Error(
|
||||
`Expected to affect 1 asset, but affected ${result.affectedRows}`
|
||||
);
|
||||
}
|
||||
console.log(
|
||||
`Loaded and saved manifest for ${layer.type} ${layer.remoteId}. ` +
|
||||
`DTI ID: ${layer.id}. Exists?: ${Boolean(manifest)}`
|
||||
);
|
||||
|
||||
return manifest;
|
||||
}
|
||||
|
||||
const SWF_URL_PATTERN = /^http:\/\/images\.neopets\.com\/cp\/(.+?)\/swf\/(.+?)\.swf$/;
|
||||
|
||||
function convertSwfUrlToManifestUrl(swfUrl) {
|
||||
|
|
Loading…
Reference in a new issue