Files
pokemon-showdown-client/build-tools/build-learnsets
Guangcong Luo 57e9c46f9d Preact minor updates batch 34
- Fix teams count in teambuilder
- Fix news publishing
- Modernize build-tools
  - Not all of them could be converted to ESM but I did what I could
- In vertical tabs, show notification on tabbar when receiving DMs
  - This is closer to Discord's behavior
- Add more info to the sprites pages
- Support custom avatars on unregistered servers
- Support reaching DMs with Alt+Shift+Arrows
- Improve pasting
  - Still quite buggy on Android, but should be much less so on desktop
2026-06-24 06:42:03 +00:00

143 lines
4.6 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* This script parses index.html and sets the version query string of each
* resource to be the MD5 hash of that resource.
* It also updates news and the learnsets-g6.js file.
*
* On the live web server, this script is set as the following git hooks:
* post-commit, post-checkout, post-merge, post-rewrite
*/
"use strict";
import fs from 'node:fs';
import dexModule from '../caches/pokemon-showdown/dist/sim/dex.js';
process.chdir(import.meta.dirname + '/..');
const thisFile = 'build-tools/build-learnsets';
const { Dex } = dexModule;
const toID = Dex.toID;
function updateLearnsets(callback) {
const numberRegExp = /^[0-9]*/;
const reservedRegExp = /^(return|\d.*)$/g; // `return` is the only ES3+ reserved keyword that (currently) raises conflicts
const alphabetize = (a, b) => a.localeCompare(b);
const formatLset = function (lset) {
const secondChar = lset.charAt(1);
if (secondChar !== 'L') return lset;
const firstFragment = lset.substr(0, 2);
const levelFragment = lset.substr(2).match(numberRegExp)[0];
const sortFragment = lset.substr(2 + levelFragment.length);
return firstFragment + levelFragment.padStart(3, '0') + sortFragment;
};
const Pokedex = Dex.data.Pokedex;
const Learnsets = Dex.data.Learnsets;
const newLearnsetsG6 = {};
for (const speciesid in Learnsets) {
const newLearnset = {};
const fullLearnset = Learnsets[speciesid].learnset;
for (const moveid in fullLearnset) {
newLearnset[moveid] = fullLearnset[moveid].filter(
learned => "87".includes(learned.charAt(0))
).map(
formatLset
).sort(
alphabetize
);
}
newLearnsetsG6[speciesid] = { learnset: newLearnset };
}
const buf = [];
const pokemonList = Object.keys(Pokedex).map(speciesId => Pokedex[speciesId]).sort((a, b) => {
// Missingno. goes first (zeroth); afterwards, CAP in descending dex order (increasingly negative)
// Finally, standard Pokémon in ascending dex order
if (a.num <= 0 && b.num > 0) return -1;
if (b.num <= 0 && a.num > 0) return 1;
if (a.num <= 0 && b.num <= 0) return b.num - a.num;
return a.num - b.num;
}).map(species => toID(species.name));
for (const speciesid of pokemonList) {
const entry = newLearnsetsG6[speciesid];
if (!entry || !entry.learnset) continue;
const lsetSerialized = '{' + Object.keys(entry.learnset).sort(alphabetize).map(
moveid => moveid.replace(reservedRegExp, '"$1"') + ':' + JSON.stringify(entry.learnset[moveid])
).join(',') + '}';
buf.push(speciesid + ':{learnset:' + lsetSerialized + '}');
}
const writeStream = fs.createWriteStream('play.pokemonshowdown.com/data/learnsets-g6.js').on('error', callback);
writeStream.write('exports.BattleLearnsets = {\n\t' + buf.join(',\n\t') + '\n};\n');
writeStream.end(callback);
}
let indexStats, updateStats, indexMTime, updateMTime;
try {
indexStats = fs.statSync('play.pokemonshowdown.com/index.html');
indexMTime = indexStats.mtime.getTime();
} catch (err) {
if (err.code !== 'ENOENT') throw err;
// It doesn't exist currently, but it will by the end of the script execution.
// Any other error is unacceptable and will throw.
}
{
updateStats = fs.statSync(thisFile);
updateMTime = updateStats.mtime.getTime();
}
// update learnsets-g6
process.stdout.write("Updating file `data/learnsets-g6`... ");
let learnsetsStats;
let learnsetsG6Stats;
let learnsetsG6ToUpdate = true;
try {
learnsetsStats = fs.statSync('play.pokemonshowdown.com/data/learnsets.js');
} catch {
// Couldn't find learnsets.js, but that's not the end of the world: skip to next task.
console.error("Couldn't find `data/learnsets.js`. Task aborted.");
learnsetsG6ToUpdate = false;
}
if (learnsetsG6ToUpdate) {
try {
learnsetsG6Stats = fs.statSync('play.pokemonshowdown.com/data/learnsets-g6.js');
} catch (err) {
if (err.code === 'ENOENT') {
// It doesn't exist currently, but it will by the end of the script execution.
} else {
// Any other error is unacceptable for learnsets-g6.js update: skip to next task.
console.error("Failed to read `data/learnsets-g6.js`. Task aborted.");
learnsetsG6ToUpdate = false;
}
}
}
if (learnsetsG6ToUpdate && (
!indexStats || !learnsetsG6Stats || indexMTime < updateMTime || indexMTime < learnsetsStats.mtime.getTime() ||
indexMTime < learnsetsG6Stats.mtime.getTime()
)) {
// Only merge learnsets.js with learnsets-g6.js if any of those files, or this one, have been modified recently (or if we don't know what "recently" means)
updateLearnsets(err => {
if (err) {
let stack = err.stack || '';
stack = "File `data/learnsets-g6` failed to update.\n" + stack;
console.error(stack);
} else {
console.log("DONE");
}
});
} else {
console.log("CACHED");
}