forked from keinBot/cuffeo
test
This commit is contained in:
196
src/clients/irc.mjs
Normal file
196
src/clients/irc.mjs
Normal file
@@ -0,0 +1,196 @@
|
||||
import { logger } from "../inc/log";
|
||||
import { getLevel } from "../inc/admin";
|
||||
|
||||
import modules from "./irc/index";
|
||||
|
||||
import net from "net";
|
||||
import tls from "tls";
|
||||
import EventEmitter from "events";
|
||||
|
||||
const colors = {
|
||||
red: "\x0304$1\x0304",
|
||||
blue: "\x0312$1\x0312",
|
||||
yellow: "\x0308$1\x0308"
|
||||
};
|
||||
const msgmodes = {
|
||||
normal: "PRIVMSG {recipient} :{msg}",
|
||||
action: "PRIVMSG {recipient} :\u0001ACTION {msg}\u0001",
|
||||
notice: "NOTICE {recipient} :{msg}"
|
||||
};
|
||||
|
||||
const replaceColor = (match, color, text) => {
|
||||
if (colors.hasOwnProperty(color))
|
||||
return colors[color].replace("\$1", text);
|
||||
return text;
|
||||
};
|
||||
|
||||
export class irc extends EventEmitter {
|
||||
constructor(options) {
|
||||
super();
|
||||
this.options = options || {};
|
||||
this.options.channels = this.options.channels || [];
|
||||
this.options.host = this.options.host || "127.0.0.1";
|
||||
this.options.port = this.options.port || 6667;
|
||||
this.options.ssl = this.options.ssl || false;
|
||||
this.options.selfSigned = this.options.selfSigned || false;
|
||||
this.options.sasl = this.options.sasl || false;
|
||||
this.network = this.options.network || "test";
|
||||
this.nickname = this.options.nickname || "test";
|
||||
this.username = this.options.username || "test";
|
||||
this.realname = this.options.realname || "test";
|
||||
this.channels = this.options.channels || [];
|
||||
this.set = this.options.set || "all";
|
||||
this._recachetime = 60 * 30; // 30 minutes
|
||||
this._cmd = new Map();
|
||||
|
||||
modules.forEach(mod => mod(this));
|
||||
|
||||
this.server = {
|
||||
set: this.set,
|
||||
motd: "",
|
||||
debug: false,
|
||||
me: {},
|
||||
channel: [],
|
||||
user: new Map()
|
||||
};
|
||||
this.socket = (this.options.ssl ? tls : net).connect({
|
||||
host: this.options.host,
|
||||
port: this.options.port,
|
||||
rejectUnauthorized: !this.options.selfSigned
|
||||
}, () => {
|
||||
this.send(`NICK ${this.nickname}`);
|
||||
this.send(`USER ${this.username} 0 * : ${this.realname}`);
|
||||
if(this.options.sasl)
|
||||
this.send("CAP LS");
|
||||
});
|
||||
this.socket.setEncoding("utf-8");
|
||||
this.socket.on("data", msg => {
|
||||
msg.split(/\r?\n|\r/).filter(tmp => tmp.length > 0).forEach(tmp => {
|
||||
const cmd = this.parse(tmp);
|
||||
if (this._cmd.has(cmd.command))
|
||||
this._cmd.get(cmd.command)(cmd);
|
||||
})
|
||||
});
|
||||
}
|
||||
send(data) {
|
||||
this.socket.write(`${data}\n`);
|
||||
logger.debug(`(${this.network}) out: ${data}`);
|
||||
}
|
||||
sendmsg(mode, recipient, msg) {
|
||||
msg = msg.split(/\r?\n/);
|
||||
if(msg.length > 6)
|
||||
return false;
|
||||
msg.forEach(e => {
|
||||
this.send( msgmodes[mode].replace("{recipient}", recipient).replace("{msg}", e) );
|
||||
});
|
||||
}
|
||||
parse(data, [a, ...b] = data.split(/ +:/)) {
|
||||
let tmp = a.split(" ").concat(b);
|
||||
logger.debug(`(${this.network}) in: ${[...tmp]}`);
|
||||
return data.charAt(0) === ":" ? {
|
||||
prefix: tmp.shift(),
|
||||
command: tmp.shift(),
|
||||
params: tmp
|
||||
} : {
|
||||
prefix: null,
|
||||
command: tmp.shift(),
|
||||
params: tmp
|
||||
};
|
||||
}
|
||||
reply(tmp) {
|
||||
return {
|
||||
type: "irc",
|
||||
network: this.network,
|
||||
channel: tmp.params[0],
|
||||
channelid: tmp.params[0],
|
||||
user: Object.assign(this.parsePrefix(tmp.prefix), {
|
||||
account: this.server.user.geti(this.parsePrefix(tmp.prefix).nick).account,
|
||||
prefix: tmp.prefix.charAt(0) === ":" ? tmp.prefix.substring(1) : tmp.prefix,
|
||||
level: getLevel(this.network, Object.assign(this.parsePrefix(tmp.prefix), {
|
||||
account: this.server.user.geti(this.parsePrefix(tmp.prefix).nick).account,
|
||||
prefix: tmp.prefix.charAt(0) === ":" ? tmp.prefix.substring(1) : tmp.prefix
|
||||
}))
|
||||
}),
|
||||
message: tmp.params[1],
|
||||
time: ~~(Date.now() / 1000),
|
||||
raw: tmp,
|
||||
reply: msg => this.sendmsg("normal", tmp.params[0], this.format(""+msg)),
|
||||
replyAction: msg => this.sendmsg("action", tmp.params[0], this.format(""+msg)),
|
||||
replyNotice: msg => this.sendmsg("notice", tmp.params[0], this.format(""+msg)),
|
||||
self: this.server,
|
||||
_chan: this.server.channel[tmp.params[0]],
|
||||
_user: this.server.user,
|
||||
_cmd: this._cmd,
|
||||
join: chan => this.join(chan),
|
||||
part: (chan, msg) => this.part(chan, msg),
|
||||
whois: user => this.whois(user),
|
||||
write: msg => this.send(msg),
|
||||
socket: this.socket
|
||||
};
|
||||
}
|
||||
join(channel) {
|
||||
this.send(`JOIN ${(typeof channel === "object") ? channel.join(",") : channel}`);
|
||||
}
|
||||
part(channel, msg=false) {
|
||||
this.send(`PART ${(typeof channel === "object") ? channel.join(",") : channel}${msg ? " " + msg : " part"}`);
|
||||
}
|
||||
whois(user, force = false) {
|
||||
user = user.toLowerCase();
|
||||
let tmpuser = {};
|
||||
if(this.server.user.hasi(user) && !force) {
|
||||
tmpuser = this.server.user.geti(user);
|
||||
if(tmpuser.cached >= ~~(Date.now() / 1000) - this._recachetime)
|
||||
return;
|
||||
}
|
||||
|
||||
tmpuser = {
|
||||
nickname: tmpuser.nickname || false,
|
||||
username: tmpuser.username || false,
|
||||
hostname: tmpuser.hostname || false,
|
||||
realname: tmpuser.realname || false,
|
||||
account: tmpuser.account || false,
|
||||
prefix: tmpuser.prefix || false,
|
||||
registered: tmpuser.registered || false,
|
||||
oper: tmpuser.oper || false,
|
||||
channels: tmpuser.channels || [],
|
||||
cached: ~~(Date.now() / 1000)
|
||||
};
|
||||
this.server.user.set(user, tmpuser);
|
||||
this.send(`WHOIS ${user}`);
|
||||
}
|
||||
parsePrefix(prefix) {
|
||||
prefix = /:?(.*)\!(.*)@(.*)/.exec(prefix);
|
||||
if(!prefix)
|
||||
return false; //this.parsePrefix(arguments);
|
||||
return {
|
||||
nick: prefix[1],
|
||||
username: prefix[2],
|
||||
hostname: prefix[3]
|
||||
};
|
||||
}
|
||||
format(msg) {
|
||||
return msg
|
||||
.replace(/\[b\](.*?)\[\/b\]/g, "\x02$1\x02") // bold
|
||||
.replace(/\[i\](.*?)\[\/i\]/g, "\x1D$1\x1D") // italic
|
||||
.replace(/\[color=(.*?)](.*?)\[\/color\]/g, replaceColor) // colors
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
Map.prototype.hasi = function(val) {
|
||||
for (let [key] of this)
|
||||
if(key.toLowerCase() === val.toLowerCase())
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
Map.prototype.geti = function(val) {
|
||||
for (let [key, value] of this)
|
||||
if(key.toLowerCase() === val.toLowerCase())
|
||||
return value;
|
||||
return false;
|
||||
};
|
||||
Map.prototype.deli = function(val) {
|
||||
for (let [key] of this)
|
||||
if(key.toLowerCase() === val.toLowerCase())
|
||||
this.delete(key);
|
||||
};
|
||||
Reference in New Issue
Block a user