Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.4</version>
<version>1.2.8</version>
</dependency>
</dependencies>
</project>
40 changes: 33 additions & 7 deletions src/main/java/rocks/learnercouncil/cameron/Cameron.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public static void main(String[] args) throws InterruptedException, LoginExcepti
new ReportCommand(),
new KickCommand(),
new BanCommand(),
new JoinlistCommand(),
//Events
new EditEvent(),
new MessageEvent(),
Expand All @@ -73,14 +74,38 @@ public static void main(String[] args) throws InterruptedException, LoginExcepti
PronounsCommand.initializeRoles(guild);
Cameron.logger.info("Found Guild: " + guild.getName());
MessageCache.initializeMessages(guild);
//Currently guild commands but may be changed to global commands on release
//i.e. jda.updateCommands().addCommands(...).queue();
guild.updateCommands().addCommands(Commands.slash("ping", "Ping Pong!"), Commands.slash("request", "Request Access to the server"), Commands.slash("rps", "Play 'Rock, Paper, Scissors' with Cameron"), Commands.slash("say", "Make cameron say something").addOption(OptionType.STRING, "message", "The thing to Cameron will say", true).setDefaultEnabled(false), Commands.slash("sayembed", "Make cameron say something as an embed").addOptions(
new OptionData(OptionType.STRING, "color", "The color of the sidebar of the embed", true, true), new OptionData(OptionType.STRING, "title", "The title of the embed", true), new OptionData(OptionType.STRING, "message", "The thing cameron will say", true)).setDefaultEnabled(false), Commands.slash("pronouns", "Set your pronouns"), Commands.slash("whois", "Check the information of a certain user").addOption(OptionType.USER, "user", "The usre to get the information of", true), Commands.slash("report", "Report a user").addOptions(new OptionData(OptionType.USER, "user", "The user you're reporting.", true), new OptionData(OptionType.STRING, "reason", "The reason you're reporting them.", true)), Commands.slash("kick", "Kicks a user").addOptions(new OptionData(OptionType.USER, "user", "the user to kick", true), new OptionData(OptionType.STRING, "reason", "the reason you're kicking them", false)).setDefaultEnabled(false),
Commands.slash("ban", "Kicks a user").addOptions(
//Global commands don't seem to work, even after waiting for the alotted time, so for the time being I'm sticking to guild commands.
guild.updateCommands().addCommands(
Commands.slash("ping", "Ping Pong!"),
Commands.slash("request", "Request Access to the server"),
Commands.slash("rps", "Play 'Rock, Paper, Scissors' with Cameron"),
Commands.slash("say", "Make cameron say something")
.addOption(OptionType.STRING, "message", "The thing to Cameron will say", true)
.setDefaultEnabled(false),
Commands.slash("sayembed", "Make cameron say something as an embed")
.addOptions(
new OptionData(OptionType.STRING, "color", "The color of the sidebar of the embed", true, true),
new OptionData(OptionType.STRING, "title", "The title of the embed", true),
new OptionData(OptionType.STRING, "message", "The thing cameron will say", true))
.setDefaultEnabled(false),
Commands.slash("pronouns", "Set your pronouns"),
Commands.slash("whois", "Check the information of a certain user").addOption(OptionType.USER, "user", "The usre to get the information of", true),
Commands.slash("report", "Report a user")
.addOptions(
new OptionData(OptionType.USER, "user", "The user you're reporting.", true),
new OptionData(OptionType.STRING, "reason", "The reason you're reporting them.", true)),
Commands.slash("kick", "Kicks a user").addOptions(
new OptionData(OptionType.USER, "user", "the user to kick", true),
new OptionData(OptionType.STRING, "reason", "the reason you're kicking them", false),
new OptionData(OptionType.INTEGER, "delete_history_days", "The amount of days of recent message history from this user you want to delete.", false)).setDefaultEnabled(false)
new OptionData(OptionType.STRING, "reason", "the reason you're kicking them", false))
.setDefaultEnabled(false),
Commands.slash("ban", "Kicks a user")
.addOptions(
new OptionData(OptionType.USER, "user", "the user to kick", true),
new OptionData(OptionType.STRING, "reason", "the reason you're kicking them", false),
new OptionData(OptionType.INTEGER, "delete_history_days", "The amount of days of recent message history from this user you want to delete.", false))
.setDefaultEnabled(false),
Commands.slash("joinlist", "Request access to the Minecraft Server")
.addOption(OptionType.STRING, "username", "Your Minecraft username", true)
).queue(c -> logger.info("Loaded Commands"));
guild.loadMembers().onSuccess(l -> {
logger.info("Loaded Members");
Expand Down Expand Up @@ -142,6 +167,7 @@ public static JDA getJDA() {
return jda;
}

@NotNull
public static Guild getGuild() {
return guild;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package rocks.learnercouncil.cameron.commands;

import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.jetbrains.annotations.NotNull;
import rocks.learnercouncil.cameron.Cameron;

import java.awt.Color;
import java.io.IOException;
import java.time.Instant;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JoinlistCommand extends ListenerAdapter {

private static final OkHttpClient client = new OkHttpClient();

private static final Button acceptButton = Button.success("jl_accept", "Accept");
private static final Button denyButton = Button.danger("jl_deny", "Deny");

@Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
if(event.getOption("username") == null) return;
String username = Objects.requireNonNull(event.getOption("username")).getAsString();
String jsonString = sendRequest(username);
if(jsonString.startsWith("#ERR INVALID_CHARS")) {
String invalid_characters = jsonString.split(":")[1];
StringBuilder stringBuilder = new StringBuilder();
for(char character : invalid_characters.toCharArray()) {
stringBuilder.append('\'');
stringBuilder.append(character);
stringBuilder.append("', ");
}
event.reply("The username you typed contains characters that can't be in a Minecraft username: " + stringBuilder.substring(0, stringBuilder.length() - 2) +
"Please check to make sure you spelled your username correctly.").setEphemeral(true).queue();
return;
}
if(jsonString.isEmpty()) {
event.reply("I can't find the minecraft username '" + username + "', check that it's spelled correctly.").setEphemeral(true).queue();
return;
}
Map<String, String> json = parseJson(jsonString);
if(json.containsKey("error")) {
event.reply("I can't find the minecraft username '" + username + "', check that it's spelled correctly.").setEphemeral(true).queue();
return;
}
if (!json.containsKey("id")) return;
if(event.getMember() == null) return;

Cameron.getExistingChannel("mc-joinlist").sendMessageEmbeds(
new EmbedBuilder()
.setColor(Color.YELLOW)
.setAuthor("Request Pending...")
.setDescription(event.getUser().getAsMention() + " is requesting to join the Minecraft server.\n" +
"If you wish to accept the request, add them to the joinlist and click **Accept**. Otherwise, click **Deny**.")
.addField(new MessageEmbed.Field("> **Name:**", event.getUser().getAsMention(), false))
.addField(new MessageEmbed.Field("> **Username:**", json.get("name"), false))
.addField(new MessageEmbed.Field("> **UUID:**", formatUUID(json.get("id")), false))
.build()
).setActionRow(acceptButton, denyButton).queue();

event.reply("Request sent! A council member will review it soon.").setEphemeral(true).queue();
}

private String formatUUID(String uuid) {
return new StringBuilder(uuid).insert(8, '-').insert(13, '-').insert(18, '-').insert(23, '-').toString();
}

@Override
public void onButtonInteraction(@NotNull ButtonInteractionEvent event) {
if(event.getComponentId().equals("jl_accept")) {
List<MessageEmbed.Field> fields = new ArrayList<>();
MessageEmbed embed = event.getMessage().getEmbeds().get(0);
if(!embed.getFields().isEmpty())
fields = embed.getFields();

event.editMessageEmbeds(
new EmbedBuilder()
.setColor(Color.GREEN)
.setAuthor("Accepted.")
.setDescription("Request accepted.\n")
.addField(fields.get(0))
.addField(fields.get(1))
.addField(fields.get(2))
.setTimestamp(Instant.now())
.build()).setActionRows().queue();
return;
}
if(event.getComponentId().equals("jl_deny")) {
event.editMessageEmbeds(new EmbedBuilder()
.setAuthor("Denied.")
.setColor(Color.RED)
.setDescription("Request Denied.")
.build()).setActionRows().queue(m -> m.deleteOriginal().queueAfter(120, TimeUnit.SECONDS));
}
}

private String sendRequest(String username) {
Pattern pattern = Pattern.compile("[a-zA-Z0-9\\-_]+");
Matcher matcher = pattern.matcher(username);
if(!matcher.matches()) return "#ERR INVALID_CHARS:" + matcher.replaceAll("");
String url = "https://api.mojang.com/users/profiles/minecraft/" + username;
Request request = new Request.Builder()
.url(url)
.header("User-Agent", "application/json")
.build();
try {
Response response = client.newCall(request).execute();
//System.out.println(Objects.requireNonNull(response.body()).string());
return Objects.requireNonNull(response.body()).string();
} catch (IOException e) {
System.out.println("IOException occured via /joinlist");
return "#ERR IOEXCEPTION";
}
}

private Map<String, String> parseJson(String json) {
json = json.replace("\s*", "");
Map<String, String> map = new LinkedHashMap<>();
String[] pairs = json.substring(1, json.length() - 1).split(",");
for(String pair : pairs) {
String[] parts = pair.split(":");
if(parts.length != 2) continue;
map.put(parts[0].substring(1, parts[0].length() - 1), parts[1].substring(1, parts[1].length() - 1));
}
return map;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,11 @@ public static void initializeRoles(Guild guild) {
Cameron.logger.info("Initializing roles");
pronounRoles.clear();
if(guild == null) return;
Cameron.logger.info("Guild isn't null");
Cameron.getExistingChannel("pronouns").getIterableHistory().forEach(m -> {
Cameron.logger.info("Message: " + m.getContentStripped());
if(guild.getRolesByName(PREFIX + m.getContentStripped(), true).isEmpty())
addPronounRole(guild, PREFIX + m.getContentStripped());
});
guild.getRoles().stream().filter(r -> r.getName().startsWith(PREFIX)).forEach(pronounRoles::add);
Cameron.logger.info(pronounRoles.toString());
}

private static boolean matchesAnyInChannel(Role r, MessageChannel channel) {
Expand All @@ -51,7 +48,7 @@ public static void addPronounRole(Guild guild, String name) {
guild.createRole().setName(PREFIX + name).queue(pronounRoles::add);
}
public static void removePronounRole(String name, Guild guild) {
Cameron.logger.info("Deleting: " + name);
Cameron.logger.info("Deleting Pronoun Role: " + name);
pronounRoles.remove(Cameron.getExistingRole(PREFIX + name));
Cameron.getExistingRole(PREFIX + name).delete().queue();
}
Expand All @@ -60,17 +57,14 @@ public static void removePronounRole(String name, Guild guild) {
@Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
if(!event.getName().equals("pronouns")) return;
Cameron.logger.info("Command Executed");
if(!event.isFromGuild()) {
event.reply("This command must be run from inside a server").queue();
return;
}
Cameron.logger.info("Command is from guild");
event.deferReply().setEphemeral(true).queue();
if(pronounRoles.isEmpty()) {
initializeRoles(event.getGuild());
}
Cameron.logger.info("Pronouns: " + pronounRoles);
MessageEmbed embed = new EmbedBuilder()
.setColor(Color.GREEN)
.setAuthor("Set your pronouns! (Select all that apply.)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,5 @@ public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent even
}, false)
.build()
).queue();
Cameron.logger.info(member.getOnlineStatus().toString());
}
}