Esempio n. 1
0
  @SuppressWarnings("unused")
  public void doFree(
      final DownloadLink downloadLink,
      final boolean resumable,
      final int maxchunks,
      final String directlinkproperty)
      throws Exception, PluginException {
    br.setFollowRedirects(false);
    passCode = downloadLink.getStringProperty("pass");
    // First, bring up saved final links
    String dllink = checkDirectLink(downloadLink, directlinkproperty);
    // Second, check for streaming links on the first page
    if (dllink == null) {
      dllink = getDllink();
    }
    // Third, do they provide video hosting?
    if (dllink == null && VIDEOHOSTER) {
      final Browser brv = br.cloneBrowser();
      brv.getPage(
          "/vidembed-" + new Regex(downloadLink.getDownloadURL(), "([a-z0-9]+)$").getMatch(0));
      dllink = brv.getRedirectLocation();
    }
    // Fourth, continue like normal.
    if (dllink == null) {
      checkErrors(downloadLink, false);
      final Form download1 = getFormByKey("op", "download1");
      if (download1 != null) {
        download1.remove("method_premium");
        // stable is lame, issue finding input data fields correctly. eg. closes at ' quotation mark
        // - remove when jd2 goes stable!
        if (downloadLink.getName().contains("'")) {
          String fname =
              new Regex(br, "<input type=\"hidden\" name=\"fname\" value=\"([^\"]+)\">")
                  .getMatch(0);
          if (fname != null) {
            download1.put("fname", Encoding.urlEncode(fname));
          } else {
            logger.warning("Could not find 'fname'");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
        }
        // end of backward compatibility
        sendForm(download1);
        checkErrors(downloadLink, false);
        dllink = getDllink();
      }
    }
    if (dllink == null) {
      Form dlForm = br.getFormbyProperty("name", "F1");
      if (dlForm == null) {
        throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
      }
      // how many forms deep do you want to try.
      int repeat = 2;
      for (int i = 0; i <= repeat; i++) {
        dlForm.remove(null);
        final long timeBefore = System.currentTimeMillis();
        boolean password = false;
        boolean skipWaittime = false;
        if (new Regex(correctedBR, PASSWORDTEXT).matches()) {
          password = true;
          logger.info("The downloadlink seems to be password protected.");
        }
        // md5 can be on the subsequent pages
        if (downloadLink.getMD5Hash() == null) {
          String md5hash = new Regex(correctedBR, "<b>MD5.*?</b>.*?nowrap>(.*?)<").getMatch(0);
          if (md5hash != null) {
            downloadLink.setMD5Hash(md5hash.trim());
          }
        }
        /* Captcha START */
        if (correctedBR.contains(";background:#ccc;text-align")) {
          logger.info("Detected captcha method \"plaintext captchas\" for this host");
          /** Captcha method by ManiacMansion */
          final String[][] letters =
              new Regex(
                      br,
                      "<span style=\\'position:absolute;padding\\-left:(\\d+)px;padding\\-top:\\d+px;\\'>(&#\\d+;)</span>")
                  .getMatches();
          if (letters == null || letters.length == 0) {
            logger.warning("plaintext captchahandling broken!");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
          final SortedMap<Integer, String> capMap = new TreeMap<Integer, String>();
          for (String[] letter : letters) {
            capMap.put(Integer.parseInt(letter[0]), Encoding.htmlDecode(letter[1]));
          }
          final StringBuilder code = new StringBuilder();
          for (String value : capMap.values()) {
            code.append(value);
          }
          dlForm.put("code", code.toString());
          logger.info(
              "Put captchacode "
                  + code.toString()
                  + " obtained by captcha metod \"plaintext captchas\" in the form.");
        } else if (correctedBR.contains("/captchas/")) {
          logger.info("Detected captcha method \"Standard captcha\" for this host");
          final String[] sitelinks = HTMLParser.getHttpLinks(br.toString(), null);
          String captchaurl = null;
          if (sitelinks == null || sitelinks.length == 0) {
            logger.warning("Standard captcha captchahandling broken!");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
          for (String link : sitelinks) {
            if (link.contains("/captchas/")) {
              captchaurl = link;
              break;
            }
          }
          if (captchaurl == null) {
            logger.warning("Standard captcha captchahandling broken!");
            throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
          }
          String code = getCaptchaCode("xfilesharingprobasic", captchaurl, downloadLink);
          dlForm.put("code", code);
          logger.info(
              "Put captchacode "
                  + code
                  + " obtained by captcha metod \"Standard captcha\" in the form.");
        } else if (new Regex(correctedBR, "(api\\.recaptcha\\.net|google\\.com/recaptcha/api/)")
            .matches()) {
          logger.info("Detected captcha method \"Re Captcha\" for this host");
          final PluginForHost recplug = JDUtilities.getPluginForHost("DirectHTTP");
          final jd.plugins.hoster.DirectHTTP.Recaptcha rc = ((DirectHTTP) recplug).getReCaptcha(br);
          rc.findID();
          rc.load();
          final File cf = rc.downloadCaptcha(getLocalCaptchaFile());
          final String c = getCaptchaCode("recaptcha", cf, downloadLink);
          dlForm.put("recaptcha_challenge_field", rc.getChallenge());
          dlForm.put("recaptcha_response_field", Encoding.urlEncode(c));
          logger.info(
              "Put captchacode "
                  + c
                  + " obtained by captcha metod \"Re Captcha\" in the form and submitted it.");
          /** wait time is often skippable for reCaptcha handling */
          skipWaittime = true;
        } else if (br.containsHTML("solvemedia\\.com/papi/")) {
          logger.info("Detected captcha method \"solvemedia\" for this host");

          final org.jdownloader.captcha.v2.challenge.solvemedia.SolveMedia sm =
              new org.jdownloader.captcha.v2.challenge.solvemedia.SolveMedia(br);
          final File cf = sm.downloadCaptcha(getLocalCaptchaFile());
          final String code = getCaptchaCode(cf, downloadLink);
          final String chid = sm.getChallenge(code);
          dlForm.put("adcopy_challenge", chid);
          dlForm.put("adcopy_response", "manual_challenge");
        } else if (br.containsHTML("id=\"capcode\" name= \"capcode\"")) {
          logger.info("Detected captcha method \"keycaptca\"");
          String result =
              handleCaptchaChallenge(
                  getDownloadLink(),
                  new KeyCaptcha(this, br, getDownloadLink()).createChallenge(this));
          if (result == null) {
            throw new PluginException(LinkStatus.ERROR_CAPTCHA);
          }
          if ("CANCEL".equals(result)) {
            throw new PluginException(LinkStatus.ERROR_FATAL);
          }
          dlForm.put("capcode", result);
          /** wait time is often skippable for reCaptcha handling */
          skipWaittime = false;
        }
        /* Captcha END */
        if (password) {
          passCode = handlePassword(dlForm, downloadLink);
        }
        if (!skipWaittime) {
          waitTime(timeBefore, downloadLink);
        }
        sendForm(dlForm);
        logger.info("Submitted DLForm");
        checkErrors(downloadLink, true);
        dllink = getDllink();
        if (dllink == null
            && (!br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"") || i == repeat)) {
          logger.warning("Final downloadlink (String is \"dllink\") regex didn't match!");
          throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
        } else if (dllink == null
            && br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"")) {
          dlForm = br.getFormbyProperty("name", "F1");
          try {
            invalidateLastChallengeResponse();
          } catch (final Throwable e) {
          }
          continue;
        } else {
          try {
            validateLastChallengeResponse();
          } catch (final Throwable e) {
          }
          break;
        }
      }
    }
    logger.info("Final downloadlink = " + dllink + " starting the download...");
    dl = jd.plugins.BrowserAdapter.openDownload(br, downloadLink, dllink, resumable, maxchunks);
    if (dl.getConnection().getContentType().contains("html")) {
      if (dl.getConnection().getResponseCode() == 503) {
        throw new PluginException(
            LinkStatus.ERROR_HOSTER_TEMPORARILY_UNAVAILABLE,
            "Connection limit reached, please contact our support!",
            5 * 60 * 1000l);
      }
      logger.warning("The final dllink seems not to be a file!");
      br.followConnection();
      correctBR();
      checkServerErrors();
      throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
    }
    downloadLink.setProperty(directlinkproperty, dllink);
    fixFilename(downloadLink);
    try {
      // add a download slot
      controlFree(+1);
      // start the dl
      dl.startDownload();
    } finally {
      // remove download slot
      controlFree(-1);
    }
  }
Esempio n. 2
0
 @SuppressWarnings("unused")
 public void doFree(
     final DownloadLink downloadLink,
     final boolean resumable,
     final int maxchunks,
     final String directlinkproperty)
     throws Exception, PluginException {
   br.setFollowRedirects(false);
   passCode = downloadLink.getStringProperty("pass");
   /* First, bring up saved final links */
   String dllink = checkDirectLink(downloadLink, directlinkproperty);
   /* Second, check for streaming/direct links on the first page */
   if (dllink == null) {
     dllink = getDllink();
   }
   /* Third, do they provide video hosting? */
   if (dllink == null && VIDEOHOSTER) {
     try {
       logger.info("Trying to get link via vidembed");
       final Browser brv = br.cloneBrowser();
       brv.getPage("/vidembed-" + fuid);
       dllink = brv.getRedirectLocation();
       if (dllink == null) {
         logger.info("Failed to get link via vidembed");
       } else {
         logger.info("Successfully found link via vidembed");
       }
     } catch (final Throwable e) {
       logger.info("Failed to get link via vidembed");
     }
   }
   if (dllink == null && VIDEOHOSTER_2) {
     try {
       logger.info("Trying to get link via embed");
       final String embed_access =
           "http://" + COOKIE_HOST.replace("http://", "") + "/embed-" + fuid + ".html";
       this.postPage(
           embed_access,
           "op=video_embed3&usr_login=&id2="
               + fuid
               + "&fname="
               + Encoding.urlEncode(downloadLink.getName())
               + "&referer=&file_code="
               + fuid
               + "&method_free=Click+here+to+watch+the+Video");
       // brv.getPage("http://grifthost.com/embed-" + fuid + ".html");
       dllink = getDllink();
       if (dllink == null) {
         logger.info("Failed to get link via embed");
       } else {
         logger.info("Successfully found link via embed");
       }
     } catch (final Throwable e) {
       logger.info("Failed to get link via embed");
     }
     if (dllink == null) {
       getPage(downloadLink.getDownloadURL());
     }
   }
   /* Fourth, continue like normal */
   if (dllink == null) {
     checkErrors(downloadLink, false);
     final Form download1 = getFormByKey("op", "download1");
     if (download1 != null) {
       download1.remove("method_premium");
       /* stable is lame, issue finding input data fields correctly. eg. closes at ' quotation mark - remove when jd2 goes stable! */
       if (downloadLink.getName().contains("'")) {
         String fname =
             new Regex(br, "<input type=\"hidden\" name=\"fname\" value=\"([^\"]+)\">")
                 .getMatch(0);
         if (fname != null) {
           download1.put("fname", Encoding.urlEncode(fname));
         } else {
           logger.warning("Could not find 'fname'");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
       }
       /* end of backward compatibility */
       sendForm(download1);
       checkErrors(downloadLink, false);
       dllink = getDllink();
     }
   }
   if (dllink == null) {
     Form dlForm = br.getFormbyProperty("name", "F1");
     if (dlForm == null) {
       handlePluginBroken(downloadLink, "dlform_f1_null", 3);
     }
     /* how many forms deep do you want to try? */
     int repeat = 2;
     for (int i = 0; i <= repeat; i++) {
       dlForm.remove(null);
       final long timeBefore = System.currentTimeMillis();
       boolean password = false;
       boolean skipWaittime = false;
       if (new Regex(correctedBR, PASSWORDTEXT).matches()) {
         password = true;
         logger.info("The downloadlink seems to be password protected.");
       }
       /* md5 can be on the subsequent pages - it is to be found very rare in current XFS versions */
       if (downloadLink.getMD5Hash() == null) {
         String md5hash = new Regex(correctedBR, "<b>MD5.*?</b>.*?nowrap>(.*?)<").getMatch(0);
         if (md5hash != null) {
           downloadLink.setMD5Hash(md5hash.trim());
         }
       }
       /* Captcha START */
       if (correctedBR.contains(";background:#ccc;text-align")) {
         logger.info("Detected captcha method \"plaintext captchas\" for this host");
         /* Captcha method by ManiacMansion */
         final String[][] letters =
             new Regex(
                     br,
                     "<span style=\\'position:absolute;padding\\-left:(\\d+)px;padding\\-top:\\d+px;\\'>(&#\\d+;)</span>")
                 .getMatches();
         if (letters == null || letters.length == 0) {
           logger.warning("plaintext captchahandling broken!");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
         final SortedMap<Integer, String> capMap = new TreeMap<Integer, String>();
         for (String[] letter : letters) {
           capMap.put(Integer.parseInt(letter[0]), Encoding.htmlDecode(letter[1]));
         }
         final StringBuilder code = new StringBuilder();
         for (String value : capMap.values()) {
           code.append(value);
         }
         dlForm.put("code", code.toString());
         logger.info(
             "Put captchacode "
                 + code.toString()
                 + " obtained by captcha metod \"plaintext captchas\" in the form.");
       } else if (correctedBR.contains("/captchas/")) {
         logger.info("Detected captcha method \"Standard captcha\" for this host");
         final String[] sitelinks = HTMLParser.getHttpLinks(br.toString(), null);
         String captchaurl = null;
         if (sitelinks == null || sitelinks.length == 0) {
           logger.warning("Standard captcha captchahandling broken!");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
         for (String link : sitelinks) {
           if (link.contains("/captchas/")) {
             captchaurl = link;
             break;
           }
         }
         if (captchaurl == null) {
           logger.warning("Standard captcha captchahandling broken!");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
         String code = getCaptchaCode("xfilesharingprobasic", captchaurl, downloadLink);
         dlForm.put("code", code);
         logger.info(
             "Put captchacode "
                 + code
                 + " obtained by captcha metod \"Standard captcha\" in the form.");
       } else if (new Regex(correctedBR, "(api\\.recaptcha\\.net|google\\.com/recaptcha/api/)")
           .matches()) {
         logger.info("Detected captcha method \"Re Captcha\" for this host");
         final PluginForHost recplug = JDUtilities.getPluginForHost("DirectHTTP");
         final jd.plugins.hoster.DirectHTTP.Recaptcha rc = ((DirectHTTP) recplug).getReCaptcha(br);
         rc.findID();
         rc.load();
         final File cf = rc.downloadCaptcha(getLocalCaptchaFile());
         final String c = getCaptchaCode(cf, downloadLink);
         dlForm.put("recaptcha_challenge_field", rc.getChallenge());
         dlForm.put("recaptcha_response_field", Encoding.urlEncode(c));
         logger.info(
             "Put captchacode "
                 + c
                 + " obtained by captcha metod \"Re Captcha\" in the form and submitted it.");
         /* wait time is usually skippable for reCaptcha handling */
         skipWaittime = true;
       } else if (br.containsHTML("solvemedia\\.com/papi/")) {
         logger.info("Detected captcha method \"solvemedia\" for this host");
         final PluginForDecrypt solveplug = JDUtilities.getPluginForDecrypt("linkcrypt.ws");
         final jd.plugins.decrypter.LnkCrptWs.SolveMedia sm =
             ((jd.plugins.decrypter.LnkCrptWs) solveplug).getSolveMedia(br);
         File cf = null;
         try {
           cf = sm.downloadCaptcha(getLocalCaptchaFile());
         } catch (final Exception e) {
           if (jd.plugins.decrypter.LnkCrptWs.SolveMedia.FAIL_CAUSE_CKEY_MISSING.equals(
               e.getMessage())) {
             throw new PluginException(
                 LinkStatus.ERROR_FATAL,
                 "Host side solvemedia.com captcha error - please contact the "
                     + this.getHost()
                     + " support");
           }
           throw e;
         }
         final String code = getCaptchaCode(cf, downloadLink);
         final String chid = sm.getChallenge(code);
         dlForm.put("adcopy_challenge", chid);
         dlForm.put("adcopy_response", "manual_challenge");
       } else if (br.containsHTML("id=\"capcode\" name= \"capcode\"")) {
         logger.info("Detected captcha method \"keycaptca\"");
         String result = null;
         final PluginForDecrypt keycplug = JDUtilities.getPluginForDecrypt("linkcrypt.ws");
         try {
           final jd.plugins.decrypter.LnkCrptWs.KeyCaptcha kc =
               ((jd.plugins.decrypter.LnkCrptWs) keycplug).getKeyCaptcha(br);
           result = kc.showDialog(downloadLink.getDownloadURL());
         } catch (final Throwable e) {
           result = null;
         }
         if (result == null) {
           throw new PluginException(LinkStatus.ERROR_CAPTCHA);
         }
         if ("CANCEL".equals(result)) {
           throw new PluginException(LinkStatus.ERROR_FATAL);
         }
         dlForm.put("capcode", result);
         skipWaittime = false;
       }
       /* Captcha END */
       if (password) {
         passCode = handlePassword(dlForm, downloadLink);
       }
       if (!skipWaittime) {
         waitTime(timeBefore, downloadLink);
       }
       sendForm(dlForm);
       logger.info("Submitted DLForm");
       checkErrors(downloadLink, true);
       dllink = getDllink();
       if (dllink == null
           && (!br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"") || i == repeat)) {
         logger.warning("Final downloadlink (String is \"dllink\") regex didn't match!");
         throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
       } else if (dllink == null
           && br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"")) {
         dlForm = br.getFormbyProperty("name", "F1");
         continue;
       } else {
         break;
       }
     }
   }
   logger.info("Final downloadlink = " + dllink + " starting the download...");
   dl = jd.plugins.BrowserAdapter.openDownload(br, downloadLink, dllink, resumable, maxchunks);
   if (dl.getConnection().getContentType().contains("html")) {
     if (dl.getConnection().getResponseCode() == 503) {
       throw new PluginException(
           LinkStatus.ERROR_HOSTER_TEMPORARILY_UNAVAILABLE,
           "Connection limit reached, please contact our support!",
           5 * 60 * 1000l);
     }
     logger.warning("The final dllink seems not to be a file!");
     br.followConnection();
     correctBR();
     checkServerErrors();
     handlePluginBroken(downloadLink, "dllinknofile", 3);
   }
   downloadLink.setProperty(directlinkproperty, dllink);
   fixFilename(downloadLink);
   try {
     /* add a download slot */
     controlFree(+1);
     /* start the dl */
     dl.startDownload();
   } finally {
     /* remove download slot */
     controlFree(-1);
   }
 }
Esempio n. 3
0
 @SuppressWarnings("unused")
 public void doFree(
     final DownloadLink downloadLink,
     boolean resumable,
     int maxchunks,
     final String directlinkproperty)
     throws Exception, PluginException {
   br.setFollowRedirects(false);
   passCode = downloadLink.getStringProperty("pass");
   // First, bring up saved final links
   String dllink = checkDirectLink(downloadLink, directlinkproperty);
   // Second, check for streaming links on the first page
   if (dllink == null) {
     dllink = getDllink();
   }
   // Third, do they provide video hosting?
   if (dllink == null && VIDEOHOSTER) {
     try {
       logger.info("Trying to get link via vidembed");
       final Browser brv = br.cloneBrowser();
       brv.getPage("/vidembed-" + fuid);
       dllink = brv.getRedirectLocation();
       if (dllink == null) {
         logger.info("Failed to get link via vidembed");
       }
     } catch (final Throwable e) {
       logger.info("Failed to get link via vidembed");
     }
   }
   // Possibility to skip captcha & (reconnect) waittimes
   dllink = null;
   boolean special_success = false;
   boolean special2_success = false;
   if (dllink == null
       && TRY_SPECIAL_WAY
       && !downloadLink.getBooleanProperty("special2_failed", false)) {
     try {
       final String temp_id =
           this.getPluginConfig().getStringProperty("spaceforfiles_tempid", null);
       if (temp_id != null) {
         final String checklink =
             "http://www.filespace.com/cgi-bin/dl.cgi/"
                 + temp_id
                 + "/"
                 + Encoding.urlEncode(downloadLink.getName());
         final boolean isvalid = checkDirectLink(checklink);
         if (isvalid) {
           dllink = checklink;
           special_success = true;
         }
       }
     } catch (final Throwable e) {
     }
   }
   if (dllink == null
       && TRY_SPECIAL_WAY_2
       && !downloadLink.getBooleanProperty("special2_failed", false)) {
     try {
       /* Pattern of finallinks generated here: http://www.spaceforfiles.com/dlcdn/xxxxxxxxxxxx/filename.ext */
       final Browser brad = br.cloneBrowser();
       final String fid = new Regex(downloadLink.getDownloadURL(), "([a-z0-9]{12})$").getMatch(0);
       final String postDataF1 =
           "op=download1&usr_login=&id="
               + fid
               + "&fname="
               + Encoding.urlEncode(downloadLink.getName())
               + "&referer=&lck=1&method_free=Free+Download";
       brad.postPage(br.getURL(), postDataF1);
       final String md5 = brad.getRegex("MD5 Checksum: ([a-f0-9]{32})").getMatch(0);
       if (md5 != null) {
         downloadLink.setMD5Hash(md5);
       }
       final String start_referer = brad.getURL();
       final String rand = brad.getRegex("name=\"rand\" value=\"([a-z0-9]+)\"").getMatch(0);
       if (rand == null) {
         throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
       }
       // br.postPage("http://filespace.com/xxxxxxxxxxxx", "op=download2&id=" + fid + "&rand=" +
       // rand +
       // "&referer=&method_free=Free+Download&method_premium=&adcopy_response=&adcopy_challenge=&down_script=1");
       brad.cloneBrowser().getPage("http://www.filespace.com/locker/locker.js?1");
       brad.getPage("http://www.filespace.com/locker/lockurl.php?uniqueid=" + fid);
       if (!brad.containsHTML("\"lockid\":\\-1")) {
         final String lockid = brad.getRegex("\"lockid\":(\")?(\\d+)").getMatch(1);
         final String hash = brad.getRegex("\"hash\":\"([a-z0-9]+)\"").getMatch(0);
         if (lockid == null || hash == null) {
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
         brad.getPage(
             "http://www.spaceforfiles.com/locker/offers.php?hash=" + hash + "&sid=" + fid);
         brad.cloneBrowser()
             .getPage("http://www.filespace.com/locker/checkoffer.php?lockid=" + lockid);
       }
       brad.getHeaders().put("Referer", start_referer);
       final String postData =
           "op=download2&id="
               + fid
               + "&rand="
               + rand
               + "&referer="
               + Encoding.urlEncode(br.getURL())
               + "&method_free=Free+Download&method_premium=&method_highspeed=1&lck=1&down_script=1";
       brad.postPage(start_referer, postData);
       dllink = brad.getRedirectLocation();
       if (dllink != null) {
         // resumable = true;
         // maxchunks = 0;
         special2_success = true;
       }
     } catch (final Throwable e) {
     }
   }
   // Fourth, continue like normal.
   if (dllink == null) {
     checkErrors(downloadLink, false);
     final Form download1 = getFormByKey("op", "download1");
     if (download1 != null) {
       download1.remove("method_premium");
       // stable is lame, issue finding input data fields correctly. eg. closes at ' quotation mark
       // - remove when jd2 goes stable!
       if (downloadLink.getName().contains("'")) {
         String fname =
             new Regex(br, "<input type=\"hidden\" name=\"fname\" value=\"([^\"]+)\">")
                 .getMatch(0);
         if (fname != null) {
           download1.put("fname", Encoding.urlEncode(fname));
         } else {
           logger.warning("Could not find 'fname'");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
       }
       // end of backward compatibility
       sendForm(download1);
       checkErrors(downloadLink, false);
       dllink = getDllink();
     }
   }
   if (dllink == null) {
     Form dlForm = br.getFormbyProperty("name", "F1");
     if (dlForm == null) {
       throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
     }
     // how many forms deep do you want to try.
     int repeat = 2;
     for (int i = 0; i <= repeat; i++) {
       dlForm.remove(null);
       final long timeBefore = System.currentTimeMillis();
       boolean password = false;
       boolean skipWaittime = false;
       if (new Regex(correctedBR, PASSWORDTEXT).matches()) {
         password = true;
         logger.info("The downloadlink seems to be password protected.");
       }
       // md5 can be on the subsequent pages
       if (downloadLink.getMD5Hash() == null) {
         String md5hash = new Regex(correctedBR, "<b>MD5.*?</b>.*?nowrap>(.*?)<").getMatch(0);
         if (md5hash != null) {
           downloadLink.setMD5Hash(md5hash.trim());
         }
       }
       /* Captcha START */
       if (correctedBR.contains(";background:#ccc;text-align")) {
         logger.info("Detected captcha method \"plaintext captchas\" for this host");
         /** Captcha method by ManiacMansion */
         final String[][] letters =
             new Regex(
                     br,
                     "<span style=\\'position:absolute;padding\\-left:(\\d+)px;padding\\-top:\\d+px;\\'>(&#\\d+;)</span>")
                 .getMatches();
         if (letters == null || letters.length == 0) {
           logger.warning("plaintext captchahandling broken!");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
         final SortedMap<Integer, String> capMap = new TreeMap<Integer, String>();
         for (String[] letter : letters) {
           capMap.put(Integer.parseInt(letter[0]), Encoding.htmlDecode(letter[1]));
         }
         final StringBuilder code = new StringBuilder();
         for (String value : capMap.values()) {
           code.append(value);
         }
         dlForm.put("code", code.toString());
         logger.info(
             "Put captchacode "
                 + code.toString()
                 + " obtained by captcha metod \"plaintext captchas\" in the form.");
       } else if (correctedBR.contains("/captchas/")) {
         logger.info("Detected captcha method \"Standard captcha\" for this host");
         final String[] sitelinks = HTMLParser.getHttpLinks(br.toString(), null);
         String captchaurl = null;
         if (sitelinks == null || sitelinks.length == 0) {
           logger.warning("Standard captcha captchahandling broken!");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
         for (String link : sitelinks) {
           if (link.contains("/captchas/")) {
             captchaurl = link;
             break;
           }
         }
         if (captchaurl == null) {
           logger.warning("Standard captcha captchahandling broken!");
           throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
         }
         String code = getCaptchaCode("xfilesharingprobasic", captchaurl, downloadLink);
         dlForm.put("code", code);
         logger.info(
             "Put captchacode "
                 + code
                 + " obtained by captcha metod \"Standard captcha\" in the form.");
       } else if (new Regex(correctedBR, "(api\\.recaptcha\\.net|google\\.com/recaptcha/api/)")
           .matches()) {
         logger.info("Detected captcha method \"Re Captcha\" for this host");
         final PluginForHost recplug = JDUtilities.getPluginForHost("DirectHTTP");
         final jd.plugins.hoster.DirectHTTP.Recaptcha rc = ((DirectHTTP) recplug).getReCaptcha(br);
         rc.findID();
         rc.load();
         final File cf = rc.downloadCaptcha(getLocalCaptchaFile());
         final String c = getCaptchaCode(cf, downloadLink);
         dlForm.put("recaptcha_challenge_field", rc.getChallenge());
         dlForm.put("recaptcha_response_field", Encoding.urlEncode(c));
         logger.info(
             "Put captchacode "
                 + c
                 + " obtained by captcha metod \"Re Captcha\" in the form and submitted it.");
         /** wait time is often skippable for reCaptcha handling */
         skipWaittime = true;
       } else if (br.containsHTML("solvemedia\\.com/papi/")) {
         logger.info("Detected captcha method \"solvemedia\" for this host");
         final PluginForDecrypt solveplug = JDUtilities.getPluginForDecrypt("linkcrypt.ws");
         final jd.plugins.decrypter.LnkCrptWs.SolveMedia sm =
             ((jd.plugins.decrypter.LnkCrptWs) solveplug).getSolveMedia(br);
         File cf = null;
         try {
           cf = sm.downloadCaptcha(getLocalCaptchaFile());
         } catch (final Exception e) {
           if (jd.plugins.decrypter.LnkCrptWs.SolveMedia.FAIL_CAUSE_CKEY_MISSING.equals(
               e.getMessage())) {
             throw new PluginException(
                 LinkStatus.ERROR_FATAL,
                 "Host side solvemedia.com captcha error - please contact the "
                     + this.getHost()
                     + " support");
           }
           throw e;
         }
         final String code = getCaptchaCode(cf, downloadLink);
         final String chid = sm.getChallenge(code);
         dlForm.put("adcopy_challenge", chid);
         dlForm.put("adcopy_response", "manual_challenge");
       } else if (br.containsHTML("id=\"capcode\" name= \"capcode\"")) {
         logger.info("Detected captcha method \"keycaptca\"");
         String result = null;
         final PluginForDecrypt keycplug = JDUtilities.getPluginForDecrypt("linkcrypt.ws");
         try {
           final jd.plugins.decrypter.LnkCrptWs.KeyCaptcha kc =
               ((jd.plugins.decrypter.LnkCrptWs) keycplug).getKeyCaptcha(br);
           result = kc.showDialog(downloadLink.getDownloadURL());
         } catch (final Throwable e) {
           result = null;
         }
         if (result == null) {
           throw new PluginException(LinkStatus.ERROR_CAPTCHA);
         }
         if ("CANCEL".equals(result)) {
           throw new PluginException(LinkStatus.ERROR_FATAL);
         }
         dlForm.put("capcode", result);
         /** wait time is often skippable for reCaptcha handling */
         skipWaittime = false;
       }
       /* Captcha END */
       if (password) {
         passCode = handlePassword(dlForm, downloadLink);
       }
       if (!skipWaittime) {
         waitTime(timeBefore, downloadLink);
       }
       sendForm(dlForm);
       logger.info("Submitted DLForm");
       checkErrors(downloadLink, true);
       dllink = getDllink();
       if (dllink == null
           && (!br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"") || i == repeat)) {
         logger.warning("Final downloadlink (String is \"dllink\") regex didn't match!");
         throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
       } else if (dllink == null
           && br.containsHTML("<Form name=\"F1\" method=\"POST\" action=\"\"")) {
         dlForm = br.getFormbyProperty("name", "F1");
         try {
           invalidateLastChallengeResponse();
         } catch (final Throwable e) {
         }
         continue;
       } else {
         try {
           validateLastChallengeResponse();
         } catch (final Throwable e) {
         }
         break;
       }
     }
   }
   logger.info("Final downloadlink = " + dllink + " starting the download...");
   dl = jd.plugins.BrowserAdapter.openDownload(br, downloadLink, dllink, resumable, maxchunks);
   if (dl.getConnection().getContentType().contains("html")) {
     if (dl.getConnection().getResponseCode() == 503) {
       throw new PluginException(
           LinkStatus.ERROR_HOSTER_TEMPORARILY_UNAVAILABLE,
           "Connection limit reached, please contact our support!",
           5 * 60 * 1000l);
     }
     logger.warning("The final dllink seems not to be a file!");
     br.followConnection();
     correctBR();
     checkServerErrors();
     if (special_success) {
       downloadLink.setProperty("special_failed", true);
     } else if (special2_success) {
       downloadLink.setProperty("special2_failed", true);
     }
     int timesFailed =
         downloadLink.getIntegerProperty(NICE_HOSTproperty + "failedtimes_dllinknofile", 0);
     downloadLink.getLinkStatus().setRetryCount(0);
     if (timesFailed <= 2) {
       logger.info(NICE_HOST + ": Final link is no file -> Retrying");
       timesFailed++;
       downloadLink.setProperty(NICE_HOSTproperty + "failedtimes_dllinknofile", timesFailed);
       throw new PluginException(LinkStatus.ERROR_RETRY, "Final download link not found");
     } else {
       downloadLink.setProperty(NICE_HOSTproperty + "failedtimes_dllinknofile", Property.NULL);
       logger.info(NICE_HOST + ": Final link is no file -> Plugin is broken");
       throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
     }
   }
   final String tempid = new Regex(dllink, "cgi\\-bin/dl\\.cgi/([a-z0-9]+)/").getMatch(0);
   if (tempid != null) {
     this.getPluginConfig().setProperty("spaceforfiles_tempid", tempid);
   }
   downloadLink.setProperty(directlinkproperty, dllink);
   fixFilename(downloadLink);
   try {
     // add a download slot
     controlFree(+1);
     // start the dl
     dl.startDownload();
   } finally {
     // remove download slot
     controlFree(-1);
   }
 }