From d8832dff8f7772bd2221f0cd13c101fe889265ff Mon Sep 17 00:00:00 2001 From: "Cathy J. Fitzpatrick" Date: Fri, 26 Apr 2013 19:10:27 -0600 Subject: [PATCH] Remove sim.js --- js/sim.js | 3852 ----------------------------------------------------- 1 file changed, 3852 deletions(-) delete mode 100644 js/sim.js diff --git a/js/sim.js b/js/sim.js deleted file mode 100644 index a0aa1507a..000000000 --- a/js/sim.js +++ /dev/null @@ -1,3852 +0,0 @@ -// some setting-like stuff -Config.defaultserver = { - server: 'sim.smogon.com', - serverid: 'showdown', - serverport: 8000, - serveraltport: 80, - serverprotocol: 'ws', - registeredserver: true -}; -Config.sockjsprefix = '/showdown'; -Config.locprefix = '/'; - -var me = (function() { - var me = { - name: '', - named: false, - registered: false, - userid: '', - challengekeyid: -1, - challenge: '', - renameQueued: false, - users: {}, - rooms: {}, - ignore: {}, - lastChallengeNotification: '', - pm: {}, - curPopup: '', - popups: [], - socket: null, - socketInit: null, - initialized: false, - loc: 'lobby' - }; - me.getActionPHP = function() { - var ret = '/~~' + Config.serverid + '/action.php'; - if (Config.testclient) { - ret = 'http://play.pokemonshowdown.com' + ret; - } - return (this.getActionPHP = function() { - return ret; - })(); - }; - me.isMuted = function() { - return !!Tools.prefs('mute'); - }; - var finishRename = function(name, assertion) { - if (assertion === ';') { - overlay('login', {name: name}); - } else if (assertion.substr(0, 2) === ';;') { - overlay('rename', {error: assertion.substr(2)}); - } else if (assertion.indexOf('\n') >= 0) { - alert("The login server is overloaded. Please try again later."); - } else { - rooms.lobby.send('/trn '+name+',0,'+assertion); - } - }; - me.rename = function(name) { - if (this.userid !== toUserid(name)) { - var query = me.getActionPHP() + '?act=getassertion&userid=' + - encodeURIComponent(toUserid(name)) + - '&challengekeyid=' + encodeURIComponent(this.challengekeyid) + - '&challenge=' + encodeURIComponent(this.challenge); - if (Config.testclient) { - overlay('testclientproxy', { - name: name, - query: query, - action: 'getassertion' - }); - return; - } - if (name === '') { - return; - } - $.get(query, function(data) { - finishRename(name, data); - }); - } else { - rooms.lobby.send('/trn '+name); - } - }; - me.finishUpkeepRename = Tools.safeJSON(function(data) { - if (!data.username) return; - if (data.loggedin) { - this.registered = { - username: data.username, - userid: toUserid(data.username) - }; - } - finishRename(data.username, data.assertion); - }); - me.upkeepRename = function() { - var query = me.getActionPHP() + '?act=upkeep' + - '&challengekeyid=' + encodeURIComponent(this.challengekeyid) + - '&challenge=' + encodeURIComponent(this.challenge); - if (Config.testclient) { - overlay('testclientproxy', { - query: query, - action: 'upkeep' - }); - return; - } - $.get(query, me.finishUpkeepRename, 'text'); - }; - me.logout = function() { - $.post(me.getActionPHP(), { - act: 'logout', - userid: this.userid // anti-CSRF - }); - rooms.lobby.send('/logout'); - }; - me.setPersistentName = function(name) { - $.cookie('showdown_username', (name !== undefined) ? name : this.name, { - expires: 14 - }); - }; - me.setNamed = function(named) { - this.named = named; - if (!named) { - this.setPersistentName(null); // kill `showdown_username` cookie - } - }; - me.changeState = function() {}; - return me; -})(); -var rooms = {}; -var curRoom = null; -var curTitle = 'Showdown!'; -var battles = {}; -var formats = ['']; -var teams = null; - -var isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1 && navigator.userAgent.toLowerCase().indexOf("firefox") <= -1; - -// -function selectTab(tab, e) { - if (e && e.preventDefault) e.preventDefault(); - if (!tab) tab = 'lobby'; - if (!rooms[tab]) { - joinTab(tab); - return false; - } - if (curRoom && tab !== curRoom.id && curRoom.battle) { - curRoom.battle.pause(); - } - curRoom = rooms[tab]; - $('#main').children().hide(); - $('#leftbar a').removeClass('cur'); - $('#tab-' + tab).show(); - if (!$('#tabtab-' + tab).length) { - updateRoomList(); - } - $('#tabtab-' + tab).addClass('cur'); - if (curRoom && curRoom.battle) { - curRoom.battle.setMute(me.isMuted()); - curRoom.battle.play(); - } - curRoom.focus(); - $(window).scrollTop(51); - if (tab === 'lobby') $('#backbutton').addClass('lobby'); - else $('#backbutton').removeClass('lobby'); - me.changeState(tab); - updateLobbyChat(tab); - return false; -} - -function joinTab(tab) { - if (!tab || tab === 'lobby') return; - if (rooms.lobby) rooms.lobby.send('/join '+tab); -} - -function leaveTab(tab, confirm) { - if (rooms[tab]) { - if (rooms[tab].me.side && rooms[tab].battle && rooms[tab].battle.rated && !rooms[tab].battleEnded && !confirm) { - overlay('forfeit', tab); - return; - } - rooms[tab].send('/leave'); - rooms[tab].dealloc(); - delete rooms[tab]; - } - $('#tab-' + tab).remove(); - if (curRoom.id === tab) { - curRoom = null; - selectTab('lobby'); - } else { - updateRoomList(); - } -} - -function addTab(tab, type) { - if (rooms[tab] && rooms[tab].elem) { - if (tab !== 'lobby') selectTab(tab); - return; - } - var elem; - switch (type) { - case 'lobby': - $('#main').append('
'); - elem = $('#main').children().last(); - rooms[tab] = new Lobby(tab, elem); - break; - case 'teambuilder': - $('#main').append('
'); - elem = $('#main').children().last(); - rooms[tab] = new Teambuilder(tab, elem); - break; - case 'ladder': - $('#main').append('
'); - elem = $('#main').children().last(); - rooms[tab] = new Ladder(tab, elem); - break; - case 'battle': - $('#main').append('
'); - elem = $('#main').children().last(); - rooms[tab] = new BattleRoom(tab, elem); - break; - default: - $('#main').append('
error
'); - var room = { - id: tab, - type: 'error' - }; - room.elem = $('#main').children().last(); - rooms[tab] = room; - break; - } - if (tab === me.loc || (tab !== 'lobby' && tab !== 'teambuilder' && tab !== 'ladder')) { - selectTab(tab); - } else { - rooms[tab].elem.hide(); - } -} - -function emit(socket, type, data) { - if (Config.serverprotocol === 'io') { - socket.emit(type, data); - } else { - if (typeof data === 'object') data.type = type; - else data = {type: type, message: data}; - - if (data.type === 'chat') { - // if (window.console && console.log) console.log('>> '+data.room+'|'+data.message); - socket.send(''+data.room+'|'+data.message); - } else { - socket.send($.toJSON(data)); - } - } -} - -function BattleRoom(id, elem) { - var selfR = this; - this.id = id; - this.elem = elem; - this.meIdent = { - name: me.name, - named: 'init' - }; - this.notifying = false; - me.rooms[id] = {}; - selfR.me = me.rooms[id]; - - elem.html('
Battle is here
Connecting...
'); - - this.battleElem = elem.find('.battle'); - this.controlsElem = elem.find('.replay-controls'); - this.chatFrameElem = elem.find('.battle-log'); - this.chatElem = null; - this.chatAddElem = elem.find('.battle-log-add'); - this.chatboxElem = null; - this.joinElem = null; - this.foeHintElem = elem.find('.foehint'); - - this.battleEnded = false; - - this.dealloc = function () { - if (selfR.battle) selfR.battle.dealloc(); - }; - this.focus = function () { - selfR.updateMe(); - if (selfR.chatElem) selfR.chatFrameElem.scrollTop(selfR.chatElem.height()); - if (selfR.chatboxElem) selfR.chatboxElem.focus(); - }; - this.updateJoinButton = function () { - if (selfR.battle.done) selfR.battleEnded = true; - if (selfR.battleEnded) { - selfR.controlsElem.html('
'); - if (selfR.me.side) { - selfR.controlsElem.html('
'); - } - if (selfR.joinElem) { - selfR.joinElem.remove(); - } - //selfR.battleElem.append('
'); - //selfR.joinElem = selfR.battleElem.children().last(); - } else if (selfR.battle.mySide.initialized && selfR.battle.yourSide.initialized) { - if (selfR.joinElem) { - selfR.joinElem.remove(); - } - selfR.joinElem = null; - } else if (selfR.me.side) { - if (selfR.joinElem) { - selfR.joinElem.remove(); - } - selfR.joinElem = null; - if (selfR.battle.kickingInactive) { - selfR.controlsElem.html('

← Your opponent has disconnected. Click this to delay your victory.

'); - } else { - selfR.controlsElem.html('

← Your opponent has disconnected. Click this if they don\'t reconnect.

'); - } - } else { - if (selfR.joinElem) { - selfR.joinElem.remove(); - } - selfR.battleElem.append('
'); - selfR.joinElem = selfR.battleElem.children().last(); - } - }; - this.init = function (data) { - this.version = (data.version !== undefined) ? data.version : 0; - if (selfR.battle.activityQueue) { - // re-initialize - selfR.battleEnded = false; - selfR.battle = new Battle(selfR.battleElem, selfR.chatFrameElem); - - if (widthClass !== 'tiny-layout') { - selfR.battle.messageSpeed = 80; - } - - selfR.battle.setMute(me.isMuted()); - selfR.battle.customCallback = selfR.callback; - selfR.battle.startCallback = selfR.updateJoinButton; - selfR.battle.stagnateCallback = selfR.updateJoinButton; - selfR.battle.endCallback = selfR.updateJoinButton; - selfR.chatFrameElem.find('.inner').html(''); - selfR.controlsElem.html(''); - } - selfR.battle.play(); - if (data.battlelog) { - for (var i = 0; i < data.battlelog.length; i++) { - selfR.battle.add(data.battlelog[i]); - } - selfR.battle.fastForwardTo(-1); - } - selfR.updateMe(); - if (selfR.chatElem) { - selfR.chatFrameElem.scrollTop(selfR.chatElem.height()); - } - }; - this.rawMessage = function(message) { - this.message({rawMessage: message}); - }; - this.message = function (message, andLobby) { - if (message.pm) { - var pmuserid = (toUserid(message.name) === me.userid ? toUserid(message.pm) : toUserid(message.name)) - if (me.ignore[toUserid(message.name)] && message.name.substr(0, 1) === ' ') return; - selfR.add('|pm|' + message.name.substr(1) + '|' + pmuserid + '|' + message.pm + '|' + message.message); - } else if (message.rawMessage) { - // This is sanitised in battle.js. - selfR.add('|chatmsg-raw|' + message.rawMessage); - } else if (message.evalRulesRedirect || message.evalRawMessage) { - // TODO: This will be removed in due course. - window.location.href = 'http://pokemonshowdown.com/rules'; - } else if (message.name) { - selfR.add('|chat|' + message.name.substr(1) + '|' + message.message); - } else if (message.message) { - selfR.add('|chatmsg|' + message.message); - } else { - selfR.add('|chatmsg|' + message); - } - - if (andLobby && rooms.lobby) { - rooms.lobby.message(message); - } - }; - this.send = function (message) { - emit(me.socket, 'chat', {room:this.id,message:message}); - }; - // Same as send, but appends the rqid to the message so that the server - // can verify that the decision is sent in response to the correct request. - this.sendDecision = function (message) { - this.send(message + '|' + this.me.request.rqid); - }; - this.add = function (log) { - if (typeof log === 'string') log = log.split('\n'); - selfR.update({updates:log}); - }; - this.update = function (update) { - if (update.updates) { - var updated = false; - for (var i = 0; i < update.updates.length; i++) { - if (!updated && (update.updates[i] === '')) { - selfR.me.callbackWaiting = false; - updated = true; - selfR.controlsElem.html(''); - } - if (update.updates[i] === 'RESET') { - selfR.foeHintElem.html(''); - var blog = selfR.chatFrameElem.find('.inner').html(); - delete selfR.me.side; - selfR.battleEnded = false; - selfR.battle = new Battle(selfR.battleElem, selfR.chatFrameElem); - - if (widthClass !== 'tiny-layout') { - selfR.battle.messageSpeed = 80; - } - - selfR.battle.setMute(me.isMuted()); - selfR.battle.customCallback = selfR.callback; - selfR.battle.startCallback = selfR.updateJoinButton; - selfR.battle.stagnateCallback = selfR.updateJoinButton; - selfR.battle.endCallback = selfR.updateJoinButton; - selfR.chatFrameElem.find('.inner').html(blog + '

NEW GAME

'); - selfR.chatFrameElem.scrollTop(selfR.chatFrameElem.find('.inner').height()); - selfR.controlsElem.html(''); - selfR.battle.play(); - selfR.updateJoinButton(); - break; - } - if (update.updates[i].substr(0, 6) === '|chat|' || update.updates[i].substr(0, 9) === '|chatmsg|' || update.updates[i].substr(0, 10) === '|inactive|') { - selfR.battle.instantAdd(update.updates[i]); - } else { - if (update.updates[i].substr(0,10) === '|callback|') selfR.controlsElem.html(''); - if (update.updates[i].substr(0,12) === '| callback | ') selfR.controlsElem.html(''); - selfR.battle.add(update.updates[i], Tools.prefs('noanim')); - } - } - } - if (update.request) { - selfR.me.request = update.request; // currently unused - selfR.me.request.requestType = 'move'; - var notifyObject = null; - if (selfR.me.request.forceSwitch) { - selfR.me.request.requestType = 'switch'; - notifyObject = { - type: 'yourSwitch', - room: selfR.id - }; - } else if (selfR.me.request.teamPreview) { - selfR.me.request.requestType = 'team'; - notifyObject = { - type: 'yourSwitch', - room: selfR.id - }; - } else if (selfR.me.request.wait) { - selfR.me.request.requestType = 'wait'; - } else { - notifyObject = { - type: 'yourMove', - room: selfR.id - }; - } - if (notifyObject) { - var doNotify = function() { - notify(notifyObject); - selfR.notifying = true; - updateRoomList(); - }; - if (selfR.battle.yourSide.initialized) { - // The opponent's name is already known. - notifyObject.user = selfR.battle.yourSide.name; - doNotify(); - } else { - // The opponent's name isn't known yet, so wait until it is - // known before sending the notification, so that it can include - // the opponent's name. - var callback = selfR.battle.stagnateCallback; - selfR.battle.stagnateCallback = function(battle) { - notifyObject.user = battle.yourSide.name; - doNotify(); - battle.stagnateCallback = callback; - if (callback) callback(battle); - }; - } - } - //if (selfR.me.callbackWaiting) selfR.callback(); - } - if (typeof update.active !== 'undefined') { - if (!update.active && selfR.me.side) { - selfR.controlsElem.html('
'); - } - } - if (update.side) { - if (update.side === 'none') { - $('#controls').html(''); - delete selfR.me.side; - } else { - selfR.me.side = update.side; - } - } - if (update.sideData) { - selfR.updateSide(update.sideData, update.midBattle); - } - selfR.updateMe(); - }; - this.updateSide = function(sideData, midBattle) { - var sidesSwitched = false; - selfR.me.sideData = sideData; // just for easy debugging - if (selfR.battle.sidesSwitched !== !!(selfR.me.side === 'p2')) { - sidesSwitched = true; - selfR.battle.reset(); - selfR.battle.switchSides(); - } - for (var i = 0; i < sideData.pokemon.length; i++) { - var pokemonData = sideData.pokemon[i]; - var pokemon; - if (i == 0) { - pokemon = selfR.battle.getPokemon(''+pokemonData.ident, pokemonData.details); - pokemon.slot = 0; - pokemon.side.pokemon = [pokemon]; - // if (pokemon.side.active[0] && pokemon.side.active[0].ident == pokemon.ident) pokemon.side.active[0] = pokemon; - } else if (i < selfR.battle.mySide.active.length) { - pokemon = selfR.battle.getPokemon('new: '+pokemonData.ident, pokemonData.details); - pokemon.slot = i; - // if (pokemon.side.active[i] && pokemon.side.active[i].ident == pokemon.ident) pokemon.side.active[i] = pokemon; - if (pokemon.side.active[i] && pokemon.side.active[i].ident == pokemon.ident) { - pokemon.side.active[i].item = pokemon.item; - pokemon.side.active[i].ability = pokemon.ability; - pokemon.side.active[i].baseAbility = pokemon.baseAbility; - } - } else { - pokemon = selfR.battle.getPokemon('new: '+pokemonData.ident, pokemonData.details); - } - pokemon.healthParse(pokemonData.condition); - if (pokemonData.baseAbility) { - pokemon.baseAbility = pokemonData.baseAbility; - if (!pokemon.ability) pokemon.ability = pokemon.baseAbility; - } - pokemon.item = pokemonData.item; - pokemon.moves = pokemonData.moves; - } - selfR.battle.mySide.updateSidebar(); - if (sidesSwitched) { - if (midBattle) { - selfR.battle.fastForwardTo(-1); - } else { - selfR.battle.play(); - } - } - }; - 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(rooms['lobby'].formKeyDown); - selfR.chatboxElem.autoResize({ - animateDuration: 100, - extraSpace: 0 - }); - selfR.chatboxElem.focus(); - } else { - selfR.chatAddElem.html('
'); - } - - selfR.meIdent.name = me.name; - selfR.meIdent.named = me.named; - } - var inner = selfR.chatFrameElem.find('.inner'); - if (inner.length) selfR.chatElem = inner; - else selfR.chatElem = null; - selfR.updateJoinButton(); - }; - this.callback = function (battle, type, moveTarget) { - if (!battle) battle = selfR.battle; - selfR.notifying = false; - if (type === 'restart') { - selfR.me.callbackWaiting = false; - selfR.battleEnded = true; - updateRoomList(); - return; - } else if (type === 'trapped') { - var idx = parseInt(moveTarget[1], 10); // moveTarget is a poor name now... - if (selfR.me.request && selfR.me.request.active && - selfR.me.request.active[idx]) { - // This pokemon is now known to be trapped. - selfR.me.request.active[idx].trapped = true; - // TODO: Maybe a more sophisticated UI for this. - // In singles, this isn't really necessary because the switch UI will be - // immediately disabled. However, in doubles it might not be obvious why - // the player is being asked to make a new decision without this message. - selfR.battle.add(selfR.battle.mySide.active[idx].getName() + ' is trapped!'); - } - } - - var myActive = selfR.battle.mySide.active; - var yourActive = selfR.battle.yourSide.active; - var text = ''; - if (yourActive[1]) { - text += '
'; - } - if (yourActive[0]) { - text += '
'; - } - if (myActive[0]) { - text += '
'; - } - if (myActive[1]) { - text += '
'; - } - selfR.foeHintElem.html(text); - - if (!selfR.me.request) { - selfR.controlsElem.html('
Waiting for players...
'); - selfR.updateJoinButton(); - updateRoomList(); - return; - } - if (selfR.me.request.side) { - selfR.updateSide(selfR.me.request.side, true); - } - selfR.me.callbackWaiting = true; - var active = selfR.battle.mySide.active[0]; - if (!active) active = {}; - if (selfR.battle.kickingInactive) { - selfR.controlsElem.html('
Waiting for opponent...
'); - } else { - selfR.controlsElem.html('
Waiting for opponent...
'); - } - var act = ''; - var switchables = []; - - if (selfR.me.request) { - act = selfR.me.request.requestType; - if (selfR.me.request.side) { - switchables = selfR.battle.mySide.pokemon; - } - } - switch (act) { - case 'move': - { - if (type !== 'move2' && type !== 'movetarget') { - selfR.choices = []; - selfR.choiceSwitchFlags = {}; - while (switchables[selfR.choices.length] && switchables[selfR.choices.length].fainted) selfR.choices.push('pass'); - } - var pos = selfR.choices.length - (type === 'movetarget'?1:0); - var hpbar = ''; - { - if (switchables[pos].hp * 5 / switchables[pos].maxhp < 1) { - hpbar = ''; - } else if (switchables[pos].hp * 2 / switchables[pos].maxhp < 1) { - hpbar = ''; - } else { - hpbar = ''; - } - hpbar += ''+switchables[pos].hp+'/'+switchables[pos].maxhp+''; - } - var active = selfR.me.request; - if (active.active) active = active.active[pos]; - var moves = active.moves; - var trapped = active.trapped; - selfR.me.finalDecision = active.maybeTrapped || false; - if (selfR.me.finalDecision) { - for (var i = pos + 1; i < selfR.battle.mySide.active.length; ++i) { - var p = selfR.battle.mySide.active[i]; - if (p && !p.fainted) { - selfR.me.finalDecision = false; - } - } - } - - var controls = '
'; - if (type === 'move2' || type === 'movetarget') { - controls += ' '; - } - - // Target selector - - if (type === 'movetarget') { - controls += 'At who? '+hpbar+'
'; - controls += '
'; - - var myActive = selfR.battle.mySide.active; - var yourActive = selfR.battle.yourSide.active; - var yourSlot = yourActive.length-1-pos; - for (var i = yourActive.length-1; i >= 0; i--) { - var pokemon = yourActive[i]; - - var disabled = false; - if (moveTarget === 'adjacentAlly' || moveTarget === 'adjacentAllyOrSelf') { - disabled = true; - } else if (moveTarget === 'normal' || moveTarget === 'adjacentFoe') { - if (Math.abs(yourSlot-i) > 1) disabled = true; - } - - if (!pokemon) { - controls += ' '; - } else if (disabled || pokemon.zerohp) { - controls += ' '; - } else { - controls += ' '; - } - } - controls += '
'; - for (var i = 0; i < myActive.length; i++) { - var pokemon = myActive[i]; - - var disabled = false; - if (moveTarget === 'adjacentFoe') { - disabled = true; - } else if (moveTarget === 'normal' || moveTarget === 'adjacentAlly' || moveTarget === 'adjacentAllyOrSelf') { - if (Math.abs(pos-i) > 1) disabled = true; - } - if (moveTarget !== 'adjacentAllyOrSelf' && pos == i) disabled = true; - - if (!pokemon) { - controls += ' '; - } else if (disabled || pokemon.zerohp) { - controls += ' '; - } else { - controls += ' '; - } - } - controls += '
'; - controls += '
'; - selfR.controlsElem.html(controls); - break; - } - - // Move chooser - - controls += 'What will ' + Tools.escapeHTML(switchables[pos].name) + ' do? '+hpbar+''; - var hasMoves = false; - var hasDisabled = false; - controls += '
'; - var movebuttons = ''; - for (var i = 0; i < moves.length; i++) { - var moveData = moves[i]; - var move = Tools.getMove(moves[i].move); - if (!move) { - move = { - name: moves[i].move, - id: moves[i].move, - type: '' - }; - } - var name = move.name; - var pp = moveData.pp + '/' + moveData.maxpp; - if (!moveData.maxpp) pp = '–'; - if (move.id === 'Struggle' || move.id === 'Recharge') pp = '–'; - if (move.id === 'Recharge') move.type = '–'; - if (name.substr(0, 12) === 'Hidden Power') name = 'Hidden Power'; - if (moveData.disabled) { - movebuttons += ' '; - } - if (!hasMoves) { - controls += ' '; - } else { - controls += movebuttons; - } - controls += '
'; - if (hasDisabled) { - // controls += '(grayed out moves have been disabled by Disable, Encore, or something like that)'; - } - controls += '
'; - if (trapped) { - controls += 'You are trapped and cannot switch!'; - } else { - controls += ''; - if (selfR.me.finalDecision) { - controls += 'You might be trapped, so you won\'t be able to cancel a switch!
'; - } - for (var i = 0; i < switchables.length; i++) { - var pokemon = switchables[i]; - pokemon.name = pokemon.ident.substr(4); - if (pokemon.zerohp || i < selfR.battle.mySide.active.length || selfR.choiceSwitchFlags[i]) { - controls += ' '; - } else { - controls += ' '; - } - } - if (selfR.battle.mySide.pokemon.length > 6) { - //controls += 'Pokeball data corrupt. Please copy the text from this button: and tell aesoft.'; - } - } - controls += '
'; - selfR.controlsElem.html(controls); - } - selfR.notifying = true; - break; - case 'switch': - selfR.me.finalDecision = false; - if (type !== 'switch2') { - selfR.choices = []; - selfR.choiceSwitchFlags = {}; - if (selfR.me.request.forceSwitch !== true) { - while (!selfR.me.request.forceSwitch[selfR.choices.length] && selfR.choices.length < 6) selfR.choices.push('pass'); - } - } - var pos = selfR.choices.length; - var controls = '
'; - if (type === 'switch2') { - controls += ' '; - } - controls += 'Switch '+Tools.escapeHTML(switchables[pos].name)+' to:
'; - controls += '
'; - for (var i = 0; i < switchables.length; i++) { - var pokemon = switchables[i]; - if (i >= 6) { - //controls += 'Pokeball data corrupt. Please copy the text from this button: and tell aesoft.'; - break; - } - if (pokemon.zerohp || i < selfR.battle.mySide.active.length || selfR.choiceSwitchFlags[i]) { - controls += ' '; - } else { - controls += ' '; - } - } - controls += '
'; - selfR.controlsElem.html(controls); - selfR.formSelectSwitch(); - selfR.notifying = true; - break; - case 'team': - var controls = '
'; - if (type !== 'team2') { - selfR.teamPreviewChoice = [1,2,3,4,5,6].slice(0,switchables.length); - selfR.teamPreviewDone = 0; - selfR.teamPreviewCount = 0; - if (selfR.battle.gameType === 'doubles') { - selfR.teamPreviewCount = 2; - } - controls += 'How will you start the battle?
'; - controls += '
'; - for (var i = 0; i < switchables.length; i++) { - var pokemon = switchables[i]; - if (i >= 6) { - break; - } - if (toId(pokemon.baseAbility) === 'illusion') { - selfR.teamPreviewCount = 6; - } - controls += ' '; - } - if (selfR.battle.teamPreviewCount) selfR.teamPreviewCount = parseInt(selfR.battle.teamPreviewCount,10); - controls += '
'; - } else { - controls += ' What about the rest of your team?
'; - controls += '
'; - for (var i = 0; i < switchables.length; i++) { - var pokemon = switchables[selfR.teamPreviewChoice[i]-1]; - if (i >= 6) { - break; - } - if (i < selfR.teamPreviewDone) { - controls += ' '; - } else { - controls += ' '; - } - } - controls += '
'; - } - controls += '
'; - selfR.controlsElem.html(controls); - selfR.formSelectSwitch(); - selfR.notifying = true; - break; - } - updateRoomList(); - }; - this.formJoinBattle = function () { - selfR.send('/joinbattle'); - return false; - }; - this.formKickInactive = function () { - selfR.send('/kickinactive'); - return false; - }; - this.formStopBattleTimer = function () { - selfR.send('/timer off'); - return false; - }; - this.formForfeit = function () { - selfR.send('/forfeit'); - return false; - }; - this.formSaveReplay = function () { - selfR.send('/savereplay'); - return false; - }; - this.formRestart = function () { - /* hideTooltip(); - selfR.send('/restart'); */ - selfR.me.request = null; - selfR.battle.reset(); - selfR.battle.play(); - return false; - }; - this.formUseMove = function (move, target) { - var myActive = selfR.battle.mySide.active; - hideTooltip(); - if (move !== undefined) { - var choosableTargets = {normal:1, any:1, adjacentAlly:1, adjacentAllyOrSelf:1, adjacentFoe:1}; - selfR.choices.push('move '+move); - if (myActive.length > 1 && target in choosableTargets) { - selfR.callback(selfR.battle, 'movetarget', target); - return false; - } - } - while (myActive.length > selfR.choices.length && !myActive[selfR.choices.length]) { - selfR.choices.push('pass'); - } - if (myActive.length > selfR.choices.length) { - selfR.callback(selfR.battle, 'move2'); - return false; - } - selfR.me.finalDecision = false; - if (selfR.battle.kickingInactive) { - selfR.controlsElem.html('
Waiting for opponent... ' + (selfR.me.finalDecision ? '' : '') + '

'); - } else { - selfR.controlsElem.html('
Waiting for opponent... ' + (selfR.me.finalDecision ? '' : '') + '

'); - } - selfR.sendDecision('/choose '+selfR.choices.join(',')); - selfR.notifying = false; - updateRoomList(); - return false; - }; - this.formSelectTarget = function (pos, isMySide) { - var posString; - if (isMySide) { - posString = ''+(-(pos+1)); - } else { - posString = ''+(pos+1); - } - selfR.choices[selfR.choices.length-1] += ' '+posString; - selfR.formUseMove(); - return false; - }; - this.formSwitchTo = function (pos) { - hideTooltip(); - selfR.choices.push('switch '+(parseInt(pos,10)+1)); - selfR.choiceSwitchFlags[pos] = true; - if (selfR.me.request && selfR.me.request.requestType === 'move' && selfR.battle.mySide.active.length > selfR.choices.length) { - selfR.callback(selfR.battle, 'move2'); - return false; - } - if (selfR.me.request && selfR.me.request.requestType === 'switch') { - if (selfR.me.request.forceSwitch !== true) { - while (selfR.battle.mySide.active.length > selfR.choices.length && !selfR.me.request.forceSwitch[selfR.choices.length]) selfR.choices.push('pass'); - } - if (selfR.battle.mySide.active.length > selfR.choices.length) { - selfR.callback(selfR.battle, 'switch2'); - return false; - } - } - if (selfR.battle.kickingInactive) { - selfR.controlsElem.html('
Waiting for opponent... ' + (selfR.me.finalDecision ? '' : '') + '

'); - } else { - selfR.controlsElem.html('
Waiting for opponent... ' + (selfR.me.finalDecision ? '' : '') + '

'); - } - selfR.sendDecision('/choose '+selfR.choices.join(',')); - selfR.notifying = false; - updateRoomList(); - return false; - }; - this.formTeamPreviewSelect = function (pos) { - pos = parseInt(pos,10); - hideTooltip(); - if (selfR.teamPreviewCount) { - var temp = selfR.teamPreviewChoice[pos]; - selfR.teamPreviewChoice[pos] = selfR.teamPreviewChoice[selfR.teamPreviewDone]; - selfR.teamPreviewChoice[selfR.teamPreviewDone] = temp; - - selfR.teamPreviewDone++; - - if (selfR.teamPreviewDone < Math.min(selfR.teamPreviewChoice.length, selfR.teamPreviewCount)) { - selfR.callback(selfR.battle, 'team2'); - return false; - } - pos = selfR.teamPreviewChoice.join(''); - } else { - pos = pos+1; - } - if (selfR.battle.kickingInactive) { - selfR.controlsElem.html('
Waiting for opponent... ' + (selfR.me.finalDecision ? '' : '') + '

'); - } else { - selfR.controlsElem.html('
Waiting for opponent... ' + (selfR.me.finalDecision ? '' : '') + '

'); - } - selfR.sendDecision('/team '+(pos)); - selfR.notifying = false; - updateRoomList(); - return false; - }; - this.formUndoDecision = function (pos) { - selfR.send('/undo'); - selfR.notifying = true; - selfR.callback(selfR.battle, 'decision'); - return false; - }; - // Key press in the battle chat textbox. - this.formKeyPress = function (e) { - hideTooltip(); - if (e.keyCode === 13) { - if (selfR.chatboxElem.val()) { - var text = selfR.chatboxElem.val(); - rooms.lobby.tabComplete.reset(); - rooms.lobby.chatHistory.push(text); - text = rooms.lobby.parseCommand(text); - if (text) { - selfR.send(text); - } - selfR.chatboxElem.val(''); - } - return false; - } - return true; - }; - this.formRename = function () { - overlay('rename'); - return false; - }; - this.formLeaveBattle = function () { - hideTooltip(); - selfR.send('/leavebattle'); - selfR.notifying = false; - updateRoomList(); - return false; - }; - this.formSelectSwitch = function () { - hideTooltip(); - selfR.controlsElem.find('.controls').attr('class', 'controls switch-controls'); - return false; - }; - this.formSelectMove = function () { - hideTooltip(); - selfR.controlsElem.find('.controls').attr('class', 'controls move-controls'); - return false; - }; - - this.battle = new Battle(this.battleElem, this.chatFrameElem); - - if (widthClass !== 'tiny-layout') { - this.battle.messageSpeed = 80; - } - - this.battle.setMute(me.isMuted()); - this.battle.customCallback = this.callback; - this.battle.endCallback = this.endCallback; - this.battle.startCallback = this.updateMe; - this.battle.stagnateCallback = this.updateMe; -} -var lobbyChatElem = null; - -function updateLobbyChat(tab) { - if (!tab && curRoom) tab = curRoom.id; - if (tab === 'lobby') { - $('#lobbychat').prop('class', 'lobbychat mainlobbychat'); - $('#lobbychat').show(); - if (rooms.lobby && rooms.lobby.chatElem) rooms.lobby.chatFrameElem.scrollTop(rooms.lobby.chatElem.height()); - if (rooms.lobby && rooms.lobby.chatboxElem) rooms.lobby.chatboxElem.focus(); - } else if (tab === 'teambuilder' || tab === 'ladder') { - $('#lobbychat').prop('class', 'lobbychat sidelobbychat'); - $('#lobbychat').show(); - if (rooms.lobby && rooms.lobby.chatElem) rooms.lobby.chatFrameElem.scrollTop(rooms.lobby.chatElem.height()); - if (rooms.lobby && rooms.lobby.chatboxElem) rooms.lobby.chatboxElem.focus(); - } else if (widthClass === 'huge-layout') { - $('#lobbychat').prop('class', 'lobbychat secondarylobbychat'); - $('#lobbychat').show(); - } else $('#lobbychat').hide(); -} - -function Lobby(id, elem) { - var selfR = this; - this.id = id; - this.elem = elem; - this.meIdent = { - name: me.name, - named: 'init' - }; - me.rooms[id] = {}; - this.me = me.rooms[id]; - this.joinLeave = { - 'join': [], - 'leave': [] - }; - this.joinLeaveElem = null; - this.userCount = {}; - this.userList = {}; - this.userActivity = []; - this.tabComplete = { - candidates: null, - index: 0, - prefix: null, - cursor: -1, - reset: function() { - this.cursor = -1; - } - }; - this.chatHistory = (function() { - var self = { - lines: [], - index: 0, - push: function(line) { - if (self.lines.length > 100) { - self.lines.splice(0, 20); - } - self.lines.push(line); - self.index = self.lines.length; - } - }; - return self; - })(); - this.highlightRegExp = null; - this.searcher = null; - this.selectedTeam = 0; - this.selectedFormat = ''; - - elem.html('
'); - $('#lobbychat').html('
Connecting...
'); - - this.mainElem = elem.find('.mainsection'); - this.mainTopElem = elem.find('.maintop'); - this.mainBottomElem = elem.find('.mainbottom'); - this.popupElem = elem.find('.mainpopup'); - this.chatFrameElem = $('#lobbychat').find('.battle-log'); - this.chatElem = $('#lobbychat').find('.battle-log .inner'); - this.chatAddElem = $('#lobbychat').find('.battle-log-add'); - this.chatboxElem = null; - - this.dealloc = function () {}; - this.focus = function () { - selfR.updateMe(); - selfR.updateMainTop(true); - selfR.chatFrameElem.scrollTop(selfR.chatElem.height()); - if (selfR.chatboxElem) selfR.chatboxElem.focus(); - }; - this.rawMessage = function(message) { - this.message({rawMessage: message}); - }; - this.message = function (message) { - if (typeof message !== 'string') { - selfR.add([message]); - } else { - selfR.add([{ - message: message - }]); - } - }; - this.send = function (message) { - emit(me.socket, 'chat', {room:'',message:message}); - }; - this.clear = function () { - selfR.chatElem.html(''); - }; - this.popupClose = function (i) { - if (!me.popups.length) return; - if (typeof i === 'undefined') i = me.popups.length - 1; - me.popups.splice(i, 1); - selfR.updatePopup(); - selfR.popupChatboxElem.val(''); - if (selfR.chatboxElem) { - selfR.chatboxElem.focus(); - } - }; - this.popupKeyUp = function (e) { - if (e.keyCode === 27) { - selfR.popupClose(); - return false; - } - }; - this.popupKeyPress = function (e) { - hideTooltip(); - if (e.keyCode === 13) { - var text; - if ((text = selfR.popupChatboxElem.val())) { - selfR.tabComplete.reset(); - selfR.chatHistory.push(text); - text = selfR.parseCommand(text); - if (text) { - var splitText = text.split('\n'); - for (var i=0, len=splitText.length; i 0) { - cmd = text.substr(1, spaceIndex-1); - target = text.substr(spaceIndex+1); - } else { - cmd = text.substr(1); - target = ''; - } - } - - switch (cmd.toLowerCase()) { - case 'challenge': - case 'user': - case 'open': - if (!target) target = prompt('Who?'); - if (target) rooms.lobby.formChallenge(target); - return false; - - case 'ignore': - if (me.ignore[toUserid(target)]) { - this.message('User ' + target + ' is already on your ignore list. (Moderator messages will not be ignored.)'); - } else { - me.ignore[toUserid(target)] = 1; - this.message('User ' + target + ' ignored. (Moderator messages will not be ignored.)'); - } - return false; - - case 'unignore': - if (!me.ignore[toUserid(target)]) { - this.message('User ' + target + ' isn\'t on your ignore list.'); - } else { - delete me.ignore[toUserid(target)]; - this.message('User ' + target + ' no longer ignored.'); - } - return false; - - case 'clear': - if (this.clear) this.clear(); - return false; - - case 'nick': - if (target) { - me.rename(target); - } else { - rooms.lobby.formRename(); - } - return false; - - case 'showjoins': - rooms.lobby.add('Join/leave messages: ON'); - Tools.prefs('showjoins', true); - return false; - case 'hidejoins': - rooms.lobby.add('Join/leave messages: HIDDEN'); - Tools.prefs('showjoins', false); - return false; - - case 'showbattles': - rooms.lobby.add('Battle messages: ON'); - Tools.prefs('showbattles', true); - return false; - case 'hidebattles': - rooms.lobby.add('Battle messages: HIDDEN'); - Tools.prefs('showbattles', false); - return false; - - case 'timestamps': - var targets = target.split(','); - if ((['all', 'lobby', 'pms'].indexOf(targets[0]) === -1) - || (targets.length < 2) - || (['off', 'minutes', 'seconds'].indexOf( - targets[1] = targets[1].trim()) === -1)) { - rooms.lobby.add('Error: Invalid /timestamps command'); - return '/help timestamps'; // show help - } - var timestamps = Tools.prefs('timestamps') || {}; - if (typeof timestamps === 'string') { - // The previous has a timestamps preference from the previous - // regime. We can't set properties of a string, so set it to - // an empty object. - timestamps = {}; - } - switch (targets[0]) { - case 'all': - timestamps.lobby = targets[1]; - timestamps.pms = targets[1]; - break; - case 'lobby': - timestamps.lobby = targets[1]; - break; - case 'pms': - timestamps.pms = targets[1]; - break; - } - rooms.lobby.add('Timestamps preference set to: `' + targets[1] + '` for `' + targets[0] + '`.'); - Tools.prefs('timestamps', timestamps); - return false; - - case 'highlight': - var highlights = Tools.prefs('highlights') || []; - if (target.indexOf(',') > -1) { - var targets = target.split(','); - // trim the targets to be safe - for (var i=0, len=targets.length; i 0) { - var hls = highlights.join(', '); - rooms.lobby.add('Current highlight list: ' + hls); - } else { - rooms.lobby.add('Your highlight list is empty.'); - } - } else { - // Wrong command - rooms.lobby.add('Error: Invalid /highlight command.'); - return '/help highlight'; // show help - } - } - return false; - - case 'rank': - case 'ranking': - case 'rating': - case 'ladder': - if (!target) target = me.userid; - var self = this; - $.get(me.getActionPHP() + '?act=ladderget&user='+encodeURIComponent(target), Tools.safeJSON(function(data) { - try { - var buffer = '
'; - buffer += ''; - if (!data.length) { - buffer += ''; - } else { - buffer += ''; - for (var i=0; i'; - } - } - buffer += '
User: '+target+'
This user has not played any ladder games yet.
FormatACREGXEGlicko2WLT
'+Math.round(row.acre)+''+Math.round(row.gxe,1)+''; - if (row.rprd > 50) { - buffer += ''+Math.round(row.rpr)+' ± '+Math.round(row.rprd)+' (provisional)'; - } else { - buffer += ''+Math.round(row.rpr)+' ± '+Math.round(row.rprd)+''; - } - buffer += ''+row.w+''+row.l+''+row.t+'
'; - self.rawMessage(buffer); - } catch(e) { - } - }), 'text'); - return false; - - case 'buttonban': - var reason = prompt('Why do you wish to ban this user?'); - if (reason === null) return false; - if (reason === false) reason = ''; - rooms.lobby.send('/ban ' + target + ', ' + reason); - return false; - - case 'buttonmute': - var reason = prompt('Why do you wish to mute this user?'); - if (reason === null) return false; - if (reason === false) reason = ''; - rooms.lobby.send('/mute ' + target + ', ' + reason); - return false; - - case 'buttonunmute': - rooms.lobby.send('/unmute ' + target); - return false; - - case 'buttonkick': - var reason = prompt('Why do you wish to kick this user?'); - if (reason === null) return false; - if (reason === false) reason = ''; - rooms.lobby.send('/kick ' + target + ', ' + reason); - return false; - - case 'avatar': - var parts = target.split(','); - var avatar = parseInt(parts[0], 10); - if (avatar) { - Tools.prefs('avatar', avatar); - } - return text; // Send the /avatar command through to the server. - - } - - return text; - }; - this.popupOpen = function (userid) { - userid = toUserid(userid); - for (var i = 0; i < me.popups.length; i++) { - if (me.popups[i] === userid) return selfR.popupFocus(i); - } - me.popups.push(userid); - selfR.updatePopup(); - selfR.popupChatboxElem.focus(); - }; - this.popupFocus = function (i) { - if (!me.popups.length) return; - if (i == me.popups.length - 1) return; - me.popups = me.popups.concat(me.popups.splice(i, 1)); - selfR.updatePopup(); - selfR.popupChatboxElem.focus(); - }; - this.updatePopup = function (data) { - if (selfR.popupState && !me.popups.length) { - selfR.popupElem.html(''); - selfR.popupElem.hide(); - selfR.popupState = ''; - } else if (selfR.popupState !== 'pm-' + me.popups.join(',')) { - var code = '
'; - var popupListCode = ''; - var name; - for (var i = 0; i < me.popups.length - 1; i++) { - name = Tools.escapeHTML(me.users[me.popups[i]] || me.popups[i]); - popupListCode += '

' + name + '

'; - } - if (me.curPopup === me.popups[i]) { - $('#' + selfR.id + '-pmlog-list').html(popupListCode); - } - me.curPopup = me.popups[i]; - code += popupListCode; - code += '
'; - var clickableName = '' + Tools.escapeHTML(me.users[me.curPopup] || me.curPopup) + ''; - code += '

' + clickableName + '

'; - code += '
' + (me.pm[me.curPopup] || '') + '
'; - if (!selfR.popupElem.children('.battle-log-add').length) { - code += '
'; - selfR.popupElem.html(code); - } else { - selfR.popupElem.contents().not('.battle-log-add').remove(); - selfR.popupElem.prepend(code); - } - selfR.popupChatboxElem = selfR.popupElem.find('textarea').last(); - selfR.popupChatboxElem.keydown(rooms['lobby'].formKeyDown); - selfR.popupElem.show(); - $('#' + selfR.id + '-pmlog-frame').scrollTop($('#' + selfR.id + '-pmlog').height()); - selfR.popupChatboxElem.autoResize({ - animateDuration: 100, - extraSpace: 0 - }); - selfR.popupState = 'pm-' + me.popups.join(','); - } else if (me.popups.length) { - if ($('#' + selfR.id + '-pmlog-frame').scrollTop() + 60 >= $('#' + selfR.id + '-pmlog').height() - $('#' + selfR.id + '-pmlog-frame').height()) { - autoscroll = true; - } - $('#' + selfR.id + '-pmlog').append(data); - if (autoscroll) { - $('#' + selfR.id + '-pmlog-frame').scrollTop($('#' + selfR.id + '-pmlog').height()); - } - } - }; - // Mark a user as active for the purpose of tab complete. - this.markUserActive = function (userid) { - var idx = selfR.userActivity.indexOf(userid); - if (idx !== -1) { - selfR.userActivity.splice(idx, 1); - } - selfR.userActivity.push(userid); - if (selfR.userActivity.length > 100) { - // Prune the list. - selfR.userActivity.splice(0, 20); - } - }; - this.getTimestamp = function (section) { - var pref = Tools.prefs('timestamps') || {}; - var sectionPref = ((section === 'pms') ? pref.pms : pref.lobby) || 'off'; - if ((sectionPref === 'off') || (sectionPref === undefined)) return ''; - var date = new Date(); - var components = [ date.getHours(), date.getMinutes() ]; - if (sectionPref === 'seconds') { - components.push(date.getSeconds()); - } - return '[' + components.map( - function(x) { return (x < 10) ? '0' + x : x; } - ).join(':') + '] '; - }; - this.getHighlight = function (message) { - var highlights = Tools.prefs('highlights') || []; - if (!this.highlightRegExp) { - try { - this.highlightRegExp = new RegExp('\\b('+highlights.join('|')+')\\b', 'i'); - } catch (e) { - // If the expression above is not a regexp, we'll get here. - // Don't throw an exception because that would prevent the chat - // message from showing up, or, when the lobby is initialising, - // it will prevent the initialisation from completing. - return false; - } - } - return ((highlights.length > 0) && this.highlightRegExp.test(message)); - }; - this.add = function (log) { - if (typeof log === 'string') log = log.split('\n'); - var autoscroll = false; - if (selfR.chatFrameElem.scrollTop() + 60 >= selfR.chatElem.height() - selfR.chatFrameElem.height()) { - autoscroll = true; - } - selfR.lastUpdate = log; - for (var i = 0; i < log.length; i++) { - if (typeof log[i] === 'string') { - if (log[i].substr(0,1) !== '|') log[i] = '||'+log[i]; - var row = log[i].substr(1).split('|'); - switch (row[0]) { - case 'c': - case 'chat': - log[i] = { - name: row[1], - message: row.slice(2).join('|') - }; - break; - case 'b': - case 'B': - log[i] = { - action: 'battle', - room: row[1], - name: row[2], - name2: row[3], - silent: (row[0] === 'B') - }; - break; - case 'j': - case 'J': - log[i] = { - action: 'join', - name: row[1], - silent: (row[0] === 'J') - }; - break; - case 'l': - case 'L': - log[i] = { - action: 'leave', - name: row[1], - silent: (row[0] === 'L') - }; - break; - case 'n': - case 'N': - log[i] = { - action: 'rename', - name: row[1], - oldid: row[2], - silent: true - }; - break; - case 'raw': - log[i] = { - rawMessage: row.slice(1).join('|') - }; - break; - case 'refresh': - // refresh the page - document.location.reload(true); - break; - case 'formats': - var isSection = false; - var section = ''; - BattleFormats = {}; - for (var j=1; j' + Tools.escapeHTML(log[i].name.substr(1)) + ''; - var message = log[i].message; - var isHighlighted = selfR.getHighlight(message); - if (isHighlighted) { - notify({ - type: 'highlight', - user: log[i].name - }); - } - var highlight = isHighlighted ? ' style="background-color:#FDA;"' : ''; - var chatDiv = '
'; - 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 + '• ' + clickableName + ' ' + messageSanitize(message.substr(4)) + ''); - } else if (message.substr(0,5).toLowerCase() === '/mee ') { - selfR.chatElem.append(chatDiv + timestamp + '• ' + clickableName + '' + messageSanitize(message.substr(5)) + ''); - } else if (message.substr(0,10).toLowerCase() === '/announce ') { - selfR.chatElem.append(chatDiv + timestamp + '' + clickableName + ': ' + messageSanitize(message.substr(10)) + ''); - } else if (message.substr(0,6).toLowerCase() === '/warn ') { - overlay('rules', {warning: message.substr(6)}); - } else if (message.substr(0,14).toLowerCase() === '/data-pokemon ') { - selfR.chatElem.append('
    '+Chart.pokemonRow(Tools.getTemplate(message.substr(14)),'',{})+'
'); - } else if (message.substr(0,11).toLowerCase() === '/data-item ') { - selfR.chatElem.append('
    '+Chart.itemRow(Tools.getItem(message.substr(11)),'',{})+'
'); - } else if (message.substr(0,14).toLowerCase() === '/data-ability ') { - selfR.chatElem.append('
    '+Chart.abilityRow(Tools.getAbility(message.substr(14)),'',{})+'
'); - } else if (message.substr(0,11).toLowerCase() === '/data-move ') { - selfR.chatElem.append('
    '+Chart.moveRow(Tools.getMove(message.substr(11)),'',{})+'
'); - } else { - // Normal chat message. - selfR.chatElem.append(chatDiv + timestamp + '' + clickableName + ': ' + messageSanitize(message) + ''); - } - } else if (log[i].name && log[i].action === 'battle') { - var id = log[i].room; - var matches = selfR.parseBattleID(id); - if (!matches) { - continue; // bogus room ID could be used to inject JavaScript - } - var format = (matches ? matches[1] : ''); - selfR.rooms.push({ - id: id, - format: format, - p1: log[i].name, - p2: log[i].name2 - }); - if (selfR.rooms.length > 6) selfR.rooms.shift(); - - selfR.debounceUpdate(); - - if (log[i].silent && !Tools.prefs('showbattles')) continue; - - selfR.joinLeaveElem = null; - selfR.joinLeave = { - 'join': [], - 'leave': [] - }; - var id = log[i].room; - var battletype = 'Battle'; - if (log[i].format) { - battletype = log[i].format + ' battle'; - if (log[i].format === 'Random Battle') battletype = 'Random Battle'; - } - selfR.chatElem.append(''); - } else if (log[i].message) { - selfR.chatElem.append('
' + Tools.escapeHTML(log[i].message) + '
'); - } else if (log[i].rawMessage) { - selfR.chatElem.append('
' + Tools.sanitizeHTML(log[i].rawMessage) + '
'); - } else if (log[i].evalRulesRedirect || log[i].evalRawMessage) { - // TODO: This will be removed in due course. - window.location.href = 'http://pokemonshowdown.com/rules'; - } else if (log[i].name && (log[i].action === 'join' || log[i].action === 'leave' || log[i].action === 'rename')) { - var userid = toUserid(log[i].name); - if (log[i].action === 'join') { - if (log[i].oldid) delete me.users[toUserid(log[i].oldid)]; - if (!me.users[userid]) selfR.userCount.users++; - me.users[userid] = log[i].name; - selfR.userList.add(userid); - selfR.userList.updateUserCount(); - selfR.userList.updateNoUsersOnline(); - } else if (log[i].action === 'leave') { - if (me.users[userid]) selfR.userCount.users--; - delete me.users[userid]; - selfR.userList.remove(userid); - selfR.userList.updateUserCount(); - selfR.userList.updateNoUsersOnline(); - } else if (log[i].action === 'rename') { - if (log[i].oldid) delete me.users[toUserid(log[i].oldid)]; - me.users[userid] = log[i].name; - selfR.userList.remove(log[i].oldid); - selfR.userList.add(userid); - continue; - } - if (log[i].silent && !Tools.prefs('showjoins')) continue; - if (!selfR.joinLeaveElem) { - selfR.chatElem.append('
Loading...
'); - selfR.joinLeaveElem = selfR.chatElem.children().last(); - } - selfR.joinLeave[log[i].action].push(log[i].name); - var message = ''; - if (selfR.joinLeave['join'].length) { - var preList = selfR.joinLeave['join']; - var list = []; - var named = {}; - for (var j = 0; j < preList.length; j++) { - if (!named[preList[j]]) list.push(preList[j]); - named[preList[j]] = true; - } - for (var j = 0; j < list.length; j++) { - if (j >= 5) { - message += ', and ' + (list.length - 5) + ' others'; - break; - } - if (j > 0) { - if (j == 1 && list.length == 2) { - message += ' and '; - } else if (j == list.length - 1) { - message += ', and '; - } else { - message += ', '; - } - } - message += Tools.escapeHTML(list[j]); - } - message += ' joined'; - } - if (selfR.joinLeave['leave'].length) { - if (selfR.joinLeave['join'].length) { - message += '; '; - } - var preList = selfR.joinLeave['leave']; - var list = []; - var named = {}; - for (var j = 0; j < preList.length; j++) { - if (!named[preList[j]]) list.push(preList[j]); - named[preList[j]] = true; - } - for (var j = 0; j < list.length; j++) { - if (j >= 5) { - message += ', and ' + (list.length - 5) + ' others'; - break; - } - if (j > 0) { - if (j == 1 && list.length == 2) { - message += ' and '; - } else if (j == list.length - 1) { - message += ', and '; - } else { - message += ', '; - } - } - message += Tools.escapeHTML(list[j]); - } - message += ' left
'; - } - selfR.joinLeaveElem.html('' + message + ''); - } - } - if (autoscroll) { - selfR.chatFrameElem.scrollTop(selfR.chatElem.height()); - } - var $children = selfR.chatElem.children(); - if ($children.length > 900) { - $children.slice(0,100).remove(); - } - }; - // Lobby init - this.init = function (data) { - if (data.log) { - selfR.chatElem.html(''); - // Disable timestamps for the past log because the server doesn't - // tell us what time the messages were sent at. - var timestamps = Tools.prefs('timestamps'); - Tools.prefs('timestamps', 'off', false); - selfR.add(data.log); // Add past log. - Tools.prefs('timestamps', timestamps, false); - } - selfR.update(data); - selfR.chatFrameElem.scrollTop(selfR.chatElem.height()); - selfR.updateMe(); - // Preferred avatar feature - var avatar = Tools.prefs('avatar'); - if (avatar) { - // This will be compatible even with servers that don't support - // the second argument for /avatar yet. - selfR.send('/avatar ' + avatar + ',1'); - } - if (me.renameQueued) { - me.upkeepRename(); - me.renameQueued = false; - } - }; - this.update = function (data) { - if (data.logUpdate) { - selfR.add(data.logUpdate); - } - if (typeof data.searching !== 'undefined') { - selfR.me.searching = data.searching; - selfR.updateMainTop(); - } - if (typeof data.searcher !== 'undefined') { - selfR.searcher = data.searcher; - } - if (typeof data.u !== 'undefined') { - selfR.userCount = {}; - me.users = {}; - var commaIndex = data.u.indexOf(','); - if (commaIndex >= 0) { - selfR.userCount.users = parseInt(data.u.substr(0,commaIndex),10); - var users = data.u.substr(commaIndex+1).split(','); - for (var i=0,len=users.length; i 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 = '
In rooms:
' + 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 += ''; - } else { - banMuteBuffer += ''; - } - if (mygroup !== '%') { - banMuteBuffer += ' '; - banMuteBuffer += ' '; - } - } - 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) + '
' + Tools.escapeHTML(challenge.format) + '
'; - text += '' + selfR.getTeamSelect(challenge.format) + '
'; - text += '
'; - } 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 = '
Loading...
'; - selfR.send('/cmd roomlist'); - } else { - text = '
'; - text += '' + Tools.escapeHTML(name) + '
'; - text += '' + (group || '') + '
'; - text += '
'; - if (userid === me.userid) { - text += '
'; - } else { - text += ' '; - text += ''; - } - 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) + '
'; - } else if (selfR.me.searching) { - if (selfR.mainTopState === 'searching') return; - selfR.mainTopState = 'searching'; - - text = '
Format: ' + Tools.escapeHTML(selfR.me.searching.format) + '
Searching...
'; - } 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 += ''; - - 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 += '
'; - } - else - { - text += '
'; - } - 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 += ''; - 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 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('
    '); - } - - 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 += ' '; - 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 ' Random Team'; - } else { - var 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 = ' '; - } */ - - //var mutebutton = ' '; - var buttons = ' '; - if (me.named) { - $('#userbar').html(notifybutton + ' ' + Tools.escapeHTML(me.name) + buttons + ' '); - me.setPersistentName(); - } else { - $('#userbar').html(notifybutton + ' ' + Tools.escapeHTML(me.name) + buttons + ' '); - } - $('#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 += '
    Lobby'; - code += ' Teambuilder'; - code += ' Ladder
    '; - - 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 = '
    '; - text += '

    ' + move.name + '
    '+Tools.getTypeIcon(move.type)+' ' + move.category + '

    '; - text += '

    Base power: ' + basePower + '

    '; - text += '

    Accuracy: ' + accuracy + '

    '; - if (move.desc) { - text += '

    ' + move.desc + '

    '; - } - 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 = '
    '; - text += '

    ' + pokemon.getFullName() + (pokemon.level !== 100 ? ' L' + pokemon.level + '' : '') + '
    '; - - var types = pokemon.types; - var template = pokemon; - if (pokemon.volatiles.transform && pokemon.volatiles.formechange) { - template = Tools.getTemplate(pokemon.volatiles.formechange[2]); - types = template.types; - text += '(Transformed into '+pokemon.volatiles.formechange[2]+')
    '; - } else if (pokemon.volatiles.formechange) { - template = Tools.getTemplate(pokemon.volatiles.formechange[2]); - types = template.types; - text += '(Forme: '+pokemon.volatiles.formechange[2]+')
    '; - } - if (pokemon.volatiles.typechange) { - text += '(Type changed)
    '; - types = [pokemon.volatiles.typechange[2]]; - } - text += Tools.getTypeIcon(types[0]); - if (types[1]) { - text += ' '+Tools.getTypeIcon(types[1]); - } - text += '

    '; - var exacthp = ''; - if (pokemon.maxhp != 100 && pokemon.maxhp != 1000 && pokemon.maxhp != 48) exacthp = ' ('+pokemon.hp+'/'+pokemon.maxhp+')'; - if (pokemon.maxhp == 48 && isActive) exacthp = ' ('+pokemon.hp+'/'+pokemon.maxhp+' pixels)'; - text += '

    HP: ' + pokemon.hpDisplay() +exacthp+(pokemon.status?' '+pokemon.status.toUpperCase()+'':'')+'

    '; - if (!pokemon.baseAbility && !pokemon.ability) { - text += '

    Possible abilities: ' + Tools.getAbility(template.abilities['0']).name; - if (template.abilities['1']) text += ', ' + Tools.getAbility(template.abilities['1']).name; - if (template.abilities['DW']) text += ', ' + Tools.getAbility(template.abilities['DW']).name; - text += '

    '; - } else if (pokemon.ability) { - text += '

    Ability: ' + Tools.getAbility(pokemon.ability).name + '

    '; - } else if (pokemon.baseAbility) { - text += '

    Ability: ' + Tools.getAbility(pokemon.baseAbility).name + '

    '; - } - if (pokemon.item) { - text += '

    Item: ' + Tools.getItem(pokemon.item).name + '

    '; - } - if (pokemon.moves && pokemon.moves.length && (!isActive || isActive === 'foe')) { - text += '

    '; - for (var i = 0; i < pokemon.moves.length; i++) { - var name = Tools.getMove(pokemon.moves[i]).name; - text += '⋅ ' + name + '
    '; - } - text += '

    '; - } - 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 += '

    '; - focusElem = '#overlay_ok'; - break; - case 'replayuploaded': - contents = '

    Your replay has been uploaded! It\'s available at:

    '; - contents += '

    http://pokemonshowdown.com/replay/'+data+'

    '; - contents += '

    '; - 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 += '

    '; - 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 += '

    '; - 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 += '

    ' + (data.name || me.name) + '

    '; - contents += '

    '; - contents += '

    '; - contents += '

    '; - contents += '

    '; - contents += '

    '; - 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 += '

    ' + data.name + '

    '; - contents += '

    '; - contents += '

    '; - selectElem = '#overlay_password'; - break; - case 'options': - contents += '

    '; - - contents += '

    '; - - contents += ''; - - var timestamps = (Tools.prefs('timestamps') || {}); - contents += '

    '; - contents += '

    '; - - contents += ''; - contents += ''; - - contents += '

    '; - - if (curRoom.battle) { - contents += '

    Current room

    '; - contents += '

    '; - } - - contents += '

    '; - break; - case 'avatars': - customAttrs = ' style="max-width:860px"'; - contents += '

    Choose an avatar or

    '; - - 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 += '

    '; - 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 += '

    '; - contents += '

    '; - 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 += '

    '; - contents += '

    '; - contents += '

    '; - 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 += '
    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. '; - contents += '
    3. Usernames may not reference sexual activity, directly or indirectly.
    4. '; - contents += '
    5. Usernames may not impersonate a recognized user (a user with %, @, &, or ~ next to their name).
    6. '; - contents += '
    '; - } - } - contents += '

    '; - contents += '

    '; - selectElem = '#overlay_name'; - break; - case 'forfeit': - contents += '

    Are you sure you want to forfeit?

    '; - contents += '

    '; - 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 += '

    '; - 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 += '

    You will be able to close this in 5 seconds

    '; - setTimeout(function(){ - $('#overlay_ok')[0].disabled = false; - $('#overlay_warn').hide(); - }, 5000); - } else { - contents += '

    '; - 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); -})();