invites, +m, +i
This commit is contained in:
@@ -21,6 +21,7 @@ class WTVIRC {
|
|||||||
this.channelops = new Map(); // channel -> Set of operators
|
this.channelops = new Map(); // channel -> Set of operators
|
||||||
this.channelvoices = new Map(); // channel -> Set of voiced users
|
this.channelvoices = new Map(); // channel -> Set of voiced users
|
||||||
this.channeltopics = new Map(); // channel -> topic
|
this.channeltopics = new Map(); // channel -> topic
|
||||||
|
this.channelinvites = new Map(); // channel -> Set of invited users
|
||||||
this.channelbans = new Map(); // channel -> Set of banned users
|
this.channelbans = new Map(); // channel -> Set of banned users
|
||||||
this.channelmodes = new Map(); // channel -> modes
|
this.channelmodes = new Map(); // channel -> modes
|
||||||
this.nicknames = new Map(); // socket -> nickname
|
this.nicknames = new Map(); // socket -> nickname
|
||||||
@@ -165,6 +166,66 @@ class WTVIRC {
|
|||||||
const modes = this.channelmodes.get(channel) || '';
|
const modes = this.channelmodes.get(channel) || '';
|
||||||
socket.write(`:${this.servername} 324 ${nickname} ${channel} ${modes}\r\n`);
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} ${modes}\r\n`);
|
||||||
break;
|
break;
|
||||||
|
} else if (mode.startsWith('+m')) {
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '') + 'm');
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} +m\r\n`);
|
||||||
|
break;
|
||||||
|
} else if (mode.startsWith('-m')) {
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '').replace('m', ''));
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} -m\r\n`);
|
||||||
|
break;
|
||||||
|
} else if (mode.startsWith('+l')) {
|
||||||
|
if (params.length < 3) {
|
||||||
|
socket.write(`:${this.servername} 461 ${nickname} MODE :Not enough parameters\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const limit = parseInt(params[2], 10);
|
||||||
|
if (isNaN(limit) || limit < 0) {
|
||||||
|
socket.write(`:${this.servername} 501 ${nickname} :Invalid channel limit\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '') + `l${limit}`);
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} +l ${limit}\r\n`);
|
||||||
|
break;
|
||||||
|
} else if (mode.startsWith('-l')) {
|
||||||
|
if (params.length < 3) {
|
||||||
|
socket.write(`:${this.servername} 461 ${nickname} MODE :Not enough parameters\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const limit = parseInt(params[2], 10);
|
||||||
|
if (isNaN(limit) || limit < 0) {
|
||||||
|
socket.write(`:${this.servername} 501 ${nickname} :Invalid channel limit\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '').replace(`l${limit}`, ''));
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} -l ${limit}\r\n`);
|
||||||
|
break;
|
||||||
|
} else if (mode.startsWith('+k')) {
|
||||||
|
if (params.length < 3) {
|
||||||
|
socket.write(`:${this.servername} 461 ${nickname} MODE :Not enough parameters\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const key = params[2];
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '') + `k${key}`);
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} +k ${key}\r\n`);
|
||||||
|
break;
|
||||||
|
} else if (mode.startsWith('-k')) {
|
||||||
|
if (params.length < 3) {
|
||||||
|
socket.write(`:${this.servername} 461 ${nickname} MODE :Not enough parameters\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const key = params[2];
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '').replace(`k${key}`, ''));
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} -k ${key}\r\n`);
|
||||||
|
break;
|
||||||
|
} else if (mode.startsWith('+i')) {
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '') + 'i');
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} +i\r\n`);
|
||||||
|
break;
|
||||||
|
} else if (mode.startsWith('-i')) {
|
||||||
|
this.channelmodes.set(channel, (this.channelmodes.get(channel) || '').replace('i', ''));
|
||||||
|
socket.write(`:${this.servername} 324 ${nickname} ${channel} -i\r\n`);
|
||||||
|
break;
|
||||||
} else if (mode.startsWith('+o')) {
|
} else if (mode.startsWith('+o')) {
|
||||||
if (!this.channelops.has(channel) || this.channelops.get(channel) === true) {
|
if (!this.channelops.has(channel) || this.channelops.get(channel) === true) {
|
||||||
socket.write(`:${this.servername} 482 ${nickname} ${channel} :You're not channel operator\r\n`);
|
socket.write(`:${this.servername} 482 ${nickname} ${channel} :You're not channel operator\r\n`);
|
||||||
@@ -372,6 +433,34 @@ class WTVIRC {
|
|||||||
continue; // Skip joining this channel
|
continue; // Skip joining this channel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.channelmodes.has(ch)) {
|
||||||
|
const modes = this.channelmodes.get(ch);
|
||||||
|
const keyMatch = modes.match(/k([^\s]+)/);
|
||||||
|
if (keyMatch) {
|
||||||
|
const channelKey = keyMatch[1];
|
||||||
|
// 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.
|
||||||
|
// For simplicity, assume only one channel per JOIN or the key is always params[1]
|
||||||
|
const providedKey = params[1];
|
||||||
|
if (!providedKey || providedKey !== channelKey) {
|
||||||
|
socket.write(`:${this.servername} 475 ${nickname} ${ch} :Cannot join channel (+k)\r\n`);
|
||||||
|
continue; // Skip joining this channel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.channelmodes.has(ch) && this.channelmodes.get(ch).includes('i')) {
|
||||||
|
// Channel is invite-only (+i)
|
||||||
|
// For simplicity, let's assume you have an invited list per channel (not implemented yet)
|
||||||
|
// We'll use a Map: this.channelinvites = new Map(); // channel -> Set of invited nicks
|
||||||
|
if (!this.channelinvites) this.channelinvites = new Map();
|
||||||
|
const invited = this.channelinvites.get(ch) || new Set();
|
||||||
|
if (!invited.has(nickname)) {
|
||||||
|
socket.write(`:${this.servername} 473 ${nickname} ${ch} :Cannot join channel (+i)\r\n`);
|
||||||
|
continue; // Skip joining this channel
|
||||||
|
}
|
||||||
|
invited.delete(nickname);
|
||||||
|
this.channelinvites.set(ch, invited);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Recursively process each channel join
|
// Recursively process each channel join
|
||||||
const joinLine = `JOIN ${ch}`;
|
const joinLine = `JOIN ${ch}`;
|
||||||
// Simulate a JOIN command for each channel
|
// Simulate a JOIN command for each channel
|
||||||
@@ -456,6 +545,51 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'INVITE':
|
||||||
|
if (!registered) {
|
||||||
|
socket.write(`:${this.servername} 451 ${nickname} :You have not registered\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (params.length < 2) {
|
||||||
|
socket.write(`:${this.servername} 461 ${nickname} INVITE :Not enough parameters\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const invitee = params[0];
|
||||||
|
channel = params[1];
|
||||||
|
if (!this.channels.has(channel)) {
|
||||||
|
socket.write(`:${this.servername} 403 ${nickname} ${channel} :No such channel\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!this.channelops.has(channel) || this.channelops.get(channel) === true) {
|
||||||
|
socket.write(`:${this.servername} 482 ${nickname} ${channel} :You're not channel operator\r\n`);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (!this.channelops.get(channel).has(nickname)) {
|
||||||
|
socket.write(`:${this.servername} 482 ${nickname} ${channel} :You're not channel operator\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.nicknames.has(socket)) {
|
||||||
|
socket.write(`:${this.servername} 401 ${nickname} ${invitee} :No such nick/channel\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const inviteeSocket = Array.from(this.nicknames.keys()).find(s => this.nicknames.get(s) === invitee);
|
||||||
|
if (!inviteeSocket) {
|
||||||
|
socket.write(`:${this.servername} 401 ${nickname} ${invitee} :No such nick/channel\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!this.channels.has(channel) || !this.channels.get(channel).has(invitee)) {
|
||||||
|
if (!this.channelinvites) this.channelinvites = new Map();
|
||||||
|
const invited = this.channelinvites.get(channel) || new Set();
|
||||||
|
invited.add(invitee);
|
||||||
|
this.channelinvites.set(channel, invited);
|
||||||
|
socket.write(`:${this.servername} 341 ${nickname} ${invitee} ${channel} :Invited to channel\r\n`);
|
||||||
|
inviteeSocket.write(`:${this.servername} 341 ${nickname} ${invitee} ${channel} :You have been invited to join ${channel}\r\n`);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
socket.write(`:${this.servername} 443 ${nickname} ${invitee} ${channel} :${invitee} is already on that channel\r\n`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'LIST':
|
case 'LIST':
|
||||||
if (!registered) {
|
if (!registered) {
|
||||||
socket.write(`:${this.servername} 451 ${nickname} :You have not registered\r\n`);
|
socket.write(`:${this.servername} 451 ${nickname} :You have not registered\r\n`);
|
||||||
@@ -519,6 +653,19 @@ class WTVIRC {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (params[0]) {
|
if (params[0]) {
|
||||||
|
const target = params[0];
|
||||||
|
if (target.startsWith('#')) {
|
||||||
|
// Channel message
|
||||||
|
if (this.channelmodes.has(target) && this.channelmodes.get(target).includes('m')) {
|
||||||
|
// Channel is moderated (+m)
|
||||||
|
const voices = this.channelvoices.get(target) || new Set();
|
||||||
|
const ops = this.channelops.get(target) || new Set();
|
||||||
|
if (!(voices.has(nickname) || ops.has(nickname))) {
|
||||||
|
socket.write(`:${this.servername} 404 ${nickname} ${target} :Cannot send to channel (+m)\r\n`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
const msg = line.slice(line.indexOf(':', 1) + 1);
|
const msg = line.slice(line.indexOf(':', 1) + 1);
|
||||||
this.broadcast(`:${nickname}!${username}@${host} PRIVMSG ${params[0]} :${msg}\r\n`, socket);
|
this.broadcast(`:${nickname}!${username}@${host} PRIVMSG ${params[0]} :${msg}\r\n`, socket);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user