Added the ability to add custom loading banners and started transitioning away from the Canvas module

This commit is contained in:
ION606
2022-10-24 20:13:15 -04:00
parent 2ff7a84bee
commit df7d79e69a
6 changed files with 1261 additions and 809 deletions
+20
View File
@@ -2,6 +2,8 @@
const { MongoClient, ServerApiVersion } = require('mongodb');
const { Constants } = require('discord.js');
const { CreateNewCollection } = require("../db/econ");
const { checkRole } = require('./verify.js');
const fetch = require('node-fetch');
async function setWelcomeChannel(dbo, message, channelname) {
@@ -99,6 +101,22 @@ async function execute(interaction, Discord, Client, bot) {
} else if (command == "remove_mod_role") {
dbo.updateOne({_id: "roles"}, { $pull: { commands: { $in: [ args[i].value ] }} });
interaction.reply({ content: "Role removed!", ephemeral: true });
} else if (command == "welcome_banner") {
const response = await fetch(interaction.options.data[0].attachment.attachment);
const arrayBuffer = await response.arrayBuffer();
const imgbfr = Buffer.from(arrayBuffer);
dbo.updateOne({_id: 'WELCOME'}, {$set: {welcomebanner: imgbfr.toString('base64')}});
interaction.reply({ content: "Banner updated!", ephemeral: true });
} else if ("welcome_text_color") {
const reg = /^#[0-9A-F]{6}$/i;
const newCol = interaction.options.data[0].value;
if (reg.test(newCol)) {
dbo.updateOne({_id: 'WELCOME'}, {$set: {welcometextcolor: newCol}});
interaction.reply("Color updated!");
} else {
interaction.reply("Please chose a valid hex color");
}
} else {
interaction.reply({content: "Please chose a valid option", ephemeral: true});
}
@@ -137,6 +155,8 @@ module.exports = {
options: [
{name: 'welcome_channel', description: 'Sets the channel for welcome messages', type: Constants.ApplicationCommandOptionTypes.CHANNEL },
{name: 'welcome_message', description: 'Sets the welcome message, Use {un} for username, {ut} for user tag and {sn} for server name', type: Constants.ApplicationCommandOptionTypes.STRING },
{name: 'welcome_banner', description: 'Sets the welcome banner', type: Constants.ApplicationCommandOptionTypes.ATTACHMENT},
{name: 'welcome_text_color', description: 'Sets the welcome banner text color', type: Constants.ApplicationCommandOptionTypes.STRING},
{name: 'keep_logs', description: 'Toggles logging', type: Constants.ApplicationCommandOptionTypes.BOOLEAN },
{name: 'log_channel', description: 'Sets the logging channel', type: Constants.ApplicationCommandOptionTypes.CHANNEL },
{name: 'log_severity', description: 'Sets the logging Severity (logs this/lower tiers)', type: Constants.ApplicationCommandOptionTypes.STRING, choices: [{name: 'none', value: 'none'}, {name: 'low', value: 'low'}, {name: 'medium', value: 'medium'}, {name: 'high', value: 'high'}] },
-33
View File
@@ -1,33 +0,0 @@
const { checkRole } = require('./verify.js');
const { Constants } = require('discord.js');
module.exports = {
name: 'unlock',
description: 'Unlock a channel',
execute(interaction, Discord, Client, bot) {
const arg = interaction.options.data[0];
const guild = bot.guilds.cache.get(interaction.guildId);
if (!checkRole(bot, guild, interaction.user.id)) { return message.reply('Insufficient Permissions!'); }
var channel;
if (arg) {
channel = arg.channel;
} else {
channel = interaction.channel;
}
let role = interaction.guild.roles.cache.find(r => r.name === "@everyone");
channel.permissionOverwrites.edit(role.id, {
VIEW_CHANNEL: true,
SEND_MESSAGES: true,
READ_MESSAGE_HISTORY: true,
ATTACH_FILES: true
});
interaction.reply(`${channel} has been unlocked!`);
},
options: [{name: 'channel', description: 'The channel to unlock (defaults to current channel)', type: Constants.ApplicationCommandOptionTypes.CHANNEL, required: false}]
}
+95 -86
View File
@@ -1,105 +1,114 @@
const { MessageAttachment } = require('discord.js');
// const { readFile } = require('fs/promises');
const fs = require("fs");
const sharp = require('sharp');
const fetch = require('node-fetch');
const arrayBufferToBuffer = require('arraybuffer-to-buffer');
const { request } = require('undici');
const CanvasImport = require('@napi-rs/canvas');
const canvas = CanvasImport.createCanvas(700, 250)
const context = canvas.getContext('2d')
//https://some-random-api.ml/welcome
async function welcome(member, welcomechannel, welcomemessage = null, welcomebanner = null) {
//Draw Stuff
const context = canvas.getContext('2d');
var bkimgsrc;
let bkurl = 'https://github.com/ION606/selmerBot/blob/main/commands/admin/wallpaper.jpg';
const response = await fetch(bkurl);
response.arrayBuffer().then(async (data) => {
// const background = new CanvasImport.Image();
// background.src = arrayBufferToBuffer(data);
const { GuildMember } = require('discord.js');
// This uses the canvas dimensions to stretch the image onto the entire canvas
// context.drawImage(background, 0, 0, canvas.width, canvas.height);
context.fillStyle = 'rgba(0,0,0,1)';
context.fillRect(0,0, canvas.width, canvas.height);
//Draw the Border
context.strokeStyle = '#0099ff';
context.strokeRect(0, 0, canvas.width, canvas.height);
//Add Text
//have the function here, because returns are whack
const applyText = (canvas, text) => {
const context = canvas.getContext('2d');
// Declare a base size of the font
let fontSize = 70;
let i = 0;
do {
// Assign the font to the context and decrement it so it can be measured again
context.font = `italic ${fontSize -= 10}px sans-serif`;
// Compare pixel width of the text to the canvas minus the approximate avatar size
i ++;
} while (context.measureText(text).width > canvas.width - 100);
// Return the result to use in the actual canvas
return context.font;
};
//message.author.username == interaction.member.displayName
//message.guild.name == interaction.member.guild.name
let text = `Welcome to ${member.guild.name} ${member.user.username}#${member.user.discriminator}!`;
if(welcomemessage != null) {
function formatMessage(member, welcomemessage) {
return new Promise((resolve, reject) => {
let text = `Welcome to ${member.guild.name} ${member.user.tag}!`;
if (welcomemessage != null) {
text = welcomemessage;
text = text.replace('{sn}', member.guild.name);
text = text.replace('{un}', member.user.username);
text = text.replace('{ut}', member.user.discriminator);
}
context.font= applyText(canvas, text);
context.fillStyle = '#ffffff';
context.fillText(text, (canvas.width/2) - (context.measureText(text).width)/2, canvas.height - 15);
resolve(text);
});
}
/**
* @param {GuildMember} member
* @param {*} welcomeChannel
*/
async function welcome(member, welcomeChannel, welcomemessage, welcomebanner, welcomeTextCol) {
formatMessage(member, welcomemessage).then(async (wmsg) => {
const width = 1024;
const height = 500;
const usernameText = `${wmsg}`;
const memberCountText = `You are member ${member.guild.memberCount}`;
const username = `
<svg width="${width}" height="${height}">
<style>
.username { fill: ${welcomeTextCol}; font-size: ${Math.round(wmsg.length/2)}px; font-weight: bold;}
</style>
<text x="50%" y="50%" text-anchor="middle" class="username" font-family='Didot'>${usernameText}</text>
</svg>
`;
const memberCount = `
<svg width="${width}" height="${height}">
<style>
.memberCount { fill: ${welcomeTextCol}; font-size: 40px; font-weight: bold;}
</style>
<text x="50%" y="50%" text-anchor="middle" class="memberCount" font-family='Didot'>${memberCountText}</text>
</svg>
`;
//Draw a white circle
context.beginPath();
context.arc((canvas.width/2), 90, 85, 0, 2 * Math.PI, false);
context.fillStyle = 'white';
context.fill();
context.closePath();
const r = 100;
const circleShape = Buffer.from(`<svg><circle cx="${r}" cy="${r}" r="${r}" /></svg>`);
var response, arrayBuffer;
const usernameBuffer = Buffer.from(username);
const memberCountBuffer = Buffer.from(memberCount);
response = await fetch(member.displayAvatarURL());
arrayBuffer = await response.arrayBuffer();
const iconBuffer = Buffer.from(arrayBuffer);
//ANYTHING DRAWN AFTER THIS WILL BE CLIPPED!!!
//Make whatever image will be draw (the user's avatar) into a circular format
context.beginPath();
context.arc((canvas.width/2), 90, 80, 0, Math.PI * 2, true);
context.closePath();
var bkBuffer;
// Clip off the region you just drew (enforce template?)
context.clip();
if (!welcomebanner) {
response = await fetch('https://wallpapercave.com/wp/wp3258574.png');
arrayBuffer = await response.arrayBuffer();
bkBuffer = Buffer.from(arrayBuffer);
} else {
// return console.log(welcomebanner);
bkBuffer = Buffer.from(welcomebanner, 'base64');
}
sharp(iconBuffer)
.resize(300, 300)
.composite([{
input: circleShape,
blend: 'dest-in'
}])
.toBuffer().then((iconBufferNew) => {
sharp(bkBuffer)
.resize(1024, 500)
.composite([
{
input: usernameBuffer,
top: 80,
left: -10,
},
{
input: memberCountBuffer,
top: 130,
left: -10,
},
{
input: iconBufferNew,
top: 10,
left: 1024/2 - 300/2,
},
]).toBuffer((err, buffer) => {
if (err) { return console.error(err); }
//Add the user's profile pic (message.author == interaction.user)
const { body } = await request(member.displayAvatarURL({ format: 'jpg' }));
const avatar = new CanvasImport.Image();
avatar.src = Buffer.from(await body.arrayBuffer());
context.drawImage(avatar, (canvas.width/2) - 80, 10, 160, 160);
// return console.log(buffer.byteLength * 0.000001);
welcomeChannel.send({
content: "content",
files: [buffer],
});
});
});
});
// Use the helpful Attachment class structure to process the file for you
const attachment = new MessageAttachment(canvas.toBuffer('image/png'), 'profile-image.png');
welcomechannel.send({ files: [attachment] });
})
// .toFile("./events/output.jpeg", (err, info) => {
// if (err) throw err;
// const attachment = new DJS.MessageAttachment("./events/output.jpeg");
// welcomeChannel.send({
// content: content,
// files: [attachment],
// });*/
// });
}
module.exports = { welcome }
+7 -5
View File
@@ -1,7 +1,7 @@
//#region imports
const { Client, Intents } = require('discord.js');
const Discord = require('discord.js');
const { MongoClient, ServerApiVersion } = require('mongodb');
const { MongoClient, ServerApiVersion, GridFSBucket } = require('mongodb');
const fs = require('fs');
// const OpenAI = require('openai-api')
const { Configuration, OpenAIApi } = require("openai");
@@ -245,8 +245,9 @@ bot.on('interactionCreate', async interaction => {
} else if (econList.includes(commandName)) {
bot.commands.get('econ').execute(bot, interaction, Discord, mongouri, items, xp_collection);
} else if (commandName == 'game') {
return console.log(interaction);
bot.commands.get(bot, interaction, command, Discord, mongouri, items, xp_collection)
return interaction.reply("This command is still in development, use normal text\nEx: _!game tictactoe @opponent_")
const command = interaction.options.data[0];
bot.commands.get('game').execute(bot, interaction, command, Discord, mongouri, items, xp_collection);
} else if (bot.commands.has(commandName)) {
bot.commands.get(commandName).execute(interaction, Discord, Client, bot);
} else {
@@ -281,7 +282,8 @@ bot.on("guildCreate", guild => {
bot.mongoconnection.then(client => {
const dbo = client.db(guild.id).collection('SETUP');
dbo.insertMany([{_id: 'WELCOME', 'welcomechannel': null, 'welcomemessage': null, 'welcomebanner': null}, {_id: 'LOG', 'keepLogs': false, 'logchannel': null, 'severity': 0}, {_id: 'announcement', channel: null, role: null}]);
dbo.insertMany([{_id: 'WELCOME', 'welcomechannel': null, 'welcomemessage': null, 'welcomebanner': null}, {_id: 'LOG', 'keepLogs': false, 'logchannel': null, 'severity': 0},
{_id: 'announcement', channel: null, role: null}, {_id: 'roles', commands: ["Selmer Bot Commands"], announcements: "Selmer Bot Calendar"}]);
});
});
@@ -362,7 +364,7 @@ bot.on('guildMemberAdd', async (member) => {
return console.log('No welcome channel detected');
}
await welcome(member, welcomechannel, docs[0].welcomemessage);
await welcome(member, welcomechannel, docs[0].welcomemessage, docs[0].welcomebanner, (docs[0].welcometextcolor) ? docs[0].welcometextcolor : "#FFFFFF");
})
})
});
+1136 -680
View File
File diff suppressed because it is too large Load Diff
+1 -3
View File
@@ -4,12 +4,10 @@
"@discordjs/opus": "github:discordjs/opus",
"@discordjs/rest": "^1.1.0",
"@discordjs/voice": "^0.8.0",
"@napi-rs/canvas": "^0.1.22",
"apt": "^0.0.2",
"arraybuffer-to-buffer": "^0.0.7",
"axios": "^0.27.2",
"body-parser": "^1.20.0",
"canvas": "^2.9.3",
"cheerio": "^1.0.0-rc.10",
"coingecko-api": "^1.0.10",
"cors": "^2.8.5",
@@ -35,11 +33,11 @@
"openai": "^3.0.0",
"play-dl": "^1.9.4",
"pusher": "^5.1.1-beta",
"random-memes": "^3.1.0",
"request": "^2.88.2",
"robinhood": "^1.8.0",
"rss-parser": "^3.12.0",
"sequelize": "^6.19.0",
"sharp": "^0.31.1",
"sqlite3": "^5.0.3",
"stripe": "^9.11.0",
"sudo": "^1.0.3",