···160160161161 collect_batch(kind: string, opt?: {
162162 /** ask handlers not to touch any messages in this batch.
163163- * this is helpful for implementing, say, `draft/event-playback` support */
163163+ * this is helpful for implementing, say, `draft/event-playback` support */
164164 mask?: boolean,
165165 params?: string[],
166166 }) {
···232232233233 if (this.start.matches(message)) {
234234 this.is_collecting = true;
235235+ if (this.include_start_finish) {
236236+ this.collected.push(message);
237237+ }
235238 return false;
236239 }
237240···240243241244 if (this.finish.matches(message)) {
242245 this.resolve(this.collected);
246246+ if (this.include_start_finish) {
247247+ this.collected.push(message);
248248+ }
243249 return true;
244250 }
245251
+3-3
core/sasl.ts
···128128129129 }
130130131131- get probably_insecure() {
132132- return !this.get_mechs().includes("SCRAM-SHA-256")
133133- }
131131+ // get probably_insecure() {
132132+ // return !this.get_mechs().includes("SCRAM-SHA-256")
133133+ // } update: scram-sha-256 does not work how I thought it would. oops!
134134}
+104
core/whois.ts
···11+import { Connection } from ".";
22+import { supported_keys } from "./metadata";
33+import { Mode, parse_modestring } from "./modes";
44+import { ArrayMatcher, Matcher, Wildcard } from "./queue";
55+import { Numeric } from "./support";
66+77+export interface UserMetadata {
88+ nick: string,
99+ realname: string,
1010+ ident: string,
1111+ host: string,
1212+ metadata: Record<string, string>,
1313+ operator: boolean,
1414+ registered: boolean,
1515+ account?: string,
1616+ modes: Mode[],
1717+}
1818+1919+const whois_numerics = [
2020+ Numeric.RPL_WHOISCERTFP,
2121+ Numeric.RPL_WHOISREGNICK,
2222+ Numeric.RPL_WHOISUSER,
2323+ Numeric.RPL_WHOISSERVER,
2424+ Numeric.RPL_WHOISOPERATOR,
2525+ Numeric.RPL_WHOISIDLE,
2626+ Numeric.RPL_WHOISCHANNELS,
2727+ Numeric.RPL_WHOISSPECIAL,
2828+ Numeric.RPL_WHOISACCOUNT,
2929+ Numeric.RPL_WHOISACTUALLY,
3030+ Numeric.RPL_WHOISHOST,
3131+ Numeric.RPL_WHOISMODES,
3232+ Numeric.RPL_WHOISSECURE,
3333+ Numeric.RPL_AWAY,
3434+]
3535+3636+export async function get_a_load_of_this_guy(nick: string, conn: Connection): Promise<UserMetadata> {
3737+ const q = conn.collect(`whois lookup for ${nick}`, {
3838+ start: new Matcher(Numeric.RPL_WHOISUSER, Wildcard.Any, nick),
3939+ finish: new Matcher(Numeric.RPL_ENDOFWHOIS, Wildcard.Any, nick),
4040+ include: new ArrayMatcher(
4141+ ...whois_numerics.map(x => new Matcher(x, Wildcard.Any, nick))
4242+ ),
4343+ include_start_finish: true,
4444+ reject_on: new ArrayMatcher(
4545+ new Matcher(Numeric.ERR_NOSUCHNICK, Wildcard.Any, nick),
4646+ new Matcher(Numeric.ERR_NOSUCHSERVER),
4747+ new Matcher(Numeric.ERR_NONICKNAMEGIVEN),
4848+ )
4949+ })
5050+ conn.send(`WHOIS :${nick}`);
5151+ const result = await q;
5252+5353+ if (conn.supports.metadata()) {
5454+ const meta_query = conn.collect_batch("metadata");
5555+ conn.send(`METADATA ${nick} GET ${supported_keys.join(" ")}`);
5656+ result.push(...(await meta_query));
5757+ }
5858+5959+ let thisguy: Partial<UserMetadata> = {
6060+ metadata: {},
6161+ operator: false,
6262+ registered: false,
6363+ modes: [],
6464+ };
6565+6666+ for (const msg of result) {
6767+ if (!msg.params) continue;
6868+ switch (msg.command) {
6969+ case Numeric.RPL_WHOISUSER:
7070+ thisguy.nick = msg.params[1];
7171+ thisguy.ident = msg.params[2];
7272+ thisguy.host = msg.params[3];
7373+ thisguy.realname = msg.params.at(-1);
7474+ break;
7575+ case Numeric.RPL_KEYVALUE:
7676+ const key = msg.params[2];
7777+ const value = msg.params.at(-1);
7878+ if (!value) break;
7979+ thisguy.metadata![key] = value;
8080+ break;
8181+ case Numeric.RPL_WHOISOPERATOR:
8282+ thisguy.operator = true
8383+ break;
8484+ case Numeric.RPL_WHOISREGNICK:
8585+ thisguy.registered = true;
8686+ break;
8787+ case Numeric.RPL_WHOISACCOUNT:
8888+ thisguy.account = msg.params[2];
8989+ break;
9090+ case Numeric.RPL_WHOISMODES:
9191+ // this seems completely batshit and likely to topple over upon
9292+ // experiencing a gentle summer breeze but I can't see any
9393+ // other way to do it in the spec. maybe this protocol is washed.
9494+ const modestring = msg.params.at(-1)!.split(" ").find(x => x.startsWith("+"));
9595+ if (!modestring) continue;
9696+ thisguy.modes = parse_modestring(modestring);
9797+ break;
9898+ }
9999+ }
100100+101101+ console.log(result);
102102+ console.log(thisguy);
103103+ return thisguy as UserMetadata
104104+}