From d91cd806039699275a653967a3a769fa11f122fc Mon Sep 17 00:00:00 2001 From: Matchu Date: Mon, 31 Aug 2020 19:23:56 -0700 Subject: [PATCH] add support for UC zone restrictions --- src/app/components/useOutfitAppearance.js | 15 +- src/server/index.js | 23 +- src/server/query-tests/PetAppearance.test.js | 109 ++++- .../__snapshots__/PetAppearance.test.js.snap | 415 ++++++++++++------ src/server/util.js | 11 + 5 files changed, 428 insertions(+), 145 deletions(-) diff --git a/src/app/components/useOutfitAppearance.js b/src/app/components/useOutfitAppearance.js index e8f3186..06e3fdf 100644 --- a/src/app/components/useOutfitAppearance.js +++ b/src/app/components/useOutfitAppearance.js @@ -119,13 +119,21 @@ export function getVisibleLayers(petAppearance, itemAppearances) { .map((l) => ({ ...l, source: "item" })); let allLayers = [...petLayers, ...itemLayers]; - const allRestrictedZoneIds = validItemAppearances + const itemRestrictedZoneIds = validItemAppearances + .map((a) => a.restrictedZones) + .flat() + .map((z) => z.id); + const petRestrictedZoneIds = petLayers .map((l) => l.restrictedZones) .flat() .map((z) => z.id); + const allRestrictedZoneIds = new Set([ + ...itemRestrictedZoneIds, + ...petRestrictedZoneIds, + ]); const visibleLayers = allLayers.filter( - (l) => !allRestrictedZoneIds.includes(l.zone.id) + (l) => !allRestrictedZoneIds.has(l.zone.id) ); visibleLayers.sort((a, b) => a.zone.depth - b.zone.depth); @@ -166,6 +174,9 @@ export const petAppearanceFragment = gql` id depth @client } + restrictedZones { + id + } } } `; diff --git a/src/server/index.js b/src/server/index.js index c0ce3c0..7fd82af 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -12,6 +12,7 @@ const { getEmotion, getGenderPresentation, getPoseName, + getRestrictedZoneIds, loadBodyName, logToDiscord, normalizeRow, @@ -102,6 +103,7 @@ const typeDefs = gql` bodyId: ID! layers: [AppearanceLayer!]! + petStateId: ID! # Deprecated, an alias for id # Whether this PetAppearance is known to look incorrect. This is a manual # flag that we set, in the case where this glitchy PetAppearance really did @@ -157,6 +159,14 @@ const typeDefs = gql` The item this layer is for, if any. (For pet layers, this is null.) """ item: Item + + """ + The zones that this layer restricts, if any. Note that, for item layers, + this is generally empty and the restriction is on the ItemAppearance, not + the individual layers. For pet layers, this is generally used for + Unconverted pets. + """ + restrictedZones: [Zone!]! } # Cache for 1 week (unlikely to change) @@ -347,14 +357,7 @@ const resolvers = { }, restrictedZones: async ({ item: { id: itemId } }, _, { itemLoader }) => { const item = await itemLoader.load(itemId); - const restrictedZones = []; - for (const [i, bit] of Array.from(item.zonesRestrict).entries()) { - if (bit === "1") { - const zone = { id: i + 1 }; - restrictedZones.push(zone); - } - } - return restrictedZones; + return getRestrictedZoneIds(item.zonesRestrict).map((id) => ({ id })); }, }, PetAppearance: { @@ -400,6 +403,10 @@ const resolvers = { const layer = await swfAssetLoader.load(id); return { id: layer.zoneId }; }, + restrictedZones: async ({ id }, _, { swfAssetLoader }) => { + const layer = await swfAssetLoader.load(id); + return getRestrictedZoneIds(layer.zonesRestrict).map((id) => ({ id })); + }, swfUrl: async ({ id }, _, { swfAssetLoader }) => { const layer = await swfAssetLoader.load(id); return layer.url; diff --git a/src/server/query-tests/PetAppearance.test.js b/src/server/query-tests/PetAppearance.test.js index 82c65d8..21af4f4 100644 --- a/src/server/query-tests/PetAppearance.test.js +++ b/src/server/query-tests/PetAppearance.test.js @@ -27,6 +27,9 @@ describe("PetAppearance", () => { zone { depth } + restrictedZones { + id + } } } } @@ -47,7 +50,8 @@ describe("PetAppearance", () => { Array [ "SELECT * FROM pet_states WHERE pet_type_id IN (?) - ORDER BY mood_id ASC, female DESC, id DESC", + ORDER BY (mood_id IS NULL) ASC, mood_id ASC, female DESC, + unconverted DESC, glitched ASC, id DESC", Array [ "2", ], @@ -143,7 +147,8 @@ describe("PetAppearance", () => { Array [ "SELECT * FROM pet_states WHERE pet_type_id IN (?) - ORDER BY mood_id ASC, female DESC, id DESC", + ORDER BY (mood_id IS NULL) ASC, mood_id ASC, female DESC, + unconverted DESC, glitched ASC, id DESC", Array [ "2", ], @@ -155,14 +160,14 @@ describe("PetAppearance", () => { rel.swf_asset_id = sa.id WHERE rel.parent_id IN (?,?,?,?,?,?,?,?)", Array [ - "4751", - "2", "17723", "17742", "5991", "436", "10014", "11089", + "4751", + "2", ], ], Array [ @@ -186,8 +191,102 @@ describe("PetAppearance", () => { "5", "37", "30", - "34", "33", + "34", + ], + ], + ] + `); + }); + + it("loads unconverted appearance", async () => { + const res = await query({ + query: gql` + query { + petAppearance(speciesId: "1", colorId: "63", pose: UNCONVERTED) { + id + + species { + id + name + } + + color { + id + name + isStandard + } + + layers { + id + imageUrl(size: SIZE_600) + svgUrl + zone { + depth + } + restrictedZones { + id + } + } + } + } + `, + }); + + expect(res).toHaveNoErrors(); + expect(res.data).toMatchSnapshot(); + expect(getDbCalls()).toMatchInlineSnapshot(` + Array [ + Array [ + "SELECT * FROM pet_types WHERE (species_id = ? AND color_id = ?)", + Array [ + "1", + "63", + ], + ], + Array [ + "SELECT * FROM pet_states + WHERE pet_type_id IN (?) + ORDER BY (mood_id IS NULL) ASC, mood_id ASC, female DESC, + unconverted DESC, glitched ASC, id DESC", + Array [ + "2274", + ], + ], + 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 [ + "2571", + ], + ], + Array [ + "SELECT * FROM species_translations + WHERE species_id IN (?) AND locale = \\"en\\"", + Array [ + "1", + ], + ], + Array [ + "SELECT * FROM color_translations + WHERE color_id IN (?) AND locale = \\"en\\"", + Array [ + "63", + ], + ], + Array [ + "SELECT * FROM colors WHERE id IN (?) AND prank = 0", + Array [ + "63", + ], + ], + Array [ + "SELECT * FROM zones WHERE id IN (?)", + Array [ + "46", ], ], ] diff --git a/src/server/query-tests/__snapshots__/PetAppearance.test.js.snap b/src/server/query-tests/__snapshots__/PetAppearance.test.js.snap index ef701eb..d2da180 100644 --- a/src/server/query-tests/__snapshots__/PetAppearance.test.js.snap +++ b/src/server/query-tests/__snapshots__/PetAppearance.test.js.snap @@ -13,6 +13,7 @@ Object { Object { "id": "5995", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0", + "restrictedZones": Array [], "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7941_2c4cc4b846/7941.svg", "zone": Object { "depth": 18, @@ -21,6 +22,7 @@ Object { Object { "id": "5996", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0", + "restrictedZones": Array [], "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7942_2eab06fd7b/7942.svg", "zone": Object { "depth": 7, @@ -29,6 +31,7 @@ Object { Object { "id": "6000", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0", + "restrictedZones": Array [], "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/007/7946_0348dad587/7946.svg", "zone": Object { "depth": 40, @@ -37,6 +40,7 @@ Object { Object { "id": "16467", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0", + "restrictedZones": Array [], "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/024/24008_a05fe9876a/24008.svg", "zone": Object { "depth": 34, @@ -45,6 +49,7 @@ Object { Object { "id": "19784", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28892/600x600.png?v2-1313418652000", + "restrictedZones": Array [], "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/028/28892_a8e3a8b430/28892.svg", "zone": Object { "depth": 37, @@ -53,6 +58,7 @@ Object { Object { "id": "178150", "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/036/36887/600x600.png?v2-1354240708000", + "restrictedZones": Array [], "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/036/36887_a335fbba09/36887.svg", "zone": Object { "depth": 38, @@ -70,136 +76,6 @@ Object { exports[`PetAppearance loads multiple for species and color 1`] = ` Object { "petAppearances": Array [ - Object { - "bodyId": "180", - "color": Object { - "id": "75", - "name": "Starry", - }, - "id": "4751", - "layers": Array [ - Object { - "id": "5995", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0", - "zone": Object { - "depth": 18, - }, - }, - Object { - "id": "5996", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0", - "zone": Object { - "depth": 7, - }, - }, - Object { - "id": "6000", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0", - "zone": Object { - "depth": 40, - }, - }, - Object { - "id": "16467", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0", - "zone": Object { - "depth": 34, - }, - }, - Object { - "id": "19550", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0", - "zone": Object { - "depth": 38, - }, - }, - Object { - "id": "19784", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28892/600x600.png?v2-1313418652000", - "zone": Object { - "depth": 37, - }, - }, - Object { - "id": "163528", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000", - "zone": Object { - "depth": 38, - }, - }, - ], - "petStateId": "4751", - "pose": "UNKNOWN", - "species": Object { - "id": "54", - "name": "Zafara", - }, - }, - Object { - "bodyId": "180", - "color": Object { - "id": "75", - "name": "Starry", - }, - "id": "2", - "layers": Array [ - Object { - "id": "5995", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0", - "zone": Object { - "depth": 18, - }, - }, - Object { - "id": "5996", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0", - "zone": Object { - "depth": 7, - }, - }, - Object { - "id": "6000", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0", - "zone": Object { - "depth": 40, - }, - }, - Object { - "id": "16467", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0", - "zone": Object { - "depth": 34, - }, - }, - Object { - "id": "19549", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28548/600x600.png?v2-1345719457000", - "zone": Object { - "depth": 37, - }, - }, - Object { - "id": "19550", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0", - "zone": Object { - "depth": 38, - }, - }, - Object { - "id": "163528", - "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000", - "zone": Object { - "depth": 38, - }, - }, - ], - "petStateId": "2", - "pose": "UNKNOWN", - "species": Object { - "id": "54", - "name": "Zafara", - }, - }, Object { "bodyId": "180", "color": Object { @@ -548,6 +424,285 @@ Object { "name": "Zafara", }, }, + Object { + "bodyId": "180", + "color": Object { + "id": "75", + "name": "Starry", + }, + "id": "4751", + "layers": Array [ + Object { + "id": "5995", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0", + "zone": Object { + "depth": 18, + }, + }, + Object { + "id": "5996", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0", + "zone": Object { + "depth": 7, + }, + }, + Object { + "id": "6000", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0", + "zone": Object { + "depth": 40, + }, + }, + Object { + "id": "16467", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0", + "zone": Object { + "depth": 34, + }, + }, + Object { + "id": "19550", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0", + "zone": Object { + "depth": 38, + }, + }, + Object { + "id": "19784", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28892/600x600.png?v2-1313418652000", + "zone": Object { + "depth": 37, + }, + }, + Object { + "id": "163528", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000", + "zone": Object { + "depth": 38, + }, + }, + ], + "petStateId": "4751", + "pose": "UNKNOWN", + "species": Object { + "id": "54", + "name": "Zafara", + }, + }, + Object { + "bodyId": "180", + "color": Object { + "id": "75", + "name": "Starry", + }, + "id": "2", + "layers": Array [ + Object { + "id": "5995", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7941/600x600.png?v2-0", + "zone": Object { + "depth": 18, + }, + }, + Object { + "id": "5996", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7942/600x600.png?v2-0", + "zone": Object { + "depth": 7, + }, + }, + Object { + "id": "6000", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/007/7946/600x600.png?v2-0", + "zone": Object { + "depth": 40, + }, + }, + Object { + "id": "16467", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/024/24008/600x600.png?v2-0", + "zone": Object { + "depth": 34, + }, + }, + Object { + "id": "19549", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28548/600x600.png?v2-1345719457000", + "zone": Object { + "depth": 37, + }, + }, + Object { + "id": "19550", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-0", + "zone": Object { + "depth": 38, + }, + }, + Object { + "id": "163528", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/028/28549/600x600.png?v2-1326455337000", + "zone": Object { + "depth": 38, + }, + }, + ], + "petStateId": "2", + "pose": "UNKNOWN", + "species": Object { + "id": "54", + "name": "Zafara", + }, + }, ], } `; + +exports[`PetAppearance loads unconverted appearance 1`] = ` +Object { + "petAppearance": Object { + "color": Object { + "id": "63", + "isStandard": true, + "name": "Royalboy", + }, + "id": "2571", + "layers": Array [ + Object { + "id": "9941", + "imageUrl": "https://impress-asset-images.s3.amazonaws.com/biology/000/000/013/13024/600x600.png?v2-0", + "restrictedZones": Array [ + Object { + "id": "4", + }, + Object { + "id": "5", + }, + Object { + "id": "6", + }, + Object { + "id": "7", + }, + Object { + "id": "8", + }, + Object { + "id": "9", + }, + Object { + "id": "10", + }, + Object { + "id": "11", + }, + Object { + "id": "12", + }, + Object { + "id": "13", + }, + Object { + "id": "14", + }, + Object { + "id": "15", + }, + Object { + "id": "16", + }, + Object { + "id": "17", + }, + Object { + "id": "18", + }, + Object { + "id": "19", + }, + Object { + "id": "20", + }, + Object { + "id": "21", + }, + Object { + "id": "22", + }, + Object { + "id": "23", + }, + Object { + "id": "24", + }, + Object { + "id": "25", + }, + Object { + "id": "26", + }, + Object { + "id": "27", + }, + Object { + "id": "28", + }, + Object { + "id": "29", + }, + Object { + "id": "30", + }, + Object { + "id": "31", + }, + Object { + "id": "32", + }, + Object { + "id": "33", + }, + Object { + "id": "34", + }, + Object { + "id": "35", + }, + Object { + "id": "36", + }, + Object { + "id": "37", + }, + Object { + "id": "38", + }, + Object { + "id": "39", + }, + Object { + "id": "40", + }, + Object { + "id": "41", + }, + Object { + "id": "42", + }, + Object { + "id": "43", + }, + ], + "svgUrl": "http://images.neopets.com/cp/bio/data/000/000/013/13024_18911a85d1/13024.svg", + "zone": Object { + "depth": 48, + }, + }, + ], + "species": Object { + "id": "1", + "name": "Acara", + }, + }, +} +`; diff --git a/src/server/util.js b/src/server/util.js index 2b0bfce..dd4ccd8 100644 --- a/src/server/util.js +++ b/src/server/util.js @@ -122,6 +122,16 @@ function getPoseName(pose) { return POSE_NAMES[pose]; } +function getRestrictedZoneIds(zonesRestrict) { + const restrictedZoneIds = []; + for (const [i, bit] of Array.from(zonesRestrict).entries()) { + if (bit === "1") { + restrictedZoneIds.push(i + 1); + } + } + return restrictedZoneIds; +} + async function loadBodyName(bodyId, db) { if (String(bodyId) === "0") { return "All bodies"; @@ -188,6 +198,7 @@ module.exports = { getPetStateFieldsFromPose, getPoseFromPetData, getPoseName, + getRestrictedZoneIds, loadBodyName, logToDiscord, normalizeRow,