<commit_before>/**
 * Command parser
 * Pokemon Showdown - http://pokemonshowdown.com/
 *
 * This is the command parser. Call it with CommandParser.parse
 * (scroll down to its definition for details)
 *
 * Individual commands are put in:
 *   commands.js - "core" commands that shouldn't be modified
 *   chat-plugins/ - other commands that can be safely modified
 *
 * The command API is (mostly) documented in chat-plugins/COMMANDS.md
 *
 * @license MIT license
 */

/*

To reload chat commands:

/hotpatch chat

*/

'use strict';

const MAX_MESSAGE_LENGTH = 300;

const BROADCAST_COOLDOWN = 20 * 1000;

const MESSAGE_COOLDOWN = 5 * 60 * 1000;

const MAX_PARSE_RECURSION = 10;

const VALID_COMMAND_TOKENS = '/!';

const BROADCAST_TOKEN = '!';

const fs = require('fs');
const path = require('path');

exports.multiLinePattern = {
	elements: [],
	regexp: null,
	register: function (elem) {
		if (Array.isArray(elem)) {
			elem.forEach(elem => this.elements.push(elem));
		} else {
			this.elements.push(elem);
		}
		this.regexp = new RegExp('^(' + this.elements.map(elem => '(?:' + elem + ')').join('|') + ')', 'i');
	},
	test: function (text) {
		if (!this.regexp) return false;
		return this.regexp.test(text);
	},
};

/*********************************************************
 * Load command files
 *********************************************************/

let baseCommands = exports.baseCommands = require('./commands.js').commands;
let commands = exports.commands = Object.assign({}, baseCommands);

// Install plug-in commands

// info always goes first so other plugins can shadow it
Object.assign(commands, require('./chat-plugins/info.js').commands);

for (let file of fs.readdirSync(path.resolve(__dirname, 'chat-plugins'))) {
	if (file.substr(-3) !== '.js' || file === 'info.js') continue;
	Object.assign(commands, require('./chat-plugins/' + file).commands);
}

/*********************************************************
 * Modlog
 *********************************************************/

let modlog = exports.modlog = {
	lobby: fs.createWriteStream(path.resolve(__dirname, 'logs/modlog/modlog_lobby.txt'), {flags:'a+'}),
	battle: fs.createWriteStream(path.resolve(__dirname, 'logs/modlog/modlog_battle.txt'), {flags:'a+'}),
};

let writeModlog = exports.writeModlog = function (roomid, text) {
	if (!modlog[roomid]) {
		modlog[roomid] = fs.createWriteStream(path.resolve(__dirname, 'logs/modlog/modlog_' + roomid + '.txt'), {flags:'a+'});
	}
	modlog[roomid].write('[' + (new Date().toJSON()) + '] ' + text + '\n');
};

/*********************************************************
 * Parser
 *********************************************************/

class CommandContext {
	constructor(options) {
		this.cmd = options.cmd || '';
		this.cmdToken = options.cmdToken || '';

		this.target = options.target || '';
		this.message = options.message || '';

		this.levelsDeep = options.levelsDeep || 0;
		this.namespaces = options.namespaces || null;

		this.room = options.room || null;
		this.user = options.user || null;
		this.connection = options.connection || null;

		this.targetUser = null;
		this.targetUsername = '';
		this.inputUsername = '';
	}

	checkFormat(room, message) {
		if (!room) return false;
		if (!room.filterStretching && !room.filterCaps && !room.filterSpoilers) return false;
		let formatError = [];
		// Removes extra spaces and null characters
		message = message.trim().replace(/[ \u0000\u200B-\u200F]+/g, ' ');

		let stretchMatch = room.filterStretching && message.match(/(.+?)\1{7,}/i);<commit_msg>Remove unused variable in checkFormat (#2688)<commit_after>/**
 * Command parser
 * Pokemon Showdown - http://pokemonshowdown.com/
 *
 * This is the command parser. Call it with CommandParser.parse
 * (scroll down to its definition for details)
 *
 * Individual commands are put in:
 *   commands.js - "core" commands that shouldn't be modified
 *   chat-plugins/ - other commands that can be safely modified
 *
 * The command API is (mostly) documented in chat-plugins/COMMANDS.md
 *
 * @license MIT license
 */

/*

To reload chat commands:

/hotpatch chat

*/

'use strict';

const MAX_MESSAGE_LENGTH = 300;

const BROADCAST_COOLDOWN = 20 * 1000;

const MESSAGE_COOLDOWN = 5 * 60 * 1000;

const MAX_PARSE_RECURSION = 10;

const VALID_COMMAND_TOKENS = '/!';

const BROADCAST_TOKEN = '!';

const fs = require('fs');
const path = require('path');

exports.multiLinePattern = {
	elements: [],
	regexp: null,
	register: function (elem) {
		if (Array.isArray(elem)) {
			elem.forEach(elem => this.elements.push(elem));
		} else {
			this.elements.push(elem);
		}
		this.regexp = new RegExp('^(' + this.elements.map(elem => '(?:' + elem + ')').join('|') + ')', 'i');
	},
	test: function (text) {
		if (!this.regexp) return false;
		return this.regexp.test(text);
	},
};

/*********************************************************
 * Load command files
 *********************************************************/

let baseCommands = exports.baseCommands = require('./commands.js').commands;
let commands = exports.commands = Object.assign({}, baseCommands);

// Install plug-in commands

// info always goes first so other plugins can shadow it
Object.assign(commands, require('./chat-plugins/info.js').commands);

for (let file of fs.readdirSync(path.resolve(__dirname, 'chat-plugins'))) {
	if (file.substr(-3) !== '.js' || file === 'info.js') continue;
	Object.assign(commands, require('./chat-plugins/' + file).commands);
}

/*********************************************************
 * Modlog
 *********************************************************/

let modlog = exports.modlog = {
	lobby: fs.createWriteStream(path.resolve(__dirname, 'logs/modlog/modlog_lobby.txt'), {flags:'a+'}),
	battle: fs.createWriteStream(path.resolve(__dirname, 'logs/modlog/modlog_battle.txt'), {flags:'a+'}),
};

let writeModlog = exports.writeModlog = function (roomid, text) {
	if (!modlog[roomid]) {
		modlog[roomid] = fs.createWriteStream(path.resolve(__dirname, 'logs/modlog/modlog_' + roomid + '.txt'), {flags:'a+'});
	}
	modlog[roomid].write('[' + (new Date().toJSON()) + '] ' + text + '\n');
};

/*********************************************************
 * Parser
 *********************************************************/

class CommandContext {
	constructor(options) {
		this.cmd = options.cmd || '';
		this.cmdToken = options.cmdToken || '';

		this.target = options.target || '';
		this.message = options.message || '';

		this.levelsDeep = options.levelsDeep || 0;
		this.namespaces = options.namespaces || null;

		this.room = options.room || null;
		this.user = options.user || null;
		this.connection = options.connection || null;

		this.targetUser = null;
		this.targetUsername = '';
		this.inputUsername = '';
	}

	checkFormat(room, message) {
		if (!room) return false;
		if (!room.filterStretching && !room.filterCaps) return false;
		let formatError = [];
		// Removes extra spaces and null characters
		message = message.trim().replace(/[ \u0000\u200B-\u200F]+/g, ' ');

		let stretchMatch = room.filterStretching && message.match(/(.+?)\1{7,}/i);
{'fraction_non_alphanumeric': 0.25098647125140927, 'fraction_numerical': 0.009582863585118376, 'mean_word_length': 4.557556773688332, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '7511311', 'n_tokens_mistral': 2317, 'n_tokens_neox': 2176, 'n_words': 495}