<commit_before>"use strict";

const Chan = require("../../models/chan");
const Msg = require("../../models/msg");
const LinkPrefetch = require("./link");
const cleanIrcMessage = require("../../../client/js/libs/handlebars/ircmessageparser/cleanIrcMessage");
const nickRegExp = /(?:\x03[0-9]{1,2}(?:,[0-9]{1,2})?)?([\w[\]\\`^{|}-]{4,})/g;

module.exports = function(irc, network) {
	const client = this;

	irc.on("notice", function(data) {
		// Some servers send notices without any nickname
		if (!data.nick) {
			data.from_server = true;
			data.nick = network.host;
		}

		data.type = Msg.Type.NOTICE;
		handleMessage(data);
	});

	irc.on("action", function(data) {
		data.type = Msg.Type.ACTION;
		handleMessage(data);
	});

	irc.on("privmsg", function(data) {
		data.type = Msg.Type.MESSAGE;
		handleMessage(data);
	});

	irc.on("wallops", function(data) {
		data.from_server = true;
		data.type = Msg.Type.NOTICE;
		handleMessage(data);
	});

	function handleMessage(data) {
		let chan;
		const msg = new Msg({
			type: data.type,
			time: data.time,
			text: data.message,
			self: data.nick === irc.user.nick,
			highlight: false,
			users: [],
		});

		// Server messages go to server window, no questions asked
		if (data.from_server) {
			chan = network.channels[0];
			msg.from = chan.getUser(data.nick);
		} else {
			let target = data.target;

			// If the message is targeted at us, use sender as target instead
			if (target.toLowerCase() === irc.user.nick.toLowerCase()) {
				target = data.nick;
			}

			chan = network.getChannel(target);

			if (typeof chan === "undefined") {
				// Send notices that are not targeted at us into the server window
				if (data.type === Msg.Type.NOTICE) {
					msg.showInActive = true;
					chan = network.channels[0];
				} else {
					chan = new Chan({
						type: Chan.Type.QUERY,
						name: target,
					});
					network.channels.push(chan);
					client.emit("join", {
						network: network.id,
						chan: chan.getFilteredClone(true),
					});
				}
			}

			msg.from = chan.getUser(data.nick);

			// Query messages (unless self) always highlight
			if (chan.type === Chan.Type.QUERY) {
				msg.highlight = !msg.self;
			} else if (chan.type === Chan.Type.CHANNEL) {
				msg.from.lastMessage = data.time || Date.now();
			}
		}

		// Self messages in channels are never highlighted
		// Non-self messages are highlighted as soon as the nick is detected
		if (!msg.highlight && !msg.self) {
			msg.highlight = network.highlightRegex.test(data.message);
		}

		let match;
		while ((match = nickRegExp.exec(data.message))) {
			if (chan.findUser(match[1])) {
				msg.users.push(match[1]);<commit_msg>Fix possible issues with `from` in messages<commit_after>"use strict";

const Chan = require("../../models/chan");
const Msg = require("../../models/msg");
const LinkPrefetch = require("./link");
const cleanIrcMessage = require("../../../client/js/libs/handlebars/ircmessageparser/cleanIrcMessage");
const nickRegExp = /(?:\x03[0-9]{1,2}(?:,[0-9]{1,2})?)?([\w[\]\\`^{|}-]{4,})/g;

module.exports = function(irc, network) {
	const client = this;

	irc.on("notice", function(data) {
		// Some servers send notices without any nickname
		if (!data.nick) {
			data.from_server = true;
			data.nick = network.host;
		}

		data.type = Msg.Type.NOTICE;
		handleMessage(data);
	});

	irc.on("action", function(data) {
		data.type = Msg.Type.ACTION;
		handleMessage(data);
	});

	irc.on("privmsg", function(data) {
		data.type = Msg.Type.MESSAGE;
		handleMessage(data);
	});

	irc.on("wallops", function(data) {
		data.from_server = true;
		data.type = Msg.Type.NOTICE;
		handleMessage(data);
	});

	function handleMessage(data) {
		let chan;
		const from = chan.getUser(data.nick);
		const msg = new Msg({
			type: data.type,
			time: data.time,
			text: data.message,
			self: data.nick === irc.user.nick,
			from: from,
			highlight: false,
			users: [],
		});

		// Server messages go to server window, no questions asked
		if (data.from_server) {
			chan = network.channels[0];
		} else {
			let target = data.target;

			// If the message is targeted at us, use sender as target instead
			if (target.toLowerCase() === irc.user.nick.toLowerCase()) {
				target = data.nick;
			}

			chan = network.getChannel(target);

			if (typeof chan === "undefined") {
				// Send notices that are not targeted at us into the server window
				if (data.type === Msg.Type.NOTICE) {
					msg.showInActive = true;
					chan = network.channels[0];
				} else {
					chan = new Chan({
						type: Chan.Type.QUERY,
						name: target,
					});
					network.channels.push(chan);
					client.emit("join", {
						network: network.id,
						chan: chan.getFilteredClone(true),
					});
				}
			}

			// Query messages (unless self) always highlight
			if (chan.type === Chan.Type.QUERY) {
				msg.highlight = !msg.self;
			} else if (chan.type === Chan.Type.CHANNEL) {
				from.lastMessage = data.time || Date.now();
			}
		}

		// Self messages in channels are never highlighted
		// Non-self messages are highlighted as soon as the nick is detected
		if (!msg.highlight && !msg.self) {
			msg.highlight = network.highlightRegex.test(data.message);
		}

		let match;
		while ((match = nickRegExp.exec(data.message))) {
			if (chan.findUser(match[1])) {
				msg.users.push(match[1]);
{'fraction_non_alphanumeric': 0.16948833709556058, 'fraction_numerical': 0.0056433408577878106, 'mean_word_length': 3.0587786259541985, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '6119708', 'n_tokens_mistral': 2138, 'n_tokens_neox': 1774, 'n_words': 414}