summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/net/tylermurphy/ken/Ken.java7
-rw-r--r--src/main/java/net/tylermurphy/ken/command/Responder.java15
-rw-r--r--src/main/java/net/tylermurphy/ken/command/main/Help.java6
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/Ban.java11
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/History.java54
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/Kick.java15
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/Mute.java104
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/Purge.java (renamed from src/main/java/net/tylermurphy/ken/command/main/Purge.java)2
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/TempBan.java47
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/UnBan.java9
-rw-r--r--src/main/java/net/tylermurphy/ken/command/moderation/UnMute.java73
-rw-r--r--src/main/java/net/tylermurphy/ken/database/ModerationTable.java6
-rw-r--r--src/main/java/net/tylermurphy/ken/util/Checks.java42
-rw-r--r--src/main/java/net/tylermurphy/ken/util/ModerationChecker.java64
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);
+ }
+
+}