Add drop and pull cooldowns
This commit is contained in:
31
commands/cooldowns.js
Normal file
31
commands/cooldowns.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
const { SlashCommandBuilder } = require("discord.js");
|
||||||
|
const { Card, User, Character } = require("../models");
|
||||||
|
const { UserUtils } = require("../util");
|
||||||
|
|
||||||
|
//fetch all cards owned by the user and list them
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("cooldowns")
|
||||||
|
.setDescription("List cooldowns"),
|
||||||
|
async execute(interaction) {
|
||||||
|
//fetch the user given the userID and include his cards
|
||||||
|
const user = await UserUtils.getUserByDiscordId(interaction.member.id);
|
||||||
|
|
||||||
|
//get user cooldowns using user utils
|
||||||
|
const cooldowns = await UserUtils.getCooldowns(user);
|
||||||
|
|
||||||
|
let reply = "Cooldowns:\n";
|
||||||
|
for (cooldown in cooldowns) {
|
||||||
|
//if cooldown contains the string formatted
|
||||||
|
if (cooldown.includes("Formatted")) {
|
||||||
|
reply += `${cooldowns[cooldown]}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interaction.reply({
|
||||||
|
content: reply,
|
||||||
|
ephemeral: false
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
const { SlashCommandBuilder, ComponentType, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
|
const { SlashCommandBuilder, ComponentType, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require("discord.js");
|
||||||
const { customAlphabet } = require("nanoid");
|
const { customAlphabet } = require("nanoid");
|
||||||
const { Card, User, Character } = require("../models");
|
const { Card, User } = require("../models");
|
||||||
const Util = require("../util/cards");
|
const { UserUtils, CardUtils, GeneralUtils } = require("../util");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
@@ -15,8 +15,8 @@ module.exports = {
|
|||||||
),
|
),
|
||||||
|
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
const identifier = Util.generateIdentifier();
|
const identifier = CardUtils.generateIdentifier();
|
||||||
|
let user = await UserUtils.getUserByDiscordId(interaction.member.id);
|
||||||
switch (interaction.options.getString("feature")) {
|
switch (interaction.options.getString("feature")) {
|
||||||
case "ping":
|
case "ping":
|
||||||
interaction.reply({
|
interaction.reply({
|
||||||
@@ -45,6 +45,31 @@ module.exports = {
|
|||||||
content: `Cleared ${cards.length} cards`,
|
content: `Cleared ${cards.length} cards`,
|
||||||
ephemeral: false
|
ephemeral: false
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
|
case "cooldowns":
|
||||||
|
const timeouts = await UserUtils.getCooldowns(user);
|
||||||
|
console.log(`UserTimeouts: ${JSON.stringify(timeouts)}`);
|
||||||
|
let timeoutInMinutes = 0;
|
||||||
|
interaction.reply({
|
||||||
|
content: `\`\`\`${JSON.stringify(timeouts, null, 2)}\`\`\` `,
|
||||||
|
ephemeral: false
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "bot":
|
||||||
|
let botProperties = await GeneralUtils.getBotProperty(null);
|
||||||
|
interaction.reply({
|
||||||
|
content: `\`\`\`${JSON.stringify(botProperties, null, 2)}\`\`\` `,
|
||||||
|
ephemeral: false
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "reset_cd":
|
||||||
|
await UserUtils.setCooldown(user, "pull", 1);
|
||||||
|
await UserUtils.setCooldown(user, "drop", 1);
|
||||||
|
await UserUtils.setCooldown(user, "daily", 1);
|
||||||
|
interaction.reply({
|
||||||
|
content: `Reset cooldowns`,
|
||||||
|
ephemeral: false
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } = require("discord.js");
|
const { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, ComponentType } = require("discord.js");
|
||||||
const { Card, User, Character } = require("../models");
|
const { Card, User, Character } = require("../models");
|
||||||
const { customAlphabet } = require("nanoid");
|
const { customAlphabet } = require("nanoid");
|
||||||
const { CardUtils, UserUtils, ReplyUtils } = require("../util");
|
const { CardUtils, UserUtils, ReplyUtils, GeneralUtils } = require("../util");
|
||||||
const card = require("../models/card");
|
const card = require("../models/card");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@@ -10,11 +10,16 @@ module.exports = {
|
|||||||
.setDescription("Drop a card"),
|
.setDescription("Drop a card"),
|
||||||
|
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
const user = await User.findOne({
|
const user = await UserUtils.getUserByDiscordId(interaction.member.id);
|
||||||
where: {
|
|
||||||
discordId: interaction.member.id
|
const cooldowns = await UserUtils.getCooldowns(user);
|
||||||
}
|
if (cooldowns.dropCooldown > 0) {
|
||||||
});
|
interaction.reply({
|
||||||
|
content: `You can't drop cards for another ${cooldowns.dropCooldown} milliseconds`,
|
||||||
|
ephemeral: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Generate 3 cards, each is persisted with an initial userId of NULL
|
//Generate 3 cards, each is persisted with an initial userId of NULL
|
||||||
const cards = [];
|
const cards = [];
|
||||||
@@ -55,6 +60,8 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const message = await interaction.reply({ content: reply, components: [row], fetchReply: true });
|
const message = await interaction.reply({ content: reply, components: [row], fetchReply: true });
|
||||||
|
//set users drop cooldown
|
||||||
|
await UserUtils.setCooldown(user, "drop", await GeneralUtils.getBotProperty("dropTimeout"));
|
||||||
|
|
||||||
const filter = m => m.author.id === interaction.user.id;
|
const filter = m => m.author.id === interaction.user.id;
|
||||||
const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button, time: 15000 });
|
const collector = message.createMessageComponentCollector({ componentType: ComponentType.Button, time: 15000 });
|
||||||
@@ -64,10 +71,21 @@ module.exports = {
|
|||||||
if (await cards[cardId].userId) { i.reply({ content: "This card has already been claimed!", ephemeral: true }); return; }
|
if (await cards[cardId].userId) { i.reply({ content: "This card has already been claimed!", ephemeral: true }); return; }
|
||||||
|
|
||||||
let claimUser = await UserUtils.getUserByDiscordId(i.user.id);
|
let claimUser = await UserUtils.getUserByDiscordId(i.user.id);
|
||||||
|
const cooldowns = await UserUtils.getCooldowns(user);
|
||||||
|
if (cooldowns.pullCooldown > 0) {
|
||||||
|
i.reply({
|
||||||
|
content: `You can't claim cards for another ${cooldowns.dropCooldown} milliseconds`,
|
||||||
|
ephemeral: false
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (claimUser) {
|
if (claimUser) {
|
||||||
//Update card with the user id
|
//Update card with the user id
|
||||||
cards[cardId].userId = claimUser.id;
|
cards[cardId].userId = claimUser.id;
|
||||||
|
await UserUtils.setCooldown(user, "pull", await GeneralUtils.getBotProperty("pullTimeout"));
|
||||||
await cards[cardId].save();
|
await cards[cardId].save();
|
||||||
|
|
||||||
//fetch character name from database given the character id
|
//fetch character name from database given the character id
|
||||||
let character = await Character.findOne({
|
let character = await Character.findOne({
|
||||||
attributes: ["name"],
|
attributes: ["name"],
|
||||||
@@ -87,7 +105,7 @@ module.exports = {
|
|||||||
|
|
||||||
collector.on('end', collected => {
|
collector.on('end', collected => {
|
||||||
console.log(`Collected ${collected.size} interactions.`);
|
console.log(`Collected ${collected.size} interactions.`);
|
||||||
message.interaction.editReply({ components: [], deferred: true });
|
message.edit({ components: [] });
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ services:
|
|||||||
image: node:16.9.0-alpine
|
image: node:16.9.0-alpine
|
||||||
command: sh -c "npm install && node ."
|
command: sh -c "npm install && node ."
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Berlin
|
||||||
depends_on:
|
depends_on:
|
||||||
- "mysql"
|
- "mysql"
|
||||||
working_dir: /app
|
working_dir: /app
|
||||||
@@ -18,11 +20,11 @@ services:
|
|||||||
- bandbot-db:/var/lib/mysql
|
- bandbot-db:/var/lib/mysql
|
||||||
- ./db:/tmp/db
|
- ./db:/tmp/db
|
||||||
environment:
|
environment:
|
||||||
MYSQL_ROOT_PASSWORD: ${DB_ROOTPW}
|
- TZ=Europe/Berlin
|
||||||
MYSQL_DATABASE: ${DB_DATABASE}
|
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
|
||||||
MYSQL_USER: ${DB_USERNAME}
|
- MYSQL_DATABASE=${DB_DATABASE}
|
||||||
MYSQL_PASSWORD: ${DB_PASSWORD}
|
- MYSQL_USER=${DB_USERNAME}
|
||||||
|
- MYSQL_PASSWORD=${DB_PASSWORD}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
bandbot-db:
|
bandbot-db:
|
||||||
@@ -12,7 +12,7 @@ module.exports = {
|
|||||||
async down (queryInterface, Sequelize) {
|
async down (queryInterface, Sequelize) {
|
||||||
await queryInterface.changeColumn('Cards', 'userId', {
|
await queryInterface.changeColumn('Cards', 'userId', {
|
||||||
type: Sequelize.INTEGER,
|
type: Sequelize.INTEGER,
|
||||||
allowNull: false
|
defaultValue: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
39
migrations/20220819073326-add-cooldown-fields-to-user.js
Normal file
39
migrations/20220819073326-add-cooldown-fields-to-user.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
async up (queryInterface, Sequelize) {
|
||||||
|
await queryInterface.addColumn('Users', 'nextDrop', {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
|
||||||
|
});
|
||||||
|
await queryInterface.addColumn('Users', 'nextPull', {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
|
||||||
|
});
|
||||||
|
await queryInterface.addColumn('Users', 'nextDaily', {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: Sequelize.literal('CURRENT_TIMESTAMP')
|
||||||
|
});
|
||||||
|
await queryInterface.addColumn('Bots', 'pullTimeout', {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: 300000 // 5 minutes
|
||||||
|
});
|
||||||
|
await queryInterface.addColumn('Bots', 'dropTimeout', {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: 900000 // 15 minutes
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async down (queryInterface, Sequelize) {
|
||||||
|
await queryInterface.removeColumn('Users', 'nextDrop');
|
||||||
|
await queryInterface.removeColumn('Users', 'nextPull');
|
||||||
|
await queryInterface.removeColumn('Users', 'nextDaily');
|
||||||
|
await queryInterface.removeColumn('Bots', 'pullTimeout');
|
||||||
|
await queryInterface.removeColumn('Bots', 'dropTimeout');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -17,7 +17,10 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
User.init({
|
User.init({
|
||||||
discordId: DataTypes.BIGINT,
|
discordId: DataTypes.BIGINT,
|
||||||
active: DataTypes.INTEGER,
|
active: DataTypes.INTEGER,
|
||||||
privacy: DataTypes.INTEGER
|
privacy: DataTypes.INTEGER,
|
||||||
|
nextDrop: DataTypes.DATE,
|
||||||
|
nextPull: DataTypes.DATE,
|
||||||
|
nextDaily: DataTypes.DATE
|
||||||
}, {
|
}, {
|
||||||
sequelize,
|
sequelize,
|
||||||
modelName: 'User',
|
modelName: 'User',
|
||||||
|
|||||||
@@ -15,14 +15,55 @@ module.exports = {
|
|||||||
if (user) {
|
if (user) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!interaction.isButton() && interaction.commandName === "register") {
|
if (!interaction.isButton() && interaction.commandName === "register") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.reply({
|
interaction.reply({
|
||||||
content: `${interaction.member} You are not registered, use the /register command`,
|
content: `${interaction.member} You are not registered, use the /register command`,
|
||||||
ephemeral: false
|
ephemeral: false
|
||||||
});
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
getCooldowns: async function(user) {
|
||||||
|
/* Returns an object with the following properties:
|
||||||
|
* now: the current time in milliseconds
|
||||||
|
--- For each key in cooldownKeys ---
|
||||||
|
* nextPullTimestamp: the next time the user can pull a card in milliseconds
|
||||||
|
* pullCooldown: time in milliseconds until the user can pull again
|
||||||
|
* pullCooldownFormatted: print friendly version of pullCooldown in hours and minutes
|
||||||
|
*/
|
||||||
|
|
||||||
|
const cooldownKeys = ["Pull", "Drop", "Daily"]
|
||||||
|
|
||||||
|
let reply = {
|
||||||
|
now: new Date().getTime()
|
||||||
|
};
|
||||||
|
|
||||||
|
for (key of cooldownKeys) {
|
||||||
|
reply[`next${key}Timestamp`] = user[`next${key}`].getTime();
|
||||||
|
let cooldown = Math.max(reply[`next${key}Timestamp`] - reply['now'], 0);
|
||||||
|
reply[`${key.toLowerCase()}Cooldown`] = cooldown;
|
||||||
|
if (cooldown > 0) {
|
||||||
|
reply[`${key.toLowerCase()}CooldownFormatted`] = `Next ${key} in ${Math.floor(cooldown / 3600000)} hours ` +
|
||||||
|
`and ${Math.floor((cooldown % 3600000) / 60000)} minutes`;
|
||||||
|
} else {
|
||||||
|
reply[`${key.toLowerCase()}CooldownFormatted`] = `${key} Ready!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
},
|
||||||
|
|
||||||
|
setCooldown: async function(user, cooldownType, cooldown) {
|
||||||
|
/* cooldownType: "pull", "drop", "daily"
|
||||||
|
* cooldown: time in milliseconds
|
||||||
|
*/
|
||||||
|
let newCooldown = new Date(new Date().getTime() + cooldown);
|
||||||
|
user[`next${cooldownType[0].toUpperCase() + cooldownType.slice(1)}`] = newCooldown;
|
||||||
|
await user.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user