mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-03-21 17:50:29 -05:00
The idea is to eventually move all client parts to their domain name subdirectory, for clarity and better organization. New Replays is just first. Anyway, yeah, minor updates to New Replays, but otherwise it's just getting deployed as-is, straight to https://replay.pokemonshowdown.com/ The old URLs are getting taken down; they were only used for development anyway.
215 lines
7.5 KiB
JavaScript
Executable File
215 lines
7.5 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.
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
const crypto = require('crypto');
|
|
const child_process = require('child_process');
|
|
const compiler = require('./compiler');
|
|
|
|
const thisDir = __dirname;
|
|
const rootDir = path.resolve(thisDir, '..');
|
|
process.chdir(rootDir);
|
|
|
|
const AUTOCONFIG_START = '/*** Begin automatically generated configuration ***/';
|
|
const AUTOCONFIG_END = '/*** End automatically generated configuration ***/';
|
|
|
|
function escapeRegex(string) {
|
|
return string.replace(/[\/\*\.]/g, '\\$&');
|
|
}
|
|
|
|
/*********************************************************
|
|
* Update version number
|
|
*********************************************************/
|
|
|
|
process.stdout.write("Updating version... ");
|
|
|
|
let version = require('../package.json').version;
|
|
try {
|
|
let commit = child_process.execSync('git rev-parse HEAD', {
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
});
|
|
const head = ('' + commit).trim();
|
|
commit = child_process.execSync('git merge-base origin/master HEAD', {
|
|
stdio: ['ignore', 'pipe', 'ignore'],
|
|
});
|
|
const origin = ('' + commit).trim();
|
|
version += ` (${head.slice(0, 8)}${head !== origin ? `/${origin.slice(0, 8)}` : ''})`;
|
|
} catch (e) {}
|
|
|
|
const routes = JSON.parse(fs.readFileSync('config/routes.json'));
|
|
const autoconfigRegex = new RegExp(`${escapeRegex(AUTOCONFIG_START)}[^]+${escapeRegex(AUTOCONFIG_END)}`);
|
|
const autoconfig = `${AUTOCONFIG_START}
|
|
Config.version = ${JSON.stringify(version)};
|
|
|
|
Config.routes = {
|
|
root: '${routes.root}',
|
|
client: '${routes.client}',
|
|
dex: '${routes.dex}',
|
|
replays: '${routes.replays}',
|
|
users: '${routes.users}',
|
|
};
|
|
${AUTOCONFIG_END}`;
|
|
|
|
// remove old automatically generated configuration and add the new one
|
|
let configBuf = fs.readFileSync('config/config.js', {encoding: 'utf8'});
|
|
if (autoconfigRegex.test(configBuf)) {
|
|
configBuf = configBuf.replace(autoconfigRegex, autoconfig);
|
|
} else {
|
|
configBuf += autoconfig;
|
|
}
|
|
fs.writeFileSync('config/config.js', configBuf);
|
|
console.log("DONE");
|
|
|
|
/*********************************************************
|
|
* Compile TS files
|
|
*********************************************************/
|
|
|
|
process.stdout.write("Compiling TS files... ");
|
|
|
|
let compileStartTime = process.hrtime();
|
|
let compiledFiles = 0;
|
|
|
|
// Babel can't find babelrc if we try to compile stuff in data/pokemon-showdown/ fsr
|
|
let compileOpts = Object.assign(eval('(' + fs.readFileSync('.babelrc') + ')'), {
|
|
babelrc: false,
|
|
incremental: true,
|
|
ignore: ['src/battle-animations.js', 'src/battle-animations-moves.js'],
|
|
});
|
|
if (process.argv[2] === 'full') {
|
|
delete compileOpts.ignore;
|
|
compiler.compileToDir(
|
|
['data/pokemon-showdown/server/chat-formatter.ts'],
|
|
'js/server/',
|
|
compileOpts
|
|
);
|
|
} else {
|
|
try {
|
|
fs.statSync('data/graphics.js');
|
|
// graphics.js exists, recompile it
|
|
delete compileOpts.ignore;
|
|
} catch (e) {}
|
|
}
|
|
|
|
compiledFiles += compiler.compileToDir(`src`, `js`, compileOpts);
|
|
|
|
compiledFiles += compiler.compileToDir(`replay.pokemonshowdown.com/src`, `replay.pokemonshowdown.com/js`, compileOpts);
|
|
|
|
compiledFiles += compiler.compileToFile(
|
|
['src/battle-dex.ts', 'src/battle-dex-data.ts', 'src/battle-log.ts', 'src/battle-log-misc.js', 'data/pokemon-showdown/server/chat-formatter.ts', 'data/text.js', 'src/battle-text-parser.ts'],
|
|
'js/battledata.js',
|
|
compileOpts
|
|
);
|
|
|
|
if (!compileOpts.ignore) {
|
|
compiledFiles += compiler.compileToFile(
|
|
['src/battle-animations.ts', 'src/battle-animations-moves.ts'],
|
|
'data/graphics.js',
|
|
compileOpts
|
|
);
|
|
}
|
|
|
|
const diff = process.hrtime(compileStartTime);
|
|
console.log(
|
|
`(${compiledFiles} ${compiledFiles !== 1 ? "files" : "file"} in ${diff[0] + Math.round(diff[1] / 1e6) / 1e3}s) DONE`
|
|
);
|
|
|
|
/*********************************************************
|
|
* Update cachebuster and News
|
|
*********************************************************/
|
|
|
|
process.stdout.write("Updating cachebuster and URLs... ");
|
|
|
|
const URL_REGEX = /(src|href)="(.*?)(\?[a-z0-9]*?)?"/g;
|
|
|
|
function updateURL(a, b, c, d) {
|
|
c = c.replace('/replay.pokemonshowdown.com/', '/' + routes.replays + '/');
|
|
c = c.replace('/dex.pokemonshowdown.com/', '/' + routes.dex + '/');
|
|
c = c.replace('/play.pokemonshowdown.com/', '/' + routes.client + '/');
|
|
c = c.replace('/pokemonshowdown.com/', '/' + routes.root + '/');
|
|
|
|
if (d) {
|
|
if (c.startsWith('/')) {
|
|
let hash = Math.random(); // just in case creating the hash fails
|
|
try {
|
|
const filename = c.slice(1).replace('/' + routes.client + '/', '');
|
|
const fstr = fs.readFileSync(filename, {encoding: 'utf8'});
|
|
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
|
|
} catch (e) {}
|
|
|
|
return b + '="' + c + '?' + hash + '"';
|
|
} else {
|
|
// hardcoded to Replays rn; TODO: generalize
|
|
let hash;
|
|
try {
|
|
const fstr = fs.readFileSync('replay.pokemonshowdown.com/' + c, {encoding: 'utf8'});
|
|
hash = crypto.createHash('md5').update(fstr).digest('hex').substr(0, 8);
|
|
} catch (e) {}
|
|
|
|
return b + '="' + c + '?' + (hash || 'v1') + '"';
|
|
}
|
|
} else {
|
|
return b + '="' + c + '"';
|
|
}
|
|
}
|
|
|
|
function writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents) {
|
|
fs.writeFileSync('index.html', indexContents);
|
|
fs.writeFileSync('preactalpha.html', preactIndexContents);
|
|
fs.writeFileSync('crossprotocol.html', crossprotocolContents);
|
|
fs.writeFileSync('js/replay-embed.js', replayEmbedContents);
|
|
|
|
let replaysContents = fs.readFileSync('replay.pokemonshowdown.com/index.template.html', {encoding: 'utf8'});
|
|
replaysContents = replaysContents.replace(URL_REGEX, updateURL);
|
|
fs.writeFileSync('replay.pokemonshowdown.com/index.html', replaysContents);
|
|
|
|
console.log("DONE");
|
|
}
|
|
|
|
function updateFiles() {
|
|
// add hashes to js and css files and rewrite URLs
|
|
let indexContents = fs.readFileSync('index.template.html', {encoding: 'utf8'});
|
|
indexContents = indexContents.replace(URL_REGEX, updateURL);
|
|
let preactIndexContents = fs.readFileSync('preactalpha.template.html', {encoding: 'utf8'});
|
|
preactIndexContents = preactIndexContents.replace(URL_REGEX, updateURL);
|
|
let crossprotocolContents = fs.readFileSync('crossprotocol.template.html', {encoding: 'utf8'});
|
|
crossprotocolContents = crossprotocolContents.replace(URL_REGEX, updateURL);
|
|
let replayEmbedContents = fs.readFileSync('js/replay-embed.template.js', {encoding: 'utf8'});
|
|
replayEmbedContents = replayEmbedContents.replace(/play\.pokemonshowdown\.com/g, routes.client);
|
|
|
|
// add news, only if it's actually likely to exist
|
|
if (__dirname.endsWith('play.pokemonshowdown.com/build-tools')) {
|
|
process.stdout.write("and news... ");
|
|
child_process.exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) {
|
|
let newsData = [0, '[failed to retrieve news]'];
|
|
if (!error && !stderr) {
|
|
try {
|
|
newsData = JSON.parse(stdout);
|
|
} catch (e) {
|
|
console.log("git hook failed to retrieve news (parsing JSON failed):\n" + e.stack);
|
|
}
|
|
} else {
|
|
console.log("git hook failed to retrieve news (exec command failed):\n" + (error + stderr + stdout));
|
|
}
|
|
|
|
indexContents = indexContents.replace(/<!-- newsid -->/g, newsData[0]);
|
|
indexContents = indexContents.replace(/<!-- news -->/g, newsData[1]);
|
|
|
|
indexContents = indexContents.replace(/<!-- head custom -->/g, '' + fs.readFileSync('config/head-custom.html'));
|
|
|
|
writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents);
|
|
});
|
|
} else {
|
|
writeFiles(indexContents, preactIndexContents, crossprotocolContents, replayEmbedContents);
|
|
}
|
|
}
|
|
|
|
updateFiles();
|