diff options
author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-07-17 10:25:46 -0400 |
---|---|---|
committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-07-17 10:25:46 -0400 |
commit | d1724227abfb8f0fcd9e573f7e9772cf0be8257a (patch) | |
tree | 52c9dbae1fbbbd3c777d9c16ab643c477141ae21 /src/commands/utilities | |
parent | 53d2b18f7f73d5696fb7cd86d1c164a790dfdcc3 (diff) | |
download | tanzanite-d1724227abfb8f0fcd9e573f7e9772cf0be8257a.tar.gz tanzanite-d1724227abfb8f0fcd9e573f7e9772cf0be8257a.tar.bz2 tanzanite-d1724227abfb8f0fcd9e573f7e9772cf0be8257a.zip |
honestly no idea what I did at this point
Diffstat (limited to 'src/commands/utilities')
-rw-r--r-- | src/commands/utilities/_whoHasRole.ts | 0 | ||||
-rw-r--r-- | src/commands/utilities/hash.ts | 42 | ||||
-rw-r--r-- | src/commands/utilities/price.ts | 220 | ||||
-rw-r--r-- | src/commands/utilities/viewraw.ts | 2 | ||||
-rw-r--r-- | src/commands/utilities/whoHasRole.ts | 53 |
5 files changed, 316 insertions, 1 deletions
diff --git a/src/commands/utilities/_whoHasRole.ts b/src/commands/utilities/_whoHasRole.ts deleted file mode 100644 index e69de29..0000000 --- a/src/commands/utilities/_whoHasRole.ts +++ /dev/null diff --git a/src/commands/utilities/hash.ts b/src/commands/utilities/hash.ts new file mode 100644 index 0000000..4b5b01c --- /dev/null +++ b/src/commands/utilities/hash.ts @@ -0,0 +1,42 @@ +import crypto from 'crypto'; +import { Constants } from 'discord-akairo'; +import got from 'got'; +import { BushCommand, BushMessage } from '../../lib'; + +export default class HashCommand extends BushCommand { + constructor() { + super('hash', { + aliases: ['hash'], + category: 'utilities', + description: { + content: 'Gets the file hash of the given discord link', + usage: 'hash <file url>', + examples: ['hash https://cdn.discordapp.com/emojis/782630946435366942.png?v=1'] //nice + }, + args: [ + { + id: 'url', + type: Constants.ArgumentTypes.URL, + match: Constants.ArgumentMatches.PHRASE, + prompt: { + start: 'What url would you like to find the hash of?', + retry: '{error} Enter a valid url.' + } + } + ], + clientPermissions: ['SEND_MESSAGES'] + }); + } + + public async exec(message: BushMessage, { url }: { url: string }): Promise<void> { + try { + const req = await got.get(url); + const rawHash = crypto.createHash('md5'); + rawHash.update(req.rawBody.toString('binary')); + const hash = rawHash.digest('hex'); + await message.util.reply(`\`${hash}\``); + } catch { + await message.util.reply('Unable to calculate hash.'); + } + } +} diff --git a/src/commands/utilities/price.ts b/src/commands/utilities/price.ts new file mode 100644 index 0000000..231930c --- /dev/null +++ b/src/commands/utilities/price.ts @@ -0,0 +1,220 @@ +import { Constants } from 'discord-akairo'; +import { ColorResolvable, MessageEmbed } from 'discord.js'; +import Fuse from 'fuse.js'; +import got from 'got'; +import { BushCommand, BushMessage } from '../../lib'; + +interface Summary { + amount: number; + pricePerUnit: number; + orders: number; +} + +interface Bazaar { + success: boolean; + lastUpdated: number; + products: { + [key: string]: { + product_id: string; + sell_summary: Summary[]; + buy_summary: Summary[]; + quick_status: { + productId: string; + sellPrice: number; + sellVolume: number; + sellMovingWeek: number; + sellOrders: number; + buyPrice: number; + buyVolume: number; + buyMovingWeek: number; + buyOrders: number; + }; + }; + }; +} + +interface LowestBIN { + [key: string]: number; +} + +interface AuctionAverages { + [key: string]: { + price?: number; + count?: number; + sales?: number; + clean_price?: number; + clean_sales?: number; + }; +} + +export default class PriceCommand extends BushCommand { + public constructor() { + super('price', { + aliases: ['price'], + category: 'utilities', + clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], + description: { + usage: 'price <item id>', + examples: ['price ASPECT_OF_THE_END'], + content: 'Finds the price information of an item.' + }, + ratelimit: 4, + cooldown: 4000, + typing: true, + args: [ + { + id: 'item', + match: Constants.ArgumentMatches.CONTENT, + type: Constants.ArgumentTypes.STRING, + prompt: { + start: 'What item would you like to find the price of?', + retry: '{error} Choose a valid item.' + } + }, + { + id: 'strict', + match: Constants.ArgumentMatches.FLAG, + flag: '--strict', + default: false + } + ], + slash: true, + slashOptions: [ + { + name: 'item', + description: 'The item that you would you like to find the price of.', + type: 'STRING', + required: true + }, + { + name: 'strict', + description: 'Whether or not to bypass the fuzzy search.', + type: 'BOOLEAN', + required: false + } + ] + }); + } + + public async exec(message: BushMessage, { item, strict }: { item: string; strict: boolean }): Promise<unknown> { + const errors = new Array<string>(); + const bazaar: Bazaar = await get('https://api.hypixel.net/skyblock/bazaar').catch(() => errors.push('bazaar')); + const currentLowestBIN: LowestBIN = await get('https://moulberry.codes/lowestbin.json').catch(() => + errors.push('current lowest BIN') + ); + const averageLowestBIN: LowestBIN = await get('https://moulberry.codes/auction_averages_lbin/3day.json').catch(() => + errors.push('average Lowest BIN') + ); + const auctionAverages: AuctionAverages = await get('https://moulberry.codes/auction_averages/3day.json').catch(() => + errors.push('auction average') + ); + // adds _ to item name + let parsedItem = item.toString().toUpperCase().replace(/ /g, '_').replace(/'S/g, ''); + const priceEmbed = new MessageEmbed(); + + if (errors?.length) { + priceEmbed.setFooter; + } + + //combines all the item names from each + const itemNames = Array.from( + new Set( + (averageLowestBIN ? Object.keys(averageLowestBIN) : []).concat( + currentLowestBIN ? Object.keys(currentLowestBIN) : [], + auctionAverages ? Object.keys(auctionAverages) : [], + bazaar?.products ? Object.keys(bazaar.products) : [] + ) + ) + ); + + // fuzzy search + if (!strict) { + parsedItem = new Fuse(itemNames)?.search(parsedItem)[0]?.item; + } + + // If bazaar item then it there should not be any ah data + if (bazaar['products'][parsedItem]) { + const bazaarPriceEmbed = new MessageEmbed() + .setColor( + errors?.length + ? (this.client.util.emojis.warn as ColorResolvable) + : (this.client.util.colors.success as ColorResolvable) + ) + .setTitle(`Bazaar Information for \`${parsedItem}\``) + .addField('Sell Price', Bazaar('sellPrice', 2, true)) + .addField('Buy Price', Bazaar('buyPrice', 2, true)) + .addField('Margin', (Number(Bazaar('buyPrice', 2, false)) - Number(Bazaar('sellPrice', 2, false))).toLocaleString()) + .addField('Current Sell Orders', Bazaar('sellOrders', 0, true)) + .addField('Current Buy Orders', Bazaar('buyOrders', 0, true)); + return await message.util.reply({ embeds: [bazaarPriceEmbed] }); + } + + // Checks if the item exists in any of the action information otherwise it is not a valid item + if (currentLowestBIN?.[parsedItem] || averageLowestBIN?.[parsedItem] || auctionAverages?.[parsedItem]) { + priceEmbed + .setColor(this.client.util.colors.success) + .setTitle(`Price Information for \`${parsedItem}\``) + .setFooter('All information is based on the last 3 days.'); + } else { + const errorEmbed = new MessageEmbed(); + errorEmbed + .setColor(this.client.util.colors.error) + .setDescription( + `${this.client.util.emojis.error} \`${parsedItem}\` is not a valid item id, or it has no auction data.` + ); + return await message.util.reply({ embeds: [errorEmbed] }); + } + + if (currentLowestBIN?.[parsedItem]) { + const currentLowestBINPrice = currentLowestBIN[parsedItem].toLocaleString(); + priceEmbed.addField('Current Lowest BIN', currentLowestBINPrice); + } + if (averageLowestBIN?.[parsedItem]) { + const averageLowestBINPrice = averageLowestBIN[parsedItem].toLocaleString(); + priceEmbed.addField('Average Lowest BIN', averageLowestBINPrice); + } + if (auctionAverages?.[parsedItem]?.price) { + const auctionAveragesPrice = auctionAverages[parsedItem].price.toLocaleString(); + priceEmbed.addField('Average Auction Price', auctionAveragesPrice); + } + if (auctionAverages?.[parsedItem]?.count) { + const auctionAveragesCountPrice = auctionAverages[parsedItem].count.toLocaleString(); + priceEmbed.addField('Average Auction Count', auctionAveragesCountPrice); + } + if (auctionAverages?.[parsedItem]?.sales) { + const auctionAveragesSalesPrice = auctionAverages[parsedItem].sales.toLocaleString(); + priceEmbed.addField('Average Auction Sales', auctionAveragesSalesPrice); + } + if (auctionAverages?.[parsedItem]?.clean_price) { + const auctionAveragesCleanPrice = auctionAverages[parsedItem].clean_price.toLocaleString(); + priceEmbed.addField('Average Auction Clean Price', auctionAveragesCleanPrice); + } + if (auctionAverages?.[parsedItem]?.clean_sales) { + const auctionAveragesCleanSales = auctionAverages[parsedItem].clean_sales.toLocaleString(); + priceEmbed.addField('Average Auction Clean Sales', auctionAveragesCleanSales); + } + return await message.util.reply({ embeds: [priceEmbed] }); + + //Helper functions + function Bazaar(Information: string, digits: number, commas: boolean): string { + const price = bazaar?.products[parsedItem]?.quick_status?.[Information]; + const a = Number(Number(price).toFixed(digits)); + return commas ? a?.toLocaleString() : a?.toString(); + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async function get(url: string): Promise<any> { + const data = await got.get(url).catch((error) => { + this.client.console.warn('PriceCommand', `There was an problem fetching data from <<${url}>> with error:\n${error}`); + throw 'Error Fetching price data'; + }); + try { + const json = JSON.parse(data.body); + return json; + } catch (error) { + this.client.console.warn('PriceCommand', `There was an problem parsing data from <<${url}>> with error:\n${error}`); + throw 'json error'; + } + } + } +} diff --git a/src/commands/utilities/viewraw.ts b/src/commands/utilities/viewraw.ts index 7642b2a..3658bde 100644 --- a/src/commands/utilities/viewraw.ts +++ b/src/commands/utilities/viewraw.ts @@ -7,7 +7,7 @@ export default class ViewRawCommand extends BushCommand { public constructor() { super('viewraw', { aliases: ['viewraw'], - category: 'info', + category: 'utilities', clientPermissions: ['EMBED_LINKS'], description: { usage: 'viewraw <message id> <channel>', diff --git a/src/commands/utilities/whoHasRole.ts b/src/commands/utilities/whoHasRole.ts new file mode 100644 index 0000000..1828c95 --- /dev/null +++ b/src/commands/utilities/whoHasRole.ts @@ -0,0 +1,53 @@ +import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; +import { MessageEmbed, Role, Util } from 'discord.js'; + +export default class WhoHasRoleCommand extends BushCommand { + public constructor() { + super('whohasrole', { + aliases: ['whohasrole'], + category: 'utilities', + description: { + content: 'Allows you to view what users have a certain role.', + usage: 'template <requiredArg> [optionalArg]', + examples: ['template 1 2'] + }, + args: [ + { + id: 'role', + type: 'role', + prompt: { + start: 'What role would you like to find the users of?', + retry: '{error} Pick a valid role.', + optional: false + } + } + ], + slash: true, + slashOptions: [ + { + name: 'role', + description: 'What role would you like to find the users of?', + type: 'ROLE', + required: true + } + ], + channel: 'guild', + clientPermissions: ['SEND_MESSAGES'], + userPermissions: ['SEND_MESSAGES'] + }); + } + public async exec(message: BushMessage | BushSlashMessage, args: { role: Role }): Promise<unknown> { + const roleMembers = args.role.members.map((member) => `${member.user} (${Util.escapeMarkdown(member.user.tag)})`); + + const chunkedRoleMembers = this.client.util.chunk(roleMembers, 30); + const embedPages = chunkedRoleMembers.map( + (chunk) => + new MessageEmbed({ + title: `${args.role.name}'s Members`, + description: chunk.join('\n'), + color: this.client.util.colors.default + }) + ); + return await this.client.util.buttonPaginate(message, embedPages, null, true); + } +} |