mirror of
https://github.com/p-stream/providers.git
synced 2026-01-11 20:10:33 +00:00
fix ridomovies (closeload)
This commit is contained in:
parent
e248b7b7ee
commit
8b6266d897
1 changed files with 131 additions and 3 deletions
|
|
@ -7,6 +7,56 @@ import { NotFoundError } from '@/utils/errors';
|
|||
import { makeEmbed } from '../base';
|
||||
import { Caption, getCaptionTypeFromUrl, labelToLanguageCode } from '../captions';
|
||||
|
||||
// Custom base64 decoder for problematic strings
|
||||
function customAtob(input: string): string {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
const str = input.replace(/=+$/, '');
|
||||
let output = '';
|
||||
if (str.length % 4 === 1) {
|
||||
throw new Error('The string to be decoded is not correctly encoded.');
|
||||
}
|
||||
for (let bc = 0, bs = 0, i = 0; i < str.length; i++) {
|
||||
const buffer = str.charAt(i);
|
||||
const charIndex = chars.indexOf(buffer);
|
||||
if (charIndex === -1) continue;
|
||||
bs = bc % 4 ? bs * 64 + charIndex : charIndex;
|
||||
if (bc++ % 4) {
|
||||
output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)));
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// Implement the closeload decoding function
|
||||
function decodeCloseload(valueParts: string[]): string {
|
||||
const value = valueParts.join('');
|
||||
let result = value;
|
||||
|
||||
// Step 1: base64 decode
|
||||
result = atob(result);
|
||||
|
||||
// Step 2: ROT13-like transformation
|
||||
result = result.replace(/[a-zA-Z]/g, function rot13Transform(c) {
|
||||
const charCode = c.charCodeAt(0);
|
||||
const newCharCode = charCode + 13;
|
||||
const maxCode = c <= 'Z' ? 90 : 122;
|
||||
return String.fromCharCode(newCharCode <= maxCode ? newCharCode : newCharCode - 26);
|
||||
});
|
||||
|
||||
// Step 3: reverse the string
|
||||
result = result.split('').reverse().join('');
|
||||
|
||||
// Step 4: custom unmixing
|
||||
let unmix = '';
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let charCode = result.charCodeAt(i);
|
||||
charCode = (charCode - (399756995 % (i + 5)) + 256) % 256;
|
||||
unmix += String.fromCharCode(charCode);
|
||||
}
|
||||
|
||||
return unmix;
|
||||
}
|
||||
|
||||
const referer = 'https://ridomovies.tv/';
|
||||
|
||||
export const closeLoadScraper = makeEmbed({
|
||||
|
|
@ -47,11 +97,89 @@ export const closeLoadScraper = makeEmbed({
|
|||
})
|
||||
.html();
|
||||
if (!evalCode) throw new Error("Couldn't find eval code");
|
||||
|
||||
const decoded = unpack(evalCode);
|
||||
const regexPattern = /var\s+(\w+)\s*=\s*"([^"]+)";/g;
|
||||
const base64EncodedUrl = regexPattern.exec(decoded)?.[2];
|
||||
|
||||
let base64EncodedUrl: string | undefined;
|
||||
|
||||
// Look for the dc_* function call pattern (function names are dynamic)
|
||||
const functionCallMatch = decoded.match(/dc_\w+\(\[([^\]]+)\]\)/);
|
||||
if (functionCallMatch) {
|
||||
// Extract the array of strings passed to the function
|
||||
const arrayContent = functionCallMatch[1];
|
||||
|
||||
// Parse the array of strings
|
||||
const stringMatches = arrayContent.match(/"([^"]+)"/g);
|
||||
if (stringMatches) {
|
||||
// Extract the strings from the array
|
||||
const valueParts = stringMatches.map((s) => s.slice(1, -1));
|
||||
|
||||
// Use the closeload decoding function
|
||||
try {
|
||||
const decodedUrl = decodeCloseload(valueParts);
|
||||
|
||||
// Check if the decoded result looks like a URL
|
||||
if (decodedUrl.startsWith('http://') || decodedUrl.startsWith('https://')) {
|
||||
base64EncodedUrl = decodedUrl; // This will be the final URL, not base64
|
||||
}
|
||||
} catch (error) {
|
||||
// Continue to fallback patterns if decoding fails
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to original patterns if function call not found
|
||||
if (!base64EncodedUrl) {
|
||||
const patterns = [/var\s+(\w+)\s*=\s*"([^"]+)";/g, /(\w+)\s*=\s*"([^"]+)"/g, /"([A-Za-z0-9+/=]+)"/g];
|
||||
|
||||
for (const pattern of patterns) {
|
||||
const match = pattern.exec(decoded);
|
||||
if (match) {
|
||||
const potentialUrl = match[2] || match[1];
|
||||
// Check if it looks like base64
|
||||
if (/^[A-Za-z0-9+/]*={0,2}$/.test(potentialUrl) && potentialUrl.length > 10) {
|
||||
base64EncodedUrl = potentialUrl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!base64EncodedUrl) throw new NotFoundError('Unable to find source url');
|
||||
const url = atob(base64EncodedUrl);
|
||||
|
||||
// If base64EncodedUrl is already a URL (from closeload decoding), use it directly
|
||||
let url: string;
|
||||
if (base64EncodedUrl.startsWith('http://') || base64EncodedUrl.startsWith('https://')) {
|
||||
url = base64EncodedUrl;
|
||||
} else {
|
||||
// Fallback to original base64 decoding logic
|
||||
// Validate base64 string before decoding
|
||||
const isValidBase64 = /^[A-Za-z0-9+/]*={0,2}$/.test(base64EncodedUrl);
|
||||
if (!isValidBase64) {
|
||||
throw new NotFoundError('Invalid base64 encoding found in source url');
|
||||
}
|
||||
|
||||
let decodedString: string;
|
||||
try {
|
||||
decodedString = atob(base64EncodedUrl);
|
||||
} catch (error) {
|
||||
// Try custom decoder as fallback
|
||||
try {
|
||||
decodedString = customAtob(base64EncodedUrl);
|
||||
} catch (customError) {
|
||||
throw new NotFoundError(`Failed to decode base64 source url: ${base64EncodedUrl.substring(0, 50)}...`);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find a URL in the decoded string
|
||||
const urlMatch = decodedString.match(/(https?:\/\/[^\s"']+)/);
|
||||
if (urlMatch) {
|
||||
url = urlMatch[1];
|
||||
} else if (decodedString.startsWith('http://') || decodedString.startsWith('https://')) {
|
||||
url = decodedString;
|
||||
} else {
|
||||
throw new NotFoundError(`Decoded string is not a valid URL: ${decodedString.substring(0, 100)}...`);
|
||||
}
|
||||
}
|
||||
return {
|
||||
stream: [
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue