Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name PS
- // @namespace k
- // @match http://*.psim.us/
- // @version 1
- // @grant none
- // ==/UserScript==
- var pmLogs = {};
- window.app.customOpts = {
- rps: false,
- bj: false,
- uno: false,
- rpsCount: 0,
- btCounter: 0,
- ignorePMFrom: [],
- monsToCheck: [],
- monsToEvolve: [],
- };
- if (window.localStorage['pms']) pmLogs = JSON.parse(window.localStorage['pms']);
- addGlobalStyle('.pm-logs {background: rgba(108, 106, 106, 0.52);};');
- addGlobalStyle('.userbar {position: absolute; top: 12px; right: 47px; font-weight: bold;};');
- addGlobalStyle('.userbar2 {position: absolute; top: 12px; right: 17px; font-weight: bold;};');
- addGlobalStyle('.userbar2 button.icon {height: 25px;width: 27px;font-size: 16px;text-align: center;padding: 0;};');
- /*
- * PM Logging
- */
- window.resetPMLogs = function () {
- pmLogs = {};
- window.localStorage['pms'] = "{}";
- }
- window.logPM = function logPM(windowName, message) {
- if (~windowName.indexOf('news')) return;
- if (!pmLogs[windowName]) pmLogs[windowName] = [];
- pmLogs[windowName].push(message);
- if (pmLogs[windowName].length > 50) pmLogs[windowName].splice(0, 1);
- window.localStorage['pms'] = JSON.stringify(pmLogs);
- }
- window.room.openPM = function (name, dontFocus) {
- var userid = toId(name);
- var $pmWindow = this.$pmBox.find('.pm-window-' + userid);
- if (!$pmWindow.length) {
- var group = name.charAt(0);
- if (group === ' ') {
- group = '';
- } else {
- group = '<small>' + Tools.escapeHTML(group) + '</small>';
- }
- var buf = '<div class="pm-window pm-window-' + userid + '" data-userid="' + userid + '" data-name="' + name + '">';
- buf += '<h3><button class="closebutton" href="' + app.root + 'teambuilder" tabindex="-1"><i class="fa fa-times-circle"></i></button>';
- buf += '<button class="minimizebutton" href="' + app.root + 'teambuilder" tabindex="-1"><i class="fa fa-minus-circle"></i></button>';
- buf += group + Tools.escapeHTML(name.substr(1)) + '</h3>';
- buf += '<div class="pm-log"><div class="inner"></div></div>';
- buf += '<div class="pm-log-add"><form class="chatbox nolabel"><textarea class="textbox" type="text" size="70" autocomplete="off" name="message"></textarea></form></div></div>';
- $pmWindow = $(buf).prependTo(this.$pmBox);
- $pmWindow.find('textarea').autoResize({
- animate: false,
- extraSpace: 0
- });
- // create up/down history for this PM
- this.chatHistories[userid] = new ChatHistory();
- if (pmLogs[userid]) {
- var $chat = $pmWindow.find('.inner');
- for (var u in pmLogs[userid]) {
- $chat.append(pmLogs[userid][u]);
- }
- }
- } else {
- $pmWindow.show();
- if (!dontFocus) {
- var $chatFrame = $pmWindow.find('.pm-log');
- var $chat = $pmWindow.find('.inner');
- $chatFrame.scrollTop($chat.height());
- }
- }
- if (!dontFocus) this.$el.scrollTop(0);
- return $pmWindow;
- }
- window.room.addPM = function (name, message, target) {
- var userid = toUserid(name);
- if (app.ignore[userid] && name.substr(0, 1) in {' ': 1, '!': 1, '✖': 1, '‽': 1}) return;
- var isSelf = (toId(name) === app.user.get('userid'));
- var oName = isSelf ? target : name;
- Storage.logChat('pm-' + toId(oName), '' + name + ': ' + message);
- var $pmWindow = this.openPM(oName, true);
- var $chatFrame = $pmWindow.find('.pm-log');
- var $chat = $pmWindow.find('.inner');
- var autoscroll = ($chatFrame.scrollTop() + 60 >= $chat.height() - $chatFrame.height());
- var parsedMessage = Tools.parseChatMessage(message, name, ChatRoom.getTimestamp('pms'));
- if (!$.isArray(parsedMessage)) parsedMessage = [parsedMessage];
- for (var i = 0; i < parsedMessage.length; i++) {
- if (!parsedMessage[i]) continue;
- $chat.append(parsedMessage[i]);
- logPM(toId(oName), '<div class="pm-logs">' + parsedMessage[i] + '</div>');
- }
- var $lastMessage = $chat.children().last();
- var textContent = $lastMessage.html().indexOf('<span class="spoiler">') >= 0 ? '(spoiler)' : $lastMessage.children().last().text();
- if (textContent && app.curSideRoom && app.curSideRoom.addPM && Tools.prefs('inchatpm')) {
- app.curSideRoom.addPM(name, textContent, target);
- }
- if (!isSelf && textContent) {
- this.notifyOnce("PM from " + name, "\"" + textContent + "\"", 'pm');
- }
- if (autoscroll) {
- $chatFrame.scrollTop($chat.height());
- }
- if (!$pmWindow.hasClass('focused') && name.substr(1) !== app.user.get('name')) {
- $pmWindow.find('h3').addClass('pm-notifying');
- }
- }
- /*
- * Options
- */
- window.app.topbar.updateUserbar = function () {
- var buf = '';
- var name = ' ' + app.user.get('name');
- var color = hashColor(app.user.get('userid'));
- if (!app.user.loaded) {
- buf = '<button disabled>Loading...</button>';
- } else if (app.user.get('named')) {
- buf = '<span class="username" data-name="' + Tools.escapeHTML(name) + '" style="' + color + '"><i class="fa fa-user" style="color:#779EC5"></i> ' + Tools.escapeHTML(name) + '</span>';
- } else {
- buf = '<button name="login">Choose name</button>';
- }
- buf += ' <button class="icon button" name="openSounds" title="Sound"><i class="' + (Tools.prefs('mute') ? 'fa fa-volume-off' : 'fa fa-volume-up') + '"></i></button> <button class="icon button" name="openOptions" title="Options"><i class="fa fa-cog"></i></button>';
- buf += ' <button class="icon button" name="openCustomOptions" title="Custom Options"><i class="fa fa-cog"></i></button>'
- this.$userbar.html(buf);
- }
- window.app.topbar.openCustomOptions = function () {
- app.addPopup(CustomOptionsPopup);
- }
- window.CustomOptionsPopup = this.CustomOptionsPopup = window.Popup.extend({
- initialize: function (data) {
- app.user.on('change', this.update, this);
- this.update();
- },
- events: {
- 'change input[name=noanim]': 'setNoanim',
- 'change input[name=bwgfx]': 'setBwgfx',
- 'change input[name=nopastgens]': 'setNopastgens',
- 'change input[name=notournaments]': 'setNotournaments',
- 'change input[name=inchatpm]': 'setInchatpm',
- 'change input[name=dark]': 'setDark',
- 'change input[name=temporarynotifications]': 'setTemporaryNotifications',
- 'change select[name=bg]': 'setBg',
- 'change select[name=timestamps-lobby]': 'setTimestampsLobby',
- 'change select[name=timestamps-pms]': 'setTimestampsPMs',
- 'change input[name=logchat]': 'setLogChat',
- 'change input[name=selfhighlight]': 'setSelfHighlight',
- 'click img': 'avatars'
- },
- update: function () {
- var buf = '';
- var timestamps = this.timestamps = (Tools.prefs('timestamps') || {});
- buf += '<p>Marketplace:</p>';
- buf += '<p><label class="optlabel">Autojoin Giveaways: <button name="joinGiveaways" ' + (Tools.prefs('joinGiveaways') ? 'disabled' : '') + '>On</button> <button name="joinGiveaways" ' + (Tools.prefs('joinGiveaways') ? '' : 'disabled') + '>Off</button></label></p>';
- buf += '<p><label class="optlabel">Auto Blackjack: <button name="toggleBJ" ' + (app.customOpts.bj ? 'disabled' : '') + '>On</button> <button name="toggleBJ" ' + (app.customOpts.bj ? '' : 'disabled') + '>Off</button></label></p>';
- buf += '<p><label class="optlabel">Auto Uno: <button name="toggleUno" ' + (app.customOpts.uno ? 'disabled' : '') + '>On</button> <button name="toggleUno" ' + (app.customOpts.uno ? '' : 'disabled') + '>Off</button></label></p>';
- buf += '<p>Experience Grinding:</p>';
- buf += '<p><label class="optlabel">Auto RPS: <button name="toggleRPS" ' + (app.customOpts.rps ? 'disabled' : '') + '>On</button> <button name="toggleRPS" ' + (app.customOpts.rps ? '' : 'disabled') + '>Off</button></label></p>';
- buf += '<p><label class="optlabel">Auto BT: <button name="toggleBT" ' + (app.customOpts.bt ? 'disabled' : '') + '>On</button> <button name="toggleBT" ' + (app.customOpts.bt ? '' : 'disabled') + '>Off</button></label></p>';
- buf += '<p>RPS Messages: ' + app.customOpts.rpsCount + '</p>';
- buf += '<p>BT Messages: ' + app.customOpts.btCounter + '</p>';
- buf += '<p>Misc:</p>';
- buf += '<p><label class="optlabel"><button name="massPM">Mass PM</button></label></p>';
- buf += '<p><label class="optlabel"><button name="buyEggs">Buy All Eggs</button></label></p>';
- buf += '<p><label class="optlabel"><button name="findMons">Evolve All Pets</button></label></p>';
- this.$el.html(buf).css('min-width', 160);
- },
- toggleRPS: function () {
- app.customOpts.rps = !app.customOpts.rps;
- if (app.customOpts.rps) {
- app.send('/rps search');
- } else {
- app.send('/rps endsearch');
- }
- this.update();
- },
- toggleBJ: function () {
- app.customOpts.bj = !app.customOpts.bj;
- this.update();
- },
- toggleBT: function () {
- app.customOpts.bt = !app.customOpts.bt;
- if (app.customOpts.bt) {
- app.send('/bt set battlefactory');
- app.send('/bt');
- }
- this.update();
- },
- toggleUno: function () {
- app.customOpts.uno = !app.customOpts.uno;
- this.update();
- },
- joinGiveaways: function () {
- var toggle = !Tools.prefs('joinGiveaways');
- Tools.prefs('joinGiveaways', toggle);
- this.update();
- },
- buyEggs: function () {
- if (app.customOpts.buyingEggs) return this.close();
- app.customOpts.buyingEggs = true;
- app.send('/pets');
- this.close();
- },
- findMons: function () {
- if (app.customOpts.findMons) return this.close();
- app.customOpts.findMons = true;
- app.send('/pets');
- this.close();
- },
- massPM: function () {
- this.close();
- app.addPopup(app.massPMPopup);
- }
- });
- window.app.receive = function (data) {
- var roomid = '';
- var autojoined = false;
- if (data.trim() === 'You are now searching for a game of Rock/Paper/Scissors (ladder).') return;
- if (data.substr(0, 1) === '>') {
- var nlIndex = data.indexOf('\n');
- if (nlIndex < 0) return;
- roomid = toRoomid(data.substr(1, nlIndex - 1));
- data = data.substr(nlIndex + 1);
- }
- if (data.substr(0, 6) === '|init|') {
- if (!roomid) roomid = 'lobby';
- var roomType = data.substr(6);
- var roomTypeLFIndex = roomType.indexOf('\n');
- if (roomTypeLFIndex >= 0) roomType = roomType.substr(0, roomTypeLFIndex);
- roomType = toId(roomType);
- if (this.rooms[roomid] || roomid === 'staff' || roomid === 'upperstaff') {
- // autojoin rooms are joined in background
- this.addRoom(roomid, roomType, true);
- } else {
- this.joinRoom(roomid, roomType, true);
- }
- if (roomType === 'chat') autojoined = true;
- } else if ((data + '|').substr(0, 8) === '|expire|') {
- var room = this.rooms[roomid];
- if (room) {
- room.expired = (data.substr(8) || true);
- if (room.updateUser) room.updateUser();
- }
- return;
- } else if ((data + '|').substr(0, 8) === '|deinit|' || (data + '|').substr(0, 8) === '|noinit|') {
- if (!roomid) roomid = 'lobby';
- if (this.rooms[roomid] && this.rooms[roomid].expired) {
- // expired rooms aren't closed when left
- return;
- }
- var isdeinit = (data.charAt(1) === 'd');
- data = data.substr(8);
- var pipeIndex = data.indexOf('|');
- var errormessage;
- if (pipeIndex >= 0) {
- errormessage = data.substr(pipeIndex + 1);
- data = data.substr(0, pipeIndex);
- }
- // handle error codes here
- // data is the error code
- if (data === 'namerequired') {
- var self = this;
- this.once('init:choosename', function () {
- self.send('/join ' + roomid);
- });
- } else if (data !== 'namepending') {
- if (isdeinit) { // deinit
- if (this.rooms[roomid] && this.rooms[roomid].type === 'chat') {
- this.removeRoom(roomid, true);
- this.updateAutojoin();
- } else {
- this.removeRoom(roomid, true);
- }
- } else { // noinit
- this.unjoinRoom(roomid);
- if (roomid === 'lobby') this.joinRoom('rooms');
- }
- if (errormessage) {
- if (data === 'nonexistent' && Config.server.id && roomid.slice(0, 7) === 'battle-') {
- var replayid = roomid.slice(7);
- if (Config.server.id !== 'showdown') replayid = Config.server.id + '-' + replayid;
- var replayLink = 'http://replay.pokemonshowdown.com/' + replayid;
- errormessage += '\n\nYou might want to try the replay: ' + replayLink;
- }
- this.addPopupMessage(errormessage);
- }
- }
- return;
- } else if (data.substr(0, 3) === '|N|') {
- var names = data.substr(1).split('|');
- if (app.ignore[toUserid(names[2])]) {
- app.ignore[toUserid(names[1])] = 1;
- }
- }
- if (roomid) {
- if (this.rooms[roomid]) {
- this.rooms[roomid].receive(data);
- }
- if (autojoined) this.updateAutojoin();
- return;
- }
- // Since roomid is blank, it could be either a global message or
- // a lobby message. (For bandwidth reasons, lobby messages can
- // have blank roomids.)
- // If it starts with a messagetype in the global messagetype
- // list, we'll assume global; otherwise, we'll assume lobby.
- var parts;
- if (data.charAt(0) === '|') {
- parts = data.substr(1).split('|');
- } else {
- parts = [];
- }
- switch (parts[0]) {
- case 'challstr':
- if (parts[2]) {
- this.user.receiveChallstr(parts[1] + '|' + parts[2]);
- } else {
- this.user.receiveChallstr(parts[1]);
- }
- break;
- case 'formats':
- this.parseFormats(parts);
- break;
- case 'updateuser':
- setTimeout(function () {app.topbar.updateUserbar();}, 5000);
- var nlIndex = data.indexOf('\n');
- if (nlIndex > 0) {
- this.receive(data.substr(nlIndex + 1));
- nlIndex = parts[3].indexOf('\n');
- parts[3] = parts[3].substr(0, nlIndex);
- }
- var name = parts[1];
- var named = !!+parts[2];
- var userid = toUserid(name);
- if (userid === this.user.get('userid') && name !== this.user.get('name')) {
- $.post(app.user.getActionPHP(), {
- act: 'changeusername',
- username: name
- }, function () {}, 'text');
- }
- this.user.set({
- name: name,
- userid: userid,
- named: named,
- avatar: parts[3]
- });
- this.user.setPersistentName(named ? name : null);
- if (named) {
- this.trigger('init:choosename');
- }
- if (app.ignore[toUserid(name)]) {
- delete app.ignore[toUserid(name)];
- }
- break;
- case 'nametaken':
- app.addPopup(LoginPopup, {name: parts[1] || '', error: parts[2] || ''});
- break;
- case 'queryresponse':
- var responseData = JSON.parse(data.substr(16 + parts[1].length));
- app.trigger('response:' + parts[1], responseData);
- break;
- case 'updatechallenges':
- if (this.rooms['']) {
- this.rooms[''].updateChallenges($.parseJSON(data.substr(18)));
- }
- break;
- case 'updatesearch':
- if (this.rooms['']) {
- this.rooms[''].updateSearch($.parseJSON(data.substr(14)));
- }
- break;
- case 'popup':
- var maxWidth;
- var type = 'semimodal';
- data = data.substr(7);
- if (data.substr(0, 6) === '|wide|') {
- data = data.substr(6);
- maxWidth = 960;
- }
- if (data.substr(0, 7) === '|modal|') {
- data = data.substr(7);
- type = 'modal';
- }
- if (data.substr(0, 6) === '|html|') {
- data = data.substr(6);
- if (app.customOpts.bt) {
- if (data.match(/\"\/petbattles choose [a-z]+\"/g)) {
- app.send(data.match(/\"\/petbattles choose [a-z]+\"/g)[0].replace(/\"/g, ''));
- app.customOpts.btCounter++;
- return;
- }
- if (app.customOpts.bt && data.match(/has won the battle\!/g)) {
- app.send('/bt');
- app.customOpts.btCounter++;
- return;
- }
- }
- if (app.customOpts.buyingEggs && data.match(/₽[0-9]+/)) {
- var money = Number(data.match(/₽[0-9]+/)[0].replace(/₽/, ''));
- if (money > 250) {
- app.send('/pets buyegg');
- } else {
- app.customOpts.buyingEggs = false;
- }
- }
- if (app.customOpts.findMons && data.match(/₽[0-9]+/)) {
- console.log('finding mons');
- var ids = [];
- data = data.replace(/<button name=send value="\/pets viewmon m-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+" class="card\-button" ><div style="height:80px; width: 80px; background\-image: url\('http:\/\/cdn\.bulbagarden\.net\/upload\/d\/dc\/Spr_3r_Egg\.png'\); background\-repeat: no\-repeat; background\-size: contain; background\-position: center"><\/div><\/button>/g, '');
- var matches = data.match(/\/pets viewmon m-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+/g);
- for (var u in matches) {
- app.customOpts.monsToCheck.push(matches[u].replace(/\/pets viewmon /, ''));
- }
- app.customOpts.findMons = false;
- if (app.customOpts.monsToCheck.length > 0) {
- app.customOpts.checkMons = true;
- console.log('mons found: checkMons true');
- app.send('/pets viewmon ' + app.customOpts.monsToCheck[0]);
- }
- }
- if (app.customOpts.checkMons && data.match(/₽[0-9]+/) && data.match(/\/pets evolve m-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+, [a-z]+/)) {
- console.log('evolving mon');
- app.customOpts.monsToEvolve.push(data.match(/\/pets evolve m-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+-[a0-z9]+, [a-z]+/)[0]);
- app.customOpts.monsToCheck.splice(0, 1);
- if (app.customOpts.monsToCheck.length > 0) {
- app.send('/pets viewmon ' + app.customOpts.monsToCheck[0]);
- console.log('viewing next mon');
- } else {
- console.log('out of mons to check');
- app.customOpts.checkMons = false;
- evolveMons();
- }
- }
- if (app.customOpts.checkMons && data.match(/₽[0-9]+/) && data.match(/(Unable to evolve|\(Requires [0-9]+ more EXP to evolve\))/)) {
- console.log('unable to evolve');
- app.customOpts.monsToCheck.splice(0, 1);
- if (app.customOpts.monsToCheck.length > 0) {
- console.log('checking next mon');
- app.send('/pets viewmon ' + app.customOpts.monsToCheck[0]);
- } else {
- console.log('out of mons to check 2');
- app.customOpts.checkMons = false;
- evolveMons();
- }
- }
- app.addPopup(Popup, {
- type: type,
- maxWidth: maxWidth,
- htmlMessage: Tools.sanitizeHTML(data)
- });
- } else {
- app.addPopup(Popup, {
- type: type,
- maxWidth: maxWidth,
- message: data.replace(/\|\|/g, '\n')
- });
- }
- if (this.rooms['']) this.rooms[''].resetPending();
- break;
- case 'disconnect':
- app.trigger('init:socketclosed', Tools.sanitizeHTML(data.substr(12)));
- break;
- case 'pm':
- var dataLines = data.split('\n');
- for (var i = 0; i < dataLines.length; i++) {
- parts = dataLines[i].slice(1).split('|');
- var message = parts.slice(3).join('|');
- if (~app.customOpts.ignorePMFrom.indexOf(toId(parts[2]))) {
- app.customOpts.ignorePMFrom.splice(app.customOpts.ignorePMFrom.indexOf(toId(parts[1])), 1);
- return;
- }
- if (message.match(/\/rps choose P [A-Z]+-[0-9]+/)) {
- let rpsId = message.match(/\/rps choose P [A-Z]+-[0-9]+/)[0].split(' ').pop();
- let rpsChoices = ['R', 'P', 'S'];
- app.send('/rps choose ' + rpsChoices[Math.floor(Math.random() * rpsChoices.length)] + ' ' + rpsId);
- }
- if (app.customOpts.rps && parts[1] === '~Rock/Paper/Scissors Host' && data.match(/(You have lost the game against|You have won the game against|The game with)/)) {
- app.send('/rps search');
- }
- if (parts[1] === '~Rock/Paper/Scissors Host') {
- app.customOpts.rpsCount++;
- continue;
- }
- if (app.customOpts.bj && toId(parts[1]) === 'afterlifeguardian' && data.match(/Your hand is/)) {
- var id = toId(message.match(/\[[a-z]+\]/)[0]);
- var score = Number(message.split(' ').pop());
- if (score < 22) {
- if (score >= 18) {
- setTimeout(function () {
- app.send('.stay', id);
- }, randomNumber(5, 15) * 1000);
- } else {
- setTimeout(function () {
- app.send('.hit', id);
- }, randomNumber(5, 15) * 1000);
- }
- }
- }
- this.rooms[''].addPM(parts[1], message, parts[2]);
- if (toUserid(parts[1]) !== app.user.get('userid')) {
- app.user.lastPM = toUserid(parts[1]);
- }
- }
- break;
- case 'roomerror':
- // deprecated; use |deinit| or |noinit|
- this.unjoinRoom(parts[1]);
- this.addPopupMessage(parts.slice(2).join('|'));
- break;
- case 'refresh':
- // refresh the page
- document.location.reload(true);
- break;
- case 'c':
- case 'chat':
- if (parts[1] === '~') {
- if (parts[2].substr(0, 6) === '/warn ') {
- app.addPopup(RulesPopup, {warning: parts[2].substr(6)});
- break;
- }
- }
- /* fall through */
- default:
- // the messagetype wasn't in our list of recognized global
- // messagetypes; so the message is presumed to be for the
- // lobby.
- if (this.rooms['lobby']) {
- this.rooms['lobby'].receive(data);
- }
- break;
- }
- }
- window.ChatRoom = this.ChatRoom = ConsoleRoom.extend({
- minWidth: 320,
- minMainWidth: 580,
- maxWidth: 1024,
- isSideRoom: true,
- initialize: function () {
- var buf = '<div class="tournament-wrapper"></div><div class="chat-log"><div class="inner"></div></div></div><div class="chat-log-add">Connecting...</div><ul class="userlist"></ul>';
- this.$el.addClass('ps-room-light').html(buf);
- this.$chatAdd = this.$('.chat-log-add');
- this.$chatFrame = this.$('.chat-log');
- this.$chat = this.$('.inner');
- this.$chatbox = null;
- this.$tournamentWrapper = this.$('.tournament-wrapper');
- this.tournamentBox = null;
- this.users = {};
- this.userCount = {};
- this.$joinLeave = null;
- this.joinLeave = {
- 'join': [],
- 'leave': []
- };
- this.$userList = this.$('.userlist');
- this.userList = new UserList({
- el: this.$userList,
- room: this
- });
- },
- updateLayout: function () {
- if (this.$el.width() >= 570) {
- this.userList.show();
- this.$chatFrame.addClass('hasuserlist');
- this.$chatAdd.addClass('hasuserlist');
- this.$tournamentWrapper.addClass('hasuserlist');
- } else {
- this.userList.hide();
- this.$chatFrame.removeClass('hasuserlist');
- this.$chatAdd.removeClass('hasuserlist');
- this.$tournamentWrapper.removeClass('hasuserlist');
- }
- this.$chatFrame.scrollTop(this.$chat.height());
- if (this.tournamentBox) this.tournamentBox.updateLayout();
- },
- show: function () {
- Room.prototype.show.apply(this, arguments);
- this.updateLayout();
- },
- join: function () {
- app.send('/join ' + this.id);
- },
- leave: function () {
- app.send('/leave ' + this.id);
- app.updateAutojoin();
- },
- receive: function (data) {
- this.add(data);
- },
- add: function (log) {
- if (typeof log === 'string') log = log.split('\n');
- var autoscroll = false;
- if (this.$chatFrame.scrollTop() + 60 >= this.$chat.height() - this.$chatFrame.height()) {
- autoscroll = true;
- }
- var userlist = '';
- for (var i = 0; i < log.length; i++) {
- if (log[i].substr(0, 7) === '|users|') {
- userlist = log[i];
- } else {
- this.addRow(log[i]);
- }
- }
- if (userlist) this.addRow(userlist);
- if (autoscroll) {
- this.$chatFrame.scrollTop(this.$chat.height());
- }
- var $children = this.$chat.children();
- if ($children.length > 900) {
- $children.slice(0, 100).remove();
- }
- },
- addPM: function (user, message, pm) {
- var autoscroll = false;
- if (this.$chatFrame.scrollTop() + 60 >= this.$chat.height() - this.$chatFrame.height()) {
- autoscroll = true;
- }
- this.addChat(user, message, pm);
- if (autoscroll) {
- this.$chatFrame.scrollTop(this.$chat.height());
- }
- if (!app.focused && !Tools.prefs('mute') && Tools.prefs('notifvolume')) {
- soundManager.getSoundById('notif').setVolume(Tools.prefs('notifvolume')).play();
- }
- },
- addRow: function (line) {
- var name, name2, room, action, silent, oldid;
- var self = this;
- if (line && typeof line === 'string') {
- if (line.substr(0, 1) !== '|') line = '||' + line;
- var row = line.substr(1).split('|');
- switch (row[0]) {
- case 'init':
- // ignore (handled elsewhere)
- break;
- case 'title':
- this.title = row[1];
- app.roomTitleChanged(this);
- app.topbar.updateTabbar();
- break;
- case 'c':
- case 'chat':
- if (/[a-zA-Z0-9]/.test(row[1].charAt(0))) row[1] = ' ' + row[1];
- this.addChat(row[1], row.slice(2).join('|'));
- break;
- case ':':
- this.timeOffset = ~~(Date.now() / 1000) - (parseInt(row[1], 10) || 0);
- break;
- case 'c:':
- if (/[a-zA-Z0-9]/.test(row[2].charAt(0))) row[2] = ' ' + row[2];
- var msgTime = this.timeOffset + (parseInt(row[1], 10) || 0);
- this.addChat(row[2], row.slice(3).join('|'), false, msgTime);
- if (app.customOpts.bj && toId(row[2]) === 'afterlifeguardian' && (row.slice(3).join('|').trim() === 'A new game of blackjack is starting. do +join to join the game!' || row.slice(3).join('|').trim() === 'A new game of blakejack is starting. do +join to join the game!')) {
- setTimeout(function () {
- app.send('.join', self.id);
- }, randomNumber(5, 30) * 1000);
- }
- break;
- case 'tc':
- if (/[a-zA-Z0-9]/.test(row[2].charAt(0))) row[2] = ' ' + row[2];
- var msgTime = row[1] ? ~~(Date.now() / 1000) - (parseInt(row[1], 10) || 0) : 0;
- this.addChat(row[2], row.slice(3).join('|'), false, msgTime);
- break;
- case 'b':
- case 'B':
- var id = row[1];
- name = row[2];
- name2 = row[3];
- silent = (row[0] === 'B');
- var matches = ChatRoom.parseBattleID(id);
- if (!matches) {
- return; // bogus room ID could be used to inject JavaScript
- }
- var format = Tools.escapeFormat(matches ? matches[1] : '');
- if (silent && !Tools.prefs('showbattles')) return;
- this.addJoinLeave();
- var battletype = 'Battle';
- if (format) {
- battletype = format + ' battle';
- if (format === 'Random Battle') battletype = 'Random Battle';
- }
- this.$chat.append('<div class="notice"><a href="' + app.root + id + '" class="ilink">' + battletype + ' started between <strong style="' + hashColor(toUserid(name)) + '">' + Tools.escapeHTML(name) + '</strong> and <strong style="' + hashColor(toUserid(name2)) + '">' + Tools.escapeHTML(name2) + '</strong>.</a></div>');
- break;
- case 'j':
- case 'join':
- case 'J':
- this.addJoinLeave('join', row[1], null, row[0] === 'J');
- break;
- case 'l':
- case 'leave':
- case 'L':
- this.addJoinLeave('leave', row[1], null, row[0] === 'L');
- break;
- case 'n':
- case 'name':
- case 'N':
- this.addJoinLeave('rename', row[1], row[2], true);
- break;
- case 'users':
- this.parseUserList(row[1]);
- break;
- case 'usercount':
- if (this.id === 'lobby') {
- this.userCount.globalUsers = parseInt(row[1], 10);
- this.userList.updateUserCount();
- }
- break;
- case 'formats':
- // deprecated; please send formats to the global room
- app.parseFormats(row);
- break;
- case 'raw':
- case 'html':
- this.$chat.append('<div class="notice">' + Tools.sanitizeHTML(row.slice(1).join('|')) + '</div>');
- var id = this.id;
- if (app.customOpts.uno && row.slice(1).join('|').match(/A new game of UNO is starting!/)) {
- setTimeout(function () {
- app.send('/uno join', id);
- }, randomNumber(5, 30) * 1000);
- }
- break;
- case 'error':
- this.$chat.append('<div class="notice message-error">' + Tools.escapeHTML(row.slice(1).join('|')) + '</div>');
- break;
- case 'uhtml':
- this.$chat.append('<div class="notice uhtml-' + toId(row[1]) + '">' + Tools.sanitizeHTML(row.slice(2).join('|')) + '</div>');
- var html = row.slice(2).join('|');
- if (html.match(/<button name="send" value="\/giveaway joinlottery">/) && Tools.prefs('joinGiveaways')) {
- app.send('/giveaway joinlottery', this.id);
- }
- if (app.customOpts.uno && html.match(/y [A0-Z9](\+[A0-Z9]|[A0-Z9])/g)) {
- parseUno(html, this.id);
- }
- break;
- case 'uhtmlchange':
- var $elements = this.$chat.find('div.uhtml-' + toId(row[1]));
- if (!$elements.length) break;
- $elements.html(Tools.sanitizeHTML(row.slice(2).join('|')));
- var html = row.slice(2).join('|');
- if (app.customOpts.uno && html.match(/y [A0-Z9](\+[A0-Z9]|[A0-Z9])/g)) {
- parseUno(html, this.id);
- }
- break;
- case 'unlink':
- // note: this message has global effects, but it's handled here
- // so that it can be included in the scrollback buffer.
- if (Tools.prefs('nounlink')) return;
- var user = toId(row[2]) || toId(row[1]);
- var $messages = $('.chatmessage-' + user);
- if (!$messages.length) break;
- $messages.find('a').contents().unwrap();
- if (row[2]) {
- // there used to be a condition for
- // row[1] === 'roomhide'
- // but it's now always applied
- $messages = this.$chat.find('.chatmessage-' + user);
- if (!$messages.length) break;
- $messages.hide().addClass('revealed').find('button').parent().remove();
- this.$chat.children().last().append(' <button name="toggleMessages" value="' + user + '" class="subtle"><small>(' + $messages.length + ' line' + ($messages.length > 1 ? 's' : '') + ' from ' + user + ' hidden)</small></button>');
- }
- break;
- case 'tournament':
- case 'tournaments':
- if (Tools.prefs('notournaments')) break;
- if (!this.tournamentBox) this.tournamentBox = new TournamentBox(this, this.$tournamentWrapper);
- if (!this.tournamentBox.parseMessage(row.slice(1), row[0] === 'tournaments')) break;
- // fallthrough in case of unparsed message
- case '':
- this.$chat.append('<div class="notice">' + Tools.escapeHTML(row.slice(1).join('|')) + '</div>');
- break;
- default:
- this.$chat.append('<div class="notice"><code>|' + Tools.escapeHTML(row.join('|')) + '</code></div>');
- break;
- }
- }
- },
- toggleMessages: function (user, button) {
- var $messages = this.$('.chatmessage-' + user + '.revealed');
- var $button = $(button);
- if (!$messages.is(':hidden')) {
- $messages.hide();
- $button.html('<small>(' + ($messages.length) + ' line' + ($messages.length !== 1 ? 's' : '') + ' from ' + user + ' hidden)</small>');
- } else {
- $button.html('<small>(Hide ' + ($messages.length) + ' line' + ($messages.length !== 1 ? 's' : '') + ' from ' + user + ')</small>');
- $messages.show();
- }
- },
- tournamentButton: function (val, button) {
- if (this.tournamentBox) this.tournamentBox[$(button).data('type')](val, button);
- },
- parseUserList: function (userList) {
- this.userCount = {};
- this.users = {};
- var commaIndex = userList.indexOf(',');
- if (commaIndex >= 0) {
- this.userCount.users = parseInt(userList.substr(0, commaIndex), 10);
- var users = userList.substr(commaIndex + 1).split(',');
- for (var i = 0, len = users.length; i < len; i++) {
- if (users[i]) this.users[toId(users[i])] = users[i];
- }
- } else {
- this.userCount.users = parseInt(userList, 10);
- this.userCount.guests = this.userCount.users;
- }
- this.userList.construct();
- },
- addJoinLeave: function (action, name, oldid, silent) {
- var userid = toUserid(name);
- if (!action) {
- this.$joinLeave = null;
- this.joinLeave = {
- 'join': [],
- 'leave': []
- };
- return;
- } else if (action === 'join') {
- if (oldid) delete this.users[toUserid(oldid)];
- if (!this.users[userid]) this.userCount.users++;
- this.users[userid] = name;
- this.userList.add(userid);
- this.userList.updateUserCount();
- this.userList.updateNoUsersOnline();
- } else if (action === 'leave') {
- if (this.users[userid]) this.userCount.users--;
- delete this.users[userid];
- this.userList.remove(userid);
- this.userList.updateUserCount();
- this.userList.updateNoUsersOnline();
- } else if (action === 'rename') {
- if (oldid) delete this.users[toUserid(oldid)];
- this.users[userid] = name;
- this.userList.remove(oldid);
- this.userList.add(userid);
- return;
- }
- var allShowjoins = Tools.prefs('showjoins') || {};
- var showjoins = allShowjoins[Config.server.id];
- if (silent && (!showjoins || (!showjoins['global'] && !showjoins[this.id]) || showjoins[this.id] === 0)) {
- return;
- }
- if (!this.$joinLeave) {
- this.$chat.append('<div class="message"><small>Loading...</small></div>');
- this.$joinLeave = this.$chat.children().last();
- }
- this.joinLeave[action].push(name);
- var message = '';
- if (this.joinLeave['join'].length) {
- var preList = this.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 (this.joinLeave['leave'].length) {
- if (this.joinLeave['join'].length) {
- message += '; ';
- }
- var preList = this.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<br />';
- }
- this.$joinLeave.html('<small style="color: #555555">' + message + '</small>');
- },
- addChat: function (name, message, pm, msgTime) {
- var userid = toUserid(name);
- if (app.ignore[userid] && (name.charAt(0) === ' ' || name.charAt(0) === '+')) return;
- // Add this user to the list of people who have spoken recently.
- this.markUserActive(userid);
- this.$joinLeave = null;
- this.joinLeave = {
- 'join': [],
- 'leave': []
- };
- if (pm) {
- var pmuserid = toUserid(pm);
- var oName = pmuserid === app.user.get('userid') ? name : pm;
- var clickableName = '<span class="username" data-name="' + Tools.escapeHTML(name) + '">' + Tools.escapeHTML(name.substr(1)) + '</span>';
- this.$chat.append(
- '<div class="chat chatmessage-' + toId(name) + '">' + ChatRoom.getTimestamp('lobby', msgTime) +
- '<strong style="' + hashColor(userid) + '">' + clickableName + ':</strong>' +
- '<span class="message-pm"><i class="pmnote" data-name="' + Tools.escapeHTML(oName) + '">(Private to ' + Tools.escapeHTML(pm) + ')</i> ' + Tools.parseMessage(message) + '</span>' +
- '</div>'
- );
- return; // PMs independently notify in the man menu; no need to make them notify again with `inchatpm`.
- }
- var lastMessageDates = Tools.prefs('logtimes') || (Tools.prefs('logtimes', {}), Tools.prefs('logtimes'));
- if (!lastMessageDates[Config.server.id]) lastMessageDates[Config.server.id] = {};
- var lastMessageDate = lastMessageDates[Config.server.id][this.id] || 0;
- var mayNotify = msgTime > lastMessageDate && userid !== app.user.get('userid');
- if (app.focused && (this === app.curSideRoom || this === app.curRoom)) {
- this.lastMessageDate = 0;
- lastMessageDates[Config.server.id][this.id] = msgTime;
- Storage.prefs.save();
- } else {
- // To be saved on focus
- this.lastMessageDate = Math.max(this.lastMessageDate || 0, msgTime);
- }
- var isHighlighted = userid !== app.user.get('userid') && this.getHighlight(message);
- var parsedMessage = Tools.parseChatMessage(message, name, ChatRoom.getTimestamp('chat', msgTime), isHighlighted);
- if (!$.isArray(parsedMessage)) parsedMessage = [parsedMessage];
- for (var i = 0; i < parsedMessage.length; i++) {
- if (!parsedMessage[i]) continue;
- this.$chat.append(parsedMessage[i]);
- }
- if (mayNotify && isHighlighted) {
- if (!Tools.prefs('mute') && Tools.prefs('notifvolume')) {
- soundManager.getSoundById('notif').setVolume(Tools.prefs('notifvolume')).play();
- }
- var $lastMessage = this.$chat.children().last();
- var notifyTitle = "Mentioned by " + name + (this.id === 'lobby' ? '' : " in " + this.title);
- var notifyText = $lastMessage.html().indexOf('<span class="spoiler">') >= 0 ? '(spoiler)' : $lastMessage.children().last().text();
- this.notifyOnce(notifyTitle, "\"" + notifyText + "\"", 'highlight');
- } else if (mayNotify && name !== '~') { // |c:|~| prefixes a system message
- this.subtleNotifyOnce();
- }
- if (message.slice(0, 4) === '/me ' || message.slice(0, 5) === '/mee') {
- Storage.logChat(this.id, '* ' + name + (message.slice(0, 4) === '/me ' ? ' ' : '') + message);
- } else if (message.slice(0, 5) === '/log ') {
- Storage.logChat(this.id, '' + message.slice(5));
- } else {
- Storage.logChat(this.id, '' + name + ': ' + message);
- }
- },
- destroy: function (alreadyLeft) {
- if (this.tournamentBox) {
- app.user.off('saveteams', this.tournamentBox.updateTeams, this.tournamentBox);
- }
- ConsoleRoom.prototype.destroy.call(this, alreadyLeft);
- },
- }, {
- getTimestamp: function (section, msgTime) {
- var pref = Tools.prefs('timestamps') || {};
- var sectionPref = ((section === 'pms') ? pref.pms : pref.lobby) || 'off';
- if ((sectionPref === 'off') || (sectionPref === undefined)) return '';
- var date = (msgTime && !isNaN(msgTime) ? new Date(msgTime * 1000) : new Date());
- var components = [date.getHours(), date.getMinutes()];
- if (sectionPref === 'seconds') {
- components.push(date.getSeconds());
- }
- return '<small>[' + components.map(
- function (x) { return (x < 10) ? '0' + x : x; }
- ).join(':') + '] </small>';
- },
- parseBattleID: function (id) {
- if (id.lastIndexOf('-') > 6) {
- return id.match(/^battle\-([a-z0-9]*)\-?[0-9]*$/);
- }
- return id.match(/^battle\-([a-z0-9]*[a-z])[0-9]*$/);
- }
- });
- /*
- * Mass PM
- */
- /*
- <select name="cars">
- <option value="volvo">Volvo</option>
- <option value="saab">Saab</option>
- <option value="fiat">Fiat</option>
- <option v
- */
- var MassPMPopup = app.massPMPopup = Popup.extend({
- type: 'semimodal',
- initialize: function (data) {
- var buf = '<form>';
- var rooms = [];
- for (var u in app.rooms) {
- if (!app.rooms[u].title || app.rooms[u].title.length < 1) continue;
- rooms.push(app.rooms[u].title);
- }
- if (data.error) {
- buf += '<p class="error">' + data.error + '</p>';
- }
- buf += '<p>Mass PM:</p>'
- buf += '<p>Room: <select name="room">';
- for (var i in rooms) buf += '<option value="' + toId(rooms[i]) + '">' + Tools.escapeHTML(rooms[i]) + '</option>';
- buf += '</select></p>';
- buf += '<p>Message: <label><input class="textbox autofocus" name="message"/></label></p>';
- buf += '<p>PM Staff: <label><input type="checkbox" name="staff"/></label></p>';
- buf += '<p class="buttonbar"><button type="submit"><strong>Submit</strong></button> <button name="close">Cancel</button></p></form>';
- this.$el.html(buf);
- },
- submit: function (data) {
- if (!data.message) {
- return app.addPopup(MassPMPopup, {error: "Message may not be blank"});
- }
- massPM(data.message, data.room, (data.staff ? true : false));
- this.close();
- }
- });
- /*
- * Functions
- */
- function evolveMons() {
- if (app.customOpts.monsToEvolve.length < 1) return;
- app.customOpts.evolveTimer = setInterval(function () {
- if (app.customOpts.monsToEvolve.length < 1) return clearInterval(app.customOpts.evolveTimer);
- app.send(app.customOpts.monsToEvolve[0]);
- app.customOpts.monsToEvolve.splice(0, 1);
- }, 600);
- }
- function massPM(message, room, pmStaff) {
- var users = [];
- for (var u in app.rooms[toId(room)].users) {
- if (!pmStaff && app.rooms[toId(room)].users[u].charAt(0) !== ' ' || toId(app.rooms[toId(room)].users[u]) === toId(app.user.get('name'))) continue;
- users.push(app.rooms[toId(room)].users[u]);
- }
- var messages = [];
- for (var i in users) {
- app.customOpts.ignorePMFrom.push(toId(users[i]));
- messages.push('/msg ' + users[i] + ', ' + message);
- }
- app.customOpts.pmTimer = setInterval(function () {
- if (!messages[0]) return clearInterval(app.customOpts.pmTimer);
- app.send(messages[0]);
- messages.splice(0, 1);
- }, 600);
- }
- function parseUno(html, id) {
- var cards = html.match(/y [A0-Z9](\+[A0-Z9]|[A0-Z9])/g)
- var colour = html.match(/background: [a-z]+/)[0].replace(/background: /, '');
- var type = html.match(/(white">|white" size=6>|black">|black" size=6>|size=4>)(\+4|S|W|R|\+[0-9]|[0-9])/)[0].replace(/(white">|white" size=6>|black">|black" size=6>|size=4>)/, '');
- var drawn = html.match(/You have drawn/);
- var newColour = '';
- var played;
- if (type === '+4' || type === 'W') newColour = html.match(/Change to: <font color="[a-z]+/)[0].replace(/Change to: <font color="/, '');
- for (var u in cards) cards[u] = cards[u].replace(/y /, '');
- console.log('uno cards: ' + cards.join(', '));
- console.log('uno colour: ' + colour);
- console.log('uno type: ' + type);
- console.log('uno newColour: ' + newColour);
- for (var i in cards) {
- if (cards[i].charAt(0) === 'W' || cards[i].charAt(0) === '+') continue;
- console.log('uno currentCard: ' + cards[i]);
- if ((cards[i].charAt(0).toLowerCase() === colour.charAt(0) && colour !== 'black') || cards[i].charAt(0).toLowerCase() === newColour.charAt(0)) { // card matches played card colour
- console.log('uno: card matches target card colour');
- setTimeout(function () {
- app.send('/uno play ' + cards[i], id);
- }, randomNumber(5, 15) * 1000);
- played = true;
- break;
- }
- if ((colour !== 'black' && cards[i].charAt(0).toLowerCase() === colour.charAt(0).toLowerCase()) || cards[i] === type) { // card matches played card number/type
- console.log('uno: card matches number/type');
- setTimeout(function () {
- app.send('/uno play ' + cards[i], id);
- }, randomNumber(5, 15) * 1000);
- played = true;
- break;
- }
- if (cards[i].substr(1, 2) === '+2' && type === '+2') {
- console.log('top card +2; playing our +2 (no colour match)');
- setTimeout(function () {
- app.send('/uno play ' + cards[i], id);
- }, randomNumber(5, 15) * 1000);
- played = true;
- break;
- }
- if (cards[i].charAt(1) === type) { // matching numbers
- console.log('uno: (' + cards[i] + ') (' + type + ')');
- setTimeout(function () {
- app.send('/uno play ' + cards[i], id);
- }, randomNumber(5, 15) * 1000);
- played = true;
- break;
- }
- }
- for (var o in cards) {
- console.log('uno wildcard played');
- if (cards[i] === 'W+4' || cards[i] === 'WW') { // we have a wildcard; play it
- console.log('uno: we have +4; playing it');
- var changeTo = 'R';
- for (var c in cards) {
- if (cards[c].charAt(0) in ['R', 'B', 'G', 'Y']) changeTo = cards[c].charAt(0);
- }
- setTimeout(function () {
- app.send('/uno play ' + cards[i] + ' ' + changeTo, id);
- }, randomNumber(5, 15) * 1000);
- played = true;
- break;
- }
- }
- if (!played) {
- if (!drawn) {
- setTimeout(function () {
- app.send('/uno draw', id);
- }, randomNumber(5, 15) * 1000);
- } else {
- setTimeout(function () {
- app.send('/uno pass', id);
- }, randomNumber(3, 7) * 1000);
- }
- }
- }
- function randomNumber(min, max) {
- return Math.floor(Math.random() * (max - min + 1) + min);
- }
- function randomString(length) {
- return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
- }
- function addGlobalStyle(css) {
- var head, style;
- head = document.getElementsByTagName('head')[0];
- if (!head) { return; }
- style = document.createElement('style');
- style.type = 'text/css';
- style.innerHTML = css;
- head.appendChild(style);
- }
Add Comment
Please, Sign In to add comment