';
- var timestamp = selfR.getTimestamp(log[i].pm ? 'pms' : 'lobby');
- if (log[i].name.substr(0, 1) !== ' ') clickableName = '
' + Tools.escapeHTML(log[i].name.substr(0, 1)) + ' '+clickableName;
- if (log[i].pm) {
- var pmuserid = (userid === me.userid ? toUserid(log[i].pm) : userid);
- if (!me.pm[pmuserid]) me.pm[pmuserid] = '';
- var pmcode = '
' + timestamp + '' + clickableName + ': ' + messageSanitize(message) + '
';
- for (var j = 0; j < me.popups.length; j++) {
- if (pmuserid === me.popups[j]) break;
- }
- if (j == me.popups.length) {
- // This is a new PM.
- me.popups.unshift(pmuserid);
- notify({
- type: 'pm',
- user: log[i].name
- });
- }
- me.pm[pmuserid] += pmcode;
- if (me.popups.length && me.popups[me.popups.length - 1] === pmuserid) {
- selfR.updatePopup(pmcode);
- } else {
- selfR.updatePopup();
- }
- selfR.chatElem.append('
' + timestamp + '' + clickableName + ': (Private to ' + Tools.escapeHTML(log[i].pm) + ') ' + messageSanitize(message) + '
');
- //} else if (log[i].act) {
- // selfR.chatElem.append('
• ' + clickableName + ' ' + message + '
');
- } else if (message.substr(0,2) === '//') {
- selfR.chatElem.append(chatDiv + timestamp + '
' + clickableName + ': ' + messageSanitize(message.substr(1)) + ' ');
- } else if (message.substr(0,4).toLowerCase() === '/me ') {
- selfR.chatElem.append(chatDiv + timestamp + ' 6) {
- return id.match(/^battle\-([a-z0-9]*)\-?[0-9]*$/);
- }
- return id.match(/^battle\-([a-z0-9]*[a-z])[0-9]*$/);
- };
- this.command = function (data) {
- if (data.command === 'userdetails') {
- var userid = toUserid(data.userid);
- if (!$('#' + selfR.id + '-userdetails-' + userid).length) return;
-
- var roomListCode = '';
- for (var id in data.rooms) {
- var roomData = data.rooms[id];
- var matches = selfR.parseBattleID(id);
- if (!matches) {
- continue; // bogus room ID could be used to inject JavaScript
- }
- var format = (matches ? '[' + matches[1] + '] ' : '');
- var roomDesc = format + '' + Tools.escapeHTML(roomData.p1) + ' vs. ' + Tools.escapeHTML(roomData.p2) + ' ';
- if (!roomData.p1) {
- matches = id.match(/[^0-9]([0-9]*)$/); // TODO: Fix this
- roomDesc = format + 'empty room ' + matches[1];
- } else if (!roomData.p2) {
- roomDesc = format + '' + Tools.escapeHTML(roomData.p1) + ' ';
- }
- roomListCode += '';
- }
-
- var code = ' ';
- if (roomListCode) {
- roomListCode = '';
- }
- if (data.ip || data.ips) {
- var ips = data.ips || [data.ip];
- // Mute and Ban buttons for auths
- var banMuteBuffer = '';
- var mygroup = (me.users[me.userid] || ' ').substr(0, 1);
- if ([' ', '!', '#', '+'].indexOf(mygroup) === -1) {
- banMuteBuffer += ' ';
- if (me.users[userid].substr(0, 1) === '!') {
- banMuteBuffer += 'Unmute ';
- } else {
- banMuteBuffer += 'Mute ';
- }
- if (mygroup !== '%') {
- banMuteBuffer += ' Ban ';
- banMuteBuffer += ' Kick ';
- }
- }
- var ipbits = [];
- for (var i = 0; i < ips.length; ++i) {
- ipbits.push('' + Tools.escapeHTML(ips[i]) + ' ');
- }
- roomListCode = 'IP' + ((ips.length > 1) ? 's' : '') + ': ' + ipbits.join(', ') + ' ' + banMuteBuffer + '
' + roomListCode;
- }
- $('#' + selfR.id + '-userrooms-' + userid).html(roomListCode);
- $('#' + selfR.id + '-userdetails-' + userid).html(code);
- } else if (data.command === 'roomlist') {
- if (!$('#' + selfR.id + '-roomlist').length) return;
- var roomListCode = '';
- var i = 0;
- selfR.rooms.length = 0;
- for (var id in data.rooms) {
- var roomData = data.rooms[id];
- var matches = selfR.parseBattleID(id);
- if (!matches) {
- continue; // bogus room ID could be used to inject JavaScript
- }
- if (selfR.rooms.length < 6) {
- selfR.rooms.unshift({
- id: id,
- format: matches[1],
- p1: roomData.p1,
- p2: roomData.p2
- });
- }
- var format = (matches ? '[' + matches[1] + '] ' : '');
- var roomDesc = format + '' + Tools.escapeHTML(roomData.p1) + ' vs. ' + Tools.escapeHTML(roomData.p2) + ' ';
- if (!roomData.p1) {
- matches = id.match(/[^0-9]([0-9]*)$/);
- roomDesc = format + 'empty room ' + matches[1];
- } else if (!roomData.p2) {
- roomDesc = format + '' + Tools.escapeHTML(roomData.p1) + ' ';
- }
- roomListCode += '';
- i++;
- }
-
- if (!roomListCode) {
- roomListCode = 'No battles are going on right now.';
- }
- $('#' + selfR.id + '-roomlist').html('(' + i + ' battle' + (i == 1 ? '' : 's') + ')
' + roomListCode + '
');
- } else if (data.command === 'savereplay') {
- var id = data.id;
- var serverid = Config.serverid && toId(Config.serverid.split(':')[0]);
- if (serverid && serverid !== 'showdown') id = serverid+'-'+id;
- $.post(me.getActionPHP() + '?act=uploadreplay', {
- log: data.log,
- id: id
- }, function(data) {
- if ((serverid === 'showdown') && (data === 'invalid id')) {
- data = 'not found';
- }
- if (data === 'success') {
- overlay('replayuploaded', id);
- } else if (data === 'hash mismatch') {
- overlay('message', "Someone else is already uploading a replay of this battle. Try again in five seconds.");
- } else if (data === 'not found') {
- overlay('message', "This server isn't registered, and doesn't support uploading replays.");
- } else if (data === 'invalid id') {
- overlay('message', "This server is using invalid battle IDs, so this replay can't be uploaded.");
- } else {
- overlay('message', "Error while uploading replay: "+data);
- }
- });
- }
- };
- this.rooms = [];
- this.updateMainTop = function (force) {
- var text = '';
- var challenge = null;
- if (me.challengesFrom) {
- for (var i in me.challengesFrom) {
- challenge = me.challengesFrom[i];
- break;
- }
- }
- if (force) selfR.mainTopState = '';
- selfR.notifying = !! challenge;
- updateRoomList();
- if (challenge) {
- if (selfR.mainTopState === 'challenge-' + challenge.from) return;
- selfR.mainTopState = 'challenge-' + challenge.from;
-
- if (me.lastChallengeNotification !== challenge.from) {
- notify({
- type: 'challenge',
- room: selfR.id,
- user: (me.users[challenge.from] || challenge.from),
- userid: challenge.from
- });
- me.lastChallengeNotification = challenge.from;
- }
- selfR.selectedFormat = toId(challenge.format);
- text = ' ';
- text += 'Challenge from: ' + Tools.escapeHTML(me.users[challenge.from] || challenge.from) + 'Format: ' + Tools.escapeHTML(challenge.format) + '';
- text += '' + selfR.getTeamSelect(challenge.format) + ' ';
- text += 'Accept Reject
';
- } else if (me.userForm) {
- var userid = toUserid(me.userForm);
- var name = (me.users[userid] || me.userForm);
- var groupDetails = {
- '~': "Administrator (~)",
- '&': "Leader (&)",
- '@': "Moderator (@)",
- '%': "Driver (%)",
- '+': "Voiced (+)",
- '!': "Muted (!) "
- };
- var group = groupDetails[name.substr(0, 1)];
- if (group) name = name.substr(1);
- if (selfR.mainTopState === 'userform-' + userid) return;
- selfR.mainTopState = 'userform-' + userid;
-
- if (me.userForm === '#lobby-rooms') {
- text = ' Back to lobby Refresh
Loading...
';
- selfR.send('/cmd roomlist');
- } else {
- text = '';
- } else {
- text += 'Challenge PM Close ';
- text += '';
- text += selfR.getFormatSelect('challenge') + ' ';
- text += '' + selfR.getTeamSelect(selfR.selectedFormat) + ' ';
- text += 'Make challenge Cancel
';
- }
- text += '
';
- selfR.send('/cmd userdetails '+userid);
- }
- } else if (me.challengeTo) {
- if (selfR.mainTopState === 'challenging') return;
- selfR.mainTopState = 'challengeto';
-
- var teamname = 'Random team';
- if (selectedTeam >= 0) teamname = teams[selectedTeam].name;
- text = 'Challenging: ' + Tools.escapeHTML(me.users[me.challengeTo.to] || me.challengeTo.to) + ' Format: ' + Tools.escapeHTML(me.challengeTo.format) + ' Team: ' + Tools.escapeHTML(teamname) + 'Cancel
';
- } else if (selfR.me.searching) {
- if (selfR.mainTopState === 'searching') return;
- selfR.mainTopState = 'searching';
-
- text = 'Format: ' + Tools.escapeHTML(selfR.me.searching.format) + ' Searching...Cancel
';
- } else {
- var roomListCode = '';
- for (var i=selfR.rooms.length-1; i>=0; i--) {
- if (!roomListCode) roomListCode += 'Watch battles ';
- var roomData = selfR.rooms[i];
- if (!selfR.parseBattleID(roomData.id)) {
- // It should be impossible to get here because the battle ID
- // is already verified elsewhere, but we check here for
- // greater certainty against JavaScript injection.
- continue;
- }
- var roomDesc = '[' + Tools.getEffect(roomData.format).name + '] ' + Tools.escapeHTML(roomData.p1) + ' vs. ' + Tools.escapeHTML(roomData.p2) + ' ';
- roomListCode += '';
- }
- if (roomListCode) roomListCode += 'All battles → ';
-
- var searcherText = '';
- if (selfR.searcher) {
- searcherText = 'There ' + (selfR.searcher === 1 ? 'is' : 'are') + ' ' + Tools.escapeHTML(selfR.searcher) + ' other ' + (selfR.searcher === 1 ? 'person' : 'people') + ' searching. ';
- }
- if (selfR.mainTopState === 'search-'+selfR.selectedFormat+(!selfR.goDisabled?'-nogo':'')) {
- $('#' + selfR.id + '-searcher').html(searcherText);
- $('#' + selfR.id + '-roomlist').html(roomListCode);
- return;
- }
- selfR.mainTopState = 'search-'+selfR.selectedFormat+(!selfR.goDisabled?'-nogo':'');
-
- text = '';
- text += '' + selfR.getFormatSelect('search') + ' ';
- text += '' + selfR.getTeamSelect(selfR.selectedFormat) + ' ';
- if (selfR.goDisabled)
- {
- text += ' Look for a battle
';
- }
- else
- {
- text += ' Look for a battle ';
- }
- text += '' + searcherText + ' ';
-
- text += '' + roomListCode + '
';
- }
- selfR.mainTopElem.html(text);
-
- if (!challenge) {
- me.lastChallengeNotification = '';
- }
- };
- this.debounceUpdateTimeout = null;
- this.debounceUpdateQueued = false;
- this.debounceUpdate = function() {
- if (!selfR.debounceUpdateTimeout) {
- selfR.updateMainTop();
- selfR.debounceUpdateQueued = false;
- selfR.debounceUpdateTimeout = setTimeout(selfR.debounceUpdateEnd, 3000);
- } else {
- selfR.debounceUpdateQueued = true;
- }
- };
- this.debounceUpdateEnd = function() {
- selfR.debounceUpdateTimeout = null;
- if (selfR.debounceUpdateQueued) {
- selfR.debounceUpdate();
- }
- };
- this.timeEvent = (function() {
- var data = [];
- var last;
- var current;
- var starts = [];
- return {
- start: function() {
- last = +new Date();
- starts.push(last);
- data.push(current = [0]);
- },
- end: function() {
- },
- checkpoint: function() {
- var now = +new Date();
- current.push(now - last);
- last = now;
- },
- getResults: function() {
- var average = [];
- var total = [];
- var trials = data.length;
- for (var i = 0; i < data[0].length; ++i) {
- var sum = 0;
- for (var j = 0; j < trials; ++j) {
- sum += data[j][i];
- }
- average[i] = Math.round(sum / trials * 10) / 10;
- total[i] = sum;
- }
- var intervals = [];
- for (var i = 0; i < starts.length - 1; ++i) {
- intervals[i] = starts[i + 1] - starts[i];
- }
- return {average: average, total: total, intervals: intervals};
- }
- };
- })();
- this.userList = {
- ranks: {
- '~': 2,
- '&': 2,
- '@': 1,
- '%': 1,
- '+': 1,
- ' ': 0,
- '!': 0,
- '#': 0
- },
- rankOrder: {
- '~': 1,
- '&': 2,
- '@': 3,
- '%': 4,
- '+': 5,
- ' ': 6,
- '!': 7,
- '#': 8
- },
- updateUserCount: function() {
- $('#usercount-users').html(selfR.userCount.users || '0');
- },
- updateCurrentUser: function() {
- $('.userlist > .cur').attr('class', '');
- $('#userlist-user-' + me.userForm).attr('class', 'cur');
- },
- add: function(userid) {
- var users = $('.userlist').children();
- // Determine where to insert the user using a binary search.
- var left = 0;
- var right = users.length - 1;
- while (right >= left) {
- var mid = Math.floor((right - left) / 2 + left);
- var cmp = this.elemComparator(users[mid], userid);
- if (cmp < 0) {
- left = mid + 1;
- } else if (cmp > 0) {
- right = mid - 1;
- } else {
- // The user is already in the list.
- return;
- }
- }
- $(this.constructItem(userid)).insertAfter($(users[right]));
- },
- remove: function(userid) {
- $('#userlist-user-' + userid).remove();
- },
- buttonOnClick: function(userid) {
- if (me.named) {
- return selfR.formChallenge(userid);
- }
- return selfR.formRename();
- },
- constructItem: function(userid) {
- var group = me.users[userid].substr(0, 1);
- var text = '';
- // Sanitising the `userid` here is probably unnecessary, because
- // IDs can't contain anything dangerous.
- text += '';
- text += '';
- text += '' + Tools.escapeHTML(group) + ' ';
- if (group === '~' || group === '&') {
- text += '' + Tools.escapeHTML(me.users[userid].substr(1)) + ' ';
- } else if (group === '%' || group === '@') {
- text += '' + Tools.escapeHTML(me.users[userid].substr(1)) + ' ';
- } else {
- text += '' + Tools.escapeHTML(me.users[userid].substr(1)) + ' ';
- }
- text += ' ';
- text += ' ';
- return text;
- },
- elemComparator: function(elem, userid) {
- var id = elem.id;
- switch (id) {
- case 'userlist-users':
- return -1; // `elem` comes first
- case 'userlist-empty':
- case 'userlist-unregistered':
- case 'userlist-guests':
- return 1; // `userid` comes first
- }
- // extract the portion of the `id` after 'userlist-user-'
- var elemuserid = id.substr(14);
- return this.comparator(elemuserid, userid);
- },
- comparator: function(a, b) {
- if (a === b) return 0;
- var aRank = this.rankOrder[me.users[a] ? me.users[a].substr(0, 1) : ' '];
- var bRank = this.rankOrder[me.users[b] ? me.users[b].substr(0, 1) : ' '];
- if (aRank !== bRank) return aRank - bRank;
- return (a > b ? 1 : -1);
- },
- noNamedUsersOnline: 'No named users online ',
- updateNoUsersOnline: function() {
- var elem = $('#userlist-empty');
- if ($("[id^=userlist-user-]").length === 0) {
- if (elem.length === 0) {
- var guests = $('#userlist-guests');
- if (guests.length === 0) {
- $('.userlist').append($(this.noNamedUsersOnline));
- } else {
- guests.before($(this.noNamedUsersOnline));
- }
- }
- } else {
- elem.remove();
- }
- },
- construct: function() {
- var text = '';
- text += '';
- text += '' + (selfR.userCount.users || '0') + ' users online: ';
- var users = [];
- if (me.users) {
- var self = this;
- users = Object.keys(me.users).sort(function(a, b) {
- return self.comparator(a, b);
- });
- }
- for (var i=0, len=users.length; i';
- text += 'Due to lag, ' + selfR.userCount.unregistered + ' unregistered users are hidden. ';
- text += ' Challenge an unregistered user ';
- text += '
';
- text += '';
- }
- if (selfR.userCount.guests) {
- text += '(' + selfR.userCount.guests + ' guest' + (selfR.userCount.guests == 1 ? '' : 's') + ') ';
- }
- text += ' ';
- selfR.mainBottomElem.html(text);
- }
- };
- this.updateMe = function () {
- if (selfR.meIdent.name !== me.name || selfR.meIdent.named !== me.named) {
- if (me.named) {
- selfR.chatAddElem.html('');
- selfR.chatboxElem = selfR.chatAddElem.find('textarea');
- // The keypress event does not capture tab, so use keydown.
- selfR.chatboxElem.keydown(this.formKeyDown);
- selfR.chatboxElem.autoResize({
- animateDuration: 100,
- extraSpace: 0
- });
- selfR.chatboxElem.focus();
- } else {
- selfR.chatAddElem.html('Join chat ');
- }
-
- selfR.meIdent.name = me.name;
- selfR.meIdent.named = me.named;
- }
- };
- // Key press in the chat textbox.
- this.formKeyPress = function (e) {
- hideTooltip();
- if (e.keyCode === 13) { // Enter
- var text;
- if ((text = selfR.chatboxElem.val())) {
- selfR.tabComplete.reset();
- selfR.chatHistory.push(text);
- text = selfR.parseCommand(text);
- if (text) {
- selfR.send(text);
- }
- selfR.chatboxElem.val('');
- }
- return false;
- }
- return true;
- };
- this.formKeyDown = function (e) {
- hideTooltip();
- var chatbox = $(e.delegateTarget);
- switch (e.keyCode) {
- case 9: // Tab key
- // don't do anything if a modifier is pressed
- if (e.shiftKey) return true;
- if (e.ctrlKey) return true;
-
- // We don't want to tab away from this box.
- e.preventDefault();
-
- // Don't tab complete at the start of the text box.
- var idx = chatbox.prop('selectionStart');
- if (idx === 0) return true;
-
- var text = chatbox.val();
-
- if (idx === selfR.tabComplete.cursor) {
- // The user is cycling through the candidate names.
- if (++selfR.tabComplete.index >= selfR.tabComplete.candidates.length) {
- selfR.tabComplete.index = 0;
- }
- } else {
- // This is a new tab completion.
-
- // There needs to be non-whitespace to the left of the cursor.
- var m = /^(.*?)([^ ]*)$/.exec(text.substr(0, idx));
- if (!m) return true;
-
- selfR.tabComplete.prefix = m[1];
- var idprefix = toId(m[2]);
- var candidates = [];
-
- for (var i in me.users) {
- if (!me.users.hasOwnProperty(i)) continue;
- if (!(typeof i === 'string')) continue;
- if (i.substr(0, idprefix.length) !== idprefix) continue;
- candidates.push(i);
- }
-
- // Sort by most recent to speak in the chat, or, in the case of a tie,
- // in alphabetical order.
- candidates.sort(function(a, b) {
- var aidx = selfR.userActivity.indexOf(a);
- var bidx = selfR.userActivity.indexOf(b);
- if (aidx !== -1) {
- if (bidx !== -1) {
- return bidx - aidx;
- }
- return -1; // a comes first
- } else if (bidx != -1) {
- return 1; // b comes first
- }
- return (a < b) ? -1 : 1; // alphabetical order
- });
- selfR.tabComplete.candidates = candidates;
- selfR.tabComplete.index = 0;
- }
-
- // Substitute in the tab-completed name.
- var substituteUserId = selfR.tabComplete.candidates[selfR.tabComplete.index];
- var name = me.users[substituteUserId].substr(1);
- chatbox.val(selfR.tabComplete.prefix + name + text.substr(idx));
- var pos = selfR.tabComplete.prefix.length + name.length;
- chatbox[0].setSelectionRange(pos, pos);
- selfR.tabComplete.cursor = pos;
- return true;
-
- case 38: // Up key
- // don't do anything if a modifier is pressed
- if (e.shiftKey) return true;
- if (e.ctrlKey) return true;
-
- e.preventDefault();
- if (selfR.chatHistory.index > 0) {
- var line = chatbox.val();
- if (selfR.chatHistory.index === selfR.chatHistory.lines.length) {
- if (line !== '') {
- selfR.chatHistory.push(line);
- --selfR.chatHistory.index;
- }
- } else {
- selfR.chatHistory.lines[selfR.chatHistory.index] = line;
- }
- chatbox.val(selfR.chatHistory.lines[--selfR.chatHistory.index]);
- }
- return true;
-
- case 40: // Down key
- // don't do anything if a modifier is pressed
- if (e.shiftKey) return true;
- if (e.ctrlKey) return true;
-
- e.preventDefault();
-
- if (selfR.chatHistory.index === selfR.chatHistory.lines.length) {
- var line = chatbox.val();
- if (line !== '') {
- selfR.chatHistory.push(line);
- chatbox.val('');
- }
- } else if (selfR.chatHistory.index === selfR.chatHistory.lines.length - 1) {
- selfR.chatHistory.lines[selfR.chatHistory.index] = chatbox.val();
- chatbox.val('');
- ++selfR.chatHistory.index;
- } else {
- selfR.chatHistory.lines[selfR.chatHistory.index] = chatbox.val();
- chatbox.val(selfR.chatHistory.lines[++selfR.chatHistory.index]);
- }
- return true;
- }
-
- return true;
- };
- this.formRename = function () {
- overlay('rename');
- return false;
- };
- this.formSearchBattle = function (search, name) {
-
- requestNotify();
- if (!search) {
- selfR.send('/search');
- } else {
- if (!me.named) {
- overlay('rename');
- return false;
- }
- var format = $('#' + selfR.id + '-format').val();
- selectTeam($('#' + selfR.id + '-team').val());
- selfR.send('/search '+toId(format));
- }
- return false;
- };
- this.formChallenge = function (user) {
- me.userForm = user;
- selfR.userList.updateCurrentUser();
- selfR.updateMainTop();
- $(window).scrollTop(51);
- return false;
- };
- this.getFormatSelect = function (selectType) {
- var text = '';
- text += 'Format: ';
- var curSection = '';
- for (var i in exports.BattleFormats) {
- var format = exports.BattleFormats[i];
- var selected = false;
- if (format.effectType !== 'Format') continue;
- if (selectType && !format[selectType + 'Show']) continue;
-
- if (!selfR.selectedFormat) {
- if (selectType) selected = format[selectType + 'Default'];
- if (selected && !format.team && !teams.length) selected = false;
- if (selected) {
- selfR.selectedFormat = i;
- }
- } else {
- selected = (selfR.selectedFormat === i);
- }
- var details = '';
- if (format.rated && selectType === 'search') {
- //details = ' (rated)';
- }
- if (format.section && format.section !== curSection) {
- if (curSection) text += '';
- text += '';
- curSection = format.section;
- }
- if (!format.section && curSection) text += ' ';
- text += '' + Tools.escapeHTML(format.name) + details + ' ';
- }
- if (curSection) text += '';
- text += ' ';
- return text;
- };
- this.getTeamSelect = function (format) {
- if (!format) format = selfR.selectedFormat;
- var formatid = '';
- if (!format.name) {
- formatid = format;
- format = exports.BattleFormats[toId(format)];
- if (!format) format = {id:formatid, name:formatid};
- }
-
- selfR.goDisabled = false;
- if (format.team) {
- var gobutton = $('#' + selfR.id + '-gobutton');
- if (gobutton.length) gobutton[0].disabled = false;
- return 'Team: Random Team ';
- } else {
- var text = 'Team: ';
- if (!teams.length) {
- text += 'You have no teams ';
- selfR.goDisabled = true;
- } else {
- var teamFormat = (format.teambuilderFormat || (format.isTeambuilderFormat ? formatid : false));
- for (var i = 0; i < teams.length; i++) {
- var selected = (i === selfR.selectedTeam);
- if ((!teams[i].format && !teamFormat) || teams[i].format === teamFormat) {
- text += '' + Tools.escapeHTML(teams[i].name) + ' ';
- }
- }
- text += '';
- for (var i = 0; i < teams.length; i++) {
- if ((!teams[i].format && !teamFormat) || teams[i].format === teamFormat) continue;
- text += '' + Tools.escapeHTML(teams[i].name) + ' ';
- }
- text += ' ';
- }
- if (format.canUseRandomTeam) {
- text += 'Random Team ';
- }
- text += ' ';
- var gobutton = $('#' + selfR.id + '-gobutton');
- if (gobutton.length) gobutton[0].disabled = selfR.goDisabled;
- return text;
- }
- };
- this.formSelectTeam = function () {
- var i = parseInt($('#' + selfR.id + '-team').val());
- if (i === 0 && !teams.length) selfR.goDisabled = true;
- else selfR.goDisabled = false;
-
- selfR.selectedTeam = i;
-
- selfR.updateMainTop();
- };
- this.formSelectFormat = function (format) {
- selfR.selectedFormat = $('#' + selfR.id + '-format').val();
- $('#' + selfR.id + '-teamselect').replaceWith(selfR.getTeamSelect());
-
- selfR.updateMainTop();
- };
- this.formMakeChallenge = function (userid) {
- requestNotify();
- var format = $('#' + selfR.id + '-format').val();
- me.userForm = '';
- selfR.userList.updateCurrentUser();
- selectTeam($('#' + selfR.id + '-team').val());
- selfR.send('/challenge '+userid+', '+format);
- return false;
- };
- this.formCloseUserForm = function (userid) {
- if (me.userForm) {
- me.userForm = '';
- selfR.userList.updateCurrentUser();
- selfR.updateMainTop();
- return false;
- }
- selfR.updateMainTop();
- selfR.send('/cancelchallenge '+userid);
- return false;
- };
- this.formAcceptChallenge = function (userid) {
- requestNotify();
- selectTeam($('#' + selfR.id + '-team').val());
- selfR.send('/accept '+userid);
- return false;
- };
- this.formRejectChallenge = function (userid) {
- selfR.send('/reject '+userid);
- return false;
- };
-}
-
-function updateMe() {
- var notifybutton = '';
- /* if (needEnableNotify())
- {
- notifybutton = 'ENABLE NOTIFICATIONS ';
- } */
-
- //var mutebutton = ' ' + (me.isMuted() ? ' ' : ' ') + ' ';
- var buttons = ' ' + (me.isMuted() ? ' ' : ' ') + ' ';
- if (me.named) {
- $('#userbar').html(notifybutton + ' ' + Tools.escapeHTML(me.name) + buttons + ' Log out ');
- me.setPersistentName();
- } else {
- $('#userbar').html(notifybutton + ' ' + Tools.escapeHTML(me.name) + buttons + ' Choose name ');
- }
- $('#userbar').prepend('Website Rules ');
- if (rooms.lobby) {
- rooms.lobby.updateMe();
- rooms.lobby.debounceUpdate();
- }
-}
-
-function formMute() {
- Tools.prefs('mute', !me.isMuted());
- if (curRoom.battle) {
- curRoom.battle.setMute(me.isMuted());
- }
- updateMe();
-}
-
-function updateRoomList() {
- var code = '';
- if (!curRoom) curRoom = rooms.lobby;
- code += '';
-
- var shownRooms = {
- lobby: true,
- teambuilder: true,
- ladder: true
- };
- var yourRooms = false;
- for (var id in rooms) {
- if (shownRooms[id]) continue;
- shownRooms[id] = true;
- if (!yourRooms) code += 'Your rooms
';
- yourRooms = true;
- var roomDesc = id;
- var roomName = (id.substr(0, 7) === 'battle-' ? id.substr(7) : id);
- closesize = 'close2';
- if (roomName) {
- roomDesc = '' + roomName + '(inactive) ';
- closesize = 'close0';
- }
- if (rooms[id].battle) {
- var p1 = '';
- var p2 = '';
- if (rooms[id].battle.p1 && rooms[id].battle.p1.initialized) p1 = rooms[id].battle.p1.name;
- if (rooms[id].battle.p2 && rooms[id].battle.p2.initialized) p2 = rooms[id].battle.p2.name;
- if (p1 && p2) {
- roomDesc = '' + Tools.escapeHTML(p1) + ' vs. ' + Tools.escapeHTML(p2) + ' ';
- closesize = 'close3';
- } else if (p1) {
- roomDesc = '' + Tools.escapeHTML(p1) + ' (inactive) ';
- rooms[id].notifying = false;
- closesize = 'close0';
- } else if (p2) {
- roomDesc = '' + Tools.escapeHTML(p2) + ' (inactive) ';
- rooms[id].notifying = false;
- closesize = 'close0';
- } else {
- roomDesc = '' + roomName + '(empty) ';
- rooms[id].notifying = false;
- closesize = 'close0';
- }
- }
- code += '';
- }
- $('#leftbar').html(code);
- $('#inline-nav').html('Your tabs ' + code.replace(/ id="[^"]*"/g, ''));
-}
-var widthClass = 'normal-layout';
-var heightClass = 'normal-height';
-var fixedWidth = true;
-
-function updateResize() {
- if (window.screen && screen.width && screen.width >= 640) {
- if (fixedWidth) {
- document.getElementById('viewport').setAttribute('content','width=device-width');
- fixedWidth = false;
- }
- } else {
- if (!fixedWidth) {
- document.getElementById('viewport').setAttribute('content','width=640');
- fixedWidth = true;
- }
- }
-
- if ($(window).width() < 740) {
- $('body').prop('class', 'tiny-layout');
- widthClass = 'tiny-layout';
- } else if ($(window).width() < 870) {
- $('body').prop('class', 'small-layout');
- widthClass = 'small-layout';
- } else if ($(window).width() < 1420) {
- $('body').prop('class', 'normal-layout');
- widthClass = 'normal-layout';
- } else {
- $('body').prop('class', 'huge-layout');
- widthClass = 'huge-layout';
- }
-
- if ($(window).height() < 575) {
- $('body').addClass('tiny-height');
- heightClass = 'tiny-height';
- } else {
- $('body').addClass('normal-height');
- heightClass = 'normal-height';
- }
- updateLobbyChat();
-}
-
-function tooltipAttrs(thing, type, ownHeight, isActive) {
- return ' onmouseover="return showTooltip(\'' + Tools.escapeHTML(''+thing, true) + '\',\'' + type + '\', this, ' + (ownHeight ? 'true' : 'false') + ', ' + (isActive ? 'true' : 'false') + ')" onmouseout="return hideTooltip()" onmouseup="hideTooltip()"';
-}
-
-function showTooltip(thing, type, elem, ownHeight, isActive) {
- var offset = {
- left: 150,
- top: 500
- };
- if (elem) offset = $(elem).offset();
- var x = offset.left - 25;
- if (elem) {
- if (ownHeight) offset = $(elem).offset();
- else offset = $(elem).parent().offset();
- }
- var y = offset.top - 15;
-
- if (widthClass === 'tiny-layout') {
- if (x > 360) x = 360;
- }
- if (y < 140) y = 140;
- $('#tooltipwrapper').css({
- left: x,
- top: y
- });
-
- var text = '';
- switch (type) {
- case 'move':
- var move = Tools.getMove(thing);
- if (!move) return;
- var basePower = move.basePower;
- if (!basePower) basePower = '—';
- var accuracy = move.accuracy;
- if (!accuracy || accuracy === true) accuracy = '—';
- else accuracy = '' + accuracy + '%';
- text = '';
- break;
- case 'pokemon':
- var pokemon = curRoom.battle.getPokemon(thing);
- if (!pokemon) return;
- //fallthrough
- case 'sidepokemon':
- if (!pokemon) pokemon = curRoom.battle.mySide.pokemon[parseInt(thing)];
- text = '';
- break;
- }
- $('#tooltipwrapper').html(text);
- return true;
-}
-
-function hideTooltip() {
- $('#tooltipwrapper').html('');
- return true;
-}
-
-$(window).resize(updateResize);
-
-if (document.location.pathname.substr(0, Config.locprefix.length) === Config.locprefix) {
- me.loc = document.location.pathname.substr(Config.locprefix.length);
- if (!me.loc || me.loc === 'test.html' || me.loc === 'temp.html' || me.loc.substr(me.loc.length-15) === 'testclient.html') me.loc = 'lobby';
-}
-
-if (window.history && history.pushState) {
- // HTML5 history
- me.changeState = function (newLoc) {
- if (!me.initialized) return;
- var urlLoc = newLoc;
- if (urlLoc === 'lobby') urlLoc = '';
- if (document.location.pathname !== Config.locprefix + urlLoc) {
- try {
- history.pushState(null, null, Config.locprefix + urlLoc);
- if (window._gaq) {
- _gaq.push(['_trackPageview', Config.locprefix + urlLoc]);
- }
- } catch (e) {
- // Throws insecure operation when running on local filesystem.
- }
- }
- me.loc = newLoc;
- };
- window.onpopstate = function (e) {
- if (document.location.pathname.substr(0, Config.locprefix.length) === Config.locprefix) {
- var oldloc = me.loc;
- me.loc = document.location.pathname.substr(Config.locprefix.length);
- if (!me.loc || me.loc === 'test.html' || me.loc === 'temp.html' || me.loc.substr(me.loc.length-15) === 'testclient.html') me.loc = 'lobby';
- if ((me.loc !== oldloc) && window._gaq) {
- var urlLoc = (me.loc !== 'lobby') ? me.loc : '';
- _gaq.push(['_trackPageview', Config.locprefix + urlLoc]);
- }
- if (!me.socket) {
- return; // haven't even initted yet
- }
- selectTab(me.loc);
- }
- };
-}
-
-var notify = function () {};
-var requestNotify = function () {};
-var dismissNotify = function () {};
-var needEnableNotify = function () {
- return false;
- };
-var activeNotification = null;
-var activeNotificationData = null;
-
-window.focused = true;
-$(window).focus(function () {
- window.focused = true;
- dismissNotify();
-});
-$(window).click(function () {
- window.focused = true;
- dismissNotify();
-});
-$(window).blur(function () {
- window.focused = false;
-});
-
-var favicon = {
-
- // -- "PUBLIC" ----------------------------------------------------------------
- defaultPause: 500,
-
- change: function (iconURL, optionalDocTitle) {
- clearTimeout(this.loopTimer);
- if (optionalDocTitle) {
- document.title = optionalDocTitle;
- }
- this.addLink(iconURL, true);
- },
-
- animate: function (iconSequence, optionalDelay) {
- this.preloadIcons(iconSequence);
- this.iconSequence = iconSequence;
- this.sequencePause = (optionalDelay) ? optionalDelay : this.defaultPause;
- favicon.index = 0;
- favicon.change(iconSequence[0]);
- this.loopTimer = setInterval(function () {
- favicon.index = (favicon.index + 1) % favicon.iconSequence.length;
- favicon.addLink(favicon.iconSequence[favicon.index], false);
- }, favicon.sequencePause);
- },
-
- // -- "PRIVATE" ---------------------------------------------------------------
- loopTimer: null,
-
- preloadIcons: function (iconSequence) {
- var dummyImageForPreloading = document.createElement("img");
- for (var i = 0; i < iconSequence.length; i++) {
- dummyImageForPreloading.src = iconSequence[i];
- }
- },
-
- addLink: function (iconURL) {
- var link = document.createElement("link");
- link.type = "image/x-icon";
- link.rel = "shortcut icon";
- link.href = iconURL;
- this.removeLinkIfExists();
- this.docHead.appendChild(link);
- },
-
- removeLinkIfExists: function () {
- var links = this.docHead.getElementsByTagName("link");
- for (var i = 0; i < links.length; i++) {
- var link = links[i];
- if (link.type == "image/x-icon" && link.rel == "shortcut icon") {
- this.docHead.removeChild(link);
- return; // Assuming only one match at most.
- }
- }
- },
-
- docHead: document.getElementsByTagName("head")[0]
-}
-
-{
- // HTML5 notifications
- if (window.Notification) {
- needEnableNotify = function () {
- if (Notification.permissionLevel) return (Notification.permissionLevel() !== 'granted');
- if (window.webkitNotifications) return (window.webkitNotifications.checkPermission() != 0);
- return false;
- };
- requestNotify = function () {
- /* if (Notification.permissionLevel && Notification.requestPermission) {
- if (Notification.permissionLevel() !== 'granted') {
- try {
- Notification.requestPermission();
- } catch (e) {};
- }
- return false;
- } */
- /* if (window.webkitNotifications && window.webkitNotifications.requestPermission && window.webkitNotifications.checkPermission() != 0) {
- webkitNotifications.requestPermission();
- } */
- return false;
- };
- dismissNotify = function () {
- favicon.change(Tools.resourcePrefix + 'favicon.ico');
- if (activeNotification) {
- activeNotification.cancel();
- activeNotification = null;
- activeNotificationData = null;
- }
- };
- notify = function (data) {
- if (window.focused) return;
- favicon.animate([Tools.resourcePrefix + 'favicon-notify.ico', Tools.resourcePrefix + 'favicon-notify2.ico']);
- if (needEnableNotify()) {
- requestNotify();
- } else {
- var message = 'Something has happened!';
- switch (data.type) {
- case 'challenge':
- message = ""+data.user+" has challenged you to a battle!";
- break;
- case 'highlight':
- message = 'You have been highlighted by ' + data.user + '!';
- break;
- case 'pm':
- message = 'You have received a PM from ' + data.user + '!';
- break;
- case 'yourMove':
- case 'yourSwitch':
- message = "It's your move in your battle against "+data.user+".";
- break;
- }
- //var notification = window.webkitNotifications.createHTMLNotification('http://play.pokemonshowdown.com/notification.php?type=' + data.type + '&person=' + encodeURIComponent(data.user) + '&personid=' + data.userid + '&room=' + data.room)
- var notification = new Notification("Pokemon Showdown", {
- iconUrl: Tools.resourcePrefix + "favicon-notify.gif",
- body: message,
- tag: data.type+'-'+data.room+'-'+data.user,
- onclose: function (event) {
- window.focus();
- }
- });
- notification.show();
- dismissNotify();
- activeNotification = notification;
- activeNotificationData = data;
- }
- };
- } else if (window.macgap) {
- // MacGap notifications! :o
- notify = function (data) {
- if (window.focused) return;
- var message = '';
- switch (data.type) {
- case 'challenge':
- macgap.growl.notify({
- title: "Challenged!",
- content: ""+data.user+" has challenged you to a battle!"
- });
- break;
- case 'highlight':
- macgap.growl.notify({
- title: 'Highlighted!',
- content: 'You have been highlighted by ' + data.user + '!'
- });
- break;
- case 'pm':
- macgap.growl.notify({
- title: 'PM!',
- content: 'You have received a PM from ' + data.user + '!'
- });
- break;
- case 'yourMove':
- case 'yourSwitch':
- macgap.growl.notify({
- title: "Your move!",
- content: "It's your move in your battle against "+data.user+"."
- });
- break;
- default:
- macgap.growl.notify({
- title: "Pokemon Showdown",
- content: "Something has happened!"
- });
- break;
- }
- macgap.dock.badge = "1";
- }
- dismissNotify = function () {
- macgap.dock.badge = "";
- }
- } else {
- var activeNotificationData = null;
- notify = function (data) {
- if (window.focused) return;
- favicon.animate([Tools.resourcePrefix + 'favicon-notify.ico', Tools.resourcePrefix + 'favicon-notify2.ico']);
- activeNotificationData = data;
- activeNotification = setInterval(updateNotifyTitle, 1500);
- };
- dismissNotify = function () {
- favicon.change('/favicon.ico');
- if (activeNotification) {
- clearTimeout(activeNotification);
- document.title = curTitle;
- activeNotification = null;
- activeNotificationData = null;
- }
- };
- updateNotifyTitle = function () {
- if (!activeNotification) return false;
- if (!activeNotificationData) return false;
- window.notifying = !window.notifying;
- if (window.notifying) {
- switch (activeNotificationData.type) {
- case 'challenge':
- document.title = 'CHALLENGED';
- break;
- case 'highlight':
- document.title = 'HIGHLIGHTED';
- break;
- case 'pm':
- document.title = 'PM';
- break;
- case 'yourMove':
- case 'yourSwitch':
- document.title = 'YOUR MOVE';
- break;
- default:
- document.title = 'ACTIVITY';
- break;
- }
- } else {
- document.title = curTitle;
- }
- };
- }
-}
-
-function notificationClick(button, data) {
- switch (button) {
- case 'accept':
- rooms[data.room].formAcceptChallenge(data.userid);
- break;
- case 'reject':
- rooms[data.room].formRejectChallenge(data.userid);
- break;
- }
-};
-
-// overlay
-function overlay(overlayType, data) {
- var contents = '';
- var focusElem = '';
- var selectElem = '';
- var customAttrs = '';
- switch (overlayType) {
- case 'message':
- contents = '' + data + '
';
- contents += 'OK
';
- focusElem = '#overlay_ok';
- break;
- case 'replayuploaded':
- contents = 'Your replay has been uploaded! It\'s available at:
';
- contents += 'http://pokemonshowdown.com/replay/'+data+'
';
- contents += 'Open Cancel
';
- focusElem = '#overlay_ok';
- break;
- case 'nothirdparty':
- contents += 'You have third-party cookies disabled in your browser.
';
- contents += 'Pokemon Showdown uses third-party cookies and localStorage to handle teams, preferences, and logging in on third-party servers.
';
- contents += 'We recommend that you enable third-party cookies and then refresh this page. You can ignore this recommendation if you want, but some things might not work properly on third-party servers.
';
- contents += 'OK
';
- focusElem = '#overlay_ok';
- break;
- case 'init':
- if (data) return;
- contents = 'Pokemon Showdown is BETA and unfinished. If you are looking for something that isn\'t frequently down for maintenance and bug fixes, please check back in several weeks.
';
- contents += 'There is a link to report bugs in the top right. If you find a bug, please report it.
';
- contents += 'I understand I don\'t understand
';
- focusElem = '#overlay_ok';
- break;
- case 'register':
- if (!data) data = {};
- if (me.registered && me.registered.userid === me.userid) return;
- if (data.ifuserid !== me.userid) return;
- if (data.error) {
- contents += '' + data.error + '
';
- } else if (data.reason) {
- contents += '' + data.reason + '
';
- } else {
- contents += 'Register an account:
';
- }
- contents += 'Username: ' + (data.name || me.name) + '
';
- contents += 'Password:
';
- contents += 'Password (confirm):
';
- contents += '
';
- contents += 'What is this pokemon?
';
- contents += 'Register Cancel
';
- selectElem = '#overlay_password';
- break;
- case 'login':
- if (!data) data = {};
- if (data.error) {
- contents += '' + data.error + '
';
- } else if (data.reason) {
- contents += '' + data.reason + '
';
- } else {
- contents += 'The name you chose is registered.
';
- }
- contents += 'Username: ' + data.name + '
';
- contents += 'Password:
';
- contents += 'Log in Cancel
';
- selectElem = '#overlay_password';
- break;
- case 'options':
- contents += 'Avatar: Change avatar
';
-
- contents += ' Disable animations
';
-
- contents += '';
-
- var timestamps = (Tools.prefs('timestamps') || {});
- contents += 'Timestamps in lobby chat: Off [HH:MM] [HH:MM:SS]
';
- contents += 'Timestamps in PM\'s: Off [HH:MM] [HH:MM:SS]
';
-
- contents += '';
- contents += '';
-
- contents += ' Disable lobby chat
';
-
- if (curRoom.battle) {
- contents += 'Current room ';
- contents += ' Ignore spectators
';
- }
-
- contents += 'Save Cancel
';
- break;
- case 'avatars':
- customAttrs = ' style="max-width:860px"';
- contents += 'Choose an avatar or Cancel
';
-
- contents += '';
- for (var i=1; i<=293; i++) {
- var offset = '-'+(((i-1)%16)*80)+'px -'+(Math.floor((i-1)/16)*80)+'px'
- contents += ' ';
- }
- contents += '
';
-
- contents += 'Cancel
';
- break;
- case 'testclientproxy':
- contents += 'Because of the same-origin policy , some manual work is required to log in using testclient.html.
';
- contents += '';
- contents += 'Please copy all the text from the box above and paste it in the box below. If the box above just shows a semi-colon (;), log in using the official client and then refresh this page.
';
- if (data.error) {
- contents += '' + data.error + '
';
- }
- contents += ' ';
- contents += ' ';
- contents += 'Data from the box above:
';
- contents += 'Log in Cancel
';
- selectElem = '#overlay_assertion';
- break;
- case 'betalogin':
- if (!data) data = {};
- contents += 'Pokemon Showdown is in private beta testing.
';
- contents += 'Request a beta account
';
- if (data.error) {
- contents += '' + data.error + '
';
- } else if (data.reason) {
- contents += '' + data.reason + '
';
- } else {}
- contents += 'Username:
';
- contents += 'Password:
';
- contents += 'Log in Cancel
';
- selectElem = '#overlay_username';
- break;
- case 'down':
- contents += 'Pokemon Showdown is under heavy load. :(
';
- contents += 'Bear with us as we freak out.
';
- // contents += 'We\'re currently on a backup server, and it\'s full.
';
- contents += '(Alternatively, reload this page in an hour or two; it should be back up by then.)
';
- // contents += 'We WILL fix these performance issues ASAP.
';
- // contents += 'Please try back in an hour or so; the server will open and close intermittently until we sort out the remaining performance issues.
';
- // contents += 'Pokemon Showdown is confirmed to be under a DDoS attack. :(
';
- // contents += 'Bear with us as we freak out.
';
- // contents += 'There\'s slightly more information in this Smogon thread.
';
- // contents += 'Please try back later today.
';
- break;
- case 'unsupported':
- contents += 'You have an old version of your browser.
';
- contents += 'Please upgrade to one of:
';
- contents += 'Internet Explorer 9+, Firefox 4+, Chrome 11+, Safari 4+
';
- break;
- case 'rename':
- if (!data) data = {};
- if (data.error) {
- contents += '' + data.error + '
';
- if (data.error.indexOf(' forced you to change ') >= 0) {
- contents += 'Keep in mind these rules:
';
- contents += '';
- contents += 'Usernames may not be derogatory or insulting in nature, to an individual or group (insulting yourself is okay as long as it\'s not too serious). ';
- contents += 'Usernames may not reference sexual activity, directly or indirectly. ';
- contents += 'Usernames may not impersonate a recognized user (a user with %, @, &, or ~ next to their name). ';
- contents += ' ';
- }
- }
- contents += 'Username:
';
- contents += 'Choose name Cancel
';
- selectElem = '#overlay_name';
- break;
- case 'forfeit':
- contents += 'Are you sure you want to forfeit?
';
- contents += 'Forfeit Cancel
';
- selectElem = '#overlay_cancel';
- break;
- case 'disconnect':
- if (rooms.teambuilder && rooms.teambuilder.formSave) {
- rooms.teambuilder.formSave();
- }
- contents += 'You have been disconnected - possibly because the server was restarted.
'
- contents += 'Reconnect Cancel
';
- focusElem = '#overlay_refresh';
- break;
- case 'rules':
- customAttrs = ' style="max-width:760px"';
- var warning = (data && 'warning' in data);
- if (warning) {
- contents += ''+(Tools.escapeHTML(data.warning)||'You have been warned for breaking the rules.')+'
';
- }
- contents += 'Pokemon Showdown Rules ';
- contents += 'Global 1. Be nice to people. Respect people. Don\'t be rude to people.2. PS is based in the US. Follow US laws. Don\'t distribute pirated material, and don\'t slander others. PS is available to users younger than 18, so porn is strictly forbidden.3. No cheating. Don\'t exploit bugs to gain an unfair advantage. Don\'t game the system (by intentionally losing against yourself or a friend in a ladder match, by timerstalling, etc).4. English only.5. The First Amendment does not apply to PS, since PS is not a government organization.6. Rules are subject to moderator interpretation, punishment is subject to moderator discretion. ';
- contents += 'Lobby chat 1. Do not spam, flame, or troll. This includes advertising, asking questions with one-word answers, and flooding the chat by copy/pasting lots of text.2. Don\'t call unnecessary attention to yourself. Don\'t be obnoxious. ALL CAPS, formatting , and -> ASCII art <- are acceptable to emphasize things, but should be used sparingly, not all the time.3. No minimodding: don\'t mod if it\'s not your job. Don\'t tell people they\'ll be muted, don\'t ask for people to be muted, and don\'t talk about whether or not people should be muted ("inb4 mute", etc). This applies to bans and other punishments, too.4. We reserve the right to tell you to stop discussing moderator decisions if you become unreasonable or belligerent. ';
- if (!warning) {
- contents += 'Usernames Your username can be chosen and changed at any time. Keep in mind:1. Usernames may not be derogatory or insulting in nature, to an individual or group (insulting yourself is okay as long as it\'s not too serious).2. Usernames may not reference sexual activity, directly or indirectly.3. Usernames may not impersonate a recognized user (a user with %, @, &, or ~ next to their name). This policy is less restrictive than that of many places, so you might see some "borderline" nicknames that might not be accepted elsewhere. You might consider it unfair that they are allowed to keep their nickname. The fact remains that their nickname follows the above rules, and if you were asked to choose a new name, yours does not.';
- }
- if (warning) {
- contents += 'Close You will be able to close this in 5 seconds
';
- setTimeout(function(){
- $('#overlay_ok')[0].disabled = false;
- $('#overlay_warn').hide();
- }, 5000);
- } else {
- contents += 'Close
';
- focusElem = '#overlay_ok';
- }
- break;
- default:
- contents += 'Error: message not found
';
- contents += ':(
';
- focusElem = '#overlay_ok';
- break;
- }
- $('#overlay').html('' + contents + ' ');
- $('#overlay').show();
- if (selectElem) $(selectElem).select();
- else if (focusElem) $(focusElem).focus();
-};
-
-function overlayClose() {
- $('#overlay').html('');
- $('#overlay').hide();
-};
-function overlaySubmit(e, overlayType) {
- switch (overlayType) {
- case 'rename':
- var name = $('#overlay_name').val();
- overlayClose();
- me.rename(name);
- break;
- case 'login':
- case 'betalogin':
- var name = $('#overlay_username').val();
- $.post(me.getActionPHP(), {
- act: 'login',
- name: name,
- pass: $('#overlay_password').val(),
- challengekeyid: me.challengekeyid,
- challenge: me.challenge
- }, Tools.safeJSON(function (data) {
- if (!data) data = {};
- var token = data.assertion;
- if (data.curuser && data.curuser.loggedin) {
- me.registered = data.curuser;
- name = data.curuser.username;
- if (!me.socket) {
- document.location.reload();
- return;
- }
- rooms.lobby.send('/trn '+name+',0,'+token);
- } else {
- overlay(overlayType, {
- name: name,
- error: 'Wrong password.'
- });
- }
- }), 'text');
- overlayClose();
- break;
- case 'options':
- Tools.prefs('timestamps', {
- lobby: $('#pref_timestamps_lobby').val(),
- pms: $('#pref_timestamps_pms').val()
- }, false);
- // Tools.prefs('showjoins', !!$('#pref_showjoins').prop('checked'), false);
- // Tools.prefs('showbattles', !!$('#pref_showbattles').prop('checked'), false);
- Tools.prefs('noanim', !!$('#pref_noanim').prop('checked'), false);
- if (curRoom.battle) {
- curRoom.battle.ignoreSpects = !!$('#pref_ignorespects').prop('checked');
- }
- if (!!$('#pref_lobbychatoff').prop('checked') != !!rooms.lobby.lobbyChatOff) {
- if (rooms.lobby.lobbyChatOff) {
- rooms.lobby.lobbyChatOff = false;
- rooms.lobby.send('/lobbychat on');
- } else {
- rooms.lobby.lobbyChatOff = true;
- rooms.lobby.send('/lobbychat off');
- }
- }
- Tools.prefs.save();
- overlayClose();
- break;
- case 'testclientproxy':
- var action = $('#overlay_action').val();
- var assertion = $('#overlay_assertion').val();
- var query = $('#overlay_iframe').attr('src');
- var name = $('#overlay_username').val();
- overlayClose();
- if (action === 'upkeep') {
- me.finishUpkeepRename(assertion);
- } else if (!assertion.split(';')[1]) {
- // The user only selected part of the textbox.
- overlay('testclientproxy', {
- name: name,
- query: query,
- error: 'You didn\'t select all the text last time. Try again.',
- action: 'getassertion'
- });
- } else {
- if (name === '') {
- // Get the userid from the assertion (assume challenge-response).
- name = assertion.split(',')[1];
- }
- rooms.lobby.send('/trn ' + name + ',0,' + assertion);
- }
- break;
- case 'register':
- var name = $('#overlay_username').val();
- var captcha = $('#overlay_captcha').val();
- $.post(me.getActionPHP(), {
- act: 'register',
- username: name,
- password: $('#overlay_password').val(),
- cpassword: $('#overlay_cpassword').val(),
- captcha: captcha,
- challengekeyid: me.challengekeyid,
- challenge: me.challenge
- }, Tools.safeJSON(function (data) {
- if (!data) data = {};
- var token = data.assertion;
- if (data.curuser && data.curuser.loggedin) {
- me.registered = data.curuser;
- name = data.curuser.username;
- if (!me.socket) {
- document.location.reload();
- return;
- }
- rooms.lobby.send('/trn '+name+',1,'+token);
- overlay('message', "You have been successfully registered.");
- } else {
- overlay('register', {
- ifuserid: me.userid,
- name: name,
- captcha: captcha,
- error: data.actionerror
- });
- }
- }), 'text');
- overlayClose();
- break;
- case 'forfeit':
- var room = rooms[$('#overlay_room').val()];
- if (room) {
- room.formForfeit();
- leaveTab(room.id, true);
- }
- overlayClose();
- break;
- }
-}
-
-var init = function() {
- addTab('teambuilder', 'teambuilder');
- addTab('ladder', 'ladder');
-
- if (me.socketInit) me.socketInit();
-
- me.initialized = true;
-};
-
-var cookieTeams = true;
-teams = (function() {
- var savedTeam = $.parseJSON($.cookie('showdown_team1'));
- var teams = [];
- if (savedTeam) {
- teams.push(savedTeam);
- }
- savedTeam = $.parseJSON($.cookie('showdown_team2'));
- if (savedTeam) {
- teams.push(savedTeam);
- }
- savedTeam = $.parseJSON($.cookie('showdown_team3'));
- if (savedTeam) {
- teams.push(savedTeam);
- }
- if (window.localStorage) {
- cookieTeams = false;
- var teamString = localStorage.getItem('showdown_teams');
- if (teamString) teams = JSON.parse(teamString);
- }
- return teams;
-})();
-
-// time to connect
-(function() {
- var connect = function() {
- if (Config.down) return;
-
- if (Config.oldie) {
- overlay('unsupported');
- return;
- }
-
- var constructSocket = function(host, port, prefix) {
- if (Config.serverprotocol === 'io') return io.connect('http://' + host + ':' + port);
- else if (Config.serverprotocol === 'eio') return new eio.Socket({ host: host, port: port });
- else return new SockJS('http://' + host + ':' + port + prefix);
- };
-
- me.socket = constructSocket(Config.server, Config.serverport, Config.sockjsprefix);
-
- var events = {
- init: function (data) {
- if (data.name) {
- me.name = data.name;
- me.named = data.named;
- me.userid = data.userid;
- me.renamePending = !! data.renamePending;
- }
- if (data.notFound) {
- selectTab('lobby');
- return;
- }
- var tempInitialize = function () {
- if (!(/^[a-z0-9-]*$/.test('' + data.room))) {
- return; // bogus room ID could be used to inject JavaScript
- }
- addTab(data.room, data.roomType);
- var room = rooms[data.room];
- room.init(data);
- updateMe(data);
- $('#loading-message').remove();
- if (me.loc && me.loc !== 'lobby') {
- selectTab(me.loc);
- }
- };
- if (!me.initialized) {
- me.socketInit = tempInitialize;
- } else {
- tempInitialize();
- }
- },
- update: function (data) {
- if (typeof data.name !== 'undefined') {
- me.name = data.name;
- me.setNamed(data.named);
- me.userid = data.userid;
- me.renamePending = !! data.renamePending;
- }
- if (typeof data.challengesFrom !== 'undefined') {
- me.challengesFrom = data.challengesFrom;
- rooms.lobby.notifying = false;
- for (var i in me.challengesFrom) {
- rooms.lobby.notifying = true;
- break;
- }
- updateRoomList();
- rooms.lobby.updateMainTop();
- }
- if (typeof data.challengeTo !== 'undefined') {
- me.challengeTo = data.challengeTo;
- rooms.lobby.updateMainTop();
- }
- updateMe(data);
- if (data.room && rooms[data.room]) {
- rooms[data.room].update(data);
- } else if (curRoom) {
- //curRoom.update(data);
- }
- },
- disconnect: function () {
- $('#userbar').prepend('disconnect detected ');
- overlay('disconnect');
- },
- nameTaken: function (data) {
- if (data && data.permanent) {
- overlay('message', data.reason);
- } else if (data && data.name) {
- overlay('login', data);
- } else if (data) {
- overlay('rename', {
- error: data.reason
- });
- } else {
- alert('nameTaken signal');
- $('#userbar').prepend('nameTaken signal ');
- }
- },
- message: function (message) {
- if (message.html) {
- overlay('message', message.html);
- return;
- }
- if (message.message) message = message.message;
- overlay('message', '' + message + '
');
- },
- command: function (message) {
- if (message.room && rooms[message.room]) {
- rooms[message.room].command(message);
- }
- },
- console: function (message) {
- var room = null;
- if (message.room && rooms[message.room]) {
- room = rooms[message.room];
- if (room) room.add(message);
- //if (room.id === 'lobby' && message.silent) room.updateMainTop();
- } else {
- if (curRoom) curRoom.message(message, true);
- }
- }
- };
-
- function parseSpecialData(text) {
- var parts = text.split('|');
- if (parts.length < 2) return false;
-
- switch (parts[1]) {
- case 'challenge-string':
- case 'challstr':
- me.challengekeyid = parseInt(parts[2], 10);
- me.challenge = parts[3];
- if (rooms.lobby !== undefined) {
- me.upkeepRename();
- } else {
- me.renameQueued = true;
- }
- return true;
- }
- return false;
- }
-
- if (Config.serverprotocol === 'io') {
- for (var e in events) {
- me.socket.on(e, (function(type) {
- return function(data) {
- events[type](data);
- };
- })(e));
- }
- me.socket.on('data', function(text) {
- var roomid = 'lobby';
- if (text.substr(0,1) === '>') {
- var nlIndex = text.indexOf('\n');
- if (nlIndex < 0) return;
- roomid = text.substr(1,nlIndex-1);
- text = text.substr(nlIndex+1);
- }
- if (!parseSpecialData(text) && (rooms[roomid] !== undefined)) {
- rooms[roomid].add(text);
- }
- });
- document.getElementById('loading-message').innerHTML += ' DONE Connecting to Showdown server...';
- emit(me.socket, 'join', {room: 'lobby'});
- } else {
- var socketopened = false;
- var altport = (Config.serverport === Config.serveraltport);
- var altprefix = false;
- document.getElementById('loading-message').innerHTML += ' DONE Connecting to Showdown server...';
- me.socket.onopen = function() {
- socketopened = true;
- if (altport && window._gaq) {
- _gaq.push(['_trackEvent', 'Alt port connection', Config.serverid]);
- }
- document.getElementById('loading-message').innerHTML += ' DONE Joining Showdown server...';
- emit(me.socket, 'join', {room: 'lobby'});
- };
- me.socket.onmessage = function(msg) {
- if (msg.data.substr(0,1) !== '{') {
- var text = msg.data;
- var roomid = 'lobby';
- if (text.substr(0,1) === '>') {
- var nlIndex = text.indexOf('\n');
- if (nlIndex < 0) return;
- roomid = text.substr(1,nlIndex-1);
- text = text.substr(nlIndex+1);
- }
- if (!parseSpecialData(text) && (rooms[roomid] !== undefined)) {
- rooms[roomid].add(text);
- }
- return;
- }
- var data = $.parseJSON(msg.data);
- if (!data) return;
- if (events[data.type]) events[data.type](data);
- };
- var reconstructSocket = function(socket) {
- var s = constructSocket(Config.server, Config.serverport, Config.sockjsprefix);
- s.onopen = socket.onopen;
- s.onmessage = socket.onmessage;
- s.onclose = socket.onclose;
- return s;
- };
- me.socket.onclose = function () {
- if (!socketopened) {
- if (Config.serveraltport && !altport) {
- altport = true;
- Config.serverport = Config.serveraltport;
- me.socket = reconstructSocket(me.socket);
- return;
- }
- if (!altprefix) {
- altprefix = true;
- Config.sockjsprefix = (Config.sockjsprefix === '/showdown') ? '' : '/showdown';
- me.socket = reconstructSocket(me.socket);
- return;
- }
- }
- $('#userbar').prepend('disconnect detected ');
- overlay('disconnect');
- };
- }
- };
- if (!Config.psim) {
- if (!Config.testclient) {
- $.extend(Config, Config.defaultserver);
- }
- return connect();
- } else if (!window.postMessage) {
- // browser does not support cross-document messaging
- return overlay('unsupported');
- }
- $(window).on('message', (function() {
- var origin = 'http://play.pokemonshowdown.com';
- var callbacks = [];
- var init = window.init;
- window.init = null;
- return function($e) {
- var e = $e.originalEvent;
- if (e.origin !== origin) return;
- var data = $.parseJSON(e.data);
- if (data.config) {
- var postCrossDomainMessage = function(data) {
- return e.source.postMessage($.toJSON(data), origin);
- };
- // server config information
- // `data.config.serverprotocol` is ignored for now
- $.extend(Config, data.config);
- if (Config.registeredserver) {
- var $link = $(' ');
- $('head').append($link);
- }
- // persistent username
- me.setPersistentName = function() {
- postCrossDomainMessage({username: this.name});
- };
- // ajax requests
- $.get = function(uri, callback, type) {
- var idx = callbacks.length;
- callbacks[idx] = callback;
- postCrossDomainMessage({get: [uri, idx, type]});
- };
- $.post = function(uri, data, callback, type) {
- var idx = callbacks.length;
- callbacks[idx] = callback;
- postCrossDomainMessage({post: [uri, data, idx, type]});
- };
- // teams
- if (data.teams) {
- cookieTeams = false;
- teams = $.parseJSON(data.teams);
- }
- Teambuilder.writeTeams = function() {
- postCrossDomainMessage({teams: $.toJSON(teams)});
- };
- // prefs
- if (data.prefs) {
- Tools.prefs.data = $.parseJSON(data.prefs);
- }
- Tools.prefs.save = function() {
- postCrossDomainMessage({prefs: $.toJSON(this.data)});
- };
- // check for third-party cookies being disabled
- if (data.nothirdparty) {
- overlay('nothirdparty');
- }
- // connect
- connect();
- init();
- } else if (data.ajax) {
- var idx = data.ajax[0];
- if (callbacks[idx]) {
- callbacks[idx](data.ajax[1]);
- delete callbacks[idx];
- }
- }
- };
- })());
- var $iframe = $(
- ''
- );
- $('body').append($iframe);
-})();