parent
db54eab0ae
commit
fb7c7249d0
@ -1 +1,2 @@ |
||||
json/auth.json |
||||
json/auth.json |
||||
node_modules/ |
@ -0,0 +1,6 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="JavaScriptLibraryMappings"> |
||||
<includedPredefinedLibrary name="Node.js Core" /> |
||||
</component> |
||||
</project> |
@ -0,0 +1,12 @@ |
||||
module.exports = { |
||||
name: "ping", |
||||
aliases: ["p"], |
||||
syntax: '`ping`', |
||||
category: 'Misc', |
||||
info: "Provides latency information for debugging purposes; Ensures the bot is working.", |
||||
help: null, |
||||
guildOnly: false, |
||||
async run(client, message, args, cmd) { |
||||
message.reply("Pong! This is Senko you're speaking with \\*tips hat*"); |
||||
} //TODO provide actual latency info
|
||||
}; |
@ -0,0 +1,38 @@ |
||||
const chalk = require('chalk'); |
||||
const {Embed, EmbedBuilder} = require('discord.js'); |
||||
|
||||
module.exports = async (client, message) => { |
||||
if (!message.content || !message.content.length) {return;} //privileged intent fallback //TODO edit for privileged intent
|
||||
|
||||
let prefix = client.basePrefix; //TODO prefixes
|
||||
|
||||
if ([`<@${client.user.id}>`, `<@!${client.user.id}>`].includes(message.content.trim())) { //Ping hello
|
||||
message.channel.send({embeds: [client.embeds.base() |
||||
.setTitle(client.utils.gr(client.config.randResp.pinghello)) |
||||
.setDescription(`You've reached ${client.config.options.dev ? "a developer (beta) instance of" : ''} Senko! My prefix here is \`${prefix}\`, and you can use the \`help\` command to get started.`) |
||||
]}); |
||||
} //TODO random senko img on ping
|
||||
|
||||
let cmd = {}; |
||||
cmd.msg = message.content.toLowerCase().trim(); //i believe in shitty naming conventions :D
|
||||
|
||||
let prefixUsed = cmd.msg.startsWith(client.basePrefix) ? client.basePrefix //standard default/dev client prefix
|
||||
: cmd.msg.startsWith(`<@${client.user.id}>`) ? `<@${client.user.id}>` //mention prefix
|
||||
: cmd.msg.startsWith(`<@!${client.user.id}>`) ? `<@!${client.user.id}>` //nicknamed mention prefix
|
||||
: null //no prefix used
|
||||
|
||||
cmd.prefix = prefixUsed; |
||||
|
||||
if (!cmd.prefix) {return;} // ----------> PREFIXED GATEWAY <----------
|
||||
|
||||
cmd.msg = cmd.msg.slice(prefixUsed.length); |
||||
let args = cmd.msg.split(/\s+/gm); //"args" is split by ALL WHITESPACE AND IS LOWERCASED
|
||||
cmd.name = args.shift(); //the command without the prefix
|
||||
cmd.msg = args.join(" "); |
||||
cmd.args = message.content.trim().slice(prefixUsed.length).trim().split(/ +/gm).slice(1); //args but preserves text state and newlines
|
||||
|
||||
let cmdToRun = client.commands.get(cmd.name) || client.commands.get(client.aliases.get(cmd.name)); |
||||
if (!cmdToRun) {return;} |
||||
try {cmdToRun.run(client, message, args, cmd).catch(e => client.error(`There was an error in the ${cmdToRun.name} command.`, 0, 1, e, '\n'));} |
||||
catch (e) {client.error(`There was an error in the ${cmdToRun.name} command.`, 0, 1, e, '\n');} |
||||
}; |
@ -0,0 +1,10 @@ |
||||
module.exports = async client => { |
||||
client.basePrefix = client.config.options.dev ? client.config.options.prefix || client.config.bot.devPrefix : client.config.bot.prefix; |
||||
|
||||
//await require('../../../api/index')(client);
|
||||
|
||||
require('../../startup/run/hello')(client); // startup info
|
||||
require('../../startup/run/setstatus')(client); |
||||
|
||||
client.log(client.utils.gr(client.config.randResp.cliloaded), {color: "#78d9f8", source: client.config.bot.consoleName}, true, true); //senko doing some more complaining
|
||||
}; |
@ -0,0 +1,53 @@ |
||||
const fs = require('fs'); |
||||
const chalk = require('chalk'); |
||||
const {Collection} = require('discord.js'); |
||||
|
||||
const commandsDirName = './bot/runtime/commands'; |
||||
|
||||
module.exports = async client => { |
||||
client.aliases = new Collection(); //THIS SHIT WAS ALREADY FUCKING EMPTY
|
||||
|
||||
let dirErrors = []; let fileErrors = []; //collect error objects to output them all at the end
|
||||
let readDirs = []; //list of dirs to print at the end
|
||||
let conflictingAliases = {}; |
||||
client.log('Loading commands...', {source: 'boot', color: 'blue'}, 0, 1); |
||||
const readDir = dir => { //when you're trying to comment your code but realize you have good variable naming for once and don't need to :D
|
||||
let dirRead; |
||||
try {dirRead = fs.readdirSync(dir);} |
||||
catch (e) { |
||||
client.error(`Failed to read directory ${chalk.white(dir)}`); |
||||
return dirErrors.push([`Unable to read directory ${chalk.white(dir)}. Error:`, e]); |
||||
} |
||||
let files = dirRead.filter(item => item.endsWith('.js')); |
||||
let folders = dirRead.filter(item => fs.lstatSync(`${dir}/${item}`).isDirectory()); |
||||
files.forEach(file => { |
||||
try { |
||||
const command = require(`../../../${dir.slice(2)}/${file}`); |
||||
client.commands.set(command.name, command); |
||||
if (command.aliases) {command.aliases.forEach(alias => { |
||||
if (client.aliases.has(alias)) { |
||||
if (conflictingAliases[alias]) {conflictingAliases[alias].push(command.name);} //object of alias conflictions keyed by alias -> array[command names]
|
||||
else {conflictingAliases[alias] = [command.name];} |
||||
} |
||||
client.aliases.set(alias, command.name); |
||||
});} |
||||
client.log(`Loaded ${chalk.white(command.name)} with ${chalk.white(`${command.aliases ? command.aliases.length : 0}`)} alias${command.aliases && command.aliases.length === 1 ? '' : 'es'}.`, {color: 'blueBright', source: 'boot', sourceColor: 'blue'}); |
||||
} |
||||
catch (e) { |
||||
client.error(`Failed to read file ${chalk.white(file)}`); |
||||
return fileErrors.push([`Unable to read file ${chalk.white(file)}. Error:`, e]); |
||||
} |
||||
}); |
||||
readDirs.push(`${dir.split('/').slice(4).join('/')}/`); // "commands/..."
|
||||
return folders.forEach(folder => readDir(`${dir}/${folder}`)); //recurse infinitely
|
||||
}; |
||||
readDir(commandsDirName); |
||||
console.log(""); |
||||
dirErrors.forEach(error => client.error(error[0], 0, 0, 1, error[1])); |
||||
fileErrors.forEach(error => client.error(error[0], 0, 0, 1, error[1])); |
||||
readDirs.forEach(dir => client.log(`Read from directory ${chalk.green(dir)}`, {source: 'proc'})); |
||||
console.log(''); |
||||
Object.keys(conflictingAliases).forEach(alias => client.warn(`Alias ${chalk.white(alias)} appears on ${client.utils.as(conflictingAliases[alias].length, 'command')} ${chalk.white(conflictingAliases[alias].join(chalk.yellow(', ')))}`)); |
||||
if (Object.keys(conflictingAliases).length) {console.log('')}; |
||||
client.log(`Loaded ${chalk.white(client.commands.size)} command${client.utils.s(client.commands.size)}!`, {color: 'blue', source: 'boot'}, 0, 1); |
||||
}; |
@ -0,0 +1,46 @@ |
||||
const fs = require('fs'); |
||||
const chalk = require('chalk'); |
||||
const {Collection} = require('discord.js'); |
||||
|
||||
const eventsDirName = './bot/runtime/events'; |
||||
|
||||
module.exports = async client => { |
||||
//client.aliases = new Collection(); //THIS SHIT EMPTY
|
||||
|
||||
let dirErrors = []; let fileErrors = []; //collect error objects to output them all at the end
|
||||
let readDirs = []; //list of dirs to print at the end
|
||||
let totalEvents = 0; |
||||
client.log('Loading events...', {source: 'boot', color: 'blue'}, 0, 1); |
||||
const readDir = dir => { |
||||
let dirRead; |
||||
try {dirRead = fs.readdirSync(dir);} |
||||
catch (e) { |
||||
client.error(`Failed to read directory ${chalk.white(dir)}`); |
||||
return dirErrors.push([`Unable to read directory ${chalk.white(dir)}. Error:`, e]); |
||||
} |
||||
let files = dirRead.filter(item => item.endsWith('.js')); |
||||
let folders = dirRead.filter(item => fs.lstatSync(`${dir}/${item}`).isDirectory()); |
||||
files.forEach(file => { |
||||
try { |
||||
const event = require(`../../../${dir.slice(2)}/${file}`); |
||||
const eventName = file.split('.')[0]; |
||||
client.removeAllListeners(eventName); |
||||
client.on(eventName, event.bind(null, client)); |
||||
client.log(`Loaded event ${chalk.white(eventName)}`, {color: 'blueBright', source: 'boot', sourceColor: 'blue'}); |
||||
totalEvents++; |
||||
} |
||||
catch (e) { |
||||
client.error(`Failed to read file ${chalk.white(file)}`); |
||||
return fileErrors.push([`Unable to read file ${chalk.white(file)}. Error:`, e]); |
||||
} |
||||
}); |
||||
readDirs.push(`${dir.split('/').slice(4).join('/')}/`); // "events/..."
|
||||
return folders.forEach(folder => readDir(`${dir}/${folder}`)); //recurse infinitely
|
||||
}; |
||||
readDir(eventsDirName); |
||||
console.log(""); |
||||
dirErrors.forEach(error => client.error(error[0], 0, 0, 1, error[1])); |
||||
fileErrors.forEach(error => client.error(error[0], 0, 0, 1, error[1])); |
||||
readDirs.forEach(dir => client.log(`Read from directory ${chalk.green(dir)}`, {source: 'proc'})); |
||||
client.log(`Loaded ${chalk.white(totalEvents)} event${client.utils.s(totalEvents)}!`, {color: 'blue', source: 'boot'}, 1, 1); |
||||
}; |
@ -0,0 +1,8 @@ |
||||
const {Collection} = require("discord.js"); |
||||
|
||||
module.exports = async client => { |
||||
for (const x of ['commands', 'events']) { |
||||
client[x] = new Collection(); |
||||
await require(`../collect/${x}`)(client); |
||||
} |
||||
}; |
@ -0,0 +1,20 @@ |
||||
const chalk = require('chalk'); |
||||
|
||||
const {Tag, TagFilter} = require('../../../util/ts/tagfilter'); |
||||
|
||||
module.exports = client => { |
||||
const options = new TagFilter([ |
||||
new Tag(['dev', 'd', 'developer', 'test'], 'dev', 'toggle'), |
||||
new Tag(['prefix', 'devprefix', 'p'], 'prefix', 'append') |
||||
]).test(process.argv.slice(2).join(" ")); |
||||
client.config.options = {}; |
||||
|
||||
if (Object.keys(options).length) { //log and set options
|
||||
client.log(`${chalk.gray.bold("Arguments detected.")}`, {source: 'args'}, 0, 1); |
||||
Object.keys(options).forEach(arg => { |
||||
client.config.options[arg] = options[arg]; |
||||
client.log(`${chalk.gray.bold(arg)}${chalk.gray(':')} ${chalk.blue(options[arg])}`, {source: 'args'}); |
||||
}); |
||||
console.log(''); |
||||
} |
||||
}; |
@ -0,0 +1,12 @@ |
||||
const moment = require("moment"); |
||||
const chalk = require('chalk'); |
||||
const os = require('os'); |
||||
const gs = require('gradient-string'); |
||||
|
||||
module.exports = client => { |
||||
client.log(`Logged in as ${gs.instagram(client.user.username)}. ${chalk.greenBright(`[${chalk.grey(client.user.id)}]`)}`); |
||||
client.log(`Time: ${chalk.blueBright(moment().format('MMMM d, YYYY - HH:MM:SS'))}`); |
||||
client.log(`This ${chalk.blue('heap')} has ${chalk.blueBright((process.memoryUsage().heapTotal / (1024 ** 2)).toFixed(2))}MB allocated; The ${chalk.blue('machine')} has ${chalk.blueBright((os.totalmem() / (1024 ** 3)).toFixed(2))}GB (${chalk.blueBright((os.freemem() / (1024 ** 3)).toFixed(2))}GB free)`); |
||||
client.log(`Running on ${chalk.blueBright(client.guilds.cache.size)} ${chalk.blue("servers")} and interacting with about ${chalk.blueBright(client.users.cache.size)} ${chalk.blue("users")}.`); |
||||
client.log(`Listening for prefix ${chalk.greenBright(client.basePrefix)} || ${chalk.greenBright(`${client.basePrefix}help`)} to get started!`); |
||||
}; |
@ -0,0 +1,21 @@ |
||||
const chalk = require('chalk'); |
||||
|
||||
const ora = require('../../../util/log/ora'); |
||||
|
||||
module.exports = async (client) => { |
||||
const t = Date.now(); |
||||
client.misc = {}; |
||||
client.misc.dscconnected = true; |
||||
|
||||
await ora(`Waking up Natsuki... ${chalk.blueBright.bold.underline("(Connecting to Discord...)")}`, |
||||
client.login(client.auth.token) |
||||
).catch((e) => { |
||||
client.error("Failed to connect to Discord!! Error below.", 0, 0, true, e); |
||||
client.misc.dscconnected = false; |
||||
}); |
||||
if (!client.misc.dscconnected) { |
||||
client.warn("Discord not connected, considering runtime to be unusable and exiting.", 0, true, true); |
||||
throw new Error(); |
||||
} |
||||
return client.success(`Connected to Discord in ${chalk.white(`${Date.now() - t}ms`)}.`, 0, 0, 1); |
||||
}; |
@ -0,0 +1,24 @@ |
||||
module.exports = client => { |
||||
const prefix = client.basePrefix; |
||||
const statuses = { |
||||
"PLAYING": [ |
||||
`with fluffy tails!`, `with some new recipes`, |
||||
`cleaning up PRs' rooms`, `cleaning up TLs' rooms`, |
||||
`with Kitsuu's sanity (I won't stop crashing)` |
||||
], |
||||
"WATCHING": [ |
||||
`over the lovely members of LHT!`, `my tail get fluffed`, |
||||
`tonight's dinner cook`, `LHT staff do great work!` |
||||
] |
||||
}; |
||||
|
||||
try {if (client.misc.statusTimeout) {clearTimeout(client.misc.statusTimeout)};} catch {} |
||||
|
||||
const setStatus = () => { |
||||
let type = Object.keys(statuses)[Math.floor(Math.random() * Object.keys(statuses).length)]; |
||||
if (type === "PLAYING") {client.user.setActivity(statuses[type][Math.floor(Math.random() * statuses[type].length)] + " | " + prefix + "help");} |
||||
else {client.user.setActivity(statuses[type][Math.floor(Math.random() * statuses[type].length)] + " | " + prefix + "help", {type: type});} |
||||
}; |
||||
setStatus(); |
||||
client.misc.statusTimeout = setTimeout(setStatus, 14400000); |
||||
}; |
@ -0,0 +1,24 @@ |
||||
const chalk = require('chalk'); |
||||
const mongoose = require('mongoose'); |
||||
|
||||
const ora = require('../util/log/ora'); |
||||
|
||||
module.exports = async client => { |
||||
if (!client.misc) {client.misc = {};} |
||||
const auth = client.auth; |
||||
const t = Date.now(); |
||||
client.misc.dbconnected = true; |
||||
await ora(chalk.blueBright.bold.underline("Connecting to MongoDB..."), |
||||
mongoose.connect(`mongodb+srv://${auth.database.user}:${auth.database.password}@${auth.database.cluster}.uqyvv.mongodb.net/test`, { |
||||
dbName: auth.database.name //TODO research mongo connect options
|
||||
}) |
||||
).catch((e) => { |
||||
client.error("Failed to connect to mongoose!! Error below.", 0, 0, true, e); |
||||
client.misc.dbconnected = false; |
||||
}); |
||||
if (!client.misc.dbconnected) { |
||||
client.warn("Database not connected, considering runtime to be unusable and exiting.", 0, true, true); |
||||
throw new Error(); |
||||
} |
||||
return client.success(`Connected to Mongo Database in ${chalk.white(`${Date.now() - t}ms`)}.`, 0, 0, 1); |
||||
}; |
@ -0,0 +1,11 @@ |
||||
{ |
||||
"clistart": [ |
||||
"Let me go wake Senko real quick..." |
||||
], |
||||
"cliloaded": [ |
||||
"*rubs tired eyes* Senko reporting for duty..." |
||||
], |
||||
"pinghello": [ |
||||
"You rang?", " That's me, teehee", "\"At your service, milord,\" she says in a posh accent" |
||||
] |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@ |
||||
const chalk = require('chalk'); |
||||
|
||||
module.exports = (client, e, p) => { |
||||
console.log(`#######################################\n\n[${chalk.grey(client.config.bot.consoleName)}] >> ${chalk.hex('#78d9f8')("Well this is awkward.")}\n`); |
||||
console.log(`${chalk.bold.redBright.underline(`There was an error that killed ${client.utils.ps(client.config.bot.name)} process.`)}\n${chalk.redBright("See available stack trace and error information below.")}\n`); |
||||
if (p) { |
||||
client.log("This exception originates from an unhandled, uncaught promise rejection. Ya doofus.", 0, 0, 1); |
||||
} |
||||
console.error(e); |
||||
console.log(`\n#######################################`); |
||||
}; |
@ -0,0 +1,14 @@ |
||||
const config = require('../../json/config.json'); |
||||
const levels = require('./levels.json'); |
||||
const validStrings = Object.keys(levels); |
||||
|
||||
const getLevel = (level) => { |
||||
if (typeof level === 'number') { |
||||
if (level <= 0) {return 0;} |
||||
if (level > 3) {return 3;} |
||||
return Math.floor(level); |
||||
} else { |
||||
const levelM = `${level}`.trim().toUpperCase(); |
||||
return validStrings.includes(levelM) ? levels[levelM] : typeof config.log.defaultLevel === 'number' ? getLevel(config.log.defaultLevel) : 1; |
||||
} |
||||
}; |
@ -0,0 +1,5 @@ |
||||
{ |
||||
"TOP": 0, |
||||
"STANDARD": 1, |
||||
"VERBOSE": 2 |
||||
} |
@ -0,0 +1,37 @@ |
||||
const chalk = require('chalk'); |
||||
|
||||
const getLevel = require('./getlevel'); |
||||
const types = require('./types'); |
||||
|
||||
const config = require('../../json/config.json'); |
||||
|
||||
let defaultOptions = { |
||||
color: "white", |
||||
source: "USER", |
||||
sourceColor: "gray", |
||||
level: typeof config.log.defaultLevel === 'number' ? config.log.defaultLevel : 1, |
||||
suffix: " >> " |
||||
}; |
||||
|
||||
const tlog = (client) => (message = "Test Log", options = {}, prenl = false, postnl = false, ...multcons) => { |
||||
let opt = {}; |
||||
if (typeof options !== 'object') {options = {};} |
||||
opt.color = options.color || defaultOptions.color; |
||||
opt.level = ['string', 'number'].includes(typeof options.level) ? options.level : defaultOptions.level; |
||||
opt.suffix = typeof options.suffix === 'string' ? options.suffix : defaultOptions.suffix; |
||||
opt.source = options.source || defaultOptions.source; |
||||
opt.sourceColor = options.sourceColor || defaultOptions.sourceColor; |
||||
try {if (client.config.logLevel < opt.level) {return;}} |
||||
catch { |
||||
client.config.logLevel = getLevel(client.config.logLevel); |
||||
if (client.config.logLevel < opt.level) {return;} |
||||
} |
||||
console.log(`${prenl ? '\n' : ''}${(opt.sourceColor.startsWith('#') ? chalk.hex(opt.sourceColor) : chalk[opt.sourceColor])(`[${opt.source.toUpperCase()}]`)}${opt.suffix}${options.nc || options.noColor ? message : (opt.color.startsWith('#') ? chalk.hex(opt.color) : chalk[opt.color])(message)}${postnl ? '\n' : ''}`, ...multcons); |
||||
}; |
||||
|
||||
module.exports = (client) => { |
||||
return { |
||||
log: tlog(client), |
||||
...types(tlog(client)) |
||||
}; |
||||
}; |
@ -0,0 +1,18 @@ |
||||
const ora = require('ora'); |
||||
|
||||
module.exports = async (text, promise, callback) => { |
||||
return new Promise(async (resolve, reject) => { |
||||
let spin = ora(text).start(); |
||||
return await promise |
||||
.catch(e => { |
||||
spin.stop(); |
||||
spin.clear(); |
||||
return reject(e) |
||||
}) |
||||
.then((...args) => { |
||||
spin.stop(); |
||||
spin.clear(); |
||||
return callback ? resolve(callback(spin, args)) : resolve(true); |
||||
}); |
||||
}); |
||||
}; |
@ -0,0 +1,20 @@ |
||||
module.exports = (log) => { return { |
||||
error: (message, options, prenl, postnl, ...multcons) => log(message, { |
||||
color: 'redBright', |
||||
source: 'err!', |
||||
sourceColor: 'red', |
||||
level: 0 |
||||
}, prenl, postnl, ...multcons), |
||||
warn: (message, options, prenl, postnl, ...multcons) => log(message, { |
||||
color: 'yellowBright', |
||||
source: 'warn', |
||||
sourceColor: 'yellow', |
||||
level: 1 |
||||
}, prenl, postnl, ...multcons), |
||||
success: (message, options, prenl, postnl, ...multcons) => log(message, { |
||||
color: 'greenBright', |
||||
source: 'proc' || options && options.source, |
||||
sourceColor: 'green', |
||||
level: options && typeof options.level !== 'undefined' ? options.level : 0 |
||||
}, prenl, postnl, ...multcons) |
||||
}}; |
@ -0,0 +1,13 @@ |
||||
const errorhandler = require("../log/errorhandler"); |
||||
const chalk = require('chalk'); |
||||
|
||||
module.exports = client => { |
||||
process.on('unhandledRejection', (e, p) => { //nested promise rejections like to be icky so this should catch them all
|
||||
errorhandler(client, e, p); |
||||
return process.exit(1); //i guess this handler does keep the event loop running but i'll adopt a zero-tolerance policy for unhandled rejections
|
||||
}); // gotta catch 'em all
|
||||
process.on('exit', code => { |
||||
client.log("Back to sleepies...", {color: "#78d9f8", source: client.config.bot.consoleName}, true); |
||||
return console.log(chalk.grey(`Exit code ${chalk.white(code)}`)); |
||||
}); |
||||
}; |
@ -0,0 +1,22 @@ |
||||
module.exports = client => { |
||||
client.utils = {}; //small collection of basic string manipulation utilities so prettier strings are easier
|
||||
|
||||
//pluralize most strings based on a number
|
||||
client.utils.s = num => num === 1 ? '' : 's'; |
||||
//pluralize but pass in the text to make plural
|
||||
client.utils.as = (num, text) => `${text}${client.utils.s(num)}`; |
||||
// "a" or "an" based on the provided string, caps to begin with capital letter
|
||||
client.utils.an = (text, caps) => `${caps ? 'A' : 'a'}${['a', 'e', 'i', 'o', 'u'].includes(text.toLowerCase().trim().slice(0, 1)) ? 'n' : ''} ${text}`; |
||||
//capitalize a string automatically, "a" if rest of string should be automatically lowercased
|
||||
client.utils.c = (text, a=true) => `${text.slice(0, 1).toUpperCase()}${a ? text.slice(1).toLowerCase() : text.slice(1)}`; |
||||
//split text into words and autocap each one
|
||||
client.utils.ca = (text, a=true) => text.split(/\s+/gm).map(t => client.utils.c(t, a)).join(" "); |
||||
//format a moment-presice-range object
|
||||
client.utils.sm = (mpr, ago=true) => `${mpr.years ? `${mpr.years} year${client.utils.s(mpr.years)} ` : ''}${mpr.months ? `${mpr.months} month${client.utils.s(mpr.months)} ` : ''}${mpr.days} day${client.utils.s(mpr.days)}${ago ? ' ago' : ''}`; |
||||
//add a grammatically correct possessive indicator to the end of a word/string
|
||||
client.utils.p = (text) => text.endsWith('s') ? "'" : "'s"; |
||||
//possessivise but pass in the text to possessivize
|
||||
client.utils.ps = (text) => `${text}${client.utils.p(text)}`; |
||||
//random element of array
|
||||
client.utils.gr = list => list[Math.floor(Math.random() * list.length)]; |
||||
}; |
@ -0,0 +1,7 @@ |
||||
module.exports = (time) => { |
||||
return new Promise(function (resolve) { |
||||
setTimeout(function () { |
||||
resolve(null); |
||||
}, time); |
||||
}); |
||||
}; |
@ -0,0 +1,25 @@ |
||||
export class Tag { |
||||
triggers: string[] = []; |
||||
tagName: string; |
||||
filterType: TagFilterType; |
||||
|
||||
constructor(triggers: string[], tagName: string, filterType: TagFilterType) { |
||||
let trigger: string; for (trigger of triggers) { |
||||
this.triggers.push( |
||||
trigger.trim().startsWith("-") ? trigger.trim() : `-${trigger.trim()}` |
||||
); |
||||
} |
||||
|
||||
this.tagName = tagName; |
||||
this.filterType = filterType; |
||||
}; |
||||
|
||||
public addTrigger(trigger: string): Tag { |
||||
this.triggers.push( |
||||
trigger.trim().startsWith("-") ? trigger.trim() : `-${trigger.trim()}` |
||||
); |
||||
return this; |
||||
}; |
||||
} |
||||
|
||||
type TagFilterType = "append" | "toggle" | "listAppend"; |
@ -0,0 +1,63 @@ |
||||
import {Tag} from "./tag"; |
||||
|
||||
export {Tag}; |
||||
export class TagFilter { |
||||
tags: Tag[]; |
||||
triggers: Map<String, String>; |
||||
filterTypes: Map<String, TagFilterType>; |
||||
|
||||
constructor(tags: Tag[]) { |
||||
this.tags = tags; |
||||
this.triggers = new Map<String, String>(); |
||||
this.filterTypes = new Map<String, TagFilterType>(); |
||||
let tag: Tag; |
||||
for (tag of this.tags) { |
||||
let trigger: string; for (trigger of tag.triggers) { |
||||
this.triggers.set(trigger, tag.tagName); |
||||
} |
||||
if (!this.filterTypes.has(tag.tagName)) {this.filterTypes.set(tag.tagName, tag.filterType);} |
||||
} |
||||
} |
||||
|
||||
public test(text: string): object { |
||||
var filtered: object = {}; |
||||
var reading: string = null; |
||||
var filterType: TagFilterType; |
||||
var ticks = {}; |
||||
|
||||
let words = text.trim().split(/\s+/g); |
||||
let word: string; for (word of words) { |
||||
if (word.startsWith('-') && word.length > 1 && this.triggers.has(word.trim())) { |
||||
filterType = this.filterTypes.get(this.triggers.get(word.trim())); |
||||
reading = !['append', 'listAppend'].includes(filterType) ? null : word.trim(); |
||||
if (!reading) {filtered[`${this.triggers.get(word.trim())}`] = true;} |
||||
else {filtered[`${this.triggers.get(reading)}`] = filterType == 'append' ? '' : Array.isArray(filtered[`${this.triggers.get(reading)}`]) ? filtered[`${this.triggers.get(reading)}`] : [];} |
||||
if (filterType == "listAppend") { |
||||
if (ticks[`${this.triggers.get(word.trim())}`] && ticks[`${this.triggers.get(word.trim())}`].length) {filtered[`${this.triggers.get(word.trim())}`].push(ticks[`${this.triggers.get(word.trim())}`]);} |
||||
ticks[`${this.triggers.get(word.trim())}`] = ''; |
||||
} |
||||
} |
||||
else if (reading) { |
||||
if (filterType == "listAppend") {ticks[`${this.triggers.get(reading)}`] += ` ${word}`;} |
||||
else {filtered[`${this.triggers.get(reading)}`] = `${filtered[`${this.triggers.get(reading)}`]} ${word}`;} |
||||
} |
||||
} |
||||
|
||||
let tick: string; for (tick of Object.keys(ticks)) { |
||||
if (ticks[tick].length) {filtered[tick].push(ticks[tick]);} |
||||
} |
||||
|
||||
let key: string; for (key of Object.keys(filtered)) { |
||||
if (typeof filtered[key] == 'string') {filtered[key] = filtered[key].trim();} |
||||
else if (Array.isArray(filtered[key])) { |
||||
let subkey: string; for (subkey of filtered[key]) { |
||||
filtered[key][filtered[key].indexOf(subkey)] = subkey.trim(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return filtered; |
||||
}; |
||||
} |
||||
|
||||
type TagFilterType = "append" | "toggle" | "listAppend"; |
@ -0,0 +1,9 @@ |
||||
export declare class Tag { |
||||
triggers: string[]; |
||||
tagName: string; |
||||
filterType: TagFilterType; |
||||
constructor(triggers: string[], tagName: string, filterType: TagFilterType); |
||||
addTrigger(trigger: string): Tag; |
||||
} |
||||
declare type TagFilterType = "append" | "toggle" | "listAppend"; |
||||
export {}; |
@ -0,0 +1,21 @@ |
||||
"use strict"; |
||||
Object.defineProperty(exports, "__esModule", { value: true }); |
||||
exports.Tag = void 0; |
||||
class Tag { |
||||
constructor(triggers, tagName, filterType) { |
||||
this.triggers = []; |
||||
let trigger; |
||||
for (trigger of triggers) { |
||||
this.triggers.push(trigger.trim().startsWith("-") ? trigger.trim() : `-${trigger.trim()}`); |
||||
} |
||||
this.tagName = tagName; |
||||
this.filterType = filterType; |
||||
} |
||||
; |
||||
addTrigger(trigger) { |
||||
this.triggers.push(trigger.trim().startsWith("-") ? trigger.trim() : `-${trigger.trim()}`); |
||||
return this; |
||||
} |
||||
; |
||||
} |
||||
exports.Tag = Tag; |
@ -0,0 +1,10 @@ |
||||
import { Tag } from "./tag"; |
||||
export { Tag }; |
||||
export declare class TagFilter { |
||||
tags: Tag[]; |
||||
triggers: Map<String, String>; |
||||
filterTypes: Map<String, TagFilterType>; |
||||
constructor(tags: Tag[]); |
||||
test(text: string): object; |
||||
} |
||||
declare type TagFilterType = "append" | "toggle" | "listAppend"; |
@ -0,0 +1,77 @@ |
||||
"use strict"; |
||||
Object.defineProperty(exports, "__esModule", { value: true }); |
||||
exports.TagFilter = exports.Tag = void 0; |
||||
const tag_1 = require("./tag"); |
||||
Object.defineProperty(exports, "Tag", { enumerable: true, get: function () { return tag_1.Tag; } }); |
||||
class TagFilter { |
||||
constructor(tags) { |
||||
this.tags = tags; |
||||
this.triggers = new Map(); |
||||
this.filterTypes = new Map(); |
||||
let tag; |
||||
for (tag of this.tags) { |
||||
let trigger; |
||||
for (trigger of tag.triggers) { |
||||
this.triggers.set(trigger, tag.tagName); |
||||
} |
||||
if (!this.filterTypes.has(tag.tagName)) { |
||||
this.filterTypes.set(tag.tagName, tag.filterType); |
||||
} |
||||
} |
||||
} |
||||
test(text) { |
||||
var filtered = {}; |
||||
var reading = null; |
||||
var filterType; |
||||
var ticks = {}; |
||||
let words = text.trim().split(/\s+/g); |
||||
let word; |
||||
for (word of words) { |
||||
if (word.startsWith('-') && word.length > 1 && this.triggers.has(word.trim())) { |
||||
filterType = this.filterTypes.get(this.triggers.get(word.trim())); |
||||
reading = !['append', 'listAppend'].includes(filterType) ? null : word.trim(); |
||||
if (!reading) { |
||||
filtered[`${this.triggers.get(word.trim())}`] = true; |
||||
} |
||||
else { |
||||
filtered[`${this.triggers.get(reading)}`] = filterType == 'append' ? '' : Array.isArray(filtered[`${this.triggers.get(reading)}`]) ? filtered[`${this.triggers.get(reading)}`] : []; |
||||
} |
||||
if (filterType == "listAppend") { |
||||
if (ticks[`${this.triggers.get(word.trim())}`] && ticks[`${this.triggers.get(word.trim())}`].length) { |
||||
filtered[`${this.triggers.get(word.trim())}`].push(ticks[`${this.triggers.get(word.trim())}`]); |
||||
} |
||||
ticks[`${this.triggers.get(word.trim())}`] = ''; |
||||
} |
||||
} |
||||
else if (reading) { |
||||
if (filterType == "listAppend") { |
||||
ticks[`${this.triggers.get(reading)}`] += ` ${word}`; |
||||
} |
||||
else { |
||||
filtered[`${this.triggers.get(reading)}`] = `${filtered[`${this.triggers.get(reading)}`]} ${word}`; |
||||
} |
||||
} |
||||
} |
||||
let tick; |
||||
for (tick of Object.keys(ticks)) { |
||||
if (ticks[tick].length) { |
||||
filtered[tick].push(ticks[tick]); |
||||
} |
||||
} |
||||
let key; |
||||
for (key of Object.keys(filtered)) { |
||||
if (typeof filtered[key] == 'string') { |
||||
filtered[key] = filtered[key].trim(); |
||||
} |
||||
else if (Array.isArray(filtered[key])) { |
||||
let subkey; |
||||
for (subkey of filtered[key]) { |
||||
filtered[key][filtered[key].indexOf(subkey)] = subkey.trim(); |
||||
} |
||||
} |
||||
} |
||||
return filtered; |
||||
} |
||||
; |
||||
} |
||||
exports.TagFilter = TagFilter; |
@ -0,0 +1,11 @@ |
||||
{ |
||||
"compilerOptions": { |
||||
"module": "commonjs", |
||||
"lib": ["es2017", "es6", "dom"], |
||||
"target": "es2017", |
||||
"declaration": true, |
||||
"outDir": "./" |
||||
}, |
||||
"include": ["src/**/*"], |
||||
"exclude": [] |
||||
} |
Loading…
Reference in new issue