/src/jd/captcha/JAntiCaptcha.java
https://bitbucket.org/jorgenio/jdownloader · Java · 2022 lines · 1479 code · 249 blank · 294 comment · 391 complexity · c7b1cfed3d209b39158660b898c3aa15 MD5 · raw file
Large files are truncated click here to view the full file
- // jDownloader - Downloadmanager
- // Copyright (C) 2008 JD-Team support@jdownloader.org
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- package jd.captcha;
-
- import java.awt.Color;
- import java.awt.Graphics;
- import java.awt.GridBagLayout;
- import java.awt.GridLayout;
- import java.awt.Image;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.io.FileFilter;
- import java.io.IOException;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.ListIterator;
- import java.util.Vector;
- import java.util.logging.Logger;
-
- import javax.imageio.ImageIO;
- import javax.swing.ImageIcon;
- import javax.swing.JButton;
- import javax.swing.JCheckBox;
- import javax.swing.JDialog;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JOptionPane;
- import javax.swing.JPanel;
- import javax.swing.JScrollPane;
- import javax.swing.JTextArea;
-
- import jd.captcha.configuration.JACScript;
- import jd.captcha.gui.BasicWindow;
- import jd.captcha.gui.ImageComponent;
- import jd.captcha.gui.ScrollPaneWindow;
- import jd.captcha.pixelgrid.Captcha;
- import jd.captcha.pixelgrid.Letter;
- import jd.captcha.utils.Utilities;
- import jd.controlling.JDLogger;
- import jd.gui.userio.DummyFrame;
- import jd.http.Browser;
- import jd.nutils.Executer;
- import jd.nutils.JDHash;
- import jd.nutils.io.JDIO;
- import jd.utils.JDUtilities;
-
- import org.appwork.utils.Regex;
- import org.appwork.utils.os.CrossSystem;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.NamedNodeMap;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
-
- /**
- * Diese Klasse stellt alle public Methoden zur captcha Erkennung zur Verfügung.
- * Sie verküpft Letter und captcha Klassen. Gleichzeitig dient sie als
- * Parameter-Dump.
- *
- * @author JD-Team
- */
- public class JAntiCaptcha {
-
- /**
- * Logger
- */
- private static Logger logger = Utilities.getLogger();
-
- /**
- * Testet die Angegebene Methode. Dabei werden analysebilder erstellt.
- *
- * @param file
- */
- public static void testMethod(File file) {
- int checkCaptchas = 20;
- String code;
- String inputCode;
- int totalLetters = 0;
- int correctLetters = 0;
- File captchaFile;
- Image img;
- String methodName = file.getName();
- File captchaDir = new File(file.getAbsolutePath() + "/captchas");
- if (Utilities.isLoggerActive()) {
- logger.info("Test Method: " + methodName);
- }
- new JAntiCaptcha(methodName);
- File[] entries = captchaDir.listFiles(new FileFilter() {
- public boolean accept(File pathname) {
- // if(Utilities.isLoggerActive())logger.info(pathname.getName(
- // ));
- if (pathname.getName().endsWith(".jpg") || pathname.getName().endsWith(".png") || pathname.getName().endsWith(".gif")) {
-
- return true;
- } else {
- return false;
- }
- }
-
- });
- ScrollPaneWindow w = new ScrollPaneWindow();
- w.setTitle(" Test Captchas: " + file.getAbsolutePath());
-
- w.resizeWindow(100);
- if (Utilities.isLoggerActive()) {
- logger.info("Found Testcaptchas: " + entries.length);
- }
- int testNum = Math.min(checkCaptchas, entries.length);
- if (Utilities.isLoggerActive()) {
- logger.info("Test " + testNum + " Captchas");
- }
- int i = 0;
- for (i = 0; i < testNum; i++) {
- captchaFile = entries[(int) (Math.random() * entries.length)];
-
- logger.info("JJJJJJJJ" + captchaFile);
- img = Utilities.loadImage(captchaFile);
- w.setText(0, i, captchaFile.getName());
- w.setImage(1, i, img);
-
- w.repack();
-
- JAntiCaptcha jac = new JAntiCaptcha(methodName);
- // BasicWindow.showImage(img);
- Captcha cap = jac.createCaptcha(img);
- if (cap == null) {
- if (Utilities.isLoggerActive()) {
- logger.severe("Captcha Bild konnte nicht eingelesen werden");
- }
- continue;
- }
-
- w.setImage(2, i, cap.getImage());
- // BasicWindow.showImage(cap.getImageWithGaps(2));
- code = jac.checkCaptcha(captchaFile, cap);
- w.setImage(3, i, cap.getImage());
-
- w.setText(4, i, "JAC:" + code);
-
- w.repack();
-
- inputCode = JOptionPane.showInputDialog("Bitte Captcha Code eingeben", code);
-
- w.setText(5, i, "User:" + inputCode);
- w.repack();
- if (code == null) {
- code = "";
- }
- if (inputCode == null) {
- inputCode = "";
- }
- code = code.toLowerCase();
- inputCode = inputCode.toLowerCase();
- for (int x = 0; x < inputCode.length(); x++) {
- totalLetters++;
-
- if (inputCode.length() == code.length() && inputCode.charAt(x) == code.charAt(x)) {
- correctLetters++;
- }
- }
- if (Utilities.isLoggerActive()) {
- logger.info("Erkennung: " + correctLetters + "/" + totalLetters + " = " + Utilities.getPercent(correctLetters, totalLetters) + "%");
- }
- }
- w.setText(0, i + 1, "Erkennung: " + Utilities.getPercent(correctLetters, totalLetters) + "%");
- w.setText(4, i + 1, "Richtig: " + correctLetters);
- w.setText(5, i + 1, "Falsch: " + (totalLetters - correctLetters));
- JOptionPane.showMessageDialog(new JFrame(), "Erkennung: " + correctLetters + "/" + totalLetters + " = " + Utilities.getPercent(correctLetters, totalLetters) + "%");
- }
-
- /**
- * Führt einen Testlauf mit den übergebenen Methoden durch
- *
- * @param methods
- */
- public static void testMethods(File[] methods) {
- for (File element : methods) {
- JAntiCaptcha.testMethod(element);
- }
-
- }
-
- /**
- * Fenster die eigentlich nur zur Entwicklung sind um Basic GUI Elemente zu
- * haben
- */
- private BasicWindow bw2;
-
- private BasicWindow bw3;
-
- private JDialog f;
-
- /**
- * Bildtyp. Falls dieser von jpg unterschiedlich ist, muss zuerst
- * konvertiert werden.
- */
- private String imageType;
-
- /**
- * jas Script Instanz. Sie verarbneitet das JACScript und speichert die
- * Parameter
- */
- public JACScript jas;
- /**
- * Vector mit den Buchstaben aus der MTHO File
- */
- public ArrayList<Letter> letterDB;
-
- private int[][] letterMap = null;
-
- /**
- * Anzahl der Buchstaben im Captcha. Wird aus der jacinfo.xml gelesen
- */
- private int letterNum;
-
- /**
- * ordnername der methode
- */
- private String methodDirName;
-
- private boolean showDebugGui = false;
-
- private Vector<ScrollPaneWindow> spw = new Vector<ScrollPaneWindow>();
-
- private Captcha workingCaptcha;
-
- private boolean extern;
-
- public boolean isExtern() {
- return extern;
- }
-
- private String command;
-
- private String dstFile;
-
- private String srcFile;
-
- private Image sourceImage;
-
- public JAntiCaptcha(String methodName) {
- JACMethod method = JACMethod.forServiceName(methodName);
- if (method == null) {
- logger.severe("no such method found! " + methodName);
- return;
- }
- methodDirName = method.getFileName();
-
- getJACInfo();
-
- jas = new JACScript(this, methodDirName);
- long time = System.currentTimeMillis();
- loadMTHFile();
-
- time = System.currentTimeMillis() - time;
- System.out.println(time);
- if (Utilities.isLoggerActive()) {
- logger.fine("letter DB loaded: Buchstaben: " + letterDB.size());
- }
- }
-
- /**
- * prüft den übergebenen Captcha und gibt den Code als String zurück. Das
- * lettersarray des Catchas wird dabei bearbeitet. Es werden decoedvalue,
- * avlityvalue und parent gesetzt WICHTIG: Nach dem Decoden eines Captcha
- * herrscht Verwirrung. Es stehen unterschiedliche Methoden zur Verfügung um
- * an bestimmte Informationen zu kommen: captcha.getDecodedLetters() gibt
- * Die letter aus der datenbank zurück. Deren werte sind nicht fest. Auf den
- * Wert von getvalityvalue und getValityPercent kann man sich absolut nicht
- * verlassen. Einzig getDecodedValue() lässt sich zuverlässig auslesen
- * captcha.getLetters() gibt die Wirklichen Letter des captchas zurück. Hier
- * lassen sich alle wichtigen Infos abfragen. z.B. ValityValue,
- * ValityPercent, Decodedvalue, etc. Wer immer das hier liest sollte auf
- * keinen fall den fehler machen und sich auf Wert aus dem getdecodedLetters
- * array verlassen
- *
- * @param captcha
- * Captcha instanz
- * @return CaptchaCode
- */
- public String checkCaptcha(File file, Captcha captcha) {
- if (extern) return callExtern();
- workingCaptcha = captcha;
- // Führe prepare aus
- jas.executePrepareCommands(file, captcha);
- Letter[] letters = captcha.getLetters(getLetterNum());
- if (letters == null) {
- captcha.setValityPercent(100.0);
- if (Utilities.isLoggerActive()) {
- logger.severe("Captcha konnte nicht erkannt werden!");
- }
- return null;
- }
- String ret = "";
- double correct = 0;
- LetterComperator akt;
-
- // Scannen
- Vector<LetterComperator> newLettersVector = new Vector<LetterComperator>();
- for (int i = 0; i < letters.length; i++) {
- letters[i].setId(i);
- if (letters[i].detected != null) {
- akt = letters[i].detected;
- } else {
- akt = getLetter(letters[i]);
- }
- akt.getA().setId(i);
-
- newLettersVector.add(akt);
-
- }
- if (letters.length > getLetterNum()) {
- // sortieren
- Collections.sort(newLettersVector, new Comparator<LetterComperator>() {
- public int compare(LetterComperator obj1, LetterComperator obj2) {
-
- if (obj1.getValityPercent() < obj2.getValityPercent()) { return -1; }
- if (obj1.getValityPercent() > obj2.getValityPercent()) { return 1; }
- return 0;
- }
- });
-
- // schlechte entfernen
- if (Utilities.isLoggerActive()) {
- logger.info(getLetterNum() + "");
- }
-
- if (!jas.getBoolean("autoLetterNum")) {
- for (int i = newLettersVector.size() - 1; i >= getLetterNum(); i--) {
- newLettersVector.remove(i);
- }
- }
- // Wieder in die richtige reihenfolge sortieren
- Collections.sort(newLettersVector, new Comparator<LetterComperator>() {
- public int compare(LetterComperator obj1, LetterComperator obj2) {
-
- if (obj1.getA().getId() < obj2.getA().getId()) { return -1; }
- if (obj1.getA().getId() > obj2.getA().getId()) { return 1; }
- return 0;
- }
- });
- }
-
- if (getJas().getString("useLettercomparatorFilter") != null && getJas().getString("useLettercomparatorFilter").length() > 0) {
- String[] ref = getJas().getString("useLettercomparatorFilter").split("\\.");
- if (ref.length != 2) {
- captcha.setValityPercent(100.0);
- if (Utilities.isLoggerActive()) {
- logger.severe("useLettercomparatorFilter should have the format Class.Method");
- }
- return null;
- }
- String cl = ref[0];
- String methodname = ref[1];
-
- Class<?> newClass;
- try {
- newClass = Class.forName("jd.captcha.specials." + cl);
-
- Class<?>[] parameterTypes = new Class[] { newLettersVector.getClass(), this.getClass() };
- Method method = newClass.getMethod(methodname, parameterTypes);
- Object[] arguments = new Object[] { newLettersVector, this };
- Object instance = null;
- method.invoke(instance, arguments);
-
- } catch (Exception e) {
- if (Utilities.isLoggerActive()) {
- logger.severe("Fehler in useLettercomparatorFilter:" + e.getLocalizedMessage() + " / " + getJas().getString("useLettercomparatorFilter"));
- }
- JDLogger.exception(e);
- }
-
- }
- for (int i = 0; i < newLettersVector.size(); i++) {
- akt = newLettersVector.get(i);
-
- if (akt == null || akt.getValityPercent() >= 100.0) {
- ret += "-";
- correct += 100.0;
- } else {
- ret += akt.getDecodedValue();
-
- akt.getA().setId(i);
- correct += akt.getValityPercent();
-
- }
- // if(Utilities.isLoggerActive())logger.finer("Validty: " +
- // correct);
- }
- if (newLettersVector.size() == 0) {
- captcha.setValityPercent(100.0);
-
- return null;
- }
- captcha.setLetterComperators(newLettersVector.toArray(new LetterComperator[] {}));
-
- if (Utilities.isLoggerActive()) {
- logger.finer("Vality: " + (int) (correct / newLettersVector.size()));
- }
- captcha.setValityPercent(correct / newLettersVector.size());
- return ret;
- }
-
- /**
- * Exportiert die aktelle Datenbank als PNG einzelbilder
- */
- public void exportDB() {
- File path = Utilities.directoryChooser();
-
- File file;
- BufferedImage img;
- int i = 0;
- for (Letter letter : letterDB) {
-
- img = letter.getFullImage();
- file = new File(path + "/letterDB/" + i++ + "_" + letter.getDecodedValue() + ".png");
- file.mkdirs();
-
- try {
- logger.info("Write Db: " + file);
- ImageIO.write(img, "png", file);
- } catch (IOException e) {
- JDLogger.exception(e);
- }
- }
- }
-
- private BufferedImage toBufferedImage(Image i) {
- if (i instanceof BufferedImage) { return (BufferedImage) i; }
- Image img;
- img = new ImageIcon(i).getImage();
- BufferedImage b;
- b = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
- Graphics g = b.createGraphics();
- g.drawImage(img, 0, 0, null);
- g.dispose();
- return b;
- }
-
- private String callExtern() {
- try {
- File file = JDUtilities.getResourceFile(this.srcFile);
- file.getParentFile().mkdirs();
- String ext = CrossSystem.getFileExtension(file.getName());
- ImageIO.write(toBufferedImage(this.sourceImage), ext, file);
- } catch (Exception e) {
- JDLogger.exception(e);
- return null;
- }
- Executer exec = new Executer(JDUtilities.getResourceFile(this.command).getAbsolutePath());
- exec.setRunin(JDUtilities.getResourceFile(this.command).getParent());
- exec.setWaitTimeout(30);
- exec.start();
- exec.waitTimeout();
- // String ret = exec.getOutputStream() + " \r\n " +
- // exec.getErrorStream();
-
- String res = JDIO.readFileToString(JDUtilities.getResourceFile(this.dstFile));
- if (res == null) return null;
- return res.trim();
-
- }
-
- /**
- * Gibt den erkannten CaptchaText zurück
- *
- * @param captchafile
- * Pfad zum Bild
- * @return CaptchaCode
- */
- public String checkCaptcha(File captchafile) {
- if (Utilities.isLoggerActive()) {
- logger.finer("check " + captchafile);
- }
- Image captchaImage = Utilities.loadImage(captchafile);
- Captcha captcha = createCaptcha(captchaImage);
- if (captcha != null) captcha.setCaptchaFile(captchafile);
- // captcha.printCaptcha();
- return checkCaptcha(captchafile, captcha);
- }
-
- /**
- * Factory Methode zur Captcha erstellung
- *
- * @param captchaImage
- * Image instanz
- * @return captcha
- */
- public Captcha createCaptcha(Image captchaImage) {
- this.sourceImage = captchaImage;
- if (extern) return null;
- if (captchaImage.getWidth(null) <= 0 || captchaImage.getHeight(null) <= 0) {
- if (Utilities.isLoggerActive()) {
- logger.severe("Image Dimensionen zu klein. Image hat keinen Inahlt. Pfad/Url prüfen!");
- }
- return null;
- }
- Captcha ret = Captcha.getCaptcha(captchaImage, this);
- if (ret == null) { return null; }
- ret.setOwner(this);
- return ret;
- }
-
- /**
- * Aus gründen der geschwindigkeit wird die MTH XMl in einen vector
- * umgewandelt
- */
- private void createLetterDBFormMTH(Document mth) {
- letterDB = new ArrayList<Letter>();
- long start1 = System.currentTimeMillis();
- try {
-
- if (mth == null || mth.getFirstChild() == null) { return; }
- NodeList nl = mth.getFirstChild().getChildNodes();
- Letter tmp;
- for (int i = 0; i < nl.getLength(); i++) {
- // Get child node
- Node childNode = nl.item(i);
- if (childNode.getNodeName().equals("letter")) {
- NamedNodeMap att = childNode.getAttributes();
-
- tmp = new Letter();
- tmp.setOwner(this);
- String id = JDUtilities.getAttribute(childNode, "id");
- if (!tmp.setTextGrid(childNode.getTextContent())) {
-
- logger.severe("Error in Letters DB line: " + i + ":" + childNode.getTextContent() + " id:" + id);
- continue;
- }
-
- if (id != null) {
- tmp.setId(Integer.parseInt(id));
- }
- tmp.setSourcehash(att.getNamedItem("captchaHash").getNodeValue());
- tmp.setDecodedValue(att.getNamedItem("value").getNodeValue());
- tmp.setBadDetections(Integer.parseInt(JDUtilities.getAttribute(childNode, "bad")));
- tmp.setGoodDetections(Integer.parseInt(JDUtilities.getAttribute(childNode, "good")));
- letterDB.add(tmp);
- } else if (childNode.getNodeName().equals("map")) {
- if (Utilities.isLoggerActive()) {
- logger.fine("Parse LetterMap");
- }
- long start2 = System.currentTimeMillis();
- String[] map = childNode.getTextContent().split("\\|");
- letterMap = new int[map.length][map.length];
- for (int x = 0; x < map.length; x++) {
- String[] row = map[x].split("\\,");
- for (int y = 0; y < map.length; y++) {
- letterMap[x][y] = Integer.parseInt(row[y]);
- }
-
- }
- if (Utilities.isLoggerActive()) {
- logger.fine("LetterMap Parsing time: " + (System.currentTimeMillis() - start2));
- }
- }
- }
- } catch (Exception e) {
- JDLogger.exception(e);
- if (Utilities.isLoggerActive()) {
- logger.severe("Fehler bein lesen der MTH Datei!!. Methode kann nicht funktionieren!");
- }
-
- }
- if (Utilities.isLoggerActive()) {
- logger.fine("Mth Parsing time: " + (System.currentTimeMillis() - start1));
- }
- }
-
- /**
- * Diese methode trainiert einen captcha
- *
- * @param captchafile
- * File zum Bild
- * @param letterNum
- * Anzahl der Buchstaben im captcha
- * @return int -1: Übersprungen Sonst: anzahl der richtig erkanten Letter
- */
-
- private Document createXMLFromLetterDB() {
- Document xml = JDUtilities.parseXmlString("<jDownloader></jDownloader>", false);
- if (letterMap != null) {
- Element element = xml.createElement("map");
- xml.getFirstChild().appendChild(element);
- element.appendChild(xml.createTextNode(getLetterMapString()));
- }
-
- int i = 0;
- for (Letter letter : letterDB) {
- Element element = xml.createElement("letter");
- xml.getFirstChild().appendChild(element);
- element.appendChild(xml.createTextNode(letter.getPixelString()));
- element.setAttribute("id", i++ + "");
- element.setAttribute("value", letter.getDecodedValue());
- element.setAttribute("captchaHash", letter.getSourcehash());
- element.setAttribute("good", letter.getGoodDetections() + "");
- element.setAttribute("bad", letter.getBadDetections() + "");
-
- }
- return xml;
-
- }
-
- private void destroyScrollPaneWindows() {
- while (spw.size() > 0) {
- spw.remove(0).destroy();
- }
- }
-
- /**
- * Zeigt die Momentane Library an. Buchstaben können gelöscht werden
- */
- public void displayLibrary() {
- if (letterDB == null || letterDB.size() == 0) { return; }
- // final BasicWindow w = BasicWindow.getWindow("Library: " +
- // letterDB.size() + " Datensätze", 400, 300);
- final JFrame w = new JFrame();
- // w.setLayout(new GridBagLayout());
- sortLetterDB();
- JPanel p = new JPanel(new GridLayout(letterDB.size() + 1, 3));
- w.add(new JScrollPane(p));
-
- final Letter[] list = new Letter[letterDB.size()];
-
- int y = 0;
- int i = 0;
- ListIterator<Letter> iter = letterDB.listIterator(letterDB.size());
- final ArrayList<Integer> rem = new ArrayList<Integer>();
- while (iter.hasPrevious()) {
- final Letter tmp = iter.previous();
- list[i] = tmp;
-
- JLabel lbl = null;
- if ((tmp.getGoodDetections() == 0 && tmp.getBadDetections() > 3) || ((double) tmp.getBadDetections() / (double) tmp.getGoodDetections() >= 3)) {
- lbl = new JLabel("<html><p><font color=\"#ff0000\" " + "size=\"3\">" + tmp.getId() + ": " + tmp.getDecodedValue() + "(" + tmp.getGoodDetections() + "/" + tmp.getBadDetections() + ") Size: " + tmp.toPixelObject(0.85).getSize() + "</font> </p>" + "</html>");
- } else {
- lbl = new JLabel(tmp.getId() + ": " + tmp.getDecodedValue() + "(" + tmp.getGoodDetections() + "/" + tmp.getBadDetections() + ") Size: " + tmp.toPixelObject(0.85).getSize());
- }
-
- ImageComponent img = new ImageComponent(tmp.getImage());
-
- final JCheckBox bt = new JCheckBox("DELETE");
- final int ii = i;
- bt.addActionListener(new ActionListener() {
- public Integer id = ii;
-
- public void actionPerformed(ActionEvent arg) {
- JCheckBox src = ((JCheckBox) arg.getSource());
- if (src.getText().equals("DELETE")) {
- rem.add(id);
- } else {
- rem.remove(id);
- }
- }
-
- });
- p.add(lbl);
- p.add(img);
- p.add(bt);
- i++;
- y++;
- // if (y > 20) {
- // y = 0;
- // x += 6;
- // }
- }
- JButton b = new JButton("Invoke");
- p.add(b);
- b.addActionListener(new ActionListener() {
-
- public void actionPerformed(ActionEvent e) {
- // System.out.println(rem + "");
- ArrayList<Letter> list = new ArrayList<Letter>();
- int s = letterDB.size();
- for (Integer i : rem) {
- try {
- Letter let = letterDB.get(s - 1 - i);
- list.add(let);
-
- } catch (Exception ew) {
- JDLogger.exception(ew);
- }
- }
- for (Letter letter : list) {
- removeLetterFromLibrary(letter);
- }
- saveMTHFile();
- displayLibrary();
- }
- });
- w.pack();
- w.setVisible(true);
- }
-
- public String getCodeFromFileName(String name) {
- return new Regex(name, "captcha_(.*?)_code(.*?)\\.(.*?)").getMatch(1);
- }
-
- /**
- * Liest den captchaornder aus
- *
- * @param path
- * @return File Array
- */
- public File[] getImages(String path) {
- File dir = new File(path);
-
- if (dir == null || !dir.exists()) {
- if (Utilities.isLoggerActive()) {
- logger.severe("Image dir nicht gefunden " + path);
- }
-
- }
- logger.info(dir + "");
- File[] entries = dir.listFiles(new FileFilter() {
- public boolean accept(File pathname) {
- if (Utilities.isLoggerActive()) {
- logger.info(pathname.getName());
- }
- if (pathname.getName().endsWith(".bmp") || pathname.getName().endsWith(".jpg") || pathname.getName().endsWith(".png") || pathname.getName().endsWith(".gif")) {
-
- return true;
- } else {
- return false;
- }
- }
-
- });
- return entries;
-
- }
-
- /**
- * @return the imageType
- */
- public String getImageType() {
- return imageType;
- }
-
- /**
- * Die Methode parsed die jacinfo.xml
- */
- private void getJACInfo() {
- File f = getResourceFile("jacinfo.xml");
- if (!f.exists()) {
- if (Utilities.isLoggerActive()) {
- logger.severe("jacinfo.xml is missing2");
- }
- return;
- }
- Document doc = JDUtilities.parseXmlString(JDIO.readFileToString(f), false);
- if (doc == null) {
- if (Utilities.isLoggerActive()) {
- logger.severe("jacinfo.xml is missing2");
- }
- return;
- }
-
- NodeList nl = doc.getFirstChild().getChildNodes();
- for (int i = 0; i < nl.getLength(); i++) {
- // Get child node
- Node childNode = nl.item(i);
-
- if (childNode.getNodeName().equals("method")) {
- try {
- this.extern = JDUtilities.getAttribute(childNode, "type").equalsIgnoreCase("extern");
- } catch (Exception e) {
- }
- } else if (childNode.getNodeName().equals("command")) {
-
- this.srcFile = JDUtilities.getAttribute(childNode, "src");
- this.dstFile = JDUtilities.getAttribute(childNode, "dst");
- this.command = JDUtilities.getAttribute(childNode, "cmd");
-
- } else if (childNode.getNodeName().equals("format")) {
- try {
- setLetterNum(Integer.parseInt(JDUtilities.getAttribute(childNode, "letterNum")));
- } catch (Exception e) {
- }
-
- setImageType(JDUtilities.getAttribute(childNode, "type"));
- }
- }
- }
-
- /**
- * @return JACscript Instanz
- */
- public JACScript getJas() {
- return jas;
- }
-
- /**
- * Vergleicht a und b und gibt eine Vergleichszahl zurück. a und b werden
- * gegeneinander verschoben und b wird über die Parameter gedreht. Praktisch
- * heißt das, dass derjenige Treffer als gut eingestuft wird, bei dem der
- * Datenbank Datensatz möglichst optimal überdeckt wird.
- *
- * @param a
- * Original Letter
- * @param B
- * Vergleichsletter
- * @return int 0(super)-0xffffff (ganz übel)
- */
- public LetterComperator getLetter(Letter letter) {
- if (jas.getDouble("quickScanValityLimit") <= 0) {
- logger.info("quickscan disabled");
- return getLetterExtended(letter);
-
- }
-
- logger.info("Work on Letter:" + letter);
- // long startTime = Utilities.getTimer();
- LetterComperator res = null;
- double lastPercent = 100.0;
- int bvX, bvY;
- try {
-
- if (letterDB == null) {
- if (Utilities.isLoggerActive()) {
- logger.severe("letterDB nicht vorhanden");
- }
- return null;
- }
-
- LetterComperator lc;
- ScrollPaneWindow w = null;
- if (isShowDebugGui()) {
- w = new ScrollPaneWindow();
-
- w.setTitle(" Letter " + letter.getId());
- }
- bvX = jas.getInteger("borderVarianceX");
- bvY = jas.getInteger("borderVarianceY");
- int line = 0;
- lc = new LetterComperator(letter, null);
- lc.setScanVariance(0, 0);
- lc.setOwner(this);
- res = lc;
- int tt = 0;
- logger.info("Do quickscan");
- Method preValueFilterMethod = null;
- Class<?>[] preValueFilterParameterTypes = null;
- Object[] preValueFilterArguments = new Object[] { null, this };
- if (jas.getString("preValueFilter").length() > 0) {
- String[] ref = jas.getString("preValueFilter").split("\\.");
- if (ref.length != 2) {
- if (Utilities.isLoggerActive()) {
- logger.severe("preValueFilter should have the format Class.Method");
- }
- return null;
- }
- String cl = ref[0];
- String methodname = ref[1];
- Class<?> newClass;
- try {
- newClass = Class.forName("jd.captcha.specials." + cl);
- preValueFilterParameterTypes = new Class[] { LetterComperator.class, this.getClass() };
- preValueFilterMethod = newClass.getMethod(methodname, preValueFilterParameterTypes);
-
- } catch (Exception e) {
- JDLogger.exception(e);
- }
- }
- Method postValueFilterMethod = null;
- Class<?>[] postValueFilterParameterTypes = null;
- Object[] postValueFilterArguments = new Object[] { null, this };
- if (jas.getString("postValueFilter").length() > 0) {
- String[] ref = jas.getString("postValueFilter").split("\\.");
- if (ref.length != 2) {
- if (Utilities.isLoggerActive()) {
- logger.severe("postValueFilter should have the format Class.Method");
- }
- return null;
- }
- String cl = ref[0];
- String methodname = ref[1];
- Class<?> newClass;
- try {
- newClass = Class.forName("jd.captcha.specials." + cl);
- postValueFilterParameterTypes = new Class[] { LetterComperator.class, this.getClass() };
- postValueFilterMethod = newClass.getMethod(methodname, postValueFilterParameterTypes);
-
- } catch (Exception e) {
- JDLogger.exception(e);
- }
- }
- for (Letter tmp : letterDB) {
- if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
-
- if (Math.abs(tmp.getHeight() - letter.getHeight()) > bvY || Math.abs(tmp.getWidth() - letter.getWidth()) > bvX) {
- continue;
- }
-
- lc = new LetterComperator(letter, tmp);
- // commented out only experimental
- // lc.setScanVariance(0, 0);
- lc.setOwner(this);
-
- if (preValueFilterMethod != null) {
- preValueFilterArguments[0] = tmp;
- preValueFilterArguments[1] = lc;
- if (!((Boolean) preValueFilterMethod.invoke(null, preValueFilterArguments))) {
- continue;
- }
-
- }
- lc.run();
- tt++;
- if (isShowDebugGui()) {
- w.setText(0, line, "0° Quick " + tt);
- w.setImage(1, line, lc.getA().getImage(2));
- w.setText(2, line, lc.getA().getDim());
- w.setImage(3, line, lc.getB().getImage(2));
- w.setText(4, line, lc.getB().getDim());
- w.setImage(5, line, lc.getIntersectionLetter().getImage(2));
- w.setText(6, line, lc.getIntersectionLetter().getDim());
- w.setText(7, line, lc);
- line++;
- }
- postValueFilterArguments[0] = lc;
- if (postValueFilterMethod == null || (Boolean) postValueFilterMethod.invoke(null, postValueFilterArguments)) {
- if (res == null || lc.getValityPercent() < res.getValityPercent()) {
- if (res != null && res.getValityPercent() < lastPercent) {
- lastPercent = res.getValityPercent();
- }
- res = lc;
- if (jas.getDouble("LetterSearchLimitPerfectPercent") >= lc.getValityPercent()) {
- if (Utilities.isLoggerActive()) {
- logger.finer(" Perfect Match: " + res.getB().getDecodedValue() + res.getValityPercent() + " good:" + tmp.getGoodDetections() + " bad: " + tmp.getBadDetections() + " - " + res);
- }
- res.setDetectionType(LetterComperator.QUICKSCANPERFECTMATCH);
- res.setReliability(lastPercent - res.getValityPercent());
- return res;
- }
- // if(Utilities.isLoggerActive())logger.finer("dim "
- // +
- // lc.getA().getDim() + "|" + lc.getB().getDim() + " New
- // Best value: " + lc.getDecodedValue() + " "
- // +lc.getValityPercent() + " good:" +
- // tmp.getGoodDetections() + " bad: " +
- // tmp.getBadDetections() + " - " + lc);
- } else if (res != null) {
- if (lc.getValityPercent() < lastPercent) {
- lastPercent = lc.getValityPercent();
- }
- }
- }
- }
-
- } catch (Exception e) {
-
- JDLogger.exception(e);
- }
- if (res != null && res.getB() != null) {
- if (Utilities.isLoggerActive()) {
- logger.finer(" Normal Match: " + res.getB().getDecodedValue() + " " + res.getValityPercent() + " good:" + res.getB().getGoodDetections() + " bad: " + res.getB().getBadDetections());
- }
- // if (Utilities.isLoggerActive()) logger.fine("Letter erkannt
- // in: " + (Utilities.getTimer() - startTime) + " ms");
- res.setReliability(lastPercent - res.getValityPercent());
- if (res.getReliability() >= jas.getDouble("quickScanReliabilityLimit") && res.getValityPercent() < jas.getDouble("quickScanValityLimit")) {
- res.setDetectionType(LetterComperator.QUICKSCANMATCH);
- logger.info("Qickscan found " + res.getValityPercent() + "<" + jas.getDouble("quickScanValityLimit"));
- return res;
- } else {
- if (Utilities.isLoggerActive()) {
- logger.warning("Letter nicht ausreichend erkannt. Try Extended " + res.getReliability() + " - " + jas.getDouble("quickScanReliabilityLimit") + " /" + res.getValityPercent() + "-" + jas.getDouble("quickScanValityLimit"));
- }
- return getLetterExtended(letter);
- }
- } else {
- if (Utilities.isLoggerActive()) {
- logger.warning("Letter nicht erkannt. Try Extended");
- }
- return getLetterExtended(letter);
- }
-
- }
-
- /**
- * Sucht in der MTH ANch dem besten übereinstimmenem letter
- *
- * @param letter
- * (refferenz)
- * @return Letter. Beste Übereinstimmung
- */
- private LetterComperator getLetterExtended(Letter letter) {
- // long startTime = Utilities.getTimer();
- LetterComperator res = null;
- logger.info("Extended SCAN");
- double lastPercent = 100.0;
- JTextArea tf = null;
- try {
-
- if (letterDB == null) {
- if (Utilities.isLoggerActive()) {
- logger.severe("letterDB nicht vorhanden");
- }
- return null;
- }
-
- Letter tmp;
- int leftAngle = jas.getInteger("scanAngleLeft");
- int rightAngle = jas.getInteger("scanAngleRight");
- if (leftAngle > rightAngle) {
- int temp = leftAngle;
- leftAngle = rightAngle;
- rightAngle = temp;
- if (Utilities.isLoggerActive()) {
- logger.warning("param.scanAngleLeft>paramscanAngleRight");
- }
- }
- int steps = Math.max(1, jas.getInteger("scanAngleSteps"));
- boolean turnDB = jas.getBoolean("turnDB");
- int angle;
- Letter orgLetter = letter;
- LetterComperator lc;
-
- ScrollPaneWindow w = null;
- if (isShowDebugGui()) {
- w = new ScrollPaneWindow();
-
- w.setTitle(" Letter " + letter.getId());
- }
- int line = 0;
- lc = new LetterComperator(letter, null);
- lc.setOwner(this);
- res = lc;
-
- Method preValueFilterMethod = null;
- Class<?>[] preValueFilterParameterTypes = null;
- Object[] preValueFilterArguments = new Object[] { null, this };
- if (jas.getString("preValueFilter").length() > 0) {
- String[] ref = jas.getString("preValueFilter").split("\\.");
- if (ref.length != 2) {
- if (Utilities.isLoggerActive()) {
- logger.severe("preValueFilter should have the format Class.Method");
- }
- return null;
- }
- String cl = ref[0];
- String methodname = ref[1];
- Class<?> newClass;
- try {
- newClass = Class.forName("jd.captcha.specials." + cl);
- preValueFilterParameterTypes = new Class[] { LetterComperator.class, this.getClass() };
- preValueFilterMethod = newClass.getMethod(methodname, preValueFilterParameterTypes);
-
- } catch (Exception e) {
- JDLogger.exception(e);
- }
- }
- Method postValueFilterMethod = null;
- Class<?>[] postValueFilterParameterTypes = null;
- Object[] postValueFilterArguments = new Object[] { null, this };
- if (jas.getString("postValueFilter").length() > 0) {
- String[] ref = jas.getString("postValueFilter").split("\\.");
- if (ref.length != 2) {
- if (Utilities.isLoggerActive()) {
- logger.severe("postValueFilter should have the format Class.Method");
- }
- return null;
- }
- String cl = ref[0];
- String methodname = ref[1];
- Class<?> newClass;
- try {
- newClass = Class.forName("jd.captcha.specials." + cl);
- postValueFilterParameterTypes = new Class[] { LetterComperator.class, this.getClass() };
- postValueFilterMethod = newClass.getMethod(methodname, postValueFilterParameterTypes);
-
- } catch (Exception e) {
- JDLogger.exception(e);
- }
- }
- for (angle = Utilities.getJumperStart(leftAngle, rightAngle); Utilities.checkJumper(angle, leftAngle, rightAngle); angle = Utilities.nextJump(angle, leftAngle, rightAngle, steps)) {
-
- if (turnDB) {
- letter = orgLetter;
- } else {
- letter = orgLetter.turn(angle);
- }
- // if(Utilities.isLoggerActive())logger.finer(" Angle " +
- // angle + " : " + letter.getDim());
-
- int tt = 0;
- for (Letter ltr : letterDB) {
- if (Thread.currentThread().isInterrupted()) throw new InterruptedException();
-
- if (turnDB) {
- tmp = ltr.turn(angle);
-
- } else {
- tmp = ltr;
- }
-
- if (Math.abs(tmp.getHeight() - letter.getHeight()) > jas.getInteger("borderVarianceY") || Math.abs(tmp.getWidth() - letter.getWidth()) > jas.getInteger("borderVarianceX")) {
- continue;
- }
-
- lc = new LetterComperator(letter, tmp);
- lc.setOwner(this);
-
- if (preValueFilterMethod != null) {
- preValueFilterArguments[0] = lc;
- preValueFilterArguments[1] = this;
- if (!((Boolean) preValueFilterMethod.invoke(null, preValueFilterArguments))) {
- continue;
- }
-
- }
- lc.run();
- // if(Utilities.isLoggerActive())logger.info("Duration:
- // "+(Utilities.getTimer()-timer) +"
- // Loops: "+lc.loopCounter);
- tt++;
-
- if (isShowDebugGui()) {
- w.setText(0, line, angle + "° " + tt);
- w.setImage(1, line, lc.getA().getImage(2));
- w.setText(2, line, lc.getA().getDim());
- w.setImage(3, line, lc.getB().getImage(2));
- w.setText(4, line, lc.getB().getDim());
- w.setImage(5, line, lc.getIntersectionLetter().getImage(2));
- w.setText(6, line, lc.getIntersectionLetter().getDim());
-
- w.setComponent(7, line, tf = new JTextArea());
- tf.setText(lc.toString());
- if (lc.getPreValityPercent() > jas.getInteger("preScanFilter") && jas.getInteger("preScanFilter") > 0) {
- tf.setBackground(Color.LIGHT_GRAY);
- }
- line++;
- }
- postValueFilterArguments[0] = lc;
- if (postValueFilterMethod == null || (Boolean) postValueFilterMethod.invoke(null, postValueFilterArguments)) {
-
- if (res == null || lc.getValityPercent() < res.getValityPercent()) {
- if (res != null && res.getValityPercent() < lastPercent) {
- lastPercent = res.getValityPercent();
- }
- res = lc;
-
- if (jas.getDouble("LetterSearchLimitPerfectPercent") >= lc.getValityPercent()) {
- res.setDetectionType(LetterComperator.PERFECTMATCH);
- res.setReliability(lastPercent - res.getValityPercent());
- if (Utilities.isLoggerActive()) {
- logger.finer(" Perfect Match: " + res.getB().getDecodedValue() + " " + res.getValityPercent() + " good:" + tmp.getGoodDetections() + " bad: " + tmp.getBadDetections() + " - " + res);
- }
- if (isShowDebugGui()) {
- tf.setBackground(Color.GREEN);
- }
- return res;
- }
- if (isShowDebugGui()) {
- tf.setBackground(Color.BLUE);
- }
- if (Utilities.isLoggerActive()) {
- logger.finer("Angle " + angle + "dim " + lc.getA().getDim() + "|" + lc.getB().getDim() + " New Best value: " + lc.getDecodedValue() + " " + lc.getValityPercent() + " good:" + tmp.getGoodDetections() + " bad: " + tmp.getBadDetections() + " - " + lc);
- }
-
- } else if (res != null) {
- // if (Utilities.isLoggerActive()&&
- // lc.getDecodedValue().equalsIgnoreCase("G"))
- // logger.finer("Angle " + angle + "dim " +
- // lc.getA().getDim() + "|" + lc.getB().getDim() + "
- // value: " + lc.getDecodedValue() + " " +
- // lc.getValityPercent() + " good:" +
- // tmp.getGoodDetections() + " bad: " +
- // tmp.getBadDetections() + " - " + lc);
-
- if (lc.getValityPercent() < lastPercent) {
- lastPercent = lc.getValityPercent();
- }
- }
- }
-
- }
- // if(Utilities.isLoggerActive())logger.info("Full Angle scan
- // in
- // "+(Utilities.getTimer()-startTime2));
- }
- // w.refreshUI();
- } catch (Exception e) {
- JDLogger.exception(e);
- }
-
- if (res != null && res.getB() != null) {
- if (Utilities.isLoggerActive()) {
- logger.finer(" Normal Match: " + res.getB().getDecodedValue() + " " + res.getValityPercent() + " good:" + res.getB().getGoodDetections() + " bad: " + res.getB().getBadDetections());
- }
-
- res.setReliability(lastPercent - res.getValityPercent());
- } else {
- if (getJas().getInteger("preScanEmergencyFilter") > getJas().getInteger("preScanFilter")) {
- logger.warning("nicht erkannt. Verwende erweiterte Emergencydatenbank");
- int psf = getJas().getInteger("preScanFilter");
- getJas().set("preScanFilter", getJas().getInteger("preScanEmergencyFilter"));
- LetterComperator ret = getLetterExtended(letter);
- getJas().set("preScanFilter", psf);
- return ret;
-
- }
- if (Utilities.isLoggerActive()) {
- logger.severe("Letter entgültig nicht erkannt");
- }
- if (isShowDebugGui() && tf != null) {
- tf.setBackground(Color.RED);
- }
-
- }
-
- return res;
-
- }
-
- /**
- * @return gibt die Lettermap als String zurück
- */
- private String getLetterMapString() {
- StringBuilder ret = new StringBuilder();
- int i = 0;
- for (int x = 0; x < letterMap.length; x++) {
- ret.append("|");
- i++;
- for (int y = 0; y < letterMap[0].length; y++) {
-
- ret.append(letterMap[x][y]);
- i++;
- ret.append(",");
- i++;
- }
- ret.deleteCharAt(ret.length() - 1);
- if (Utilities.isLoggerActive()) {…