AFKGuard allows you to detect even the most tricky AFK machines and cheats, by being fully configurable and accessible!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
4.9 KiB

package com.entryrise.afkguard.antiafk.captcha;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SplittableRandom;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import com.entryrise.afkguard.Main;
import com.entryrise.afkguard.mineutils.ItemBuilder;
public class CaptchaGUI implements Listener {
public static List<Integer> filler = new ArrayList<Integer>();
private static SplittableRandom sr = new SplittableRandom();
// Fillers where selector items can stay;
static {
for (int i = 19; i < 26; i++) {
filler.add(i);
}
for (int i = 28; i < 35; i++) {
filler.add(i);
}
for (int i = 37; i < 44; i++) {
filler.add(i);
}
filler.add(10);
filler.add(11);
filler.add(15);
filler.add(16);
}
public static class CaptchaData {
public CaptchaCategory category;
public Material example;
public Inventory inv;
public int counter;
public CaptchaData() {
this.category = CaptchaCategory.getCategory(null);
this.example = category.getRandom(null);
}
}
public static Map<UUID, CaptchaData> invs = new HashMap<UUID, CaptchaData>();
public static Inventory getInventory(Player p, int counter) {
return getInventory(p.getUniqueId(), counter);
}
public static boolean existsAlready(Player p) {
return existsAlready(p.getUniqueId());
}
public static boolean existsAlready(UUID u) {
return invs.containsKey(u);
}
public static Inventory getInventory(UUID u, int counter) {
if (existsAlready(u)) {
return invs.get(u).inv;
} else if (counter != -1) {
return createInventory(u, counter);
}
return null;
}
private static Inventory createInventory(UUID u, int counter) {
CaptchaData cd = new CaptchaData();
Inventory inv = Bukkit.createInventory(null, 54, getTitle(cd.category.getName()));
setBorders(inv);
setRandomExample(inv, cd);
setRandomAnswers(inv, cd);
cd.inv = inv;
cd.counter = counter;
invs.put(u, cd);
return inv;
}
public static String getTitle(String categoryname) {
return ChatColor.translateAlternateColorCodes('&', Main.config.getString("settings.captcha.gui.title"))
.replace("%category%", categoryname);
}
@EventHandler
public void onInventoryClick(InventoryClickEvent e) {
HumanEntity hm = e.getWhoClicked();
if (!(hm instanceof Player)) {
return;
}
Player p = (Player) hm;
Inventory invent = e.getInventory();
ItemStack itm = e.getCurrentItem();
if (itm == null) {
return;
}
if (!invs.containsKey(p.getUniqueId())) {
return;
}
if (!invent.equals(invs.get(p.getUniqueId()).inv)) {
return;
}
// Done checks to make sure it's a verify gui. We can now do the work required.
int slot = e.getSlot();
// Make sure you're not clicking anywhere except verify items.
e.setCancelled(true);
if (!filler.contains(slot)) {
return;
}
Main.captchaResult(p, itm.getType());
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent e) {
HumanEntity hm = e.getPlayer();
if (!(hm instanceof Player)) {
return;
}
Player p = (Player) hm;
Inventory invent = e.getInventory();
if (!invs.containsKey(p.getUniqueId())) {
return;
}
if (!invent.equals(invs.get(p.getUniqueId()).inv)) {
return;
}
Bukkit.getScheduler().runTaskLater(Main.p, () -> p.openInventory(CaptchaGUI.getInventory(p, -1)), 5);
}
public static void setBorders(Inventory inv) {
ItemStack pane = new ItemBuilder(Main.config, "settings.captcha.gui.glass-pane").build();
for (int i = 4; i <= 49; i += 9) {
inv.setItem(i - 4, pane);
inv.setItem(i + 4, pane);
}
for (int i = 1; i <= 7; i++) {
inv.setItem(i, pane);
inv.setItem(i + 45, pane);
}
inv.setItem(12, pane);
inv.setItem(13, pane);
inv.setItem(14, pane);
}
public static void setRandomExample(Inventory inv, CaptchaData cd) {
ItemStack itm = new ItemBuilder(Main.config, "settings.captcha.gui.example").setType(cd.example.name()).build();
inv.setItem(4, itm);
}
public static void setRandomAnswers(Inventory inv, CaptchaData cd) {
List<Material> mats = cd.category.getShuffledFiller();
for (int i = 0; i < filler.size(); i++) {
Material mat = mats.get(i);
int slot = filler.get(i);
ItemStack itm = prepareItemStack(mat);
inv.setItem(slot, itm);
}
inv.setItem(filler.get(sr.nextInt(filler.size())), prepareItemStack(cd.category.getRandom(cd.example)));
}
private static ItemStack prepareItemStack(Material mat) {
ItemStack itm = new ItemBuilder(Main.config, "settings.captcha.gui.item").setType(mat.name()).build();
return itm;
}
}