First commit

This commit is contained in:
Neko Life 2021-05-08 15:24:56 +00:00
parent 6ebe37cda7
commit 64b4ad0fe7
30 changed files with 2052 additions and 0 deletions

119
.gitignore vendored Normal file
View file

@ -0,0 +1,119 @@
config.json
package-lock.json
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

75
Main.js Normal file
View file

@ -0,0 +1,75 @@
'use strict';
const Commando = require('@iceprod/discord.js-commando');
const client = new Commando.Client({
owner: '750335181285490760',
partials: ["CHANNEL", "GUILD_MEMBER", "MESSAGE", "REACTION", "USER"]
});
const sqlite = require('sqlite');
let configFile = require('./config.json');
const { errLog, trySend } = require('./resources/functions');
const { join } = require('path');
const { chatAnswer } = require("./resources/shaChat");
require("./database/mongo");
client.registry
.registerGroups([
'utility',
'moderation',
'experiment',
'image',
'fun'
])
.registerDefaults()
.registerCommandsIn(join(__dirname, 'cmds'));
client.setProvider(
sqlite.open({
filename:join(__dirname, 'settings.sqlite3'),
driver:require("sqlite3").Database
}).then(db => new Commando.SQLiteProvider(db))
).catch(e => errLog(e));
const guildLog = "840154722434154496";
let shaGuild;
client.registry.findCommands
client.on('ready', async () => {
//shaGuild = client.guilds.cache.map(g => g);
//console.log(`Member in ${shaGuild.length} guilds.`);
//console.log(client.user.tag+' logged in!');
});
client.on("message", async msg => {
if (msg.channel.id === "837178237322919966" && !msg.author.bot && !msg.content.toLowerCase().startsWith(client.commandPrefix+"chat")) {
chatAnswer(client, msg);
}
if (!msg.guild) {
//console.log(`(${msg.channel.recipient.id}) ${msg.channel.recipient.tag}: (${msg.author.id}) ${msg.author.tag}: ${msg.content}`);
}
});
client.on("guildMemberRemove", memberLeave => {
//console.log(`User ${memberLeave.displayName} (${memberLeave.user.tag}) (${memberLeave.id}) left ${memberLeave.guild.name} (${memberLeave.guild.id}). Now it has ${memberLeave.guild.memberCount} total members count.`);
});
client.on("guildCreate", newShaGuild => {
shaGuild = client.guilds.cache.map(g => g);
trySend(client, guildLog, `Joined **${newShaGuild.name}** (${newShaGuild.id}) <:awamazedLife:795227334339985418> I'm in ${shaGuild.length} servers now.`);
});
client.on("guildDelete", leaveShaGuild => {
shaGuild = client.guilds.cache.map(g => g);
trySend(client, guildLog, `Left **${leaveShaGuild.name}** (${leaveShaGuild.id}) <:WhenLife:773061840351657984> I'm in ${shaGuild.length} servers now.`);
});
client.on("guildMemberAdd", newMember => {
//console.log(`New member ${newMember.displayName} (${newMember.user.tag}) (${newMember.id}) joined ${newMember.guild.name} (${newMember.guild.id})! Now it has ${newMember.guild.memberCount} total members count.`);
});
// client.on("debug", (...args) => console.log(...args));
client.login(configFile.token);

View file

@ -0,0 +1,29 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { errLog, trySend, ranLog } = require("../../resources/functions");
const { database } = require("../../database/mongo");
module.exports = class mydatabase extends commando.Command {
constructor(client) {
super(client, {
name: "mydatabase",
memberName: "mydatabase",
group: "experiment",
description: "Show all document collection."
});
}
run(msg) {
const data = msg.guild ? "Guild" : "User";
const doc = msg.guild?.id ?? msg.author.id;
database.collection(data).find({document: doc}).toArray(async (e, fetched) => {
if (e) {
return errLog(e, msg, this.client);
}
let mes = `Fetched documents for ${msg.guild ? `server **${msg.guild.name}**` : `**${msg.author.tag}**`}`;
mes = `${mes}\`\`\`js\n${JSON.stringify(fetched).split(',"').join(',\n"').split(',{').join(',\n{').split("{\"").join("{\n\"").split("\"}").join("\"\n}")}\`\`\``;
trySend(this.client, msg, mes);
return ranLog(msg, "mydatabase", fetched);
});
}
};

View file

@ -0,0 +1,36 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { ranLog, trySend, errLog } = require("../../resources/functions");
const { database } = require("../../database/mongo");
module.exports = class resetdatabase extends commando.Command {
constructor(client) {
super(client, {
name: "resetdatabase",
memberName: "resetdatabase",
group: "experiment",
description: "Reset your server/private database."
});
}
async run(msg) {
const doc = msg.guild?.id ?? msg.author.id;
const col = database.collection(msg.guild ? "Guild" : "User");
trySend(this.client, msg, "Are you sure? You will lose every saved settings. This process can't be undone. Type `yes` in 30 seconds to confirm.");
const confirm = msg.channel.createMessageCollector(() => true, {time:30000});
confirm.on("collect", h => {
if (h.author === msg.author) {
if (h.content.trim() === "yes") {
col.findOneAndDelete({document: doc})
.then(
trySend(this.client, msg, "Wiped!"))
.catch(e => errLog(e, msg, this.client));
} else {
trySend(this.client, msg, "Request aborted.");
}
confirm.stop();
return ranLog(msg, "resetdatabase", h.content);
}
});
}
};

18
cmds/fun/chat.js Normal file
View file

@ -0,0 +1,18 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { chatAnswer } = require("../../resources/shaChat");
module.exports = class chat extends commando.Command {
constructor(client) {
super(client, {
name: "chat",
memberName: "chat",
group: "fun",
description: "Lets chat!"
});
}
async run(msg) {
chatAnswer(this.client, msg);
}
};

23
cmds/image/neko.js Normal file
View file

@ -0,0 +1,23 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { trySend, ranLog, defaultImageEmbed } = require("../../resources/functions");
module.exports = class neko extends commando.Command {
constructor(client) {
super(client, {
name: "neko",
memberName: "neko",
group: "image",
description: "Neko."
});
}
async run(msg) {
const aut = msg.guild ? msg.guild.member(msg.author) : msg.author;
const title = `${msg.guild ? aut.displayName : aut.username}! ~Nyann~ (UwU) <3`;
const image = `https://nekos.best/nekos/${String(Math.floor(Math.random() * 314)).padStart(4, '0')}.png`;
const emb = await defaultImageEmbed(this.client, msg, image, aut, title);
trySend(this.client, msg, emb);
return ranLog(msg, "neko");
}
};

97
cmds/moderation/mute.js Normal file
View file

@ -0,0 +1,97 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { getUser, trySend } = require("../../resources/functions");
const { database } = require("../../database/mongo");
const { muteDurationMultiplier } = require("../../resources/date");
const col = database.collection("Guild");
const dbExp = database.collection("Experiment");
module.exports = class mute extends commando.Command {
constructor(client) {
super(client, {
name: "mute",
memberName: "mute",
group: "moderation",
description: "Mute.",
guildOnly: true,
userPermissions:['MANAGE_ROLES']
});
}
/**
*
* @param {commando.CommandoMessage} msg
* @param {*} arg
* @returns
*/
async run(msg, arg) {
const doc = await col.findOne({document: msg.guild.id});
const muteConf = doc?.["moderation"]?.mute;
const args = arg.trim().split(/ +/);
const setArgs = arg.trim().split(/(\-\-)+/);
/* if (config.mute.role.length === 0) {
return msg.channel.send(`Mute role isn't set! Run \`${this.client.commandPrefix}mute --role <role_[mention, ID]>\`. If you insist i will just give them admin perms <:purifyLife:774102054046007298>`)
}
if (setArgs) {
for(let set of setArgs) {
set = set.toLowerCase();
switch(set) {
case startsWith('role'): {
let role = set.slice('role'.length).trim();
if (role.startsWith('<&')) {
role = role.slice(2,-1);
}
//const foundRole =
}
}
}
}*/
if (args[0]) {
const targetUser = await getUser(this.client, msg, args[0]);
if (targetUser) {
let duration = muteConf?.defaultDuration;
if (/^\d+(?![^ymwdhs])[ymwdhs]?o?/i.test(args[1])) {
duration = 0;
const durationRegExp = /\d+(?![^ymwdhs])[ymwdhs]?o?/gi;
const durationArg = args[1].match(durationRegExp);
for (const value of durationArg) {
console.log(value);
if (value.endsWith("h") || value.endsWith("ho")) {
duration = muteDurationMultiplier(duration, value, 60 * 60 * 1000);
}
if (value.endsWith("y")) {
duration = muteDurationMultiplier(duration, value, 365 * 24 * 60 * 60 * 1000);
}
if (value.endsWith("mo")) {
duration = muteDurationMultiplier(duration, value, 30 * 24 * 60 * 60 * 1000)
}
if (value.endsWith("w")) {
duration = muteDurationMultiplier(duration, value, 7 * 24 * 60 * 60 * 1000)
}
if (value.endsWith("d")) {
duration = muteDurationMultiplier(duration, value, 24 * 60 * 60 * 1000)
}
if (value.endsWith("m")) {
duration = muteDurationMultiplier(duration, value, 60 * 1000)
}
if (value.endsWith("s")) {
duration = muteDurationMultiplier(duration, value, 1000)
}
if (!/\D/.test(value)) {
duration = muteDurationMultiplier(duration, value, 1000)
}
}
const dateDur = new Date(msg.createdAt.valueOf() + duration).toUTCString();
/*const yearDate = dateDur.getFullYear();
const monthDate = dateDur.getMonth();
const dayDate = dateDur.getDay();
const hourDate = dateDur.getHours();
const minuteDate = dateDur.getMinutes();
const secondDate = dateDur.getSeconds();*/
return trySend(this.client, msg, `Result:\`\`\`js\n${duration} ms\n${dateDur}\`\`\``);
}
} else
return trySend(this.client, msg, "No user with that ID.");
}
}
};

201
cmds/utility/avatar.js Normal file
View file

@ -0,0 +1,201 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { MessageEmbed } = require("discord.js");
const { ranLog, errLog, trySend, findMemberRegEx, multipleMembersFound } = require("../../resources/functions");
const { database } = require("../../database/mongo");
const { randomColors } = require("../../config.json");
module.exports = class avatar extends commando.Command {
constructor(client) {
super(client, {
name: "avatar",
aliases:["av","avat"],
memberName: "avatar",
group: "utility",
description: "Avatar showcase."
});
}
/**
*
* @param {commando.CommandoMessage} msg
* @param {*} arg
*/
async run(msg, arg) {
const doc = msg.guild?.id ?? msg.author.id;
const config = database.collection(msg.guild ? "Guild" : "User");
config.findOne({document: doc}, async (docErr, r) => {
if (docErr) {
errLog(docErr, msg, this.client);
}
const footerQuote = r?.["settings"]?.defaultEmbed?.footerQuote;
const withPerm = arg.trim().split(/,/);
const option = arg.trim().split(/(\-\-)+/);
let user, avatar, member, show;
let [allEmb, multipleMemMes, dupliCheck] = [[], [], []];
if (!arg) {
user = msg.guild ? msg.guild.member(msg.author) : msg.author;
avatar = msg.author.displayAvatarURL({size:4096,dynamic:true});
}
let args;
if (!msg.guild || msg.guild.member(msg.author).hasPermission("MANAGE_MESSAGES")) {
args = withPerm;
} else {
args = withPerm[0];
if (withPerm.length > 1) {
trySend(this.client, msg, "Manage messages permission required to show two or more avatar at once!");
}
}
for (const ops of option) {
if (ops.toLowerCase().startsWith("show")) {
const val = ops.trim().split(/ +/);
const theVal = val[1]?.trim().replace(",", "");
if (theVal && !/\D/.test(theVal)) {
show = parseInt(val[1].trim(), 10);
}
}
}
if (arg) {
for(const theAvThis of args) {
const avThis = theAvThis.replace(/\-\-show *\d*/i, "");
let uID = avThis.trim();
if (uID.startsWith('<@')) {
uID = uID.slice(2);
}
if (uID.startsWith('!')) {
uID = uID.slice(1);
}
if (uID.endsWith('>')) {
uID = uID.slice(0,-1)
}
if (uID.startsWith("@")) {
uID = uID.slice(1);
}
if (uID.length === 1) {
return trySend(this.client, msg, "One character for searching member isn't allowed <:catstareLife:794930503076675584>");
} else {
if (uID) {
let ree = [];
async function nonDigit(client) {
const theree = await findMemberRegEx(msg, client, uID);
if (theree.length === 0) {
user = undefined;
trySend(client, msg, `Can't find user: **${avThis.trim()}**`);
}
for (const reeRes of theree) {
ree.push(reeRes);
}
}
if (/\D/.test(uID)) {
await nonDigit(this.client);
} else {
if (msg.guild.member(uID)) {
ree.push(msg.guild.member(uID));
} else {
await this.client.users.fetch(uID).then(r => ree.push(r)).catch(async e => await nonDigit(this.client));
}
}
if (ree.length > 0) {
const duplicateRes = dupliCheck.findIndex(yes => yes === ree[0].id);
if (duplicateRes !== -1) {
allEmb[duplicateRes].setDescription(`Duplicate result for: **${avThis.trim()}**`);
user = undefined;
} else {
dupliCheck.push(ree[0].id);
user = ree[0].user ?? ree[0];
multipleMemMes.push(await multipleMembersFound(this.client, msg, ree, uID, show));
}
}
if (user) {
avatar = user.displayAvatarURL({size:4096,dynamic:true});
let emb = new MessageEmbed()
.setImage(avatar)
.setFooter(footerQuote ?? "");
member = msg.guild ? msg.guild.member(user) : undefined;
if (member) {
emb.setTitle(member.displayName);
if (member.displayColor) {
emb.setColor(member.displayColor)
}
} else {
emb.setTitle(user.username);
}
if (!msg.guild) {
emb.setColor(randomColors[Math.floor(Math.random() * randomColors.length)]);
}
if (emb.color === 16777215) {
emb.setColor(16777214);
}
allEmb.push(emb);
}
}
}
}
} else {
let emb = new MessageEmbed()
.setTitle(user.displayName ?? user.username)
.setImage(avatar)
.setFooter(footerQuote ?? "");
if (user.displayColor) {
emb.setColor(user.displayColor);
}
if (!msg.guild) {
emb.setColor(randomColors[Math.floor(Math.random() * randomColors.length)]);
}
if (emb.color === 16777215) {
emb.setColor(16777214);
}
allEmb.push(emb);
}
for (let index = 0; index < allEmb.length; index++) {
const embelement = allEmb[index];
const contelement = multipleMemMes[index];
trySend(this.client, msg, { embed: embelement, content: contelement, split:{maxLength:2000,char: ", " || ",\n" || ". " || ".\n" || "," || ".",append:',```',prepend:'```md\n# ' }});
}
return ranLog(msg,'avatar',arg);
});
}
};
// Old codes
/*args = args.split(/ +/);
try {
let member;
let avUrl;
let avatar = new MessageEmbed();
if (args[0]) {
member = await getUser(this.client, args[0]);
}
if (!args[0]) {
avUrl = msg.author.displayAvatarURL({size:4096,dynamic:true});
avatar
.setColor(msg.member.displayColor)
.setTitle(msg.member.displayName);
} else
if (member) {
avUrl = member.displayAvatarURL({size:4096,dynamic:true});
try {
avatar.setColor(msg.guild.member(member).displayColor);
} catch (e) {errLog(e)}
try {
avatar
.setTitle(msg.guild.member(member).displayName);
} catch (e) {
errLog(e);
avatar
.setTitle(member.username);
}
}
if (!avUrl) {
return msg.channel.send('Who is that? I dunno them!');
}
avatar
//.setAuthor(msg.author.username, msg.author.displayAvatarURL({size:4096, dynamic:true}))
.setImage(avUrl)
.setFooter(footerQuote);
msg.channel.send(avatar);
return ranLog(msg,'avatar', `${member ? `Avatar of ${member.tag} (${member.id}): ` : `Self avatar: `} ${avUrl}`);
} catch (e) {
await msg.channel.send('Who is that? I dunno them!');
return errLog(e);
}*/

50
cmds/utility/clonemb.js Normal file
View file

@ -0,0 +1,50 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { MessageEmbed } = require("discord.js");
const { getChannelMessage, errLog, ranLog, trySend, tryReact } = require("../../resources/functions");
module.exports = class clonemb extends commando.Command {
constructor(client) {
super(client, {
name: "clonemb",
aliases: ["cloneemb","cloneembed", "clonembed"],
memberName: "clonemb",
group: "utility",
description: "Clone an Embed."
});
}
async run(msg, cargs) {
const args = cargs.trim().split(/ +/);
const {defaultErrorLogChannel} = require("../../config.json");
try {
const theMes = await getChannelMessage(this.client,msg,args[0],args[1]);
let content;
if (theMes.content) {
content = theMes.content;
}
if (!theMes.embeds || (theMes.embeds).length === 0) {
return trySend(this.client, msg, 'No embed found.');
}
if (!args[0]) {
return trySend(this.client, msg, 'Which embed??');
}
trySend(this.client, msg, {content:content,embed:theMes.embeds[0]});
const moreEmb = theMes.embeds.slice(1);
for(const emb of moreEmb) {
trySend(this.client, msg, new MessageEmbed(emb));
}
tryReact(msg, "a:yesLife:794788847996370945");
return ranLog(msg,'clonemb',`Embed ${theMes.url} (${theMes.id}) in ${theMes.channel.name} (${theMes.channel.id}) of ${theMes.guild.name} cloned.`);
} catch (e) {
return errLog(
e,
msg,
this.client,
false,
"No embed found. Use `<channel_[mention, ID]> <message_ID>` if it's in another channel.",
true
);
}
}
};

322
cmds/utility/embmaker.js Normal file
View file

@ -0,0 +1,322 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { MessageEmbed } = require("discord.js");
const { ranLog, errLog, getChannelMessage, noPerm, tryReact } = require("../../resources/functions");
const getColor = require("../../resources/getColor");
module.exports = class embmaker extends commando.Command {
constructor(client) {
super(client, {
name: "embmaker",
memberName: "embmaker",
aliases: ["embedmaker","createmb","creatembed"],
group: "utility",
description: "Embed creator.",
details:`Embed creator: You can just copy this template and remove unneeded argument. Every argument is optional.\`\`\`\n--title [text]\n--description [text]\n--author:\n -name [text]\n -icon [url]\n -url [url]\n--color [hex, number, name of color]\n--image [url]\n--thumbnail [url]\n--url [url]\n--newfield:\n -name [text]\n -desc [text]\n -inline (true if provided)\n--footer:\n -text [text]\n -icon [url]\n--content [text]\n--channel [channel_[mention, ID]]\n--timestamp [ISO 8601, UNIX Timestamp (Milliseconds)] - Use https://time.lol \n--attachments [url] - You can put [-copy] when editing to copy all the message attachments (Cannot remove existing attachment unless [--channel] provided) \`\`\`Embed editor: You can put \`\`\`--edit <[message_ID, channel_[mention, ID] message_ID]>\`\`\` as first argument to edit the embed in a message. All existing property will be replaced with provided argument. Put \`\`\`--remove [author, fields, footer]\`\`\` to remove all existing property of the provided argument in the embed.\n\nOther arguments:\`\`\`\n--quote <[message_ID, channel_[mention, ID] message_ID]> - Quote a message\`\`\``,
ownerOnly:false,
hidden:false
});
}
async run(msg, arg) {
const args = arg.trim().split(/(\-\-)+/);
let embed = new MessageEmbed();
let autName, footertext, autIcon, autUrl, footericon, content, channel, editSrc, newAttach = [];
try {
for(const value of args) {
if (value.toLowerCase().startsWith('edit')) {
const editArg = value.slice('edit'.length).trim().split(/ +/);
if (editArg) {
editSrc = await getChannelMessage(this.client, msg, editArg[0], editArg[1]);
if (editSrc) {
const editEmb = editSrc.embeds[0];
if (editSrc.content) {
content = editSrc.content;
}
if (editEmb) {
embed = new MessageEmbed(editEmb);
if (editEmb.author) {
if (editEmb.author.name) {
autName = editEmb.author.name;
}
if (editEmb.author.url) {
autUrl = editEmb.author.url;
}
if (editEmb.author.iconURL) {
autIcon = editEmb.author.iconURL;
}
}
if (editEmb.footer) {
if (editEmb.footer.text) {
footertext = editEmb.footer.text;
}
if (editEmb.footer.iconURL) {
footericon = editEmb.footer.iconURL;
}
}
}
}
}
}
if (value.toLowerCase().startsWith('quote')) {
const quoteargs = value.slice('quote'.length).toLowerCase().trim().split(/ +/);
if (quoteargs) {
await getChannelMessage(this.client, msg, quoteargs[0], quoteargs[1])
.then(quoteThis => {
if (quoteThis) {
const author = quoteThis.guild.member(quoteThis.author);
autName = author ? author.displayName : quoteThis.author.username;
autIcon = quoteThis.author.displayAvatarURL({size:4096,dynamic:true});
autUrl = quoteThis.url;
embed
.setAuthor(author ? author.displayName : quoteThis.author.username,quoteThis.author.displayAvatarURL({size:4096,dynamic:true}),quoteThis.url)
.setDescription(quoteThis.content)
.setTimestamp(quoteThis.createdAt);
if (author && author.displayColor) {
embed.setColor(author.displayColor);
}
if (quoteThis.attachments) {
for(const attach of quoteThis.attachments) {
attach.map(g => {
if (/^http/.test(g.proxyURL)) {
newAttach.push(g.proxyURL);
}
});
}
}
}
});
}
}
if (value.toLowerCase().startsWith('remove')) {
const remove = value.slice('remove'.length).toLowerCase().trim().split(/ +/);
for(const remThis of remove) {
if (remThis === 'fields') {
embed.fields = [];
}
if (remThis === 'author') {
autName = null;
autIcon = null;
autUrl = null;
embed.author = null;
}
if (remThis === 'footer') {
footertext = null;
footericon = null;
embed.footer = null;
}
}
}
if (value.toLowerCase().startsWith('title')) {
embed.setTitle(value.slice('title'.length).trim().replace(/\\(?!\\)/g,''));
}
if (value.toLowerCase().startsWith('desc')) {
embed.setDescription(value.slice('desc'.length).trim().replace(/\\(?!\\)/g,''));
}
if (value.toLowerCase().startsWith('description')) {
embed.setDescription(value.slice('description'.length).trim().replace(/\\(?!\\)/g,''));
}
if (value.toLowerCase().startsWith("author")) {
const autData = value.trim().split(/( \-)+/);
for(const autVal of autData) {
if (autVal.toLowerCase().startsWith('name')) {
autName = autVal.slice('name'.length).trim().replace(/\\(?!\\)/g,'');
}
if (autVal.toLowerCase().startsWith('icon')) {
if (/^http/.test(autVal.slice('icon'.length).trim())) {
autIcon = autVal.slice('icon'.length).trim();
} else {
autIcon = null;
}
}
if (autVal.toLowerCase().startsWith('url')) {
if (/^http/.test(autVal.slice('url'.length).trim())) {
autUrl = autVal.slice('url'.length).trim();
} else {
autUrl = null;
}
}
}
}
if (value.toLowerCase().startsWith("color")) {
const colorName = value.slice("color".length).trim();
const color = getColor(colorName);
if (color) {
embed.setColor(color);
}
}
if (value.toLowerCase().startsWith("image")) {
if (/^http/.test(value.slice("image".length).trim())) {
embed.setImage(value.slice("image".length).trim());
} else {
embed.setImage(null);
}
}
if (value.toLowerCase().startsWith("thumbnail")) {
if (/^http/.test(value.slice("thumbnail".length).trim())) {
embed.setThumbnail(value.slice("thumbnail".length).trim());
} else {
embed.setThumbnail(null);
}
}
if (value.toLowerCase().startsWith('url')) {
if (/^http/.test(value.slice("url".length).trim())) {
embed.setURL(value.slice("url".length).trim());
} else {
embed.setURL(null);
}
}
if (value.toLowerCase().startsWith('attachment')) {
const attach = value.slice("attachments".length).trim().split(/ +/);
for(const theFile of attach) {
if (/^http/.test(theFile)) {
newAttach.push(theFile);
}
if (theFile === '-copy' && editSrc) {
if (editSrc.attachments) {
for(const attach of editSrc.attachments) {
attach.map(g => {
if (/^http/.test(g.proxyURL)) {
newAttach.push(g.proxyURL);
}
});
}
}
}
}
}
if (value.toLowerCase().startsWith("timestamp")) {
if(!/[a-zA-Z]/.test(value.slice("timestamp".length).trim())) {
embed.setTimestamp(parseInt(value.slice("timestamp".length).trim(), 10));
} else {
if (value.slice("timestamp".length).trim().toLowerCase() === 'now') {
embed.setTimestamp(msg.createdAt);
} else {
embed.setTimestamp(value.slice("timestamp".length).trim());
}
}
}
if (value.toLowerCase().startsWith('footer')) {
const footerData = value.trim().split(/( \-)+/);
for(const footval of footerData) {
if (footval.toLowerCase().startsWith('text')) {
footertext = footval.slice("text".length).trim().replace(/\\(?!\\)/g,'');
}
if (footval.toLowerCase().startsWith('icon')) {
if (/^http/.test(footval.slice('icon'.length).trim())) {
footericon = footval.slice('icon'.length).trim();
} else {
footericon = null;
}
}
}
}
if (value.toLowerCase().startsWith('newfield')) {
const fieldData = value.trim().split(/( \-)+/);
let fieldName,fieldValue, inline = false;
for(const data of fieldData) {
if (data.toLowerCase().startsWith('name')) {
fieldName = data.slice('name'.length).trim().replace(/\\(?!\\)/g,'');
}
if (data.toLowerCase().startsWith('desc')) {
fieldValue = data.slice('desc'.length).trim().replace(/\\(?!\\)/g,'');
}
if (data.toLowerCase().startsWith('description')) {
fieldValue = data.slice('description'.length).trim().replace(/\\(?!\\)/g,'');
}
if (data.toLowerCase().startsWith('inline')) {
inline = true;
}
}
if (!fieldName) {
fieldName = '';
}
if (!fieldValue) {
fieldValue = '';
}
embed.addField(fieldName,fieldValue,inline);
}
if (value.toLowerCase().startsWith('content')) {
content = value.slice('content'.length).trim().replace(/\\(?!\\)/g,'');
}
if (value.toLowerCase().startsWith('channel')) {
let ID = value.slice('channel'.length).trim();
if (ID.toLowerCase() === 'here') {
channel = msg.channel;
}
if (ID.startsWith('<#') && ID.endsWith('>')) {
ID = ID.slice(2, -1);
}
if (!/\D/.test(ID)) {
channel = this.client.channels.cache.get(ID);
}
}
}
if(autIcon === false) {
if (embed.author.name) {
delete embed.author.name;
}
}
if (!autName && autIcon) {
autName = '';
}
if (autName || autIcon && embed.author !== null) {
embed.setAuthor(autName,autIcon,autUrl);
}
if (!footertext && footericon) {
footertext = '';
}
if (footertext || footericon && embed.footer !== null) {
embed.setFooter(footertext,footericon);
}
if (embed.length === 0 && (embed.thumbnail === null || embed.thumbnail.url === null) && embed.author === null && (embed.image === null || embed.image.url === null)) {
embed.setDescription('');
}
if (embed.color === 16777215) {
embed.setColor(16777214);
}
if (embed.description === '' && (content || newAttach.length > 0)) {
embed = null;
}
if (newAttach.length > 0) {
console.log("Uploading attachments...");
}
console.log(embed);
if (editSrc) {
if (channel) {
channel.send({content:content,embed:embed,files:newAttach}).catch(e => noPerm(msg));
} else {
channel = msg.channel;
if (editSrc.author === this.client.user) {
try {
editSrc.edit({content:content,embed:embed,files:newAttach}).catch(e => errLog(e, msg, this.client));
} catch (e) {
try {
channel.send('Something\'s wrong, i can\'t edit that so here <:WhenLife:773061840351657984>');
channel.send({content:content,embed:embed,files:newAttach});
} catch (e) {
noPerm(msg);
}
}
} else {
try {
channel.send('I can\'t edit that, so here <:catstareLife:794930503076675584>');
channel.send({content:content,embed:embed,files:newAttach});
} catch (e) {
noPerm(msg);
}
}
}
} else {
if (!channel) {
channel = msg.channel;
}
channel.send({content:content,embed:embed,files:newAttach}).catch(e => noPerm(msg));
}
tryReact(msg, "a:yesLife:794788847996370945");
return ranLog(msg,'embmaker',`${arg}\nContent: ${content}\nAttachments: ${newAttach}`);
} catch (e) {
return errLog(e, msg, this.client, true, "", true);
}
}
};

20
cmds/utility/invite.js Normal file
View file

@ -0,0 +1,20 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { ranLog, trySend } = require("../../resources/functions");
const conf = require('../../config.json');
module.exports = class invite extends commando.Command {
constructor(client) {
super(client, {
name: "invite",
memberName: "invite",
group: "utility",
description: "Give you spam.",
});
}
run(msg) {
trySend(this.client, msg, "Mute me after cuz it's spam\n"+conf.invite);
return ranLog(msg, "invite");
}
};

28
cmds/utility/mesemb.js Normal file
View file

@ -0,0 +1,28 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { getChannelMessage, ranLog, errLog, noPerm } = require("../../resources/functions");
module.exports = class mesemb extends commando.Command {
constructor(client) {
super(client, {
name: "mesemb",
memberName: "mesemb",
group: "utility",
description: "Fetch embed info in a message."
});
}
async run(msg, arg) {
const args = arg.trim().split(/ +/);
try {
const message = await getChannelMessage(this.client,msg,args[0],args[1]);
console.log(message.embeds);
const mesemb = '```js\n'+JSON.stringify(message.embeds).split(',"').join(',\n"').split(',{').join(',\n{').replace(/`/g,"\\`")+'```';
const result = msg.channel.send({content:'Collected:'+mesemb,split:{maxLength:2000,char: ", " || ",\n" || ". " || ".\n" || "," || ".",append:',```',prepend:'```js\n'}});
return ranLog(msg,'mesemb',await result.content);
} catch (e) {
noPerm(msg);
return errLog(e, msg, this.client);
}
}
};

37
cmds/utility/mesinfo.js Normal file
View file

@ -0,0 +1,37 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { errLog, getChannelMessage, ranLog, noPerm, trySend } = require("../../resources/functions");
module.exports = class mesinfo extends commando.Command {
constructor(client) {
super(client, {
name: "mesinfo",
memberName: "mesinfo",
group: "utility",
description: "Fetch message info."
});
}
async run(msg, arg) {
const {defaultErrorLogChannel} = require("../../config.json");
const args = arg.trim().split(/ +/);
const message = await getChannelMessage(this.client, msg, args[0], args[1]);
console.log(message);
if (!message) {
return trySend(this.client, msg, "No message with that ID <:catstareLife:794930503076675584>")
} else {
try {
const mesinfo = 'Collected:```js\n'+JSON.stringify(message).split(',"').join(',\n"').split(',{').join(',\n{').replace(/`/g,"\\`")+'```';
const mentionJSON = message.mentions.toJSON();
const sendMentionInfo = 'Mentions:```js\n'+JSON.stringify(mentionJSON).split(',"').join(',\n"').split(',{').join(',\n{')+'```';
const Attachments = 'Attachments:```js\n'+JSON.stringify(message.attachments).split(',"').join(',\n"').split(',{').join(',\n{')+'```';
const sendmesinfo = mesinfo+sendMentionInfo+Attachments;
const result1 = msg.channel.send({content:sendmesinfo,split:{maxLength:2000,char: ", " || ",\n" || ". " || ".\n" || "," || ".",append:',```',prepend:'```js\n'}});
return ranLog(msg,'mesinfo',`${await result1}`);
} catch (e) {
noPerm(msg);
return errLog(e, msg, this.client, false, "", false, defaultErrorLogChannel);
}
}
}
};

View file

@ -0,0 +1,63 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { MessageEmbed } = require("discord.js");
const { getChannelMessage, ranLog, errLog, noPerm, tryReact, trySend } = require("../../resources/functions");
const { database } = require("../../database/mongo");
const col = database.collection("Guild");
module.exports = class newquoteotd extends commando.Command {
constructor(client) {
super(client, {
name: "newquoteotd",
memberName: "newquoteotd",
group: "utility",
description: "The Life exclusive command for Quote of the day.",
guildOnly: true
});
}
async run(msg, arg) {
const args = arg.trim().split(/ +/);
const colorConf = require(`../../config.json`);
const findDoc = await col.findOne({document: msg.guild.id});
const quoteOTD = findDoc?.["settings"]?.quoteOTD;
const color = colorConf.randomColors;
if (!quoteOTD || !quoteOTD.channel) {
return msg.channel.send(`Quote OTD channel not set! Run \`${this.client.commandPrefix}quoteotd\` to set one.`);
}
if (!args[0]) {
return msg.channel.send('Provide `<message_ID>`!');
}
try {
let emb = new MessageEmbed();
const mes = await getChannelMessage(this.client,msg,args[0],args[1]);
if (mes) {
const author = mes.guild.member(mes.author);
let description = mes.content;
if (!description.endsWith('.')) {
description = description+'.';
}
const thumbnail = mes.author.displayAvatarURL({size:4096,dynamic:true});
let name;
if (author.displayName) {
name = author.displayName;
} else {
name = author.username;
}
emb
.setTitle(name)
.setDescription(description)
.setThumbnail(thumbnail)
.setFooter(quoteOTD.footerText, quoteOTD.footerIcon)
.setColor(color[Math.floor(Math.random()*color.length)]);
await trySend(this.client, quoteOTD.channel, emb);
tryReact(msg, "a:yesLife:794788847996370945");
return ranLog(msg,'newqotd',`${msg.author.tag} (${msg.author.id}) made new QOTD \`${description}\` by ${author.tag} (${author.id})`);
}
return msg.channel.send('No message with that ID from this channel. Use `[<channel_[mention, ID]> <message_ID>, message_link]` if it\'s in another channel.');
} catch (e) {
noPerm(msg);
return errLog(e, msg, this.client, true, "", true);
}
}
};

46
cmds/utility/profile.js Normal file
View file

@ -0,0 +1,46 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { MessageEmbed } = require("discord.js");
const { errLog, trySend } = require("../../resources/functions");
module.exports = class profile extends commando.Command {
constructor(client) {
super(client, {
name: "profile",
memberName: "profile",
group: "utility",
description: "Show Users/Member profile"
});
}
async run(msg, arg) {
const args = arg.trim().split(/ +/);
let Users = [];
let emb = new MessageEmbed();
if (!arg) {
Users.push(msg.author);
} else {
for(const userArr of args) {
let theUser = userArr;
if (theUser.startsWith("<")) {
theUser.slice(2);
}
if (theUser.endsWith(">")) {
theUser.slice(0,-1);
}
if (theUser.startsWith("!")) {
theUser.slice(1);
}
if (!/\D/.test(theUser)) {
try {
Users.push(await this.client.users.fetch(theUser));
} catch (e) {
errLog(e, msg, this.client, false, `Can't find user \`${userArr}\``);
}
} else {
trySend(this.client, msg, `Invalid user provided \`${userArr}\``);
}
}
}
}
};

64
cmds/utility/quoteotd.js Normal file
View file

@ -0,0 +1,64 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { writeJSONSync } = require("fs-extra");
const { join } = require("path");
const { ranLog, trySend } = require("../../resources/functions");
const { database } = require("../../database/mongo");
const col = database.collection("Guild");
module.exports = class quoteotd extends commando.Command {
constructor(client) {
super(client, {
name: "quoteotd",
memberName: "quoteotd",
group: "utility",
description: "Set Quote of the day channel and settings.",
details:"```\n--channel\n--text\n--icon```",
guildOnly: true
});
}
async run(msg, arg) {
const args = arg.trim().split(/(\-\-)+/);
if (args.length < 2) {
return trySend(this.client, msg, `Provide argument: \`--channel [mention, ID], --text [footer text], --icon [url footer icon]\``);
}
let result = '';
for(const arr of args) {
const startW = arr.toLowerCase();
let data;
if (startW.startsWith('channel')) {
data = arr.slice('channel'.length).trim();
if (data.startsWith('<')) {
data = data.slice(2,-1);
}
if (!this.client.channels.cache.get(data)) {
return trySend(this.client, msg, 'Invalid/unknown channel provided! Try mentioning a channel or use `ChannelID`');
} else {
col.updateOne({document: msg.guild.id}, {$set: {"settings.quoteOTD.channel": data}}, { upsert: true });
result = result+`Channel set to \`${this.client.channels.cache.get(data).name}\`\n`;
}
}
if (startW.startsWith('text')) {
data = arr.slice('text'.length).trim();
col.updateOne({document: msg.guild.id}, {$set: {"settings.quoteOTD.footerText": data}}, { upsert: true });
result = result+`Footer text set to \`${data}\`\n`;
}
if (startW.startsWith('icon')) {
data = arr.slice('icon'.length).trim();
if (!/^http/.test(data)) {
return trySend(this.client, msg, 'Invalid icon url provided!');
} else {
col.updateOne({document: msg.guild.id}, {$set: {"settings.quoteOTD.footerIcon": data}}, { upsert: true });
result = result+`Footer icon set!\n`;
}
}
}
if (result.length > 0) {
trySend(this.client, msg, result);
} else {
return trySend(this.client, msg, `Provide argument: \`--channel [mention, ID], --text [footer text], --icon [url footer icon]\``);
}
return ranLog(msg,'qotd',result);
}
};

26
cmds/utility/say.js Normal file
View file

@ -0,0 +1,26 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { errLog, ranLog, trySend, tryDelete } = require("../../resources/functions");
module.exports = class say extends commando.Command {
constructor(client) {
super(client, {
name: "say",
memberName: "say",
group: "utility",
description: "Say."
});
}
run(msg, args) {
let noArgs = `<@!${msg.author.id}> what to say?`;
if (!args) {
args = noArgs;
}
trySend(this.client, msg, args);
if (args !== noArgs && msg.channel.guild) {
tryDelete(msg);
}
return ranLog(msg,'say',`Content: ${args}`);
}
};

49
cmds/utility/send.js Normal file
View file

@ -0,0 +1,49 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { ranLog, errLog, trySend, sentAdCheck, tryReact } = require("../../resources/functions");
module.exports = class send extends commando.Command {
constructor(client) {
super(client, {
name: "send",
memberName: "send",
group: "utility",
description: "Send message to designated channel."
});
}
async run(msg, args ) {
const comarg = args.trim().split(/ +/);
const bot = this.client;
let at = comarg[0];
if (!comarg[0]) {
return trySend(this.client, msg, 'Where?!?');
}
if (comarg[0].startsWith('<#') && comarg[0].endsWith('>')) {
at = comarg[0].slice(2, -1);
}
const channel = bot.channels.cache.get(at);
const sendTheMes = args.slice(comarg[0].length).trim();
if (!channel) {
return trySend(this.client, msg, "Give me the right `channel_[mention, ID]` bruh");
}
try {
if (sendTheMes.length === 0) {
return trySend(this.client, at, `<@!${msg.author.id}> If you wanna send nothin then why you even typed that <:bruhLife:798789686242967554>`);
}
const send = await channel.send(sendTheMes);
sentAdCheck(send);
const filter = () => true;
const collector = send.createReactionCollector(filter, {time: 15*6*1000, dispose:true});
collector.on('collect', r => {
try {
msg.react(r.emoji);
} catch (e) {}
});
collector.on('remove', async r => await msg.reactions.resolve(r).id.remove(r.id));
tryReact(msg, 'yeLife:796401669188354090');
return ranLog(msg,'send',`ID: ${send.id} url: ${send.url}\nSent to channel: ${channel.name} (${channel.id}) of ${send.guild.name}\nContent: ${args.slice(at.length)}`);
} catch (e) {
return errLog(e, msg, this.client);
}
}
};

57
cmds/utility/servav.js Normal file
View file

@ -0,0 +1,57 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { MessageEmbed } = require("discord.js");
const { database } = require("../../database/mongo");
const { errLog, trySend, ranLog } = require("../../resources/functions");
const getColor = require("../../resources/getColor");
module.exports = class servav extends commando.Command {
constructor(client) {
super(client, {
name: "servav",
memberName: "servav",
aliases: ["serveravatar", "servavatar", "serverav"],
group: "utility",
description: "Show server avatar."
});
}
run(msg, arg) {
const server_ID = arg.split(/ +/)[0];
const doc = msg.guild?.id ?? msg.author.id;
const col = database.collection(msg.guild ? "Guild" : "User");
col.findOne({document: doc}, async (err, res) => {
if (err) {
errLog(err, msg, this.client);
}
const footerQuote = res?.["settings"]?.defaultEmbed?.footerQuote;
let icon, target;
if (server_ID) {
if (!/\D/.test(server_ID)) {
target = this.client.guilds.cache.get(server_ID);
} else {
return trySend(this.client, msg, "Invalid `server_ID` provided!");
}
} else {
target = msg.guild;
}
if (target) {
icon = target.iconURL({size:4096, dynamic:true});
} else {
return trySend(this.client, msg, "I'm not in that server...");
}
if (icon) {
let embed = new MessageEmbed()
.setImage(icon)
.setTitle(target.name)
.setFooter(footerQuote ?? "");
if (target.owner.displayColor) {
const color = getColor(target.owner.displayColor)
embed.setColor(color);
}
trySend(this.client, msg, embed);
return ranLog(msg, "servav", `**${target.name}** (${target.id})`);
}
});
}
};

37
cmds/utility/setfootq.js Normal file
View file

@ -0,0 +1,37 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { ranLog, errLog, trySend } = require("../../resources/functions");
const { database } = require("../../database/mongo");
module.exports = class setfootq extends commando.Command {
constructor(client) {
super(client, {
name: "setfootq",
aliases:["setfooterquote"],
memberName: "setfootq",
group: "utility",
description: "Set server embed footer text."
});
}
async run(msg, args) {
try {
if (!msg.guild?.member(msg.author).hasPermission("MANAGE_GUILD" && !this.client.owners.includes(msg.author))) {
return trySend(this.client, msg, 'No lol');
}
const data = msg.guild ? "Guild" : "User";
const col = database.collection(data);
const doc = msg.guild?.id ?? msg.author.id;
const oldQ = await col.findOne({document: doc});
col.updateOne({document: doc}, {$set: {"settings.defaultEmbed.footerQuote": args.trim()}}, { upsert: true }, async (e) => {
if (e) {
return errLog(e, msg, this.client);
}
const result = await trySend(this.client, msg, `Changed from \`${oldQ?.["settings"]?.defaultEmbed?.footerQuote}\` to \`${args.trim()}\``);
return ranLog(msg, "setfooterquote", result.content);
});
} catch (e) {
return errLog(e, msg, this.client);
}
}
};

44
cmds/utility/uinfo.js Normal file
View file

@ -0,0 +1,44 @@
'use strict';
const commando = require("@iceprod/discord.js-commando");
const { getUser, errLog, ranLog, trySend } = require("../../resources/functions");
module.exports = class uinfo extends commando.Command {
constructor(client) {
super(client, {
name: "uinfo",
memberName: "uinfo",
group: "utility",
description: "\"Detailed\" Profile."
});
}
async run(msg, arg ) {
const args = arg.trim().split(/ +/);
try {
let profile;
if (args[0]) {
profile = await getUser(this.client, msg, args[0]);
} else {
profile = msg.author;
}
const member = await msg.guild.member(profile);
let result = 'User: '+profile.tag+'```js\n';
if (profile) {
console.log(profile);
result = result+JSON.stringify(profile).split(',"').join(',\n"').split(',{').join(',\n{')+'```';
}
if (member) {
console.log(member);
result = result+'As member: '+member.displayName+'```js\n'+JSON.stringify(member).split(',"').join(',\n"').split(',{').join(',\n{')+'```';
if ((member.displayColor)) {
console.log(member.displayColor);
result = result+'Display color:```js\n'+member.displayColor+'```';
}
}
trySend(this.client, msg, result,{split:{maxLength:2000,char: ", " || ",\n" || ". " || ".\n" || "," || ".",append:',```',prepend:'```js\n'}});
return ranLog(msg,'profile',msg.content);
} catch (e) {
return errLog(e, msg, this.client, false, 'Gimme the right ID!', true);
}
}
};

26
config copy.json Normal file
View file

@ -0,0 +1,26 @@
{
"invite": "https://discord.com/oauth2/authorize?client_id=788006279837909032&scope=bot&permissions=8",
"token": "",
"errLogChannel": "822877910138224660",
"randomColors": [
12357519,
16711935,
128,
32896,
15277667,
"00ff00",
"ff0000",
"ff94f2",
"f1e40f",
"ff8c00",
"a0522d",
3447003,
"0fffff",
"803c9d",
"faa775",
"000000",
16777214
],
"defaultErrorLogChannel":"822877910138224660",
"mongoServer":"mongodb://localhost:27017"
}

22
database/mongo.js Normal file
View file

@ -0,0 +1,22 @@
'use strict';
const { mongoServer } = require("../config.json");
const { MongoClient } = require("mongodb");
const dbClient = new MongoClient(mongoServer,{
useUnifiedTopology: true
});
dbClient.connect(e => {
if (e) {
console.error(e);
return process.exit();
}
console.log("Database connected!");
});
const database = dbClient.db("Shasha");
/**
* @type {dbClient: MongoClient, database: Db}
*/
module.exports = { dbClient, database }

24
package.json Normal file
View file

@ -0,0 +1,24 @@
{
"dependencies": {
"@iceprod/discord.js-commando": "^0.14.3",
"bree": "^6.2.0",
"bufferutil": "^4.0.3",
"cabin": "^9.0.4",
"cleverbot-node": "^0.3.11",
"discord.js": "^12.5.2",
"discord.js-commando": "^0.12.3",
"erlpack": "github:discord/erlpack",
"fs-extra": "^9.1.0",
"lodash": "^4.17.21",
"mongodb": "^3.6.6",
"nightmare": "^3.0.2",
"node": "^15.12.0",
"node-fetch": "^2.6.1",
"pup": "^0.0.2",
"puppeteer": "^9.0.0",
"sqlite": "^4.0.21",
"sqlite3": "^5.0.2",
"utf-8-validate": "^5.0.4",
"zlib-sync": "^0.1.7"
}
}

16
resources/date.js Normal file
View file

@ -0,0 +1,16 @@
'use strict';
/**
* @param {Number} duration - Original duration
* @param {String} value (24h)
* @param {Number} multi - Multiplier
* @returns {Number}
* @example
* const duration = muteDurationMultiplier(5000, 23h, 1 * 60 * 60 * 1000);
*/
function muteDurationMultiplier(duration, value, multi = 0) {
const digit = parseInt(value.match(/\d+/), 10);
return duration + digit * multi;
}
module.exports = { muteDurationMultiplier }

332
resources/functions.js Normal file
View file

@ -0,0 +1,332 @@
'use strict';
const fs = require('fs-extra');
const { MessageEmbed, Message, GuildMember, User, Channel, Client } = require('discord.js');
const { defaultErrorLogChannel } = require("../config.json");
const { database } = require("../database/mongo");
/**
* Log an error. If second argument, third argument is required
* @param {Error} theError - Catched error (error)
* @param {Message} msg - Message object (msg)
* @param {Client} client - This client (this.client)
* @param {Boolean} sendTheError - Add error content to notify message (true | false)
* @param {String} errorMessage - Error message ("You don't have enough permission to use that command!")
* @param {Boolean} notify - Send error to user who ran the command
*/
async function errLog(theError, msg, client, sendTheError, errorMessage, notify) {
let errLogPath, [logThis, inLogChannel, sendErr] = ['', '', ''];
if (msg) {
const comErr = msg.content.trim().split(/ +/)[0];
logThis = `\`${comErr}\` (${msg.id}) ${msg.url} in ${msg.guild ? `**${msg.channel.name}** (${msg.channel.id}) of **${msg.guild.name}** (${msg.guild.id})` : `**DM**`} ran by **${msg.author.tag}** (${msg.author.id}) \n\n`;
msg.guild ? errLogPath = `../Guilds/${msg.guild.id}/Log/` : errLogPath = '../Log/';
if (errorMessage) {
if (errorMessage.length > 0) {
sendErr = sendErr + errorMessage+'\n\n';
inLogChannel = errorMessage+'\n';
}
}
if (sendTheError) {
sendErr = sendErr+'```js\n'+theError.stack+'```';
}
if (notify) {
try {
msg.channel.send(sendErr.trim(),{split:true});
} catch (e) {
errLog(e,msg);
}
}
} else {
errLogPath = '../Log/';
}
if (client) {
try {
inLogChannel = inLogChannel+'```js\n'+theError.stack+'```';
if (msg && msg.guild && msg.guild.id === "823815890285756447") {
logThis = "";
}
const sendAt = await client.channels.cache.get(defaultErrorLogChannel);
sendAt.send(logThis + inLogChannel.trim(),{split:true});
} catch (errmes) {
errLog(errmes, msg);
}
}
const f = new Date().toUTCString();
logThis = logThis+theError.stack+"\nat: "+f;
return //console.log(logThis);
}
/*
fs.appendFile(join(__dirname, errLogPath + 'Error.txt'), logThis+"\n", (err) => {
if (err) {
console.error(err);
fs.mkdir(join(__dirname, errLogPath), { recursive: true }, (err) => {
if (err) {
return console.error('Unable to create directory. Error: ' + err.stack);
}
console.log(errLogPath + ' created.');
fs.writeFile(join(__dirname, errLogPath + 'Error.txt'), logThis+"\n", (err2) => {
if (err2) {
return console.error(err2);
}
console.error(logThis);
});
});
}
console.error(logThis);
}); */
/**
* Get message object from the message channel or provided channel
* @param {Client} client - This client (this.client)
* @param {Message} msg - Message object (msg)
* @param {String} MainID - Message ID | Channel ID | Channel Mention
* @param {String} SecondID - Message ID
* @returns {Promise<Message>} Message object
*/
async function getChannelMessage(client, msg, MainID, SecondID) {
if (!MainID) {
return
}
if (/\//.test(MainID)) {
const splitURL = MainID.split(/\/+/);
SecondID = splitURL[splitURL.length-1];
MainID = splitURL[splitURL.length-2];
}
if (MainID.startsWith('<') && MainID.endsWith('>')) {
MainID = MainID.slice(2, -1);
}
if (SecondID && (!/\D/.test(SecondID))) {
try {
const meschannel = client.channels.cache.get(MainID);
return await meschannel.messages.fetch(SecondID);
} catch (theError) {
return errLog(theError, msg, client);
}
}
return await msg.channel.messages.fetch(MainID).catch(e => {return errLog(e, msg, client)});
}
/**
* Get user object
* @param {Client} client - This client (this.client)
* @param {String} MainID - User ID | User Mention
* @returns {Promise<User>} User object
* @example const user = getUser(this.client, args[0]);
*/
async function getUser(client, msg, MainID) {
if (MainID.startsWith('<') && MainID.endsWith('>')) {
MainID = MainID.slice(2, -1);
}
if (MainID.startsWith('!')) {
MainID = (MainID.slice(1));
}
try {
return await client.users.fetch(MainID);
} catch (theError) {
return errLog(theError, msg, client);
}
}
function execCB(error, stdout, stderr) {
if (error) {
console.error(error);
return errLog(error);
}
console.log('stdout:\n'+stdout);
console.log('stderr:\n'+stderr);
}
async function ranLog(msg, cmd, addition) {
let errLogPath;
if (msg.guild) {
errLogPath = `../Guilds/${msg.guild.id}/Log/`;
} else {
errLogPath = '../Log/';
}
let add = '\n'+addition;
const b = new Date().toUTCString();
const inLog = `NEW USAGE! Message ID: ${msg.id} url: ${msg.url}\nCommand \`${cmd}\` ran by **${msg.author.tag}** (${msg.author.id}) in ${msg.guild ? `**${msg.channel.name}**` : 'DM'} (${msg.channel.id}) ${msg.guild ? `of **${msg.guild.name}** (${msg.guild.id})` : ``}${add}\nAt: ${b}`;
return //console.log(inLog);
}
/* fs.appendFile(join(__dirname, `${errLogPath}CmdUsage.txt`),`${inLog}\n`, e => {
if (e) {
fs.mkdir(join(errLogPath),{recursive:true}, e2 => {
if (e2) {}
fs.writeFile(join(__dirname, `${errLogPath}CmdUsage.txt`),`${inLog}\n`, e3 => {
if (e3) {
errLog(e3, msg);
} else {
console.log(`${errLogPath}CmdUsage.txt created.`);
}
});
});
}
});
*/
/**
* Notify when more than one member found when looking in the member list
* @param {Client} client - (this.client)
* @param {Message} msg - Message object
* @param {GuildMember[]} arr - Test array
* @param {String} key - Keyword
* @param {Number} max - Max length
* @returns {Promise<String>}
*/
async function multipleMembersFound(client, msg, arr, key, max) {
if (!max) {
max = 5;
}
if (arr.length > 1) {
try {
let multipleFound = [];
for(const one of arr) {
multipleFound.push((await (client.users.fetch(one.id))).tag);
}
let multi = [];
for(const mu of multipleFound) {
if (multipleFound.indexOf(mu) < max) {
multi.push(mu);
}
}
let mes = multi.join(", ");
if (multipleFound.length > max) {
mes = mes+` and ${multipleFound.length - max} more...`;
}
return `Multiple members found for: **${key}**\`\`\`md\n# ${mes}\`\`\``;
} catch (e) {
errLog(e, msg, client);
}
} else {
return '';
}
}
/**
* Get member object with RegExp
* @param {Message} msg
* @param {String} name
* @returns {Promise<GuildMember[]>} Member object found
*/
async function findMemberRegEx(msg, client, name) {
let found = [];
const re = new RegExp(name, "i");
const list = msg.guild.members.cache.map(g => g);
for(const mem of list) {
if (re.test(mem.displayName) || re.test((await client.users.fetch(mem.id)).tag)) {
found.push(mem);
}
}
return found;
}
/**
* React when it try something but fail because has not enough perms
* @param {Message} msg
*/
function noPerm(msg) {
if (msg) {
msg.react("sadduLife:797107817001386025").catch(e => {});
}
}
/**
* Send message
* @param {Client} client - (this.client)
* @param {Message | String} msg Message object | channel_ID
* @param {...any} content - ({content:content,optionblabla})
* @returns {Promise<Message>} Sent message object
*/
async function trySend(client, msg, ...content) {
//console.log(...content);
let msgOf;
if (msg?.channel) {
msgOf = msg.channel;
} else {
msgOf = client.channels.cache.get(msg);
}
const sentMes = await msgOf.send(...content)
.catch(e => {
if (msg?.channel) {
noPerm(msg);
}
return
});
sentAdCheck(sentMes);
return sentMes;
}
/**
* Delete message
* @param {Message} msg - Message to delete (msg)
*/
function tryDelete(msg) {
if (msg) {
msg.delete().catch(noPerm(msg));
}
}
/**
* React message
* @param {Message} msg - Message to react (msg)
* @param {String} reaction - Emote ("name:ID")
*/
function tryReact(msg, reaction) {
if (msg) {
msg.react(reaction).catch(() => {});
}
}
/**
* Check a message sent by client for ads
* @param {Message} sent - Sent message object (await msg.channel.send("discord.gg/banana"))
*/
function sentAdCheck(sent) {
if (sent) {
if (/(https:\/\/)?(www\.)?discord\.gg\/(?:\w{2,15}(?!\w)(?= *))/.test(sent.content)) {
let newCont = sent.content.replace(/(https:\/\/)?(www\.)?discord\.gg\/(?:\w{2,15}(?!\w)(?= *))/, '`Some invite link goes here`');
sent.edit(newCont, `Command abuse: Contain server invite link.`);
}
}
}
/**
* Make default image embed
* @param {Client} client
* @param {Message} msg
* @param {URL} image
* @param {GuildMember | User} author
* @param {String} title
* @param {String} footerText
* @returns {Promise<MessageEmbed>}
*/
async function defaultImageEmbed(client, msg, image, author, title, footerText) {
const { randomColors } = require("../config.json");
let footerQuote = footerText;
if (!footerQuote) {
const doc = await database.collection(msg.guild ? "Guild" : "User").findOne({document: msg.guild?.id ?? msg.author.id});
footerQuote = doc?.["settings"]?.defaultEmbed?.footerQuote || "";
}
let emb = new MessageEmbed();
try {
emb
.setTitle(title)
.setImage(image)
.setColor(msg.guild ? author?.displayColor : randomColors[Math.floor(Math.random() * randomColors.length)])
.setFooter(footerQuote);
if (author?.displayColor === 16777215) {
emb.setColor(16777214);
}
} catch (e) {
return errLog(e, msg, client, false, "", false);
}
return emb;
}
module.exports = {
multipleMembersFound,
findMemberRegEx, getUser,
getChannelMessage, errLog,
execCB, ranLog, noPerm,
trySend, tryDelete, tryReact,
sentAdCheck, defaultImageEmbed }

67
resources/getColor.js Normal file
View file

@ -0,0 +1,67 @@
'use strict';
/**
* Get color by name
* @param {String | Number} name - Name of color | Hex | Number
* @returns {String | Number} Color hex | Color number
*/
module.exports = function getColor(name) {
if (typeof name === "string") {
name = name.toLowerCase();
}
if (typeof name === 'number') {
if ( name === 16777215) {
return 16777214;
} else {
return name;
}
}
switch(name) {
case 'rosy brown':
return 12357519;
case 'magenta':
return 16711935;
case 'navy blue':
return 128;
case 'teal':
return 32896;
case 'ruby':
return 15277667;
case 'green':
return '00ff00';
case 'red':
return 'ff0000';
case 'pink':
return 'ff94f2';
case 'yellow':
return 'f1e40f';
case 'orange':
return 'ff8c00';
case 'brown':
return 'a0522d';
case 'blue':
return 3447003;
case 'light blue':
return '0fffff';
case 'cyan':
return '0fffff';
case 'purple':
return '803c9d';
case 'peach':
return 'faa775';
case 'black':
return '000000';
case 'white':
return 16777214;
default: {
if (/\D/.test(name)) {
if (name.startsWith("#")) {
name = name.slice(1);
}
return name;
} else {
return parseInt(name, 10);
}
}
}
}

10
resources/scheduler.js Normal file
View file

@ -0,0 +1,10 @@
'use strict';
const bree = require("bree");
const cabin = require("cabin");
module.exports.schedule = new bree({
// logger: new cabin(),
root: false,
workerMessageHandler: () => console.log
});

114
resources/shaChat.js Normal file
View file

@ -0,0 +1,114 @@
'use strict';
const puppeteer = require('puppeteer');
const { trySend, errLog, ranLog, noPerm } = require('./functions');
const Commando = require("@iceprod/discord.js-commando");
require("discord.js");
//'4, 15, 10, 11, 14, 17, 18'
const URL = [
'https://rebot.me/simsimi', 'https://rebot.me/ryuko-matoi',//1
'https://rebot.me/xmonikax', 'https://rebot.me/futa-nun',//3
'https://rebot.me/shinku-rozen', 'https://rebot.me/alessandro-magrini',//5
'https://rebot.me/cassie-87', 'https://rebot.me/agatha-14',//7
'https://rebot.me/himiko-toga-1', 'https://rebot.me/your-girlfriend-sister-slut',//9
'https://rebot.me/muffin-6', 'https://rebot.me/paris-1',//11
'https://rebot.me/song-answers', 'https://rebot.me/loretta-martin',//13
'https://rebot.me/zozo', 'https://rebot.me/sn0w',//15
'https://rebot.me/cinnamonwolf', 'https://rebot.me/saori-8',//17
'https://rebot.me/zacharie-1', 'https://rebot.me/natsuki-41',//19
'https://rebot.me/lea-7062078', 'https://rebot.me/bunny-exe',//21
'https://rebot.me/just-monika-56'
];
const browser = puppeteer.launch({headless:false});
const page1 = browser.then(r => r.newPage());
page1.then(r => r.goto(URL[10]).catch(console.error));
/**
* Chat with Shasha
* @param {Commando.Client} client - (this.client)
* @param {Number} index - Index of answer
* @param {Commando.Message} question - Message object
* @returns {Promise<String | Boolean>} Reply
*/
async function shaChat(client, index, question) {
if (page1) {
let query = question.content.trim();
if (query.toLowerCase().startsWith(client.commandPrefix+"chat")) {
query = query.slice((client.commandPrefix+"chat").length).trim();
}
try {
const page = await page1;
console.log("New chat query: "+query);
await page.waitForSelector("input[id=\"question\"]");
await page.type("input[id=\"question\"]", query);
await page.keyboard.press("Enter");
await page.waitForSelector(`#answer > div:nth-child(${index})`, {timeout:5000}).catch(() => {});
return getAnswerIndex(page, index);
} catch (error) {
throw error;
}
}
}
/**
* @param {puppeteer.Page} page
* @param {Number} index
* @returns {String}
*/
async function getAnswerIndex(page, index) {
try {
const result = await page.evaluate((index) => {
const res = document.querySelector(`#answer > div:nth-child(${index})`).childNodes[4].textContent;
return res;
}, index);
return result;
} catch (e) {
throw e;
}
}
let chatIndex = 3;
/**
* @param {Commando.Client} client
* @param {Commando.CommandoMessage} message
* @returns
*/
async function chatAnswer(client, message) {
console.log(message.content);
console.log(chatIndex);
if (message.content.trim().length === 0) {
return
} else {
try {
message.channel.startTyping();
await shaChat(client, chatIndex, message).then(async answer => {
chatIndex += 2;
if (message.channel.lastMessage.author === client.user && answer?.trim() === message.channel.lastMessage.content.trim()) {
return trySend(client, message, "Please speak one by one, I'm overwhelmed <:catstareLife:794930503076675584>");
} else {
trySend(client, message, answer.trim()).then(() => {
message.channel.stopTyping();
}).catch(e => {
noPerm(message);
message.channel.stopTyping();
});
}
return ranLog(message, message.content.trim(), answer);
}).catch(e => {
noPerm(message);
message.channel.stopTyping();
});
} catch (e) {
noPerm(message);
message.channel.stopTyping();
}
}
}
module.exports = { shaChat, chatAnswer }

BIN
settings.sqlite3 Normal file

Binary file not shown.