From 13a1480d368ff261185367eae7b01fb2e38617cd Mon Sep 17 00:00:00 2001 From: thmsdy Date: Sun, 31 May 2020 22:33:34 -0500 Subject: [PATCH] Improve Captcha readability --- dependency-reduced-pom.xml | 2 +- pom.xml | 2 +- .../java/com/fpghoti/biscuit/Biscuit.java | 4 +- src/main/java/com/fpghoti/biscuit/Main.java | 3 - .../com/fpghoti/biscuit/captcha/BCage.java | 34 +++++ .../fpghoti/biscuit/listener/DMListener.java | 133 +++++++++++++----- .../com/fpghoti/biscuit/user/PreUser.java | 31 +++- .../java/com/fpghoti/biscuit/util/Util.java | 28 +--- 8 files changed, 168 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/fpghoti/biscuit/captcha/BCage.java diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 69a33e3..3b6dd03 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.fpghoti Biscuit - 1.2 + 1.2.1 src/main/java diff --git a/pom.xml b/pom.xml index bc7a462..fbec5e2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.fpghoti Biscuit - 1.2 + 1.2.1 src/main/java diff --git a/src/main/java/com/fpghoti/biscuit/Biscuit.java b/src/main/java/com/fpghoti/biscuit/Biscuit.java index ff1c1fa..d04410d 100644 --- a/src/main/java/com/fpghoti/biscuit/Biscuit.java +++ b/src/main/java/com/fpghoti/biscuit/Biscuit.java @@ -7,12 +7,12 @@ import java.util.Timer; import org.slf4j.Logger; +import com.fpghoti.biscuit.captcha.BCage; import com.fpghoti.biscuit.commands.CommandManager; import com.fpghoti.biscuit.config.PropertiesRetrieval; import com.fpghoti.biscuit.timer.BiscuitTimer; import com.fpghoti.biscuit.user.PreUser; import com.github.cage.Cage; -import com.github.cage.GCage; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; @@ -45,7 +45,7 @@ public class Biscuit { captchaDir = new File(PluginCore.plugin.getDataFolder(), "captcha"); } captchaDir.mkdir(); - cage = new GCage(); + cage = new BCage(); wipeCaptchaDir(); loadPreUsers(); } diff --git a/src/main/java/com/fpghoti/biscuit/Main.java b/src/main/java/com/fpghoti/biscuit/Main.java index 6e1ab32..25b848f 100644 --- a/src/main/java/com/fpghoti/biscuit/Main.java +++ b/src/main/java/com/fpghoti/biscuit/Main.java @@ -75,9 +75,6 @@ public class Main { jda.addEventListener(new DMListener()); String link = "NULL"; -// Properties.naughtyList = ConfigRetrieval.getFromConfig("NaughtyList"); -// Properties.customdefaultrole = ConfigRetrieval.getFromConfig("UseCustomDefaultRole").equalsIgnoreCase("true"); -// Properties.roleName = ConfigRetrieval.getFromConfig("DefaultRoleName"); biscuit.addTimer(new ChatCountTimer()); biscuit.addTimer(new BotMsgRemoveTimer()); diff --git a/src/main/java/com/fpghoti/biscuit/captcha/BCage.java b/src/main/java/com/fpghoti/biscuit/captcha/BCage.java new file mode 100644 index 0000000..e5b75b1 --- /dev/null +++ b/src/main/java/com/fpghoti/biscuit/captcha/BCage.java @@ -0,0 +1,34 @@ +package com.fpghoti.biscuit.captcha; + +import java.awt.Font; +import java.util.Random; + +import com.github.cage.Cage; +import com.github.cage.ObjectRoulette; +import com.github.cage.image.EffectConfig; +import com.github.cage.image.Painter; +import com.github.cage.image.RgbColorGenerator; +import com.github.cage.image.ScaleConfig; +import com.github.cage.token.RandomCharacterGeneratorFactory; +import com.github.cage.token.RandomTokenGenerator; + +public class BCage extends Cage { + + private static int width = 300; + private static int height = 100; + private static int fontHeight = 80; + private static String chars = "abcdefhijkmnoprstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ123456789"; + private static int length = 6; + + public BCage() { + this(new Random()); + } + + protected BCage(Random rnd) { + super(new Painter(width, height, null, null, new EffectConfig(true, + false, true, false, new ScaleConfig(0.85f, 0.85f)), rnd), + new ObjectRoulette(rnd, new Font(Font.SERIF, Font.PLAIN, fontHeight)), // + new RgbColorGenerator(rnd), null, null, + new RandomTokenGenerator(rnd, new RandomCharacterGeneratorFactory(chars.toCharArray(), null, rnd), length, 0), rnd); + } +} \ No newline at end of file diff --git a/src/main/java/com/fpghoti/biscuit/listener/DMListener.java b/src/main/java/com/fpghoti/biscuit/listener/DMListener.java index 3718ca1..f447bf0 100644 --- a/src/main/java/com/fpghoti/biscuit/listener/DMListener.java +++ b/src/main/java/com/fpghoti/biscuit/listener/DMListener.java @@ -5,6 +5,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; import org.slf4j.Logger; @@ -12,8 +13,10 @@ import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.PluginCore; import com.fpghoti.biscuit.config.PropertiesRetrieval; import com.fpghoti.biscuit.user.PreUser; +import com.fpghoti.biscuit.util.PermUtil; import com.github.cage.Cage; +import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Member; @@ -27,27 +30,68 @@ public class DMListener extends ListenerAdapter{ Logger log = Main.log; + private static ArrayList testers = new ArrayList(); + @Override public void onMessageReceived(MessageReceivedEvent event){ if (event.isFromType(ChannelType.PRIVATE) && !event.getAuthor().isBot()) { - if(PropertiesRetrieval.logChat()) { - log.info( "NEW PRIVATE MESSAGE - MSGID: " + event.getMessageId() + "- @" + event.getAuthor().getName() + " " + event.getAuthor().getAsMention() + " - " + event.getMessage().getContentDisplay()); + String content = event.getMessage().getContentDisplay(); + User user = event.getAuthor(); + boolean isTest = false; + boolean found = false; + if(testers.size() > 0) { + for(User u : testers) { + if(user.getId().equals(u.getId())) { + isTest = true; + found = true; + } + } } - handleCaptcha(event); + if(content.equalsIgnoreCase("captcha pls") || content.equalsIgnoreCase("cpls")) { + JDA jda = Main.getBiscuit().getJDA(); + for(Guild g : jda.getGuilds()) { + if(g.isMember(user)) { + Member m = g.getMember(user); + if(PermUtil.isAdmin(m)) { + isTest = true; + if(!found) { + PreUser.testusers.add(new PreUser(user,true)); + testers.add(user); + } + } + } + } + } + if(PropertiesRetrieval.logChat()) { + log.info( "NEW PRIVATE MESSAGE - MSGID: " + event.getMessageId() + "- @" + user.getName() + " " + event.getAuthor().getAsMention() + " - " + content); + } + handleCaptcha(event, isTest); } } - private void handleCaptcha(MessageReceivedEvent event) { + private void handleCaptcha(MessageReceivedEvent event, boolean isTest) { + PreUser preu; PrivateChannel channel = event.getPrivateChannel(); User author = event.getAuthor(); - if(PreUser.getPreUser(author) != null) { - PreUser preu = PreUser.getPreUser(author); - if(preu.getToken() == null || !event.getMessage().getContentDisplay().equals(preu.getToken())) { - - if(preu.getToken() != null) { - channel.sendMessage("Sorry! That's not quite right! Please try again.").queue(); + if(PreUser.getPreUser(author) != null || isTest) { + if(isTest) { + preu = PreUser.getTestUser(author); + }else { + preu = PreUser.getPreUser(author); + } + + + String response = leeway(event.getMessage().getContentDisplay()); + + if(preu.getToken() == null || !response.equalsIgnoreCase(preu.getToken())) { + String tlabel = ""; + if(isTest) { + tlabel = "[TEST] "; } - Main.log.info("Generating captcha challenge for user " + author.getName() + " " + author.getAsMention() + "..."); + if(preu.getToken() != null) { + channel.sendMessage(tlabel + "Sorry! That's not quite right! Please try again.").queue(); + } + Main.log.info(tlabel + "Generating captcha challenge for user " + author.getName() + " " + author.getAsMention() + "..."); Cage cage = Main.getBiscuit().getCage(); @@ -85,44 +129,61 @@ public class DMListener extends ListenerAdapter{ }else { captcha = new File(PluginCore.plugin.getDataFolder(), "captcha/" + author.getId() + ".jpg"); } - channel.sendMessage("Respond with the exact text in this image (case-sensitive)").queue(); + channel.sendMessage(tlabel+ "Respond with the exact text in this image.").queue(); channel.sendFile(captcha).queue(); }else { + String tlabel = ""; + if(isTest) { + tlabel = "[TEST] "; + } preu.setDone(); - Main.log.info(author.getName() + " successfully completed a captcha challenge. Granting role."); + Main.log.info(tlabel + author.getName() + " successfully completed a captcha challenge. Granting role."); Role newrole = null; Role defaultrole = null; - for(Guild g : preu.getGuilds()) { - for(Role r : g.getRoles()) { - if(r.getName().toLowerCase().contains(PropertiesRetrieval.getCaptchaReward().toLowerCase())) { - newrole = r; - }else if(r.getName().toLowerCase().contains(PropertiesRetrieval.getDefaultRole().toLowerCase())) { - defaultrole = r; - } - } - if(newrole == null) { - Main.log.error("Cannot find captcha reward role!"); - return; - } - - if(defaultrole == null) { - Main.log.error("Cannot find captcha default role!"); - return; - } - - Member member = g.getMemberById(author.getId()); - - g.addRoleToMember(member, newrole).queue(); - g.removeRoleFromMember(member, defaultrole).queue(); + if(isTest) { + testers.remove(author); preu.remove(); + }else { + for(Guild g : preu.getGuilds()) { + for(Role r : g.getRoles()) { + if(r.getName().toLowerCase().contains(PropertiesRetrieval.getCaptchaReward().toLowerCase())) { + newrole = r; + }else if(r.getName().toLowerCase().contains(PropertiesRetrieval.getDefaultRole().toLowerCase())) { + defaultrole = r; + } + } + if(newrole == null) { + Main.log.error("Cannot find captcha reward role!"); + return; + } + + if(defaultrole == null) { + Main.log.error("Cannot find captcha default role!"); + return; + } + + Member member = g.getMemberById(author.getId()); + + g.addRoleToMember(member, newrole).queue(); + g.removeRoleFromMember(member, defaultrole).queue(); + preu.remove(); + } } - channel.sendMessage("Well done, " + author.getAsMention() + "!").queue(); + channel.sendMessage(tlabel + "Well done, " + author.getAsMention() + "!").queue(); } } } + + private String leeway(String s) { + s = s.replace("l", "1"); + s = s.replace("g", "9"); + s = s.replace("0", "O"); + return s; + } + } diff --git a/src/main/java/com/fpghoti/biscuit/user/PreUser.java b/src/main/java/com/fpghoti/biscuit/user/PreUser.java index 8055698..a36418c 100644 --- a/src/main/java/com/fpghoti/biscuit/user/PreUser.java +++ b/src/main/java/com/fpghoti/biscuit/user/PreUser.java @@ -8,6 +8,7 @@ import com.fpghoti.biscuit.Main; import com.fpghoti.biscuit.PluginCore; import com.fpghoti.biscuit.config.PropertiesRetrieval; import com.fpghoti.biscuit.util.Util; +import com.github.cage.Cage; import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.entities.Guild; @@ -15,8 +16,18 @@ import net.dv8tion.jda.api.entities.User; public class PreUser { + public static CopyOnWriteArrayList testusers = new CopyOnWriteArrayList(); public static CopyOnWriteArrayList users = new CopyOnWriteArrayList(); + public static PreUser getTestUser(User user) { + for(PreUser u : testusers) { + if(u.getUser().getId().equals(user.getId())) { + return u; + } + } + return null; + } + public static PreUser getPreUser(User user) { for(PreUser u : users) { if(u.getUser().getId().equals(user.getId())) { @@ -34,13 +45,21 @@ public class PreUser { private String token; private int timeLeft; private boolean done; + private boolean test; public PreUser(User user) { + this(user, false); + } + + public PreUser(User user, boolean test) { + this.test = test; this.user = user; this.token = null; this.done = false; this.timeLeft = PropertiesRetrieval.noCaptchaKickTime() + 1; - users.add(this); + if(!test) { + users.add(this); + } } public User getUser() { @@ -51,10 +70,9 @@ public class PreUser { return this.token; } - //Going to use custom string gen for more char types in captcha public void genToken() { - //token = Main.getBiscuit().getCage().getTokenGenerator().next(); - token = Util.randomString(6); + Cage cage = Main.getBiscuit().getCage(); + token = cage.getTokenGenerator().next(); } public void setDone() { @@ -66,6 +84,10 @@ public class PreUser { remove(); return; } + + if(test) { + return; + } if(!done) { if(PropertiesRetrieval.noCaptchaKick()) { @@ -115,6 +137,7 @@ public class PreUser { token = null; captcha.delete(); users.remove(this); + testusers.remove(this); } } diff --git a/src/main/java/com/fpghoti/biscuit/util/Util.java b/src/main/java/com/fpghoti/biscuit/util/Util.java index a1b609b..805ff1a 100644 --- a/src/main/java/com/fpghoti/biscuit/util/Util.java +++ b/src/main/java/com/fpghoti/biscuit/util/Util.java @@ -8,13 +8,13 @@ import net.dv8tion.jda.api.entities.TextChannel; public class Util { public static int randInt(int min, int max) { - Random rand = new Random(); + Random rand = new Random(); - int randomNum = rand.nextInt((max - min) + 1) + min; + int randomNum = rand.nextInt((max - min) + 1) + min; - return randomNum; + return randomNum; } - + public static Boolean isLoggable(TextChannel c) { if(c == null) { return true; @@ -27,11 +27,11 @@ public class Util { } return a; } - + public static boolean isDigit(String s){ return s.matches("[0-9]+"); } - + public static boolean isDeciDigit(String s){ int i = 0; String s2 = ""; @@ -43,21 +43,5 @@ public class Util { } return s2.replace(".", "").matches("[0-9]+"); } - - private static String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - public static String randomString(int size) { - Random rand = new Random(); - if (size <= 0) { - return ""; - } - String str = ""; - for (int i = 0; i < size; i++) { - int ind = rand.nextInt(chars.length()); - char rchar = chars.charAt(ind); - str = str + rchar; - } - return str; - } - }