diff --git a/package.json b/package.json index a0764f31..ca0077ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "movie-web", - "version": "3.2.2", + "version": "3.2.3", "private": true, "homepage": "https://movie-web.app", "dependencies": { diff --git a/src/backend/embeds/upcloud.ts b/src/backend/embeds/upcloud.ts index 4bac2b94..be1228f5 100644 --- a/src/backend/embeds/upcloud.ts +++ b/src/backend/embeds/upcloud.ts @@ -29,6 +29,32 @@ function isJSON(json: string) { } } +function extractKey(script: string): [number, number][] | null { + const startOfSwitch = script.lastIndexOf("switch"); + const endOfCases = script.indexOf("partKeyStartPosition"); + const switchBody = script.slice(startOfSwitch, endOfCases); + + const nums: [number, number][] = []; + const matches = switchBody.matchAll( + /:[a-zA-Z0-9]+=([a-zA-Z0-9]+),[a-zA-Z0-9]+=([a-zA-Z0-9]+);/g + ); + for (const match of matches) { + const innerNumbers: number[] = []; + for (const varMatch of [match[1], match[2]]) { + const regex = new RegExp(`${varMatch}=0x([a-zA-Z0-9]+)`, "g"); + const varMatches = [...script.matchAll(regex)]; + const lastMatch = varMatches[varMatches.length - 1]; + if (!lastMatch) return null; + const number = parseInt(lastMatch[1], 16); + innerNumbers.push(number); + } + + nums.push([innerNumbers[0], innerNumbers[1]]); + } + + return nums; +} + registerEmbedScraper({ id: "upcloud", displayName: "UpCloud", @@ -54,23 +80,31 @@ registerEmbedScraper({ let sources: { file: string; type: string } | null = null; if (!isJSON(streamRes.sources)) { - const decryptionKey = JSON.parse( - await proxiedFetch( - `https://raw.githubusercontent.com/enimax-anime/key/e4/key.txt` - ) - ) as [number, number][]; + const scriptJs = await proxiedFetch( + `https://rabbitstream.net/js/player/prod/e4-player.min.js`, + { + responseType: "text" as any, + } + ); + const decryptionKey = extractKey(scriptJs); + if (!decryptionKey) throw new Error("Key extraction failed"); let extractedKey = ""; - const sourcesArray = streamRes.sources.split(""); - for (const index of decryptionKey) { - for (let i: number = index[0]; i < index[1]; i += 1) { - extractedKey += streamRes.sources[i]; - sourcesArray[i] = ""; - } - } + let strippedSources = streamRes.sources; + let totalledOffset = 0; + decryptionKey.forEach(([a, b]) => { + const start = a + totalledOffset; + const end = start + b; + extractedKey += streamRes.sources.slice(start, end); + strippedSources = strippedSources.replace( + streamRes.sources.substring(start, end), + "" + ); + totalledOffset += b; + }); const decryptedStream = AES.decrypt( - sourcesArray.join(""), + strippedSources, extractedKey ).toString(enc.Utf8); const parsedStream = JSON.parse(decryptedStream)[0];