more plugins ported over
This commit is contained in:
parent
303c9e9828
commit
0621386e55
9
debug/plugin.json
Normal file
9
debug/plugin.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "plugin.js",
|
||||
"name": "debug",
|
||||
"description": "In-chat debugging tools",
|
||||
"version": "1.0.0",
|
||||
"tags": ["commands", "tools"],
|
||||
"dependencies": ["simplecommands"],
|
||||
"npmDependencies": []
|
||||
}
|
118
debug/plugin.ts
Normal file
118
debug/plugin.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import util from 'util';
|
||||
import cprog from 'child_process';
|
||||
|
||||
import {
|
||||
Plugin,
|
||||
Configurable,
|
||||
EventListener,
|
||||
DependencyLoad
|
||||
} from '@squeebot/core/lib/plugin';
|
||||
|
||||
import { IMessage } from '@squeebot/core/lib/types';
|
||||
|
||||
import { ISqueebotCore, logger } from '@squeebot/core/lib/core';
|
||||
|
||||
function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
const cmds = [{
|
||||
plugin: plugin.manifest.name,
|
||||
name: 'evaljs',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
if (!simplified[0]) {
|
||||
return true;
|
||||
}
|
||||
const script = msg.data.split(' ').slice(1).join(' ');
|
||||
|
||||
// Disallow child_process when shell is disallowed
|
||||
if ((script.indexOf('child_process') !== -1 ||
|
||||
script.indexOf('cprog') !== -1 ||
|
||||
script.indexOf('fork') !== -1) &&
|
||||
!plugin.config.config.allowShell) {
|
||||
msg.resolve('Error: child_process is not allowed in evaljs due to security reasons.');
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// tslint:disable-next-line: no-eval
|
||||
const mesh = eval(script);
|
||||
if (mesh === undefined) {
|
||||
return true;
|
||||
}
|
||||
msg.resolve(util.format(mesh));
|
||||
} catch (e) {
|
||||
msg.resolve('Error: ' + e.message);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
usage: '<javascript>',
|
||||
description: 'Execute JavaScript in a command context',
|
||||
permissions: ['system_execute'],
|
||||
hidden: true
|
||||
}];
|
||||
|
||||
if (plugin.config.config.allowShell) {
|
||||
logger.warn('WARNING! Shell command execution is enabled! Make absolutely sure that there is proper authentication!');
|
||||
if (process.getuid && process.getuid() === 0) {
|
||||
logger.warn('NEVER run Squeebot as root! Run `useradd squeebot`! We are not responsible for possible security leaks!');
|
||||
}
|
||||
|
||||
cmds.push({
|
||||
plugin: plugin.manifest.name,
|
||||
name: 'sh',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
const stripnl = (simplified[0] !== '-n');
|
||||
const cmd = simplified.slice(stripnl ? 0 : 1).join(' ');
|
||||
if (!cmd) {
|
||||
msg.resolve('Nothing to execute!');
|
||||
return true;
|
||||
}
|
||||
|
||||
cprog.exec(cmd, {shell: '/bin/bash'}, (error, stdout, stderr) => {
|
||||
if (stdout) {
|
||||
if (stripnl) { stdout = stdout.replace(/\n/g, ' ;; '); }
|
||||
|
||||
return msg.resolve(stdout);
|
||||
}
|
||||
|
||||
msg.resolve('Error executing command.');
|
||||
logger.error(stderr || error);
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
description: 'Run raw shell command',
|
||||
usage: '<shell>',
|
||||
hidden: true,
|
||||
permissions: ['system_shell'],
|
||||
});
|
||||
}
|
||||
|
||||
commands.registerCommand(cmds);
|
||||
}
|
||||
|
||||
@Configurable({
|
||||
allowShell: false,
|
||||
})
|
||||
class UtilityPlugin extends Plugin {
|
||||
public core: ISqueebotCore | null = null;
|
||||
|
||||
@DependencyLoad('simplecommands')
|
||||
addCommands(cmd: any): void {
|
||||
addCommands(this, cmd);
|
||||
}
|
||||
|
||||
@EventListener('pluginUnload')
|
||||
public unloadEventHandler(plugin: string | Plugin): void {
|
||||
if (plugin === this.name || plugin === this) {
|
||||
this.config.save().then(() =>
|
||||
this.emit('pluginUnloaded', this));
|
||||
}
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
this.on('core', (c: ISqueebotCore) => this.core = c);
|
||||
this.emitTo('core', 'request-core', this.name);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UtilityPlugin;
|
9
diction/plugin.json
Normal file
9
diction/plugin.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "plugin.js",
|
||||
"name": "diction",
|
||||
"description": "Find definitions for words",
|
||||
"version": "1.0.0",
|
||||
"tags": ["commands", "utility", "dictionary"],
|
||||
"dependencies": ["simplecommands"],
|
||||
"npmDependencies": []
|
||||
}
|
121
diction/plugin.ts
Normal file
121
diction/plugin.ts
Normal file
@ -0,0 +1,121 @@
|
||||
import { httpGET } from '@squeebot/core/lib/common';
|
||||
import { logger } from '@squeebot/core/lib/core';
|
||||
import {
|
||||
Plugin,
|
||||
Configurable,
|
||||
EventListener,
|
||||
DependencyLoad
|
||||
} from '@squeebot/core/lib/plugin';
|
||||
import { IMessage } from '@squeebot/core/lib/types';
|
||||
|
||||
const poslist = [
|
||||
'noun',
|
||||
'verb',
|
||||
'adjective',
|
||||
'adverb',
|
||||
'participle',
|
||||
'article',
|
||||
'pronoun',
|
||||
'preposition',
|
||||
'conjunction',
|
||||
'interjection',
|
||||
'determiner',
|
||||
];
|
||||
|
||||
let lastQuery = 0;
|
||||
|
||||
@Configurable({
|
||||
lexicala: {
|
||||
username: '',
|
||||
password: '',
|
||||
},
|
||||
cooldown: 5,
|
||||
})
|
||||
class DictionPlugin extends Plugin {
|
||||
@EventListener('pluginUnload')
|
||||
public unloadEventHandler(plugin: string | Plugin): void {
|
||||
if (plugin === this.name || plugin === this) {
|
||||
this.emit('pluginUnloaded', this);
|
||||
}
|
||||
}
|
||||
|
||||
@DependencyLoad('simplecommands')
|
||||
addCommands(cmd: any): void {
|
||||
const user = this.config.get('lexicala.username');
|
||||
const passwd = this.config.get('lexicala.password');
|
||||
const rate = this.config.get('cooldown', 5);
|
||||
const rauth = 'Basic ' + Buffer.from(`${user}:${passwd}`).toString('base64');
|
||||
|
||||
if (!user || !passwd) {
|
||||
logger.warn('Lexicala define command is disabled due to no credentials.');
|
||||
return;
|
||||
}
|
||||
|
||||
cmd.registerCommand({
|
||||
name: 'define',
|
||||
plugin: this.name,
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
if (lastQuery > Date.now() - rate * 1000) {
|
||||
msg.resolve('You\'re doing that too fast!');
|
||||
return true;
|
||||
}
|
||||
|
||||
let pos: string | null = simplified[0];
|
||||
if (pos && poslist.indexOf(pos.toLowerCase()) !== -1 && simplified.length > 1) {
|
||||
pos = '&pos=' + pos;
|
||||
} else {
|
||||
pos = '';
|
||||
}
|
||||
|
||||
const word = encodeURIComponent(msg.text.split(' ').slice(pos ? 2 : 1).join(' '));
|
||||
|
||||
if (!word) {
|
||||
msg.resolve('Please specifiy a word or term!');
|
||||
return true;
|
||||
}
|
||||
|
||||
lastQuery = Date.now();
|
||||
|
||||
let response;
|
||||
try {
|
||||
const s = `https://dictapi.lexicala.com/search?source=global&language=en${pos}&text=${word}`;
|
||||
response = await httpGET(s, { Authorization: rauth });
|
||||
response = JSON.parse(response);
|
||||
} catch (e) {
|
||||
msg.resolve('Server did not respond.');
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!response.n_results || response.n_results === 0 || !response.results) {
|
||||
msg.resolve('Nothing found.');
|
||||
return true;
|
||||
}
|
||||
|
||||
const resolve = [];
|
||||
for (const def of response.results) {
|
||||
const wd = def.headword.text;
|
||||
const wdp = def.headword.pos;
|
||||
const results = def.senses.map((rep: any) => rep.definition).slice(0, 4);
|
||||
|
||||
resolve.push({
|
||||
word: wd,
|
||||
type: wdp,
|
||||
results,
|
||||
});
|
||||
}
|
||||
|
||||
const str = resolve.slice(0, 4).map((rep: any) => {
|
||||
return `${rep.word} (${rep.type}):\n` + rep.results.join('\n');
|
||||
}).join('\n');
|
||||
|
||||
msg.resolve(str);
|
||||
return true;
|
||||
},
|
||||
aliases: ['df'],
|
||||
description: 'Find definitions for words',
|
||||
usage: '[<pos>] <word>'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DictionPlugin;
|
9
fun/plugin.json
Normal file
9
fun/plugin.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "plugin.js",
|
||||
"name": "fun",
|
||||
"description": "Fun commands",
|
||||
"version": "1.0.0",
|
||||
"tags": ["commands", "fun"],
|
||||
"dependencies": ["simplecommands"],
|
||||
"npmDependencies": []
|
||||
}
|
85
fun/plugin.ts
Normal file
85
fun/plugin.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import {
|
||||
Plugin,
|
||||
Configurable,
|
||||
EventListener,
|
||||
DependencyLoad
|
||||
} from '@squeebot/core/lib/plugin';
|
||||
|
||||
import { IMessage } from '@squeebot/core/lib/types';
|
||||
|
||||
const alpaca = ['a3d53439', '870b9e10', 'c40c5aad', '77e87cd4', '5815410d', '1855876d', 'd134d47f', '6e0db005', 'b2e471da', 'd083213f', '9ac93967', '1f53ea27', '00ab6411', 'bfdc0079', 'ce29fc6f', '552665d0', '8be91f16', 'b7499ec2', 'b9d52259', '6e505095', '4bc30df8', 'c1854975', 'fe87532c', '9e6cb311', '9e6d6e69', 'f79992bf', '11aa0714', 'c27e712f', '8ee7d28c', 'd79b158f', 'a495bad4', 'df93dc7e', '57ed2f42', '9e2c0722', '3a6c0bab', '4268b737', '490f09bf', 'f6d8fca6', '3d3d96b1', 'f1d82aaa', 'fb1a6e0e', '31a96aee', 'a0cc346f', '9f88d146', 'a55a91a4', '83ee2889', '94c60ee3', '30e66d58', '27870c50', '7adf19c6', '2920ceac', 'ddd62b77', '86a6efe7', '02d2d4f4', 'bebd657c', '1c5a3508', 'c3c6fc4b', '1761ebbc', '7eeaab38', 'd9a12e72', '42356945', 'dff46a1a', '413c741a', 'a7761c60', 'f3316806', '782b8b6c', '6547d625', 'd17bea20', 'fdc5c329', '56bb5991', '9a9ebe09', '8bb0818e', '4692f354', '9d91ce89', 'b3fb3715', '0d03a684', '115af660', '845031e2', '945d26bd', 'd3b1dd25', 'c2cb872f', '0c202666', '357e5195', 'fef6732c', '8a88104e', '1fdbc9ec', 'f6ad84dc', '473eb851', 'd078e723', '5079e902', '8a81a94f', '285c6ef8', '443b7f25', '0ba9ecac', '36d044a9', '7fa1366e', '88dedd53', '7839d770', '50ee9fd7', 'f0a4f672', '74526d28', '639106bf', '8aa61988', 'f6615095', '42385e98', 'ba94be4d', '8c81f5ee', '7bfb19f9', '5cc54d76', '962d2cfb', 'eaee222d', '994575be', '114927a6', 'd3119ed2', 'ce62f835', '0dc3fbb7', 'dc7f629f', '103d03cb', '96e54eb1', 'be395291', 'c469785e', '0c3d13cf', 'f61a1b43', 'bb64b44e', 'c8cdf1e7', '9cd9589a', '92f745d3', 'c9a168e4', 'b5a59c3e', 'ae5e3337', 'ff2a8f2d', 'eef41a7e', 'ef4fad05', '4a2f3a69', '7f9af8df', '9731dcba', 'f4b64638', 'f19b7a28', '87b5f9bb', '8e261176', '6353444c', '68cf22f1', 'e8c05fa5', '0d080496', 'f15c48a1', 'd0dcb52d', '1774d947', 'ead69e2f', '16a9d0d0', 'bae38658', '1b802c4b', '4502f826', '0a4bbb94', '957892e3', '54b50c3b', '6d0e742e', 'e3231c9d', '4e88f997', 'de8a6111', '9d9ff907', 'dbecd1de', 'c11dd818', '6ce07218', 'e73aec0b', 'e5a030b1', '52c22730', '6648a887', 'dabec190', '079c58e1', '94b7882c', 'ac905c5f', '11845f34', '87a871cd', 'bacb3cb9', '9f8584fd', 'f6788d62', 'fae5c010', '8d73c238', '1fe8c363', 'c7408956', '313bd1fb', '0a2de87a', '0fec45a8', '5a23fe9f', '9496c280', 'dc04d424', '1dee8f8b', '44f222a4', 'a0d96fd5', '70563299', 'b3e7bfd2', '49f47c49', '20d103e1', '7ebe873a', '7b13e329', '85cc1c96', 'b569d2d5', '61ccd52f', '8e99ecad', '63b87b93', '3b2e9d58', 'c07a484a', '3e414e22', 'ea030f21', 'd94348a6', '87b486cf', 'fbd5f38e', '81d7c9fc', '4a8aec26', '0d5cb865', 'f840c174', '8762c66d', '5a99399c', 'c00c8cf1', '122ae6de', 'adb4efc5', '84e09e92', 'b21658fd', 'c25cfcaf', '0ac96278', 'a8e49500', '05a639ef', 'bb10bed8', '6a844be3', 'ab06cede', 'b9a8c57e', '6e6b1745', 'a8bf0e1d', 'ae9c19bf', '0392b422', '9dc049e4', '61efd0d2', 'f0759c3d', '29482eb7', 'aa059afe', '7a03c62f', 'a8a8b79c', '59629470', 'c1949ac1', '721db006', '486a31f9', '793cf9cd', '81eb3518', '319c6398', 'd35b269d', '1d1a5014', 'a10506a9', 'ed61196c', '5fd4c99e', '1d92b5ab', 'c34a7a0e', 'ad19db59', '25346668', '0b17393e', '466bd057', 'f9860642', '7d74f7d0', '6719ce53', '95864f2a', 'e810e07c', '9a0a127d', '428f9e7c', '98d645ba', '444a27d5', '999f6fe9'];
|
||||
|
||||
@Configurable({
|
||||
simpleReplies: {
|
||||
ping: 'pong'
|
||||
}
|
||||
})
|
||||
class FunPlugin extends Plugin {
|
||||
@EventListener('pluginUnload')
|
||||
public unloadEventHandler(plugin: string | Plugin): void {
|
||||
if (plugin === this.name || plugin === this) {
|
||||
this.emit('pluginUnloaded', this);
|
||||
}
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
// Hug action
|
||||
this.on('message', (data: IMessage) => {
|
||||
const messageRefined = data.text.toLowerCase().trim().replace(/@/g, '');
|
||||
const myName = data.source.me.name.toLowerCase();
|
||||
if (messageRefined.indexOf('hugs ' + myName) !== -1) {
|
||||
// Add a little bit of delay (personal preference)
|
||||
setTimeout(() => {
|
||||
if (data.sender) {
|
||||
data.resolve(data.source.format.format('action', 'hugs ' +
|
||||
data.mention(data.sender)));
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@DependencyLoad('simplecommands')
|
||||
addCommands(cmd: any): void {
|
||||
const cmds: any = [];
|
||||
if (this.config.config.simpleReplies) {
|
||||
const simpleReply = this.config.config.simpleReplies;
|
||||
for (const name in simpleReply) {
|
||||
cmds.push({
|
||||
name,
|
||||
plugin: this.name,
|
||||
execute: async (msg: IMessage): Promise<boolean> => {
|
||||
msg.resolve(simpleReply[name]);
|
||||
return true;
|
||||
},
|
||||
hidden: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cmds.push({
|
||||
name: 'hug',
|
||||
plugin: this.name,
|
||||
execute: async (msg: IMessage): Promise<boolean> => {
|
||||
msg.resolve(msg.source.format.format('action', 'hugs %s'), msg.sender?.name);
|
||||
return true;
|
||||
},
|
||||
hidden: true
|
||||
});
|
||||
|
||||
cmds.push({
|
||||
name: 'alpaca',
|
||||
plugin: this.name,
|
||||
execute: async (msg: IMessage): Promise<boolean> => {
|
||||
const rand = Math.floor(Math.random() * alpaca.length);
|
||||
msg.resolve('http://jocketf.se/c/' + alpaca[rand]);
|
||||
return true;
|
||||
},
|
||||
hidden: true
|
||||
});
|
||||
|
||||
cmd.registerCommand(cmds);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FunPlugin;
|
9
gamedig/plugin.json
Normal file
9
gamedig/plugin.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "plugin.js",
|
||||
"name": "gamedig",
|
||||
"description": "Game server status string",
|
||||
"version": "1.0.0",
|
||||
"tags": ["commands", "games"],
|
||||
"dependencies": ["simplecommands"],
|
||||
"npmDependencies": ["gamedig@^2.0.23"]
|
||||
}
|
116
gamedig/plugin.ts
Normal file
116
gamedig/plugin.ts
Normal file
@ -0,0 +1,116 @@
|
||||
import {
|
||||
Plugin,
|
||||
Configurable,
|
||||
EventListener,
|
||||
DependencyLoad
|
||||
} from '@squeebot/core/lib/plugin';
|
||||
|
||||
import { IMessage } from '@squeebot/core/lib/types';
|
||||
|
||||
import { query } from 'gamedig';
|
||||
|
||||
interface IMinecraftType {
|
||||
vanilla: {
|
||||
raw: {
|
||||
description: {
|
||||
extra: [
|
||||
{
|
||||
text: string;
|
||||
}
|
||||
];
|
||||
},
|
||||
players: {
|
||||
max: number,
|
||||
online: number;
|
||||
},
|
||||
version: {
|
||||
name: string;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Configurable({
|
||||
games: []
|
||||
})
|
||||
class GamePlugin extends Plugin {
|
||||
@EventListener('pluginUnload')
|
||||
public unloadEventHandler(plugin: string | Plugin): void {
|
||||
if (plugin === this.name || plugin === this) {
|
||||
this.emit('pluginUnloaded', this);
|
||||
}
|
||||
}
|
||||
|
||||
@DependencyLoad('simplecommands')
|
||||
addCommands(cmd: any): void {
|
||||
for (const i in this.config.get('games', [])) {
|
||||
const game = this.config.get('games', [])[i];
|
||||
if (game.game === 'minecraft' && game.host) {
|
||||
const port = game.port || 25565;
|
||||
const command: any = {
|
||||
plugin: this.name,
|
||||
name: 'minecraft',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
const keys: any[] = [];
|
||||
let inclPlayers = false;
|
||||
if (simplified[0] === 'players' || simplified[0] === 'online') {
|
||||
inclPlayers = true;
|
||||
}
|
||||
|
||||
keys.push(['field', 'Minecraft', { type: 'title' }]);
|
||||
|
||||
let state;
|
||||
try {
|
||||
state = await query({
|
||||
type: 'minecraftping',
|
||||
host: game.host,
|
||||
port,
|
||||
});
|
||||
if (!state) {
|
||||
throw new Error();
|
||||
}
|
||||
} catch (e) {
|
||||
msg.resolve([['field', 'Server is offline.', { type: 'title' }]]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (inclPlayers) {
|
||||
const players = [];
|
||||
if (state.players.length > 0) {
|
||||
for (const j in state.players) {
|
||||
players.push(state.players[j].name);
|
||||
}
|
||||
}
|
||||
keys.push(['field', players.length ? players.join(', ') : 'No players', { label: 'Players online' }]);
|
||||
msg.resolve(keys);
|
||||
return true;
|
||||
}
|
||||
|
||||
keys.push(['field', state.connect, { label: 'Address' }]);
|
||||
|
||||
const raw = state.raw as IMinecraftType;
|
||||
if (raw && raw.vanilla && raw.vanilla.raw) {
|
||||
keys.push(['field', raw.vanilla.raw.description.extra[0].text
|
||||
.replace(/§./g, '').replace(/\n/g, ' '), { label: 'MOTD', type: 'description' }]);
|
||||
keys.push(['field', state.players.length + '/' + state.maxplayers, { label: 'Players' }]);
|
||||
keys.push(['field', raw.vanilla.raw.version.name, { label: 'Version' }]);
|
||||
}
|
||||
|
||||
msg.resolve(keys);
|
||||
return true;
|
||||
},
|
||||
description: 'Minecraft server',
|
||||
usage: '[players]',
|
||||
aliases: ['mc']
|
||||
};
|
||||
|
||||
if (game.rooms) {
|
||||
command.source = game.rooms;
|
||||
}
|
||||
cmd.registerCommand(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GamePlugin;
|
575
package-lock.json
generated
575
package-lock.json
generated
@ -4,6 +4,11 @@
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz",
|
||||
"integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ=="
|
||||
},
|
||||
"@squeebot/core": {
|
||||
"version": "file:../core",
|
||||
"requires": {
|
||||
@ -451,12 +456,59 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@szmarczak/http-timer": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
|
||||
"integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
|
||||
"requires": {
|
||||
"defer-to-connect": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@types/cacheable-request": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz",
|
||||
"integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==",
|
||||
"requires": {
|
||||
"@types/http-cache-semantics": "*",
|
||||
"@types/keyv": "*",
|
||||
"@types/node": "*",
|
||||
"@types/responselike": "*"
|
||||
}
|
||||
},
|
||||
"@types/cheerio": {
|
||||
"version": "0.22.22",
|
||||
"resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.22.tgz",
|
||||
"integrity": "sha512-05DYX4zU96IBfZFY+t3Mh88nlwSMtmmzSYaQkKN48T495VV1dkHSah6qYyDTN5ngaS0i0VonH37m+RuzSM0YiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/convert-units": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/convert-units/-/convert-units-2.3.3.tgz",
|
||||
"integrity": "sha512-oo4ZyjU0nZMDQFP0AKYk4KvFjydlSpbgXTCdF+TC3d/TL4b85/zi0W5pC97UrzXXpwsbcVEfS01nEgUqKgjSww==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/gamedig": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/gamedig/-/gamedig-2.0.1.tgz",
|
||||
"integrity": "sha512-lMMFmfcVfX4auHXaxyPGswwQn5e/SwoQ/OmdRvpGxf/TpoGgQAyr9UXMxeTfqbaisi1JfhdlyM5mNNcQ3fQI3Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/http-cache-semantics": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz",
|
||||
"integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A=="
|
||||
},
|
||||
"@types/keyv": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz",
|
||||
"integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/mathjs": {
|
||||
"version": "6.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/mathjs/-/mathjs-6.0.8.tgz",
|
||||
@ -469,14 +521,119 @@
|
||||
"@types/node": {
|
||||
"version": "14.14.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.10.tgz",
|
||||
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ=="
|
||||
},
|
||||
"@types/responselike": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
|
||||
"integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"amdefine": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
|
||||
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
|
||||
},
|
||||
"any-promise": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
||||
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
|
||||
},
|
||||
"barse": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/barse/-/barse-0.4.3.tgz",
|
||||
"integrity": "sha1-KJhk15XQECu7sYHmbs0IxUobwMs=",
|
||||
"requires": {
|
||||
"readable-stream": "~1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "1.0.34",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.1",
|
||||
"isarray": "0.0.1",
|
||||
"string_decoder": "~0.10.x"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||
}
|
||||
}
|
||||
},
|
||||
"boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
},
|
||||
"cacheable-lookup": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz",
|
||||
"integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w=="
|
||||
},
|
||||
"cacheable-request": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz",
|
||||
"integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==",
|
||||
"requires": {
|
||||
"clone-response": "^1.0.2",
|
||||
"get-stream": "^5.1.0",
|
||||
"http-cache-semantics": "^4.0.0",
|
||||
"keyv": "^4.0.0",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"normalize-url": "^4.1.0",
|
||||
"responselike": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"cheerio": {
|
||||
"version": "1.0.0-rc.3",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
|
||||
"integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
|
||||
"requires": {
|
||||
"css-select": "~1.2.0",
|
||||
"dom-serializer": "~0.1.1",
|
||||
"entities": "~1.1.1",
|
||||
"htmlparser2": "^3.9.1",
|
||||
"lodash": "^4.15.0",
|
||||
"parse5": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"clone-response": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
|
||||
"integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
|
||||
"requires": {
|
||||
"mimic-response": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
|
||||
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
|
||||
"requires": {
|
||||
"graceful-readlink": ">= 1.0.0"
|
||||
}
|
||||
},
|
||||
"complex.js": {
|
||||
"version": "2.0.11",
|
||||
"resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.11.tgz",
|
||||
"integrity": "sha512-6IArJLApNtdg1P1dFtn3dnyzoZBEF0MwMnrfF1exSBRpZYoy4yieMkpZhQDC0uwctw48vii0CFVyHfpgZ/DfGw=="
|
||||
},
|
||||
"compressjs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/compressjs/-/compressjs-1.0.3.tgz",
|
||||
"integrity": "sha1-ldt03VuQOM+AvKMhqw7eJxtJWbY=",
|
||||
"requires": {
|
||||
"amdefine": "~1.0.0",
|
||||
"commander": "~2.8.1"
|
||||
}
|
||||
},
|
||||
"convert-units": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/convert-units/-/convert-units-2.3.4.tgz",
|
||||
@ -486,26 +643,239 @@
|
||||
"lodash.keys": "2.3.x"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"css-select": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
|
||||
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
|
||||
"requires": {
|
||||
"boolbase": "~1.0.0",
|
||||
"css-what": "2.1",
|
||||
"domutils": "1.5.1",
|
||||
"nth-check": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
|
||||
},
|
||||
"decimal.js": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
|
||||
"integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw=="
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"requires": {
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"defer-to-connect": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz",
|
||||
"integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg=="
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
||||
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.0",
|
||||
"entities": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||
"requires": {
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
||||
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
|
||||
"requires": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||
},
|
||||
"escape-latex": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz",
|
||||
"integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw=="
|
||||
},
|
||||
"event-to-promise": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/event-to-promise/-/event-to-promise-0.7.0.tgz",
|
||||
"integrity": "sha1-ywffzUGNoiIdkPd+q3E7wjXiCQ8="
|
||||
},
|
||||
"fraction.js": {
|
||||
"version": "4.0.12",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.12.tgz",
|
||||
"integrity": "sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA=="
|
||||
},
|
||||
"gamedig": {
|
||||
"version": "2.0.23",
|
||||
"resolved": "https://registry.npmjs.org/gamedig/-/gamedig-2.0.23.tgz",
|
||||
"integrity": "sha512-RNVRjdnPK1PaeB0ypqkqZQZnCIkINPs5d5ynQFUsptuNwL1rXjKwFOhYhM3euFYq3zOiaGd6yJfnBkizgDWlQg==",
|
||||
"requires": {
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"compressjs": "^1.0.2",
|
||||
"gbxremote": "^0.2.1",
|
||||
"got": "^11.5.1",
|
||||
"iconv-lite": "^0.6.2",
|
||||
"long": "^4.0.0",
|
||||
"minimist": "^1.2.5",
|
||||
"moment": "^2.27.0",
|
||||
"punycode": "^2.1.1",
|
||||
"varint": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"gbxremote": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/gbxremote/-/gbxremote-0.2.1.tgz",
|
||||
"integrity": "sha1-hN9PvXgXgNxdaS0krASi1/Bd23w=",
|
||||
"requires": {
|
||||
"any-promise": "^1.1.0",
|
||||
"barse": "~0.4.2",
|
||||
"event-to-promise": "^0.7.0",
|
||||
"string-to-stream": "^1.0.1",
|
||||
"xmlrpc": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "11.8.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-11.8.0.tgz",
|
||||
"integrity": "sha512-k9noyoIIY9EejuhaBNLyZ31D5328LeqnyPNXJQb2XlJZcKakLqN5m6O/ikhq/0lw56kUYS54fVm+D1x57YC9oQ==",
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^4.0.0",
|
||||
"@szmarczak/http-timer": "^4.0.5",
|
||||
"@types/cacheable-request": "^6.0.1",
|
||||
"@types/responselike": "^1.0.0",
|
||||
"cacheable-lookup": "^5.0.3",
|
||||
"cacheable-request": "^7.0.1",
|
||||
"decompress-response": "^6.0.0",
|
||||
"http2-wrapper": "^1.0.0-beta.5.2",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"p-cancelable": "^2.0.0",
|
||||
"responselike": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-readlink": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
|
||||
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.1",
|
||||
"domhandler": "^2.3.0",
|
||||
"domutils": "^1.5.1",
|
||||
"entities": "^1.1.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
|
||||
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
|
||||
},
|
||||
"http2-wrapper": {
|
||||
"version": "1.0.0-beta.5.2",
|
||||
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz",
|
||||
"integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==",
|
||||
"requires": {
|
||||
"quick-lru": "^5.1.1",
|
||||
"resolve-alpn": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
||||
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"javascript-natural-sort": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
|
||||
"integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k="
|
||||
},
|
||||
"json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||
},
|
||||
"keyv": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz",
|
||||
"integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==",
|
||||
"requires": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"lodash._basebind": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.3.0.tgz",
|
||||
@ -660,6 +1030,16 @@
|
||||
"lodash._renative": "~2.3.0"
|
||||
}
|
||||
},
|
||||
"long": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
|
||||
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
|
||||
},
|
||||
"mathjs": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mathjs/-/mathjs-8.0.1.tgz",
|
||||
@ -675,11 +1055,173 @@
|
||||
"typed-function": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
},
|
||||
"normalize-url": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ=="
|
||||
},
|
||||
"nth-check": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
|
||||
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
|
||||
"requires": {
|
||||
"boolbase": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"p-cancelable": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz",
|
||||
"integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg=="
|
||||
},
|
||||
"parse5": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
|
||||
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
},
|
||||
"quick-lru": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
|
||||
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"resolve-alpn": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz",
|
||||
"integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA=="
|
||||
},
|
||||
"responselike": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
|
||||
"integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
|
||||
"requires": {
|
||||
"lowercase-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"seedrandom": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
|
||||
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
|
||||
},
|
||||
"string-to-stream": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-to-stream/-/string-to-stream-1.1.1.tgz",
|
||||
"integrity": "sha512-QySF2+3Rwq0SdO3s7BAp4x+c3qsClpPQ6abAmb0DGViiSBAkT5kL6JT2iyzEVP+T1SmzHrQD1TwlP9QAHCc+Sw==",
|
||||
"requires": {
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"tiny-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
|
||||
@ -694,6 +1236,35 @@
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz",
|
||||
"integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ=="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"varint": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
|
||||
"integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "8.2.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz",
|
||||
"integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M="
|
||||
},
|
||||
"xmlrpc": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/xmlrpc/-/xmlrpc-1.3.2.tgz",
|
||||
"integrity": "sha1-JrLqNHhI0Ciqx+dRS1NRl23j6D0=",
|
||||
"requires": {
|
||||
"sax": "1.2.x",
|
||||
"xmlbuilder": "8.2.x"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,16 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@squeebot/core": "file:../core",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"convert-units": "^2.3.4",
|
||||
"gamedig": "^2.0.23",
|
||||
"mathjs": "^8.0.1",
|
||||
"typescript": "^4.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/cheerio": "^0.22.22",
|
||||
"@types/convert-units": "^2.3.3",
|
||||
"@types/gamedig": "^2.0.1",
|
||||
"@types/mathjs": "^6.0.8",
|
||||
"@types/node": "^14.14.10"
|
||||
}
|
||||
|
@ -1,6 +1,34 @@
|
||||
{
|
||||
"name": "plugins-evert",
|
||||
"plugins": [
|
||||
{
|
||||
"name": "debug",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "diction",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "fun",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "gamedig",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "timezone",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "url-fediverse",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "urlreply",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"name": "utility",
|
||||
"version": "3.0.0"
|
||||
|
9
timezone/plugin.json
Normal file
9
timezone/plugin.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "plugin.js",
|
||||
"name": "timezone",
|
||||
"description": "Show time from different time zones",
|
||||
"version": "1.0.0",
|
||||
"tags": ["commands", "utility", "time"],
|
||||
"dependencies": ["simplecommands"],
|
||||
"npmDependencies": []
|
||||
}
|
64
timezone/plugin.ts
Normal file
64
timezone/plugin.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import {
|
||||
Plugin,
|
||||
Configurable,
|
||||
EventListener,
|
||||
DependencyLoad
|
||||
} from '@squeebot/core/lib/plugin';
|
||||
import { IMessage } from '@squeebot/core/lib/types';
|
||||
|
||||
const tz: {[key: string]: number} = {'UTC-12': -12, 'UTC-11': -11, 'UTC-10': -10, 'UTC-9': -9, 'UTC-9:30': -9.5, 'UTC-8': -8, 'UTC-7': -7, 'UTC-6': -6, 'UTC-5': -5, 'UTC-4': -4, 'UTC-3': -3, 'UTC-3:30': -3.5, 'UTC-2': -2, 'UTC-1': -1, UTC: 0, 'UTC+1': 1, 'UTC+2': 2, 'UTC+3': 3, 'UTC+4': 4, 'UTC+4:30': 4.5, 'UTC+5': 5, 'UTC+5:30': 5.5, 'UTC+5:45': 5.75, 'UTC+6': 6, 'UTC+6:30': 6.5, 'UTC+7': 7, 'UTC+8': 8, 'UTC+8:30': 8.5, 'UTC+8:45': 8.75, 'UTC+9': 9, 'UTC+9:30': 9.5, 'UTC+10': 10, 'UTC+10:30': 10.5, 'UTC+11': 11, 'UTC+12': 12, 'UTC+12:45': 12.75, 'UTC+13': 13, 'UTC+13:45': 13.75, 'UTC+14': 14, BST: 1, CET: 1, DFT: 1, IST: 1, MET: 1, WAT: 1, WEST: 1, CAT: 2, CEST: 2, EET: 2, HAEC: 2, MEST: 2, SAST: 2, USZ1: 2, WAST: 2, AST: 3, EAT: 3, EEST: 3, FET: 3, IDT: 3, IOT: 3, MSK: 3, SYOT: 3, TRT: 3, IRST: 3.5, AMT: 4, AZT: 4, GET: 4, GST: 4, MUT: 4, RET: 4, SAMT: 4, SCT: 4, VOLT: 4, AFT: 4.5, IRDT: 4.5, MAWT: 5, MVT: 5, ORAT: 5, PKT: 5, TFT: 5, TJT: 5, TMT: 5, UZT: 5, YEKT: 5, IndianST: 5.5, SLST: 5.5, NPT: 5.75, BIOT: 6, BTT: 6, KGT: 6, OMST: 6, VOST: 6, CCT: 6.5, MMT: 6.5, ACT: 6.5, CXT: 7, DAVT: 7, HOVT: 7, ICT: 7, KRAT: 7, THA: 7, WIT: 7, AWST: 8, BDT: 8, CHOT: 8, CIT: 8, CT: 8, HKT: 8, HOVST: 8, IRKT: 8, MST: 8, MYT: 8, PHT: 8, SGT: 8, SST: 8, ULAT: 8, WST: 8, CWST: 8.5, CHOST: 9, EIT: 9, JST: 9, KST: 9, TLT: 9, ULAST: 9, YAKT: 9, ACST: 9.5, AEST: 10, CHST: 10, CHUT: 10, DDUT: 10, PGT: 10, VLAT: 10, ACDT: 10.5, LHST: 10.5, AEDT: 11, KOST: 11, MIST: 11, NCT: 11, NFT: 11, PONT: 11, SAKT: 11, SBT: 11, SRET: 11, VUT: 11, FJT: 12, GILT: 12, MAGT: 12, MHT: 12, NZST: 12, PETT: 12, TVT: 12, WAKT: 12, CHAST: 12.75, NZDT: 13, PHOT: 13, TKT: 13, TOT: 13, CHADT: 13.75, LINT: 14, AZOT: -1, CVT: -1, EGT: -1, BRST: -2, FNT: -2, PMDT: -2, UYST: -2, NDT: -2.5, ADT: -3, AMST: -3, ART: -3, BRT: -3, CLST: -3, FKST: -3, GFT: -3, PMST: -3, PYST: -3, ROTT: -3, UYT: -3, NST: -3.5, NT: -3.5, AtST: -4, BOT: -4, CLT: -4, COST: -4, ECT: -4, EDT: -4, FKT: -4, GYT: -4, PYT: -4, VET: -4, CDT: -5, COT: -5, EASST: -5, EST: -5, PET: -5, CST: -6, EAST: -6, GALT: -6, MDT: -6, PDT: -7, AKDT: -8, CIST: -8, PST: -8, AKST: -9, GAMT: -9, GIT: -9, HADT: -9, MART: -9.5, MIT: -9.5, CKT: -10, HAST: -10, TAHT: -10, NUT: -11, BIT: -12, GMT: 0, WET: 0};
|
||||
|
||||
// Offset timezone from UTC
|
||||
function offsetTZ(offset: number): number {
|
||||
const utc = new Date(new Date().toUTCString()).getTime();
|
||||
return utc + 3600000 * offset;
|
||||
}
|
||||
|
||||
// Offset timezone from UTC (readable string)
|
||||
function offsetTZStr(offset: number, tzn: string | null): string {
|
||||
const real = offset >= 0 ? '+' + offset : offset;
|
||||
return new Date(offsetTZ(offset)).toUTCString().replace('GMT', 'UTC') + real + (tzn ? ' (' + tzn + ')' : '');
|
||||
}
|
||||
|
||||
function timeNow(short: string): string | null {
|
||||
short = short.toUpperCase();
|
||||
const offset = tz[short];
|
||||
if (offset == null) { return null; }
|
||||
return offsetTZStr(offset, short.indexOf('UTC') !== 0 ? short : null);
|
||||
}
|
||||
|
||||
@Configurable({
|
||||
timezone: 'UTC'
|
||||
})
|
||||
class TZPlugin extends Plugin {
|
||||
@EventListener('pluginUnload')
|
||||
public unloadEventHandler(plugin: string | Plugin): void {
|
||||
if (plugin === this.name || plugin === this) {
|
||||
this.emit('pluginUnloaded', this);
|
||||
}
|
||||
}
|
||||
|
||||
@DependencyLoad('simplecommands')
|
||||
addCommands(cmd: any): void {
|
||||
cmd.registerCommand({
|
||||
name: 'timezone',
|
||||
plugin: this.name,
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
const cfg = this.config.get('timezone', 'UTC');
|
||||
const tn = timeNow(simplified[0] || cfg);
|
||||
if (!tn) {
|
||||
msg.resolve('Unknown or unlisted timezone abbreviation');
|
||||
return true;
|
||||
}
|
||||
|
||||
msg.resolve(tn);
|
||||
return true;
|
||||
},
|
||||
aliases: ['tz'],
|
||||
description: 'Date and Time in a certain time zone',
|
||||
usage: '[abbrv]|UTC<+|-><offset>'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TZPlugin;
|
9
url-fediverse/plugin.json
Normal file
9
url-fediverse/plugin.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "plugin.js",
|
||||
"name": "url-fediverse",
|
||||
"description": "URLReply Fediverse",
|
||||
"version": "1.0.0",
|
||||
"tags": ["urlreply"],
|
||||
"dependencies": ["urlreply"],
|
||||
"npmDependencies": []
|
||||
}
|
99
url-fediverse/plugin.ts
Normal file
99
url-fediverse/plugin.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import { httpGET, sanitizeEscapedText } from '@squeebot/core/lib/common';
|
||||
import {
|
||||
Plugin,
|
||||
EventListener,
|
||||
DependencyLoad
|
||||
} from '@squeebot/core/lib/plugin';
|
||||
|
||||
import { IMessage } from '@squeebot/core/lib/types';
|
||||
|
||||
async function mastodonResponse(msg: IMessage, url: string, type = 'Mastodon'): Promise<boolean> {
|
||||
let murl;
|
||||
if (type === 'Mastodon') {
|
||||
murl = url.match(/^(https?):\/\/((?:[\w\d-]+\.)*[\w\d-]+\.\w{2,16})\/(?:users\/)?@?([\w-_]+)\/(?:statuses\/)?(\d+[^&#?\s/])/i);
|
||||
} else if (type === 'Pleroma') {
|
||||
murl = url.match(/^(https?):\/\/((?:[\w\d-]+\.)*[\w\d-]+\.\w{2,16})\/(notice)\/([^&#?\s/]+)/i);
|
||||
}
|
||||
if (!murl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const url2go = `${murl[1]}://${murl[2]}/api/v1/statuses/${murl[4]}`;
|
||||
let data;
|
||||
|
||||
try {
|
||||
data = await httpGET(url2go);
|
||||
if (!data) {
|
||||
throw new Error('No API response, probably not ' + type + ' after all.')
|
||||
}
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let content = data.content;
|
||||
|
||||
if (!content) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data.spoiler_text) {
|
||||
content = '[CW] ' + data.spoiler_text;
|
||||
}
|
||||
|
||||
const keys = [];
|
||||
let end = sanitizeEscapedText(content.replace(/<\/p>/g, '\n') // Add newlines to paragraph endings
|
||||
.replace(/<br \/>/g, '\n') // Add newlines instead of <br />
|
||||
.replace(/(<([^>]+)>)/ig, '')); // Strip the rest of the HTML out
|
||||
|
||||
if (end.length > 220) {
|
||||
end = end.substring(0, 220) + '…';
|
||||
}
|
||||
|
||||
keys.push(['field', type, { color: 'cyan', type: 'title' }]);
|
||||
keys.push(['field', data.favourites_count.toString(), { color: 'red', label: ['★', 'Favourites'], type: 'metric' }]);
|
||||
keys.push(['field', data.reblogs_count.toString(), { color: 'green', label: ['↱↲', 'Reblogs'], type: 'metric' }]);
|
||||
keys.push(['bold', '@' + data.account.acct + ':']);
|
||||
keys.push(['field', end, { type: 'content' }]);
|
||||
|
||||
msg.resolve(keys);
|
||||
return true;
|
||||
}
|
||||
|
||||
class FediResponsePlugin extends Plugin {
|
||||
@EventListener('pluginUnload')
|
||||
public unloadEventHandler(plugin: string | Plugin): void {
|
||||
if (plugin === this.name || plugin === this) {
|
||||
this.emit('pluginUnloaded', this);
|
||||
}
|
||||
}
|
||||
|
||||
@DependencyLoad('urlreply')
|
||||
addUrlReply(urlreply: any): void {
|
||||
urlreply.registerHandler(this.name, 'html/mastodon',
|
||||
async (url: string, msg: IMessage, title: string, body: any): Promise<boolean> => {
|
||||
const type = title === 'Pleroma' ? 'Pleroma' : 'Mastodon';
|
||||
let pass = false;
|
||||
|
||||
if (type === 'Pleroma') {
|
||||
pass = true;
|
||||
} else {
|
||||
const tag = body('a[href="https://joinmastodon.org/"]');
|
||||
if (tag && tag.text() && tag.text().indexOf('Mastodon') !== -1) {
|
||||
pass = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pass) {
|
||||
const mastodonTest = await mastodonResponse(msg, url, type);
|
||||
if (mastodonTest) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FediResponsePlugin;
|
9
urlreply/plugin.json
Normal file
9
urlreply/plugin.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"main": "plugin.js",
|
||||
"name": "urlreply",
|
||||
"description": "Fetch titles from web pages, specifically made for IRC",
|
||||
"version": "1.0.0",
|
||||
"tags": ["irc"],
|
||||
"dependencies": [],
|
||||
"npmDependencies": ["cheerio@^1.0.0-rc.3"]
|
||||
}
|
384
urlreply/plugin.ts
Normal file
384
urlreply/plugin.ts
Normal file
@ -0,0 +1,384 @@
|
||||
import { httpGET, parseTimeToSeconds, toHHMMSS } from '@squeebot/core/lib/common';
|
||||
import { logger } from '@squeebot/core/lib/core';
|
||||
import {
|
||||
Plugin,
|
||||
Configurable,
|
||||
EventListener,
|
||||
} from '@squeebot/core/lib/plugin';
|
||||
import { IMessage } from '@squeebot/core/lib/types';
|
||||
|
||||
import cheerio from 'cheerio';
|
||||
import * as urllib from 'url';
|
||||
|
||||
interface URLHandler {
|
||||
plugin: string;
|
||||
action: Function;
|
||||
}
|
||||
|
||||
let urlHandlers: {[key: string]: URLHandler} = {};
|
||||
let htmlHandlers: any[] = [];
|
||||
|
||||
const urlRegex = /(((ftp|https?):\/\/)[-\w@:%_+.~#?,&//=]+)/g;
|
||||
|
||||
function findUrls(text: string): string[] {
|
||||
const source = (text || '').toString();
|
||||
const urlArray = [];
|
||||
let matchArray = urlRegex.exec(source);
|
||||
|
||||
while (matchArray !== null) {
|
||||
urlArray.push(matchArray[0]);
|
||||
matchArray = urlRegex.exec(source);
|
||||
}
|
||||
|
||||
return urlArray;
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/a/22149575
|
||||
function ytDuration(source: string): string {
|
||||
const a = source.match(/\d+/g);
|
||||
let res;
|
||||
|
||||
if (!a) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (source.indexOf('M') >= 0 && source.indexOf('H') === -1 && source.indexOf('S') === -1) {
|
||||
res = [0, a[0], 0];
|
||||
}
|
||||
|
||||
if (source.indexOf('H') >= 0 && source.indexOf('M') === -1) {
|
||||
res = [a[0], 0, a[1]];
|
||||
}
|
||||
|
||||
if (source.indexOf('H') >= 0 && source.indexOf('M') === -1 && source.indexOf('S') === -1) {
|
||||
res = [a[0], 0, 0];
|
||||
}
|
||||
|
||||
let duration = 0;
|
||||
|
||||
if (a.length === 3) {
|
||||
duration = duration + parseInt(a[0], 10) * 3600;
|
||||
duration = duration + parseInt(a[1], 10) * 60;
|
||||
duration = duration + parseInt(a[2], 10);
|
||||
}
|
||||
|
||||
if (a.length === 2) {
|
||||
duration = duration + parseInt(a[0], 10) * 60;
|
||||
duration = duration + parseInt(a[1], 10);
|
||||
}
|
||||
|
||||
if (a.length === 1) {
|
||||
duration = duration + parseInt(a[0], 10);
|
||||
}
|
||||
|
||||
return toHHMMSS(duration.toString());
|
||||
}
|
||||
|
||||
async function dailymotionFromId(id: string, msg: IMessage): Promise<boolean> {
|
||||
const url = 'https://api.dailymotion.com/video/' + id + '?fields=id,title,owner,owner.screenname,duration,views_total';
|
||||
|
||||
let data = await httpGET(url);
|
||||
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const keys = [];
|
||||
|
||||
keys.push(['field', 'Dailymotion', { type: 'title' }]);
|
||||
keys.push(['field', data.title, { type: 'description' }]);
|
||||
keys.push(['field', data.views_total.toString(), { label: 'Views', type: 'metric' }]);
|
||||
keys.push(['field', data.duration.toString(), { label: 'Duration', type: 'duration' }]);
|
||||
keys.push(['field', data['owner.screenname'], { label: ['By'] }]);
|
||||
|
||||
msg.resolve(keys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async function getSoundcloudFromUrl(plugin: URLReplyPlugin, url: string, msg: IMessage): Promise<boolean> {
|
||||
const token = plugin.config.get('tokens.soundcloud');
|
||||
if (!token) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const sAPI = 'https://api.soundcloud.com/resolve?url=' + encodeURIComponent(url) + '&client_id=' + token;
|
||||
|
||||
let data = await httpGET(sAPI);
|
||||
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
const keys = [];
|
||||
|
||||
keys.push(['field', 'SoundCloud' + ((data.kind === 'playlist') ? ' Playlist' : ''), { type: 'title', color: 'gold' }]);
|
||||
keys.push(['field', data.title, { type: 'description' }]);
|
||||
|
||||
if (data.kind === 'track') {
|
||||
keys.push(['field', data.playback_count.toString(), { color: 'green', label: ['▶', 'Plays'], type: 'metric' }]);
|
||||
keys.push(['field', data.favoritings_count.toString(), { color: 'red', label: ['♥', 'Favourites'], type: 'metric' }]);
|
||||
} else {
|
||||
keys.push(['field', data.track_count.toString(), { label: 'Tracks', type: 'metric' }]);
|
||||
}
|
||||
|
||||
keys.push(['field', Math.floor(data.duration / 1000).toString(), { label: 'Duration', type: 'duration' }]);
|
||||
keys.push(['field', data.user.username, { label: ['By'] }]);
|
||||
|
||||
msg.resolve(keys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async function getYoutubeFromVideo(
|
||||
plugin: URLReplyPlugin,
|
||||
id: string,
|
||||
full: urllib.URL,
|
||||
msg: IMessage): Promise<boolean> {
|
||||
const gtoken = plugin.config.get('tokens.google');
|
||||
|
||||
if (!gtoken) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const gAPI = 'https://www.googleapis.com/youtube/v3/videos?id=' + id + '&key=' +
|
||||
gtoken + '&part=snippet,contentDetails,statistics';
|
||||
|
||||
let data = await httpGET(gAPI);
|
||||
try {
|
||||
data = JSON.parse(data);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!data || !data.items || !data.items.length) {
|
||||
msg.resolve('Video does not exist or is private.');
|
||||
return false;
|
||||
}
|
||||
|
||||
const vid = data.items[0];
|
||||
const time = full.searchParams.get('t');
|
||||
let live = false;
|
||||
|
||||
if (!vid.snippet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const keys = [];
|
||||
|
||||
if (vid.snippet.liveBroadcastContent === 'live') {
|
||||
live = true;
|
||||
keys.push(['field', '[LIVE]', {color: 'red'}]);
|
||||
}
|
||||
|
||||
if (time) {
|
||||
let tag = parseInt(time, 10);
|
||||
if (tag != null && !isNaN(tag)) {
|
||||
if (time.indexOf('s') !== -1 || time.indexOf('m') !== -1 || time.indexOf('h') !== -1) {
|
||||
tag = parseTimeToSeconds(time);
|
||||
}
|
||||
keys.push(['field', `[${toHHMMSS(tag)}]`, {color: 'red'}]);
|
||||
}
|
||||
}
|
||||
|
||||
keys.push(['field', 'You' + msg.source.format.color('brown', 'Tube'), { color: 'white', type: 'title' }]);
|
||||
keys.push(['field', vid.snippet.title, {type: 'description'}]);
|
||||
|
||||
keys.push(['field', vid.statistics.viewCount.toString(), { type: 'metric', label: 'Views' }]);
|
||||
|
||||
if (!live) {
|
||||
keys.push(['field', ytDuration(vid.contentDetails.duration.toString()), { label: 'Duration' }]);
|
||||
}
|
||||
|
||||
if (vid.statistics && vid.statistics.likeCount != null) {
|
||||
const likeCount = vid.statistics.likeCount.toString();
|
||||
const dislikeCount = vid.statistics.dislikeCount.toString();
|
||||
|
||||
keys.push(['field', likeCount, { color: 'limegreen', label: ['▲', 'Likes'], type: 'metric' }]);
|
||||
keys.push(['field', dislikeCount, { color: 'red', label: ['▼', 'Dislikes'], type: 'metric' }]);
|
||||
}
|
||||
|
||||
keys.push(['field', vid.snippet.channelTitle, { label: ['By'] }]);
|
||||
|
||||
msg.resolve(keys);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Configurable({
|
||||
tokens: {
|
||||
google: null,
|
||||
soundcloud: null
|
||||
}
|
||||
})
|
||||
class URLReplyPlugin extends Plugin {
|
||||
registerHandler(plugin: string, match: string, handler: Function): void {
|
||||
if (!handler || typeof handler !== 'function') {
|
||||
throw new Error('Expected handler function as third argument.');
|
||||
}
|
||||
|
||||
if (plugin !== 'urlreply') {
|
||||
logger.log('[urlreply] %s has added an handler for "%s"', plugin, match);
|
||||
}
|
||||
|
||||
if (match.indexOf('html') === 0) {
|
||||
htmlHandlers.push([plugin, handler]);
|
||||
} else {
|
||||
urlHandlers[match] = {
|
||||
plugin, action: handler
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
resetHandlers(): void {
|
||||
urlHandlers = {};
|
||||
htmlHandlers = [];
|
||||
|
||||
// YouTube
|
||||
this.registerHandler(this.name, 'youtube.com/', async (url: urllib.URL, msg: IMessage, data: any) => {
|
||||
const det = url.searchParams.get('v');
|
||||
|
||||
if (!det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getYoutubeFromVideo.apply(this, [this, det, url, msg]);
|
||||
});
|
||||
|
||||
this.registerHandler(this.name, 'youtu.be/', async (url: urllib.URL, msg: IMessage, data: any) => {
|
||||
const det = url.pathname.substring(1);
|
||||
|
||||
if (!det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getYoutubeFromVideo.apply(this, [this, det, url, msg]);
|
||||
});
|
||||
|
||||
// Dailymotion
|
||||
this.registerHandler(this.name, 'dailymotion.com/video/', async (url: urllib.URL, msg: IMessage, data: any) => {
|
||||
const det = url.href.match('/video/([^?&#]*)');
|
||||
|
||||
if (!det) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return dailymotionFromId.apply(this, [det[1], msg]);
|
||||
});
|
||||
|
||||
// SoundCloud
|
||||
this.registerHandler(this.name, 'soundcloud.com/', async (url: urllib.URL, msg: IMessage, data: any) => {
|
||||
return getSoundcloudFromUrl.apply(this, [this, url.href, msg]);
|
||||
});
|
||||
}
|
||||
|
||||
@EventListener('pluginUnload')
|
||||
public unloadEventHandler(plugin: string | Plugin): void {
|
||||
if (plugin === this.name || plugin === this) {
|
||||
this.emit('pluginUnloaded', this);
|
||||
}
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
this.resetHandlers();
|
||||
this.on('message', async (msg: IMessage) => {
|
||||
// Find URLS in the message
|
||||
const urls = findUrls(msg.text);
|
||||
if (!urls.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const url = urls[0];
|
||||
let matched = false;
|
||||
|
||||
// Find handlers matching this URL
|
||||
for (const handler in urlHandlers) {
|
||||
const obj = urlHandlers[handler];
|
||||
if (url.indexOf(handler) !== -1 || !obj.action) {
|
||||
try {
|
||||
const urlParsed = new urllib.URL(url);
|
||||
|
||||
matched = await obj.action.apply(this, [urlParsed, msg]);
|
||||
} catch (e) {
|
||||
logger.error(e.stack);
|
||||
matched = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If there were no matches, pull the title of the website
|
||||
if (!matched) {
|
||||
try {
|
||||
const data = await httpGET(url, {}, true);
|
||||
if (!data) { return; }
|
||||
|
||||
const full = cheerio.load(data);
|
||||
const head = full('head');
|
||||
|
||||
if (!head) { return; }
|
||||
|
||||
const titleEl = head.find('title');
|
||||
|
||||
if (!titleEl || !titleEl.length) { return; }
|
||||
let title = titleEl.eq(0).text();
|
||||
title = title.replace(/\n/g, ' ').trim();
|
||||
title = msg.source.format.strip(title);
|
||||
|
||||
// Try HTML handlers
|
||||
let htmlHandle = false;
|
||||
for (const k in htmlHandlers) {
|
||||
const handler = htmlHandlers[k];
|
||||
if (htmlHandle) { break; }
|
||||
// Ensure handler is a function
|
||||
if (!handler[1] || typeof handler[1] !== 'function') { continue; }
|
||||
try {
|
||||
htmlHandle = await handler[1].apply(this, [url, msg, title, full]);
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
htmlHandle = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (htmlHandle) { return; }
|
||||
if (title.length > 140) { title = title.substring(0, 140) + '…'; }
|
||||
|
||||
msg.resolve(msg.source.format.color('purple', '[ ') + title + msg.source.format.color('purple', ' ]'));
|
||||
} catch (e) {
|
||||
logger.error(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventListener('pluginUnloaded')
|
||||
unloadedPlugin(plugin: string | Plugin): void {
|
||||
const id = typeof plugin === 'string' ? plugin : plugin.manifest.name;
|
||||
|
||||
// Delete URL handlers for plugin
|
||||
for (const i in urlHandlers) {
|
||||
if (urlHandlers[i].plugin === id) {
|
||||
delete urlHandlers[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Delete HTML handlers for plugin
|
||||
const resolve = [];
|
||||
for (const i in htmlHandlers) {
|
||||
const k = htmlHandlers[i];
|
||||
if (k[0] !== id) {
|
||||
resolve.push(k);
|
||||
}
|
||||
}
|
||||
htmlHandlers = resolve;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = URLReplyPlugin;
|
@ -1,6 +1,5 @@
|
||||
import path from 'path';
|
||||
import net from 'net';
|
||||
import util from 'util';
|
||||
import cprog from 'child_process';
|
||||
import convert from 'convert-units';
|
||||
|
||||
@ -114,6 +113,61 @@ function rgbToHex(r: number, g: number, b: number): string {
|
||||
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
||||
}
|
||||
|
||||
function RGBToHSL(r: number, g: number, b: number): {[key: string]: number} | null {
|
||||
// Make r, g, and b fractions of 1
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
|
||||
// Find greatest and smallest channel values
|
||||
const cmin = Math.min(r, g, b);
|
||||
const cmax = Math.max(r, g, b);
|
||||
const delta = cmax - cmin;
|
||||
let h = 0;
|
||||
let s = 0;
|
||||
let l = 0;
|
||||
|
||||
// Calculate hue
|
||||
// No difference
|
||||
if (delta === 0) {
|
||||
h = 0;
|
||||
}
|
||||
|
||||
// Red is max
|
||||
else if (cmax === r) {
|
||||
h = ((g - b) / delta) % 6;
|
||||
}
|
||||
|
||||
// Green is max
|
||||
else if (cmax === g) {
|
||||
h = (b - r) / delta + 2;
|
||||
}
|
||||
|
||||
// Blue is max
|
||||
else {
|
||||
h = (r - g) / delta + 4;
|
||||
}
|
||||
|
||||
h = Math.round(h * 60);
|
||||
|
||||
// Make negative hues positive behind 360°
|
||||
if (h < 0) {
|
||||
h += 360;
|
||||
}
|
||||
|
||||
// Calculate lightness
|
||||
l = (cmax + cmin) / 2;
|
||||
|
||||
// Calculate saturation
|
||||
s = delta === 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
|
||||
|
||||
// Multiply l and s by 100
|
||||
s = +(s * 100).toFixed(1);
|
||||
l = +(l * 100).toFixed(1);
|
||||
|
||||
return { h, s, l };
|
||||
}
|
||||
|
||||
function hexToRgb(hex: string): {[key: string]: number} | null {
|
||||
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
|
||||
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||
@ -183,7 +237,7 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
let response = '';
|
||||
let strArr;
|
||||
let i;
|
||||
let text = msg.data.split(' ').slice(2).join(' ');
|
||||
let text = msg.text.split(' ').slice(2).join(' ');
|
||||
|
||||
try {
|
||||
switch (simplified[0] ? simplified[0].toUpperCase() : null) {
|
||||
@ -226,7 +280,7 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
let response = '';
|
||||
let i;
|
||||
let text = msg.data.split(' ').slice(2).join(' ');
|
||||
let text = msg.text.split(' ').slice(2).join(' ');
|
||||
|
||||
try {
|
||||
switch (simplified[0] ? simplified[0].toUpperCase() : null) {
|
||||
@ -261,7 +315,7 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
name: 'base64',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
let response = '';
|
||||
const text = msg.data.split(' ').slice(2).join(' ');
|
||||
const text = msg.text.split(' ').slice(2).join(' ');
|
||||
|
||||
try {
|
||||
switch (simplified[0] ? simplified[0].toUpperCase() : null) {
|
||||
@ -324,7 +378,7 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
cmds.push({
|
||||
name: 'converttime',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
const str = msg.data.split(' ').slice(1).join(' ');
|
||||
const str = msg.text.split(' ').slice(1).join(' ');
|
||||
|
||||
if (!str) {
|
||||
msg.resolve('Invalid input');
|
||||
@ -342,7 +396,7 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
cmds.push({
|
||||
name: 'reconverttime',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
const str = msg.data.split(' ').slice(1).join(' ');
|
||||
const str = msg.text.split(' ').slice(1).join(' ');
|
||||
|
||||
if (!str) {
|
||||
msg.resolve('Invalid input');
|
||||
@ -364,13 +418,14 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
return true;
|
||||
}
|
||||
|
||||
const wholeRow = msg.data.split(' ').slice(1).join(' ');
|
||||
const wholeRow = msg.text.split(' ').slice(1).join(' ');
|
||||
|
||||
opMath(wholeRow).then((repl) => {
|
||||
try {
|
||||
const repl = await opMath(wholeRow);
|
||||
msg.resolve(repl);
|
||||
}, (e) => {
|
||||
} catch (e) {
|
||||
msg.resolve('Could not evaluate expression:', e.message);
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
@ -386,13 +441,14 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
return true;
|
||||
}
|
||||
|
||||
const wholeRow = msg.data.split(' ').slice(1).join(' ');
|
||||
const wholeRow = msg.text.split(' ').slice(1).join(' ');
|
||||
|
||||
opMath(wholeRow, 'simplify').then((repl) => {
|
||||
try {
|
||||
const repl = await opMath(wholeRow, 'simplify');
|
||||
msg.resolve(repl);
|
||||
}, () => {
|
||||
msg.resolve('Could not evaluate expression!');
|
||||
});
|
||||
} catch (e) {
|
||||
msg.resolve('Could not evaluate expression:', e.message);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
@ -401,40 +457,6 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
description: 'Simplify a math expression'
|
||||
});
|
||||
|
||||
cmds.push({
|
||||
name: 'evaljs',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
if (!simplified[0]) {
|
||||
return true;
|
||||
}
|
||||
const script = msg.data.split(' ').slice(1).join(' ');
|
||||
|
||||
// Disallow child_process when shell is disallowed
|
||||
if ((script.indexOf('child_process') !== -1 ||
|
||||
script.indexOf('cprog') !== -1 ||
|
||||
script.indexOf('fork') !== -1) &&
|
||||
!plugin.config.config.allowShell) {
|
||||
msg.resolve('Error: child_process is not allowed in evaljs due to security reasons.');
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
const mesh = eval(script); /* eslint no-eval: off */
|
||||
if (mesh === undefined) {
|
||||
return true;
|
||||
}
|
||||
msg.resolve(util.format(mesh));
|
||||
} catch (e) {
|
||||
msg.resolve('Error: ' + e.message);
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
description: 'Execute JavaScript in a command context',
|
||||
permissions: ['system_execute'],
|
||||
hidden: true
|
||||
});
|
||||
|
||||
cmds.push({
|
||||
name: 'userid',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
@ -479,7 +501,7 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
return true;
|
||||
}
|
||||
|
||||
const fullmsg = msg.data.split(' ').slice(1).join(' ');
|
||||
const fullmsg = msg.text.split(' ').slice(1).join(' ');
|
||||
const channels = fullmsg.match(/(rgb)?\(?(\d{1,3}),?\s(\d{1,3}),?\s(\d{1,3})\)?/i);
|
||||
if (!channels || channels[2] == null) {
|
||||
msg.resolve('Invalid parameter');
|
||||
@ -503,6 +525,37 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
usage: '[rgb](<r>, <g>, <b>)|<r> <g> <b>'
|
||||
});
|
||||
|
||||
cmds.push({
|
||||
name: 'rgb2hsl',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
if (!simplified[0]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const fullmsg = msg.text.split(' ').slice(1).join(' ');
|
||||
const channels = fullmsg.match(/(rgb)?\(?(\d{1,3}),?\s(\d{1,3}),?\s(\d{1,3})\)?/i);
|
||||
if (!channels || channels[2] == null) {
|
||||
msg.resolve('Invalid parameter');
|
||||
return true;
|
||||
}
|
||||
|
||||
const r = parseInt(channels[2], 10);
|
||||
const g = parseInt(channels[3], 10);
|
||||
const b = parseInt(channels[4], 10);
|
||||
|
||||
if (r > 255 || g > 255 || b > 255) {
|
||||
msg.resolve('Invalid colors');
|
||||
return true;
|
||||
}
|
||||
const hsl = RGBToHSL(r, g, b);
|
||||
|
||||
msg.resolve('hsl(%d, %d%, %d%)', hsl?.h, hsl?.s, hsl?.l);
|
||||
return true;
|
||||
},
|
||||
description: 'Convert RGB to HSL colors',
|
||||
usage: '[rgb](<r>, <g>, <b>)|<r> <g> <b>'
|
||||
});
|
||||
|
||||
cmds.push({
|
||||
name: 'hex2rgb',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
@ -743,42 +796,6 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
aliases: ['rnum', 'rand']
|
||||
});
|
||||
|
||||
if (plugin.config.config.allowShell) {
|
||||
logger.warn('WARNING! Shell command execution is enabled! Make absolutely sure that there is proper authentication!');
|
||||
if (process.getuid && process.getuid() === 0) {
|
||||
logger.warn('NEVER run Squeebot as root! Run `useradd squeebot`! We are not responsible for possible security leaks!');
|
||||
}
|
||||
|
||||
cmds.push({
|
||||
name: 'sh',
|
||||
execute: async (msg: IMessage, spec: any, prefix: string, ...simplified: any[]): Promise<boolean> => {
|
||||
const stripnl = (simplified[0] !== '-n');
|
||||
const cmd = simplified.slice(stripnl ? 0 : 1).join(' ');
|
||||
if (!cmd) {
|
||||
msg.resolve('Nothing to execute!');
|
||||
return true;
|
||||
}
|
||||
|
||||
cprog.exec(cmd, {shell: '/bin/bash'}, (error, stdout, stderr) => {
|
||||
if (stdout) {
|
||||
if (stripnl) { stdout = stdout.replace(/\n/g, ' ;; '); }
|
||||
|
||||
return msg.resolve(stdout);
|
||||
}
|
||||
|
||||
msg.resolve('Error executing command.');
|
||||
logger.error(stderr || error);
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
description: 'Run raw shell command.',
|
||||
usage: '<query>',
|
||||
hidden: true,
|
||||
permissions: ['system_execute'],
|
||||
});
|
||||
}
|
||||
|
||||
commands.registerCommand(cmds.map((x: any) => {
|
||||
x.plugin = plugin.manifest.name;
|
||||
return x;
|
||||
@ -786,27 +803,10 @@ function addCommands(plugin: UtilityPlugin, commands: any): void {
|
||||
}
|
||||
|
||||
@Configurable({
|
||||
allowShell: false,
|
||||
googleapikey: null,
|
||||
ipfsGateway: 'https://ipfs.io',
|
||||
randomMax: 64
|
||||
})
|
||||
class UtilityPlugin extends Plugin {
|
||||
bindEvents(): void {
|
||||
this.on('message', (msg: IMessage) => {
|
||||
// Pre-regex check
|
||||
if (msg.data.indexOf('ipfs://') === -1 && msg.data.indexOf('Qm') === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// IPFS urlify
|
||||
const mmatch = msg.data.match(/(?:ipfs:\/\/|\s|^)(Qm[\w\d]{44})(?:\s|$)/);
|
||||
if (mmatch && mmatch[1]) {
|
||||
msg.resolve(this.config.config.ipfsGateway + '/ipfs/' + mmatch[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@DependencyLoad('simplecommands')
|
||||
addCommands(cmd: any): void {
|
||||
addCommands(this, cmd);
|
||||
@ -821,8 +821,18 @@ class UtilityPlugin extends Plugin {
|
||||
}
|
||||
|
||||
initialize(): void {
|
||||
this.bindEvents();
|
||||
this.emit('pluginLoaded', this);
|
||||
this.on('message', (msg: IMessage) => {
|
||||
// Pre-regex check
|
||||
if (msg.text.indexOf('ipfs://') === -1 && msg.text.indexOf('Qm') === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// IPFS urlify
|
||||
const mmatch = msg.text.match(/(?:ipfs:\/\/|\s|^)(Qm[\w\d]{44})(?:\s|$)/);
|
||||
if (mmatch && mmatch[1]) {
|
||||
msg.resolve(this.config.config.ipfsGateway + '/ipfs/' + mmatch[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user