如何在Discord JDA中为单个服务器限定命令开关布尔值
实现Discord JDA服务器独立的命令开关
核心思路是把全局布尔值替换为按服务器ID存储开关状态的集合,让每个服务器拥有独立的开关设置。
1. 替换全局变量为Map存储
用Map<Long, Boolean>保存每个服务器的开关状态,键是服务器ID(Long类型,对应Guild.getIdLong()的返回值),值是开关的启用/禁用状态。由于Discord事件是多线程处理的,推荐使用ConcurrentHashMap避免并发问题:
// 全局存储每个服务器的开关状态,默认所有服务器启用该命令 private final Map<Long, Boolean> commandToggle = new ConcurrentHashMap<>();
2. 修改开关控制命令的逻辑
在原来的开关命令中,先获取当前服务器的ID,再对应该服务器的开关状态进行修改:
if (event.getMessage().getContentStripped().equalsIgnoreCase("message")) { // 先判断是否在服务器频道(避免私聊触发) Guild guild = event.getGuild(); if (guild == null) { event.getChannel().sendMessage("这个命令只能在服务器内使用。").queue(); return; } // 检查用户是否拥有管理员权限 if (event.getMember().getPermissions().contains(Permission.ADMINISTRATOR)) { long guildId = guild.getIdLong(); // 获取当前服务器的开关状态,未设置过则默认启用(true) boolean currentState = commandToggle.getOrDefault(guildId, true); if (currentState) { commandToggle.put(guildId, false); event.getChannel().sendMessage("成功禁用该命令。").queue(); } else { event.getChannel().sendMessage("该命令已经处于禁用状态。").queue(); } } else { event.getChannel().sendMessage("你没有权限执行此命令。").queue(); } }
3. 在目标命令中检查开关状态
当用户触发需要被控制的目标命令时,先检查当前服务器的开关状态,只有启用时才执行命令逻辑:
// 示例:被控制的目标命令 if (event.getMessage().getContentStripped().equalsIgnoreCase("target-command")) { Guild guild = event.getGuild(); if (guild == null) { event.getChannel().sendMessage("这个命令只能在服务器内使用。").queue(); return; } long guildId = guild.getIdLong(); // 获取当前服务器的开关状态,默认启用 boolean isCommandEnabled = commandToggle.getOrDefault(guildId, true); if (!isCommandEnabled) { event.getChannel().sendMessage("该命令目前已被禁用。").queue(); return; } // 这里编写命令正常执行的逻辑 event.getChannel().sendMessage("命令执行成功!").queue(); }
可选:持久化开关状态
上面的实现是内存存储,机器人重启后开关状态会丢失。如果需要持久化,可以把commandToggle中的数据保存到JSON/YAML文件或数据库中,机器人启动时读取加载。例如用Jackson库将Map序列化为JSON文件,重启时反序列化加载。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

