diff options
author | Tyler Murphy <tylermurphy534@gmail.com> | 2022-09-01 00:15:36 -0400 |
---|---|---|
committer | Tyler Murphy <tylermurphy534@gmail.com> | 2022-09-01 00:15:36 -0400 |
commit | 2bb0dcd0e299127ca234643d267ef71b2605947c (patch) | |
tree | 69c90e8f2272bfcc28d95347a9cfe8bec0e013fe /src | |
parent | v9 (diff) | |
download | ken-2bb0dcd0e299127ca234643d267ef71b2605947c.tar.gz ken-2bb0dcd0e299127ca234643d267ef71b2605947c.tar.bz2 ken-2bb0dcd0e299127ca234643d267ef71b2605947c.zip |
v10
Diffstat (limited to 'src')
14 files changed, 409 insertions, 46 deletions
diff --git a/src/main/java/net/tylermurphy/ken/Ken.java b/src/main/java/net/tylermurphy/ken/Ken.java index a69ddc2..235479a 100644 --- a/src/main/java/net/tylermurphy/ken/Ken.java +++ b/src/main/java/net/tylermurphy/ken/Ken.java @@ -7,6 +7,7 @@ import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.entities.Activity; +import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.hooks.ListenerAdapter; @@ -16,6 +17,7 @@ import net.tylermurphy.ken.command.Responder; import net.tylermurphy.ken.database.Database; import net.tylermurphy.ken.music.PlayerManager; import net.tylermurphy.ken.util.ImageFetcher; +import net.tylermurphy.ken.util.ModerationChecker; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,6 +69,7 @@ public class Ken { log.error(e.getMessage()); throw new RuntimeException("Unable to connect with YouTube API"); } + new ModerationChecker().start(); } public static Ken getInstance(){ @@ -101,6 +104,10 @@ public class Ken { public User getUserByName(String username, String discriminator) { return api.getUserByTag(username, discriminator); } + public Guild getGuildById(long id) { return api.getGuildById(id); } + + public User getUserById(long id) { return api.getUserById(id); } + public EmbedBuilder getDefaultEmbed() { EmbedBuilder builder = new EmbedBuilder(); builder.setColor(new Color( diff --git a/src/main/java/net/tylermurphy/ken/command/Responder.java b/src/main/java/net/tylermurphy/ken/command/Responder.java index 9ea898a..38b78be 100644 --- a/src/main/java/net/tylermurphy/ken/command/Responder.java +++ b/src/main/java/net/tylermurphy/ken/command/Responder.java @@ -151,7 +151,6 @@ public class Responder extends ListenerAdapter { .setTitle(":x: **Error**") .setDescription(e.getCause() != null ? e.getCause().getMessage() : e.getMessage()); event.getHook().sendMessageEmbeds(builder.build()).setEphemeral(true).queue(); - e.printStackTrace(); } } @@ -246,7 +245,7 @@ public class Responder extends ListenerAdapter { .setColor(Color.RED) .setTitle(":x: **Error**") .setDescription(e.getCause().getMessage()); - event.getHook().editOriginalEmbeds(builder.build()).queue(); + event.getHook().sendMessageEmbeds(builder.build()).queue(); } } @@ -319,8 +318,16 @@ public class Responder extends ListenerAdapter { boolean setValue = false; String value = Ken.getInstance().getDatabase().getGuildSettingsTable().getData(event.getGuild().getIdLong(), "closeServer"); if(value != null) setValue = Boolean.parseBoolean(value); - if(!setValue){ - event.getGuild().kick(user, "Server is currently closed").queue(); + if(setValue){ + try { + event.getGuild().kick(user, "Server is currently closed").queue(); + user.openPrivateChannel().queue(privateChannel -> { + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .appendDescription("Kicked from "+event.getGuild().getName() + " because the server is currently closed"); + privateChannel.sendMessageEmbeds(builder.build()).queue(); + + }); + } catch (Exception ignored){} } } diff --git a/src/main/java/net/tylermurphy/ken/command/main/Help.java b/src/main/java/net/tylermurphy/ken/command/main/Help.java index bf692f8..59c69b8 100644 --- a/src/main/java/net/tylermurphy/ken/command/main/Help.java +++ b/src/main/java/net/tylermurphy/ken/command/main/Help.java @@ -44,12 +44,14 @@ public class Help { ), Ken.getInstance().getDefaultEmbed() .setAuthor("Command List") - .setTitle(":tools: **Admin Commands**") + .setTitle(":tools: **Moderation Commands**") .appendDescription("**/purge <amount>** Purges an amount of messages from a channel\n") .appendDescription("**/kick <user> <reason>** Kick a user from the server\n") - .appendDescription("**/tempban <user> <days> <hours> <reason> <delete>** Temp ban a user from the server\n") + .appendDescription("**/tempban <user> <time> <reason> <delete>** Temp ban a user from the server\n") .appendDescription("**/ban <user> <reason> <delete>** Bans a user from the server\n") .appendDescription("**/unban <username> <discriminator>** Unbans a user from the server\n") + .appendDescription("**/mute <user> <time> <reason>** Mutes a user in the server\n") + .appendDescription("**/unmute <user> <reason>** Un mutes a user in the server\n") .appendDescription("**/history <username> <discriminator>** Gets users moderation history\n") .appendDescription("**/setjoining <toggle>** Disable joining to the server\n"), Ken.getInstance().getDefaultEmbed() diff --git a/src/main/java/net/tylermurphy/ken/command/moderation/Ban.java b/src/main/java/net/tylermurphy/ken/command/moderation/Ban.java index 1a6b8a2..5262afd 100644 --- a/src/main/java/net/tylermurphy/ken/command/moderation/Ban.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/Ban.java @@ -58,6 +58,16 @@ public class Ban { String data = table.getData(guild.getIdLong(), target.getUser().getIdLong()); JSONObject json = table.updateData(data); + try { + guild.removeTimeout(target).queue(); + } catch (Exception ignored){} + + try { + guild.ban(target,purge ? 1 : 0,reason).queue(); + } catch (Exception e){ + return Response.error("Failed to ban user"); + } + JSONObject status = json.getJSONObject("status"); status.put("type", "ban"); status.put("reason", reason); @@ -82,7 +92,6 @@ public class Ban { .appendDescription("`Reason:` " + reason); channel.sendMessageEmbeds(builder.build()).queue(); } - guild.ban(target,purge ? 1 : 0,reason).queue(); EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() .appendDescription(String.format("Permanently banned %s for %s", target, reason)); return Response.success(builder.build()); diff --git a/src/main/java/net/tylermurphy/ken/command/moderation/History.java b/src/main/java/net/tylermurphy/ken/command/moderation/History.java index d69a507..7a360b3 100644 --- a/src/main/java/net/tylermurphy/ken/command/moderation/History.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/History.java @@ -6,6 +6,7 @@ import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.interactions.commands.OptionType; import net.tylermurphy.ken.Ken; import net.tylermurphy.ken.command.Response; +import net.tylermurphy.ken.command.annotation.ButtonCallback; import net.tylermurphy.ken.command.annotation.Command; import net.tylermurphy.ken.command.annotation.Option; import net.tylermurphy.ken.command.annotation.Requirement; @@ -40,19 +41,58 @@ public class History { ModerationTable table = Ken.getInstance().getDatabase().getModerationTable(); String data = table.getData(guild.getIdLong(), target); JSONObject json = table.updateData(data); + JSONArray history = json.getJSONArray("history"); + + int page = 1; + int pages = (history.length()-1)/4+1; + return Response.success(generateEmbed(history, page, username, discriminator)).addSecondaryButton("history", "previous", "Previous").addSecondaryButton("history", "next", "Next"); + } + + @ButtonCallback(name="history") + public Response onButton(String id, Message message, Guild guild){ + if(message == null || message.getEmbeds().size() < 1){ + return Response.error("Message missing"); + } + + MessageEmbed temp = message.getEmbeds().get(0); + String username = temp.getDescription().substring(6).split("#")[0]; + String discriminator = temp.getDescription().substring(6).split("#")[1]; + + long target = Ken.getInstance().getDatabase().getUserTable().getData(username, Integer.parseInt(discriminator)); + if(target == 0L || temp.getFooter() == null) { + return Response.error("Either the user is invalid or the user has no cached history"); + } + + ModerationTable table = Ken.getInstance().getDatabase().getModerationTable(); + String data = table.getData(guild.getIdLong(), target); + JSONObject json = table.updateData(data); JSONArray history = json.getJSONArray("history"); - EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() - .setAuthor("Moderation History"); + int page = Integer.parseInt(temp.getFooter().getText().split("/")[0].substring(5)); + int pages = (history.length()-1)/4+1; + if(id.equals("previous")) + page = page - 1 < 1 ? pages : page - 1; + else + page = page + 1 > pages ? 1 : page + 1; + MessageEmbed embed = generateEmbed(history, page, username, discriminator); + return Response.success(embed); + } + private MessageEmbed generateEmbed(JSONArray history, int page, String username, String discriminator){ + int pages = (history.length()-1)/4+1; + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .setAuthor("Moderation History") + .setDescription("User: "+username+"#"+discriminator) + .setFooter("Page "+page+"/"+pages); if(history.length() < 1){ builder.appendDescription("User has no moderation history"); } else { - history.forEach(audit -> builder.addField(parseStatus((JSONObject) audit))); + for(int i =(page-1)*4; i<Math.min((page-1)*4+4, history.length()); i++){ + builder.addField(parseStatus(history.getJSONObject(history.length()-i-1))); + } } - - return Response.success(builder.build()); + return builder.build(); } private MessageEmbed.Field parseStatus(JSONObject status){ @@ -63,9 +103,11 @@ public class History { case "temp-ban" -> "Temp banned"; case "unban" -> "Unbanned"; case "kick" -> "Kicked"; + case "mute" -> "Muted"; + case "unmute" -> "Unmuted"; default -> throw new RuntimeException("Unknown value: " + type); }; - SimpleDateFormat format = new SimpleDateFormat("MMM d, y ha zz"); + SimpleDateFormat format = new SimpleDateFormat("MMM d, y h:ma zz"); String date = status.has("until") ? "Until: " + format.format(new Date(status.getLong("until"))) : "Date: " + format.format(new Date(status.getLong("date"))); diff --git a/src/main/java/net/tylermurphy/ken/command/moderation/Kick.java b/src/main/java/net/tylermurphy/ken/command/moderation/Kick.java index 5b0ed69..3dae4eb 100644 --- a/src/main/java/net/tylermurphy/ken/command/moderation/Kick.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/Kick.java @@ -56,6 +56,16 @@ public class Kick { String data = table.getData(guild.getIdLong(), target.getUser().getIdLong()); JSONObject json = table.updateData(data); + try { + guild.removeTimeout(target).queue(); + } catch (Exception ignored){} + + try { + guild.kick(target).queue(); + } catch (Exception e){ + return Response.error("Failed to kick user"); + } + JSONObject status = json.getJSONObject("status"); status.put("type", "None"); status.put("reason", ""); @@ -63,7 +73,7 @@ public class Kick { json.put("status", status); JSONArray history = json.getJSONArray("history"); - history.put(new JSONObject().put("type", "kick").put("reason", reason).put("date",new Date().getTime())); + history.put(new JSONObject().put("type", "kick").put("reason", reason).put("date",new Date().getTime()).put("by", sender.getIdLong())); json.put("history", history); table.setData(guild.getIdLong(), target.getUser().getIdLong(), json.toString()); @@ -73,14 +83,13 @@ public class Kick { PrivateChannel channel = target.getUser().openPrivateChannel().complete(); if(channel != null){ EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() - .setColor(Color.red) + .setColor(new Color(250,63,63)) .setTitle("**Kicked**") .appendDescription("You have been kicked from "+guild.getName()+"\n") .appendDescription("`By:` " + sender.getEffectiveName()+"\n") .appendDescription("`Reason:` " + reason); channel.sendMessageEmbeds(builder.build()).queue(); } - guild.kick(target, reason).queue(); EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() .appendDescription(String.format("Kicked %s for %s", target, reason)); return Response.success(builder.build()); diff --git a/src/main/java/net/tylermurphy/ken/command/moderation/Mute.java b/src/main/java/net/tylermurphy/ken/command/moderation/Mute.java index 6e23d74..0d32832 100644 --- a/src/main/java/net/tylermurphy/ken/command/moderation/Mute.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/Mute.java @@ -1,4 +1,108 @@ package net.tylermurphy.ken.command.moderation; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.PrivateChannel; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.exceptions.ErrorResponseException; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.tylermurphy.ken.Ken; +import net.tylermurphy.ken.command.Response; +import net.tylermurphy.ken.command.annotation.Command; +import net.tylermurphy.ken.command.annotation.Option; +import net.tylermurphy.ken.command.annotation.Requirement; +import net.tylermurphy.ken.database.ModerationTable; +import net.tylermurphy.ken.util.Checks; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.awt.*; +import java.sql.Time; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.concurrent.TimeUnit; + public class Mute { + + @Command(name="mute", description="Mute a user") + @Option(name="member", description="Member to mute", type= OptionType.USER, required=true) + @Option(name="time", description="Time for mute", type= OptionType.STRING, required=true) + @Option(name="reason", description="Reason for mute", type=OptionType.STRING, required=true) + @Requirement(Permission.MODERATE_MEMBERS) + public Response execute(Member sender, List<Object> args, Guild guild){ + Member target = (Member) args.get(0); + String timeString = (String) args.get(1); + String reason = (String) args.get(2); + if(target == sender){ + return Response.error("You are not allowed to do this to yourself"); + } + Role low = Checks.getHighestRole(target); + Role high = Checks.getHighestRole(sender); + if(!Checks.getRolePermission(high, low)){ + return Response.error("You need a higher role than the target"); + } + Role self = Checks.getHighestRole(guild.getSelfMember()); + if(!Checks.getRolePermission(self, low)){ + return Response.error("I need a higher role than the target"); + } + if(guild.getOwner() == target){ + return Response.error("You cannot to this to the server owner"); + } + if(target.isTimedOut()){ + return Response.error("User is already muted"); + } + long time = Checks.convertTime(timeString); + if(time == 0L){ + return Response.error("Time to ban cannot be 0"); + } + long diff = TimeUnit.DAYS.convert(Math.abs(new Date().getTime() - new Date(time).getTime()), TimeUnit.MILLISECONDS); + if(diff >= 28) { + return Response.error("Time cannot be or exceed 28 days"); + } + SimpleDateFormat format = new SimpleDateFormat("MMM d, y h:ma zz"); + String date = format.format(time); + + ModerationTable table = Ken.getInstance().getDatabase().getModerationTable(); + String data = table.getData(guild.getIdLong(), target.getUser().getIdLong()); + JSONObject json = table.updateData(data); + + try { + guild.timeoutUntil(target, new Date(time).toInstant()).queue(); + } catch (Exception e){ + return Response.error("Failed to mute user"); + } + + JSONObject status = json.getJSONObject("status"); + status.put("type", "mute"); + status.put("reason", reason); + status.put("until", time); + json.put("status", status); + + JSONArray history = json.getJSONArray("history"); + history.put(new JSONObject().put("type", "mute").put("reason", reason).put("date",new Date().getTime()).put("by", sender.getIdLong())); + json.put("history", history); + + table.setData(guild.getIdLong(), target.getUser().getIdLong(), json.toString()); + + Ken.getInstance().getDatabase().getUserTable().setData(target.getIdLong(), target.getUser().getName(), Integer.parseInt(target.getUser().getDiscriminator())); + + PrivateChannel channel = target.getUser().openPrivateChannel().complete(); + if(channel != null){ + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .setColor(new Color(250,140,140)) + .setTitle("**Muted**") + .appendDescription("You have been muted from "+guild.getName()+"\n") + .appendDescription("`By:` " + sender.getEffectiveName()+"\n") + .appendDescription("`Reason:` " + reason+"\n") + .appendDescription("`Until:` " + date); + channel.sendMessageEmbeds(builder.build()).queue(); + } + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .appendDescription(String.format("Muted %s for %s until %s", target, reason, date)); + return Response.success(builder.build()); + } + } diff --git a/src/main/java/net/tylermurphy/ken/command/main/Purge.java b/src/main/java/net/tylermurphy/ken/command/moderation/Purge.java index 1bdabb0..ab7eeea 100644 --- a/src/main/java/net/tylermurphy/ken/command/main/Purge.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/Purge.java @@ -1,4 +1,4 @@ -package net.tylermurphy.ken.command.main; +package net.tylermurphy.ken.command.moderation; import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Guild; diff --git a/src/main/java/net/tylermurphy/ken/command/moderation/TempBan.java b/src/main/java/net/tylermurphy/ken/command/moderation/TempBan.java index 4c1d7a3..00780fc 100644 --- a/src/main/java/net/tylermurphy/ken/command/moderation/TempBan.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/TempBan.java @@ -20,7 +20,6 @@ import org.json.JSONObject; import java.awt.*; import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.Date; import java.util.List; @@ -28,17 +27,15 @@ public class TempBan { @Command(name="tempban", description="Temp ban a user and delete all messages in past 24h") @Option(name="member", description="Member to temp-ban", type= OptionType.USER, required=true) - @Option(name="days", description="Days for temp ban", type= OptionType.INTEGER, required=true) - @Option(name="hours", description="Hours for temp ban", type= OptionType.INTEGER, required=true) + @Option(name="time", description="Time for temp ban", type= OptionType.STRING, required=true) @Option(name="reason", description="Reason to temp-ban", type=OptionType.STRING, required=true) @Option(name="delete_messages", description="Delete messages from past 24h", type=OptionType.BOOLEAN, required=true) @Requirement(Permission.BAN_MEMBERS) public Response execute(Member sender, List<Object> args, Guild guild){ Member target = (Member) args.get(0); - int days = (int) args.get(1); - int hours = (int) args.get(2); - String reason = (String) args.get(3); - boolean purge = (boolean) args.get(4); + String timeString = (String) args.get(1); + String reason = (String) args.get(2); + boolean purge = (boolean) args.get(3); if(target == sender){ return Response.error("You are not allowed to do this to yourself"); } @@ -54,36 +51,35 @@ public class TempBan { if(guild.getOwner() == target){ return Response.error("You cannot to this to the server owner"); } - if(hours < 0){ - return Response.error("Hours must be 0 or greater"); - } - if(days < 0){ - return Response.error("Days must be 0 or greater"); - } - if(days == 0 && hours == 0){ - return Response.error("Time to ban cannot be 0"); - } - try { guild.retrieveBan(target).complete(); return Response.error("User is already banned from this server"); } catch (ErrorResponseException ignored) {} - - Calendar cal = Calendar.getInstance(); - cal.setTime(new Date()); - cal.add(Calendar.DATE, days); - cal.add(Calendar.HOUR, hours); - SimpleDateFormat format = new SimpleDateFormat("MMM d, y ha zz"); - String date = format.format(cal.getTime()); + long time = Checks.convertTime(timeString); + if(time == 0L){ + return Response.error("Time to ban cannot be 0"); + } + SimpleDateFormat format = new SimpleDateFormat("MMM d, y h:ma zz"); + String date = format.format(time); ModerationTable table = Ken.getInstance().getDatabase().getModerationTable(); String data = table.getData(guild.getIdLong(), target.getUser().getIdLong()); JSONObject json = table.updateData(data); + try { + guild.removeTimeout(target).queue(); + } catch (Exception ignored){} + + try { + guild.ban(target,purge ? 1 : 0,reason).queue(); + } catch (Exception e){ + return Response.error("Failed to temp ban user"); + } + JSONObject status = json.getJSONObject("status"); status.put("type", "temp-ban"); status.put("reason", reason); - status.put("until", cal.getTime().getTime()); + status.put("until", time); json.put("status", status); JSONArray history = json.getJSONArray("history"); @@ -105,7 +101,6 @@ public class TempBan { .appendDescription("`Until:` " + date); channel.sendMessageEmbeds(builder.build()).queue(); } - guild.ban(target,purge ? 1 : 0,reason).queue(); EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() .appendDescription(String.format("Temporarily banned %s for %s until %s", target, reason, date)); return Response.success(builder.build()); diff --git a/src/main/java/net/tylermurphy/ken/command/moderation/UnBan.java b/src/main/java/net/tylermurphy/ken/command/moderation/UnBan.java index e871a0b..0628131 100644 --- a/src/main/java/net/tylermurphy/ken/command/moderation/UnBan.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/UnBan.java @@ -62,6 +62,12 @@ public class UnBan { String data = table.getData(guild.getIdLong(), target.getIdLong()); JSONObject json = table.updateData(data); + try { + guild.unban(target).queue(); + } catch (Exception e){ + return Response.error("Failed to unban user"); + } + JSONObject status = json.getJSONObject("status"); status.put("type", "None"); status.put("reason", ""); @@ -79,14 +85,13 @@ public class UnBan { PrivateChannel channel = target.openPrivateChannel().complete(); if(channel != null){ EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() - .setColor(Color.green) + .setColor(new Color(138,255,138)) .setTitle("**Unbanned**") .appendDescription("You have been unbanned from "+guild.getName()+"\n") .appendDescription("`By:` " + sender.getEffectiveName()+"\n") .appendDescription("`Reason:` " + reason); channel.sendMessageEmbeds(builder.build()).queue(); } - guild.unban(target).queue(); EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() .appendDescription(String.format("Unbanned %s for %s", target, reason)); return Response.success(builder.build()); diff --git a/src/main/java/net/tylermurphy/ken/command/moderation/UnMute.java b/src/main/java/net/tylermurphy/ken/command/moderation/UnMute.java index 99ef6de..df60a8d 100644 --- a/src/main/java/net/tylermurphy/ken/command/moderation/UnMute.java +++ b/src/main/java/net/tylermurphy/ken/command/moderation/UnMute.java @@ -1,4 +1,77 @@ package net.tylermurphy.ken.command.moderation; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.tylermurphy.ken.Ken; +import net.tylermurphy.ken.command.Response; +import net.tylermurphy.ken.command.annotation.Command; +import net.tylermurphy.ken.command.annotation.Option; +import net.tylermurphy.ken.command.annotation.Requirement; +import net.tylermurphy.ken.database.ModerationTable; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.awt.*; +import java.util.Date; +import java.util.List; + public class UnMute { + + @Command(name="unmute", description="Unmute a user") + @Option(name="member", description="Member to unmute", type= OptionType.USER, required=true) + @Option(name="reason", description="Reason for mute", type=OptionType.STRING, required=true) + @Requirement(Permission.MODERATE_MEMBERS) + public Response execute(Member sender, List<Object> args, Guild guild){ + Member target = (Member) args.get(0); + String reason = (String) args.get(1); + + if(target.getUser() == sender.getUser()){ + return Response.error("You are not allowed to do this to yourself"); + } + + if(!target.isTimedOut()){ + return Response.error("User is not muted"); + } + + ModerationTable table = Ken.getInstance().getDatabase().getModerationTable(); + String data = table.getData(guild.getIdLong(), target.getIdLong()); + JSONObject json = table.updateData(data); + + try { + guild.removeTimeout(target).queue(); + } catch (Exception e){ + return Response.error("Failed to unmute user"); + } + + JSONObject status = json.getJSONObject("status"); + status.put("type", "None"); + status.put("reason", ""); + status.put("until", 0L); + json.put("status", status); + + JSONArray history = json.getJSONArray("history"); + history.put(new JSONObject().put("type", "unmute").put("reason", reason).put("date",new Date().getTime()).put("by", sender.getIdLong())); + json.put("history", history); + + table.setData(guild.getIdLong(), target.getIdLong(), json.toString()); + + Ken.getInstance().getDatabase().getUserTable().setData(target.getIdLong(), target.getUser().getName(), Integer.parseInt(target.getUser().getDiscriminator())); + + PrivateChannel channel = target.getUser().openPrivateChannel().complete(); + if(channel != null){ + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .setColor(new Color(138,255,138)) + .setTitle("**Unmuted**") + .appendDescription("You have been un muted from "+guild.getName()+"\n") + .appendDescription("`By:` " + sender.getEffectiveName()+"\n") + .appendDescription("`Reason:` " + reason); + channel.sendMessageEmbeds(builder.build()).queue(); + } + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .appendDescription(String.format("Unmutted %s for %s", target, reason)); + return Response.success(builder.build()); + } + } diff --git a/src/main/java/net/tylermurphy/ken/database/ModerationTable.java b/src/main/java/net/tylermurphy/ken/database/ModerationTable.java index 9e0061d..6849fae 100644 --- a/src/main/java/net/tylermurphy/ken/database/ModerationTable.java +++ b/src/main/java/net/tylermurphy/ken/database/ModerationTable.java @@ -5,6 +5,8 @@ import org.json.JSONArray; import org.json.JSONObject; import java.sql.*; +import java.util.ArrayList; +import java.util.List; import java.util.function.Consumer; public class ModerationTable { @@ -61,16 +63,18 @@ public class ModerationTable { public void callOverdue(long date, Consumer<String[]> callback){ String sql = "SELECT * FROM moderation_data WHERE until < ? AND until > 0"; + List<String[]> store = new ArrayList<>(); try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { statement.setLong(1, date); ResultSet rs = statement.executeQuery(); while (rs.next()){ String[] data = {String.valueOf(rs.getLong("guild_id")), String.valueOf(rs.getLong("user_id")), rs.getString("data")}; - callback.accept(data); + store.add(data); } } catch (SQLException e) { Ken.getInstance().getLogger().error("SQL Error: " + e.getMessage()); } + store.forEach(callback); } public JSONObject updateData(String data) { diff --git a/src/main/java/net/tylermurphy/ken/util/Checks.java b/src/main/java/net/tylermurphy/ken/util/Checks.java index 7c3daa1..3609b02 100644 --- a/src/main/java/net/tylermurphy/ken/util/Checks.java +++ b/src/main/java/net/tylermurphy/ken/util/Checks.java @@ -3,6 +3,8 @@ package net.tylermurphy.ken.util; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Role; +import java.util.Calendar; +import java.util.Date; import java.util.List; public class Checks { @@ -23,6 +25,7 @@ public class Checks { }).orElse(null); } + @SuppressWarnings("BooleanMethodIsAlwaysInverted") public static boolean getRolePermission(Role first, Role second){ if(first == null) return false; if(second == null) return true; @@ -30,4 +33,43 @@ public class Checks { return first.getPosition() > second.getPosition(); } + public static long convertTime(String pattern){ + Date date = new Date(); + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + String[] data = pattern.toLowerCase().split("(?<!^)(?=\\D)|(?<=\\D)"); + for(int i=0; i<data.length;){ + if(i+1 == data.length) break; + if(!isInt(data[i])) { i++; continue; } + if(isInt(data[i+1])) { i++; continue; } + int n = Integer.parseInt(data[i]); + char c = data[i+1].charAt(0); + switch (c) { + case 'y' -> cal.add(Calendar.YEAR, n); + case 'm' -> cal.add(Calendar.MONTH, n); + case 'w' -> cal.add(Calendar.WEEK_OF_YEAR, n); + case 'd' -> cal.add(Calendar.DAY_OF_YEAR, n); + case 'h' -> cal.add(Calendar.HOUR, n); + } + i+=2; + } + Date newDate = cal.getTime(); + if(newDate.getTime() == date.getTime()) { + return 0L; + } else { + return newDate.getTime(); + } + } + + public static boolean isInt(String number){ + try { + Integer.parseInt(number); + return true; + } catch (NumberFormatException e){ + return false; + } + } + + + } diff --git a/src/main/java/net/tylermurphy/ken/util/ModerationChecker.java b/src/main/java/net/tylermurphy/ken/util/ModerationChecker.java new file mode 100644 index 0000000..0999e92 --- /dev/null +++ b/src/main/java/net/tylermurphy/ken/util/ModerationChecker.java @@ -0,0 +1,64 @@ +package net.tylermurphy.ken.util; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.PrivateChannel; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.exceptions.ErrorResponseException; +import net.tylermurphy.ken.Ken; +import net.tylermurphy.ken.database.ModerationTable; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.awt.*; +import java.util.*; +import java.util.List; + +public class ModerationChecker { + private final Timer timer = new Timer(); + + public void start(){ + int minutes = 30; + timer.scheduleAtFixedRate(new TimerTask() { + public void run() { + Ken.getInstance().getDatabase().getModerationTable().callOverdue(new Date().getTime(), data -> { + long guildId = Long.parseLong(data[0]); + long userId = Long.parseLong(data[1]); + JSONObject json = new JSONObject(data[2]); + JSONObject status = json.getJSONObject("status"); + String type = status.getString("type"); + if(!type.equals("temp-ban")) return; + Guild guild = Ken.getInstance().getGuildById(guildId); + if(guild == null) return; + List<Guild.Ban> bans = guild.retrieveBanList().complete(); + Optional<Guild.Ban> ban = bans.stream().filter(temp-> temp.getUser().getIdLong() == userId).findFirst(); + if(ban.isEmpty()) return; + User user = ban.get().getUser(); + try { + guild.unban(user).queue(); + PrivateChannel channel = user.openPrivateChannel().complete(); + if(channel != null){ + EmbedBuilder builder = Ken.getInstance().getDefaultEmbed() + .setColor(new Color(138,255,138)) + .setTitle("**Unbanned**") + .appendDescription("You have been unbanned from "+guild.getName()+"\n") + .appendDescription("`By:` Automated System\n") + .appendDescription("`Reason:` Ban period ended"); + channel.sendMessageEmbeds(builder.build()).queue(); + } + status.put("type", "None"); + status.put("reason", ""); + status.put("until", 0L); + + JSONArray history = json.getJSONArray("history"); + history.put(new JSONObject().put("type", "unban").put("reason", "Ban Period Ended").put("date",new Date().getTime()).put("by", guild.getSelfMember().getIdLong())); + json.put("history", history); + json.put("status", status); + Ken.getInstance().getDatabase().getModerationTable().setData(guildId, userId, json.toString()); + } catch (ErrorResponseException ignored) {} + }); + } + }, 0, minutes * 60 * 1000); + } + +} |