<commit_before>// When false nothing will be logged. 
// Configuration goes here.
require('./config.js');

if (!configuration.DEBUG) {
    console.log = function() {};
}


const Discord = require("discord.js");
const fs = require('fs');
let net;
let netOptions = {};

if (configuration.tlsEnabled) {
    net = require('tls');
    netOptions = {
        key: fs.readFileSync(configuration.tlsOptions.keyPath),
        cert: fs.readFileSync(configuration.tlsOptions.certPath)
    }

} else {
    net = require('net');
}

let request;

if (configuration.handleCode) {
    request = require('request');
}




//
// Let's ready some variables and stuff we will use later on.
//

// Object which will contain channel information.
let ircDetails = {
    DMserver: {
        lastPRIVMSG: []
    }
};

// Since we want a seperate connection for each discord server we will need to store our sockets. 
let ircClients = [];

// Simply used to give each new socket a unique number. 
let ircClientCount = 0;

// This is used to make sure that if discord reconnects not everything is wiped. 
let discordFirstConnection = true;

// Max line lenght for irc messages. 
const maxLineLength = 510;

//
// Generic functions
//

// Function that parses irc messages. 
// Shamelessly stolen from node-irc https://github.com/aredridel/node-ircd
function parseMessage(line) {
    let message = {};
    let m = /(:[^ ]+ )?([A-Z0-9]+)(?: (.*))?/i.exec(line);
    if (!m) {
        message['error'] = 'Unable to parse message';
    } else {
        let i;
        if (m[3] && (i = m[3].indexOf(':')) !== -1) {
            let rest = m[3].slice(i + 1);
            message.params = m[3].slice(0, i - 1).split(' ');
            message.params.push(rest);
        } else {
            if (m[3]) {
                message.params = m[3].split(' ');
            } else {
                message.params = [];
            }
        }
        if (m[2]) {
            message.command = m[2].toUpperCase();
        }
        if (m[1]) {
            message.sender = m[1];
        }
    }
    return message;
}

// Returns a number based on the discord server that increases per call.
// Used to make fairly sure nicknames on irc end up being unique after being scrubbed. 
// Make nicknames work for irc. 
function ircNickname(discordDisplayName, botuser, discriminator) {
    const replaceRegex = /[^a-zA-Z0-9_\\[\]\{\}\^`\|]/g;
    const shortenRegex = /_{1,}/g;

    if (replaceRegex.test(discordDisplayName)) {

        let newDisplayname = `${discordDisplayName.replace(replaceRegex, '_')}${discriminator}`;
        newDisplayname = newDisplayname.replace(shortenRegex, '_');

        return botuser ? `${newDisplayname}[BOT]` : newDisplayname;

    } else {
        return botuser ? `${discordDisplayName}[BOT]` : discordDisplayName;
    }


}


// Parses discord lines to make them work better on irc. 
function parseDiscordLine(line, discordID) {
    // Discord markdown parsing the lazy way. Probably fails in a bunch of different ways but at least it is easy. 
    line = line.replace(/\*\*(.*?)\*\*/g, '\x02$1\x0F');
    line = line.replace(/\*(.*?)\*/g, '\x1D$1\x0F');
    line = line.replace(/^_(.*?)\_/g, '\x01ACTION $1\x01');
    line = line.replace(/__(.*?)__/g, '\x1F$1\x0F');

    // With the above regex we might end up with to many end characters. This replaces the, 
    line = line.replace(/\x0F{2,}/g, '\x0F');

    // Now let's replace mentions with names we can recognize. 
    const mentionUserRegex = /(<@!?\d{1,}?>)/g;
    const mentionUserFound = line.match(mentionUserRegex);

    if (mentionUserFound) {
        mentionUserFound.forEach(function(mention) {
            const userID = mention.replace(/<@!?(\d{1,}?)>/, '$1');
            const memberObject = discordClient.guilds.get(discordID).members.get(userID);
            const displayName = memberObject.displayName;
            const isBot = memberObject.user.bot;
            const discriminator = memberObject.user.discriminator;

            const userName = ircNickname(displayName, isBot, discriminator);
            const replaceRegex = new RegExp(mention, 'g');
            if (userName) {
                line = line.replace(replaceRegex, `@${userName}`);
            }
        });
    }

    // Now let's do this again and replace mentions with roles we can recognize. 
    const mentionRoleRegex = /(<@&\d{1,}?>)/g;
    const mentionRoleFound = line.match(mentionRoleRegex);
    if (mentionRoleFound) {
        mentionRoleFound.forEach(function(mention) {
            const roleID = mention.replace(/<@&(\d{1,}?)>/, '$1');
            const roleObject = discordClient.guilds.get(discordID).roles.get(roleID);

            const replaceRegex = new RegExp(mention, 'g');
            if (roleObject) {
                const name = roleObject.name;
                line = line.replace(replaceRegex, `@${name}`);
            }
        });
    }

    // Channels are also a thing!. 
    const mentionChannelRegex = /(<#\d{1,}?>)/g;
    const mentionChannelFound = line.match(mentionChannelRegex);
    if (mentionChannelFound) {
        mentionChannelFound.forEach(function(mention) {
            const channelID = mention.replace(/<#(\d{1,}?)>/, '$1');
            const channelObject = discordClient.guilds.get(discordID).channels.get(channelID);

            const replaceRegex = new RegExp(mention, 'g');
            if (channelObject) {
                const name = channelObject.name;
                line = line.replace(replaceRegex, `@${name}`);
            }
        });
    }

    return line;
}

// Parse irc lines to make them work better on discord.<commit_msg>Fix channel names using # instead of @<commit_after>// When false nothing will be logged. 
// Configuration goes here.
require('./config.js');

if (!configuration.DEBUG) {
    console.log = function() {};
}


const Discord = require("discord.js");
const fs = require('fs');
let net;
let netOptions = {};

if (configuration.tlsEnabled) {
    net = require('tls');
    netOptions = {
        key: fs.readFileSync(configuration.tlsOptions.keyPath),
        cert: fs.readFileSync(configuration.tlsOptions.certPath)
    }

} else {
    net = require('net');
}

let request;

if (configuration.handleCode) {
    request = require('request');
}




//
// Let's ready some variables and stuff we will use later on.
//

// Object which will contain channel information.
let ircDetails = {
    DMserver: {
        lastPRIVMSG: []
    }
};

// Since we want a seperate connection for each discord server we will need to store our sockets. 
let ircClients = [];

// Simply used to give each new socket a unique number. 
let ircClientCount = 0;

// This is used to make sure that if discord reconnects not everything is wiped. 
let discordFirstConnection = true;

// Max line lenght for irc messages. 
const maxLineLength = 510;

//
// Generic functions
//

// Function that parses irc messages. 
// Shamelessly stolen from node-irc https://github.com/aredridel/node-ircd
function parseMessage(line) {
    let message = {};
    let m = /(:[^ ]+ )?([A-Z0-9]+)(?: (.*))?/i.exec(line);
    if (!m) {
        message['error'] = 'Unable to parse message';
    } else {
        let i;
        if (m[3] && (i = m[3].indexOf(':')) !== -1) {
            let rest = m[3].slice(i + 1);
            message.params = m[3].slice(0, i - 1).split(' ');
            message.params.push(rest);
        } else {
            if (m[3]) {
                message.params = m[3].split(' ');
            } else {
                message.params = [];
            }
        }
        if (m[2]) {
            message.command = m[2].toUpperCase();
        }
        if (m[1]) {
            message.sender = m[1];
        }
    }
    return message;
}

// Returns a number based on the discord server that increases per call.
// Used to make fairly sure nicknames on irc end up being unique after being scrubbed. 
// Make nicknames work for irc. 
function ircNickname(discordDisplayName, botuser, discriminator) {
    const replaceRegex = /[^a-zA-Z0-9_\\[\]\{\}\^`\|]/g;
    const shortenRegex = /_{1,}/g;

    if (replaceRegex.test(discordDisplayName)) {

        let newDisplayname = `${discordDisplayName.replace(replaceRegex, '_')}${discriminator}`;
        newDisplayname = newDisplayname.replace(shortenRegex, '_');

        return botuser ? `${newDisplayname}[BOT]` : newDisplayname;

    } else {
        return botuser ? `${discordDisplayName}[BOT]` : discordDisplayName;
    }


}


// Parses discord lines to make them work better on irc. 
function parseDiscordLine(line, discordID) {
    // Discord markdown parsing the lazy way. Probably fails in a bunch of different ways but at least it is easy. 
    line = line.replace(/\*\*(.*?)\*\*/g, '\x02$1\x0F');
    line = line.replace(/\*(.*?)\*/g, '\x1D$1\x0F');
    line = line.replace(/^_(.*?)\_/g, '\x01ACTION $1\x01');
    line = line.replace(/__(.*?)__/g, '\x1F$1\x0F');

    // With the above regex we might end up with to many end characters. This replaces the, 
    line = line.replace(/\x0F{2,}/g, '\x0F');

    // Now let's replace mentions with names we can recognize. 
    const mentionUserRegex = /(<@!?\d{1,}?>)/g;
    const mentionUserFound = line.match(mentionUserRegex);

    if (mentionUserFound) {
        mentionUserFound.forEach(function(mention) {
            const userID = mention.replace(/<@!?(\d{1,}?)>/, '$1');
            const memberObject = discordClient.guilds.get(discordID).members.get(userID);
            const displayName = memberObject.displayName;
            const isBot = memberObject.user.bot;
            const discriminator = memberObject.user.discriminator;

            const userName = ircNickname(displayName, isBot, discriminator);
            const replaceRegex = new RegExp(mention, 'g');
            if (userName) {
                line = line.replace(replaceRegex, `@${userName}`);
            }
        });
    }

    // Now let's do this again and replace mentions with roles we can recognize. 
    const mentionRoleRegex = /(<@&\d{1,}?>)/g;
    const mentionRoleFound = line.match(mentionRoleRegex);
    if (mentionRoleFound) {
        mentionRoleFound.forEach(function(mention) {
            const roleID = mention.replace(/<@&(\d{1,}?)>/, '$1');
            const roleObject = discordClient.guilds.get(discordID).roles.get(roleID);

            const replaceRegex = new RegExp(mention, 'g');
            if (roleObject) {
                const name = roleObject.name;
                line = line.replace(replaceRegex, `@${name}`);
            }
        });
    }

    // Channels are also a thing!. 
    const mentionChannelRegex = /(<#\d{1,}?>)/g;
    const mentionChannelFound = line.match(mentionChannelRegex);
    if (mentionChannelFound) {
        mentionChannelFound.forEach(function(mention) {
            const channelID = mention.replace(/<#(\d{1,}?)>/, '$1');
            const channelObject = discordClient.guilds.get(discordID).channels.get(channelID);

            const replaceRegex = new RegExp(mention, 'g');
            if (channelObject) {
                const name = channelObject.name;
                line = line.replace(replaceRegex, `#${name}`);
            }
        });
    }

    return line;
}

// Parse irc lines to make them work better on discord.
{'fraction_non_alphanumeric': 0.14737962223995743, 'fraction_numerical': 0.008867606632969762, 'mean_word_length': 2.419648271679806, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5118255', 'n_tokens_mistral': 3559, 'n_tokens_neox': 3416, 'n_words': 893}