mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-05-17 01:42:20 +00:00
214 lines
6.6 KiB
Dart
214 lines
6.6 KiB
Dart
import 'dart:io';
|
|
import 'package:desktop_webview_window/desktop_webview_window.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
|
import 'package:html/dom.dart' as dom;
|
|
import 'package:html/dom.dart';
|
|
import 'package:mangayomi/main.dart';
|
|
import 'package:mangayomi/models/settings.dart';
|
|
import 'package:mangayomi/modules/webview/webview.dart';
|
|
import 'package:mangayomi/services/http_service/cloudflare/cookie.dart';
|
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
part 'cloudflare_bypass.g.dart';
|
|
|
|
@riverpod
|
|
Future<dom.Document?> cloudflareBypassDom(CloudflareBypassDomRef ref,
|
|
{required String url,
|
|
required String source,
|
|
required bool useUserAgent}) async {
|
|
final ua = isar.settings.getSync(227)!.userAgent!;
|
|
bool isOk = false;
|
|
dom.Document? htmll;
|
|
if (Platform.isWindows || Platform.isLinux) {
|
|
String? html;
|
|
final webview = await WebviewWindow.create(
|
|
configuration: CreateConfiguration(
|
|
windowHeight: 500,
|
|
windowWidth: 500,
|
|
userDataFolderWindows: await getWebViewPath(),
|
|
),
|
|
);
|
|
webview
|
|
..setBrightness(Brightness.dark)
|
|
..setApplicationNameForUserAgent(useUserAgent ? ua : '')
|
|
..launch(url);
|
|
|
|
await Future.delayed(const Duration(seconds: 10));
|
|
html = await decodeHtml(webview);
|
|
isOk = true;
|
|
await Future.doWhile(() async {
|
|
await Future.delayed(const Duration(seconds: 1));
|
|
if (isOk == true) {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
html = await decodeHtml(webview);
|
|
htmll = dom.Document.html(html!);
|
|
webview.close();
|
|
} else {
|
|
HeadlessInAppWebView? headlessWebView;
|
|
headlessWebView = HeadlessInAppWebView(
|
|
onLoadStop: (controller, u) async {
|
|
String? html;
|
|
html = await controller.evaluateJavascript(
|
|
source:
|
|
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
|
await Future.doWhile(() async {
|
|
if (html == null ||
|
|
html!.contains("Just a moment") ||
|
|
html!.contains("Un instant…") ||
|
|
html!.contains("https://challenges.cloudflare.com")) {
|
|
html = await controller.evaluateJavascript(
|
|
source:
|
|
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
html = await controller.evaluateJavascript(
|
|
source:
|
|
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
|
htmll = dom.Document.html(html!);
|
|
isOk = true;
|
|
headlessWebView!.dispose();
|
|
},
|
|
initialSettings: InAppWebViewSettings(
|
|
userAgent: useUserAgent ? ua : "",
|
|
),
|
|
initialUrlRequest: URLRequest(
|
|
url: WebUri.uri(Uri.parse(url)),
|
|
),
|
|
);
|
|
|
|
headlessWebView.run();
|
|
|
|
await Future.doWhile(() async {
|
|
await Future.delayed(const Duration(seconds: 1));
|
|
if (isOk == true) {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
await ref.watch(setCookieProvider(source, url).future);
|
|
}
|
|
return htmll;
|
|
}
|
|
|
|
@riverpod
|
|
Future<String> cloudflareBypassHtml(CloudflareBypassHtmlRef ref,
|
|
{required String url,
|
|
required String source,
|
|
required bool useUserAgent}) async {
|
|
final ua = isar.settings.getSync(227)!.userAgent!;
|
|
bool isOk = false;
|
|
String? html;
|
|
if (Platform.isWindows || Platform.isLinux) {
|
|
final webview = await WebviewWindow.create(
|
|
configuration: CreateConfiguration(
|
|
windowHeight: 500,
|
|
windowWidth: 500,
|
|
userDataFolderWindows: await getWebViewPath(),
|
|
),
|
|
);
|
|
webview
|
|
..setBrightness(Brightness.dark)
|
|
..setApplicationNameForUserAgent(useUserAgent ? ua : '')
|
|
..launch(url);
|
|
|
|
await Future.doWhile(() async {
|
|
await Future.delayed(const Duration(seconds: 5));
|
|
if (html == null) {
|
|
html = await decodeHtml(webview);
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
|
|
isOk = true;
|
|
webview.close();
|
|
} else {
|
|
HeadlessInAppWebView? headlessWebView;
|
|
headlessWebView = HeadlessInAppWebView(
|
|
onLoadStop: (controller, u) async {
|
|
html = await controller.evaluateJavascript(
|
|
source:
|
|
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
|
await Future.doWhile(() async {
|
|
if (html == null ||
|
|
html!.contains("Just a moment") ||
|
|
html!.contains("Un instant…") ||
|
|
html!.contains("https://challenges.cloudflare.com")) {
|
|
html = await controller.evaluateJavascript(
|
|
source:
|
|
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
await Future.delayed(const Duration(seconds: 10));
|
|
html = await controller.evaluateJavascript(
|
|
source:
|
|
"window.document.getElementsByTagName('html')[0].outerHTML;");
|
|
isOk = true;
|
|
headlessWebView!.dispose();
|
|
},
|
|
initialSettings: InAppWebViewSettings(
|
|
userAgent: useUserAgent ? ua : "",
|
|
),
|
|
initialUrlRequest: URLRequest(
|
|
url: WebUri.uri(Uri.parse(url)),
|
|
),
|
|
);
|
|
|
|
headlessWebView.run();
|
|
await Future.doWhile(() async {
|
|
await Future.delayed(const Duration(seconds: 1));
|
|
if (isOk == true) {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
await ref.watch(setCookieProvider(source, url).future);
|
|
}
|
|
return html!;
|
|
}
|
|
|
|
List<ContentBlocker> adsContentBlockers() {
|
|
final List<ContentBlocker> contentBlockers = [];
|
|
// list of Ad URL filters to be used to block ads loading.
|
|
final adUrlFilters = [
|
|
".*.doubleclick.net/.*",
|
|
".*.ads.pubmatic.com/.*",
|
|
".*.googlesyndication.com/.*",
|
|
".*.google-analytics.com/.*",
|
|
".*.adservice.google.*/.*",
|
|
".*.adbrite.com/.*",
|
|
".*.exponential.com/.*",
|
|
".*.quantserve.com/.*",
|
|
".*.scorecardresearch.com/.*",
|
|
".*.zedo.com/.*",
|
|
".*.adsafeprotected.com/.*",
|
|
".*.teads.tv/.*",
|
|
".*.outbrain.com/.*"
|
|
];
|
|
for (final adUrlFilter in adUrlFilters) {
|
|
contentBlockers.add(ContentBlocker(
|
|
trigger: ContentBlockerTrigger(
|
|
urlFilter: adUrlFilter,
|
|
),
|
|
action: ContentBlockerAction(
|
|
type: ContentBlockerActionType.BLOCK,
|
|
)));
|
|
}
|
|
|
|
// apply the "display: none" style to some HTML elements
|
|
contentBlockers.add(ContentBlocker(
|
|
trigger: ContentBlockerTrigger(
|
|
urlFilter: ".*",
|
|
),
|
|
action: ContentBlockerAction(
|
|
type: ContentBlockerActionType.CSS_DISPLAY_NONE,
|
|
selector: ".banner, .banners, .ads, .ad, .advert")));
|
|
return contentBlockers;
|
|
}
|