const fs = require('fs'); const xml2js = require('xml2js'); const { Client, Intents } = require('discord.js-selfbot-v13'); const irc = require('irc'); // Load config.xml let config; const parser = new xml2js.Parser({ explicitArray: false }); try { const xmlData = fs.readFileSync('config.xml', 'utf8'); parser.parseString(xmlData, (err, result) => { if (err) throw err; config = result.BridgeConfig; }); } catch (e) { console.error('Failed to load or parse config.xml:', e); process.exit(1); } const DISCORD_TOKEN = config.Discord.Token; const bridges = Array.isArray(config.Bridges.Bridge) ? config.Bridges.Bridge : [config.Bridges.Bridge]; // Create Discord client const discordClient = new Client({ checkUpdate: false, intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); // Map to hold IRC clients and their config const ircClients = new Map(); // Helper function to create and connect an IRC client for each bridge function createIRCClient(bridge) { const ircConfig = bridge.IRC; const discordChannelId = bridge.Discord.ChannelId; const server = ircConfig.Server; const port = parseInt(ircConfig.Port, 10); const nick = ircConfig.Nick; const channel = ircConfig.Channel; const client = new irc.Client(server, nick, { channels: [channel], port: port, autoConnect: false }); client.on('error', (message) => { console.error(`IRC error on ${server} (${channel}):`, message); }); client.on('message', (from, to, message) => { // Avoid echoing own messages if (from === nick) return; const ircMessage = `<${from}> ${message}`; const discordChannel = discordClient.channels.cache.get(discordChannelId); if (discordChannel) { discordChannel.send(ircMessage).catch(console.error); } else { console.warn(`Discord channel ${discordChannelId} not found.`); } }); return { client, server, channel, nick, discordChannelId }; } // Initialize all IRC clients for (const bridge of bridges) { const { client, server, channel, nick } = createIRCClient(bridge); ircClients.set(client, { server, channel, nick, discordChannelId: bridge.Discord.ChannelId }); } // Connect all IRC clients once Discord is ready discordClient.once('ready', () => { console.log(`Logged in as ${discordClient.user.tag}`); for (const [ircClient, info] of ircClients.entries()) { console.log(`Connecting to IRC server ${info.server} on channel ${info.channel}...`); ircClient.connect(5, () => { console.log(`Connected to IRC server ${info.server} channel ${info.channel}`); }); } }); // Forward Discord messages to corresponding IRC channel discordClient.on('messageCreate', (message) => { if (message.author.bot) return; // Find the IRC client(s) that correspond to this Discord channel for (const [ircClient, info] of ircClients.entries()) { if (message.channel.id === info.discordChannelId) { // Avoid echoing messages sent by the bot itself if (message.author.id === discordClient.user.id) return; const discordMessage = `<${message.author.username}> ${message.content}`; console.log(`Forwarding Discord message to IRC [${info.server} ${info.channel}]: ${discordMessage}`); ircClient.say(info.channel, discordMessage); } } }); // Login to Discord discordClient.login(DISCORD_TOKEN).catch(err => { console.error('Failed to login to Discord:', err); });