feat: "hashing" via discord by DM-ing the bot hash
This commit is contained in:
@@ -107,6 +107,8 @@ public class Configuration {
|
||||
public static class Discord {
|
||||
public boolean enabled = false;
|
||||
public String prefix = "default!";
|
||||
public String serverId;
|
||||
public boolean enableDiscordHashing = true;
|
||||
public String token;
|
||||
public Map<String, String> servers = new HashMap<>();
|
||||
public EmbedColors embedColors = new EmbedColors();
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package me.chayapak1.chomens_bot.command;
|
||||
|
||||
import me.chayapak1.chomens_bot.Configuration;
|
||||
import me.chayapak1.chomens_bot.Main;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public enum TrustLevel {
|
||||
PUBLIC(0, Component.text("Public").color(NamedTextColor.GREEN)),
|
||||
TRUSTED(1, Component.text("Trusted").color(NamedTextColor.RED)),
|
||||
@@ -16,4 +21,29 @@ public enum TrustLevel {
|
||||
this.level = level;
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public static TrustLevel fromDiscordRoles (final List<Role> roles) {
|
||||
if (Main.discord == null) return PUBLIC;
|
||||
|
||||
final Configuration.Discord options = Main.discord.options;
|
||||
|
||||
if (options == null) return PUBLIC;
|
||||
|
||||
TrustLevel userTrustLevel = PUBLIC;
|
||||
|
||||
for (final Role role : roles) {
|
||||
if (role.getName().equalsIgnoreCase(options.ownerRoleName)) {
|
||||
userTrustLevel = OWNER;
|
||||
break;
|
||||
} else if (role.getName().equalsIgnoreCase(options.adminRoleName)) {
|
||||
userTrustLevel = ADMIN;
|
||||
break;
|
||||
} else if (role.getName().equalsIgnoreCase(options.trustedRoleName)) {
|
||||
userTrustLevel = TRUSTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return userTrustLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@ public enum LogType {
|
||||
ERROR(Component.text("Error").color(NamedTextColor.RED)),
|
||||
COMMAND_OUTPUT(Component.text("Command Output").color(NamedTextColor.LIGHT_PURPLE)),
|
||||
AUTH(Component.text("Auth").color(NamedTextColor.RED)),
|
||||
SIMPLE_VOICE_CHAT(Component.text("Simple Voice Chat").color(NamedTextColor.AQUA));
|
||||
SIMPLE_VOICE_CHAT(Component.text("Simple Voice Chat").color(NamedTextColor.AQUA)),
|
||||
DISCORD(Component.text("Discord").color(NamedTextColor.BLUE));
|
||||
|
||||
public final Component component;
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
package me.chayapak1.chomens_bot.discord;
|
||||
|
||||
import me.chayapak1.chomens_bot.Configuration;
|
||||
import me.chayapak1.chomens_bot.command.TrustLevel;
|
||||
import me.chayapak1.chomens_bot.data.logging.LogType;
|
||||
import me.chayapak1.chomens_bot.plugins.HashingPlugin;
|
||||
import me.chayapak1.chomens_bot.util.LoggerUtilities;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import net.dv8tion.jda.api.requests.ErrorResponse;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DirectMessageEventHandler extends ListenerAdapter {
|
||||
private static final String HASH_MESSAGE = "hash";
|
||||
|
||||
private final JDA jda;
|
||||
|
||||
private final Configuration.Discord options;
|
||||
|
||||
public DirectMessageEventHandler (
|
||||
final JDA jda,
|
||||
final Configuration.Discord options
|
||||
) {
|
||||
this.jda = jda;
|
||||
this.options = options;
|
||||
|
||||
jda.addEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessageReceived (@NotNull final MessageReceivedEvent event) {
|
||||
if (!options.enableDiscordHashing || event.getChannelType() != ChannelType.PRIVATE) return;
|
||||
|
||||
final Message message = event.getMessage();
|
||||
|
||||
if (!message.getContentDisplay().equalsIgnoreCase(HASH_MESSAGE)) return;
|
||||
|
||||
final Guild guild;
|
||||
|
||||
try {
|
||||
guild = jda.getGuildById(options.serverId);
|
||||
} catch (final NumberFormatException e) {
|
||||
// there will be a custom error message
|
||||
// from JDA when it fails to parse a snowflake,
|
||||
// the user will read that
|
||||
LoggerUtilities.error(e);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (guild == null) return;
|
||||
|
||||
guild.retrieveMember(message.getAuthor())
|
||||
.queue(
|
||||
member -> {
|
||||
if (member == null) return;
|
||||
|
||||
final TrustLevel trustLevel = TrustLevel.fromDiscordRoles(member.getRoles());
|
||||
|
||||
if (trustLevel == TrustLevel.PUBLIC) {
|
||||
LoggerUtilities.log(
|
||||
LogType.DISCORD,
|
||||
Component.translatable(
|
||||
"User %s tried to get hash in Discord without any trusted roles!",
|
||||
Component.text(member.toString())
|
||||
)
|
||||
);
|
||||
message.reply("You do not have any trusted roles!")
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
|
||||
sendHash(trustLevel, message, member);
|
||||
},
|
||||
exception -> {
|
||||
if (!(exception instanceof final ErrorResponseException error)) return;
|
||||
|
||||
final ErrorResponse errorResponse = error.getErrorResponse();
|
||||
|
||||
if (errorResponse == ErrorResponse.UNKNOWN_MEMBER) {
|
||||
message.reply("You are not in " + guild.getName() + "!")
|
||||
.queue();
|
||||
} else if (errorResponse == ErrorResponse.UNKNOWN_USER) {
|
||||
LoggerUtilities.error(
|
||||
Component.translatable(
|
||||
"Got ErrorResponse.UNKNOWN_USER while trying to " +
|
||||
"retrieve member! Weird user. User: %s",
|
||||
Component.text(message.getAuthor().toString())
|
||||
)
|
||||
);
|
||||
}
|
||||
// that's all the possible errors, the javadocs said
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void sendHash (final TrustLevel trustLevel, final Message message, final Member member) {
|
||||
final String result = HashingPlugin.generateDiscordHash(member.getIdLong(), trustLevel);
|
||||
|
||||
message
|
||||
.reply(
|
||||
String.format(
|
||||
"Hash for %s trust level: **%s**",
|
||||
trustLevel,
|
||||
result
|
||||
)
|
||||
)
|
||||
.queue();
|
||||
|
||||
LoggerUtilities.log(
|
||||
LogType.DISCORD,
|
||||
Component.translatable(
|
||||
"Generated hash %s (%s) for user %s",
|
||||
Component.text(result),
|
||||
Component.text(trustLevel.toString()),
|
||||
Component.text(member.getEffectiveName())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -174,20 +174,7 @@ public class CommandHandlerPlugin implements TickPlugin.Listener {
|
||||
|
||||
final List<Role> roles = member.getRoles();
|
||||
|
||||
TrustLevel userTrustLevel = TrustLevel.PUBLIC;
|
||||
|
||||
for (final Role role : roles) {
|
||||
if (role.getName().equalsIgnoreCase(bot.config.discord.ownerRoleName)) {
|
||||
userTrustLevel = TrustLevel.OWNER;
|
||||
break;
|
||||
} else if (role.getName().equalsIgnoreCase(bot.config.discord.adminRoleName)) {
|
||||
userTrustLevel = TrustLevel.ADMIN;
|
||||
break;
|
||||
} else if (role.getName().equalsIgnoreCase(bot.config.discord.trustedRoleName)) {
|
||||
userTrustLevel = TrustLevel.TRUSTED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final TrustLevel userTrustLevel = TrustLevel.fromDiscordRoles(roles);
|
||||
|
||||
if (trustLevel.level > userTrustLevel.level) {
|
||||
context.sendOutput(
|
||||
|
||||
@@ -3,6 +3,7 @@ package me.chayapak1.chomens_bot.plugins;
|
||||
import me.chayapak1.chomens_bot.Bot;
|
||||
import me.chayapak1.chomens_bot.Configuration;
|
||||
import me.chayapak1.chomens_bot.Main;
|
||||
import me.chayapak1.chomens_bot.discord.DirectMessageEventHandler;
|
||||
import me.chayapak1.chomens_bot.discord.GuildMessageEventHandler;
|
||||
import me.chayapak1.chomens_bot.util.CodeBlockUtilities;
|
||||
import me.chayapak1.chomens_bot.util.ComponentUtilities;
|
||||
@@ -29,6 +30,8 @@ import java.util.regex.Matcher;
|
||||
public class DiscordPlugin {
|
||||
public JDA jda;
|
||||
|
||||
public Configuration.Discord options;
|
||||
|
||||
public final Map<String, String> servers;
|
||||
|
||||
public final String prefix;
|
||||
@@ -38,7 +41,7 @@ public class DiscordPlugin {
|
||||
public final String discordUrl;
|
||||
|
||||
public DiscordPlugin (final Configuration config) {
|
||||
final Configuration.Discord options = config.discord;
|
||||
this.options = config.discord;
|
||||
this.prefix = options.prefix;
|
||||
this.servers = options.servers;
|
||||
this.discordUrl = config.discord.inviteLink;
|
||||
@@ -53,7 +56,11 @@ public class DiscordPlugin {
|
||||
.clickEvent(ClickEvent.openUrl(discordUrl));
|
||||
|
||||
final JDABuilder builder = JDABuilder.createDefault(config.discord.token);
|
||||
builder.enableIntents(GatewayIntent.MESSAGE_CONTENT);
|
||||
builder.enableIntents(
|
||||
GatewayIntent.MESSAGE_CONTENT,
|
||||
GatewayIntent.DIRECT_MESSAGES,
|
||||
GatewayIntent.GUILD_MEMBERS
|
||||
);
|
||||
builder.setEnableShutdownHook(false);
|
||||
|
||||
try {
|
||||
@@ -66,6 +73,7 @@ public class DiscordPlugin {
|
||||
jda.getPresence().setPresence(Activity.playing(config.discord.statusMessage), false);
|
||||
|
||||
new GuildMessageEventHandler(jda, prefix, messagePrefix);
|
||||
new DirectMessageEventHandler(jda, options);
|
||||
|
||||
Main.EXECUTOR.scheduleAtFixedRate(this::onDiscordTick, 0, 50, TimeUnit.MILLISECONDS);
|
||||
|
||||
|
||||
@@ -4,11 +4,18 @@ import com.google.common.hash.Hashing;
|
||||
import me.chayapak1.chomens_bot.Bot;
|
||||
import me.chayapak1.chomens_bot.command.TrustLevel;
|
||||
import me.chayapak1.chomens_bot.data.player.PlayerEntry;
|
||||
import me.chayapak1.chomens_bot.util.RandomStringUtilities;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class HashingPlugin {
|
||||
public static final Map<Long, Pair<TrustLevel, String>> discordHashes = new ConcurrentHashMap<>();
|
||||
|
||||
private final Bot bot;
|
||||
|
||||
public HashingPlugin (final Bot bot) {
|
||||
@@ -64,10 +71,42 @@ public class HashingPlugin {
|
||||
checkHash(getOwnerHash(prefix, sender, false), input);
|
||||
}
|
||||
|
||||
public boolean isCorrectDiscordHash (final String input) {
|
||||
for (final Pair<TrustLevel, String> pair : discordHashes.values()) {
|
||||
if (checkHash(pair.getRight(), input)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public TrustLevel getDiscordHashTrustLevel (final String input) {
|
||||
for (final Map.Entry<Long, Pair<TrustLevel, String>> entry : new ArrayList<>(discordHashes.entrySet())) {
|
||||
final Pair<TrustLevel, String> pair = entry.getValue();
|
||||
|
||||
if (!pair.getRight().equals(input)) continue;
|
||||
|
||||
discordHashes.remove(entry.getKey());
|
||||
|
||||
return pair.getLeft();
|
||||
}
|
||||
|
||||
return TrustLevel.PUBLIC;
|
||||
}
|
||||
|
||||
public TrustLevel getTrustLevel (final String input, final String prefix, final PlayerEntry sender) {
|
||||
if (isCorrectOwnerHash(input, prefix, sender)) return TrustLevel.OWNER;
|
||||
else if (isCorrectAdminHash(input, prefix, sender)) return TrustLevel.ADMIN;
|
||||
else if (isCorrectHash(input, prefix, sender)) return TrustLevel.TRUSTED;
|
||||
else if (isCorrectDiscordHash(input)) return getDiscordHashTrustLevel(input);
|
||||
else return TrustLevel.PUBLIC;
|
||||
}
|
||||
|
||||
public static String generateDiscordHash (final long userId, final TrustLevel trustLevel) {
|
||||
// i wouldn't say it's a hash, it's just a random string
|
||||
final String string = RandomStringUtilities.generate(16);
|
||||
|
||||
discordHashes.putIfAbsent(userId, Pair.of(trustLevel, string));
|
||||
|
||||
return discordHashes.get(userId).getRight();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user