From d85e5a1eb231bd6076dbb786afd4f94f1b978d8e Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 3 Sep 2023 17:34:03 +0100 Subject: [PATCH 1/4] Add card setup function to bot setup --- .../{CardSetupFunctions.ts => CardSetupFunction.ts} | 2 +- src/client/client.ts | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) rename src/Functions/{CardSetupFunctions.ts => CardSetupFunction.ts} (98%) diff --git a/src/Functions/CardSetupFunctions.ts b/src/Functions/CardSetupFunction.ts similarity index 98% rename from src/Functions/CardSetupFunctions.ts rename to src/Functions/CardSetupFunction.ts index 8e7fbf4..9d0218a 100644 --- a/src/Functions/CardSetupFunctions.ts +++ b/src/Functions/CardSetupFunction.ts @@ -5,7 +5,7 @@ import Series from "../database/entities/card/Series"; import path from "path"; import { CardRarity } from "../constants/CardRarity"; -export default class CardSetupFunctions { +export default class CardSetupFunction { public async Execute() { await this.ClearDatabase(); await this.ReadSeries(); diff --git a/src/client/client.ts b/src/client/client.ts index a928d3b..9404eac 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -7,7 +7,8 @@ import { Command } from "../type/command"; import { Events } from "./events"; import { Util } from "./util"; -import AppDataSource from "../database/dataSources/appDataSource"; +import CardSetupFunction from "../Functions/CardSetupFunction"; +import CardDataSource from "../database/dataSources/cardDataSource"; export class CoreClient extends Client { private static _commandItems: ICommandItem[]; @@ -15,6 +16,7 @@ export class CoreClient extends Client { private _events: Events; private _util: Util; + private _cardSetupFunc: CardSetupFunction; public static get commandItems(): ICommandItem[] { return this._commandItems; @@ -33,6 +35,7 @@ export class CoreClient extends Client { this._events = new Events(); this._util = new Util(); + this._cardSetupFunc = new CardSetupFunction(); } public async start() { @@ -41,13 +44,15 @@ export class CoreClient extends Client { return; } - await AppDataSource.initialize() - .then(() => console.log("Data Source Initialized")) - .catch((err) => console.error("Error Initialising Data Source", err)); + await CardDataSource.initialize() + .then(() => console.log("Card Data Source Initialised")) + .catch(err => console.error("Error initialising Card Data Source", err)); super.on("interactionCreate", this._events.onInteractionCreate); super.on("ready", this._events.onReady); + await this._cardSetupFunc.Execute(); + await super.login(process.env.BOT_TOKEN); this._util.loadEvents(this, CoreClient._eventItems); -- 2.43.4 From 1887470e2f0d86b6d7f0cb607e8a3b351c9e1fa2 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 3 Sep 2023 18:59:53 +0100 Subject: [PATCH 2/4] Add basic drop functionality --- .dev.env | 2 +- .stage.env | 2 +- src/Functions/CardSetupFunction.ts | 10 ++++---- src/client/client.ts | 1 + src/commands/drop.ts | 35 +++++++++++++++++++++++++ src/constants/CardRarity.ts | 28 ++++++++++++++++++++ src/constants/EmbedColours.ts | 4 +++ src/database/entities/card/Card.ts | 20 ++++++--------- src/database/entities/card/Series.ts | 10 ++------ src/helpers/CardDropHelper.ts | 38 ++++++++++++++++++++++++++++ src/registry.ts | 2 ++ 11 files changed, 125 insertions(+), 27 deletions(-) create mode 100644 src/commands/drop.ts create mode 100644 src/helpers/CardDropHelper.ts diff --git a/.dev.env b/.dev.env index 1e90070..0089c5e 100644 --- a/.dev.env +++ b/.dev.env @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.1.0 +BOT_VER=0.1.0 DEV BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=682942374040961060 diff --git a/.stage.env b/.stage.env index 389c429..19590a2 100644 --- a/.stage.env +++ b/.stage.env @@ -7,7 +7,7 @@ # any secret values. BOT_TOKEN= -BOT_VER=0.1.0 +BOT_VER=0.1.0 BETA BOT_AUTHOR=Vylpes BOT_OWNERID=147392775707426816 BOT_CLIENTID=1016767908740857949 diff --git a/src/Functions/CardSetupFunction.ts b/src/Functions/CardSetupFunction.ts index 9d0218a..a9098ec 100644 --- a/src/Functions/CardSetupFunction.ts +++ b/src/Functions/CardSetupFunction.ts @@ -42,7 +42,7 @@ export default class CardSetupFunction { } private async ReadCards() { - const loadedSeries = await Series.FetchAll(Series); + const loadedSeries = await Series.FetchAll(Series, [ "Cards", "Cards.Series" ]); const cardRepository = CardDataSource.getRepository(Card); @@ -65,7 +65,7 @@ export default class CardSetupFunction { const cardId = filePart[0]; const cardName = filePart[0]; - const card = new Card(cardId, cardName, CardRarity.Bronze); + const card = new Card(cardId, cardName, CardRarity.Bronze, path.join(path.join(process.cwd(), 'cards', series.Path, 'BRONZE', file)), series); cardsToSave.push(card); } @@ -76,7 +76,7 @@ export default class CardSetupFunction { const cardId = filePart[0]; const cardName = filePart[0]; - const card = new Card(cardId, cardName, CardRarity.Gold); + const card = new Card(cardId, cardName, CardRarity.Gold, path.join(path.join(process.cwd(), 'cards', series.Path, 'GOLD', file)), series); cardsToSave.push(card); } @@ -87,7 +87,7 @@ export default class CardSetupFunction { const cardId = filePart[0]; const cardName = filePart[0]; - const card = new Card(cardId, cardName, CardRarity.Legendary); + const card = new Card(cardId, cardName, CardRarity.Legendary, path.join(path.join(process.cwd(), 'cards', series.Path, 'LEGENDARY', file)), series); cardsToSave.push(card); } @@ -98,7 +98,7 @@ export default class CardSetupFunction { const cardId = filePart[0]; const cardName = filePart[0]; - const card = new Card(cardId, cardName, CardRarity.Silver); + const card = new Card(cardId, cardName, CardRarity.Silver, path.join(path.join(process.cwd(), 'cards', series.Path, 'SILVER', file)), series); cardsToSave.push(card); } diff --git a/src/client/client.ts b/src/client/client.ts index 9404eac..04f00d0 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -9,6 +9,7 @@ import { Events } from "./events"; import { Util } from "./util"; import CardSetupFunction from "../Functions/CardSetupFunction"; import CardDataSource from "../database/dataSources/cardDataSource"; +import CardDropHelper from "../helpers/CardDropHelper"; export class CoreClient extends Client { private static _commandItems: ICommandItem[]; diff --git a/src/commands/drop.ts b/src/commands/drop.ts new file mode 100644 index 0000000..2b95365 --- /dev/null +++ b/src/commands/drop.ts @@ -0,0 +1,35 @@ +import { AttachmentBuilder, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import { Command } from "../type/command"; +import CardDropHelper from "../helpers/CardDropHelper"; +import { CardRarityToColour, CardRarityToString } from "../constants/CardRarity"; +import { readFileSync } from "fs"; + +export default class Drop extends Command { + constructor() { + super(); + + super.CommandBuilder = new SlashCommandBuilder() + .setName('drop') + .setDescription('Summon a new card drop'); + } + + public override async execute(interaction: CommandInteraction) { + const randomCard = await CardDropHelper.GetRandomCard(); + + const image = readFileSync(randomCard.Path); + + const attachment = new AttachmentBuilder(image, { name: `${randomCard.Id}.png` }); + + const embed = new EmbedBuilder() + .setTitle(randomCard.Name) + .setDescription(randomCard.Series.Name) + .setFooter({ text: CardRarityToString(randomCard.Rarity) }) + .setColor(CardRarityToColour(randomCard.Rarity)) + .setImage(`attachment://${randomCard.Id}.png`); + + await interaction.reply({ + embeds: [ embed ], + files: [ attachment ], + }); + } +} \ No newline at end of file diff --git a/src/constants/CardRarity.ts b/src/constants/CardRarity.ts index 541ff36..92a5141 100644 --- a/src/constants/CardRarity.ts +++ b/src/constants/CardRarity.ts @@ -1,6 +1,34 @@ +import EmbedColours from "./EmbedColours"; + export enum CardRarity { Bronze, Silver, Gold, Legendary, +} + +export function CardRarityToString(rarity: CardRarity): string { + switch (rarity) { + case CardRarity.Bronze: + return "Bronze"; + case CardRarity.Silver: + return "Silver"; + case CardRarity.Gold: + return "Gold"; + case CardRarity.Legendary: + return "Legendary"; + } +} + +export function CardRarityToColour(rarity: CardRarity): number { + switch (rarity) { + case CardRarity.Bronze: + return EmbedColours.BronzeCard; + case CardRarity.Silver: + return EmbedColours.SilverCard; + case CardRarity.Gold: + return EmbedColours.GoldCard; + case CardRarity.Legendary: + return EmbedColours.LegendaryCard; + } } \ No newline at end of file diff --git a/src/constants/EmbedColours.ts b/src/constants/EmbedColours.ts index 023c77a..d889f5d 100644 --- a/src/constants/EmbedColours.ts +++ b/src/constants/EmbedColours.ts @@ -1,3 +1,7 @@ export default class EmbedColours { public static readonly Ok = 0x3050ba; + public static readonly BronzeCard = 0xcd7f32; + public static readonly SilverCard = 0xc0c0c0; + public static readonly GoldCard = 0xffd700; + public static readonly LegendaryCard = 0x50c878; } \ No newline at end of file diff --git a/src/database/entities/card/Card.ts b/src/database/entities/card/Card.ts index 0a368f9..f354fd6 100644 --- a/src/database/entities/card/Card.ts +++ b/src/database/entities/card/Card.ts @@ -1,17 +1,18 @@ -import { Column, Entity, OneToMany } from "typeorm"; +import { Column, Entity, ManyToOne } from "typeorm"; import CardBaseEntity from "../../../contracts/CardBaseEntity"; import { CardRarity } from "../../../constants/CardRarity"; import Series from "./Series"; -import CardDataSource from "../../dataSources/cardDataSource"; @Entity() export default class Card extends CardBaseEntity { - constructor(cardNumber: string, name: string, rarity: CardRarity) { + constructor(cardNumber: string, name: string, rarity: CardRarity, path: string, series: Series) { super(); this.CardNumber = cardNumber; this.Name = name; this.Rarity = rarity; + this.Path = path; + this.Series = series; } @Column() @@ -23,14 +24,9 @@ export default class Card extends CardBaseEntity { @Column() Rarity: CardRarity; - @OneToMany(() => Series, x => x.Cards) + @Column() + Path: string + + @ManyToOne(() => Series, x => x.Cards) Series: Series; - - public static async FetchAllByRarity(rarity: CardRarity): Promise { - const repository = CardDataSource.getRepository(Card); - - const all = await repository.find({ where: { Rarity: rarity }}); - - return all; - } } \ No newline at end of file diff --git a/src/database/entities/card/Series.ts b/src/database/entities/card/Series.ts index 5a8dca3..eb990cc 100644 --- a/src/database/entities/card/Series.ts +++ b/src/database/entities/card/Series.ts @@ -1,4 +1,4 @@ -import { Column, Entity, ManyToOne } from "typeorm"; +import { Column, Entity, OneToMany } from "typeorm"; import CardBaseEntity from "../../../contracts/CardBaseEntity"; import Card from "./Card"; @@ -18,12 +18,6 @@ export default class Series extends CardBaseEntity { @Column() Path: string; - @ManyToOne(() => Card, x => x.Series) + @OneToMany(() => Card, x => x.Series) Cards: Card[]; - - public async AddCard(card: Card) { - if (!this.Cards) return; - - this.Cards.push(card); - } } \ No newline at end of file diff --git a/src/helpers/CardDropHelper.ts b/src/helpers/CardDropHelper.ts new file mode 100644 index 0000000..9ab63ca --- /dev/null +++ b/src/helpers/CardDropHelper.ts @@ -0,0 +1,38 @@ +import { CardRarity } from "../constants/CardRarity"; +import CardDataSource from "../database/dataSources/cardDataSource"; +import Card from "../database/entities/card/Card"; +import Series from "../database/entities/card/Series"; + +export default class CardDropHelper { + public static async GetRandomCard(): Promise { + const seriesRepository = CardDataSource.getRepository(Series); + + const allSeries = await Series.FetchAll(Series, [ "Cards", "Cards.Series" ]); + const allSeriesWithCards = allSeries.filter(x => x.Cards.length > 0); + + const randomSeriesIndex = Math.floor(Math.random() * allSeriesWithCards.length); + + const randomSeries = allSeriesWithCards[randomSeriesIndex]; + + const randomRarity = Math.random() * 100; + + let cardRarity: CardRarity; + + const bronzeChance = 62; + const silverChance = bronzeChance + 31; + const goldChance = silverChance + 6.4; + + if (randomRarity < bronzeChance) cardRarity = CardRarity.Bronze; + else if (randomRarity < silverChance) cardRarity = CardRarity.Silver; + else if (randomRarity < goldChance) cardRarity = CardRarity.Gold; + else cardRarity = CardRarity.Legendary; + + const allCards = randomSeries.Cards.filter(x => x.Rarity == cardRarity); + + const randomCardIndex = Math.floor(Math.random() * allCards.length); + + const randomCard = allCards[randomCardIndex]; + + return randomCard; + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index 774015a..8514119 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -1,10 +1,12 @@ import { CoreClient } from "./client/client"; import About from "./commands/about"; +import Drop from "./commands/drop"; export default class Registry { public static RegisterCommands() { CoreClient.RegisterCommand('about', new About()); + CoreClient.RegisterCommand('drop', new Drop()); } public static RegisterEvents() { -- 2.43.4 From 08e99ee2d7dd60fa7587586544868192b20e8e75 Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 3 Sep 2023 19:54:16 +0100 Subject: [PATCH 3/4] Claim button --- src/bot.ts | 1 + src/buttonEvents/Claim.ts | 38 +++++++++++++++ src/client/client.ts | 24 ++++++++++ src/client/events.ts | 25 +++------- src/client/interactionCreate/Button.ts | 17 +++++++ .../interactionCreate/ChatInputCommand.ts | 27 +++++++++++ src/commands/drop.ts | 19 +++++++- src/contracts/IButtonEventItem.ts | 6 +++ src/database/entities/app/.gitkeep | 0 src/database/entities/app/Inventory.ts | 47 +++++++++++++++++++ src/registry.ts | 6 +++ src/type/buttonEvent.ts | 7 +++ 12 files changed, 197 insertions(+), 20 deletions(-) create mode 100644 src/buttonEvents/Claim.ts create mode 100644 src/client/interactionCreate/Button.ts create mode 100644 src/client/interactionCreate/ChatInputCommand.ts create mode 100644 src/contracts/IButtonEventItem.ts delete mode 100644 src/database/entities/app/.gitkeep create mode 100644 src/database/entities/app/Inventory.ts create mode 100644 src/type/buttonEvent.ts diff --git a/src/bot.ts b/src/bot.ts index baca574..e8c1dd3 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -32,5 +32,6 @@ const client = new CoreClient([ Registry.RegisterCommands(); Registry.RegisterEvents(); +Registry.RegisterButtonEvents(); client.start(); \ No newline at end of file diff --git a/src/buttonEvents/Claim.ts b/src/buttonEvents/Claim.ts new file mode 100644 index 0000000..5412db8 --- /dev/null +++ b/src/buttonEvents/Claim.ts @@ -0,0 +1,38 @@ +import { ButtonInteraction } from "discord.js"; +import { ButtonEvent } from "../type/buttonEvent"; +import Inventory from "../database/entities/app/Inventory"; +import { CoreClient } from "../client/client"; + +export default class Claim extends ButtonEvent { + public override async execute(interaction: ButtonInteraction) { + if (!interaction.guild || !interaction.guildId) return; + + const cardNumber = interaction.customId.split(' ')[1]; + const claimId = interaction.customId.split(' ')[2]; + const userId = interaction.user.id; + + const claimed = await Inventory.FetchOneByClaimId(claimId); + + if (claimed) { + await interaction.reply('This card has already been claimed'); + return; + } + + if (claimId != CoreClient.ClaimId) { + await interaction.reply('This card has expired'); + return; + } + + let inventory = await Inventory.FetchOneByCardNumberAndUserId(userId, cardNumber); + + if (!inventory) { + inventory = new Inventory(userId, cardNumber, 1, claimId); + } else { + inventory.SetQuantity(inventory.Quantity + 1); + } + + await inventory.Save(Inventory, inventory); + + await interaction.reply('Card claimed'); + } +} \ No newline at end of file diff --git a/src/client/client.ts b/src/client/client.ts index 04f00d0..b517a28 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -10,15 +10,21 @@ import { Util } from "./util"; import CardSetupFunction from "../Functions/CardSetupFunction"; import CardDataSource from "../database/dataSources/cardDataSource"; import CardDropHelper from "../helpers/CardDropHelper"; +import IButtonEventItem from "../contracts/IButtonEventItem"; +import { ButtonEvent } from "../type/buttonEvent"; +import AppDataSource from "../database/dataSources/appDataSource"; export class CoreClient extends Client { private static _commandItems: ICommandItem[]; private static _eventItems: IEventItem[]; + private static _buttonEvents: IButtonEventItem[]; private _events: Events; private _util: Util; private _cardSetupFunc: CardSetupFunction; + public static ClaimId: string; + public static get commandItems(): ICommandItem[] { return this._commandItems; } @@ -27,12 +33,17 @@ export class CoreClient extends Client { return this._eventItems; } + public static get buttonEvents(): IButtonEventItem[] { + return this._buttonEvents; + } + constructor(intents: number[]) { super({ intents: intents }); dotenv.config(); CoreClient._commandItems = []; CoreClient._eventItems = []; + CoreClient._buttonEvents = []; this._events = new Events(); this._util = new Util(); @@ -45,6 +56,10 @@ export class CoreClient extends Client { return; } + await AppDataSource.initialize() + .then(() => console.log("App Data Source Initialised")) + .catch(err => console.error("Error initialising App Data Source", err)); + await CardDataSource.initialize() .then(() => console.log("Card Data Source Initialised")) .catch(err => console.error("Error initialising Card Data Source", err)); @@ -78,4 +93,13 @@ export class CoreClient extends Client { CoreClient._eventItems.push(item); } + + public static RegisterButtonEvent(buttonId: string, event: ButtonEvent) { + const item: IButtonEventItem = { + ButtonId: buttonId, + Event: event, + }; + + CoreClient._buttonEvents.push(item); + } } diff --git a/src/client/events.ts b/src/client/events.ts index bfbe7ec..db6cfc4 100644 --- a/src/client/events.ts +++ b/src/client/events.ts @@ -1,29 +1,18 @@ import { Interaction } from "discord.js"; -import ICommandItem from "../contracts/ICommandItem"; -import { CoreClient } from "./client"; +import ChatInputCommand from "./interactionCreate/ChatInputCommand"; +import Button from "./interactionCreate/Button"; export class Events { public async onInteractionCreate(interaction: Interaction) { - if (!interaction.isChatInputCommand()) return; if (!interaction.guildId) return; - const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId); - const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId); - - let itemToUse: ICommandItem; - - if (!itemForServer) { - if (!item) { - await interaction.reply('Command not found'); - return; - } - - itemToUse = item; - } else { - itemToUse = itemForServer; + if (interaction.isChatInputCommand()) { + ChatInputCommand.onChatInput(interaction); } - itemToUse.Command.execute(interaction); + if (interaction.isButton()) { + Button.onButtonClicked(interaction); + } } // Emit when bot is logged in and ready to use diff --git a/src/client/interactionCreate/Button.ts b/src/client/interactionCreate/Button.ts new file mode 100644 index 0000000..165e426 --- /dev/null +++ b/src/client/interactionCreate/Button.ts @@ -0,0 +1,17 @@ +import { ButtonInteraction, Interaction } from "discord.js"; +import { CoreClient } from "../client"; + +export default class Button { + public static async onButtonClicked(interaction: ButtonInteraction) { + if (!interaction.isButton) return; + + const item = CoreClient.buttonEvents.find(x => x.ButtonId == interaction.customId.split(' ')[0]); + + if (!item) { + await interaction.reply('Event not found'); + return; + } + + item.Event.execute(interaction); + } +} \ No newline at end of file diff --git a/src/client/interactionCreate/ChatInputCommand.ts b/src/client/interactionCreate/ChatInputCommand.ts new file mode 100644 index 0000000..d483f1d --- /dev/null +++ b/src/client/interactionCreate/ChatInputCommand.ts @@ -0,0 +1,27 @@ +import { Interaction } from "discord.js"; +import { CoreClient } from "../client"; +import ICommandItem from "../../contracts/ICommandItem"; + +export default class ChatInputCommand { + public static async onChatInput(interaction: Interaction) { + if (!interaction.isChatInputCommand()) return; + + const item = CoreClient.commandItems.find(x => x.Name == interaction.commandName && !x.ServerId); + const itemForServer = CoreClient.commandItems.find(x => x.Name == interaction.commandName && x.ServerId == interaction.guildId); + + let itemToUse: ICommandItem; + + if (!itemForServer) { + if (!item) { + await interaction.reply('Command not found'); + return; + } + + itemToUse = item; + } else { + itemToUse = itemForServer; + } + + itemToUse.Command.execute(interaction); + } +} \ No newline at end of file diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 2b95365..9d24d46 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -1,8 +1,10 @@ -import { AttachmentBuilder, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; +import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"; import { Command } from "../type/command"; import CardDropHelper from "../helpers/CardDropHelper"; import { CardRarityToColour, CardRarityToString } from "../constants/CardRarity"; import { readFileSync } from "fs"; +import { CoreClient } from "../client/client"; +import { v4 } from "uuid"; export default class Drop extends Command { constructor() { @@ -27,9 +29,22 @@ export default class Drop extends Command { .setColor(CardRarityToColour(randomCard.Rarity)) .setImage(`attachment://${randomCard.Id}.png`); - await interaction.reply({ + const row = new ActionRowBuilder(); + + const claimId = v4(); + + row.addComponents( + new ButtonBuilder() + .setCustomId(`claim ${randomCard.CardNumber} ${claimId}`) + .setLabel("Claim") + .setStyle(ButtonStyle.Primary)); + + const message = await interaction.reply({ embeds: [ embed ], files: [ attachment ], + components: [ row ], }); + + CoreClient.ClaimId = claimId; } } \ No newline at end of file diff --git a/src/contracts/IButtonEventItem.ts b/src/contracts/IButtonEventItem.ts new file mode 100644 index 0000000..6be9f6e --- /dev/null +++ b/src/contracts/IButtonEventItem.ts @@ -0,0 +1,6 @@ +import { ButtonEvent } from "../type/buttonEvent"; + +export default interface IButtonEventItem { + ButtonId: string, + Event: ButtonEvent, +} \ No newline at end of file diff --git a/src/database/entities/app/.gitkeep b/src/database/entities/app/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/database/entities/app/Inventory.ts b/src/database/entities/app/Inventory.ts new file mode 100644 index 0000000..c6319a9 --- /dev/null +++ b/src/database/entities/app/Inventory.ts @@ -0,0 +1,47 @@ +import { Column, Entity } from "typeorm"; +import AppBaseEntity from "../../../contracts/AppBaseEntity"; +import AppDataSource from "../../dataSources/appDataSource"; + +@Entity() +export default class Inventory extends AppBaseEntity { + constructor(userId: string, cardNumber: string, quantity: number, claimId: string) { + super(); + + this.UserId = userId; + this.CardNumber = cardNumber; + this.Quantity = quantity; + this.ClaimId = claimId; + } + + @Column() + UserId: string; + + @Column() + CardNumber: string; + + @Column() + Quantity: number; + + @Column() + ClaimId: string; + + public SetQuantity(quantity: number) { + this.Quantity = quantity; + } + + public static async FetchOneByCardNumberAndUserId(userId: string, cardNumber: string): Promise { + const repository = AppDataSource.getRepository(Inventory); + + const single = await repository.findOne({ where: { UserId: userId, CardNumber: cardNumber }}); + + return single; + } + + public static async FetchOneByClaimId(claimId: string): Promise { + const repository = AppDataSource.getRepository(Inventory); + + const single = await repository.findOne({ where: { ClaimId: claimId }}); + + return single; + } +} \ No newline at end of file diff --git a/src/registry.ts b/src/registry.ts index 8514119..2cc953d 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -3,6 +3,8 @@ import { CoreClient } from "./client/client"; import About from "./commands/about"; import Drop from "./commands/drop"; +import Claim from "./buttonEvents/Claim"; + export default class Registry { public static RegisterCommands() { CoreClient.RegisterCommand('about', new About()); @@ -12,4 +14,8 @@ export default class Registry { public static RegisterEvents() { } + + public static RegisterButtonEvents() { + CoreClient.RegisterButtonEvent('claim', new Claim()); + } } \ No newline at end of file diff --git a/src/type/buttonEvent.ts b/src/type/buttonEvent.ts new file mode 100644 index 0000000..3a691cf --- /dev/null +++ b/src/type/buttonEvent.ts @@ -0,0 +1,7 @@ +import { ButtonInteraction } from "discord.js"; + +export class ButtonEvent { + public execute(interaction: ButtonInteraction) { + + } +} \ No newline at end of file -- 2.43.4 From 2809cc1014a0ac9031022f3b2672be1b1a4a66eb Mon Sep 17 00:00:00 2001 From: Ethan Lane Date: Sun, 3 Sep 2023 20:04:17 +0100 Subject: [PATCH 4/4] Add reroll button --- src/buttonEvents/Reroll.ts | 48 ++++++++++++++++++++++++++++++++++++++ src/commands/drop.ts | 8 +++++-- src/registry.ts | 2 ++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/buttonEvents/Reroll.ts diff --git a/src/buttonEvents/Reroll.ts b/src/buttonEvents/Reroll.ts new file mode 100644 index 0000000..f1c4bcc --- /dev/null +++ b/src/buttonEvents/Reroll.ts @@ -0,0 +1,48 @@ +import { ActionRowBuilder, AttachmentBuilder, ButtonBuilder, ButtonInteraction, ButtonStyle, CacheType, EmbedBuilder } from "discord.js"; +import { ButtonEvent } from "../type/buttonEvent"; +import CardDropHelper from "../helpers/CardDropHelper"; +import { readFileSync } from "fs"; +import { CardRarityToColour, CardRarityToString } from "../constants/CardRarity"; +import { v4 } from "uuid"; +import { CoreClient } from "../client/client"; + +export default class Reroll extends ButtonEvent { + public override async execute(interaction: ButtonInteraction) { + if (!interaction.guild || !interaction.guildId) return; + + const randomCard = await CardDropHelper.GetRandomCard(); + + const image = readFileSync(randomCard.Path); + + const attachment = new AttachmentBuilder(image, { name: `${randomCard.Id}.png` }); + + const embed = new EmbedBuilder() + .setTitle(randomCard.Name) + .setDescription(randomCard.Series.Name) + .setFooter({ text: CardRarityToString(randomCard.Rarity) }) + .setColor(CardRarityToColour(randomCard.Rarity)) + .setImage(`attachment://${randomCard.Id}.png`); + + const row = new ActionRowBuilder(); + + const claimId = v4(); + + row.addComponents( + new ButtonBuilder() + .setCustomId(`claim ${randomCard.CardNumber} ${claimId}`) + .setLabel("Claim") + .setStyle(ButtonStyle.Primary), + new ButtonBuilder() + .setCustomId(`reroll`) + .setLabel("Reroll") + .setStyle(ButtonStyle.Secondary)); + + await interaction.reply({ + embeds: [ embed ], + files: [ attachment ], + components: [ row ], + }); + + CoreClient.ClaimId = claimId; + } +} \ No newline at end of file diff --git a/src/commands/drop.ts b/src/commands/drop.ts index 9d24d46..861fb18 100644 --- a/src/commands/drop.ts +++ b/src/commands/drop.ts @@ -37,9 +37,13 @@ export default class Drop extends Command { new ButtonBuilder() .setCustomId(`claim ${randomCard.CardNumber} ${claimId}`) .setLabel("Claim") - .setStyle(ButtonStyle.Primary)); + .setStyle(ButtonStyle.Primary), + new ButtonBuilder() + .setCustomId(`reroll`) + .setLabel("Reroll") + .setStyle(ButtonStyle.Secondary)); - const message = await interaction.reply({ + await interaction.reply({ embeds: [ embed ], files: [ attachment ], components: [ row ], diff --git a/src/registry.ts b/src/registry.ts index 2cc953d..c517af3 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -4,6 +4,7 @@ import About from "./commands/about"; import Drop from "./commands/drop"; import Claim from "./buttonEvents/Claim"; +import Reroll from "./buttonEvents/Reroll"; export default class Registry { public static RegisterCommands() { @@ -17,5 +18,6 @@ export default class Registry { public static RegisterButtonEvents() { CoreClient.RegisterButtonEvent('claim', new Claim()); + CoreClient.RegisterButtonEvent('reroll', new Reroll()); } } \ No newline at end of file -- 2.43.4