diff --git a/pages/api/validPetPoses.js b/pages/api/validPetPoses.js index 20d3eaa..6014825 100644 --- a/pages/api/validPetPoses.js +++ b/pages/api/validPetPoses.js @@ -12,13 +12,17 @@ import { getPoseFromPetState, normalizeRow } from "../../src/server/util"; export async function getValidPetPoses() { const db = await connectToDb(); - const numSpeciesPromise = getNumSpecies(db); - const numColorsPromise = getNumColors(db); + const largestSpeciesIdPromise = getLargestSpeciesId(db); + const largestColorIdPromise = getLargestColorId(db); const distinctPetStatesPromise = getDistinctPetStates(db); - const [numSpecies, numColors, distinctPetStates] = await Promise.all([ - numSpeciesPromise, - numColorsPromise, + const [ + largestSpeciesId, + largestColorId, + distinctPetStates, + ] = await Promise.all([ + largestSpeciesIdPromise, + largestColorIdPromise, distinctPetStatesPromise, ]); @@ -35,14 +39,23 @@ export async function getValidPetPoses() { return poseStrs.has(poseStr); } - const numPairs = numSpecies * numColors; + // NOTE: We base the size of the array on the _largest_ color and species IDs + // in the database, not the _number_ of colors and species. This is + // because TNT sometimes skips IDs when working on multiple colors at + // once, so it's possible to have e.g. 113 released colors, but have + // the largest color ID be #114, because #113 was skipped. In that case, + // we leave an empty byte at skipped IDs, and that's okay because they + // don't skip a whole bunch of color IDs at once. (This would be a bad + // idea for network perf if e.g. TNT skipped to color #9999, because we + // would then leave a LOT of empty bytes in the array!) + const numPairs = largestSpeciesId * largestColorId; const buffer = Buffer.alloc(numPairs + 2); - buffer.writeUInt8(numSpecies, 0); - buffer.writeUInt8(numColors, 1); + buffer.writeUInt8(largestSpeciesId, 0); + buffer.writeUInt8(largestColorId, 1); - for (let speciesId = 1; speciesId <= numSpecies; speciesId++) { + for (let speciesId = 1; speciesId <= largestSpeciesId; speciesId++) { const speciesIndex = speciesId - 1; - for (let colorId = 1; colorId <= numColors; colorId++) { + for (let colorId = 1; colorId <= largestColorId; colorId++) { const colorIndex = colorId - 1; // We fill in the high bits first, and shift left as we go! @@ -63,21 +76,21 @@ export async function getValidPetPoses() { byte <<= 1; byte += hasPose(speciesId, colorId, "HAPPY_MASC") ? 1 : 0; - buffer.writeUInt8(byte, speciesIndex * numColors + colorIndex + 2); + buffer.writeUInt8(byte, speciesIndex * largestColorId + colorIndex + 2); } } return buffer; } -async function getNumSpecies(db) { - const [rows] = await db.query(`SELECT count(*) FROM species`); - return rows[0]["count(*)"]; +async function getLargestSpeciesId(db) { + const [rows] = await db.query(`SELECT max(id) FROM species`); + return rows[0]["max(id)"]; } -async function getNumColors(db) { - const [rows] = await db.query(`SELECT count(*) FROM colors WHERE prank = 0`); - return rows[0]["count(*)"]; +async function getLargestColorId(db) { + const [rows] = await db.query(`SELECT max(id) FROM colors WHERE prank = 0`); + return rows[0]["max(id)"]; } async function getDistinctPetStates(db) {