@@ -0,0 +1,500 @@
|
||||
/** Slash-command table for /bin/irc (modern client + common aliases). */
|
||||
|
||||
var BARE_IRC_FEATURED_ROOMS = [
|
||||
{ name: '#libera', users: '', topic: 'Official Libera.Chat help' },
|
||||
{ name: '#linux', users: '', topic: 'Linux discussion' },
|
||||
{ name: '#programming', users: '', topic: 'Programming' },
|
||||
{ name: '#javascript', users: '', topic: 'JavaScript' },
|
||||
{ name: '#python', users: '', topic: 'Python' },
|
||||
{ name: '#rust', users: '', topic: 'Rust' },
|
||||
{ name: '#archlinux', users: '', topic: 'Arch Linux' },
|
||||
{ name: '#debian', users: '', topic: 'Debian' },
|
||||
{ name: '#ubuntu', users: '', topic: 'Ubuntu' },
|
||||
{ name: '#vim', users: '', topic: 'Vim' },
|
||||
{ name: '#emacs', users: '', topic: 'Emacs' },
|
||||
{ name: '#git', users: '', topic: 'Git' }
|
||||
]
|
||||
|
||||
function bareIrcNeedTarget(buf) {
|
||||
return buf && buf.kind && buf.kind !== 'server' ? buf.name : ''
|
||||
}
|
||||
|
||||
function bareIrcModeNicks(client, chan, flag, nicks) {
|
||||
if (!chan || !nicks.length) return false
|
||||
var i
|
||||
for (i = 0; i < nicks.length; i++) {
|
||||
client.sendRaw('MODE', [chan, flag, nicks[i]])
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function bareIrcRunSlash(client, rawLine, opts) {
|
||||
opts = opts || {}
|
||||
var buf = opts.buf || null
|
||||
var ctx = opts.ctx
|
||||
var line = String(rawLine || '').trim()
|
||||
var out = {
|
||||
ok: true,
|
||||
help: false,
|
||||
rooms: false,
|
||||
roomsQuery: '',
|
||||
quit: false,
|
||||
close: false,
|
||||
clear: false,
|
||||
usage: '',
|
||||
note: ''
|
||||
}
|
||||
if (!line || line.charAt(0) !== '/') {
|
||||
out.ok = false
|
||||
return out
|
||||
}
|
||||
var body = line.slice(1)
|
||||
var sp = body.search(/\s/)
|
||||
var cmd = (sp < 0 ? body : body.slice(0, sp)).toLowerCase()
|
||||
var rest = sp < 0 ? '' : body.slice(sp + 1).trim()
|
||||
var parts = rest ? rest.split(/\s+/) : []
|
||||
var chan = bareIrcNeedTarget(buf)
|
||||
|
||||
if (cmd === 'help' || cmd === 'h' || cmd === '?') {
|
||||
out.help = true
|
||||
return out
|
||||
}
|
||||
if (cmd === 'quit' || cmd === 'exit') {
|
||||
client.quit(rest || 'Leaving')
|
||||
out.quit = true
|
||||
return out
|
||||
}
|
||||
if (cmd === 'disconnect') {
|
||||
client.quit(rest || 'Disconnect')
|
||||
return out
|
||||
}
|
||||
if (cmd === 'reconnect') {
|
||||
if (opts.reconnect) opts.reconnect()
|
||||
else out.note = 'reconnect unavailable'
|
||||
return out
|
||||
}
|
||||
if (cmd === 'join' || cmd === 'j') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/join #channel [key]'
|
||||
return out
|
||||
}
|
||||
client.join(parts[0], parts[1])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'part' || cmd === 'leave') {
|
||||
var pchan = parts[0] && parts[0].charAt(0) === '#' ? parts.shift() : chan
|
||||
if (!pchan) {
|
||||
out.usage = '/part [#channel] [reason]'
|
||||
return out
|
||||
}
|
||||
client.part(pchan, parts.join(' '))
|
||||
return out
|
||||
}
|
||||
if (cmd === 'cycle' || cmd === 'hop') {
|
||||
var cchan = parts[0] || chan
|
||||
if (!cchan) {
|
||||
out.usage = '/cycle [#channel]'
|
||||
return out
|
||||
}
|
||||
client.part(cchan, 'cycling')
|
||||
client.join(cchan)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'query' || cmd === 'q') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/query NICK [text]'
|
||||
return out
|
||||
}
|
||||
var qb = bareIrcEnsureBuffer(client.state, 'query', parts[0])
|
||||
client.state.currentId = qb.id
|
||||
if (parts.slice(1).join(' '))
|
||||
client.sendPrivmsg(parts[0], parts.slice(1).join(' '))
|
||||
return out
|
||||
}
|
||||
if (cmd === 'msg' || cmd === 'privmsg' || cmd === 'm') {
|
||||
if (!parts[0] || !parts.slice(1).join(' ')) {
|
||||
out.usage = '/msg TARGET text'
|
||||
return out
|
||||
}
|
||||
client.sendPrivmsg(parts[0], parts.slice(1).join(' '))
|
||||
return out
|
||||
}
|
||||
if (cmd === 'notice') {
|
||||
if (!parts[0] || !parts.slice(1).join(' ')) {
|
||||
out.usage = '/notice TARGET text'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('NOTICE', [parts[0], parts.slice(1).join(' ')])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'nick') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/nick NEWNICK'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('NICK', [parts[0]])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'whois') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/whois NICK'
|
||||
return out
|
||||
}
|
||||
client.sendRaw(
|
||||
'WHOIS',
|
||||
parts.length > 1 ? [parts[0], parts[1]] : [parts[0]]
|
||||
)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'whowas') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/whowas NICK'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('WHOWAS', [parts[0]])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'who') {
|
||||
client.sendRaw('WHO', [parts[0] || chan || '*'])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'names') {
|
||||
client.sendRaw('NAMES', [parts[0] || chan || ''].filter(Boolean))
|
||||
return out
|
||||
}
|
||||
if (cmd === 'topic') {
|
||||
var tchan = chan
|
||||
var topic = rest
|
||||
if (
|
||||
parts[0] &&
|
||||
(parts[0].charAt(0) === '#' || parts[0].charAt(0) === '&')
|
||||
) {
|
||||
tchan = parts[0]
|
||||
topic = parts.slice(1).join(' ')
|
||||
}
|
||||
if (!tchan) {
|
||||
out.usage = '/topic [#channel] [text]'
|
||||
return out
|
||||
}
|
||||
if (topic) client.sendRaw('TOPIC', [tchan, topic])
|
||||
else client.sendRaw('TOPIC', [tchan])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'me' || cmd === 'action') {
|
||||
if (!rest || !chan) {
|
||||
out.usage = '/me action text (in a channel or query)'
|
||||
return out
|
||||
}
|
||||
client.sendPrivmsg(chan, '\x01ACTION ' + rest + '\x01')
|
||||
return out
|
||||
}
|
||||
if (cmd === 'away') {
|
||||
client.sendRaw('AWAY', rest ? [rest] : [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'back') {
|
||||
client.sendRaw('AWAY', [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'quote' || cmd === 'raw') {
|
||||
if (!rest) {
|
||||
out.usage = '/quote COMMAND [params]'
|
||||
return out
|
||||
}
|
||||
var qparts = rest.split(/\s+/)
|
||||
client.sendRaw(qparts[0], qparts.slice(1))
|
||||
return out
|
||||
}
|
||||
if (cmd === 'list' || cmd === 'rooms' || cmd === 'browse') {
|
||||
out.rooms = true
|
||||
out.roomsQuery = rest
|
||||
return out
|
||||
}
|
||||
if (cmd === 'motd') {
|
||||
client.sendRaw('MOTD', parts[0] ? [parts[0]] : [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'lusers') {
|
||||
client.sendRaw('LUSERS', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'admin') {
|
||||
client.sendRaw('ADMIN', parts[0] ? [parts[0]] : [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'info') {
|
||||
client.sendRaw('INFO', parts[0] ? [parts[0]] : [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'time') {
|
||||
client.sendRaw('TIME', parts[0] ? [parts[0]] : [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'links') {
|
||||
client.sendRaw('LINKS', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'map') {
|
||||
client.sendRaw('MAP', [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'rules') {
|
||||
client.sendRaw('RULES', [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'stats') {
|
||||
client.sendRaw('STATS', parts[0] ? parts : ['u'])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'version') {
|
||||
if (parts[0] && parts[0].charAt(0) !== '#') {
|
||||
client.sendRaw('PRIVMSG', [parts[0], '\x01VERSION\x01'])
|
||||
return out
|
||||
}
|
||||
client.sendRaw('VERSION', parts[0] ? [parts[0]] : [])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'userhost') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/userhost NICK [NICK...]'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('USERHOST', parts.slice(0, 5))
|
||||
return out
|
||||
}
|
||||
if (cmd === 'ison') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/ison NICK [NICK...]'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('ISON', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'mode') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/mode TARGET [modes] [args]'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('MODE', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'umode') {
|
||||
client.sendRaw(
|
||||
'MODE',
|
||||
[client.state.nick].concat(parts.length ? parts : [])
|
||||
)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'kick') {
|
||||
var kchan = chan
|
||||
var knick = parts[0]
|
||||
var kreason = parts.slice(1).join(' ')
|
||||
if (
|
||||
parts[0] &&
|
||||
(parts[0].charAt(0) === '#' || parts[0].charAt(0) === '&')
|
||||
) {
|
||||
kchan = parts[0]
|
||||
knick = parts[1]
|
||||
kreason = parts.slice(2).join(' ')
|
||||
}
|
||||
if (!kchan || !knick) {
|
||||
out.usage = '/kick [channel] NICK [reason]'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('KICK', kreason ? [kchan, knick, kreason] : [kchan, knick])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'invite') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/invite NICK [#channel]'
|
||||
return out
|
||||
}
|
||||
var ichan = parts[1] || chan
|
||||
if (!ichan) {
|
||||
out.usage = '/invite NICK #channel'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('INVITE', [parts[0], ichan])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'ban') {
|
||||
if (!chan) {
|
||||
out.usage = '/ban [mask] (in a channel)'
|
||||
return out
|
||||
}
|
||||
if (!parts[0]) client.sendRaw('MODE', [chan, '+b'])
|
||||
else client.sendRaw('MODE', [chan, '+b', parts[0]])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'unban') {
|
||||
if (!chan || !parts[0]) {
|
||||
out.usage = '/unban mask (in a channel)'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('MODE', [chan, '-b', parts[0]])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'op') {
|
||||
if (!chan || !parts[0]) {
|
||||
out.usage = '/op NICK [NICK...] (in a channel)'
|
||||
return out
|
||||
}
|
||||
bareIrcModeNicks(client, chan, '+o', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'deop') {
|
||||
if (!chan || !parts[0]) {
|
||||
out.usage = '/deop NICK [NICK...]'
|
||||
return out
|
||||
}
|
||||
bareIrcModeNicks(client, chan, '-o', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'voice') {
|
||||
if (!chan || !parts[0]) {
|
||||
out.usage = '/voice NICK [NICK...]'
|
||||
return out
|
||||
}
|
||||
bareIrcModeNicks(client, chan, '+v', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'devoice') {
|
||||
if (!chan || !parts[0]) {
|
||||
out.usage = '/devoice NICK [NICK...]'
|
||||
return out
|
||||
}
|
||||
bareIrcModeNicks(client, chan, '-v', parts)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'knock') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/knock #channel [message]'
|
||||
return out
|
||||
}
|
||||
client.sendRaw(
|
||||
'KNOCK',
|
||||
parts.slice(1).join(' ')
|
||||
? [parts[0], parts.slice(1).join(' ')]
|
||||
: [parts[0]]
|
||||
)
|
||||
return out
|
||||
}
|
||||
if (cmd === 'ctcp') {
|
||||
if (!parts[0] || !parts[1]) {
|
||||
out.usage = '/ctcp NICK CMD [args]'
|
||||
return out
|
||||
}
|
||||
var ctcp =
|
||||
parts[1].toUpperCase() +
|
||||
(parts.slice(2).join(' ') ? ' ' + parts.slice(2).join(' ') : '')
|
||||
client.sendRaw('PRIVMSG', [parts[0], '\x01' + ctcp + '\x01'])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'ping') {
|
||||
if (parts[0]) {
|
||||
client.sendRaw('PRIVMSG', [parts[0], '\x01PING ' + Date.now() + '\x01'])
|
||||
} else {
|
||||
client.sendRaw('PING', [client.state.nick || 'irc'])
|
||||
}
|
||||
return out
|
||||
}
|
||||
if (cmd === 'ignore') {
|
||||
if (!parts[0]) {
|
||||
var keys = Object.keys(client.state.ignore || {})
|
||||
out.note = keys.length
|
||||
? 'ignoring: ' + keys.join(', ')
|
||||
: 'ignore list empty'
|
||||
return out
|
||||
}
|
||||
if (!client.state.ignore) client.state.ignore = {}
|
||||
client.state.ignore[
|
||||
bareIrcCasemap(parts[0], bareIrcCasemapping(client.state.isupport))
|
||||
] = parts[0]
|
||||
out.note = 'ignoring ' + parts[0]
|
||||
return out
|
||||
}
|
||||
if (cmd === 'unignore') {
|
||||
if (!parts[0]) {
|
||||
out.usage = '/unignore NICK'
|
||||
return out
|
||||
}
|
||||
if (client.state.ignore) {
|
||||
delete client.state.ignore[
|
||||
bareIrcCasemap(parts[0], bareIrcCasemapping(client.state.isupport))
|
||||
]
|
||||
}
|
||||
out.note = 'unignored ' + parts[0]
|
||||
return out
|
||||
}
|
||||
if (cmd === 'clear') {
|
||||
out.clear = true
|
||||
return out
|
||||
}
|
||||
if (cmd === 'close' || cmd === 'wc') {
|
||||
out.close = true
|
||||
return out
|
||||
}
|
||||
if (cmd === 'win' || cmd === 'buffer' || cmd === 'window') {
|
||||
var n = parseInt(parts[0], 10)
|
||||
var list = bareIrcListBuffers(client.state)
|
||||
if (n >= 1 && n <= list.length) client.state.currentId = list[n - 1].id
|
||||
else out.usage = '/win N (1–' + list.length + ')'
|
||||
return out
|
||||
}
|
||||
if (cmd === 'p2p') {
|
||||
if (parts[0] === 'open' && parts[1]) {
|
||||
var name = String(parts[1])
|
||||
if (name.indexOf('[p2p]') < 0) name = name + ' [p2p]'
|
||||
var pb = bareIrcEnsureBuffer(client.state, 'p2p', name)
|
||||
client.state.currentId = pb.id
|
||||
bareIrcPushLine(client.state, pb, {
|
||||
atMs: Date.now(),
|
||||
kind: 'info',
|
||||
text: 'Shadow room — not Libera. Messages stay on the swarm sideband.'
|
||||
})
|
||||
if (ctx && typeof ctx.bareOsIrcShadowOpen === 'function') {
|
||||
try {
|
||||
ctx.bareOsIrcShadowOpen(parts[1])
|
||||
} catch (e) {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
out.usage = '/p2p open #name'
|
||||
return out
|
||||
}
|
||||
if (cmd === 'oper') {
|
||||
if (parts.length < 2) {
|
||||
out.usage = '/oper USER PASS'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('OPER', [parts[0], parts[1]])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'squery') {
|
||||
if (!parts[0] || !parts.slice(1).join(' ')) {
|
||||
out.usage = '/squery SERVICE text'
|
||||
return out
|
||||
}
|
||||
client.sendRaw('SQUERY', [parts[0], parts.slice(1).join(' ')])
|
||||
return out
|
||||
}
|
||||
if (cmd === 'set') {
|
||||
out.note = 'config is ~/.irc/config.json (nick, autojoin, saslUser)'
|
||||
return out
|
||||
}
|
||||
if (cmd === 'server') {
|
||||
out.note =
|
||||
(client.state.network || 'irc') +
|
||||
' ' +
|
||||
(client.opts.host || '') +
|
||||
':' +
|
||||
(client.opts.port || '')
|
||||
return out
|
||||
}
|
||||
|
||||
out.ok = false
|
||||
out.usage = 'unknown command /' + cmd + ' try /help'
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user