diff --git a/src/js/irc.js b/src/js/irc.js index 4458547..892ea81 100644 --- a/src/js/irc.js +++ b/src/js/irc.js @@ -538,6 +538,7 @@ class IRCConnectionHandler { case 'MODE': let isChannelMode = false let method = '+' + let lts = line.trailing ? line.trailing.split(' ') : [] if (line.arguments[0].indexOf('#') !== -1) { isChannelMode = true } @@ -560,12 +561,17 @@ class IRCConnectionHandler { if (isChannelMode) { for (let i in modes) { let mode = modes[i] + let modei = parseInt(i) if (this.conn.data.supportedModes[mode]) { this.conn.emit('fromServer', { type: 'mode' + (method === '+' ? 'Add' : 'Del'), target: line.arguments[0], mode: mode, - modeTarget: line.arguments[2 + parseInt(i)], + modeTarget: line.arguments[2] + ? (line.arguments[2 + modei] + ? line.arguments[2 + modei] + : lts[modei - 1]) + : lts[modei], server: serverName, user: { nickname: sender @@ -596,11 +602,38 @@ class IRCConnectionHandler { this.conn.write('NICK ' + newNick) this.conn.config.nickname = newNick break + case '352': + // who query response + // [*][@|+] : + if (!this.conn.queue.who) { + this.conn.queue.who = [] + } + this.conn.queue.who.push({ + channel: line.arguments[1], + server: line.arguments[4], + modes: line.arguments[6], + hopcount: line.trailing.split(' ')[0], + hostmask: format('%s@%s', line.arguments[2], line.arguments[3]), + nickname: line.arguments[5], + realname: line.trailing.split(' ').slice(1).join(' ') + }) + break + case '315': + this.conn.emit('fromServer', { + type: 'whoResponse', + who: this.conn.queue.who, + target: line.arguments[1], + message: line.trailing, + server: serverName, + from: realServerName + }) + delete this.conn.queue.who + break case '311': // start whois queue list = { nickname: line.arguments[1], - hostmask: format('%s!%s@%s', line.arguments[1], line.arguments[2], line.arguments[3]), + hostmask: format('%s@%s', line.arguments[2], line.arguments[3]), realname: line.trailing || '' } this.whoisManage(line.arguments[1], list) diff --git a/src/js/main.js b/src/js/main.js index 5b0fb46..7d4af28 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -175,6 +175,63 @@ function whoisMessage (whoisData, buffer) { } } +const whoQueue = {} +/* +function queryChannelMembers (server, channel) { + whoQueue[channel] = true + sendToServer(server, { command: 'who', arguments: [channel] }) +} +*/ + +function whoResponse (data, buffer) { + let srv = irc.chat.getChatBuffersByServer(data.from) + let channels = [] + for (let i in srv) { + let j = srv[i] + if (j.type === 'channel' && j.name === data.target) { + channels.push(j) + } + } + + if (channels.length > 0) { + for (let c in channels) { + let chan = channels[c] + if (!chan.nicklist) continue + for (let i in data.who) { + let who = data.who[i] + chan.nicklist.setModesFromString(who.modes, who.nickname) + } + } + } + + // Send message to buffer + if (whoQueue[data.target]) { + delete whoQueue[data.target] + return + } + + let messages = [] + for (let i in data.who) { + let dt = data.who[i] + messages.push( + sf('[%s] %s %s %s %s (%s)', + span(dt.channel, ['channel']), + span(dt.nickname, ['nick']), + span(dt.hostmask, ['hostmask']), + dt.modes, + dt.hopcount, + validators.escapeHTML(dt.realname) + ) + ) + } + + messages.push(sf('[%s] %s', span(data.target, [(data.target.indexOf('#') === 0 ? 'channel' : 'nick')]), data.message)) + + for (let i in messages) { + buffer.addMessage(messages[i], null, 'whois') + } +} + const asterisk = span('ℹ', ['asterisk']) const arrowout = span('⬅', ['arrowout']) const arrowin = span('➡', ['arrowin']) @@ -567,15 +624,20 @@ let commands = { whois: { execute: function (buffer, handler, command, message, listargs) { - if (!listargs[1]) { - return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!') - } - + if (!listargs[1]) return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!') sendToServer(buffer.server, { command: 'whois', message: '', arguments: [listargs[1]] }) }, description: ' - Display information about a user.' }, + who: { + execute: function (buffer, handler, command, message, listargs) { + if (!listargs[1]) listargs[1] = buffer.name + sendToServer(buffer.server, { command: 'who', arguments: [listargs[1]] }) + }, + description: '[] - Display some information.' + }, + connect: { execute: function (buffer, handler, command, message, listargs) { clientdom.connector.frame.style.display = 'block' @@ -595,9 +657,7 @@ let commands = { help: { execute: function (buffer, handler, command, message, listargs) { - if (!listargs[1]) { - return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!') - } + if (!listargs[1]) return handler.commandError(buffer, listargs[0].toUpperCase() + ': Missing parameters!') let cmd = listargs[1].toLowerCase() if (cmd.indexOf('/') === 0) { @@ -692,6 +752,11 @@ class Nicklist { clientdom.nicklist.appendChild(str) } + reset () { + this.nicks = [] + this.simplifiedNicksList = [] + } + render () { if (!this.buffer.active) return if (!irc.serverData[this.buffer.server]) return @@ -758,6 +823,20 @@ class Nicklist { return result } + highestPriorityMode (modes) { + let highest = null + let modeTranslations = irc.serverData[this.buffer.server].modeTranslation + + for (let mode in modeTranslations) { + if (modes.indexOf(mode) !== -1) { + highest = mode + break + } + } + + return { highest, prefix: highest ? modeTranslations[highest] : null } + } + modeAdded (nickname, newMode) { let nickIndex = this.getNickIndex(nickname) let nick = null @@ -768,25 +847,11 @@ class Nicklist { return } - let modeTranslations = irc.serverData[this.buffer.server].modeTranslation - let prefixes = irc.serverData[this.buffer.server].supportedPrefixes - + // Add mode to nicks' modes list nick.modes.push(newMode) - for (let mode in modeTranslations) { - let prefix = modeTranslations[mode] - if (nick.modes.indexOf(mode) === -1) continue - let a = nick.modes.indexOf(mode) - 1 - if (a >= 0) { - if (prefixes.indexOf(modeTranslations[nick.modes[a]]) < prefixes.indexOf(prefix)) { - nick.prefix = modeTranslations[nick.modes[a]] - break - } - } else { - nick.prefix = prefix - break - } - } + // Find the prefix to give to the nick + nick.prefix = this.highestPriorityMode(nick.modes).prefix || '' this.render() } @@ -801,29 +866,37 @@ class Nicklist { return } - let modeTranslations = irc.serverData[this.buffer.server].modeTranslation - let prefixes = irc.serverData[this.buffer.server].supportedPrefixes - + // Remove mode from nicks' modes list removeStr(nick.modes, oldMode) - let currentLowest = '' + // Find the prefix to give to the nick + nick.prefix = this.highestPriorityMode(nick.modes).prefix || '' - for (let n in nick.modes) { - let mode = nick.modes[n] - let nextMode = nick.modes[n + 1] - if (!nextMode && mode) { - currentLowest = modeTranslations[mode] - break - } else if (nextMode) { - if (prefixes.indexOf(modeTranslations[nextMode]) > prefixes.indexOf(modeTranslations[mode])) { - currentLowest = modeTranslations[nextMode] + this.render() + } + + setModesFromString (str, nickname) { + if (this.getNickIndex(nickname) === null) return + + let spfx = irc.serverData[this.buffer.server].modeTranslation + let modes = [] + let split = str.split('') + for (let i in split) { + let char = split[i] + if (char === 'H' || char === 'G' || char === '*' || char === 's') continue + for (let mode in spfx) { + let prefix = spfx[mode] + if (char === prefix) { + modes.push(mode) + break } - } else { - break } } - nick.prefix = currentLowest + let nick = this.nicks[this.getNickIndex(nickname)] + + nick.modes = modes + nick.prefix = this.highestPriorityMode(nick.modes).prefix || '' this.render() } @@ -958,9 +1031,9 @@ class ChatBuffer { if (this.topic != null && this.topic !== '') { addClass(clientdom.chat, 'vtopic') if (irc.config.colors) { - clientdom.topicbar.innerHTML = processors.linkify(processors.channelify(colorizer.stylize(this.topic))) + clientdom.topicbar.innerHTML = processors.channelify(processors.linkify(colorizer.stylize(this.topic))) } else { - clientdom.topicbar.innerHTML = processors.linkify(processors.channelify(colorizer.strip(this.topic))) + clientdom.topicbar.innerHTML = processors.channelify(processors.linkify(colorizer.strip(this.topic))) } } @@ -1400,6 +1473,9 @@ class ConnectionHandler { case 'whoisResponse': whoisMessage(data.whois, irc.chat.getActiveChatBuffer()) break + case 'whoResponse': + whoResponse(data, irc.chat.getActiveChatBuffer()) + break case 'listedChannel': irc.chat.messageChatBuffer(server, server, { @@ -2020,6 +2096,8 @@ class IRCChatWindow { let channelSendNicks = [] + buf.nicklist.reset() + for (let n in nicks) { let nick = { nickname: '', prefix: '', modes: [] } diff --git a/src/server/logger.js b/src/server/logger.js index 7f61edd..9d65148 100644 --- a/src/server/logger.js +++ b/src/server/logger.js @@ -1,5 +1,5 @@ import util from 'util' -import config from './config' +import config from '../globals' module.exports.log = function () { console.log.apply(null, arguments)