mirror of
https://git.luna-app.eu/50n50/sources
synced 2025-12-21 13:16:21 +01:00
Update checkmate/checkmate.js
This commit is contained in:
parent
648c3c29aa
commit
4279c1da72
1 changed files with 268 additions and 6 deletions
|
|
@ -188,10 +188,11 @@ async function extractStreamUrl(ID) {
|
|||
const betaPromise = beta(ID).then(result => ({ source: 'beta', data: JSON.parse(result) })).catch(err => ({ source: 'beta', error: err }));
|
||||
const gammaPromise = gamma(ID).then(result => ({ source: 'gamma', data: JSON.parse(result) })).catch(err => ({ source: 'gamma', error: err }));
|
||||
const deltaPromise = delta(ID).then(result => ({ source: 'delta', data: JSON.parse(result) })).catch(err => ({ source: 'delta', error: err }));
|
||||
const epsilonPromise = epsilon(ID).then(result => ({ source: 'epsilon', data: JSON.parse(result) })).catch(err => ({ source: 'epsilon', error: err }));
|
||||
|
||||
const racePromise = Promise.race([alphaPromise, gammaPromise, deltaPromise]);
|
||||
|
||||
const [fastestResult, betaResult, alphaResult] = await Promise.all([racePromise, betaPromise, alphaPromise]);
|
||||
const [fastestResult, betaResult, alphaResult, epsilonResult] = await Promise.all([racePromise, betaPromise, alphaPromise, epsilonPromise]);
|
||||
|
||||
const resultStreams = [];
|
||||
let subtitle = null;
|
||||
|
|
@ -242,6 +243,28 @@ async function extractStreamUrl(ID) {
|
|||
console.log('Alpha did not return a 4K stream');
|
||||
}
|
||||
}
|
||||
|
||||
if (epsilonResult && !epsilonResult.error && epsilonResult.data && epsilonResult.data.streams) {
|
||||
const streams = epsilonResult.data.streams;
|
||||
let fourKUrl = null;
|
||||
|
||||
for (const stream of streams) {
|
||||
if (stream.title && stream.title.includes('4K') && stream.streamUrl) {
|
||||
fourKUrl = stream;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fourKUrl) {
|
||||
resultStreams.push({
|
||||
title: "4K Secondary",
|
||||
streamUrl: fourKUrl.streamUrl,
|
||||
headers: fourKUrl.headers || { "Referer": "https://mapple.uk/", "Origin": "https://mapple.uk" }
|
||||
});
|
||||
} else {
|
||||
console.log('Epsilon did not return a 4K stream');
|
||||
}
|
||||
}
|
||||
console.log(JSON.stringify({
|
||||
streams: resultStreams,
|
||||
subtitles: subtitle
|
||||
|
|
@ -281,7 +304,7 @@ async function soraFetch(url, options = { headers: {}, method: 'GET', body: null
|
|||
async function alpha(ID) {
|
||||
if (ID.includes('movie')) {
|
||||
const tmdbID = ID.replace('/movie/', '');
|
||||
const cinebyResponse = await soraFetch(`https://jumpfreedom.com/3/movie/${tmdbID}?append_to_response=external_ids&language=en&api_key=ad301b7cc82ffe19273e55e4d4206885`);
|
||||
const cinebyResponse = await soraFetch(`https://db.videasy.net/3/movie/${tmdbID}?append_to_response=external_ids&language=en&api_key=ad301b7cc82ffe19273e55e4d4206885`);
|
||||
const cinebyData = await cinebyResponse.json();
|
||||
|
||||
const title = encodeURIComponent(cinebyData.title);
|
||||
|
|
@ -333,7 +356,7 @@ async function alpha(ID) {
|
|||
const seasonNumber = parts[3];
|
||||
const episodeNumber = parts[4];
|
||||
|
||||
const cinebyResponse = await soraFetch(`https://jumpfreedom.com/3/tv/${tmdbID}?append_to_response=external_ids&language=en&api_key=ad301b7cc82ffe19273e55e4d4206885`);
|
||||
const cinebyResponse = await soraFetch(`hhttps://db.videasy.net/3/tv/${tmdbID}?append_to_response=external_ids&language=en&api_key=ad301b7cc82ffe19273e55e4d4206885`);
|
||||
const cinebyData = await cinebyResponse.json();
|
||||
|
||||
const title = encodeURIComponent(cinebyData.name);
|
||||
|
|
@ -610,6 +633,202 @@ async function delta(ID) {
|
|||
}
|
||||
}
|
||||
|
||||
async function epsilon(ID) {
|
||||
const actionIdentifier = await ilovethighs("https://mapple.uk/watch/movie/1061474-superman");
|
||||
|
||||
console.log("Action Identifier: " + actionIdentifier);
|
||||
|
||||
const sessionResponse = await soraFetch("https://enc-dec.app/api/enc-mapple");
|
||||
const sessionData = await sessionResponse.json();
|
||||
console.log("Session Data: " + JSON.stringify(sessionData));
|
||||
const sessionID = sessionData.result.sessionId || "N/A";
|
||||
console.log("ID: " + ID);
|
||||
if (ID.startsWith('/movie/') || ID.startsWith('movie/')) {
|
||||
const match = ID.match(/movie\/(\d+)/);
|
||||
const tmdbID = match ? match[1] : '';
|
||||
console.log("Extracted TMDB ID: " + tmdbID);
|
||||
const headers = {
|
||||
"Content-Type": "text/plain",
|
||||
"next-action": actionIdentifier
|
||||
};
|
||||
const postData = `[{"mediaId":${tmdbID},"mediaType":"movie","tv_slug":"","source":"mapple","useFallbackVideo":false,"sessionId":"${sessionID}"}]`;
|
||||
const response = await fetchv2("https://mapple.uk/watch/"+ ID, headers, "POST", postData);
|
||||
const data = await response.text();
|
||||
console.log("Stream data: " + data);
|
||||
|
||||
const lines = data.split('\n');
|
||||
let streamData = null;
|
||||
for (const line of lines) {
|
||||
if (line.includes('"success":true')) {
|
||||
streamData = JSON.parse(line.substring(line.indexOf('{')));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (streamData && streamData.data && streamData.data.stream_url) {
|
||||
const m3u8Response = await soraFetch(streamData.data.stream_url, {
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
const m3u8Text = await m3u8Response.text();
|
||||
console.log("M3U8 Playlist: " + m3u8Text);
|
||||
|
||||
const streams = [];
|
||||
const lines = m3u8Text.split('\n');
|
||||
const resolutionNames = {
|
||||
"3840x2160": "4K",
|
||||
"1920x1080": "1080p",
|
||||
"1280x720": "720p",
|
||||
"640x360": "360p"
|
||||
};
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].startsWith('#EXT-X-STREAM-INF')) {
|
||||
const resolutionMatch = lines[i].match(/RESOLUTION=(\d+x\d+)/);
|
||||
const streamUrl = lines[i + 1];
|
||||
if (resolutionMatch && streamUrl && streamUrl.trim()) {
|
||||
const resolution = resolutionMatch[1];
|
||||
const friendlyName = resolutionNames[resolution] || resolution;
|
||||
streams.push({
|
||||
title: friendlyName,
|
||||
streamUrl: streamUrl.trim(),
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let englishSubtitleUrl = "";
|
||||
try {
|
||||
const subResponse = await soraFetch(`https://mapple.uk/api/subtitles?id=${tmdbID}&mediaType=movie`);
|
||||
const subData = await subResponse.json();
|
||||
const englishSub = subData.find(sub => sub.language === "en");
|
||||
if (englishSub) {
|
||||
englishSubtitleUrl = englishSub.url;
|
||||
}
|
||||
} catch (e) {
|
||||
englishSubtitleUrl = "";
|
||||
}
|
||||
console.log("English Subtitle URL: " + englishSubtitleUrl);
|
||||
console.log("Extracted streams: " + JSON.stringify(streams));
|
||||
|
||||
return JSON.stringify({
|
||||
streams: streams.length > 0 ? streams : [
|
||||
{
|
||||
title: "Mapple Server",
|
||||
streamUrl: streamData.data.stream_url,
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
}
|
||||
],
|
||||
subtitle: englishSubtitleUrl || ""
|
||||
});
|
||||
} else {
|
||||
throw new Error("Failed to extract stream URL");
|
||||
}
|
||||
} else if (ID.startsWith('/tv/') || ID.startsWith('tv/')) {
|
||||
const match = ID.match(/tv\/(\d+)-(\d+)-(\d+)/);
|
||||
if (!match) throw new Error("Invalid TV URL format");
|
||||
|
||||
const tmdbID = match[1];
|
||||
const seasonNumber = match[2];
|
||||
const episodeNumber = match[3];
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "text/plain",
|
||||
"next-action": actionIdentifier
|
||||
};
|
||||
const postData = `[{"mediaId":${tmdbID},"mediaType":"tv","tv_slug":"${seasonNumber}-${episodeNumber}","source":"mapple","useFallbackVideo":false,"sessionId":"${sessionID}"}]`;
|
||||
const response = await fetchv2("https://mapple.uk/watch"+ ID, headers, "POST", postData);
|
||||
const data = await response.text();
|
||||
console.log("Stream data: " + data);
|
||||
|
||||
const lines = data.split('\n');
|
||||
let streamData = null;
|
||||
for (const line of lines) {
|
||||
if (line.includes('"success":true')) {
|
||||
streamData = JSON.parse(line.substring(line.indexOf('{')));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (streamData && streamData.data && streamData.data.stream_url) {
|
||||
const m3u8Response = await soraFetch(streamData.data.stream_url, {
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
const m3u8Text = await m3u8Response.text();
|
||||
console.log("M3U8 Playlist: " + m3u8Text);
|
||||
|
||||
const streams = [];
|
||||
const lines = m3u8Text.split('\n');
|
||||
const resolutionNames = {
|
||||
"3840x2160": "4K",
|
||||
"1920x1080": "1080p",
|
||||
"1280x720": "720p",
|
||||
"640x360": "360p"
|
||||
};
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if (lines[i].startsWith('#EXT-X-STREAM-INF')) {
|
||||
const resolutionMatch = lines[i].match(/RESOLUTION=(\d+x\d+)/);
|
||||
const streamUrl = lines[i + 1];
|
||||
if (resolutionMatch && streamUrl && streamUrl.trim()) {
|
||||
const resolution = resolutionMatch[1];
|
||||
const friendlyName = resolutionNames[resolution] || resolution;
|
||||
streams.push({
|
||||
title: friendlyName,
|
||||
streamUrl: streamUrl.trim(),
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let englishSubtitleUrl = "";
|
||||
try {
|
||||
const subResponse = await soraFetch(`https://mapple.uk/api/subtitles?id=${tmdbID}&mediaType=tv&season=${seasonNumber}&episode=${episodeNumber}`);
|
||||
const subData = await subResponse.json();
|
||||
const englishSub = subData.find(sub => sub.language === "en");
|
||||
if (englishSub) {
|
||||
englishSubtitleUrl = englishSub.url;
|
||||
}
|
||||
} catch (e) {
|
||||
englishSubtitleUrl = "";
|
||||
}
|
||||
console.log("English Subtitle URL: " + englishSubtitleUrl);
|
||||
console.log("Extracted streams: " + JSON.stringify(streams));
|
||||
|
||||
return JSON.stringify({
|
||||
streams: streams.length > 0 ? streams : [
|
||||
{
|
||||
title: "Mapple Server",
|
||||
streamUrl: streamData.data.stream_url,
|
||||
headers: {
|
||||
"referer": "https://mapple.uk/",
|
||||
"origin": "https://mapple.uk"
|
||||
}
|
||||
}
|
||||
],
|
||||
subtitle: englishSubtitleUrl || ""
|
||||
});
|
||||
} else {
|
||||
throw new Error("Failed to extract stream URL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function soraFetch(url, options = { headers: {}, method: 'GET', body: null, encoding: 'utf-8' }) {
|
||||
try {
|
||||
return await fetchv2(
|
||||
|
|
@ -998,6 +1217,51 @@ async function ilovefeet(imdbId, isSeries = false, season = null, episode = null
|
|||
};
|
||||
}
|
||||
|
||||
async function ilovethighs(watchUrl) {
|
||||
const htmlResponse = await soraFetch(watchUrl);
|
||||
const htmlText = await htmlResponse.text();
|
||||
|
||||
const layoutMatch = htmlText.match(/<script[^>]*src="([^"]*app\/watch\/movie\/[^"]*layout-[^"]*\.js)"[^>]*><\/script><link rel="preload"/);
|
||||
|
||||
if (!layoutMatch || !layoutMatch[1]) {
|
||||
throw new Error("error 1");
|
||||
}
|
||||
|
||||
const beforeLayoutMatch = htmlText.match(/<script[^>]*src="([^"]*\.js)"[^>]*><\/script><script[^>]*src="[^"]*app\/watch\/(movie|tv)\/[^"]*layout-[^"]*\.js"/);
|
||||
|
||||
if (!beforeLayoutMatch || !beforeLayoutMatch[1]) {
|
||||
throw new Error("error 2");
|
||||
}
|
||||
|
||||
let targetUrl = beforeLayoutMatch[1];
|
||||
if (targetUrl.startsWith('/_next/')) {
|
||||
targetUrl = 'https://mapple.uk' + targetUrl;
|
||||
} else if (!targetUrl.startsWith('http')) {
|
||||
targetUrl = 'https://mapple.uk/' + targetUrl;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await soraFetch(targetUrl);
|
||||
const text = await response.text();
|
||||
|
||||
let actionMatch = text.match(/createServerReference\)\("([a-f0-9]{40,})"[^"]*"getStreamUrl/);
|
||||
if (!actionMatch) {
|
||||
actionMatch = text.match(/createServerReference\)\("([a-f0-9]{40,})"/);
|
||||
}
|
||||
if (!actionMatch) {
|
||||
actionMatch = text.match(/"([a-f0-9]{40,})"[^"]*"getStreamUrl/);
|
||||
}
|
||||
|
||||
if (actionMatch && actionMatch[1]) {
|
||||
return actionMatch[1];
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error("error 3: " + e);
|
||||
}
|
||||
|
||||
throw new Error("error 4");
|
||||
}
|
||||
|
||||
function wordArrayToUint8Array(wordArray) {
|
||||
const words = wordArray.words;
|
||||
const sigBytes = wordArray.sigBytes;
|
||||
|
|
@ -7226,6 +7490,4 @@ function uint8ArrayToBase64Url(bytes) {
|
|||
|
||||
}));
|
||||
|
||||
//const CryptoJS = module.exports;
|
||||
|
||||
|
||||
// Veni Vidi Veci
|
||||
Loading…
Add table
Add a link
Reference in a new issue