forked from CringeStudios/gamja
Add support for WHOX
This allows querying the account of the user.
This commit is contained in:
parent
0b32d9295a
commit
329f9063d0
@ -585,8 +585,7 @@ export default class App extends Component {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
this.createBuffer(serverID, buf.name);
|
this.createBuffer(serverID, buf.name);
|
||||||
client.who(buf.name);
|
this.whoUserBuffer(buf.name, serverID);
|
||||||
client.monitor(buf.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastReceipt = this.latestReceipt(ReceiptType.DELIVERED);
|
let lastReceipt = this.latestReceipt(ReceiptType.DELIVERED);
|
||||||
@ -853,6 +852,15 @@ export default class App extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
whoUserBuffer(target, serverID) {
|
||||||
|
let client = this.clients.get(serverID);
|
||||||
|
|
||||||
|
client.who(target, {
|
||||||
|
fields: ["flags", "hostname", "nick", "realname", "username", "account"],
|
||||||
|
});
|
||||||
|
client.monitor(target);
|
||||||
|
}
|
||||||
|
|
||||||
open(target, serverID) {
|
open(target, serverID) {
|
||||||
if (!serverID) {
|
if (!serverID) {
|
||||||
serverID = State.getActiveServerID(this.state);
|
serverID = State.getActiveServerID(this.state);
|
||||||
@ -865,8 +873,7 @@ export default class App extends Component {
|
|||||||
this.switchToChannel = target;
|
this.switchToChannel = target;
|
||||||
client.send({ command: "JOIN", params: [target] });
|
client.send({ command: "JOIN", params: [target] });
|
||||||
} else {
|
} else {
|
||||||
client.who(target);
|
this.whoUserBuffer(target, serverID);
|
||||||
client.monitor(target);
|
|
||||||
this.createBuffer(serverID, target);
|
this.createBuffer(serverID, target);
|
||||||
this.switchBuffer({ server: serverID, name: target });
|
this.switchBuffer({ server: serverID, name: target });
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,21 @@ const NORMAL_CLOSURE = 1000;
|
|||||||
const GOING_AWAY = 1001;
|
const GOING_AWAY = 1001;
|
||||||
const UNSUPPORTED_DATA = 1003;
|
const UNSUPPORTED_DATA = 1003;
|
||||||
|
|
||||||
|
// See https://github.com/quakenet/snircd/blob/master/doc/readme.who
|
||||||
|
// Sorted by order of appearance in RPL_WHOSPCRPL
|
||||||
|
const WHOX_FIELDS = {
|
||||||
|
"channel": "c",
|
||||||
|
"username": "u",
|
||||||
|
"hostname": "h",
|
||||||
|
"server": "s",
|
||||||
|
"nick": "n",
|
||||||
|
"flags": "f",
|
||||||
|
"account": "a",
|
||||||
|
"realname": "r",
|
||||||
|
};
|
||||||
|
|
||||||
let lastLabel = 0;
|
let lastLabel = 0;
|
||||||
|
let lastWhoxToken = 0;
|
||||||
|
|
||||||
export default class Client extends EventTarget {
|
export default class Client extends EventTarget {
|
||||||
static Status = {
|
static Status = {
|
||||||
@ -65,6 +79,7 @@ export default class Client extends EventTarget {
|
|||||||
cm = irc.CaseMapping.RFC1459;
|
cm = irc.CaseMapping.RFC1459;
|
||||||
monitored = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
|
monitored = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
|
||||||
whoisDB = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
|
whoisDB = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
|
||||||
|
whoxQueries = new Map();
|
||||||
|
|
||||||
constructor(params) {
|
constructor(params) {
|
||||||
super();
|
super();
|
||||||
@ -332,14 +347,43 @@ export default class Client extends EventTarget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
who(mask) {
|
who(mask, options) {
|
||||||
let msg = { command: "WHO", params: [mask] };
|
let params = [mask];
|
||||||
|
|
||||||
|
let fields = "", token = "";
|
||||||
|
if (options && this.isupport.has("WHOX")) {
|
||||||
|
let match = ""; // Matches exact channel or nick
|
||||||
|
|
||||||
|
fields = "t"; // Always include token in reply
|
||||||
|
if (options.fields) {
|
||||||
|
options.fields.forEach((k) => {
|
||||||
|
if (!WHOX_FIELDS[k]) {
|
||||||
|
throw new Error(`Unknown WHOX field ${k}`);
|
||||||
|
}
|
||||||
|
fields += WHOX_FIELDS[k];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
token = String(lastWhoxToken % 1000);
|
||||||
|
lastWhoxToken++;
|
||||||
|
|
||||||
|
params.push(`${match}%${fields},${token}`);
|
||||||
|
this.whoxQueries.set(token, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = { command: "WHO", params };
|
||||||
let l = [];
|
let l = [];
|
||||||
return this.roundtrip(msg, (msg) => {
|
return this.roundtrip(msg, (msg) => {
|
||||||
switch (msg.command) {
|
switch (msg.command) {
|
||||||
case irc.RPL_WHOREPLY:
|
case irc.RPL_WHOREPLY:
|
||||||
// TODO: match with mask
|
// TODO: match with mask
|
||||||
l.push(msg);
|
l.push(this.parseWhoReply(msg));
|
||||||
|
break;
|
||||||
|
case irc.RPL_WHOSPCRPL:
|
||||||
|
if (msg.params.length !== fields.length || msg.params[1] !== token) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
l.push(this.parseWhoReply(msg));
|
||||||
break;
|
break;
|
||||||
case irc.RPL_ENDOFWHO:
|
case irc.RPL_ENDOFWHO:
|
||||||
if (msg.params[1] === mask) {
|
if (msg.params[1] === mask) {
|
||||||
@ -347,9 +391,45 @@ export default class Client extends EventTarget {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
this.whoxQueries.delete(token);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parseWhoReply(msg) {
|
||||||
|
switch (msg.command) {
|
||||||
|
case irc.RPL_WHOREPLY:
|
||||||
|
let last = msg.params[msg.params.length - 1];
|
||||||
|
return {
|
||||||
|
username: msg.params[2],
|
||||||
|
hostname: msg.params[3],
|
||||||
|
server: msg.params[4],
|
||||||
|
nick: msg.params[5],
|
||||||
|
flags: msg.params[6],
|
||||||
|
realname: last.slice(last.indexOf(" ") + 1),
|
||||||
|
};
|
||||||
|
case irc.RPL_WHOSPCRPL:
|
||||||
|
let token = msg.params[1];
|
||||||
|
let fields = this.whoxQueries.get(token);
|
||||||
|
if (!fields) {
|
||||||
|
throw new Error("Unknown WHOX token: " + token);
|
||||||
|
}
|
||||||
|
let who = {};
|
||||||
|
let i = 0;
|
||||||
|
Object.keys(WHOX_FIELDS).forEach((k) => {
|
||||||
|
if (fields.indexOf(WHOX_FIELDS[k]) < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
who[k] = msg.params[2 + i];
|
||||||
|
i++;
|
||||||
|
});
|
||||||
|
return who;
|
||||||
|
default:
|
||||||
|
throw new Error("Not a WHO reply: " + msg.command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
whois(target) {
|
whois(target) {
|
||||||
let targetCM = this.cm(target);
|
let targetCM = this.cm(target);
|
||||||
let msg = { command: "WHOIS", params: [target] };
|
let msg = { command: "WHOIS", params: [target] };
|
||||||
|
@ -23,6 +23,7 @@ export const RPL_EXCEPTLIST = "348";
|
|||||||
export const RPL_ENDOFEXCEPTLIST = "349";
|
export const RPL_ENDOFEXCEPTLIST = "349";
|
||||||
export const RPL_WHOREPLY = "352";
|
export const RPL_WHOREPLY = "352";
|
||||||
export const RPL_NAMREPLY = "353";
|
export const RPL_NAMREPLY = "353";
|
||||||
|
export const RPL_WHOSPCRPL = "354";
|
||||||
export const RPL_ENDOFNAMES = "366";
|
export const RPL_ENDOFNAMES = "366";
|
||||||
export const RPL_BANLIST = "367";
|
export const RPL_BANLIST = "367";
|
||||||
export const RPL_ENDOFBANLIST = "368";
|
export const RPL_ENDOFBANLIST = "368";
|
||||||
|
20
state.js
20
state.js
@ -363,16 +363,16 @@ export const State = {
|
|||||||
case irc.RPL_ENDOFNAMES:
|
case irc.RPL_ENDOFNAMES:
|
||||||
break;
|
break;
|
||||||
case irc.RPL_WHOREPLY:
|
case irc.RPL_WHOREPLY:
|
||||||
let last = msg.params[msg.params.length - 1];
|
case irc.RPL_WHOSPCRPL:
|
||||||
who = {
|
let who = client.parseWhoReply(msg);
|
||||||
username: msg.params[2],
|
|
||||||
hostname: msg.params[3],
|
if (who.flags !== undefined) {
|
||||||
server: msg.params[4],
|
who.away = who.flags.indexOf("G") >= 0; // H for here, G for gone
|
||||||
nick: msg.params[5],
|
delete who.flags;
|
||||||
away: msg.params[6] == 'G', // H for here, G for gone
|
}
|
||||||
realname: last.slice(last.indexOf(" ") + 1),
|
|
||||||
offline: false,
|
who.offline = false;
|
||||||
};
|
|
||||||
return updateUser(who.nick, who);
|
return updateUser(who.nick, who);
|
||||||
case irc.RPL_ENDOFWHO:
|
case irc.RPL_ENDOFWHO:
|
||||||
target = msg.params[1];
|
target = msg.params[1];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user