UNPKG

@m3rcena/weky

Version:

A fun npm package to play games within Discord with buttons!

344 lines (343 loc) 11.3 kB
import axios from "axios"; import chalk from "chalk"; import { load } from "cheerio"; import { exec } from "child_process"; import { randomBytes } from "crypto"; import { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } from "discord.js"; import { ofetch } from "ofetch"; import stringWidth from "string-width"; import { promisify } from "util"; import { createCanvas } from "@napi-rs/canvas"; import weky_package from "../../package.json"; import wordList from "../data/words.json"; export const getRandomString = function (length) { const randomChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; const randomBytesArray = new Uint8Array(length); randomBytes(length).forEach((byte, index) => { randomBytesArray[index] = byte % randomChars.length; }); let result = 'weky_'; for (let i = 0; i < length; i++) { result += randomChars.charAt(randomBytesArray[i]); } return result; }; export const createButton = function (label, disabled) { let style = ButtonStyle.Secondary; if (label === 'AC' || label === 'DC' || label === '⌫') { style = ButtonStyle.Danger; } else if (label === ' = ') { style = ButtonStyle.Success; } else if (label === '(' || label === ')' || label === '^' || label === '%' || label === '÷' || label === 'x' || label === ' - ' || label === ' + ' || label === '.' || label === 'RND' || label === 'SIN' || label === 'COS' || label === 'TAN' || label === 'LG' || label === 'LN' || label === 'SQRT' || label === 'x!' || label === '1/x' || label === 'π' || label === 'e' || label === 'ans') { style = ButtonStyle.Primary; } if (disabled) { const btn = new ButtonBuilder() .setLabel(label) .setStyle(style) .setDisabled(); if (label === '\u200b') { btn.setCustomId(getRandomString(10)); } else { btn.setCustomId('cal' + label); } return btn; } else { const btn = new ButtonBuilder().setLabel(label).setStyle(style); if (label === '\u200b') { btn.setDisabled(); btn.setCustomId(getRandomString(10)); } else { btn.setCustomId('cal' + label); } return btn; } }; export const createDisabledButton = function (label) { let style = ButtonStyle.Secondary; if (label === 'AC' || label === 'DC' || label === '⌫') { style = ButtonStyle.Danger; } else if (label === ' = ') { style = ButtonStyle.Success; } else if (label === '(' || label === ')' || label === '^' || label === '%' || label === '÷' || label === 'x' || label === ' - ' || label === ' + ' || label === '.' || label === 'RND' || label === 'SIN' || label === 'COS' || label === 'TAN' || label === 'LG' || label === 'LN' || label === 'SQRT' || label === 'x!' || label === '1/x' || label === 'π' || label === 'e' || label === 'ans') { style = ButtonStyle.Primary; } const btn = new ButtonBuilder().setLabel(label).setStyle(style); if (label === '\u200b') { btn.setDisabled(); btn.setCustomId(getRandomString(10)); } else { btn.setCustomId('cal' + label); } const disabledLabels = ["^", "%", '÷', 'AC', '⌫', 'x!', 'x', '1/x']; if (disabledLabels.includes(label)) { btn.setDisabled(true); } ; return btn; }; export const addRow = function (btns) { const row = new ActionRowBuilder(); for (const btn of btns) { row.addComponents(btn); } return row; }; export const getRandomSentence = function (length) { const word = []; const words = wordList; for (let i = 0; i < length; i++) { word.push(words[Math.floor(Math.random() * words.length)]); } return word; }; export const convertTime = function (time) { const absoluteSeconds = Math.floor((time / 1000) % 60); const absoluteMinutes = Math.floor((time / (1000 * 60)) % 60); const absoluteHours = Math.floor((time / (1000 * 60 * 60)) % 24); const absoluteDays = Math.floor((time / (1000 * 60 * 60 * 24))); const d = absoluteDays ? absoluteDays === 1 ? '1 day' : `${absoluteDays} days` : null; const h = absoluteHours ? absoluteHours === 1 ? '1 hour' : `${absoluteHours} hours` : null; const m = absoluteMinutes ? absoluteMinutes === 1 ? '1 minute' : `${absoluteMinutes} minutes` : null; const s = absoluteSeconds ? absoluteSeconds === 1 ? '1 second' : `${absoluteSeconds} seconds` : null; const absoluteTime = []; if (d) absoluteTime.push(d); if (h) absoluteTime.push(h); if (m) absoluteTime.push(m); if (s) absoluteTime.push(s); return absoluteTime.join(', '); }; export const checkPackageUpdates = async function (name, notifyUpdate) { if (notifyUpdate === false) return; try { const execPromise = promisify(exec); const { stdout } = await execPromise('npm show @m3rcena/weky version'); if (stdout.trim().toString() > weky_package.version) { const advertise = chalk(`Are you using ${chalk.red(name)}? Don't lose out on new features!`); const msg = chalk(`New ${chalk.green('version')} of ${chalk.yellow('@m3rcena/weky')} is available!`); const msg2 = chalk(`${chalk.red(weky_package.version)} -> ${chalk.green(stdout.trim().toString())}`); const tip = chalk(`Registry: ${chalk.cyan('https://www.npmjs.com/package/@m3rcena/weky')}`); const install = chalk(`Run ${chalk.green(`npm i @m3rcena/weky@${stdout.trim().toString()}`)} to update!`); boxConsole([advertise, msg, msg2, tip, install]); } } catch (error) { console.error(error); } }; export const boxConsole = function (messages) { let tips = []; let maxLen = 0; const defaultSpace = 4; const spaceWidth = stringWidth(' '); if (Array.isArray(messages)) { tips = Array.from(messages); } else { tips = [messages]; } tips = [' ', ...tips, ' ']; tips = tips.map((msg) => ({ val: msg, len: stringWidth(msg) })); maxLen = tips.reduce((len, tip) => { maxLen = Math.max(len, tip.len); return maxLen; }, maxLen); maxLen += spaceWidth * 2 * defaultSpace; tips = tips.map(({ val, len }) => { let i = 0; let j = 0; while (len + i * 2 * spaceWidth < maxLen) { i++; } j = i; while (j > 0 && len + i * spaceWidth + j * spaceWidth > maxLen) { j--; } return ' '.repeat(i) + val + ' '.repeat(j); }); const line = chalk.yellow('─'.repeat(maxLen)); console.log(chalk.yellow('┌') + line + chalk.yellow('┐')); for (const msg of tips) { console.log(chalk.yellow('│') + msg + chalk.yellow('│')); } console.log(chalk.yellow('└') + line + chalk.yellow('┘')); }; export const replaceHexCharacters = function (text) { const hexRegex = /&#x([a-fA-F0-9]+);/g; return text.replace(hexRegex, (_, hex) => String.fromCharCode(parseInt(hex, 16))); }; export const getButtonDilemma = async function () { const data = await ofetch('https://weky.miv4.com/api/wyptb', { method: 'GET', }); return data; }; export const shuffleArray = function (array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); const temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; }; export const createHangman = async function (state = 0) { return new Promise((res) => { const canvas = createCanvas(300, 350); const ctx = canvas.getContext('2d'); ctx.lineWidth = 5; // Poll base createLine(ctx, 50, 330, 150, 330); // Poll Mid createLine(ctx, 100, 330, 100, 50); // Poll Head createLine(ctx, 100, 50, 200, 50); // Poll To Man Connector createLine(ctx, 200, 50, 200, 80); // Head ctx.strokeStyle = state < 1 ? "#a3a3a3" : "#000000"; ctx.beginPath(); ctx.arc(200, 100, 20, 0, 2 * Math.PI); ctx.stroke(); ctx.closePath(); // Main Body createLine(ctx, 200, 120, 200, 200, state < 2 ? "#a3a3a3" : "#000000"); // Hands createLine(ctx, 200, 150, 170, 130, state < 3 ? "#a3a3a3" : "#000000"); createLine(ctx, 200, 150, 230, 130, state < 4 ? "#a3a3a3" : "#000000"); // Legs createLine(ctx, 200, 200, 180, 230, state < 5 ? "#a3a3a3" : "#000000"); createLine(ctx, 200, 200, 220, 230, state < 6 ? "#a3a3a3" : "#000000"); res(canvas.toBuffer("image/png")); }); }; function createLine(ctx, fromX, fromY, toX, toY, color = "#000000") { ctx.beginPath(); ctx.strokeStyle = color; ctx.moveTo(fromX, fromY); ctx.lineTo(toX, toY); ctx.stroke(); ctx.closePath(); } ; export const fetchhtml = async function (url) { const options = { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36', referer: 'https://www.google.com/', }, }; const html = await axios.get(url, options); return load(html.data); }; export const shuffleString = function (string) { const seed = Date.now(); const str = string.split(''); const length = str.length; for (let i = length - 1; i > 0; i--) { const j = Math.floor((Math.random() * seed) % (i + 1)); const tmp = str[i]; str[i] = str[j]; str[j] = tmp; } ; return str.join(''); }; export const randomHexColor = function () { return ('#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6)); }; const defaultFooter = { text: "©️ M3rcena Development | Powered by Mivator", iconURL: "https://raw.githubusercontent.com/M3rcena/m3rcena-weky/refs/heads/main/assets/logo.png" }; export const createEmbed = (embedOptions, noFields = false) => { const embed = new EmbedBuilder() .setTitle(embedOptions.title) .setDescription(embedOptions.description ?? null) .setColor(embedOptions.color ?? "Blurple") .setURL(embedOptions.url || null) .setThumbnail(embedOptions.thumbnail || null) .addFields(noFields ? [] : embedOptions.fields || []) .setImage(embedOptions.image || null) .setTimestamp(embedOptions.timestamp ? new Date() : null) .setFooter(embedOptions.footer || defaultFooter); if (embedOptions.author) { embed.setAuthor({ name: embedOptions.author.name, iconURL: embedOptions.author.icon_url, url: embedOptions.author.url }); } ; return embed; };