more fixes
This commit is contained in:
@@ -39,6 +39,8 @@ class WTVIRC {
|
|||||||
this.clients = [];
|
this.clients = [];
|
||||||
this.usernames = new Map(); // nickname -> username
|
this.usernames = new Map(); // nickname -> username
|
||||||
this.channels = new Map();
|
this.channels = new Map();
|
||||||
|
this.channelkeys = new Map(); // channel -> password
|
||||||
|
this.channellimits = new Map(); // channel -> limit of users
|
||||||
this.channeltimestamps = new Map(); // channel -> timestamp of creation
|
this.channeltimestamps = new Map(); // channel -> timestamp of creation
|
||||||
this.channelops = new Map(); // channel -> Set of operators
|
this.channelops = new Map(); // channel -> Set of operators
|
||||||
this.channelhalfops = new Map(); // channel -> Set of half-operators
|
this.channelhalfops = new Map(); // channel -> Set of half-operators
|
||||||
@@ -779,29 +781,33 @@ class WTVIRC {
|
|||||||
} else if (flags[i] === '+l' || flags[i] === '-l') {
|
} else if (flags[i] === '+l' || flags[i] === '-l') {
|
||||||
// Check if 'l' mode is already present, if not, add it with the limit
|
// Check if 'l' mode is already present, if not, add it with the limit
|
||||||
let chan_modes = this.channelmodes.get(targetUniqueId) || [];
|
let chan_modes = this.channelmodes.get(targetUniqueId) || [];
|
||||||
if (!chan_modes.some(m => /^l\d+$/.test(m))) {
|
if (chan_modes === true) {
|
||||||
// Remove any old l modes, then update if it exists, else add new
|
chan_modes = [];
|
||||||
const limitValue = target;
|
}
|
||||||
const existingIndex = chan_modes.findIndex(m => /^l\d+$/.test(m));
|
// Check if 'l' mode is already present
|
||||||
if (existingIndex !== -1) {
|
if (flags[i] === '+l') {
|
||||||
chan_modes[existingIndex] = `l${limitValue}`;
|
if (!chan_modes.includes('l')) {
|
||||||
} else {
|
chan_modes.push('l');
|
||||||
chan_modes.push(`l${limitValue}`);
|
this.channelmodes.set(targetUniqueId, chan_modes);
|
||||||
|
this.channellimits.set(targetUniqueId, target);
|
||||||
}
|
}
|
||||||
this.channelmodes.set(targetUniqueId, chan_modes);
|
} else {
|
||||||
|
chan_modes = chan_modes.filter(mode => mode !== 'l');
|
||||||
|
this.channellimits.delete(targetUniqueId);
|
||||||
}
|
}
|
||||||
} else if (flags[i] === '+k' || flags[i] === '-k') {
|
} else if (flags[i] === '+k' || flags[i] === '-k') {
|
||||||
let chan_modes = this.channelmodes.get(targetUniqueId) || [];
|
let chan_modes = this.channelmodes.get(targetUniqueId) || [];
|
||||||
if (!chan_modes || chan_modes === true) {
|
if (!chan_modes || chan_modes === true) {
|
||||||
chan_modes = [];
|
chan_modes = [];
|
||||||
}
|
}
|
||||||
const keyModeIndex = chan_modes.findIndex(m => typeof m === 'string' && m.startsWith('k '));
|
if (flags[i] === '+k') {
|
||||||
if (keyModeIndex !== -1) {
|
if (!chan_modes.includes('k')) {
|
||||||
// Update existing key
|
chan_modes.push('k');
|
||||||
chan_modes[keyModeIndex] = `k ${target}`;
|
this.channelkeys.set(targetUniqueId, target);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Add new key mode
|
chan_modes = chan_modes.filter(mode => mode !== 'k');
|
||||||
chan_modes.push(`k ${target}`);
|
this.channelkeys.delete(targetUniqueId);
|
||||||
}
|
}
|
||||||
this.channelmodes.set(targetUniqueId, chan_modes);
|
this.channelmodes.set(targetUniqueId, chan_modes);
|
||||||
}
|
}
|
||||||
@@ -1270,16 +1276,28 @@ class WTVIRC {
|
|||||||
return mode;
|
return mode;
|
||||||
});
|
});
|
||||||
if (chan_modes.length > 0) {
|
if (chan_modes.length > 0) {
|
||||||
|
var params2 = [];
|
||||||
// Batch all modes into a single 324 reply
|
// Batch all modes into a single 324 reply
|
||||||
const modeString = chan_modes
|
var modeString = chan_modes
|
||||||
.map(m => {
|
.map(m => {
|
||||||
// For modes with parameters (like k <key> or l<limit>)
|
// For modes with parameters (like k <key> or l<limit>)
|
||||||
if (typeof m === 'string' && (m.startsWith('k ') || /^l\d+$/.test(m))) {
|
console.log(m);
|
||||||
return m;
|
if (typeof m === 'string' && (m === '+k' || m === '+l')) {
|
||||||
|
if (m === '+l') {
|
||||||
|
params2.push(this.channellimits.get(channel));
|
||||||
|
} else if (m === '+k') {
|
||||||
|
params2.push(this.channelkeys.get(channel));
|
||||||
|
}
|
||||||
|
return m.replace(/^\+/, '');
|
||||||
}
|
}
|
||||||
return m;
|
return m.replace(/^\+/, ''); // Remove leading '+' for other modes
|
||||||
})
|
})
|
||||||
.join('').replace(/\+/g, '');
|
.join('');
|
||||||
|
params2.forEach(param => {
|
||||||
|
if (param) {
|
||||||
|
modeString += ` ${param}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
socket.write(`:${this.servername} 324 ${socket.nickname} ${channel} +${modeString}\r\n`);
|
socket.write(`:${this.servername} 324 ${socket.nickname} ${channel} +${modeString}\r\n`);
|
||||||
} else {
|
} else {
|
||||||
socket.write(`:${this.servername} 324 ${socket.nickname} ${channel}\r\n`);
|
socket.write(`:${this.servername} 324 ${socket.nickname} ${channel}\r\n`);
|
||||||
@@ -1453,9 +1471,8 @@ class WTVIRC {
|
|||||||
continue; // Skip if no modes are set
|
continue; // Skip if no modes are set
|
||||||
}
|
}
|
||||||
// Check if the user is in too many channels
|
// Check if the user is in too many channels
|
||||||
const keyMode = modes.find(m => typeof m === 'string' && m.startsWith('k '));
|
if (this.channelmodes.has(ch) && this.channelmodes.get(ch).includes('k')) {
|
||||||
if (keyMode) {
|
const channelKey = this.channelkeys.get(ch);
|
||||||
const channelKey = keyMode.split(' ')[1];
|
|
||||||
// The key must be provided as the second parameter in the JOIN command
|
// The key must be provided as the second parameter in the JOIN command
|
||||||
// params[1] is the key for the first channel, params[2] for the second, etc.
|
// params[1] is the key for the first channel, params[2] for the second, etc.
|
||||||
// For simplicity, assume only one channel per JOIN or the key is always params[1]
|
// For simplicity, assume only one channel per JOIN or the key is always params[1]
|
||||||
@@ -1465,6 +1482,14 @@ class WTVIRC {
|
|||||||
continue; // Skip joining this channel
|
continue; // Skip joining this channel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.channelmodes.has(ch) && this.channelmodes.get(ch).includes('l')) {
|
||||||
|
// Channel has a user limit (+l)
|
||||||
|
const limit = this.channellimits.get(ch) || null;
|
||||||
|
if (limit !== null && this.channels.get(ch).size >= limit) {
|
||||||
|
socket.write(`:${this.servername} 471 ${socket.nickname} ${ch} :Cannot join channel (+l)\r\n`);
|
||||||
|
continue; // Skip joining this channel
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this.channelmodes.has(ch) && this.channelmodes.get(ch).includes('i')) {
|
if (this.channelmodes.has(ch) && this.channelmodes.get(ch).includes('i')) {
|
||||||
// Channel is invite-only (+i)
|
// Channel is invite-only (+i)
|
||||||
// For simplicity, let's assume you have an invited list per channel (not implemented yet)
|
// For simplicity, let's assume you have an invited list per channel (not implemented yet)
|
||||||
@@ -1501,17 +1526,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if the channel user limit has been reached
|
|
||||||
if (this.channelmodes.has(ch) && this.channelmodes.get(ch).includes('l')) {
|
|
||||||
const limitMatch = this.channelmodes.get(ch).match(/l(\d+)/);
|
|
||||||
if (limitMatch) {
|
|
||||||
const limit = parseInt(limitMatch[1], 10);
|
|
||||||
if (this.channels.has(ch) && this.channels.get(ch).size >= limit) {
|
|
||||||
socket.write(`:${this.servername} 471 ${socket.nickname} ${ch} :Cannot join channel (+l)\r\n`);
|
|
||||||
continue; // Skip joining this channel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we reach here, the user can join the channel
|
// If we reach here, the user can join the channel
|
||||||
// Reuse the JOIN logic for each channel
|
// Reuse the JOIN logic for each channel
|
||||||
// Only run the code after $PLACEHOLDER$ for each channel
|
// Only run the code after $PLACEHOLDER$ for each channel
|
||||||
@@ -2678,9 +2693,8 @@ class WTVIRC {
|
|||||||
if (!chan_modes || chan_modes === true) {
|
if (!chan_modes || chan_modes === true) {
|
||||||
chan_modes = [];
|
chan_modes = [];
|
||||||
}
|
}
|
||||||
// replace limit mode if it exists
|
this.channellimits.set(channel, limit);
|
||||||
chan_modes = chan_modes.filter(m => !/^l\d+$/.test(m));
|
this.channelmodes.set(channel, [...chan_modes, 'l']);
|
||||||
this.channelmodes.set(channel, [...chan_modes, `l${limit}`]);
|
|
||||||
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} +l ${limit}\r\n`);
|
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} +l ${limit}\r\n`);
|
||||||
return;
|
return;
|
||||||
} else if (mode.startsWith('-l')) {
|
} else if (mode.startsWith('-l')) {
|
||||||
@@ -2692,7 +2706,8 @@ class WTVIRC {
|
|||||||
if (!chan_modes || chan_modes === true) {
|
if (!chan_modes || chan_modes === true) {
|
||||||
chan_modes = [];
|
chan_modes = [];
|
||||||
}
|
}
|
||||||
this.channelmodes.set(channel, (chan_modes).filter(m => !/^l\d+$/.test(m)));
|
this.channellimits.delete(channel);
|
||||||
|
this.channelmodes.set(channel, (chan_modes).filter(m => m !== 'l'));
|
||||||
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} -l\r\n`);
|
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} -l\r\n`);
|
||||||
return;
|
return;
|
||||||
} else if (mode.startsWith('+k')) {
|
} else if (mode.startsWith('+k')) {
|
||||||
@@ -2709,7 +2724,9 @@ class WTVIRC {
|
|||||||
if (!chan_modes || chan_modes === true) {
|
if (!chan_modes || chan_modes === true) {
|
||||||
chan_modes = [];
|
chan_modes = [];
|
||||||
}
|
}
|
||||||
this.channelmodes.set(channel, [...chan_modes, `k ${key}`]);
|
// replace key mode if it exists
|
||||||
|
this.channelkeys.set(channel, key);
|
||||||
|
this.channelmodes.set(channel, [...chan_modes, 'k']);
|
||||||
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} +k ${key}\r\n`);
|
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} +k ${key}\r\n`);
|
||||||
return;
|
return;
|
||||||
} else if (mode.startsWith('-k')) {
|
} else if (mode.startsWith('-k')) {
|
||||||
@@ -2717,7 +2734,8 @@ class WTVIRC {
|
|||||||
if (!chan_modes || chan_modes === true) {
|
if (!chan_modes || chan_modes === true) {
|
||||||
chan_modes = [];
|
chan_modes = [];
|
||||||
}
|
}
|
||||||
this.channelmodes.set(channel, (chan_modes).filter(m => !/^k.*$/.test(m)));
|
this.channelkeys.delete(channel);
|
||||||
|
this.channelmodes.set(channel, (chan_modes).filter(m => m !== 'k'));
|
||||||
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} -k\r\n`);
|
this.broadcastChannel(channel, `:${nickname}!${username}@${socket.host} MODE ${channel} -k\r\n`);
|
||||||
return;
|
return;
|
||||||
} else if (mode.startsWith('+i')) {
|
} else if (mode.startsWith('+i')) {
|
||||||
|
|||||||
Reference in New Issue
Block a user