mirror of
https://github.com/smogon/pokemon-showdown-client.git
synced 2026-05-05 21:16:26 -05:00
1000 lines
25 KiB
JavaScript
1000 lines
25 KiB
JavaScript
|
|
function Storage() {}
|
|
|
|
Storage.initialize = function() {
|
|
if (window.nodewebkit) {
|
|
window.fs = require('fs');
|
|
|
|
this.initDirectory();
|
|
this.startLoggingChat = this.nwStartLoggingChat;
|
|
this.stopLoggingChat = this.nwStopLoggingChat;
|
|
this.logChat = this.nwLogChat;
|
|
}
|
|
};
|
|
|
|
/*********************************************************
|
|
* Teams
|
|
*********************************************************/
|
|
|
|
/**
|
|
* Teams are normally loaded from `localStorage`.
|
|
* If the client isn't running on `play.pokemonshowdown.com`, though,
|
|
* teams are received from `crossdomain.php` instead.
|
|
*/
|
|
|
|
Storage.teams = null;
|
|
|
|
Storage.loadTeams = function() {
|
|
if (window.nodewebkit) {
|
|
return;
|
|
}
|
|
this.teams = [];
|
|
if (window.localStorage) {
|
|
Storage.loadPackedTeams(localStorage.getItem('showdown_teams'));
|
|
app.trigger('init:loadteams');
|
|
}
|
|
};
|
|
|
|
Storage.loadPackedTeams = function(buffer) {
|
|
try {
|
|
this.teams = Storage.unpackAllTeams(buffer);
|
|
} catch (e) {
|
|
app.addPopup(Popup, {
|
|
type: 'modal',
|
|
htmlMessage: "Your teams are corrupt and could not be loaded. :( We may be able to recover a team from this data:<br /><textarea rows=\"10\" cols=\"60\">" + Tools.escapeHTML(buffer) + "</textarea>"
|
|
});
|
|
}
|
|
};
|
|
|
|
Storage.saveTeams = function() {
|
|
if (window.localStorage) {
|
|
Storage.cantSave = false;
|
|
try {
|
|
localStorage.setItem('showdown_teams', Storage.packAllTeams(this.teams));
|
|
} catch (e) {
|
|
if (e.code === DOMException.QUOTA_EXCEEDED_ERR) {
|
|
Storage.cantSave = true;
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Storage.getPackedTeams = function() {
|
|
var packedTeams = '';
|
|
try {
|
|
packedTeams = localStorage.getItem('showdown_teams');
|
|
} catch (e) {}
|
|
if (packedTeams) return packedTeams;
|
|
return Storage.packAllTeams(this.teams);
|
|
};
|
|
|
|
Storage.saveTeam = function() {
|
|
this.saveTeams();
|
|
};
|
|
|
|
Storage.deleteTeam = function() {
|
|
this.saveTeams();
|
|
};
|
|
|
|
Storage.saveAllTeams = function() {
|
|
this.saveTeams();
|
|
};
|
|
|
|
/*********************************************************
|
|
* Team importing and exporting
|
|
*********************************************************/
|
|
|
|
Storage.unpackAllTeams = function(buffer) {
|
|
if (!buffer) return [];
|
|
|
|
if (buffer.charAt(0) === '[') {
|
|
// old format
|
|
return JSON.parse(buffer).map(function (oldTeam) {
|
|
return {
|
|
name: oldTeam.name || '',
|
|
format: oldTeam.format || '',
|
|
team: Storage.packTeam(oldTeam.team),
|
|
iconCache: ''
|
|
};
|
|
});
|
|
return;
|
|
}
|
|
|
|
return buffer.split('\n').map(function (line) {
|
|
var pipeIndex = line.indexOf('|');
|
|
if (pipeIndex < 0) return;
|
|
var bracketIndex = line.indexOf(']');
|
|
if (bracketIndex > pipeIndex) bracketIndex = -1;
|
|
return {
|
|
name: line.slice(bracketIndex + 1, pipeIndex),
|
|
format: bracketIndex > 0 ? line.slice(0, bracketIndex) : '',
|
|
team: line.slice(pipeIndex + 1),
|
|
iconCache: ''
|
|
};
|
|
}).filter(function (v) { return v; });
|
|
};
|
|
|
|
Storage.packAllTeams = function(teams) {
|
|
return teams.map(function (team) {
|
|
return (team.format ? ''+team.format+']' : '') + team.name + '|' + Storage.getPackedTeam(team);
|
|
}).join('\n');
|
|
};
|
|
|
|
Storage.packTeam = function(team) {
|
|
var buf = '';
|
|
if (!team) return '';
|
|
|
|
for (var i=0; i<team.length; i++) {
|
|
var set = team[i];
|
|
if (buf) buf += ']';
|
|
|
|
// name
|
|
buf += (set.name || set.species);
|
|
|
|
// species
|
|
var id = toId(set.species || set.name);
|
|
buf += '|' + (toId(set.name || set.species) === id ? '' : id);
|
|
|
|
// item
|
|
buf += '|' + toId(set.item);
|
|
|
|
// ability
|
|
var template = Tools.getTemplate(set.species || set.name);
|
|
var abilities = template.abilities;
|
|
id = toId(set.ability);
|
|
if (abilities) {
|
|
if (id == toId(abilities['0'])) {
|
|
buf += '|';
|
|
} else if (id === toId(abilities['1'])) {
|
|
buf += '|1';
|
|
} else if (id === toId(abilities['H'])) {
|
|
buf += '|H';
|
|
} else {
|
|
buf += '|' + id;
|
|
}
|
|
} else {
|
|
buf += '|' + id;
|
|
}
|
|
|
|
// moves
|
|
if (set.moves) {
|
|
buf += '|' + set.moves.map(toId).join(',');
|
|
} else {
|
|
buf += '|';
|
|
}
|
|
|
|
// nature
|
|
buf += '|' + set.nature;
|
|
|
|
// evs
|
|
var evs = '|';
|
|
if (set.evs) {
|
|
evs = '|' + (set.evs['hp']||'') + ',' + (set.evs['atk']||'') + ',' + (set.evs['def']||'') + ',' + (set.evs['spa']||'') + ',' + (set.evs['spd']||'') + ',' + (set.evs['spe']||'');
|
|
}
|
|
if (evs === '|,,,,,') {
|
|
buf += '|';
|
|
} else {
|
|
buf += evs;
|
|
}
|
|
|
|
// gender
|
|
if (set.gender && set.gender !== template.gender) {
|
|
buf += '|'+set.gender;
|
|
} else {
|
|
buf += '|';
|
|
}
|
|
|
|
// ivs
|
|
var ivs = '|';
|
|
if (set.ivs) {
|
|
ivs = '|' + (set.ivs['hp']===31||set.ivs['hp']===undefined ? '' : set.ivs['hp']) + ',' + (set.ivs['atk']===31||set.ivs['atk']===undefined ? '' : set.ivs['atk']) + ',' + (set.ivs['def']===31||set.ivs['def']===undefined ? '' : set.ivs['def']) + ',' + (set.ivs['spa']===31||set.ivs['spa']===undefined ? '' : set.ivs['spa']) + ',' + (set.ivs['spd']===31||set.ivs['spd']===undefined ? '' : set.ivs['spd']) + ',' + (set.ivs['spe']===31||set.ivs['spe']===undefined ? '' : set.ivs['spe']);
|
|
}
|
|
if (ivs === '|,,,,,') {
|
|
buf += '|';
|
|
} else {
|
|
buf += ivs;
|
|
}
|
|
|
|
// shiny
|
|
if (set.shiny) {
|
|
buf += '|S';
|
|
} else {
|
|
buf += '|';
|
|
}
|
|
|
|
// level
|
|
if (set.level && set.level != 100) {
|
|
buf += '|'+set.level;
|
|
} else {
|
|
buf += '|';
|
|
}
|
|
|
|
// happiness
|
|
if (set.happiness !== undefined && set.happiness !== 255) {
|
|
buf += '|'+set.happiness;
|
|
} else {
|
|
buf += '|';
|
|
}
|
|
}
|
|
|
|
return buf;
|
|
};
|
|
|
|
Storage.fastUnpackTeam = function(buf) {
|
|
if (!buf) return [];
|
|
|
|
var team = [];
|
|
var i = 0, j = 0;
|
|
|
|
while (true) {
|
|
var set = {};
|
|
team.push(set);
|
|
|
|
// name
|
|
j = buf.indexOf('|', i);
|
|
set.name = buf.substring(i, j);
|
|
i = j+1;
|
|
|
|
// species
|
|
j = buf.indexOf('|', i);
|
|
set.species = buf.substring(i, j) || set.name;
|
|
i = j+1;
|
|
|
|
// item
|
|
j = buf.indexOf('|', i);
|
|
set.item = buf.substring(i, j);
|
|
i = j+1;
|
|
|
|
// ability
|
|
j = buf.indexOf('|', i);
|
|
var ability = buf.substring(i, j);
|
|
var template = Tools.getTemplate(set.species);
|
|
set.ability = (template.abilities && ability in {'':1, 0:1, 1:1, H:1} ? template.abilities[ability||'0'] : ability);
|
|
i = j+1;
|
|
|
|
// moves
|
|
j = buf.indexOf('|', i);
|
|
set.moves = buf.substring(i, j).split(',');
|
|
i = j+1;
|
|
|
|
// nature
|
|
j = buf.indexOf('|', i);
|
|
set.nature = buf.substring(i, j);
|
|
i = j+1;
|
|
|
|
// evs
|
|
j = buf.indexOf('|', i);
|
|
if (j !== i) {
|
|
var evs = buf.substring(i, j).split(',');
|
|
set.evs = {
|
|
hp: Number(evs[0])||0,
|
|
atk: Number(evs[1])||0,
|
|
def: Number(evs[2])||0,
|
|
spa: Number(evs[3])||0,
|
|
spd: Number(evs[4])||0,
|
|
spe: Number(evs[5])||0
|
|
};
|
|
}
|
|
i = j+1;
|
|
|
|
// gender
|
|
j = buf.indexOf('|', i);
|
|
if (i !== j) set.gender = buf.substring(i, j);
|
|
i = j+1;
|
|
|
|
// ivs
|
|
j = buf.indexOf('|', i);
|
|
if (j !== i) {
|
|
var ivs = buf.substring(i, j).split(',');
|
|
set.ivs = {
|
|
hp: ivs[0]==='' ? 31 : Number(ivs[0]),
|
|
atk: ivs[1]==='' ? 31 : Number(ivs[1]),
|
|
def: ivs[2]==='' ? 31 : Number(ivs[2]),
|
|
spa: ivs[3]==='' ? 31 : Number(ivs[3]),
|
|
spd: ivs[4]==='' ? 31 : Number(ivs[4]),
|
|
spe: ivs[5]==='' ? 31 : Number(ivs[5])
|
|
};
|
|
}
|
|
i = j+1;
|
|
|
|
// shiny
|
|
j = buf.indexOf('|', i);
|
|
if (i !== j) set.shiny = true;
|
|
i = j+1;
|
|
|
|
// level
|
|
j = buf.indexOf('|', i);
|
|
if (i !== j) set.level = parseInt(buf.substring(i, j), 10);
|
|
i = j+1;
|
|
|
|
// happiness
|
|
j = buf.indexOf(']', i);
|
|
if (j < 0) {
|
|
if (buf.substring(i)) {
|
|
set.happiness = Number(buf.substring(i));
|
|
}
|
|
break;
|
|
}
|
|
if (i !== j) set.happiness = Number(buf.substring(i, j));
|
|
i = j+1;
|
|
}
|
|
|
|
return team;
|
|
};
|
|
|
|
Storage.unpackTeam = function(buf) {
|
|
if (!buf) return [];
|
|
|
|
var team = [];
|
|
var i = 0, j = 0;
|
|
|
|
while (true) {
|
|
var set = {};
|
|
team.push(set);
|
|
|
|
// name
|
|
j = buf.indexOf('|', i);
|
|
set.name = buf.substring(i, j);
|
|
i = j+1;
|
|
|
|
// species
|
|
j = buf.indexOf('|', i);
|
|
set.species = Tools.getTemplate(buf.substring(i, j)).name || set.name;
|
|
i = j+1;
|
|
|
|
// item
|
|
j = buf.indexOf('|', i);
|
|
set.item = Tools.getItem(buf.substring(i, j)).name;
|
|
i = j+1;
|
|
|
|
// ability
|
|
j = buf.indexOf('|', i);
|
|
var ability = Tools.getAbility(buf.substring(i, j)).name;
|
|
var template = Tools.getTemplate(set.species);
|
|
set.ability = (template.abilities && ability in {'':1, 0:1, 1:1, H:1} ? template.abilities[ability||'0'] : ability);
|
|
i = j+1;
|
|
|
|
// moves
|
|
j = buf.indexOf('|', i);
|
|
set.moves = buf.substring(i, j).split(',').map(function(moveid) {
|
|
return Tools.getMove(moveid).name
|
|
});
|
|
i = j+1;
|
|
|
|
// nature
|
|
j = buf.indexOf('|', i);
|
|
set.nature = buf.substring(i, j);
|
|
i = j+1;
|
|
|
|
// evs
|
|
j = buf.indexOf('|', i);
|
|
if (j !== i) {
|
|
var evs = buf.substring(i, j).split(',');
|
|
set.evs = {
|
|
hp: Number(evs[0])||0,
|
|
atk: Number(evs[1])||0,
|
|
def: Number(evs[2])||0,
|
|
spa: Number(evs[3])||0,
|
|
spd: Number(evs[4])||0,
|
|
spe: Number(evs[5])||0
|
|
};
|
|
}
|
|
i = j+1;
|
|
|
|
// gender
|
|
j = buf.indexOf('|', i);
|
|
if (i !== j) set.gender = buf.substring(i, j);
|
|
i = j+1;
|
|
|
|
// ivs
|
|
j = buf.indexOf('|', i);
|
|
if (j !== i) {
|
|
var ivs = buf.substring(i, j).split(',');
|
|
set.ivs = {
|
|
hp: ivs[0]==='' ? 31 : Number(ivs[0]),
|
|
atk: ivs[1]==='' ? 31 : Number(ivs[1]),
|
|
def: ivs[2]==='' ? 31 : Number(ivs[2]),
|
|
spa: ivs[3]==='' ? 31 : Number(ivs[3]),
|
|
spd: ivs[4]==='' ? 31 : Number(ivs[4]),
|
|
spe: ivs[5]==='' ? 31 : Number(ivs[5])
|
|
};
|
|
}
|
|
i = j+1;
|
|
|
|
// shiny
|
|
j = buf.indexOf('|', i);
|
|
if (i !== j) set.shiny = true;
|
|
i = j+1;
|
|
|
|
// level
|
|
j = buf.indexOf('|', i);
|
|
if (i !== j) set.level = parseInt(buf.substring(i, j), 10);
|
|
i = j+1;
|
|
|
|
// happiness
|
|
j = buf.indexOf(']', i);
|
|
if (j < 0) {
|
|
if (buf.substring(i)) {
|
|
set.happiness = Number(buf.substring(i));
|
|
}
|
|
break;
|
|
}
|
|
if (i !== j) set.happiness = Number(buf.substring(i, j));
|
|
i = j+1;
|
|
}
|
|
|
|
return team;
|
|
};
|
|
|
|
Storage.packedTeamNames = function(buf) {
|
|
if (!buf) return '';
|
|
|
|
var team = [];
|
|
var i = 0;
|
|
|
|
while (true) {
|
|
var name = buf.substring(i, buf.indexOf('|', i));
|
|
i = buf.indexOf('|', i) + 1;
|
|
|
|
team.push(buf.substring(i, buf.indexOf('|', i)) || name);
|
|
|
|
for (var k=0; k<9; k++) {
|
|
i = buf.indexOf('|', i) + 1;
|
|
}
|
|
|
|
i = buf.indexOf(']', i) + 1;
|
|
|
|
if (i < 1) break;
|
|
}
|
|
|
|
return team;
|
|
};
|
|
|
|
Storage.packedTeamIcons = function(buf) {
|
|
if (!buf) return '<em>(empty team)</em>';
|
|
|
|
return this.packedTeamNames(buf).map(function (species) {
|
|
return '<span class="pokemonicon" style="' + Tools.getIcon(species) + ';float:left;overflow:visible"><span style="font-size:0px">' + toId(species) + '</span></span>';
|
|
}).join('');
|
|
};
|
|
|
|
Storage.getTeamIcons = function(team) {
|
|
if (team.iconCache === '!') {
|
|
// an icon cache of '!' means that not only are the icons not cached,
|
|
// but the packed team isn't guaranteed to be updated to the latest
|
|
// changes from the teambuilder, either.
|
|
|
|
// we use Storage.activeSetList instead of reading from
|
|
// app.rooms.teambuilder.curSetList because the teambuilder
|
|
// room may have been closed by the time we need to get
|
|
// a packed team.
|
|
team.team = Storage.packTeam(Storage.activeSetList);
|
|
Storage.activeSetList = null;
|
|
team.iconCache = Storage.packedTeamIcons(team.team);
|
|
} else if (!team.iconCache) {
|
|
team.iconCache = Storage.packedTeamIcons(team.team);
|
|
}
|
|
return team.iconCache;
|
|
};
|
|
|
|
Storage.getPackedTeam = function(team) {
|
|
if (!team) return null;
|
|
if (team.iconCache === '!') {
|
|
// see the same case in Storage.getTeamIcons
|
|
team.team = Storage.packTeam(Storage.activeSetList);
|
|
Storage.activeSetList = null;
|
|
team.iconCache = '';
|
|
}
|
|
return team.team;
|
|
};
|
|
|
|
Storage.importTeam = function(text, teams) {
|
|
var text = text.split("\n");
|
|
var team = [];
|
|
var curSet = null;
|
|
if (teams === true) {
|
|
Storage.teams = [];
|
|
teams = Storage.teams;
|
|
}
|
|
for (var i=0; i<text.length; i++) {
|
|
var line = $.trim(text[i]);
|
|
if (line === '' || line === '---') {
|
|
curSet = null;
|
|
} else if (line.substr(0, 3) === '===' && teams) {
|
|
team = [];
|
|
line = $.trim(line.substr(3, line.length-6));
|
|
var format = '';
|
|
var bracketIndex = line.indexOf(']');
|
|
if (bracketIndex >= 0) {
|
|
format = line.substr(1, bracketIndex-1);
|
|
line = $.trim(line.substr(bracketIndex+1));
|
|
}
|
|
if (teams.length) {
|
|
teams[teams.length - 1].team = Storage.packTeam(teams[teams.length - 1].team);
|
|
}
|
|
teams.push({
|
|
name: line,
|
|
format: format,
|
|
team: team,
|
|
iconCache: ''
|
|
});
|
|
} else if (!curSet) {
|
|
curSet = {name: '', species: '', gender: ''};
|
|
team.push(curSet);
|
|
var atIndex = line.lastIndexOf(' @ ');
|
|
if (atIndex !== -1) {
|
|
curSet.item = line.substr(atIndex+3);
|
|
if (toId(curSet.item) === 'noitem') curSet.item = '';
|
|
line = line.substr(0, atIndex);
|
|
}
|
|
if (line.substr(line.length-4) === ' (M)') {
|
|
curSet.gender = 'M';
|
|
line = line.substr(0, line.length-4);
|
|
}
|
|
if (line.substr(line.length-4) === ' (F)') {
|
|
curSet.gender = 'F';
|
|
line = line.substr(0, line.length-4);
|
|
}
|
|
var parenIndex = line.lastIndexOf(' (');
|
|
if (line.substr(line.length-1) === ')' && parenIndex !== -1) {
|
|
line = line.substr(0, line.length-1);
|
|
curSet.species = Tools.getTemplate(line.substr(parenIndex+2)).name;
|
|
line = line.substr(0, parenIndex);
|
|
curSet.name = line;
|
|
} else {
|
|
curSet.species = Tools.getTemplate(line).name;
|
|
curSet.name = curSet.species;
|
|
}
|
|
} else if (line.substr(0, 7) === 'Trait: ') {
|
|
line = line.substr(7);
|
|
curSet.ability = line;
|
|
} else if (line.substr(0, 9) === 'Ability: ') {
|
|
line = line.substr(9);
|
|
curSet.ability = line;
|
|
} else if (line === 'Shiny: Yes') {
|
|
curSet.shiny = true;
|
|
} else if (line.substr(0, 7) === 'Level: ') {
|
|
line = line.substr(7);
|
|
curSet.level = +line;
|
|
} else if (line.substr(0, 11) === 'Happiness: ') {
|
|
line = line.substr(11);
|
|
curSet.happiness = +line;
|
|
} else if (line.substr(0, 9) === 'Ability: ') {
|
|
line = line.substr(9);
|
|
curSet.ability = line;
|
|
} else if (line.substr(0, 5) === 'EVs: ') {
|
|
line = line.substr(5);
|
|
var evLines = line.split('/');
|
|
curSet.evs = {hp: 0, atk: 0, def: 0, spa: 0, spd: 0, spe: 0};
|
|
for (var j=0; j<evLines.length; j++) {
|
|
var evLine = $.trim(evLines[j]);
|
|
var spaceIndex = evLine.indexOf(' ');
|
|
if (spaceIndex === -1) continue;
|
|
var statid = BattleStatIDs[evLine.substr(spaceIndex+1)];
|
|
var statval = parseInt(evLine.substr(0, spaceIndex));
|
|
if (!statid) continue;
|
|
curSet.evs[statid] = statval;
|
|
}
|
|
} else if (line.substr(0, 5) === 'IVs: ') {
|
|
line = line.substr(5);
|
|
var ivLines = line.split(' / ');
|
|
curSet.ivs = {hp: 31, atk: 31, def: 31, spa: 31, spd: 31, spe: 31};
|
|
for (var j=0; j<ivLines.length; j++) {
|
|
var ivLine = ivLines[j];
|
|
var spaceIndex = ivLine.indexOf(' ');
|
|
if (spaceIndex === -1) continue;
|
|
var statid = BattleStatIDs[ivLine.substr(spaceIndex+1)];
|
|
var statval = parseInt(ivLine.substr(0, spaceIndex));
|
|
if (!statid) continue;
|
|
if (isNaN(statval)) statval = 31;
|
|
curSet.ivs[statid] = statval;
|
|
}
|
|
} else if (line.match(/^[A-Za-z]+ (N|n)ature/)) {
|
|
var natureIndex = line.indexOf(' Nature');
|
|
if (natureIndex === -1) natureIndex = line.indexOf(' nature');
|
|
if (natureIndex === -1) continue;
|
|
line = line.substr(0, natureIndex);
|
|
curSet.nature = line;
|
|
} else if (line.substr(0,1) === '-' || line.substr(0,1) === '~') {
|
|
line = line.substr(1);
|
|
if (line.substr(0,1) === ' ') line = line.substr(1);
|
|
if (!curSet.moves) curSet.moves = [];
|
|
if (line.substr(0,14) === 'Hidden Power [') {
|
|
var hptype = line.substr(14, line.length-15);
|
|
line = 'Hidden Power ' + hptype;
|
|
if (!curSet.ivs && window.BattleTypeChart) {
|
|
curSet.ivs = {};
|
|
for (var stat in window.BattleTypeChart[hptype].HPivs) {
|
|
curSet.ivs[stat] = window.BattleTypeChart[hptype].HPivs[stat];
|
|
}
|
|
}
|
|
}
|
|
if (line === 'Frustration') {
|
|
curSet.happiness = 0;
|
|
}
|
|
curSet.moves.push(line);
|
|
}
|
|
}
|
|
if (teams && teams.length) {
|
|
teams[teams.length - 1].team = Storage.packTeam(teams[teams.length - 1].team);
|
|
}
|
|
return team;
|
|
};
|
|
Storage.exportAllTeams = function() {
|
|
var buf = '';
|
|
for (var i=0,len=Storage.teams.length; i<len; i++) {
|
|
var team = Storage.teams[i];
|
|
buf += '=== '+(team.format?'['+team.format+'] ':'')+team.name+' ===\n\n';
|
|
buf += Storage.exportTeam(team.team);
|
|
buf += '\n';
|
|
}
|
|
return buf;
|
|
};
|
|
Storage.exportTeam = function(team) {
|
|
if (!team) return "";
|
|
if (typeof team === 'string') {
|
|
if (team.indexOf('\n') >= 0) return team;
|
|
team = Storage.fastUnpackTeam(team);
|
|
}
|
|
var text = '';
|
|
for (var i=0; i<team.length; i++) {
|
|
var curSet = team[i];
|
|
if (curSet.name !== curSet.species) {
|
|
text += ''+curSet.name+' ('+curSet.species+')';
|
|
} else {
|
|
text += ''+curSet.species;
|
|
}
|
|
if (curSet.gender === 'M') text += ' (M)';
|
|
if (curSet.gender === 'F') text += ' (F)';
|
|
if (curSet.item) {
|
|
text += ' @ '+curSet.item;
|
|
}
|
|
text += "\n";
|
|
if (curSet.ability) {
|
|
text += 'Ability: '+curSet.ability+"\n";
|
|
}
|
|
if (curSet.level && curSet.level != 100) {
|
|
text += 'Level: '+curSet.level+"\n";
|
|
}
|
|
if (curSet.shiny) {
|
|
text += 'Shiny: Yes\n';
|
|
}
|
|
if (typeof curSet.happiness === 'number' && curSet.happiness !== 255) {
|
|
text += 'Happiness: '+curSet.happiness+"\n";
|
|
}
|
|
var first = true;
|
|
if (curSet.evs) {
|
|
for (var j in BattleStatNames) {
|
|
if (!curSet.evs[j]) continue;
|
|
if (first) {
|
|
text += 'EVs: ';
|
|
first = false;
|
|
} else {
|
|
text += ' / ';
|
|
}
|
|
text += ''+curSet.evs[j]+' '+BattleStatNames[j];
|
|
}
|
|
}
|
|
if (!first) {
|
|
text += "\n";
|
|
}
|
|
if (curSet.nature) {
|
|
text += ''+curSet.nature+' Nature'+"\n";
|
|
}
|
|
var first = true;
|
|
if (curSet.ivs) {
|
|
var defaultIvs = true;
|
|
var hpType = false;
|
|
for (var j=0; j<curSet.moves.length; j++) {
|
|
var move = curSet.moves[j];
|
|
if (move.substr(0,13) === 'Hidden Power ' && move.substr(0,14) !== 'Hidden Power [') {
|
|
hpType = move.substr(13);
|
|
if (!exports.BattleTypeChart[hpType].HPivs) {
|
|
alert("That is not a valid Hidden Power type.");
|
|
continue;
|
|
}
|
|
for (var stat in BattleStatNames) {
|
|
if ((curSet.ivs[stat]===undefined?31:curSet.ivs[stat]) !== (exports.BattleTypeChart[hpType].HPivs[stat]||31)) {
|
|
defaultIvs = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (defaultIvs && !hpType) {
|
|
for (var stat in BattleStatNames) {
|
|
if (curSet.ivs[stat] !== 31 && typeof curSet.ivs[stat] !== undefined) {
|
|
defaultIvs = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!defaultIvs) {
|
|
for (var stat in BattleStatNames) {
|
|
if (typeof curSet.ivs[stat] === 'undefined' || isNaN(curSet.ivs[stat]) || curSet.ivs[stat] == 31) continue;
|
|
if (first) {
|
|
text += 'IVs: ';
|
|
first = false;
|
|
} else {
|
|
text += ' / ';
|
|
}
|
|
text += ''+curSet.ivs[stat]+' '+BattleStatNames[stat];
|
|
}
|
|
}
|
|
}
|
|
if (!first) {
|
|
text += "\n";
|
|
}
|
|
if (curSet.moves) for (var j=0; j<curSet.moves.length; j++) {
|
|
var move = curSet.moves[j];
|
|
if (move.substr(0,13) === 'Hidden Power ') {
|
|
move = move.substr(0,13) + '[' + move.substr(13) + ']';
|
|
}
|
|
text += '- '+move+"\n";
|
|
}
|
|
text += "\n";
|
|
}
|
|
return text;
|
|
};
|
|
|
|
/*********************************************************
|
|
* Node-webkit
|
|
*********************************************************/
|
|
|
|
Storage.initDirectory = function() {
|
|
var self = this;
|
|
|
|
var dir = process.env.HOME || process.env.USERPROFILE || process.env.HOMEPATH;
|
|
if (!(dir.charAt(dir.length-1) in {'/':1, '\\':1})) dir += '/';
|
|
fs.stat(dir+'Documents', function(err, stats) {
|
|
if (err || !stats.isDirectory()) {
|
|
fs.stat(dir+'My Documents', function(err, stats) {
|
|
if (err || !stats.isDirectory()) {
|
|
self.documentsDir = dir;
|
|
} else {
|
|
self.documentsDir = dir+'My Documents/';
|
|
}
|
|
self.initDirectory2();
|
|
});
|
|
} else {
|
|
self.documentsDir = dir+'Documents/';
|
|
self.initDirectory2();
|
|
}
|
|
});
|
|
};
|
|
|
|
Storage.initDirectory2 = function() {
|
|
var self = this;
|
|
fs.mkdir(self.documentsDir+'My Games', function() {
|
|
fs.mkdir(self.documentsDir+'My Games/Pokemon Showdown', function() {
|
|
fs.stat(self.documentsDir+'My Games/Pokemon Showdown', function(err, stats) {
|
|
if (err) return;
|
|
if (stats.isDirectory()) {
|
|
self.dir = self.documentsDir+'My Games/Pokemon Showdown/';
|
|
fs.mkdir(self.dir+'Logs', function() {});
|
|
fs.mkdir(self.dir+'Teams', function() {});
|
|
|
|
// load teams
|
|
self.nwLoadTeams();
|
|
self.saveAllTeams = self.nwSaveAllTeams;
|
|
self.saveTeam = self.nwSaveTeam;
|
|
self.deleteTeam = self.nwDeleteTeam;
|
|
|
|
// logging
|
|
if (Tools.prefs('logchat')) self.startLoggingChat();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
Storage.revealFolder = function() {
|
|
gui.Shell.openItem(this.dir);
|
|
};
|
|
|
|
// teams
|
|
|
|
Storage.nwLoadTeams = function() {
|
|
var self = this;
|
|
var localApp = window.app;
|
|
fs.readdir(this.dir+'Teams', function(err, files) {
|
|
if (err) return;
|
|
self.teams = [];
|
|
self.nwTeamsLeft = files.length;
|
|
for (var i=0; i<files.length; i++) {
|
|
self.nwLoadTeamFile(files[i], localApp);
|
|
}
|
|
});
|
|
};
|
|
|
|
Storage.nwLoadTeamFile = function(filename, localApp) {
|
|
var self = this;
|
|
var line = filename;
|
|
if (line.substr(line.length-4).toLowerCase() === '.txt') {
|
|
line = line.substr(0, line.length-4);
|
|
} else {
|
|
// not a team file
|
|
self.nwTeamsLeft--;
|
|
if (!self.nwTeamsLeft) {
|
|
self.nwFinishedLoadingTeams(localApp);
|
|
}
|
|
return;
|
|
}
|
|
var format = '';
|
|
var bracketIndex = line.indexOf(']');
|
|
if (bracketIndex >= 0) {
|
|
format = line.substr(1, bracketIndex-1);
|
|
line = $.trim(line.substr(bracketIndex+1));
|
|
}
|
|
fs.readFile(this.dir+'Teams/'+filename, function(err, data) {
|
|
if (!err) {
|
|
self.teams.push({
|
|
name: line,
|
|
format: format,
|
|
team: Storage.packTeam(Storage.importTeam(''+data)),
|
|
iconCache: '',
|
|
filename: filename
|
|
});
|
|
self.nwTeamsLeft--;
|
|
if (!self.nwTeamsLeft) {
|
|
self.nwFinishedLoadingTeams(localApp);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
Storage.nwFinishedLoadingTeams = function(app) {
|
|
this.teams.sort(this.teamCompare);
|
|
if (!app) app = window.app;
|
|
if (app) app.trigger('init:loadteams');
|
|
};
|
|
|
|
Storage.teamCompare = function(a, b) {
|
|
if (a.name > b.name) return 1;
|
|
if (a.name < b.name) return -1;
|
|
return 0;
|
|
};
|
|
|
|
Storage.nwDeleteAllTeams = function(callback) {
|
|
var self = this;
|
|
fs.readdir(this.dir+'Teams', function(err, files) {
|
|
if (err) return;
|
|
self.nwTeamsLeft = files.length;
|
|
if (!self.nwTeamsLeft) {
|
|
callback();
|
|
return;
|
|
}
|
|
for (var i=0; i<files.length; i++) {
|
|
self.nwDeleteTeamFile(files[i], callback);
|
|
}
|
|
});
|
|
};
|
|
|
|
Storage.nwDeleteTeamFile = function(filename, callback) {
|
|
var self = this;
|
|
var line = filename;
|
|
if (line.substr(line.length-4).toLowerCase() === '.txt') {
|
|
line = line.substr(0, line.length-4);
|
|
} else {
|
|
// not a team file
|
|
self.nwTeamsLeft--;
|
|
if (!self.nwTeamsLeft) callback();
|
|
return;
|
|
}
|
|
fs.unlink(this.dir+'Teams/'+filename, function(err) {
|
|
self.nwTeamsLeft--;
|
|
if (!self.nwTeamsLeft) callback();
|
|
});
|
|
};
|
|
|
|
Storage.nwSaveTeam = function(team) {
|
|
var filename = team.name+'.txt';
|
|
if (team.format) filename = '['+team.format+'] '+filename;
|
|
filename = $.trim(filename).replace(/[\\\/]+/g, '');
|
|
|
|
if (team.filename && filename !== team.filename) {
|
|
fs.unlink(this.dir+'Teams/'+team.filename, function() {});
|
|
}
|
|
team.filename = filename;
|
|
fs.writeFile(this.dir+'Teams/'+filename, Storage.exportTeam(team.team).replace(/\n/g,'\r\n'));
|
|
};
|
|
|
|
Storage.nwDeleteTeam = function(team) {
|
|
if (team.filename) {
|
|
fs.unlink(this.dir+'Teams/'+team.filename, function() {});
|
|
delete team.filename;
|
|
}
|
|
};
|
|
|
|
Storage.nwSaveAllTeams = function() {
|
|
var self = this;
|
|
this.nwDeleteAllTeams(function() {
|
|
self.nwDoSaveAllTeams();
|
|
});
|
|
};
|
|
|
|
Storage.nwDoSaveAllTeams = function() {
|
|
for (var i=0; i<this.teams.length; i++) {
|
|
var team = this.teams[i];
|
|
var filename = team.name+'.txt';
|
|
if (team.format) filename = '['+team.format+'] '+filename;
|
|
filename = $.trim(filename).replace(/[\\\/]+/g, '');
|
|
|
|
team.filename = filename;
|
|
fs.writeFile(this.dir+'Teams/'+filename, Storage.exportTeam(team.team).replace(/\n/g,'\r\n'));
|
|
}
|
|
};
|
|
|
|
// logs
|
|
|
|
Storage.getLogMonth = function() {
|
|
var now = new Date();
|
|
var month = ''+(now.getMonth()+1);
|
|
if (month.length < 2) month = '0'+month;
|
|
return ''+now.getFullYear()+'-'+month;
|
|
};
|
|
Storage.nwStartLoggingChat = function() {
|
|
var self = this;
|
|
if (!self.documentsDir) return; // too early; initDirectory2 will call us when it's time
|
|
if (self.loggingChat) return;
|
|
// callback hell! ^_^
|
|
fs.mkdir(self.dir+'Logs', function() {
|
|
self.chatLogFdMonth = self.getLogMonth();
|
|
fs.mkdir(self.dir+'Logs/'+self.chatLogFdMonth, function() {
|
|
fs.stat(self.dir+'Logs/'+self.chatLogFdMonth, function(err, stats) {
|
|
if (err) return;
|
|
if (stats.isDirectory()) {
|
|
self.loggingChat = true;
|
|
self.chatLogStreams = {};
|
|
}
|
|
});
|
|
});
|
|
});
|
|
};
|
|
Storage.nwStopLoggingChat = function() {
|
|
if (!this.loggingChat) return;
|
|
this.loggingChat = false;
|
|
var streams = this.chatLogStreams;
|
|
this.chatLogStreams = null;
|
|
for (var i in streams) {
|
|
streams[i].end();
|
|
}
|
|
};
|
|
Storage.nwLogChat = function(roomid, line) {
|
|
roomid = toRoomid(roomid);
|
|
var self = this;
|
|
if (!this.loggingChat) return;
|
|
var chatLogFdMonth = this.getLogMonth();
|
|
if (chatLogFdMonth !== this.chatLogFdMonth) {
|
|
this.chatLogFdMonth = chatLogFdMonth;
|
|
var streams = this.chatLogStreams;
|
|
this.chatLogStreams = {};
|
|
for (var i in streams) {
|
|
streams[i].end();
|
|
}
|
|
}
|
|
|
|
var now = new Date();
|
|
var hours = ''+now.getHours();
|
|
if (hours.length < 2) hours = '0'+hours;
|
|
var minutes = ''+now.getMinutes();
|
|
if (minutes.length < 2) minutes = '0'+minutes;
|
|
var timestamp = '['+hours+':'+minutes+'] ';
|
|
|
|
if (!this.chatLogStreams[roomid]) {
|
|
this.chatLogStreams[roomid] = fs.createWriteStream(this.dir+'Logs/'+chatLogFdMonth+'/'+roomid+'.txt', {flags:'a'});
|
|
this.chatLogStreams[roomid].write('\n\n\nLog starting '+now+'\n\n');
|
|
}
|
|
this.chatLogStreams[roomid].write(timestamp+line+'\n');
|
|
};
|
|
|
|
// saving
|
|
|
|
Storage.startLoggingChat = function() {};
|
|
Storage.stopLoggingChat = function() {};
|
|
Storage.logChat = function() {};
|
|
|
|
Storage.initialize();
|