From 3247f3a731922a30ef4e6f170eea1906fd39f888 Mon Sep 17 00:00:00 2001 From: endoverdosing Date: Thu, 30 Jul 2026 09:25:08 -0700 Subject: [PATCH] Fixed all sources, rewrote, made test easier for developers to test everything --- .gitignore | 3 +- .npmignore | 1 + src/config.js | 73 ++++------- src/sdk.d.ts | 1 - src/sources/1embed.js | 45 +++++-- src/sources/anihq.js | 16 ++- src/sources/anineko.js | 137 +++++++++++++++++--- src/sources/flaxmovies.js | 30 +++-- src/sources/fsonic.js | 4 +- src/sources/fsonline.js | 4 +- src/sources/goated.js | 262 -------------------------------------- src/sources/lmscript.js | 43 +++++++ src/sources/nebula.js | 62 --------- src/sources/videasy.js | 18 +-- src/sources/vidvault.js | 114 +++++++++++++++++ src/sources/vidzee.js | 154 ++++++++++------------ src/sources/vixsrc.js | 42 ++++-- src/utils/helpers.js | 76 ++++++++--- test/index.js | 197 +++++++++++++++++++++++----- 19 files changed, 705 insertions(+), 577 deletions(-) delete mode 100644 src/sources/goated.js create mode 100644 src/sources/lmscript.js delete mode 100644 src/sources/nebula.js create mode 100644 src/sources/vidvault.js diff --git a/.gitignore b/.gitignore index d16f63d..24129b2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -.env \ No newline at end of file +.env +test/debug-output.json \ No newline at end of file diff --git a/.npmignore b/.npmignore index 482a67f..3ffcf26 100644 --- a/.npmignore +++ b/.npmignore @@ -2,3 +2,4 @@ .env test/ node_modules/ +test/debug-output.json \ No newline at end of file diff --git a/src/config.js b/src/config.js index 05d00cc..5580c20 100644 --- a/src/config.js +++ b/src/config.js @@ -1,4 +1,4 @@ -// Currently active sources reported on 7:47:50 PM PST 7/6/2026 +// Currently active sources reported on 9:22:41 PM PST 7/30/2026 // None Anime Tested: 936075 // Anime Tested: 37854 @@ -135,7 +135,7 @@ export const SOURCES = [ jitter: 500, retries: 2, multiUrl: true, - disabled: true, // Temporarily disabled because their site is down, all streams are returning 403's + skipProxy: true, cdnHeaders: [{ pattern: /flix2watch\.pro/i, headers: { @@ -161,18 +161,6 @@ export const SOURCES = [ }, }, - { - key: 'goated', - label: 'Goated', - sourceFile: 'goated', - proxyParam: 'gt', - timeout: 25000, - jitter: 500, - retries: 2, - multiUrl: true, - skipProxy: true, - }, - { key: 'fsonic', label: 'Fsonic', @@ -216,6 +204,17 @@ export const SOURCES = [ retries: 1, }, + { + key: 'lmscript', + label: 'LMScript', + sourceFile: 'lmscript', + proxyParam: 'lmsc', + timeout: 20000, + jitter: 500, + retries: 2, + multiUrl: true, + }, + { key: 'lookmovie', label: 'LookMovie', @@ -252,38 +251,6 @@ export const SOURCES = [ skipProxy: true }, - { - key: 'nebula', - label: 'Nebula', - sourceFile: 'nebula', - proxyParam: 'nb', - timeout: 25000, - jitter: 500, - retries: 1, - multiUrl: true, - skipProxy: true, - }, - - { - key: 'nekowatch-sub', - sourceFile: 'nekowatch', - label: 'NekoWatch (Sub)', - proxyParam: 'nwsub', - timeout: 30000, - jitter: 500, - retries: 2 - }, - - { - key: 'nekowatch-dub', - sourceFile: 'nekowatch', - label: 'NekoWatch (Dub)', - proxyParam: 'nwdub', - timeout: 30000, - jitter: 500, - retries: 2 - }, - { key: 'opstream', label: 'OpStream', @@ -332,6 +299,7 @@ export const SOURCES = [ timeout: 20000, jitter: 500, retries: 2, + skipProxy: true }, { @@ -485,6 +453,17 @@ export const SOURCES = [ multiUrl: true }, + { + key: 'vidvault', + label: 'VidVault', + sourceFile: 'vidvault', + proxyParam: 'vv', + timeout: 25000, + jitter: 500, + retries: 2, + multiUrl: true, + }, + { key: 'vidzee', label: 'VidZee', @@ -494,13 +473,13 @@ export const SOURCES = [ sourcesTimeout: 10000, jitter: 400, retries: 3, - disabled: true, // Temporarily disabled because their site is down, all streams are returning 403's verifyHeaders: { Accept: '/', 'Accept-Language': 'en-US,en;q=0.9', Referer: 'https://player.vidzee.wtf', Origin: 'https://player.vidzee.wtf', }, + disabled: true // Disabled temporarily due to decryption issues }, { diff --git a/src/sdk.d.ts b/src/sdk.d.ts index 7bef6e3..d547113 100644 --- a/src/sdk.d.ts +++ b/src/sdk.d.ts @@ -59,7 +59,6 @@ export interface VylaSDKOptions { tmdbApiKey?: string; } -// Descriptions written with Claude. export default class VylaSDK { tmdbApiKey?: string; diff --git a/src/sources/1embed.js b/src/sources/1embed.js index ef35f4c..835533e 100644 --- a/src/sources/1embed.js +++ b/src/sources/1embed.js @@ -3,13 +3,11 @@ import { USER_AGENT } from '../utils/helpers.js'; const BASE_URL = "https://1embed.cc"; const PROVIDERS = [ - { id: "sdev", name: "1Embed - SDev" }, - { id: "xpa", name: "1Embed - XPass" }, - { id: "vnes", name: "1Embed - VidNest" }, - { id: "pro", name: "1Embed - Pro" }, - { id: "pur", name: "1Embed - Purstream" }, - { id: "czo", name: "1Embed - Cinezo" }, - { id: "fas", name: "1Embed - VidFast" } + { id: "BUKE", name: "1Embed - BUKE" }, + { id: "YOTA", name: "1Embed - YOTA" }, + { id: "NEPT", name: "1Embed - NEPT" }, + { id: "AZURE", name: "1Embed - AZURE" }, + { id: "YORU", name: "1Embed - YORU" } ]; let cachedToken = null; @@ -28,6 +26,30 @@ async function getToken() { } catch { return null; } } +function decodeBsUrl(url) { + if (!url) return url; + let target = url; + if (url.includes('d=')) { + try { + const parts = url.split(/[?&]/); + for (const part of parts) { + if (part.startsWith('d=')) { + target = decodeURIComponent(part.substring(2)); + break; + } + } + } catch { } + } + if (target.startsWith('bs_')) { + try { + const decoded = Buffer.from(target.slice(3), 'base64').toString('utf-8'); + const reversed = decoded.split('').reverse().join(''); + if (reversed.startsWith('http')) return reversed; + } catch { } + } + return url; +} + async function fetchProviderStream(provider, type, id, s, e, token) { try { const referer = type === "movie" ? `${BASE_URL}/embed/movie/${id}` : `${BASE_URL}/embed/tv/${id}/${s}/${e}`; @@ -51,11 +73,12 @@ async function fetchProviderStream(provider, type, id, s, e, token) { const results = []; for (const src of rawSources) { if (typeof src !== 'object' || !src) continue; - let streamUrl = src.url || src.file || src.link; - if (typeof streamUrl !== 'string') continue; + let rawUrl = src.url || src.file || src.link; + if (typeof rawUrl !== 'string') continue; + let streamUrl = decodeBsUrl(rawUrl); if (streamUrl.startsWith('/')) streamUrl = `${BASE_URL}${streamUrl}`; const isWorker = streamUrl.includes('omena-puu') || streamUrl.includes('nocach') || streamUrl.includes('?p='); - const isHls = src.type === 'hls' || streamUrl.includes('m3u8') || isWorker; + const isHls = src.type === 'hls' || src.type === 'm3u8' || streamUrl.includes('m3u8') || isWorker; if (isHls && !streamUrl.includes('m3u8')) streamUrl += streamUrl.includes('?') ? '&format=.m3u8' : '?format=.m3u8'; const srcHeaders = (src.headers && typeof src.headers === 'object') ? src.headers : {}; results.push({ @@ -80,7 +103,7 @@ export async function getStream(args) { let targets = PROVIDERS; if (server && server !== 'all') { const cleanName = server.replace('1Embed - ', '').toLowerCase(); - targets = PROVIDERS.filter(p => p.id === cleanName || p.name.toLowerCase().includes(cleanName)); + targets = PROVIDERS.filter(p => p.id.toLowerCase() === cleanName || p.name.toLowerCase().includes(cleanName)); if (!targets.length) targets = PROVIDERS; } const settled = await Promise.allSettled(targets.map(p => fetchProviderStream(p, type, id, s, e, token))); diff --git a/src/sources/anihq.js b/src/sources/anihq.js index e2c148b..13b9e9f 100644 --- a/src/sources/anihq.js +++ b/src/sources/anihq.js @@ -2,15 +2,27 @@ import { getTmdbInfo, USER_AGENT } from '../utils/helpers.js'; async function extractVoe(voeUrl) { try { - const res = await fetch(voeUrl, { + let res = await fetch(voeUrl, { headers: { 'User-Agent': USER_AGENT, 'Referer': 'https://anihq.cc/' } }); + let html = await res.text(); + + const redirectMatch = html.match(/window\.location\.href\s*=\s*['"](https?:\/\/[^'"]+)['"]/); + if (redirectMatch) { + res = await fetch(redirectMatch[1], { + headers: { + 'User-Agent': USER_AGENT, + 'Referer': 'https://anihq.cc/' + } + }); + html = await res.text(); + } + const mirrorUrl = res.url; - const html = await res.text(); const scriptMatch = html.match(/