Improve Captcha readability

This commit is contained in:
Ghoti 2020-05-31 22:33:34 -05:00
parent d686d70bd4
commit 13a1480d36
8 changed files with 168 additions and 69 deletions

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.fpghoti</groupId> <groupId>com.fpghoti</groupId>
<artifactId>Biscuit</artifactId> <artifactId>Biscuit</artifactId>
<version>1.2</version> <version>1.2.1</version>
<build> <build>
<sourceDirectory>src/main/java</sourceDirectory> <sourceDirectory>src/main/java</sourceDirectory>
<resources> <resources>

View File

@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.fpghoti</groupId> <groupId>com.fpghoti</groupId>
<artifactId>Biscuit</artifactId> <artifactId>Biscuit</artifactId>
<version>1.2</version> <version>1.2.1</version>
<build> <build>
<sourceDirectory>src/main/java</sourceDirectory> <sourceDirectory>src/main/java</sourceDirectory>
<resources> <resources>

View File

@ -7,12 +7,12 @@ import java.util.Timer;
import org.slf4j.Logger; import org.slf4j.Logger;
import com.fpghoti.biscuit.captcha.BCage;
import com.fpghoti.biscuit.commands.CommandManager; import com.fpghoti.biscuit.commands.CommandManager;
import com.fpghoti.biscuit.config.PropertiesRetrieval; import com.fpghoti.biscuit.config.PropertiesRetrieval;
import com.fpghoti.biscuit.timer.BiscuitTimer; import com.fpghoti.biscuit.timer.BiscuitTimer;
import com.fpghoti.biscuit.user.PreUser; import com.fpghoti.biscuit.user.PreUser;
import com.github.cage.Cage; import com.github.cage.Cage;
import com.github.cage.GCage;
import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
@ -45,7 +45,7 @@ public class Biscuit {
captchaDir = new File(PluginCore.plugin.getDataFolder(), "captcha"); captchaDir = new File(PluginCore.plugin.getDataFolder(), "captcha");
} }
captchaDir.mkdir(); captchaDir.mkdir();
cage = new GCage(); cage = new BCage();
wipeCaptchaDir(); wipeCaptchaDir();
loadPreUsers(); loadPreUsers();
} }

View File

@ -75,9 +75,6 @@ public class Main {
jda.addEventListener(new DMListener()); jda.addEventListener(new DMListener());
String link = "NULL"; 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 ChatCountTimer());
biscuit.addTimer(new BotMsgRemoveTimer()); biscuit.addTimer(new BotMsgRemoveTimer());

View File

@ -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<Font>(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);
}
}

View File

@ -5,6 +5,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -12,8 +13,10 @@ import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.PluginCore; import com.fpghoti.biscuit.PluginCore;
import com.fpghoti.biscuit.config.PropertiesRetrieval; import com.fpghoti.biscuit.config.PropertiesRetrieval;
import com.fpghoti.biscuit.user.PreUser; import com.fpghoti.biscuit.user.PreUser;
import com.fpghoti.biscuit.util.PermUtil;
import com.github.cage.Cage; import com.github.cage.Cage;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.ChannelType; import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
@ -27,27 +30,68 @@ public class DMListener extends ListenerAdapter{
Logger log = Main.log; Logger log = Main.log;
private static ArrayList<User> testers = new ArrayList<User>();
@Override @Override
public void onMessageReceived(MessageReceivedEvent event){ public void onMessageReceived(MessageReceivedEvent event){
if (event.isFromType(ChannelType.PRIVATE) && !event.getAuthor().isBot()) { if (event.isFromType(ChannelType.PRIVATE) && !event.getAuthor().isBot()) {
if(PropertiesRetrieval.logChat()) { String content = event.getMessage().getContentDisplay();
log.info( "NEW PRIVATE MESSAGE - MSGID: " + event.getMessageId() + "- @" + event.getAuthor().getName() + " " + event.getAuthor().getAsMention() + " - " + 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(); PrivateChannel channel = event.getPrivateChannel();
User author = event.getAuthor(); User author = event.getAuthor();
if(PreUser.getPreUser(author) != null) { if(PreUser.getPreUser(author) != null || isTest) {
PreUser preu = PreUser.getPreUser(author); if(isTest) {
if(preu.getToken() == null || !event.getMessage().getContentDisplay().equals(preu.getToken())) { preu = PreUser.getTestUser(author);
}else {
preu = PreUser.getPreUser(author);
}
if(preu.getToken() != null) {
channel.sendMessage("Sorry! That's not quite right! Please try again.").queue(); 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(); Cage cage = Main.getBiscuit().getCage();
@ -85,44 +129,61 @@ public class DMListener extends ListenerAdapter{
}else { }else {
captcha = new File(PluginCore.plugin.getDataFolder(), "captcha/" + author.getId() + ".jpg"); 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(); channel.sendFile(captcha).queue();
}else { }else {
String tlabel = "";
if(isTest) {
tlabel = "[TEST] ";
}
preu.setDone(); 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 newrole = null;
Role defaultrole = null; Role defaultrole = null;
for(Guild g : preu.getGuilds()) { if(isTest) {
for(Role r : g.getRoles()) { testers.remove(author);
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(); 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;
}
} }

View File

@ -8,6 +8,7 @@ import com.fpghoti.biscuit.Main;
import com.fpghoti.biscuit.PluginCore; import com.fpghoti.biscuit.PluginCore;
import com.fpghoti.biscuit.config.PropertiesRetrieval; import com.fpghoti.biscuit.config.PropertiesRetrieval;
import com.fpghoti.biscuit.util.Util; import com.fpghoti.biscuit.util.Util;
import com.github.cage.Cage;
import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
@ -15,8 +16,18 @@ import net.dv8tion.jda.api.entities.User;
public class PreUser { public class PreUser {
public static CopyOnWriteArrayList<PreUser> testusers = new CopyOnWriteArrayList<PreUser>();
public static CopyOnWriteArrayList<PreUser> users = new CopyOnWriteArrayList<PreUser>(); public static CopyOnWriteArrayList<PreUser> users = new CopyOnWriteArrayList<PreUser>();
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) { public static PreUser getPreUser(User user) {
for(PreUser u : users) { for(PreUser u : users) {
if(u.getUser().getId().equals(user.getId())) { if(u.getUser().getId().equals(user.getId())) {
@ -34,13 +45,21 @@ public class PreUser {
private String token; private String token;
private int timeLeft; private int timeLeft;
private boolean done; private boolean done;
private boolean test;
public PreUser(User user) { public PreUser(User user) {
this(user, false);
}
public PreUser(User user, boolean test) {
this.test = test;
this.user = user; this.user = user;
this.token = null; this.token = null;
this.done = false; this.done = false;
this.timeLeft = PropertiesRetrieval.noCaptchaKickTime() + 1; this.timeLeft = PropertiesRetrieval.noCaptchaKickTime() + 1;
users.add(this); if(!test) {
users.add(this);
}
} }
public User getUser() { public User getUser() {
@ -51,10 +70,9 @@ public class PreUser {
return this.token; return this.token;
} }
//Going to use custom string gen for more char types in captcha
public void genToken() { public void genToken() {
//token = Main.getBiscuit().getCage().getTokenGenerator().next(); Cage cage = Main.getBiscuit().getCage();
token = Util.randomString(6); token = cage.getTokenGenerator().next();
} }
public void setDone() { public void setDone() {
@ -67,6 +85,10 @@ public class PreUser {
return; return;
} }
if(test) {
return;
}
if(!done) { if(!done) {
if(PropertiesRetrieval.noCaptchaKick()) { if(PropertiesRetrieval.noCaptchaKick()) {
timeLeft = timeLeft - 1; timeLeft = timeLeft - 1;
@ -115,6 +137,7 @@ public class PreUser {
token = null; token = null;
captcha.delete(); captcha.delete();
users.remove(this); users.remove(this);
testusers.remove(this);
} }
} }

View File

@ -8,11 +8,11 @@ import net.dv8tion.jda.api.entities.TextChannel;
public class Util { public class Util {
public static int randInt(int min, int max) { 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) { public static Boolean isLoggable(TextChannel c) {
@ -44,20 +44,4 @@ public class Util {
return s2.replace(".", "").matches("[0-9]+"); 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;
}
} }