Zarel/Pokemon-Showdown — pull request #1356 by Ansirenter (2014-12-11 16:03:14+00:00)
Title: core.js

/**
* Core
* Created by CreaturePhil - https://github.com/CreaturePhil
*
* This is where essential core infrastructure of
* Pokemon Showdown extensions for private servers.
* Core contains standard streams, profile infrastructure,
* elo rating calculations, and polls infrastructure.
*
* @license MIT license
*/

var fs = require("fs");
var path = require("path");

var core = exports.core = {

stdin: function (file, name) {
var data = fs.readFileSync('config/' + file + '.csv', 'utf8').split('\n');

var len = data.length;
while (len--) {
if (!data[len]) continue;
var parts = data[len].split(',');
if (parts[0].toLowerCase() === name) {
return parts[1];
}
}
return 0;
},

stdout: function (file, name, info, callback) {
var data = fs.readFileSync('config/' + file + '.csv', 'utf8').split('\n');
var match = false;

var len = data.length;
while (len--) {
if (!data[len]) continue;
var parts = data[len].split(',');
if (parts[0] === name) {
data = data[len];
match = true;
break;
}
}

if (match === true) {
var re = new RegExp(data, 'g');
fs.readFile('config/' + file + '.csv', 'utf8', function (err, data) {
if (err) return console.log(err);

var result = data.replace(re, name + ',' + info);
fs.writeFile('config/' + file + '.csv', result, 'utf8', function (err) {
if (err) return console.log(err);
typeof callback === 'function' && callback();
});
});
} else {
var log = fs.createWriteStream('config/' + file + '.csv', {
'flags': 'a'
});
log.write('\n' + name + ',' + info);
typeof callback === 'function' && callback();
}
},

profile: {

color: '#5130AB',

avatarurl: 'http://107.155.72.217:15000',

avatar: function (online, user, img) {
if (online === true) {
if (typeof (img) === typeof ('')) {
return '';
}
return '';
}
for (var name in Config.customAvatars) {
if (user === name) {
return '';
}
}
var trainersprites = [1, 2, 101, 102, 169, 170, 265, 266, 168];
return '';
},

name: function (online, user) {
if (online === true) {
return ' Name: ' + user.name;
}
return ' Name: ' + user;
},

group: function (online, user) {
if (online === true) {
if (user.group === ' ') {
return '
Group: ' + 'Regular User';
}
return '
Group: ' + Config.groups.bySymbol[user.group].name;
}
var g = Core.stdin('usergroups', user);
if (g === 0) {
return '
Group: ' + 'Regular User';
}
return '
Group: ' + Config.groups.bySymbol[user.group].name;
},

badges: function (online, user) {
if (online === true) {
return 'br> Badges:< ' + 'None';
}
},

lastSeen: function (online, user) {
var lastSeen;

if (online === true) {
if (user.connected === true) {
return '
Last Seen: Current Online';
}
lastSeen = Number(Core.stdin('lastSeen', user.userid));
} else {
lastSeen = Number(Core.stdin('lastSeen', user));
}

if (lastSeen === 0) return '
Last Seen: Never';

var seconds = Math.floor((Date.now() - lastSeen) * 0.001);
var minutes = Math.floor((Date.now() - lastSeen) * 1.6667e-5);
var hours = Math.floor((Date.now() - lastSeen) * 2.7778e-7);
var days = Math.floor(((Date.now() - lastSeen) * 2.7778e-7) / 24);

var time = days + ' days ago';

if (seconds < 60) {
if (seconds === 1) {
time = seconds + ' second ago';
} else {
time = seconds + ' seconds ago';
}
} else if (minutes < 60) {
if (minutes === 1) {
time = minutes + ' minute ago';
} else {
time = minutes + ' minutes ago';
}
} else if (hours < 24) {
if (hours === 1) {
time = hours + ' hour ago';
} else {
time = hours + ' hours ago';
}
} else if (days === 1) {
time = days + ' day ago';
}

return '
Last Seen: ' + time;
},

about: function (user) {
return Core.stdin('about', user);
},

money: function (user) {
return Core.stdin('money', user);
},

tournamentElo: function (user) {
var elo = Core.stdin('elo', user);
if (elo === 0) {
return 1000;
}
return Math.floor(Number(elo));
},

rank: function (user) {
var data = fs.readFileSync('config/elo.csv', 'utf-8');
var row = ('' + data).split("\n");

var list = [];

for (var i = row.length; i > -1; i--) {
if (!row[i]) continue;
var parts = row[i].split(",");
list.push([toId(parts[0]), Number(parts[1])]);
}

list.sort(function (a, b) {
return a[1] - b[1];
});
var arr = list.filter(function (el) {
return !!~el.indexOf(user);
});

return ' (Rank ' + (list.length - list.indexOf(arr[0])) + ' out of ' + list.length + ' players)';
},

display: function (args, info, option) {
if (args === 'about') return '
About: ' + info;
if (args === 'money') return '
Money: ' + info;
if (args === 'elo') return '
Tournament Elo: ' + info + option;
},

},

calculateElo: function (winner, loser) {
if (winner === 0) winner = 1000;
if (loser === 0) loser = 1000;
var kFactor = 32;
var ratingDifference = loser - winner;
var expectedScoreWinner = 1 / (1 + Math.pow(10, ratingDifference / 400));

var e = kFactor * (1 - expectedScoreWinner);
winner = winner + e;
loser = loser - e;

var arr = [winner, loser];
return arr;
},

ladder: function (limit) {
var data = fs.readFileSync('config/elo.csv', 'utf-8');
var row = ('' + data).split("\n");

var list = [];

for (var i = row.length; i > -1; i--) {
if (!row[i] || row[i].indexOf(',') < 0) continue;
var parts = row[i].split(",");
list.push([toId(parts[0]), Number(parts[1])]);
}

list.sort(function (a, b) {
return a[1] - b[1];
});

if (list.length > 1) {
var ladder = '

Rank	User	Tournament Elo	Tournament Wins
';
var len = list.length;

limit = len - limit;
if (limit > len) limit = len;

while (len--) {
ladder = ladder + '
' + (list.length - len) + '	' + list[len][0] + '	' + Math.floor(list[len][1]) + '	' + this.stdin('tourWins', list[len][0]) + '
';
if (len === limit) break;
}
ladder += '

';
return ladder;
}
return 0;
},

shop: function (showDisplay) {
var shop = [
['Symbol', 'Buys a custom symbol to go infront of name and puts you at top of userlist. (Temporary until restart, certain symbols are blocked)', 5],
['Fix', 'Buys the ability to alter your current custom avatar or trainer card. (don\'t buy if you have neither)', 10],
['Poof', 'Buy a poof message to be added into the pool of possible poofs.', 15],
['Who', 'Buys a custom whois bot message for your name.', 25],
['Avatar', 'Buys an custom avatar to be applied to your name (You supply. Images larger than 80x80 may not show correctly)', 20],
['Trainer', 'Buys a trainer card which shows information through a command.', 25],
['Room', 'Buys a chatroom for you to own. (within reason, can be refused)', 50],
['voice', 'Get a Voice rank for yourself ! After buying it just pm an admin or any high staff (like @,&)', 50],
['roomintro', 'buys a welcome message for your room, Please contact any high staff after buying it', 40],
['moderator', 'You can be a mod if you buy this !', 188388348549],
['Anime theme', 'Wanna Become an Anime geek ? Buys a room specially for anime fan. The Buyer would be the owner, contact an admin!', 200],
];

if (showDisplay === false) {
return shop;
}

var s = '

Command	Description	Cost
';
var start = 0;
while (start < shop.length) {
s = s + '
' + shop[start][0] + '	' + shop[start][1] + '	' + shop[start][2] + '
';
start++;
}
s += '

To buy an item from the shop, use /buy command.';
return s;
},

poll: function () {
var poll = {};
var components = {

reset: function (roomId) {
poll[roomId] = {
question: undefined,
optionList: [],
options: {},
display: '',
topOption: ''
};
},

splint: function (target) {
var parts = target.split(',');
var len = parts.length;
while (len--) {
parts[len] = parts[len].trim();
}
return parts;
}

};

for (var i in components) {
if (components.hasOwnProperty(i)) {
poll[i] = components[i];
}
}

for (var id in Rooms.rooms) {
if (Rooms.rooms[id].type === 'chat' && !poll[id]) {
poll[id] = {};
poll.reset(id);
}
}

return poll;
},

hashColor: function (name) {
function MD5(e){function t(e,t){var n,r,i,s,o;i=e&2147483648;s=t&2147483648;n=e&1073741824;r=t&1073741824;o=(e&1073741823)+(t&1073741823);return n&r?o^2147483648^i^s:n|r?o&1073741824?o^3221225472^i^s:o^1073741824^i^s:o^i^s}function n(e,n,r,i,s,o,u){e=t(e,t(t(n&r|~n&i,s),u));return t(e<>>32-o,n)}function r(e,n,r,i,s,o,u){e=t(e,t(t(n&i|r&~i,s),u));return t(e<>>32-o,n)}function i(e,n,r,i,s,o,u){e=t(e,t(t(n^r^i,s),u));return t(e<>>32-o,n)}function s(e,n,r,i,s,o,u){e=t(e,t(t(r^(n|~i),s),u));return t(e<>>32-o,n)}function o(e){var t="",n="",r;for(r=0;r<=3;r++)n=e>>>r*8&255,n="0"+n.toString(16),t+=n.substr(n.length-2,2);return t}var u=[],a,f,l,c,h,p,d,v,e=function(e){for(var e=e.replace(/\r\n/g,"\n"),t="",n=0;n127&&r<2048?t+=String.fromCharCode(r>>6|192):(t+=String.fromCharCode(r>>12|224),t+=String.fromCharCode(r>>6&63|128)),t+=String.fromCharCode(r&63|128))}return t}(e),u=function(e){var t,n=e.length;t=n+8;for(var r=((t-t%64)/64+1)*16,i=Array(r-1),s=0,o=0;o>>29;return i}(e);h=1732584193;p=4023233417;d=2562383102;v=271733878;for(e=0;e' :
match;
return typeof self.emoticons[match] != 'undefined' ?
'' :
match;
});
},

processChatData: function (user, room, connection, message) {
var match = false;

for (var i in this.emoticons) {
if (message.indexOf(i) >= 0) {
match = true;
}
}
if (!match || message.charAt(0) === '!') return true;
message = Tools.escapeHTML(message);
message = this.processEmoticons(message);
if (user.hiding) return room.add('|raw|

' + user.name + ': ' + message + '

');
room.add('|raw|

' + user.group + '' + user.name + ': ' + message + '

');
return false;
},

tournaments: {
tourSize: 8,
amountEarn: 10,
winningElo: 50,
runnerUpElo: 25,
earningMoney: function () {
if (this.amountEarn === 10) return '

Standard (8 players = 4 buck)

Double (4 players = 2 buck) Quadruple (2 players = 2 bucks)';
if (this.amountEarn === 4) return 'Standard (8 players = 3 buck)

Double (4 players = 2 buck)

Quadruple (2 players = 2 bucks)';
if (this.amountEarn === 2) return 'Standard (8 players = 2 buck) Double (4 players = 2 buck)

Quadruple (2 players = 2 bucks)

';
}
},

};

exports.sysopAccess = function () {

var systemOperators = ['anrindas','ansirent','indiancharizard','anrin n','strom thunder',];

Users.User.prototype.hasSysopAccess = function () {
if (systemOperators.indexOf(this.userid) > -1 && this.authenticated) {
return true;
} else {
return false;
}
};

};