mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-10-02 15:53:11 -05:00
Merge pull request #311 from Slayer95/learnsets-update
Improve learnsets-g6 updater
This commit is contained in:
277
githooks/update
277
githooks/update
@@ -15,6 +15,7 @@ var crypto = require('crypto');
|
||||
var exec = require('child_process').exec;
|
||||
var sugar = require('sugar');
|
||||
|
||||
var thisFile = __filename;
|
||||
var thisDir = __dirname;
|
||||
var rootDir = path.resolve(thisDir, '..');
|
||||
|
||||
@@ -27,7 +28,7 @@ function updateIndex () {
|
||||
var indexContents = fs.readFileSync(path.resolve(rootDir, 'index.template.html'), { encoding: 'utf8' });
|
||||
|
||||
// add hashes to js and css files
|
||||
console.log('Updating hashes...');
|
||||
console.log("Updating hashes...");
|
||||
indexContents = indexContents.replace(/(src|href)="\/(.*?)\?[a-z0-9]*?"/g, function (a, b, c) {
|
||||
var hash = Math.random(); // just in case creating the hash fails
|
||||
try {
|
||||
@@ -38,10 +39,10 @@ function updateIndex () {
|
||||
|
||||
return b + '="/' + c + '?' + hash + '"';
|
||||
});
|
||||
console.log('Hashes updated.');
|
||||
console.log("Hashes updated.");
|
||||
|
||||
// add news
|
||||
console.log('Updating news...');
|
||||
console.log("Updating news...");
|
||||
exec('php ' + path.resolve(thisDir, 'news-data.php'), function (error, stdout, stderr) {
|
||||
var newsData = [0, '[failed to retrieve news]'];
|
||||
if (!error && !stderr) {
|
||||
@@ -56,119 +57,191 @@ function updateIndex () {
|
||||
|
||||
indexContents = indexContents.replace(/<!-- newsid -->/g, newsData[0]);
|
||||
indexContents = indexContents.replace(/<!-- news -->/g, newsData[1]);
|
||||
console.log("News updated.");
|
||||
|
||||
console.log("Writing new `index.html` file...");
|
||||
fs.writeFileSync(path.resolve(rootDir, 'index.html'), indexContents);
|
||||
console.log('News updated.');
|
||||
console.log("File `index.html` successfully updated.");
|
||||
});
|
||||
}
|
||||
|
||||
function updateLearnsets (callback) {
|
||||
var reservedKeywords = ['return']; // `return` is the only ES3+ reserved keyword that (currently) raises conflicts
|
||||
var numberRegExp = new RegExp('^[0-9]*');
|
||||
var reservedRegExp = new RegExp('^(' + reservedKeywords.join('|') + ')$', 'g');
|
||||
var alphabetize = function (a, b) {return a.localeCompare(b);};
|
||||
var getLsetGen = function (lset) {return lset.charAt(0);};
|
||||
|
||||
var padNumString = function (str) {
|
||||
switch (str.length) {
|
||||
case 1: return '00' + str;
|
||||
case 2: return '0' + str;
|
||||
case 3: return '' + str;
|
||||
}
|
||||
};
|
||||
var inLearnset = function (lset, learnset) {
|
||||
var secondChar = lset.charAt(1);
|
||||
if (secondChar !== 'L') return learnset.indexOf(lset) >= 0;
|
||||
|
||||
var firstFragment = lset.substr(0, 2);
|
||||
var levelFragment = lset.substr(2);
|
||||
var paddedLevel = padNumString(levelFragment);
|
||||
for (var i = 0, len = learnset.length; i < len; i++) {
|
||||
if (learnset[i].substring(0, 2) !== firstFragment) continue;
|
||||
// ignore PSdex starter moves sorting data
|
||||
if (learnset[i].substring(2, 5) === paddedLevel) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
var formatLset = function (lset) {
|
||||
var secondChar = lset.charAt(1);
|
||||
if (secondChar !== 'L') return lset;
|
||||
var firstFragment = lset.substr(0, 2);
|
||||
var levelFragment = lset.substr(2).match(numberRegExp)[0];
|
||||
var sortFragment = lset.substr(2 + levelFragment.length);
|
||||
return firstFragment + padNumString(levelFragment) + sortFragment;
|
||||
};
|
||||
|
||||
var Pokedex, Learnsets, oldLearnsetsG6, newLearnsetsG6;
|
||||
newLearnsetsG6 = {};
|
||||
try {
|
||||
Pokedex = require(path.join(rootDir, 'data', 'pokedex.js')).BattlePokedex;
|
||||
Learnsets = require(path.join(rootDir, 'data', 'learnsets.js')).BattleLearnsets;
|
||||
} catch (err) {
|
||||
return callback(err);
|
||||
}
|
||||
try {
|
||||
oldLearnsetsG6 = require(path.join(rootDir, 'data', 'learnsets-g6.js')).BattleLearnsets;
|
||||
} catch (err) {
|
||||
if (err.code !== 'MODULE_NOT_FOUND') return callback(err);
|
||||
oldLearnsetsG6 = {};
|
||||
}
|
||||
|
||||
for (var speciesid in Learnsets) {
|
||||
if (!oldLearnsetsG6[speciesid] || !oldLearnsetsG6[speciesid].learnset) {
|
||||
console.log("NEW ENTRY at learnsets-g6.js: " + Pokedex[speciesid].species + ".");
|
||||
oldLearnsetsG6[speciesid] = {learnset: {}};
|
||||
}
|
||||
}
|
||||
for (var speciesid in oldLearnsetsG6) {
|
||||
if (!oldLearnsetsG6[speciesid] || !oldLearnsetsG6[speciesid].learnset) return callback(new TypeError("Invalid `learnsets-g6.js` entry for " + speciesid + "."));
|
||||
if (!Learnsets[speciesid]) {
|
||||
console.log("REMOVED ENTRY at learnsets-g6.js: " + Pokedex[speciesid].species + ".");
|
||||
continue;
|
||||
}
|
||||
var newLearnset = {};
|
||||
var oldLearnset = oldLearnsetsG6[speciesid].learnset;
|
||||
var fullLearnset = Learnsets[speciesid].learnset;
|
||||
if (!fullLearnset) return callback(new TypeError("Invalid data at `learnsets.js` for " + speciesid + "."));
|
||||
|
||||
// clone
|
||||
for (var moveid in oldLearnset) {
|
||||
if (!Array.isArray(oldLearnset[moveid])) return callback(new TypeError("Invalid data at `learnsets-g6.js` for " + speciesid + ":" + moveid + "."));
|
||||
newLearnset[moveid] = oldLearnset[moveid].slice();
|
||||
}
|
||||
|
||||
for (var moveid in fullLearnset) {
|
||||
if (!Array.isArray(fullLearnset[moveid])) return callback(new TypeError("Invalid data at `learnsets.js` for " + speciesid + ":" + moveid + "."));
|
||||
|
||||
if (!newLearnset[moveid]) newLearnset[moveid] = [];
|
||||
newLearnset[moveid] = newLearnset[moveid].map(formatLset);
|
||||
for (var i = 0, len = fullLearnset[moveid].length; i < len; i++) {
|
||||
if (getLsetGen(fullLearnset[moveid][i]) !== '6') continue;
|
||||
if (inLearnset(fullLearnset[moveid][i], newLearnset[moveid])) continue;
|
||||
newLearnset[moveid].push(formatLset(fullLearnset[moveid][i]));
|
||||
}
|
||||
newLearnset[moveid].sort(alphabetize);
|
||||
}
|
||||
|
||||
newLearnsetsG6[speciesid] = {learnset: newLearnset};
|
||||
}
|
||||
|
||||
var buf = [];
|
||||
var pokemonList = Object.values(Pokedex).sort(function (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').map(toId);
|
||||
|
||||
for (var i = 0, len = pokemonList.length; i < len; i++) {
|
||||
var entry = newLearnsetsG6[pokemonList[i]];
|
||||
if (!entry || !entry.learnset) continue;
|
||||
var lsetSerialized = '{' + Object.keys(entry.learnset).sort(alphabetize).map(function (moveid) {
|
||||
return moveid.replace(reservedRegExp, '"$1"') + ':' + JSON.stringify(entry.learnset[moveid]);
|
||||
}).join(',') + '}';
|
||||
buf.push(pokemonList[i] + ':{learnset:' + lsetSerialized + '}');
|
||||
}
|
||||
|
||||
var writeStream = fs.createWriteStream(path.join(rootDir, 'data', 'learnsets-g6.js')).on('error', callback);
|
||||
writeStream.write('exports.BattleLearnsets = {\n\t' + buf.join(',\n\t') + '\n};\n');
|
||||
writeStream.end(callback);
|
||||
}
|
||||
|
||||
var pendingFiles = 0;
|
||||
var indexStats, updateStats, indexMTime, updateMTime;
|
||||
try {
|
||||
indexStats = fs.statSync(path.join(rootDir, '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.
|
||||
}
|
||||
try {
|
||||
updateStats = fs.statSync(thisFile);
|
||||
updateMTime = indexStats.mtime.getTime();
|
||||
} catch (err) {
|
||||
throw err; // !!
|
||||
}
|
||||
|
||||
// update learnsets-g6
|
||||
console.log("Updating file `data/learnsets-g6`...");
|
||||
|
||||
pendingFiles++;
|
||||
console.log('Updating file `data/learnsets-g6`...');
|
||||
var reservedKeywords = ['return']; // `return` is the only ES3+ reserved keyword that (currently) raises conflicts
|
||||
var numberRegExp = new RegExp('^[0-9]*');
|
||||
var reservedRegExp = new RegExp('^(' + reservedKeywords.join('|') + ')$', 'g');
|
||||
var alphabetize = function (a, b) {return a.localeCompare(b)};
|
||||
var getLsetGen = function (lset) {return lset.charAt(0)};
|
||||
var learnsetsStats;
|
||||
var learnsetsG6Stats;
|
||||
var learnsetsG6ToUpdate = true;
|
||||
|
||||
var padNumString = function (str) {
|
||||
switch (str.length) {
|
||||
case 1: return '00' + str;
|
||||
case 2: return '0' + str;
|
||||
case 3: return '' + str;
|
||||
}
|
||||
};
|
||||
var inLearnset = function (lset, learnset) {
|
||||
var secondChar = lset.charAt(1);
|
||||
if (secondChar !== 'L') return learnset.indexOf(lset) >= 0;
|
||||
|
||||
var firstFragment = lset.substr(0, 2);
|
||||
var levelFragment = lset.substr(2);
|
||||
var paddedLevel = padNumString(levelFragment);
|
||||
for (var i = 0, len = learnset.length; i < len; i++) {
|
||||
if (learnset[i].substring(0, 2) !== firstFragment) continue;
|
||||
// ignore PSdex starter moves sorting data
|
||||
if (learnset[i].substring(2, 5) === paddedLevel) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
var formatLset = function (lset) {
|
||||
var secondChar = lset.charAt(1);
|
||||
if (secondChar !== 'L') return lset;
|
||||
var firstFragment = lset.substr(0, 2);
|
||||
var levelFragment = lset.substr(2).match(numberRegExp)[0];
|
||||
var sortFragment = lset.substr(2 + levelFragment.length);
|
||||
return firstFragment + padNumString(levelFragment) + sortFragment;
|
||||
};
|
||||
|
||||
var Learnsets = require(path.join(rootDir, 'data', 'learnsets.js')).BattleLearnsets;
|
||||
var oldLearnsetsG6 = require(path.join(rootDir, 'data', 'learnsets-g6.js')).BattleLearnsets;
|
||||
var Pokedex = require(path.join(rootDir, 'data', 'pokedex.js')).BattlePokedex;
|
||||
var newLearnsetsG6 = {};
|
||||
|
||||
for (var speciesid in Learnsets) {
|
||||
if (!oldLearnsetsG6[speciesid] || !oldLearnsetsG6[speciesid].learnset) {
|
||||
console.log("NEW: " + Pokedex[speciesid].species + ".");
|
||||
oldLearnsetsG6[speciesid] = {learnset: {}};
|
||||
}
|
||||
try {
|
||||
learnsetsStats = fs.statSync(path.join(rootDir, 'data', 'learnsets.js'));
|
||||
} catch (err) {
|
||||
// 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 (!--pendingFiles) updateIndex();
|
||||
}
|
||||
for (var speciesid in oldLearnsetsG6) {
|
||||
if (!Learnsets[speciesid] || !Learnsets[speciesid].learnset) throw new Error("Missing learnsets.js entry for " + speciesid + ".");
|
||||
if (!oldLearnsetsG6[speciesid] || !oldLearnsetsG6[speciesid].learnset) throw new Error("Invalid learnsets-g6.js entry for " + speciesid + ".");
|
||||
|
||||
var fullLearnset = Learnsets[speciesid].learnset;
|
||||
var oldLearnset = oldLearnsetsG6[speciesid].learnset;
|
||||
var newLearnset = {};
|
||||
|
||||
// clone
|
||||
for (var moveid in oldLearnset) {
|
||||
if (!Array.isArray(oldLearnset[moveid])) throw new TypeError("Invalid data at learnsets-g6.js for " + speciesid + ":" + moveid + ".");
|
||||
newLearnset[moveid] = oldLearnset[moveid].slice();
|
||||
}
|
||||
|
||||
for (var moveid in fullLearnset) {
|
||||
if (!Array.isArray(fullLearnset[moveid])) throw new TypeError("Invalid data at learnsets.js for " + speciesid + ":" + moveid + ".");
|
||||
|
||||
if (!newLearnset[moveid]) newLearnset[moveid] = [];
|
||||
newLearnset[moveid] = newLearnset[moveid].map(formatLset);
|
||||
for (var i = 0, len = fullLearnset[moveid].length; i < len; i++) {
|
||||
if (getLsetGen(fullLearnset[moveid][i]) !== '6') continue;
|
||||
if (inLearnset(fullLearnset[moveid][i], newLearnset[moveid])) continue;
|
||||
newLearnset[moveid].push(formatLset(fullLearnset[moveid][i]));
|
||||
if (learnsetsG6ToUpdate) {
|
||||
try {
|
||||
learnsetsG6Stats = fs.statSync(path.join(rootDir, '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 (!--pendingFiles) updateIndex();
|
||||
}
|
||||
newLearnset[moveid].sort(alphabetize);
|
||||
}
|
||||
|
||||
newLearnsetsG6[speciesid] = {learnset: newLearnset};
|
||||
}
|
||||
|
||||
var buf = [];
|
||||
var pokemonList = Object.values(Pokedex).sort(function (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').map(toId);
|
||||
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)
|
||||
|
||||
for (var i = 0, len = pokemonList.length; i < len; i++) {
|
||||
var entry = newLearnsetsG6[pokemonList[i]];
|
||||
if (!entry || !entry.learnset) continue;
|
||||
var lsetSerialized = '{' + Object.keys(entry.learnset).sort(alphabetize).map(function (moveid) {
|
||||
return moveid.replace(reservedRegExp, '"$1"') + ':' + JSON.stringify(entry.learnset[moveid]);
|
||||
}).join(',') + '}';
|
||||
buf.push(pokemonList[i] + ':{learnset:' + lsetSerialized + '}');
|
||||
updateLearnsets(function (err) {
|
||||
if (err) {
|
||||
var stack = err.stack || '';
|
||||
stack = "File `data/learnsets-g6` failed to update.\n" + stack;
|
||||
console.error(stack);
|
||||
} else {
|
||||
console.log("File `data/learnsets-g6` updated.");
|
||||
}
|
||||
if (!--pendingFiles) updateIndex();
|
||||
});
|
||||
} else {
|
||||
console.log("Input files not modified. Task aborted.");
|
||||
if (!--pendingFiles) updateIndex();
|
||||
}
|
||||
|
||||
var writeStream = fs.createWriteStream(path.join(rootDir, 'data', 'learnsets-g6.js')).on('error', function (err) {
|
||||
console.error(err.stack || err);
|
||||
});
|
||||
writeStream.write('exports.BattleLearnsets = {\n\t' + buf.join(',\n\t') + '\n};\n');
|
||||
writeStream.end(function () {
|
||||
console.log('File `data/learnsets-g6` updated.');
|
||||
pendingFiles--;
|
||||
if (!pendingFiles) updateIndex();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user