mirror of
https://git.sr.ht/~emersion/gamja
synced 2024-11-28 18:45:51 -05:00
Refactor ISUPPORT handling
Add a helper class to parse ISUPPORT tokens. Instead of having manual ISUPPORT handling all over the place, use pre-processed values.
This commit is contained in:
parent
31b293fa03
commit
ab3d4dd661
7 changed files with 128 additions and 84 deletions
|
@ -718,7 +718,7 @@ export default class App extends Component {
|
||||||
target = SERVER_BUFFER;
|
target = SERVER_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
let allowedPrefixes = client.isupport.get("STATUSMSG");
|
let allowedPrefixes = client.isupport.statusMsg();
|
||||||
if (allowedPrefixes) {
|
if (allowedPrefixes) {
|
||||||
let parts = irc.parseTargetPrefix(target, allowedPrefixes);
|
let parts = irc.parseTargetPrefix(target, allowedPrefixes);
|
||||||
if (client.isChannel(parts.name)) {
|
if (client.isChannel(parts.name)) {
|
||||||
|
@ -890,7 +890,7 @@ export default class App extends Component {
|
||||||
|
|
||||||
// Auto-join channels given at connect-time
|
// Auto-join channels given at connect-time
|
||||||
let server = this.state.servers.get(serverID);
|
let server = this.state.servers.get(serverID);
|
||||||
let bouncerNetID = server.isupport.get("BOUNCER_NETID");
|
let bouncerNetID = server.bouncerNetID;
|
||||||
let bouncerNetwork = null;
|
let bouncerNetwork = null;
|
||||||
if (bouncerNetID) {
|
if (bouncerNetID) {
|
||||||
bouncerNetwork = this.state.bouncerNetworks.get(bouncerNetID);
|
bouncerNetwork = this.state.bouncerNetworks.get(bouncerNetID);
|
||||||
|
@ -936,7 +936,7 @@ export default class App extends Component {
|
||||||
break; // We're only interested in network updates
|
break; // We're only interested in network updates
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client.isupport.has("BOUNCER_NETID")) {
|
if (client.isupport.bouncerNetID()) {
|
||||||
// This can happen if the user has specified a network to bind
|
// This can happen if the user has specified a network to bind
|
||||||
// to via other means, e.g. "<username>/<network>".
|
// to via other means, e.g. "<username>/<network>".
|
||||||
break;
|
break;
|
||||||
|
@ -1081,7 +1081,7 @@ export default class App extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let [id, server] of this.state.servers) {
|
for (let [id, server] of this.state.servers) {
|
||||||
if (server.isupport.get("BOUNCER_NETID") === bouncerNetID) {
|
if (server.bouncerNetID === bouncerNetID) {
|
||||||
serverID = id;
|
serverID = id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1529,7 +1529,7 @@ export default class App extends Component {
|
||||||
|
|
||||||
handleManageNetworkClick(serverID) {
|
handleManageNetworkClick(serverID) {
|
||||||
let server = this.state.servers.get(serverID);
|
let server = this.state.servers.get(serverID);
|
||||||
let bouncerNetID = server.isupport.get("BOUNCER_NETID");
|
let bouncerNetID = server.bouncerNetID;
|
||||||
let bouncerNetwork = this.state.bouncerNetworks.get(bouncerNetID);
|
let bouncerNetwork = this.state.bouncerNetworks.get(bouncerNetID);
|
||||||
this.openDialog("network", {
|
this.openDialog("network", {
|
||||||
id: bouncerNetID,
|
id: bouncerNetID,
|
||||||
|
@ -1599,7 +1599,7 @@ export default class App extends Component {
|
||||||
let activeClient = this.clients.get(activeBuffer.server);
|
let activeClient = this.clients.get(activeBuffer.server);
|
||||||
isBouncer = activeClient && activeClient.enabledCaps["soju.im/bouncer-networks"];
|
isBouncer = activeClient && activeClient.enabledCaps["soju.im/bouncer-networks"];
|
||||||
|
|
||||||
let bouncerNetID = activeServer.isupport.get("BOUNCER_NETID");
|
let bouncerNetID = activeServer.bouncerNetID;
|
||||||
if (bouncerNetID) {
|
if (bouncerNetID) {
|
||||||
activeBouncerNetwork = this.state.bouncerNetworks.get(bouncerNetID);
|
activeBouncerNetwork = this.state.bouncerNetworks.get(bouncerNetID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ export default function BufferHeader(props) {
|
||||||
`;
|
`;
|
||||||
|
|
||||||
if (props.isBouncer) {
|
if (props.isBouncer) {
|
||||||
if (props.server.isupport.get("BOUNCER_NETID")) {
|
if (props.server.bouncerNetID) {
|
||||||
if (fullyConnected) {
|
if (fullyConnected) {
|
||||||
actions.push(joinButton);
|
actions.push(joinButton);
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ export default function BufferHeader(props) {
|
||||||
item = `authenticated as ${props.user.account}`;
|
item = `authenticated as ${props.user.account}`;
|
||||||
}
|
}
|
||||||
details.push(html`<abbr title=${desc}>${item}</abbr>`);
|
details.push(html`<abbr title=${desc}>${item}</abbr>`);
|
||||||
} else if (props.server.isupport.has("MONITOR") && props.server.isupport.has("WHOX")) {
|
} else if (props.server.reliableUserAccounts) {
|
||||||
// If the server supports MONITOR and WHOX, we can faithfully
|
// If the server supports MONITOR and WHOX, we can faithfully
|
||||||
// keep user.account up-to-date for user queries
|
// keep user.account up-to-date for user queries
|
||||||
let desc = "This user has not been verified and is not logged in.";
|
let desc = "This user has not been verified and is not logged in.";
|
||||||
|
|
|
@ -44,7 +44,7 @@ export default function BufferList(props) {
|
||||||
let server = props.servers.get(buf.server);
|
let server = props.servers.get(buf.server);
|
||||||
|
|
||||||
let bouncerNetwork = null;
|
let bouncerNetwork = null;
|
||||||
let bouncerNetID = server.isupport.get("BOUNCER_NETID");
|
let bouncerNetID = server.bouncerNetID;
|
||||||
if (bouncerNetID) {
|
if (bouncerNetID) {
|
||||||
bouncerNetwork = props.bouncerNetworks.get(bouncerNetID);
|
bouncerNetwork = props.bouncerNetworks.get(bouncerNetID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ class LogLine extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
let status = null;
|
let status = null;
|
||||||
let allowedPrefixes = server.isupport.get("STATUSMSG");
|
let allowedPrefixes = server.statusMsg;
|
||||||
if (target !== buf.name && allowedPrefixes) {
|
if (target !== buf.name && allowedPrefixes) {
|
||||||
let parts = irc.parseTargetPrefix(target, allowedPrefixes);
|
let parts = irc.parseTargetPrefix(target, allowedPrefixes);
|
||||||
if (parts.name === buf.name) {
|
if (parts.name === buf.name) {
|
||||||
|
@ -487,8 +487,8 @@ class ProtocolHandlerNagger extends Component {
|
||||||
|
|
||||||
function AccountNagger({ server, onAuthClick, onRegisterClick }) {
|
function AccountNagger({ server, onAuthClick, onRegisterClick }) {
|
||||||
let accDesc = "an account on this server";
|
let accDesc = "an account on this server";
|
||||||
if (server.isupport.has("NETWORK")) {
|
if (server.name) {
|
||||||
accDesc = "a " + server.isupport.get("NETWORK") + " account";
|
accDesc = "a " + server.name + " account";
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAuthClick(event) {
|
function handleAuthClick(event) {
|
||||||
|
@ -564,13 +564,13 @@ export default class Buffer extends Component {
|
||||||
|
|
||||||
let server = this.props.server;
|
let server = this.props.server;
|
||||||
let bouncerNetwork = this.props.bouncerNetwork;
|
let bouncerNetwork = this.props.bouncerNetwork;
|
||||||
let serverName = server.isupport.get("NETWORK");
|
let serverName = server.name;
|
||||||
|
|
||||||
let children = [];
|
let children = [];
|
||||||
if (buf.type == BufferType.SERVER) {
|
if (buf.type == BufferType.SERVER) {
|
||||||
children.push(html`<${NotificationNagger}/>`);
|
children.push(html`<${NotificationNagger}/>`);
|
||||||
}
|
}
|
||||||
if (buf.type == BufferType.SERVER && this.props.isBouncer && !server.isupport.has("BOUNCER_NETID")) {
|
if (buf.type == BufferType.SERVER && this.props.isBouncer && !server.bouncerNetID) {
|
||||||
children.push(html`<${ProtocolHandlerNagger} bouncerName=${serverName}/>`);
|
children.push(html`<${ProtocolHandlerNagger} bouncerName=${serverName}/>`);
|
||||||
}
|
}
|
||||||
if (buf.type == BufferType.SERVER && server.status == ServerStatus.REGISTERED && server.supportsSASLPlain && !server.account) {
|
if (buf.type == BufferType.SERVER && server.status == ServerStatus.REGISTERED && server.supportsSASLPlain && !server.account) {
|
||||||
|
|
|
@ -78,7 +78,7 @@ export default class Client extends EventTarget {
|
||||||
supportsCap = false;
|
supportsCap = false;
|
||||||
availableCaps = {};
|
availableCaps = {};
|
||||||
enabledCaps = {};
|
enabledCaps = {};
|
||||||
isupport = new Map();
|
isupport = new irc.Isupport();
|
||||||
|
|
||||||
ws = null;
|
ws = null;
|
||||||
params = {
|
params = {
|
||||||
|
@ -159,7 +159,7 @@ export default class Client extends EventTarget {
|
||||||
Object.keys(this.pendingCmds).forEach((k) => {
|
Object.keys(this.pendingCmds).forEach((k) => {
|
||||||
this.pendingCmds[k] = Promise.resolve(null);
|
this.pendingCmds[k] = Promise.resolve(null);
|
||||||
});
|
});
|
||||||
this.isupport = new Map();
|
this.isupport = new irc.Isupport();
|
||||||
this.monitored = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
|
this.monitored = new irc.CaseMapMap(null, irc.CaseMapping.RFC1459);
|
||||||
|
|
||||||
if (this.autoReconnect) {
|
if (this.autoReconnect) {
|
||||||
|
@ -282,22 +282,24 @@ export default class Client extends EventTarget {
|
||||||
this.setStatus(Client.Status.REGISTERED);
|
this.setStatus(Client.Status.REGISTERED);
|
||||||
break;
|
break;
|
||||||
case irc.RPL_ISUPPORT:
|
case irc.RPL_ISUPPORT:
|
||||||
|
let prevMaxMonitorTargets = this.isupport.monitor();
|
||||||
|
|
||||||
let tokens = msg.params.slice(1, -1);
|
let tokens = msg.params.slice(1, -1);
|
||||||
let changed = irc.parseISUPPORT(tokens, this.isupport);
|
this.isupport.parse(tokens);
|
||||||
if (changed.indexOf("CASEMAPPING") >= 0) {
|
this.updateCaseMapping();
|
||||||
this.setCaseMapping(this.isupport.get("CASEMAPPING"));
|
|
||||||
}
|
let maxMonitorTargets = this.isupport.monitor();
|
||||||
if (changed.indexOf("MONITOR") >= 0 && this.isupport.has("MONITOR") && this.monitored.size > 0) {
|
if (prevMaxMonitorTargets === 0 && this.monitored.size > 0 && maxMonitorTargets > 0) {
|
||||||
let targets = Array.from(this.monitored.keys()).slice(0, this.maxMonitorTargets());
|
let targets = Array.from(this.monitored.keys()).slice(0, maxMonitorTargets);
|
||||||
this.send({ command: "MONITOR", params: ["+", targets.join(",")] });
|
this.send({ command: "MONITOR", params: ["+", targets.join(",")] });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case irc.RPL_ENDOFMOTD:
|
case irc.RPL_ENDOFMOTD:
|
||||||
case irc.ERR_NOMOTD:
|
case irc.ERR_NOMOTD:
|
||||||
// These messages are used to indicate the end of the ISUPPORT list
|
// These messages are used to indicate the end of the ISUPPORT list
|
||||||
if (!this.isupport.has("CASEMAPPING")) {
|
if (!this.isupport.raw.has("CASEMAPPING")) {
|
||||||
// Server didn't send any CASEMAPPING token, assume RFC 1459
|
// Server didn't send any CASEMAPPING token, assume RFC 1459
|
||||||
this.setCaseMapping("rfc1459");
|
this.updateCaseMapping();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "CAP":
|
case "CAP":
|
||||||
|
@ -451,7 +453,7 @@ export default class Client extends EventTarget {
|
||||||
let params = [mask];
|
let params = [mask];
|
||||||
|
|
||||||
let fields = "", token = "";
|
let fields = "", token = "";
|
||||||
if (options && this.isupport.has("WHOX")) {
|
if (options && this.isupport.whox()) {
|
||||||
let match = ""; // Matches exact channel or nick
|
let match = ""; // Matches exact channel or nick
|
||||||
|
|
||||||
fields = "t"; // Always include token in reply
|
fields = "t"; // Always include token in reply
|
||||||
|
@ -685,13 +687,8 @@ export default class Client extends EventTarget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setCaseMapping(name) {
|
updateCaseMapping() {
|
||||||
this.cm = irc.CaseMapping.byName(name);
|
this.cm = this.isupport.caseMapping();
|
||||||
if (!this.cm) {
|
|
||||||
console.error("Unsupported case-mapping '" + name + "', falling back to RFC 1459");
|
|
||||||
this.cm = irc.CaseMapping.RFC1459;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.pendingLists = new irc.CaseMapMap(this.pendingLists, this.cm);
|
this.pendingLists = new irc.CaseMapMap(this.pendingLists, this.cm);
|
||||||
this.monitored = new irc.CaseMapMap(this.monitored, this.cm);
|
this.monitored = new irc.CaseMapMap(this.monitored, this.cm);
|
||||||
}
|
}
|
||||||
|
@ -705,7 +702,7 @@ export default class Client extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
isChannel(name) {
|
isChannel(name) {
|
||||||
let chanTypes = this.isupport.get("CHANTYPES") || irc.STD_CHANTYPES;
|
let chanTypes = this.isupport.chanTypes();
|
||||||
return chanTypes.indexOf(name[0]) >= 0;
|
return chanTypes.indexOf(name[0]) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -870,19 +867,9 @@ export default class Client extends EventTarget {
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
chatHistoryPageSize() {
|
|
||||||
if (this.isupport.has("CHATHISTORY")) {
|
|
||||||
let pageSize = parseInt(this.isupport.get("CHATHISTORY"), 10);
|
|
||||||
if (pageSize > 0) {
|
|
||||||
return pageSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fetch one page of history before the given date. */
|
/* Fetch one page of history before the given date. */
|
||||||
fetchHistoryBefore(target, before, limit) {
|
fetchHistoryBefore(target, before, limit) {
|
||||||
let max = Math.min(limit, this.chatHistoryPageSize());
|
let max = Math.min(limit, this.isupport.chatHistory());
|
||||||
let params = ["BEFORE", target, "timestamp=" + before, max];
|
let params = ["BEFORE", target, "timestamp=" + before, max];
|
||||||
return this.roundtripChatHistory(params).then((messages) => {
|
return this.roundtripChatHistory(params).then((messages) => {
|
||||||
return { more: messages.length >= max };
|
return { more: messages.length >= max };
|
||||||
|
@ -891,7 +878,7 @@ export default class Client extends EventTarget {
|
||||||
|
|
||||||
/* Fetch history in ascending order. */
|
/* Fetch history in ascending order. */
|
||||||
fetchHistoryBetween(target, after, before, limit) {
|
fetchHistoryBetween(target, after, before, limit) {
|
||||||
let max = Math.min(limit, this.chatHistoryPageSize());
|
let max = Math.min(limit, this.isupport.chatHistory());
|
||||||
let params = ["AFTER", target, "timestamp=" + after.time, max];
|
let params = ["AFTER", target, "timestamp=" + after.time, max];
|
||||||
return this.roundtripChatHistory(params).then((messages) => {
|
return this.roundtripChatHistory(params).then((messages) => {
|
||||||
limit -= messages.length;
|
limit -= messages.length;
|
||||||
|
@ -943,17 +930,6 @@ export default class Client extends EventTarget {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
maxMonitorTargets() {
|
|
||||||
if (!this.isupport.has("MONITOR")) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
let v = this.isupport.get("MONITOR");
|
|
||||||
if (v === "") {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
return parseInt(v, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor(target) {
|
monitor(target) {
|
||||||
if (this.monitored.has(target)) {
|
if (this.monitored.has(target)) {
|
||||||
return;
|
return;
|
||||||
|
@ -962,7 +938,7 @@ export default class Client extends EventTarget {
|
||||||
this.monitored.set(target, true);
|
this.monitored.set(target, true);
|
||||||
|
|
||||||
// TODO: add poll-based fallback when MONITOR is not supported
|
// TODO: add poll-based fallback when MONITOR is not supported
|
||||||
if (this.monitored.size + 1 > this.maxMonitorTargets()) {
|
if (this.monitored.size + 1 > this.isupport.monitor()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -976,7 +952,7 @@ export default class Client extends EventTarget {
|
||||||
|
|
||||||
this.monitored.delete(target);
|
this.monitored.delete(target);
|
||||||
|
|
||||||
if (!this.isupport.has("MONITOR")) {
|
if (this.isupport.monitor() <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
100
lib/irc.js
100
lib/irc.js
|
@ -382,28 +382,88 @@ function unescapeISUPPORTValue(s) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseISUPPORT(tokens, params) {
|
export class Isupport {
|
||||||
let changed = [];
|
raw = new Map();
|
||||||
tokens.forEach((tok) => {
|
|
||||||
if (tok.startsWith("-")) {
|
parse(tokens) {
|
||||||
let k = tok.slice(1);
|
tokens.forEach((tok) => {
|
||||||
params.delete(k.toUpperCase());
|
if (tok.startsWith("-")) {
|
||||||
return;
|
let k = tok.slice(1);
|
||||||
|
this.raw.delete(k.toUpperCase());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = tok.indexOf("=");
|
||||||
|
let k = tok, v = "";
|
||||||
|
if (i >= 0) {
|
||||||
|
k = tok.slice(0, i);
|
||||||
|
v = unescapeISUPPORTValue(tok.slice(i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
k = k.toUpperCase();
|
||||||
|
|
||||||
|
this.raw.set(k, v);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
caseMapping() {
|
||||||
|
let name = this.raw.get("CASEMAPPING");
|
||||||
|
if (!name) {
|
||||||
|
return CaseMapping.RFC1459;
|
||||||
}
|
}
|
||||||
|
let cm = CaseMapping.byName(name);
|
||||||
let i = tok.indexOf("=");
|
if (!cm) {
|
||||||
let k = tok, v = "";
|
console.error("Unsupported case-mapping '" + name + "', falling back to RFC 1459");
|
||||||
if (i >= 0) {
|
return CaseMapping.RFC1459;
|
||||||
k = tok.slice(0, i);
|
|
||||||
v = unescapeISUPPORTValue(tok.slice(i + 1));
|
|
||||||
}
|
}
|
||||||
|
return cm;
|
||||||
|
}
|
||||||
|
|
||||||
k = k.toUpperCase();
|
monitor() {
|
||||||
|
if (!this.raw.has("MONITOR")) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let v = this.raw.get("MONITOR");
|
||||||
|
if (v === "") {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
return parseInt(v, 10);
|
||||||
|
}
|
||||||
|
|
||||||
params.set(k, v);
|
whox() {
|
||||||
changed.push(k);
|
return this.raw.has("WHOX");
|
||||||
});
|
}
|
||||||
return changed;
|
|
||||||
|
prefix() {
|
||||||
|
return this.raw.get("PREFIX") || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
chanTypes() {
|
||||||
|
return this.raw.get("CHANTYPES") || STD_CHANTYPES;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusMsg() {
|
||||||
|
return this.raw.get("STATUSMSG");
|
||||||
|
}
|
||||||
|
|
||||||
|
network() {
|
||||||
|
return this.raw.get("NETWORK");
|
||||||
|
}
|
||||||
|
|
||||||
|
chatHistory() {
|
||||||
|
if (!this.raw.has("CHATHISTORY")) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let n = parseInt(this.raw.get("CHATHISTORY"), 10);
|
||||||
|
if (n <= 0) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
bouncerNetID() {
|
||||||
|
return this.raw.get("BOUNCER_NETID");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CaseMapping = {
|
export const CaseMapping = {
|
||||||
|
@ -612,8 +672,8 @@ export function getMessageLabel(msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function forEachChannelModeUpdate(msg, isupport, callback) {
|
export function forEachChannelModeUpdate(msg, isupport, callback) {
|
||||||
let chanmodes = isupport.get("CHANMODES") || STD_CHANMODES;
|
let chanmodes = isupport.chanModes();
|
||||||
let prefix = isupport.get("PREFIX") || "";
|
let prefix = isupport.prefix();
|
||||||
|
|
||||||
let typeByMode = new Map();
|
let typeByMode = new Map();
|
||||||
let [a, b, c, d] = chanmodes.split(",");
|
let [a, b, c, d] = chanmodes.split(",");
|
||||||
|
|
20
state.js
20
state.js
|
@ -64,7 +64,7 @@ export function getMessageURL(buf, msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getServerName(server, bouncerNetwork, isBouncer) {
|
export function getServerName(server, bouncerNetwork, isBouncer) {
|
||||||
let netName = server.isupport.get("NETWORK");
|
let netName = server.name;
|
||||||
|
|
||||||
if (bouncerNetwork && bouncerNetwork.name && bouncerNetwork.name !== bouncerNetwork.host) {
|
if (bouncerNetwork && bouncerNetwork.name && bouncerNetwork.name !== bouncerNetwork.host) {
|
||||||
// User has picked a custom name for the network, use that
|
// User has picked a custom name for the network, use that
|
||||||
|
@ -118,7 +118,7 @@ function compareBuffers(a, b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMembership(membership, letter, add, client) {
|
function updateMembership(membership, letter, add, client) {
|
||||||
let prefix = client.isupport.get("PREFIX") || "";
|
let prefix = client.isupport.prefix();
|
||||||
|
|
||||||
let prefixPrivs = new Map(irc.parseMembershipModes(prefix).map((membership, i) => {
|
let prefixPrivs = new Map(irc.parseMembershipModes(prefix).map((membership, i) => {
|
||||||
return [membership.prefix, i];
|
return [membership.prefix, i];
|
||||||
|
@ -231,7 +231,7 @@ export const State = {
|
||||||
let cm = irc.CaseMapping.RFC1459;
|
let cm = irc.CaseMapping.RFC1459;
|
||||||
let server = state.servers.get(serverID);
|
let server = state.servers.get(serverID);
|
||||||
if (server) {
|
if (server) {
|
||||||
cm = irc.CaseMapping.byName(server.isupport.get("CASEMAPPING")) || cm;
|
cm = server.cm;
|
||||||
}
|
}
|
||||||
|
|
||||||
let nameCM = cm(name);
|
let nameCM = cm(name);
|
||||||
|
@ -252,12 +252,16 @@ export const State = {
|
||||||
let servers = new Map(state.servers);
|
let servers = new Map(state.servers);
|
||||||
servers.set(id, {
|
servers.set(id, {
|
||||||
id,
|
id,
|
||||||
|
name: null, // from ISUPPORT NETWORK
|
||||||
status: ServerStatus.DISCONNECTED,
|
status: ServerStatus.DISCONNECTED,
|
||||||
isupport: new Map(),
|
cm: irc.CaseMapping.RFC1459,
|
||||||
users: new irc.CaseMapMap(null, irc.CaseMapping.RFC1459),
|
users: new irc.CaseMapMap(null, irc.CaseMapping.RFC1459),
|
||||||
account: null,
|
account: null,
|
||||||
supportsSASLPlain: false,
|
supportsSASLPlain: false,
|
||||||
supportsAccountRegistration: false,
|
supportsAccountRegistration: false,
|
||||||
|
reliableUserAccounts: false,
|
||||||
|
statusMsg: null, // from ISUPPORT STATUSMSG
|
||||||
|
bouncerNetID: null,
|
||||||
});
|
});
|
||||||
return [id, { servers }];
|
return [id, { servers }];
|
||||||
},
|
},
|
||||||
|
@ -343,8 +347,12 @@ export const State = {
|
||||||
buffers,
|
buffers,
|
||||||
...updateServer((server) => {
|
...updateServer((server) => {
|
||||||
return {
|
return {
|
||||||
isupport: new Map(client.isupport),
|
name: client.isupport.network(),
|
||||||
|
cm: client.cm,
|
||||||
users: new irc.CaseMapMap(server.users, client.cm),
|
users: new irc.CaseMapMap(server.users, client.cm),
|
||||||
|
reliableUserAccounts: client.isupport.monitor() > 0 && client.isupport.whox(),
|
||||||
|
statusMsg: client.isupport.statusMsg(),
|
||||||
|
bouncerNetID: client.isupport.bouncerNetID,
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
@ -550,7 +558,7 @@ export const State = {
|
||||||
return; // TODO: handle user mode changes too
|
return; // TODO: handle user mode changes too
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefix = client.isupport.get("PREFIX") || "";
|
let prefix = client.prefix();
|
||||||
let prefixByMode = new Map(irc.parseMembershipModes(prefix).map((membership) => {
|
let prefixByMode = new Map(irc.parseMembershipModes(prefix).map((membership) => {
|
||||||
return [membership.mode, membership.prefix];
|
return [membership.mode, membership.prefix];
|
||||||
}));
|
}));
|
||||||
|
|
Loading…
Reference in a new issue