【问题标题】:Time Counter Command Keep The whole time | Discord.js时间计数器命令保持整个时间|不和谐.js
【发布时间】:2021-03-30 06:52:42
【问题描述】:

我有这段代码可以保持命令 !start!end 之间的时间用于时间计数器命令,但我希望它发送类似于“您的时间是 14:23:02(小时、分钟、秒)和花费的全部时间是 27:24:32(小时、分钟、秒)"

这是我的代码:

/**
 * A map from user IDs to start timestamps
 * @type Map<string, number>
 */
const startTimestamps = new Map()

/**
 * Pads a number to 2 digits.
 * @param {number} value
 * @returns {string}
 */
const pad2Digits = value => String(value).padStart(2, '0')

bot.on('message', async message => {
  try {
    if (message.content === '!start') {
      // Sets the start time. This overrides any existing timers
      // Date.now() is equivalent to new Date().getTime()
      startTimestamps.set(message.author.id, Date.now())
      await message.reply('Timer started.')
    } else if (message.content === '!end') {
      if (startTimestamps.has(message.author.id)) {
        // The user has an existing timer to stop
        // Calculate the timer result
        const ms = Date.now() - startTimestamps.get(message.author.id)
        const totalSecs = Math.floor(ms / 1000)
        const totalMins = Math.floor(totalSecs / 60)
        const hrs = Math.floor(totalMins / 60)
        const mins = totalMins % 60
        const secs = totalSecs % 60
        // Reply with result
        await message.reply(`Your time: ${hrs}:${pad2Digits(mins)}:${pad2Digits(secs)}`)
        // Remove timestamp from map
        startTimestamps.delete(message.author.id)
      } else {
        // The user does not have an existing timer
        await message.reply('You need to use `!start` first!')
      }
    }
  } catch (error) {
    console.error(error)
  }
})

【问题讨论】:

  • 我不确定我是否能理解它。什么是“你的时间”和“花费的全部时间”?你想有一个总时间,所以当他们第二次启动和结束计时器时,他们可以看到这次花费的时间以及这一次和上一次的总和?
  • 我想在使用 !start 然后 !end 计算这些命令之间的时间,例如当我再做一次时,我想制作“!myname time”并显示所有时间我已经在那个命令中花费了

标签: javascript node.js discord discord.js


【解决方案1】:

如果您使用简单的地图来存储这些计时器,则每次重新启动机器人时都会丢失它们。您需要使用某种数据库(首选)或 JSON 文件。

如果我能正确理解,您希望显示上次会话花费的时间以及用户在不同会话中花费的总时间。您可以像这样存储开始和结束时间的数组:

/**
 * A map from user IDs to start timestamps
 * @type Map<string, number>
 */
const timestamps = new Map();

/**
 * Pads a number to 2 digits.
 * @param {number} value
 * @returns {string}
 */
const pad2Digits = (value) => String(value).padStart(2, '0');

/**
 * Counts the total number of milliseconds of timers.
 * @param {array} timers
 * @returns {number}
 */
const countTotalMs = (timers) =>
  timers.reduce((acc, curr) => (curr.end ? acc + curr.end - curr.start : acc), 0);

/**
 * Converts milliseconds to hours, minutes, and seconds
 * @param {number} ms
 * @returns {object}
 */
const getTime = (ms) => {
  const totalSecs = Math.floor(ms / 1000);
  const totalMins = Math.floor(totalSecs / 60);
  const hrs = Math.floor(totalMins / 60);
  const mins = totalMins % 60;
  const secs = totalSecs % 60;

  const formatted = `${hrs}:${pad2Digits(mins)}:${pad2Digits(secs)}`;

  return { formatted, hrs, mins, secs };
};

client.on('message', async (message) => {
  try {
    if (message.content === '!start') {
      const timers = timestamps.get(message.author.id) || [];
      const lastTimer = timers[timers.length - 1];

      // Check if the previous one is finished
      if (lastTimer && !lastTimer.end) {
        return message.reply(
          'You need to finish your previous timer first. Use `!end`!',
        );
      }

      timestamps.set(message.author.id, [
        ...timers,
        { start: Date.now(), end: null },
      ]);

      return message.reply('Timer started.');
    }

    if (message.content === '!end') {
      const timers = timestamps.get(message.author.id);
      // The user does not have an existing timer
      if (!timers) {
        return message.reply('You need to use `!start` first!');
      }

      const lastTimer = timers[timers.length - 1];

      // If the last timer is already finished
      if (lastTimer.end) {
        return message.reply('You need to use `!start` first!');
      }

      const currentTime = getTime(Date.now() - lastTimer.start);

      lastTimer.end = Date.now();

      const totalTimeInMs = countTotalMs(timers);
      const totalTime = getTime(totalTimeInMs);

      timestamps.set(message.author.id, timers);

      return message.reply(
        `Your time: ${currentTime.formatted}. Total time: ${totalTime.formatted}`,
      );
    }

    if (message.content.startsWith('!hours')) {
      const member = message.mentions.members.first() || message.author;

      if (!member) {
        return message.channel.send('You need to mention someone');
      }

      const timers = timestamps.get(member.id) || [];
      const totalTimeInMs = countTotalMs(timers);
      const totalTime = getTime(totalTimeInMs);

      return message.channel.send(
        `Total time of ${member}: ${totalTime.formatted}`,
      );
    }
  } catch (error) {
    console.error(error);
  }
});

【讨论】:

  • 我希望它出现在像“!hours @cake”这样的命令中,如果你能帮助我,我会很高兴:)
  • 那会做什么?
  • 命令:!hours @cake 响应:蛋糕的总时间是:0:01:16
  • 不确定我是否能理解它是如何工作的。哦,您的意思是您可以提及某人并获得总时间?
  • 实际上是的,但我已经编写了代码,但感谢您的时间,您在不止一个问题上帮助了我很多:) @Zsolt Meszaros
猜你喜欢
  • 2018-06-08
  • 2021-07-06
  • 2021-10-08
  • 2017-05-31
  • 2021-06-30
  • 2018-05-30
  • 2021-07-17
  • 2021-04-06
  • 2021-05-01
相关资源
最近更新 更多