diff --git a/.gitignore b/.gitignore index a4b3f4b..bc52bc7 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ /avatars/ /backups/ /database/ +/.idea/ nb*.xml \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4dcac6d..b9c1da9 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,12 @@ jcenter-bintray http://jcenter.bintray.com + + + jcenter-jagrosh + jcenter-jagrosh + https://dl.bintray.com/jagrosh/maven + diff --git a/src/main/java/com/jagrosh/vortex/automod/AutoMod.java b/src/main/java/com/jagrosh/vortex/automod/AutoMod.java index ad1154c..8b39686 100644 --- a/src/main/java/com/jagrosh/vortex/automod/AutoMod.java +++ b/src/main/java/com/jagrosh/vortex/automod/AutoMod.java @@ -398,7 +398,7 @@ for(String inviteCode : invites) { long gid = inviteResolver.resolve(message.getJDA(), inviteCode); - if(gid != message.getGuild().getIdLong()) + if(gid != message.getGuild().getIdLong() && !settings.whitelistedInvites.contains(gid)) { strikeTotal += settings.inviteStrikes; reason.append(", Advertising"); @@ -482,7 +482,8 @@ { if(settings.inviteStrikes>0 && resolved.matches(INVITE_LINK)) { - if(inviteResolver.resolve(message.getJDA(), resolved.replaceAll(INVITE_LINK, "$1")) != message.getGuild().getIdLong()) + long invite = inviteResolver.resolve(message.getJDA(), resolved.replaceAll(INVITE_LINK, "$1")); + if(invite != message.getGuild().getIdLong() && !settings.whitelistedInvites.contains(invite)) containsInvite = true; } if(settings.refStrikes>0) diff --git a/src/main/java/com/jagrosh/vortex/commands/automod/AntiinviteCmd.java b/src/main/java/com/jagrosh/vortex/commands/automod/AntiinviteCmd.java index 4bf0519..2face8c 100644 --- a/src/main/java/com/jagrosh/vortex/commands/automod/AntiinviteCmd.java +++ b/src/main/java/com/jagrosh/vortex/commands/automod/AntiinviteCmd.java @@ -37,9 +37,10 @@ this.guildOnly = true; this.aliases = new String[]{"antinvite","anti-invite"}; this.category = new Category("AutoMod"); - this.arguments = ""; + this.arguments = ""; this.help = "sets strikes for posting invites"; this.userPermissions = new Permission[]{Permission.MANAGE_SERVER}; + this.children = new Command[] {new WhitelistInvitesCmd(vortex)}; } @Override diff --git a/src/main/java/com/jagrosh/vortex/commands/automod/WhitelistInvitesCmd.java b/src/main/java/com/jagrosh/vortex/commands/automod/WhitelistInvitesCmd.java new file mode 100644 index 0000000..11cb9ad --- /dev/null +++ b/src/main/java/com/jagrosh/vortex/commands/automod/WhitelistInvitesCmd.java @@ -0,0 +1,103 @@ +/* + * 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.automod; + +import com.jagrosh.jdautilities.command.Command; +import com.jagrosh.jdautilities.command.CommandEvent; +import com.jagrosh.vortex.Vortex; +import net.dv8tion.jda.core.Permission; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * + * @author John Grosh (john.a.grosh@gmail.com) + */ +public class WhitelistInvitesCmd extends Command +{ + private final Vortex vortex; + private final static String DESCRIPTION = "Used to add/remove guilds from the invite whitelist. When an invite to a whitelisted guild is posted, no strikes are given."; + + public WhitelistInvitesCmd(Vortex vortex) + { + this.vortex = vortex; + this.name = "whitelist"; + this.guildOnly = true; + this.category = new Category("AutoMod"); + this.arguments = ""; + this.help = "if strikes for invites are enabled, add/remove whitelisted guilds"; + this.userPermissions = new Permission[]{Permission.MANAGE_SERVER}; + } + + @Override + protected void execute(CommandEvent event) + { + String[] args = event.getArgs().toLowerCase().split("\\s+"); + if(event.getArgs().equalsIgnoreCase("show") || (args.length == 2 && (args[0].equals("add") || args[0].equals("remove")))) + { + List currentWL = vortex.getDatabase().automod.getSettings(event.getGuild()).whitelistedInvites; + if(event.getArgs().equalsIgnoreCase("show")) + { + event.replySuccess("Whitelisted Guild IDs:\n" + (currentWL.isEmpty() ? "None" : + currentWL.stream().map(String::valueOf).collect(Collectors.joining(", ")))); + } + else + { + long guildId; + try + { + guildId = Long.parseUnsignedLong(args[1]); + } + catch(NumberFormatException ex) + { + event.replyWarning("Invalid Guild-ID provided!"); + return; + } + List newWhitelist; + if(args[0].equals("add")) + { + if(currentWL.contains(guildId)) + { + event.replyWarning("Given Guild was already whitelisted"); + return; + } + newWhitelist = new ArrayList<>(currentWL.size() + 1); + newWhitelist.addAll(currentWL); + newWhitelist.add(guildId); + } + else + { + if(!currentWL.contains(guildId)) + { + event.replyWarning("Given Guild was not whitelisted"); + return; + } + newWhitelist = new ArrayList<>(currentWL.size() - 1); + currentWL.stream().filter(id -> id != guildId).forEach(newWhitelist::add); + } + vortex.getDatabase().automod.setWhitelistedInvites(event.getGuild(), newWhitelist); + event.replySuccess("Whitelist has been modified"); + } + } + else + { + event.replyWarning(DESCRIPTION+"\nValid options are `ADD GUILD_ID`, `REMOVE GUILD_ID` and `show`"); + } + + } +} diff --git a/src/main/java/com/jagrosh/vortex/database/ArrayColumn.java b/src/main/java/com/jagrosh/vortex/database/ArrayColumn.java new file mode 100644 index 0000000..b0cfd2f --- /dev/null +++ b/src/main/java/com/jagrosh/vortex/database/ArrayColumn.java @@ -0,0 +1,58 @@ +/* + * Copyright 2017 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.database; + +import com.jagrosh.easysql.SQLColumn; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * + * @author John Grosh (john.a.grosh@gmail.com) + */ +public class ArrayColumn extends SQLColumn> +{ + public ArrayColumn(String name) + { + this(name, false); + } + + public ArrayColumn(String name, boolean publicKey) + { + super(name, false, null, publicKey); + } + + @Override + public String getDataDescription() + { + return "ARRAY DEFAULT ()" + nullable() + (primaryKey ? " PRIMARY KEY" : ""); + } + + @Override + public List getValue(ResultSet results) throws SQLException + { + return new ArrayList<>(Arrays.asList((T[]) results.getArray(name).getArray())); + } + + @Override + public void updateValue(ResultSet results, List newValue) throws SQLException + { + results.updateObject(name, newValue.toArray()); + } +} diff --git a/src/main/java/com/jagrosh/vortex/database/managers/AutomodManager.java b/src/main/java/com/jagrosh/vortex/database/managers/AutomodManager.java index c30aef7..5b4fcbc 100644 --- a/src/main/java/com/jagrosh/vortex/database/managers/AutomodManager.java +++ b/src/main/java/com/jagrosh/vortex/database/managers/AutomodManager.java @@ -20,9 +20,13 @@ import com.jagrosh.easysql.SQLColumn; import com.jagrosh.easysql.columns.*; import com.jagrosh.vortex.Action; +import com.jagrosh.vortex.database.ArrayColumn; import com.jagrosh.vortex.utils.FixedCache; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collections; +import java.util.List; + import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.MessageEmbed.Field; @@ -58,6 +62,8 @@ public final static SQLColumn DUPE_STRIKE_THRESH = new IntegerColumn("DUPE_STRIKES_THRESH", false, 0); public final static SQLColumn DEHOIST_CHAR = new IntegerColumn("DEHOIST_CHAR", false, 0); + + public final static SQLColumn> WHITELISTED_INVITES = new ArrayColumn("WHITELISTED_INVITES"); // Cache private final FixedCache cache = new FixedCache<>(1000); @@ -361,6 +367,26 @@ } }); } + + public void setWhitelistedInvites(Guild guild, List whitelistedIds) + { + invalidateCache(guild); + readWrite(selectAll(GUILD_ID.is(guild.getIdLong())), rs -> + { + if(rs.next()) + { + WHITELISTED_INVITES.updateValue(rs, whitelistedIds); + rs.updateRow(); + } + else + { + rs.moveToInsertRow(); + GUILD_ID.updateValue(rs, guild.getIdLong()); + WHITELISTED_INVITES.updateValue(rs, whitelistedIds); + rs.insertRow(); + } + }); + } private void invalidateCache(Guild guild) { @@ -381,6 +407,7 @@ public final int inviteStrikes, refStrikes, copypastaStrikes, everyoneStrikes; public final int dupeStrikes, dupeDeleteThresh, dupeStrikeThresh; public final char dehoistChar; + public final List whitelistedInvites; private AutomodSettings() { @@ -398,6 +425,7 @@ this.dupeDeleteThresh = 0; this.dupeStrikeThresh = 0; this.dehoistChar = 0; + this.whitelistedInvites = Collections.emptyList(); } private AutomodSettings(ResultSet rs) throws SQLException @@ -416,6 +444,7 @@ this.dupeDeleteThresh = DUPE_DELETE_THRESH.getValue(rs); this.dupeStrikeThresh = DUPE_STRIKE_THRESH.getValue(rs); this.dehoistChar = (char)((int)DEHOIST_CHAR.getValue(rs)); + this.whitelistedInvites = Collections.unmodifiableList(WHITELISTED_INVITES.getValue(rs)); } public boolean useAutoRaidMode()