add reserved channel feature
This commit is contained in:
@@ -84,6 +84,17 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
|
if (this.irc_config.channels) {
|
||||||
|
for (const channel of this.irc_config.channels) {
|
||||||
|
this.createChannel(channel.name);
|
||||||
|
if (channel.modes && Array.isArray(channel.modes)) {
|
||||||
|
this.channelmodes.set(channel.name, channel.modes.slice());
|
||||||
|
}
|
||||||
|
if (channel.topic) {
|
||||||
|
this.channeltopics.set(channel.name, channel.topic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.server_start_time = Date.now();
|
this.server_start_time = Date.now();
|
||||||
this.server = net.createServer((socket) => {
|
this.server = net.createServer((socket) => {
|
||||||
// Detect SSL handshake and wrap socket if needed
|
// Detect SSL handshake and wrap socket if needed
|
||||||
@@ -773,6 +784,16 @@ class WTVIRC {
|
|||||||
socket.write(`:${this.servername} 353 ${socket.nickname} = ${ch} :${users.join(' ')}\r\n`);
|
socket.write(`:${this.servername} 353 ${socket.nickname} = ${ch} :${users.join(' ')}\r\n`);
|
||||||
}
|
}
|
||||||
socket.write(`:${this.servername} 366 ${socket.nickname} ${ch} :End of /NAMES list\r\n`);
|
socket.write(`:${this.servername} 366 ${socket.nickname} ${ch} :End of /NAMES list\r\n`);
|
||||||
|
if (this.isReservedChannel(ch)) {
|
||||||
|
if (this.checkIfReservedChannelOp(socket, ch)) {
|
||||||
|
if (!this.channelops.has(ch) || this.channelops.get(ch) === true) {
|
||||||
|
this.channelops.set(ch, new Set());
|
||||||
|
}
|
||||||
|
this.channelops.get(ch).add(socket.nickname);
|
||||||
|
this.broadcastChannel(ch, `:${socket.nickname}!${socket.username}@${socket.host} MODE ${ch} +o ${socket.nickname}\r\n`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'NAMES':
|
case 'NAMES':
|
||||||
@@ -1236,6 +1257,7 @@ class WTVIRC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteChannel(channel) {
|
deleteChannel(channel) {
|
||||||
|
if (!this.isReservedChannel(channel)) {
|
||||||
this.channels.delete(channel);
|
this.channels.delete(channel);
|
||||||
this.channelops.delete(channel);
|
this.channelops.delete(channel);
|
||||||
this.channelvoices.delete(channel);
|
this.channelvoices.delete(channel);
|
||||||
@@ -1248,6 +1270,11 @@ class WTVIRC {
|
|||||||
if (this.debug) {
|
if (this.debug) {
|
||||||
console.log(`Channel ${channel} deleted`);
|
console.log(`Channel ${channel} deleted`);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (this.debug) {
|
||||||
|
console.warn(`Attempted to delete reserved channel ${channel}, operation ignored.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
terminateSession(socket, close = false) {
|
terminateSession(socket, close = false) {
|
||||||
@@ -1408,10 +1435,12 @@ class WTVIRC {
|
|||||||
if (!username) return false;
|
if (!username) return false;
|
||||||
console.log
|
console.log
|
||||||
const userIdent = this.usernames.get(username) || username;
|
const userIdent = this.usernames.get(username) || username;
|
||||||
const host = socket.host
|
const host = socket.host;
|
||||||
const realhost = socket.realhost
|
const realhost = socket.realhost;
|
||||||
|
const realaddress = socket.remoteAddress;
|
||||||
const fullMask = `${username}!${userIdent}@${host}`;
|
const fullMask = `${username}!${userIdent}@${host}`;
|
||||||
const fullMask2 = `${username}!${userIdent}@${realhost}`;
|
const fullMask2 = `${username}!${userIdent}@${realhost}`;
|
||||||
|
const fullMask3 = `${username}!${userIdent}@${realaddress}`;
|
||||||
|
|
||||||
// If mask does not contain '!', treat as nickname or username only
|
// If mask does not contain '!', treat as nickname or username only
|
||||||
if (!mask.includes('!')) {
|
if (!mask.includes('!')) {
|
||||||
@@ -1441,6 +1470,12 @@ class WTVIRC {
|
|||||||
const [fullUser2, fullHost2] = (fullRest2 || '').split('@', 2);
|
const [fullUser2, fullHost2] = (fullRest2 || '').split('@', 2);
|
||||||
matches = nickRegex.test(fullNick2) && userRegex.test(fullUser2) && hostRegex.test(fullHost2);
|
matches = nickRegex.test(fullNick2) && userRegex.test(fullUser2) && hostRegex.test(fullHost2);
|
||||||
}
|
}
|
||||||
|
if (!matches && fullMask3) {
|
||||||
|
// Try matching against the real host if available
|
||||||
|
const [fullNick3, fullRest3] = fullMask3.split('!', 2);
|
||||||
|
const [fullUser3, fullHost3] = (fullRest3 || '').split('@', 2);
|
||||||
|
matches = nickRegex.test(fullNick3) && userRegex.test(fullUser3) && hostRegex.test(fullHost3);
|
||||||
|
}
|
||||||
return matches;
|
return matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1964,6 +1999,28 @@ class WTVIRC {
|
|||||||
socket.write(`:${this.servername} 376 ${nickname} :End of /MOTD command\r\n`);
|
socket.write(`:${this.servername} 376 ${nickname} :End of /MOTD command\r\n`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReservedChannel(channel) {
|
||||||
|
if (this.irc_config.channels && Array.isArray(this.irc_config.channels)) {
|
||||||
|
return this.irc_config.channels.some(ch => ch.name === channel);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkIfReservedChannelOp(socket, channel) {
|
||||||
|
if (this.isReservedChannel(channel)) {
|
||||||
|
const reservedChannel = this.irc_config.channels.find(ch => ch.name === channel);
|
||||||
|
// reservedChannel.ops is an array of masks
|
||||||
|
if (reservedChannel && reservedChannel.ops && Array.isArray(reservedChannel.ops)) {
|
||||||
|
for (const mask of reservedChannel.ops) {
|
||||||
|
if (this.checkMask(mask, socket)) {
|
||||||
|
return true; // User is an operator for this reserved channel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false; // User is not an operator for this reserved channel
|
||||||
|
}
|
||||||
|
|
||||||
doLogin(nickname, socket) {
|
doLogin(nickname, socket) {
|
||||||
socket.write(`:${this.servername} 001 ${nickname} :Welcome to the IRC server, ${nickname}\r\n`);
|
socket.write(`:${this.servername} 001 ${nickname} :Welcome to the IRC server, ${nickname}\r\n`);
|
||||||
socket.write(`:${this.servername} 002 ${nickname} :Your host is ${this.servername}, running version minisrv ${this.minisrv_config.version}\r\n`);
|
socket.write(`:${this.servername} 002 ${nickname} :Your host is ${this.servername}, running version minisrv ${this.minisrv_config.version}\r\n`);
|
||||||
|
|||||||
@@ -73,7 +73,17 @@
|
|||||||
/* self-signed, can be replaced with another cert */
|
/* self-signed, can be replaced with another cert */
|
||||||
"cert": "%ServiceDeps%/irc/selfsigned_cert.pem",
|
"cert": "%ServiceDeps%/irc/selfsigned_cert.pem",
|
||||||
"key": "%ServiceDeps%/irc/selfsigned_key.pem"
|
"key": "%ServiceDeps%/irc/selfsigned_key.pem"
|
||||||
|
},
|
||||||
|
"channels": [
|
||||||
|
{
|
||||||
|
"name": "#general",
|
||||||
|
"modes": ["n","t"],
|
||||||
|
"topic": "General Chat Channel",
|
||||||
|
"ops": [
|
||||||
|
"*!*@127.0.0.1"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"pc_admin": {
|
"pc_admin": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
|||||||
Reference in New Issue
Block a user