<commit_before>/**
 * Miscellaneous commands
 *
 * Fixed/Improved upon by: The Run, HoeenHero, and Mystifi.
 *
 * Some of this code was borrowed from panpawn/jd/other contributors; as
 * such, credits go to them as well.
 */

'use strict';

let fs = require('fs');
let moment = require('moment');
let request = require('request');
let regdateCache = {};

//let badges = fs.createWriteStream('badges.txt', {'flags': 'a'});

function loadRegdateCache() {
	try {
		regdateCache = JSON.parse(fs.readFileSync('config/regdate.json', 'utf8'));
	} catch (e) {}
}
loadRegdateCache();

function saveRegdateCache() {
	fs.writeFileSync('config/regdate.json', JSON.stringify(regdateCache));
}


function getLastSeen (userid) {
	if (!global.LastSeen) return "(not available)";
	if (!LastSeen[userid]) return null;
	let f = new Date(LastSeen[userid]);
	let n = new Date(); // Now
	let diff = (Date.now() - LastSeen[userid]) / 1000;
	let text;
	if (diff > 24 * 60 * 60) {
		let days = Math.floor(diff / (24 * 60 * 60));
		text = days + " " + (days === 1 ? "day" : "days");
		let hours = Math.floor(diff / (60 * 60)) - days * 24;
		if (hours) text += ", " + hours + " " + (hours === 1 ? "hour" : "hours");
	} else {
		text = diff.seconds().duration();
	}
	return f.toString().substr(0, 25) + " (" + text + " ago)";
}

function clearRoom(room) {
	let len = (room.log && room.log.length) || 0;
	let users = [];
	while (len--) {
		room.log[len] = '';
	}
	for (let u in room.users) {
		users.push(u);
		Users(u).leaveRoom(room, Users(u).connections[0]);
	}
	len = users.length;
	setTimeout(() => {
		while (len--) {
			Users(users[len]).joinRoom(room, Users(users[len]).connections[0]);
		}
	}, 1000);
}

exports.commands = {
	globalauth: 'gal',
	stafflist: 'gal',
	authlist: 'gal',
	auth: 'gal',
	gal: function (target, room, user, connection) {
		let rankLists = {};
		let ranks = Object.keys(Config.groups);
		let persons = [];
		for (let u in Users.usergroups) {
			let rank = Users.usergroups[u].charAt(0);
			if (ranks.indexOf(rank) >= 0) {
				let name = Users.usergroups[u].substr(1);
				persons.push({name: name, rank: rank});
			}
		}
		let staff = {
			"admins": [],
			"leaders": [],
			"bots": [],
			"mods": [],
			"drivers": [],
			"voices": []
		};
		persons = persons.sort((a, b) => toId(a.name).localeCompare(toId(b.name))); // No need to return, arrow functions with single lines have an implicit return
		function nameColor (name) {
			if (Users.getExact(name) && Users(name).connected) {
				return '<b><i><font color="' + hashColorWithCustoms(name) + '">' + Chat.escapeHTML(Users.getExact(name).name) + '</font></i></b>';
			} else {
				return '<font color="' + hashColorWithCustoms(name) + '">' + Chat.escapeHTML(name) + '</font>';
			}
		}
		for (let j = 0; j < persons.length; j++) {
			let rank = persons[j].rank;
			let person = persons[j].name;
			switch (rank) {
				case '~':
					staff['admins'].push(nameColor(person));
					break;
				case '&':
					staff['leaders'].push(nameColor(person));
					break;
				case '*':
					staff['bots'].push(nameColor(person));
					break;
				case '@':
					staff['mods'].push(nameColor(person));
					break;
				case '%':
					staff['drivers'].push(nameColor(person));
					break;
				case '+':
					staff['voices'].push(nameColor(person));
					break;
				default:
					continue;

			}
		}
		connection.popup('|html|' +
			'<h3>SpacialGaze Authority List</h3>' +
			'<b><u>~Administrators (' + staff['admins'].length + ')</u></b>:<br />' + staff['admins'].join(', ') +
			'<br />' +
			'<br /><b><u>&Leaders (' + staff['leaders'].length + ')</u></b>:<br />' + staff['leaders'].join(', ') +
			'<br />' +
			'<br /><b><u>*Bots (' + staff['bots'].length + ')</u></b><br />' + staff['bots'].join(', ') +
			'<br />' +
			'<br /><b><u>@Moderators (' + staff['mods'].length + ')</u></b>:<br />' + staff['mods'].join(', ') +
			'<br />' +
			'<br /><b><u>%Drivers (' + staff['drivers'].length + ')</u></b>:<br />' + staff['drivers'].join(', ') +
			'<br />' +
			'<br /><b><u>+Voices (' + staff['voices'].length + ')</u></b>:<br />' + staff['voices'].join(', ') +
			'<br /><br /><blink>(<b>Bold</b> / <i>Italic</i> = Currently Online)</blink>'
		);
	},

	clearall: function (target, room, user) {
		if (!this.can('declare')) return false;
		if (room.battle) return this.sendReply("You cannot clearall in battle rooms.");

		clearRoom(room);

		this.privateModCommand(`(${user.name} used /clearall.)`);
	},

	gclearall: 'globalclearall',<commit_msg>Change 'SpacialGaze' to 'Tsunami' in /auth<commit_after>/**
 * Miscellaneous commands
 *
 * Fixed/Improved upon by: The Run, HoeenHero, and Mystifi.
 *
 * Some of this code was borrowed from panpawn/jd/other contributors; as
 * such, credits go to them as well.
 */

'use strict';

let fs = require('fs');
let moment = require('moment');
let request = require('request');
let regdateCache = {};

//let badges = fs.createWriteStream('badges.txt', {'flags': 'a'});

function loadRegdateCache() {
	try {
		regdateCache = JSON.parse(fs.readFileSync('config/regdate.json', 'utf8'));
	} catch (e) {}
}
loadRegdateCache();

function saveRegdateCache() {
	fs.writeFileSync('config/regdate.json', JSON.stringify(regdateCache));
}


function getLastSeen (userid) {
	if (!global.LastSeen) return "(not available)";
	if (!LastSeen[userid]) return null;
	let f = new Date(LastSeen[userid]);
	let n = new Date(); // Now
	let diff = (Date.now() - LastSeen[userid]) / 1000;
	let text;
	if (diff > 24 * 60 * 60) {
		let days = Math.floor(diff / (24 * 60 * 60));
		text = days + " " + (days === 1 ? "day" : "days");
		let hours = Math.floor(diff / (60 * 60)) - days * 24;
		if (hours) text += ", " + hours + " " + (hours === 1 ? "hour" : "hours");
	} else {
		text = diff.seconds().duration();
	}
	return f.toString().substr(0, 25) + " (" + text + " ago)";
}

function clearRoom(room) {
	let len = (room.log && room.log.length) || 0;
	let users = [];
	while (len--) {
		room.log[len] = '';
	}
	for (let u in room.users) {
		users.push(u);
		Users(u).leaveRoom(room, Users(u).connections[0]);
	}
	len = users.length;
	setTimeout(() => {
		while (len--) {
			Users(users[len]).joinRoom(room, Users(users[len]).connections[0]);
		}
	}, 1000);
}

exports.commands = {
	globalauth: 'gal',
	stafflist: 'gal',
	authlist: 'gal',
	auth: 'gal',
	gal: function (target, room, user, connection) {
		let rankLists = {};
		let ranks = Object.keys(Config.groups);
		let persons = [];
		for (let u in Users.usergroups) {
			let rank = Users.usergroups[u].charAt(0);
			if (ranks.indexOf(rank) >= 0) {
				let name = Users.usergroups[u].substr(1);
				persons.push({name: name, rank: rank});
			}
		}
		let staff = {
			"admins": [],
			"leaders": [],
			"bots": [],
			"mods": [],
			"drivers": [],
			"voices": []
		};
		persons = persons.sort((a, b) => toId(a.name).localeCompare(toId(b.name))); // No need to return, arrow functions with single lines have an implicit return
		function nameColor (name) {
			if (Users.getExact(name) && Users(name).connected) {
				return '<b><i><font color="' + hashColorWithCustoms(name) + '">' + Chat.escapeHTML(Users.getExact(name).name) + '</font></i></b>';
			} else {
				return '<font color="' + hashColorWithCustoms(name) + '">' + Chat.escapeHTML(name) + '</font>';
			}
		}
		for (let j = 0; j < persons.length; j++) {
			let rank = persons[j].rank;
			let person = persons[j].name;
			switch (rank) {
				case '~':
					staff['admins'].push(nameColor(person));
					break;
				case '&':
					staff['leaders'].push(nameColor(person));
					break;
				case '*':
					staff['bots'].push(nameColor(person));
					break;
				case '@':
					staff['mods'].push(nameColor(person));
					break;
				case '%':
					staff['drivers'].push(nameColor(person));
					break;
				case '+':
					staff['voices'].push(nameColor(person));
					break;
				default:
					continue;

			}
		}
		connection.popup('|html|' +
			'<h3>Tsunami Authority List</h3>' +
			'<b><u>~Administrators (' + staff['admins'].length + ')</u></b>:<br />' + staff['admins'].join(', ') +
			'<br />' +
			'<br /><b><u>&Leaders (' + staff['leaders'].length + ')</u></b>:<br />' + staff['leaders'].join(', ') +
			'<br />' +
			'<br /><b><u>*Bots (' + staff['bots'].length + ')</u></b><br />' + staff['bots'].join(', ') +
			'<br />' +
			'<br /><b><u>@Moderators (' + staff['mods'].length + ')</u></b>:<br />' + staff['mods'].join(', ') +
			'<br />' +
			'<br /><b><u>%Drivers (' + staff['drivers'].length + ')</u></b>:<br />' + staff['drivers'].join(', ') +
			'<br />' +
			'<br /><b><u>+Voices (' + staff['voices'].length + ')</u></b>:<br />' + staff['voices'].join(', ') +
			'<br /><br /><blink>(<b>Bold</b> / <i>Italic</i> = Currently Online)</blink>'
		);
	},

	clearall: function (target, room, user) {
		if (!this.can('declare')) return false;
		if (room.battle) return this.sendReply("You cannot clearall in battle rooms.");

		clearRoom(room);

		this.privateModCommand(`(${user.name} used /clearall.)`);
	},

	gclearall: 'globalclearall',
{'fraction_non_alphanumeric': 0.23421724176189948, 'fraction_numerical': 0.009097969599467437, 'mean_word_length': 3.5002496255616573, 'pattern_counts': {'":': 12, '<': 121, '<?xml version=': 0, '>': 127, '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': '6159456', 'n_tokens_mistral': 3795, 'n_tokens_neox': 3318, 'n_words': 690}