Add trade command #172
4 changed files with 307 additions and 1 deletions
174
src/buttonEvents/Trade.ts
Normal file
174
src/buttonEvents/Trade.ts
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
import { ButtonInteraction, EmbedBuilder } from "discord.js";
|
||||||
|
import { ButtonEvent } from "../type/buttonEvent";
|
||||||
|
import { CoreClient } from "../client/client";
|
||||||
|
import Inventory from "../database/entities/app/Inventory";
|
||||||
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
|
|
||||||
|
export default class Trade extends ButtonEvent {
|
||||||
|
public override async execute(interaction: ButtonInteraction) {
|
||||||
|
const action = interaction.customId.split(" ")[1];
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case "accept":
|
||||||
|
await this.AcceptTrade(interaction);
|
||||||
|
break;
|
||||||
|
case "decline":
|
||||||
|
await this.DeclineTrade(interaction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async AcceptTrade(interaction: ButtonInteraction) {
|
||||||
|
const giveUserId = interaction.customId.split(" ")[2];
|
||||||
|
const receiveUserId = interaction.customId.split(" ")[3];
|
||||||
|
const giveCardNumber = interaction.customId.split(" ")[4];
|
||||||
|
const receiveCardNumber = interaction.customId.split(" ")[5];
|
||||||
|
const expiry = interaction.customId.split(" ")[6];
|
||||||
|
const timeoutId = interaction.customId.split(" ")[7];
|
||||||
|
|
||||||
|
const expiryDate = new Date(expiry);
|
||||||
|
|
||||||
|
if (expiryDate < new Date()) {
|
||||||
|
await interaction.reply("Trade has expired");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.user.id !== receiveUserId) {
|
||||||
|
await interaction.reply("You are not the user who the trade is intended for");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === giveCardNumber);
|
||||||
|
|
||||||
|
const receiveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveItem || !receiveItem) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveUser = interaction.client.users.cache.get(giveUserId) || await interaction.client.users.fetch(giveUserId);
|
||||||
|
const receiveUser = interaction.client.users.cache.get(receiveUserId) || await interaction.client.users.fetch(receiveUserId);
|
||||||
|
|
||||||
|
const giveUserInventory1 = await Inventory.FetchOneByCardNumberAndUserId(giveUserId, giveCardNumber);
|
||||||
|
const receiveUserInventory1 = await Inventory.FetchOneByCardNumberAndUserId(receiveUserId, receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveUserInventory1 || !receiveUserInventory1) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (giveUserInventory1.Quantity < 1 || receiveUserInventory1.Quantity < 1) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
giveUserInventory1.SetQuantity(giveUserInventory1.Quantity - 1);
|
||||||
|
receiveUserInventory1.SetQuantity(receiveUserInventory1.Quantity - 1);
|
||||||
|
|
||||||
|
await giveUserInventory1.Save(Inventory, giveUserInventory1);
|
||||||
|
await receiveUserInventory1.Save(Inventory, receiveUserInventory1);
|
||||||
|
|
||||||
|
let giveUserInventory2 = await Inventory.FetchOneByCardNumberAndUserId(receiveUserId, giveCardNumber);
|
||||||
|
let receiveUserInventory2 = await Inventory.FetchOneByCardNumberAndUserId(giveUserId, receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveUserInventory2) {
|
||||||
|
giveUserInventory2 = new Inventory(receiveUserId, giveCardNumber, 1);
|
||||||
|
} else {
|
||||||
|
giveUserInventory2.SetQuantity(giveUserInventory2.Quantity + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!receiveUserInventory2) {
|
||||||
|
receiveUserInventory2 = new Inventory(giveUserId, receiveCardNumber, 1);
|
||||||
|
} else {
|
||||||
|
receiveUserInventory2.SetQuantity(receiveUserInventory2.Quantity + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
await giveUserInventory2.Save(Inventory, giveUserInventory2);
|
||||||
|
await receiveUserInventory2.Save(Inventory, receiveUserInventory2);
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("Trade Accepted")
|
||||||
|
.setDescription(`Trade initiated between ${receiveUser.username} and ${giveUser.username}`)
|
||||||
|
.setColor(EmbedColours.Success)
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: `${receiveUser.username} is giving`,
|
||||||
|
value: `${giveItem.id}: ${giveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `${giveUser.username} is giving`,
|
||||||
|
value: `${receiveItem.id}: ${receiveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Complete",
|
||||||
|
value: new Date().toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.update({ embeds: [ tradeEmbed ]});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async DeclineTrade(interaction: ButtonInteraction) {
|
||||||
|
const giveUserId = interaction.customId.split(" ")[2];
|
||||||
|
const receiveUserId = interaction.customId.split(" ")[3];
|
||||||
|
const giveCardNumber = interaction.customId.split(" ")[4];
|
||||||
|
const receiveCardNumber = interaction.customId.split(" ")[5];
|
||||||
|
// No need to get expiry date
|
||||||
|
const timeoutId = interaction.customId.split(" ")[7];
|
||||||
|
|
||||||
|
if (interaction.user.id !== receiveUserId || interaction.user.id !== giveUserId) {
|
||||||
|
await interaction.reply("You are not the user who the trade is intended for");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveUser = interaction.client.users.cache.get(giveUserId) || await interaction.client.users.fetch(giveUserId);
|
||||||
|
const receiveUser = interaction.client.users.cache.get(receiveUserId) || await interaction.client.users.fetch(receiveUserId);
|
||||||
|
|
||||||
|
const giveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === giveCardNumber);
|
||||||
|
|
||||||
|
const receiveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === receiveCardNumber);
|
||||||
|
|
||||||
|
if (!giveItem || !receiveItem) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("Trade Declined")
|
||||||
|
.setDescription(`Trade initiated between ${receiveUser.username} and ${giveUser.username}`)
|
||||||
|
.setColor(EmbedColours.Error)
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: `${receiveUser.username} is giving`,
|
||||||
|
value: `${giveItem.id}: ${giveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `${giveUser.username} is giving`,
|
||||||
|
value: `${receiveItem.id}: ${receiveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Declined",
|
||||||
|
value: new Date().toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.update({ embeds: [ tradeEmbed ]});
|
||||||
|
}
|
||||||
|
}
|
127
src/commands/trade.ts
Normal file
127
src/commands/trade.ts
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
import { ActionRowBuilder, ButtonBuilder, ButtonStyle, CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
|
||||||
|
import { Command } from "../type/command";
|
||||||
|
import Inventory from "../database/entities/app/Inventory";
|
||||||
|
import { CoreClient } from "../client/client";
|
||||||
|
import EmbedColours from "../constants/EmbedColours";
|
||||||
|
|
||||||
|
export default class Trade extends Command {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.CommandBuilder = new SlashCommandBuilder()
|
||||||
|
.setName("trade")
|
||||||
|
.setDescription("Initiate a trade with another user.")
|
||||||
|
.addUserOption(x =>
|
||||||
|
x
|
||||||
|
.setName("user")
|
||||||
|
.setDescription("User to trade with")
|
||||||
|
.setRequired(true))
|
||||||
|
.addStringOption(x =>
|
||||||
|
x
|
||||||
|
.setName("give")
|
||||||
|
.setDescription("Item to give")
|
||||||
|
.setRequired(true))
|
||||||
|
.addStringOption(x =>
|
||||||
|
x
|
||||||
|
.setName("receive")
|
||||||
|
.setDescription("Item to receive")
|
||||||
|
.setRequired(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async execute(interaction: CommandInteraction) {
|
||||||
|
const user = interaction.options.getUser("user")!;
|
||||||
|
const give = interaction.options.get("give")!;
|
||||||
|
const receive = interaction.options.get("receive")!;
|
||||||
|
|
||||||
|
const giveItemEntity = await Inventory.FetchOneByCardNumberAndUserId(interaction.user.id, give.value!.toString());
|
||||||
|
const receiveItemEntity = await Inventory.FetchOneByCardNumberAndUserId(user.id, receive.value!.toString());
|
||||||
|
|
||||||
|
if (!giveItemEntity) {
|
||||||
|
await interaction.reply("You do not have the item you are trying to trade.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!receiveItemEntity) {
|
||||||
|
await interaction.reply("The user you are trying to trade with does not have the item you are trying to trade for.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const giveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === give.value!.toString());
|
||||||
|
|
||||||
|
const receiveItem = CoreClient.Cards
|
||||||
|
.flatMap(x => x.cards)
|
||||||
|
.find(x => x.id === receive.value!.toString());
|
||||||
|
|
||||||
|
if (!giveItem || !receiveItem) {
|
||||||
|
await interaction.reply("One or more of the items you are trying to trade does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
const expiry = now.setMinutes(now.getMinutes() + 15);
|
||||||
|
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("Trade Offer")
|
||||||
|
.setDescription(`Trade initiated between ${interaction.user.username} and ${user.username}`)
|
||||||
|
.setColor(EmbedColours.Grey)
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: `${interaction.user.username} is giving`,
|
||||||
|
value: `${giveItem.id}: ${giveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `${user.username} is giving`,
|
||||||
|
value: `${receiveItem.id}: ${receiveItem.name}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Expires",
|
||||||
|
value: new Date(expiry).toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
const timeoutId = setTimeout(async () => this.autoDecline(interaction, interaction.user.username, user.username, giveItem.id, receiveItem.id, giveItem.name, receiveItem.name), 1000 * 60 * 15); // 15 minutes
|
||||||
|
|
||||||
|
const row = new ActionRowBuilder<ButtonBuilder>()
|
||||||
|
.addComponents([
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`trade accept ${interaction.user.id} ${user.id} ${giveItem.id} ${receiveItem.id} ${expiry} ${timeoutId}`)
|
||||||
|
.setLabel("Accept")
|
||||||
|
.setStyle(ButtonStyle.Success),
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`trade decline ${interaction.user.id} ${user.id} ${giveItem.id} ${receiveItem.id} ${expiry} ${timeoutId}`)
|
||||||
|
.setLabel("Decline")
|
||||||
|
.setStyle(ButtonStyle.Danger),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.reply({ content: `${user}`, embeds: [ tradeEmbed ], components: [ row ] });
|
||||||
|
}
|
||||||
|
|
||||||
|
private async autoDecline(interaction: CommandInteraction, giveUsername: string, receiveUsername: string, giveCardNumber: string, receiveCardNumber: string, giveCardName: string, receiveCardName: string) {
|
||||||
|
const tradeEmbed = new EmbedBuilder()
|
||||||
|
.setTitle("Trade Expired")
|
||||||
|
.setDescription(`Trade initiated between ${receiveUsername} and ${giveUsername}`)
|
||||||
|
.setColor(EmbedColours.Error)
|
||||||
|
.addFields([
|
||||||
|
{
|
||||||
|
name: `${receiveUsername} is giving`,
|
||||||
|
value: `${giveCardNumber}: ${giveCardName}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: `${giveUsername} is giving`,
|
||||||
|
value: `${receiveCardNumber}: ${receiveCardName}`,
|
||||||
|
inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Expired",
|
||||||
|
value: new Date().toLocaleString(),
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [ tradeEmbed ]});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
export default class EmbedColours {
|
export default class EmbedColours {
|
||||||
public static readonly Ok = 0x3050ba;
|
public static readonly Ok = 0x3050ba;
|
||||||
|
public static readonly Success = 0x50c878;
|
||||||
public static readonly Error = 0xff0000;
|
public static readonly Error = 0xff0000;
|
||||||
public static readonly Grey = 0xd3d3d3;
|
public static readonly Grey = 0xd3d3d3;
|
||||||
public static readonly BronzeCard = 0xcd7f32;
|
public static readonly BronzeCard = 0xcd7f32;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import Gdrivesync from "./commands/gdrivesync";
|
||||||
import Give from "./commands/give";
|
import Give from "./commands/give";
|
||||||
import Inventory from "./commands/inventory";
|
import Inventory from "./commands/inventory";
|
||||||
import Resync from "./commands/resync";
|
import Resync from "./commands/resync";
|
||||||
|
import Trade from "./commands/trade";
|
||||||
import View from "./commands/view";
|
import View from "./commands/view";
|
||||||
|
|
||||||
// Test Command Imports
|
// Test Command Imports
|
||||||
|
@ -18,6 +19,7 @@ import Droprarity from "./commands/stage/droprarity";
|
||||||
import Claim from "./buttonEvents/Claim";
|
import Claim from "./buttonEvents/Claim";
|
||||||
import InventoryButtonEvent from "./buttonEvents/Inventory";
|
import InventoryButtonEvent from "./buttonEvents/Inventory";
|
||||||
import Reroll from "./buttonEvents/Reroll";
|
import Reroll from "./buttonEvents/Reroll";
|
||||||
|
import TradeButtonEvent from "./buttonEvents/Trade";
|
||||||
|
|
||||||
export default class Registry {
|
export default class Registry {
|
||||||
public static RegisterCommands() {
|
public static RegisterCommands() {
|
||||||
|
@ -28,6 +30,7 @@ export default class Registry {
|
||||||
CoreClient.RegisterCommand("give", new Give());
|
CoreClient.RegisterCommand("give", new Give());
|
||||||
CoreClient.RegisterCommand("inventory", new Inventory());
|
CoreClient.RegisterCommand("inventory", new Inventory());
|
||||||
CoreClient.RegisterCommand("resync", new Resync());
|
CoreClient.RegisterCommand("resync", new Resync());
|
||||||
|
CoreClient.RegisterCommand("trade", new Trade());
|
||||||
CoreClient.RegisterCommand("view", new View());
|
CoreClient.RegisterCommand("view", new View());
|
||||||
|
|
||||||
// Test Commands
|
// Test Commands
|
||||||
|
@ -41,7 +44,8 @@ export default class Registry {
|
||||||
|
|
||||||
public static RegisterButtonEvents() {
|
public static RegisterButtonEvents() {
|
||||||
CoreClient.RegisterButtonEvent("claim", new Claim());
|
CoreClient.RegisterButtonEvent("claim", new Claim());
|
||||||
CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent);
|
CoreClient.RegisterButtonEvent("inventory", new InventoryButtonEvent());
|
||||||
CoreClient.RegisterButtonEvent("reroll", new Reroll());
|
CoreClient.RegisterButtonEvent("reroll", new Reroll());
|
||||||
|
CoreClient.RegisterButtonEvent("trade", new TradeButtonEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue