From 0b3f5ef88b11999287cd0318f45418de75069b24 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 11 Jun 2021 12:54:42 +0200 Subject: [PATCH] Add irc.forEachChannelModeUpdate helper --- lib/irc.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ state.js | 40 ++-------------------------------------- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/lib/irc.js b/lib/irc.js index e56fef2..e485140 100644 --- a/lib/irc.js +++ b/lib/irc.js @@ -571,3 +571,50 @@ export function getMessageLabel(msg) { return null; } + +export function forEachChannelModeUpdate(msg, isupport, callback) { + let chanmodes = isupport.get("CHANMODES") || STD_CHANMODES; + let prefix = isupport.get("PREFIX") || ""; + + let typeByMode = new Map(); + let [a, b, c, d] = chanmodes.split(","); + Array.from(a).forEach((mode) => typeByMode.set(mode, "A")); + Array.from(b).forEach((mode) => typeByMode.set(mode, "B")); + Array.from(c).forEach((mode) => typeByMode.set(mode, "C")); + Array.from(d).forEach((mode) => typeByMode.set(mode, "D")); + parseMembershipModes(prefix).forEach((membership) => typeByMode.set(membership.mode, "B")); + + if (msg.command !== "MODE") { + throw new Error("Expected a MODE message"); + } + let change = msg.params[1]; + let args = msg.params.slice(2); + + let plusMinus = null; + let j = 0; + for (let i = 0; i < change.length; i++) { + if (change[i] === "+" || change[i] === "-") { + plusMinus = change[i]; + continue; + } + if (!plusMinus) { + throw new Error("malformed mode string: missing plus/minus"); + } + + let mode = change[i]; + let add = plusMinus === "+"; + + let modeType = typeByMode.get(mode); + if (!modeType) { + continue; + } + + let arg = null; + if (modeType === "A" || modeType === "B" || (modeType === "C" && add)) { + arg = args[j]; + j++; + } + + callback(mode, add, arg); + } +} diff --git a/state.js b/state.js index f823e1c..c0f70d4 100644 --- a/state.js +++ b/state.js @@ -413,63 +413,27 @@ export const State = { return updateBuffer(channel, { topic }); case "MODE": target = msg.params[0]; - let change = msg.params[1]; - let args = msg.params.slice(2); if (!client.isChannel(target)) { return; // TODO: handle user mode changes too } - let chanmodes = client.isupport.get("CHANMODES") || irc.STD_CHANMODES; let prefix = client.isupport.get("PREFIX") || ""; - let prefixByMode = new Map(irc.parseMembershipModes(prefix).map((membership) => { return [membership.mode, membership.prefix]; })); - let typeByMode = new Map(); - let [a, b, c, d] = chanmodes.split(","); - Array.from(a).forEach((mode) => typeByMode.set(mode, "A")); - Array.from(b).forEach((mode) => typeByMode.set(mode, "B")); - Array.from(c).forEach((mode) => typeByMode.set(mode, "C")); - Array.from(d).forEach((mode) => typeByMode.set(mode, "D")); - prefixByMode.forEach((prefix, mode) => typeByMode.set(mode, "B")); - return updateBuffer(target, (buf) => { let members = new irc.CaseMapMap(buf.members); - let plusMinus = null; - let j = 0; - for (let i = 0; i < change.length; i++) { - if (change[i] === "+" || change[i] === "-") { - plusMinus = change[i]; - continue; - } - if (!plusMinus) { - throw new Error("malformed mode string: missing plus/minus"); - } - - let mode = change[i]; - let add = plusMinus === "+"; - - let modeType = typeByMode.get(mode); - if (!modeType) { - continue; - } - - let arg = null; - if (modeType === "A" || modeType === "B" || (modeType === "C" && add)) { - arg = args[j]; - j++; - } - + irc.forEachChannelModeUpdate(msg, client.isupport, (mode, add, arg) => { if (prefixByMode.has(mode)) { let nick = arg; let membership = members.get(nick); let letter = prefixByMode.get(mode); members.set(nick, updateMembership(membership, letter, add, client)); } - } + }); return { members }; });