如何基于JDA实现每小时仅可使用一次的>deadchat命令?
实现每小时冷却一次的>deadchat命令
核心思路
通过记录命令上次执行的时间戳,每次触发时对比当前时间与上次时间的间隔,判断是否满足1小时的冷却要求。
单服务器场景实现(全局冷却)
如果命令是全机器人范围内的冷却,用全局变量存储上次执行时间即可:
// 全局变量:记录上次执行deadchat命令的时间戳,初始为0 private static long lastDeadChatTime = 0; // 冷却时长:1小时 = 3600000毫秒 private static final long COOLDOWN = 3600000; public void onMessageReceived(MessageReceivedEvent event) { String msg = event.getMessage().getContentRaw(); if (msg.equalsIgnoreCase(">deadchat")) { long now = System.currentTimeMillis(); // 检查是否在冷却期内 if (now - lastDeadChatTime < COOLDOWN) { long remainingMin = (COOLDOWN - (now - lastDeadChatTime)) / 1000 / 60; event.getChannel().sendMessage("该命令每小时仅能使用一次,还剩" + remainingMin + "分钟冷却").queue(); return; } // 执行deadchat命令的核心逻辑 event.getChannel().sendMessage("Dead chat? Time to spice things up!").queue(); // 更新上次执行时间 lastDeadChatTime = now; } }
多服务器场景实现(分服务器冷却)
如果需要每个服务器独立计算冷却,用Map存储每个服务器的上次执行时间:
// 存储各服务器的冷却时间,Key为服务器ID,Value为上次执行时间戳 private static Map<Long, Long> guildCooldownMap = new HashMap<>(); private static final long COOLDOWN = 3600000; public void onMessageReceived(MessageReceivedEvent event) { // 仅处理服务器内的消息 if (!event.isFromGuild()) return; long guildId = event.getGuild().getIdLong(); String msg = event.getMessage().getContentRaw(); if (msg.equalsIgnoreCase(">deadchat")) { long now = System.currentTimeMillis(); // 获取当前服务器的上次执行时间,默认0 long lastTime = guildCooldownMap.getOrDefault(guildId, 0L); if (now - lastTime < COOLDOWN) { long remainingMin = (COOLDOWN - (now - lastTime)) / 1000 / 60; event.getChannel().sendMessage("该命令每小时仅能使用一次,还剩" + remainingMin + "分钟冷却").queue(); return; } // 执行命令逻辑 event.getChannel().sendMessage("Dead chat? Let's get this conversation going!").queue(); // 更新当前服务器的冷却时间 guildCooldownMap.put(guildId, now); } }
常见问题说明
之前用简单计时器失效,大概率是因为每次触发命令都重新创建计时器,没有持久化记录历史执行时间点。上面的方案通过直接记录时间戳做差值对比,逻辑更可靠,也不会出现计时器重复创建的问题。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

