source/mavanimes/mavanimes.js
2025-10-11 17:18:45 +02:00

225 lines
No EOL
6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

async function searchResults(keyword) {
const results = [];
const headers = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest"
};
const regex = /background-image:\s*url\("([^"]+)"\)[^]*?<h3><a[^']+'([^']+)'[^>]*>\s*([^<]+)/g;
const postData = `action=ajaxsearchlite_search&aslp=${keyword}&asid=1&options=qtranslate_lang%3D0%26set_intitle%3DNone%26set_incontent%3DNone%26set_inexcerpt%3DNone%26set_inpages%3DNone`;
try {
const response = await fetchv2("https://www.mavanimes.co/wp-admin/admin-ajax.php", headers, "POST", postData);
const html = await response.text();
let match;
while ((match = regex.exec(html)) !== null) {
results.push({
title: match[3].trim(),
image: match[1].trim(),
href: match[2].trim()
});
}
return JSON.stringify(results);
} catch (err) {
return JSON.stringify([{
title: "Error",
image: "Error",
href: "Error"
}]);
}
}
async function extractDetails(url) {
try {
return JSON.stringify([{
description: "Désolé, le format des données est incohérent, impossible dextraire de manière fiable.",
aliases: "N/A",
airdate: "N/A"
}]);
} catch (err) {
return JSON.stringify([{
description: "Error",
aliases: "Error",
airdate: "Error"
}]);
}
}
async function extractEpisodes(url) {
const results = [];
const regex = /<h2[^>]*>\s*<a href="([^"]+)">/gi;
try {
const response = await fetchv2(url);
const html = await response.text();
let match;
let count = 1;
while ((match = regex.exec(html)) !== null) {
results.push({
href: match[1].trim(),
number: count
});
count++;
}
results.forEach((item, i) => {
item.number = results.length - i;
});
return JSON.stringify(results.reverse());
} catch (err) {
return JSON.stringify([{
href: "Error",
number: "Error"
}]);
}
}
async function extractStreamUrl(url) {
try {
const response = await fetchv2(url);
const html = await response.text();
const voeMatch = html.match(/https:\/\/voe\.sx\/e\/[a-zA-Z0-9]+/);
if (!voeMatch) return null;
const voeLink = voeMatch[0];
const voeResponse = await fetchv2(voeLink);
const voeHtml = await voeResponse.text();
const redirectMatch = voeHtml.match(/window\.location\.href\s*=\s*['"]([^'"]+)['"]/);
if (!redirectMatch) return null;
const finalLink = redirectMatch[1];
const streamUrlOne = finalLink;
const responseTwo = await fetchv2(streamUrlOne);
const finalHtml = await responseTwo.text();
let streamUrl = null;
try {
streamUrl = voeExtractor(finalHtml);
} catch (error) {
console.log("VOE extraction error:", error);
return null;
}
console.log("Voe Stream URL: " + streamUrl);
return streamUrl;
} catch (error) {
console.log("Extract stream URL error:", error);
return null;
}
}
/* SCHEME START */
/**
* @name voeExtractor
* @author Cufiy
*/
function voeExtractor(html, url = null) {
// Extract the first <script type="application/json">...</script>
const jsonScriptMatch = html.match(
/<script[^>]+type=["']application\/json["'][^>]*>([\s\S]*?)<\/script>/i
);
if (!jsonScriptMatch) {
console.log("No application/json script tag found");
return null;
}
const obfuscatedJson = jsonScriptMatch[1].trim();
let data;
try {
data = JSON.parse(obfuscatedJson);
} catch (e) {
throw new Error("Invalid JSON input.");
}
if (!Array.isArray(data) || typeof data[0] !== "string") {
throw new Error("Input doesn't match expected format.");
}
let obfuscatedString = data[0];
// Step 1: ROT13
let step1 = voeRot13(obfuscatedString);
// Step 2: Remove patterns
let step2 = voeRemovePatterns(step1);
// Step 3: Base64 decode
let step3 = voeBase64Decode(step2);
// Step 4: Subtract 3 from each char code
let step4 = voeShiftChars(step3, 3);
// Step 5: Reverse string
let step5 = step4.split("").reverse().join("");
// Step 6: Base64 decode again
let step6 = voeBase64Decode(step5);
// Step 7: Parse as JSON
let result;
try {
result = JSON.parse(step6);
} catch (e) {
throw new Error("Final JSON parse error: " + e.message);
}
// console.log("Decoded JSON:", result);
// check if direct_access_url is set, not null and starts with http
if (result && typeof result === "object") {
const streamUrl =
result.direct_access_url ||
result.source
.map((source) => source.direct_access_url)
.find((url) => url && url.startsWith("http"));
if (streamUrl) {
console.log("Voe Stream URL: " + streamUrl);
return streamUrl;
} else {
console.log("No stream URL found in the decoded JSON");
}
}
return result;
}
function voeRot13(str) {
return str.replace(/[a-zA-Z]/g, function (c) {
return String.fromCharCode(
(c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13)
? c
: c - 26
);
});
}
function voeRemovePatterns(str) {
const patterns = ["@$", "^^", "~@", "%?", "*~", "!!", "#&"];
let result = str;
for (const pat of patterns) {
result = result.split(pat).join("");
}
return result;
}
function voeBase64Decode(str) {
// atob is available in browsers and Node >= 16
if (typeof atob === "function") {
return atob(str);
}
// Node.js fallback
return Buffer.from(str, "base64").toString("utf-8");
}
function voeShiftChars(str, shift) {
return str
.split("")
.map((c) => String.fromCharCode(c.charCodeAt(0) - shift))
.join("");
}
/* SCHEME END */