diff --git a/src/background.ts b/src/background.ts new file mode 100644 index 0000000..50d60f0 --- /dev/null +++ b/src/background.ts @@ -0,0 +1,16 @@ +import {getMatch} from "./match/match"; +import {storageGet, storageSet} from "./store/store"; +import {Match} from "./match/matches"; + +chrome.webRequest.onBeforeRedirect.addListener(async details => { + // check if redirects origins from a previous redirect + if (await storageGet('redirect') === undefined) { + let match: Match + if ((match = await getMatch(new URL(details.url).host)) !== undefined) { + await storageSet('redirect', match.id) + } + } +}, { + urls: [''], + types: ['main_frame', 'sub_frame'] +}) diff --git a/src/index.ts b/src/index.ts index be14a37..4fe9103 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,24 +1,26 @@ -import {matches} from "./match/match"; -import {getAllDisabled, getDisabled} from "./store/store"; +import {getMatch} from "./match/match"; +import {storageDelete, storageGet} from "./store/store"; +import {Match, matches} from "./match/matches"; async function main() { - if (await getAllDisabled()) { + let match: Match; + if ((match = await getMatch(window.location.host)) === undefined) { + let id: string + if ((id = await storageGet('redirect')) !== undefined) { + match = matches.find(m => m.id === id) + await storageDelete('redirect') + } else { + return + } + } + + const re = document.body.innerHTML.match(match.regex) + if (re === null) { return } - for (const match of matches) { - if (!match.domains.some((v) => window.location.host.indexOf(v) !== -1) || ((await getDisabled()).some((v) => v === match))) { - continue - } - - const re = document.body.innerHTML.match(match.regex) - if (re === null) { - continue - } - - const url = await match.match(re) - location.assign(chrome.runtime.getURL(`ui/player/player.html?id=${match.id}&url=${encodeURIComponent(url)}`)) - } + const url = await match.match(re) + location.assign(chrome.runtime.getURL(`ui/player/player.html?id=${match.id}&url=${encodeURIComponent(url)}`)) } main() diff --git a/src/manifest.json b/src/manifest.json index 9d2beed..d0044a8 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -14,21 +14,7 @@ { "all_frames": true, "matches": [ - "*://*.evoload.io/*", - "*://*.mixdrop.co/*", - "*://*.newgrounds.com/*", - "*://*.streamtape.com/*", - "*://*.streamzz.to/*", - "*://*.streamz.ws/*", - "*://*.upstream.to/*", - "*://*.vidlox.me/*", - "*://*.vidoza.net/*", - "*://*.vivo.sx/*", - "*://*.voe.sx/*", - "*://*.voeunblk.com/*", - "*://*.voeun-block.net/*", - "*://*.un-block-voe.net/*", - "*://*.vupload.com/*" + "" ], "js": [ "index.js" @@ -36,8 +22,15 @@ "run_at": "document_end" } ], + "background": { + "scripts": [ + "background.js" + ] + }, "permissions": [ - "storage" + "storage", + "webRequest", + "" ], "browser_action": { "default_icon": { diff --git a/src/match/match.ts b/src/match/match.ts new file mode 100644 index 0000000..8884986 --- /dev/null +++ b/src/match/match.ts @@ -0,0 +1,14 @@ +import {Match, matches} from "./matches"; +import {getAllDisabled, getDisabled} from "../store/store"; + +export async function getMatch(host: string): Promise { + if (await getAllDisabled()) { + return undefined + } + + for (const match of matches) { + if (match.domains.some(v => host.indexOf(v) !== -1) && !((await getDisabled()).some(v => v === match))) { + return match + } + } +} diff --git a/src/match/matches.ts b/src/match/matches.ts index 896fd42..a41a1bf 100644 --- a/src/match/matches.ts +++ b/src/match/matches.ts @@ -192,10 +192,7 @@ class Voe implements Match { id = 'voe' reliability = Reliability.HIGH domains = [ - 'voe.sx', - 'voeunblk.com', - 'voeun-block.net', - 'un-block-voe.net' + 'voe.sx' ] regex = new RegExp(/https?:\/\/\S*m3u8(?=")/gm) diff --git a/src/store/store.ts b/src/store/store.ts index 60de76f..d28ae5e 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -1,6 +1,6 @@ -import {Match, matches} from "../match/match"; +import {Match, matches} from "../match/matches"; -async function storageGet(key: string): Promise { +export async function storageGet(key: string): Promise { return new Promise((resolve) => { chrome.storage.local.get(key, (value) => { resolve(value[key]) @@ -8,12 +8,16 @@ async function storageGet(key: string): Promise { }) } -async function storageSet(key: string, value: any) { +export async function storageSet(key: string, value: any) { const obj = {} obj[key] = value await chrome.storage.local.set(obj) } +export async function storageDelete(key: string) { + await chrome.storage.local.remove(key) +} + export async function getDisabled(): Promise { const localMatches = [] diff --git a/src/ui/player/player.ts b/src/ui/player/player.ts index 0f3cd18..bd665af 100644 --- a/src/ui/player/player.ts +++ b/src/ui/player/player.ts @@ -1,4 +1,4 @@ -import {Match, matches, Reliability} from "../../match/match"; +import {Match, matches, Reliability} from "../../match/matches"; // @ts-ignore import Hls from "hls.js"; diff --git a/src/ui/popup/popup.ts b/src/ui/popup/popup.ts index eca6e38..b4fc106 100644 --- a/src/ui/popup/popup.ts +++ b/src/ui/popup/popup.ts @@ -1,5 +1,5 @@ import {getDisabled, disable, enable, getAllDisabled, enableAll, disableAll} from "../../store/store"; -import {matches, Reliability} from "../../match/match"; +import {matches, Reliability} from "../../match/matches"; async function main() { const disabled = await getDisabled() diff --git a/tasks/build.ts b/tasks/build.ts index 69e085b..b5db602 100644 --- a/tasks/build.ts +++ b/tasks/build.ts @@ -9,59 +9,11 @@ const sass = require('node-sass') const sassPluginNodeImport = require('node-sass-package-importer') const typescript = require('typescript') -function getDomains() { - // because nodejs is nodejs, the simple commented out code below cannot be used. - // thus, the following bloated regexes must be used - /*const manifestMatches = [] - for (const m of matches) { - for (const domain of m.domains) { - manifestMatches.push(`*://*.${domain}/*`) - } - } - manifest['content_scripts']['matches'] = manifestMatches*/ - - let domains = [] - - const matchesRegex = new RegExp(/export\s+const\s+matches\s+=\s+(?\[.*?])/gms) - const matchesClassesRegex = new RegExp(/(?\w+)\(\)/gms) - - const matchTs = fs.readFileSync('src/match/matches.ts') - const jsMatches = matchesRegex.exec(matchTs).groups.matches - let m - while ((m = matchesClassesRegex.exec(jsMatches))) { - if (m.index === matchesClassesRegex.lastIndex) { - matchesClassesRegex.lastIndex++ - } - - if (m.groups.class !== undefined) { - const classDomainsRegex = new RegExp('class\\s+' + m.groups.class + '.*?domains\\s*=\\s*(?\\[.*?])', 'gms') - let mm - while ((mm = classDomainsRegex.exec(matchTs))) { - if (mm.index === classDomainsRegex.lastIndex) { - classDomainsRegex.lastIndex++ - } - - if (mm.groups.domains !== undefined) { - const matches = [] - for (const domain of JSON.parse(mm.groups.domains.replace(/'/g, '"', -1))) { - matches.push(domain) - } - domains = domains.concat(matches) - } - } - } - } - - return domains -} - async function buildManifest() { const manifest = JSON.parse(fs.readFileSync('src/manifest.json')) manifest['version'] = process.env.npm_package_version - manifest['content_scripts'][0]['matches'] = getDomains().map((domain) => {return `*://*.${domain}/*`}) - fs.writeFileSync('src/manifest.json', JSON.stringify(manifest, null, 2)) } @@ -115,6 +67,7 @@ async function buildJs() { 'src/ui/player/player.ts': 'build/ui/player/player.js', 'src/index.ts': 'build/index.js', + 'src/background.ts': 'build/background.js' } for (const [src, dst] of Object.entries(files)) {