mirroring bot - 2025/05/01

This commit is contained in:
updating-bot 2025-05-01 05:33:04 +00:00
parent 987eb4bba6
commit 29b47451a0
41 changed files with 897 additions and 711 deletions

View File

@ -967,6 +967,7 @@ public class Browser {
* @deprecated use {@link #createPostRequest(String, UrlQuery, String)
*
*
*
*/
@Deprecated
public PostRequest createPostRequest(String url, final List<KeyValueStringEntry> post, final String encoding) throws IOException {
@ -1779,8 +1780,8 @@ public class Browser {
}
/**
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site </br> auto completes Sec-Fetch-Site, some websites(eg
* facebook) check it
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-Fetch-Site </br>
* auto completes Sec-Fetch-Site, some websites(eg facebook) check it
*/
protected void autoCompleteHeaders(final Request request) {
if (request != null) {
@ -2438,7 +2439,8 @@ public class Browser {
}
/**
* Sets Browser upper page load limit Byte value. </br> Use Integer.MAX_VALUE for "unlimited" (do not use "-1"!).
* Sets Browser upper page load limit Byte value. </br>
* Use Integer.MAX_VALUE for "unlimited" (do not use "-1"!).
*
* @since JD2
* @param i
@ -2583,7 +2585,8 @@ public class Browser {
}
/**
* Checks for block by firewalls and similar. </br> To be called after a sent request.
* Checks for block by firewalls and similar. </br>
* To be called after a sent request.
*/
public void checkForBlockedByAfterLoadConnection(Request request) throws IOException {
if (this.getThrowExceptionOnBlockedBy(request)) {
@ -2607,19 +2610,18 @@ public class Browser {
final HTTPConnection con;
if (request == null || !request.isLoaded() || (con = request.getHttpConnection()) == null) {
return null;
} else {
}
// final boolean isCloudflareHeaderCfRayExistent = req.getResponseHeader("cf-ray") != null;
final boolean isCloudflareServer = StringUtils.containsIgnoreCase(request.getResponseHeader(HTTPConstants.HEADER_RESPONSE_SERVER), "cloudflare");
final boolean isTypicalCloudflareResponseCode = con.getResponseCode() == 403 || con.getResponseCode() == 502 || con.getResponseCode() == 503 || con.getResponseCode() == 429 || con.getResponseCode() == 522 || con.getResponseCode() == 523;
// TODO: Add better Cloudflare detection (more/better html snippets)
// TODO: Add separate BlockedType for Cloudflare-Captcha, see: https://svn.jdownloader.org/issues/90281
/**
* TODO: 2023-12-21: Maybe remove reliance on http status-code as it looks like literally any status code can be returned when a
* Cloudflare block happens. </br> I've just added code 502 to the list of "Cloudflare response-codes".
* Cloudflare block happens. </br>
* I've just added code 502 to the list of "Cloudflare response-codes".
*/
/*
* It is really important to also check for Cloudflare html else stuff will fail/break e.g. icerbox.com wrong login ->
* Cloudflare check without html --> Fails!
* It is really important to also check for Cloudflare html else stuff will fail/break e.g. icerbox.com wrong login -> Cloudflare
* check without html --> Fails!
*/
if (isCloudflareServer && isTypicalCloudflareResponseCode) {
final boolean isCloudflareChallengeHTML = request.containsHTML("(?i)<title>\\s*Attention Required!(\\s*\\| Cloudflare)?\\s*</title>") || request.containsHTML("data-translate=\"challenge_headline\"") || request.containsHTML("<title>\\s*Just a moment\\.*\\s*</title>") && request.containsHTML("<form id\\s*=\\s*\"challenge-form\"");
@ -2649,7 +2651,6 @@ public class Browser {
return CloudflareBlockedType.CLOUDFLARE_SITE;
}
}
}
return null;
}
@ -2657,13 +2658,12 @@ public class Browser {
final HTTPConnection con;
if (request == null || !request.isRequested() || (con = request.getHttpConnection()) == null) {
return null;
} else {
}
final boolean isCloudflareServer = StringUtils.containsIgnoreCase(request.getResponseHeader(HTTPConstants.HEADER_RESPONSE_SERVER), "cloudflare");
if (isCloudflareServer && !con.isOK()) {
con.setAllowedResponseCodes(Browser.buildAllowedResponseCodes(con.getAllowedResponseCodes(), con.getResponseCode()));
return Boolean.TRUE;
}
}
return null;
}
@ -3263,6 +3263,45 @@ public class Browser {
return BlockSourceType.SERVICE;
}
@Override
public Boolean prepareBlockDetection(Browser browser, Request request) {
return null;
}
},
AMAZON_AWS_WAF_WEB_APPLICATION_FIREWALL {
@Override
public String getLabel() {
return "Amazon AWS Web Application Firewall";
}
@Override
public BlockedTypeInterface isBlocked(Browser browser, Request request) {
final HTTPConnection con;
if (request == null || !request.isLoaded() || (con = request.getHttpConnection()) == null) {
return null;
}
if (con.getResponseCode() == 202 && request.getResponseHeader("x-amzn-waf-action") != null && StringUtils.containsIgnoreCase(request.getResponseHeader("server"), "awselb")) {
/**
* Typical reaponse-headers: <br>
* Server: awselb/2.0 <br>
* x-amzn-waf-action: challenge <br>
* Access-Control-Allow-Headers: x-amzn-waf-action
*/
return this;
}
return null;
}
@Override
public BlockLevelType getBlockLevelType() {
return BlockLevelType.SITE;
}
@Override
public BlockSourceType getBlockSourceType() {
return BlockSourceType.SERVICE;
}
@Override
public Boolean prepareBlockDetection(Browser browser, Request request) {
return null;
@ -3284,8 +3323,8 @@ public class Browser {
}
/**
* Returns true if any antiddos provider/other sort of blocking is blocking at this moment. </br> See also:
* https://svn.jdownloader.org/issues/89834
* Returns true if any antiddos provider/other sort of blocking is blocking at this moment. </br>
* See also: https://svn.jdownloader.org/issues/89834
*/
public boolean isBlocked() {
final Request request = this.getRequest();

View File

@ -45,6 +45,11 @@ public class BrowserAdapter {
} else {
dl = new jd.plugins.download.raf.OldRAFDownload(downloadable, request);
}
return applySettings(dl, resumeEnabled, pluginConnections);
}
public static DownloadInterface applySettings(final DownloadInterface dl, boolean resumeEnabled, int pluginConnections) throws Exception {
final Downloadable downloadable = dl.getDownloadable();
findDomainRuleChunks: if (pluginConnections <= 0) {
final DomainRuleSet domainRuleSet = downloadable.getDownloadLinkController().getDownloadLinkCandidate().getDomainRuleSet();
Integer domainRuleChunksInteger = null;
@ -112,6 +117,7 @@ public class BrowserAdapter {
((OldRAFDownload) dl).setResume(resumeEnabled);
}
return dl;
}
public static Downloadable getDownloadable(DownloadLink downloadLink, Browser br) {

View File

@ -49,7 +49,7 @@ import jd.plugins.components.PluginJSonUtils;
import jd.plugins.components.SiteType.SiteTemplate;
import jd.plugins.hoster.ChoMikujPl;
@DecrypterPlugin(revision = "$Revision: 47418 $", interfaceVersion = 2, names = { "chomikuj.pl" }, urls = { "https?://((?:www\\.)?chomikuj\\.pl//?[^<>\"]+|chomikujpagedecrypt\\.pl/result/.+)" })
@DecrypterPlugin(revision = "$Revision: 51030 $", interfaceVersion = 2, names = { "chomikuj.pl" }, urls = { "https?://((?:www\\.)?chomikuj\\.pl//?[^<>\"]+|chomikujpagedecrypt\\.pl/result/.+)" })
public class ChoMikujPlFolder extends PluginForDecrypt {
public ChoMikujPlFolder(PluginWrapper wrapper) {
super(wrapper);
@ -330,7 +330,7 @@ public class ChoMikujPlFolder extends PluginForDecrypt {
}
String subfolderStructure = br.getRegex("value=\"https?://[^/]+/([^\"]+)\"[^>]*id=\"FolderAddress\"").getMatch(0);
final PluginForHost hosterPlugin = this.getNewPluginForHostInstance(this.getHost());
final boolean decryptFolders = hosterPlugin.getPluginConfig().getBooleanProperty(ChoMikujPl.DECRYPTFOLDERS, false);
final boolean decryptFolders = hosterPlugin.getPluginConfig().getBooleanProperty(ChoMikujPl.CRAWL_SUBFOLDERS, ChoMikujPl.default_CRAWL_SUBFOLDERS);
String[][] allFolders = null;
FilePackage fp = null;
if (subfolderStructure != null) {

View File

@ -26,6 +26,7 @@ import jd.controlling.ProgressController;
import jd.http.Browser;
import jd.parser.Regex;
import jd.plugins.Account;
import jd.plugins.AccountRequiredException;
import jd.plugins.CryptedLink;
import jd.plugins.DecrypterPlugin;
import jd.plugins.DownloadLink;
@ -36,7 +37,7 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForDecrypt;
import jd.plugins.hoster.DownloadRu;
@DecrypterPlugin(revision = "$Revision: 51028 $", interfaceVersion = 3, names = {}, urls = {})
@DecrypterPlugin(revision = "$Revision: 51029 $", interfaceVersion = 3, names = {}, urls = {})
@PluginDependencies(dependencies = { DownloadRu.class })
public class DownloadRuFolder extends PluginForDecrypt {
public DownloadRuFolder(PluginWrapper wrapper) {
@ -80,7 +81,9 @@ public class DownloadRuFolder extends PluginForDecrypt {
br.getHeaders().put("Referer", param.getCryptedUrl());
br.getHeaders().put("Accept", "application/json, text/plain, */*");
br.getPage("https://" + getHost() + "/folders/" + folder_id + ".json");
if (br.getHttpConnection().getResponseCode() == 404) {
if (br.getHttpConnection().getResponseCode() == 403) {
throw new AccountRequiredException();
} else if (br.getHttpConnection().getResponseCode() == 404) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
final Map<String, Object> entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);

View File

@ -50,7 +50,7 @@ import jd.plugins.PluginForDecrypt;
import jd.plugins.PluginForHost;
import jd.plugins.components.SiteType.SiteTemplate;
@DecrypterPlugin(revision = "$Revision: 50731 $", interfaceVersion = 3, names = {}, urls = {})
@DecrypterPlugin(revision = "$Revision: 51032 $", interfaceVersion = 3, names = {}, urls = {})
public class GenericYetiShareFolder extends PluginForDecrypt {
public GenericYetiShareFolder(PluginWrapper wrapper) {
super(wrapper);
@ -92,7 +92,6 @@ public class GenericYetiShareFolder extends PluginForDecrypt {
ret.add(new String[] { "iceyfile.net", "iceyfile.com" });
ret.add(new String[] { "anonzip.com" });
ret.add(new String[] { "fileknot.io" });
ret.add(new String[] { "blazingshare.me" });
ret.add(new String[] { "iwara.zip" });
ret.add(new String[] { "megaup.net" });
ret.add(new String[] { "sqzfile.com" });

View File

@ -39,7 +39,7 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForDecrypt;
import jd.plugins.hoster.TorboxApp;
@DecrypterPlugin(revision = "$Revision: 51023 $", interfaceVersion = 3, names = {}, urls = {})
@DecrypterPlugin(revision = "$Revision: 51030 $", interfaceVersion = 3, names = {}, urls = {})
public class TorboxAppCrawler extends PluginForDecrypt {
public TorboxAppCrawler(PluginWrapper wrapper) {
super(wrapper);
@ -83,7 +83,7 @@ public class TorboxAppCrawler extends PluginForDecrypt {
public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressController progress) throws Exception {
final Account account = AccountController.getInstance().getValidAccount(this.getHost());
if (account == null) {
/* Account required to access any torbox.app content */
/* Account required to access any torbox.app selfhosted content! */
throw new AccountRequiredException();
}
final TorboxApp hosterplugin = (TorboxApp) this.getNewPluginForHostInstance(this.getHost());
@ -91,13 +91,11 @@ public class TorboxAppCrawler extends PluginForDecrypt {
if (br.getHttpConnection().getResponseCode() == 404) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
final ArrayList<DownloadLink> ret = new ArrayList<DownloadLink>();
final UrlQuery query = UrlQuery.parse(param.getCryptedUrl());
final String dl_id = query.get("id");
final String dl_type = query.get("type");
// final String dl_name = query.get("name");
List<Map<String, Object>> files = null;
Map<String, Object> data = null;
final Map<String, Object> data;
if (dl_type.equalsIgnoreCase("torrents")) {
final Request req = br.createGetRequest(TorboxApp.API_BASE + "/torrents/mylist?" + query.toString());
data = (Map<String, Object>) hosterplugin.callAPI(br, req, account, null);
@ -108,16 +106,18 @@ public class TorboxAppCrawler extends PluginForDecrypt {
final Request req = br.createGetRequest(TorboxApp.API_BASE + "/usenet/mylist?" + query.toString());
data = (Map<String, Object>) hosterplugin.callAPI(br, req, account, null);
} else {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT, "Unsupported type");
/* This should never happen */
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT, "Unsupported type: " + dl_type);
}
files = (List<Map<String, Object>>) data.get("files");
final ArrayList<DownloadLink> ret = new ArrayList<DownloadLink>();
final List<Map<String, Object>> files = (List<Map<String, Object>>) data.get("files");
for (final Map<String, Object> file : files) {
final String filename = file.get("short_name").toString();
final String md5 = (String) file.get("md5");
final String internalName = file.get("name").toString();
/* Remove filename from path */
String path = internalName.replaceFirst("/" + Pattern.quote(filename) + "$", "");
final DownloadLink link = this.createDownloadlink("https://dummy.link.todo/" + file.get("name") + ".jdeatme");
final DownloadLink link = this.createDownloadlink("https://dummy.link/" + file.get("name"));
link.setHost(hosterplugin.getHost());
link.setDefaultPlugin(hosterplugin);
link.setProperty(TorboxApp.PROPERTY_DOWNLOAD_TYPE, dl_type);

View File

@ -37,12 +37,19 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForDecrypt;
import jd.plugins.hoster.GenericM3u8;
@DecrypterPlugin(revision = "$Revision: 50190 $", interfaceVersion = 3, names = {}, urls = {})
@DecrypterPlugin(revision = "$Revision: 51029 $", interfaceVersion = 3, names = {}, urls = {})
public class VepornNet extends PluginForDecrypt {
public VepornNet(PluginWrapper wrapper) {
super(wrapper);
}
@Override
public Browser createNewBrowserInstance() {
final Browser br = super.createNewBrowserInstance();
br.setFollowRedirects(true);
return br;
}
public static List<String[]> getPluginDomains() {
final List<String[]> ret = new ArrayList<String[]>();
// each entry in List<String[]> will result in one PluginForDecrypt, Plugin.getHost() will return String[0]->main domain
@ -79,14 +86,13 @@ public class VepornNet extends PluginForDecrypt {
public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressController progress) throws Exception {
final ArrayList<DownloadLink> ret = new ArrayList<DownloadLink>();
final String urlSlug = new Regex(param.getCryptedUrl(), this.getSupportedLinks()).getMatch(0);
final String url = param.getCryptedUrl().replaceFirst("https?://m\\.", "https://www.");
br.setFollowRedirects(true);
br.getPage(url);
final String contenturl = param.getCryptedUrl().replaceFirst("https?://m\\.", "https://www.");
br.getPage(contenturl);
final String rateLimitRegex = "(?i)>\\s*Site is too crowded\\s*<";
if (br.containsHTML(rateLimitRegex)) {
for (int i = 1; i <= 3; i++) {
sleep(i * 3 * 1001l, param);
br.getPage(url);
br.getPage(contenturl);
if (!br.containsHTML(rateLimitRegex)) {
break;
}
@ -151,8 +157,9 @@ public class VepornNet extends PluginForDecrypt {
counter++;
}
}
title = Encoding.htmlDecode(title).trim();
final FilePackage fp = FilePackage.getInstance();
fp.setName(Encoding.htmlDecode(title).trim());
fp.setName(title);
fp.addLinks(ret);
return ret;
}

View File

@ -23,17 +23,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.appwork.net.protocol.http.HTTPConstants;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.JSonStorage;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.TimeFormatter;
import org.appwork.utils.parser.UrlQuery;
import org.jdownloader.plugins.controller.LazyPlugin;
import org.jdownloader.scripting.JavaScriptEngineFactory;
import jd.PluginWrapper;
import jd.http.Browser;
import jd.http.URLConnectionAdapter;
@ -44,6 +33,7 @@ import jd.plugins.Account.AccountType;
import jd.plugins.AccountInfo;
import jd.plugins.AccountInvalidException;
import jd.plugins.AccountUnavailableException;
import jd.plugins.BrowserAdapter;
import jd.plugins.DownloadLink;
import jd.plugins.DownloadLink.AvailableStatus;
import jd.plugins.HostPlugin;
@ -55,11 +45,21 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
import jd.plugins.components.MultiHosterManagement;
@HostPlugin(revision = "$Revision: 51022 $", interfaceVersion = 3, names = { "boxbit.app" }, urls = { "https://download\\.boxbit\\.app/([a-f0-9]{32})(/([^/]+))?" })
import org.appwork.net.protocol.http.HTTPConstants;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.JSonStorage;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.TimeFormatter;
import org.appwork.utils.parser.UrlQuery;
import org.jdownloader.plugins.controller.LazyPlugin;
import org.jdownloader.scripting.JavaScriptEngineFactory;
@HostPlugin(revision = "$Revision: 51034 $", interfaceVersion = 3, names = { "boxbit.app" }, urls = { "https://download\\.boxbit\\.app/([a-f0-9]{32})(/([^/]+))?" })
public class BoxbitApp extends PluginForHost {
/**
* New project of: geragera.com.br </br>
* API docs: https://boxbit.readme.io/reference/introduction
* New project of: geragera.com.br </br> API docs: https://boxbit.readme.io/reference/introduction
*/
private static final String API_BASE = "https://api.boxbit.app";
private static MultiHosterManagement mhm = new MultiHosterManagement("boxbit.app");
@ -198,11 +198,14 @@ public class BoxbitApp extends PluginForHost {
if (account != null) {
this.setLoginHeader(br, account);
}
final int maxChunks = this.getMaxChunks(link);
logger.info("maxChunks: " + maxChunks);
int maxChunks = this.getMaxChunks(link);
logger.info("maxChunks(BeforeOpen): " + maxChunks);
dl = jd.plugins.BrowserAdapter.openDownload(br, link, link.getPluginPatternMatcher(), this.isResumeable(link, account), maxChunks);
this.handleConnectionErrors(br, dl.getConnection());
parseAndSetMaxChunksLimitFromHeader(link, dl.getConnection());
maxChunks = this.getMaxChunks(link);
logger.info("maxChunks(AfterOpen): " + maxChunks);
BrowserAdapter.applySettings(dl, this.isResumeable(link, account), maxChunks);
dl.startDownload();
}
@ -238,8 +241,8 @@ public class BoxbitApp extends PluginForHost {
}
link.setProperty(PROPERTY_DOWNLOADLINK_maxchunks, entries.get("max_chunks"));
}
final int maxChunks = this.getMaxChunks(link);
logger.info("maxChunks: " + maxChunks);
int maxChunks = this.getMaxChunks(link);
logger.info("maxChunks(BeforeOpen): " + maxChunks);
try {
dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, this.isResumeable(link, account), maxChunks);
if (!this.looksLikeDownloadableContent(dl.getConnection())) {
@ -259,6 +262,10 @@ public class BoxbitApp extends PluginForHost {
if (storedDirecturl == null) {
link.setProperty(this.getHost() + PROPERTY_DOWNLOADLINK_directlink, dl.getConnection().getURL().toExternalForm());
}
parseAndSetMaxChunksLimitFromHeader(link, dl.getConnection());
maxChunks = this.getMaxChunks(link);
logger.info("maxChunks(AfterOpen): " + maxChunks);
BrowserAdapter.applySettings(dl, this.isResumeable(link, account), maxChunks);
dl.startDownload();
}

View File

@ -37,7 +37,7 @@ import org.appwork.utils.formatter.SizeFormatter;
import org.jdownloader.plugins.components.config.BunkrConfig;
import org.jdownloader.plugins.config.PluginJsonConfig;
@HostPlugin(revision = "$Revision: 50969 $", interfaceVersion = 3, names = {}, urls = {})
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 3, names = {}, urls = {})
@PluginDependencies(dependencies = { BunkrAlbum.class })
public class Bunkr extends PluginForHost {
public Bunkr(PluginWrapper wrapper) {
@ -109,7 +109,7 @@ public class Bunkr extends PluginForHost {
}
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
private final static Pattern PATTERN_FID = Pattern.compile("(-([A-Za-z0-9]{8}))(\\.[^\\.]+)?$");
/* Plugin properties */
private static final String PROPERTY_LAST_GRABBED_DIRECTURL = "last_grabbed_directurl";

View File

@ -15,8 +15,6 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package jd.plugins.hoster;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Random;
@ -33,10 +31,8 @@ import jd.config.ConfigEntry;
import jd.controlling.AccountController;
import jd.http.Browser;
import jd.http.Cookies;
import jd.http.Request;
import jd.http.URLConnectionAdapter;
import jd.http.requests.PostRequest;
import jd.nutils.JDHash;
import jd.nutils.encoding.Encoding;
import jd.parser.html.Form;
import jd.plugins.Account;
@ -56,19 +52,17 @@ import jd.plugins.components.PluginJSonUtils;
import jd.plugins.components.SiteType.SiteTemplate;
import jd.plugins.decrypter.ChoMikujPlFolder;
@HostPlugin(revision = "$Revision: 51022 $", interfaceVersion = 3, names = { "chomikuj.pl" }, urls = { "https?://chomikujdecrypted\\.pl/.*?,\\d+$" })
@HostPlugin(revision = "$Revision: 51033 $", interfaceVersion = 3, names = { "chomikuj.pl" }, urls = { "https?://chomikujdecrypted\\.pl/.*?,\\d+$" })
public class ChoMikujPl extends antiDDoSForHost {
private String dllink = null;
private static final String ACCESSDENIED = "Nie masz w tej chwili uprawnień do tego pliku lub dostęp do niego nie jest w tej chwili możliwy z innych powodów\\.";
private static final String MAINPAGE = "https://chomikuj.pl/";
/* Plugin settings */
public static final String DECRYPTFOLDERS = "DECRYPTFOLDERS";
private static final String AVOIDPREMIUMMP3TRAFFICUSAGE = "AVOIDPREMIUMMP3TRAFFICUSAGE";
private static final boolean default_AVOIDPREMIUMMP3TRAFFICUSAGE = false;
private static final String FREE_ANONYMOUS_MODE_ALLOW_STREAM_DOWNLOAD_AS_FALLBACK = "FREE_ANONYMOUS_MODE_ALLOW_STREAM_DOWNLOAD_AS_FALLBACK";
public static final String CRAWL_SUBFOLDERS = "CRAWL_SUBFOLDERS";
public static final boolean default_CRAWL_SUBFOLDERS = true;
private static final String ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES = "ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES";
private static final boolean default_ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES = false;
private static final String ALLOW_STREAM_DOWNLOAD_AS_FALLBACK = "ALLOW_STREAM_DOWNLOAD_AS_FALLBACK";
private static final boolean default_ALLOW_STREAM_DOWNLOAD_AS_FALLBACK = true;
private static final String IGNORE_TRAFFIC_LIMIT = "IGNORE_TRAFFIC_LIMIT";
private Browser cbr = null;
private boolean adultContent = false;
private static final boolean default_IGNORE_TRAFFIC_LIMIT = false;
public ChoMikujPl(PluginWrapper wrapper) {
super(wrapper);
@ -115,13 +109,9 @@ public class ChoMikujPl extends antiDDoSForHost {
@Override
public boolean isResumeable(final DownloadLink link, final Account account) {
final AccountType type = account != null ? account.getType() : null;
if (AccountType.FREE.equals(type)) {
if (account != null) {
/* Free Account */
return true;
} else if (AccountType.PREMIUM.equals(type) || AccountType.LIFETIME.equals(type)) {
/* Premium account */
return true;
} else {
/* Free(anonymous) and unknown account type */
return false;
@ -129,15 +119,9 @@ public class ChoMikujPl extends antiDDoSForHost {
}
public int getMaxChunks(final DownloadLink link, final Account account) {
final AccountType type = account != null ? account.getType() : null;
if (AccountType.FREE.equals(type)) {
/* Free Account */
return 1;
} else if (AccountType.PREMIUM.equals(type) || AccountType.LIFETIME.equals(type)) {
/* Premium account */
if (account != null) {
return 0;
} else {
/* Free(anonymous) and unknown account type */
return 1;
}
}
@ -172,8 +156,6 @@ public class ChoMikujPl extends antiDDoSForHost {
}
public AvailableStatus requestFileInformation(final DownloadLink link, final Account account, final boolean isDownload) throws Exception {
adultContent = false;
dllink = null;
final String fid = getFID(link);
final String mainlink = getMainlink(link);
if (fid == null) {
@ -183,7 +165,9 @@ public class ChoMikujPl extends antiDDoSForHost {
if (account != null) {
this.login(account, false);
}
if (mainlink != null) {
if (mainlink == null) {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
/* Try to find better filename - usually only needed for single links. */
getPage(mainlink);
if (isDownload) {
@ -210,8 +194,6 @@ public class ChoMikujPl extends antiDDoSForHost {
} else {
logger.info("Failed to find html filename for single link");
}
adultContent = br.containsHTML("\"FormAdultViewAccepted\"");
}
return AvailableStatus.TRUE;
}
@ -221,7 +203,7 @@ public class ChoMikujPl extends antiDDoSForHost {
login(account, true);
final String remainingTraffic = br.getRegex("<strong>([^<>\"]*?)</strong>\\s*transferu").getMatch(0);
if (remainingTraffic != null) {
if (this.getPluginConfig().getBooleanProperty(ChoMikujPl.IGNORE_TRAFFIC_LIMIT, false) || this.getPluginConfig().getBooleanProperty(ChoMikujPl.AVOIDPREMIUMMP3TRAFFICUSAGE, default_AVOIDPREMIUMMP3TRAFFICUSAGE)) {
if (this.getPluginConfig().getBooleanProperty(ChoMikujPl.IGNORE_TRAFFIC_LIMIT, default_IGNORE_TRAFFIC_LIMIT) || this.getPluginConfig().getBooleanProperty(ChoMikujPl.ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES, default_ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES)) {
/*
* Uploaders can always download their OWN files no matter how much traffic they have left and downloading streams does not
* use up any traffic.
@ -314,7 +296,6 @@ public class ChoMikujPl extends antiDDoSForHost {
* If an error occurs
*/
private String getDllink(final DownloadLink link, final Account account) throws Exception {
final boolean isPremium = account != null && AccountType.PREMIUM.equals(account.getType());
final boolean isVideo = isVideo(link);
final boolean isAudio = StringUtils.endsWithCaseInsensitive(link.getName(), ".mp3");
String downloadUrl = null;
@ -322,14 +303,12 @@ public class ChoMikujPl extends antiDDoSForHost {
br.getHeaders().put("Accept", "*/*");
br.getHeaders().put("X-Requested-With", "XMLHttpRequest");
// Check if account wants to force MP3 stream download
if (isPremium && isAudio && this.getPluginConfig().getBooleanProperty(AVOIDPREMIUMMP3TRAFFICUSAGE, default_AVOIDPREMIUMMP3TRAFFICUSAGE)) {
/* User wants to force stream download for .mp3 files --> Does not use up any premium traffic. */
if (account != null && isAudio && this.getPluginConfig().getBooleanProperty(ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES, default_ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES)) {
/* User prefers stream download for .mp3 files --> Does not use up any account traffic. */
return getDllinkAudioStream(link);
}
// Premium users check for traffic (if traffic checking is enabled)
final boolean accountHasLessTrafficThanRequiredForThisFile = isPremium && !account.getAccountInfo().isSpecialTraffic() && account.getAccountInfo().getTrafficLeft() < link.getView().getBytesTotal();
String content = null;
try {
// Account users check for traffic (if traffic checking is enabled)
final boolean accountHasLessTrafficThanRequiredForThisFile = account != null && account.getAccountInfo() != null && !account.getAccountInfo().isSpecialTraffic() && account.getAccountInfo().getTrafficLeft() < link.getView().getBytesTotal();
// Perform a special file info check for account users
if (account != null) {
final Browser brc = br.cloneBrowser();
@ -353,55 +332,56 @@ public class ChoMikujPl extends antiDDoSForHost {
}
// Set cookies and make initial request
br.setCookie(getHost(), "cookiesAccepted", "1");
if (isPremium) {
br.setCookie("http://chomikuj.pl/", "__RequestVerificationToken_Lw__", requestVerificationToken);
if (account != null) {
br.setCookie(getHost(), "__RequestVerificationToken_Lw__", requestVerificationToken);
br.getHeaders().put("Referer", link.getPluginPatternMatcher());
}
Browser dummy = br.cloneBrowser();
postPageWithCleanup(br, "https://" + getHost() + "/action/License/DownloadContext", "FileId=" + fid + "&__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
final Browser content_br = br.cloneBrowser();
br.postPage("https://" + getHost() + "/action/License/DownloadContext", "FileId=" + fid + "&__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
Map<String, Object> entries = JSonStorage.restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
content = (String) entries.get("Content");
dummy.getRequest().setHtmlCode(content);
String content = (String) entries.get("Content");
content_br.getRequest().setHtmlCode(content);
// Check for access denied
if (cbr.containsHTML(ACCESSDENIED)) {
final String accessDenied = "Nie masz w tej chwili uprawnień do tego pliku lub dostęp do niego nie jest w tej chwili możliwy z innych powodów";
if (StringUtils.containsIgnoreCase(content, accessDenied)) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
final String serializedUserSelection = cbr.getRegex("name=\"SerializedUserSelection\" type=\"hidden\" value=\"([^<>\"]*?)\"").getMatch(0);
final String serializedOrgFile = cbr.getRegex("name=\"SerializedOrgFile\" type=\"hidden\" value=\"([^<>\"]*?)\"").getMatch(0);
final Form form_DownloadWarningAccept = dummy.getFormbyAction("/action/License/DownloadWarningAccept");
final String serializedUserSelection = content_br.getRegex("name=\"SerializedUserSelection\" type=\"hidden\" value=\"([^<>\"]*?)\"").getMatch(0);
final String serializedOrgFile = content_br.getRegex("name=\"SerializedOrgFile\" type=\"hidden\" value=\"([^<>\"]*?)\"").getMatch(0);
final Form form_DownloadWarningAccept = content_br.getFormbyAction("/action/License/DownloadWarningAccept");
if (form_DownloadWarningAccept != null) {
form_DownloadWarningAccept.put("__RequestVerificationToken", Encoding.urlEncode(requestVerificationToken));
br.submitForm(form_DownloadWarningAccept);
entries = JSonStorage.restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
content = (String) entries.get("Content");
dummy.getRequest().setHtmlCode(content);
content_br.getRequest().setHtmlCode(content);
}
if (account != null) {
// Handle "don't show box" dialog
if (cbr.containsHTML("dontShowBoxInSession")) {
if (content_br.containsHTML("dontShowBoxInSession")) {
/* TODO: Check if this is still needed */
postPageWithCleanup(br, "/action/chomikbox/DontDownloadWithBox", "__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
postPageWithCleanup(br, "/action/License/Download", "FileId=" + fid + "&__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
br.postPage("/action/chomikbox/DontDownloadWithBox", "__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
br.postPage("/action/License/Download", "FileId=" + fid + "&__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
entries = JSonStorage.restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
content = (String) entries.get("Content");
dummy.getRequest().setHtmlCode(content);
content_br.getRequest().setHtmlCode(content);
}
// Handle large transfer acceptance
final Form form_acceptLargeTransfer = dummy.getFormbyAction("/action/License/acceptLargeTransfer");
final Form form_AcceptOwnTransfer = dummy.getFormbyAction("/action/License/AcceptOwnTransfer");
final Form form_acceptLargeTransfer = content_br.getFormbyAction("/action/License/acceptLargeTransfer");
final Form form_AcceptOwnTransfer = content_br.getFormbyAction("/action/License/AcceptOwnTransfer");
if (form_acceptLargeTransfer != null) {
/* 2025-04-28: This still exists */
form_acceptLargeTransfer.put("__RequestVerificationToken", Encoding.urlEncode(requestVerificationToken));
br.submitForm(form_acceptLargeTransfer);
entries = JSonStorage.restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
content = (String) entries.get("Content");
dummy.getRequest().setHtmlCode(content);
content_br.getRequest().setHtmlCode(content);
} else if (form_AcceptOwnTransfer != null) {
form_AcceptOwnTransfer.put("__RequestVerificationToken", Encoding.urlEncode(requestVerificationToken));
br.submitForm(form_AcceptOwnTransfer);
entries = JSonStorage.restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
content = (String) entries.get("Content");
dummy.getRequest().setHtmlCode(content);
content_br.getRequest().setHtmlCode(content);
}
} else {
// Handle captcha for free users
@ -416,25 +396,52 @@ public class ChoMikujPl extends antiDDoSForHost {
logger.info("Handling captcha");
final String recaptchaV2Response = new CaptchaHelperHostPluginRecaptchaV2(this, br, rcSiteKey).getToken();
final String postData = "FileId=" + fid + "&SerializedUserSelection=" + Encoding.urlEncode(serializedUserSelection) + "&SerializedOrgFile=" + Encoding.urlEncode(serializedOrgFile) + "&FileName=" + Encoding.urlEncode(link.getName()) + "&g-recaptcha-response=" + Encoding.urlEncode(recaptchaV2Response) + "&__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken);
postPageWithCleanup(br, "/action/License/DownloadNotLoggedCaptchaEntered", postData);
br.postPage("/action/License/DownloadNotLoggedCaptchaEntered", postData);
entries = JSonStorage.restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
content = (String) entries.get("Content");
dummy.getRequest().setHtmlCode(content);
content_br.getRequest().setHtmlCode(content);
} else {
postPageWithCleanup(br, "/action/License/Download", "FileId=" + fid + "&__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
br.postPage("/action/License/Download", "FileId=" + fid + "&__RequestVerificationToken=" + Encoding.urlEncode(requestVerificationToken));
entries = JSonStorage.restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
content = (String) entries.get("Content");
dummy.getRequest().setHtmlCode(content);
content_br.getRequest().setHtmlCode(content);
}
if (cbr.containsHTML("(Aby pobrać ten plik, musisz być zalogowany lub wysłać jeden SMS\\.|Właściciel tego chomika udostępnia swój transfer, ale nie ma go już w wystarczającej|wymaga opłacenia kosztów transferu z serwerów Chomikuj\\.pl)")) {
if (content_br.containsHTML("(Aby pobrać ten plik, musisz być zalogowany lub wysłać jeden SMS\\.|Właściciel tego chomika udostępnia swój transfer, ale nie ma go już w wystarczającej|wymaga opłacenia kosztów transferu z serwerów Chomikuj\\.pl)")) {
throw new AccountRequiredException();
} else if (cbr.containsHTML(ACCESSDENIED)) {
} else if (StringUtils.containsIgnoreCase(content, accessDenied)) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
}
// Extract the download URL from the response
downloadUrl = (String) entries.get("redirectUrl");
if (StringUtils.isEmpty(downloadUrl)) {
if (!StringUtils.isEmpty(downloadUrl)) {
logger.info("Found official downloadurl");
return downloadUrl;
}
logger.info("Account required for official download -> Checking if stream download fallback is possible");
if (isAudio || isVideo) {
/* Fall back to stream download if possible && allowed */
if (!this.getPluginConfig().getBooleanProperty(ALLOW_STREAM_DOWNLOAD_AS_FALLBACK, default_ALLOW_STREAM_DOWNLOAD_AS_FALLBACK)) {
if (account != null) {
throw new AccountRequiredException("Buy account balance or allow stream download fallback in plugin settings to download this file.");
} else {
throw new AccountRequiredException("Add an account or allow stream download fallback in plugin settings to download this file.");
}
}
/* Stream download */
if (isVideo) {
/* Download video stream (free download) */
logger.info("Attempting to download MP4 stream");
downloadUrl = getDllinkVideoStream(link);
} else {
/* Download mp3 stream */
logger.info("Attempting to download MP3 stream");
downloadUrl = getDllinkAudioStream(link);
}
/* Reset verifiedFilesize if it was set because file size of stream download may differ from previously set verifiedFilesize. */
link.setVerifiedFileSize(-1);
return downloadUrl;
}
if (StringUtils.containsIgnoreCase(content, "\"BuyAdditionalTransfer")) {
/* E.g. Próbujesz pobrać plik o rozmiarze 103,06 MB. Każdy plik powyżej 1 MB wymaga opłacenia kosztów trasferu. */
if (account != null) {
@ -443,47 +450,13 @@ public class ChoMikujPl extends antiDDoSForHost {
throw new AccountRequiredException();
}
}
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT, "Failed to find final downloadurl");
if (accountHasLessTrafficThanRequiredForThisFile) {
throw new AccountUnavailableException("Not enough traffic available", 5 * 60 * 1000);
}
if (StringUtils.containsIgnoreCase(downloadUrl, "#SliderTransfer")) {
throw new AccountUnavailableException("Traffic limit reached", 5 * 60 * 1000);
}
} catch (final Exception e) {
if (isPremium) {
throw e;
}
/* Fall back to stream download for free users if possible && allowed */
if (!isAudio && !isVideo) {
/* Stream download impossible -> We failed to find a downloadlink */
// return null;
/* Check for possible error message in "content" field. */
if (!StringUtils.isEmpty(content) && content.length() <= 200) {
/* Try to display more precise errormessage, avoid plugin defect. */
throw new PluginException(LinkStatus.ERROR_FATAL, content);
} else {
throw e;
}
}
logger.info("Failed to get official downloadurl --> Checking if stream download fallback is possible");
if (!this.getPluginConfig().getBooleanProperty(FREE_ANONYMOUS_MODE_ALLOW_STREAM_DOWNLOAD_AS_FALLBACK, true)) {
throw new AccountRequiredException("Add a premium account or allow stream download fallback in plugin settings to download this file.");
}
/* Stream download */
if (isVideo) {
/* Download video stream (free download) */
logger.info("Attempting to download MP4 stream");
getPageWithCleanup(br, "https://" + this.getHost() + "/ShowVideo.aspx?id=" + fid);
if (br.getURL().contains("chomikuj.pl/Error404.aspx") || cbr.containsHTML("(Nie znaleziono|Strona, której szukasz nie została odnaleziona w portalu\\.<|>Sprawdź czy na pewno posługujesz się dobrym adresem)")) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
downloadUrl = getDllinkVideoStream(link);
} else {
/* Download mp3 stream */
logger.info("Attempting to download MP3 stream");
downloadUrl = getDllinkAudioStream(link);
}
}
return downloadUrl;
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
private String getDllinkAudioStream(final DownloadLink link) throws Exception {
@ -523,21 +496,18 @@ public class ChoMikujPl extends antiDDoSForHost {
}
public void handleDownload(final DownloadLink link, final Account account) throws Exception, PluginException {
dllink = checkDirectLink(link, account);
String dllink = checkDirectLink(link, account);
if (dllink == null) {
requestFileInformation(link, account, true);
final boolean adultContent = br.containsHTML("\"FormAdultViewAccepted\"");
if (adultContent) {
throw new AccountRequiredException("Account required to download adult content");
}
this.dllink = this.getDllink(link, account);
if (StringUtils.isEmpty(this.dllink)) {
/* 2020-04-20: Lazy handling because most files are premiumonly: Final downloadlink not found = premiumonly */
throw new AccountRequiredException();
}
}
if (dllink == null) {
dllink = this.getDllink(link, account);
if (StringUtils.isEmpty(dllink)) {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
}
boolean resume = this.isResumeable(link, account);
int maxChunks = this.getMaxChunks(link, account);
final boolean isAudioStreamDownload = StringUtils.containsIgnoreCase(dllink, "/Audio.ashx");
@ -578,7 +548,6 @@ public class ChoMikujPl extends antiDDoSForHost {
URLConnectionAdapter con = null;
try {
final Browser br2 = br.cloneBrowser();
br2.setFollowRedirects(true);
con = br2.openHeadConnection(dllink);
if (this.looksLikeDownloadableContent(con)) {
return dllink;
@ -601,16 +570,16 @@ public class ChoMikujPl extends antiDDoSForHost {
public void login(final Account account, final boolean force) throws Exception {
synchronized (account) {
br.setCookiesExclusive(true);
br.setFollowRedirects(true);
final Cookies cookies = account.loadCookies("");
final String url_path_user_profile = "/" + Encoding.urlEncode(account.getUser());
if (cookies != null) {
br.setCookies(cookies);
if (!force) {
/* Do not verify cookies */
return;
}
getPageWithCleanup(br, MAINPAGE);
if (this.isLoggedIn(br)) {
br.getPage("https://" + getHost() + url_path_user_profile);
if (this.isLoggedInHTML(br)) {
logger.info("Successfully loggedin via cookies");
/* Save new cookie timestamp */
account.saveCookies(br.getCookies(br.getHost()), "");
@ -620,11 +589,18 @@ public class ChoMikujPl extends antiDDoSForHost {
}
}
logger.info("Performing full login");
br.clearCookies(account.getHoster());
prepBrowser(br, account.getHoster());
br.clearCookies(null);
prepBrowser(br, getHost());
br.setCookiesExclusive(true);
br.setFollowRedirects(true);
getPageWithCleanup(br, MAINPAGE);
br.getPage("https://" + getHost());
// final Form loginform = br.getFormByRegex("loginDummy");
// if (loginform == null) {
// throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
// }
// loginform.setAction("/action/Login/TopBarLogin");
// loginform.put("Login", Encoding.urlEncode(account.getUser()));
// loginform.put("Password", Encoding.urlEncode(account.getPass()));
// br.submitForm(loginform);
String postData = "ReturnUrl=&Login=" + Encoding.urlEncode(account.getUser()) + "&Password=" + Encoding.urlEncode(account.getPass());
final String[] requestVerificationTokens = br.getRegex("<input name=\"__RequestVerificationToken\" type=\"hidden\" value=\"([^<>\"\\']+)\"").getColumn(0);
if (requestVerificationTokens.length > 0) {
@ -639,100 +615,36 @@ public class ChoMikujPl extends antiDDoSForHost {
} else {
logger.info("Failed to find any '__RequestVerificationToken' - trying to login without it");
}
PostRequest postRequest = br.createPostRequest("/action/Login/TopBarLogin", postData);
final PostRequest postRequest = br.createPostRequest("/action/Login/TopBarLogin", postData);
postRequest.getHeaders().put("X-Requested-With", "XMLHttpRequest");
// postPageRawWithCleanup(br, "/action/Login/TopBarLogin",
// "rememberLogin=true&rememberLogin=false&ReturnUrl=&Login=" + Encoding.urlEncode(account.getUser()) + "&Password=" +
// Encoding.urlEncode(account.getPass()) + "&__RequestVerificationToken=" +
// Encoding.urlEncode(requestVerificationToken));
br.getPage(postRequest);
if (!isLoggedIn(br)) {
final Map<String, Object> entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
/* E.g. success: {"IsSuccess":true,"Message":null,"Data":{"LoggedIn":true},"Type":3} */
if (!Boolean.TRUE.equals(entries.get("IsSuccess"))) {
throw new AccountInvalidException((String) entries.get("Message"));
} else if (!this.isLoggedInCookie(br)) {
throw new AccountInvalidException();
}
/* Double-check */
br.getPage(url_path_user_profile);
if (!isLoggedInHTML(br)) {
throw new AccountInvalidException();
}
br.setCookie(br.getHost(), "cookiesAccepted", "1");
br.setCookie(br.getHost(), "spt", "0");
br.setCookie(br.getHost(), "rcid", "1");
br.getPage("/" + Encoding.urlEncode(account.getUser()));
account.saveCookies(br.getCookies(br.getHost()), "");
}
}
/** Checks for presence of logged-in related html. */
private boolean isLoggedInHTML(final Browser br) {
return br.containsHTML("/Login/LogOut\"");
}
/** Checks for presence of logged-in cookie. */
private boolean isLoggedIn(final Browser br) {
return br.getCookie(MAINPAGE, "RememberMe", Cookies.NOTDELETEDPATTERN) != null;
}
/** Performs request and then puts cleaned up html into cbr browser instance. */
@Deprecated
private void getPageWithCleanup(final Browser br, final String url) throws Exception {
getPage(br, url);
cbr = br.cloneBrowser();
cleanupBrowser(cbr, correctBR(br.getRequest().getHtmlCode()));
}
/** Performs request and then puts cleaned up html into cbr browser instance. */
@Deprecated
private void postPageWithCleanup(final Browser br, final String url, final String postData) throws Exception {
postPage(br, url, postData);
cbr = br.cloneBrowser();
cleanupBrowser(cbr, correctBR(br.getRequest().getHtmlCode()));
}
@Deprecated
private String correctBR(final String input) {
return input.replace("\\", "");
}
/**
* This allows backward compatibility for design flaw in setHtmlCode(), It injects updated html into all browsers that share the same
* request id. This is needed as request.cloneRequest() was never fully implemented like browser.cloneBrowser().
*
* @param ibr
* Import Browser
* @param t
* Provided replacement string output browser
* @author raztoki
*/
@Deprecated
private void cleanupBrowser(final Browser ibr, final String t) throws Exception {
String dMD5 = JDHash.getMD5(ibr.getRequest().getHtmlCode());
// preserve valuable original request components.
final String oURL = ibr.getURL();
final URLConnectionAdapter con = ibr.getRequest().getHttpConnection();
Request req = new Request(oURL) {
{
boolean okay = false;
try {
final Field field = this.getClass().getSuperclass().getDeclaredField("requested");
field.setAccessible(true);
field.setBoolean(this, true);
okay = true;
} catch (final Throwable e2) {
e2.printStackTrace();
}
if (okay == false) {
try {
requested = true;
} catch (final Throwable e) {
e.printStackTrace();
}
}
httpConnection = con;
setHtmlCode(t);
}
public long postRequest() throws IOException {
return 0;
}
public void preRequest() throws IOException {
}
};
ibr.setRequest(req);
if (ibr.isDebug()) {
logger.info("\r\ndirtyMD5sum = " + dMD5 + "\r\ncleanMD5sum = " + JDHash.getMD5(ibr.getRequest().getHtmlCode()) + "\r\n");
// System.out.println(ibr.getRequest().getHtmlCode());
}
private boolean isLoggedInCookie(final Browser br) {
return br.getCookie("https://" + getHost() + "/", "RememberMe", Cookies.NOTDELETEDPATTERN) != null;
}
@Override
@ -756,17 +668,9 @@ public class ChoMikujPl extends antiDDoSForHost {
}
private void setConfigElements() {
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.AVOIDPREMIUMMP3TRAFFICUSAGE, "Account download: Prefer download of stream versions of audio files in account mode?\r\n<html><b>Avoids premium traffic usage for audio files!</b></html>").setDefaultValue(default_AVOIDPREMIUMMP3TRAFFICUSAGE));
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.FREE_ANONYMOUS_MODE_ALLOW_STREAM_DOWNLOAD_AS_FALLBACK, "Allow fallback to stream download if original file is not downloadable without account?").setDefaultValue(true));
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.DECRYPTFOLDERS, "Crawl subfolders in folders").setDefaultValue(true));
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.IGNORE_TRAFFIC_LIMIT, "Ignore trafficlimit in account (e.g. useful to download self uploaded files or stream download in account mode)?").setDefaultValue(false));
}
@Override
public void reset() {
}
@Override
public void resetDownloadlink(DownloadLink link) {
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES, "Account download: Prefer download of stream versions of audio files in account mode?\r\n<html><b>Avoids traffic usage for audio files!</b></html>").setDefaultValue(default_ACCOUNT_DOWNLOAD_AVOID_TRAFFIC_USAGE_FOR_AUDIO_FILES));
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.ALLOW_STREAM_DOWNLOAD_AS_FALLBACK, "Allow fallback to preview/stream download if original file is only downloadable with premium account?").setDefaultValue(default_ALLOW_STREAM_DOWNLOAD_AS_FALLBACK));
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.CRAWL_SUBFOLDERS, "Crawl subfolders in folders").setDefaultValue(default_CRAWL_SUBFOLDERS));
getConfig().addEntry(new ConfigEntry(ConfigContainer.TYPE_CHECKBOX, getPluginConfig(), ChoMikujPl.IGNORE_TRAFFIC_LIMIT, "Ignore trafficlimit in account (e.g. useful to download self uploaded files or stream download in account mode)?").setDefaultValue(default_IGNORE_TRAFFIC_LIMIT));
}
}

View File

@ -30,6 +30,7 @@ import jd.http.Browser;
import jd.http.URLConnectionAdapter;
import jd.parser.Regex;
import jd.plugins.Account.AccountType;
import jd.plugins.AccountRequiredException;
import jd.plugins.DownloadLink;
import jd.plugins.DownloadLink.AvailableStatus;
import jd.plugins.HostPlugin;
@ -37,7 +38,7 @@ import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
@HostPlugin(revision = "$Revision: 51028 $", interfaceVersion = 3, names = {}, urls = {})
@HostPlugin(revision = "$Revision: 51029 $", interfaceVersion = 3, names = {}, urls = {})
public class DownloadRu extends PluginForHost {
public DownloadRu(PluginWrapper wrapper) {
super(wrapper);
@ -107,7 +108,15 @@ public class DownloadRu extends PluginForHost {
br.getHeaders().put("Accept", "application/json, text/plain, */*");
/* 2020-09-25: Their website can be used like an API. Their official API is broken or not yet usable: https://download.ru/api */
br.getPage("https://" + this.getHost() + "/files/" + this.getFID(link) + ".json");
if (br.getHttpConnection().getResponseCode() == 404) {
final PluginEnvironment pe = this.getPluginEnvironment();
if (br.getHttpConnection().getResponseCode() == 403) {
/* Item is online but account is required to download it */
/* {"code":403,"reason":"permission_denied","message":"Permission denied"} */
if (pe != PluginEnvironment.LINK_CHECK) {
throw new AccountRequiredException();
}
return AvailableStatus.TRUE;
} else if (br.getHttpConnection().getResponseCode() == 404) {
/* 2020-09-25: E.g. {"code":404,"reason":"file","message":"File not found."} */
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}

View File

@ -15,6 +15,7 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package jd.plugins.hoster;
import java.util.List;
import java.util.Map;
import org.appwork.storage.TypeRef;
@ -34,7 +35,7 @@ import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
@HostPlugin(revision = "$Revision: 49004 $", interfaceVersion = 2, names = { "eltrecetv.com.ar" }, urls = { "https?://(?:www\\.)?eltrecetv\\.com\\.ar/.+\\d+/?$" })
@HostPlugin(revision = "$Revision: 51029 $", interfaceVersion = 2, names = { "eltrecetv.com.ar" }, urls = { "https?://(?:www\\.)?eltrecetv\\.com\\.ar/.+\\d+/?$" })
public class EltrecetvComAr extends PluginForHost {
public EltrecetvComAr(final PluginWrapper wrapper) {
super(wrapper);
@ -55,7 +56,8 @@ public class EltrecetvComAr extends PluginForHost {
return Integer.MAX_VALUE;
}
private String hlsurl = null;
private String hls_url = null;
private String hls_master = null;
protected String getFID(final DownloadLink link) {
return new Regex(link.getPluginPatternMatcher(), "(\\d+)/?$").getMatch(0);
@ -78,7 +80,7 @@ public class EltrecetvComAr extends PluginForHost {
if (!link.isNameSet() && fid != null) {
link.setName(fid + extDefault);
}
hlsurl = null;
hls_url = null;
this.setBrowserExclusive();
br.setFollowRedirects(true);
br.getPage(link.getPluginPatternMatcher());
@ -94,9 +96,14 @@ public class EltrecetvComAr extends PluginForHost {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
final Map<String, Object> entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
hlsurl = (String) entries.get("m3u8_url");
if (StringUtils.isEmpty(hlsurl)) {
hlsurl = (String) JavaScriptEngineFactory.walkJson(entries, "sources/{0}/src");
final List<Object> qualities_array = (List<Object>) entries.get("qualities_array");
if (qualities_array != null && qualities_array.size() > 0) {
/* First item = Best quality */
hls_url = (String) JavaScriptEngineFactory.walkJson(qualities_array, "{0}/src");
}
hls_master = (String) JavaScriptEngineFactory.walkJson(entries, "sources/{0}/src");
if (StringUtils.isEmpty(hls_master)) {
hls_master = (String) entries.get("m3u8_url");
}
title = entries.get("video_name").toString();
} else {
@ -113,7 +120,7 @@ public class EltrecetvComAr extends PluginForHost {
}
final Map<String, Object> entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
/* 2021-09-15: HTTP stream is also available but only in lower quality 480p. */
this.hlsurl = JavaScriptEngineFactory.walkJson(entries, "sources/{0}/src").toString();
this.hls_url = JavaScriptEngineFactory.walkJson(entries, "sources/{0}/src").toString();
title = entries.get("video_name").toString();
}
if (title != null && subtitle != null) {
@ -140,13 +147,16 @@ public class EltrecetvComAr extends PluginForHost {
private void download(final DownloadLink link) throws Exception {
requestFileInformation(link);
if (StringUtils.isEmpty(hlsurl)) {
if (StringUtils.isEmpty(hls_url) && StringUtils.isEmpty(hls_master)) {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
br.getPage(hlsurl);
if (StringUtils.isEmpty(hls_url)) {
br.getPage(hls_master);
final HlsContainer hlsbest = HlsContainer.findBestVideoByBandwidth(HlsContainer.getHlsQualities(this.br));
hls_url = hlsbest.getDownloadurl();
}
checkFFmpeg(link, "Download a HLS Stream");
dl = new HLSDownloader(link, br, hlsbest.getDownloadurl());
dl = new HLSDownloader(link, br, hls_url);
dl.startDownload();
}

View File

@ -19,13 +19,6 @@ import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.plugins.components.config.FilestoreToConfig;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.plugins.controller.LazyPlugin;
import jd.PluginWrapper;
import jd.http.Browser;
import jd.http.Cookies;
@ -46,7 +39,14 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
import jd.plugins.components.UserAgents;
@HostPlugin(revision = "$Revision: 51002 $", interfaceVersion = 2, names = { "filestore.to" }, urls = { "https?://(?:www\\.)?filestore\\.to/\\?d=([A-Z0-9]+)" })
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.plugins.components.config.FilestoreToConfig;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.plugins.controller.LazyPlugin;
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 2, names = { "filestore.to" }, urls = { "https?://(?:www\\.)?filestore\\.to/\\?d=([A-Z0-9]+)" })
public class FilestoreTo extends PluginForHost {
public FilestoreTo(final PluginWrapper wrapper) {
super(wrapper);
@ -73,7 +73,7 @@ public class FilestoreTo extends PluginForHost {
}
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
@Override
public String getLinkID(final DownloadLink link) {

View File

@ -27,21 +27,6 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.AbstractRecaptchaV2;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperCrawlerPluginRecaptchaV2;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
import org.jdownloader.plugins.components.config.FreeDiscPlConfig;
import org.jdownloader.plugins.components.config.FreeDiscPlConfig.StreamDownloadMode;
import org.jdownloader.plugins.config.PluginConfigInterface;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.scripting.JavaScriptEngineFactory;
import jd.PluginWrapper;
import jd.controlling.AccountController;
import jd.http.Browser;
@ -67,7 +52,22 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForDecrypt;
import jd.plugins.PluginForHost;
@HostPlugin(revision = "$Revision: 50764 $", interfaceVersion = 2, names = {}, urls = {})
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.AbstractRecaptchaV2;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperCrawlerPluginRecaptchaV2;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
import org.jdownloader.plugins.components.config.FreeDiscPlConfig;
import org.jdownloader.plugins.components.config.FreeDiscPlConfig.StreamDownloadMode;
import org.jdownloader.plugins.config.PluginConfigInterface;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.scripting.JavaScriptEngineFactory;
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 2, names = {}, urls = {})
public class FreeDiscPl extends PluginForHost {
public FreeDiscPl(PluginWrapper wrapper) {
super(wrapper);
@ -123,7 +123,7 @@ public class FreeDiscPl extends PluginForHost {
protected static Cookies botSafeCookies = new Cookies();
private static final AtomicLong timestampLastFreeDownloadStarted = new AtomicLong(0);
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
private static final String TYPE_FILE = "https?://[^/]+/(?:#(?:!|%21))?([A-Za-z0-9\\-_]+,f-(\\d+)(,([\\w\\-]+))?)";
private static final String TYPE_EMBED_ALL = "https?://[^/]+/embed/(audio|video)/(\\d+)";
private static final String TYPE_EMBED_AUDIO = "https?://[^/]+/embed/audio/(\\d+)";
@ -929,8 +929,7 @@ public class FreeDiscPl extends PluginForHost {
} else if (errMsg.equalsIgnoreCase("Jeden użytkownik, jedno konto! Pozostałe konta zostały czasowo zablokowane!")) {
/**
* 2022-03-22: Account is temp. banned under current IP. This can happen when trying to login with two accounts under
* the same IP. </br>
* Solution: Wait and retry later or delete cookies, change IP and try again.
* the same IP. </br> Solution: Wait and retry later or delete cookies, change IP and try again.
*/
throw new AccountUnavailableException(errMsg, 5 * 60 * 1000l);
} else {

View File

@ -65,7 +65,7 @@ import org.jdownloader.plugins.controller.LazyPlugin;
import org.jdownloader.plugins.controller.LazyPlugin.FEATURE;
import org.jdownloader.scripting.JavaScriptEngineFactory;
@HostPlugin(revision = "$Revision: 50937 $", interfaceVersion = 3, names = { "gofile.io" }, urls = { "" })
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 3, names = { "gofile.io" }, urls = { "" })
public class GofileIo extends PluginForHost {
public GofileIo(PluginWrapper wrapper) {
super(wrapper);
@ -124,7 +124,7 @@ public class GofileIo extends PluginForHost {
private static final String PROPERTY_PARENT_FOLDER_ID = "parent_folder_id";
public static final String PROPERTY_PARENT_FOLDER_SHORT_ID = "parent_folder_short_id";
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
@Override
public boolean isResumeable(final DownloadLink link, final Account account) {

View File

@ -20,13 +20,6 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.appwork.storage.TypeRef;
import org.appwork.utils.StringUtils;
import org.appwork.utils.encoding.URLEncode;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.parser.UrlQuery;
import org.jdownloader.plugins.controller.LazyPlugin;
import jd.PluginWrapper;
import jd.nutils.encoding.Encoding;
import jd.parser.Regex;
@ -42,7 +35,14 @@ import jd.plugins.PluginForHost;
import jd.plugins.components.SiteType.SiteTemplate;
import jd.plugins.decrypter.JpgChurchCrawler;
@HostPlugin(revision = "$Revision: 50517 $", interfaceVersion = 3, names = {}, urls = {})
import org.appwork.storage.TypeRef;
import org.appwork.utils.StringUtils;
import org.appwork.utils.encoding.URLEncode;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.parser.UrlQuery;
import org.jdownloader.plugins.controller.LazyPlugin;
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 3, names = {}, urls = {})
public class JpgChurch extends PluginForHost {
public JpgChurch(PluginWrapper wrapper) {
super(wrapper);
@ -68,7 +68,7 @@ public class JpgChurch extends PluginForHost {
/* Position of item if added as part of album (starts from 1). */
public static final String PROPERTY_POSITION = "position";
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
public static List<String[]> getPluginDomains() {
final List<String[]> ret = new ArrayList<String[]>();

View File

@ -42,7 +42,7 @@ import jd.plugins.DownloadLink;
import jd.plugins.DownloadLink.AvailableStatus;
import jd.plugins.HostPlugin;
@HostPlugin(revision = "$Revision: 50429 $", interfaceVersion = 3, names = {}, urls = {})
@HostPlugin(revision = "$Revision: 51030 $", interfaceVersion = 3, names = {}, urls = {})
public class KernelVideoSharingComThepornbangCom extends KernelVideoSharingComV2 {
public KernelVideoSharingComThepornbangCom(final PluginWrapper wrapper) {
super(wrapper);
@ -52,6 +52,7 @@ public class KernelVideoSharingComThepornbangCom extends KernelVideoSharingComV2
public static List<String[]> getPluginDomains() {
final List<String[]> ret = new ArrayList<String[]>();
ret.add(new String[] { "thepornbang.com" });
ret.add(new String[] { "porngrey.net" });
return ret;
}
@ -138,6 +139,7 @@ public class KernelVideoSharingComThepornbangCom extends KernelVideoSharingComV2
}
} catch (final Throwable e) {
logger.log(e);
logger.warning("Special handling failed due to Exception");
}
return super.handleQualitySelection(br, link, qualityMap);
}
@ -160,6 +162,12 @@ public class KernelVideoSharingComThepornbangCom extends KernelVideoSharingComV2
@Override
public Class<? extends KVSConfig> getConfigInterface() {
return KVSConfigThepornbangCom.class;
// TODO: Use the commented out code down below
// if(this.getHost().equals("thepornbang.com")) {
// return KVSConfigThepornbangCom.class;
// }else {
// return KVSConfigPorngreyNet.class;
// }
}
@Override

View File

@ -21,12 +21,6 @@ import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.AbstractRecaptchaV2;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
import jd.PluginWrapper;
import jd.http.Browser;
import jd.http.Cookies;
@ -44,7 +38,13 @@ import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
@HostPlugin(revision = "$Revision: 50515 $", interfaceVersion = 3, names = {}, urls = {})
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.AbstractRecaptchaV2;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 3, names = {}, urls = {})
public class ModsfireCom extends PluginForHost {
public ModsfireCom(PluginWrapper wrapper) {
super(wrapper);
@ -88,7 +88,7 @@ public class ModsfireCom extends PluginForHost {
}
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
@Override
public String getLinkID(final DownloadLink link) {

View File

@ -45,7 +45,7 @@ import jd.plugins.PluginForHost;
*
* @author raztoki<br />
*/
@HostPlugin(revision = "$Revision: 51022 $", interfaceVersion = 3, names = {}, urls = {})
@HostPlugin(revision = "$Revision: 51032 $", interfaceVersion = 3, names = {}, urls = {})
public class Offline extends PluginForHost {
public static String getOfflineVersion() {
final HostPlugin hostPlugin = Offline.class.getAnnotation(HostPlugin.class);
@ -209,6 +209,7 @@ public class Offline extends PluginForHost {
ret.add(new String[] { "bitporno.to", "bitporno.sx", "bitporno.com" });
ret.add(new String[] { "bit-shares.com" });
ret.add(new String[] { "docplayer.net" });
ret.add(new String[] { "blazingshare.me" });
if (cache != null) {
cache.put(cacheID, ret);
}

View File

@ -0,0 +1,65 @@
package jd.plugins.hoster;
import java.util.ArrayList;
import java.util.List;
import org.jdownloader.plugins.components.captchasolver.abstractPluginForCaptchaSolverTwoCaptchaAPIV2;
import org.jdownloader.plugins.controller.LazyPlugin;
import jd.PluginWrapper;
import jd.plugins.HostPlugin;
@HostPlugin(revision = "$Revision: 51033 $", interfaceVersion = 3, names = { "captchas.io" }, urls = { "" })
public class PluginForCaptchaSolverCaptchasIo extends abstractPluginForCaptchaSolverTwoCaptchaAPIV2 {
@Override
public LazyPlugin.FEATURE[] getFeatures() {
return new LazyPlugin.FEATURE[] { LazyPlugin.FEATURE.CAPTCHA_SOLVER, LazyPlugin.FEATURE.BUBBLE_NOTIFICATION, LazyPlugin.FEATURE.API_KEY_LOGIN };
}
public PluginForCaptchaSolverCaptchasIo(PluginWrapper wrapper) {
super(wrapper);
}
@Override
public String getBuyPremiumUrl() {
return "https://app." + getHost() + "/clients/v2/packages";
}
@Override
public List<CAPTCHA_TYPE> getSupportedCaptchaTypes() {
final List<CAPTCHA_TYPE> types = new ArrayList<CAPTCHA_TYPE>();
types.add(CAPTCHA_TYPE.IMAGE);
types.add(CAPTCHA_TYPE.SINGLE_CLICK_CAPTCHA);
types.add(CAPTCHA_TYPE.MULTI_CLICK_CAPTCHA);
types.add(CAPTCHA_TYPE.RECAPTCHA_V2);
types.add(CAPTCHA_TYPE.RECAPTCHA_V2_ENTERPRISE);
types.add(CAPTCHA_TYPE.RECAPTCHA_V2_INVISIBLE);
types.add(CAPTCHA_TYPE.HCAPTCHA);
// types.add(CAPTCHA_TYPE.KEY_CAPTCHA);
types.add(CAPTCHA_TYPE.CLOUDFLARE_TURNSTILE);
// types.add(CAPTCHA_TYPE.MT_CAPTCHA);
return types;
}
protected String getApiBase() {
return "https://api." + getHost();
}
@Override
public String getAGBLink() {
return "https://" + getHost() + "/agreement";
}
@Override
protected boolean looksLikeValidAPIKey(final String str) {
if (str == null) {
return false;
}
return str.matches("[a-f0-9-.]{32}");
}
@Override
protected String getAPILoginHelpURL() {
return "https://app." + getHost() + "/clients/v2/index";
}
}

View File

@ -9,10 +9,7 @@ import org.jdownloader.plugins.controller.LazyPlugin;
import jd.PluginWrapper;
import jd.plugins.HostPlugin;
/**
* Plugin for 2Captcha captcha solving service (https://2captcha.com/).
*/
@HostPlugin(revision = "$Revision: 50898 $", interfaceVersion = 3, names = { "2captcha.com" }, urls = { "" })
@HostPlugin(revision = "$Revision: 51033 $", interfaceVersion = 3, names = { "2captcha.com" }, urls = { "" })
public class PluginForCaptchaSolverTwoCaptcha extends abstractPluginForCaptchaSolverTwoCaptchaAPIV2 {
@Override
public LazyPlugin.FEATURE[] getFeatures() {
@ -30,7 +27,7 @@ public class PluginForCaptchaSolverTwoCaptcha extends abstractPluginForCaptchaSo
@Override
public List<CAPTCHA_TYPE> getSupportedCaptchaTypes() {
List<CAPTCHA_TYPE> types = new ArrayList<CAPTCHA_TYPE>();
final List<CAPTCHA_TYPE> types = new ArrayList<CAPTCHA_TYPE>();
types.add(CAPTCHA_TYPE.IMAGE);
types.add(CAPTCHA_TYPE.SINGLE_CLICK_CAPTCHA);
types.add(CAPTCHA_TYPE.MULTI_CLICK_CAPTCHA);
@ -40,6 +37,7 @@ public class PluginForCaptchaSolverTwoCaptcha extends abstractPluginForCaptchaSo
types.add(CAPTCHA_TYPE.HCAPTCHA);
types.add(CAPTCHA_TYPE.KEY_CAPTCHA);
types.add(CAPTCHA_TYPE.CLOUDFLARE_TURNSTILE);
types.add(CAPTCHA_TYPE.MT_CAPTCHA);
return types;
}

View File

@ -28,24 +28,6 @@ import java.util.Map.Entry;
import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.appwork.net.protocol.http.HTTPConstants;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.Time;
import org.appwork.utils.encoding.URLEncode;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.appwork.utils.net.URLHelper;
import org.jdownloader.captcha.v2.Challenge;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
import org.jdownloader.plugins.components.config.RapidGatorConfig;
import org.jdownloader.plugins.components.config.RapidGatorConfig.PremiumDownloadBehaviorForSubscriberOnlyFiles;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.plugins.controller.LazyPlugin;
import org.jdownloader.settings.staticreferences.CFG_CAPTCHA;
import jd.PluginWrapper;
import jd.controlling.AccountController;
import jd.controlling.reconnect.ipcheck.BalancedWebIPCheck;
@ -70,7 +52,25 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
import jd.plugins.components.PluginJSonUtils;
@HostPlugin(revision = "$Revision: 51026 $", interfaceVersion = 3, names = {}, urls = {})
import org.appwork.net.protocol.http.HTTPConstants;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.Time;
import org.appwork.utils.encoding.URLEncode;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.appwork.utils.net.URLHelper;
import org.jdownloader.captcha.v2.Challenge;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
import org.jdownloader.plugins.components.config.RapidGatorConfig;
import org.jdownloader.plugins.components.config.RapidGatorConfig.PremiumDownloadBehaviorForSubscriberOnlyFiles;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.plugins.controller.LazyPlugin;
import org.jdownloader.settings.staticreferences.CFG_CAPTCHA;
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 3, names = {}, urls = {})
public class RapidGatorNet extends PluginForHost {
public RapidGatorNet(final PluginWrapper wrapper) {
super(wrapper);
@ -148,7 +148,7 @@ public class RapidGatorNet extends PluginForHost {
private final long FREE_RECONNECTWAIT_BETWEEN_DOWNLOADS_MILLIS = 2 * 60 * 60 * 1000L;
private final int FREE_CAPTCHA_EXPIRE_TIME_MILLIS = 105 * 1000;
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
private static final String PROPERTY_LAST_USED_CAPTCHA_TYPE = "last_used_captcha_type";
private static final String CAPTCHA_TYPE_RECAPTCHA = "recaptcha";
@ -308,8 +308,8 @@ public class RapidGatorNet extends PluginForHost {
try {
if (this.looksLikeDownloadableContent(con)) {
/**
* Looks like direct-downloadable item. </br>
* Either we're logged in as a premium user or this item was made hot-linked by a premium user.
* Looks like direct-downloadable item. </br> Either we're logged in as a premium user or this item was made hot-linked by a
* premium user.
*/
if (con.getCompleteContentLength() > 0) {
if (con.isContentDecoded()) {
@ -449,10 +449,9 @@ public class RapidGatorNet extends PluginForHost {
}
if (finalDownloadURL != null) {
/**
* Premium downloadlink found! </br>
* This does not mean that the user owns a premium account. It can also mean that this is a subscription-only file and
* the user owns the needed subscription. </br>
* The maps down below help us to determine the resumeability of such items.
* Premium downloadlink found! </br> This does not mean that the user owns a premium account. It can also mean that this
* is a subscription-only file and the user owns the needed subscription. </br> The maps down below help us to determine
* the resumeability of such items.
*/
logger.info("Premium account or active subscription");
if (account != null) {
@ -520,9 +519,8 @@ public class RapidGatorNet extends PluginForHost {
if (cfg.isEnableFreeDownloadModeCaptchaDuringPreDownloadWait() && lastUsedCaptchaType != null) {
/**
* 2023-10-03: A small trick: We know their captcha key and can thus always obtain captcha solutions at any point of
* time. </br>
* Requesting the captcha here basically allows us to solve it during the serverside wait time which is impossible to do
* in browser.
* time. </br> Requesting the captcha here basically allows us to solve it during the serverside wait time which is
* impossible to do in browser.
*/
final long timeBeforeCaptchaInput = Time.systemIndependentCurrentJVMTimeMillis();
if (CAPTCHA_TYPE_RECAPTCHA.equals(lastUsedCaptchaType)) {
@ -668,8 +666,8 @@ public class RapidGatorNet extends PluginForHost {
link.setResumeable(false);
}
/**
* Save timestamp when download was started. </br>
* Serverside wait time until next download can be started counts from beginning of first/last download.
* Save timestamp when download was started. </br> Serverside wait time until next download can be started counts from beginning
* of first/last download.
*/
if (currentIP != null) {
synchronized (blockedIPsMap) {
@ -733,11 +731,10 @@ public class RapidGatorNet extends PluginForHost {
public int getChallengeTimeout(Challenge<?> challenge) {
/**
* If users need more than X seconds to enter the captcha [in free download mode before final download-step] and we actually send
* the captcha input after this time has passed, rapidgator will 'ban' the IP of the user for at least 60 minutes. </br>
* RG will first display a precise errormessage but then it will display the same message which is displayed when the user has
* reached the daily/hourly download-limit. </br>
* This function exists to avoid this. Instead of sending the captcha it can throw a retry exception, avoiding the 60+ minutes IP
* 'ban'.
* the captcha input after this time has passed, rapidgator will 'ban' the IP of the user for at least 60 minutes. </br> RG will
* first display a precise errormessage but then it will display the same message which is displayed when the user has reached the
* daily/hourly download-limit. </br> This function exists to avoid this. Instead of sending the captcha it can throw a retry
* exception, avoiding the 60+ minutes IP 'ban'.
*/
if (useShortChallengeTimeoutToAvoidServersideBan) {
return FREE_CAPTCHA_EXPIRE_TIME_MILLIS;
@ -1111,8 +1108,7 @@ public class RapidGatorNet extends PluginForHost {
if (br.containsHTML(">\\s*Invalid auth code")) {
/**
* 2FA code required or previously entered code is invalid. This also means that the users' login credentials are
* valid. </br>
* Ask user for 2FA login code in next round.
* valid. </br> Ask user for 2FA login code in next round.
*/
logger.info("2FA code needed");
accountRequires2FALoginCode = true;
@ -1609,8 +1605,8 @@ public class RapidGatorNet extends PluginForHost {
/**
* Returns error message for files that require the user to be subscribed to a specific uploader to be able to download them. <br>
*
* This can even happen for premium account owners since an extra subscription is needed to download such files. </br>
* This can be the same as when "isBuyFile()" returns true but with a more detailed error message.
* This can even happen for premium account owners since an extra subscription is needed to download such files. </br> This can be the
* same as when "isBuyFile()" returns true but with a more detailed error message.
*/
private String getErrormessageSubscriberOnlyDownload(final Browser br) {
return br.getRegex("(The files of this publisher \"[^\"<>]+\" can be downloaded only by subscribers\\.)").getMatch(0);
@ -1667,11 +1663,11 @@ public class RapidGatorNet extends PluginForHost {
if (br.containsHTML("id=\"exceeded_storage\"")) {
/**
* 2024-10-31: <br>
* Your storage space is full. Delete some files or upgrade to the new
* <a href="/article/premium" style="color: #ff801a;">storage plan</a>.<br>
* Your storage space is full. Delete some files or upgrade to the new <a href="/article/premium"
* style="color: #ff801a;">storage plan</a>.<br>
* It looks like this error can happen even when a user is not logged in. At this moment we just assume that this means that the
* uploaders' account is out of space and for this reason, the file can't be downloaded. </br>
* This could also be a fake message which they display whenever the user tried to use a blocked proxy/VPN.
* uploaders' account is out of space and for this reason, the file can't be downloaded. </br> This could also be a fake message
* which they display whenever the user tried to use a blocked proxy/VPN.
*
*/
throw new PluginException(LinkStatus.ERROR_IP_BLOCKED, "Uploaders' storage is full. Wait until uploader buys more traffic to download this file");

View File

@ -26,15 +26,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.appwork.storage.JSonStorage;
import org.appwork.storage.TypeRef;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.parser.UrlQuery;
import org.jdownloader.plugins.components.config.SankakucomplexComConfig;
import org.jdownloader.plugins.components.config.SankakucomplexComConfig.AccessMode;
import org.jdownloader.plugins.config.PluginJsonConfig;
import jd.PluginWrapper;
import jd.controlling.AccountController;
import jd.http.Browser;
@ -56,7 +47,16 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
import jd.plugins.decrypter.SankakucomplexComCrawler;
@HostPlugin(revision = "$Revision: 51005 $", interfaceVersion = 2, names = { "sankakucomplex.com" }, urls = { "https?://(?:beta|chan|idol|www)\\.sankakucomplex\\.com/(?:[a-z]{2}/)?(?:post/show|posts)/([A-Za-z0-9]+)" })
import org.appwork.storage.JSonStorage;
import org.appwork.storage.TypeRef;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.parser.UrlQuery;
import org.jdownloader.plugins.components.config.SankakucomplexComConfig;
import org.jdownloader.plugins.components.config.SankakucomplexComConfig.AccessMode;
import org.jdownloader.plugins.config.PluginJsonConfig;
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 2, names = { "sankakucomplex.com" }, urls = { "https?://(?:beta|chan|idol|www)\\.sankakucomplex\\.com/(?:[a-z]{2}/)?(?:post/show|posts)/([A-Za-z0-9]+)" })
public class SankakucomplexCom extends PluginForHost {
public SankakucomplexCom(PluginWrapper wrapper) {
super(wrapper);
@ -102,8 +102,8 @@ public class SankakucomplexCom extends PluginForHost {
/* 2024-04-26: Refresh-token is currently not used. */
private static final String PROPERTY_ACCOUNT_REFRESH_TOKEN = "refresh_token";
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static final AtomicInteger premiumRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger premiumRunning = new AtomicInteger(0);
@Override
public String getAGBLink() {
@ -465,8 +465,8 @@ public class SankakucomplexCom extends PluginForHost {
private static void prepareDownloadHeaders(final Browser br) {
/**
* 2024-11-12: Do not send a referer header! </br>
* This is really important else we may get redirected to a dummy image. Looks to be some kind of pseudo protection.
* 2024-11-12: Do not send a referer header! </br> This is really important else we may get redirected to a dummy image. Looks to be
* some kind of pseudo protection.
*/
br.getHeaders().put("Referer", "");
// br.setCurrentURL(null);
@ -496,8 +496,8 @@ public class SankakucomplexCom extends PluginForHost {
final String errortext = "Broken or temporarily unavailable file";
if (System.currentTimeMillis() - timestampLastTimeFileMaybeBroken <= 5 * 60 * 1000l) {
/**
* Failed again in a short time even with fresh direct URL: </br>
* Wait longer time before retry as we've just recently tried and it failed again.
* Failed again in a short time even with fresh direct URL: </br> Wait longer time before retry as we've just recently tried and
* it failed again.
*/
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, errortext, 5 * 60 * 1000l);
} else {

View File

@ -0,0 +1,116 @@
//jDownloader - Downloadmanager
//Copyright (C) 2013 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.plugins.hoster;
import java.util.ArrayList;
import java.util.List;
import org.jdownloader.plugins.components.XFileSharingProBasic;
import jd.PluginWrapper;
import jd.plugins.Account;
import jd.plugins.Account.AccountType;
import jd.plugins.DownloadLink;
import jd.plugins.HostPlugin;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
@HostPlugin(revision = "$Revision: 51032 $", interfaceVersion = 3, names = {}, urls = {})
public class StreamboltTv extends XFileSharingProBasic {
public StreamboltTv(final PluginWrapper wrapper) {
super(wrapper);
this.enablePremium(super.getPurchasePremiumURL());
}
/**
* DEV NOTES XfileSharingProBasic Version SEE SUPER-CLASS<br />
* mods: See overridden functions<br />
* limit-info:<br />
* captchatype-info: 2025-04-30: Unsupported captcha type "MTCaptcha" <br />
* other:<br />
*/
public static List<String[]> getPluginDomains() {
final List<String[]> ret = new ArrayList<String[]>();
// each entry in List<String[]> will result in one PluginForHost, Plugin.getHost() will return String[0]->main domain
ret.add(new String[] { "streambolt.tv" });
return ret;
}
public static String[] getAnnotationNames() {
return buildAnnotationNames(getPluginDomains());
}
@Override
public String[] siteSupportedNames() {
return buildSupportedNames(getPluginDomains());
}
public static String[] getAnnotationUrls() {
return XFileSharingProBasic.buildAnnotationUrls(getPluginDomains());
}
@Override
public boolean isResumeable(final DownloadLink link, final Account account) {
final AccountType type = account != null ? account.getType() : null;
if (AccountType.FREE.equals(type)) {
/* Free Account */
return true;
} else if (AccountType.PREMIUM.equals(type) || AccountType.LIFETIME.equals(type)) {
/* Premium account */
return true;
} else {
/* Free(anonymous) and unknown account type */
return true;
}
}
@Override
public int getMaxChunks(final Account account) {
final AccountType type = account != null ? account.getType() : null;
if (AccountType.FREE.equals(type)) {
/* Free Account */
return 0;
} else if (AccountType.PREMIUM.equals(type) || AccountType.LIFETIME.equals(type)) {
/* Premium account */
return 0;
} else {
/* Free(anonymous) and unknown account type */
return 0;
}
}
@Override
public int getMaxSimultaneousFreeAnonymousDownloads() {
return -1;
}
@Override
public int getMaxSimultaneousFreeAccountDownloads() {
return -1;
}
@Override
public int getMaxSimultanPremiumDownloadNum() {
return -1;
}
@Override
protected void handleDownload(final DownloadLink link, final Account account, final String officialVideoDownloadURL, final String directurl) throws Exception {
if (true) {
throw new PluginException(LinkStatus.ERROR_FATAL, "Unsupported captcha type 'MTCaptcha'");
}
}
}

View File

@ -25,15 +25,6 @@ import java.util.Map.Entry;
import java.util.TimeZone;
import java.util.concurrent.atomic.AtomicInteger;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.hcaptcha.CaptchaHelperHostPluginHCaptcha;
import org.jdownloader.plugins.components.antiDDoSForHost;
import org.jdownloader.plugins.components.config.UpstoReConfig;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.plugins.controller.LazyPlugin;
import jd.PluginWrapper;
import jd.controlling.reconnect.ipcheck.BalancedWebIPCheck;
import jd.http.Browser;
@ -53,7 +44,16 @@ import jd.plugins.HostPlugin;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
@HostPlugin(revision = "$Revision: 50770 $", interfaceVersion = 3, names = {}, urls = {})
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.hcaptcha.CaptchaHelperHostPluginHCaptcha;
import org.jdownloader.plugins.components.antiDDoSForHost;
import org.jdownloader.plugins.components.config.UpstoReConfig;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.plugins.controller.LazyPlugin;
@HostPlugin(revision = "$Revision: 51036 $", interfaceVersion = 3, names = {}, urls = {})
public class UpstoRe extends antiDDoSForHost {
public UpstoRe(PluginWrapper wrapper) {
super(wrapper);
@ -110,7 +110,7 @@ public class UpstoRe extends antiDDoSForHost {
private static Map<String, Long> blockedIPsMap = new HashMap<String, Long>();
private static final String PROPERTY_last_blockedIPsMap = "UPSTORE_last_blockedIPsMap";
/* Don't touch the following! */
private static final AtomicInteger freeRunning = new AtomicInteger(0);
private static AtomicInteger freeRunning = new AtomicInteger(0);
@Override
public String getLinkID(final DownloadLink link) {

View File

@ -329,21 +329,26 @@ public class ChallengeResponseController {
final List<Account> solverAccounts = AccountController.getInstance().listAccounts(af);
final HashSet<String> unavailableSolverDomains = new HashSet<String>();
for (final Account solverAccount : solverAccounts) {
boolean success = false;
try {
final abstractPluginForCaptchaSolver plugin = (abstractPluginForCaptchaSolver) solverAccount.getPlugin();
final PluginChallengeSolver<T> solver = plugin.getPluginChallengeSolver(c, solverAccount);
if (solver == null) {
/* E.g. solver cannot handle challenge it gets presented */
unavailableSolverDomains.add(solverAccount.getHoster());
continue;
}
unavailableSolverDomains.remove(solverAccount.getHoster());
ret.add(solver);
success = true;
} catch (final Throwable e) {
logger.log(e);
} finally {
if (success) {
unavailableSolverDomains.remove(solverAccount.getHoster());
} else {
unavailableSolverDomains.add(solverAccount.getHoster());
}
}
}
logger.info("Solver accounts that cannot be used for this challenge: " + unavailableSolverDomains);
}
return ret;

View File

@ -13,14 +13,14 @@ import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import jd.controlling.captcha.SkipException;
import org.appwork.exceptions.WTFException;
import org.appwork.utils.StringUtils;
import org.jdownloader.captcha.v2.solver.browser.AbstractBrowserChallenge;
import org.jdownloader.captcha.v2.solver.jac.SolverException;
import org.jdownloader.captcha.v2.solverjob.SolverJob;
import jd.controlling.captcha.SkipException;
public abstract class ChallengeSolver<T> {
public static final ChallengeSolver EXTERN = new ChallengeSolver<Object>() {
@Override
@ -46,7 +46,7 @@ public abstract class ChallengeSolver<T> {
protected ThreadPoolExecutor threadPool;
private Class<T> resultType;
private SolverService service;
protected SolverService service;
/**
*

View File

@ -3,6 +3,7 @@ package org.jdownloader.captcha.v2;
import org.jdownloader.captcha.v2.solver.CESSolverJob;
import org.jdownloader.captcha.v2.solver.jac.SolverException;
import org.jdownloader.captcha.v2.solverjob.SolverJob;
import org.jdownloader.plugins.components.captchasolver.PluginForCaptchaSolverSolverService;
import org.jdownloader.plugins.components.captchasolver.abstractPluginForCaptchaSolver;
import jd.controlling.captcha.SkipException;
@ -16,9 +17,15 @@ import jd.plugins.PluginException;
public class PluginChallengeSolver<T> extends ChallengeSolver<T> {
protected final Account account;
protected final abstractPluginForCaptchaSolver plugin;
// public PluginChallengeSolver(abstractPluginForCaptchaSolver plugin, Account account, SolverService solverService) {
// super(solverService, 0);
// this.service = new PluginForCaptchaSolverSolverService(plugin);
// this.account = account;
// this.plugin = plugin;
// }
public PluginChallengeSolver(abstractPluginForCaptchaSolver plugin, Account account, SolverService solverService) {
super(solverService, 0);
public PluginChallengeSolver(abstractPluginForCaptchaSolver plugin, Account account) {
this.service = new PluginForCaptchaSolverSolverService(plugin);
this.account = account;
this.plugin = plugin;
}

View File

@ -66,25 +66,7 @@ public abstract class CESChallengeSolver<T> extends ChallengeSolver<T> {
cesJob.hideBubble();
}
}
/**
* Enum representing different types of captchas. <br>
* Mockup code
*/
// public enum CAPTCHA_TYPE {
// IMAGE,
// RECAPTCHA_V2,
// HCAPTCHA,
// FUNCAPTCHA,
// GEETEST,
// KEYCAPTCHA
// }
/** Placeholder / mockup code */
// public java.util.List<CAPTCHA_TYPE> getSupportedCaptchaTypes() {
// java.util.List<CAPTCHA_TYPE> types = new java.util.ArrayList<CAPTCHA_TYPE>();
// types.add(CAPTCHA_TYPE.IMAGE);
// return types;
// }
protected Browser createNewBrowserInstance() {
return new Browser();
}

View File

@ -17,6 +17,7 @@
package org.jdownloader.launcher;
import java.io.File;
import java.net.SocketAddress;
import java.util.Arrays;
import org.appwork.app.launcher.parameterparser.ParameterParser;
@ -110,13 +111,14 @@ public class StandaloneLauncher {
singleInstance.setForwardMessageDirectIfNoOtherInstanceIsFound(false);
try {
singleInstance.start(new ResponseListener() {
@Override
public void onReceivedResponse(Response r) {
public void onReceivedResponse(SingleAppInstance instance, Response r) {
LOGGER.info("Received Response from existing instance: " + r);
}
@Override
public void onConnected(String[] message) {
public void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] args) {
LOGGER.info("existing jD instance found!");
LOGGER.info("Send parameters to existing jD instance and exit: " + Arrays.toString(args));
}

View File

@ -16,7 +16,10 @@ import jd.gui.swing.jdgui.components.premiumbar.ServicePanelExtender;
import jd.gui.swing.jdgui.views.settings.panels.anticaptcha.AbstractCaptchaSolverConfigPanel;
public class PluginForCaptchaSolverSolverService extends AbstractSolverService implements ServicePanelExtender {
public PluginForCaptchaSolverSolverService() {
protected final abstractPluginForCaptchaSolver plugin;
public PluginForCaptchaSolverSolverService(final abstractPluginForCaptchaSolver plugin) {
this.plugin = plugin;
}
@Override
@ -26,6 +29,8 @@ public class PluginForCaptchaSolverSolverService extends AbstractSolverService i
@Override
public Icon getIcon(int size) {
// TODO: Return plugin favicon
// return this.plugin.getFavIcon(this.plugin.getHost());
return NewTheme.I().getIcon(IconKey.ICON_LOGO_DBC, size);
}
@ -36,7 +41,7 @@ public class PluginForCaptchaSolverSolverService extends AbstractSolverService i
@Override
public String getName() {
return "TODO_DUMMY";
return this.plugin.getHost();
}
@Override
@ -46,7 +51,7 @@ public class PluginForCaptchaSolverSolverService extends AbstractSolverService i
@Override
public String getID() {
return "TODO";
return this.plugin.getHost();
}
@Override

View File

@ -121,6 +121,14 @@ public abstract class abstractPluginForCaptchaSolver extends PluginForHost {
public boolean canHandle(Challenge<?> c) {
return c instanceof CloudflareTurnstileChallenge;
}
},
MT_CAPTCHA {
/* https://www.mtcaptcha.com/ */
@Override
public boolean canHandle(Challenge<?> c) {
/* 2025-04-30: Not supported by JDownloader yet. */
return false;
}
};
/**
@ -161,27 +169,22 @@ public abstract class abstractPluginForCaptchaSolver extends PluginForHost {
if (!validateBlackWhite(c)) {
return false;
}
boolean allowedByType = false;
final List<CAPTCHA_TYPE> supportedTypes = this.getSupportedCaptchaTypes();
for (final CAPTCHA_TYPE supportedType : supportedTypes) {
if (supportedType.canHandle(c)) {
allowedByType = true;
break;
}
}
if (!allowedByType) {
return false;
}
return true;
}
}
return false;
}
public <T> PluginChallengeSolver<T> getPluginChallengeSolver(final Challenge<T> c, Account account) throws Exception {
if (!canHandle(c)) {
return null;
}
final abstractPluginForCaptchaSolver plugin = getNewPluginInstance(getLazyP());
final PluginForCaptchaSolverSolverService dummyService = new PluginForCaptchaSolverSolverService();
return new PluginChallengeSolver<T>(plugin, account, /* TODO */dummyService);
plugin.setBrowser(plugin.createNewBrowserInstance());
return new PluginChallengeSolver<T>(plugin, account);
}
/**
@ -248,7 +251,7 @@ public abstract class abstractPluginForCaptchaSolver extends PluginForHost {
* @return true if the user should be notified on low balance, false otherwise
*/
public boolean notifyOnLowBalance() {
// TODO: Implement logic
// TODO: Implement setting and logic
return true;
}

View File

@ -0,0 +1,8 @@
package org.jdownloader.plugins.components.config;
import org.jdownloader.plugins.config.PluginHost;
import org.jdownloader.plugins.config.Type;
@PluginHost(host = "porngrey.net", type = Type.HOSTER)
public interface KVSConfigPorngreyNet extends KVSConfig {
}

View File

@ -37,6 +37,22 @@ import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import jd.controlling.AccountController;
import jd.controlling.accountchecker.AccountCheckerThread;
import jd.http.Browser;
import jd.http.Browser.BrowserException;
import jd.http.Request;
import jd.http.StaticProxySelector;
import jd.http.URLConnectionAdapter;
import jd.http.requests.GetRequest;
import jd.http.requests.PostRequest;
import jd.nutils.encoding.Encoding;
import jd.parser.html.Form;
import jd.plugins.Account;
import jd.plugins.DownloadLink;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import org.appwork.exceptions.WTFException;
import org.appwork.net.protocol.http.HTTPConstants;
import org.appwork.storage.JSonStorage;
@ -105,22 +121,6 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import jd.controlling.AccountController;
import jd.controlling.accountchecker.AccountCheckerThread;
import jd.http.Browser;
import jd.http.Browser.BrowserException;
import jd.http.Request;
import jd.http.StaticProxySelector;
import jd.http.URLConnectionAdapter;
import jd.http.requests.GetRequest;
import jd.http.requests.PostRequest;
import jd.nutils.encoding.Encoding;
import jd.parser.html.Form;
import jd.plugins.Account;
import jd.plugins.DownloadLink;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
public class YoutubeHelper {
static {
final YoutubeConfig cfg = PluginJsonConfig.get(YoutubeConfig.class);
@ -1525,7 +1525,7 @@ public class YoutubeHelper {
} catch (Exception e) {
final String undefined = new Regex(e.getMessage(), "ReferenceError\\s*:\\s*\"(.*?)\"\\s*(is not defined|n'est pas défini|未定义)?").getMatch(0);
if (undefined != null && !additionalMap.containsKey(undefined)) {
final String reference = new Regex(ensurePlayerSource(), "(var\\s*" + Pattern.quote(undefined) + ".*?;)\\w+\\s*=\\s*function").getMatch(0);
final String reference = new Regex(ensurePlayerSource(), "(var\\s*" + Pattern.quote(undefined) + ".*?;)[\\s\r\n]*\\w+\\s*=\\s*function").getMatch(0);
if (reference != null) {
additionalMap.put(undefined, reference);
continue;
@ -1671,7 +1671,7 @@ public class YoutubeHelper {
// lets look for missing reference
String ref = new Regex(html5PlayerSource, "var\\s+" + Pattern.quote(ee) + "\\s*=\\s*\\{.*?\\};").getMatch(-1);
if (ref == null) {
ref = new Regex(html5PlayerSource, "(var\\s*" + Pattern.quote(ee) + ".*?;)\\w+\\s*=\\s*function").getMatch(0);
ref = new Regex(html5PlayerSource, "(var\\s*" + Pattern.quote(ee) + ".*?;)[\\s\r\n]*\\w+\\s*=\\s*function").getMatch(0);
}
if (ref != null) {
all = ref + "\r\n" + all;

View File

@ -66,6 +66,7 @@ import org.appwork.resources.ThemeContext.Target;
import org.appwork.storage.config.MinTimeWeakReference;
import org.appwork.storage.config.MinTimeWeakReferenceCleanup;
import org.appwork.swing.components.CheckBoxIcon;
import org.appwork.swing.components.HeadlessCheckboxIconRef;
import org.appwork.utils.Application;
import org.appwork.utils.DebugMode;
import org.appwork.utils.IO;
@ -334,9 +335,9 @@ public class Theme implements MinTimeWeakReferenceCleanup {
context = createNewDefaultContext();
}
// jd webinterface
if (StringUtils.equalsIgnoreCase(relativePath, "disabled") || StringUtils.equalsIgnoreCase(relativePath, "checkbox_false")) {
if (StringUtils.equalsIgnoreCase(relativePath, "disabled") || (Target.ICON.equals(context.getTarget()) && HeadlessCheckboxIconRef.HEADLESS_checkbox_false.path().equals(relativePath))) {
ret = new CheckBoxIcon(Math.max(width, height), false, true);
} else if (StringUtils.equalsIgnoreCase(relativePath, "enabled") || StringUtils.equalsIgnoreCase(relativePath, "checkbox_true")) {
} else if (StringUtils.equalsIgnoreCase(relativePath, "enabled") || (Target.ICON.equals(context.getTarget()) && HeadlessCheckboxIconRef.HEADLESS_checkbox_true.path().equals(relativePath))) {
ret = new CheckBoxIcon(Math.max(width, height), true, true);
} else if (StringUtils.equalsIgnoreCase(relativePath, "checkbox_undefined")) {
ret = new CheckBoxIcon(Math.max(width, height), true, false);

View File

@ -47,7 +47,6 @@ import javax.swing.JCheckBox;
import org.appwork.loggingv3.LogV3;
import org.appwork.utils.Application;
import org.appwork.utils.DebugMode;
import org.appwork.utils.images.IconDebugger;
import org.appwork.utils.images.IconIO;
import org.appwork.utils.images.ScalableIcon;
@ -56,9 +55,9 @@ public final class CheckBoxIcon implements Icon, ScalableIcon, IDIcon {
public static final Icon TRUE = (new CheckBoxIcon(true));
public static final Icon UNDEFINED = (new CheckBoxIcon(true, false));
private int size;
private JCheckBox checkBox;
private final JCheckBox checkBox;
private Rectangle2D unscaledDimensionAndPosition;
private Image image;
private final Image image;
private boolean selected;
private boolean enabled;
@ -66,26 +65,29 @@ public final class CheckBoxIcon implements Icon, ScalableIcon, IDIcon {
this(-1, selected, enabled);
}
public static void main(String[] args) {
IconDebugger.show(TRUE, "TRUE");
IconDebugger.show(FALSE, "FALSE");
IconDebugger.show(UNDEFINED, "UNDEFINED");
protected Image buildHeadlessCheckBoxIcon(int size, boolean selected, boolean enabled) {
final Image ret;
if (selected) {
ret = HeadlessCheckboxIconRef.HEADLESS_checkbox_true.image(size);
} else {
ret = HeadlessCheckboxIconRef.HEADLESS_checkbox_false.image(size);
}
if (!enabled) {
return IconIO.toGrayScale(ret);
}
return ret;
}
public CheckBoxIcon(int size, boolean selected, boolean enabled) {
this.selected = selected;
this.enabled = enabled;
this.size = size;
if (Application.isHeadless() || false) {
if (selected) {
image = HeadlessCheckboxIconRef.HEADLESS_checkbox_true.image(size);
} else {
image = HeadlessCheckboxIconRef.HEADLESS_checkbox_false.image(size);
}
if (!enabled) {
image = IconIO.toGrayScale(image);
}
if (Application.isHeadless()) {
checkBox = null;
image = buildHeadlessCheckBoxIcon(size, selected, enabled);
} else {
Image image = null;
JCheckBox checkBox = null;
try {
checkBox = new JCheckBox();
checkBox.setEnabled(enabled);
@ -102,16 +104,12 @@ public final class CheckBoxIcon implements Icon, ScalableIcon, IDIcon {
g2d.dispose();
unscaledDimensionAndPosition = record.getCompleteDrawnArea();
} catch (Exception e) {
checkBox = null;
LogV3.log(e);
if (selected) {
image = HeadlessCheckboxIconRef.HEADLESS_checkbox_true.image(size);
} else {
image = HeadlessCheckboxIconRef.HEADLESS_checkbox_false.image(size);
}
if (!enabled) {
image = IconIO.toGrayScale(image);
}
image = buildHeadlessCheckBoxIcon(size, selected, enabled);
}
this.checkBox = checkBox;
this.image = image;
}
}

View File

@ -554,7 +554,7 @@ public class IconIO {
if (resource != null && StringUtils.endsWithCaseInsensitive(resource.getPath(), ".svg")) {
if (getSvgFactory() != null) {
try {
InputStream is = resource.openStream();
final InputStream is = resource.openStream();
try {
return getSvgFactory().getIconFromSVG(is, null, w, h, null);
} finally {

View File

@ -33,6 +33,8 @@
* ==================================================================================================================================================== */
package org.appwork.utils.singleapp;
import java.net.SocketAddress;
/**
* @author thomas
* @date 27.03.2023
@ -43,13 +45,13 @@ public abstract class ResponseAdapter implements ResponseListener {
* @see org.appwork.utils.singleapp.ResponseListener#onConnected(java.lang.String[])
*/
@Override
public void onConnected(String[] message) {
public void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] message) {
}
/* (non-Javadoc)
* @see org.appwork.utils.singleapp.ResponseListener#onReceivedResponse(org.appwork.utils.singleapp.Response)
*/
@Override
public void onReceivedResponse(Response r) {
public void onReceivedResponse(SingleAppInstance instance, Response r) {
}
}

View File

@ -33,6 +33,8 @@
* ==================================================================================================================================================== */
package org.appwork.utils.singleapp;
import java.net.SocketAddress;
/**
* @author thomas
* @date 27.03.2023
@ -40,12 +42,15 @@ package org.appwork.utils.singleapp;
*/
public interface ResponseListener {
/**
* @param instance TODO
* @param remoteSocket TODO
* @param message
*/
void onConnected(String[] message);
void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] message);
/**
* @param instance TODO
* @param r
*/
void onReceivedResponse(Response r);
void onReceivedResponse(SingleAppInstance instance, Response r);
}

View File

@ -424,12 +424,12 @@ public class SingleAppInstance {
if (message == null || message.length == 0) {
this.writeLine(chunkedOut, "0");
if (callback != null) {
callback.onConnected(message);
callback.onConnected(this, socket.getRemoteSocketAddress(), message);
}
} else {
this.writeLine(chunkedOut, message.length + "");
if (callback != null) {
callback.onConnected(message);
callback.onConnected(this, socket.getRemoteSocketAddress(), message);
}
for (final String msg : message) {
this.writeLine(chunkedOut, msg);
@ -515,7 +515,7 @@ public class SingleAppInstance {
clientIDOK = true;
continue;
} else if (callback != null) {
callback.onReceivedResponse(response);
callback.onReceivedResponse(this, response);
}
}
if (exception != null) {
@ -683,7 +683,7 @@ public class SingleAppInstance {
listener.onIncommingMessage(new ResponseSender() {
@Override
public void sendResponse(final Response response) {
responseListener.onReceivedResponse(response);
responseListener.onReceivedResponse(SingleAppInstance.this, response);
}
}, message);
}

View File

@ -36,6 +36,7 @@ package org.appwork.utils.singleapp.test;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
@ -142,13 +143,13 @@ public class TestSingleInstance extends AWTest {
};
private ResponseListener mayNotGetResponses = new ResponseListener() {
@Override
public void onReceivedResponse(Response r) {
public void onReceivedResponse(SingleAppInstance instance, Response r) {
exception = new Exception("Received Response - this should not happen");
LogV3.info(Application.getThreadDump());
}
@Override
public void onConnected(String[] message) {
public void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] message) {
}
};
@ -427,11 +428,11 @@ public class TestSingleInstance extends AWTest {
}.start();
client.start(new ResponseListener() {
@Override
public void onConnected(String[] message) {
public void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] message) {
}
@Override
public void onReceivedResponse(Response r) {
public void onReceivedResponse(SingleAppInstance instance, Response r) {
LogV3.info("Client " + Thread.currentThread().getName() + ":" + r);
responsesViaCallback.add(r);
}
@ -526,12 +527,12 @@ public class TestSingleInstance extends AWTest {
server.setForwardMessageDirectIfNoOtherInstanceIsFound(false);
server.start(new ResponseListener() {
@Override
public void onReceivedResponse(Response r) {
public void onReceivedResponse(SingleAppInstance instance, Response r) {
exception = new Exception("Received Response 1 - this should not happen");
}
@Override
public void onConnected(String[] message) {
public void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] message) {
exception = new Exception("Received Response 1 - this should not happen");
}
}, "");
@ -562,13 +563,13 @@ public class TestSingleInstance extends AWTest {
}
client.start(new ResponseListener() {
@Override
public void onConnected(String[] message) {
public void onReceivedResponse(SingleAppInstance instance, Response r) {
LogV3.info("Client " + Thread.currentThread().getName() + ":" + r);
responsesViaCallback.add(r);
}
@Override
public void onReceivedResponse(Response r) {
LogV3.info("Client " + Thread.currentThread().getName() + ":" + r);
responsesViaCallback.add(r);
public void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] message) {
}
}, withStart);
throw new Exception("Should not reach this part");
@ -650,11 +651,11 @@ public class TestSingleInstance extends AWTest {
String toSend = "test" + System.currentTimeMillis();
ResponseListener callback = new ResponseListener() {
@Override
public void onConnected(String[] message) {
public void onConnected(SingleAppInstance instance, SocketAddress remoteSocket, String[] message) {
}
@Override
public void onReceivedResponse(Response r) {
public void onReceivedResponse(SingleAppInstance instance, Response r) {
System.out.println("Received Response " + r);
synchronized (LOCK) {
responses.add(r.toString());