diff --git a/pom.xml b/pom.xml index deaa85d..b662f98 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,6 @@ UTF-8 1.8 1.8 - 2.3.21 @@ -90,41 +89,6 @@ - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - true - - - kotlin-compile - compile - - compile - - - - src/main/kotlin - - src/main/java - - - - - kotlin-test-compile - test-compile - - test-compile - - - - src/test/kotlin - src/test/java - - - - - - org.apache.maven.plugins maven-compiler-plugin 3.15.0 diff --git a/src/main/java/com/jagrosh/vortex/Vortex.java b/src/main/java/com/jagrosh/vortex/Vortex.java index ec49ff4..88b716e 100644 --- a/src/main/java/com/jagrosh/vortex/Vortex.java +++ b/src/main/java/com/jagrosh/vortex/Vortex.java @@ -125,8 +125,8 @@ new SilentbanCmd(this), new UnbanCmd(this), new CleanCmd(this), - new VoicemoveCmd(this), - // new VoicekickCmd(this), + // new VoicemoveCmd(this), + new VoicekickCmd(this), new MuteCmd(this), new UnmuteCmd(this), new RaidCmd(this), @@ -167,11 +167,11 @@ // Tools new AnnounceCmd(), - // new AuditCmd(), + new AuditCmd(), new DehoistCmd(), new ExportCmd(this), new InvitepruneCmd(this), - // new LookupCmd(this), + new LookupCmd(this), // Owner new EvalCmd(this), diff --git a/src/main/java/com/jagrosh/vortex/automod/AutoMod.java b/src/main/java/com/jagrosh/vortex/automod/AutoMod.java index b56dc20..f6d0186 100644 --- a/src/main/java/com/jagrosh/vortex/automod/AutoMod.java +++ b/src/main/java/com/jagrosh/vortex/automod/AutoMod.java @@ -64,7 +64,7 @@ private String[] refLinkList; private final URLResolver urlResolver; - // private final InviteResolver inviteResolver = new InviteResolver(); + private final InviteResolver inviteResolver = new InviteResolver(); private final CopypastaResolver copypastaResolver = new CopypastaResolver(); private final FixedCache spams = new FixedCache<>(3000); private final HashMap latestGuildJoin = new HashMap<>(); @@ -288,8 +288,7 @@ } if(preventInvites) { - //FIXME!! - //runAntiInvite(settings, currentStatus, message, inviteWhitelist); + runAntiInvite(settings, currentStatus, message, inviteWhitelist); } runAntiMention(settings, currentStatus, message); runAntiMentionRoles(settings, currentStatus, message); @@ -343,10 +342,9 @@ { String code = resolved.replaceAll(INVITE_LINK, "$1"); LOG.info("Delayed resolving invite in " + message.getGuild().getId() + ": " + code); - // FIXME!!! - // long invite = inviteResolver.resolve(code, message.getJDA()); - // if(invite != message.getGuild().getIdLong() && !inviteWhitelist.contains(invite)) - // containsInvite = true; + long invite = inviteResolver.resolve(code, message.getJDA()); + if(invite != message.getGuild().getIdLong() && !inviteWhitelist.contains(invite)) + containsInvite = true; containsInvite = false; } if(settings.refStrikes>0) @@ -478,29 +476,28 @@ } } - // FIXME!!! - // private void runAntiInvite(AutomodSettings settings, AutomodStatus currentStatus, Message message, List inviteWhitelist) - // { - // if(settings.inviteStrikes <= 0) - // return; - // List invites = new ArrayList<>(); - // Matcher m = INVITES.matcher(message.getContentRaw()); - // while(m.find()) - // invites.add(m.group(1)); - // LOG.trace("Found "+invites.size()+" invites."); - // for(String inviteCode : invites) - // { - // long gid = inviteResolver.resolve(inviteCode, message.getJDA()); - // LOG.info("Resolving invite in " + message.getGuild().getId() + ": " + inviteCode + " -> " + gid); - // if(gid != message.getGuild().getIdLong() && !inviteWhitelist.contains(gid)) - // { - // currentStatus.addStrikes(settings.inviteStrikes); - // currentStatus.appendReason("Advertising"); - // currentStatus.deleteMessage(); - // break; - // } - // } - // } + private void runAntiInvite(AutomodSettings settings, AutomodStatus currentStatus, Message message, List inviteWhitelist) + { + if(settings.inviteStrikes <= 0) + return; + List invites = new ArrayList<>(); + Matcher m = INVITES.matcher(message.getContentRaw()); + while(m.find()) + invites.add(m.group(1)); + LOG.trace("Found "+invites.size()+" invites."); + for(String inviteCode : invites) + { + long gid = inviteResolver.resolve(inviteCode, message.getJDA()); + LOG.info("Resolving invite in " + message.getGuild().getId() + ": " + inviteCode + " -> " + gid); + if(gid != message.getGuild().getIdLong() && !inviteWhitelist.contains(gid)) + { + currentStatus.addStrikes(settings.inviteStrikes); + currentStatus.appendReason("Advertising"); + currentStatus.deleteMessage(); + break; + } + } + } private void runAntiReferral(AutomodSettings settings, AutomodStatus currentStatus, Message message) { diff --git a/src/main/java/com/jagrosh/vortex/automod/InviteResolver.java b/src/main/java/com/jagrosh/vortex/automod/InviteResolver.java new file mode 100644 index 0000000..5bee2a6 --- /dev/null +++ b/src/main/java/com/jagrosh/vortex/automod/InviteResolver.java @@ -0,0 +1,65 @@ +/* + * Copyright 2018 John Grosh (john.a.grosh@gmail.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jagrosh.vortex.automod; + +import com.jagrosh.vortex.utils.FixedCache; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Invite; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author John Grosh (john.a.grosh@gmail.com) + */ +public class InviteResolver +{ + private final Logger log = LoggerFactory.getLogger(InviteResolver.class); + private final FixedCache cached = new FixedCache<>(5000); + + public Invite resolveFull(String code, JDA jda) + { + log.debug("Attempting to resolve " + code); + try + { + return Invite.resolve(jda, code).complete(); + } + catch(Exception ex) + { + log.warn("Failed to resolve full invite context for code: " + code, ex); + return null; + } + } + + public long resolve(String code, JDA jda) + { + log.debug("Attempting to resolve " + code); + if(cached.contains(code)) + return cached.get(code); + try + { + Invite invite = Invite.resolve(jda, code).complete(); + long guildId = (invite.getGuild() != null) ? invite.getGuild().getIdLong() : 0L; + cached.put(code, guildId); + return guildId; + } + catch(Exception ex) + { + cached.put(code, 0L); + return 0L; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/jagrosh/vortex/automod/InviteResolver.java.no b/src/main/java/com/jagrosh/vortex/automod/InviteResolver.java.no deleted file mode 100644 index 91d3555..0000000 --- a/src/main/java/com/jagrosh/vortex/automod/InviteResolver.java.no +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2018 John Grosh (john.a.grosh@gmail.com). - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.jagrosh.vortex.automod; - -import com.jagrosh.vortex.utils.FixedCache; -import java.io.IOException; -import java.time.OffsetDateTime; -import java.util.Collections; -import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.entities.channel.ChannelType; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.Invite; -import net.dv8tion.jda.api.utils.MiscUtil; -import net.dv8tion.jda.internal.entities.InviteImpl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author John Grosh (john.a.grosh@gmail.com) - */ -public class InviteResolver -{ - private final static String[] BASE_URLS = {"discordapp.com", "ptb.discordapp.com", "canary.discordapp.com", - /*"discord.com",*/ "ptb.discord.com", "canary.discord.com", "discord.co", "watchanimeattheoffice.com", "discord.new"}; - private final Logger log = LoggerFactory.getLogger(InviteResolver.class); - private final FixedCache cached = new FixedCache<>(5000); - private final OkHttpClient client = new OkHttpClient.Builder().build(); - - public Invite resolveFull(String code, JDA jda) - { - return resolveFull(code, jda.getToken()); - } - - public Invite resolveFull(String code, String token) - { - log.debug("Attempting to resolve " + code); - try - { - return getInvite(code, token); - } - catch(Exception ex) - { - return null; - } - } - - public long resolve(String code, JDA jda) - { - return resolve(code, jda.getToken()); - } - - public long resolve(String code, String token) - { - log.debug("Attempting to resolve " + code); - if(cached.contains(code)) - return cached.get(code); - try - { - long guildId = getInviteGuild(code, token); - //long guildId = Invite.resolve(jda, code).complete(false).getGuild().getIdLong(); - cached.put(code, guildId); - return guildId; - } - catch(Exception ex) - { - cached.put(code, 0L); - return 0L; - } - } - - private long getInviteGuild(String code, String token) throws IOException - { - JSONObject json = getInviteJSON(code, token); - if(json != null) - return MiscUtil.parseSnowflake(json.getJSONObject("guild").getString("id")); - return 0L; - } - - private InviteImpl getInvite(String code, String token) throws IOException - { - JSONObject json = getInviteJSON(code, token); - if(json != null) - { - Invite.Channel channel; - if(json.has("channel")) - { - JSONObject c = json.getJSONObject("channel"); - channel = new InviteImpl.ChannelImpl(c.optLong("id"), c.optString("name"), c.optInt("type") == 0 ? ChannelType.TEXT : ChannelType.UNKNOWN); - } - else - channel = null; - Invite.Guild guild; - if(json.has("guild")) - { - JSONObject g = json.getJSONObject("guild"); - guild = new InviteImpl.GuildImpl(g.optLong("id"), g.optString("icon"), g.optString("name"), g.optString("splash"), Guild.VerificationLevel.UNKNOWN, -1, -1, Collections.emptySet()); - } - else - guild = null; - return new InviteImpl(null, code, false, null, 0, 0, false, OffsetDateTime.now(), 0, channel, guild, null, null, Invite.InviteType.GUILD); - } - return null; - } - - private JSONObject getInviteJSON(String code, String token) throws IOException - { - Response res = client.newCall(new Request.Builder().get() - .addHeader("Authorization", token) - .addHeader("User-Agent", "DiscordBot (FryeInviteResolverBasedOnVortex, 1.0)") - .url("https://" + rand(BASE_URLS) + "/api/invites/" + code) - .build()).execute(); - if(res.isSuccessful()) - { - return new JSONObject(res.body().string()); - } - - // if it failed, log why (usually unknown invite or cloudflare issue) - try - { - String message = new JSONObject(res.body().string()).getString("message"); - log.warn(String.format("Unsuccessful resolving '%s': %s", code, message)); - } - catch(Exception ex) - { - log.warn(String.format("Unsuccessful resolving '%s' | Headers: %s | Body: %s", code, - res.headers().toMultimap().toString(), res.body() == null ? null : res.body().string())); - } - return null; - } - - private T rand(T[] items) - { - return items[(int)(Math.random() * items.length)]; - } -} diff --git a/src/main/java/com/jagrosh/vortex/commands/moderation/VoicekickCmd.java b/src/main/java/com/jagrosh/vortex/commands/moderation/VoicekickCmd.java new file mode 100644 index 0000000..c14bd12 --- /dev/null +++ b/src/main/java/com/jagrosh/vortex/commands/moderation/VoicekickCmd.java @@ -0,0 +1,111 @@ +/* + * Copyright 2016 John Grosh (jagrosh). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jagrosh.vortex.commands.moderation; + +import java.util.LinkedList; +import com.jagrosh.jdautilities.command.CommandEvent; +import com.jagrosh.vortex.Vortex; +import com.jagrosh.vortex.commands.CommandExceptionListener.CommandErrorException; +import com.jagrosh.vortex.commands.ModCommand; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import com.jagrosh.vortex.utils.ArgsUtil; +import com.jagrosh.vortex.utils.FormatUtil; +import com.jagrosh.vortex.utils.LogUtil; +import java.util.List; +import net.dv8tion.jda.api.entities.Role; + +/** + * + * @author John Grosh (jagrosh) + */ +public class VoicekickCmd extends ModCommand +{ + public VoicekickCmd(Vortex vortex) + { + super(vortex, Permission.VOICE_MOVE_OTHERS); + this.name = "voicekick"; + this.aliases = new String[]{"vckick"}; + this.arguments = "<@users> [reason]"; + this.help = "removes users from voice channels"; + this.botPermissions = new Permission[]{Permission.MANAGE_CHANNEL}; + } + + @Override + protected void execute(CommandEvent event) + { + if(!event.getSelfMember().hasPermission(Permission.VOICE_MOVE_OTHERS, Permission.VOICE_CONNECT)) + throw new CommandErrorException("I need permission to connect to voice channels and move members to do that!"); + ArgsUtil.ResolvedArgs args = ArgsUtil.resolve(event.getArgs(), event.getGuild()); + if(args.isEmpty()) + { + event.replyError("Please include at least one user to kick from voice (@mention or ID)!"); + return; + } + String reason = LogUtil.auditReasonFormat(event.getMember(), args.reason); + Role modrole = vortex.getDatabase().settings.getSettings(event.getGuild()).getModeratorRole(event.getGuild()); + StringBuilder builder = new StringBuilder(); + List toKick = new LinkedList<>(); + + args.members.forEach(m -> + { + if(!event.getMember().canInteract(m)) + builder.append("\n").append(event.getClient().getError()).append(" You do not have permission to voicekick ").append(FormatUtil.formatUser(m.getUser())); + else if(!event.getSelfMember().canInteract(m)) + builder.append("\n").append(event.getClient().getError()).append(" I am unable to voicekick ").append(FormatUtil.formatUser(m.getUser())); + else if(!m.getVoiceState().inAudioChannel()) + builder.append("\n").append(event.getClient().getWarning()).append(" ").append(FormatUtil.formatUser(m.getUser())).append(" is not in a voice channel!"); + else if(modrole!=null && m.getRoles().contains(modrole)) + builder.append("\n").append(event.getClient().getError()).append(" I won't voicekick ").append(FormatUtil.formatUser(m.getUser())).append(" because they have the Moderator Role"); + else + toKick.add(m); + }); + + args.unresolved.forEach(un -> builder.append("\n").append(event.getClient().getWarning()).append(" Could not resolve `").append(un).append("` to a member")); + + args.users.forEach(u -> builder.append("\n").append(event.getClient().getWarning()).append("The user ").append(FormatUtil.formatUser(u)).append(" is not in this server.")); + + args.ids.forEach(id -> builder.append("\n").append(event.getClient().getWarning()).append("The user <@").append(id).append("> is not in this server.")); + + if(toKick.isEmpty()) + { + event.reply(builder.toString()); + return; + } + + if(toKick.size() > 5) + event.reactSuccess(); + + // do this async because its a nightmare to do it sync + event.async(() -> + { + for(int i=0; i toKick = new LinkedList<>(); - - args.members.forEach(m -> - { - if(!event.getMember().canInteract(m)) - builder.append("\n").append(event.getClient().getError()).append(" You do not have permission to voicekick ").append(FormatUtil.formatUser(m.getUser())); - else if(!event.getSelfMember().canInteract(m)) - builder.append("\n").append(event.getClient().getError()).append(" I am unable to voicekick ").append(FormatUtil.formatUser(m.getUser())); - else if(!m.getVoiceState().inVoiceChannel()) - builder.append("\n").append(event.getClient().getWarning()).append(" ").append(FormatUtil.formatUser(m.getUser())).append(" is not in a voice channel!"); - else if(modrole!=null && m.getRoles().contains(modrole)) - builder.append("\n").append(event.getClient().getError()).append(" I won't voicekick ").append(FormatUtil.formatUser(m.getUser())).append(" because they have the Moderator Role"); - else - toKick.add(m); - }); - - args.unresolved.forEach(un -> builder.append("\n").append(event.getClient().getWarning()).append(" Could not resolve `").append(un).append("` to a member")); - - args.users.forEach(u -> builder.append("\n").append(event.getClient().getWarning()).append("The user ").append(FormatUtil.formatUser(u)).append(" is not in this server.")); - - args.ids.forEach(id -> builder.append("\n").append(event.getClient().getWarning()).append("The user <@").append(id).append("> is not in this server.")); - - if(toKick.isEmpty()) - { - event.reply(builder.toString()); - return; - } - - if(toKick.size() > 5) - event.reactSuccess(); - - // do this async because its a nightmare to do it sync - event.async(() -> - { - for(int i=0; i list = FinderUtil.findVoiceChannels(event.getArgs(), event.getGuild()); +// if(list.isEmpty()) +// { +// event.replyError("No voice channel found matching `"+event.getArgs()+"`!"); +// return; +// } +// if(list.size()>1) +// { +// event.replyWarning(FormatUtil.filterEveryone(FormatUtil.listOfVoice(list, event.getArgs()))); +// return; +// } +// vc = list.get(0); +// } +// else +// { +// vc = event.getMember().getVoiceState().getChannel(); +// } +// if(!event.getMember().hasPermission(Permission.VOICE_MOVE_OTHERS)) +// { +// event.replyError("You don't have permission to move users out of **"+vc.getName()+"**!"); +// return; +// } +// if(!event.getSelfMember().hasPermission(Permission.VOICE_MOVE_OTHERS)) +// { +// event.replyError("I don't have permission to move users out of **"+vc.getName()+"**!"); +// return; +// } +// try +// { +// event.getGuild().getAudioManager().openAudioConnection(vc); +// } +// catch(Exception e) +// { +// event.replyWarning(FormatUtil.filterEveryone("I could not connect to **"+vc.getName()+"**")); +// event.getGuild().getAudioManager().closeAudioConnection(); +// return; +// } +// vortex.getEventWaiter().waitForEvent(GuildVoiceMoveEvent.class, +// (GuildVoiceMoveEvent e) -> +// e.getGuild().equals(event.getGuild()) && e.getMember().equals(event.getGuild().getSelfMember()), +// (GuildVoiceMoveEvent e) -> { +// event.getGuild().getAudioManager().closeAudioConnection(); +// e.getChannelLeft().getMembers().stream().forEach(m -> event.getGuild().moveVoiceMember(m, e.getChannelJoined()).queue()); +// }, 1, TimeUnit.MINUTES, () -> { +// event.getGuild().getAudioManager().closeAudioConnection(); +// event.replyWarning("You waited too long, "+event.getMember().getAsMention()); +// }); +// event.reply("\uD83C\uDF9B Now, move me and I'll drag users to a new voice channel."); // 🎛 +// // failsafe to leave voice channel +// event.getClient().getScheduleExecutor().schedule(() -> event.getGuild().getAudioManager().closeAudioConnection(), 2, TimeUnit.MINUTES); +// } + +// } + + +// just move the member manually lazy ass \ No newline at end of file diff --git a/src/main/java/com/jagrosh/vortex/commands/moderation/VoicemoveCmd.java.fixmel8r b/src/main/java/com/jagrosh/vortex/commands/moderation/VoicemoveCmd.java.fixmel8r deleted file mode 100644 index 3f55736..0000000 --- a/src/main/java/com/jagrosh/vortex/commands/moderation/VoicemoveCmd.java.fixmel8r +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2016 John Grosh (jagrosh). - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.jagrosh.vortex.commands.moderation; - -import java.util.List; -import java.util.concurrent.TimeUnit; -import com.jagrosh.jdautilities.command.CommandEvent; -import com.jagrosh.jdautilities.commons.utils.FinderUtil; -import com.jagrosh.vortex.Vortex; -import com.jagrosh.vortex.commands.ModCommand; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.channel.concrete.VoiceChannel; -import net.dv8tion.jda.api.events.guild.voice.GuildVoiceMoveEvent; -import com.jagrosh.vortex.utils.FormatUtil; - -/** - * - * @author John Grosh (jagrosh) - */ -public class VoicemoveCmd extends ModCommand -{ - public VoicemoveCmd(Vortex vortex) - { - super(vortex, Permission.VOICE_MOVE_OTHERS); - this.name = "voicemove"; - this.aliases = new String[]{"magnet"}; - this.help = "mass-moves voice channel users"; - this.arguments = "[channel]"; - this.cooldown = 20; - this.cooldownScope = CooldownScope.GUILD; - } - - @Override - protected void execute(CommandEvent event) - { - if(event.getGuild().getSelfMember().getVoiceState().inVoiceChannel()) - { - event.replyWarning("I am already in a voice channel; move me to drag all users."); - return; - } - if(event.getArgs().isEmpty() && !event.getMember().getVoiceState().inVoiceChannel()) - { - event.replyError("You must be in or specify a voice channel to move users from!"); - return; - } - VoiceChannel vc; - if(!event.getArgs().isEmpty()) - { - List list = FinderUtil.findVoiceChannels(event.getArgs(), event.getGuild()); - if(list.isEmpty()) - { - event.replyError("No voice channel found matching `"+event.getArgs()+"`!"); - return; - } - if(list.size()>1) - { - event.replyWarning(FormatUtil.filterEveryone(FormatUtil.listOfVoice(list, event.getArgs()))); - return; - } - vc = list.get(0); - } - else - { - vc = event.getMember().getVoiceState().getChannel(); - } - if(!event.getMember().hasPermission(Permission.VOICE_MOVE_OTHERS)) - { - event.replyError("You don't have permission to move users out of **"+vc.getName()+"**!"); - return; - } - if(!event.getSelfMember().hasPermission(Permission.VOICE_MOVE_OTHERS)) - { - event.replyError("I don't have permission to move users out of **"+vc.getName()+"**!"); - return; - } - try - { - event.getGuild().getAudioManager().openAudioConnection(vc); - } - catch(Exception e) - { - event.replyWarning(FormatUtil.filterEveryone("I could not connect to **"+vc.getName()+"**")); - event.getGuild().getAudioManager().closeAudioConnection(); - return; - } - vortex.getEventWaiter().waitForEvent(GuildVoiceMoveEvent.class, - (GuildVoiceMoveEvent e) -> - e.getGuild().equals(event.getGuild()) && e.getMember().equals(event.getGuild().getSelfMember()), - (GuildVoiceMoveEvent e) -> { - event.getGuild().getAudioManager().closeAudioConnection(); - e.getChannelLeft().getMembers().stream().forEach(m -> event.getGuild().moveVoiceMember(m, e.getChannelJoined()).queue()); - }, 1, TimeUnit.MINUTES, () -> { - event.getGuild().getAudioManager().closeAudioConnection(); - event.replyWarning("You waited too long, "+event.getMember().getAsMention()); - }); - event.reply("\uD83C\uDF9B Now, move me and I'll drag users to a new voice channel."); // 🎛 - // failsafe to leave voice channel - event.getClient().getScheduleExecutor().schedule(() -> event.getGuild().getAudioManager().closeAudioConnection(), 2, TimeUnit.MINUTES); - } - -} diff --git a/src/main/java/com/jagrosh/vortex/commands/settings/MuteroleCmd.java b/src/main/java/com/jagrosh/vortex/commands/settings/MuteroleCmd.java index 550009b..223163c 100644 --- a/src/main/java/com/jagrosh/vortex/commands/settings/MuteroleCmd.java +++ b/src/main/java/com/jagrosh/vortex/commands/settings/MuteroleCmd.java @@ -56,7 +56,7 @@ else if(event.getArgs().equalsIgnoreCase("none") || event.getArgs().equalsIgnoreCase("off")) { vortex.getDatabase().settings.setMutedRole(event.getGuild(), null); - event.replySuccess("Vortex will use Timeouts instead of a Mute role."); + event.replySuccess("Frye will use Timeouts instead of a Mute role."); return; } diff --git a/src/main/java/com/jagrosh/vortex/commands/tools/AuditCmd.disabled.no.fuckoff.fucku b/src/main/java/com/jagrosh/vortex/commands/tools/AuditCmd.disabled.no.fuckoff.fucku deleted file mode 100644 index a8b0498..0000000 --- a/src/main/java/com/jagrosh/vortex/commands/tools/AuditCmd.disabled.no.fuckoff.fucku +++ /dev/null @@ -1,241 +0,0 @@ -// /* -// * Copyright 2018 John Grosh (john.a.grosh@gmail.com). -// * -// * Licensed under the Apache License, Version 2.0 (the "License"); -// * you may not use this file except in compliance with the License. -// * You may obtain a copy of the License at -// * -// * http://www.apache.org/licenses/LICENSE-2.0 -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, -// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// * See the License for the specific language governing permissions and -// * limitations under the License. -// */ -// package com.jagrosh.vortex.commands.tools; - -// import com.jagrosh.jdautilities.command.Command; -// import com.jagrosh.jdautilities.command.CommandEvent; -// import com.jagrosh.jdautilities.commons.utils.FinderUtil; -// import com.jagrosh.vortex.commands.CommandExceptionListener.CommandErrorException; -// import com.jagrosh.vortex.commands.CommandExceptionListener.CommandWarningException; -// import com.jagrosh.vortex.utils.FormatUtil; -// import java.time.format.DateTimeFormatter; -// import java.util.List; -// import net.dv8tion.jda.api.EmbedBuilder; -// import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; -// import net.dv8tion.jda.api.Permission; -// import net.dv8tion.jda.api.audit.ActionType; -// import net.dv8tion.jda.api.audit.AuditLogChange; -// import net.dv8tion.jda.api.entities.Emote; -// import net.dv8tion.jda.api.entities.Role; -// import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; -// import net.dv8tion.jda.api.entities.User; -// import net.dv8tion.jda.api.requests.restaction.pagination.AuditLogPaginationAction; - -// /** -// * -// * @author John Grosh (john.a.grosh@gmail.com) -// */ -// public class AuditCmd extends Command -// { -// private final static String LINESTART = "\u25AB"; // ▫ -// private final static String UNKNOWN = "*Unknown*"; - -// private final String actions; - -// public AuditCmd() -// { -// this.name = "audit"; -// this.aliases = new String[]{"auditlog","auditlogs","audits"}; -// this.arguments = " [target]"; -// this.help = "fetches recent audit logs"; -// this.guildOnly = true; -// this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS, Permission.VIEW_AUDIT_LOGS, Permission.MESSAGE_EXT_EMOJI}; -// this.userPermissions = new Permission[]{Permission.VIEW_AUDIT_LOGS}; -// this.cooldown = 5; -// this.category = new Category("Tools"); -// StringBuilder sb = new StringBuilder("\n\nValid actions: `"); -// for(ActionType type: ActionType.values()) -// sb.append(type.name()).append("`, `"); -// actions = sb.toString().substring(0, sb.length()-3); -// } - -// @Override -// protected void execute(CommandEvent event) -// { -// String[] parts = event.getArgs().split("\\s+", 2); -// AuditLogPaginationAction action = event.getGuild().retrieveAuditLogs().cache(false).limit(10); -// switch(parts[0].toLowerCase()) -// { -// case "all": -// break; -// case "from": -// if(parts.length==1) -// throw new CommandErrorException("Please include a user"); -// List list = FinderUtil.findUsers(parts[1], event.getJDA()); -// if(list.isEmpty()) -// throw new CommandWarningException("No users found matching `"+parts[1]+"`"); -// if(list.size()>1) -// throw new CommandWarningException(FormatUtil.listOfUser(list, event.getArgs())); -// action = action.user(list.get(0)); -// break; -// case "action": -// if(parts.length==1) -// throw new CommandErrorException("Please include an action"+actions); -// ActionType type = null; -// for(ActionType t: ActionType.values()) -// { -// if(t.name().toLowerCase().replace("_", "").equals(parts[1].toLowerCase().replace("_", "").replace(" ", ""))) -// { -// type = t; -// break; -// } -// } -// if(type==null) -// throw new CommandErrorException("Please include a valid action"+actions); -// action = action.type(type); -// break; -// default: -// throw new CommandErrorException("Valid subcommands:\n\n" -// + "`" + event.getClient().getPrefix() + name + " all` - shows recent audit log entries\n" -// + "`" + event.getClient().getPrefix() + name + " from ` - shows recent entries by a user\n" -// + "`" + event.getClient().getPrefix() + name + " action ` shows recent entries of a certain action"); -// } -// event.getChannel().asTextChannel().sendTyping().queue(); -// action.queue(list -> -// { -// if(list.isEmpty()) -// { -// event.replyWarning("No audit log entries found matching your criteria"); -// return; -// } -// EmbedBuilder eb = new EmbedBuilder().setColor(event.getSelfMember().getColor()); -// list.forEach(ale -> -// { -// StringBuilder sb = new StringBuilder(); -// sb.append(LINESTART).append("User: ").append(FormatUtil.formatFullUser(ale.getUser())); -// switch(ale.getTargetType()) -// { -// case CHANNEL: -// TextChannel tc = event.getGuild().getTextChannelById(ale.getTargetIdLong()); -// sb.append("\n").append(LINESTART).append("Channel: ") -// .append(tc==null ? UNKNOWN : "**#"+tc.getName()+"**") -// .append(" (ID:").append(ale.getTargetId()).append(")"); -// break; -// case EMOTE: -// Emote e = event.getGuild().getEmoteById(ale.getTargetIdLong()); -// sb.append("\n").append(LINESTART).append("Emote: ") -// .append(e==null ? UNKNOWN : e.getAsMention()) -// .append(" (ID:").append(ale.getTargetId()).append(")"); -// break; -// case GUILD: -// break; -// case INVITE: -// break; -// case MEMBER: -// User u = event.getJDA().getUserById(ale.getTargetIdLong()); -// sb.append("\n").append(LINESTART).append("Member: ") -// .append(u==null ? UNKNOWN : FormatUtil.formatUser(u)) -// .append(" (ID:").append(ale.getTargetId()).append(")"); -// break; -// case ROLE: -// Role r = event.getGuild().getRoleById(ale.getTargetIdLong()); -// sb.append("\n").append(LINESTART).append("Role: ") -// .append(r==null ? UNKNOWN : "**"+r.getName()+"**") -// .append(" (ID:").append(ale.getTargetId()).append(")"); -// break; -// case WEBHOOK: -// sb.append("\n").append(LINESTART).append("Webhook ID: ").append(ale.getTargetId()); -// break; -// case UNKNOWN: -// default: -// sb.append("\n").append(LINESTART).append("Target ID: ").append(ale.getTargetId()); -// } -// ale.getChanges().keySet().forEach(change -> -// { -// AuditLogChange alc = ale.getChangeByKey(change); -// if(alc != null) -// sb.append("\n").append(LINESTART).append(fixCase(change)).append(": ") -// .append(alc.getOldValue()==null ? "" : "**"+alc.getOldValue()+"**") -// .append(alc.getOldValue()==null || alc.getNewValue()==null ? "" : " → ") -// .append(alc.getNewValue()==null ? "" : "**"+alc.getNewValue()+"**"); -// }); -// ale.getOptions().keySet().forEach(option -> -// { -// sb.append("\n").append(LINESTART).append(fixCase(option)).append(": ") -// .append(ale.getOptionByName(option)==null ? UNKNOWN : "**"+ale.getOptionByName(option)+"**"); -// }); -// if(ale.getReason()!=null) -// sb.append("\n").append(LINESTART).append("Reason: ").append(ale.getReason()); -// sb.append("\n").append(LINESTART).append("Time: **").append(ale.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME)).append("**\n\u200B"); -// String str = sb.length()>1024 ? sb.substring(0,1020)+" ..." : sb.toString(); -// eb.addField(actionToEmote(ale.getType())+" "+fixCase(ale.getType().name()), str, true); -// }); -// event.reply(new MessageCreateBuilder() -// .setContent(event.getClient().getSuccess()+" Recent Audit Logs in **"+FormatUtil.filterEveryone(event.getGuild().getName())+"**:") -// .setEmbeds(eb.build()).build()); -// }, f -> event.replyWarning("Failed to retrieve audit logs")); -// } - -// private String fixCase(String input) -// { -// String ret = ""; -// for(int i=0; i"; -// case KICK: return "<:DeleteUser:274789150920671232>"; -// case UNBAN: return "<:Unban:274789150689984513>"; -// case PRUNE: return "<:removeMember:417574812718858250>"; - -// case CHANNEL_CREATE: return "<:addChannel:417574812425125888>"; -// case CHANNEL_DELETE: return "<:deleteChannel:417574812622258186>"; -// case CHANNEL_UPDATE: return "<:updateChannel:417574812240576514>"; - -// case CHANNEL_OVERRIDE_CREATE: return "<:addChannel:417574812425125888>"; -// case CHANNEL_OVERRIDE_DELETE: return "<:deleteChannel:417574812622258186>"; -// case CHANNEL_OVERRIDE_UPDATE: return "<:updateChannel:417574812240576514>"; - -// case EMOTE_CREATE: return "<:createEmoji:417574812689498112>"; -// case EMOTE_DELETE: return "<:deleteEmoji:417574812521725962>"; -// case EMOTE_UPDATE: return "<:updateEmoji:417574812601548800>"; - -// case GUILD_UPDATE: return "<:updateServer:417574812534177793>"; - -// case INVITE_CREATE: return "<:addInvite:417574812517662721>"; -// case INVITE_DELETE: return "<:deleteInvite:417574812521725953>"; -// case INVITE_UPDATE: return "<:updateInvite:417574812429320192>"; - -// case MEMBER_ROLE_UPDATE: return "<:updateMember:417574812504948736>"; -// case MEMBER_UPDATE: return "<:updateMember:417574812504948736>"; - -// case MESSAGE_CREATE: return "<:createMessage:446853279926845452>"; -// case MESSAGE_DELETE: return "<:deleteMessage:417574812399960065>"; -// case MESSAGE_UPDATE: return "<:updateMessage:446853280308396032>"; - -// case ROLE_CREATE: return "<:createRole:417574812399960075>"; -// case ROLE_DELETE: return "<:deleteRole:417574812463136769>"; -// case ROLE_UPDATE: return "<:updateRole:417574812165210126>"; - -// case WEBHOOK_CREATE: return "<:createWebhook:417574812714532864>"; -// case WEBHOOK_REMOVE: return "<:deleteWebhook:417574812098101250>"; -// case WEBHOOK_UPDATE: return "<:updateWebhook:417574812534439946>"; - -// case UNKNOWN: return "\u2753"; // ❓ -// default: return "\u2753"; // ❓ -// } -// } -// } diff --git a/src/main/java/com/jagrosh/vortex/commands/tools/AuditCmd.java b/src/main/java/com/jagrosh/vortex/commands/tools/AuditCmd.java new file mode 100644 index 0000000..dd0f198 --- /dev/null +++ b/src/main/java/com/jagrosh/vortex/commands/tools/AuditCmd.java @@ -0,0 +1,241 @@ +/* + * Copyright 2018 John Grosh (john.a.grosh@gmail.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jagrosh.vortex.commands.tools; + +import com.jagrosh.jdautilities.command.Command; +import com.jagrosh.jdautilities.command.CommandEvent; +import com.jagrosh.jdautilities.commons.utils.FinderUtil; +import com.jagrosh.vortex.commands.CommandExceptionListener.CommandErrorException; +import com.jagrosh.vortex.commands.CommandExceptionListener.CommandWarningException; +import com.jagrosh.vortex.utils.FormatUtil; +import java.time.format.DateTimeFormatter; +import java.util.List; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.audit.ActionType; +import net.dv8tion.jda.api.audit.AuditLogChange; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.requests.restaction.pagination.AuditLogPaginationAction; + +/** + * + * @author John Grosh (john.a.grosh@gmail.com) + */ +public class AuditCmd extends Command +{ + private final static String LINESTART = "\u25AB"; // ▫ + private final static String UNKNOWN = "*Unknown*"; + + private final String actions; + + public AuditCmd() + { + this.name = "audit"; + this.aliases = new String[]{"auditlog","auditlogs","audits"}; + this.arguments = " [target]"; + this.help = "fetches recent audit logs"; + this.guildOnly = true; + this.botPermissions = new Permission[]{Permission.MESSAGE_EMBED_LINKS, Permission.VIEW_AUDIT_LOGS, Permission.MESSAGE_EXT_EMOJI}; + this.userPermissions = new Permission[]{Permission.VIEW_AUDIT_LOGS}; + this.cooldown = 5; + this.category = new Category("Tools"); + StringBuilder sb = new StringBuilder("\n\nValid actions: `"); + for(ActionType type: ActionType.values()) + sb.append(type.name()).append("`, `"); + actions = sb.toString().substring(0, sb.length()-3); + } + + @Override + protected void execute(CommandEvent event) + { + String[] parts = event.getArgs().split("\\s+", 2); + AuditLogPaginationAction action = event.getGuild().retrieveAuditLogs().cache(false).limit(10); + switch(parts[0].toLowerCase()) + { + case "all": + break; + case "from": + if(parts.length==1) + throw new CommandErrorException("Please include a user"); + List list = FinderUtil.findUsers(parts[1], event.getJDA()); + if(list.isEmpty()) + throw new CommandWarningException("No users found matching `"+parts[1]+"`"); + if(list.size()>1) + throw new CommandWarningException(FormatUtil.listOfUser(list, event.getArgs())); + action = action.user(list.get(0)); + break; + case "action": + if(parts.length==1) + throw new CommandErrorException("Please include an action"+actions); + ActionType type = null; + for(ActionType t: ActionType.values()) + { + if(t.name().toLowerCase().replace("_", "").equals(parts[1].toLowerCase().replace("_", "").replace(" ", ""))) + { + type = t; + break; + } + } + if(type==null) + throw new CommandErrorException("Please include a valid action"+actions); + action = action.type(type); + break; + default: + throw new CommandErrorException("Valid subcommands:\n\n" + + "`" + event.getClient().getPrefix() + name + " all` - shows recent audit log entries\n" + + "`" + event.getClient().getPrefix() + name + " from ` - shows recent entries by a user\n" + + "`" + event.getClient().getPrefix() + name + " action ` shows recent entries of a certain action"); + } + event.getChannel().sendTyping().queue(); + action.queue(list -> + { + if(list.isEmpty()) + { + event.replyWarning("No audit log entries found matching your criteria"); + return; + } + EmbedBuilder eb = new EmbedBuilder().setColor(event.getSelfMember().getColor()); + list.forEach(ale -> + { + StringBuilder sb = new StringBuilder(); + sb.append(LINESTART).append("User: ").append(FormatUtil.formatFullUser(ale.getUser())); + switch(ale.getTargetType()) + { + case CHANNEL: + TextChannel tc = event.getGuild().getTextChannelById(ale.getTargetIdLong()); + sb.append("\n").append(LINESTART).append("Channel: ") + .append(tc==null ? UNKNOWN : "**#"+tc.getName()+"**") + .append(" (ID:").append(ale.getTargetId()).append(")"); + break; + case EMOJI: + Emoji e = event.getGuild().getEmojiById(ale.getTargetIdLong()); + sb.append("\n").append(LINESTART).append("Emote: ") + .append(e==null ? UNKNOWN : e.getAsReactionCode()) + .append(" (ID:").append(ale.getTargetId()).append(")"); + break; + case GUILD: + break; + case INVITE: + break; + case MEMBER: + User u = event.getJDA().getUserById(ale.getTargetIdLong()); + sb.append("\n").append(LINESTART).append("Member: ") + .append(u==null ? UNKNOWN : FormatUtil.formatUser(u)) + .append(" (ID:").append(ale.getTargetId()).append(")"); + break; + case ROLE: + Role r = event.getGuild().getRoleById(ale.getTargetIdLong()); + sb.append("\n").append(LINESTART).append("Role: ") + .append(r==null ? UNKNOWN : "**"+r.getName()+"**") + .append(" (ID:").append(ale.getTargetId()).append(")"); + break; + case WEBHOOK: + sb.append("\n").append(LINESTART).append("Webhook ID: ").append(ale.getTargetId()); + break; + case UNKNOWN: + default: + sb.append("\n").append(LINESTART).append("Target ID: ").append(ale.getTargetId()); + } + ale.getChanges().keySet().forEach(change -> + { + AuditLogChange alc = ale.getChangeByKey(change); + if(alc != null) + sb.append("\n").append(LINESTART).append(fixCase(change)).append(": ") + .append(alc.getOldValue()==null ? "" : "**"+alc.getOldValue()+"**") + .append(alc.getOldValue()==null || alc.getNewValue()==null ? "" : " → ") + .append(alc.getNewValue()==null ? "" : "**"+alc.getNewValue()+"**"); + }); + ale.getOptions().keySet().forEach(option -> + { + sb.append("\n").append(LINESTART).append(fixCase(option)).append(": ") + .append(ale.getOptionByName(option)==null ? UNKNOWN : "**"+ale.getOptionByName(option)+"**"); + }); + if(ale.getReason()!=null) + sb.append("\n").append(LINESTART).append("Reason: ").append(ale.getReason()); + sb.append("\n").append(LINESTART).append("Time: **").append(ale.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME)).append("**\n\u200B"); + String str = sb.length()>1024 ? sb.substring(0,1020)+" ..." : sb.toString(); + eb.addField(actionToEmote(ale.getType())+" "+fixCase(ale.getType().name()), str, true); + }); + event.reply(new MessageCreateBuilder() + .setContent(event.getClient().getSuccess()+" Recent Audit Logs in **"+FormatUtil.filterEveryone(event.getGuild().getName())+"**:") + .setEmbeds(eb.build()).build()); + }, f -> event.replyWarning("Failed to retrieve audit logs")); + } + + private String fixCase(String input) + { + String ret = ""; + for(int i=0; i"; + case KICK: return "<:DeleteUser:274789150920671232>"; + case UNBAN: return "<:Unban:274789150689984513>"; + case PRUNE: return "<:removeMember:417574812718858250>"; + + case CHANNEL_CREATE: return "<:addChannel:417574812425125888>"; + case CHANNEL_DELETE: return "<:deleteChannel:417574812622258186>"; + case CHANNEL_UPDATE: return "<:updateChannel:417574812240576514>"; + + case CHANNEL_OVERRIDE_CREATE: return "<:addChannel:417574812425125888>"; + case CHANNEL_OVERRIDE_DELETE: return "<:deleteChannel:417574812622258186>"; + case CHANNEL_OVERRIDE_UPDATE: return "<:updateChannel:417574812240576514>"; + + case EMOJI_CREATE: return "<:createEmoji:417574812689498112>"; + case EMOJI_DELETE: return "<:deleteEmoji:417574812521725962>"; + case EMOJI_UPDATE: return "<:updateEmoji:417574812601548800>"; + + case GUILD_UPDATE: return "<:updateServer:417574812534177793>"; + + case INVITE_CREATE: return "<:addInvite:417574812517662721>"; + case INVITE_DELETE: return "<:deleteInvite:417574812521725953>"; + case INVITE_UPDATE: return "<:updateInvite:417574812429320192>"; + + case MEMBER_ROLE_UPDATE: return "<:updateMember:417574812504948736>"; + case MEMBER_UPDATE: return "<:updateMember:417574812504948736>"; + + case MESSAGE_CREATE: return "<:createMessage:446853279926845452>"; + case MESSAGE_DELETE: return "<:deleteMessage:417574812399960065>"; + case MESSAGE_UPDATE: return "<:updateMessage:446853280308396032>"; + + case ROLE_CREATE: return "<:createRole:417574812399960075>"; + case ROLE_DELETE: return "<:deleteRole:417574812463136769>"; + case ROLE_UPDATE: return "<:updateRole:417574812165210126>"; + + case WEBHOOK_CREATE: return "<:createWebhook:417574812714532864>"; + case WEBHOOK_REMOVE: return "<:deleteWebhook:417574812098101250>"; + case WEBHOOK_UPDATE: return "<:updateWebhook:417574812534439946>"; + + case UNKNOWN: return "\u2753"; // ❓ + default: return "\u2753"; // ❓ + } + } +} diff --git a/src/main/java/com/jagrosh/vortex/commands/tools/LookupCmd.java b/src/main/java/com/jagrosh/vortex/commands/tools/LookupCmd.java new file mode 100644 index 0000000..f522bf9 --- /dev/null +++ b/src/main/java/com/jagrosh/vortex/commands/tools/LookupCmd.java @@ -0,0 +1,255 @@ +/* + * Copyright 2018 John Grosh (john.a.grosh@gmail.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://wwwidget.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jagrosh.vortex.commands.tools; + +import com.jagrosh.jdautilities.command.Command; +import com.jagrosh.jdautilities.command.CommandEvent; +import com.jagrosh.vortex.Constants; +import com.jagrosh.vortex.Emoji; +import com.jagrosh.vortex.Vortex; +import com.jagrosh.vortex.automod.InviteResolver; +import com.jagrosh.vortex.database.managers.PremiumManager; +import com.jagrosh.vortex.utils.FormatUtil; +import com.jagrosh.vortex.utils.OtherUtil; +import java.time.format.DateTimeFormatter; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.Invite; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.exceptions.RateLimitedException; +import net.dv8tion.jda.api.utils.TimeUtil; +import net.dv8tion.jda.api.utils.WidgetUtil; +import net.dv8tion.jda.api.entities.Widget; + +/** + * + * @author John Grosh (john.a.grosh@gmail.com) + */ +public class LookupCmd extends Command +{ + private final static String USER_EMOJI = "\uD83D\uDC64"; // 👤 + private final static String GUILD_EMOJI = "\uD83D\uDDA5"; // 🖥 + private final static String UNKNOWN_ID = "\uD83C\uDD94"; // 🆔 + private final static String LINESTART = "\u25AB"; // ▫ + + private final InviteResolver ir = new InviteResolver(); + private final Vortex vortex; + + public LookupCmd(Vortex vortex) + { + this.vortex = vortex; + this.name = "lookup"; + this.arguments = ""; + this.help = "finds information about a user or server"; + this.cooldown = 5; + this.category = new Category("Tools"); + } + + @Override + protected void execute(CommandEvent event) + { + if(event.isFromType(ChannelType.TEXT) && event.getMember().getRoles().isEmpty()) + { + event.reactError(); + return; + } + if(event.getArgs().isEmpty()) + { + event.replyError("Please provide a User ID, Server ID, or Invite Code\n" + + "This command provides information about a user or server. " + + "All of the information provided is information that Discord makes publically-available."); + return; + } + event.getChannel().sendTyping().queue(); + event.async(() -> + { + // determine if this is a valid ID + long id = -1; + try + { + id = Long.parseLong(event.getArgs()); + } + catch(NumberFormatException ignore) {} + + // if it's valid and we find a user, we're done + if(id > 0 && lookupUser(id, event)) + return; + + // require Vortex Plus for looking up guilds + if(!vortex.getDatabase().premium.getPremiumInfo(event.getGuild()).level.isAtLeast(PremiumManager.Level.PLUS)) + { + event.reply("No users found. Searching for guilds is not available here.\n" + PremiumManager.Level.PLUS.getRequirementMessage()); + return; + } + + // if valid id, use widget, otherwise try invite code + if(id > 0) + lookupGuild(id, event); + else + lookupGuild(extractCode(event.getArgs()), event); + }); + } + + private String extractCode(String args) + { + return args.substring(args.lastIndexOf("/")+1); + } + + private boolean lookupUser(long userId, CommandEvent event) + { + User u = vortex.getShardManager().getUserById(userId); + if(u==null) try + { + u = vortex.getShardManager().retrieveUserById(userId).complete(false); + } + catch(RateLimitedException ratelimited) + { + event.reactWarning(); + return true; + } + catch(Exception ignore) {} + if(u == null) + return false; + String text = (u.isBot() ? Emoji.BOT : USER_EMOJI) + " Information about **" + u.getName() + "**:"; + EmbedBuilder eb = new EmbedBuilder(); + eb.setThumbnail(u.getEffectiveAvatarUrl()); + StringBuilder str = new StringBuilder(LINESTART + "Discord ID: **" + u.getId() + "** "); + u.getFlags().forEach(flag -> str.append(OtherUtil.getEmoji(flag))); + if(u.getAvatarId() != null && u.getAvatarId().startsWith("a_")) + str.append(Emoji.BADGE_NITRO); + str.append("\n" + LINESTART + "Account Creation: **").append(TimeUtil.getDateTimeString(u.getTimeCreated())).append("**"); + eb.setDescription(str.toString()); + event.reply(new MessageCreateBuilder().addContent(FormatUtil.filterEveryone(text)).setEmbeds(eb.build()).build()); + return true; + } + + private void lookupGuild(long guildId, CommandEvent event) + { + Invite invite = null; + Widget widget = null; + try + { + widget = WidgetUtil.getWidget(guildId); + } + catch(RateLimitedException ratelimited) + { + event.reactWarning(); + return; + } + catch(Exception ignore) {} + if(widget != null && widget.isAvailable()) + { + String invCode = widget.getInviteCode(); + if(invCode != null) + { + try + { + invite = ir.resolveFull(invCode, event.getJDA()); + } + catch(Exception ignore) {} + } + } + event.reply(constructMessage(invite, widget, guildId)); + } + + private void lookupGuild(String inviteCode, CommandEvent event) + { + Invite invite = null; + Widget widget = null; + try + { + invite = ir.resolveFull(inviteCode, event.getJDA()); + } + catch(Exception ex) + { + event.reactWarning(); + return; + } + if(invite != null) + { + Invite.Guild g = invite.getGuild(); + if(g != null) + { + try + { + widget = WidgetUtil.getWidget(g.getIdLong()); + } + catch(Exception ignore) {} + } + } + event.reply(constructMessage(invite, widget, 0)); + } + + private MessageCreateData constructMessage(Invite invite, Widget widget, long input) + { + String gname = null; + long gid = 0L; + int users = -1; + if(invite == null) + { + if(widget == null) + { + if(input == 0) + return new MessageCreateBuilder().addContent(Constants.ERROR + " No users, guilds, or invites found.").build(); + + return new MessageCreateBuilder() + .addContent(UNKNOWN_ID + " Information about an unknown ID:") + .setEmbeds(new EmbedBuilder() + .appendDescription(LINESTART + "Creation: " + "**"+TimeUtil.getTimeCreated(input).format(DateTimeFormatter.RFC_1123_DATE_TIME)+"**").build()) + .build(); + } + + + gid = widget.getIdLong(); + if(widget.isAvailable()) + { + gname = widget.getName(); + users = widget.getMembers().size(); + } + } + else + { + Invite.Guild g = invite.getGuild(); + if(g != null) + { + gid = g.getIdLong(); + gname = g.getName(); + users = g.getOnlineCount(); + } + } + + String text = GUILD_EMOJI + " Information about " + (gname == null ? "an unknown guild" : "**"+gname+"**") + ":"; + EmbedBuilder eb = new EmbedBuilder(); + eb.appendDescription(LINESTART + "ID: " + (gid == 0 ? "N/A" : "**"+gid+"**") + + "\n" + LINESTART + "Creation: " + (gid == 0 ? "N/A" : "**"+TimeUtil.getTimeCreated(gid).format(DateTimeFormatter.RFC_1123_DATE_TIME)+"**") + + "\n" + LINESTART + "Users: " + (users == -1 ? "N/A" : "**" + users + "** online") + + (widget != null && widget.isAvailable() ? "\n" + LINESTART + "Channels: **" + widget.getVoiceChannels().size() + "** voice" : "")); + if(invite != null) + { + Invite.Guild g = invite.getGuild(); + eb.setThumbnail(g.getIconUrl()); + eb.setImage(g.getSplashId() == null ? null : g.getSplashUrl() + "?size=1024"); + eb.addField("Invite Info", LINESTART + "Invite: **" + invite.getCode() + "**" + + "\n" + LINESTART + "Channel: **" + (invite.getChannel().getType() == ChannelType.TEXT ? "#" : "") + invite.getChannel().getName() + "** (ID:" +invite.getChannel().getId() + ")" + + "\n" + LINESTART + "Inviter: " + (invite.getInviter() == null ? "N/A" : FormatUtil.formatFullUser(invite.getInviter())) + + (g.getSplashId() == null ? "" : "\n" + LINESTART + "Splash: "), false); + } + return new MessageCreateBuilder().addContent(FormatUtil.filterEveryone(text)).setEmbeds(eb.build()).build(); + } +} diff --git a/src/main/java/com/jagrosh/vortex/commands/tools/LookupCmd.java.fucku b/src/main/java/com/jagrosh/vortex/commands/tools/LookupCmd.java.fucku deleted file mode 100644 index d1f3ce6..0000000 --- a/src/main/java/com/jagrosh/vortex/commands/tools/LookupCmd.java.fucku +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2018 John Grosh (john.a.grosh@gmail.com). - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://wwwidget.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.jagrosh.vortex.commands.tools; - -import com.jagrosh.jdautilities.command.Command; -import com.jagrosh.jdautilities.command.CommandEvent; -import com.jagrosh.vortex.Constants; -import com.jagrosh.vortex.Emoji; -import com.jagrosh.vortex.Vortex; -import com.jagrosh.vortex.automod.InviteResolver; -import com.jagrosh.vortex.database.managers.PremiumManager; -import com.jagrosh.vortex.utils.FormatUtil; -import com.jagrosh.vortex.utils.OtherUtil; -import java.time.format.DateTimeFormatter; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; -import net.dv8tion.jda.api.entities.channel.ChannelType; -import net.dv8tion.jda.api.entities.Invite; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.exceptions.RateLimitedException; -import net.dv8tion.jda.api.utils.TimeUtil; -import net.dv8tion.jda.api.utils.WidgetUtil; -import net.dv8tion.jda.api.entities.GuildWidget; - -/** - * - * @author John Grosh (john.a.grosh@gmail.com) - */ -public class LookupCmd extends Command -{ - private final static String USER_EMOJI = "\uD83D\uDC64"; // 👤 - private final static String GUILD_EMOJI = "\uD83D\uDDA5"; // 🖥 - private final static String UNKNOWN_ID = "\uD83C\uDD94"; // 🆔 - private final static String LINESTART = "\u25AB"; // ▫ - - private final InviteResolver ir = new InviteResolver(); - private final Vortex vortex; - - public LookupCmd(Vortex vortex) - { - this.vortex = vortex; - this.name = "lookup"; - this.arguments = ""; - this.help = "finds information about a user or server"; - this.cooldown = 5; - this.category = new Category("Tools"); - } - - @Override - protected void execute(CommandEvent event) - { - if(event.isFromType(ChannelType.TEXT) && event.getMember().getRoles().isEmpty()) - { - event.reactError(); - return; - } - if(event.getArgs().isEmpty()) - { - event.replyError("Please provide a User ID, Server ID, or Invite Code\n" - + "This command provides information about a user or server. " - + "All of the information provided is information that Discord makes publically-available."); - return; - } - event.getChannel().asTextChannel().sendTyping().queue(); - event.async(() -> - { - // determine if this is a valid ID - long id = -1; - try - { - id = Long.parseLong(event.getArgs()); - } - catch(NumberFormatException ignore) {} - - // if it's valid and we find a user, we're done - if(id > 0 && lookupUser(id, event)) - return; - - // require Vortex Plus for looking up guilds - if(!vortex.getDatabase().premium.getPremiumInfo(event.getGuild()).level.isAtLeast(PremiumManager.Level.PLUS)) - { - event.reply("No users found. Searching for guilds is not available here.\n" + PremiumManager.Level.PLUS.getRequirementMessage()); - return; - } - - // if valid id, use widget, otherwise try invite code - if(id > 0) - lookupGuild(id, event); - else - lookupGuild(extractCode(event.getArgs()), event); - }); - } - - private String extractCode(String args) - { - return args.substring(args.lastIndexOf("/")+1); - } - - private boolean lookupUser(long userId, CommandEvent event) - { - User u = vortex.getShardManager().getUserById(userId); - if(u==null) try - { - u = vortex.getShardManager().retrieveUserById(userId).complete(false); - } - catch(RateLimitedException ratelimited) - { - event.reactWarning(); - return true; - } - catch(Exception ignore) {} - if(u == null) - return false; - String text = (u.isBot() ? Emoji.BOT : USER_EMOJI) + " Information about **" + u.getName() + "**:"; - EmbedBuilder eb = new EmbedBuilder(); - eb.setThumbnail(u.getEffectiveAvatarUrl()); - StringBuilder str = new StringBuilder(LINESTART + "Discord ID: **" + u.getId() + "** "); - u.getFlags().forEach(flag -> str.append(OtherUtil.getEmoji(flag))); - if(u.getAvatarId() != null && u.getAvatarId().startsWith("a_")) - str.append(Emoji.BADGE_NITRO); - str.append("\n" + LINESTART + "Account Creation: **").append(TimeUtil.getDateTimeString(u.getTimeCreated())).append("**"); - eb.setDescription(str.toString()); - event.reply(new MessageCreateBuilder().addContent(FormatUtil.filterEveryone(text)).setEmbeds(eb.build()).build()); - return true; - } - - private void lookupGuild(long guildId, CommandEvent event) - { - Invite invite = null; - GuildWidget widget = null; - try - { - widget = WidgetUtil.getWidget(guildId); - } - catch(RateLimitedException ratelimited) - { - event.reactWarning(); - return; - } - catch(Exception ignore) {} - if(widget != null && widget.isAvailable()) - { - String invCode = widget.getInviteCode(); - if(invCode != null) - { - try - { - invite = ir.resolveFull(invCode, event.getJDA()); - } - catch(Exception ignore) {} - } - } - event.reply(constructMessage(invite, widget, guildId)); - } - - private void lookupGuild(String inviteCode, CommandEvent event) - { - Invite invite = null; - GuildWidget widget = null; - try - { - invite = ir.resolveFull(inviteCode, event.getJDA()); - } - catch(Exception ex) - { - event.reactWarning(); - return; - } - if(invite != null) - { - Invite.Guild g = invite.getGuild(); - if(g != null) - { - try - { - widget = WidgetUtil.getWidget(g.getIdLong()); - } - catch(Exception ignore) {} - } - } - event.reply(constructMessage(invite, widget, 0)); - } - - private Message constructMessage(Invite invite, GuildWidget widget, long input) - { - String gname = null; - long gid = 0L; - int users = -1; - if(invite == null) - { - if(widget == null) - { - if(input == 0) - return new MessageCreateBuilder().addContent(Constants.ERROR + " No users, guilds, or invites found.").build(); - - return new MessageCreateBuilder() - .addContent(UNKNOWN_ID + " Information about an unknown ID:") - .setEmbeds(new EmbedBuilder() - .appendDescription(LINESTART + "Creation: " + "**"+TimeUtil.getTimeCreated(input).format(DateTimeFormatter.RFC_1123_DATE_TIME)+"**").build()) - .build(); - } - - - gid = widget.getIdLong(); - if(widget.isAvailable()) - { - gname = widget.getName(); - users = widget.getMembers().size(); - } - } - else - { - Invite.Guild g = invite.getGuild(); - if(g != null) - { - gid = g.getIdLong(); - gname = g.getName(); - users = g.getOnlineCount(); - } - } - - String text = GUILD_EMOJI + " Information about " + (gname == null ? "an unknown guild" : "**"+gname+"**") + ":"; - EmbedBuilder eb = new EmbedBuilder(); - eb.appendDescription(LINESTART + "ID: " + (gid == 0 ? "N/A" : "**"+gid+"**") - + "\n" + LINESTART + "Creation: " + (gid == 0 ? "N/A" : "**"+TimeUtil.getTimeCreated(gid).format(DateTimeFormatter.RFC_1123_DATE_TIME)+"**") - + "\n" + LINESTART + "Users: " + (users == -1 ? "N/A" : "**" + users + "** online") - + (widget != null && widget.isAvailable() ? "\n" + LINESTART + "Channels: **" + widget.getVoiceChannels().size() + "** voice" : "")); - if(invite != null) - { - Invite.Guild g = invite.getGuild(); - eb.setThumbnail(g.getIconUrl()); - eb.setImage(g.getSplashId() == null ? null : g.getSplashUrl() + "?size=1024"); - eb.addField("Invite Info", LINESTART + "Invite: **" + invite.getCode() + "**" - + "\n" + LINESTART + "Channel: **" + (invite.getChannel().getType() == ChannelType.TEXT ? "#" : "") + invite.getChannel().getName() + "** (ID:" +invite.getChannel().getId() + ")" - + "\n" + LINESTART + "Inviter: " + (invite.getInviter() == null ? "N/A" : FormatUtil.formatFullUser(invite.getInviter())) - + (g.getSplashId() == null ? "" : "\n" + LINESTART + "Splash: "), false); - } - return new MessageCreateBuilder().addContent(FormatUtil.filterEveryone(text)).setEmbeds(eb.build()).build(); - } -} diff --git a/src/main/kotlin/com/jagrosh/vortex/commands/VoicekickCmd.kt b/src/main/kotlin/com/jagrosh/vortex/commands/VoicekickCmd.kt deleted file mode 100644 index 1ef7b38..0000000 --- a/src/main/kotlin/com/jagrosh/vortex/commands/VoicekickCmd.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.jagrosh.vortex.commands - -import com.jagrosh.jdautilities.command.CommandEvent -import com.jagrosh.vortex.Vortex -import net.dv8tion.jda.api.Permission - -class VoicekickCmd(vortex: Vortex) : ModCommand(vortex, Permission.VOICE_MOVE_OTHERS){ - override fun execute(event: CommandEvent?) { - if (event == null){ - return - } - event.reply("no :3"); - } -} \ No newline at end of file