Fix Anikoto encrypted source resolution
This commit is contained in:
@@ -22,9 +22,36 @@
|
||||
* service of the target website.
|
||||
*/
|
||||
|
||||
const crypto = require("crypto");
|
||||
const cheerio = require("cheerio");
|
||||
|
||||
const baseUrl = "https://anikototv.to";
|
||||
const megaPlayEncKey = "i?LMTAx0Q6,:}50U";
|
||||
const megaPlayEncIv = "W0;27ToaUpl_P%'c";
|
||||
|
||||
function decodeMegaPlayEnc(value) {
|
||||
if (!value || typeof value !== "string") return null;
|
||||
try {
|
||||
const key = Buffer.alloc(32);
|
||||
Buffer.from(megaPlayEncKey).copy(key);
|
||||
const input = Buffer.from(
|
||||
value.replace(/-/g, "+").replace(/_/g, "/"),
|
||||
"base64",
|
||||
);
|
||||
const decipher = crypto.createDecipheriv(
|
||||
"aes-256-cbc",
|
||||
key,
|
||||
Buffer.from(megaPlayEncIv),
|
||||
);
|
||||
const decoded = Buffer.concat([
|
||||
decipher.update(input),
|
||||
decipher.final(),
|
||||
]).toString("utf8");
|
||||
return JSON.parse(decoded);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function parsePagination($, defaultPage) {
|
||||
let totalPages = 1;
|
||||
@@ -229,11 +256,17 @@ async function fetchServerTypes(dataIds) {
|
||||
});
|
||||
const $ = cheerio.load(serverRes.data?.result || "");
|
||||
const types = new Set();
|
||||
const serverLinkSelector =
|
||||
"[data-link-id], li[data-id], a[data-id], button[data-id], .server-item[data-id], .item[data-id]";
|
||||
$(".servers .type[data-type], [data-type]").each((i, el) => {
|
||||
const type = String($(el).attr("data-type") || "")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
if (type) types.add(type);
|
||||
const hasOwnServerLink =
|
||||
Boolean($(el).attr("data-link-id")) ||
|
||||
($(el).is("li,a,button,.server-item,.item") && Boolean($(el).attr("data-id")));
|
||||
const hasNestedServerLink = $(el).find(serverLinkSelector).length > 0;
|
||||
if (type && (hasOwnServerLink || hasNestedServerLink)) types.add(type);
|
||||
});
|
||||
return types;
|
||||
} catch (e) {
|
||||
@@ -406,8 +439,13 @@ async function processServer(server) {
|
||||
},
|
||||
);
|
||||
|
||||
if (sourcesRes.data && sourcesRes.data.sources) {
|
||||
const rawSrc = sourcesRes.data.sources;
|
||||
const decodedSourcesData =
|
||||
sourcesRes.data?.sources || sourcesRes.data?.file
|
||||
? sourcesRes.data
|
||||
: decodeMegaPlayEnc(sourcesRes.data?.enc);
|
||||
|
||||
if (decodedSourcesData && (decodedSourcesData.sources || decodedSourcesData.file)) {
|
||||
const rawSrc = decodedSourcesData.sources || decodedSourcesData.file;
|
||||
const m3u8Url =
|
||||
typeof rawSrc === "string"
|
||||
? rawSrc
|
||||
@@ -425,7 +463,7 @@ async function processServer(server) {
|
||||
global.setFallbackReferer(playerReferer);
|
||||
} catch (e) {}
|
||||
|
||||
const subtitles = (sourcesRes.data.tracks || [])
|
||||
const subtitles = (sourcesRes.data.tracks || decodedSourcesData.tracks || [])
|
||||
.filter(
|
||||
(t) => t.file && (!t.kind || t.kind.toLowerCase() !== "thumbnails"),
|
||||
)
|
||||
@@ -584,7 +622,7 @@ async function fetchEpisodeSources(episodeIdStr, category = null) {
|
||||
|
||||
module.exports = {
|
||||
name: "anikoto",
|
||||
version: "5.0.3",
|
||||
version: "5.0.4",
|
||||
SearchAnime,
|
||||
AnimeInfo,
|
||||
fetchEpisodeSources,
|
||||
|
||||
Reference in New Issue
Block a user