more tweaks to irc

This commit is contained in:
zefie
2025-06-13 19:25:51 -04:00
parent 78c5bc9404
commit c18fd3f878

View File

@@ -63,6 +63,7 @@ class WTVIRC {
let nickname = ''; let nickname = '';
let username = ''; let username = '';
let channel = ''; let channel = '';
let realhost = this.getHostname(socket);
let host = this.getHostname(socket); let host = this.getHostname(socket);
let timestamp = Date.now(); let timestamp = Date.now();
@@ -1004,7 +1005,7 @@ class WTVIRC {
const userPart = maskParts[1] || '*'; const userPart = maskParts[1] || '*';
const hostPart = maskParts[2] || '*'; const hostPart = maskParts[2] || '*';
// Build user mask for this user // Build user mask for this user
const userMask = `${nickname}!${username}@${host}`; const userMask = `${nickname}!${username}@${realhost}`;
// Convert mask to regex // Convert mask to regex
const maskRegex = new RegExp('^' + const maskRegex = new RegExp('^' +
inviteMask inviteMask
@@ -1117,14 +1118,7 @@ class WTVIRC {
if (this.channels.has(channel)) { if (this.channels.has(channel)) {
this.channels.get(channel).delete(nickname); this.channels.get(channel).delete(nickname);
if (this.channels.get(channel).size === 0) { if (this.channels.get(channel).size === 0) {
this.channels.delete(channel); this.deleteChannel(channel);
this.channelops.delete(channel);
this.channelvoices.delete(channel);
this.channeltopics.delete(channel);
this.channelbans.delete(channel);
this.channelexemptions.delete(channel);
this.channelinvites.delete(channel);
this.channelmodes.delete(channel);
} }
} }
break; break;
@@ -1430,7 +1424,7 @@ class WTVIRC {
// Broadcast the KILL message to all users // Broadcast the KILL message to all users
this.broadcastUser(target_nick, `:${nickname}!${username}@${host} KILL ${target_nick} :${cleanKillReason}\r\n`); this.broadcastUser(target_nick, `:${nickname}!${username}@${host} KILL ${target_nick} :${cleanKillReason}\r\n`);
this.terminateSession(targetSocket, target_nick); this.terminateSession(targetSocket, true);
break; break;
case 'QUIT': case 'QUIT':
if (!registered) { if (!registered) {
@@ -1448,7 +1442,7 @@ class WTVIRC {
this.broadcastUser(nickname, `:${nickname}!${username}@${host} QUIT\r\n`, socket); this.broadcastUser(nickname, `:${nickname}!${username}@${host} QUIT\r\n`, socket);
} }
} }
this.terminateSession(socket, nickname); this.terminateSession(socket, true);
break; break;
default: default:
// Ignore unknown commands // Ignore unknown commands
@@ -1459,12 +1453,12 @@ class WTVIRC {
socket.on('end', () => { socket.on('end', () => {
this.clients = this.clients.filter(c => c !== socket); this.clients = this.clients.filter(c => c !== socket);
this.nicknames.delete(socket); this.terminateSession(socket, false);
}); });
socket.on('error', () => { socket.on('error', () => {
this.clients = this.clients.filter(c => c !== socket); this.clients = this.clients.filter(c => c !== socket);
this.nicknames.delete(socket); this.terminateSession(socket, true);
}); });
}); });
@@ -1475,7 +1469,22 @@ class WTVIRC {
}); });
} }
terminateSession(socket, nickname) { deleteChannel(channel) {
this.channels.delete(channel);
this.channelops.delete(channel);
this.channelvoices.delete(channel);
this.channeltopics.delete(channel);
this.channelbans.delete(channel);
this.channelexemptions.delete(channel);
this.channelinvites.delete(channel);
this.channelmodes.delete(channel);
if (this.debug) {
console.log(`Channel ${channel} deleted`);
}
}
terminateSession(socket, close = false) {
const nickname = this.nicknames.get(socket);
if (nickname) { if (nickname) {
this.usertimestamps.delete(nickname); this.usertimestamps.delete(nickname);
this.usersignontimestamps.delete(nickname); this.usersignontimestamps.delete(nickname);
@@ -1499,20 +1508,16 @@ class WTVIRC {
if (users.has(nickname)) { if (users.has(nickname)) {
users.delete(nickname); users.delete(nickname);
if (users.size === 0) { if (users.size === 0) {
this.channels.delete(ch); this.deleteChannel(ch);
this.channelops.delete(ch);
this.channelvoices.delete(ch);
this.channeltopics.delete(ch);
this.channelbans.delete(ch);
this.channelexemptions.delete(ch);
this.channelinvites.delete(ch);
this.channelmodes.delete(ch);
} }
} }
}); });
this.nicknames.delete(socket);
} }
if (close) {
socket.end(); socket.end();
} }
}
isBanned(nickname, channel) { isBanned(nickname, channel) {
if (this.channelbans.has(channel)) { if (this.channelbans.has(channel)) {
@@ -1648,24 +1653,31 @@ class WTVIRC {
getHostname(socket) { getHostname(socket) {
const username = this.nicknames.get(socket); const username = this.nicknames.get(socket);
const modes = this.usermodes.get(username); var modes = null;
var hostname = ''; if (username) {
modes = this.usermodes.get(username);
}
var hostname = 'unknown.host';
if (socket && socket.remoteAddress) { if (socket && socket.remoteAddress) {
try { try {
// Synchronously resolve the hostname (not recommended for production, but simple for this context)
// For async, you'd need to refactor the call site to handle promises/callbacks
let resolved = socket.remoteAddress; let resolved = socket.remoteAddress;
dns.reverse(socket.remoteAddress, (err, hostnames) => { dns.reverse(socket.remoteAddress, (err, hostnames) => {
if (!err && hostnames && hostnames.length > 0) { if (!err && hostnames && hostnames.length > 0) {
resolved = hostnames[0]; resolved = hostnames[0];
} else if (this.debug) {
console.error(`DNS reverse lookup failed for ${socket.remoteAddress}:`, err);
} }
}); });
hostname = resolved; hostname = resolved;
} catch (e) { } catch (e) {
if (this.debug) {
console.error(`Error resolving hostname for ${socket.remoteAddress}:`, e);
}
hostname = socket.remoteAddress; hostname = socket.remoteAddress;
} }
} }
if (modes) {
if (Array.isArray(modes) && modes.includes('h')) { if (Array.isArray(modes) && modes.includes('h')) {
// Masked hostname for +h users // Masked hostname for +h users
if (typeof hostname === 'string') { if (typeof hostname === 'string') {
@@ -1683,10 +1695,8 @@ class WTVIRC {
return 'hidden.host'; return 'hidden.host';
} }
} }
if (hostname) {
return hostname;
} }
return 'unknown.host'; return hostname;
} }
doLogin(nickname, socket) { doLogin(nickname, socket) {