Add WHO handing, fix nicklist prefixing

This commit is contained in:
Evert Prants 2020-02-08 15:31:01 +02:00
parent 4067ea31e0
commit 2db9b22cbf
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
3 changed files with 156 additions and 45 deletions

View File

@ -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
// <channel> <user> <host> <server> <nick> <H|G>[*][@|+] :<hopcount> <real_name>
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)

View File

@ -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]&nbsp;%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]&nbsp;%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('&#8505;', ['asterisk'])
const arrowout = span('&#11013;', ['arrowout'])
const arrowin = span('&#10145;', ['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: '<nickname> - 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: '[<target>] - 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()
}
} else {
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
}
}
}
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: [] }

View File

@ -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)